Questions from Beginners MQL5 MT5 MetaTrader 5 - page 1164

 
Roman:

It is necessary to think in advance how the code is executed at the level of memory, initialization and value return.

You don't have to think it through, there are manuals for these things, and there has never been a manual for memory allocation in MQL, only messages from developers, and often with a clarification that the implementation may change

Ok, the discussion boils down to who reads what programming book, I've been reading it since high school and I'm still reading it for the last 30 years.

 
Igor Makanu:

You don't have to think it through, there are manuals for these things, and there has never been a manual for memory allocation in MQL, only messages from developers, and often with a clarification that the implementation may change

Ok, the discussion boils down to who reads what programming book, I've been reading it since high school and I'm still reading it for the last 30 years

Of course you don't have to think it through, why should you... The compiler will do it all by itself. ))
C# is not C

And look at the video on __inline.
It explains there how functions work in memory for those who don't make any difference.

 
Vladimir Karputov:

Draw a picture first and specify what the 'zero bar' for an indicator with the shift parameter is for you.

Drawn. The zero bar is highlighted with a vertical line.


 
RickD:

Drawn. The zero bar is highlighted with a vertical line.


Example code:

//+------------------------------------------------------------------+
//|                                        iMA Values on a Chart.mq5 |
//|                              Copyright © 2019, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2019, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
//--- input parameters
input int                  Inp_MA_ma_period     = 12;          // MA: averaging period
input int                  Inp_MA_ma_shift      = 5;           // MA: horizontal shift
input ENUM_MA_METHOD       Inp_MA_ma_method     = MODE_SMA;    // MA: smoothing type
input ENUM_APPLIED_PRICE   Inp_MA_applied_price = PRICE_CLOSE; // MA: type of price
//---
int    handle_iMA;                           // variable for storing the handle of the iMA indicator
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create handle of the indicator iMA
   handle_iMA=iMA(Symbol(),Period(),Inp_MA_ma_period,Inp_MA_ma_shift,
                  Inp_MA_ma_method,Inp_MA_applied_price);
//--- if the handle is not created
   if(handle_iMA==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code
      PrintFormat("Failed to create handle of the iMA indicator for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(Period()),
                  GetLastError());
      //--- the indicator is stopped early
      return(INIT_FAILED);
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   double array_ma[];
   ArraySetAsSeries(array_ma,true);
   int start_pos=0,count=3;
   if(!iGetArray(handle_iMA,0,start_pos,count,array_ma))
      return;

   string text="";
   for(int i=0; i<count; i++)
      text=text+IntegerToString(i)+": "+DoubleToString(array_ma[i],Digits()+1)+"\n";

   Comment(text);
  }
//+------------------------------------------------------------------+
//| Get value of buffers                                             |
//+------------------------------------------------------------------+
bool iGetArray(const int handle,const int buffer,const int start_pos,
               const int count,double &arr_buffer[])
  {
   bool result=true;
   if(!ArrayIsDynamic(arr_buffer))
     {
      PrintFormat("ERROR! EA: %s, FUNCTION: %s, this a no dynamic array!",__FILE__,__FUNCTION__);
      return(false);
     }
   ArrayFree(arr_buffer);
//--- reset error code
   ResetLastError();
//--- fill a part of the iBands array with values from the indicator buffer
   int copied=CopyBuffer(handle,buffer,start_pos,count,arr_buffer);
   if(copied!=count)
     {
      //--- if the copying fails, tell the error code
      PrintFormat("ERROR! EA: %s, FUNCTION: %s, amount to copy: %d, copied: %d, error code %d",
                  __FILE__,__FUNCTION__,count,copied,GetLastError());
      //--- quit with zero result - it means that the indicator is considered as not calculated
      return(false);
     }
   return(result);
  }
//+------------------------------------------------------------------+

Result:


As you can see, it's copyable without any tinkering.

 
Vladimir Karputov:

Example code:

Result:


As you can see it's copied easily, without any tambourine.

Example code. Based on an indicator. Indicator is busy allocating buffer memory.

#property copyright "Copyright 2019"
#property link      ""
#property version   "1.00"

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   0

//---

input int                  MA_period = 12;
input int                  MA_shift = 5;
input ENUM_MA_METHOD       MA_method = MODE_SMA;
input ENUM_APPLIED_PRICE   MA_applied_price = PRICE_CLOSE;

int start_pos = 0;

//---

double MA_Calc_Buf[];

int hMA = INVALID_HANDLE;


int OnInit()
{
  SetIndexBuffer(0, MA_Calc_Buf, INDICATOR_CALCULATIONS); 
  ArraySetAsSeries(MA_Calc_Buf, true);
 
  hMA = iMA(NULL, 0, MA_period, MA_shift, MA_method, MA_applied_price);   
  if (hMA == INVALID_HANDLE)
  {
    int LErr = GetLastError();
    PrintFormat("iMA create failed (%d)", LErr);
    return (INIT_FAILED);
  }
 
  return (INIT_SUCCEEDED);
}

void OnDeinit(const int reason)
{
  if (hMA != INVALID_HANDLE)
  {
    IndicatorRelease(hMA);
    hMA = INVALID_HANDLE;
  }
}

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[])
{ 
  int copied;
  copied = CopyBuffer(hMA, 0, start_pos, rates_total, MA_Calc_Buf);
  if (copied == -1)
  {
    int LErr = GetLastError();
    PrintFormat("CopyBuffer(hMA) failed (%d)", LErr);
    return (prev_calculated);
  }
 
  if (copied == 0)
  {
    PrintFormat("CopyBuffer(hMA) copied 0 bars");
    return (prev_calculated);
  } 
 
  string text = "";
  for (int i=0; i<15; i++)
    text = text + IntegerToString(i) + ": " + DoubleToString(MA_Calc_Buf[i], Digits()+1) + "\n";
 
  Comment(text);

  return (rates_total);
}

When start_pos = 0, the value corresponding to the 0th bar of the chart is on position 5. 1.017041 It is on position 0 in your EA. Ok.


But I need to get this value at zero position.

I set start_pos = 5. I don't get the required result. The value I am looking for is again at position 5.


I set start_pos = -5. I do not get the desired result. Again the value I am looking for is at position 5.


I set start_pos = -10. And only now I get the desired result.


 
RickD:

Example code. Based on the indicator. The indicator is busy allocating buffer memory.

When start_pos = 0, the value corresponding to the 0th bar of the chart we see on position 5. 1.017041 In your EA it is on position 0. Ok.


But I need to get this value at zero position.

I set start_pos = 5. I don't get the desired result. The value I am looking for is again at position 5.


I set start_pos = -5. I do not get the desired result. Again the value I am looking for is at position 5.


I set start_pos = -10. And only now I get the desired result.


We need to understand the difference between the work from the Expert Advisor and from the indicator. For work from indicator use example from help(iMA).

Документация по MQL5: Технические индикаторы / iMA
Документация по MQL5: Технические индикаторы / iMA
  • www.mql5.com
//|                                                     Demo_iMA.mq5 | //|                        Copyright 2011, MetaQuotes Software Corp. | //|                                             https://www.mql5.com | //| Перечисление способов создания хэндла                            |  Creation             type=Call_iMA;                ...
 
Vladimir Karputov:

You need to understand the difference between operating from an EA and from an indicator. To work from an indicator, use the example from the help(iMA).

So you take an example from the iMA help, add

   ArraySetAsSeries(iMABuffer, true);
   comm = (string)DoubleToString(iMABuffer[0], Digits());
   ArraySetAsSeries(iMABuffer, false);

   Comment(comm);   

and verify that the value is different from your EA's output value by exactly ma_shift of bars.

I, on the other hand, need to get in the indicator in iMABuffer[0] the value as you have in your Expert Advisor in array_ma[0].

At least at the moment we can see that behavior of CopyBuffer for Expert Advisors and indicators is different. If you understand the difference in CopyBuffer when working with an EA and an indicator, please specify the appropriate section of the documentation to study.

 

I'll try to simplify the question. How do I get these MA values (starting from the red vertical line and to the left) to the buffer in the indicator? Can you write an example?


 
RickD:

I'll try to simplify the question. How do I get these MA values (starting from the red vertical line and to the left) to the buffer in the indicator? Can you write an example?


In the screenshot, the buffer display is shifted five bars to the right. So - to get the fifth bar of the indicator buffer (index 4), and further to the left in the list, where should we get them from? From Buffer[4] and further to the left.

In theory. In practice - I haven't opened the indicator code or worked with it for a long time - almost a year... Give it a try.

 
Artyom Trishkin:


In theory. In practice - I haven't opened the indicator code or worked with it for a long time - almost a year... Give it a try.

You can't lose a skill.