Cette stratégie est un système de suivi des tendances basé sur des indicateurs d'indicateurs de dynamique et d'indicateurs de moyenne mobile exponentielle (EMA). Elle génère des signaux de trading grâce à la combinaison de signaux de percée de dynamique et de filtres de tendance EMA, exécutant des transactions lorsque les tendances du marché sont clairement définies.
La logique de base de la stratégie repose sur plusieurs éléments clés:
Risque de choc du marché: peut générer de fréquents faux signaux de rupture sur les marchés latéraux. Solution suggérée: ajouter des filtres d'oscillateur ou augmenter les seuils de percée.
Risque de glissement: risque de glissement significatif pendant les périodes de forte volatilité. Solution suggérée: établir des plages de stop-loss raisonnables et éviter de négocier en période de forte volatilité.
Risque de surtrading: des signaux fréquents peuvent conduire à un trading excessif. Suggestion de solution: Fixez des limites de trading quotidiennes appropriées.
Il s'agit d'une stratégie bien conçue de suivi des tendances qui capture les opportunités du marché grâce à la combinaison de la percée de l'élan et des tendances EMA. La stratégie dispose d'un système complet de gestion des risques et de puissantes fonctions d'analyse statistique, offrant une bonne praticité et une évolutivité. Grâce à l'optimisation et à l'amélioration continues, cette stratégie a le potentiel de maintenir une performance stable dans différents environnements de marché.
/*backtest start: 2019-12-23 08:00:00 end: 2024-12-09 08:00:00 period: 2d basePeriod: 2d exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=6 strategy("[Mustang Algo] EMA Momentum Strategy", shorttitle="[Mustang Algo] Mom Strategy", overlay=true, initial_capital=10000, default_qty_type=strategy.fixed, default_qty_value=1, pyramiding=0, calc_on_every_tick=false, max_bars_back=5000) // Momentum Parameters len = input.int(10, minval=1, title="Length") src = input(close, title="Source") momTimeframe = input.timeframe("", title="Momentum Timeframe") timeframe_gaps = input.bool(true, title="Autoriser les gaps de timeframe") momFilterLong = input.float(5, title="Filtre Momentum Long", minval=0) momFilterShort = input.float(-5, title="Filtre Momentum Short", maxval=0) // EMA Filter useEmaFilter = input.bool(true, title="Utiliser Filtre EMA") emaLength = input.int(200, title="EMA Length", minval=1) // Position Size contractSize = input.float(1.0, title="Taille de position", minval=0.01, step=0.01) // Time filter settings use_time_filter = input.bool(false, title="Utiliser le Filtre de Temps") start_hour = input.int(9, title="Heure de Début", minval=0, maxval=23) start_minute = input.int(30, title="Minute de Début", minval=0, maxval=59) end_hour = input.int(16, title="Heure de Fin", minval=0, maxval=23) end_minute = input.int(30, title="Minute de Fin", minval=0, maxval=59) gmt_offset = input.int(0, title="Décalage GMT", minval=-12, maxval=14) // Risk Management useAtrSl = input.bool(false, title="Utiliser ATR pour SL/TP") atrPeriod = input.int(14, title="Période ATR", minval=1) atrMultiplier = input.float(1.5, title="Multiplicateur ATR pour SL", minval=0.1, step=0.1) stopLossPerc = input.float(1.0, title="Stop Loss (%)", minval=0.01, step=0.01) tpRatio = input.float(2.0, title="Take Profit Ratio", minval=0.1, step=0.1) // Daily trade limit maxDailyTrades = input.int(2, title="Limite de trades par jour", minval=1) // Variables for tracking daily trades var int dailyTradeCount = 0 // Reset daily trade count if dayofweek != dayofweek[1] dailyTradeCount := 0 // Time filter function is_within_session() => current_time = time(timeframe.period, "0000-0000:1234567", gmt_offset) start_time = timestamp(year, month, dayofmonth, start_hour, start_minute, 0) end_time = timestamp(year, month, dayofmonth, end_hour, end_minute, 0) in_session = current_time >= start_time and current_time <= end_time not use_time_filter or in_session // EMA Calculation ema200 = ta.ema(close, emaLength) // Momentum Calculation gapFillMode = timeframe_gaps ? barmerge.gaps_on : barmerge.gaps_off mom = request.security(syminfo.tickerid, momTimeframe, src - src[len], gapFillMode) // ATR Calculation atr = ta.atr(atrPeriod) // Signal Detection with Filters crossoverUp = ta.crossover(mom, momFilterLong) crossoverDown = ta.crossunder(mom, momFilterShort) emaUpTrend = close > ema200 emaDownTrend = close < ema200 // Trading Conditions longCondition = crossoverUp and (not useEmaFilter or emaUpTrend) and is_within_session() and dailyTradeCount < maxDailyTrades and barstate.isconfirmed shortCondition = crossoverDown and (not useEmaFilter or emaDownTrend) and is_within_session() and dailyTradeCount < maxDailyTrades and barstate.isconfirmed // Calcul des niveaux de Stop Loss et Take Profit float stopLoss = useAtrSl ? (atr * atrMultiplier) : (close * stopLossPerc / 100) float takeProfit = stopLoss * tpRatio // Modification des variables pour éviter les erreurs de repainting var float entryPrice = na var float currentStopLoss = na var float currentTakeProfit = na // Exécution des ordres avec gestion des positions if strategy.position_size == 0 if longCondition entryPrice := close currentStopLoss := entryPrice - stopLoss currentTakeProfit := entryPrice + takeProfit strategy.entry("Long", strategy.long, qty=contractSize) strategy.exit("Exit Long", "Long", stop=currentStopLoss, limit=currentTakeProfit) dailyTradeCount += 1 if shortCondition entryPrice := close currentStopLoss := entryPrice + stopLoss currentTakeProfit := entryPrice - takeProfit strategy.entry("Short", strategy.short, qty=contractSize) strategy.exit("Exit Short", "Short", stop=currentStopLoss, limit=currentTakeProfit) dailyTradeCount += 1 // Plot EMA plot(ema200, color=color.yellow, linewidth=2, title="EMA 200") // Plot Signals plotshape(longCondition, title="Long Signal", location=location.belowbar, color=color.green, style=shape.triangleup, size=size.small) plotshape(shortCondition, title="Short Signal", location=location.abovebar, color=color.red, style=shape.triangledown, size=size.small) // // Performance Statistics // var int longWins = 0 // var int longLosses = 0 // var int shortWins = 0 // var int shortLosses = 0 // if strategy.closedtrades > 0 // trade = strategy.closedtrades - 1 // isLong = strategy.closedtrades.entry_price(trade) < strategy.closedtrades.exit_price(trade) // isWin = strategy.closedtrades.profit(trade) > 0 // if isLong and isWin // longWins += 1 // else if isLong and not isWin // longLosses += 1 // else if not isLong and isWin // shortWins += 1 // else if not isLong and not isWin // shortLosses += 1 // longTrades = longWins + longLosses // shortTrades = shortWins + shortLosses // longWinRate = longTrades > 0 ? (longWins / longTrades) * 100 : 0 // shortWinRate = shortTrades > 0 ? (shortWins / shortTrades) * 100 : 0 // overallWinRate = strategy.closedtrades > 0 ? (strategy.wintrades / strategy.closedtrades) * 100 : 0 // avgRR = strategy.grossloss != 0 ? math.abs(strategy.grossprofit / strategy.grossloss) : 0 // // Display Statistics // var table statsTable = table.new(position.top_right, 4, 7, border_width=1) // if barstate.islastconfirmedhistory // table.cell(statsTable, 0, 0, "Type", bgcolor=color.new(color.blue, 90)) // table.cell(statsTable, 1, 0, "Win", bgcolor=color.new(color.blue, 90)) // table.cell(statsTable, 2, 0, "Lose", bgcolor=color.new(color.blue, 90)) // table.cell(statsTable, 3, 0, "Daily Trades", bgcolor=color.new(color.blue, 90)) // table.cell(statsTable, 0, 1, "Long", bgcolor=color.new(color.blue, 90)) // table.cell(statsTable, 1, 1, str.tostring(longWins), bgcolor=color.new(color.blue, 90)) // table.cell(statsTable, 2, 1, str.tostring(longLosses), bgcolor=color.new(color.blue, 90)) // table.cell(statsTable, 3, 1, str.tostring(dailyTradeCount) + "/" + str.tostring(maxDailyTrades), bgcolor=color.new(color.blue, 90)) // table.cell(statsTable, 0, 2, "Short", bgcolor=color.new(color.blue, 90)) // table.cell(statsTable, 1, 2, str.tostring(shortWins), bgcolor=color.new(color.blue, 90)) // table.cell(statsTable, 2, 2, str.tostring(shortLosses), bgcolor=color.new(color.blue, 90)) // table.cell(statsTable, 0, 3, "Win Rate", bgcolor=color.new(color.blue, 90)) // table.cell(statsTable, 1, 3, "Long: " + str.tostring(longWinRate, "#.##") + "%", bgcolor=color.new(color.blue, 90)) // table.cell(statsTable, 2, 3, "Short: " + str.tostring(shortWinRate, "#.##") + "%", bgcolor=color.new(color.blue, 90)) // table.cell(statsTable, 0, 4, "Overall", bgcolor=color.new(color.blue, 90)) // table.cell(statsTable, 1, 4, "Win Rate: " + str.tostring(overallWinRate, "#.##") + "%", bgcolor=color.new(color.blue, 90)) // table.cell(statsTable, 2, 4, "Total: " + str.tostring(strategy.closedtrades) + " | RR: " + str.tostring(avgRR, "#.##"), bgcolor=color.new(color.blue, 90)) // table.cell(statsTable, 0, 5, "Trading Hours", bgcolor=color.new(color.blue, 90)) // table.cell(statsTable, 1, 5, "Start: " + str.format("{0,time,HH:mm}", start_hour * 60 * 60 * 1000 + start_minute * 60 * 1000), bgcolor=color.new(color.blue, 90)) // table.cell(statsTable, 2, 5, "End: " + str.format("{0,time,HH:mm}", end_hour * 60 * 60 * 1000 + end_minute * 60 * 1000), bgcolor=color.new(color.blue, 90)) // table.cell(statsTable, 3, 5, "GMT: " + (gmt_offset >= 0 ? "+" : "") + str.tostring(gmt_offset), bgcolor=color.new(color.blue, 90)) // table.cell(statsTable, 0, 6, "SL/TP Method", bgcolor=color.new(color.blue, 90)) // table.cell(statsTable, 1, 6, useAtrSl ? "ATR-based" : "Percentage-based", bgcolor=color.new(color.blue, 90)) // table.cell(statsTable, 2, 6, useAtrSl ? "ATR: " + str.tostring(atrPeriod) : "SL%: " + str.tostring(stopLossPerc), bgcolor=color.new(color.blue, 90)) // table.cell(statsTable, 3, 6, "TP Ratio: " + str.tostring(tpRatio), bgcolor=color.new(color.blue, 90))