
La estrategia se basa en el indicador de tendencia promedio DI+ y DI-, se utiliza el indicador de DI de dos marcos de tiempo diferentes para determinar la dirección de la tendencia, y luego se hace más de baja. Cuando el marco de tiempo más grande y el marco de tiempo más pequeño DI+ son superiores a DI-, se juzga como una tendencia alcista, hacer más; cuando los dos marcos de tiempo DI- son superiores a DI+, se juzga como una tendencia bajista, hacer más de baja.
La estrategia se basa principalmente en los siguientes principios:
Cálculo de DI+ y DI- mediante la obtención de precios altos, precios de cierre y precios bajos.
Comparación de dos marcos de tiempo DI+ y DI-。 en el marco de tiempo principal (por ejemplo, 1 hora) y en el marco de tiempo más grande (por ejemplo, la línea de sol) se calculan DI+ y DI-, respectivamente, y se compara la relación de mayor y menor tamaño。
Cuando el DI+ de un marco de tiempo mayor y el DI+ de un marco de tiempo menor son mayores que el DI-, se considera una tendencia de varios encabezados; cuando el DI- de ambos marcos de tiempo es mayor que el DI+ se considera una tendencia de encabezados.
Emite una señal de transacción. La señal de multitapa es para dos marcos de tiempo DI+>DI-, hacer más; la señal de cabezal vacío es para dos marcos de tiempo DI->DI+, hacer vacío.
Establecer un stop. Basado en el cálculo de la parada de pérdida ATR, para lograr un stop de seguimiento de tendencias.
Condiciones de salida: cesación de la posición cuando el deterioro se desencadena o la reversión del precio.
La estrategia tiene las siguientes ventajas:
Utilizando el DI de doble marco de tiempo para juzgar tendencias, se pueden filtrar algunas brechas falsas.
El ATR tiene un seguimiento dinámico de las pérdidas, lo que permite proteger al máximo los beneficios y evitar que las pérdidas sean excesivas.
La pérdida de tiempo puede ser controlada por una sola pérdida.
El comercio de la tendencia permite capturar continuamente las oportunidades de la tendencia.
Las reglas son claras y fáciles de entender, y son fáciles de manejar en el disco.
La estrategia también tiene los siguientes riesgos:
Los indicadores de DI están atrasados y pueden perder el momento de entrada. Se pueden optimizar los parámetros adecuadamente o combinar con otros indicadores.
El juicio de doble marco de tiempo puede tener discrepancias de arriba a abajo. Se puede agregar una señal de verificación de marco de tiempo.
El stop loss demasiado radical puede causar un comercio demasiado frecuente. Se puede relajar adecuadamente el multiplicador ATR.
En situaciones convulsivas, se puede generar un intercambio frecuente. Se puede reducir la frecuencia de las transacciones mediante el aumento de las condiciones de filtración.
La optimización de los parámetros depende de los datos históricos, y es posible que haya una optimización excesiva en el disco. La robustez de los parámetros debe evaluarse con cuidado.
La estrategia puede ser optimizada en los siguientes aspectos:
Optimización de los parámetros calculados por el DI para encontrar la combinación óptima de parámetros.
Añadir filtros de otros indicadores para mejorar la precisión de la señal, como MACD, KDJ, etc.
Optimización de la estrategia de stop loss para adaptarse a más condiciones de mercado. Se puede cambiar a stop loss móvil o stop loss fijo.
En el blog de la empresa, se puede leer: “Aumentar el filtro de las horas de transacción para evitar noticias importantes”.
Prueba de la robustez de los parámetros de las diferentes variedades para mejorar la adaptabilidad.
Aumentar el componente de aprendizaje automático para entrenar modelos de juicio con datos históricos.
La estrategia en su conjunto es una estrategia típica de seguimiento de tendencias, que utiliza los indicadores de DI para determinar la dirección de la tendencia, establecer un stop loss para bloquear la ganancia y mantener la ganancia en la tendencia. La ventaja de la estrategia reside en la claridad de la estrategia y la facilidad de operación en el campo.
/*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