La stratégie Donchian Trend Following est développée sur la base du principe Donchian Channel décrit dans l'article
La stratégie est basée sur l'indicateur du canal de Donchian pour juger de la direction de la tendance. Le canal de Donchian se compose d'un canal de période plus longue et d'un canal de période plus courte. Lorsque le prix traverse le canal de période plus longue, il indique le début d'une tendance. Lorsque le prix traverse le canal de période plus courte, il indique la fin de la tendance.
Plus précisément, la longueur du canal de plus longue période est de 50 jours ou 20 jours, et la longueur du canal de plus courte période est de 50 jours, 20 jours ou 10 jours. Si le prix est égal au prix le plus élevé en 50 jours, une position longue est ouverte. Si le prix est égal au prix le plus bas en 50 jours, une position courte est ouverte. Si le prix est égal au prix le plus bas en 20 ou 10 jours, les positions longues sont fermées. Si le prix est égal au prix le plus élevé en 20 ou 10 jours, les positions courtes sont fermées.
En combinant deux canaux de Donchian de périodes différentes, il peut déterminer la direction pour établir des positions lorsqu'une tendance commence, et réaliser un stop loss rapide lorsque la tendance se termine.
Les principaux avantages de cette stratégie sont les suivants:
Il peut suivre les tendances efficacement en identifiant le début et la fin des tendances à l'aide des ruptures du canal de Donchian.
Il utilise un stop loss mobile pour contrôler les pertes d'une seule transaction.
La combinaison des périodes de canal peut être librement sélectionnée pour s'adapter à différents produits et environnements de marché.
La logique de négociation est simple et claire, facile à comprendre et à mettre en œuvre.
Les risques de cette stratégie comprennent:
Incapacité à s'adapter à des marchés limités par la fourchette. Il souffrira de petites pertes consécutives lorsque la tendance est incertaine.
Risque d'échec de rupture. Les prix peuvent reculer après avoir franchi le canal, provoquant un stop loss.
Risque de sélection de la période: des réglages inappropriés de la période de diffusion peuvent entraîner un trafic de bruit.
Risque de baisse du ratio Sharpe: une augmentation de la taille de la position sans ajustement du stop loss peut entraîner une baisse du ratio Sharpe.
Les solutions sont les suivantes:
Les orientations d'optimisation de cette stratégie:
Ajout de conditions de filtrage pour éviter les éclaboussures, par exemple combiner le volume pour juger des véritables éclaboussures.
Optimisation de la combinaison des périodes de canal et de la taille des positions pour augmenter le taux de profit.
J'essaie d'optimiser le point de rupture pour trouver des ensembles de paramètres optimaux.
Augmentation des algorithmes d'apprentissage automatique pour l'optimisation dynamique et le réglage des paramètres.
La stratégie de suivi des tendances de Donchian identifie le début et la fin des tendances des prix en utilisant des canaux doubles, et adopte le style de trading suivant la tendance avec un contrôle efficace des pertes de transaction unique. Cette stratégie a un ajustement flexible des paramètres et une mise en œuvre facile, ce qui en fait une stratégie de suivi des tendances très pratique.
/*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 // =============================================================================