Customer indicator works correct, but in EA has the indicator buffer incorrect content - page 3

 

One thing that's difficult at least for me is trying to debug a loop with only Pint or Alert as a tool. So I add a text object painter inside both ADI Ea & SuperTrend. 

It turned out, calling iCustom to an indicator that has ObjectCreate in it triggers its drawing also.  So I decided to add SuperTrend2 to compare them with drawing made from SuperTrend (which was not attached but drawing text also), just to make sure. All other calculations are left intact. 

With SuperTrend2 you can opt for using drawing from inside the loop or outside. The text will indicate ST2o when UseInsideLoop input is set to false. 

Have a try at them. I use them on USDCAD M1 so I can see new bar values forming quickly. Don't forget to select scale option (F8) to Scale Fix One to One to check past candles and AutoScroll turned-off.  

extern double    TakeProfit=350.0; 
extern double    Lots=0.1;             
extern double    TrailingStop=0.0;  
extern bool      Test=false;
extern string    IndicatorName = "SuperTrends101109_ok";
extern int       BufferNumber = 2;

extern int     Nbr_Periods=10;
extern double  Multiplier=3.0;

int c_altBars=0;                    
bool b_trade=false;                 
bool b_print=false;

int vNudge = 7;

int init()
{
}

int deinit()
{
   for(int g = 0; g<Bars; g++) ObjectDelete("ADI_"+g);
   for( g = 0; g<Bars; g++) ObjectDelete("STi_"+g);
   for( g = 0; g<Bars; g++) ObjectDelete("STo_"+g);
}
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
{
   int cnt, ticket, total, isCrossed;

//   if (Bars<100) {
//      Print("bars less than 100");
//      return (0);
//   }

//   if (c_altBars < Bars) 
//   {
//      c_altBars = Bars;
    
      // only for test purposes
      double sT_5   = iCustom(NULL,0,"Heiken Ashi and TK1",Nbr_Periods,Multiplier,7,5);
      double sT_4   = iCustom(NULL,0,"Heiken Ashi and TK1",Nbr_Periods,Multiplier,7,4);
      double sT_3   = iCustom(NULL,0,"Heiken Ashi and TK1",Nbr_Periods,Multiplier,7,3);
      double sT_2   = iCustom(NULL,0,"Heiken Ashi and TK1",Nbr_Periods,Multiplier,7,2);
      double sT_0   = iCustom(NULL,0,"Heiken Ashi and TK1",Nbr_Periods,Multiplier,7,0);

      // changeTrend[1] in indicator; buffer7[1] is trade trigger in EA
      double sT_1   = iCustom(NULL,0,"Heiken Ashi and TK1",Nbr_Periods,Multiplier,7,1);
      
      for(int i = Bars; i>=0; i--)
      {
         double price = iCustom(NULL,0,IndicatorName,Nbr_Periods,Multiplier,BufferNumber,i);
         double txprice = Bid; //iMA(NULL,0,50,0,MODE_SMMA,PRICE_TYPICAL,i);
         string name = StringConcatenate("ADI_",i);
         string text = StringConcatenate(i," - ",DoubleToStr(price,Digits)," - ADI");
         if(ObjectFind(name) == -1)
            ObjectCreate(name,OBJ_TEXT,0,Time[i],txprice + vNudge * Point);
            ObjectSetText(name,text, 9, "Arial", Silver);
            ObjectSet(name,OBJPROP_TIME1,Time[i]);
            ObjectSet(name,OBJPROP_PRICE1,txprice + vNudge * Point);
            ObjectSet(name,OBJPROP_ANGLE,90.0);
         if(price == 1.38) ObjectSet(name,OBJPROP_COLOR,Red);
         if(price == 1.42) ObjectSet(name,OBJPROP_COLOR,Lime);
      }   
         

      if (sT_1 == 1.38)
      { 
         isCrossed = 1; Print ("Crossed = 1 "+" "+TimeToStr(Time[0]));
      }   
      else if (sT_1 == 1.42)
      {  
         isCrossed = 2; Print ("Crossed = 2"+" "+TimeToStr(Time[0]));
      }
      else isCrossed = 0; 
   
      if (Test == false) b_trade = true;
      else b_trade = false;            

      total=OrdersTotal();
      if(total<1) 
      {
         if(isCrossed ==1 && b_trade == true) {
            isCrossed = 0;
            b_trade = false;

            ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,1,0,0,"ADI EA",12345,0,Green);
            if(ticket>0) {
               if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
               Print("BUY order opened: ",OrderOpenPrice());
            }
            else 
               Print("Error openning BUY order: ",GetLastError());
            return (0);
         }
         if(isCrossed==2 && b_trade == true) {
             isCrossed = 0;
             b_trade = false;

            ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,1,0,0,"ADI EA",12345,0,Red);
            if(ticket>0) {
               if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
               Print("SELL order opened: ",OrderOpenPrice());
            }
            else 
               Print("Error openning SELL order: ",GetLastError());
            return (0);
         }
         return (0);
      }   
   
      for(cnt=0;cnt<total;cnt++) {
         OrderSelect(cnt, SELECT_BY_POS,MODE_TRADES);
         if(OrderType()<=OP_SELL && OrderSymbol()==Symbol()) {
            if(OrderType()==OP_BUY) {                                //long position is opened
               // should be closed?
               if(isCrossed==2 && b_trade == true) {
                  isCrossed = 0; b_trade = false;
               // close long position     
                  OrderClose(OrderTicket(),OrderLots(),Bid,1,Violet);//close position
               // and open short position                                                       
                  ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,1,0,0,"ADI EA",12345,0,Red);
                  if(ticket>0) {
                     if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
                        Print("SELL order opened: ",OrderOpenPrice());
                  }
                  else Print("Error openning SELL order: ",GetLastError());
                  return(0);           // exit
               }
               // check for trailing stop, by buy trend
               if(TrailingStop>0) {
                  if(Bid-OrderOpenPrice()>Point*TrailingStop) {
                     if(OrderStopLoss()<Bid-Point*TrailingStop) {
                        OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green);
                        return(0);
                     }
                  }
               }
            }
            else { // go to short position
               // should be closed?
               if(isCrossed==1 && b_trade == true) {
                  isCrossed = 0; b_trade = false;
               // close short position    
                  OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet);   //close position
               // and open long position
                  ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,1,0,0,"ADI EA",12345,0,Green);
                  if(ticket>0) {
                     if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
                     Print("BUY order opened: ",OrderOpenPrice());
                  }
                  else 
                     Print("Error openning BUY order: ",GetLastError());
                  return(0);                                         // exit
               }
               // chack for trailing stop, by sell trend
               if(TrailingStop>0) {
                  if(OrderOpenPrice()-Ask>Point*TrailingStop) {
                     if((OrderStopLoss()>(Ask-Point*TrailingStop)) || (OrderStopLoss()==0)) {
                        OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,OrderTakeProfit(),0,Red);
                        return(0); 
                     }
                  }
               }
            }   
         }   
      }
   //} //  eimal pro Periode
   return(0);
}
Files:
 
Here's the SuperTrend
Files:
 

... and SuperTrend2 (seems files can't be attached all at once). Remember only the ADI and SuperTrend2 are attached to chart. 

I observe a glitch occured once (I can't confirmed it) when the Supertrend2 value suddenly change past value (bar 200 something). But overall, it seems the whole calculate-all-bars-on-every-tick thing -- although I still would not personally use it as is  --  is not generating anything flawed on a constant basis.

So this three experts serve as a confirmation that all values from EA & indicator matched bar per bar on every tick

 

So to further convince you that the mistake was not from the iteration (my previous culprit), but from the incorrect interpreting of your Print/Alert debugger... I quote this from page 2. 

I use D1. values in EA are unambiguously wrong!!!. See please the time information 9. - 11.11.2010 by print debugging in. There entry 1.42000000 is absent.
Position i=0 10.11.2010 and i=1 11.11.2010 must be 1.42000000

Indicator:
Heiken Ashi and TK1 EURUSD,Daily: 2010.11.10 00:00 1.42000000 8 short 2115
---------------- Info --- -- Time ---

EA:
ADI_EA_14112010_1 EURUSD,Daily: Alert: 1089 1.40000000 1.40000000 1.40000000 1.40000000 1.40000000 1.40000000 2010.11.11 00:00
ADI_EA_14112010_1 EURUSD,Daily: Alert: 1088 1.40000000 1.40000000 1.40000000 1.40000000 1.40000000 1.40000000 2010.11.10 00:00
ADI_EA_14112010_1 EURUSD,Daily: Alert: 1087 1.40000000 1.40000000 1.40000000 1.40000000 1.40000000 1.40000000 2010.11.09 00:00
------------------------------------Info--------------- i= 4 i=3 i=2 i=1 i=0 --Time--

 The bars you're comparing are different though the date was the same. Why was the date the same I will leave that to you... but let's compare both parts for debugging on EA

double sT_5   = iCustom(NULL,0,"Heiken Ashi and TK1",Nbr_Periods,Multiplier,7,5);
double sT_4   = iCustom(NULL,0,"Heiken Ashi and TK1",Nbr_Periods,Multiplier,7,4);
double sT_3   = iCustom(NULL,0,"Heiken Ashi and TK1",Nbr_Periods,Multiplier,7,4);
double sT_2   = iCustom(NULL,0,"Heiken Ashi and TK1",Nbr_Periods,Multiplier,7,2);
double sT_0   = iCustom(NULL,0,"Heiken Ashi and TK1",Nbr_Periods,Multiplier,7,0);

// changeTrend[1] in indicator; buffer7[1] is trade trigger in EA
double sT_1   = iCustom(NULL,0,"Heiken Ashi and TK1",Nbr_Periods,Multiplier,7,1);

Alert(Bars+" "+sT_5+" "+sT_4+" "+sT_3+" "+sT_2+" "+sT_1+" "+sT_0+" "+TimeToStr(Time[0])); // inside start() {
... and HeikenAshiTK1
Print(TimeToStr(Time[i])+": "+changeTrend[i]+" "+i+" long "+Bars); // inside for (i = Bars; i >= 0; i--) {
As I've said the indicator's Print didn't have a chance to display value of 0 bar and time from Time[0], while your EA conveniently display Time[0] on every tick. That's a very different source of values for comparison. Try your previous debugging on M1 to see this more clearly, or see if you can replicate that 'incorrect' result (having new perspective in mind). Hope that helps.
 

Thank you for your engagement and detailed reasons. This is great!!

Unfortunately, as I have already written, the simple SuperTrend 101109 indicator (1-step super trend logic) returns correct values in EA but the complexe Heiken Ashi and TK1 indicator(1.step Heiken Ashi logic and 2.step SuperTrend logic), incorrect values. Difference between the two indicators is only the Heiken Ashi logic, which is upstream in the complexe Heiken Ashi and TK1 indicator. I.e. for SuperTrend logic will not take the values from the chart, but from Heiken Ashi logic.

I brought the simple SuperTrend 101109 indicator in the game, only you can prove to that the super trend logic is correct. Conclusion: you have proved what I already knew, that delivers SuperTrend 101109 right values.

This to me is not easier to find the error, if EA is working with the complexe Heiken Ashi and TK1 indicator.

Cameofx,
nevertheless many thanks!
 

After an intensive search, I found that the error is generated by the ATR calculation in the complexe indicator.

I.e. Call returns correct indicator values in my EA:

atr = iATR(NULL, 0, Nbr_Periods, i);

Call returns the wrong indicator value in my EA:

atr = AtrBuffer[i];

Unfortunately, the first call, it only programmatically correct, expertly not, because it is based on the chart values instead Heiken Ashi values.
The ATR logic (part of Heiken Ashi and TK1 indicator) that leads to the problem is:

 //---- ATR calculation (it is based on standard indicator) -----
   int i, limit;
   double TempBuffer1[5000];
   double high, low, prevclose;

   ArraySetAsSeries(TempBuffer1, false);
//   atrCountedBars=IndicatorCounted();
   int atrCountedBars=countedBars;

   if(Bars<=Nbr_Periods) return(0);
//---- initial zero
   if(atrCountedBars<1)
      for(i=1;i<=Nbr_Periods;i++) AtrBuffer[Bars-i]=0.0;

   if(atrCountedBars>0) atrCountedBars--; 
   i=Bars-atrCountedBars-1;

// main loop
   while(i>=0) {
// no chart, but Heiken Ashi value
      if (ExtMapBuffer1[i] > ExtMapBuffer2[i]) {
         high=ExtMapBuffer1[i];
         low=ExtMapBuffer2[i];
      }
      else {
         high=ExtMapBuffer2[i];
         low=ExtMapBuffer1[i];
      }
      if(i==Bars-1) TempBuffer1[i]=high-low;
      else {
// Heiken Ashi value
         prevclose=ExtMapBuffer4[i+1];
         TempBuffer1[i]=MathMax(high,prevclose)-MathMin(low,prevclose);
      }
      i--;
   } // --- end of main loop --------

   if(atrCountedBars>0) atrCountedBars--;
   limit=Bars-atrCountedBars;   
   for(i=0; i<limit; i++) 
         AtrBuffer[i]= iMAOnArray(TempBuffer1,Bars,Nbr_Periods,0,MODE_SMA,i);
//---- END of ATR -------------    

I have the logic of the standard ATR indicator in this source code taken

Conclusion:

My complexe IIndicator need logic based on Heiken Ashi values. I.e. I have the source of errors but no final solution.

Reason: