how an indicator is running within an EA?

 

Hi all

I believe people here may have heard of NonLagMA indicator, basically this is a trend indicator. I am trying to use this indicator to build a strategy, e.g when the trend has change, go long or short accordingly.

However, working on a M30 timeframe, I have way too many trade open. I am using rule provided in this example:

<link removed>/building-strategies-custom-indicators-icustom-function#nonlagea1

BuyCondif (trend_macurrent==1 && trend_maprevious==-1)
SellCondif (trend_macurrent==-1 && trend_maprevious==1)


   trend_now = iCustom(NULL,0,"NonLagMA",3,1);
   trend_pre = iCustom(NULL,0,"NonLagMA",3,2);
   
   if (trend_now == 1 && trend_pre == -1)
      OpenLong();
   
   if (trend_now == -1 && trend_pre == 1)
      OpenShort();

but the result is, on the red line, I have both buy and sell open during this downtrend.

Can someone explain to me why? I am not fully understand how a EA is running, as I expect the indicator look back to the previous bar and the previous previous bar (hence both are history and never change) to make the decision, but obviously it seems to do more.


Many thanks 

 
   trend_now = iCustom(NULL,0,"NonLagMA",3,1);
   trend_pre = iCustom(NULL,0,"NonLagMA",3,2);
   
   if (trend_now == 1 && trend_pre == -1)

If this will be true, it will be true for every tick of bar zero.

  1. Either only check once at the start of a new bar.

    For a new bar test, Bars is unreliable (a refresh/reconnect can change number of bars on chart,) volume is unreliable (miss ticks,) Price is unreliable (duplicate prices and The == operand. - MQL4 and MetaTrader 4 - MQL4 programming forum.) Always use time.

    I disagree with making a new bar function, because it can only be called once per tick. A variable can be tested multiple times.

  2. Or look for a change in condition.
    static double trend_now=0;
    double trend_pre=trend_now
    trend_now = iCustom(NULL,0,"NonLagMA",3,1);
    
       if (trend_now == 1 && trend_pre != trend_now)
 
whroeder1:

If this will be true, it will be true for every tick of bar zero.

  1. Either only check once at the start of a new bar.
  2. Or look for a change in condition.

Many thanks for sharing your idea.

I made the change as you suggested, using trend_now and trend_pre. The variables are created in initialization, and the main code runs in start(). However, the result is more less the same.

static double trend_now=0;
double trend_pre=trend_now;

trend_now = iCustom(NULL,0,"NonLagMA",3,1);

   if (trend_now == 1 && trend_pre != trend_now)
      OpenLong();

   if (trend_now == -1 && trend_pre != trend_now)
      OpenShort();

On the printscreen attached, you can see a lot of both buy and sell order are open during a trend, however these order should never be opened at all. For example, during the red trend, because the previous bar and the previous previous bar are both red, meaning the trend is -1, defined by NonLagMA, there was no trend changed, these bars are histories and the trend is fixed history, hence when the indicator runs on bar 1 and bar 2, should return -1 for both, so why the EA would open the trade please?


 
luckyvictor: the variables are created in initialization, and the main code runs in start().
  1. The variables have nothing to do with "initialization," only with start. Your posted code is without context, there are no mind readers here.
  2. Use the debugger or print out your variables, including _LastError and find out why.
  3. Start using the new Event Handling Functions.
 
whroeder1:
  1. The variables have nothing to do with "initialization," only with start. Your posted code is without context, there are no mind readers here.
  2. Use the debugger or print out your variables, including _LastError and find out why.
  3. Start using the new Event Handling Functions.

I stated it so I know I didn't make the mistake of having the variable created and defined in start() all the time.

Would you please tell me how often the code start() is run please? Should I use start() or ontick() actually please?

Below is literally the main function, of course other functions are defined outside.

int init()
{
      LastTradeBarTime = Time[1]; 
      t = 0;
      trend_now = 0;
      long_ticket = -1;
      short_ticket = -1;
      count = 0;
      sl = MarketInfo(Symbol(), MODE_STOPLEVEL)*Point + MarketInfo(Symbol(), MODE_SPREAD)*Point;
      tp = MarketInfo(Symbol(), MODE_STOPLEVEL)*Point + MarketInfo(Symbol(), MODE_SPREAD)*Point;  
      return(0);
  }

int start()
  {             
     // Trades opened
   int l_TotalTrades_buy = GetTotalTrades(OP_BUY);
   int l_TotalTrades_sell = GetTotalTrades(OP_SELL);
   
   if (LastTradeBarTime == Time[0]) return(0);

   trend_pre = trend_now;
   trend_now = iCustom(NULL,0,"NonLagMA",3,1);

   if (trend_now == 1 && trend_pre != trend_now)
      OpenLong();
   
   if (trend_now == -1 && trend_pre != trend_now)
      OpenShort();
   
   return(0);
  }

 
//trend_now = iCustom ( NULL , 0 , "NonLagMA" , 3 , 1 );
trend_now = iCustom ( NULL , 0 , "NonLagMA" ,4, 1 );

You refer to number 3 of the buffer, but in my program it should be number 4 (trend).

Since number 3 is for prices, it not output 1 or -1.

 
luckyvictor:

I stated it so I know I didn't make the mistake of having the variable created and defined in start() all the time.

Would you please tell me how often the code start() is run please? Should I use start() or ontick() actually please?

Below is literally the main function, of course other functions are defined outside.


You should add:

LastTradeBarTime = Time[0];

somewhere in start below the line:

if(LastTradeBarTime == Time[0]) return(0);

and remove it from init.

Something like this:

int start()
{             
  if(LastTradeBarTime == Time[0]) return(0);
  LastTradeBarTime = Time[0];

  // Trades opened
  int l_TotalTrades_buy = GetTotalTrades(OP_BUY);
  int l_TotalTrades_sell = GetTotalTrades(OP_SELL);
   
  trend_pre = trend_now;
  trend_now = iCustom(NULL,0,"NonLagMA",3,1);

  if(trend_now == 1 && trend_pre != trend_now)
    OpenLong();
   
  if(trend_now == -1 && trend_pre != trend_now)
    OpenShort();
   
  return(0);
}

Start is running on every new tick. You may use start and OnTick interchangeably.

 
Naguisa Unada:

You refer to number 3 of the buffer, but in my program it should be number 4 (trend).

Since number 3 is for prices, it not output 1 or -1.


which NonLagMA do you use please? mine one is v7.1, and the code is below, and I used print to check its output, it is either 1 or -1.

   IndicatorBuffers(6);

   SetIndexStyle(0,DRAW_LINE);

   SetIndexBuffer(0,MABuffer);

   SetIndexStyle(1,DRAW_LINE);

   SetIndexBuffer(1,UpBuffer);

   SetIndexStyle(2,DRAW_LINE);

   SetIndexBuffer(2,DnBuffer);

   SetIndexBuffer(3,trend);

   SetIndexBuffer(4,Del);

   SetIndexBuffer(5,AvgDel); 

 
Stanislav Korotky:

You should add:

somewhere in start below the line:

and remove it from init.

Something like this:

Start is running on every new tick. You may use start and OnTick interchangeably.


I have this code

LastTradeBarTime = Time[0];

within the function of OpenLong() and OpenShort(), the code is executed only if a position is successfully open, e.g. a ticket is return and no error when OrderSend is called

So this start(), if it is run every tick, I still dont understand how it can open a trade within a trend, as the code is designed to open a trade at the change of a trend. 

Obviously when I print out the result of trend_now, trend_pre, they do fulfil the conditional statement and called OpenLong() or OpenShort().

 
luckyvictor :

which NonLagMA do you use please? mine one is v7.1, and the code is below, and I used print to check its output, it is either 1 or -1.

There is no version number. It may be older than yours.

If number 3 is "trend", there is no problem so I will cancel my last comment.

Reason: