Cette stratégie utilise les hauts et les bas de la volatilité des prix pour déterminer le moment d’entrer ou de sortir d’une position. L’objectif est d’établir des positions multiples lorsque la volatilité des prix est élevée et de terminer les positions rentables lorsque la tendance des prix se transforme en avantage.
L’indicateur ATR sert à mesurer la volatilité des prix. Il calcule l’ATR pour les 20 derniers cycles et calcule sa moyenne mobile et son écart-type. Si l’ATR actuel est supérieur à la moyenne plus un écart-type, le taux de volatilité est considéré comme élevé.
Le taux de variation du cours de la paire de première étape est utilisé pour déterminer la tendance des prix. Calculer le taux de variation du cours de clôture de la paire de la dernière période de 20 cycles et calculer sa moyenne mobile. Si le taux de variation actuel est supérieur à la moyenne et positif pendant 3 jours consécutifs, le prix est considéré comme en tendance à la hausse.
Lorsque la volatilité des prix est élevée et que les prix ont tendance à augmenter, ouvrez une position supplémentaire. Lorsque les prix reviennent et que le prix stop-loss est déclenché, la position est levée.
Utilisez les fluctuations des prix et les tendances pour faire plus de prises de position et éviter de négocier fréquemment dans les marchés en crise.
Modifier dynamiquement le prix de stop-loss pour éviter que le stop-loss ne soit trop souple et qu’il n’entraîne des pertes importantes.
La rétroaction montre un rendement annuel de 159% sur la stratégie entre 2015 et 2021, bien au-delà du rendement annuel de 120% sur la stratégie Buy and Hold.
Un réglage trop radical des paramètres ATR peut entraîner un manque d’accès. Les paramètres peuvent être étendus de manière appropriée pour augmenter la fréquence d’accès.
Les indicateurs de jugement de la tendance peuvent générer des erreurs de jugement et ne correspondent pas à la tendance réelle. Les facteurs de confirmation doivent être ajoutés pour éviter les pertes potentielles.
La période de récupération est de seulement 6 ans, il faut élargir la plage d’échantillonnage et faire des tests de robustesse pour éviter une suradaptation.
Les performances dans des situations extrêmes ne peuvent pas être évaluées, comme une monopolisation rapide, une intervention manuelle ou un arrêt de programmation.
L’ajout d’indicateurs de confirmation de tendance, tels que MACD, KDJ, etc., permet de déterminer plus précisément la direction de la tendance.
Les paramètres ATR peuvent être adaptés en fonction des variétés et des conditions du marché, afin d’optimiser la volatilité.
Ajout d’un module de jugement de rupture, configuration d’un facteur d’accélération de tendance et augmentation de la position en cas de rupture.
Tester l’efficacité de différentes méthodes de réduction des pertes, telles que la réduction des pertes en pourcentage, la réduction des pertes en fluctuation, etc.
L’évaluation du nombre de transactions, de la stabilité de la courbe de rendement, du retrait maximal, etc. est effectuée pour assurer la solidité de la stratégie.
La stratégie intègre les avantages de la volatilité des prix et de la tendance à juger le moment où les prix peuvent se retourner en cas d’intensification de la volatilité, la mise en place d’un stop-loss dynamique pour contrôler les risques, et les résultats de la rétro-évaluation ont permis de réaliser de bons gains excédentaires. Cependant, l’intervalle de l’échantillon est de 6 ans.
/*backtest
start: 2022-09-14 00:00:00
end: 2023-09-20 00:00:00
period: 1d
basePeriod: 1h
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/
// © DojiEmoji (kevinhhl)
//@version=4
strategy("Mean Reversion (ATR) Strategy [KL]",overlay=true,pyramiding=1)
ENUM_LONG = "Long"
// Timeframe {
backtest_timeframe_start = input(defval = timestamp("01 Apr 2000 13:30 +0000"), title = "Backtest Start Time", type = input.time)
USE_ENDTIME = input(false,title="Define backtest end-time (If false, will test up to most recent candle)")
backtest_timeframe_end = input(defval = timestamp("01 May 2021 19:30 +0000"), title = "Backtest End Time (if checked above)", type = input.time)
within_timeframe = true
// }
// Trailing stop loss {
ATR_X2_TSL = atr(input(14,title="Length of ATR for trailing stop loss")) * input(2.0,title="ATR Multiplier for trailing stop loss",type=input.float)
TSL_source = low
var stop_loss_price = float(0)
TSL_line_color = color.green, TSL_transp = 100
if strategy.position_size == 0 or not within_timeframe
TSL_line_color := color.black
stop_loss_price := TSL_source - ATR_X2_TSL
else if strategy.position_size > 0
stop_loss_price := max(stop_loss_price, TSL_source - ATR_X2_TSL)
TSL_transp := 0
plot(stop_loss_price, color=color.new(TSL_line_color, TSL_transp))
// }
// Variables for confirmations of entry {
_len_volat = input(20,title="Length of ATR to determine volatility")
_ATR_volat = atr(_len_volat)
_avg_atr = sma(_ATR_volat, _len_volat)
_std_volat = stdev(_ATR_volat,_len_volat)
signal_diverted_ATR = _ATR_volat > (_avg_atr + _std_volat) or _ATR_volat < (_avg_atr - _std_volat)
_len_drift = input(20,title="Length of Drift")//default set to const: _len_vol's default value
_prcntge_chng = log(close/close[1])
_drift = sma(_prcntge_chng, _len_drift) - pow(stdev(_prcntge_chng, _len_drift),2)*0.5
_chg_drift = _drift/_drift[1]-1
signal_uptrend = (_drift > _drift[1] and _drift > _drift[2]) or _drift > 0
entry_signal_all = signal_diverted_ATR and signal_uptrend
// }
alert_per_bar(msg)=>
prefix = "[" + syminfo.root + "] "
suffix = "(P=" + tostring(close) + "; atr=" + tostring(_ATR_volat) + ")"
alert(tostring(prefix) + tostring(msg) + tostring(suffix), alert.freq_once_per_bar)
// MAIN {
if within_timeframe
if strategy.position_size > 0 and strategy.position_size[1] > 0 and (stop_loss_price/stop_loss_price[1]-1) > 0.005
alert_per_bar("TSL raised to " + tostring(stop_loss_price))
// EXIT:
if strategy.position_size > 0 and TSL_source <= stop_loss_price
exit_msg = close <= strategy.position_avg_price ? "stop loss" : "take profit"
strategy.close(ENUM_LONG, comment=exit_msg)
// ENTRY:
else if entry_signal_all and (strategy.position_size == 0 or (strategy.position_size > 0 and close > stop_loss_price))
entry_msg = strategy.position_size > 0 ? "adding" : "initial"
strategy.entry(ENUM_LONG, strategy.long, comment=entry_msg)
if strategy.position_size == 0
stop_loss_price := float(0)
// }