Вопросы от начинающих MQL5 MT5 MetaTrader 5 - страница 1164

 
Roman:

Необходимо заранее продумывать как исполняется код на уровне памяти, инициализации и возврата значения. 

не надо ничего продумывать, для этих вещей служат мануалы, а мануала по распределению памяти в MQL никогда не было, только сообщения разработчиков, причем часто с уточнением, что реализация может измениться

ладно, разговор сводится кто какую книжку по программированию читал, я со школы и до сих пор читаю и так последние 30 лет

 
Igor Makanu:

не надо ничего продумывать, для этих вещей служат мануалы, а мануала по распределению памяти в MQL никогда не было, только сообщения разработчиков, причем часто с уточнением, что реализация может измениться

ладно, разговор сводится кто какую книжку по программированию читал, я со школы и до сих пор читаю и так последние 30 лет

Конечно не надо продумывать, а зачем... компилятор сам всё сделает. ))
C# не С

А по __inline смотри видос.
Там как раз объясняется как работают функции в памяти, для тех кому нет ни какой разницы.

 
Vladimir Karputov:

Картинку сначала нарисуйте и укажите что для Вас "нулевой бар" для индикатора с параметром shift.

Нарисовал. Нулевой бар выделен вертикальной линией.


 
RickD:

Нарисовал. Нулевой бар выделен вертикальной линией.


Пример кода:

//+------------------------------------------------------------------+
//|                                        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);
  }
//+------------------------------------------------------------------+

Результат:


Как видите спокойно копируется, без танцев с бубном.

Файлы:
 
Vladimir Karputov:

Пример кода:

Результат:


Как видите спокойно копируется, без танцев с бубном.

Пример кода. На основе индикатора. Индикатор занимается распледелением памяти буфера.

#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);
}

Когда start_pos = 0, то значение, соответствующее 0-му бару чарта, мы видим на 5-й позиции. 1.017041 В вашем эксперте оно на нулевой позиции. Ok.


Но мне нужно получить это значение на нулевой позиции.

Я задаю start_pos = 5. Не получаю нужный результат. Опять искомое значение на 5-й позиции.


Я задаю start_pos = -5. Не получаю нужный результат. Опять искомое значение на 5-й позиции.


Я задаю start_pos = -10. И только сейчас получаю нужный результат.


 
RickD:

Пример кода. На основе индикатора. Индикатор занимается распледелением памяти буфера.

Когда start_pos = 0, то значение, соответствующее 0-му бару чарта, мы видим на 5-й позиции. 1.017041 В вашем эксперте оно на нулевой позиции. Ok.


Но мне нужно получить это значение на нулевой позиции.

Я задаю start_pos = 5. Не получаю нужный результат. Опять искомое значение на 5-й позиции.


Я задаю start_pos = -5. Не получаю нужный результат. Опять искомое значение на 5-й позиции.


Я задаю start_pos = -10. И только сейчас получаю нужный результат.


Нужно понимать разницу при работе ИЗ советника и ИЗ индикатора. Для работы из индикатора пользуйтесь примером из справки (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:

Нужно понимать разницу при работе ИЗ советника и ИЗ индикатора. Для работы из индикатора пользуйтесь примером из справки (iMA).

Так вы возьмите пример из справки iMA, добавьте

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

   Comment(comm);   

и убедитесь, что значение отличается от значения, выводимого вашим экспертом, ровно на ma_shift баров.

Мне же нужно получить в индикаторе в iMABuffer[0] значение, как у вас в эксперте в array_ma[0].

Как минимум, на текущий момент можно видеть, что поведение CopyBuffer для экспертов и для индикаторов отличается. Если вы понимаете разницу CopyBuffer при работе ИЗ советника и ИЗ индикатора, просьба указать соответствующий раздел документации для изучения.

 

Я попробую упростить вопрос. Как мне в индикаторе получить в буфер вот эти значения MA (начиная от красной вертикальной линии и влево)? Можете написать пример?


 
RickD:

Я попробую упростить вопрос. Как мне в индикаторе получить в буфер вот эти значения MA (начиная от красной вертикальной линии и влево)? Можете написать пример?


На скрине отображение буфера смещено на пять баров вправо. Значит - чтобы получить пятый бар индикаторного буфера (с индексом 4), и далее по списку влево, откуда их нужно получить? Из Buffer[4] и далее влево.

В теории. На практике - дааавно не открывал код индикаторов, и не работал с ними - почти год как... Попробуйте.

 
Artyom Trishkin:


В теории. На практике - дааавно не открывал код индикаторов, и не работал с ними - почти год как... Попробуйте.

Мастерство не пропьёшь.

Причина обращения: