Динамический ценовой канал со стратегией отслеживания стоп-лосса

Автор:Чао Чжан, Дата: 2024-02-01 10:52:33
Тэги:

img

Обзор

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

Принцип стратегии

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

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

Сигнал длинного входа: открыть длинный, когда цена превышает верхний предел канала h и возвращается в канал

Долгий выходный сигнал: закрыть длинный, когда цена ниже центра средней линии канала (стоп-потеря) или выше цены получения прибыли tpl (получение прибыли)

Сигнал короткого входа: открыть короткий, когда цена ниже нижнего предела канала l и возвращается в канал

Сигнал короткого выхода: закрыть короткий, когда цена выше центра средней линии канала (стоп-лосс) или ниже цены получения прибыли (take profit)

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

Преимущества этой стратегии:

  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)

Больше