Untitled
unknown
plain_text
2 months ago
6.9 kB
2
Indexable
#include <Trade/Trade.mqh> #include <Arrays/ArrayLong.mqh> // Lot sizes for up to 20 orders in one cycle static double lotSizes[20] = {0.01, 0.02, 0.02, 0.03, 0.05, 0.08, 0.11, 0.17, 0.26, 0.38, 0.58, 0.86, 1.30, 1.95, 2.92, 4.38, 6.75, 9.85, 10, 10}; // Adjustable parameters input double StepPercent = 0.2; // Percentage change relative to the open price to trigger step-in input double ProfitLotStep = 10; // Profit threshold (scaled by lot) to close the cycle input double StopLoss = 300; // Stop-loss threshold (in account currency) to cut losses // Separate arrays to store tickets for BUY and SELL orders CArrayLong buyTickets; CArrayLong sellTickets; int barsTotal = 0; int OnInit() { barsTotal = iBars(_Symbol, PERIOD_M15); // Initialize barsTotal return(INIT_SUCCEEDED); } void OnDeinit(const int reason) { } // Function to close all BUY positions void CloseBuyPositions(CTrade &trade) { for (int i = buyTickets.Total() - 1; i >= 0; i--) { CPositionInfo pos; if (pos.SelectByTicket(buyTickets.At(i))) { if (trade.PositionClose(pos.Ticket())) { buyTickets.Delete(i); } } } } // Function to close all SELL positions void CloseSellPositions(CTrade &trade) { for (int i = sellTickets.Total() - 1; i >= 0; i--) { CPositionInfo pos; if (pos.SelectByTicket(sellTickets.At(i))) { if (trade.PositionClose(pos.Ticket())) { sellTickets.Delete(i); } } } } void OnTick() { // Update barsTotal if a new M15 bar is formed int currentBars = iBars(_Symbol, PERIOD_M15); if(currentBars != barsTotal) { barsTotal = currentBars; } CTrade trade; double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); // Calculate profit and total lot separately for BUY orders double buyProfit = 0, buyLots = 0; for (int i = 0; i < buyTickets.Total(); i++) { CPositionInfo pos; if (pos.SelectByTicket(buyTickets.At(i))) { buyProfit += pos.Profit() + pos.Swap(); buyLots += pos.Volume(); } } // Calculate profit and total lot separately for SELL orders double sellProfit = 0, sellLots = 0; for (int i = 0; i < sellTickets.Total(); i++) { CPositionInfo pos; if (pos.SelectByTicket(sellTickets.At(i))) { sellProfit += pos.Profit() + pos.Swap(); sellLots += pos.Volume(); } } double lotstep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP); // --- STEP-IN for BUY cycle --- if (buyTickets.Total() > 0 && buyTickets.Total() < 20) { CPositionInfo pos; if (pos.SelectByTicket(buyTickets.At(buyTickets.Total() - 1))) { double newLot = lotSizes[buyTickets.Total()]; // If the current bid is sufficiently lower than the open price of the last BUY order if (bid < pos.PriceOpen() - pos.PriceOpen() * StepPercent / 100) { Print(__FUNCTION__, " > Step buy Signal with lot ", newLot, "..."); if (trade.Buy(newLot) && trade.ResultOrder() > 0 && trade.ResultRetcode() == TRADE_RETCODE_DONE) buyTickets.Add(trade.ResultOrder()); } } } // --- STEP-IN for SELL cycle --- if (sellTickets.Total() > 0 && sellTickets.Total() < 20) { CPositionInfo pos; if (pos.SelectByTicket(sellTickets.At(sellTickets.Total() - 1))) { double newLot = lotSizes[sellTickets.Total()]; // If the current bid is sufficiently higher than the open price of the last SELL order if (bid > pos.PriceOpen() + pos.PriceOpen() * StepPercent / 100) { Print(__FUNCTION__, " > Step sell Signal with lot ", newLot, "..."); if (trade.Sell(newLot) && trade.ResultOrder() > 0 && trade.ResultRetcode() == TRADE_RETCODE_DONE) sellTickets.Add(trade.ResultOrder()); } } } // --- Activate initial orders for each independent cycle --- double openPrevious = iOpen(_Symbol, PERIOD_M15, 1); double openCurrent = iOpen(_Symbol, PERIOD_M15, 0); // If there are no BUY orders and the market is falling, then enter a BUY order if (buyTickets.Total() == 0 && openCurrent < openPrevious) { double newLot = lotSizes[0]; Print(__FUNCTION__, " Initial buy Signal with lot ", newLot, "..."); if (trade.Buy(newLot) && trade.ResultOrder() > 0 && trade.ResultRetcode() == TRADE_RETCODE_DONE) buyTickets.Add(trade.ResultOrder()); } // If there are no SELL orders and the market is rising, then enter a SELL order if (sellTickets.Total() == 0 && openCurrent > openPrevious) { double newLot = lotSizes[0]; Print(__FUNCTION__, " Initial sell Signal with lot ", newLot, "..."); if (trade.Sell(newLot) && trade.ResultOrder() > 0 && trade.ResultRetcode() == TRADE_RETCODE_DONE) sellTickets.Add(trade.ResultOrder()); } // --- Risk management for BUY cycle --- if (buyTickets.Total() > 0) { // If the profit target for the BUY cycle is reached if (buyProfit > ProfitLotStep * buyLots / lotstep) { Print(__FUNCTION__, " > BUY cycle hit profit target, closing BUY positions..."); CloseBuyPositions(trade); } // If loss exceeds the StopLoss for the BUY cycle if (buyProfit <= -StopLoss) { Print(__FUNCTION__, " > BUY cycle StopLoss reached (loss ", buyProfit, "), closing BUY positions..."); CloseBuyPositions(trade); } // If 20 BUY orders are reached in the cycle if (buyTickets.Total() >= 20) { Print(__FUNCTION__, " > 20 BUY orders reached, closing BUY cycle..."); CloseBuyPositions(trade); } } // --- Risk management for SELL cycle --- if (sellTickets.Total() > 0) { // If the profit target for the SELL cycle is reached if (sellProfit > ProfitLotStep * sellLots / lotstep) { Print(__FUNCTION__, " > SELL cycle hit profit target, closing SELL positions..."); CloseSellPositions(trade); } // If loss exceeds the StopLoss for the SELL cycle if (sellProfit <= -StopLoss) { Print(__FUNCTION__, " > SELL cycle StopLoss reached (loss ", sellProfit, "), closing SELL positions..."); CloseSellPositions(trade); } // If 20 SELL orders are reached in the cycle if (sellTickets.Total() >= 20) { Print(__FUNCTION__, " > 20 SELL orders reached, closing SELL cycle..."); CloseSellPositions(trade); } } }
Editor is loading...
Leave a Comment