Il s'agit d'une stratégie de trading quantitative qui utilise des moyennes mobiles et des indicateurs MACD pour des opérations de percée dans les deux directions.
La stratégie utilise 3 moyennes mobiles SMMA de différentes longueurs et 1 moyenne mobile EMA pour déterminer la direction de la tendance. En même temps, elle combine l'indicateur MACD pour juger des tendances à court terme et des opportunités d'entrée. Plus précisément, la condition de déclenchement de l'achat est la suivante: le prix traverse toutes les moyennes mobiles vers le haut, et les moyennes plus courtes sont au-dessus des moyennes plus longues; tandis que la condition de déclenchement de la vente est l'inverse, le prix traverse toutes les moyennes mobiles vers le bas, et les moyennes plus courtes sont en dessous des moyennes plus longues.
On peut voir que cette stratégie utilise des moyennes mobiles pour juger des tendances à moyen et à long terme, et le MACD pour saisir de meilleures opportunités d'entrée en jugeant les renversements à court terme.
L'avantage de cette opération interpériodique est qu'elle permet de sélectionner des points d'inversion à court terme appropriés pour entrer dans la direction de tendance à forte probabilité, obtenant ainsi un meilleur rapport risque/rendement.
Les 3 moyennes SMMA plus le filtrage à plusieurs niveaux d'une ligne EMA permettent de déterminer efficacement la direction de la tendance à moyen et à long terme afin d'éviter de négocier contre tendance.
L'indicateur MACD qui évalue les points d'inversion à court terme pour entrer peut obtenir de meilleurs niveaux de prix d'entrée.
La stricte relation de séquence de moyenne mobile comme condition de filtrage peut réduire la probabilité de dysfonctionnements.
Les principaux risques de cette stratégie sont les suivants:
Les moyennes mobiles ont elles-mêmes des propriétés de retard plus élevées, ce qui peut manquer les opportunités d'inversion de tendance à court terme.
Les indicateurs MACD sont sujets à générer de faux signaux et doivent être filtrés en combinaison avec les niveaux de prix.
Les jugements sur plusieurs délais augmentent la complexité de la stratégie et sont sujets à l'échec.
Pour faire face au risque 1 et au risque 2, nous pouvons optimiser en raccourcissant de manière appropriée la moyenne mobile et le cycle du signal pour répondre rapidement aux renversements de tendance à court terme. Pour le risque 3, nous devons optimiser et tester pour différentes variétés et cycles afin d'adapter strictement les paramètres de stratégie aux caractéristiques de cette variété.
Les principaux aspects qui permettent d'optimiser cette stratégie sont les suivants:
Optimiser les paramètres des moyennes mobiles et du MACD pour mieux correspondre aux caractéristiques des différents cycles et variétés.
Augmenter les stratégies de stop loss en utilisant l'ATR ou d'autres indicateurs pour définir des stops mobiles raisonnables. Cela peut améliorer considérablement le contrôle des risques de la stratégie.
Cherchez de meilleurs indicateurs ou méthodes de filtrage pour remplacer les signaux MACD.
Testez différentes relations de ratio profit/perte afin d'obtenir des combinaisons de paramètres avec de meilleurs ratios risque/rendement.
En général, il s'agit d'un système innovant unique avec une pensée transversale. Il utilise les avantages des moyennes mobiles et du MACD pour réaliser une stratégie d'opération de jugement conjoint sur plusieurs délais. En optimisant et en ajustant les paramètres et les critères de filtrage, cette stratégie peut devenir une solution de trading quantitative très pratique.
/*backtest start: 2023-10-22 00:00:00 end: 2023-11-21 00:00:00 period: 1h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © SoftKill21 //@version=4 strategy("Koala Script",initial_capital=1000, commission_type=strategy.commission.cash_per_contract, commission_value=0.000065, slippage=3) fromDay = input(defval = 1, title = "From Day", minval = 1, maxval = 31) fromMonth = input(defval = 1, title = "From Month", minval = 1, maxval = 12) fromYear = input(defval = 2000, title = "From Year", minval = 1970) // To Date Inputs toDay = input(defval = 1, title = "To Day", minval = 1, maxval = 31) toMonth = input(defval = 8, title = "To Month", minval = 1, maxval = 12) toYear = input(defval = 2031, title = "To Year", minval = 1970) startDate = timestamp(fromYear, fromMonth, fromDay, 00, 00) finishDate = timestamp(toYear, toMonth, toDay, 00, 00) len = input(3, minval=1, title="Length") src = input(hl2, title="Source") smma = 0.0 sma1 = sma(src, len) smma := na(smma[1]) ? sma1 : (smma[1] * (len - 1) + src) / len len2 = input(6, minval=1, title="Length") src2 = input(hl2, title="Source") smma2 = 0.0 sma2 = sma(src2, len2) smma2 := na(smma2[1]) ? sma2 : (smma2[1] * (len2 - 1) + src2) / len2 len3 = input(9, minval=1, title="Length") src3 = input(hl2, title="Source") smma3 = 0.0 sma3 = sma(src3, len3) smma3 := na(smma3[1]) ? sma3 : (smma3[1] * (len3 - 1) + src3) / len3 len4 = input(50, minval=1, title="Length") src4 = input(close, title="Source") smma4 = 0.0 sma4 = sma(src4, len4) smma4 := na(smma4[1]) ? sma4 : (smma4[1] * (len4 - 1) + src4) / len4 len5 = input(200, minval=1, title="Length") src5 = input(close, title="Source") out5 = ema(src5, len5) timeinrange(res, sess) => time(res, sess) != 0 london=timeinrange(timeframe.period, "0300-1045") londonEntry=timeinrange(timeframe.period, "0300-0845") time_cond = time >= startDate and time <= finishDate and londonEntry fast_length = input(title="Fast Length", type=input.integer, defval=12) slow_length = input(title="Slow Length", type=input.integer, defval=26) srcc = input(title="Source", type=input.source, defval=close) signal_length = input(title="Signal Smoothing", type=input.integer, minval = 1, maxval = 50, defval = 9) sma_source = input(title="Simple MA(Oscillator)", type=input.bool, defval=false) sma_signal = input(title="Simple MA(Signal Line)", type=input.bool, defval=false) // Calculating fast_ma = sma_source ? sma(srcc, fast_length) : ema(srcc, fast_length) slow_ma = sma_source ? sma(srcc, slow_length) : ema(srcc, slow_length) macd = fast_ma - slow_ma signal = sma_signal ? sma(macd, signal_length) : ema(macd, signal_length) hist = macd - signal longCond = close > out5 and close > smma4 and close > smma3 and close > smma2 and close > smma and londonEntry and smma > smma2 and smma2>smma3 and smma3>smma4 and smma4>out5 shortCond = close < out5 and close < smma4 and close < smma3 and close < smma2 and close < smma and londonEntry and smma < smma2 and smma2<smma3 and smma3<smma4 and smma4<out5 //longCond2 = crossover(close,out5) and crossover(close,smma4) and crossover(close,smma3) and crossover(close,smma2) and crossover(close,smma) and time_cond //shortCond2 = crossunder(close,out5) and crossunder(close,smma4) and crossunder(close,smma3) and crossunder(close,smma2) and crossunder(close,smma) and time_cond length=input(14, title="ATR Length") mult=input(1.0, title="Percentage Multiplier (for ex., 0.7 = 70%)", step=0.1, minval=0.1, maxval=5.0) oa=input(false, title="Show actual ATR") ii=syminfo.pointvalue==0 s=ii?na:oa?atr(length):(syminfo.pointvalue * mult * atr(length)) tp=input(300,title="tp") sl=input(300,title="sl") //tp = s*10000 //sl= s*10000 //if(tp>300) // tp:=300 //if(sl>300) // sl:=300 //if(sl<150) // sl:=150 //if(tp<150) // tp:=150 strategy.initial_capital = 50000 //MONEY MANAGEMENT--------------------------------------------------------------'' balance = strategy.netprofit + strategy.initial_capital //current balance floating = strategy.openprofit //floating profit/loss risk = input(3,type=input.float,title="Risk %")/100 //risk % per trade //Calculate the size of the next trade temp01 = balance * risk //Risk in USD temp02 = temp01/sl //Risk in lots temp03 = temp02*100000 //Convert to contracts size = temp03 - temp03%1000 //Normalize to 1000s (Trade size) if(size < 10000) size := 10000 //Set min. lot size strategy.entry("long",1,when=longCond ) strategy.exit("closelong","long", profit=tp,loss=sl) //strategy.close("long",when= crossunder(close[4],smma4) and close[4] > close[3] and close[3]>close[2] and close[2] > close[1] and close[1] > close) strategy.entry("short",0,when=shortCond ) strategy.exit("closeshort","short", profit=tp,loss=sl) //strategy.close("short",when= crossover(close[4],smma4) and close[4] < close[3] and close[3]< close[2] and close[2] < close[1] and close[1] < close) strategy.close_all(when = not london) maxEntry=input(2,title="max entries") // strategy.risk.max_intraday_filled_orders(maxEntry)