Need help on inconsistent EA's Entry

 

Hi

I have an EA that could be compiled. However, the entry system when run in the strategy trader is quite whacky. Here is the summary for the entry rules

The Red line is TenkanSen.
The Blue line is KijunSen.

Open Buy if

if(TenkanSen > KijunSen && BuyTicket == 0 && LastClose > MathMax(SenkouSpanA,SenkouSpanB))

    • 1.)    Red line > Blue line
    • 2.)    There is no other buy position
    • 3.)    The close price above the dotted lines.

The position will be closed if the Blue Line is less than the Red Line.

Open Sell if

if(TenkanSen < KijunSen && SellTicket == 0 && LastClose < MathMin(SenkouSpanA,SenkouSpanB))

      • 1.)    Blue line > Red line
      • 2.)    There is no other sell position
      • 3.)    The close price below the dotted lines.

The position will be closed if the Red Line is less than the Blue Line.

The code works… but not always.

Pic 1 shows how it works as supposed to.

Pic 1 

 

Unfortunately, it doesn't work anymore.

Pic 2 

 

My guess is the problem could be the third condition. But if it's the case, then the position in Pic 2 should have been opened since the 1st condition is met, right?

Your help is highly appreciated.

 
#include <stdlib.mqh>

// External variables
extern bool DynamicLotSize = false;
extern double EquityPercent = 2;
extern double FixedLotSize = 0.01;
extern double StopLoss = 50;
extern double TakeProfit = 0;
extern int Slippage = 5;
extern int MagicNumber = 12345;

//Ichimoku Periods
extern double TenkanSenPeriod = 9;
extern double KijunSenPeriod = 26;
extern double SenkouSpanAPeriod = 999;
extern double SenkouSpanBPeriod = 52;
//End Ichimoku Periods



// Global variables
int BuyTicket;
int SellTicket;
int LastClose; //This is variable to compare with SpanA and SpanB

double UsePoint;
int UseSlippage;

int ErrorCode;


// Init function
int init()
    {
        UsePoint = PipPoint(Symbol());
        UseSlippage = GetSlippage(Symbol(),Slippage);
        
        return(0);
    }


// Start function
int start()
    {
     
     //Ichimoku
        double TenkanSen=iIchimoku(NULL,0,TenkanSenPeriod,KijunSenPeriod,SenkouSpanBPeriod,MODE_TENKANSEN,1);
        double KijunSen=iIchimoku(NULL,0,TenkanSenPeriod,KijunSenPeriod,SenkouSpanBPeriod,MODE_KIJUNSEN,1);
        double SenkouSpanA=iIchimoku(NULL,0,TenkanSenPeriod,KijunSenPeriod,SenkouSpanBPeriod,MODE_SENKOUSPANA,1);
        double SenkouSpanB=iIchimoku(NULL,0,TenkanSenPeriod,KijunSenPeriod,SenkouSpanBPeriod,MODE_SENKOUSPANB,1);

    //iClose
        LastClose = iClose(NULL,0,1);
        
      // Lot size calculation
      if(DynamicLotSize == true)
        {
           double RiskAmount = AccountEquity() * (EquityPercent / 100);
           double TickValue = MarketInfo(Symbol(),MODE_TICKVALUE);
           if(Point == 0.001 || Point == 0.00001) TickValue *= 10;
           double CalcLots = (RiskAmount / StopLoss) / TickValue;
           double LotSize = CalcLots;
        }
      else LotSize = FixedLotSize;
     
     
      // Lot size verification
      if(LotSize < MarketInfo(Symbol(),MODE_MINLOT))
        {
           LotSize = MarketInfo(Symbol(),MODE_MINLOT);
        }
      else if(LotSize > MarketInfo(Symbol(),MODE_MAXLOT))
        {
           LotSize = MarketInfo(Symbol(),MODE_MAXLOT);
        }
        
      if(MarketInfo(Symbol(),MODE_LOTSTEP) == 0.1)
        {
           LotSize = NormalizeDouble(LotSize,1);
        }
      else LotSize = NormalizeDouble(LotSize,2);
    
        
        // Buy Order
        if(TenkanSen > KijunSen && BuyTicket == 0 && LastClose > MathMax(SenkouSpanA,SenkouSpanB))
         {
            // Close Order
            OrderSelect(SellTicket,SELECT_BY_TICKET);
              
              if(OrderCloseTime() == 0 && SellTicket > 0)
                  {
                      double CloseLots = OrderLots();
                      
                      while(IsTradeContextBusy()) Sleep(100);

                  RefreshRates();
                  double ClosePrice = Ask;

                  bool Closed = OrderClose(SellTicket,CloseLots,ClosePrice,UseSlippage,Red);
                  
                  // Error handling
                  if(Closed == false)
                     {
                        ErrorCode = GetLastError();
                        string ErrDesc = ErrorDescription(ErrorCode);

                        string ErrAlert = StringConcatenate("Close Sell Order - Error ",ErrorCode,": ",ErrDesc);
                        Alert(ErrAlert);

                        string ErrLog = StringConcatenate("Ask: ",Ask," Lots: ",LotSize," Ticket: ",SellTicket);
                        Print (ErrLog);
                     }
                      
                  }
                
                // Open buy order
                while(IsTradeContextBusy()) Sleep(100);
                RefreshRates();
            
            BuyTicket = OrderSend(Symbol(),OP_BUY,LotSize,Ask,UseSlippage,0,0,"Buy Order",MagicNumber,0,Green);
            
            // Error handling
            if(BuyTicket == -1)
               {
                  ErrorCode = GetLastError();
                  ErrDesc = ErrorDescription(ErrorCode);

                  ErrAlert = StringConcatenate("Open Buy Order - Error ",ErrorCode,": ",ErrDesc);
                  Alert(ErrAlert);

                  ErrLog = StringConcatenate("Ask: ",Ask," Lots: ",LotSize);
                  Print (ErrLog);
               }

            // Order modification
            
            else
               {
                  OrderSelect(BuyTicket,SELECT_BY_TICKET);
                  double OpenPrice = OrderOpenPrice();

                  // Calculate stop level
                      double StopLevel = MarketInfo(Symbol(),MODE_STOPLEVEL) * Point;

                      RefreshRates();
                      double UpperStopLevel = Ask + StopLevel;
                      double LowerStopLevel = Bid - StopLevel;

                      double MinStop = 5 * UsePoint;
                      
                      // Calculate stop loss and take profit
                      if(StopLoss > 0) double BuyStopLoss = OpenPrice - (StopLoss * UsePoint);
                  if(TakeProfit > 0) double BuyTakeProfit = OpenPrice + (TakeProfit * UsePoint);

                      // Verify stop loss and take profit
                      if(BuyStopLoss > 0 && BuyStopLoss > LowerStopLevel)
                          {
                              BuyStopLoss = LowerStopLevel - MinStop;
                          }
                      
                      if(BuyTakeProfit > 0 && BuyTakeProfit < UpperStopLevel)
                          {
                              BuyTakeProfit = UpperStopLevel + MinStop;
                          }

                      // Modify order
                      if(IsTradeContextBusy()) Sleep(100);

                  if(BuyStopLoss > 0 || BuyTakeProfit > 0)
                     {
                        bool TicketMod = OrderModify(BuyTicket,OpenPrice,BuyStopLoss,BuyTakeProfit,0);
                       
                        // Error handling
                        if(TicketMod == false)
                           {
                              ErrorCode = GetLastError();
                              ErrDesc = ErrorDescription(ErrorCode);

                              ErrAlert = StringConcatenate("Modify Buy Order - Error ",ErrorCode,": ",ErrDesc);
                              Alert(ErrAlert);

                              ErrLog = StringConcatenate("Ask: ",Ask," Bid: ",Bid," Ticket: ",BuyTicket," Stop: ",BuyStopLoss," Profit: ",BuyTakeProfit);
                              Print (ErrLog);
                           }
                     }
               }

              SellTicket = 0;
         }



   //Exit Buy Strategy
   if(TenkanSen < KijunSen && BuyTicket > 0)
   {
           //Close Order
           OrderSelect(BuyTicket, SELECT_BY_TICKET);

                   if(OrderCloseTime() == 0 && BuyTicket > 0)
                           {
                                   CloseLots = OrderLots();
                                   while(IsTradeContextBusy()) Sleep(100);

                           RefreshRates();
                              ClosePrice = Bid;

                              Closed = OrderClose(BuyTicket,CloseLots,ClosePrice,UseSlippage,Red);

                           //Error Handling
                           if(Closed == false)
                                   {
                                   ErrorCode = GetLastError();
                                   ErrDesc = ErrorDescription(ErrorCode);
                                   
                                   ErrAlert = StringConcatenate("Close Sell Order - Error ",ErrorCode,": ",ErrDesc);
                                   Alert(ErrAlert);
                                   
                                   ErrLog = StringConcatenate("Bid: ",Bid," Lots: ",LotSize," Ticket: ",BuyTicket);
                                   Print (ErrLog);
                                   }
                                }
        
        
    }
        
        // Sell Order
        if(TenkanSen < KijunSen && SellTicket == 0 && LastClose < MathMin(SenkouSpanA,SenkouSpanB))
            {
                OrderSelect(BuyTicket,SELECT_BY_TICKET);
        
              if(OrderCloseTime() == 0 && BuyTicket > 0)
               {
                  CloseLots = OrderLots();

                  while(IsTradeContextBusy()) Sleep(10);

                  RefreshRates();
                  ClosePrice = Bid;

                  Closed = OrderClose(BuyTicket,CloseLots,ClosePrice,UseSlippage,Red);
                  
                  // Error handling
                  if(Closed == false)
                     {
                        ErrorCode = GetLastError();
                        ErrDesc = ErrorDescription(ErrorCode);

                        ErrAlert = StringConcatenate("Close Buy Order - Error ",ErrorCode,": ",ErrDesc);
                        Alert(ErrAlert);

                        ErrLog = StringConcatenate("Bid: ",Bid," Lots: ",LotSize," Ticket: ",BuyTicket);
                        Print (ErrLog);
                     }
               }
                
               while(IsTradeContextBusy()) Sleep(100);
                RefreshRates();
                            
                SellTicket = OrderSend(Symbol(),OP_SELL,LotSize,Bid,UseSlippage,0,0,"Sell Order",MagicNumber,0,Red);
                
                // Error handling
            if(SellTicket == -1)
               {
                  ErrorCode = GetLastError();
                  ErrDesc = ErrorDescription(ErrorCode);

                  ErrAlert = StringConcatenate("Open Sell Order - Error ",ErrorCode,": ",ErrDesc);
                  Alert(ErrAlert);

                  ErrLog = StringConcatenate("Bid: ",Bid," Lots: ",LotSize);
                  Print (ErrLog);
               }
                    
                else
               {
                  OrderSelect(SellTicket,SELECT_BY_TICKET);
                  OpenPrice = OrderOpenPrice();

                      StopLevel = MarketInfo(Symbol(),MODE_STOPLEVEL) * Point;

                      RefreshRates();
                      UpperStopLevel = Ask + StopLevel;
                      LowerStopLevel = Bid - StopLevel;

                      MinStop = 5 * UsePoint;
                      
                      if(StopLoss > 0) double SellStopLoss = OpenPrice + (StopLoss * UsePoint);
                      if(TakeProfit > 0) double SellTakeProfit = OpenPrice - (TakeProfit *  UsePoint);

                      if(SellStopLoss > 0 && SellStopLoss < UpperStopLevel)
                          {
                              SellStopLoss = UpperStopLevel + MinStop;
                          }
                      if(SellTakeProfit  > 0 && SellTakeProfit > LowerStopLevel)
                          {
                              SellTakeProfit = LowerStopLevel - MinStop;
                          }

                      if(IsTradeContextBusy()) Sleep(100);

                  if(SellStopLoss > 0 || SellTakeProfit > 0)
                    {
                       TicketMod = OrderModify(SellTicket,OpenPrice,SellStopLoss,SellTakeProfit,0);
                       
                       // Error handling
                       if(TicketMod == false)
                          {
                             ErrorCode = GetLastError();
                             ErrDesc = ErrorDescription(ErrorCode);

                             ErrAlert = StringConcatenate("Modify Sell Order - Error ",ErrorCode,": ",ErrDesc);
                             Alert(ErrAlert);

                             ErrLog = StringConcatenate("Ask: ",Ask," Bid: ",Bid," Ticket: ",SellTicket," Stop: ",SellStopLoss," Profit: ",SellTakeProfit);
                             Print (ErrLog);
                          }
                    }
               }
            
            BuyTicket = 0;
            }

   //Exit Sell Strategy
   if(TenkanSen > KijunSen && SellTicket > 0)
   {
           //Close Order
           OrderSelect(SellTicket, SELECT_BY_TICKET);

                   if(OrderCloseTime() == 0 && SellTicket > 0)
                           {
                                   CloseLots = OrderLots();
                                   while(IsTradeContextBusy()) Sleep(100);

                           RefreshRates();
                           ClosePrice = Ask;

                           Closed = OrderClose(SellTicket,CloseLots,ClosePrice,UseSlippage,Red);

                           //Error Handling
                           if(Closed == false)
                                   {
                                   ErrorCode = GetLastError();
                                   ErrDesc = ErrorDescription(ErrorCode);
                                   
                                   ErrAlert = StringConcatenate("Close Sell Order - Error ",ErrorCode,": ",ErrDesc);
                                   Alert(ErrAlert);
                                   
                                   ErrLog = StringConcatenate("Bid: ",Bid," Lots: ",LotSize," Ticket: ",SellTicket);
                                   Print (ErrLog);
                                   }
                                }
   }

            
        return(0);
    }




// Pip Point Function
double PipPoint(string Currency)
    {
        int CalcDigits = MarketInfo(Currency,MODE_DIGITS);
        if(CalcDigits == 2 || CalcDigits == 3) double CalcPoint = 0.01;
        else if(CalcDigits == 4 || CalcDigits == 5) CalcPoint = 0.0001;
        return(CalcPoint);
    }


// Get Slippage Function
int GetSlippage(string Currency, int SlippagePips)
    {
        int CalcDigits = MarketInfo(Currency,MODE_DIGITS);
        if(CalcDigits == 2 || CalcDigits == 4) double CalcSlippage = SlippagePips;
        else if(CalcDigits == 3 || CalcDigits == 5) CalcSlippage = SlippagePips * 10;
        return(CalcSlippage);
 
int LastClose; //This is variable to compare with SpanA and SpanB
Should be a double.
 

It works!

 

Thank you angevoyageur.

 

Can you explain to me why double does the trick?

Is it because integer doesn't support the decimal point 

 
int LastClose; //This is variable to compare with SpanA and SpanB 
LastClose = iClose(NULL,0,1);

Let us say that the previous close was 1.34567

LastClose has been declared as an integer so it can't store fractions of numbers.

So LastClose will be set as 1.

Similarly, if the previous close was 99.123 then the value of LastClose will be set to 99.

And so on. 

If you used:

#property strict

 you would have got a warning message when you compiled