Now I'm not sure that the values the EA retrieves are lagging behind the chart. I just saw a value for CCI which doesn't even appear on the chart during the displayed times.
I am going to post the code I use to test retrieving the indicator values. I was using iCustom for all 3 indicators, then changed two of them to the standard Indicator functions. No change. I have changed them back to be consistent with using the indicators in the indicator folder.
//+------------------------------------------------------------------+ //| test_indicators.mq5 | //| Copyright 2024, David Waddington. | //| https://www.mql5.com/en/users/davewaddington | //+------------------------------------------------------------------+ #include <Trade\Trade.mqh> // Standard library for trading operations #include <Trade\SymbolInfo.mqh> // Standard library for symbol information #include <Expert\Money\MoneyFixedRisk.mqh> #include <Indicators\Oscilators.mqh> #include <Trade\PositionInfo.mqh> // Global Input Variables input int TEMA_Period = 9; // TEMA period input int VWAP_Period = 9; // VWAP bands period input int CCI_Period = 9; // CCI period // Global Indicator values double TEMA_Value; double VWAP_Value; double CCI_Value; // Global variables to store indicator handles int TEMA_Handle; int VWAP_Handle; int CCI_Handle; // Global variables to store indicator buffers double tema_buffer[], vwap_buffer[], cci_buffer[]; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { // Get TEMA Handle // TEMA_Handle = iTEMA(Symbol(),0,TEMA_Period,0,PRICE_CLOSE); TEMA_Handle = iCustom(NULL,0,"TEMA", TEMA_Period, // Period 0, // Offset MODE_SMA, // Calculation method PRICE_CLOSE // Calculating on Close prices ); if(TEMA_Handle == INVALID_HANDLE) { Print("Couldn't load the TEMA indicator."); return INIT_FAILED; } Print("TEMA_Handle ", TEMA_Handle, " loaded successfully."); // this is not necessary and may reduce the code speed in optimizations, but may help you debugging errors like this sometimes // Get VWAP Handle VWAP_Handle = iCustom(NULL,0,"vwap_bands", VWAP_Period, // Period PRICE_CLOSE, // Calculating on Close prices 0, // UseRealVolume 0, // DeviationSample 1.0, // DeviationMuliplier1 2.0, // DeviationMuliplier2 2.5 // DeviationMuliplier3 ); if(VWAP_Handle == INVALID_HANDLE) { Print("Couldn't load the VWAP indicator."); return INIT_FAILED; } Print("VWAP_Handle ", VWAP_Handle, " loaded successfully."); // this is not necessary and may reduce the code speed in optimizations, but may help you debugging errors like this sometimes // Get CCI Handle // CCI_Handle = iCCI(Symbol(),0,CCI_Period,PRICE_TYPICAL); CCI_Handle = iCustom(NULL,0,"CCI", CCI_Period, // Period PRICE_TYPICAL // Calculating on Typical prices ); if(CCI_Handle == INVALID_HANDLE) { Print("Couldn't load the CCI indicator."); return INIT_FAILED; } Print("CCI_Handle ", CCI_Handle, " loaded successfully."); // this is not necessary and may reduce the code speed in optimizations, but may help you debugging errors like this sometimes // Setting the indexing in arrays the same as in timeseries, i.e. array element with zero // index will store the values of the last bar, with 1th index - the last but one, etc. ArraySetAsSeries(tema_buffer, true); ArraySetAsSeries(vwap_buffer, true); ArraySetAsSeries(cci_buffer, true); UpdateIndicators(); //Update Indicators string debugComment = StringFormat("TEMA = %d, VWAP = %d, CCI = %d", TEMA_Value, VWAP_Value, CCI_Value); printf(debugComment); Comment(debugComment); return INIT_SUCCEEDED; } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { UpdateIndicators(); //Update Indicators string debugComment = StringFormat("TEMA = %.2f, VWAP = %.2f, CCI = %.2f", TEMA_Value, VWAP_Value, CCI_Value); // printf(debugComment); Comment(debugComment); } void UpdateIndicators() { // Using indicators handles, let's copy the values of indicator // buffers to arrays, specially prepared for this purpose if (CopyBuffer(TEMA_Handle,0,0,1,tema_buffer) < 0){Print("CopyBuffer TEMA error =",GetLastError());} if (CopyBuffer(VWAP_Handle,3,0,1,vwap_buffer) < 0){Print("CopyBuffer VWAP error =",GetLastError());} if (CopyBuffer(CCI_Handle,0,0,1,cci_buffer) < 0){Print("CopyBuffer CCI error =",GetLastError());} TEMA_Value = tema_buffer[0]; VWAP_Value = vwap_buffer[0]; CCI_Value = cci_buffer[0]; }
Here is the code for vwap_bands:
//------------------------------------------------------------------ #property copyright "© mladen, 2016, MetaQuotes Software Corp." #property link "www.forex-tsd.com, www.mql5.com" #property version "1.00" //------------------------------------------------------------------ #property indicator_chart_window #property indicator_buffers 8 #property indicator_plots 7 #property indicator_type1 DRAW_LINE #property indicator_color1 clrLimeGreen #property indicator_width1 2 #property indicator_type2 DRAW_LINE #property indicator_color2 clrLimeGreen #property indicator_type3 DRAW_LINE #property indicator_color3 clrLimeGreen #property indicator_style3 STYLE_DOT #property indicator_type4 DRAW_LINE #property indicator_color4 clrSilver #property indicator_style4 STYLE_DOT #property indicator_type5 DRAW_LINE #property indicator_color5 clrSandyBrown #property indicator_style5 STYLE_DOT #property indicator_type6 DRAW_LINE #property indicator_color6 clrSandyBrown #property indicator_type7 DRAW_LINE #property indicator_color7 clrSandyBrown #property indicator_width7 2 // // // // // enum enPrices { pr_close, // Close pr_open, // Open pr_high, // High pr_low, // Low pr_median, // Median pr_typical, // Typical pr_weighted, // Weighted pr_average, // Average (high+low+open+close)/4 pr_medianb, // Average median body (open+close)/2 pr_tbiased, // Trend biased price pr_tbiased2, // Trend biased (extreme) price pr_haclose, // Heiken ashi close pr_haopen , // Heiken ashi open pr_hahigh, // Heiken ashi high pr_halow, // Heiken ashi low pr_hamedian, // Heiken ashi median pr_hatypical, // Heiken ashi typical pr_haweighted, // Heiken ashi weighted pr_haaverage, // Heiken ashi average pr_hamedianb, // Heiken ashi median body pr_hatbiased, // Heiken ashi trend biased price pr_hatbiased2 // Heiken ashi trend biased (extreme) price }; input int AvgPeriod = 20; // Volume weighted average period input enPrices Price = pr_close; // Price input bool UseRealVolume = false; // Use real volume? input bool DeviationSample = false; // Deviation with sample correction? input double DeviationMuliplier1 = 1; // First band(s) deviation input double DeviationMuliplier2 = 2; // Second band(s) deviation input double DeviationMuliplier3 = 2.5; // Third band(s) deviation double bandm[],bandu1[],bandu2[],bandu3[],bandd1[],bandd2[],bandd3[],prices[]; //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // void OnInit() { SetIndexBuffer(0,bandu3 ,INDICATOR_DATA); SetIndexBuffer(1,bandu2 ,INDICATOR_DATA); SetIndexBuffer(2,bandu1 ,INDICATOR_DATA); SetIndexBuffer(3,bandm ,INDICATOR_DATA); SetIndexBuffer(4,bandd1 ,INDICATOR_DATA); SetIndexBuffer(5,bandd2 ,INDICATOR_DATA); SetIndexBuffer(6,bandd3 ,INDICATOR_DATA); SetIndexBuffer(7,prices ,INDICATOR_CALCULATIONS); IndicatorSetString(INDICATOR_SHORTNAME,"VWAP bands ("+(string)AvgPeriod+")"); } //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // 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& real_volume[], const int& spread[]) { if (Bars(_Symbol,_Period)<rates_total) return(-1); // // // // // int i=(int)MathMax(prev_calculated-1,0); for (; i<rates_total && !_StopFlag; i++) { prices[i] = getPrice(Price,open,close,high,low,i,rates_total); double sum1=0,sum2=0, deviation = iDeviation(prices[i],AvgPeriod,DeviationSample,i,rates_total); for (int k=0; k<AvgPeriod && (i-k)>=0; k++) { double volume = (UseRealVolume) ? (double)real_volume[i-k] : (double)tick_volume[i-k]; sum1 += volume*prices[i-k]; sum2 += volume; } bandm[i] = (sum2!=0) ? sum1/sum2 : prices[i]; //PrintFormat("bandm = %.2f", bandm[i]); bandu1[i] = (DeviationMuliplier1>0) ? bandm[i]+DeviationMuliplier1*deviation : EMPTY_VALUE; bandd1[i] = (DeviationMuliplier1>0) ? bandm[i]-DeviationMuliplier1*deviation : EMPTY_VALUE; bandu2[i] = (DeviationMuliplier2>0) ? bandm[i]+DeviationMuliplier2*deviation : EMPTY_VALUE; bandd2[i] = (DeviationMuliplier2>0) ? bandm[i]-DeviationMuliplier2*deviation : EMPTY_VALUE; bandu3[i] = (DeviationMuliplier3>0) ? bandm[i]+DeviationMuliplier3*deviation : EMPTY_VALUE; bandd3[i] = (DeviationMuliplier3>0) ? bandm[i]-DeviationMuliplier3*deviation : EMPTY_VALUE; } return(i); } //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // double workDev[]; double iDeviation(double value, int length, bool isSample, int i, int bars) { if (ArraySize(workDev)!=bars) ArrayResize(workDev,bars); workDev[i] = value; // // // // // double oldMean = value; double newMean = value; double squares = 0; int k; for (k=1; k<length && (i-k)>=0; k++) { newMean = (workDev[i-k]-oldMean)/(k+1)+oldMean; squares += (workDev[i-k]-oldMean)*(workDev[i-k]-newMean); oldMean = newMean; } return(MathSqrt(squares/MathMax(k-isSample,1))); } //------------------------------------------------------------------ // //------------------------------------------------------------------ // // // // // // #define _pricesInstances 1 #define _pricesSize 4 double workHa[][_pricesInstances*_pricesSize]; double getPrice(int tprice, const double& open[], const double& close[], const double& high[], const double& low[], int i,int _bars, int instanceNo=0) { if (tprice>=pr_haclose) { if (ArrayRange(workHa,0)!= _bars) ArrayResize(workHa,_bars); instanceNo*=_pricesSize; // // // // // double haOpen; if (i>0) haOpen = (workHa[i-1][instanceNo+2] + workHa[i-1][instanceNo+3])/2.0; else haOpen = (open[i]+close[i])/2; double haClose = (open[i] + high[i] + low[i] + close[i]) / 4.0; double haHigh = MathMax(high[i], MathMax(haOpen,haClose)); double haLow = MathMin(low[i] , MathMin(haOpen,haClose)); if(haOpen <haClose) { workHa[i][instanceNo+0] = haLow; workHa[i][instanceNo+1] = haHigh; } else { workHa[i][instanceNo+0] = haHigh; workHa[i][instanceNo+1] = haLow; } workHa[i][instanceNo+2] = haOpen; workHa[i][instanceNo+3] = haClose; // // // // // switch (tprice) { case pr_haclose: return(haClose); case pr_haopen: return(haOpen); case pr_hahigh: return(haHigh); case pr_halow: return(haLow); case pr_hamedian: return((haHigh+haLow)/2.0); case pr_hamedianb: return((haOpen+haClose)/2.0); case pr_hatypical: return((haHigh+haLow+haClose)/3.0); case pr_haweighted: return((haHigh+haLow+haClose+haClose)/4.0); case pr_haaverage: return((haHigh+haLow+haClose+haOpen)/4.0); case pr_hatbiased: if (haClose>haOpen) return((haHigh+haClose)/2.0); else return((haLow+haClose)/2.0); case pr_hatbiased2: if (haClose>haOpen) return(haHigh); if (haClose<haOpen) return(haLow); return(haClose); } } // // // // // switch (tprice) { case pr_close: return(close[i]); case pr_open: return(open[i]); case pr_high: return(high[i]); case pr_low: return(low[i]); case pr_median: return((high[i]+low[i])/2.0); case pr_medianb: return((open[i]+close[i])/2.0); case pr_typical: return((high[i]+low[i]+close[i])/3.0); case pr_weighted: return((high[i]+low[i]+close[i]+close[i])/4.0); case pr_average: return((high[i]+low[i]+close[i]+open[i])/4.0); case pr_tbiased: if (close[i]>open[i]) return((high[i]+close[i])/2.0); else return((low[i]+close[i])/2.0); case pr_tbiased2: if (close[i]>open[i]) return(high[i]); if (close[i]<open[i]) return(low[i]); return(close[i]); } return(0); }
I tried putting in some trace to see what values for bandm were being saved:
bandm[i] = (sum2!=0) ? sum1/sum2 : prices[i]; PrintFormat("bandm = %.2f", bandm[i]);
The values were all over the place, from the vicinity of the value the charts shows, down to near 1.
Can you elaborate a little bit more on what do you mean by lagging? I mean, I tested the code (with the built-in CCI and TEMA) and there's no lagging here:
The values from the last bar are being correctly passed to the comment on the top of the chart.
ps: if you want to show more decimal places, change the %.2f in the StringFormat to any number of decimal places you want.
Can you elaborate a little bit more on what do you mean by lagging? I mean, I tested the code (with the built-in CCI and TEMA) and there's no lagging here:
The values from the last bar are being correctly passed to the comment on the top of the chart.
ps: if you want to show more decimal places, change the %.2f in the StringFormat to any number of decimal places you want.
Hi Emanuel. Thanks for your help again.
Well, this is odd. I just rebooted and, yes, now when I look it appears the values do seem to match.
I wasn't too worried about the decimal places because it's just for debugging. Thanks for setting straight on how to handle those values in StringFormat.
Thanks for responding.
Now the values are different again. It's for all three indicators, not just vwap_hands.
I am developing on Linux using Wine. I wonder if that could be producing issues. I have also found other issues. When I place a trade I display the trade parameters in the Experts log, including stop loss and take profit. I found that when I updated SL and TP in the code, they did not show as changed in the trace for some time.
I recently acquired a Windows laptop. I will move to there for development and see if that fixes things. I have a Windows VPS I can put it on eventually.
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Hi all.
I just got my first EA up and running and I am finding that the indicator values lag about 5 minutes behind the values displayed on the chart.
I see a bit of chatter about this. Is this a common thing?
I saw one post that suggested coding a custom indicator. I managed to find the code for one of the indicators I am using and I compiled it and replaced the original copy. That made no difference.
I have managed to find code for the other indicators. Do I need to go as far as implement the indicators within the EA?
How do people deal with this?