Help finishing EA, Full Code and specific errors attached

 

Hi All,

Running the EA on H1 EURUSD returns this message:

2019.01.22 21:50:39.658 2018.05.16 03:53:28   failed market buy 0.00 EURUSD sl: -inf [Unsupported filling mode]

And this Alert:

2019.01.22 21:50:39.693 2018.05.16 09:00:18   Alert: The Buy order request could not be completed -error:4756

For every second of the test(Screenshot attached).

After looking through other posts and checking over my code I still have no idea what is wrong.


This is the first EA I've written, which has been used as a way to get me familiar with MQL5 and coding in general. I have tried to piece together knowledge gained from all over this forum, which has led to this EA. The amount of info and help out there is amazing and I couldn't have got this far without such an active community. To go from 0 to this I am quite pleased though I need help finishing due to my lack of experience! Thanks in advance for the help with this specific problem, and any advice on debugging/coding is welcome as well as any futher corrections you may have.

Best regards to All

//+------------------------------------------------------------------+
//|                                       Volatility Breakout V4.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Merlin Lindsay"
#property version   "4.00"

#include <Trade\Trade.mqh>
//--- input parameters
input int      Setup_ATR_Long = 14;
input int      Setup_ATR_Short = 5;
input int      Percent_Range_Difference = 60;
input double    Open_ATR_Multiple = 3.0;
input double   Stop_ATR_Multiple = 3.0;
input double   Base_Risk_Percent = 3.0;
input double   Market_Risk_Percent = 2.0;
input double   Base_Equity = 1100;
input int      Max_Positions = 1;
input int      EA_Magic_No = 12345;

//---Other perameters
double ShortATRHandle;
double LongATRHandle;
double ShortATRVal[];
double LongATRVal[];

double iATRBuffer[];                                  

//+------------------------------------------------------------------+
//| Volatility indicator iteration function                              |
//+------------------------------------------------------------------+
   
double risk                = Base_Risk_Percent / 100;
double market_risk         = Market_Risk_Percent / 100;
double market_equity       = AccountInfoDouble(ACCOUNT_EQUITY) - Base_Equity;
double riskamount          = (Base_Equity * risk) + (market_equity * market_risk);

double _ticksize           = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE);           // Use the free market info indicator from our site to confirm your tick size and value
double _tickvalue          = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_VALUE);          // *** Confirm the default settings will work with your broker and change the EA if necessary ***

double _ask                = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
double _bid                = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);

double ATR_value=EMPTY_VALUE;           
double atr_range           = NormalizeDouble(ATR_value * Stop_ATR_Multiple,_Digits);

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   
   ShortATRHandle = iATR(NULL,0,Setup_ATR_Short);
   LongATRHandle = iATR(NULL,0,Setup_ATR_Long);
   
   if ((ShortATRHandle < 0) || (LongATRHandle < 0))
     {
      Alert("Error Creating Handles for indicators - error: ",GetLastError(),"!!");
      return (INIT_FAILED);
     }
   return(INIT_SUCCEEDED);
  }
  
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---Release indicator handles
   IndicatorRelease(ShortATRHandle);
   IndicatorRelease(LongATRHandle);
   
  }
   

//+------------------------------------------------------------------+
//| Trade function                                                   |
//+------------------------------------------------------------------+



void Check_for_trades()
   {
   
   ArraySetAsSeries(iATRBuffer,true);
      int    ATRh          = iATR(NULL,PERIOD_CURRENT,Setup_ATR_Long);              // The ATR Value depending on the timeframe of the input variable ATR_Periods
      if( ATRh < 0 )
         {
            Print("The iATR generated error : ",GetLastError());
         }
      if( CopyBuffer(ATRh,0,1,1,iATRBuffer) > 0 )                                // Copy Buffer calls the ATR handle and copies the ATR value to the iATRBuffer
         {
            ATR_value     = iATRBuffer[0];                                       // Setting the ATR variable
         }
      else ATR_value = 1000000000;                                               // in case of iATR error, EA still tests (without divide by zero error) but will not open any positions with much too high of a ATR range value
      
      
              
      
      double _lots_part1         = riskamount / ( ( atr_range / _ticksize ) * _tickvalue );   // Calculates (not yet rounded) the lot size when a position entry is triggered
      double _lot_step           = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);              // Gets the step of the lot sizes
      double _lots               = _lots_part1 - MathMod(_lots_part1,_lot_step);              // Using the lot size of the lot steps, gets the position size calculation matched with the lot step increments and rounds down to keep within the risk tolerance per position
      
      //string lots_final          = DoubleToString(_lots,FindDigits(_lot_step));
      double value_at_risk       = ( atr_range / _ticksize ) * (_tickvalue * _lots);
         
      MqlTick latest_price;     // To be used for getting recent/latest price quotes
      MqlTradeRequest mrequest;  // To be used for sending our trade requests
      MqlTradeResult mresult;    // To be used to get our trade results
      MqlRates mrate[];         // To be used to store the prices, volumes and spread of each bar
      ZeroMemory(mrequest);     // Initialization of mrequest structure

   // the rates arrays
      ArraySetAsSeries(mrate,true);
   // the Short ATR values array
      ArraySetAsSeries(ShortATRVal,true);
   // the Long ATR values array
      ArraySetAsSeries(LongATRVal,true);
   
   
   //--- Get the last price quote using the MQL5 MqlTick Structure
      if(!SymbolInfoTick(_Symbol,latest_price))
        {
         Alert("Error getting the latest price quote - error:",GetLastError(),"!!");
         return;
        }
   //--- Get the details of bars within Long ATR length
      if(CopyRates(_Symbol,_Period,0,Setup_ATR_Long,mrate)<0)
        {
         Alert("Error copying rates/history data - error:",GetLastError(),"!!");
         return;
        }
   
   //--- Copy the new values of our indicators to buffers (arrays) using the handle
      if(CopyBuffer(ShortATRHandle,0,0,Setup_ATR_Short,ShortATRVal)<0 || CopyBuffer(LongATRHandle,0,0,Setup_ATR_Long,LongATRVal)<0)
        {
         Alert("Error copying ATR indicator Buffers - error:",GetLastError(),"!!");
         return;
        }
   
   
   //--- Checking for open positions and their directoin
      bool Buy_opened=false;  // variable to hold the result of Buy opened position
      bool Sell_opened=false; // variables to hold the result of Sell opened position
   
      if(PositionSelect(_Symbol)==true) // we have an opened position
        {
         if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
           {
            Buy_opened=true;  //It is a Buy
           }
         else if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
           {
            Sell_opened=true; // It is a Sell
           }
        }
   // Copy the bar close price for the previous bar prior to the current bar (ie bar 1)
      double p_close = mrate[1].close;  // copy bar 1 close price to p_close
   
   
   /*
       1. Check for a long/Buy Setup : Short ATR within percentage value of Long ATR,
         Price closes above multiple of Long ATR
   */
      double P_diff = _ask - mrate[Setup_ATR_Long-1].close;
      double P_diff_abs = MathAbs(P_diff);
      
   //--- Declare bool type variables to hold our Buy Conditions
      bool Buy_Condition_1 = (ShortATRVal[0]<((0.01 * Percent_Range_Difference) * LongATRVal[0])); // Short ATR value within percentage range of Long ATR value
      bool Buy_Condition_2 = ((P_diff > 0) && (P_diff_abs > (Open_ATR_Multiple * LongATRVal[0])));         // Price change in Long ATR length >  multiple of Long ATR Value)

   //--- Putting all together   
      if(Buy_Condition_1 && Buy_Condition_2)
        {
         // any opened Buy position?
         if(Buy_opened)
           {
            Alert("We already have a Long Position!!!");
            return;    // Don't open a new Buy Position
           }
         ZeroMemory(mrequest);
         mrequest.action = TRADE_ACTION_DEAL;                                  // immediate order execution
         mrequest.price = NormalizeDouble(latest_price.ask,_Digits);           // latest ask price
         mrequest.sl = NormalizeDouble(latest_price.bid - atr_range,_Digits);        // Stop Loss
         mrequest.symbol = _Symbol;                                            // currency pair
         mrequest.volume = _lots;                                              // number of lots to trade
         mrequest.magic = EA_Magic_No;                                         // Order Magic Number
         mrequest.type = ORDER_TYPE_BUY;                                       // Buy Order
         mrequest.type_filling = ORDER_FILLING_FOK;                            // Order execution type
         mrequest.deviation=100;                                               // Deviation from current price
         //--- send order
         OrderSend(mrequest,mresult);
         // get the result code
         if(mresult.retcode==10009 || mresult.retcode==10008) //Request is completed or order placed
           {
            Alert("A Buy order has been successfully placed with Ticket#:",mresult.order,"!!");
           }
         else
           {
            Alert("The Buy order request could not be completed -error:",GetLastError());
            ResetLastError();           
            return;
           }
        }
   
   /*
       2. Check for a short/Sell Setup : Short ATR within percentage value of Long ATR,
         Price closes below multiple of Long ATR
   */
      
   //--- Declare bool type variables to hold our Buy Conditions
      bool Sell_Condition_1 = (ShortATRVal[0]<((0.01 * Percent_Range_Difference) * LongATRVal[0])); // Short ATR value within percentage range of Long ATR value
      bool Sell_Condition_2 = ((P_diff < 0) && (P_diff_abs > (Open_ATR_Multiple * LongATRVal[0])));         // Price change in Long ATR length >  multiple of Long ATR Value)
 
      if(Sell_Condition_1 && Sell_Condition_2)
        {
         // any opened Buy position?
         if(Sell_opened)
           {
            Alert("We already have a Short Position!!!");
            return;    // Don't open a new Short Position
           }
         ZeroMemory(mrequest);
         mrequest.action = TRADE_ACTION_DEAL;                                  // immediate order execution
         mrequest.price = NormalizeDouble(latest_price.bid,_Digits);           // latest bid price
         mrequest.sl = NormalizeDouble(latest_price.ask + atr_range,_Digits);         // Stop Loss
         mrequest.symbol = _Symbol;                                            // currency pair
         mrequest.volume = _lots;                                              // number of lots to trade
         mrequest.magic = EA_Magic_No;                                         // Order Magic Number
         mrequest.type = ORDER_TYPE_SELL;                                      // Buy Order
         mrequest.type_filling = ORDER_FILLING_FOK;                            // Order execution type
         mrequest.deviation=100;                                               // Deviation from current price
         //--- send order
         OrderSend(mrequest,mresult);
         // get the result code
         if(mresult.retcode==10009 || mresult.retcode==10008) //Request is completed or order placed
           {
            Alert("A Sell order has been successfully placed with Ticket#:",mresult.order,"!!");
           }
         else
           {
            Alert("The Sell order request could not be completed -error:",GetLastError());
            ResetLastError();           
            return;
           }
        }
      }         

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   if (PositionsTotal()==0)
      {
       Check_for_trades();
      }
      
   else
      {
       Trade_manage();
       }
  }
     
     double    buy_trail_stop = NormalizeDouble((_bid-atr_range),_Digits);
     double    sell_trail_stop = NormalizeDouble((_ask+atr_range),_Digits);
void Trade_manage()
  {

     MqlTradeRequest request;
     MqlTradeResult  result;
     int total=PositionsTotal(); // number of open positions   
//--- iterate over all open positions
   for(int i=0; i<total; i++)
     {
      //--- parameters of the order
      ulong  position_ticket=PositionGetTicket(i);// ticket of the position
      string position_symbol=PositionGetString(POSITION_SYMBOL); // symbol 
      int    digits=(int)SymbolInfoInteger(position_symbol,SYMBOL_DIGITS); // number of decimal places
      ulong  magic=PositionGetInteger(POSITION_MAGIC); // MagicNumber of the position
      double volume=PositionGetDouble(POSITION_VOLUME);    // volume of the position
      double sl=PositionGetDouble(POSITION_SL);  // Stop Loss of the position
      ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);  // type of the position
      //--- output information about the position
      PrintFormat("#%I64u %s  %s  %.2f  %s  sl: %s  [%I64d]",
                  position_ticket,
                  position_symbol,
                  EnumToString(type),
                  volume,
                  DoubleToString(PositionGetDouble(POSITION_PRICE_OPEN),digits),
                  DoubleToString(sl,digits),

                  magic);
      //--- if the MagicNumber matches, Stop Loss and Take Profit are not defined
      if(magic==EA_Magic_No && sl==0)
        { 
         //--- calculate the current price levels
         double price=PositionGetDouble(POSITION_PRICE_OPEN);
         //--- stop level is minimum distance from open position * to convert from int to double
         double stop_level=((int)SymbolInfoInteger(position_symbol,SYMBOL_TRADE_STOPS_LEVEL)*SymbolInfoDouble(position_symbol,SYMBOL_POINT));
        
         if(type==POSITION_TYPE_BUY)
           {
           if (stop_level>atr_range)
            {sl=NormalizeDouble(_bid-stop_level,digits);}
           else sl = buy_trail_stop;
           }
         else
           {
           if (stop_level>atr_range)
            {sl=NormalizeDouble(_ask+stop_level,digits);}
           else sl = sell_trail_stop;
           }
         //--- zeroing the request and result values
         ZeroMemory(request);
         ZeroMemory(result);
         //--- setting the operation parameters
         request.action  =TRADE_ACTION_SLTP; // type of trade operation
         request.position=position_ticket;   // ticket of the position
         request.symbol=position_symbol;     // symbol 
         request.sl      =sl;    // Stop Loss of the position
  
         request.magic=EA_Magic_No;         // MagicNumber of the position

         if(!OrderSend(request,result))
            PrintFormat("OrderSend error %d",GetLastError());  // if unable to send the request, output the error code
        }
     }
   }


Files:
Errors.PNG  17 kb
 

It probably have to do with 

mrequest.sl = NormalizeDouble(latest_price.ask + atr_range,_Digits);         // Stop Loss
mrequest.sl = NormalizeDouble(latest_price.bid - atr_range,_Digits);        // Stop Loss

Those two lines.

So you can comment them out and see if it does place orders without setting a stoploss.

 
Marco vd Heijden:

It probably have to do with 

Those two lines.

So you can comment them out and see if it does place orders without setting a stoploss.

Just tried that and I'm afraid the problem still persists. What made you think they may have been the problem? Thanks for the help
 

Because it says sl:-inf

ERR_TRADE_SEND_FAILED

4756

Trade request sending failed


Please run the request through OrderCheck() first.

 
Marco vd Heijden:

Because it says sl:-inf

ERR_TRADE_SEND_FAILED

4756

Trade request sending failed


Please run the request through OrderCheck() first.

Ok thanks, I will try and integrate that when I get home from work this evening.

I have also noticed _lots (which should be the lot size) is returning 0.0. I imagine this could be causing the error with the filling type? When changing the fill type from FOK to IOC or RETURN the error received is 10014 (insufficient volume), which may be being caused by the same issue. Again I will check later today. Any other thoughts appreciated.

Best regards

Reason: