Check stop loss price not working

 

Hi All,

i had an error in my simple engulfing EA which i tried almost a week still cant found the error.

This EA is when the IF condition is hit then execute the BUY OrderSend() without set the stop loss price because i want to avoid the candlestick shadow hit on my stoploss price while still floating in Close[0].

So i had create a sub-function "checkstoploss(double stop_loss)" to execute in every tick to check on the every candlestick closed price are passed/changed in Close[1] and compare to the stop_loss price i set. If the Close[1] is lower or equal to the stop_loss then it will execute the OrderClose().

There are no error mesg in Experts/Journal.

Any help on this are much appreciated. Thank you very much !


datetime candleStart = 0;
datetime candleEnd = 0;
datetime candlem10 = 0;
bool message_displayed = false;
bool trade_opened = false;

double MA5cds = iMA(NULL,0,5,0,MODE_EMA,PRICE_CLOSE,1);
double MA8cds = iMA(NULL,0,8,0,MODE_EMA,PRICE_CLOSE,1);
double MA13cds = iMA(NULL,0,13,0,MODE_EMA,PRICE_CLOSE,1);

bool downtrendMA = (MA13cds > MA8cds > MA5cds);
bool uptrendMA = (MA5cds > MA8cds > MA13cds);




void OnTick()
{
  
    // Get the start and end time of the current candle
    if (Time[0] != candleStart)
    {
        candleStart = Time[0];
        candleEnd = candleStart + PeriodSeconds();
        candlem10 = candleEnd - 10;
        trade_opened = false; // Reset the trade_opened flag at the start of each new candle
    }
    
    // Check for engulfing pattern
    if (Close[1]-Open[1] < 0 &&
        Close[0]-Open[0] > 0 &&
        Close[0] > Open[1] &&
        !downtrendMA
       )
    {
        Comment("Engulfing UpTrend Successfully detected! Pending confirm until candlestick close");
        
        // Check if there are no open orders and if at least 10 seconds are left until the current candlestick closes
        if (OrdersTotal() == 0 && TimeCurrent() >= candlem10 && !message_displayed)
        {
            Print("10 seconds per end");
            message_displayed = true;
        }
        
        // Check if a trade has already been opened for this candlestick
        if (!trade_opened && OrdersTotal() == 0 && TimeCurrent() >= candlem10)
        {
            double stop_loss = 0;
            double atr = iATR(_Symbol, PERIOD_CURRENT, 14, 0);
            double take_profit = Close[0] + atr * 1.5;
            int ticket = OrderSend(_Symbol, OP_BUY, 0.01, Close[0], 0, 0, take_profit);
            stop_loss = Close[1];
            Print("Stop loss value after execute Buy is " ,stop_loss);

            if (ticket > 0)
            {
                trade_opened = true;
            }
            else
            {
                Print("OrderSend error:", GetLastError());
            }
        }
    }
    else
    {
        Comment("Not detect anything");
        message_displayed = false;
        checkstoploss(stop_loss);
    }     

}




void checkstoploss(double stop_loss)
{

    // Check if the current price is below the stop loss value
    if (Close[1] =< stop_loss)
    {
        
        Print("Stop loss value within sub-function checkstoploss is " ,stop_loss);

        // Close when the stop loss is hit
        int ticket = OrderClose(OrderTicket(), OrderLots(), Ask, 1, clrRed);
        if (ticket > 0)
        {
            Print("Trade closed at stop loss");
        }
        else
        {
            Print("OrderClose error:", GetLastError());
        }
    }
}
 
double MA5cds = iMA(NULL,0,5,0,MODE_EMA,PRICE_CLOSE,1);
double MA8cds = iMA(NULL,0,8,0,MODE_EMA,PRICE_CLOSE,1);
double MA13cds = iMA(NULL,0,13,0,MODE_EMA,PRICE_CLOSE,1);

bool downtrendMA = (MA13cds > MA8cds > MA5cds);
bool uptrendMA = (MA5cds > MA8cds > MA13cds);

Those are not assignments; they are initialization of a common (globally declared), or static variable with a constant. They work exactly the same way in MT4/MT5/C/C++.

  1. They are initialized once on program load.

  2. They don't update unless you assign to them.

  3. In C/C++ you can only initialize them with constants, and they default to zero. In MTx you should only initialize them with constants. There is no default in MT5, or MT4 with strict (which you should always use).

    MT4/MT5 actually compiles with non-constants, but the order that they are initialized is unspecified and Don't try to use any price (or indicator) or server related functions in OnInit (or on load or in OnTimer before you've received a tick), as there may be no connection/chart yet:

    1. Terminal starts.
    2. Indicators/EAs are loaded. Static and globally declared variables are initialized. (Do not depend on a specific order.)
    3. OnInit is called.
    4. For indicators OnCalculate is called with any existing history.
    5. Human may have to enter password, connection to server begins.
    6. New history is received, OnCalculate called again.
    7. A new tick is received, OnCalculate/OnTick is called. Now TickValue, TimeCurrent, account information and prices are valid.

  4. Unlike indicators, EAs are not reloaded on chart change, so you must reinitialize them, if necessary.
              external static variable - MQL4 programming forum #2 (2013)

 
William Roeder #:

Those are not assignments; they are initialization of a common (globally declared), or static variable with a constant. They work exactly the same way in MT4/MT5/C/C++.

  1. They are initialized once on program load.

  2. They don't update unless you assign to them.

  3. In C/C++ you can only initialize them with constants, and they default to zero. In MTx you should only initialize them with constants. There is no default in MT5, or MT4 with strict (which you should always use).

    MT4/MT5 actually compiles with non-constants, but the order that they are initialized is unspecified and Don't try to use any price (or indicator) or server related functions in OnInit (or on load or in OnTimer before you've received a tick), as there may be no connection/chart yet:

    1. Terminal starts.
    2. Indicators/EAs are loaded. Static and globally declared variables are initialized. (Do not depend on a specific order.)
    3. OnInit is called.
    4. For indicators OnCalculate is called with any existing history.
    5. Human may have to enter password, connection to server begins.
    6. New history is received, OnCalculate called again.
    7. A new tick is received, OnCalculate/OnTick is called. Now TickValue, TimeCurrent, account information and prices are valid.

  4. Unlike indicators, EAs are not reloaded on chart change, so you must reinitialize them, if necessary.
              external static variable - MQL4 programming forum #2 (2013)

double MA5cds = iMA(NULL,0,5,0,MODE_EMA,PRICE_CLOSE,1);
double MA8cds = iMA(NULL,0,8,0,MODE_EMA,PRICE_CLOSE,1);
double MA13cds = iMA(NULL,0,13,0,MODE_EMA,PRICE_CLOSE,1);

bool downtrendMA = (MA13cds > MA8cds > MA5cds);
bool uptrendMA = (MA5cds > MA8cds > MA13cds);

I'll just have to move this under Ontick() ?

 

I had move everything that declare at global into main function ontick() and move the sub-function checkstoploss inside the IF statement condition(for open order) as below :


void OnTick()
{
datetime candleStart = 0;
datetime candleEnd = 0;
datetime candlem10 = 0;
bool message_displayed = false;
bool trade_opened = false;

double MA5cds = iMA(NULL,0,5,0,MODE_EMA,PRICE_CLOSE,1);
double MA8cds = iMA(NULL,0,8,0,MODE_EMA,PRICE_CLOSE,1);
double MA13cds = iMA(NULL,0,13,0,MODE_EMA,PRICE_CLOSE,1);

bool downtrendMA = (MA13cds > MA8cds > MA5cds);
bool uptrendMA = (MA5cds > MA8cds > MA13cds);


  

    
    // Get the start and end time of the current candle
    if (Time[0] != candleStart)
    {
        candleStart = Time[0];
        candleEnd = candleStart + PeriodSeconds();
        candlem10 = candleEnd - 5;
        trade_opened = false; // Reset the trade_opened flag at the start of each new candle
    }
    
    // Check for engulfing pattern
    if (Close[1]-Open[1] < 0 &&
        Close[0]-Open[0] > 0 &&
        Close[0] > Open[1] &&
        !downtrendMA
       )
    {
        Comment("Engulfing UpTrend Successfully detected! Pending confirm until candlestick close");
        
        // Check if there are no open orders and if at least 10 seconds are left until the current candlestick closes
        if (OrdersTotal() == 0 && TimeCurrent() >= candlem10 && !message_displayed)
        {
            Print("5 seconds per end");
            message_displayed = true;
        }
        
        // Check if a trade has already been opened for this candlestick
        if (!trade_opened && OrdersTotal() == 0 && TimeCurrent() >= candlem10)
        {
            double stop_loss = 0;
            double atr = iATR(_Symbol, PERIOD_CURRENT, 14, 0);
            double take_profit = Close[0] + atr * 1.5;
            int ticket = OrderSend(_Symbol, OP_BUY, 0.01, Close[0], 0, 0, take_profit);
            stop_loss = Close[1];
            Print("Stop loss value after execute is " ,stop_loss);

            if (ticket > 0)
            {
                trade_opened = true;

            }
            else
            {
                Print("OrderSend error:", GetLastError());
            }
        }
        
        // check if stop loss is hit <-------------------------------- move to here
        if (trade_opened)
        {
          checkstoploss(stop_loss);
        }
                
    }
    else
    {
        Comment("Not detect anything");
        message_displayed = false;

    }     

}


void checkstoploss(double stop_loss)
{

    // Check if the current price is below the stop loss value
    if (Close[1] <= stop_loss)
    {
        
        Print("Stop loss value within checkstoploss is " ,stop_loss);

        // For example, close the open trade
        int orderticket = OrderTicket();
        double lots = OrderLots();
        
        int ticket = OrderClose(orderticket, lots, Ask, 1, Red);
        if (ticket > 0)
        {
            Print("Trade closed at stop loss");
        }
        else
        {
            Print("OrderClose error:", GetLastError());
        }
    }
}


Now it is able to run the sub-function checkstoploss(stop_loss) but seem is not working proper as it look like it will immediately run the OrderClose() without matching IF statement inside the sub-function checkstoploss(stop_loss). here is the screenshot of the error as below attachment :

Files:
error.png  10 kb
 
       int orderticket = OrderTicket();
        double lots = OrderLots();

MT4: You can not use any Trade Functions until you first select an order.

 
William Roeder #:

MT4: You can not use any Trade Functions until you first select an order.

Thanks, i had add the for loop of orderselect with magicnumber. the code direct skip the IF statement and go to closed the order. anybody can help on this ?

datetime candleStart = 0;
datetime candleEnd = 0;
datetime candlem10 = 0;
bool message_displayed = false;
bool trade_opened = false;





void OnTick()
{
double MA5cds = iMA(NULL,0,5,0,MODE_EMA,PRICE_CLOSE,1);
double MA8cds = iMA(NULL,0,8,0,MODE_EMA,PRICE_CLOSE,1);
double MA13cds = iMA(NULL,0,13,0,MODE_EMA,PRICE_CLOSE,1);

bool downtrendMA = (MA13cds > MA8cds > MA5cds);
bool uptrendMA = (MA5cds > MA8cds > MA13cds);

int UptrendMagicNumber = 12345;  

    // Get the start and end time of the current candle
    if (Time[0] != candleStart)
    {
        candleStart = Time[0];
        candleEnd = candleStart + PeriodSeconds();
        candlem10 = candleEnd - 5;
        trade_opened = false; // Reset the trade_opened flag at the start of each new candle
    }
    
    // Check for engulfing pattern
    if (Close[1]-Open[1] < 0 &&
        Close[0]-Open[0] > 0 &&
        Close[0] > Open[1] &&
        !(MA13cds > MA8cds && MA8cds > MA5cds)
       )
    {
        Comment("Engulfing UpTrend Successfully detected! Pending confirm until candlestick close");
        
        // Check if there are no open orders and if at least 10 seconds are left until the current candlestick closes
        if (OrdersTotal() == 0 && TimeCurrent() >= candlem10 && !message_displayed)
        {
            Print("5 seconds per end");
            message_displayed = true;
        }
        
        // Check if a trade has already been opened for this candlestick
        if (!trade_opened && OrdersTotal() == 0 && TimeCurrent() >= candlem10)
        {
            double stop_loss = 0;
            double atr = iATR(_Symbol, PERIOD_CURRENT, 14, 0);
            double take_profit = Close[0] + atr * 1.5;
            int ticket = OrderSend(_Symbol, OP_BUY, 0.01, Close[0], 1, 0, take_profit,NULL,UptrendMagicNumber,0,clrGreen);
            stop_loss = Close[1];
            Print("Stop loss value after execute is " ,stop_loss);

            if (ticket > 0)
            {
                trade_opened = true;

            }
            else
            {
                Print("OrderSend error:", GetLastError());
            }
        }
        
        // check if stop loss is hit
        if (trade_opened)
        {
        datetime delayedTime = TimeCurrent() + 60;
        while (TimeCurrent() < delayedTime)
           {
             // Wait for 1 minute
             Comment("Wait for 1 minute !");
           }
          checkstoploss(stop_loss);
        } // end of check if stop loss is hit
                
    }
    else  // engulfing else start here
    {
        Comment("Not detect anything");
        message_displayed = false;
        //checkstoploss(stop_loss);
    }   // End of Engulfing function  



} // End of OnTick function

// only 1 trade if SL and TP meet within same candle


void checkstoploss(double stop_loss)
{

int UptrendMagicNumber = 12345;

    // Check if the current price is below the stop loss value
    if (Close[1] <= stop_loss)  <--------------------------------------this if statement are not working
    {
        
        Print("(Inside IF statement)Stop loss value within checkstoploss is " ,stop_loss);

// Loop through all open orders with the specified magic number
for (int i = 0; i < OrdersTotal(); i++)
{
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
    {
        if (OrderMagicNumber() == UptrendMagicNumber)
        {
            // Close the selected order
            int closeTicket = OrderClose(OrderTicket(), OrderLots(), Bid, 5, clrRed);
            if (closeTicket > 0)
            {
                Print("Stop loss Order closed successfully");
            }
            else
            {
                Print("Order close failed with error ", GetLastError());
            }
        }
    }
    else
    {
        Print("Failed to select order with error ", GetLastError());
    }
}




thanks

 
anyone can help on this ? thanks