Diamond
Diamond личный блог
23 ноября 2022, 23:08

Торговая система Golden Short на PineScript

Торговая система Golden Short на PineScript

В прошлый раз вы создавали простую торговую систему для TradingView и самое время улучшить её и внести небольшие изменения, которые позволят вам обгонять рынок там, где остальные трейдеры теряют деньги. Также эта система использует обновлённую версию PineScript v5 — она предполагает незначительные различия в коде.

Идея выглядит так:

1. По-прежнему в основе лежит использование «золотого креста» на дневном таймфрейме для открытия позиций

2. В систему добавляется открытие коротких позиций (шортов)

3. Добавляются стоп-лосс и тейк-профит, но только для шортов

Сначала инициализируем торговую систему и добавляем две скользящих средних SMA50 и SMA200:

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// This strategy has been created for illustration purposes only and should not be relied upon as a basis for buying, selling, or holding any asset or security.
// © Diamond

//@version=5
strategy('SMA Golden Short Strategy', overlay=true, calc_on_every_tick=false, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_value=0.04, commission_type=strategy.commission.percent)

//Inputs
smaFast = input.int(title='Fast SMA', defval=50, minval=1)
smaSlow = input.int(title='Slow SMA', defval=200, minval=1)

Добавляем переменные, доступные для настройки пользователем:

//Options to configure backtest trade range
startDate = input.time(title='Start Date', defval=timestamp('01 Jan 1998 00:00'))
endDate = input.time(title='End Date', defval=timestamp('31 Dec 2070 23:59'))

//Calculations
fastSMA = ta.sma(close, smaFast)
slowSMA = ta.sma(close, smaSlow)

Рендерим скользящие поверх графика:

//Plot
plot(series=fastSMA, color=color.new(color.orange, 0), linewidth=2)
plot(series=slowSMA, color=color.new(color.blue, 0), linewidth=3)

Условия трейдинга немного меняются — мы по-прежнему торгуем по пересечениям скользящих средних, но теперь быстрая средняя, пересекающая медленную снизу вверх, называется longCondition, а обратное условие это shortCondition:

//Conditions
inDateRange = time >= startDate and time < endDate
longOpenCondition = ta.crossover(fastSMA, slowSMA)
shortOpenCondition = ta.crossunder(fastSMA, slowSMA)

Соответственно, теперь открываются не только длинные, но и короткие позиции. Для более наглядного отображения я добавил на график label:

//Trading
if longOpenCondition and inDateRange
    strategy.entry(id='long', direction=strategy.long, comment=' ')
    label.new(bar_index, na, text='Long', size=size.normal, style=label.style_label_up, color=color.blue, textcolor=color.white, yloc=yloc.belowbar)

if shortOpenCondition and inDateRange
    strategy.entry(id='short', direction=strategy.short, comment=' ')
    label.new(bar_index, na, text='Short', size=size.normal, style=label.style_label_down, color=color.red, textcolor=color.white, yloc=yloc.abovebar)

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

//Stop Loss / Take Profit
useStopLoss = input(false, title='Use Stop Loss & Take Profit')
sl_inp = input(defval = 1.0, title='Stop Loss %')/100.0
tp_inp = input(defval = 1.5, title='Take Profit %')/100.0
stop_level = strategy.position_avg_price * (1 - sl_inp)
take_level = strategy.position_avg_price * (1 + tp_inp)
stop_level_short = strategy.position_avg_price * (1 + sl_inp)
take_level_short = strategy.position_avg_price * (1 - tp_inp)

И теперь торговая система будет закрывать шорты, если достигнут стоп-лосс или тейк-профит. Код закрытия позиций будет вызываться только в том случае, если выполняется условие useStopLoss — пользователь должен нажать на чекбокс «Use Stop Loss & Take Profit» в настройках торговой системы. Для корректной работы strategy.exit() должны совпадать id ранее открытых позиций (в данном случае, id=«long» и id=«short»):

//if useStopLoss and strategy.position_size > 0 and strategy.openprofit > 0
//    strategy.exit(id="long", comment = "Take Profit Long +" + str.tostring(math.round(strategy.openprofit)), limit = take_level)

//if useStopLoss and strategy.position_size > 0 and strategy.openprofit < 0
//    strategy.exit(id="long", comment = "Stop Loss Long -" + str.tostring(math.round(strategy.openprofit)), stop = stop_level)

if useStopLoss and strategy.position_size < 0 and strategy.openprofit > 0
    strategy.exit(id="short", comment = "Take Profit Short +" + str.tostring(math.round(strategy.openprofit)), limit = take_level_short)

if useStopLoss and strategy.position_size < 0 and strategy.openprofit < 0
    strategy.exit(id="short", comment = "Stop Loss Short -" + str.tostring(math.round(strategy.openprofit)), stop = stop_level_short)

Окно настроек выглядит так:

Торговая система Golden Short на PineScript

Комиссия по умолчанию составляет 0.04% и она учитывается в результатах тестирования, проскальзывание (Slippage) я поставил 0%, но сделок будет немного и оба параметра слабо повлияют на доходность.

Стоп-лосса менее 5% на дневном таймфрейме будет явно недостаточно — он будет часто срабатывать. Слишком большие стоп-лоссы снизят доходность. Тейк-профит лучше ставить более 30%, потому что движения вниз более сильные, чем вверх.

Поскольку в системе есть шорты, нужны такие биржевые инструменты, у которых Buy & Hold с большой вероятностью даёт отрицательную доходность. Например, VTBR (акции банка ВТБ обыкновенные):

Торговая система Golden Short на PineScript

Либо AFLT (акции Аэрофлот):

Торговая система Golden Short на PineScript

И ещё подойдут акции Русгидро с тикером HYDR:

Торговая система Golden Short на PineScript

Более волатильные инструменты вроде IRAO (акции Интер РАО) могут потребовать повышения стоп-лосса и тейк-профита:

Торговая система Golden Short на PineScript

Бэктесты на всех этих тикерах дают положительную доходность.

Результат VTBR +106.88% за 20 трейдов:

Торговая система Golden Short на PineScript

Результат AFLT +2103.92% за 27 трейдов:

Торговая система Golden Short на PineScript

Самый скромный результат у HYDR +23.47% за 18 трейдов:

Торговая система Golden Short на PineScript

Результат IRAO +518.62% за 24 трейда:

Торговая система Golden Short на PineScript

Но есть 2 существенных недостатка:

1. Торговая система всегда в рынке, не учтена плата за шорты

2. Большие просадки по 50%, нельзя торговать с плечом

Тем не менее, с помощью простой системы вы получаете дополнительное преимущество перед долгосрочными инвесторами.

Полный исходный код:

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// This strategy has been created for illustration purposes only and should not be relied upon as a basis for buying, selling, or holding any asset or security.
// © Diamond

//@version=5
strategy('SMA Golden Short Strategy', overlay=true, calc_on_every_tick=false, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_value=0.04, commission_type=strategy.commission.percent)

//Inputs
smaFast = input.int(title='Fast SMA', defval=50, minval=1)
smaSlow = input.int(title='Slow SMA', defval=200, minval=1)

//Options to configure backtest trade range
startDate = input.time(title='Start Date', defval=timestamp('01 Jan 1998 00:00'))
endDate = input.time(title='End Date', defval=timestamp('31 Dec 2070 23:59'))

//Calculations
fastSMA = ta.sma(close, smaFast)
slowSMA = ta.sma(close, smaSlow)

//Plot
plot(series=fastSMA, color=color.new(color.orange, 0), linewidth=2)
plot(series=slowSMA, color=color.new(color.blue, 0), linewidth=3)

//Conditions
inDateRange = time >= startDate and time < endDate
longOpenCondition = ta.crossover(fastSMA, slowSMA)
shortOpenCondition = ta.crossunder(fastSMA, slowSMA)

//Trading
if longOpenCondition and inDateRange
    strategy.entry(id='long', direction=strategy.long, comment=' ')
    label.new(bar_index, na, text='Long', size=size.normal, style=label.style_label_up, color=color.blue, textcolor=color.white, yloc=yloc.belowbar)

if shortOpenCondition and inDateRange
    strategy.entry(id='short', direction=strategy.short, comment=' ')
    label.new(bar_index, na, text='Short', size=size.normal, style=label.style_label_down, color=color.red, textcolor=color.white, yloc=yloc.abovebar)

//Stop Loss / Take Profit
useStopLoss = input(false, title='Use Stop Loss & Take Profit')
sl_inp = input(defval = 1.0, title='Stop Loss %')/100.0
tp_inp = input(defval = 1.5, title='Take Profit %')/100.0
stop_level = strategy.position_avg_price * (1 - sl_inp)
take_level = strategy.position_avg_price * (1 + tp_inp)
stop_level_short = strategy.position_avg_price * (1 + sl_inp)
take_level_short = strategy.position_avg_price * (1 - tp_inp)

//if useStopLoss and strategy.position_size > 0 and strategy.openprofit > 0
//    strategy.exit(id="long", comment = "Take Profit Long +" + str.tostring(math.round(strategy.openprofit)), limit = take_level)

//if useStopLoss and strategy.position_size > 0 and strategy.openprofit < 0
//    strategy.exit(id="long", comment = "Stop Loss Long -" + str.tostring(math.round(strategy.openprofit)), stop = stop_level)

if useStopLoss and strategy.position_size < 0 and strategy.openprofit > 0
    strategy.exit(id="short", comment = "Take Profit Short +" + str.tostring(math.round(strategy.openprofit)), limit = take_level_short)

if useStopLoss and strategy.position_size < 0 and strategy.openprofit < 0
    strategy.exit(id="short", comment = "Stop Loss Short -" + str.tostring(math.round(strategy.openprofit)), stop = stop_level_short)
8 Комментариев
  • ezomm
    23 ноября 2022, 23:43
    Для средней 50 норма для стоп лосса = 2 свечи тайма.Например тайм 1 час это 0.4%-0.5%.Для тайма 1 день это 2.5%-3%. Норма для профита = 1\2 от книжной прибыли те прибыль уменьшится на 50% и тогда сработает тейк профит.
  • Я Я
    24 ноября 2022, 07:25
    Результат VTBR +106.88% за 20 трейдов:
    За какой период, месяц или «за всю историю»?
  • Aurum999
    24 ноября 2022, 11:58
    Искренне не понимаю как можно на основании того что 10-20-30 лет назад, скажем спортсмен, был на пике формы и вообще всего на свете чемпион гарантировать что ПРЯМО СЕЙЧАС и тем более в неопределенном будущем он опять повторит успехи прошлого. Потестировать что код накатан без косяков-ну это ясно, а доходность-то какое к этому отношение имеет? Ну кроме слепой веры в то что так заведено и значит априори сомнению не подлежит) 
      • Aurum999
        24 ноября 2022, 13:54
        Diamond, Ну как раз дело в том что «такая система» и есть тот «спортсмен». который обязательно потеряет форму, причем гораздо раньше и неожиданно, если он основан на принципе: прошлое гарантирует будущее, особенно про выбор инструментов если речь идёт.

Активные форумы
Что сейчас обсуждают

Старый дизайн
Старый
дизайн