Stratégie de moyenne mobile de rupture en spirale

Auteur:ChaoZhang est là., Date: 15 janvier 2024 à 11h45
Les étiquettes:

img

Résumé

Cette stratégie combine l'indicateur de canal en spirale et l'indicateur de taux de changement (ROC). Elle génère des signaux d'achat lorsque le prix franchit la bande supérieure et la moyenne mobile, et des signaux de vente lorsque le prix franchit la bande inférieure et la moyenne mobile.

La logique de la stratégie

La stratégie repose sur deux indicateurs clés:

  1. Chaînes en spirale: Tracez les bandes supérieures et inférieures pour déterminer la direction de la tendance.

  2. Taux de variation (ROC): détecte une accélération des prix. ROC au-dessus d'un seuil positif suggère une accélération de la hausse des prix, tandis que ROC en dessous d'un seuil négatif indique une accélération de la baisse des prix.

Les signaux d'achat sont générés lorsque le canal en spirale et le ROC donnent des indications haussières, à savoir une rupture des prix au-dessus de la bande supérieure couplée à une dynamique haussière accélérée.

Les signaux combinés permettent d'éviter les transactions contre tendance et d'améliorer la fiabilité.

Les avantages

  1. Des signaux fiables avec un taux de gain plus élevé en exigeant un accord entre la tendance et l'élan.

  2. Fréquence de négociation personnalisable par ajustement des paramètres, par exemple réglage des paramètres ROC.

  3. Stop loss pour limiter le risque à la baisse sur les transactions individuelles.

  4. Re-entrer dans le mécanisme pour suivre les tendances et augmenter encore la rentabilité.

Les risques

  1. Manquer certaines opportunités de négociation et limiter le potentiel de profit en raison de l'exigence de fiabilité du signal.

  2. Vulnérable à être pris au piège lorsque la tendance s'inverse, ce qui peut entraîner de grosses pertes.

  3. Un mauvais réglage des paramètres peut entraîner trop peu ou trop de signaux.

  4. Pourcentage fixe de stop loss incapable d'éviter de lourdes pertes lors d'importantes fluctuations de prix défavorables.

Des possibilités d'amélioration

  1. Optimiser les paramètres ROC pour une meilleure performance.

  2. Testez différents niveaux de stop loss pour équilibrer risque et récompense.

  3. Ajoutez d'autres filtres comme le volume, les indicateurs de volatilité pour affiner les signaux.

  4. Évaluer les performances sur différents marchés pour trouver le meilleur ajustement.

  5. Introduire une dimensionnement dynamique des positions pour les différentes conditions du marché.

Conclusion

La stratégie combine Spiral Channel et ROC pour évaluer la direction et l'élan de la tendance. Elle vise la fiabilité du signal tout en maintenant la rentabilité grâce à la réentrée et à l'ajustement des paramètres. Le risque est principalement contrôlé par un pourcentage fixe de stop loss.


/*backtest
start: 2024-01-07 00:00:00
end: 2024-01-14 00:00:00
period: 45m
basePeriod: 5m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy("SSL Chaikin BF 🚀", overlay=true, precision=2, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.075)

/////////////// Time Frame ///////////////
_0 = input(false,  "════════ Test Period ═══════")
testStartYear = input(2017, "Backtest Start Year") 
testStartMonth = input(1, "Backtest Start Month")
testStartDay = input(1, "Backtest Start Day")
testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay, 0, 0)

testStopYear = input(2019, "Backtest Stop Year")
testStopMonth = input(12, "Backtest Stop Month")
testStopDay = input(31, "Backtest Stop Day")
testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay, 0, 0)

testPeriod() => true

/////////////// Chaikin MF /////////////// 
_1 = input(false,  "═══════ Chaikin MF ═══════")
length = input(20, minval=1, title = "Chaikin SMA Length")
upperThreshold = input(0.04, step=0.01, title="Upper Threshold")
lowerThreshold = input(0.02, step=0.01, title="Lower Threshold")
ad = close==high and close==low or high==low ? 0 : ((2*close-low-high)/(high-low))*volume
mf = sum(ad, length) / sum(volume, length)

/////////////// SSL Channels /////////////// 
_2 = input(false,  "═════════ SSL ══════════")
len1=input(title="SMA Length 1", defval=12)
len2=input(title="SMA Length 2", defval=13)

smaHigh = sma(high, len1)
smaLow = sma(low, len2)

Hlv = 0
Hlv := close > smaHigh ? 1 : close < smaLow ? -1 : Hlv[1]
sslDown = Hlv < 0 ? smaHigh : smaLow
sslUp = Hlv < 0 ? smaLow : smaHigh

///////////// Rate Of Change ///////////// 
_3 = input(false,  "══════ Rate of Change ══════")
source = close
roclength = input(13, "ROC Length",  minval=1)
pcntChange = input(4, "ROC % Change", minval=1)
roc = 100 * (source - source[roclength]) / source[roclength]
emaroc = ema(roc, roclength / 2)
isMoving() => emaroc > (pcntChange / 2) or emaroc < (0 - (pcntChange / 2))

///////////////  Strategy  /////////////// 
long = sslUp > sslDown and isMoving() or crossover(mf, upperThreshold)
short = sslUp < sslDown and isMoving() or crossunder(mf, lowerThreshold)

last_long = 0.0
last_short = 0.0
last_long := long ? time : nz(last_long[1])
last_short := short ? time : nz(last_short[1])

long_signal = crossover(last_long, last_short)
short_signal = crossover(last_short, last_long)

last_open_long_signal = 0.0
last_open_short_signal = 0.0
last_open_long_signal := long_signal ? open : nz(last_open_long_signal[1])
last_open_short_signal := short_signal ? open : nz(last_open_short_signal[1])

last_long_signal = 0.0
last_short_signal = 0.0
last_long_signal := long_signal ? time : nz(last_long_signal[1])
last_short_signal := short_signal ? time : nz(last_short_signal[1])

in_long_signal = last_long_signal > last_short_signal
in_short_signal = last_short_signal > last_long_signal

last_high = 0.0
last_low = 0.0
last_high := not in_long_signal ? na : in_long_signal and (na(last_high[1]) or high > nz(last_high[1])) ? high : nz(last_high[1])
last_low := not in_short_signal ? na : in_short_signal and (na(last_low[1]) or low < nz(last_low[1])) ? low : nz(last_low[1])

since_longEntry = barssince(last_open_long_signal != last_open_long_signal[1]) 
since_shortEntry = barssince(last_open_short_signal != last_open_short_signal[1]) 

//////////////// Stop loss /////////////// 
_4 = input(false,  "════════ Stop Loss ═══════")
sl_inp = input(2.0, title='Stop Loss %') / 100

slLong = in_long_signal ? strategy.position_avg_price * (1 - sl_inp) : na
slShort = strategy.position_avg_price * (1 + sl_inp)
long_sl = in_long_signal ? slLong : na
short_sl = in_short_signal ? slShort : na

/////////////// Execution /////////////// 
if testPeriod()
    strategy.entry("L", strategy.long, when=long)
    strategy.entry("S", strategy.short, when=short)
    strategy.exit("L SL", "L", stop=long_sl, when=since_longEntry > 0)
    strategy.exit("S SL", "S", stop=short_sl, when=since_shortEntry > 0)

/////////////// Plotting /////////////// 
p1 = plot(sslDown, linewidth = 1, color=color.red)
p2 = plot(sslUp, linewidth = 1, color=color.lime)
fill(p1, p2,  color = sslDown < sslUp ? color.lime : color.red, transp=80)
bgcolor(isMoving() ? long ? color.green : short ? color.red : na : color.white, transp=80)
bgcolor(long_signal ? color.lime : short_signal ? color.red : na, transp=30)
bgcolor(crossover(mf, upperThreshold) ? color.blue : crossunder(mf, lowerThreshold) ? color.orange : na, transp=30)

Plus de