
Cette stratégie est basée sur la direction de la tendance de l’indicateur de tendance moyen DI+ et DI-, en utilisant l’indicateur de DI de deux périodes différentes, puis en faisant plus de courte durée. Lorsque le DI+ de la plus grande période et le DI+ de la plus petite période sont supérieurs au DI-, il est jugé comme une tendance haussière, plus; lorsque les deux périodes de DI- sont supérieures au DI+, il est jugé comme une tendance baissière, courte durée.
Cette stratégie est basée sur les principes suivants:
Calculer les DI+ et les DI- ◄ en obtenant les prix élevés, les prix de clôture et les prix bas.
Comparer les deux périodes DI+ et DI-。 calculer les périodes DI+ et DI-, et comparer les relations de grandeur et de petiteur, respectivement, dans les périodes de la carte principale (par exemple, 1 heure) et dans les périodes plus importantes (par exemple, la ligne du soleil).
Déterminer l’orientation de la tendance. Déterminer la tendance à plusieurs têtes lorsque le DI+ de la plus grande période et le DI- de la plus petite période sont tous deux supérieurs au DI- et la tendance à vide lorsque les deux périodes sont toutes deux supérieures au DI+.
Émet un signal de transaction. Un signal de tête multiple est émis pour deux périodes: DI+>DI-, faire plus; un signal de tête vide est émis pour deux périodes: DI->DI+, faire moins.
Réglage des arrêts. Basé sur le calcul des arrêts de l’ATR, pour réaliser des arrêts de suivi de tendance.
Conditions de sortie: Placement de la position en cas de déclenchement d’un stop loss ou d’une inversion de prix.
Cette stratégie présente les avantages suivants:
L’utilisation d’un double cadre temporel DI pour juger des tendances permet de filtrer certaines fausses percées.
L’ATR est un système de suivi dynamique des pertes, qui permet de protéger au maximum les bénéfices et d’éviter les pertes minimes.
Les pertes en temps opportun peuvent être maîtrisées par des pertes ponctuelles.
Le trading sur tendance permet de saisir les opportunités de tendance de façon continue.
Les règles sont claires et faciles à comprendre pour les utilisateurs réels.
La stratégie présente également les risques suivants:
Le DI est en retard et peut être raté. Les paramètres peuvent être optimisés de manière appropriée ou combinés avec d’autres indicateurs.
Il peut y avoir des divergences en amont et en aval dans le jugement des deux périodes.
Le stop loss trop radical peut entraîner des transactions trop fréquentes. Le multiplicateur ATR peut être relâché de manière appropriée.
Il est possible de faire des transactions fréquentes dans des conditions de choc. La fréquence des transactions peut être réduite en ajoutant des conditions de filtrage.
L’optimisation des paramètres dépend de l’historique des données, et il est possible qu’il y ait une sur-optimisation sur le disque.
Cette stratégie peut être optimisée dans les domaines suivants:
Optimiser les paramètres de calcul du DI pour trouver la meilleure combinaison de paramètres.
L’ajout de filtres pour d’autres indicateurs améliore la précision du signal, tels que MACD, KDJ, etc.
Optimiser la stratégie de stop loss pour s’adapter à plus de conditions de marché.
Le filtrage des heures de transaction a été ajouté pour éviter les événements d’actualité importants.
Test de la robustesse des différents paramètres de la variété pour améliorer l’adaptation.
Ajout d’un composant d’apprentissage automatique pour former des modèles de jugement à partir de données historiques.
Cette stratégie est une stratégie de suivi de tendance typique qui utilise les indicateurs de DI pour déterminer la direction de la tendance, définir des arrêts de perte pour localiser les gains et maintenir les gains dans la tendance. L’avantage de cette stratégie réside dans la clarté de l’idée de la stratégie et la facilité d’opération sur le terrain.
/*backtest
start: 2022-10-31 00:00:00
end: 2023-11-06 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
//@version=5
strategy("DI+/- multi TF Strat [KL]", overlay=true, pyramiding=1, initial_capital=1000000000, default_qty_type=strategy.percent_of_equity, default_qty_value=5)
var string GROUP_ALERT = "Alerts"
var string GROUP_SL = "Stop loss"
var string GROUP_ORDER = "Order size"
var string GROUP_TP = "Profit taking"
var string GROUP_HORIZON = "Time horizon of backtests"
var string GROUP_IND = "Directional IndicatorDI+ DI-"
// ADX Indicator {
adx_len = input(14, group=GROUP_IND, tooltip="Typically 14")
tf1 = input.timeframe("", title="DI +/- in Timeframe 1", group=GROUP_IND, tooltip="Main: DI+ > DI-")
tf2 = input.timeframe("1D", title="DI +/- in Timeframe 2", group=GROUP_IND, tooltip="Confirmation: DI+ > DI-")
// adx_thres = input(20, group=GROUP_IND) //threshold not used in this strategy
get_ADX(_high, _close, _low) =>
// (high, close, mid) -> [plus_DM, minus_DM]
// Based on TradingView user BeikabuOyaji's implementation
_tr = math.max(math.max(_high - _low, math.abs(_high - nz(_close[1]))), math.abs(_low - nz(_close[1])))
smooth_tr = 0.0
smooth_tr := nz(smooth_tr[1]) - nz(smooth_tr[1]) / adx_len + _tr
smooth_directional_mov_plus = 0.0
smooth_directional_mov_plus := nz(smooth_directional_mov_plus[1]) - nz(smooth_directional_mov_plus[1]) / adx_len + (_high - nz(_high[1]) > nz(_low[1]) - _low ? math.max(_high - nz(_high[1]), 0) : 0)
smooth_directional_mov_minus = 0.0
smooth_directional_mov_minus := nz(smooth_directional_mov_minus[1]) - nz(smooth_directional_mov_minus[1]) / adx_len + (nz(_low[1]) - _low > _high - nz(_high[1]) ? math.max(nz(_low[1]) - _low, 0) : 0)
plus_DM = smooth_directional_mov_plus / smooth_tr * 100
minus_DM = smooth_directional_mov_minus / smooth_tr * 100
// DX = math.abs(plus_DM - minus_DM) / (plus_DM + minus_DM) * 100 // DX not used in this strategy
[plus_DM, minus_DM]
// DI +/- from timeframes 1 and 2
[plus_DM_tf1, minus_DM_tf1] = get_ADX(request.security(syminfo.tickerid, tf1, high), request.security(syminfo.tickerid, tf1, close),request.security(syminfo.tickerid, tf1, low))
[plus_DM_tf2, minus_DM_tf2] = get_ADX(request.security(syminfo.tickerid, tf2, high),request.security(syminfo.tickerid, tf2, close),request.security(syminfo.tickerid, tf2, low))
// } end of block: ADX Indicator
var string ENUM_LONG = "LONG"
var string LONG_MSG_ENTER = input.string("Long entered", title="Alert MSG for buying (Long position)", group=GROUP_ALERT)
var string LONG_MSG_EXIT = input.string("Long closed", title="Alert MSG for closing (Long position)", group=GROUP_ALERT)
backtest_timeframe_start = input(defval=timestamp("01 Apr 2020 13:30 +0000"), title="Backtest Start Time", group=GROUP_HORIZON)
within_timeframe = true
// Signals for entry
_uptrend_confirmed = plus_DM_tf1 > minus_DM_tf1 and plus_DM_tf2 > minus_DM_tf2
entry_signal_long = _uptrend_confirmed
plotshape(_uptrend_confirmed, style=shape.triangleup, location=location.bottom, color=color.green)
plotshape(not _uptrend_confirmed, style=shape.triangledown, location=location.bottom, color=color.red)
// Trailing stop loss ("TSL") {
tsl_multi = input.float(2.0, title="ATR Multiplier for trailing stoploss", group=GROUP_SL)
SL_buffer = ta.atr(input.int(14, title="Length of ATR for trailing stoploss", group=GROUP_SL)) * tsl_multi
TSL_source_long = low
var stop_loss_price_long = float(0)
var pos_opened_long = false
stop_loss_price_long := pos_opened_long ? math.max(stop_loss_price_long, TSL_source_long - SL_buffer) : TSL_source_long - SL_buffer
// MAIN: {
if pos_opened_long and TSL_source_long <= stop_loss_price_long
pos_opened_long := false
alert(LONG_MSG_EXIT, alert.freq_once_per_bar)
strategy.close(ENUM_LONG, comment=close < strategy.position_avg_price ? "stop loss" : "take profit")
// (2) Update the stoploss to latest trailing amt.
if pos_opened_long
strategy.exit(ENUM_LONG, stop=stop_loss_price_long, comment="SL")
// (3) INITIAL ENTRY:
if within_timeframe and entry_signal_long
pos_opened_long := true
alert(LONG_MSG_ENTER, alert.freq_once_per_bar)
strategy.entry(ENUM_LONG, strategy.long, comment="long")
// Plotting:
TSL_transp_long = pos_opened_long and within_timeframe ? 0 : 100
plot(stop_loss_price_long, color=color.new(color.green, TSL_transp_long))
// CLEAN UP: Setting variables back to default values once no longer in use
if ta.change(strategy.position_size) and strategy.position_size == 0
pos_opened_long := false
if not pos_opened_long
stop_loss_price_long := float(0)
// } end of MAIN block