
Тренд-последовательская стратегия Дониана - это стратегия отслеживания трендов, разработанная в соответствии с принципом Донианского канала, описанным в статье Black Box Trend Following и Lifting the Veil. Эта стратегия использует Донианский канал для определения ценовой тенденции и создания позиций, чтобы сделать больше или меньше, в зависимости от того, насколько высока или низка цена.
Стратегия основана на показателях Донианского канала для определения направления тренда. Донианский канал состоит из канала с более длинным циклом и канала с более коротким циклом. Когда цена прорывает канал с более длинным циклом, она начинается как тренд; когда цена прорывает канал с более коротким циклом, она заканчивается как тренд.
В частности, длина более длительного цикла канала составляет 50 дней или 20 дней, а длина более короткого цикла канала составляет 50 дней, 20 дней или 10 дней. Если цена равна самой высокой цене за 50 дней, то открывается дополнительный билет; если цена равна самой низкой цене за 50 дней, то открывается пустой билет. Если цена равна самой низкой цене за 20 дней или 10 дней, то закрывается дополнительный билет; если цена равна самой высокой цене за 20 дней или 10 дней, то закрывается пустой билет.
Таким образом, с помощью комбинации двух различных циклов доннионных каналов, можно определить направление позиции в начале тренда и вовремя остановить убытки в конце тренда.
Основные преимущества этой стратегии:
Сильная способность улавливать тенденции. Можно эффективно отслеживать тенденции, прорывая донный канал, чтобы определить начало и конец тенденции.
Управление рисками. Использование движущегося стопа для управления единичными потерями.
Гибкость в регулировании параметров. Можно свободно выбирать циклическое сочетание каналов, адаптируясь к различным сортам и рыночным условиям.
Простая и четкая логика транзакций.
Также существуют следующие риски:
Неспособность приспособиться к шокирующим рынкам. Когда тенденция не очевидна, будет происходить несколько небольших корректировок, приводящих к стоп-убыткам.
Риск провала прорыва. После того, как цена прорвется через канал, она может снова откликнуться, что приведет к остановке.
Риск выбора цикла. Если неправильно настроить цикл прохода, это приведет к трейдингу в шуме.
Риск снижения коэффициента Шарпа. Если увеличить позицию без корректировки величины остановки, то рискуется снижение коэффициента Шарпа.
Решение проблемы:
Эта стратегия может быть оптимизирована в следующих направлениях:
Добавить фильтрующие условия, чтобы избежать whipsaws.
Оптимизация портфеля и контроля позиций в канальном цикле, повышение убыточности. Можно ввести адаптивный механизм остановки убытков.
Попробуйте оптимизировать предел и найти оптимальную комбинацию параметров.
Добавление алгоритмов машинного обучения для динамической оптимизации и корректировки параметров.
Стратегия слежения за трендом Дониана является очень практичной стратегией слежения за трендом, используя двойной канал для определения начала и конца ценового тренда, используя метод торговли, следующий за трендом, эффективно контролируя одиночные потери. Эта стратегия имеет гибкую и легкую внедрение параметров, но также следует обратить внимание на недостаточную рентабельность при шокирующей практике и риски, связанные с выбором параметров.
/*backtest
start: 2023-12-01 00:00:00
end: 2023-12-31 23:59:59
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=5
strategy(title="Donchian", overlay=true,
pyramiding=0, initial_capital=1000,
commission_type=strategy.commission.cash_per_order,
commission_value=2, slippage=2)
// =============================================================================
// VARIABLES
// =============================================================================
donch_string = input.string(title="Length", options = ['20/10','50/20', '50/50', '20/20', '100/100'], defval='50/50')
permit_long = input.bool(title = 'Permit long', defval = true)
permit_short = input.bool(title = 'Permit short', defval = true)
risk_percent = input.float(title="Position Risk %", defval=0.5, step=0.25)
stopOffset = input.float(title="ATR mult", defval=2.0, step=0.5)
atrLen = input.int(title="ATR Length", defval=20)
close_in_end = input.bool(title = 'Close in end', defval = true)
permit_stop = input.bool(title = 'Permit stop', defval = false)
// =============================================================================
// CALCULATIONS
// =============================================================================
donch_len_big =
donch_string == '50/20' ? 50 :
donch_string == '50/50' ? 50 :
donch_string == '20/20' ? 20 :
donch_string == '20/10' ? 20 :
donch_string == '100/100' ? 100 :
na
donch_len_small =
donch_string == '50/20' ? 20 :
donch_string == '50/50' ? 50 :
donch_string == '20/20' ? 20 :
donch_string == '20/10' ? 10 :
donch_string == '100/100' ? 100 :
na
big_maxclose = ta.highest(close, donch_len_big)
big_minclose = ta.lowest(close, donch_len_big)
small_maxclose = ta.highest(close, donch_len_small)
small_minclose = ta.lowest(close, donch_len_small)
atrValue = ta.atr(atrLen)[1]
tradeWindow = true
// =============================================================================
// NOTOPEN QTY
// =============================================================================
risk_usd = (risk_percent / 100) * strategy.equity
atr_currency = (atrValue * syminfo.pointvalue)
notopen_qty = risk_usd / (stopOffset * atr_currency)
// =============================================================================
// LONG STOP
// =============================================================================
long_stop_price = 0.0
long_stop_price :=
strategy.position_size > 0 and na(long_stop_price[1]) ? strategy.position_avg_price - stopOffset * atrValue :
strategy.position_size > 0 and strategy.openprofit > risk_usd ? strategy.position_avg_price:
strategy.position_size > 0 ? long_stop_price[1] :
na
// =============================================================================
// SHORT STOP
// =============================================================================
short_stop_price = 0.0
short_stop_price :=
strategy.position_size < 0 and na(short_stop_price[1]) ? strategy.position_avg_price + stopOffset * atrValue :
strategy.position_size < 0 and strategy.openprofit > risk_usd ? strategy.position_avg_price :
strategy.position_size < 0 ? short_stop_price[1] :
na
// =============================================================================
// PLOT VERTICAL COLOR BAR
// =============================================================================
cross_up = strategy.position_size <= 0 and close == big_maxclose and close >= syminfo.mintick and tradeWindow and permit_long
cross_dn = strategy.position_size >= 0 and close == big_minclose and close >= syminfo.mintick and tradeWindow and permit_short
bg_color = cross_up ? color.green : cross_dn ? color.red : na
bg_color := color.new(bg_color, 70)
bgcolor(bg_color)
// =============================================================================
// PLOT DONCHIAN LINES
// =============================================================================
s1 = cross_up ? na : cross_dn ? na : strategy.position_size != 0 ? strategy.position_avg_price : na
s2 = cross_up ? na : cross_dn ? na : strategy.position_size > 0 ? small_minclose : strategy.position_size < 0 ? small_maxclose : na
s3 = cross_up ? na : cross_dn ? na : not permit_stop ? na :
strategy.position_size > 0 ? long_stop_price : strategy.position_size < 0 ? short_stop_price : na
plot(series=big_maxclose, style=plot.style_linebr, color=color.black, linewidth=1, title="Donch Big Maxclose Black")
plot(series=big_minclose, style=plot.style_linebr, color=color.black, linewidth=1, title="Donch Big Minclose Black")
plot(series=s1, style=plot.style_linebr, color=color.yellow, linewidth=2, title="Entry Yellow")
plot(series=s2, style=plot.style_linebr, color=color.red, linewidth=1, title="Donch Small Red")
plot(series=s3, style=plot.style_linebr, color=color.fuchsia, linewidth=2, title="Stop Fuchsia")
// =============================================================================
// ENTRY ORDERS
// =============================================================================
if strategy.position_size <= 0 and close == big_maxclose and close >= syminfo.mintick and tradeWindow and permit_long
strategy.entry("Long", strategy.long, qty=notopen_qty)
if strategy.position_size >= 0 and close == big_minclose and close >= syminfo.mintick and tradeWindow and permit_short
strategy.entry("Short", strategy.short, qty=notopen_qty)
// =============================================================================
// EXIT ORDERS
// =============================================================================
if strategy.position_size > 0 and permit_stop
strategy.exit(id="Stop", from_entry="Long", stop=long_stop_price)
if strategy.position_size < 0 and permit_stop
strategy.exit(id="Stop", from_entry="Short", stop=short_stop_price)
// ==========
if strategy.position_size > 0 and close == small_minclose and not barstate.islast
strategy.close(id="Long", comment='Donch')
if strategy.position_size < 0 and close == small_maxclose and not barstate.islast
strategy.close(id="Short", comment='Donch')
// ==========
if close_in_end
if not tradeWindow
strategy.close_all(comment='Close in end')
// =============================================================================
// END
// =============================================================================