Перейти к содержимому
Trading Terminal
Личный кабинет
Опубликовано

Pine Script v6: что изменилось и как перенести код с v5

Pine Script v6 меняет не только синтаксис. Перед переносом проверьте bool и na, ленивые and/or, динамические request.*, параметры стратегий, маржу, division int и участки с зависимостью от порядка вычислений.

Pine ScriptTradingViewразработка
Переход кода Pine Script с версии 5 на версию 6

Автоматический конвертер — старт, а не доказательство корректности. Pine v6 меняет систему типов и отдельные правила исполнения. Код может успешно компилироваться и при этом давать другой набор сигналов, заявок или запрошенных данных.

Главные изменения в одной таблице

Область Было в v5 Стало в v6 Риск при переносе
Число в bool-контексте Допускалось неявное приведение Нужен явный bool() или сравнение Ошибка компиляции
Значение bool true, false, na Только true или false Потеря третьего состояния
and и or Операнды могли вычисляться заранее Ленивое вычисление Побочный вызов может не выполниться
request.*() По умолчанию статические По умолчанию динамические Другой контекст данных
strategy.*(when=...) Параметр использовался Параметр удален Нужно условное ветвление
Маржа стратегии Старые defaults Long и short по умолчанию 100% Меняется доступный размер позиции
Деление const int Могло давать целое Может вернуть дробное Меняется формула
Лимит сделок Ошибка после 9000 Старые сделки обрезаются История результатов меняется

Полный перечень и примеры опубликованы в официальном руководстве по переходу на Pine Script v6. Перед работой сохраните исходную v5-версию отдельно.

Карта миграции Pine Script v5 в v6

Как запускать миграцию

Pine Editor конвертирует только v5-код, который уже компилируется. Исправьте старые ошибки до перехода, затем выберите Convert code to v6 в меню управления скриптом.

Рабочий порядок:

  1. сделайте копию v5 под новым именем;
  2. зафиксируйте настройки inputs и свойства стратегии;
  3. выгрузите список сделок или сделайте контрольные скриншоты;
  4. запустите конвертер;
  5. устраните ошибки компиляции по одной группе;
  6. сравните значения ключевых series на одних барах;
  7. сравните входы, выходы и размер позиции;
  8. только после этого заменяйте опубликованную версию.

Bool больше не бывает na

В v5 логика могла различать true, false и na. Например, направление позиции до первого входа было неизвестно. В v6 неизвестный boolean превращается в false, а na(), nz() и fixnan() больше не принимают bool.

Старый замысел:

true  = long
false = short
na    = позиции нет

В v6 его лучше выразить числом:

//@version=6
int direction = if strategy.position_size > 0
    1
else if strategy.position_size < 0
    -1
else
    0

Это не косметическая правка. Если просто удалить проверку na, состояние «нет позиции» смешается с short и может покрасить фон, включить алерт или вызвать выход не в тот момент.

Числа также больше не приводятся к bool неявно. Вместо if bar_index пишите конкретное условие: if bar_index > 0. Явное сравнение читается лучше, чем bool(bar_index), потому что сообщает намерение.

Ленивые and и or

В v6 правая часть and вычисляется только когда левая истинна, а правая часть or — только когда левая ложна. Это стандартное короткое замыкание и позволяет безопасно проверять границы:

bool hasPrevious = bar_index > 0 and close[1] > open[1]

Но код с расчетом или изменением состояния внутри функции справа может повести себя иначе. Функции, от которых зависит series, лучше вычислять заранее и сохранять в переменную:

float average = ta.sma(close, 20)
bool signal = enabled and close > average

Так серия средней строится на каждом баре, а условие остается прозрачным.

Динамические request.* по умолчанию

В v6 request.security() и другие request.*() могут использовать series-аргументы для символа и таймфрейма, выполняться в циклах и локальных блоках. Компилятор отключает динамический режим, когда он не требуется.

Это упрощает мультисимвольные индикаторы, но повышает требования к проверке:

  • какие наборы данных реально запрашиваются;
  • доступна ли история для всех символов;
  • нет ли будущих данных через lookahead;
  • одинаково ли ведет себя вложенный запрос;
  • укладывается ли скрипт в лимиты уникальных запросов.

Если v5-скрипт после конвертации получает другие значения, официальный migration guide предлагает для диагностики явно поставить dynamic_requests = false, когда структура кода это допускает. Не оставляйте флаг только ради совпадения: сначала поймите, какой контекст изменился.

Изменения стратегий

Параметр when удален

Вместо:

strategy.entry("Long", strategy.long, when = longCondition)

используйте:

if longCondition
    strategy.entry("Long", strategy.long)

Отдельный блок проще отлаживать и расширять проверками сессии, риска и состояния позиции.

Маржа по умолчанию стала 100%

Если v5-тест не задавал margin_long и margin_short, результат v6 может измениться. Зафиксируйте свойства стратегии явно и сравнивайте одинаковые настройки. Не подгоняйте маржу под красивую кривую — она должна отражать реальный счет и правила инструмента.

strategy.exit обрабатывает относительные и абсолютные параметры иначе

В v6 вызов больше не игнорирует относительные параметры автоматически, когда одновременно заданы связанные абсолютные. Код с profit и limit, loss и stop, trailing-параметрами нужно просмотреть вручную. Один выход должен иметь однозначную модель цены.

Старые ордера обрезаются после лимита

Вместо ошибки при превышении 9000 сделок стратегия удаляет самые старые из отчета. Это удобнее для длинного теста, но начало выборки становится подвижным. Записывайте фактический диапазон сделок, а не только даты графика.

Подробнее модель стратегий, комиссии, проскальзывание и Bar Magnifier описаны в официальной документации Strategies.

Другие несовместимости, которые легко пропустить

Деление констант

Результат деления двух const int может стать дробным. Проверьте вычисления периодов, долей и индексов. Если нужен целый результат, выразите округление явно.

timeframe.period всегда содержит множитель

Дневной период возвращается как 1D, а не D. Сравнения строк и формирование ключей нужно обновить.

transp удален

Прозрачность задается через color.new(baseColor, transparency). Это обычно механическая правка, но динамический цвет удобнее вычислить один раз.

Уникальные типы не принимают na

Параметры вроде стиля plot должны получать конкретную константу. if требует ветку else, а switch — fallback, если иначе могло получиться na.

Граница for пересчитывается

Конечное значение цикла теперь может оцениваться перед каждой итерацией. Не меняйте внутри цикла коллекцию, от размера которой зависит граница, без явного плана завершения.

Как проверить эквивалентность v5 и v6

Не начинайте с чистой прибыли. Итоговая цифра скрывает место первого расхождения.

Сравнивайте слоями:

  1. исходные OHLCV и requested series;
  2. промежуточные индикаторы;
  3. логические условия;
  4. номера баров сигналов;
  5. цену и время моделируемого исполнения;
  6. размер позиции;
  7. комиссии и проскальзывание;
  8. итоговые метрики.

Временно выводите расхождение через plot, label или table. Первый бар, где значения разошлись, обычно указывает на конкретное изменение языка. Если сигналы меняются после перезагрузки, дополнительно проверьте причины перерисовки. Если отчет стратегии выглядит слишком хорошо, используйте чек-лист ошибок бэктестинга.

Стоит ли переводить старый рабочий скрипт

Оставить v5 разумно, когда скрипт стабилен, критичен для работы и не требует функций v6. Новую разработку лучше начинать с v6: актуальная документация и примеры ориентированы на него.

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

Официальные изменения продолжают выходить, поэтому перед использованием новой функции сверяйтесь с release notes Pine Script, а не с устаревшим примером из форума.

Вывод

Самые рискованные изменения v6 находятся в поведении, а не в строке //@version=6. Bool потерял третье состояние, запросы стали динамическими, логические операторы — ленивыми, а стратегия получила новые defaults. Автоконвертер экономит ручную работу, но эквивалентность подтверждается только послойным сравнением на одинаковых данных.

Частые вопросы

Нужно ли переводить рабочий скрипт с Pine v5 на v6?

Срочной необходимости нет, если v5-скрипт компилируется и дает проверенный результат. Миграция полезна для новых возможностей, но ее нужно рассматривать как изменение поведения и перепроверять результаты.

Можно ли автоматически конвертировать Pine v5 в v6?

Да, Pine Editor умеет конвертировать компилирующийся v5-код. Конвертер закрывает типовые правки, но не подтверждает эквивалентность торговой логики и результатов стратегии.

Как в v6 хранить третье состояние bool?

Boolean в v6 имеет только true и false. Если логике нужны три состояния, используйте enum-подобную строку или int, например -1, 0 и 1.

Почему стратегия после миграции показывает другой результат?

Причиной могут быть новые значения маржи по умолчанию, поведение strategy.exit, удаленный параметр when, динамические запросы или изменившееся вычисление выражений. Сравнивайте сделки и настройки по одному фактору.