Версия 10.1.2.2
Дано: график с двумя областями, в одной инструмент имеет свечек больше, чем во второй, из-за чего во второй области, когда всё загружено, видны гэпы. Пример - EUR (данные с форекса у меня транслируются откуда-то) и SiU3 (или фьючерс и базовый актив, или RTSI + IMOEX2). Таймфрейм 1 или 5 минут, торги активны. На том инструменте, где есть гэпы, ставим два индикатора с одинаковыми параметрами (кроме может быть визуальных) - встроенный SMA и SMA из примеров , с изменением для определения скачка номеров свечей:
Этот индикатор должен быть одним из верхних (значит - приоритетных) в области.
Нажимаем Ok после добавления индикаторов. Если в сообщениях не появилось про гэпы ничего, но они есть, меняем таймфрейм туда-сюда между 1 и 5 минутами, рано или поздно у меня появляется сообщение в духе:
gap at 6061 Fri Jun 16 14:40:00 2023, jump from 4139
Почему? Потому что, видимо, квик случайным образом выбирает, какую область графика рисовать первой: ту, где гэпы возникнут после отрисовки всех областей, или ту, где свечей "больше". Если сначала рисовать более "полную" область, то во второй области индекс не прыгает, просто для отсутствующих свечей будет C(Index) = nil. Если сначала рисовать менее полную область, то индексы сначала не прыгают, все C(Index) ~= nil, потом грузится вторая область, потом при новых данных OnCalculate(Index) начинает получать внезапно большой Index (дебаг принты через PrintDbgStr номеров свечей и их времени):
... и при обращении к старым индексам уже можно получить C(i) == nil, т.к. попадёшь на гэп.
Так вот, я считаю такое поведение багом, ибо это препятствует кэшированию результатов по индексам. Например, начиная с этой свечи данные индикаторов из моего примера начинают различаться, встроенный SMA продолжает быть равным, скажем, аналогичному от TradingView, а индикатор из официальных примеров начинает немного врать. Врёт он потому, что внутри себя создаёт таблицу, индекс которой зависит от номера свечки.
Как такой баг победить? Предлагаю сначала для всех областей всех графиков "вычислять" только price (и может быть volume). После этого должно быть понятно, где будут пропуски свечей на каких областях, т.е. после этого индексы ВСЕХ старых свечей должны быть фиксированы до следующего добавления какой-нибудь области в какой-нибудь график. После этого можно вычислять и отрисовывать остальные индикаторы.
Альтернативно - дать юзеру опцию вычислять свои индикаторы в конце цикла вычисления по данному графику (вне зависимости от того, высоко он должен быть отрисован или нет), чтобы он вычислялся в ситуации, когда старые свечки не могут поменять свой индекс, и можно было бы кэшировать.
Дано: график с двумя областями, в одной инструмент имеет свечек больше, чем во второй, из-за чего во второй области, когда всё загружено, видны гэпы. Пример - EUR (данные с форекса у меня транслируются откуда-то) и SiU3 (или фьючерс и базовый актив, или RTSI + IMOEX2). Таймфрейм 1 или 5 минут, торги активны. На том инструменте, где есть гэпы, ставим два индикатора с одинаковыми параметрами (кроме может быть визуальных) - встроенный SMA и SMA из примеров , с изменением для определения скачка номеров свечей:
| Код |
|---|
function OnCalculate(Index)
if prev_index and Index > prev_index + 1 then
message(string.format("gap at %d %s, jump from %d", Index, os.date("%c", os.time(T(Index))), prev_index), 1)
end
prev_index = Index
return tonumber(Settings.Horizontal_line),ConvertValue(Settings,func(Index, Settings))
end
|
Нажимаем Ok после добавления индикаторов. Если в сообщениях не появилось про гэпы ничего, но они есть, меняем таймфрейм туда-сюда между 1 и 5 минутами, рано или поздно у меня появляется сообщение в духе:
gap at 6061 Fri Jun 16 14:40:00 2023, jump from 4139
Почему? Потому что, видимо, квик случайным образом выбирает, какую область графика рисовать первой: ту, где гэпы возникнут после отрисовки всех областей, или ту, где свечей "больше". Если сначала рисовать более "полную" область, то во второй области индекс не прыгает, просто для отсутствующих свечей будет C(Index) = nil. Если сначала рисовать менее полную область, то индексы сначала не прыгают, все C(Index) ~= nil, потом грузится вторая область, потом при новых данных OnCalculate(Index) начинает получать внезапно большой Index (дебаг принты через PrintDbgStr номеров свечей и их времени):
| Код |
|---|
[21996] 4460 2023-06-16 12:54:00 [21996] 4461 2023-06-16 12:55:00 [21996] 4462 2023-06-16 12:56:00 [21996] 10813 2023-06-16 12:56:00 [21996] 10813 2023-06-16 12:56:00 [21996] 10813 2023-06-16 12:56:00 |
Так вот, я считаю такое поведение багом, ибо это препятствует кэшированию результатов по индексам. Например, начиная с этой свечи данные индикаторов из моего примера начинают различаться, встроенный SMA продолжает быть равным, скажем, аналогичному от TradingView, а индикатор из официальных примеров начинает немного врать. Врёт он потому, что внутри себя создаёт таблицу, индекс которой зависит от номера свечки.
Как такой баг победить? Предлагаю сначала для всех областей всех графиков "вычислять" только price (и может быть volume). После этого должно быть понятно, где будут пропуски свечей на каких областях, т.е. после этого индексы ВСЕХ старых свечей должны быть фиксированы до следующего добавления какой-нибудь области в какой-нибудь график. После этого можно вычислять и отрисовывать остальные индикаторы.
Альтернативно - дать юзеру опцию вычислять свои индикаторы в конце цикла вычисления по данному графику (вне зависимости от того, высоко он должен быть отрисован или нет), чтобы он вычислялся в ситуации, когда старые свечки не могут поменять свой индекс, и можно было бы кэшировать.