
La estrategia de ruptura dinámica es una estrategia de tendencia que sigue la dinámica del mercado. Combina varios indicadores para determinar si el mercado está actualmente en una tendencia ascendente o descendente, y toma más posiciones al romper los puntos críticos de resistencia, y toma posiciones vacías al romper los puntos críticos de soporte.
La estrategia determina la tendencia del mercado y los precios clave mediante el cálculo de varios canales donchianos de largos períodos. En concreto, determina una tendencia alcista cuando el precio supera un ciclo más largo, como el de 40 días, y en esa base emite múltiples señales combinadas con condiciones de filtración, como nuevos altibajos en el año y una alineación direccional de la media móvil.
En cuanto a la salida de posiciones, la estrategia ofrece dos opciones: la línea de cancelación fija y el stop tracking. La línea de cancelación fija establece el stop en función de un período más corto, como el canal Donchian de 20 días; el stop tracking calcula el stop tracking diariamente en función del valor de ATR. Ambos métodos de stop tracking controlan el riesgo de manera eficiente.
Esta estrategia combina el juicio de la tendencia y la operación de la ruptura, capaz de capturar eficazmente las oportunidades direccionales de las líneas cortas en el mercado. En comparación con un solo indicador, que utiliza una amplia gama de condiciones de filtración, que puede filtrar algunos falsos brechas para mejorar la calidad de la señal de entrada. Además, la aplicación de la estrategia de detener los pérdidas también hace que sea más resistente, incluso si la situación de corto plazo de retroceso puede controlar eficazmente las pérdidas.
El principal riesgo de esta estrategia reside en la posibilidad de que se produzcan fuertes fluctuaciones en el mercado, lo que provoca que el stop loss sea el desencadenante de la salida de la posición. En este caso, si el mercado se invierte rápidamente, es posible que se pierda la oportunidad. Además, la aplicación de múltiples condiciones de filtración también filtra algunas oportunidades y reduce la frecuencia de la estrategia.
Para reducir el riesgo, se puede ajustar adecuadamente el valor de ATR o ampliar el intervalo de órbita Donchian, lo que reduce la posibilidad de que el stop-loss sea superado. También se pueden reducir o cancelar algunas condiciones de filtración para aumentar la frecuencia de entrada, pero el riesgo también aumenta.
La estrategia puede ser optimizada en los siguientes aspectos:
A través de la prueba de diferentes parámetros, se puede encontrar la combinación óptima de parámetros, logrando un equilibrio entre riesgos y beneficios.
La estrategia utiliza una combinación de varios indicadores para determinar la dirección de la tendencia y emite una señal de negociación cuando se rompe un punto crítico. Su mecanismo de stop loss también hace que la estrategia tenga una mayor capacidad de control de riesgos. Mediante la configuración de parámetros optimizados, la estrategia puede lograr un beneficio adicional estable.
/*backtest
start: 2024-01-23 00:00:00
end: 2024-02-22 00:00:00
period: 1h
basePeriod: 15m
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/
// © HeWhoMustNotBeNamed
//@version=4
strategy("BuyHigh-SellLow Strategy", overlay=true, initial_capital = 10000, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type = strategy.commission.percent, pyramiding = 1, commission_value = 0.01, calc_on_order_fills = true)
donchianEntryLength = input(40, step=10)
donchianExitLength = input(20, step=10)
considerNewLongTermHighLows = input(true)
shortHighLowPeriod = input(120, step=10)
longHighLowPeriod = input(180, step=10)
considerMAAlignment = input(true)
MAType = input(title="Moving Average Type", defval="ema", options=["ema", "sma", "hma", "rma", "vwma", "wma"])
LookbackPeriod = input(40, minval=10,step=10)
atrLength = input(22)
atrMult = input(4)
exitStrategy = input(title="Exit Strategy", defval="tsl", options=["dc", "tsl"])
considerYearlyHighLow = input(true)
backtestYears = input(10, minval=1, step=1)
f_getMovingAverage(source, MAType, length)=>
ma = sma(source, length)
if(MAType == "ema")
ma := ema(source,length)
if(MAType == "hma")
ma := hma(source,length)
if(MAType == "rma")
ma := rma(source,length)
if(MAType == "vwma")
ma := vwma(source,length)
if(MAType == "wma")
ma := wma(source,length)
ma
f_getTrailingStop(atr, atrMult)=>
stop = close - atrMult*atr
stop := strategy.position_size > 0 ? max(stop, stop[1]) : stop
stop
f_getMaAlignment(MAType, includePartiallyAligned)=>
ma5 = f_getMovingAverage(close,MAType,5)
ma10 = f_getMovingAverage(close,MAType,10)
ma20 = f_getMovingAverage(close,MAType,20)
ma30 = f_getMovingAverage(close,MAType,30)
ma50 = f_getMovingAverage(close,MAType,50)
ma100 = f_getMovingAverage(close,MAType,100)
ma200 = f_getMovingAverage(close,MAType,200)
upwardScore = 0
upwardScore := close > ma5? upwardScore+1:upwardScore
upwardScore := ma5 > ma10? upwardScore+1:upwardScore
upwardScore := ma10 > ma20? upwardScore+1:upwardScore
upwardScore := ma20 > ma30? upwardScore+1:upwardScore
upwardScore := ma30 > ma50? upwardScore+1:upwardScore
upwardScore := ma50 > ma100? upwardScore+1:upwardScore
upwardScore := ma100 > ma200? upwardScore+1:upwardScore
upwards = close > ma5 and ma5 > ma10 and ma10 > ma20 and ma20 > ma30 and ma30 > ma50 and ma50 > ma100 and ma100 > ma200
downwards = close < ma5 and ma5 < ma10 and ma10 < ma20 and ma20 < ma30 and ma30 < ma50 and ma50 < ma100 and ma100 < ma200
upwards?1:downwards?-1:includePartiallyAligned ? (upwardScore > 5? 0.5: upwardScore < 2?-0.5:upwardScore>3?0.25:-0.25) : 0
//////////////////////////////////// Calculate new high low condition //////////////////////////////////////////////////
f_calculateNewHighLows(shortHighLowPeriod, longHighLowPeriod, considerNewLongTermHighLows)=>
newHigh = highest(shortHighLowPeriod) == highest(longHighLowPeriod) or not considerNewLongTermHighLows
newLow = lowest(shortHighLowPeriod) == lowest(longHighLowPeriod) or not considerNewLongTermHighLows
[newHigh,newLow]
//////////////////////////////////// Calculate Yearly High Low //////////////////////////////////////////////////
f_getYearlyHighLowCondition(considerYearlyHighLow)=>
yhigh = security(syminfo.tickerid, '12M', high[1])
ylow = security(syminfo.tickerid, '12M', low[1])
yhighlast = yhigh[365]
ylowlast = ylow[365]
yhighllast = yhigh[2 * 365]
ylowllast = ylow[2 * 365]
yearlyTrendUp = na(yhigh)? true : na(yhighlast)? close > yhigh : na(yhighllast)? close > max(yhigh,yhighlast) : close > max(yhigh, min(yhighlast, yhighllast))
yearlyHighCondition = ( (na(yhigh) or na(yhighlast) ? true : (yhigh > yhighlast) ) and ( na(yhigh) or na(yhighllast) ? true : (yhigh > yhighllast))) or yearlyTrendUp or not considerYearlyHighLow
yearlyTrendDown = na(ylow)? true : na(ylowlast)? close < ylow : na(ylowllast)? close < min(ylow,ylowlast) : close < min(ylow, max(ylowlast, ylowllast))
yearlyLowCondition = ( (na(ylow) or na(ylowlast) ? true : (ylow < ylowlast) ) and ( na(ylow) or na(ylowllast) ? true : (ylow < ylowllast))) or yearlyTrendDown or not considerYearlyHighLow
label_x = time+(60*60*24*1000*1)
[yearlyHighCondition,yearlyLowCondition]
donchian(rangeLength)=>
upper = highest(rangeLength)
lower = lowest(rangeLength)
middle = (upper+lower)/2
[middle, upper, lower]
inDateRange = true
[eMiddle, eUpper, eLower] = donchian(donchianEntryLength)
[exMiddle, exUpper, exLower] = donchian(donchianExitLength)
maAlignment = f_getMaAlignment(MAType, false)
[yearlyHighCondition, yearlyLowCondition] = f_getYearlyHighLowCondition(considerYearlyHighLow)
[newHigh,newLow] = f_calculateNewHighLows(shortHighLowPeriod, longHighLowPeriod, considerNewLongTermHighLows)
maAlignmentLongCondition = highest(maAlignment, LookbackPeriod) == 1 or not considerMAAlignment
atr = atr(atrLength)
tsl = f_getTrailingStop(atr, atrMult)
//U = plot(eUpper, title="Up", color=color.green, linewidth=2, style=plot.style_linebr)
//D = plot(exLower, title="Ex Low", color=color.red, linewidth=2, style=plot.style_linebr)
longCondition = crossover(close, eUpper[1]) and yearlyHighCondition and newHigh and maAlignmentLongCondition
exitLongCondition = crossunder(close, exLower[1])
shortCondition = crossunder(close, eLower[1]) and yearlyLowCondition and newLow
exitShortCondition = crossover(close, exUpper[1])
strategy.entry("Buy", strategy.long, when=longCondition and inDateRange, oca_name="oca_buy")
strategy.exit("ExitBuyDC", "Buy", when=exitStrategy=='dc', stop=exLower)
strategy.exit("ExitBuyTSL", "Buy", when=exitStrategy=='tsl', stop=tsl)
plot(strategy.position_size > 0 ? (exitStrategy=='dc'?exLower:tsl) : na, title="Trailing Stop", color=color.red, linewidth=2, style=plot.style_linebr)
//strategy.close("Buy", when=exitLongCondition)