Is CopySpread() function working?

 

I can't make CopySpread work. It returns array of zeroes. Tried with 4 and 5 digits brokers, EURUSD, GOLD and Dow Jones index.

Code I used is for testing is copied example from CopySpread() documentation page:

#property indicator_separate_window
#property indicator_buffers 1
//---- plot Spread
#property indicator_label1  "Spread"
#property indicator_type1   DRAW_HISTOGRAM
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- input parameters
input int      bars=3000;
//--- indicator buffers
double         SpreadBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,SpreadBuffer,INDICATOR_DATA);
   IndicatorSetInteger(INDICATOR_DIGITS,0);
//---
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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(prev_calculated==0)
     {
      int spread_int[];
      ArraySetAsSeries(spread_int,true);
      int spreads=CopySpread(Symbol(),0,0,bars,spread_int);
      Print("We have received the following number of Spread values: ",spreads);
      for (int i=0;i<spreads;i++) 
      {
      SpreadBuffer[rates_total-1-i]=spread_int[i];
      if(i<=30) Print("spread["+i+"] = ",spread_int[i]);
      }
     }
   else
     {
      double Ask,Bid;
      Ask=SymbolInfoDouble(Symbol(),SYMBOL_ASK);
      Bid=SymbolInfoDouble(Symbol(),SYMBOL_BID);
      Comment("Ask = ",Ask,"  Bid = ",Bid);
      SpreadBuffer[rates_total-1]=(Ask-Bid)/Point();
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
 

drazen64:

Is CopySpread() function working?


i think it's not been implemented
 

I just tested CopyTickVolume() function - it has very similar indicator example.

On two brokers it works on M30 and bigger timeframes, on M1, M5 and M15 it returns zeros. 

Could that be some problem with history files or it is implementation problem? 

 

go to history center ("F2") check if M1, M5 and M15 (symbol() you tested) has volume,

if the answer in no: update history and test again

if the answer is yes: report to ServiceDesk (See the article MQL5.community - User Memo => 5. Service Desk)

 

Found it.

There is a bug in the CopyTickVolume() sample code. Volumes are written to the wrong side of the indicator buffer. Default was 3000 bars, so for smaller time frames, volumes were drawn far to the left (wrong bar and reversed order).

Mixup was with array indexing. Here is fixed code (changes are in yellow): 

   if(prev_calculated==0)
     {
      long timeseries[];
      ArraySetAsSeries(timeseries,true);
      int prices=CopyTickVolume(Symbol(),0,0,bars,timeseries);
      for(int i=0;i<rates_total-prices;i++) TickVolumeBuffer[i]=0.0; 
      for(int i=0;i<prices;i++) TickVolumeBuffer[i]=timeseries[i];
      Print("We have received the following number of TickVolume values: "+prices);
     }
   else
     {
      long timeseries[];
      int prices=CopyTickVolume(Symbol(),0,0,1,timeseries);
      TickVolumeBuffer[0]=timeseries[0]; 
     }  


 I reported this to ServiceDesk.

 
drazen64:

I can't make CopySpread work. It returns array of zeroes. Tried with 4 and 5 digits brokers, EURUSD, GOLD and Dow Jones index.

Code I used is for testing is copied example from CopySpread() documentation page:


There are two factors involved here:

1. The CopySread() example contains similar errors to the CopyTickVolume() sample errors you pointed out.

2. MT4 history data (hst files) post build 600 contain provision for spread and trade volume in the MqlRates struct that is used when writing the files but neither value is being instantiated.
    If an hst file is created with the spread value included, then CopySpread() does work.

1. CopySread() Example Corrections

if(prev_calculated==0)
  {
  int spread_int[];
  ArraySetAsSeries(spread_int,true);
  int spreads=CopySpread(Symbol(),0,0,bars,spread_int);
  Print("We have received the following number of Spread values: ",spreads);
  for (int i=0;i<spreads;i++)
  {
  //SpreadBuffer[rates_total-1-i]=spread_int[i];
    SpreadBuffer[i]=spread_int[i]; // Corrected line replacing the above
    if(i<=30) Print("spread["+i+"] = ",spread_int[i]);
  }
}
else
{
  double Ask,Bid;
  Ask=SymbolInfoDouble(Symbol(),SYMBOL_ASK);
  Bid=SymbolInfoDouble(Symbol(),SYMBOL_BID);
  Comment("Ask = ",Ask,"  Bid = ",Bid);
//SpreadBuffer[rates_total-1]=(Ask-Bid)/Point();
  SpreadBuffer[0]=(Ask-Bid)/Point(); // Corrected line replacing the above
}

If you run with this, spread values appear for new ticks/bars, but not history bars because of issue 2.

The example could be improved a bit further by fetching spread directly in the current block rather than by subtracting Bid from Ask, since SymbolInfoInteger(Symbol(),SYMBOL_SPREAD) does work, as follows:

  //double Ask,Bid;
  //Ask=SymbolInfoDouble(Symbol(),SYMBOL_ASK);
  //Bid=SymbolInfoDouble(Symbol(),SYMBOL_BID);
  //Comment("Ask = ",Ask,"  Bid = ",Bid);
  //SpreadBuffer[rates_total-1]=(Ask-Bid)/Point();
  //SpreadBuffer[0]=(Ask-Bid)/Point();
  int spreadNow = SymbolInfoInteger(Symbol(),SYMBOL_SPREAD); // /- replaces all of the above
  Comment("Spread = ",spreadNow);                            // |
  SpreadBuffer[0] = (double)spreadNow;                       // |


I will report the above to the Service Desk. It is poor that MetaQuotes did not correct this example as well as the CopyTickVolume() one after you reported the similar faults with that.

2. MT4 history data (hst files) Issue
MT4 history (hst) files post Build 600 use the MqlRates struct to record bar data:

struct MqlRates
  {
   datetime time;         // Period start time
   double   open;         // Open price
   double   high;         // The highest price of the period
   double   low;          // The lowest price of the period
   double   close;        // Close price
   long     tick_volume;  // Tick volume
   int      spread;       // Spread
   long     real_volume;  // Trade volume
  };
As you can see, this allows for spread and, interestingly, trade volume. However, neither of these fields are instantiated (filled in) by MT4.

The period converter script supplied with MT4 (MQL4\Scripts\PeriodConverter.mq4) just sets them to 0, and it appears that MT4 internally does the same.

However, if an hst file is created that does instantiate the spread values for each bar, which I do when preparing offline hst files for use with a better way of back testing with tick data that I am working on, then CopySpread() does work, and the CopySpread() example, as corrected, does work for historical bars as well as new ones.
 

The problem with example code is due to "copy" from mql5 documentation.

But with mql5, indicator's buffer are NOT indexed as series by default. So for the example to work with mql4 you have to add the following line after SetIndexBuffer line :

ArraySetAsSeries(TickVolumeBuffer,false);   

or

ArraySetAsSeries(SpreadBuffer,false);
Reason: