Esta estrategia utiliza el índice direccional promedio (DI +) y el índice direccional negativo (DI-) en dos marcos de tiempo para determinar la dirección de la tendencia para las operaciones largas y cortas. Cuando DI + es mayor que DI- en ambos marcos de tiempo más grandes y más pequeños, indica una tendencia alcista y se activa una señal larga. Cuando DI- es mayor que DI + en ambos marcos, indica una tendencia descendente y se activa una señal corta.
La estrategia se basa en varios principios:
Calcular DI + y DI-. Obtener DI + y DI- utilizando precios altos, cercanos y bajos.
Compare DI+ y DI- en dos plazos. Calcule DI+ y DI- respectivamente en el marco de tiempo principal del gráfico (por ejemplo, 1 hora) y un marco de tiempo más grande (por ejemplo, diario). Compare los valores entre los dos marcos de tiempo.
Determine la dirección de la tendencia. Cuando DI+ es mayor que DI- en los marcos de tiempo más grandes y más pequeños, indica una tendencia al alza. Cuando DI- es mayor que DI+ en ambos marcos, indica una tendencia a la baja.
DI+>DI- en ambos marcos da una señal larga. DI->DI+ en ambos marcos da una señal corta.
Utilice ATR para calcular el stop loss dinámico para seguir la tendencia.
Condiciones de salida. Salida cuando se alcanza el stop loss o el precio se invierte.
La estrategia tiene las siguientes ventajas:
Usando un doble marco de tiempo DI filtra algunas fugas falsas.
El ATR trailing stop maximiza la protección de las ganancias y evita que las paradas sean demasiado ajustadas.
El stop loss oportuno controla las pérdidas en operaciones individuales.
El comercio con la tendencia permite atrapar continuamente las tendencias.
Reglas simples y claras, fáciles de implementar para el comercio en vivo.
También hay varios riesgos:
El DI tiene un efecto de retraso, puede perder el tiempo de entrada, puede optimizar parámetros o agregar otros indicadores.
El marco de tiempo doble puede tener divergencias entre el TF más grande y el más pequeño. Añadir más validación del marco de tiempo.
El stop loss demasiado agresivo puede causar un exceso de trading.
El mercado lateral puede causar operaciones frecuentes. Añadir filtros para reducir la frecuencia de las operaciones.
La optimización de parámetros se basa en datos históricos y puede estar sobreajustada.
La estrategia puede mejorarse en los siguientes aspectos:
Optimizar los parámetros de cálculo del DI para el mejor conjunto de parámetros.
Añadir otros filtros de indicadores para mejorar la precisión de la señal, por ejemplo, MACD, KDJ, etc.
Mejorar la estrategia de stop loss para adaptarse a más condiciones de mercado, como el stop de seguimiento o las órdenes pendientes.
Añadir filtros de sesión de negociación para evitar eventos de noticias importantes.
Prueba la robustez de los parámetros en diferentes productos para mejorar la adaptabilidad.
Introducir el aprendizaje automático para entrenar el modelo en datos históricos.
En resumen, esta es una estrategia típica de seguimiento de tendencias que utiliza DI para determinar la dirección de la tendencia y establecer stop loss para bloquear las ganancias a lo largo de la tendencia. La ventaja radica en su lógica clara y facilidad de implementación para el comercio en vivo. También hay margen de mejora a través de la optimización de parámetros, la adición de filtros, etc. Con una mayor optimización y prueba de robustez, puede convertirse en una estrategia de seguimiento de tendencias muy práctica.
/*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