Tendance à la DI à double échéancier

Auteur:ChaoZhang est là., Date: 2023-11-07 16h31 et 07h
Les étiquettes:

img

Résumé

Cette stratégie utilise l'indice directionnel moyen (DI +) et l'indice directionnel négatif (DI-) sur deux délais pour déterminer la direction de la tendance pour les transactions longues et courtes. Lorsque DI + est supérieur à DI- sur les deux délais, il indique une tendance à la hausse et un signal long est déclenché. Lorsque DI- est supérieur à DI+ sur les deux délais, il indique une tendance à la baisse et un signal court est déclenché.

Comment fonctionne- t- il?

La stratégie repose sur plusieurs principes:

  1. Calculer le DI+ et le DI-. Obtenez le DI+ et le DI- en utilisant des prix élevés, proches et bas.

  2. Comparer les valeurs DI+ et DI- sur deux délais. Calculer les valeurs DI+ et DI- respectivement sur le calendrier principal (par exemple 1 heure) et sur un calendrier plus large (par exemple quotidien).

  3. Déterminez la direction de la tendance. Lorsque DI+ est supérieur à DI- sur les deux périodes plus grandes et plus petites, cela indique une tendance à la hausse. Lorsque DI- est supérieur à DI+ sur les deux périodes, cela indique une tendance à la baisse.

  4. DI+>DI- sur les deux images donne un signal long.

  5. Utilisez ATR pour calculer le stop loss dynamique pour suivre la tendance.

  6. Conditions de sortie: sortie lorsque le stop loss est atteint ou que le prix est inversé.

Les avantages

La stratégie présente les avantages suivants:

  1. En utilisant des filtres à double chronologie, on peut détecter de fausses fuites.

  2. L'arrêt de trail ATR maximise la protection des bénéfices et évite que les arrêts ne soient trop serrés.

  3. Un stop loss rapide permet de contrôler les pertes sur les transactions uniques.

  4. Le trading avec la tendance permet de suivre les tendances en continu.

  5. Des règles simples et claires, faciles à mettre en œuvre pour le trading en direct.

Risques et solutions

Il existe également plusieurs risques:

  1. DI a un effet de retard, peut manquer le moment d'entrée, peut optimiser des paramètres ou ajouter d'autres indicateurs.

  2. Les délais doubles peuvent avoir des divergences entre les TF plus grands et plus petits.

  3. Un stop-loss trop agressif peut entraîner une survente.

  4. L'utilisation d'une scie dans le marché latéral peut entraîner des transactions fréquentes. Ajouter des filtres pour réduire la fréquence des transactions.

  5. L'optimisation des paramètres repose sur des données historiques et peut être surchargée.

Directions d'optimisation

La stratégie peut être améliorée dans les domaines suivants:

  1. Optimiser les paramètres de calcul du DI pour le meilleur ensemble de paramètres.

  2. Ajouter d'autres filtres d'indicateur pour améliorer la précision du signal, par exemple MACD, KDJ, etc.

  3. Améliorer la stratégie de stop loss pour adapter davantage les conditions du marché, telles que le stop de suivi ou les ordres en attente.

  4. Ajoutez des filtres de session de trading pour éviter les événements d'actualité importants.

  5. Testez la robustesse des paramètres sur différents produits afin d'améliorer leur adaptabilité.

  6. Introduire l'apprentissage automatique pour former le modèle sur les données historiques.

Conclusion

En résumé, il s'agit d'une stratégie de suivi de tendance typique qui utilise DI pour déterminer la direction de la tendance et définir un stop loss pour verrouiller les bénéfices le long de la tendance.


/*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


Plus de