Работа завершена
Техническое задание
Hello,
I am trying to develop an EA for the following simple strategy:
Symbol: US30 (Dow Jones Industrial Average)
Chart: 5m
Criteria:
1. At exactly 16:30:00 one buy stop and one sell stop order should be placed 70 points above and below the closing price of the 16:25 5-minute candle.
If the 16:25 candle has a body equal to or less than 50 points, the orders should be placed 100 points from the close of the 16:25 candle.
2. The risk for each order should be 1% of the account balance, I believe this can be achieved by using dynamic lot sizing, the lot sizes should be rounded to the nearest 0.1.
3. An initial stop loss of 150 points should be used. This becomes a trailing stop loss of 150 points as soon as possible, if it's possible to implement as soon as the position opens, that's perfect, this implementation is something I have struggled with hugely.
4. The three profit targets are: 1RR (150 points), 2RR (300 points) and 3RR (450 points). At each target, one third of the trade should be closed. This will mean that at 1RR 0.33% profit is made, at 2RR an extra 0.67% profit is made and at 3RR an extra 1% profit is made.
5. Once the first profit target is reached, the trailing stop loss should remain static at the entry price.
6. Any unopened orders should be cancelled when either of the following occurs:
A position closes at the third profit target.
5 minutes has passed.
Below I have included what I have been working on, although I am not a programmer. It is probably far too long and the trailing stop does not function, but it may give you some ideas, please feel free to reach out if you need any further clarity.
Many thanks,
steero89
#include <Trade\PositionInfo.mqh> #include <Trade\Trade.mqh> #include <Trade\SymbolInfo.mqh> // Declare and initialize trade objects CPositionInfo m_position; // Trade position object CTrade m_trade; // Trading object CSymbolInfo m_symbol; // Symbol info object // Declare trailing stop parameters bool trailingStopLoss = true; // Enable trailing stop loss input ushort InpTrailingStop = 1500; // Trailing Stop (in points) input ushort InpTrailingStep = 100; // Trailing Step (in points) // Define trailing stop and step variables double ExtTrailingStop = 0.0; double ExtTrailingStep = 0.0; // Function to place pending order with appropriate take profit and stop loss ulong PlacePendingOrder(int orderType, double price, bool isBuy) { MqlTradeRequest request; ZeroMemory(request); request.action = TRADE_ACTION_PENDING; // Set action to place pending order request.type = (ENUM_ORDER_TYPE)orderType; request.symbol = Symbol(); request.volume = 3.0; // Set volume as desired request.price = price; // Set order price if (isBuy) { request.tp = price + 4500 * _Point; // Set take profit above the entry price for buy orders request.sl = price - 1500 * _Point; // Set stop loss below the entry price for buy orders } else { request.tp = price - 4500 * _Point; // Set take profit below the entry price for sell orders request.sl = price + 1500 * _Point; // Set stop loss above the entry price for sell orders } request.type_filling = ORDER_FILLING_RETURN; request.type_time = ORDER_TIME_GTC; MqlTradeResult result; ulong ticket = OrderSend(request, result); return ticket; } // Function to modify position bool PositionModify(double stopLoss, double takeProfit) { if (!PositionSelect("")) // Select the first position { Print("No positions found. Exiting PositionModify function."); return false; } ulong ticket = PositionGetInteger(POSITION_TICKET); MqlTradeRequest request; MqlTradeResult result; ZeroMemory(request); request.action = TRADE_ACTION_SLTP; // Modify stop loss and take profit request.symbol = Symbol(); request.sl = stopLoss; // New stop loss request.tp = takeProfit; // New take profit if (OrderSend(request, result)) { Print("Position ", ticket, " modified successfully. New SL: ", stopLoss, ", New TP: ", takeProfit); return true; } else { Print("Failed to modify position ", ticket, ". Error code: ", GetLastError()); return false; } } void OnInit() { // Calculate trailing stop and step in points ExtTrailingStop = InpTrailingStop * _Point; ExtTrailingStep = InpTrailingStep * _Point; } void OnTick() { // Get the current server time datetime currentTime = TimeTradeServer(); // Declare an instance of the MqlDateTime structure MqlDateTime mqlTime; // Convert the datetime value to MqlDateTime structure TimeToStruct(currentTime, mqlTime); // Extract the current hour, minute, and second int currentHour = mqlTime.hour; int currentMinute = mqlTime.min; int currentSecond = mqlTime.sec; // Check if it's after 16:30:00 if (currentHour == 16 && currentMinute >= 30 && currentSecond >= 00) { // Apply trailing stop to open positions Trailing(); } // Check if it's exactly 10:45:00 and the trade execution time has not been reached yet if (currentHour == 16 && currentMinute == 30 && currentSecond == 00) { // Place pending orders PlacePendingOrders(); } } // Function to place pending orders void PlacePendingOrders() { // Calculate buy and sell stop prices based on the closing price of the 16:25 candle double closePrice = iClose(Symbol(), PERIOD_M5, 1); // Use index 1 to get the 16:25 candle double buyStopPrice = closePrice + 700 * _Point; double sellStopPrice = closePrice - 700 * _Point; // Place buy stop order without setting initial stop loss ulong buyStopTicket = PlacePendingOrder(ORDER_TYPE_BUY_STOP, buyStopPrice, true); // Pass true for isBuy for buy stop order if (buyStopTicket == 0) { Print("Failed to place buy stop order. Error code: ", GetLastError()); return; } // Place sell stop order without setting initial stop loss ulong sellStopTicket = PlacePendingOrder(ORDER_TYPE_SELL_STOP, sellStopPrice, false); // Pass false for isBuy for sell stop order if (sellStopTicket == 0) { Print("Failed to place sell stop order. Error code: ", GetLastError()); return; } Print("Buy stop order placed successfully. Ticket: ", buyStopTicket); Print("Sell stop order placed successfully. Ticket: ", sellStopTicket); } void Trailing() { if (!trailingStopLoss) { Print("Trailing stop is disabled. Exiting Trailing function."); return; } // Get the current trailing stop value double currentTrailingStop = ExtTrailingStop / _Point; if (currentTrailingStop == 0) { Print("Trailing stop is not initialized. Exiting Trailing function."); return; } for (int i = PositionsTotal() - 1; i >= 0; i--) // Loop through open positions { if (m_position.SelectByIndex(i)) { if (m_position.Symbol() == m_symbol.Name()) { // Check if position is profitable before applying trailing stop double positionProfitPoints = m_position.Profit() / _Point; if (positionProfitPoints > 5) // Modify this threshold as needed { double currentPrice = m_position.PositionType() == POSITION_TYPE_BUY ? SymbolInfoDouble(_Symbol, SYMBOL_BID) : SymbolInfoDouble(_Symbol, SYMBOL_ASK); double newStopLoss = m_position.PositionType() == POSITION_TYPE_BUY ? currentPrice - currentTrailingStop : currentPrice + currentTrailingStop; if (PositionModify(newStopLoss, m_position.TakeProfit())) { Print("Trailing stop modified for position ", m_position.Ticket(), ". New SL: ", newStopLoss); } else { Print("Failed to modify trailing stop for position ", m_position.Ticket(), ". Error code: ", GetLastError()); } } else { Print("Position ", m_position.Ticket(), " is not yet profitable. Trailing stop will not be applied."); } } } } }