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

Три причины выхода

Длинную позицию могут закрыть:

  • достижение уровня стоп-приказа;
  • достижение уровня лимитного приказа фиксации прибыли;
  • пересечение быстрой средней вниз и исполнение рыночного закрытия.

Стоп и лимит зависят от цены. strategy.close подаёт рыночное закрытие. Их правила исполнения различаются, поэтому проверяйте и цену, и время сделки.

Расстояние или конкретная цена?

В strategy.exit есть два способа задания:

АргументЗначение
lossРасстояние убытка в тиках
profitРасстояние прибыли в тиках
stopКонкретная стоп-цена
limitКонкретная лимитная цена

loss=100 не означает 100 процентов или обязательно 100 денежных единиц. Это сто тиков от цены входа.

Тик DEMO равен 0,01. Сто тиков дают 1 ценовую единицу, двести 2. При длинном входе 200 это стоп 199 и цель 202 до дополнительных эффектов проскальзывания и исполнения.

Полная программа

Создайте protected_strategy.py:

"""
@pyne edge
"""
from pynecore.lib import close, color, input, plot, script, strategy, ta


@script.strategy(
    "Crossing Strategy with Exits",
    overlay=True,
    initial_capital=10000,
    default_qty_type=strategy.fixed,
    default_qty_value=1,
    pyramiding=1,
    commission_type=strategy.commission.percent,
    commission_value=0.1,
    slippage=2,
)
def main(
    fast_length: int = input.int(5, title="Fast length", minval=1, maxval=200),
    slow_length: int = input.int(20, title="Slow length", minval=1, maxval=200),
    stop_ticks: int = input.int(100, title="Stop distance (ticks)", minval=1),
    target_ticks: int = input.int(200, title="Target distance (ticks)", minval=1),
):
    fast_average = ta.sma(close, fast_length)
    slow_average = ta.sma(close, slow_length)
    crosses_up = ta.crossover(fast_average, slow_average)
    crosses_down = ta.crossunder(fast_average, slow_average)
    if crosses_up:
        strategy.entry("Long", strategy.long)
    if crosses_down:
        strategy.close("Long")
    strategy.exit("Bracket", "Long", loss=stop_ticks, profit=target_ticks)
    plot(fast_average, "Fast average", color=color.blue, linewidth=2)
    plot(slow_average, "Slow average", color=color.orange, linewidth=2)

Bracket идентифицирует группу выходов. Второй аргумент Long указывает связанный вход. loss и profit используют два inputs выше.

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

Запустите на демонстрационных данных. В Trades теперь возможны выходы Bracket помимо рыночного закрытия по пересечению.

protected_strategy.py выполняется в PyneIDE; сделки могут закрываться стопом или целью.
Стратегия использует выход по пересечению, стоп и цель в тиках.

Когда появляется защитный выход?

Программа может выдать вход и связанный выход в одном выполнении. Среда связывает тиковое расстояние с фактической ценой исполнения входа.

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

Выбирайте форму по правилу: loss задаёт тики от входа, stop конкретный уровень.

Свеча не содержит все шаги цены

OHLCV даёт открытие, максимум, минимум, закрытие, но не полный временной порядок промежуточных цен.

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

Исследуйте этот случай отдельно, не выбирайте вручную всегда выгодный исход. Предположение модели входит в результат.

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

Стоп и цель внутри одной свечиОба пути дают одну и ту же OHLC-свечу. Стоп на 199 и цель на 202 уже активны. Без данных меньшего таймфрейма модель сначала идёт к экстремуму, ближайшему к открытию; здесь первым исполняется стоп. Другой путь показывает, почему важна последовательность цен. open: 200; high: 203; low: 198; close: 201. stop: 199; limit: 202. open → low → high → close; open → high → low → close.Путь OHLC-моделиДругой возможный порядокO → L → H → CO → H → L → C202199202199OLHCOHLCСтоп исполняется первымЦель достигается первойO = 200 · H = 203 · L = 198 · C = 201Открытая длинная позиция; выходы активны. Без гэпов и проскальзывания.
Стоп и цель внутри одной свечиОба пути дают одну и ту же OHLC-свечу. Стоп на 199 и цель на 202 уже активны. Без данных меньшего таймфрейма модель сначала идёт к экстремуму, ближайшему к открытию; здесь первым исполняется стоп. Другой путь показывает, почему важна последовательность цен.

Расстояние и денежный убыток

Для длинной позиции в одну единицу со стоимостью пункта 1 сто тиков по 0,01 означают 1 денежную единицу ценовой разницы. При десяти единицах итог движения десятикратный.

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

Прямое qty в приказе задаёт его собственное количество. Пример использует значение по умолчанию, переопределяемое в Properties → Order size.

100 и 200 тиков для DEMO являются иллюстрацией. В другом инструменте это иные ценовые и денежные расстояния.

Попробуйте самостоятельно

Оставьте длины, количество и расходы. Запустите со стопом/целью 100/200, затем 200/400. Проверьте судьбу одного сигнала входа.

Решение

В Inputs меняйте только Stop distance (ticks) и Target distance (ticks). Большие расстояния могут изменить свечу или причину закрытия.

Выход по пересечению сохраняется. Большая цель не означает, что позиция обязательно дождётся её. Правила действуют совместно.

Сохранив inputs, дождитесь пересчёта и читайте новый результат. Для позднего сравнения сохраните экспорты под разными именами.

Найдите причину выхода

Выберите закрытую сделку, проверьте вход, тиковые расстояния и OHLC выходной свечи. По цене и времени определите объясняющее правило. Если затронуты несколько уровней, учитывайте модель исполнения.