Стратегии – Robo.trading

Стратегии

  • Пример простой стратегии
  • Применение стратегии к графику
  • Бэктестинг и форвард-тестирование
  • Эмулятор брокера
  • Команды размещения ордеров
  • Закрытие рыночной позиции
  • Группы ОСА
  • Риск-менеджмент
  • Валюта
  • Перерисовка индикаторов

Стратегия — это Pine скрипт, который может отправлять, изменять и отменять ордера на покупку/продажу. Стратегии позволяют выполнять бэктестинг (эмуляцию стратегии, торгующей на исторических данных) и форвардтестинг (эмуляцию стратегии, торгующей на данных в реальном времени) в соответствии с вашими алгоритмами.

Стратегия, написанная на Pine, имеет многие из тех же возможностей, что и индикатор Pine. Когда вы пишете стратегию, она должна начинаться с вызова аннотации strategy (вместо study). Стратегии могут отображать данные, но они также могут размещать, изменять и отменять заказы. Они также имеют доступ к важной информации об эффективности стратегии по определенным ключевым словам. Эта же информация доступна извне на вкладке Тестера стратегий. После того, как стратегия рассчитана на исторических данных, вы можете увидеть гипотетическое исполнение ордеров.

Пример простой стратегии

Как только скрипт скомпилирован и применен к графику, вы можете увидеть на нем отметки заполненных ордеров и то, как изменялся ваш баланс во время тестирования на истории (кривая капитала). Это очень простая стратегия, которая предполагает покупку и продажу на каждом баре.

В строке strategy(«test») указано, что скрипт представляет собой стратегию с именем «test». strategy.entry() это команда, которая может использоваться для отправки ордеров как на покупку, так и на продажу. plot(strategy.equity) строит кривую капитала.

//@version=4
strategy("test")
if bar_index > 4000
strategy.entry("buy", strategy.long, 10, when=strategy.position_size <= 0)
strategy.entry("sell", strategy.short, 10, when=strategy.position_size > 0)
plot(strategy.equity)

Применение стратегии к графику

Чтобы проверить свою стратегию, примените ее к графику. Используйте тикер и временные интервалы, которые вы хотите протестировать. Вы можете использовать встроенную стратегию из диалогового окна «Индикаторы и стратегии» или написать свою собственную.

Примечание

При применении стратегий к нестандартным типам графиков (Heikin Ashi, Renko и т.д.) очень важно понимать, что результаты не будут отражать реальные рыночные условия. Ордера на графиках этих типов будут исполняться на синтетических уровнях цен, используемых на этих графиках, которые часто не отражают реальные рыночные цены и, таким образом, приводят к нереалистичным результатам тестирования на истории. Поэтому мы настоятельно рекомендуем использовать только стандартные типы диаграмм для стратегий тестирования на истории.

 

Бэктестинг и форвард-тестирование

В TradingView стратегии рассчитываются на основе всех доступных исторических данных графика (бэктестинг), а затем автоматически продолжают вычисления при поступлении данных в реальном времени (форвардное тестирование).

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

При форвард-тестировании у вас есть возможность настроить расчет скрипта так, чтобы он выполнялся на каждом тике в режиме реального времени. Для этого в настройках/свойствах стратегии необходимо отметить опцию Recalculate On Every Tick (Пересчитать на каждом тике) или указать ее в коде скрипта, используя: strategy(…, calc_on_every_tick=true).

Вы можете настроить стратегию на одно дополнительное вычисление после того, как ордер будет заполнен. Для этого необходимо выполнить Recalculate After Order filled в Settings/Properties стратегии, либо сделать это в коде скрипта, используя: strategy(…, calc_on_order_fills=true).

 

Эмулятор брокера

TradingView использует эмулятор брокера при запуске стратегий. В отличие от реальной торговли, эмулятор заполняет ордера только по ценам на графике, поэтому ордер может быть исполнен только на следующем тике при форвард-тестировании и на следующем баре или позже при бэктестинге, то есть после расчета стратегии.

Для имитации заполнения ордеров используется следующая логика:

  • Если максимум бара ближе к открытию бара, чем минимум бара, эмулятор брокера предполагает, что цена внутри бара двигалась следующим образом: открытие → максимум → минимум → закрытие.
  • Если минимум бара ближе к открытию бара, чем максимум бара, эмулятор брокера предполагает, что цена внутри бара двигалась следующим образом: открытие → минимум → максимум → закрытие.
  • Эмулятор брокера предполагает, что внутри баров нет промежутков, то есть для исполнения ордеров доступен полный диапазон цен внутри бара.
  • Даже если в свойствах стратегии включена опция Пересчитать на каждом тике (или вызов стратегии скрипта использует calc_on_every_tick=true), поведение эмулятора брокера все равно использует вышеприведенную логику.

 

Вот стратегия, демонстрирующая, как ордера заполняются эмулятором брокера:

//@version=4
strategy("History SAW demo", overlay=true, pyramiding=100, calc_on_order_fills=true)
strategy.entry("LE", strategy.long)

Также можно эмулировать очередь заказов. Настройка называется Verify Price For Limit Orders и может быть найдена в свойствах стратегии или установлена в коде скрипта с помощью функции strategy(…, backtest_fill_limits_assumption=X). Указанное значение является минимальным движением цены в количестве пунктов/пипсов (значение по умолчанию равно 0). Лимитный ордер заполняется, если текущая цена является более выгодной (выше для ордеров на продажу, ниже для ордеров на покупку) на указанное количество пунктов/пипсов. Цена исполнения по-прежнему соответствует цене лимитного ордера.

Пример:

  • backtest_fill_limits_assumption = 1, Минимальное движение цены 0.25.
  • Лимитный ордер на покупку размещается по цене 12.50.
  • Текущая цена 12.50.
  • Ордер не может быть исполнен по текущей цене, так как backtest_fill_limits_assumption = 1. Для заполнения ордера цена должна быть на 0.25*1 меньше. Ордер ставится в очередь.
  • Предположим, что следующий тик идет по цене 12.00. Эта цена на 2 пункта ниже, значит, условие backtest_fill_limits_assumption = 1 выполнено, поэтому ордер должен быть исполнен. Заказ исполняется по 12.50 (первоначальной цене заказа), даже если цена больше не доступна.

 

Команды размещения ордеров

Все ключевые слова, относящиеся к стратегиям, начинаются с префикса strategy.. Для размещения ордеров используются команды: strategy.entry, strategy.order и strategy.exit.

strategy.entry

  • Эта команда только размещает ордера на вход. На это влияет настройка pyramiding в свойствах стратегии и функция strategy.risk.allow_entry_in. Если есть открытая рыночная позиция при генерации ордера противоположного направления, количество контрактов / акций / лотов / единиц будет увеличено на количество текущих открытых контрактов (эквивалент скрипта: strategy.position_size + quantitystrategy.entry). В результате размер открытой рыночной позиции будет равен размеру ордера, указанному в команде strategy.entry.

strategy.order

  • Эта команда размещает заказы на вход и выход. На него не влияют настройки пирамидинга или функции strategy.risk.allow_entry_in. Команда позволяет создавать сложные конструкции ордеров на вход и выход, когда функциональность strategy.entry и strategy.exit не подходит.

strategy.exit

  • Эта команда позволяет вам выйти из рыночной позиции или сформировать несколько стратегий выхода с использованием стоп-лосса, целевой прибыли или скользящего стопа. Все такие ордера входят в одну группу strategy.oca.reduce. Ордер на выход не может быть размещен, если нет открытой рыночной позиции или нет активного ордера на вход (ордер на выход привязан к идентификатору ордера на вход). Невозможно выйти из позиции рыночным ордером с помощью команды strategy.exit. Для этого следует использовать команды strategy.close или strategy.close_all. Если количество контрактов / акций / лотов / единиц указано для strategy.exit меньше размера текущих открытых позиций, выход будет частичным. Из одного и того же порядка входа можно выйти более одного раза, используя один и тот же идентификатор порядка выхода, что позволяет создавать стратегии выхода с несколькими уровнями. В случаях, когда рыночная позиция формируется несколькими ордерами на вход (пирамидинг включен), каждый ордер на выход должен быть связан с соответствующим ордером входа.

 

Пример 1:

//@version=4
strategy("revers demo")
if bar_index > 4000
strategy.entry("buy", strategy.long, 4, when=strategy.position_size <= 0)
strategy.entry("sell", strategy.short, 6, when=strategy.position_size > 0)
plot(strategy.equity)

Вышеуказанная стратегия постоянно разворачивает рыночную позицию от +4 до -6, туда и обратно, что и показывает график.

Пример 2:

//@version=4
strategy("exit once demo")
strategy.entry("buy", strategy.long, 4, when=strategy.position_size <= 0)
strategy.exit("bracket", "buy", 2, profit=10, stop=10)

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

Пример 3:

//@version=4
strategy("Partial exit demo")
if bar_index > 4000
strategy.entry("buy", strategy.long, 4, when=strategy.position_size <= 0)
strategy.exit("bracket1", "buy", 2, profit=10, stop=10)
strategy.exit("bracket2", "buy", profit=20, stop=20)

Этот код генерирует 2 уровня скобок (2 ордера на тейк-профит и 2 стоп-лосса). Оба уровня активируются одновременно: первый — для выхода из 2 контрактов, второй — для выхода из всех остальных.

Первый тейк-профит и стоп-лосс (уровень 1) находятся в группе OCA. Остальные заказы (уровень 2) находятся в другой группе OCA. Это означает, что по мере выполнения ордера с уровня 1 заказы с уровня 2 не отменяются; они остаются активными.

Каждая команда, размещающая заказ, имеет идентификатор (строковое значение), который является уникальным идентификатором ордера. Если ордер с таким же идентификатором уже размещен, но еще не заполнен, последняя команда изменяет существующий ордер. Если модификация невозможна (переход с покупки на продажу), старый ордер отменяется и размещается новый. strategy.entry и strategy.order работают с одинаковыми идентификаторами (они могут изменять один и тот же порядок входа). strategy.exit работает с другими идентификаторами заказов (допускается, чтобы порядок входа и порядок выхода были с одним и тем же идентификатором).

Чтобы отменить конкретный ордер по его идентификатору, следует использовать команду strategy.cancel (string ID). Для отмены всех отложенных ордеров следует использовать команду strategy.cancel_all (). Стратегические ордера размещаются, как только их условия удовлетворяются и команда вызывается в коде. Эмулятор брокера не исполняет ордера до того, как следующий тик наступит после расчета кода, тогда как в реальной торговле ордер может быть исполнен раньше. Когда рыночный ордер создается при закрытии текущего бара, эмулятор брокера исполняет его только по цене открытия следующего бара.

Пример:

//@version=4
strategy("next bar open execution demo")
if bar_index > 4000
strategy.order("buy", strategy.long, when=strategy.position_size == 0)
strategy.order("sell", strategy.short, when=strategy.position_size != 0)

Если этот код применяется к графику, все ордера заполняются при открытии каждого бара.

При расчете скрипта проверяются условия размещения ордеров (when, pyramiding, strategy.risk). Если все условия выполнены, ордер выставляется. Если какое-либо условие не выполняется, ордер не размещается. Важно отменять ценовые ордера (лимитные, стоп и стоп-лимитные ордера).

Пример (для MSFT, 1D):

//@version=4
strategy("Priced Entry demo")
var c = 0
if year > 2014
c := c + 1
if c == 1
strategy.entry("LE1", strategy.long, 2, stop = high + 35 * syminfo.mintick)
strategy.entry("LE2", strategy.long, 2, stop = high + 2 * syminfo.mintick)

Несмотря на то, что пирамидинг отключен, оба этих ордера заполняются при тестировании на истории, потому что, когда они сгенерированы, нет открытой длинной рыночной позиции. Оба ордера размещаются, и когда цена удовлетворяет условиям исполнения ордера, они оба исполняются. Рекомендуется размещать ордера в группе OCA с помощью strategy.oca.cancel. Таким образом выполняется только один ордер, а второй отменяется.

Вот модифицированный код:

//@version=4
strategy("Priced Entry demo")
var c = 0
if year > 2014
c := c + 1
if c == 1
strategy.entry("LE1", strategy.long, 2, stop = high + 35 * syminfo.mintick, oca_type = strategy.oca.cancel, oca_name = "LE")
strategy.entry("LE2", strategy.long, 2, stop = high + 2 * syminfo.mintick, oca_type = strategy.oca.cancel, oca_name = "LE")

Если по какой-то причине при выполнении команды условия размещения ордера не выполняются, то входной ордер не выставляется. Например, если в настройках пирамидинга задано значение 2, существующая позиция уже содержит два входа, а стратегия пытается разместить третий, то ордер не выставляется. Условия входа оцениваются на этапе выставления ордера, а не на этапе его исполнения. Поэтому, если Вы выставляете две ценовые позиции с отключенным пирамидингом, то после того, как одна из них будет исполнена, вторая не будет отменена автоматически. Чтобы избежать проблем, мы рекомендуем использовать для входов группы strategy.oca.cancel, чтобы при заполнении одного ордера остальные были отменены.

То же самое и с выходами ценового типа. Заказы будут размещены после выполнения их условий, т.е. Будет заполнена заявка на вход с соответствующим идентификатором.

Закрытие рыночной позиции

Несмотря на то, что можно выйти из определенной записи в коде, когда ордера отображаются в Списке сделок на вкладке Тестера стратегий, все они связаны в соответствии с правилами FIFO (first in, first out). Если для ордера выхода в коде не указан идентификатор ордера входа, то ордер выхода закрывает первый ордер входа, открывший рыночную позицию.

Рассмотрим следующий пример:

//@version=4
strategy("exit Demo", pyramiding=2, overlay=true)
strategy.entry("Buy1", strategy.long, 5,
when = strategy.position_size == 0 and year > 2014)
strategy.entry("Buy2", strategy.long,
10, stop = strategy.position_avg_price +
strategy.position_avg_price*0.1,
when = strategy.position_size == 5)
strategy.exit("bracket", loss=10, profit=10, when=strategy.position_size == 15)

Приведенный выше код размещает 2 ордера последовательно: «Buy1» по рыночной цене и «Buy2» по цене выше на 10% (стоп-ордер). Ордер на выход размещается только после того, как ордера на вход выполнены. Если вы примените код к графику, вы увидите, что каждый ордер входа закрывается ордером выхода, хотя мы не указали ID ордера входа для закрытия в этой строке: strategy.exit(«bracket», loss=10, profit=10, when=strategy.position_size == 15)

Другой пример:

//@version=4
strategy("exit Demo", pyramiding=2, overlay=true)
strategy.entry("Buy1", strategy.long, 5, when = strategy.position_size == 0)
strategy.entry("Buy2", strategy.long,
10, stop = strategy.position_avg_price +
strategy.position_avg_price*0.1,
when = strategy.position_size == 5)
strategy.close("Buy2",when=strategy.position_size == 15)
strategy.exit("bracket", "Buy1", loss=10, profit=10, when=strategy.position_size == 15)
plot(strategy.position_avg_price)
  • Открывается длинную позицию на 5 контрактов с ордером Buy1.
  • Расширяется длинная позиция, покупая еще 10 контрактов по цене на 10% выше с помощью ордера Buy2.
  • Исполняется ордер на выход (strategy.close) на продажу 10 контрактов (выход из «Buy2»).

Если вы посмотрите на график, то увидите, что средняя цена входа = цене исполнения «Buy2», и наша стратегия закрыла именно этот ордер входа, в то время как на вкладке Trade List мы видим, что он закрыл первый ордер «Buy1» и половину второго «Buy2». Это означает, что независимо от того, какой порядок входа вы укажете для закрытия своей стратегии, эмулятор брокера все равно закроет первый в соответствии с правилами FIFO. Работает так же, как и при торговле с реальным брокером.

Группы ОСА

В Pine Script можно размещать заказы в 2 разных группах One-Cancells-All (OCA).

strategy.oca.cancel

Как только ордер из группы исполнен (даже частично) или отменен, остальные заказы из той же группы отменяются. Следует иметь в виду, что если цены ордеров совпадают или близки, то может быть исполнено более 1 ордера одной группы. Этот тип группы OCA доступен только для ордеров на вход, потому что все заказы на выход размещены внутри strategy.oca.reduce.

Пример:

//@version=4
strategy("oca_cancel demo")
if year > 2014 and year < 2016
strategy.entry("LE", strategy.long, oca_type = strategy.oca.cancel, oca_name="Entry")
strategy.entry("SE", strategy.short, oca_type = strategy.oca.cancel, oca_name="Entry")

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

Стратегия выставляет все ордера, которые не противоречат правилам (в нашем случае рыночная позиция флэтовая, поэтому может быть исполнен любой ордер на вход). При расчете каждого тика сначала исполняются все заявки с выполненными условиями и только затем отменяются заявки из группы, в которой была исполнена заявка.

strategy.oca.reduce

Этот тип группы позволяет выполнять несколько ордеров внутри группы. По мере того, как один из ордеров в группе начинает заполняться, размер других ордеров уменьшается на сумму выполненных контрактов. Это очень полезно для стратегий выхода. Как только цена коснется вашего ордера тейк-профита и он будет исполнен, стоп-лосс не отменяется, а его сумма уменьшается на сумму исполненных контрактов, тем самым защищая остальную часть открытой позиции.

strategy.oca.none

Ордер размещен вне группы (значение по умолчанию для функций strategy.order и strategy.entry).

У каждой группы есть свой уникальный идентификатор, как у ордеров. Если две группы имеют одинаковый идентификатор, но разный тип, они будут считаться разными группами.

Пример:

//@version=4
strategy("My Script")
if year > 2014 and year < 2016
strategy.entry("Buy", strategy.long, oca_name="My oca", oca_type=strategy.oca.reduce)
strategy.exit("FromBy", "Buy", profit=100, loss=200, oca_name="My oca")
strategy.entry("Sell", strategy.short, oca_name="My oca", oca_type=strategy.oca.cancel)
strategy.order("Order", strategy.short, oca_name="My oca", oca_type=strategy.oca.none)

«Buy» и «Sell» будут помещены в разные группы, так как их тип различается. «Order» будет вне какой-либо группы, поскольку установлен его тип strategy.oca.none. Кроме того, «Buy» будет помещен в группу выхода, поскольку выходы всегда помещаются в группу strategy.oca.reduce_size.

Управление рисками

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

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

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

Кроме того, стоит помнить, что при использовании таймфреймов более 1 дня для правил, начинающихся с префикса strategy.risk.max_intraday_, весь бар считается 1 днем.

Пример (MSFT, 1):

//@version=4
strategy("multi risk demo", overlay=true, pyramiding=10, calc_on_order_fills = true)
if year > 2014
strategy.entry("LE", strategy.long)
strategy.risk.max_intraday_filled_orders(5)
strategy.risk.max_intraday_filled_orders(2)

Позиция будет закрыта, и торговля будет остановлена ​​до конца каждой торговой сессии после исполнения двух ордеров в этой сессии, поскольку второе правило срабатывает раньше и действует до конца торговой сессии.

Следует помнить, что strategy.risk.allow_entry_in правило применяется только ко входам, так что можно будет войти в сделку с помощью команды strategy.order, поскольку эта команда не является командой входа как таковой. Более того, когда правило strategy.risk.allow_entry_in активно, входы в «запрещенную сделку» становятся выходами, а не реверсивными сделками.

Пример (MSFT, 1D):

//@version=4
strategy("allow_entry_in demo", overlay=true)
if year > 2014
strategy.entry("LE", strategy.long, when=strategy.position_size <= 0)
strategy.entry("SE", strategy.short, when=strategy.position_size > 0)
strategy.risk.allow_entry_in(strategy.direction.long)

Поскольку короткие входы запрещены правилами риска, вместо реверсивных сделок будут совершаться длинные сделки с выходом.

Валюта

Стратегии TradingView могут работать с валютой, отличной от валюты торгового инструмента. Чистая прибыль и Открытая прибыль пересчитываются в валюте счета. Валюта счета устанавливается в выпадающем списке «Базовая валюта» стратегии или в скрипте через параметр strategy(…, currency=currency.*). Значения отчета о результатах вычисляются в выбранной валюте.

Торговая прибыль (открытая или закрытая) рассчитывается на основе прибыли в валюте инструмента, умноженной на кросс-курс по закрытию торгового дня, предшествующего бара, на котором рассчитывается стратегия.

Пример: мы торгуем EURUSD, D и в качестве валюты стратегии выбрали currency.EUR. Наша стратегия покупает и закрывает позицию, используя цель прибыли в 1 пункт или стоп-лосс.

//@version=4
strategy("Currency test", currency=currency.EUR)
if year > 2014
strategy.entry("LE", true, 1000)
strategy.exit("LX", "LE", profit=1, loss=1)
profit = strategy.netprofit
plot(abs((profit - profit[1])*100), "1 point profit", color=color.blue, linewidth=2)
plot(1 / close[1], "prev usdeur", color=color.red)

После добавления этой стратегии на график мы видим, что линии графика совпадают. Это показывает, что ставка для расчета прибыли для каждой сделки была основана на закрытии предыдущего дня.

При торговле на внутридневных таймфреймах будет использоваться кросс-курс на закрытие торгового дня, предшествующего бару, на котором рассчитывается стратегия, и он не изменится во время торговой сессии.

При торговле с таймфреймами выше 1 дня будет использоваться кросс-курс на закрытие торгового дня, предшествующего закрытию бара, на котором рассчитывается стратегия. Допустим, мы торгуем на недельном графике, тогда кросс-курс на закрытии сессии в четверг всегда будет использоваться для расчета прибыли.

В режиме реального времени используется курс закрытия вчерашнего сеанса.

Перекраска индикатора

Исторические данные не включают записи о движении цены внутри бара; только открытие, максимум, минимум и закрытие (OHLC). Это приводит к тому, что сценарий иногда работает по-разному с историческими данными и в режиме реального времени, когда известна только цена открытия и где цена обычно будет двигаться много раз до того, как окончательные значения максимума, минимума и закрытия бара в реальном времени будут установлены после реальных значений, когда закроется бар реального времени.

Если мы добавим скрипт на график, подождем, пока он вычислит на нескольких барах реального времени, а затем перезагрузим страницу, то иногда мы увидим, что графики скрипта немного меняются. Такое поведение является одним из нескольких различных типов поведения, обычно называемых перекраской индикаторов. Это тип перерисовки, который мы здесь рассматриваем и на который мы будем ссылаться при использовании перерисовки. Это связано с тем, что при использовании определенных функций в скриптах, они будут по-разному производить расчеты на исторических барах и барах в реальном времени.

Другие типы поведения, правильно или неправильно называемые перекраской, включают в себя построение графиков с отрицательным смещением на прошлых барах и использование иным образом недоступной информации о будущем, полученной через неверные вызовы функции security, которая может внести данные, недоступные в реальном времени в вычисления скрипта.

Не все индикаторы подлежат перекрашиванию, которые мы здесь обсуждаем. В большинстве случаев это зависит от того, используются ли в коде определенные функции или языковые конструкции. Обратите внимание, что этот эффект перерисовки не является ошибкой; это результат естественных различий между историческими барами и информацией о барах в реальном времени на TradingView.

Мы можем увидеть перекраску в следующих случаях:

  • Стратегии используют calc_on_every_tick=true. Стратегия с параметром calc_on_every_tick = false также может быть подвержена перерисовке, но в меньшей степени.

Использование security для запроса данных с таймфреймом выше, чем таймфрейм основного тикера графика:

// Add this study on 1 minute chart
//@version=4
study("My Script")
c = security(syminfo.tickerid, "5", close)
plot(close)
plot(c, color=color.red)
  • Этот индикатор будет рассчитыватся по-разному на данных в реальном времени и на исторических данных, независимо от значения параметра lookahead.
  • Используется security для запроса данных с таймфреймом ниже таймфрейма основного тикера графика. Если lookahead=false, то перекраска произойдет. Когда lookahead=true, перекраска менее вероятна. Это все равно может произойти, когда 1 и 5-минутные обновления перекрывают друг друга.
  • Все скрипты, расчеты которых зависят от начальной точки. Внутридневные данные выравниваются по началу недели, месяца или года, в зависимости от таймфрейма. В связи с этим результаты таких скриптов могут время от времени отличаться. Это случаи, когда скрипты будут полагаться на начальную точку:

когда они используют функции valueewhenbarssince или ema (из-за особенностей их алгоритма).

любая стратегия тестирования на истории (независимо от того, как задан параметр calc_on_every_tick). Существует зависимость между таймфреймом и выравниванием начальной точки:

  • 1–14 минут — соответствует началу недели.
  • 15–29 минут — соответствует началу месяца.
  • от 30 минут и выше — выравнивается на начало года.

При обработке данных учитываются следующие ограничения длины истории:

  • 10000 исторических баров для всех планов Pro.
  • 5000 исторических баров для других планов.
  • Изменения в исторических данных, например, из-за дробления.

Присутствие в скрипте следующих переменных обычно приводит к перерисовке:

  • barstate.isconfirmed, barstate.isfirst, barstate.ishistory, barstate.islast, barstate.isnew, barstate.isrealtime ;
  • timenow ;
  • bar_index.
/

Robo.Trading

eVe Developer
Мы используем cookie-файлы для наилучшего представления нашего сайта. Продолжая использовать этот сайт, вы соглашаетесь с использованием cookie-файлов.
Принять