Блог им. Mihalich81
-- //////////////////////////
-- // Блок перерасчёта данных индикатора
-- //////////////////////////
-- Автор: Михаил Понамаренко (pmntrade.ru)
-- Версия: 20261016
-- Данный блок актуален только для индикаторов, которые используют несколько графиков одновременно,
-- например, арбитражные.
-- В некоторых ситуациях (получение новых данных сессии терминалом, переключение таймфреймов диаграммы)
-- индикатор не отображает или отображает неверно данные. Связано это с тем, что,
-- во многих случаях, сначала рассчитываются данные индикатора, а затем терминал получает данные графиков.
-- Соответственно, индикатор отображается без данных или с некорректными данными.
-- Для решения проблемы было решено создать определённый алгоритм.
-- 1. При запуске индикатора определяем, что он загружен и обрабатывается последний бар с учётом факта, что индикатор загружается 2 раза (вероятно ошибка в QUIK). <a name="cut"></a>
-- 2. Происходит сравнение значения предпоследнего бара на индикаторе и данных полученных в результате перерасчёта.
-- 3. Если данные не совпадают, проверяем не является ли этот график относительным (дв.клик лев.кн.мыши на названии графика/индикатора-
-- Дополнительно-галочка Абсолютное значение-в поле ниже число от которого будем считать изменение в процентах.)
-- Для относительных графиков решения нет, т.к. нет возможности из LUA получить переменную, является ли график относительным.
-- 4. Если график не относительный, происходит перерасчёт всех значений индикатора и одновременный вывод на график.
-- 5. Получаем правильно рассчитанный график истории при перезаказе данных (новой сессии) и переключении таймфреймов.
-- Для получения ситуации новой сессии нужно перейти в QUIK:
-- Заказ данных - Перезаказать данные... - галочки Торговые данные текущей сессии, Локальные справочники.
-- Если после перезаказа данных история индикатора отображается,
-- нужно заменить инструмент индикатора на другой из диаграммы.
-- Если применяется относительный график (дв.клик лев.кн.мыши на названии графика/индикатора-
-- Дополнительно-галочка Абсолютное значение-в поле ниже число от которого будем считать
-- изменение в процентах.), то в параметр "Name" нужно добавить символ "%", например, "Арбитраж PRO%".
-- При этом блок перерасчёта данных будет отключён и данные могут быть некорректны при перезаказе
-- данных (новой сессии) и переключении таймфреймов.
-- В функции CalculateData(i) должен находится код для расчёта индикатора.
-- Переменная reget позволяет перерасчёт только один раз при расчёте индикатора от первого бара.
if string.find(Settings["Name"], "%%", 0) then reget = true end -- если блок перерасчёта данных отключён
if reget == nil then -- если действует флаг единоразового исполнения перерасчёта данных
-- При запуске индикатор расчитывается 2 раза (причины не ясны, вероятно ошибка разработчиков).
-- Если индекс в новом расчёте индикатора повторяется, значит индикатор загружен.
-- Блок ниже сработает только при новом тике инструмента, привязанного к индикатору.
if preindex == index then -- индекс повторяется, индикатор загружен
if GetValue(Bars, 1) ~= nil then -- если есть значение последнего бара на индикаторе
if GetValue(Bars - 1, 1) ~= CalculateData(Bars - 1) then -- если значение предпоследнего бара на индикаторе не совпадает с данными перерасчёта
for i = 1, index - 1 do -- перебор баров до предпоследнего
SetValue(i, 1, tonumber(CalculateData(i) or nil)) -- Индекс свечи начиная с 1,Номер линии индикатора начиная с 1,Число которое нужно установить либо nil
end -- выход из цикла: перебор баров до предпоследнего
reget = true -- флаг единоразового исполнения перерасчёта данных, true - перерасчёт выполнен
else -- иначе значение предпоследнего бара на индикаторе совпадает с данными перерасчёта
reget = true -- флаг единоразового исполнения перерасчёта данных, true - перерасчёт выполнен
end -- выход из условия: если нет значения предпоследнего бара на индикаторе
end -- выход из условия: если есть значение последнего бара на индикаторе
end -- выход из условия: индекс повторяется
end -- выход из условия: если действует флаг единоразового исполнения перерасчёта данных
if index == 1 then reget = nil end -- обнуление флага единоразового исполнения перерасчёта данных
preindex = index -- запись индекса, для проверки на следующем расчёте