//+------------------------------------------------------------------+ //| Grid_2.mq5 | //| AK47 | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "AK47" #property link "https://www.mql5.com" #property version "1.00" ///////INCLUDE////////// #include #include #include #include #include #include #include //#include //#include ////////GLOBALS////////////// enum Side { Buy=0, // Buy Sell=1, // Sell Both=2, // Both }; input double FixedLot=0.01; // Fixed Lot input Side EntrySide = 2; input double TakeProfitFactor=2; double StopLossFactor=3; input ushort Grid=250; // Grid Distance //input double CloseTreshold=1.05; //input double FreeMarginThreshold=0.3; //input double EquityStopLossPercent=0.9; input int PositionsThreshold=2; input double stDev = 1; // deviation int MALength = 12; input int bandsLength = 18; int ATR1Length = 12; int ATR2Length = 12; input double Grid_mul = 1.2, Vol_Mul=1.8; input string GMTstartTime = "11:30"; input string GMTendTime = "17:30"; input ENUM_TIMEFRAMES TimeFrame = PERIOD_M5; ////////////CLASSES//////////////////// CTrade trade; CDealInfo deal; CPositionInfo PosInfo; CArrayDouble List; CAccountInfo Account; COrderInfo OrdInfo; //CNews News; //CTime Time; //////////VARIABLES///////////// double MAHigh[], MAHighData, MAHighHandle, MALow[], MALowData, MALowHandle, MA[], MAData, MAHandle, Momentum[], MomentumData, MomentumHandle, bands[],bandsupper[],bandslower[], bandsHandle, bandsData, MFI[], MFIData, MFIHandle, ATR1[], ATR2[], ATR1Data, ATR2Data, ATR1Handle, ATR2Handle; //--- OPTIMIZATION: Position State Cache struct PositionState { int buyCount; int sellCount; double buyVolume; double sellVolume; double meanEntryBuy; double meanEntrySell; double highestBuy; double lowestBuy; double highestSell; double lowestSell; void Reset() { buyCount = 0; sellCount = 0; buyVolume = 0; sellVolume = 0; meanEntryBuy = 0; meanEntrySell = 0; highestBuy = 0; lowestBuy = 0; highestSell = 0; lowestSell = 0; } }; PositionState State; datetime ExpireDate; //--- END OPTIMIZATION double ask, bid, StopLossBuy=0, StopLossSell=0, TakeProfitBuy=0, TakeProfitSell=0, StartingBalance, spread, buyFactor, sellFactor, Grid_step_buy, Grid_step_sell, currentGrid, nextUpBuy, nextDownBuy, nextUpSell, nextDownSell, currentUpBuy, currentDownBuy, currentUpSell, currentDownSell, meanEntry; int upCount=0, downCount=0; double maxEquity, equityVolume = 1; string newGrid, previousGrid; double buyVolumeFactor = 1, sellVolumeFactor = 1, buyVolume, sellVolume; bool activateSL = false, buyStopSwitch = false, sellStopSwitch = false, buyLimitSwitch = false, sellLimitSwitch = false; MqlRates Bar1[]; // Removed redundant Bar2 //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- // News.LoadHistory(); StartingBalance = Account.Balance(); ChartSetSymbolPeriod(0,_Symbol,TimeFrame); MAHighHandle = iMA(_Symbol,TimeFrame,MALength,0,MODE_EMA,PRICE_HIGH); MAHandle = iMA(_Symbol,TimeFrame,MALength,0,MODE_EMA,PRICE_CLOSE); MALowHandle = iMA(_Symbol,TimeFrame,MALength,0,MODE_EMA,PRICE_LOW); bandsHandle = iBands(_Symbol,TimeFrame,bandsLength,0,stDev,PRICE_TYPICAL); ATR1Handle = iATR(_Symbol,TimeFrame,ATR1Length); ATR2Handle = iATR(_Symbol,PERIOD_H1,ATR2Length); MomentumHandle = iMomentum(_Symbol,TimeFrame,21,PRICE_MEDIAN); ArraySetAsSeries(MFI,true); ArraySetAsSeries(ATR1,true); ArraySetAsSeries(ATR2,true); ArraySetAsSeries(MAHigh,true); ArraySetAsSeries(MA,true); ArraySetAsSeries(MALow,true); ArraySetAsSeries(bands,true); ArraySetAsSeries(bandsupper,true); ArraySetAsSeries(bandslower,true); ArraySetAsSeries(Bar1, true); // Removed Bar2 initialization ArraySetAsSeries(Momentum, true); ExpireDate = StringToTime("2026.02.14"); // Optimization: Parse once bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits); ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); // double Prices[]; // double Volumes[]; // double levelstep = 5; // CalculateVolumeDistribution(3,levelstep,Volumes,Prices); // // int peaks[]; // int peak_count = ArrayPeaks(Prices,peaks,100); // // // FindIndices((ask+bid)/2,Prices,nextDown,nextUp); nextUpBuy = ask + Grid*_Point; nextDownBuy = bid - Grid*_Point; nextUpSell = ask + Grid*_Point; nextDownSell = bid - Grid*_Point; Print("Buy NextLevelUp: " + nextUpBuy); Print("Buy NextLevelDown: " + nextDownBuy); Print("Sell NextLevelUp: " + nextUpSell); Print("Sell NextLevelDown: " + nextDownSell); //Print("PeaksCount: " + peak_count); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- State.Reset(); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { UpdatePositionState(); // Optimization: Calculate all position stats once per tick // CloseByWin(); //Trailing(); //breakEven(); //TPmodify(); MqlDateTime dt; datetime gmtTime = TimeGMT(dt); bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits); ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); spread = ask - bid; //////////////TP&SL////////////////////////////////////////// MAHighData = CopyBuffer(MAHighHandle,0,0,4,MAHigh); MAData = CopyBuffer(MAHandle,0,0,4,MA); MALowData = CopyBuffer(MALowHandle,0,0,4,MALow); ATR1Data = CopyBuffer(ATR1Handle,0,0,15,ATR1); ATR2Data = CopyBuffer(ATR2Handle,0,0,15,ATR2); bandsData = CopyBuffer(bandsHandle,0,0,4,bands); bandsData = CopyBuffer(bandsHandle,1,0,4,bandsupper); bandsData = CopyBuffer(bandsHandle,2,0,4,bandslower); MomentumData = CopyBuffer(MomentumHandle,2,0,4,Momentum); CopyRates(_Symbol,TimeFrame,0,10,Bar1); // Removed redundant CopyRates for Bar2 // TakeProfitBuy = bid+Grid_step*TakeProfitFactor*_Point; // TakeProfitSell = ask-Grid_step*TakeProfitFactor*_Point; StopLossBuy = bands[1]; StopLossSell = bands[1]; //////////////////// Factors ////////////////////////////////// if(State.buyCount != 0) buyVolumeFactor = NormalizeDouble(MathPow(Vol_Mul,State.buyCount),0); else { buyVolumeFactor = 1; // Grid_step = Grid; } if(State.sellCount != 0) sellVolumeFactor = NormalizeDouble(MathPow(Vol_Mul,State.sellCount),0); else { sellVolumeFactor = 1; } if(PositionsTotal() < 1) { Grid_step_buy = Grid; Grid_step_sell = Grid; } ///////////////////BALANCEGRID////////////////////////////////// // string expire_date = "2026.02.14"; //<-- hard coded datetime // datetime e_d = StringToTime(expire_date); //bool tradetime = true;// (dt.hour == 8 || dt.hour == 14 || dt.hour == 0 || dt.hour == 1); bool tradetime = ((StringToTime(GMTstartTime) < StringToTime(GMTendTime) && gmtTime >= StringToTime(GMTstartTime) && gmtTime <= StringToTime(GMTendTime)) || (StringToTime(GMTstartTime) > StringToTime(GMTendTime) && gmtTime <= StringToTime(GMTstartTime) && gmtTime >= StringToTime(GMTendTime))); //bool tradays = !((dt.day >= 1 && dt.day <= 7 && dt.day_of_week == 5) || (dt.day >= 10 && dt.day <=13) || (dt.day == 16 && dt.mon == 10)); if(TimeCurrent() <= ExpireDate) //spread<1500*_Point){ { Grid_step_buy = Grid * MathPow(Grid_mul, State.buyCount); Grid_step_sell = Grid * MathPow(Grid_mul, State.sellCount); buyVolumeFactor = MathPow(Vol_Mul,State.buyCount); sellVolumeFactor = MathPow(Vol_Mul,State.sellCount); buyVolume = NormalizeDouble(equityVolume*buyVolumeFactor*FixedLot,2); sellVolume = NormalizeDouble(equityVolume*sellVolumeFactor*FixedLot,2); //double meanATR1 = ArrayCountAverage(ATR1,3); //double meanATR2 = ArrayCountAverage(ATR2,3); //Print("bands: " + bands[1]); //Comment("\MATR~1: " + meanATR1 + "MATR~2 " + meanATR2); //--- BuyLimit if(ask < nextDownBuy) { buyLimitSwitch = true; currentDownBuy = nextDownBuy; nextUpBuy = ask + Grid_step_buy*_Point; nextDownBuy = bid - Grid_step_buy*_Point; } //if(tradetime && (EntrySide == 2 || EntrySide == 0) && buyLimitSwitch && currentDownBuy + 10*_Point && !OtherBuyPosition(NULL) && ask < bandslower[1]) //{ // trade.Buy(buyVolume,_Symbol,0,StopLossBuy,TakeProfitBuy,"BuyLimit"); // buyLimitSwitch = false; //} //--- BuyStop if(ask > nextUpBuy) { buyStopSwitch = true; currentUpBuy = nextUpBuy; nextUpBuy = ask + Grid_step_buy*_Point; nextDownBuy = ask - Grid_step_buy*_Point; } if(tradetime && (EntrySide == 2 || EntrySide == 0) && buyStopSwitch && currentUpBuy - 1*_Point && !OtherBuyPosition(NULL) && ask > bandsupper[1] && Bar1[0].high > Bar1[1].high) { trade.Buy(buyVolume,_Symbol,0,StopLossBuy,TakeProfitBuy,"BuyStop"); buyStopSwitch = false; } //--- SellLimit if(bid > nextUpSell) { sellLimitSwitch = true; currentUpSell = nextUpSell; nextUpSell = bid + Grid_step_sell*_Point; nextDownSell = bid - Grid_step_sell*_Point; } //if(tradetime && (EntrySide == 2 || EntrySide == 1) && sellLimitSwitch && currentUpSell - 10*_Point && !OtherSellPosition(NULL) && bid > bandsupper[1]) //{ // trade.Sell(sellVolume,_Symbol,0,StopLossSell,TakeProfitSell,"SellLimit"); // sellLimitSwitch = false; //} //--- SellStop if(bid < nextDownSell)// && bid > currentDownSell + 10*_Point && ask < currentUpBuyStop - 10*_Point { sellStopSwitch = true; currentDownSell = nextDownSell; nextUpSell = bid + Grid_step_sell*_Point; nextDownSell = bid - Grid_step_sell*_Point; } if(tradetime && (EntrySide == 2 || EntrySide == 1) && sellStopSwitch && currentDownSell + 1*_Point && !OtherSellPosition(NULL) && bid < bandslower[1] && Bar1[0].low < Bar1[1].low) { trade.Sell(sellVolume,_Symbol,0,StopLossSell,TakeProfitSell,"SellStop"); sellStopSwitch = false; } } else { Comment("Your license is expired!"); } //////////////////////CLOSERS////////////////////////////////////////////// StoplossUpdate("buy"); StoplossUpdate("sell"); if(Account.Equity() > maxEquity && PositionsTotal() < 2) { maxEquity = Account.Equity(); //equityVolume = MathCeil(maxEquity/10000); //if(VolumeTotal("Total") > StartingBalance/1000) //{ // CloseAllPositions(); //} } if(Account.Equity() >= 1.01*maxEquity) { activateSL = true; maxEquity = Account.Equity(); } if(activateSL && Account.Equity() <= 1/(1.01)*maxEquity) { activateSL = false; //CloseAllPositions(); } } //+------------------------------------------------------------------+ //| Optimization: Unified Position Updater | //+------------------------------------------------------------------+ void UpdatePositionState() { State.Reset(); double buyPriceSum = 0; double sellPriceSum = 0; State.lowestBuy = 999999; // Init high State.highestBuy = 0; // Init low State.lowestSell = 999999; // Init high State.highestSell = 0; // Init low for(int i = PositionsTotal() - 1; i >= 0; i--) { ulong ticket = PositionGetTicket(i); if(ticket <= 0) continue; if(PositionGetString(POSITION_SYMBOL) == _Symbol) { long type = PositionGetInteger(POSITION_TYPE); double vol = PositionGetDouble(POSITION_VOLUME); double price = PositionGetDouble(POSITION_PRICE_OPEN); if(type == POSITION_TYPE_BUY) { State.buyCount++; State.buyVolume += vol; buyPriceSum += (vol * price); if(price < State.lowestBuy) State.lowestBuy = price; if(price > State.highestBuy) State.highestBuy = price; } else if(type == POSITION_TYPE_SELL) { State.sellCount++; State.sellVolume += vol; sellPriceSum += (vol * price); if(price < State.lowestSell) State.lowestSell = price; if(price > State.highestSell) State.highestSell = price; } } } // Calculate Means if(State.buyVolume > 0) State.meanEntryBuy = buyPriceSum / State.buyVolume; else { State.lowestBuy = 0; State.highestBuy = 0; } // Reset extremes if no positions if(State.sellVolume > 0) State.meanEntrySell = sellPriceSum / State.sellVolume; else { State.lowestSell = 0; State.highestSell = 0; } // Reset extremes if no positions } //+------------------------------------------------------------------+ //| Trade function | //+------------------------------------------------------------------+ void OnTrade() { //--- } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double ArrayCountAverage(double &array[], int count) { double sum; double mean; //if (ArraySize(array) < count - 1); //{ // Print("Array has less elements than required for mean" + ArraySize(array) + " count: " + (count-1)); //} for(int i=0;i=0; i--) { PositionGetTicket(i); ////////////////////////////////// if(type == "Buy" && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY && PositionGetString(POSITION_SYMBOL) == _Symbol) { quantity = quantity + PosInfo.Volume()*PosInfo.PriceOpen(); volume = volume + PosInfo.Volume(); } if(type == "Sell" && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL && PositionGetString(POSITION_SYMBOL) == _Symbol) { quantity = quantity + PosInfo.Volume()*PosInfo.PriceOpen(); volume = volume + PosInfo.Volume(); } if(type == "Total" && PositionGetString(POSITION_SYMBOL) == _Symbol) { quantity = quantity + PosInfo.Volume()*PosInfo.PriceOpen(); volume = volume + PosInfo.Volume(); } if(type == "BuysAbove" && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY && PosInfo.PriceOpen() > PosInfo.PriceCurrent() && PositionGetString(POSITION_SYMBOL) == _Symbol) { quantity = quantity + PosInfo.Volume()*PosInfo.PriceOpen(); volume = volume + PosInfo.Volume(); } if(type == "BuysBelow" && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY && PosInfo.PriceOpen() < PosInfo.PriceCurrent() && PositionGetString(POSITION_SYMBOL) == _Symbol) { quantity = quantity + PosInfo.Volume()*PosInfo.PriceOpen(); volume = volume + PosInfo.Volume(); } ///////////////////////////// if(type == "SellsAbove" && PosInfo.PositionType() == POSITION_TYPE_SELL && PosInfo.PriceOpen() > PosInfo.PriceCurrent() && PositionGetString(POSITION_SYMBOL) == _Symbol) { quantity = quantity + PosInfo.Volume()*PosInfo.PriceOpen(); volume = volume + PosInfo.Volume(); } if(type == "SellsBelow" && PosInfo.PositionType() == POSITION_TYPE_SELL && PosInfo.PriceOpen() < PosInfo.PriceCurrent() && PositionGetString(POSITION_SYMBOL) == _Symbol) { quantity = quantity + PosInfo.Volume()*PosInfo.PriceOpen(); volume = volume + PosInfo.Volume(); } } entry = quantity / volume; return entry; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double VolumeTotal(string positionType) { double totalVolume = 0; for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions { if(PosInfo.SelectByIndex(i) && positionType == "Buy" && PosInfo.PositionType() == POSITION_TYPE_BUY) { totalVolume += PosInfo.Volume(); } } //Print("BV: " + positionType + ": "+ totalVolume); for(int i = PositionsTotal() - 1; i >= 0; i--) { if(PosInfo.SelectByIndex(i) && positionType == "Sell" && PosInfo.PositionType() == POSITION_TYPE_SELL) { totalVolume += PosInfo.Volume(); } } //Print("SV: " + positionType + ": " + totalVolume); for(int i = PositionsTotal() - 1; i >= 0; i--) { if(PosInfo.SelectByIndex(i) && positionType == "Total") { totalVolume += PosInfo.Volume(); } } //Print("TV: " + positionType + ": " + totalVolume); return totalVolume; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int FindIndices(double value, double &arr[], int &indexlow, int &indexhigh) { int size = ArraySize(arr); // Check if the array has at least two elements if(size < 2) { Print("Array must have at least two elements."); // return -1; // Return -1 to indicate an error } // Iterate through the array to find the indices for(int i = 0; i < size - 1; i++) { if((value > arr[i] && value < arr[i+1]) || (value < arr[i] && value > arr[i+1])) { indexlow = i; indexhigh = i + 1; return 0; // Return 0 to indicate success } } // If no such indices are found Print("No indices found where the value is between two consecutive elements."); return -1; // Return -1 to indicate failure } //+------------------------------------------------------------------+ void CalculateVolumeDistribution(int Days, double levelStep, double &volumeArray[], double &priceLevelArray[]) { // Determine the number of bars in two full days int barsInFullDay = 1440; // 1440 minutes in a day int barsInDays = Days * barsInFullDay; // Calculate the number of bars that have elapsed today datetime currentTime = TimeCurrent(); datetime startOfDay = currentTime - (currentTime % 86400); // Start of the current day int barsElapsedToday = (int)((currentTime - startOfDay) / 60) ; // Convert seconds to minutes // Total lookback bars int lookbackBars = barsInDays + barsElapsedToday; // Initialize variables to store the lowest low and highest high double lowestLow = 0; double highestHigh = 0; // Arrays to store the data double lowArray[]; double highArray[]; long volumeArrayRaw[]; // Copy the data for the specified number of bars if(CopyLow(_Symbol, PERIOD_M1, 0, lookbackBars, lowArray) <= 0 || CopyHigh(_Symbol, PERIOD_M1, 0, lookbackBars, highArray) <= 0 || CopyTickVolume(_Symbol, PERIOD_M1, 0, lookbackBars, volumeArrayRaw) <= 0) { Print("Error copying data"); return; } // Loop through the lookback period to find the lowest low and highest high for(int i = 0; i < lookbackBars; i++) { double low = lowArray[i]; double high = highArray[i]; if((low != 0 && low < lowestLow) || lowestLow == 0) lowestLow = low; if(high > highestHigh) highestHigh = high; } Print("Lowest Level: ", lowestLow); Print("Highest Level: ", highestHigh); // Calculate the number of levels int numberOfLevels = int((highestHigh - lowestLow) / levelStep) + 1; // Resize the arrays to hold the data ArrayResize(volumeArray, numberOfLevels); ArrayResize(priceLevelArray, numberOfLevels); // Initialize arrays for(int i = 0; i < numberOfLevels; i++) { volumeArray[i] = 0; priceLevelArray[i] = lowestLow + i * levelStep; } // Aggregate volume for each level for(int i = 0; i < lookbackBars; i++) { double low = lowArray[i]; double high = highArray[i]; double volume = (double)volumeArrayRaw[i]; // Determine which levels the current bar's range covers int startLevel = int((low - lowestLow) / levelStep); int endLevel = int((high - lowestLow) / levelStep); // Distribute volume across the levels covered by the bar for(int level = startLevel; level <= endLevel; level++) { if(level >= 0 && level < numberOfLevels) { volumeArray[level] += volume; //Print("Level: ", level, " Volume: ", volumeArray[level]); } } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int ArrayPeaks(const double &array[], int &peaks[], double min_distance) { int LevelsToCheck = Grid; int array_size = ArraySize(array); if(array_size < LevelsToCheck) return 0; // Return 0 if the array is too small to have peaks int peak_count = 0; ArrayResize(peaks, array_size); // Resize peaks array to the maximum possible size initially // Iterate through the array to find peaks for(int i = (int)(LevelsToCheck/2); i < array_size - (int)(LevelsToCheck/2); i++) // Start from level index and end at array_size - level index { bool is_peak = true; // Check if the current element is greater than the elements in the range of indices around it for(int j = i - (int)(LevelsToCheck/2); j <= i + (int)(LevelsToCheck/2); j++) { if(j != i && array[i] <= array[j]) { is_peak = false; break; } } if(is_peak) { bool is_far_enough = true; for(int j = 0; j < peak_count; j++) { if(MathAbs(i - peaks[j]) < min_distance) { is_far_enough = false; break; } } if(is_far_enough) { peaks[peak_count] = i; peak_count++; } } } ArrayResize(peaks, peak_count); // Resize peaks array to the actual number of peaks found return peak_count; // Return the number of peaks found } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CalculateValueArea(const double &priceLevels[], const double &volumes[], double &valAreaHigh, double &valAreaLow, double percentage = 70.0) { int size = ArraySize(volumes); if(size <= 0 || size != ArraySize(priceLevels)) { //Print("Array Issue: Price Levels and Volumes don't match or are empty."); return; } // Calculate total volume double totalVolume = 0.0; for(int i = 0; i < size; i++) { totalVolume += volumes[i]; } // Target volume for the value area double targetVolume = totalVolume * (percentage / 100.0); // Find the POC int pocIndex = 0; double maxVolume = volumes[0]; for(int i = 1; i < size; i++) { if(volumes[i] > maxVolume) { maxVolume = volumes[i]; pocIndex = i; } } // Initialize the value area with the POC valAreaLow = priceLevels[pocIndex]; valAreaHigh = priceLevels[pocIndex]; double cumulativeVolume = maxVolume; // Expand the value area around the POC int leftIndex = pocIndex - 1; int rightIndex = pocIndex + 1; while(cumulativeVolume < targetVolume) { // Consider both directions and choose the one with larger volume if(leftIndex >= 0 && (rightIndex >= size || volumes[leftIndex] >= volumes[rightIndex])) { cumulativeVolume += volumes[leftIndex]; valAreaLow = priceLevels[leftIndex]; leftIndex--; } else if(rightIndex < size) { cumulativeVolume += volumes[rightIndex]; valAreaHigh = priceLevels[rightIndex]; rightIndex++; } else { // No more price levels to consider break; } } } ////////////////CLOSING FUNCTIONS//////////////////////////////////// //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CloseAllPositions() { for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions if(PosInfo.SelectByIndex(i)) // select a position { trade.PositionClose(PosInfo.Ticket()); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CancelLimits(string comment) { for(int i = OrdersTotal()-1; i>= 0; i--) if(OrdInfo.SelectByIndex(i) && PosInfo.Comment() == comment) { trade.OrderDelete(OrdInfo.Ticket()); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CloseByWinning() { for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions if(PosInfo.SelectByIndex(i)) { if(PosInfo.PositionType() == POSITION_TYPE_BUY) { double thebuy = PosInfo.PriceOpen(); int theBuyTicket = PosInfo.Ticket(); for(int i = PositionsTotal() - 1; i >= 0; i--) if(PosInfo.SelectByIndex(i)) { if(PosInfo.PositionType() == POSITION_TYPE_SELL) { double thesell = PosInfo.PriceOpen(); int theSellTicket = PosInfo.Ticket(); if(thesell - thebuy > 0) { trade.PositionCloseBy(theBuyTicket,theSellTicket); } } } } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CloseByLosing() { for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions if(PosInfo.SelectByIndex(i) && PosInfo.PositionType() == POSITION_TYPE_BUY) { double thebuy = PosInfo.PriceOpen(); int theBuyTicket = PosInfo.Ticket(); for(int i = PositionsTotal() - 1; i >= 0; i--) if(PosInfo.SelectByIndex(i) &&PosInfo.PositionType() == POSITION_TYPE_SELL) { double thesell = PosInfo.PriceOpen(); int theSellTicket = PosInfo.Ticket(); if(thesell - thebuy < -Grid*_Point) { trade.PositionCloseBy(theBuyTicket,theSellTicket); } } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CloseByWin() { int profitTicket; double profit; for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions if(PosInfo.SelectByIndex(i)) { if(PosInfo.PositionType() == POSITION_TYPE_BUY) { if(PosInfo.Profit() > profit) { profit = PosInfo.Profit(); } double thebuy = PosInfo.PriceOpen(); int theBuyTicket = PosInfo.Ticket(); for(int i = PositionsTotal() - 1; i >= 0; i--) if(PosInfo.SelectByIndex(i)) { if(PosInfo.PositionType() == POSITION_TYPE_SELL) { double thesell = PosInfo.PriceOpen(); int theSellTicket = PosInfo.Ticket(); if(thesell - thebuy > 0) { trade.PositionCloseBy(theBuyTicket,theSellTicket); } } } } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CloseByLoss() { for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions if(PosInfo.SelectByIndex(i) && PosInfo.PositionType() == POSITION_TYPE_BUY) { double thebuy = PosInfo.PriceOpen(); int theBuyTicket = PosInfo.Ticket(); for(int i = PositionsTotal() - 1; i >= 0; i--) if(PosInfo.SelectByIndex(i) &&PosInfo.PositionType() == POSITION_TYPE_SELL) { double thesell = PosInfo.PriceOpen(); int theSellTicket = PosInfo.Ticket(); if(thesell - thebuy < -Grid*_Point) { trade.PositionCloseBy(theBuyTicket,theSellTicket); } } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CloseWinners() { for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions if(PosInfo.SelectByIndex(i)) { if(PosInfo.Profit() > 0) { int Ticket = PosInfo.Ticket(); trade.PositionClose(Ticket); } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CloseLosers() { for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions if(PosInfo.SelectByIndex(i)) { if(PosInfo.Profit() < 0) { int Ticket = PosInfo.Ticket(); trade.PositionClose(Ticket); } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CloseBuyWin() { double Profit; int ProfitTicket; for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions { if(PosInfo.SelectByIndex(i)) { if(PosInfo.PositionType() == POSITION_TYPE_BUY && PosInfo.Profit() > Profit && PosInfo.Profit() > 0) { Profit = PosInfo.Profit(); ProfitTicket = PosInfo.Ticket(); } } } trade.PositionClose(ProfitTicket); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CloseSellWin() { double Profit; int ProfitTicket; for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions { if(PosInfo.SelectByIndex(i)) { if(PosInfo.PositionType() == POSITION_TYPE_SELL && PosInfo.Profit() > Profit && PosInfo.Profit() > 0) { Profit = PosInfo.Profit(); ProfitTicket = PosInfo.Ticket(); } } } trade.PositionClose(ProfitTicket); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CloseBuyLoss() { double Profit; int ProfitTicket; for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions { if(PosInfo.SelectByIndex(i)) { if(PosInfo.PositionType() == POSITION_TYPE_BUY && PosInfo.Profit() < Profit && PosInfo.Profit() < 0) { Profit = PosInfo.Profit(); ProfitTicket = PosInfo.Ticket(); } } } trade.PositionClose(ProfitTicket); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double HighestBuy() { double Price = 0; for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions { if(PosInfo.SelectByIndex(i)) { if(PosInfo.PositionType() == POSITION_TYPE_BUY && PosInfo.PriceOpen() > Price) { Price = PosInfo.PriceOpen(); } } } return Price; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double HighestSell() { double Price = 0; for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions { if(PosInfo.SelectByIndex(i)) { if(PosInfo.PositionType() == POSITION_TYPE_SELL && PosInfo.PriceOpen() > Price) { Price = PosInfo.PriceOpen(); } } } return Price; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double LowestBuy() { double Price = 2; for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions { if(PosInfo.SelectByIndex(i)) { if(PosInfo.PositionType() == POSITION_TYPE_BUY && PosInfo.PriceOpen() < Price) { Price = PosInfo.PriceOpen(); } } } return Price; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double LowestSell() { double Price = 2; for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions { if(PosInfo.SelectByIndex(i)) { if(PosInfo.PositionType() == POSITION_TYPE_SELL && PosInfo.PriceOpen() < Price) { Price = PosInfo.PriceOpen(); } } } return Price; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CloseSellLoss() { double Profit; int ProfitTicket; for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions { if(PosInfo.SelectByIndex(i)) { if(PosInfo.PositionType() == POSITION_TYPE_SELL && PosInfo.Profit() < Profit && PosInfo.Profit() < 0) { Profit = PosInfo.Profit(); ProfitTicket = PosInfo.Ticket(); } } } trade.PositionClose(ProfitTicket); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void MAStopLoss() { int ProfitTicket; for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions { if(PosInfo.SelectByIndex(i)) { if(PosInfo.PositionType() == POSITION_TYPE_BUY && PosInfo.PriceOpen() > MAHigh[0] && PosInfo.PriceCurrent() < MALow[0]) { ProfitTicket = PosInfo.Ticket(); trade.PositionClose(ProfitTicket); } if(PosInfo.PositionType() == POSITION_TYPE_SELL && PosInfo.PriceOpen() < MALow[0]&& PosInfo.PriceCurrent() > MAHigh[0]) { ProfitTicket = PosInfo.Ticket(); trade.PositionClose(ProfitTicket); } } } } ///////////////////POSITIONS CHECK///////////////////////// //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool OtherBuyPosition(string comment) { bool other = false; for(int i = PositionsTotal(); i >=0; i--) { ulong ticket = PositionGetTicket(i); if(PosInfo.SelectByTicket(ticket)) { double currentPrice = PosInfo.PriceCurrent(); double openPrice = PosInfo.PriceOpen(); if(MathAbs(currentPrice-openPrice) < Grid_step_buy*_Point && PosInfo.PositionType() == POSITION_TYPE_BUY && (comment == PosInfo.Comment() || comment == NULL)) { other = true; break; } else { other = false; } } } //Print("otherbuyposition: " + other); return other; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool OtherSellPosition(string comment) { bool other = false; for(int i = PositionsTotal(); i >=0; i--) { ulong ticket = PositionGetTicket(i); if(PosInfo.SelectByTicket(ticket)) { double currentPrice = PosInfo.PriceCurrent(); double openPrice = PosInfo.PriceOpen(); if(MathAbs(currentPrice-openPrice) < Grid_step_sell*_Point && PosInfo.PositionType() == POSITION_TYPE_SELL && (comment == PosInfo.Comment() || comment == NULL)) { other = true; break; } else { other = false; } } } //Print("othersellposition: " + other); return other; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CloseBuys() { for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions if(PosInfo.SelectByIndex(i) && PosInfo.PositionType() == POSITION_TYPE_BUY) { double thebuy = PosInfo.PriceOpen(); int theBuyTicket = PosInfo.Ticket(); trade.PositionClose(theBuyTicket); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CloseSells() { for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions if(PosInfo.SelectByIndex(i) &&PosInfo.PositionType() == POSITION_TYPE_SELL) { double thesell = PosInfo.PriceOpen(); int theSellTicket = PosInfo.Ticket(); trade.PositionClose(theSellTicket); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CloseBuy() { double Profit; int theBuyTicket = PosInfo.Ticket(); for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions { if(PosInfo.SelectByIndex(i) && PosInfo.PositionType() == POSITION_TYPE_BUY) { if(Profit>PosInfo.Profit()) { Profit = PosInfo.Profit(); theBuyTicket = PosInfo.Ticket(); } } } trade.PositionClose(theBuyTicket); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CloseSell() { double Profit; int theSellTicket = PosInfo.Ticket(); for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions { if(PosInfo.SelectByIndex(i) && PosInfo.PositionType() == POSITION_TYPE_SELL) { if(Profit>PosInfo.Profit()) { Profit = PosInfo.Profit(); theSellTicket = PosInfo.Ticket(); } } } trade.PositionClose(theSellTicket); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void Trailing() { // if(PositionGetInteger(POSITION_MAGIC) == 444444)//adding magic number, if you want you can delete this if you don't want to use magic number // { for(int i=PositionsTotal()-1; i>=0; i--) { // string symbol = PositionGetSymbol(i); ulong PositionTicket = PositionGetTicket(i); long trade_type = PositionGetInteger(POSITION_TYPE); if(trade_type == 0)// && (PositionGetString(POSITION_COMMENT) == "BuyLimit" || PositionGetString(POSITION_COMMENT) == "BuyGrid")) { if(bid > PositionGetDouble(POSITION_PRICE_OPEN) + NormalizeDouble(_Point * Grid,_Digits)) { trade.PositionModify(PositionTicket,NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN) + Grid*_Point,_Digits),PositionGetDouble(POSITION_TP)); } } if(trade_type == 1)// && (PositionGetString(POSITION_COMMENT) == "SellLimit"|| PositionGetString(POSITION_COMMENT) == "SellGrid")) { if(ask < PositionGetDouble(POSITION_PRICE_OPEN) - NormalizeDouble(_Point * Grid,_Digits)) { trade.PositionModify(PositionTicket,NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN) - Grid*_Point,_Digits),PositionGetDouble(POSITION_TP)); } } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void TPmodify() { // if(PositionGetInteger(POSITION_MAGIC) == 444444)//adding magic number, if you want you can delete this if you don't want to use magic number // { for(int i=PositionsTotal()-1; i>=0; i--) { ulong PositionTicket = PositionGetTicket(i); long trade_type = PositionGetInteger(POSITION_TYPE); if(trade_type == 0 && PosInfo.TakeProfit() != State.meanEntryBuy + TakeProfitFactor*Grid*_Point && State.buyCount > PositionsThreshold) { trade.PositionModify(PositionTicket,PositionGetDouble(POSITION_SL),PositionGetDouble(POSITION_PRICE_OPEN) + TakeProfitFactor*Grid*_Point); if(PosInfo.PriceCurrent() > State.meanEntryBuy + Grid*_Point) CloseBuys(); } if(trade_type == 1 && PosInfo.TakeProfit() != State.meanEntrySell - TakeProfitFactor*Grid*_Point && State.sellCount > PositionsThreshold) { trade.PositionModify(PositionTicket,PositionGetDouble(POSITION_SL),PositionGetDouble(POSITION_PRICE_OPEN) - TakeProfitFactor*Grid*_Point); if(PosInfo.PriceCurrent() < State.meanEntrySell - Grid*_Point) CloseSells(); } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void breakEven() { for(int i=PositionsTotal()-1; i>=0; i--) { ulong PositionTicket = PositionGetTicket(i); long trade_type = PositionGetInteger(POSITION_TYPE); if(trade_type == 0) if(PosInfo.PriceCurrent() - PosInfo.PriceOpen() > 2*Grid*_Point && (PosInfo.StopLoss() < PosInfo.PriceOpen() || PosInfo.StopLoss() == 0))// && (PositionGetString(POSITION_COMMENT) == "BuyLimit" || PositionGetString(POSITION_COMMENT) == "BuyGrid")) { trade.PositionModify(PositionTicket,NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN) + Grid*_Point,_Digits),PositionGetDouble(POSITION_TP)); } if(trade_type == 1) if(PosInfo.PriceCurrent() - PosInfo.PriceOpen() < 2*Grid*_Point && (PosInfo.StopLoss() > PosInfo.PriceOpen() || PosInfo.StopLoss() == 0))// && (PositionGetString(POSITION_COMMENT) == "BuyLimit" || PositionGetString(POSITION_COMMENT) == "BuyGrid")) { trade.PositionModify(PositionTicket,NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN) - Grid*_Point,_Digits),PositionGetDouble(POSITION_TP)); } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void slStepUp() { for(int i=PositionsTotal()-1; i>=0; i--) { ulong PositionTicket = PositionGetTicket(i); long trade_type = PositionGetInteger(POSITION_TYPE); if(trade_type == 0 && PosInfo.StopLoss() > PosInfo.PriceOpen())// && (PositionGetString(POSITION_COMMENT) == "BuyLimit" || PositionGetString(POSITION_COMMENT) == "BuyGrid")) { trade.PositionModify(PositionTicket,NormalizeDouble(PositionGetDouble(POSITION_SL) + Grid*_Point,_Digits),PositionGetDouble(POSITION_TP)); } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void slStepDown() { for(int i=PositionsTotal()-1; i>=0; i--) { ulong PositionTicket = PositionGetTicket(i); long trade_type = PositionGetInteger(POSITION_TYPE); if(trade_type == 1 && PosInfo.StopLoss() < PosInfo.PriceOpen())// && (PositionGetString(POSITION_COMMENT) == "BuyLimit" || PositionGetString(POSITION_COMMENT) == "BuyGrid")) { trade.PositionModify(PositionTicket,NormalizeDouble(PositionGetDouble(POSITION_SL) - Grid*_Point,_Digits),PositionGetDouble(POSITION_TP)); } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void StoplossUpdate(string comment) { int buyCount = State.buyCount; int sellCount = State.sellCount; double meanEntryBuy = State.meanEntryBuy; double meanEntrySell = State.meanEntrySell; for(int i=PositionsTotal()-1; i>=0; i--) { ulong PositionTicket = PositionGetTicket(i); long trade_type = PositionGetInteger(POSITION_TYPE); double newStopLoss; if(trade_type == 0 && comment == "buy") { if(ask < meanEntryBuy + TakeProfitFactor*Grid*_Point) newStopLoss = StopLossBuy; if(ask > meanEntryBuy + TakeProfitFactor*Grid*_Point && buyCount > PositionsThreshold) newStopLoss = NormalizeDouble((((ask + meanEntryBuy)/2)+ask)/2, _Digits); if(PositionGetDouble(POSITION_SL) < newStopLoss - 5*_Point && newStopLoss != PositionGetDouble(POSITION_SL)) trade.PositionModify(PositionTicket,newStopLoss,PositionGetDouble(POSITION_TP)); } if(trade_type == 1 && comment == "sell") { if(bid > meanEntrySell - TakeProfitFactor*Grid*_Point) newStopLoss = StopLossSell; if(bid < meanEntrySell - TakeProfitFactor*Grid*_Point && sellCount > PositionsThreshold) newStopLoss = NormalizeDouble((((bid + meanEntrySell)/2)+bid)/2,_Digits); if((PositionGetDouble(POSITION_SL) > newStopLoss + 5*_Point || PositionGetDouble(POSITION_SL) == 0) && newStopLoss != PositionGetDouble(POSITION_SL)) trade.PositionModify(PositionTicket,newStopLoss,PositionGetDouble(POSITION_TP)); } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ string crossOver(double &Array1[], double &Array2[]) { string crossOver; if(Array1[1] > Array2[1] && Array1[2] < Array2[2]) { crossOver = "up"; } if(Array1[1] < Array2[1] && Array1[2] > Array2[2]) { crossOver = "down"; } else { crossOver = NULL; } return (crossOver); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int BuyPositionsCount() { int Buys = 0; for(int i = PositionsTotal()-1; i>=0; i--) { PositionGetTicket(i); if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY && PositionGetString(POSITION_SYMBOL) == _Symbol) { Buys = Buys+1; } } return Buys; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int SellPositionsCount() { int Sells = 0; for(int i = PositionsTotal()-1; i>=0; i--) { PositionGetTicket(i); if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL && PositionGetString(POSITION_SYMBOL) == _Symbol) { Sells = Sells+1; } } return Sells; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void SLmodify() { // if(PositionGetInteger(POSITION_MAGIC) == 444444)//adding magic number, if you want you can delete this if you don't want to use magic number // { for(int i=PositionsTotal()-1; i>=0; i--) { ulong PositionTicket = PositionGetTicket(i); long trade_type = PositionGetInteger(POSITION_TYPE); if(trade_type == 0 && PosInfo.PriceCurrent() > State.meanEntryBuy + (0.5*Grid*_Point) && (PositionGetDouble(POSITION_SL) < PosInfo.PriceCurrent() - ((State.lowestBuy + 0.5*Grid*_Point)-State.meanEntryBuy) || PositionGetDouble(POSITION_SL) == 0)) { trade.PositionModify(PositionTicket,PosInfo.PriceCurrent() - ((State.lowestBuy + 0.5*Grid*_Point)-State.meanEntryBuy),PositionGetDouble(POSITION_TP)); Print("Lowest buy: " + State.lowestBuy); } if(trade_type == 1 && PosInfo.PriceCurrent() < State.meanEntrySell - (0.5*Grid*_Point) && (PositionGetDouble(POSITION_SL) > PosInfo.PriceCurrent() - ((State.highestSell - 0.5*Grid*_Point)-State.meanEntrySell) || PositionGetDouble(POSITION_SL) == 0)) { trade.PositionModify(PositionTicket,PosInfo.PriceCurrent() - ((State.highestSell - 0.5*Grid*_Point)-State.meanEntrySell),PositionGetDouble(POSITION_TP)); Print("highest sell: " + State.highestSell); } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double meanEntryPriceBuy() { double price = 0; double volume = 0; double entry; for(int i = PositionsTotal()-1; i>=0; i--) { PositionGetTicket(i); if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY && PositionGetString(POSITION_SYMBOL) == _Symbol) { price = price + PosInfo.Volume()*PosInfo.PriceOpen(); } } for(int i = PositionsTotal()-1; i>=0; i--) { PositionGetTicket(i); if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY && PositionGetString(POSITION_SYMBOL) == _Symbol) { volume = volume + PosInfo.Volume(); } } entry = price / volume; return entry; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double meanEntryPriceSell() { double price = 0; double volume = 0; double entry; for(int i = PositionsTotal()-1; i>=0; i--) { PositionGetTicket(i); if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL && PositionGetString(POSITION_SYMBOL) == _Symbol) { price = price + PosInfo.Volume()*PosInfo.PriceOpen(); } } for(int i = PositionsTotal()-1; i>=0; i--) { PositionGetTicket(i); if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL && PositionGetString(POSITION_SYMBOL) == _Symbol) { volume = volume + PosInfo.Volume(); } } entry = price / volume; return entry; } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+