HELP!: Invalid stop loss or take profit levels for sell order

 

Good day

I have no idea why this issue keeps on happening and am hoping you guys/gals can help me.

I have the following code;

//+------------------------------------------------------------------+
//|                                       SuperTrader_V1.1.mq5      |
//|                                   Dream Design Productions      |
//|                                      www.dreamdesign.co.za      |
//+------------------------------------------------------------------+
#property copyright "Dream Design Productions"
#property link      "www.dreamdesign.co.za"
#property version   "1.00"

#include <Trade\Trade.mqh> // Include Trade library for OrderSend function
#include <Trade\OrderInfo.mqh>
#include <Trade\HistoryOrderInfo.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\DealInfo.mqh>

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
input double LotSize = 0.1;
input int TakeProfit = 80;
input int StopLoss = 150;
input int SMAPeriodFast = 8;
input int SMAPeriodSlow = 21;
input int TrailingStop = 50; // Trailing stop in points

CTrade trade; // Instance of the CTrade class

datetime lastTradeTime = 0; // Variable to store the time of the last trade
const int tradeExpirationTime = 5 * 60; // 5 minutes in seconds

string TimeframeToString(int timeframe)
{
    switch (timeframe)
    {
        case PERIOD_M1: return "M1";
        case PERIOD_M5: return "M5";
        case PERIOD_M15: return "M15";
        case PERIOD_M30: return "M30";
        case PERIOD_H1: return "H1";
        case PERIOD_H4: return "H4";
        case PERIOD_D1: return "D1";
        case PERIOD_W1: return "W1";
        case PERIOD_MN1: return "MN1";
        default: return "Unknown";
    }
}

int OnInit()
{
    // Display the symbol and timeframe on the chart
    string info = "Symbol: " + Symbol() + ", Timeframe: " + TimeframeToString(Period());
    Comment(info);
   
    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
    // Remove the comment when the EA is removed from the chart
    Comment("");
}

//+------------------------------------------------------------------+
//| Function to check if a trade is within the expiration time       |
//+------------------------------------------------------------------+
bool IsTradeExpired()
{
    if (lastTradeTime == 0) return false; // No trades have been placed yet
    
    datetime currentTime = TimeCurrent();
    int secondsPassed = (int)(currentTime - lastTradeTime);
    return secondsPassed >= tradeExpirationTime;
}

//+------------------------------------------------------------------+
//| Function to close all positions                                  |
//+------------------------------------------------------------------+
void CloseAllPositions()
{
    for (int i = PositionsTotal() - 1; i >= 0; i--)
    {
        ulong ticket = PositionGetTicket(i);
        if (!trade.PositionClose(ticket))
        {
            Print("Error closing position with ticket ", ticket);
        }
    }
}

//+------------------------------------------------------------------+
//| Function to check for a crossover within 5 minutes after opening |
//| a trade and close the trade if a crossover occurs                |
//+------------------------------------------------------------------+
void CheckAndCloseTradeOnCrossover()
{
    double ma_fast = iMA(Symbol(), PERIOD_M1, SMAPeriodFast, 0, MODE_SMA, PRICE_CLOSE);
    double ma_slow = iMA(Symbol(), PERIOD_M1, SMAPeriodSlow, 0, MODE_SMA, PRICE_CLOSE);
    
    if (ma_fast > ma_slow && PositionsTotal() > 0) // If there are buy positions
    {
        if (IsTradeExpired())
        {
            Print("Closing buy trade due to crossover within 5 minutes after opening.");
            CloseAllPositions();
        }
    }
    else if (ma_fast < ma_slow && PositionsTotal() > 0) // If there are sell positions
    {
        if (IsTradeExpired())
        {
            Print("Closing sell trade due to crossover within 5 minutes after opening.");
            CloseAllPositions();
        }
    }
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
    // Check and close trade if there is a crossover within 5 minutes after opening
    CheckAndCloseTradeOnCrossover();

    //---
    double ma_fast = iMA(Symbol(), PERIOD_M1, SMAPeriodFast, 0, MODE_SMA, PRICE_CLOSE);
    double ma_slow = iMA(Symbol(), PERIOD_M1, SMAPeriodSlow, 0, MODE_SMA, PRICE_CLOSE);
    double Point = SymbolInfoDouble(Symbol(), SYMBOL_POINT); // Define Point outside the loop to avoid repeated calls

    if (ma_fast < ma_slow)
    {
        // Check if we are not already in a sell position
        if (PositionsTotal() == 0 || PositionGetInteger(POSITION_TYPE) != POSITION_TYPE_SELL)
        {
            double openPrice = SymbolInfoDouble(Symbol(), SYMBOL_BID);
            double stopLossPrice = openPrice + StopLoss * Point;
            double takeProfitPrice = openPrice - TakeProfit * Point;

            // Check if stop loss and take profit levels are valid
            if (stopLossPrice <= openPrice && takeProfitPrice >= openPrice) {
                MqlTradeRequest request;
                MqlTradeResult result;
                ZeroMemory(request);
                ZeroMemory(result);
                request.action = TRADE_ACTION_DEAL; // Market order
                request.symbol = Symbol();
                request.volume = LotSize;
                request.price = openPrice;
                request.sl = stopLossPrice;
                request.tp = takeProfitPrice;
                request.type = ORDER_TYPE_SELL; // Sell order
                ulong ticket = OrderSend(request, result);
                if (ticket > 0)
                {
                    Print("Sell order placed successfully. Ticket: ", ticket);
                    lastTradeTime = TimeCurrent(); // Update last trade time
                }
                else
                {
                    Print("Error placing sell order. Error code: ", GetLastError());
                }
            } else {
                Print("Invalid stop loss or take profit levels for sell order.");
            }
        }
        else // Adjust the stop loss for the existing position using trailing stop
        {
            ulong positionTicket = PositionGetTicket(0);
            double currentStopLoss = PositionGetDouble(POSITION_SL);
            double newStopLoss = SymbolInfoDouble(Symbol(), SYMBOL_BID) - TrailingStop * Point;

            // Ensure the new stop loss is closer than the current one
            if (newStopLoss > currentStopLoss)
            {
                newStopLoss = currentStopLoss;
            }

            // Only update the stop loss if it has changed
            if (newStopLoss != currentStopLoss)
            {
                if (!trade.PositionModify(positionTicket, newStopLoss, PositionGetDouble(POSITION_TP)))
                {
                    Print("Error updating trailing stop for position ", positionTicket, ". Error code: ", GetLastError());
                }
            }
        }
    }
    else if (ma_fast > ma_slow) // Condition for buy trades
    {
        // Check if we are not already in a buy position
        if (PositionsTotal() == 0 || PositionGetInteger(POSITION_TYPE) != POSITION_TYPE_BUY)
        {
            double openPrice = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
            double stopLossPrice = openPrice - StopLoss * Point;
            double takeProfitPrice = openPrice + TakeProfit * Point;

            // Check if stop loss and take profit levels are valid
            if (stopLossPrice >= openPrice && takeProfitPrice <= openPrice) {
                MqlTradeRequest request;
                MqlTradeResult result;
                ZeroMemory(request);
                ZeroMemory(result);
                request.action = TRADE_ACTION_DEAL; // Market order
                request.symbol = Symbol();
                request.volume = LotSize;
                request.price = openPrice;
                request.sl = stopLossPrice;
                request.tp = takeProfitPrice;
                request.type = ORDER_TYPE_BUY; // Buy order
                ulong ticket = OrderSend(request, result);
                if (ticket > 0)
                {
                    Print("Buy order placed successfully. Ticket: ", ticket);
                    lastTradeTime = TimeCurrent(); // Update last trade time
                }
                else
                {
                    Print("Error placing buy order. Error code: ", GetLastError());
                }
            } else {
                Print("Invalid stop loss or take profit levels for buy order.");
            }
        }
        else // Adjust the stop loss for the existing position using trailing stop
        {
            ulong positionTicket = PositionGetTicket(0);
            double currentStopLoss = PositionGetDouble(POSITION_SL);
            double newStopLoss = SymbolInfoDouble(Symbol(), SYMBOL_ASK) + TrailingStop * Point;

            // Ensure the new stop loss is closer than the current one
            if (newStopLoss < currentStopLoss)
            {
                newStopLoss = currentStopLoss;
            }

            // Only update the stop loss if it has changed
            if (newStopLoss != currentStopLoss)
            {
                if (!trade.PositionModify(positionTicket, newStopLoss, PositionGetDouble(POSITION_TP)))
                {
                    Print("Error updating trailing stop for position ", positionTicket, ". Error code: ", GetLastError());
                }
            }
        }
    }
}

It compiles fine and has no errors when I attach it to the chart window, but when I run it through the strategy tester is keeps on giving me the same error;

2024.03.07 11:44:23.507 Core 01 2024.03.05 23:59:53   Invalid stop loss or take profit levels for sell order.

2024.03.07 11:44:23.507 Core 01 2024.03.05 23:59:54   Invalid stop loss or take profit levels for sell order.

2024.03.07 11:44:23.507 Core 01 2024.03.05 23:59:55   Invalid stop loss or take profit levels for sell order.

2024.03.07 11:44:23.507 Core 01 2024.03.05 23:59:56   Invalid stop loss or take profit levels for sell order.

2024.03.07 11:44:23.507 Core 01 2024.03.05 23:59:57   Invalid stop loss or take profit levels for sell order.

2024.03.07 11:44:23.507 Core 01 2024.03.05 23:59:59   Invalid stop loss or take profit levels for sell order.

2024.03.07 11:44:23.507 Core 01 final balance 10000.00 USD

2024.03.07 11:44:23.507 Core 01 DEX 900 DOWN Index,M1: 429255 ticks, 7200 bars generated. Environment synchronized in 0:00:00.025. Test passed in 0:00:01.003.

2024.03.07 11:44:23.507 Core 01 DEX 900 DOWN Index,M1: total time from login to stop testing 0:00:01.028 (including 0:00:00.025 for history data synchronization)

2024.03.07 11:44:23.507 Core 01 914 Mb memory used including 26 Mb of history data, 64 Mb of tick data

2024.03.07 11:44:23.507 Core 01 log file "C:\Users\Dream Design\AppData\Roaming\MetaQuotes\Tester\FB9A56D617EDDDFE29EE54EBEFFE96C1\Agent-127.0.0.1-3000\logs\20240307.log" written

2024.03.07 11:44:23.883 Core 01 connection closed


Can anyone please help me or tell me what I am doing wrong?
P.S. I am not a programmer. I coded this EA using ChatGPT. It is an experiment.


Thank you.

 
Use CheckStopLoss_Takeprofit function introduced in this link.
The checks a trading robot must pass before publication in the Market
The checks a trading robot must pass before publication in the Market
  • www.mql5.com
Before any product is published in the Market, it must undergo compulsory preliminary checks in order to ensure a uniform quality standard. This article considers the most frequent errors made by developers in their technical indicators and trading robots. An also shows how to self-test a product before sending it to the Market.