Базовые индикаторы, применяемые к кастомному инструменту
Запуск индикатора на кастомном символе.
#include <Symbol.mqh> // https://www.mql5.com/ru/code/18855 void OnStart() { const SYMBOL Symb(_Symbol + "_custom"); // Создали символ Symb = _Symbol; // Скопировали с основного символа все свойства и баровую историю - клон const int handle = iMA(Symb.Name, PERIOD_CURRENT, 1, 0, MODE_SMA, PRICE_CLOSE); // индикатор на кастомных данных double Buffer[]; const int Amount = CopyBuffer(handle, 0, 0, 1, Buffer); Print(Buffer[Amount - 1]); }
В МТ5 у стандартных индикаторов можно указать цену или хэндл другого индикатора. Применится к нулевому буферу.
Для этого приходится в индикаторе iMA указывать хендл еще одного отдельного индикатора, единственная задача которого - считать кастомный временной ряд, чтобы в дальнейшем передать его в наш первоначальный индикатор в качестве хендла. Таким образом, получается своеобразный костыль, в котором существуют два индикатора вместо одного (на примере MQL4 и технических индикаторов iMaOnArray, iRsiOnArray и т.п.).
Можно называть это костылем, но это штатный способ. ;-). На английском форуме ответили примерно то же самое. Но на великом и могучем конечно же можно обсудить более понятно и для Вас, и для нас.
Здравствуйте. Задавал этот вопрос на английском форуме. Ничего, кроме совета вставить исходные коды требуемых базовых индикаторов в код своего индикатора MQL5, не получил.
Итак, существует некий кастомный временной ряд, который рассчитывается на каждом баре. К нему требуется применить (без GUI) базовые индикаторы (допустим, MA, BB, Env, не важно). Если бы это был дефолтный инструмент, мы бы просто воспользовались техническим индикатором, к примеру, iMA, в котором бы указали его наименование, получили бы хендл и не знали бы проблем. Но в случае, если мы инструмент создаётся синтетическим путём, указать его напрямую мы не можем. Для этого приходится в индикаторе iMA указывать хендл еще одного отдельного индикатора, единственная задача которого - считать кастомный временной ряд, чтобы в дальнейшем передать его в наш первоначальный индикатор в качестве хендла. Таким образом, получается своеобразный костыль, в котором существуют два индикатора вместо одного (на примере MQL4 и технических индикаторов iMaOnArray, iRsiOnArray и т.п.).
Итак, вопрос. Каким образом можно осуществить создание расчёт базовых индикаторов на синтетическом временном ряду, реализовав всё в одном индикаторе и не прибегая к копированию полного кода необходимых базовых индикаторов? Спасибо!
Может эти классы подойдут?
Каким образом можно осуществить создание расчёт базовых индикаторов на синтетическом временном ряду, реализовав всё в одном индикаторе и не прибегая к копированию полного кода необходимых базовых индикаторов? Спасибо!
Если это нужно сделать внутри своего индикатора, то проще всего сделать входной параметр bool CustomData, который сигналирует, вычислять ли кастомную дату (в нулевой буфер) или работать в нормальном режиме. Соответственно, в нормальном режиме вызывать iCustom самого себя с CusomData = true и полученный хэндл запихивать, куда хочется.
// МАшка на кастомных данных #property indicator_separate_window #property indicator_buffers 1 #property indicator_plots 1 #property indicator_type1 DRAW_LINE #property indicator_color1 clrRed #property indicator_style1 STYLE_SOLID #property indicator_width1 1 input bool CustomData = false; // true - кастомный режим для iCustom input int MAPeriod = 1e3; // Период МАшки string GetMyName( void ) { const int Length = StringLen(TerminalInfoString(TERMINAL_DATA_PATH) + "\\MQL5\\Indicators\\"); const string Path = MQLInfoString(MQL_PROGRAM_PATH); return(StringSubstr(Path, Length, StringLen(Path) - Length - 4)); } double Buffer[]; const bool Init = SetIndexBuffer(0, Buffer, INDICATOR_DATA); const int handleMA = CustomData ? INVALID_HANDLE : iMA(NULL, PERIOD_CURRENT, MAPeriod, 0, MODE_SMA, iCustom(_Symbol, PERIOD_CURRENT, GetMyName(), true)); int OnCalculate( const int rates_total, // размер входных таймсерий const int prev_calculated, // обработано баров на предыдущем вызове const datetime& time[], // Time const double& open[], // Open const double& high[], // High const double& low[], // Low const double& close[], // Close const long& tick_volume[], // Tick Volume const long& volume[], // Real Volume const int& spread[] ) // Spread { if (CustomData) for (int i = prev_calculated; i < rates_total; i++) Buffer[i] = MathRand(); // Подготовили данные return(CustomData ? rates_total : prev_calculated + CopyBuffer(handleMA, 0, prev_calculated, rates_total - prev_calculated, Buffer)); }
Если это нужно сделать внутри своего индикатора, то проще всего сделать входной параметр bool CustomData, который сигналирует, вычислять ли кастомную дату (в нулевой буфер) или работать в нормальном режиме. Соответственно, в нормальном режиме вызывать iCustom самого себя с CusomData = true и полученный хэндл запихивать, куда хочется.
Да, начал пробовать этот вариант, когда Вы еще без кода сообщение написали. Не знал, что такой вариант рекурсии возможен. То, что надо! Премного благодарен.
Всем спасибо за идеи.
Если это нужно сделать внутри своего индикатора, то проще всего сделать входной параметр bool CustomData, который сигналирует, вычислять ли кастомную дату (в нулевой буфер) или работать в нормальном режиме. Соответственно, в нормальном режиме вызывать iCustom самого себя с CusomData = true и полученный хэндл запихивать, куда хочется.
Таким способом можно достать только нулевой буфер? Или я что-то не так делал?
Таким способом можно достать только нулевой буфер?
Любой.
Любой.
Сделай пожалуйста пример, что-то у меня CopyBuffer первого буфера даёт ошибку 4806 "Запрошенные данные не найдены".
Сделай пожалуйста пример, что-то у меня CopyBuffer первого буфера даёт ошибку 4806 "Запрошенные данные не найдены".
Возможно, мы неправильно поняли друг друга. Это имел в виду
// МАшка на двух кастомных данных #property indicator_separate_window #property indicator_buffers 2 #property indicator_plots 2 #property indicator_type1 DRAW_LINE #property indicator_color1 clrRed #property indicator_style1 STYLE_SOLID #property indicator_width1 1 #property indicator_type2 DRAW_LINE #property indicator_color2 clrYellow #property indicator_style2 STYLE_SOLID #property indicator_width2 1 input int CustomData = WRONG_VALUE; // Для кастомного режима iCustom input int MAPeriod = 1e2; // Период МАшки string GetMyName( void ) { const int Length = StringLen(TerminalInfoString(TERMINAL_DATA_PATH) + "\\MQL5\\Indicators\\"); const string Path = MQLInfoString(MQL_PROGRAM_PATH); return(StringSubstr(Path, Length, StringLen(Path) - Length - 4)); } const bool FlagCustomData = (CustomData != WRONG_VALUE); double Buffer0[], Buffer1[]; const bool Init = SetIndexBuffer(0, Buffer0, INDICATOR_DATA) && (!FlagCustomData) && SetIndexBuffer(1, Buffer1, INDICATOR_DATA); const int handleMA0 = FlagCustomData ? INVALID_HANDLE : iMA(NULL, PERIOD_CURRENT, MAPeriod, 0, MODE_SMA, iCustom(_Symbol, PERIOD_CURRENT, GetMyName(), 0)); const int handleMA1 = FlagCustomData ? INVALID_HANDLE : iMA(NULL, PERIOD_CURRENT, MAPeriod, 0, MODE_SMA, iCustom(_Symbol, PERIOD_CURRENT, GetMyName(), 1)); int OnCalculate( const int rates_total, // размер входных таймсерий const int prev_calculated, // обработано баров на предыдущем вызове const datetime& time[], // Time const double& open[], // Open const double& high[], // High const double& low[], // Low const double& close[], // Close const long& tick_volume[], // Tick Volume const long& volume[], // Real Volume const int& spread[] ) // Spread { if (FlagCustomData) for (int i = prev_calculated; i < rates_total; i++) Buffer0[i] = MathRand() * (CustomData + 1); // Подготовили данные return(FlagCustomData ? rates_total : prev_calculated + MathMin(CopyBuffer(handleMA0, 0, prev_calculated, rates_total - prev_calculated, Buffer0), CopyBuffer(handleMA1, 0, prev_calculated, rates_total - prev_calculated, Buffer1))); }
Стандартные индикаторы, конечно, считают только нулевые буферы в режиме хэндла. Поэтому для каждого буфера нужно делать свой хэндл.

- Бесплатные приложения для трейдинга
- Форексный VPS бесплатно на 24 часа
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Здравствуйте. Задавал этот вопрос на английском форуме. Ничего, кроме совета вставить исходные коды требуемых базовых индикаторов в код своего индикатора MQL5, не получил.
Итак, существует некий кастомный временной ряд, который рассчитывается на каждом баре. К нему требуется применить (без GUI) базовые индикаторы (допустим, MA, BB, Env, не важно). Если бы это был дефолтный инструмент, мы бы просто воспользовались техническим индикатором, к примеру, iMA, в котором бы указали его наименование, получили бы хендл и не знали бы проблем. Но в случае, если мы инструмент создаётся синтетическим путём, указать его напрямую мы не можем. Для этого приходится в индикаторе iMA указывать хендл еще одного отдельного индикатора, единственная задача которого - считать кастомный временной ряд, чтобы в дальнейшем передать его в наш первоначальный индикатор в качестве хендла. Таким образом, получается своеобразный костыль, в котором существуют два индикатора вместо одного (на примере MQL4 и технических индикаторов iMaOnArray, iRsiOnArray и т.п.).
Итак, вопрос. Каким образом можно осуществить создание расчёт базовых индикаторов на синтетическом временном ряду, реализовав всё в одном индикаторе и не прибегая к копированию полного кода необходимых базовых индикаторов? Спасибо!