5m Chart EA Isn't Creating Results in Strategy Tester

 

Hi everyone,

Noob to coding here but I finally completed my own EA without errors or warnings...(doesn't mean it will work, I know). Any thoughts on making my code better?

When I tried to run it in the Strategy Tester it received no results and instead brought up the following errors/warnings:

  • inputs: InpBandsPeriods=20; InpBandsDeviations=2.5; InpBandsAppliedPrice=1; InpMagicNumber=11695; OrderLots=0.08; InpSLamount=300; InpTSLorder=85; InpTSLamount=30;  - I'm guessing my inputs are wrong?
  • TestGenerator: unmatched data error (volume limit 399 at 2022.11.21 04:25 exceeded) - Even after running the conversion script others have mentioned. Any other thoughts for running on 5m?

Any answers or suggestions are greatly appreciated. You guys have helped me beyond measure and I want to thank you all.

#property strict

// General
//
input int TerminalInfoInteger();
input int Period();
input int InpBandsPeriods=20; //Band Per
input double InpBandsDeviations=2.5; //Band Dev
input ENUM_APPLIED_PRICE InpBandsAppliedPrice=PRICE_OPEN; //Band App Price

// Orders
//
input int InpMagicNumber=0695;    //Magic Num
input string InpTradeS="Sell";   //Trade Comment S
input string InpTradeB="Buy";   //Trade Comment B
input double OrderLots=0.08;    //Lot size
input double InpSLamount=300;   //SL Points
input int InpTSLorder=85;  //TSL Initiates at
input int InpTSLamount=30;  //TSL Points

//initializes function
//
int OnInit(){

   if((DayOfWeek()>=1 && DayOfWeek()<=5) && (Hour()>6 && Hour()<22)){};   //Trading Days Mon-Fri & Trading Hours 12am-3pm

   return(INIT_SUCCEEDED);

}

//deinitializes function
//
void OnDeinit(const int reason){

}

//all function logic to go under this as it refreshes every tick
//
void OnTick(){
   
      struct Price{  //Refreshing bid and ask prices
      double Bid;
      double Ask;}; 
   
      double Upper = iBands(Symbol(),PERIOD_M5,InpBandsPeriods,InpBandsDeviations,0,InpBandsAppliedPrice,MODE_UPPER,0); //Upper Bollinger
      double Lower = iBands(Symbol(),PERIOD_M5,InpBandsPeriods,InpBandsDeviations,0,InpBandsAppliedPrice,MODE_LOWER,0); //Lower Bollinger

      double InpSL=SymbolInfoDouble(Symbol(),SYMBOL_POINT)*InpSLamount;    //SL Convert to S-Points
      double InpTP_TSL=SymbolInfoDouble(Symbol(),SYMBOL_POINT)*InpTSLamount;    //TSL Convert to S-Points
      double InpTPpoints=SymbolInfoDouble(Symbol(),SYMBOL_POINT)*InpTSLorder;    //Initiate TSL at
      
      if(OrdersTotal()!=0 && Bid>=Upper){ //Sell Order if
            if(OrderSend(Symbol(),OP_SELL,OrderLots,Bid,10,InpSL,0,InpTradeS,InpMagicNumber,0,clrCrimson)){};
            
            return;
            GetLastError();};     
      
      if(OrdersTotal()!=0 && Ask<=Lower){  //Buy Order if
            if(OrderSend(Symbol(),OP_BUY,OrderLots,Ask,10,InpSL,0,InpTradeB,InpMagicNumber,0,clrDarkGreen)){};
   
            return;
            GetLastError();};

      static int digits=(int)SymbolInfoInteger(Symbol(),SYMBOL_DIGITS);
      double SLmodS=NormalizeDouble(SymbolInfoDouble(Symbol(),SYMBOL_ASK)+InpTSLamount,digits); //Calc SL off Ask for Sell
      double SLmodB=NormalizeDouble(SymbolInfoDouble(Symbol(),SYMBOL_BID)-InpTSLamount,digits); //Calc SL off Bid for Buy
           
      int count=OrdersTotal();   //Runs through open orders
      for(int i=count-1; i>=0; i--){
         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)){
            if(OrderSymbol()==Symbol() && OrderMagicNumber()==InpMagicNumber){
               if(OrderType()==OP_SELL && Ask<OrderOpenPrice()-InpTPpoints){  //if met, modify Sell Order
                  if(OrderModify(OrderTicket(),OrderOpenPrice(),SLmodS,OrderTakeProfit(),OrderExpiration(),clrCrimson)){};
               }else
               if(OrderType()==OP_BUY && Bid>OrderOpenPrice()+InpTPpoints){  //if met, modify Buy Order
                  if(OrderModify(OrderTicket(),OrderOpenPrice(),SLmodB,OrderTakeProfit(),OrderExpiration(),clrDarkGreen)){};
               }   
            }
         }
      }   
}    


The Fundamentals of Testing in MetaTrader 5
The Fundamentals of Testing in MetaTrader 5
  • www.mql5.com
What are the differences between the three modes of testing in MetaTrader 5, and what should be particularly looked for? How does the testing of an EA, trading simultaneously on multiple instruments, take place? When and how are the indicator values calculated during testing, and how are the events handled? How to synchronize the bars from different instruments during testing in an "open prices only" mode? This article aims to provide answers to these and many other questions.
 
  1. Why did you post your MT4 question in the MT5 EA section instead of the MQL4 section, (bottom of the Root page)?
              General rules and best pratices of the Forum. - General - MQL5 programming forum? (2017)
    Next time, post in the correct place. The moderators will likely move this thread there soon.

  2.       if(OrdersTotal()!=0 && Bid>=Upper){ //Sell Order if

    Magic number only allows an EA to identify its trades from all others. Using OrdersTotal/OrdersHistoryTotal (MT4) or PositionsTotal (MT5), directly and/or no Magic number/symbol filtering on your OrderSelect / Position select loop means your code is incompatible with every EA (including itself on other charts and manual trading.)
              Symbol Doesn't equal Ordersymbol when another currency is added to another seperate chart . - MQL4 programming forum (2013)
              PositionClose is not working - MQL5 programming forum (2020)
              MagicNumber: "Magic" Identifier of the Order - MQL4 Articles (2006)
              Orders, Positions and Deals in MetaTrader 5 - MQL5 Articles (2011)
              Limit one open buy/sell position at a time - General - MQL5 programming forum (2022)

    You need one Magic Number for each symbol/timeframe/strategy. Trade current timeframe, one strategy, and filter by symbol requires one MN.

  3.             if(OrderSend(Symbol(),OP_SELL,OrderLots,Bid,10,InpSL,0,InpTradeS,InpMagicNumber,0,clrCrimson)){};
    

    Check your return codes, and report your errors (including market prices and your variables). Don't look at GLE/LE unless you have an error. Don't just silence the compiler (MT5/MT4+strict), it is trying to help you.

  4. OrderSend does not return a boolean.

  5. double InpSL=SymbolInfoDouble(Symbol(),SYMBOL_POINT)*InpSLamount;    //SL Convert to S-Points
    Stops are not an amount. They are a price. And you know that in your modify code.

    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, average maximum spread = 134.
      My EURCHF shows average spread = 18 points, average maximum spread = 106.
      (your broker will be similar).
                Is it reasonable to have such a huge spreads (20 PIP spreads) in EURCHF? - General - MQL5 programming forum (2022)

  6.             return;
                GetLastError();};

    You return, what is additional code doing there?

  7.       double SLmodS=NormalizeDouble(SymbolInfoDouble(Symbol(),SYMBOL_ASK)+InpTSLamount,digits); //Calc SL off Ask for Sell
          double SLmodB=NormalizeDouble(SymbolInfoDouble(Symbol(),SYMBOL_BID)-InpTSLamount,digits); //Calc SL off Bid for Buy
    

    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)