Погружаемся в особенности индикаторов MetaTrader 5 - страница 3

 

В описании функции OnCalculate() сказано, что существуют две формы её вызова, причём первая форма вызова предназначена для тех индикаторов, которые могут быть рассчитаны на одном буфере данных:

int OnCalculate (const int rates_total,      // размер массива price[]
                 const int prev_calculated,  // обработано баров на предыдущем вызове
                 const int begin,            // откуда начинаются значимые данные
                 const double& price[]       // массив для расчета
   ); 

Для первой формы вызова также указано, что "В качестве массива price[] может быть передана одна из ценовых таймсерий либо рассчитанный буфер какого-либо индикатора". Но при  этом оговорено, что "Выбор необходимой таймсерии или индикатора в качестве массива price[] производится пользователем при запуске индикатора на закладке "Parameters"", т.е. вручную. Примеров программной передачи рассчитанного буфера стороннего индикатора в качестве массива price[] я не нашёл.

Соответственно, вопрос: каким именно образом можно на программном уровне передать рассчитанный буфер какого-либо индикатора (базового индикатора) в качестве массива price[]? Иными словами, каким именно образом можно на программном уровне передать рассчитанный буфер базового индикатора без использования функции CopyBuffer()?

 
Yedelkin:

В описании функции OnCalculate() сказано, что существуют две формы её вызова, причём первая форма вызова предназначена для тех индикаторов, которые могут быть рассчитаны на одном буфере данных:

Для первой формы вызова также указано, что "В качестве массива price[] может быть передана одна из ценовых таймсерий либо рассчитанный буфер какого-либо индикатора". Но при  этом оговорено, что "Выбор необходимой таймсерии или индикатора в качестве массива price[] производится пользователем при запуске индикатора на закладке "Parameters"", т.е. вручную. Примеров программной передачи рассчитанного буфера стороннего индикатора в качестве массива price[] я не нашёл.

Соответственно, вопрос: каким именно образом можно на программном уровне передать рассчитанный буфер какого-либо индикатора (базового индикатора) в качестве массива price[]? Иными словами, каким именно образом можно на программном уровне передать рассчитанный буфер базового индикатора без использования функции CopyBuffer()?


applied_price

[in]  The price used. Can be any of the price constants ENUM_APPLIED_PRICE or a handle of another indicator.

 

antt:

applied_price

[in]  The price used. Can be any of the price constants ENUM_APPLIED_PRICE or a handle of another indicator.

 

Нет, не совсем то, что надо. Процитированное Вами описание параметра applied_price  взято из описания какого-то индикатора-функции, например:

int  iMA(
   string               symbol,          // имя символа
   ENUM_TIMEFRAMES      period,           // период
   int                  ma_period,      // период усреднения
   int                  ma_shift,       // смещение индикатора по горизонтали
   ENUM_MA_METHOD       ma_method,       // тип сглаживания
   ENUM_APPLIED_PRICE   applied_price      // тип цены или handle
   );

У меня же вопрос касается не способа передачи на программном уровне рассчитанного буфера одного индикатора в другой индикатор, а способа передачи на программном уровне рассчитанного буфера базового индикатора в качестве массива price[] для функции OnCalculate().

В частности, среди параметров функции OnCalculate() нет такого параметра, как applied_price, описание которого приведено в ответ на мой вопрос. Но этот факт не мешает вручную передавать рассчитанный буфер индикатора в качестве массива price[] для функции OnCalculate(). Вопрос в том, как от ручного способа передачи перейти к программному. Спасибо за внимание к вопросу.

...Или Вы предлагаете сначала оформить пользовательский индикатор типа myIndicator(...), у которого в целях функции iCustom() последним параметром будет параметр applied_price, а затем при вызове этого индикатора из mql5-программы (т.е. из другого индикатора) передавать ему хендл базового индикатора (т.е. передавать хендл третьего индикатора)? Но тогда получается, что невозможно напрямую (т.е. без использования указанной конструкции) передать буфер базового индикатора в качестве массива price[] для функции OnCalculate()? Правильно я понимаю?

 
Yedelkin:

 

Нет, не совсем то, что надо. Процитированное Вами описание параметра applied_price  взято из описания какого-то индикатора-функции, например:

У меня же вопрос касается не способа передачи на программном уровне рассчитанного буфера одного индикатора в другой индикатор, а способа передачи на программном уровне рассчитанного буфера базового индикатора в качестве массива price[] для функции OnCalculate().

В частности, среди параметров функции OnCalculate() нет такого параметра, как applied_price, описание которого приведено в ответ на мой вопрос. Но этот факт не мешает вручную передавать рассчитанный буфер индикатора в качестве массива price[] для функции OnCalculate(). Вопрос в том, как от ручного способа передачи перейти к программному. Спасибо за внимание к вопросу.

...Или Вы предлагаете сначала оформить пользовательский индикатор типа myIndicator(...), у которого в целях функции iCustom() последним параметром будет параметр applied_price, а затем при вызове этого индикатора из mql5-программы (т.е. из другого индикатора) передавать ему хендл базового индикатора (т.е. передавать хендл третьего индикатора)? Но тогда получается, что невозможно напрямую (т.е. без использования указанной конструкции) передать буфер базового индикатора в качестве массива price[] для функции OnCalculate()? Правильно я понимаю?

Возможно этот пример прояснит ситуацию?

int OnInit()
  {
   int base=iMA(_Symbol,_Period,13,0,MODE_EMA,PRICE_CLOSE);
   if(base==INVALID_HANDLE)
      return(1);
   int child=iCustom(_Symbol,_Period,"Examples\\Custom Moving Average",10,5,MODE_LWMA,base);
   if(child==INVALID_HANDLE)
      return(2);
   return(0);
  }

 

Второй вызов через iCustom был сделан для наглядности.

В качестве ценового массива price[] в  Custom Moving Average будет передан массив значений первого индикатора.

 
Yedelkin:

 Правильно я понимаю?

Да. Небольшое неудобство за большую гибкость и универсальность.

И то как посмотреть.

 
alexvd:

Возможно этот пример прояснит ситуацию?

Второй вызов через iCustom был сделан для наглядности.

В качестве ценового массива price[] в  Custom Moving Average будет передан массив значений первого индикатора.

Да, я понял, спасибо за пояснения. Подтверждается ситуация, сформулированная в последнем абзаце моего предыдущего сообщения.

 Дополню мысль: в индикаторах после функции OnInit() следует функция OnCalculate():

int OnInit(){...}
int OnCalculate(const int rates_total,
                const int prev_calculated,  
                const int begin,            
                const double& price[])      
  {...}

В приведённом Вами примере говорится о том, что массив значений первого индикатора (хендл base) передаётся в качестве ценового массива price[] во второй индикатор (хендл child)  в рамках функции OnInit(). Передать же массив значений первого индикатора (хендл base) или любого другого индикатора в качестве массива price[] для функции OnCalculate(), непосредственно следующей после функции OnInit(), не представляется возможным. Значит, будем использовать те возможности, которые есть.

 

TheXpert:

Да. Небольшое неудобство за большую гибкость и универсальность. И то как посмотреть.

Спасибо за пояснение! 

 
Yedelkin:
...

В приведённом Вами примере говорится о том, что массив значений первого индикатора (хендл base) передаётся в качестве ценового массива price[] во второй индикатор (хендл child)  в рамках функции OnInit(). Передать же массив значений первого индикатора (хендл base) или любого другого индикатора в качестве массива price[] для функции OnCalculate(), непосредственно следующей после функции OnInit(), не представляется возможным. Значит, будем использовать те возможности, которые есть.

Я как-то пререругался в сервисдеске с главным разработчиком компилятора mql5 Славой Стариковым (stringo) на подобную же тему. Там речь шла об обратной задаче.

Мне нужно было узнавать внутри OnCalculate() хендл того индикатора, который подаётся на вход текущего индикатора.

// Кстати, мне это и сейчас нужно. Эта возможность многие мои решения сделала бы намного более элегантными.

Слава  (stringo) просто не понимал зачем мне это нужно, когда есть такая замечательная возможность как :

int OnInit()
  {
   int base=iMA(_Symbol,_Period,13,0,MODE_EMA,PRICE_CLOSE);
   if(base==INVALID_HANDLE)
      return(1);
   int child=iCustom(_Symbol,_Period,"Examples\\Custom Moving Average",10,5,MODE_LWMA,base);
   if(child==INVALID_HANDLE)
      return(2);
   return(0);
  }

т.е. ЖЁСТКО связать  ЗАРАНЕЕ выбранный индикатор с текущим. 

Я долго пытался ему объяснить, что это я всё знаю и давно пользуюсь, но хотелось бы набрасывать свой СКОМПИЛИРОВАННЫЙ индикатор, на ЛЮБОЙ другой. Прямо в терминале.

Слава искренне расстраивался и продолжал приводить предыдущий пример...

После пятого круга взаимных объяснений я просто психанул, нахамил Славе и перестал туда писать...  :(

// А жаль  всё же, что сервис "индикатор от индикатора" до сих пор остаётся на довольно примитивном уровне.

// Идея могла бы быть колоссально развита достаточно скромными усилиями Метаквотов.  

Разработчики! Может вернёмся к теме?  Уверяю, ОНО ТОГО СТОИТ! Можно сотворить такие удобства, которых ну точно ни в одном терминале нету.

 

Всем привет!

В ветке  "Осциллятор Equity средствами MQL5" ( https://www.mql5.com/ru/forum/2963/page5 ) идет выяснение возможности программной реализации построения осциллятора изменения параметров состояния счета (например, Equity) на этапе тестирования.

На настоящий момент предлагается только 1 вариант - запись значений аккаунта в файл с последующей переброской его вручную (!) из папки файлов тестового агента в папку файлов основного режима, но вариант этот - крайне громоздкий и неудобный.

Кто может предложить вариант чисто программерный, то есть без необходимости ручного вмешательства? 

И вообще, каким образом у Вас происходит анализ эффективности торговой системы?

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

Осциллятор Equity средствами MQL5
Осциллятор Equity средствами MQL5
  • www.mql5.com
С другой стороны, трудно понять, можно ли менять график осциллятора (а точнее буфер его данных) из кода OnTick эксперта, где метод AccountInfoDouble(ACCOUNT_EQUITY) работает.
 
DV2010:
....

1) Кто может предложить вариант чисто программерный, то есть без необходимости ручного вмешательства? 

2) И вообще, каким образом у Вас происходит анализ эффективности торговой системы?

3) На мой взгляд, гораздо удобнее иметь внизу графика динамику изменения результирующих показателей, чем видеть их в отдельном окне тестера "График" без возможности непосредственного сопоставления с динамикой цен, которой этот график, собственно, всем и обязан. 

1) Загляните снова в свою ветку. Там предложен чисто программерский способ.

2) Программно.

3) Разве будет удобно наблюдать мельтешащий эквити на графике от каждого прогона тестера? Если неудобно, то результаты какого именно прогона хотелось бы увидеть? Всё решаемо. Но Вам нужно сначала точно определится со своими желаниями. И будет Вам счастье.

 

joo, Мне кажется, что за прибылью наблюдать всегда не только удобно, но даже и важно :)

А результат, который хочу видеть, - динамику по каждой отдельной сделке, динамику кумулятивную, динамику доходности в процентах от первоначального депо (т.е. ничего сверхъествественного).

 

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