Cette stratégie est basée sur des moyennes mobiles et des lignes d'enveloppe dynamiques pour mettre en œuvre à la fois le trading long et court. Elle suit les écarts de prix au-delà des lignes d'enveloppe pour établir des positions et ferme des positions lorsque le prix tombe en dessous de la moyenne mobile de base.
Tout d'abord, cette stratégie calcule la moyenne mobile de référence en fonction du type et de la longueur de la moyenne mobile définis par l'utilisateur.
Par exemple, 5% signifie établir des positions lorsque le prix fluctue de 5% au-delà de la moyenne mobile de base. Le nombre de lignes d'enveloppe peut être personnalisé.
En ce qui concerne les règles d'entrée, allez long lorsque le prix dépasse la ligne inférieure de l'enveloppe, allez court lorsque le prix dépasse la ligne supérieure de l'enveloppe.
Enfin, fermez toutes les positions lorsque le prix retombe en dessous de la moyenne mobile de base.
Il convient de noter que cette stratégie met en œuvre un établissement partiel des positions.
Les plus grands avantages de cette stratégie:
L'utilisation de la moyenne mobile pour déterminer la direction de la tendance est une méthode bien établie.
Le fait de filtrer un peu de bruit avec des lignes d'enveloppe, empêchant le commerce excessivement sensible.
L'établissement partiel de la position améliore la résilience de la stratégie. Même si un côté échoue, l'autre peut continuer à fonctionner bien. Cela optimise le rapport risque-rendement global.
Numéro de ligne de moyenne mobile et d'enveloppe personnalisable, ce qui augmente la flexibilité pour l'ajustement des paramètres en fonction des différents produits.
Les principaux risques de cette stratégie:
Le système des moyennes mobiles n'est pas sensible aux signaux de croix dorée.
Un réglage trop large de la ligne d'enveloppe peut augmenter la fréquence des transactions et le risque de glissement. Un réglage trop étroit peut manquer des mouvements plus importants.
Cette stratégie rencontre probablement plus de succès sur différents marchés, de sorte que les produits tendance sont préférables.
L'établissement partiel des limites de position par bénéfice de transaction.
Les principales orientations pour optimiser cette stratégie:
Remplacer par d'autres indicateurs d'entrée/sortie tels que KDJ, etc. ou ajouter des filtres avec plusieurs indicateurs.
Ajoutez une logique stop profit/loss, ce qui permet de réaliser des bénéfices et d'atténuer activement certains risques.
Optimiser les paramètres pour trouver les meilleures combinaisons de moyenne mobile et d'enveloppe.
Incorporer l'apprentissage en profondeur, etc. pour un réglage intelligent des paramètres.
Considérez les différences de produit et de marché, définissez plusieurs ensembles de paramètres adaptés aux différents environnements de négociation.
En conclusion, cette stratégie de moyenne mobile enveloppe dynamique fonctionne très bien pour le trading de tendance. Elle est simple, efficace, facile à comprendre et à optimiser. En tant que stratégie de base, elle a une grande plasticité et extensibilité. Lorsqu'elle est combinée à des systèmes plus complexes, elle peut être encore améliorée pour des rendements plus élevés et de meilleures mesures ajustées au risque. Elle sert donc d'excellente base pour les stratégies de trading quantitatives.
/*backtest start: 2024-01-05 00:00:00 end: 2024-02-04 00:00:00 period: 1h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=5 strategy("Envelope Strategy", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=100, initial_capital=1000, pyramiding = 5, commission_type=strategy.commission.percent, commission_value=0.0) // CopyRight Crypto Robot src = input(ohlc4, title="Source", group = "Base MA") ma_base_window = input.int(5, "Base Mooving Average Window", step = 1, group = "Base MA") ma_type = input.string(defval='1. SMA', options=['1. SMA', '2. PCMA', '3. EMA', '4. WMA', '5. DEMA', '6. ZLEMA', '7. HMA'], title='MA Type', group = "Base MA") envelope_1_pct = input.float(0.05, "Envelope 1", step = 0.01, group = "Envelopes") envelope_2_pct = input.float(0.10, "Envelope 2", step = 0.01, group = "Envelopes") envelope_3_pct = input.float(0.15, "Envelope 3", step = 0.01, group = "Envelopes") envelope_4_pct = input.float(0.0, "Envelope 4", step = 0.01, group = "Envelopes") envelope_5_pct = input.float(0.0, "Envelope 5", step = 0.01, group = "Envelopes") use_longs = input.bool(true, 'Long Positions') use_short = input.bool(true, 'Short Positions') total_envelope = 0 if envelope_1_pct > 0 total_envelope := total_envelope + 1 if envelope_2_pct > 0 total_envelope := total_envelope + 1 if envelope_3_pct > 0 total_envelope := total_envelope + 1 if envelope_4_pct > 0 total_envelope := total_envelope + 1 if envelope_5_pct > 0 total_envelope := total_envelope + 1 // --------------------------------------------- // -------------- INDICATORS ------------------- ma_function(MA_type, MA_length) => zlema_lag = (MA_length - 1) / 2 hma_src = MA_type == '7. HMA' ? 2 * ta.wma(src, math.floor(MA_length / 2)) - ta.wma(src, MA_length) : na MA_type == '1. SMA' ? ta.sma(src, MA_length) : MA_type == '2. PCMA' ? (ta.highest(high, MA_length) + ta.lowest(low, MA_length)) / 2 : MA_type == '3. EMA' ? ta.ema(src, MA_length) : MA_type == '4. WMA' ? ta.wma(src, MA_length) : MA_type == '5. DEMA' ? 2 * ta.ema(src, MA_length) - ta.ema(ta.ema(src, MA_length), MA_length) : MA_type == '6. ZLEMA' ? ta.ema(src + src - src[zlema_lag], MA_length) : MA_type == '7. HMA' ? ta.wma(hma_src, math.floor(math.sqrt(MA_length))) : na ma_base = ma_function(ma_type, ma_base_window) ma_high_1 = envelope_1_pct > 0 ? ma_base * (1 + envelope_1_pct) : na ma_high_2 = envelope_2_pct > 0 ? ma_base * (1 + envelope_2_pct) : na ma_high_3 = envelope_3_pct > 0 ? ma_base * (1 + envelope_3_pct) : na ma_high_4 = envelope_4_pct > 0 ? ma_base * (1 + envelope_4_pct) : na ma_high_5 = envelope_5_pct > 0 ? ma_base * (1 + envelope_5_pct) : na ma_low_1 = envelope_1_pct > 0 ? ma_base * (1 - envelope_1_pct) : na ma_low_2 = envelope_2_pct > 0 ? ma_base * (1 - envelope_2_pct) : na ma_low_3 = envelope_3_pct > 0 ? ma_base * (1 - envelope_3_pct) : na ma_low_4 = envelope_4_pct > 0 ? ma_base * (1 - envelope_4_pct) : na ma_low_5 = envelope_5_pct > 0 ? ma_base * (1 - envelope_5_pct) : na // --------------------------------------------- // --------------- STRATEGY -------------------- if use_longs if envelope_1_pct > 0 and strategy.opentrades < 1 strategy.entry('long 1', strategy.long, limit=ma_low_1, qty=(strategy.equity / ma_low_1) * (1 / total_envelope)) if envelope_2_pct > 0 and strategy.opentrades < 2 strategy.entry('long 2', strategy.long, limit=ma_low_2, qty=(strategy.equity / ma_low_2) * (1 / total_envelope)) if envelope_3_pct > 0 and strategy.opentrades < 3 strategy.entry('long 3', strategy.long, limit=ma_low_3, qty=(strategy.equity / ma_low_3) * (1 / total_envelope)) if envelope_4_pct > 0 and strategy.opentrades < 4 strategy.entry('long 4', strategy.long, limit=ma_low_4, qty=(strategy.equity / ma_low_4) * (1 / total_envelope)) if envelope_5_pct > 0 and strategy.opentrades < 5 strategy.entry('long 5', strategy.long, limit=ma_low_5, qty=(strategy.equity / ma_low_5) * (1 / total_envelope)) if use_short if envelope_1_pct > 0 and strategy.opentrades < 1 strategy.entry('short 1', strategy.short, limit=ma_high_1, qty=(strategy.equity / ma_high_1) * (1 / total_envelope)) if envelope_2_pct > 0 and strategy.opentrades < 2 strategy.entry('short 2', strategy.short, limit=ma_high_2, qty=(strategy.equity / ma_high_2) * (1 / total_envelope)) if envelope_3_pct > 0 and strategy.opentrades < 3 strategy.entry('short 3', strategy.short, limit=ma_high_3, qty=(strategy.equity / ma_high_3) * (1 / total_envelope)) if envelope_4_pct > 0 and strategy.opentrades < 4 strategy.entry('short 4', strategy.short, limit=ma_high_4, qty=(strategy.equity / ma_high_4) * (1 / total_envelope)) if envelope_5_pct > 0 and strategy.opentrades < 5 strategy.entry('short 5', strategy.short, limit=ma_high_5, qty=(strategy.equity / ma_high_5) * (1 / total_envelope)) strategy.exit('close', limit=ma_base) // --------------------------------------------- // ------------------ PLOT --------------------- ma_base_plot = plot(ma_base, title = "Base MA", color = color.orange, linewidth = 3, offset = 1) ma_high_1_plot = plot(ma_high_1, title = "MA high 1", color = color.red, offset = 1) ma_high_2_plot = plot(ma_high_2, title = "MA high 2", color = color.red, offset = 1) ma_high_3_plot = plot(ma_high_3, title = "MA high 3", color = color.red, offset = 1) ma_high_4_plot = plot(ma_high_4, title = "MA high 4", color = color.red, offset = 1) ma_high_5_plot = plot(ma_high_5, title = "MA high 5", color = color.red, offset = 1) ma_low_1_plot = plot(ma_low_1, title = "MA low 1", color = color.green, offset = 1) ma_low_2_plot = plot(ma_low_2, title = "MA low 2", color = color.green, offset = 1) ma_low_3_plot = plot(ma_low_3, title = "MA low 3", color = color.green, offset = 1) ma_low_4_plot = plot(ma_low_4, title = "MA low 4", color = color.green, offset = 1) ma_low_5_plot = plot(ma_low_5, title = "MA low 5", color = color.green, offset = 1) plot(ohlc4, color=color.purple) // use_period = input.bool(false, "Période spécifique ?", group="periode") // startDate = input.time(timestamp("01 Jan 2020"), "Date de début", group="periode") // endDate = input.time(timestamp("01 Jan 2025"), "Date de fin", group="periode") //------------------------------------------ //-------------Indicateurs------------------ // inDateRange = use_period ? ((time >= startDate) and (time < endDate)) : true // //--------------Backtest------------------- // strategy_pnl = strategy.netprofit + strategy.openprofit // bnh_strategy_pnl_pcnt = (strategy_pnl / strategy.initial_capital) * 100 // float bnh_start_bar = na // bnh_start_bar := na(bnh_start_bar[1]) or inDateRange != true? close : bnh_start_bar[1] // float bnl_buy_hold_equity = na // bnl_buy_hold_equity := inDateRange == true ? ((close - bnh_start_bar)/bnh_start_bar) * 100 : bnl_buy_hold_equity[1] // bnh_vs_diff = bnh_strategy_pnl_pcnt - bnl_buy_hold_equity // bnh_diff_color = bnh_vs_diff > 0 ? color.new(color.green, inDateRange ? 60 : 100) : color.new(color.red, inDateRange ? 60 : 100) // var Table = table.new(position.top_right, columns = 2, rows = 4, border_width = 1, bgcolor = color.black, border_color = color.gray) // table.cell(table_id = Table, column = 0, row = 0, text_color=(bnh_strategy_pnl_pcnt>bnl_buy_hold_equity)?color.gray:color.green, text_size = size.normal, text = "Buy & hold profit") // table.cell(table_id = Table, column = 1, row = 0, text_color=(bnh_strategy_pnl_pcnt>bnl_buy_hold_equity)?color.gray:color.green, text_size = size.normal, text = str.tostring(bnl_buy_hold_equity, '#.##') + ' %') // table.cell(table_id = Table, column = 0, row = 1, text_color=(bnh_strategy_pnl_pcnt<bnl_buy_hold_equity)?color.gray:color.green, text_size = size.normal, text = "Strategy profit") // table.cell(table_id = Table, column = 1, row = 1, text_color=(bnh_strategy_pnl_pcnt<bnl_buy_hold_equity)?color.gray:color.green, text_size = size.normal, text = str.tostring(bnh_strategy_pnl_pcnt, '#.##') + ' %') // table.cell(table_id = Table, column = 0, row = 2, text_color=color.yellow, text_size = size.normal, text = "Date de début") // table.cell(table_id = Table, column = 1, row = 2, text_color=color.yellow, text_size = size.normal, text = str.format("{0,date,dd-MM-YYYY}",strategy.closedtrades.entry_time(1)))