DBL_MAX values when copying close prices from another symbol into buffer

 

Hey guys,

I've got a question regarding CopyClose where I copy close prices from a VIX symbol (e.g. UsaVixMar25) into the current chart (e.g. Usa500).

Here's my customized ComputeBuffers method:

int CVix::ComputeBuffers(const int rates_total, const int prev_calculated, const datetime &time[],
                                                                                  const double &open[], const double &high[], const double &low[], const double &close[])
{
        if (rates_total < MAPeriodInDays) // e.g. MAPeriodInDays is 100
                return 0; // wait until rates_total is big enough to provide enough rates required for the MA

        int numberOfElementsToCopy = rates_total;
        
        if (prev_calculated > 0)
        {
                numberOfElementsToCopy = rates_total - prev_calculated; 
                //--- last value is always copied
                numberOfElementsToCopy++; 
        }

        ArraySetAsSeries(time, true);
        PrintFormat("Trying to copy %d close prices from %s to now...", numberOfElementsToCopy, TimeToString(time[numberOfElementsToCopy-1]));
        // --- this outputs: 
        // 2025.03.01 15:25:58.992      VIX (Usa500,H4) Trying to copy 12214 close prices from 2017.04.03 00:00 to now...
        // which is true (for prev_calculated being 0), since Usa500 symbol starts at 2017.04.03

        // Copying close price from VIX symbol 'UsaVixMar25', m_period is H4:
        if (CopyClose(m_VixChartSymbol, m_period, 0, numberOfElementsToCopy, m_VixBuffer) < 0) {
                Print("Failed to copy close prices into VIX buffer. Error = ", GetLastError());
                return 0;
        }

        // if I'm not doing the following, the chart will not plot my VIX indicator in the subwindow due to infinite values:
        int bufferSize = ArraySize(m_VixBuffer);

        for (int b=0; b < bufferSize; b++)
        {
                if (m_VixBuffer[b] == DBL_MAX)
                        m_VixBuffer[b] = 0;
        }

        // doing fancy calculations, but I commented out all of this to only focus on the problem above
        //SmoothedMAOnBuffer(rates_total, prev_calculated, 1, m_Actual_MA_period, m_VixBuffer, m_MA_values);
        
        return rates_total;
}

The chart with the VIX sub window looks as follows:



There are no VIX values from 2017.04.03 to 2018.03.07 due to these values being DBL_MAX (I could show you a screenshot of the m_VixBuffer, but I hope you can believe me without showing it).

And now - to my surprise - in the D1 chart that the entire subwindow of the VIX indicator is filled with VIX values.


I can rule out that the issue comes from toggling between the periods. Loading the VIX indicator in a fresh new H4 chart leads to the same issue, as shown above.

Can anyone enlighten me why the CopyClose function does not go back the entire history of the "parent symbol" when loading another symbol and BOTH have enough history available?

What pitfalls should i look for or is the CopyClose function itself not very reliable when it comes to copying data from another symbol?

 

well what way are you using  m_VixBuffer ?

If you set time to series, then you should set m_VixBuffer to series as well if you want the correct time to sync with the same indexes

You don't say much about why you're doing this:

 for (int b=0; b < bufferSize; b++)
 {
     if (m_VixBuffer[b] == DBL_MAX)
        m_VixBuffer[b] = 0;
 }

it looks like this shouldn't be necessary. Give more info about why you feel you have to do this. Buffers should normally be set to EMPTY_VALUE at the points where data shouldn't be plotted

 

Yep, I'm doing that for the vix buffer.

bool CVix::InitBuffers(void)
{
        // Indicator buffers mapping
        SetIndexBuffer(0, m_VixBuffer, INDICATOR_DATA);
        SetIndexBuffer(1, m_VixColorBuffer, INDICATOR_COLOR_INDEX);
        
        ArraySetAsSeries(m_VixBuffer, true);
        ArraySetAsSeries(m_VixColorBuffer, true);
        
        PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, 0);
        PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, 0);
        
        PlotIndexSetInteger(0, PLOT_COLOR_INDEXES, 3);
        PlotIndexSetInteger(0, PLOT_LINE_COLOR, 0, clrAqua);
        PlotIndexSetInteger(0, PLOT_LINE_COLOR, 1, clrOrange);
        PlotIndexSetInteger(0, PLOT_LINE_COLOR, 2, clrBrown);
        
        PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0.0);
        PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, 0.0);

        IndicatorSetInteger(INDICATOR_DIGITS, 2); // is there a way to obtain digits from another symbol?

        PlotIndexSetString(0, PLOT_LABEL, m_VixChartSymbol);
        
        return true;
}

I figured out that the VIX (for the S&P500) symbol has slightly different bars than the Usa500 / S&P500 itself! You can see that in my second screenshot where the red bars in my VIX history are misaligned.

I rewrote the code to ensure that for each bar the correct VIX close price is fetched:

int CVix::ComputeBuffers(const int rates_total, const int prev_calculated, const datetime &time[],
                                                                                  const double &open[], const double &high[], const double &low[], const double &close[])
{
        int numberOfElementsToCopy = rates_total;
        if (prev_calculated > 0)
        {
                numberOfElementsToCopy = rates_total - prev_calculated; 
                //--- last value is always copied
                numberOfElementsToCopy++; 
        }

        ArraySetAsSeries(time, true);
        
        PrintFormat("Trying to copy %d close prices from %s to now...", numberOfElementsToCopy, TimeToString(time[numberOfElementsToCopy-1]));
        
        CopyPastVixBars(rates_total, prev_calculated, time);

        if (LogInfo) PrintFormat("[" + __FUNCTION__ + "] Computing VIX data on %s - actual period: %d", EnumToString(_Period), m_Actual_MA_period);

        /* indeed no longer necessary:
        int bufferSize = ArraySize(m_VixBuffer);

        for (int b=0; b < bufferSize; b++)
        {
                if (m_VixBuffer[b] == DBL_MAX)
                        m_VixBuffer[b] = 0;
        }
        //*/

        // doing fancy calculations...
        //SmoothedMAOnBuffer(rates_total, prev_calculated, 1, m_Actual_MA_period, m_VixBuffer, m_MA_values);
        
        return rates_total;
}

// Copying VIX close prices one by one is VITAL as CopyClose(...) does not work since bars in both symbols may differ on the time axis!
void CVix::CopyPastVixBars(int rates_total, int prev_calculated, const datetime &time[])
{
        int toCopy = rates_total-1;
 
        if (prev_calculated > 0) // only one new bar has appeared (rates_total-1 is prev_calculated)
        {
                toCopy = rates_total - prev_calculated + 1; // last value is always copied
                //PrintFormat("%sCopying %d element(s) from vixBuffer", LogPrefix, toCopy);
        }
        
        bool copySuccess = true;
        
        for (int i=0; i < toCopy && !IsStopped(); i++)
        {
                copySuccess = GetVixValuesAndCopyToBuffer(i, time[i]);
                if (!copySuccess)
                continue;
        }
        
        if (!copySuccess)
                Print("Error(s) during copying close value(s). Probably due to non-existing dates in '", m_VixChartSymbol, "' chart.");
        }
 
bool CVix::GetVixValuesAndCopyToBuffer(const int index, const datetime time)
{
        double temp[1];
        
        if (CopyClose(m_VixChartSymbol, m_period, time, 1, temp) < 0)
                return false;
        
        m_VixBuffer[index] = temp[0];
        
        return true;
}

So, in conclusion:

Using the CopyClose iterating from first to last bar of the Usa500 symbol to simply copy the entire series of close prices of the VIX did not work - due to misaligned bars. 

Maybe that was also the reason for the indicator to not showing the first X many bars in the subwindow of my VIX indicator.

With the rewritten code, the issue has been resolved and the close prices are now properly transferred throughout the entire history of the VIX.

---

Issue is resolved.

 
Marcel Fitzner #:

Yep, I'm doing that for the vix buffer.

I figured out that the VIX (for the S&P500) symbol has slightly different bars than the Usa500 / S&P500 itself! You can see that in my second screenshot where the red bars in my VIX history are misaligned.

I rewrote the code to ensure that for each bar the correct VIX close price is fetched:

So, in conclusion:

Using the CopyClose iterating from first to last bar of the Usa500 symbol to simply copy the entire series of close prices of the VIX did not work - due to misaligned bars. 

Maybe that was also the reason for the indicator to not showing the first X many bars in the subwindow of my VIX indicator.

With the rewritten code, the issue has been resolved and the close prices are now properly transferred throughout the entire history of the VIX.

---

Issue is resolved.

CopyXXX functions can return outdated values, you always need to check if the data series are synchronized before using CopyXXX functions.

SeriesInfoInteger(symbol,tf,SERIES_SYNCHRONIZED)

Your solution using time and copying 1 value at a time can still fail and is a lot slower.

 
Thanks for that valuable feedback, Alain! :)