
ドニヤントレンドフォロー戦略は,Black Box Trend Following Lifting the Veil で説明されているドニヤンチャネル原理に基づいて開発されたトレンドフォロー戦略である.この戦略は,ドニヤンチャネルを利用して価格トレンドを判断し,価格の創新高または創新低に応じてポジションを多かれ少なかれにする.
策略はドニール・チャネル指標に基づいてトレンドの方向を判断する.ドニール・チャネルは,より長いサイクルのチャネルとより短いサイクルのチャネルで構成されている.価格がより長いサイクルのチャネルを破るとき,トレンドとして判断を開始し,価格がより短いサイクルのチャネルを破るとき,トレンドとして判断終了する.
具体的には,より長い周期の通路の長さは50日または20日,より短い周期の通路の長さは50日,20日または10日である. 価格が50日間の最高価格に等しいならば,多項を開く. 価格が50日間の最低価格に等しいならば,空の項を開く. 価格が20日間の最低価格に等しいならば,多項を平くする. 価格が20日間の最低価格に等しいならば,空の項を平くする.
このように,2つの異なる周期のドニーニウム通路の組み合わせにより,トレンドの開始時に方向を決定し,トレンドの終了時にタイミングで損益場を離れることができる.
この戦略の利点は以下の通りです.
トレンドを捉える能力が強い。ドニャール通路を突破してトレンドの始まりと終わりを判断し,トレンドを効果的に追跡することができる。
リスク管理 移動止損を単一損失の管理に用いること
パラメータ調整の柔軟性. 経路の周期组合を自由に選択し,異なる品種と市場環境に適合する.
取引の論理はシンプルで明瞭で,理解し,実行しやすい.
この戦略には以下のリスクもあります.
振動市場には適応できない.トレンドが目立たない時には,小規模な調整が繰り返し起こり,止損が起こります.
突破の失敗のリスク. 価格が通路を突破した後,再び戻ってくる可能性があり,ストップ損失を引き起こします.
周期選択リスク。通路周期が正しく設定されていない場合,trading in noiseの原因となる。
シャープ比率の低下のリスク. ポジションを拡大しても,止損幅を調整しない場合,シャープ比率の低下のリスクに直面する.
対応方法:
この戦略は以下の方向から最適化できます.
フィルタリング条件を追加し,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
// =============================================================================