Cette stratégie combine deux indicateurs pour identifier la direction de la tendance et effectuer des transactions. Premièrement, elle utilise le croisement de deux moyennes mobiles (rapides et moyennes) pour juger de la tendance à court terme; deuxièmement, elle utilise la plage de canaux et la moyenne mobile à long terme pour déterminer la direction de la tendance principale. Les signaux de trading ne sont générés que lorsque les deux jugements sont cohérents.
La stratégie utilise trois ensembles d'indicateurs pour le jugement. Premièrement, la croix d'or et la croix de mort de l'EMA rapide (26 périodes) et de l'EMA moyenne (50 périodes) pour déterminer la tendance à court terme; deuxièmement, calculer la plage de canal pour juger la tendance à moyen terme; enfin, calculer la SMA à long terme (200 périodes) et comparer avec le prix pour déterminer la direction de la tendance majeure. Les signaux de trading ne sont générés que lorsque les trois jugements sont cohérents.
Plus précisément, la logique est la suivante:
Crossover des moyennes mobiles rapides et moyennes (croix dorée pour la hausse, croix de mort pour la baisse) pour déterminer la tendance à court terme.
Si le prix traverse la fourchette pour déterminer la tendance à moyen terme. La fourchette est basée sur le MA à long terme plus/moins ATR fois un coefficient.
Comparaison du prix avec l'AM à long terme pour déterminer la tendance majeure.
Enfin, les signaux de négociation ne sont générés que lorsque les trois jugements sont cohérents.
Cette stratégie hybride à double indicateur présente plusieurs avantages:
Filtrer efficacement les faux signaux et améliorer la stabilité.
Une grande souplesse pour ajuster les paramètres pour différents marchés.
Combinez le trading de tendance et le trading de gamme. Les indicateurs à moyen et à court terme captent les tendances, l'indicateur à long terme détermine la gamme.
Une grande efficacité d'utilisation des capitaux: les ordres ne peuvent être passés que lorsque plusieurs indicateurs s'accordent, le capital peut être utilisé efficacement pour éviter les transactions inutiles.
Il y a aussi des risques:
Paramètres de réglage du risque: les périodes de MA et la plage de canaux doivent être correctement configurés, des réglages incorrects peuvent ne pas détecter les tendances ou provoquer des faux signaux excessifs.
L'augmentation du coût d'opportunité des deux indicateurs. Par rapport aux stratégies à indicateur unique, certaines opportunités de trading peuvent être manquées, incapables d'entrer et de sortir aux points optimaux.
Le mécanisme de stop loss nécessite de la prudence. Le stop loss de rupture ici peut causer des pertes inutiles. Le pourcentage de stop loss doit être configuré avec soin.
Cette stratégie fonctionne mieux sur les marchés à tendance apparente.
La stratégie peut être améliorée par les aspects suivants:
Testez différentes combinaisons de paramètres pour trouver l'optimum. Plus de backtests avec des données historiques pour localiser les configurations optimales.
Ajoutez un mécanisme d'arrêt de perte adaptatif.
Assistez avec les indicateurs de volume aux points critiques.
Optimiser la logique d'entrée. Considérer les entrées par étapes avec la moyenne des coûts pour réduire le risque d'entrée unique.
Combiner des modèles d'apprentissage automatique, introduire des réseaux neuronaux pour juger de la robustesse et de l'aptitude du modèle.
Cette stratégie tire parti des indicateurs de trois délais et de la double validation pour supprimer les faux signaux et améliorer la stabilité. Pendant ce temps, elle possède les mérites du trading de tendance et de gamme, avec une efficacité d'utilisation élevée du capital. Elle peut être améliorée par l'optimisation des paramètres, le réglage des pertes, l'intégration avec les indicateurs de volume, etc. Une stratégie quantitative hybride recommandée.
/*backtest start: 2023-11-19 00:00:00 end: 2023-12-19 00:00:00 period: 1h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=5 // Indicator to combines: // Trend Channel[Gu5] (SMA 200) + // EMA's cross (26, 50 ) + // Golden Cross (50, 200) // Author: @gu5tavo71 08/2019 // v2.3.6, 2022.02.18 // Trend Channel [Gu5] // Author: @gu5tavo71 08/2019 // // This source code is subject to these terms: // Attribution-NonCommercial 4.0 International (CC BY-NC 4.0) // https://www.safecreative.org/work/2202190517452-mix1-ema-cross-trend-channel-gu5- // You are free to: // Share, copy and redistribute this script // Adapt, transform and build on this script // Under the following terms: // Non-commercial: You cannot sell my indicator. You can't sell my work. // Attribution: If you post part of my code, you must give me proper credit // // I am using part of this code published by @PineCoders and Public Library // Disclaimer: I am not a financial advisor. // For purpose educate only. Use at your own risk. strategy(title = 'Mix1 : Ema Cross + Trend Channel [Gu5] - Backtest', shorttitle = 'Mix01', overlay = true, initial_capital = 100, default_qty_value = 100, default_qty_type = strategy.percent_of_equity, commission_value = 0.075, commission_type = strategy.commission.percent, format = format.price, precision = 2, process_orders_on_close = true) // --------- Inputs "==============================" | i_maSrc = input.source (close, 'MA Source' , group = 'EMAs') i_maFast1 = input.int (26, 'EMA Fast' , group = 'EMAs') i_maFast2 = input.int (50, 'EMA Medium' , group = 'EMAs') i_maLen = input.int (200, 'MA Trend' , group = 'Trend Channel') o_maLen1 = 'EMA' o_maLen2 = 'SMA' i_maLenSel = input.string (o_maLen2, 'MA Type' , group = 'Trend Channel', options = [o_maLen1, o_maLen2], tooltip = "EMA or SMA") i_htf = input.timeframe ('', 'Select Higher Timeframe' , tooltip = 'Only for MA Trend' , group = 'Trend Channel') i_rangeLen = input.float (0.618, 'Channel Range Length' , tooltip = 'ATR of the MA Trend', group = 'Trend Channel') i_slOn = input.bool (false, '■ Stop Loss On/Off' , group = 'Stop Loss') i_sl = input.float (2.618, 'SL %' , step = 0.1, group = 'Stop Loss') i_periodSw = input.bool (true, '■ Period On/Off' , group = 'Period') o_start = timestamp ( '2020-01-01 00:00 GMT-3' ) o_end = timestamp ( '2099-12-31 00:00 GMT-3' ) i_periodStar = input (o_start, 'Start Time' , group = 'Period') i_periodEnd = input (o_end, 'End Time' , group = 'Period') o_posSel1 = 'Only Long' o_posSel2 = 'Only Short' o_posSel3 = 'Both' i_posSel = input.string (o_posSel3, 'Position Type' , group = 'Strategy', options = [o_posSel1, o_posSel2, o_posSel3], tooltip = "Only Long, Only short or Both") o_typeS1 = 'Strategy 1' o_typeS2 = 'Strategy 2' i_typeS = input.string (o_typeS2, 'Strategy Type' , group = 'Strategy', options = [o_typeS1, o_typeS2], tooltip = "Strategy 1:\nLong, when the price (close) crosses the ema.\nStrategy 2:\nLong, only when ema goes up") i_barColOn = input.bool (true, '■ Bar Color On/Off' , group = 'Display') i_alertOn = input.bool (false, '■ Alert On/Off' , group = 'Display') i_channelOn = input.bool (false, '■ Channel Range On/Off' , tooltip = 'If the price (close) is over than the channel, the trend is bullish. If the price is under, bearish. And if the price is in the channel, it is in range', group = 'Display') i_goldenOn = input.bool (false, '■ Golden Cross On/Off' ) o_alert = '{{strategy.order.comment}}' i_alert = input.string (o_alert, 'Setting alert' , tooltip = 'For Alerts, just copy {{strategy.order.comment}} and paste in alert window.', group = 'Display') // --------- Calculations maFast1 = ta.ema(i_maSrc, i_maFast1) maFast2 = ta.ema(i_maSrc, i_maFast2) maDir = maFast1 > maFast2 ? 1 : -1 maTrend = request.security(syminfo.tickerid, i_htf, i_maLenSel == "SMA" ? ta.sma(close, i_maLen)[1] : ta.ema(close, i_maLen)[1], lookahead = barmerge.lookahead_on) //No repaint maTrendDir = i_maSrc >= maTrend ? 1 : -1 rangeAtr = ta.atr(i_maLen) * i_rangeLen rangeTop = maTrend + rangeAtr rangeBot = maTrend - rangeAtr rangeCh = (open <= rangeTop or close <= rangeTop) and (open >= rangeBot or close >= rangeBot) trendDir = i_typeS == 'Strategy 1' ? rangeCh ? 0 : maTrendDir == 1 and maDir == 1 and maTrend > maFast2 ? 0 : maTrendDir == -1 and maDir == -1 and maTrend < maFast2 ? 0 : maTrendDir == 1 and maDir == 1 ? 1 : maTrendDir == -1 and maDir == -1 ? -1 : 0 : rangeCh ? 0 : maTrendDir == 1 and maDir == 1 ? 1 : maTrendDir == -1 and maDir == -1 ? -1 : 0 GCross = i_goldenOn ? ta.crossover (maFast2, maTrend) : na DCross = i_goldenOn ? ta.crossunder(maFast2, maTrend) : na period = true // Set initial values condition = 0.0 entryLong = trendDir == 1 and i_posSel != 'Only Short' and (i_periodSw ? period : true) entryShort = trendDir == -1 and i_posSel != 'Only Long' and (i_periodSw ? period : true) exitLong = (trendDir != 1 or maDir == -1) and condition[1] == 1 and i_posSel != 'Only Short' and (i_periodSw ? period : true) exitShort = (trendDir != -1 or maDir == 1) and condition[1] == -1 and i_posSel != 'Only Long' and (i_periodSw ? period : true) closeCond = exitLong or exitShort // Stop Loss (sl) slEntry = close * i_sl / 100 slTop = close + slEntry slBot = close - slEntry slTopBuff = ta.valuewhen(condition[1] != 1 and entryLong, slBot, 0) slBotBuff = ta.valuewhen(condition[1] != -1 and entryShort, slTop, 0) slLine = condition[1] == -1 and entryLong ? slTopBuff : condition[1] == 1 and entryShort ? slBotBuff : condition[1] == 1 or entryLong ? slTopBuff : condition[1] == -1 or entryShort ? slBotBuff : na slTopCross = condition[1] == 1 and ta.crossunder(close, slLine) or high > slLine and low < slLine slBotCross = condition[1] == -1 and ta.crossover (close, slLine) or high > slLine and low < slLine slExit = i_slOn ? slTopCross or slBotCross : na // Conditions condition := condition[1] != 1 and entryLong ? 1 : condition[1] != -1 and entryShort ? -1 : condition[1] != 0 and slExit ? 0 : condition[1] != 0 and exitLong ? 0 : condition[1] != 0 and exitShort ? 0 : nz(condition[1]) long = condition[1] != 1 and condition == 1 short = condition[1] != -1 and condition == -1 xl = condition[1] == 1 and exitLong and not slExit xs = condition[1] == -1 and exitShort and not slExit sl = condition[1] != 0 and slExit // --------- Colors c_green = #006400 //Green c_greenLight = #388e3c //Green Light c_red = #8B0000 //Red c_redLight = #b71c1c //Red Light c_emas = xl ? color.new(color.orange, 99) : xs ? color.new(color.orange, 99) : trendDir == 1 and maDir == 1 ? color.new(c_green, 99) : trendDir == -1 and maDir == -1 ? color.new(c_red, 99) : color.new(color.orange, 99) c_maFill = xl ? color.new(color.orange, 70) : xs ? color.new(color.orange, 70) : trendDir == 1 and maDir == 1 ? color.new(c_green, 70) : trendDir == -1 and maDir == -1 ? color.new(c_red, 70) : color.new(color.orange, 70) c_maTrend = trendDir == 0 ? color.new(color.orange, 0) : trendDir == 1 and maTrend[1] < maTrend ? color.new(c_green, 0) : trendDir == 1 and maTrend[1] >= maTrend ? color.new(c_greenLight, 0) : trendDir == -1 and maTrend[1] < maTrend ? color.new(c_redLight, 0) : trendDir == -1 and maTrend[1] >= maTrend ? color.new(c_red, 0) : na c_ch = trendDir == 0 ? color.new(color.orange, 50) : trendDir == 1 ? color.new(c_green, 50) : trendDir == -1 ? color.new(c_red, 50) : na c_slLineUp = ta.rising (slLine, 1) c_slLineDn = ta.falling(slLine, 1) c_slLine = c_slLineUp ? na : c_slLineDn ? na : color.red c_barCol = trendDir == 0 ? color.new(color.orange, 0) : trendDir == 1 and open <= close ? color.new(c_green, 0) : trendDir == 1 and open > close ? color.new(c_greenLight, 0) : trendDir == -1 and open >= close ? color.new(c_red, 0) : trendDir == -1 and open < close ? color.new(c_redLight, 0) : color.new(color.orange, 0) // --------- Plots p_maFast1 = plot( maFast1, title = 'EMA Fast 1', color = c_emas, linewidth = 1) p_maFast2 = plot( maFast2, title = 'EMA Fast 2', color = c_emas, linewidth = 2) fill( p_maFast1, p_maFast2, title = 'EMAs Fill', color = c_maFill) plot( maTrend, title = 'SMA Trend', color = c_maTrend, linewidth = 3) p_chTop = plot( i_channelOn ? rangeTop : na, title = 'Top Channel', color = c_maTrend, linewidth = 1) p_chBot = plot( i_channelOn ? rangeBot : na, title = 'Bottom Channel', color = c_maTrend, linewidth = 1) fill( p_chTop, p_chBot, title = 'Channel', color = c_ch) plot( i_slOn and condition != 0 ? slLine : na, title = 'Stop Loss Line', color = c_slLine, linewidth = 1, style = plot.style_linebr) // --------- Alerts barcolor(i_barColOn ? c_barCol : na) plotshape( i_alertOn and long ? high : na, title = 'Long Label', text = 'Long', textcolor = color.white, color = color.new(c_green, 0), style = shape.labelup, size = size.normal, location = location.belowbar) plotshape( i_alertOn and short ? low : na, title = 'Short Label', text = 'Short', textcolor = color.white, color = color.new(c_red, 0), style = shape.labeldown, size = size.normal, location = location.abovebar) plotshape( i_alertOn and (xl or xs) ? close : na, title = 'Close Label', text = 'Close', textcolor = color.orange, color = color.new(color.orange, 0), style = shape.xcross, size = size.small, location = location.absolute) plotshape( i_alertOn and sl ? slLine : na, title = 'Stop Loss', text = 'Stop\nLoss', textcolor = color.orange, color = color.new(color.orange, 0), style = shape.xcross, size = size.small, location = location.absolute) plotshape( i_alertOn and i_goldenOn and GCross ? maTrend : na, title = 'Golden Cross Label', text = 'Golden\nCross', textcolor = color.white, color = color.new(color.orange, 0), style = shape.labelup, size = size.normal, location = location.absolute) plotshape( i_alertOn and i_goldenOn and DCross ? maTrend : na, title = 'Death Cross Label', text = 'Death\nCross', textcolor = color.white, color = color.new(color.orange, 0), style = shape.labeldown, size = size.normal, location = location.absolute) bgcolor( i_periodSw and not period ? color.new(color.gray, 90) : na, title = 'Session') // --------- Backtest if long and strategy.position_size == 0 and barstate.isconfirmed strategy.entry('Long', strategy.long, comment = 'long') if short and strategy.position_size == 0 and barstate.isconfirmed strategy.entry('Short', strategy.short, comment = 'short') strategy.exit( id = 'XL', from_entry = 'Long', stop = i_slOn ? slLine : na) strategy.exit( id = 'XS', from_entry = 'Short', stop = i_slOn ? slLine : na) strategy.close( 'Long', comment = 'Close', when = xl) strategy.close( 'Short', comment = 'Close', when = xs)