La estrategia de seguimiento de tendencia de Donchian se desarrolla sobre la base del principio del canal de Donchian descrito en el artículo
La estrategia se basa en el indicador del canal de Donchian para juzgar la dirección de la tendencia. El canal de Donchian consiste en un canal de período más largo y un canal de período más corto. Cuando el precio rompe el canal de período más largo, indica el comienzo de una tendencia. Cuando el precio rompe el canal de período más corto, indica el final de la tendencia.
Específicamente, la longitud del canal de período más largo es de 50 días o 20 días, y la longitud del canal de período más corto es de 50 días, 20 días o 10 días. Si el precio es igual al precio más alto en 50 días, se abre una posición larga. Si el precio es igual al precio más bajo en 50 días, se abre una posición corta. Si el precio es igual al precio más bajo en 20 o 10 días, se cierran las posiciones largas. Si el precio es igual al precio más alto en 20 o 10 días, se cierran las posiciones cortas.
Al combinar dos canales de Donchian de diferentes períodos, puede determinar la dirección para establecer posiciones cuando comienza una tendencia y realizar un stop loss oportuno cuando termina la tendencia.
Las principales ventajas de esta estrategia son las siguientes:
Puede rastrear las tendencias de manera efectiva mediante la identificación del comienzo y el final de las tendencias utilizando las rupturas del canal de Donchian.
Control de riesgos adecuado. Utiliza un stop loss móvil para controlar la pérdida de una sola operación.
La combinación de períodos de canal puede seleccionarse libremente para adaptarse a diferentes productos y entornos de mercado.
Lógica de negociación simple y clara, fácil de entender e implementar.
Los riesgos de esta estrategia incluyen:
Incapacidad para adaptarse a los mercados de rango limitado, sufrirá pequeñas pérdidas consecutivas cuando la tendencia no sea clara.
El riesgo de fracaso de la ruptura. Los precios pueden retrocedir después de romper el canal, causando un stop loss.
Riesgo de selección del período: la configuración inadecuada del período del canal puede conducir a la negociación de ruido.
El riesgo de disminución del ratio de Sharpe. El aumento del tamaño de la posición sin ajustar el stop loss puede conducir a una disminución del ratio de Sharpe.
Las soluciones son:
Las direcciones de optimización para esta estrategia:
Añadir condiciones de filtración para evitar las flechas, por ejemplo, combinar el volumen para juzgar los verdaderos brotes.
Optimización de la combinación de periodos de canal y dimensionamiento de posiciones para aumentar la proporción de ganancias.
Intentando la optimización del punto de ruptura para encontrar conjuntos óptimos de parámetros.
Aumentar los algoritmos de aprendizaje automático para la optimización dinámica y el ajuste de parámetros.
La estrategia de seguimiento de tendencias de Donchian identifica el comienzo y el final de las tendencias de precios utilizando canales duales, y adopta un estilo de negociación de seguimiento de tendencias con un control efectivo de pérdidas de una sola operación.
/*backtest start: 2023-12-01 00:00:00 end: 2023-12-31 23:59:59 period: 1h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=5 strategy(title="Donchian", overlay=true, pyramiding=0, initial_capital=1000, commission_type=strategy.commission.cash_per_order, commission_value=2, slippage=2) // ============================================================================= // VARIABLES // ============================================================================= donch_string = input.string(title="Length", options = ['20/10','50/20', '50/50', '20/20', '100/100'], defval='50/50') permit_long = input.bool(title = 'Permit long', defval = true) permit_short = input.bool(title = 'Permit short', defval = true) risk_percent = input.float(title="Position Risk %", defval=0.5, step=0.25) stopOffset = input.float(title="ATR mult", defval=2.0, step=0.5) atrLen = input.int(title="ATR Length", defval=20) close_in_end = input.bool(title = 'Close in end', defval = true) permit_stop = input.bool(title = 'Permit stop', defval = false) // ============================================================================= // CALCULATIONS // ============================================================================= donch_len_big = donch_string == '50/20' ? 50 : donch_string == '50/50' ? 50 : donch_string == '20/20' ? 20 : donch_string == '20/10' ? 20 : donch_string == '100/100' ? 100 : na donch_len_small = donch_string == '50/20' ? 20 : donch_string == '50/50' ? 50 : donch_string == '20/20' ? 20 : donch_string == '20/10' ? 10 : donch_string == '100/100' ? 100 : na big_maxclose = ta.highest(close, donch_len_big) big_minclose = ta.lowest(close, donch_len_big) small_maxclose = ta.highest(close, donch_len_small) small_minclose = ta.lowest(close, donch_len_small) atrValue = ta.atr(atrLen)[1] tradeWindow = true // ============================================================================= // NOTOPEN QTY // ============================================================================= risk_usd = (risk_percent / 100) * strategy.equity atr_currency = (atrValue * syminfo.pointvalue) notopen_qty = risk_usd / (stopOffset * atr_currency) // ============================================================================= // LONG STOP // ============================================================================= long_stop_price = 0.0 long_stop_price := strategy.position_size > 0 and na(long_stop_price[1]) ? strategy.position_avg_price - stopOffset * atrValue : strategy.position_size > 0 and strategy.openprofit > risk_usd ? strategy.position_avg_price: strategy.position_size > 0 ? long_stop_price[1] : na // ============================================================================= // SHORT STOP // ============================================================================= short_stop_price = 0.0 short_stop_price := strategy.position_size < 0 and na(short_stop_price[1]) ? strategy.position_avg_price + stopOffset * atrValue : strategy.position_size < 0 and strategy.openprofit > risk_usd ? strategy.position_avg_price : strategy.position_size < 0 ? short_stop_price[1] : na // ============================================================================= // PLOT VERTICAL COLOR BAR // ============================================================================= cross_up = strategy.position_size <= 0 and close == big_maxclose and close >= syminfo.mintick and tradeWindow and permit_long cross_dn = strategy.position_size >= 0 and close == big_minclose and close >= syminfo.mintick and tradeWindow and permit_short bg_color = cross_up ? color.green : cross_dn ? color.red : na bg_color := color.new(bg_color, 70) bgcolor(bg_color) // ============================================================================= // PLOT DONCHIAN LINES // ============================================================================= s1 = cross_up ? na : cross_dn ? na : strategy.position_size != 0 ? strategy.position_avg_price : na s2 = cross_up ? na : cross_dn ? na : strategy.position_size > 0 ? small_minclose : strategy.position_size < 0 ? small_maxclose : na s3 = cross_up ? na : cross_dn ? na : not permit_stop ? na : strategy.position_size > 0 ? long_stop_price : strategy.position_size < 0 ? short_stop_price : na plot(series=big_maxclose, style=plot.style_linebr, color=color.black, linewidth=1, title="Donch Big Maxclose Black") plot(series=big_minclose, style=plot.style_linebr, color=color.black, linewidth=1, title="Donch Big Minclose Black") plot(series=s1, style=plot.style_linebr, color=color.yellow, linewidth=2, title="Entry Yellow") plot(series=s2, style=plot.style_linebr, color=color.red, linewidth=1, title="Donch Small Red") plot(series=s3, style=plot.style_linebr, color=color.fuchsia, linewidth=2, title="Stop Fuchsia") // ============================================================================= // ENTRY ORDERS // ============================================================================= if strategy.position_size <= 0 and close == big_maxclose and close >= syminfo.mintick and tradeWindow and permit_long strategy.entry("Long", strategy.long, qty=notopen_qty) if strategy.position_size >= 0 and close == big_minclose and close >= syminfo.mintick and tradeWindow and permit_short strategy.entry("Short", strategy.short, qty=notopen_qty) // ============================================================================= // EXIT ORDERS // ============================================================================= if strategy.position_size > 0 and permit_stop strategy.exit(id="Stop", from_entry="Long", stop=long_stop_price) if strategy.position_size < 0 and permit_stop strategy.exit(id="Stop", from_entry="Short", stop=short_stop_price) // ========== if strategy.position_size > 0 and close == small_minclose and not barstate.islast strategy.close(id="Long", comment='Donch') if strategy.position_size < 0 and close == small_maxclose and not barstate.islast strategy.close(id="Short", comment='Donch') // ========== if close_in_end if not tradeWindow strategy.close_all(comment='Close in end') // ============================================================================= // END // =============================================================================