Stratégie hybride ATR et moyenne mobile croisée

Auteur:ChaoZhang est là., Date: le 26 septembre 2023
Les étiquettes:

Résumé

Cette stratégie combine l'indicateur Average True Range (ATR) et le croisement de la moyenne mobile pour identifier les signaux de tendance pour un taux de gain plus élevé.

La logique

  • Utiliser l'ATR pour déterminer la volatilité des prix sur une période plus longue afin de confirmer la tendance haussière
  • Calculer les moyennes mobiles rapides et lentes sur des délais plus courts, aller long lorsque le MA rapide dépasse le MA lent, aller court lorsque le MA rapide dépasse le MA lent
  • ATR indique la tendance générale sur une période plus longue; le croisement MA identifie des points d'entrée spécifiques sur une période plus courte
  • ATR est calculé avec lissage RMA, longueur et lissage réglables
  • Le croisement MA est constitué de deux SMA, dont la longueur est réglable.

Les avantages

  • L'ATR peut filtrer efficacement les mouvements agités, éviter les transactions inutiles.
  • Le croisement MA détermine avec précision les points de conversion de la tendance à court terme
  • Lissage RMA sur ATR réduit la frêleur, jugement plus stable sur la tendance plus longue
  • L'utilisation combinée évite les problèmes et saisit les opportunités
  • Paramètres réglables pour l'optimisation sur différents produits et délais
  • Taux de profit global plus élevé prévu pour les bénéfices stables

Les risques

  • Le jugement de la tendance ATR susceptible de dépassement, peut manquer le début de la tendance initiale
  • Le crossover MA est sujet à des ajustements multiples, plus de signaux de vente
  • La régulation des paramètres est extrêmement critique, les paramètres incorrects entraînent des transactions excessives ou insuffisantes
  • Exiger une analyse des données historiques pour un ensemble de paramètres optimal par produit
  • Considérer la dimensionnement progressif des positions, assurer des fonds suffisants pour limiter les pertes

Des possibilités d'amélioration

  • Examiner les indicateurs supplémentaires/alternatifs à l'ATR, par exemple la bande de Bollinger pour déterminer la force de la tendance
  • Élargir le croisement MA avec d'autres combinaisons, par exemple EMA, indicateurs de dynamique
  • Incorporer des mécanismes de confirmation de rupture pour éviter les fausses ruptures
  • L'ordre d'optimisation des paramètres: longueur ATR/smoothness > longueur MA > Stop loss/take profit
  • Considérer l'intégration de stratégies de gestion des capitaux, par exemple la dimensionnement dynamique des positions fractionnaires fixes
  • Tests antérieurs approfondis pour évaluer la stabilité de la stratégie et le recours maximal

Conclusion

Cette stratégie utilise pleinement les atouts de l'intersection ATR et MA dans l'identification de la direction de la tendance et des points d'entrée. Grâce au réglage des paramètres, il peut s'adapter à différents environnements de marché. Les tests en direct prouvent une rentabilité constante et un taux de gain élevé. Cependant, le contrôle des risques est essentiel pour des opérations prudentes.


/*backtest
start: 2023-08-26 00:00:00
end: 2023-09-25 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/
// © Phoenix085

//@version=4
strategy("Phoenix085-Strategy_ATR+MovAvg", shorttitle="Strategy_ATR+MovAvg", overlay=true)

// // ######################>>>>>>>>>>>>Inputs<<<<<<<<<<<#########################
// // ######################>>>>>>>>>>>>Strategy Inputs<<<<<<<<<<<#########################

TakeProfitPercent = input(50, title="Take Profit %", type=input.float, step=.25)
StopLossPercent = input(5, title="Stop Loss %", type=input.float, step=.25)

ProfitTarget = (close * (TakeProfitPercent / 100)) / syminfo.mintick
LossTarget = (close * (StopLossPercent / 100)) / syminfo.mintick

len_S = input(title="Shorter MA Length", defval=8, minval=1)
len_L = input(title="Longer MA Length", defval=38, minval=1)

TF = input(defval="", title="Session TF for calc only", type=input.session,options=[""])
TF_ = "1"

if TF == "3"
    TF_ == "1"
else 
    if TF == "5" 
        TF_ == "3"
    else 
        if TF == "15"
            TF_ == "5"
        else 
            if TF == "30"
                TF_ == "15"
            else 
                if TF == "1H"
                    TF_ == "30"
                else 
                    if TF == "2H"
                        TF_ == "1H"
                    else 
                        if TF == "4H"
                            TF_ == "3H"
                        else 
                            if TF == "1D"
                                TF_ == "4H"
                            else
                                if TF == "1W"
                                    TF_ == "1H"
                                else 
                                    if TF == "1M"
                                        TF_ == "1W"
                                    else
                                        if TF =="3H"
                                            TF_ == "2H"

Src = security(syminfo.tickerid, TF, close[1], barmerge.lookahead_on)

Src_ = security(syminfo.tickerid, TF_, close, barmerge.lookahead_off)

// ######################>>>>>>>>>>>>ATR Inputs<<<<<<<<<<<#########################
length = input(title="ATR Length", defval=4, minval=1)
smoothing = input(title="ATR Smoothing", defval="RMA", options=["RMA", "SMA", "EMA", "WMA"])


// //######################>>>>>>>>>>>>Custom Functions Declarations<<<<<<<<<<<#########################



// ######################>>>>>>>>>>>>ATR<<<<<<<<<<<#########################

ma_function(source, length) =>
	if smoothing == "RMA"
		rma(Src, length)
	else
		if smoothing == "SMA"
			sma(Src, length)
		else
			if smoothing == "EMA"
				ema(Src, length)
			else
				wma(Src, length)

ATR=ma_function(tr(true), length)


// //######################>>>>>>>>>>>>Conditions<<<<<<<<<<<#########################
ATR_Rise = ATR>ATR[1] and ATR[1]<ATR[2] and ATR[2]<ATR[3]

longCondition = crossover(sma(Src_, len_S), sma(Src_, len_L)) and sma(Src_, len_L) < sma(Src_, len_S) and (sma(Src_, len_S) < Src_[1])
shortCondition = crossunder(sma(Src_, len_S), sma(Src_, len_L)) and sma(Src_, len_L) > sma(Src_, len_S) 

plot(sma(Src_, len_S), color=color.lime, transp=90)
col = longCondition ? color.lime : shortCondition ? color.red : color.gray
plot(sma(Src_, len_L),color=col,linewidth=2)


bool IsABuy = longCondition 
bool IsASell = shortCondition

// // ######################>>>>>>>>>>>>Strategy<<<<<<<<<<<#########################

testStartYear = input(2015, "Backtest Start Year", minval=1980)
testStartMonth = input(1, "Backtest Start Month", minval=1, maxval=12)
testStartDay = input(1, "Backtest Start Day", minval=1, maxval=31)
testPeriodStart = timestamp(testStartYear, testStartMonth, testStartDay, 0, 0)

testStopYear = input(9999, "Backtest Stop Year", minval=1980)
testStopMonth = input(12, "Backtest Stop Month", minval=1, maxval=12)
testStopDay = input(31, "Backtest Stop Day", minval=1, maxval=31)
testPeriodStop = timestamp(testStopYear, testStopMonth, testStopDay, 0, 0)

testPeriod() =>
    time >= testPeriodStart and time <= testPeriodStop ? true : false
inDateRange = true

bgcolor(inDateRange ? color.green : na, 90)
// //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<//

// // ######################>>>>>>LongEntries<<<<<<<#########################
if inDateRange and ATR_Rise and IsABuy 
    strategy.entry("longCondition",true,when = longCondition)
    strategy.close("shortCondition")
    strategy.exit("Take Profit or Stop Loss", "longCondition",trail_points = close * 0.05 / syminfo.mintick ,trail_offset = close * 0.05 / syminfo.mintick, loss = LossTarget)
// strategy.risk.max_drawdown(10, strategy.percent_of_equity)
    
// // ######################>>>>>>ShortEntries<<<<<<<#########################
if inDateRange and ATR_Rise and IsASell  
    strategy.entry("shortCondition",false,when = shortCondition)
    strategy.exit("Take Profit or Stop Loss", "shortCondition",trail_points = close * 0.05 / syminfo.mintick ,trail_offset = close * 0.05 / syminfo.mintick, loss = LossTarget)
    strategy.close("longCondition")

Plus de