Questions from Beginners MQL5 MT5 MetaTrader 5 - page 553

 
Vitalii Ananev:

Instead of Close[2] put the indicator value on the second bar (for example iRSI(.......,2) ) and instead of Close[1] put the indicator value on the first bar. And uroven is the value of the level.

And the rest you have already been told above.

Thank you.
 
Can you tell me if anyone has seen a side volume of the day on the right side of the chart for mt5, for mt4 I found it here https://www.mql5.com/ru/code/9777. I've got two variants: either rewrite the variables in it or find a ready-made one. Or I don't see the point in ordering,,,,,,, , I need to check one equilibrium theory ,,,,. I found a work for mt5 where the profile of yesterday's day is drawn on the left but there's one important drawback, it does not draw what happens today. So I want to add to the chart pattern information from the right side what is happening at the moment of trading
Рыночный профиль ( Market Profile)
Рыночный профиль ( Market Profile)
  • votes: 6
  • 2006.10.11
  • Collector
  • www.mql5.com
Рыночный профиль ( Market Profile) использует альтернативное представление информации как о горизонтальном, так и о вертикальном движении рынка.
 
Maria Baburina:

Prerequisite:


ProfitSellDBL is calculated here

Profit_Upgr = 0.01

Tral_Start__Upgr is equated to an external variable of int type and equals to 5.

Tral_Size__Upgr is similarly equal to 4

TV - tick value, =10

SumLotSellDBL = 0.04

I have read it. Saw how it would work if Tral_Start__Upgr, Tral_Size__Upgr and their external variables were defined as double. I.e. when everything is of the same type without any conversion and data loss. The result is the same. What did I get wrong?
 
Maria Baburina:
Read. Saw how it would work if Tral_Start__Upgr, Tral_Size__Upgr and their external variables were defined as double. I.e. when everything is of the same type without any conversion and data loss. The result is the same. What did I get wrong?

A blind man talking to a deaf man. If you want someone to test it, you need the minimum possible code that can be compiled on another machine and tested. No code - nothing to talk about.

Added: Use debugging(Debugging):

-Preconfiguration

-Stoppoints

-Startdebugging

-Observableexpressions

-Call StackView

-Step-by-stepdebugging

-Stop, Resume and End Debugging

-Historydebugging

 

Forum on trading, automated trading systems and trading strategy testing

Bugs, bugs, questions

comp, 2016.04.03 18:21

Runtime error

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1

class CLASS
{
public:
  double Buffer[];
  
  CLASS( void )
  {
    SetIndexBuffer(0, this.Buffer);
  }
};

CLASS* Class;

void OnInit( void )
{
  Class = new CLASS;
    
  delete Class;

  Class = new CLASS;

  Class.Buffer[0] = 0; // array out of range
  
  delete Class;
  
  return;
}

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[] )
{  
  return(rates_total);
}

In four it worked fine! In five it's a bummer. Is this another architectural limitation compared to quad? Give me a link to a discussion on this, couldn't find it myself.


 
Do I understand correctly that you can only assign anything to the indicator buffers after the first call of the terminal itself (not manually) to OnCalculate?
 
comp:
Do I understand correctly, that something can be assigned to indicator buffers only after the first call of the terminal (not manually) OnCalculate?

Indicator buffers can be accessed after OnCalculate() has been called. At the same time, the indicator buffer itself should be declared in the global variables area:

//+------------------------------------------------------------------+
//|                                                  Accelerator.mq5 |
//|                        Copyright 2009, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright   "2009, MetaQuotes Software Corp."
#property link        "http://www.mql5.com"
#property description "Accelerator/Decelerator"

//---- indicator settings
#property indicator_separate_window
#property indicator_buffers 6
#property indicator_plots   1
#property  indicator_type1   DRAW_COLOR_HISTOGRAM
#property  indicator_color1  Green,Red
#property  indicator_width1  2
#property  indicator_label1  "AC"
//--- indicator buffers
double ExtACBuffer[];
double ExtColorBuffer[];
double ExtFastBuffer[];
double ExtSlowBuffer[];
double ExtAOBuffer[];
double ExtSMABuffer[];
//--- handles for MAs
int    ExtFastSMAHandle;
int    ExtSlowSMAHandle;
//--- bars minimum for calculation
#define  DATA_LIMIT 37
 

I think I found what I was looking for, but the antiquity of the code gives an error

Help me fix it ...... if it's not too much trouble.

and if you can help me turn it to the right side of the screen that would be great.

 
Karputov Vladimir:

The indicator buffers can be accessed after OnCalculate() has been called.

As it turns out, you are wrong. You can apply only when the terminal calls OnCalculate. In this case, the condition in MT4 is more flexible, because it's enough to call OnCalculate only once. But in MT5, you must wait for the call of OnCalculate by the terminal itself every time after the SetIndexBuffer. Proof

#property strict

#property indicator_chart_window
#property indicator_buffers 1

#ifdef __MQL5__
  #property indicator_plots 1
#endif   

#ifdef __MQL5__
  #define TRUE true
  #define FALSE false
#endif   

class CLASS
{
public:
  double Buffer[];
  
  CLASS( void )
  {
    ::SetIndexBuffer(0, this.Buffer);
  }

  #define  TIMESERIES(X)                                                  \
     ::ArraySetAsSeries(X, TRUE);                                        \
     Size = ::MathMin(Copy##X(::Symbol(), ::Period(), 0, bars, X), Size);  

  static int FullOnCalculate( void )
  {
    int Spread[];
    long RealVolume[];
    
    int Size = INT_MAX;
    
    #ifdef __MQL4__
      const int bars = ::Bars;
    #endif

    #ifdef __MQL5__
      const int bars = ::Bars(::Symbol(), ::Period());
    #endif

     TIMESERIES(Spread)
    TIMESERIES(RealVolume)
    
    #ifdef __MQL4__
      return(::OnCalculate(Size, 0, Time, Open, High, Low, Close, RealVolume, Volume, Spread));
    #endif

    #ifdef __MQL5__
      datetime Time[];
      double Open[];
      double High[];
      double Low[];
      double Close[];
      long TickVolume[];
  
      TIMESERIES(Time)
      TIMESERIES(Open)
      TIMESERIES(High)
      TIMESERIES(Low)
      TIMESERIES(Close)
      TIMESERIES(TickVolume)
    
      return(::OnCalculate(Size, 0, Time, Open, High, Low, Close, RealVolume, TickVolume, Spread));
    #endif    
  }  
};

CLASS* Class;

bool FirstRunOnCalculate = TRUE; // Необходимо TRUE, т.к. вызов OnCalculate только самим терминалом инициирует индикаторный буфер

void OnChartEvent( const int id, const long& lparam, const double& dparam, const string& sparam )
{
  if (id == CHARTEVENT_CHART_CHANGE)
  {
    Print(__FUNCTION__);
    
    ::OnDeinit();
    
    ::Class = new CLASS;
        
  if (!FirstRunOnCalculate)    
    CLASS::FullOnCalculate(); // Тут будет задница для MT5 (в MT4 - без проблем), т.к. после SetIndexBuffer в MT5 надо дожидаться вызова OnCalculate САМИМ терминалом
  }
  
  return;
}

void OnDeinit( const int Reason = 0 )
{
  if (::CheckPointer(::Class) == POINTER_DYNAMIC)
    delete ::Class;

  return;
}

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[] )
{  
  Print(__FUNCTION__);  

  if (FirstRunOnCalculate)
    FirstRunOnCalculate = FALSE;
  
  if (::CheckPointer(::Class) != POINTER_INVALID)
    ::Class.Buffer[0] = 0; // array out of range - MT5-ERROR!!!

  return(rates_total);
}

In MT4 this indicator will work without problems, in MT5 it will crash with an error. As it turned out, in MT4 you just need to wait for the first call of OnCalculate by the terminal and do whatever you want with the buffers, including their redefining using SetIndexBuffer. But in MT5 after EVERY SetIndexBuffer it is necessary to wait for the first call of OnCalculate by the terminal.

This peculiarity is not documented anywhere. And it does not seem to fit the definition of a "beginner".

Can we expect that in MT5 this behaviour will be the same as in MT4? I.e. after the first call of OnCalculate by the terminal itself it would be possible to call SetIndexBuffer without problems?

 
comp:

As it turns out, you are wrong. You can only call it when OnCalculate is called by the terminal itself. In this case, in MT4 the condition is more flexible, because you only need to call OnCalculate once. But in MT5, you must wait for the call of OnCalculate by the terminal itself every time after the SetIndexBuffer. Proof

In MT4 this indicator will work without problems, in MT5 it will crash with an error. As it turned out, in MT4 you just need to wait for the first call of OnCalculate by the terminal and then do whatever you want with the buffers, including their redefining using SetIndexBuffer. But in MT5 after EVERY SetIndexBuffer it is necessary to wait for the first call of OnCalculate by the terminal.

This feature is not documented anywhere. And it does not seem to fit the definition of a "beginner".

Can we expect that in MT5 this behaviour will be the same as in MT4? I.e. after the first call of OnCalculate by the terminal itself it will be possible to call SetIndexBuffer without problems?

Do not engage in verbiage - naturally, the call of OnCalculate implies a call by the terminal itself, because
The OnCalculate() function is called only in custom indicators when it's necessary to calculate the indicator values by theCalculateevent. This usually happens when a new tick is received for the symbol, for which the indicator is calculated. The indicator does not need to be attached to any price chart of this symbol.