В самом простом случае нужно именно так и сделать: вызвать iCustom нужное количество раз. Ведь это не ведет к реальным расчетам данных всего индикатора. Они производятся только при первом вызове (на тике, баре). После первого обращения данные всех остальных буферов уже рассчитаны и функция просто возвращает результат.
Хотя наиболее оптимальный вариант - повторить расчет данных индикатора в советнике, адаптировав этот расчет именно для нужд советника. В подавляющем большинстве случаев код индикатора для советника выходит намного лаконичнее и работает быстрее, чем индикатор.
В самом простом случае нужно именно так и сделать: вызвать iCustom нужное количество раз. Ведь это не ведет к реальным расчетам данных всего индикатора.
Вы уверены, что пересчета не будет? Речь идет о mql4
Посмотрел в mql5 iCustom сделан по уму, позволяющий не вызывать несколько раз iCustom.
Вы уверены, что пересчета не будет? Речь идет о mql4
Посмотрел в mql5 iCustom сделан по уму, позволяющий не вызывать несколько раз iCustom.
Вы уверены, что пересчета не будет? Речь идет о mql4
Посмотрел в mql5 iCustom сделан по уму, позволяющий не вызывать несколько раз iCustom.
Если индикатор написан правильно (с контролем баров, на которых он вызван), то пересчета не будет.
интересная тема, вот для проверки индикатор (tst_icustom.mql4):
#property copyright "Copyright 2019, IgorM" #property link "https://www.mql5.com/ru/users/igorm" #property version "1.00" #property strict #property indicator_separate_window #property indicator_buffers 3 #property indicator_plots 3 //--- plot Label1 #property indicator_label1 "Label1" #property indicator_type1 DRAW_LINE #property indicator_color1 clrRed #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- plot Label2 #property indicator_label2 "Label2" #property indicator_type2 DRAW_LINE #property indicator_color2 clrOrange #property indicator_style2 STYLE_SOLID #property indicator_width2 1 //--- plot Label3 #property indicator_label3 "Label3" #property indicator_type3 DRAW_LINE #property indicator_color3 clrBlue #property indicator_style3 STYLE_SOLID #property indicator_width3 1 //--- indicator buffers input double value=1.0; double Label1Buffer[]; double Label2Buffer[]; double Label3Buffer[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0,Label1Buffer); SetIndexBuffer(1,Label2Buffer); SetIndexBuffer(2,Label3Buffer); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| 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[]) { int i,limit; if(prev_calculated==0) limit=rates_total-1; else limit=rates_total-prev_calculated+1; Print("limit = ",limit," , value = ",value); for(i=limit; i>=0; i--) { Label1Buffer[i]=close[i] * value; Label2Buffer[i]=close[i] * value; Label3Buffer[i]=close[i] * value; } return(rates_total); } //+------------------------------------------------------------------+
и советник который вызовет индикатор на каждом тике:
#property copyright "Copyright 2019, IgorM" #property link "https://www.mql5.com/ru/users/igorm" #property version "1.00" #property strict //--- input parameters input double Value1 = 1.0; input double Value2 = 2.0; input double Value3 = 3.0; void OnTick() { double ind_buf1=iCustom(NULL,0,"tst_icustom",Value1,0,1); Print("Вызов буффера 1 , результат = ",ind_buf1); double ind_buf2=iCustom(NULL,0,"tst_icustom",Value2,1,1); Print("Вызов буффера 2 , результат = ",ind_buf2); double ind_buf3=iCustom(NULL,0,"tst_icustom",Value3,2,1); Print("Вызов буффера 3 , результат = ",ind_buf3); Comment("ind_buf1 = ",ind_buf1,"\n","ind_buf2 = ",ind_buf2,"\n","ind_buf3 = ",ind_buf3); }
в таком виде в логе будет 3 принта от индикатора с при первом вызове
2019.05.07 17:12:12.131 tst_ic EURUSD,H1: Вызов буффера 3 , результат = 3.354810000000001
2019.05.07 17:12:12.115 tst_icustom EURUSD,H1: limit = 133047 , value = 3.0
2019.05.07 17:12:12.100 tst_ic EURUSD,H1: Вызов буффера 2 , результат = 2.23654
2019.05.07 17:12:12.084 tst_icustom EURUSD,H1: limit = 133047 , value = 2.0
2019.05.07 17:12:12.068 tst_ic EURUSD,H1: Вызов буффера 1 , результат = 1.11827
2019.05.07 17:12:12.068 tst_icustom EURUSD,H1: limit = 133047 , value = 1.0
а если код эксперта написать так:
void OnTick() { double ind_buf1=iCustom(NULL,0,"tst_icustom",Value1,0,1); Print("Вызов буффера 1 , результат = ",ind_buf1); double ind_buf2=iCustom(NULL,0,"tst_icustom",Value1,1,1); Print("Вызов буффера 2 , результат = ",ind_buf2); double ind_buf3=iCustom(NULL,0,"tst_icustom",Value1,2,1); Print("Вызов буффера 3 , результат = ",ind_buf3); Comment("ind_buf1 = ",ind_buf1,"\n","ind_buf2 = ",ind_buf2,"\n","ind_buf3 = ",ind_buf3); }
то принты будут так:
2019.05.07 17:14:01.054 tst_icustom EURUSD,H1: limit = 1 , value = 1.0
2019.05.07 17:14:00.710 tst_ic EURUSD,H1: Вызов буффера 3 , результат = 1.11827
2019.05.07 17:14:00.710 tst_ic EURUSD,H1: Вызов буффера 2 , результат = 1.11827
2019.05.07 17:14:00.710 tst_ic EURUSD,H1: Вызов буффера 1 , результат = 1.11827
2019.05.07 17:14:00.710 tst_icustom EURUSD,H1: limit = 133047 , value = 1.0
итого, примерно так:
- если вызов индикатора с несколькими буферами из эксперта происходит с одинаковыми параметрами, тогда индикатор будет рассчитан один раз и при последующем вызове iCustom() на этом же тике будут просто возвращены данные буферов
- если вызов индикатора ... с разными параметрами, то вроде как будут или рассчитаны все буфера при каждом вызове или создается несколько копий этого индикатора? - тут пока не знаю как проверить копии индикаторов
ЗЫ: но однозначно оптимизация кода MQL на высоте, все что можно было оптимизировать - компилятор сделал!
- если вызов индикатора ... с разными параметрами, то вроде как будут или рассчитаны все буфера при каждом вызове или создается несколько копий этого индикатора?
Несколько.
Несколько.
несколько - тогда это производительнее все будет работать, хотя все в одном интерфейсном потоке эксперта... но однозначно разработчики оптимизацию делали на совесть!
как проверить, что много копий индикатора создано?
Поделитесь опытом, кто как выходил из ситуации.
Задача в следующем: есть индикатор в нем рассчитываются несколько параметров, как их вернуть в советник не вызывая несколько раз iCustom для каждого параметра (буфера)?
когда-то что-то такое делал, потому как индикатор должен был возвращать много-много флагов, а заводить по отдельному буферу на флаг как-то жаба давила :-)
битовые флаги упихиваются в битовые поля ulong x = (FLAG0 | (FLAG1<<1) | (FLAG2<<2) и копируются в doublе, на принимающей стороне обратный разворот. x=(ulong)value; FLAG0=(x & 1); FLAG1=((x>>1)&1)); etc
по идее через каждый буфер можно таскать даже структуры, но пока они помещаются в sizeof(double) и желательно не совпадают с EMPTY_VALUE..
а через группу буферов N*sizeof(double) можно проносить весьма объёмные вещи,
несколько - тогда это производительнее все будет работать, хотя все в одном интерфейсном потоке эксперта... но однозначно разработчики оптимизацию делали на совесть!
как проверить, что много копий индикатора создано?
сравнить объем занимаемой памяти при вызове одног индикатора и при вызове 40 индикаторов (параметры обязательно должны быть разные)
несколько - тогда это производительнее все будет работать, хотя все в одном интерфейсном потоке эксперта...
В зависимости от задачи.
И индикаторы не в потоке эксперта, а в потоке таймсерии (символ/тф).
как проверить, что много копий индикатора создано?
В логе есть запись о запуске каждой копии. Этого не достаточно?
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Задача в следующем: есть индикатор в нем рассчитываются несколько параметров, как их вернуть в советник не вызывая несколько раз iCustom для каждого параметра (буфера)?