Блог им. raxat

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

    • 23 ноября 2022, 23:08
    • |
    • Diamond
  • Еще
Торговая система 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)
Данная публикация является личным мнением автора. Мнение владельца сайта может не совпадать с мнением автора.
4.5К | ★11
6 комментариев
Для средней 50 норма для стоп лосса = 2 свечи тайма.Например тайм 1 час это 0.4%-0.5%.Для тайма 1 день это 2.5%-3%. Норма для профита = 1\2 от книжной прибыли те прибыль уменьшится на 50% и тогда сработает тейк профит.
avatar
Результат VTBR +106.88% за 20 трейдов:
За какой период, месяц или «за всю историю»?
avatar
Я Я, за историю. Может показаться, что это немного, но купившие эти бумаги на IPO до сих пор сидят в большом минусе.
avatar
Искренне не понимаю как можно на основании того что 10-20-30 лет назад, скажем спортсмен, был на пике формы и вообще всего на свете чемпион гарантировать что ПРЯМО СЕЙЧАС и тем более в неопределенном будущем он опять повторит успехи прошлого. Потестировать что код накатан без косяков-ну это ясно, а доходность-то какое к этому отношение имеет? Ну кроме слепой веры в то что так заведено и значит априори сомнению не подлежит) 
avatar
HD-Boy, если завтра этот спортсмен резко потеряет свою форму, то такая система на нём весьма неплохо заработает.
avatar
Diamond, Ну как раз дело в том что «такая система» и есть тот «спортсмен». который обязательно потеряет форму, причем гораздо раньше и неожиданно, если он основан на принципе: прошлое гарантирует будущее, особенно про выбор инструментов если речь идёт.
avatar

Читайте на SMART-LAB:
Фото
Диасофт: первый квартал, который не разочаровал
Диасофт отчитался за 1 квартал. Это был не полный отчет, а пресс-релиз , где были озвучены 4 финансовые метрики. Чуть позже я отыскал databook ,...
📅 Приглашаем на онлайн-звонок с Хэдхантер по итогам квартала
Уже завтра опубликуем финансовые результаты компании за второй квартал и первое полугодие.  В 14:00 проведём онлайн-звонок с аналитиками и...
Фото
Как изменился Норильск после закрытия Никелевого завода
Прошло 10 лет с того дня, как «Норникель» остановил Никелевый завод. Сегодня уже можно оценить, как это решение повлияло на город, производство и...
Фото
Ростелеком. МСФО за Q2 2026г. Пора ли менять рейтинг компании?
Компания Ростелеком опубликовала финансовые результаты за 2 квартал 2026г.: 👉Выручка — 226,8 млрд руб. (+11,4% г/г) 👉Операционные...

теги блога Diamond

....все тэги



UPDONW
Новый дизайн