Динамическая стратегия стоп-лосса Price Channel Trailing


Дата создания: 2024-02-01 10:52:33 Последнее изменение: 2024-02-01 10:52:33
Копировать: 0 Количество просмотров: 314
1
Подписаться
1166
Подписчики

Динамическая стратегия стоп-лосса Price Channel Trailing

Обзор

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

Стратегический принцип

Сначала стратегия рассчитывает верхнюю границу h и нижнюю границу ценового канала на основе параметров pclen. Центр центра является средним значением верхней и нижней границ ценового канала. Затем, на основе стоп-параметров тп для длинных и свободных позиций, вычисляются стоп-цены тпл и тпс. Стоп-стоп фиксируется как центр ценового канала.

Конкретная логика сделки:

Сигнал открытия позиции: цена превышает верхний предел h и открывает позицию, когда она опускается внутрь канала Сигналы о повышении позиции: цена ниже центральной линии канала (stop loss) или выше цены остановки (stop price)

Сигнал открытия вакансии: цена ниже нижнего предела L и возвращается к вакансии внутри канала Сигналы о закрытии позиций: цена выше центральной линии канала (stop loss) или ниже цены остановки (stop price)

Анализ преимуществ

Эта стратегия имеет следующие преимущества:

  1. Двухсторонние сделки, которые позволяют уловить обратный тренд цен
  2. Используйте ценовые каналы, чтобы определить направление тренда и избежать ложных прорывов
  3. Настройка стоп-лосса, управление рисками
  4. Расчет величины позиции в зависимости от величины риска, чтобы обеспечить контроль риска
  5. Следить за остановками и остановками, чтобы зафиксировать больше прибыли

Анализ рисков

Однако есть и риски:

  1. Неправильная настройка параметров ценового канала может привести к слишком высокой частоте торгов или упущенным торговым возможностям
  2. Слишком мягкая стоп-ценовая политика может привести к увеличению рисковых пробелов.
  3. Следование за остановкой может быть задействовано раньше в период высокой волатильности

Эти риски могут быть уменьшены и контролированы путем корректировки параметров и искусственного мониторинга.

Направление оптимизации

Эта стратегия также может быть оптимизирована в следующих аспектах:

  1. Добавление фильтров для определения показателей, чтобы избежать частого открытия позиций в условиях шока
  2. Можно протестировать различные алгоритмы стоп-стоп-лосса, такие как ATR-стоп-лосса и т.д.
  3. Расширенная система торговли в течение более высоких временных циклов для определения направления тренда
  4. Добавление модуля управления позициями, изменение позиций в зависимости от использования средств
  5. Модели машинного обучения, используемые для определения успешности ценовых прорывов и предотвращения ложных прорывов

Подвести итог

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

Исходный код стратегии
/*backtest
start: 2023-01-31 00:00:00
end: 2024-01-31 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//Noro
//2020

//@version=4
strategy(title = "Noro's RiskDonchian Strategy", shorttitle = "RiskDonchian str", overlay = true, default_qty_type = strategy.percent_of_equity, initial_capital = 100, default_qty_value = 100, commission_value = 0.1)

//Settings
needlong = input(true, defval = true, title = "Long")
needshort = input(true, defval = true, title = "Short")
tp = input(defval = 20.0, minval = 1, title = "Take-profit, %")
tptype = input(defval = "2. Fix", options = ["1. None", "2. Fix", "3. Trailing"], title = "Take-profit type")
sltype = input(defval = "2. Center", options = ["1. None", "2. Center"], title = "Take-profit type")
risklong  = input(5.0, minval = 0.0, maxval = 99.9, title = "Risk size for long, %")
riskshort = input(5.0, minval = 0.0, maxval = 99.9, title = "Risk size for short, %")
pclen = input(50, minval = 1, title = "Price Channel Length")
showll = input(true, defval = true, title = "Show lines")
showbg = input(false, defval = false, title = "Show Background")
showof = input(true, defval = true, title = "Show Offset")
showlabel = input(true, defval = true, title = "Show label")
fromyear = input(1900, defval = 1900, minval = 1900, maxval = 2100, title = "From Year")
toyear = input(2100, defval = 2100, minval = 1900, maxval = 2100, title = "To Year")
frommonth = input(01, defval = 01, minval = 01, maxval = 12, title = "From Month")
tomonth = input(12, defval = 12, minval = 01, maxval = 12, title = "To Month")
fromday = input(01, defval = 01, minval = 01, maxval = 31, title = "From day")
today = input(31, defval = 31, minval = 01, maxval = 31, title = "To day")

//Price Channel
h = highest(high, pclen)
l = lowest(low, pclen)
center = (h + l) / 2

//Take-profit
tpl = 0.0
tpl := tptype == "2. Fix" and strategy.position_size > 0 ? tpl[1] : h * (100 + tp) / 100

//Stop-loss
tps = 0.0
tps := tptype == "2. Fix" and strategy.position_size < 0 ? tps[1] : l * (100 - tp) / 100

//Lines
tplcol = showll and needlong and tptype != "1. None" ? color.lime : na
pclcol = showll and needlong ? color.blue : na
sllcol = showll and needlong and sltype != "1. None" ? color.red : na
tpscol = showll and needshort and tptype != "1. None" ? color.lime : na
pcscol = showll and needshort ? color.blue : na
slscol = showll and needshort and sltype != "1. None" ? color.red : na
offset = showof ? 1 : 0
plot(tpl, offset = offset, color = tplcol, title = "TP Long")
plot(h, offset = offset, color = pclcol, title = "Channel High")
plot(center, offset = offset, color = sllcol, title = "SL Long")
plot(center, offset = offset, color = slscol, title = "SL Short")
plot(l, offset = offset, color = pcscol, title = "Channel Low")
plot(tps, offset = offset, color = tpscol, title = "TP Short")

//Background
size = strategy.position_size
bgcol = showbg == false ? na : size > 0 ? color.lime : size < 0 ? color.red : na
bgcolor(bgcol, transp = 70)

//Lot size
risksizelong = -1 * risklong
risklonga = ((center / h) - 1) * 100
coeflong = abs(risksizelong / risklonga)
lotlong = (strategy.equity / close) * coeflong
risksizeshort = -1 * riskshort
riskshorta = ((center / l) - 1) * 100
coefshort = abs(risksizeshort / riskshorta)
lotshort = (strategy.equity / close) * coefshort

//Trading
truetime = time > timestamp(fromyear, frommonth, fromday, 00, 00) and time < timestamp(toyear, tomonth, today, 23, 59)
mo = 0
mo := strategy.position_size != 0 ? 0 : high >= center[1] and low <= center[1] ? 1 : mo[1]

if h > 0
    longlimit = tptype == "1. None" ? na : tpl
    longstop = sltype == "1. None" ? na : center
    strategy.entry("Long", strategy.long, lotlong, stop = h, when = strategy.position_size <= 0 and needlong and truetime and mo)
    strategy.exit("TP Long", "Long", limit = longlimit, stop = longstop)
    shortlimit = tptype == "1. None" ? na : tps
    shortstop = sltype == "1. None" ? na : center
    strategy.entry("Short", strategy.short, lotshort, stop = l, when = strategy.position_size >= 0 and needshort and truetime and mo)
    strategy.exit("Exit Short", "Short", limit = shortlimit, stop = shortstop)
if time > timestamp(toyear, tomonth, today, 23, 59)
    strategy.close_all()
    strategy.cancel("Long")
    strategy.cancel("Short")
    
if showlabel

    //Drawdown
    max = 0.0
    max := max(strategy.equity, nz(max[1]))
    dd = (strategy.equity / max - 1) * 100
    min = 100.0
    min := min(dd, nz(min[1]))
    
    //Label
    min := round(min * 100) / 100
    labeltext = "Drawdown: " + tostring(min) + "%"
    var label la = na
    label.delete(la)
    tc = min > -100 ? color.white : color.red
    osx = timenow + round(change(time)*10)
    osy = highest(100)