Сначала определите обещание индикатора. Если он показывает предварительное состояние текущей свечи, движение линии нормально. Если он помечает сигнал как окончательный, а после перезагрузки переносит или удаляет метку, это вводящая в заблуждение перерисовка.
TradingView определяет repainting широко: исторические и realtime-расчеты или графика ведут себя по-разному. В официальной документации Repainting отмечено, что такое поведение распространено и не всегда бесполезно. Критичны прозрачность и соответствие задаче.
Откуда берется различие истории и реального времени
Исторический бар известен целиком: open, окончательные high и low, close, volume. Открытый realtime-бар содержит только текущий снимок. На следующем тике его high, low, close и volume могут измениться.
После перезагрузки вчерашний realtime-бар становится историческим и рассчитывается один раз по финальным значениям. Все промежуточные состояния исчезают. Поэтому условие, истинное в середине свечи, может отсутствовать в восстановленной истории.
Тип 1. Сигнал на незакрытом баре
Пример — пересечение цены и средней. В середине часа цена выше SMA, затем закрывается ниже. Индикатор, рассчитываемый на каждом обновлении, закономерно покажет временное пересечение.
Есть три честных режима:
| Режим | Плюс | Минус | Реализация |
|---|---|---|---|
| Предварительный | Раннее предупреждение | Возможна отмена | Явно пометить realtime-сигнал |
| Подтвержденный | Воспроизводимая история | Задержка до close | barstate.isconfirmed |
| По прошлому бару | Максимальная стабильность | Еще один бар задержки | Использовать [1] |
Пример подтверждения:
//@version=6
indicator("Confirmed cross", overlay = true)
float average = ta.sma(close, 20)
bool crossed = ta.crossover(close, average)
bool confirmedSignal = crossed and barstate.isconfirmed
plot(average)
plotshape(confirmedSignal, style = shape.triangleup, location = location.belowbar)
Для алерта одного кода мало: выберите частоту Once Per Bar Close. Как связаны частота и снимок скрипта, описано в статье как работают алерты TradingView.
Тип 2. Неподтвержденные данные старшего таймфрейма
На пятиминутном графике дневной close текущего дня меняется до окончания дня. request.security() может возвращать это развивающееся значение. После перезагрузки дневной бар уже закрыт, поэтому история выглядит стабильнее, чем реальный процесс.
Распространенный шаблон для последнего подтвержденного HTF-значения:
float dailyClose = request.security(
syminfo.tickerid,
"1D",
close[1],
lookahead = barmerge.lookahead_on
)
Смещение выражения на один HTF-бар не дает взять текущий незакрытый close, а lookahead_on распределяет уже известное прошлое значение по текущему периоду. Этот шаблон нельзя бездумно применять к равному или младшему таймфрейму. Проверяйте отношение интервалов и при необходимости вызывайте runtime error.
Подробные варианты поведения запросов собраны в официальном разделе Other timeframes and data.
Тип 3. Утечка будущего через lookahead
Самая опасная форма возникает, когда исторический код получает значение старшего периода раньше, чем оно было известно. barmerge.lookahead_on без смещения expression может разнести финальный close дня по всем внутридневным барам этого же дня. На истории стратегия видит будущее.
Признаки:
- почти идеальные входы в начале периода;
- резкое ухудшение в realtime;
- сигналы исчезают при замене
lookahead_onнаlookahead_off; - результат зависит от наличия
[1]внутри expression.
Правило проверки: для каждого значения спросите, в какой точный момент оно стало известно. Если код использует его раньше, это lookahead bias, даже когда компилятор молчит.
Тип 4. Pivot и расчеты с правыми барами
Pivot High с параметром rightBars = 5 подтверждается только через пять баров после вершины. Сам алгоритм не обязан быть плохим: он честно использует будущие относительно pivot-точки бары и сообщает результат позже.
Вводящая в заблуждение визуализация рисует метку на вершине через отрицательный offset без объяснения задержки. Пользователь видит идеальный разворот в прошлом и предполагает, что сигнал появился там же.
Корректные варианты:
- рисовать метку на баре подтверждения;
- рисовать ее в точке pivot, но явно указывать задержку;
- не использовать такой сигнал для входа раньше подтверждения;
- в тесте исполнять решение на доступном баре, а не на прошлом.
Тип 5. Синтетические свечи и источники
Heikin Ashi и другие нестандартные графики строят расчетные OHLC. История выглядит гладкой, но синтетический close не обязательно существовал как доступная цена сделки. Стратегия может казаться стабильной и прибыльной из-за исполнения по этим значениям.
Для торговых решений запрашивайте обычные данные точного тикера и проверяйте исполнение на реальном источнике. Почему источники могут отличаться, разобрано в материале котировки TradingView и брокера.
Другие источники изменения истории
Изменение набора данных
Поставщик может исправить историю, биржа — скорректировать сделку, а continuous futures — перейти на новый контракт. Это не ошибка Pine, но результат скрипта изменится.
Расчет с timenow
timenow отражает время выполнения, а не фиксированное свойство исторического бара. Логика, зависящая от него, не обязана воспроизводиться после перезапуска.
Случайные или внешние состояния
Если данные приходят из изменяемого внешнего источника, прошлый расчет может отличаться. Зафиксируйте версию данных или явно сообщите, что история пересчитывается.
Как проверить индикатор на перерисовку
Тест перезагрузкой
- Откройте ликвидный символ на небольшом таймфрейме.
- Сделайте скриншот сигналов на последних барах.
- Дождитесь нескольких обновлений и закрытия бара.
- Перезагрузите страницу или удалите и добавьте индикатор.
- Сравните положения и число меток.
Тест realtime против confirmed
Выведите две серии: текущую и подтвержденную. Отдельный цвет покажет, где возникает различие.
Аудит request.security
Для каждого вызова запишите:
- символ;
- таймфрейм;
- expression;
- gaps;
- lookahead;
- используется текущий или прошлый бар;
- когда значение фактически доступно.
Проверка стратегии
Сопоставьте время сигнала и время исполнения. Стратегия не должна входить на баре, данные которого стали известны только позже. Общий аудит допущений есть в статье основные ошибки бэктестинга.
Как исправлять без потери смысла
Не любое исправление сводится к [1]. Задержка может уничтожить торговую идею. Сначала выберите контракт с пользователем:
- нужен ранний изменяемый сигнал;
- нужен подтвержденный сигнал;
- нужны оба, но с разным оформлением;
- нужен прогноз, качество которого оценивается только по realtime-логу.
Если нужен ранний режим, окрасьте предварительную метку иначе и не смешивайте ее со статистикой подтвержденных сигналов. Если нужен подтвержденный, примените bar state, закрытие бара и стабильный HTF-запрос. Для алертов после изменения обязательно пересоздайте серверную копию.
Вывод
Перерисовка — это несоответствие между тем, что было доступно тогда, и тем, как история выглядит сейчас. Открытый бар и текущий HTF могут меняться законно; будущие данные и перенос метки назад создают ложную картину. Надежный индикатор либо ждет подтверждения, либо ясно показывает предварительный статус и сохраняет realtime-результаты для честной проверки.
