Tendance suivant une stratégie basée sur une moyenne mobile adaptative

Auteur:ChaoZhang est là., Date: 2024-01-30 16h30 et 20h30
Les étiquettes:

img

Résumé

Cette stratégie utilise l'indicateur Kaufman Adaptive Moving Average (KAMA) pour concevoir un système de trading suivant la tendance. Il peut suivre rapidement les tendances lorsqu'elles se forment et filtrer le bruit pendant les marchés agités.

La logique de la stratégie

  • La longueur de l'indicateur KAMA est ajustée dynamiquement en fonction de la volatilité récente du marché. Lorsque les changements de prix sont plus importants que le bruit récent, la fenêtre EMA devient plus courte. Lorsque les changements de prix sont plus petits que le bruit récent, la fenêtre EMA devient plus longue. Cela permet à KAMA de suivre rapidement les tendances tout en filtrant le bruit pendant les marchés agités.

  • Le système juge principalement la direction de la tendance en fonction du KAMA le plus rapide (KAMA 1). Il va long lorsque KAMA 1 pointe vers le haut et court lorsque KAMA 1 pointe vers le bas. Pour filtrer les fausses ruptures, un filtre KAMA est défini. Les signaux de trading ne sont générés que lorsque le changement de KAMA 1 dépasse un écart type des fluctuations récentes.

  • Pour le stop loss, le système fournit trois méthodes de stop loss en option: KAMA reversal, PSAR reversal et ATR trailing stop.

Analyse des avantages

  • La conception unique de l'indicateur KAMA permet au système de détecter rapidement les tendances émergentes, d'arrêter les transactions pendant les marchés agités, de contrôler efficacement la fréquence des transactions et de réduire les coûts inutiles de glissement et de commission.

  • Les investisseurs peuvent choisir le système de stop loss approprié en fonction de leurs préférences personnelles en matière de risque afin de contrôler efficacement une seule perte.

  • Le système est entièrement basé sur des indicateurs et des lignes de stop loss, évitant ainsi les problèmes d'erreur d'entrée courants causés par des transactions changeantes.

  • Plusieurs paramètres et combinaisons de conditions offrent un grand espace pour la personnalisation du système.

Analyse des risques

  • Le système ne prend pas en compte les risques systémiques et ne peut pas contrôler efficacement les pertes dans des conditions de marché extrêmes.

  • Il peut être nécessaire d'ajuster le système PARAMETERS en fonction de différents produits et fréquences, sinon il produira des résultats trop agressifs ou trop conservateurs.

  • Si l'on s'appuie uniquement sur l'indicateur KAMA pour le stop loss, il est facile de se laisser piéger par des échecs lors de marchés agités.

Directions d'optimisation

  • Ajouter des indicateurs de filtrage de tendance tels que l'ADX ou la volatilité implicite pour éviter de générer de faux signaux pendant les étapes de transition de tendance et de tendance agitée.

  • Optimiser et tester les paramètres pour les produits individuels et les fréquences fixes pour améliorer la stabilité.

  • Essayez des modèles d'apprentissage automatique au lieu de l'optimisation des paramètres. Entraînez des réseaux de neurones ou des modèles d'arbres de décision avec beaucoup de données historiques pour juger du moment d'entrée et de sortie et arrêter les pertes.

  • Essayez de migrer la stratégie vers d'autres produits tels que les crypto-monnaies. Cela peut nécessiter d'ajuster les paramètres ou d'ajouter d'autres indicateurs auxiliaires.

Résumé

Cette stratégie intègre KAMA pour le jugement des tendances et plusieurs méthodes de stop loss pour suivre efficacement les directions des tendances et contrôler les risques. L'unicité de l'indicateur KAMA permet à la stratégie de déterminer rapidement la direction des tendances émergentes et d'éviter les faux problèmes de rupture.


/*backtest
start: 2023-12-01 00:00:00
end: 2023-12-31 23:59:59
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/
// © BenHampson
// @version=4
// Credit to:
// - ChuckBanger for much of the KAMA code
// - cheatcountry for the KAMA Filter code
// - millerrh for much of the ATR Stop code
// - racer8 for much of the Position Sizing code

// I have combined aspects of their work and built upon it to form a strategy I like. 
// The KAMA, with its filter, is used for entry.
// An ATR trailing stop loss, PSAR, and the KAMA can all optionally be used as exits, or you can use a combination of the three.

strategy(title="KAMA Strategy - Kaufman's Adaptive Moving Average", shorttitle="KAMA Strategy", overlay=true)

src = input(title="Source", type=input.source, defval=close)

// Exits
KAMA1SL = input(title = 'KAMA 1 Stop Loss', type = input.bool, defval = true)
ATRTSL = input(title = 'ATR Trailing Stop Loss', type = input.bool, defval = false)
PSARSL = input(title = 'PSAR Stop Loss', type = input.bool, defval = false)

// KAMA 1 (Fastest)
length1 = input(title="KAMA 1: Length", type=input.integer, defval=14)
fastLength1 = input(title="KAMA 1: Fast KAMA Length", type=input.integer, defval=2)
slowLength1 = input(title="KAMA 1: Slow KAMA Length", type=input.integer, defval=20)

length2 = input(title="KAMA 2: Length 2", type=input.integer, defval=15)
fastLength2 = input(title="KAMA 2: Fast KAMA Length", type=input.integer, defval=3)
slowLength2 = input(title="KAMA 2: Slow KAMA Length", type=input.integer, defval=22)

length3 = input(title="KAMA 3: Length 3", type=input.integer, defval=16)
fastLength3 = input(title="KAMA 3: Fast KAMA Length", type=input.integer, defval=4)
slowLength3 = input(title="KAMA 3: Slow KAMA Length", type=input.integer, defval=24)

length4 = input(title="KAMA 4: Length", type=input.integer, defval=17)
fastLength4 = input(title="KAMA 4: Fast KAMA Length", type=input.integer, defval=5)
slowLength4 = input(title="KAMA 4: Slow KAMA Length", type=input.integer, defval=26)

// KAMA 5 (Medium)
length5 = input(title="KAMA 5: Length", type=input.integer, defval=18)
fastLength5 = input(title="KAMA 5: Fast KAMA Length", type=input.integer, defval=6)
slowLength5 = input(title="KAMA 5: Slow KAMA Length", type=input.integer, defval=28)

length6 = input(title="KAMA 6: Length", type=input.integer, defval=19)
fastLength6 = input(title="KAMA 6: Fast KAMA Length", type=input.integer, defval=7)
slowLength6 = input(title="KAMA 6: Slow KAMA Length", type=input.integer, defval=30)

length7 = input(title="KAMA 7: Length", type=input.integer, defval=20)
fastLength7 = input(title="KAMA 7: Fast KAMA Length", type=input.integer, defval=8)
slowLength7 = input(title="KAMA 7: Slow KAMA Length", type=input.integer, defval=32)

// KAMA 8 (Slowest)
length8 = input(title="KAMA 8: Length", type=input.integer, defval=21)
fastLength8 = input(title="KAMA 8: Fast KAMA Length", type=input.integer, defval=9)
slowLength8 = input(title="KAMA 8: Slow KAMA Length", type=input.integer, defval=34)

// Kaufman's Adaptive Moving Average
getKAMA(src, length1, fastLength1, slowLength1) =>
    mom = abs(change(src, length1))
    volatility = sum(abs(change(src)), length1)
    
    // Efficiency Ratio
    er = volatility != 0 ? mom / volatility : 0
    
    fastAlpha = 2 / (fastLength1 + 1)
    slowAlpha = 2 / (slowLength1 + 1)
    
    // KAMA Alpha
    sc = pow((er * (fastAlpha - slowAlpha)) + slowAlpha, 2)
    
    kama = 0.0
    kama := sc * src + (1 - sc) * nz(kama[1])
    kama

kama1 = getKAMA(src, length1, fastLength1, slowLength1)
kama2 = getKAMA(src, length2, fastLength2, slowLength2)
kama3 = getKAMA(src, length3, fastLength3, slowLength3)
kama4 = getKAMA(src, length4, fastLength4, slowLength4)
kama5 = getKAMA(src, length5, fastLength5, slowLength5)
kama6 = getKAMA(src, length6, fastLength6, slowLength6)
kama7 = getKAMA(src, length7, fastLength7, slowLength7)
kama8 = getKAMA(src, length8, fastLength8, slowLength8)

//If the kama1 has increased...
kama1delta = kama1[0] - kama1[1]
kama3delta = kama3[0] - kama3[1]
kama8delta = kama8[0] - kama8[1]

// KAMA Plots
plot(kama1, title="KAMA 1", color=#e91e63, display=display.all, linewidth=2)
plot(kama2, title="KAMA 2", color=color.red, display=display.all)
plot(kama3, title="KAMA 3", color=color.red, display=display.all)
plot(kama4, title="KAMA 4", color=color.orange, display=display.all)
plot(kama5, title="KAMA 5", color=color.orange, display=display.all)
plot(kama6, title="KAMA 6", color=color.yellow, display=display.all)
plot(kama7, title="KAMA 7", color=color.yellow, display=display.all)
plot(kama8, title="KAMA 8", color=color.white, display=display.all)



//========================================= KAMA FILTER ===========================================

// Copyright (c) 2019-present, Franklin Moormann (cheatcountry)
// Moving Average Adaptive Filter [CC] script may be freely distributed under the MIT license.

entryFilter = input(title="KAMA Entry Filter", type=input.float, defval=1, minval=0.01)
exitFilter = input(title="KAMA Exit Filter", type=input.float, defval=0.5, minval=0.01)

entryMAAF = entryFilter * stdev(kama1delta, length1)
exitMAAF = exitFilter * stdev(kama1delta, length1)
srcEma = ema(src, length1)



//========================================= TRAILING ATR STOP ====================================

// The following is an adaptation of Trailing ATR Stops by @millerrh
// He based it on scripts by @garethyeo & @SimpleCryptoLife

// Inputs

atrLookback = input(defval=14,title="Trailing ATR Lookback Period",type=input.integer)
multiplier = input(defval=3,title="Trailing ATR Multiplier",type=input.float, step=0.1, minval=0.5, maxval=4)
trailMode = input(title="Trail Mode", defval="Trailing", options=["Running", "Trailing"])
trigInput = input(title="Trigger Trailing Stop On", defval="Wick", options=["Close","Wick"]) 

// Calculate ATR
atrValue = atr(atrLookback)
atrMultiplied = atrValue * multiplier

// Plot the price minus the ATR
atrLow = low - atrMultiplied

// Calculate the low trailing ATRs every time. The trailing stop loss never goes down.
// Set them to something to start with
trailAtrLow = atrLow

// If the ATR Low has gone up AND it has gone above the trail, the low trailing ATR should also go up. If the ATR Low has gone up or down, but not below the trail, the ATR trail stays where it is
trailAtrLow := na(trailAtrLow[1]) ? trailAtrLow : atrLow >= trailAtrLow[1] ? atrLow : trailAtrLow[1]

// Trigger stop based on candle close or low
trigSupport = trigInput == "Close" ? close : trigInput == "Wick" ? low : na

// Determine if price is below support
supportHit = trigSupport <= trailAtrLow

// If price is below support, reset the trailing ATR
trailAtrLow := supportHit ? atrLow : trailAtrLow

// Plot Lines
plotLow = ATRTSL ? trailAtrLow : na
plot(plotLow, title="ATR Low", color=color.white, transp=50, style=plot.style_linebr, linewidth=1, display=display.all)



//====================================== PSAR STOP ==========================================

start = input(0.02, "PSAR Start")
increment = input(0.02, "PSAR Increment")
maximum = input(0.2, "PSAR Max Value")
psar = sar(start, increment, maximum)
psarPlot  = PSARSL ? psar : na
plot(psarPlot, "Parabolic SAR", style=plot.style_cross, color=#3A6CA8, display=display.all)



//========================================= ENTRY & EXITS =====================================================

// Entry
long = kama1delta > 0 and kama1delta > entryMAAF
strategy.entry("Buy", true, when = long) 

// Close
longClose = (PSARSL ? crossunder(close, psar) : na) or (KAMA1SL ? kama1delta < 0 and abs(kama1delta) > exitMAAF : na) or (ATRTSL ? supportHit : na)
strategy.close("Buy", when = longClose, comment = "Sell")

Plus de