La stratégie d'inversion des moyennes mobiles doubles est une stratégie de trading quantitative qui utilise des moyennes mobiles doubles pour identifier les tendances à court et à long terme.
La stratégie d'inversion des moyennes mobiles doubles est fondée sur les hypothèses suivantes:
La SMA de 200 jours identifie la tendance à long terme prédominante du marché. Lorsque le prix est au-dessus de la ligne de 200 jours, il indique que le marché est dans une tendance haussière à long terme.
La ligne SMA de 10 jours indique les retombées à court terme du prix.
Dans une tendance haussière du marché haussier, toute baisse à court terme peut être considérée comme une opportunité d'achat pour capturer efficacement le rebond à la hausse.
Sur la base des hypothèses ci-dessus, les signaux commerciaux sont générés comme suit:
Lorsque le prix de clôture dépasse la SMA de 200 jours et dépasse simultanément la SMA de 10 jours, il déclenche un signal d'achat, car il montre que la tendance à long terme reste positive mais qu'un recul à court terme s'est produit.
Si le prix recroise au-dessus de la SMA de 10 jours lorsqu'il est dans une position longue, la tendance à court terme s'est inversée, de sorte que la position sera fermée immédiatement.
Chaque fois qu'il y a une récession majeure (dépassant un seuil prédéfini), il présente une occasion d'acheter la baisse comme un signal contraire.
Avec cette conception, la stratégie vise à capitaliser efficacement sur les retombées à la hausse lors de tendances haussières soutenues tout en contrôlant le risque en utilisant des arrêts de perte.
La stratégie d'inversion des moyennes mobiles doubles présente les principaux avantages suivants:
Bien qu'elle soit généralement efficace, la stratégie présente les limites suivantes:
Les améliorations supplémentaires apportées à cette stratégie comprennent:
En résumé, la stratégie d'inversion des moyennes mobiles doubles est une approche très pratique. Elle permet une baisse de rentabilité profitable lors de tendances haussières soutenues en utilisant l'analyse des moyennes mobiles associée à des arrêts de pertes. Elle offre également des capacités de détection du régime du marché et de contrôle des risques. Avec une amélioration continue, la stratégie offre un fort potentiel pour fournir une performance différenciée.
/*backtest start: 2023-11-24 00:00:00 end: 2023-12-24 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/ // © Gold_D_Roger //note: spreading 1 statement over multiple lines needs 1 apce + 1 tab | multi line function is 1 tab //Recommended tickers: SPY (D), QQQ (D) and big indexes, AAPL (4H) //@version=5 strategy("Davin's 10/200MA Pullback on SPY Strategy v2.0", overlay=true, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=10, // 10% of equity on each trade commission_type=strategy.commission.cash_per_contract, commission_value=0.1) //Insert your broker's rate, IB is 0.005USD or tiered //Best parameters // SPY D // Stop loss 0.15 // commission of 0.005 USD using Interactive brokers // Exit on lower close // Buy more when x% down --> 14% // DO NOT include stop condition using MA crossover // Get User Input i_ma1 = input.int(title="MA Length 1", defval=200, step=10, group="Strategy Parameters", tooltip="Long-term MA 200") i_ma2 = input.int(title="MA Length 2", defval=10, step=10, group="Strategy Parameters", tooltip="Short-term MA 10") i_ma3 = input.int(title="MA Length 3", defval=50, step=1, group="Strategy Parameters", tooltip="MA for crossover signals`") i_stopPercent = input.float(title="Stop Loss Percent", defval=0.15, step=0.01, group="Strategy Parameters", tooltip="Hard stop loss of 10%") i_startTime = input(title="Start filter", defval=timestamp("01 Jan 2013 13:30 +0000"), group="Time filter", tooltip="Start date and time to begin") i_endTime = input(title="End filter", defval=timestamp("01 Jan 2099 19:30 +0000"), group="Time filter", tooltip="End date and time to stop") i_lowerClose = input.bool(title="Exit on lower close", defval=true, group="Strategy Parameters", tooltip="Wait for lower close after above 10SMA before exiting") // optimise exit strat, boolean type creates tickbox type inputs i_contrarianBuyTheDip = input.bool(title="Buy whenever more than x% drawdown", defval=true, group="Strategy Parameters", tooltip="Buy the dip! Whenever x% or more drawdown on SPY") i_contrarianTrigger = input.int(title="Trigger % drop to buy the dip", defval=14, step=1, group="Strategy Parameters", tooltip="% drop to trigger contrarian Buy the Dip!") //14% to be best for SPY 1D //20% best for AMZN 1D i_stopByCrossover_MA2_3 = input.bool(title="Include stop condition using MA crossover", defval=false, group="Strategy Parameters", tooltip="Sell when crossover of MA2/1 happens") // Get indicator values ma1 = ta.sma(close,i_ma1) //param 1 ma2 = ta.sma(close,i_ma2) //param 2 ma3 = ta.sma(close,i_ma3) //param 3 ma_9 = ta.ema(close,9) //param 2 ma_20 = ta.ema(close,20) //param 3 // Check filter(s) f_dateFilter = true //make sure date entries are within acceptable range // Highest price of the prev 52 days: https://www.tradingcode.net/tradingview/largest-maximum-value/#:~:text=()%20versus%20ta.-,highest(),max()%20and%20ta. highest52 = ta.highest(high,52) overall_change = ((highest52 - close[0]) / highest52) * 100 // Check buy/sell conditions var float buyPrice = 0 //intialise buyPrice, this will change when we enter a trade ; float = decimal number data type 0.0 buyCondition = (close > ma1 and close < ma2 and strategy.position_size == 0 and f_dateFilter) or (strategy.position_size == 0 and i_contrarianBuyTheDip==true and overall_change > i_contrarianTrigger and f_dateFilter) // higher than 200sma, lower than short term ma (pullback) + avoid pyramiding positions sellCondition = close > ma2 and strategy.position_size > 0 and (not i_lowerClose or close < low[1]) //check if we already in trade + close above 10MA; // third condition: EITHER i_lowerClose not turned on OR closing price has to be < previous candle's LOW [1] stopDistance = strategy.position_size > 0 ? ((buyPrice - close)/close) : na // check if in trade > calc % drop dist from entry, if not na stopPrice = strategy.position_size > 0 ? (buyPrice - (buyPrice * i_stopPercent)) : na // calc SL price if in trade, if not, na stopCondition = (strategy.position_size > 0 and stopDistance > i_stopPercent) or (strategy.position_size > 0 and (i_stopByCrossover_MA2_3==true and ma3 < ma1)) // Enter positions if buyCondition strategy.entry(id="Long", direction=strategy.long) //long only if buyCondition[1] // if buyCondition is true prev candle buyPrice := open // entry price = current bar opening price // Exit position if sellCondition or stopCondition strategy.close(id="Long", comment = "Exit" + (stopCondition ? "Stop loss=true" : "")) // if condition? "Value for true" : "value for false" buyPrice := na //reset buyPrice // Plot plot(buyPrice, color=color.lime, style=plot.style_linebr) plot(stopPrice, color=color.red, style=plot.style_linebr, offset = -1) plot(ma1, color=color.blue) //defval=200 plot(ma2, color=color.white) //defval=10 plot(ma3, color=color.yellow) // defval=50