How to code an indicator properly - страница 3

 

У меня ещё возникла проблема в индикаторе.

На этот раз с MapViewOfFile из kernel32.dll

Суть проблемы: на первом запуске терминала и первом запуске индикатора, 
именованный MapViewOfFile отрабатывает корректно и возвращает указатель ранее созданного файла на память.
После удаления индикатора, файл на память закрываю корректно, а переменные заNULLяются.
Но после повторного запуска индикатора возникает ошибка из 
kernel32::GetLastError():

MapViewOfFile: ошибка получения указателя на первый элемент памяти Local\File_: 5

Помогает перезагрузка терминала, до первого удаления индикатора, потом снова эта ошибка.
В эксперте такой проблемы не наблюдается.

Кому из MQ разработчиков можно скинуть код, для воспроизведения ошибки ?

 
Roman #:
Жёлтым выделил крайний индекс, по идее уже аллоцированного на +1 буфера в момент нового бара, куда кладётся актуальное значение!
Почему система этого не понимает?
Потому, что ошибка в поведении к которой вы приспособились!
И выдаёте это, что так было всегда. НЕТ не было так всегда, это появилось несколько лет назад, и все схавали.

Желтым ваше выделенное срабатывает уже ПОСЛЕ того, как лишний вызов ArrayCopy сдвинул ВЕСЬ индикаторный буфер вместе с пустым новым элементом влево. Вы кладете значение в последний элемент, но строкой выше он был еще пустой и эта пустота скопирована в 1-й бар. Чего не понятно?

Всегда так работало в МТ5. Прям удивительно такие стандартные вещи объяснять.

 
Stanislav Korotky #:

Желтым ваше выделенное срабатывает уже ПОСЛЕ того, как лишний вызов ArrayCopy сдвинул ВЕСЬ индикаторный буфер вместе с пустым новым элементом влево. Вы кладете значение в последний элемент, но строкой выше он был еще пустой и эта пустота скопирована в 1-й бар. Чего не понятно?

Всегда так работало в МТ5. Прям удивительно такие стандартные вещи объяснять.

Да, в текущей реализации со сдвигом значений в ArrayCopy получается так как вы пишите. В понимании этого момента вопросов нет.

Как объясните тогда поведение без ArrayCopy ?
Когда отрисовка начинается только с приходом нового бара.
При этом значения в углу подокна изменяются.
Это же всё взаимосвязано, первая отрисовка и сдвиг буфера.
То есть первая отрисовка в текущей реализации
buff[rates_total-1] = SymbolInfoDouble(_Symbol, SYMBOL_BID);
будет только с приходом нового бара, возможно это и есть некорректный лаг буферного сдвига! 
Повторюсь, раньше же как то без пропусков всё отрисовывалось и начинало рисовать с момента старта, а не с приходом бара.
Это некорректное изменение появилось давно, просто не писал об этом.
Бета-версия платформы MetaTrader 5 build 5770: Расширение OpenBLAS и удобная работа с CSV в MetaEditor
Бета-версия платформы MetaTrader 5 build 5770: Расширение OpenBLAS и удобная работа с CSV в MetaEditor
  • 2026.04.15
  • www.mql5.com
В четверг 9 апреля 2026 года будет выпущена обновленная версия платформы MetaTrader 5 в бета-режиме...
 
Roman #:
То есть первая отрисовка в текущей реализации
будет только с приходом нового бара, возможно это и есть некорректный лаг буферного сдвига! 
Первая отрисовка будет тогда, когда появится вторая точка для отрисовки линии.
У Вас же в коде:
PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_LINE);

Ощущение, что вы не вникаете в ответы, а спорите с оппонентами. Вот же уже писали об этом: https://www.mql5.com/ru/forum/508121/page5#comment_59586457

 

То есть ждём когда же появиться там вторая точка?
На D1 будете сутки ждать? А на W1? Ещё скажите, что это особенность.
Детский сад какой то, а не программисты. Защищают кривую реализацию.
Со своими ИИ совсем отошли от логического мышления.

 
Sergey Gridnev #:


Запустите хотя-бы на М5, и посмотрите когда отрисуется графическое отображение.
Текущая реализация не корректна и это не есть нормально!
В текущей реализации первая точка для отрисовки создаётся на открытии бара, а не от первого переданного значения в буфер.
Сказки про начальные две точки не надо рассказывать, они легко создаются при желании корректного подхода.


#property indicator_separate_window
#property indicator_plots 1
#property indicator_buffers 1

double buff[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   SetIndexBuffer(0, buff, INDICATOR_DATA);
   PlotIndexSetInteger(0, PLOT_DRAW_TYPE,  DRAW_LINE);
   PlotIndexSetInteger(0, PLOT_LINE_STYLE, STYLE_SOLID);
   PlotIndexSetInteger(0, PLOT_LINE_COLOR, clrRed);
   PlotIndexSetInteger(0, PLOT_LINE_WIDTH, 1);
   PlotIndexSetString(0,  PLOT_LABEL,"Bid"); 
   PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0.0);   
   IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
   
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
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[])
{


   //вставка последнего значения
   buff[rates_total-1] = SymbolInfoDouble(_Symbol, SYMBOL_BID);


   return(rates_total);
}
 
Roman #:

Сказки про начальные две точки не надо рассказывать, они легко создаются при желании корректного подхода.

В этом коде задаётся значение только для одной точки построения каждый тик и всё.

Вам надо хорошо изучить всё здесь: https://www.mql5.com/ru/book/applications/indicators_make/indicators_setindexbuffer

А потом пример здесь: https://www.mql5.com/ru/docs/customind/indicators_examples/draw_line, увидите в нём цикл for в OnCalculate.

 
Andrei Iakovlev #:

В этом коде задаётся значение только для одной точки построения каждый тик и всё.

Вам надо хорошо изучить всё здесь: https://www.mql5.com/ru/book/applications/indicators_make/indicators_setindexbuffer

А потом пример здесь: https://www.mql5.com/ru/docs/customind/indicators_examples/draw_line, увидите в нём цикл for в OnCalculate.

Вам надо понять какая проблема обсуждается, а не предлагать решения которые не относятся к проблеме!
Как обрабатывать (rates_total - prev_calculated) я прекрасно знаю и для каких это решений применяется.
Хватит писать всякую ерунду.
 
Roman #:
Хватит писать всякую ерунду.

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

ArrayCopy(buff, buff, 0, 1, rates_total-1);

Вот это первая ерунда которой не должно было быть. 

 
Andrei Iakovlev #:

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

Вот это первая ерунда которой не должно было быть. 

Да что вы говорите? конечно в ваших познаниях циклы эффективней, чем сдвиг по указателю.
Сделайте тоже самое с обычным статичным массивом, что равносильно max баров в окне для буфера.
Напрочь никто не желает думать, прежде чем пишут!
Вас сюда никто не звал, писать свои убогие комментарии, не к вам была адресована проблема, а к разработчикам.
Идите мимо молча.