Stratégie de renversement de la moyenne mobile double

Auteur:ChaoZhang est là., Date: 2023-12-25 13h24 et 14h
Les étiquettes:

img

Résumé

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 logique de la stratégie

La stratégie d'inversion des moyennes mobiles doubles est fondée sur les hypothèses suivantes:

  1. 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.

  2. La ligne SMA de 10 jours indique les retombées à court terme du prix.

  3. 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:

  1. 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.

  2. 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.

  3. 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.

Les avantages

La stratégie d'inversion des moyennes mobiles doubles présente les principaux avantages suivants:

  1. La logique de la stratégie est simple et facile à comprendre.
  2. Les doubles filtres des moyennes mobiles permettent d'identifier efficacement les tendances à court et à long terme.
  3. Il offre une bonne efficacité temporelle en capitalisant sur les revers à court terme.
  4. Le mécanisme de stop loss intégré contrôle strictement le risque sur les positions individuelles.
  5. La paramétrisation flexible rend cette stratégie largement applicable pour les indices et les actions.

Les risques

Bien qu'elle soit généralement efficace, la stratégie présente les limites suivantes:

  1. La stratégie devrait être désactivée lors de consolidations prolongées.
  2. Le fait de s'appuyer uniquement sur des moyennes mobiles a des limites de précision du signal.
  3. La méthodologie du stop loss fixe manque de souplesse. D'autres techniques de stop loss pourraient être testées.
  4. Les paramètres optimaux doivent être calibrés pour différents marchés.

Des possibilités d'amélioration

Les améliorations supplémentaires apportées à cette stratégie comprennent:

  1. Tester d'autres longueurs moyennes mobiles pour trouver la combinaison optimale.
  2. Ajout d'indicateurs de soutien pour générer des signaux plus fiables, par exemple le volume, les métriques de volatilité.
  3. J'explore d'autres techniques de stop-loss comme le stop-loss à la traîne, le stop-loss basé sur le temps.
  4. Construire des capacités d'adaptation dans les règles d'entrée et les paramètres de stop loss permettant de s'adapter à l'évolution de la dynamique du marché.
  5. Incorporer des algorithmes d'apprentissage automatique pour optimiser davantage les paramètres en tirant parti de données plus historiques.

Conclusion

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






Plus de