Getting an error in while testing strategy "failed market buy 0.01 EUROUSD sl: tp: [Invalid stops]" MT5

 

Hi,

I have below code :


#include <Trade/Trade.mqh>



input double Lots = 0.02;

input double Lotfactor = 2;

input int TpPoints = 100;

input int SlPoints = 100;

input int Magic = 111;



CTrade trade;

bool isTradeAllowed = true;



int OnInit () {



   trade.SetExpertMagicNumber (Magic);





   return(INIT_SUCCEEDED);

  }



void OnDeinit(const int reason) {

  

  }



void OnTick() {



   if (isTradeAllowed) {

      double ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK);

      double tp = ask + TpPoints + _Point;

      double sl = ask - SlPoints + _Point;



      ask = NormalizeDouble(ask,_Digits);

      tp = NormalizeDouble(tp,_Digits);

      sl= NormalizeDouble(sl,_Digits);



     if(trade.Buy (Lots,_Symbol,ask,sl,tp)) {

      isTradeAllowed = false;

      }

   }

 }

 

      void OnTradeTransaction (

      const MqlTradeTransaction& trans, //trade transaction structure

      const MqlTradeRequest& request, //trade transaction structure

      const MqlTradeResult&   result //trade transaction structure) 

   ) {

   

   if(trans.type == TRADE_TRANSACTION_DEAL_ADD) {

    CDealInfo deal;

    deal.Ticket (trans.deal);

    HistorySelect (TimeCurrent ()-PeriodSeconds (PERIOD_D1),TimeCurrent ()+10);

      if(deal.Magic() == Magic && deal.Symbol () == _Symbol) {

      if(deal.Entry () == DEAL_ENTRY_OUT) {

      Print (__FUNCTION__,"> Closed pos #", trans.position);

      if(deal.Profit () > 0) {

      isTradeAllowed = true;

      }else{

      

      if(deal.DealType () == DEAL_TYPE_BUY) {

      double lots = deal.Volume () * Lotfactor;

      lots = NormalizeDouble (lots,2);

    

   double ask = SymbolInfoDouble (_Symbol, SYMBOL_ASK);

   double tp = ask + TpPoints * _Point;

   double sl = ask + SlPoints * _Point;



   ask = NormalizeDouble(ask,_Digits);

   tp = NormalizeDouble(tp,_Digits);

   sl = NormalizeDouble(sl,_Digits);



   trade.Buy (lots,_Symbol,ask,sl,tp);

  }else if (deal.DealType () == DEAL_TYPE_SELL) {

  

   double lots = deal.Volume () * Lotfactor;

      lots = NormalizeDouble (lots,2);

    

   double bid = SymbolInfoDouble (_Symbol, SYMBOL_BID);

   double tp = bid - TpPoints * _Point;

   double sl = bid + SlPoints * _Point;



   bid = NormalizeDouble(bid,_Digits);

   tp = NormalizeDouble(tp,_Digits);

   sl = NormalizeDouble(sl,_Digits);



   trade.Sell (lots,_Symbol,bid,sl,tp);



     }

       }

     }

    }

   }

  }


This giving below error while doing testing in MT5

 

When you post code please use the CODE button (Alt-S)!

Use the CODE button

 
Sergey Golubev #:

When you post code please use the CODE button (Alt-S)!

Here's the code:


#include <Trade/Trade.mqh>

input double Lots = 0.01;
input double Lotfactor = 2;
input int TpPoints = 100;
input int SlPoints = 120;
input int Magic = 111;

CTrade trade;
bool isTradeAllowed = true;

int OnInit () {

   trade.SetExpertMagicNumber (Magic);


   return(INIT_SUCCEEDED);
  }

void OnDeinit(const int reason) {
  
  }

void OnTick() {

   if (isTradeAllowed) {
      double ask = (SymbolInfoDouble(_Symbol,SYMBOL_ASK));
      double tp = (ask + TpPoints + _Point);
      double sl = (ask - SlPoints + _Point);

      ask = NormalizeDouble(ask,_Digits);
      tp = NormalizeDouble(tp,_Digits);
      sl= NormalizeDouble(sl,_Digits);

     if(trade.Buy (Lots,_Symbol,ask,sl,tp)) {
      isTradeAllowed = false;
      }
   }
 }
 
   void OnTradeTransaction (
      const MqlTradeTransaction& trans, //trade transaction structure
      const MqlTradeRequest&    request,        //trade transaction structure
      const MqlTradeResult&   result    //trade transaction structure 
   ) {
   
   if(trans.type == TRADE_TRANSACTION_DEAL_ADD) {
    CDealInfo deal;
    deal.Ticket (trans.deal);
    HistorySelect (TimeCurrent ()-PeriodSeconds (PERIOD_D1),TimeCurrent ()+10);
      if(deal.Magic() == Magic && deal.Symbol () == _Symbol) {
      if(deal.Entry () == DEAL_ENTRY_OUT) {
      Print (__FUNCTION__,"> Closed pos #", trans.position);
      if(deal.Profit () > 0) {
      isTradeAllowed = true;
      }else{
      
      if(deal.DealType () == DEAL_TYPE_BUY) {
      double lots = deal.Volume () * Lotfactor;
      lots = NormalizeDouble (lots,2);
    
           double ask = (SymbolInfoDouble (_Symbol, SYMBOL_ASK));
           double tp = (ask + TpPoints * _Point);
           double sl = (ask + SlPoints * _Point);

           ask = NormalizeDouble(ask,_Digits);
           tp = NormalizeDouble(tp,_Digits);
           sl = NormalizeDouble(sl,_Digits);

           trade.Buy (lots,_Symbol,ask,sl,tp);
          }else if (deal.DealType () == DEAL_TYPE_SELL) {
          
           double lots = deal.Volume () * Lotfactor;
      lots = NormalizeDouble (lots,2);
    
           double bid = (SymbolInfoDouble (_Symbol, SYMBOL_BID));
           double tp = (bid - TpPoints * _Point);
           double sl = (bid + SlPoints * _Point);

           bid = NormalizeDouble(bid,_Digits);
           tp = NormalizeDouble(tp,_Digits);
           sl = NormalizeDouble(sl,_Digits);

           trade.Sell (lots,_Symbol,bid,sl,tp);

             }
       }
     }
    }
   }
  }
Also attaching error screenshot
Files:
screenshot.JPG  80 kb
 
      double ask = (SymbolInfoDouble(_Symbol,SYMBOL_ASK));
      double tp = (ask + TpPoints + _Point);
      double sl = (ask - SlPoints + _Point);

      ask = NormalizeDouble(ask,_Digits);
      tp = NormalizeDouble(tp,_Digits);
      sl= NormalizeDouble(sl,_Digits);
  1. You buy at the Ask and sell at the Bid. Pending Buy Stop orders become market orders when hit by the Ask.

    1. Your buy order's TP/SL (or Sell Stop's/Sell Limit's entry) are triggered when the Bid / OrderClosePrice reaches it. Using Ask±n, makes your SL shorter and your TP longer, by the spread. Don't you want the specified amount used in either direction?

    2. Your sell order's TP/SL (or Buy Stop's/Buy Limit's entry) will be triggered when the Ask / OrderClosePrice reaches it. To trigger close to a specific Bid price, add the average spread.
                MODE_SPREAD (Paul) - MQL4 programming forum - Page 3 #25

    3. The charts show Bid prices only. Turn on the Ask line to see how big the spread is (Tools → Options (control+O) → charts → Show ask line.)
      Most brokers with variable spreads widen considerably at end of day (5 PM ET) ± 30 minutes. My GBPJPY shows average spread = 26 points, but average maximum spread = 134 (your broker will be similar).

  2. You used NormalizeDouble, It's use is usually wrong, as it is in your case.

    1. Floating point has a infinite number of decimals, it's your not understanding floating point and that some numbers can't be represented exactly. (like 1/10.)
                Double-precision floating-point format - Wikipedia, the free encyclopedia

      See also The == operand. - MQL4 programming forum (2013)

    2. Print out your values to the precision you want with DoubleToString - Conversion Functions - MQL4 Reference.

    3. SL/TP (stops) need to be normalized to tick size (not Point) — code fails on non-currencies.
                On 5Digit Broker Stops are only allowed to be placed on full pip values. How to find out in mql? - MQL4 programming forum (2011)

      And abide by the limits Requirements and Limitations in Making Trades - Appendixes - MQL4 Tutorial and that requires understanding floating point equality Can price != price ? - MQL4 programming forum (2012)

    4. Open price for pending orders need to be adjusted. On Currencies, Point == TickSize, so you will get the same answer, but it won't work on non-currencies. So do it right.
                Trailing Bar Entry EA - MQL4 programming forum (2013)
                Bid/Ask: (No Need) to use NormalizeDouble in OrderSend - MQL4 programming forum (2012)

    5. Lot size must also be adjusted to a multiple of LotStep and check against min and max. If that is not a power of 1/10 then NormalizeDouble is wrong. Do it right.
                (MT4 2013)) (MT5 2022))

    6. MathRound() and NormalizeDouble() are rounding in a different way. Make it explicit.
                MT4:NormalizeDouble - MQL5 programming forum (2017)
                How to Normalize - Expert Advisors and Automated Trading - MQL5 programming forum (2017)

    7. Prices you get from the terminal are already correct (normalized).

    8. PIP, Point, or Tick are all different in general.
                What is a TICK? - MQL4 programming forum (2014)

 

This EA is good... till crash ! Because lots starts 0.01 and goes to 60-80 lots ! 

Does anybody know the way close all positions for example ("last volume" >= "20 lot") ans start from 0.01 again  ? 

Reason: