Индикатор из учебника
Нужно найти бар текущего ТФ, который является первым баром текущих суток. Делается это при помощи функции iBarShift. Полученное значение подставляется вместо переменной History.
Спасибо большое. Сделал так. Вроде работает.
//-------------------------------------------------------------------- // separatewindow.mq4 // Предназначен для использования в качестве примера в учебнике MQL4. //-------------------------------------------------------------------- #property indicator_separate_window // Отображение в отдельном окне #property indicator_buffers 2 // Количество буферов #property indicator_color1 Blue // Цвет первой линии #property indicator_color2 Red // Цвет второй линии //extern int History =50; // Колич.баров в расчётной истории datetime time=D'2021.03.30 00:00'; bool exact=false; double Buf_0[],Buf_1[]; // Объявление индикаторного массива double Sum_H=0; double Sum_L=0; //-------------------------------------------------------------------- int init() // Специальная функция init() { SetIndexBuffer(0,Buf_0); // Назначение массива буферу SetIndexStyle (0,DRAW_LINE,STYLE_SOLID,2);// Стиль линии SetIndexBuffer(1,Buf_1); // Назначение массива буферу SetIndexStyle (1,DRAW_LINE,STYLE_SOLID,2);// Стиль линии return; // Выход из спец. ф-ии init() } //-------------------------------------------------------------------- int start() // Специальная функция start() { int i, // Индекс бара Counted_bars; // Количество просчитанных баров //-------------------------------------------------------------------- Counted_bars=IndicatorCounted(); // Количество просчитанных баров int bar_index=iBarShift(Symbol(),PERIOD_CURRENT,time,exact); i=Bars-Counted_bars-1; // Индекс первого непосчитанного if (i>bar_index-1) // Если много баров то .. i=bar_index; // ..рассчитывать заданное колич. while(i>=0) // Цикл по непосчитанным барам { if(Open[i]<Close[i]) { Sum_H=Sum_H+(Close[i]-Open[i]); Sum_L=Sum_L; } if(Open[i]>Close[i]) { Sum_L=Sum_L+(Open[i]-Close[i]); Sum_H=Sum_H; } Buf_0[i]=Sum_H;// Знач. 0 буфера на i-ом баре Buf_1[i]=Sum_L;// Знач. 1 буфера на i-ом баре i--; // Расчёт индекса следующего бара } //-------------------------------------------------------------------- return; // Выход из спец. ф-ии start() } //--------------------------------------------------------------------
Еще пару вопросов, если позволите.
Сейчас время задаю статично.
datetime time=D'2021.03.30 00:00';
Как сделать так, чтобы время и число текущего дня само подставлялось в дату?
Когда вешаю индикатор на чарт, то всё нормально. Но поступают новые данные на 0 баре и начинает рисовать хрень. Почему?
Еще пару вопросов, если позволите.
Сейчас время задаю статично.
Как сделать так, чтобы время и число текущего дня само подставлялось в дату?
datetime time=D'2021.03.30 7:33'; // Если взять остаток о деления этого времени на количество секунд в периоде D1 time%PeriodSeconds(PERIOD_D1); // то получим время биздаты // Остаётся только получить дату с временем 00:00 // А это просто iTime(_Simbol, PERIOD_D1, 0); // и потом сложить эти значения.
Но! время можно задать как строку string strTime = "7:33"; и перевести в тип datrtime функцией StringToTime(). В результате будет время с сегодняшней датой.
Но! время можно задать как строку string strTime = "7:33"; и перевести в тип datrtime функцией StringToTime(). В результате будет время с сегодняшней дато@ifitstrue
Еще пару вопросов, если позволите.
Сейчас время задаю статично.
Как сделать так, чтобы время и число текущего дня само подставлялось в дату?
если на словах - текущее время преобразуйте в структуру MqlDateTime, в структуре обнулите всё кроме даты, и далее конвертацию из переменной типа структуры MqlDateTime в значение типа datetime. Получите время открытия дня.
функции TimeToStruct, StructToTime
Но! время можно задать как строку string strTime = "7:33"; и перевести в тип datrtime функцией StringToTime(). В результате будет время с сегодняшней датой.
Вот так?
//-------------------------------------------------------------------- // separatewindow.mq4 // Предназначен для использования в качестве примера в учебнике MQL4. //-------------------------------------------------------------------- #property indicator_separate_window // Отображение в отдельном окне #property indicator_buffers 2 // Количество буферов #property indicator_color1 Blue // Цвет первой линии #property indicator_color2 Red // Цвет второй линии string strTime = "00:00"; double Buf_0[],Buf_1[]; double Sum_H=0; double Sum_L=0; //-------------------------------------------------------------------- int init() // Специальная функция init() { SetIndexBuffer(0,Buf_0); // Назначение массива буферу SetIndexStyle (0,DRAW_LINE,STYLE_SOLID,2);// Стиль линии SetIndexBuffer(1,Buf_1); // Назначение массива буферу SetIndexStyle (1,DRAW_LINE,STYLE_SOLID,2);// Стиль линии return(0); // Выход из спец. ф-ии init() } //-------------------------------------------------------------------- int start() // Специальная функция start() { int i, // Индекс бара Counted_bars; // Количество просчитанных баров //-------------------------------------------------------------------- Counted_bars=IndicatorCounted(); // Количество просчитанных баров datetime time=StringToTime(strTime); int bar_index=iBarShift(Symbol(),PERIOD_CURRENT,time,false); i=Bars-Counted_bars-1; // Индекс первого непосчитанного if (i>bar_index-1) i=bar_index; while(i>=0) // Цикл по непосчитанным барам { if(Open[i]<Close[i]) { Sum_H=Sum_H+(Close[i]-Open[i]); Sum_L=Sum_L; } if(Open[i]>Close[i]) { Sum_L=Sum_L+(Open[i]-Close[i]); Sum_H=Sum_H; } Buf_0[i]=Sum_H;// Знач. 0 буфера на i-ом баре Buf_1[i]=Sum_L;// Знач. 1 буфера на i-ом баре i--; // Расчёт индекса следующего бара } //-------------------------------------------------------------------- return(0); // Выход из спец. ф-ии start() } //--------------------------------------------------------------------
Вот так?
Да. Только это преобразование будет производиться на каждом тике, что нежелательно. В самом простом случае лучше перенести его в OnInit(). Если же нужно корректировать день в процессе работы, то сделайте расчет один раз в сутки:
static datetime dtLastDay = 0; if (iTime(NULL, PERIOD_D1, 0) != dtLastDay) { dtLastDay = iTime(NULL, PERIOD_D1, 0); time = StringToTime(strTime); }
Да. Только это преобразование будет производиться на каждом тике, что нежелательно. В самом простом случае лучше перенести его в OnInit(). Если же нужно корректировать день в процессе работы, то сделайте расчет один раз в сутки:
Спасибо!
А тут в чем косяк?
Когда вешаю индикатор на чарт, то всё нормально. Но поступают новые данные на 0 баре и начинает рисовать хрень. Почему?
Когда вешаю индикатор на чарт, то всё нормально. Но поступают новые данные на 0 баре и начинает рисовать хрень. Почему?
Проблемы алгоритма. Переменные SumL и SumH объявлены глобально. В момент загрузки индикатора их значения равны нулю. Происходит обработка данных на всей доступной истории и переменные получают уже ненулевые значения. Затем приходит новый тик и обрабатывается уже не вся история, а только текущий бар или два последних бара. А в переменных записаны значения уже с учетом этих баров.
Нужно что-то придумать с сохранением правильных значений SumL и SumH так, чтобы в случае обработки не всей истории в них были соответствующие данные.
Я обычно решаю такие проблемы перерисовкой всей истории, если обнаружено появление более, чем одного бара. А для двух последних баров сохранить данные не представляет труда.
Здравствуйте. Взял индикатор из учебника, немного переделал. Теперь хочу сделать так чтобы он начинал свой расчет и отрисовывался от первого бара дня.
Сейчас он начинает считать от указанного количества баров истории.
Прошу помочь.