Any ideas why my custom indicators are blank when I start the terminal in the morning? - page 3

 
KeyserSoze42 #:

I suspect the problem to be related to how CIndicator handles missing data from its buffer. refer to the source code on Indicator.mqh for the next statements. the Refresh function does not return any value, and ignores the value returned by its buffer. when the buffer refreshes, it runs CopyBuffer. when the returned value is < 0, CIndicator does nothing with that information. supposing that is the failure, I cannot see how that would lead to the indicator deleting the data that already populated the custom indicator buffer, and not thrown any exception/error. I expected for previous buffer content to remain, thus leaving the indicator simply not updating, but still shown on screen.

That sounds an awful lot like the end product of iMA() or iCustom() (Commented out in my code template, above).

if(CopyBuffer(handle_indicator, 0, 0, copyBars, buff_indicator) <= 0)
     return(0);

Theoretically, your fix should work.

 

@MetaQuotes, @MetaQuotes Support, when calling a CIndicator object's Refresh function, it is recorded the error CUSTOM_WRONG_PROPERTY(4603) (information retrieved inspecting _LastError value's). after that, the indicator lines vanish, leaving only the indicator's empty separate window.

is that expected?

 
KeyserSoze42 #:

@MetaQuotes, @MetaQuotes Support, when calling a CIndicator object's Refresh function, it is recorded the error CUSTOM_WRONG_PROPERTY(4603) (information retrieved inspecting _LastError value's). after that, the indicator lines vanish, leaving only the indicator's empty separate window.

is that expected?

Please post the full code to reproduce it.
 
Ryan L Johnson #:

That sounds an awful lot like the end product of iMA() or iCustom() (Commented out in my code template, above).

Theoretically, your fix should work.

Correction: For more granular control/testing of CIndicator, the result of GetData should be checked.

Admittedly, this reduces the "simplicity" of using CIndicator.

Documentation on MQL5: GetData / Standard Library
Documentation on MQL5: GetData / Standard Library
  • www.mql5.com
Gets the specified element of the specified buffer of the indicator. Refresh() should be called for working with recent data before using the...
 
Alain Verleyen #:
Please post the full code to reproduce it.
https://www.mql5.com/en/forum/469734/page2#comment_59275814
I am friendly with me, but I s not a bad guy; This is like calling a car repair shop and asking for help.
I am friendly with me, but I s not a bad guy; This is like calling a car repair shop and asking for help.
  • 2024.07.09
  • www.mql5.com
What you re doing is like calling a car repair shop and asking any idea why my car stopped working. A mechanic that showed the kind of attitudes that are the norm for some people on this forum would promptly see my backside, and that d see of me. There ve been friendly, and thank you
 
This code doesn't compile.
 
Alain Verleyen #:
This code doesn't compile.

this one does

#include <MovingAverages.mqh>
#include <Indicators\Trend.mqh>
#define LOG_MESSAGE(text) PrintFormat("%s | @%s #%d -> %s", __FILE__, __FUNCTION__, __LINE__, text)
//#define E2S(X) EnumToString(X) + "(" + IntegerToString(X) + ")"

#property indicator_separate_window
#property indicator_buffers 3
#property indicator_plots   2
#property indicator_type1   DRAW_COLOR_HISTOGRAM
#property indicator_type2   DRAW_LINE
#property indicator_color1  clrDarkSeaGreen, clrGreen, clrTomato, clrRed
#property indicator_color2  clrLime
#property indicator_width1  2
#property indicator_width2  3
#property indicator_label1  "MACD Histogram"
#property indicator_label2  "Signal"

input(name = "Fast EMA period") int FastEMAPeriod = 12;
input(name = "Slow EMA period") int SlowEMAPeriod = 26;
input(name = "Signal SMA period") int SignalSMAPeriod = 9;
input(name = "Applied price") ENUM_APPLIED_PRICE AppliedPriceType = PRICE_CLOSE;

double HistogramBuffer[];
double HistogramColourBuffer[];
double SignalBuffer[];

CiMA FastMAIndicator;
CiMA SlowMAIndicator;

void OnInit() {
   SetIndexBuffer(0, HistogramBuffer, INDICATOR_DATA);
   SetIndexBuffer(1, HistogramColourBuffer, INDICATOR_COLOR_INDEX);
   SetIndexBuffer(2, SignalBuffer, INDICATOR_DATA);

   PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, fmax(FastEMAPeriod, SlowEMAPeriod)-1);
   PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, SignalSMAPeriod-1);
   string short_name = StringFormat("MACD(%d,%d,%d)", FastEMAPeriod, SlowEMAPeriod, SignalSMAPeriod);
   IndicatorSetString(INDICATOR_SHORTNAME, short_name);
   FastMAIndicator.Create(NULL, 0, FastEMAPeriod, 0, MODE_EMA, AppliedPriceType);
   SlowMAIndicator.Create(NULL, 0, SlowEMAPeriod, 0, MODE_EMA, AppliedPriceType);
   Print("MACD started");
}

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[]) {
   if(rates_total < SignalSMAPeriod) {
      LOG_MESSAGE("rates_total < SignalSMAPeriod");
      return(0);
   }
   if(FastMAIndicator.BarsCalculated() < rates_total || SlowMAIndicator.BarsCalculated() < rates_total) {
      LOG_MESSAGE("Not all data for MACD indicator is calculated yet (" + fmin(FastMAIndicator.BarsCalculated(), SlowMAIndicator.BarsCalculated()) + " bars). Error " + GetLastError());
      return(0);
   }
   for(int i = fmax(fmax(FastEMAPeriod, SlowEMAPeriod), prev_calculated - 1), j = rates_total - i - 1; i < rates_total && !IsStopped(); i++, j--) {
      HistogramBuffer[i] = FastMAIndicator.Main(j) - SlowMAIndicator.Main(j);
      HistogramColourBuffer[i] = HistogramBuffer[i] > 0 ? 1 : 3;
      HistogramColourBuffer[i] = MathAbs(HistogramBuffer[i]) < MathAbs(HistogramBuffer[i - 1])
                                 ? HistogramColourBuffer[i] - 1
                                 : HistogramColourBuffer[i];
   }
   SimpleMAOnBuffer(rates_total, prev_calculated, 0, SignalSMAPeriod, HistogramBuffer, SignalBuffer);
   return(rates_total);
  }
 
KeyserSoze42 #:

this one does

Your code is buggy. You don't use the class CiMA correctly. Where is the Refresh() ?

Also your indexing is incorrect.

Take a look at this article for example : https://www.mql5.com/en/articles/19341

The MQL5 Standard Library Explorer (Part 1): Introduction with CTrade, CiMA, and CiATR
The MQL5 Standard Library Explorer (Part 1): Introduction with CTrade, CiMA, and CiATR
  • 2025.09.24
  • www.mql5.com
The MQL5 Standard Library plays a vital role in developing trading algorithms for MetaTrader 5. In this discussion series, our goal is to master its application to simplify the creation of efficient trading tools for MetaTrader 5. These tools include custom Expert Advisors, indicators, and other utilities. We begin today by developing a trend-following Expert Advisor using the CTrade, CiMA, and CiATR classes. This is an especially important topic for everyone—whether you are a beginner or an experienced developer. Join this discussion to discover more.
 
Alain Verleyen #:

Your code is buggy. You don't use the class CiMA correctly. Where is the Refresh() ?

Also your indexing is incorrect.

Take a look at this article for example : https://www.mql5.com/en/articles/19341

that was provided separately, on a next message. the complete indicator, with the refreshing:

#include <MovingAverages.mqh>
#include <Indicators\Trend.mqh>
#define LOG_MESSAGE(text) PrintFormat("%s | @%s #%d -> %s", __FILE__, __FUNCTION__, __LINE__, text)
//#define E2S(X) EnumToString(X) + "(" + IntegerToString(X) + ")"

#property indicator_separate_window
#property indicator_buffers 3
#property indicator_plots   2
#property indicator_type1   DRAW_COLOR_HISTOGRAM
#property indicator_type2   DRAW_LINE
#property indicator_color1  clrDarkSeaGreen, clrGreen, clrTomato, clrRed
#property indicator_color2  clrLime
#property indicator_width1  2
#property indicator_width2  3
#property indicator_label1  "MACD Histogram"
#property indicator_label2  "Signal"

input(name = "Fast EMA period") int FastEMAPeriod = 12;
input(name = "Slow EMA period") int SlowEMAPeriod = 26;
input(name = "Signal SMA period") int SignalSMAPeriod = 9;
input(name = "Applied price") ENUM_APPLIED_PRICE AppliedPriceType = PRICE_CLOSE;

double HistogramBuffer[];
double HistogramColourBuffer[];
double SignalBuffer[];

CiMA FastMAIndicator;
CiMA SlowMAIndicator;

void OnInit() {
   SetIndexBuffer(0, HistogramBuffer, INDICATOR_DATA);
   SetIndexBuffer(1, HistogramColourBuffer, INDICATOR_COLOR_INDEX);
   SetIndexBuffer(2, SignalBuffer, INDICATOR_DATA);

   PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, fmax(FastEMAPeriod, SlowEMAPeriod)-1);
   PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, SignalSMAPeriod-1);
   string short_name = StringFormat("MACD(%d,%d,%d)", FastEMAPeriod, SlowEMAPeriod, SignalSMAPeriod);
   IndicatorSetString(INDICATOR_SHORTNAME, short_name);
   FastMAIndicator.Create(NULL, 0, FastEMAPeriod, 0, MODE_EMA, AppliedPriceType);
   SlowMAIndicator.Create(NULL, 0, SlowEMAPeriod, 0, MODE_EMA, AppliedPriceType);
   Print("MACD started");
}

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[]) {
   if(rates_total < SignalSMAPeriod) {
      LOG_MESSAGE("rates_total < SignalSMAPeriod");
      return(0);
   }
   ResetLastError();
   FastMAIndicator.Refresh();
   int errorSnapshot = _LastError;
   if(errorSnapshot > 0) {
      LOG_MESSAGE(errorSnapshot);
      ResetLastError();
      return(0);
   }
   SlowMAIndicator.Refresh();
   errorSnapshot = _LastError;
   if(errorSnapshot > 0) {
      LOG_MESSAGE(errorSnapshot);
      ResetLastError();
      return(0);
   }

   if(FastMAIndicator.BarsCalculated() < rates_total || SlowMAIndicator.BarsCalculated() < rates_total) {
      LOG_MESSAGE("Not all data for MACD indicator is calculated yet (" + fmin(FastMAIndicator.BarsCalculated(), SlowMAIndicator.BarsCalculated()) + " bars). Error " + GetLastError());
      return(0);
   }
   for(int i = fmax(fmax(FastEMAPeriod, SlowEMAPeriod), prev_calculated - 1), j = rates_total - i - 1; i < rates_total && !IsStopped(); i++, j--) {
      HistogramBuffer[i] = FastMAIndicator.Main(j) - SlowMAIndicator.Main(j);
      HistogramColourBuffer[i] = HistogramBuffer[i] > 0 ? 1 : 3;
      HistogramColourBuffer[i] = MathAbs(HistogramBuffer[i]) < MathAbs(HistogramBuffer[i - 1])
                                 ? HistogramColourBuffer[i] - 1
                                 : HistogramColourBuffer[i];
   }
   SimpleMAOnBuffer(rates_total, prev_calculated, 0, SignalSMAPeriod, HistogramBuffer, SignalBuffer);
   return(rates_total);
  }



regardless, that omission would not cause the problem reported. with or without refreshing the indicators, the reported problem persists.

unfortunately, it is an intermittent problem. I could not find a method to deliberately trigger the failure witnessed. the indicator must be left running.

 
KeyserSoze42 #:
that was provided separately, on a next message.

Yeah, in your Post #20 to be precise.

Forum on trading, automated trading systems and testing trading strategies

Any ideas why my custom indicators are blank when I start the terminal in the morning?

KeyserSoze42, 2026.02.28 01:45

the fragment above does not work as intended. I replaced it by

   ResetLastError();
   FastMAIndicator.Refresh();
   int errorSnapshot = _LastError;
   if(errorSnapshot > 0) {
      LOG_MESSAGE(E2S(errorSnapshot));
      ResetLastError();
      return(0);
   }
   SlowMAIndicator.Refresh();
   errorSnapshot = _LastError;
   if(errorSnapshot > 0) {
      LOG_MESSAGE(E2S(errorSnapshot));
      ResetLastError();
      return(0);
   }
upon restarting that indicator, the error CUSTOM_WRONG_PROPERTY(4603) briefly appeared, but I could not identify where exactly (before of after indicator refresh, which one?). and now, it does not appear anymore. however, the indicator remained drawn.

Forum on trading, automated trading systems and testing trading strategies

Any ideas why my custom indicators are blank when I start the terminal in the morning?

Ryan L Johnson, 2026.02.28 14:18

Correction: For more granular control/testing of CIndicator, the result of GetData should be checked.

Admittedly, this reduces the "simplicity" of using CIndicator.