Need help to finish my EA

 

I've created an EA for 30Min chart which is supposed to open trades base on RSI values and Donchian Channel. I guess the problem is with "iCustom" function calling, cause it doesn't print the indicator when I back test it.

I appreciate if someone kindly debug this code for me.

Below are trading criteria:

BUY:

If Donchian Channel Low is already touched (Buy trade is permitted), then whenever RSI moves above 30, I should have a buy trade. Take profit level is either 300 PIP or when the Donchain Channel Upper is touched.

SELL:

If Donchian Channel Upper is already touched (Sell trade is permitted), then whenever RSI moves below 70, I should have a sell trade. Take profit level is either 300 PIP or when the Donchain Channel Low is touched.


 Below is the code:

//+------------------------------------------------------------------+
//|                                      TP - Optimized (30Min.).mq4 |
//|                                              MJSTOCK78@GMAIL.COM |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "MJSTOCK78@GMAIL.COM"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict


input double TakeProfit    =3000;
input double Lots          =0.01;
input double TrailingStop  =0;
input double StopLoss      =5000;
input int    RSIPeriod     =14;
extern int   DonchianPeriod =960;   

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick(void)
  {
   double DonchianUP,DonchianLow,RSICurrent,RSIPrev;
   int    cnt,ticket,total;
   bool   BuySignal=false;
   bool   SellSignal=false;
//---
   if(Bars<100)
     {
      Print("bars less than 100");
      return;
     }
   if(TakeProfit<10)
     {
      Print("TakeProfit less than 10");
      return;
     }
//--- to simplify the coding and speed up access data are put into internal variables
    RSICurrent=iRSI(NULL,0,RSIPeriod,PRICE_CLOSE,1);
    RSIPrev=iRSI(NULL,0,RSIPeriod,PRICE_CLOSE,2); 
    DonchianUP=iCustom(NULL,0,"DonchainChannels",DonchianPeriod,0,0);
    DonchianLow=iCustom(NULL,0,"DonchainChannels",DonchianPeriod,2,0);
   
    
//--------------------------------------------------------------------------      
   total=OrdersTotal();
   static datetime prevTime;
   if(Time[0]!=prevTime)
//   if(total<1)
     {
      //--- no opened orders identified
      if(AccountFreeMargin()<(1000*Lots))
        {
         Print("We have no money. Free Margin = ",AccountFreeMargin());
         return;
        }
      //--- check for long position (BUY) possibility
      if(iLow(Symbol(),Period(),1)==DonchianLow)
         {BuySignal=true;
          SellSignal=false;}
         
      if(BuySignal=true && RSICurrent>30 && RSIPrev<30)
        {
         ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,TakeProfit,"TP",17384,0,Green);

         if(ticket>0)
           {
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
               { Print("BUY order opened : ",OrderOpenPrice());
                 prevTime=Time[0];
                 ticket=OrderModify(OrderTicket(),OrderOpenPrice(),Bid-StopLoss*Point,TakeProfit,0,Yellow);
               }
           }
         else
            Print("Error opening BUY order : ",GetLastError());
         return;
        }
      //--- check for short position (SELL) possibility
      if(iHigh(Symbol(),Period(),1)==DonchianUP)
         {BuySignal=false;
          SellSignal=true;}
                
      if(SellSignal=true && RSICurrent<70 && RSIPrev>70)
        {
         ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,0,TakeProfit,"TP",17384,0,Red);
       
         if(ticket>0)
           {
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
               { Print("SELL order opened : ",OrderOpenPrice());
                 prevTime=Time[0];
                 ticket=OrderModify(OrderTicket(),OrderOpenPrice(),Ask+StopLoss*Point,TakeProfit,0,Yellow);
               }
           }
         else
            Print("Error opening SELL order : ",GetLastError());
        }       
      //--- exit from the "no opened orders" block
      return;
     }
     
//--- it is important to enter the market correctly, but it is more important to exit it correctly...   
   for(cnt=0;cnt<total;cnt++)
     {
      if(!OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))
         continue;
      if(OrderType()<=OP_SELL &&   // check for opened position 
         OrderSymbol()==Symbol())  // check for symbol
        {
         //--- long position is opened
         if(OrderType()==OP_BUY)
           {
            //--- should it be closed?
            if(iHigh(Symbol(),Period(),1)==DonchianUP)
              {
               //--- close order and exit
               if(!OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet))
                  Print("OrderClose error ",GetLastError());
               return;
              }
            //--- check for trailing stop
            if(TrailingStop>0)
              {
               if(Bid-OrderOpenPrice()>Point*TrailingStop)
                 {
                  if(OrderStopLoss()<Bid-Point*TrailingStop)
                    {
                     //--- modify order and exit
                     if(!OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green))
                        Print("OrderModify error ",GetLastError());
                     return;
                    }
                 }
              }
           }
         else // go to short position
           {
            //--- should it be closed?
            if(iLow(Symbol(),Period(),1)==DonchianLow)
              {
               //--- close order and exit
               if(!OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet))
                  Print("OrderClose error ",GetLastError());
               return;
              }
            //--- check for trailing stop
            if(TrailingStop>0)
              {
               if((OrderOpenPrice()-Ask)>(Point*TrailingStop))
                 {
                  if((OrderStopLoss()>(Ask+Point*TrailingStop)) || (OrderStopLoss()==0))
                    {
                     //--- modify order and exit
                     if(!OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,OrderTakeProfit(),0,Red))
                        Print("OrderModify error ",GetLastError());
                     return;
                    }
                 }
              }
           }
        }
     }     
  }
//+------------------------------------------------------------------+

 

Also, below is the code for Donchian Channel Indicator created by RasoulFX (FYI):

//+------------------------------------------------------------------+
//|                                             DonchainChannels.mq4 |
//|                                         Copyright 2014, RasoulFX |
//|                                     http://rasoulfx.blogspot.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, RasoulFX"
#property link      "http://rasoulfx.blogspot.com"
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Red
#property indicator_color2 Blue
#property indicator_color3 Green
#property indicator_width1 1
#property indicator_width2 1
#property indicator_width3 1

input int BarsToCount=20;

double     upper[];
double     middle[];
double     lower[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   IndicatorShortName("DCH("+IntegerToString(BarsToCount)+")");

   SetIndexBuffer(0,upper);
   SetIndexBuffer(1,middle);
   SetIndexBuffer(2,lower);

   SetIndexStyle(0,DRAW_LINE);
   SetIndexStyle(1,DRAW_LINE);
   SetIndexStyle(2,DRAW_LINE);
   
   SetIndexLabel(0,"Upper");
   SetIndexLabel(1,"Middle");  
   SetIndexLabel(2,"Lower");   
//---
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
//---
   //static int old_bars;
   //if(old_bars == Bars) return(0);
   
   //int counted_bars = IndicatorCounted();
   //if(counted_bars>0) counted_bars--;
   
   //int limit = Bars - counted_bars;
   int limit = rates_total - prev_calculated;
   if(prev_calculated > 0) limit++;
   
   for(int i=0; i < limit; i++)
   {
      upper[i]=iHigh(Symbol(),Period(),iHighest(Symbol(),Period(),MODE_HIGH,BarsToCount,i));
      lower[i]=iLow(Symbol(),Period(),iLowest(Symbol(),Period(),MODE_LOW,BarsToCount,i));
      middle[i] = (upper[i]+lower[i])/2;   
   }
   
   //old_bars = Bars;   
//--- return value of prev_calculated for next call
   return(rates_total);
}
//+------------------------------------------------------------------+
 
mjstock78:

I've created an EA for 30Min chart which is supposed to open trades base on RSI values and Donchian Channel. I guess the problem is with "iCustom" function calling, cause it doesn't print the indicator when I back test it.

I appreciate if someone kindly debug this code for me.

Below are trading criteria:

BUY:

If Donchian Channel Low is already touched (Buy trade is permitted), then whenever RSI moves above 30, I should have a buy trade. Take profit level is either 300 PIP or when the Donchain Channel Upper is touched.

SELL:

If Donchian Channel Upper is already touched (Sell trade is permitted), then whenever RSI moves below 70, I should have a sell trade. Take profit level is either 300 PIP or when the Donchain Channel Low is touched.


 Below is the code:

 

Also, below is the code for Donchian Channel Indicator created by RasoulFX (FYI):

Check out the Freelance section, it's awesome if you want something done!

Trading applications for MetaTrader 5 to order
Trading applications for MetaTrader 5 to order
  • www.mql5.com
I want to modify the existing csvea i possess. This one will take its action from the csv. Each column in the csv has what he will do. Input for lot will still reflect just as the previous one I have my own EA, where i am still getting an errors if i want to add my strategy to a market. I tried many ways how to change the code, but with my...
 
Kenneth Parling:

Check out the Freelance section, it's awesome if you want something done!

Thanks Kenneth for your response,  but I hope a generous expert swing by my post and kindly fix my EA for me.
 

There are several issues that need to fixed:

  • prevTime gets updated only when orders are opened, do you want checks on every tick or on new bar
  • the signals are being reset on every tick so the buy/sell flag is lost when RSI crosses the threshold
  • the exit for loop traverses orders front to back, so when closing an order you miss out the next one
  • you open order with an invalid TP (TakeProfit)
  • some checks should be moved to OnInit
  • shift on iCustom call should be 1, not 0, if you run it at new bar time
  • if you want to check RSI on every tick, RSICurrent shift should be 0
  • RSIPrev should be the previous RSICurrent, not the one from 30+ minutes ago
  • you are not checking if any order matches its magic number
 
lippmaje:

There are several issues that need to fixed:

  • prevTime gets updated only when orders are opened, do you want checks on every tick or on new bar
  • the signals are being reset on every tick so the buy/sell flag is lost when RSI crosses the threshold
  • the exit for loop traverses orders front to back, so when closing an order you miss out the next one
  • you open order with an invalid TP (TakeProfit)
  • some checks should be moved to OnInit
  • shift on iCustom call should be 1, not 0, if you run it at new bar time
  • if you want to check RSI on every tick, RSICurrent shift should be 0
  • RSIPrev should be the previous RSICurrent, not the one from 30+ minutes ago
  • you are not checking if any order matches its magic number

I tried my best to incorporate your comments into my EA, but since I'm a very novice programmer, all my effort took me nowhere, my EA became worse by every try, full of errors. So I highly appreciate if you can kindly debug my EA for me.

 
From reading your code it is unclear if you intend to check open conditions on every tick or on new bar only.
 
lippmaje:
From reading your code it is unclear if you intend to check open conditions on every tick or on new bar only.

New bar only.

Please see picture below/attached picture: 


Files:
 
mjstock78:

New bar only.

In this case you need to fix your new bar check first before going on:

   static datetime prevTime;
   if(Time[0]!=prevTime)
//   if(total<1)
     {
      //--- no opened orders identified
      if(AccountFreeMargin()<(1000*Lots))
        {
         Print("We have no money. Free Margin = ",AccountFreeMargin());
         return;
        }
      //--- check for long position (BUY) possibility
      if(iLow(Symbol(),Period(),1)==DonchianLow)
         {BuySignal=true;
          SellSignal=false;}
         
      if(BuySignal=true && RSICurrent>30 && RSIPrev<30)
        {
         ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,TakeProfit,"TP",17384,0,Green);

         if(ticket>0)
           {
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
               { Print("BUY order opened : ",OrderOpenPrice());
                 prevTime=Time[0];
                 ticket=OrderModify(OrderTicket(),OrderOpenPrice(),Bid-StopLoss*Point,TakeProfit,0,Yellow);
               }
           }
         else
            Print("Error opening BUY order : ",GetLastError());
         return;
        }
      //--- check for short position (SELL) possibility
      if(iHigh(Symbol(),Period(),1)==DonchianUP)
         {BuySignal=false;
          SellSignal=true;}
                
      if(SellSignal=true && RSICurrent<70 && RSIPrev>70)
        {
         ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,0,TakeProfit,"TP",17384,0,Red);
       
         if(ticket>0)
           {
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
               { Print("SELL order opened : ",OrderOpenPrice());
                 prevTime=Time[0];


A new bar check should work like this:

   static datetime prevTime=0;
   if(Time[0]!=prevTime)
     {
      // we got a new bar
      prevTime=Time[0];

      // action goes here
     }


Now that you've been provided with a lengthy list of issues to be fixed. Why not take this thread as job description and have that EA coded for you?

Reason: