Estrategia de ruptura basada en el impulso


Fecha de creación: 2024-02-23 14:27:21 Última modificación: 2024-02-23 14:27:21
Copiar: 0 Número de Visitas: 641
1
Seguir
1617
Seguidores

Estrategia de ruptura basada en el impulso

Descripción general

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.

Principio de estrategia

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.

Análisis de las ventajas

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.

Análisis de riesgos

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.

Dirección de optimización

La estrategia puede ser optimizada en los siguientes aspectos:

  1. Optimización de la longitud de los canales Donchianos para buscar la combinación óptima de parámetros
  2. Intentar diferentes tipos de medias móviles como indicadores de fluctuación
  3. Ajuste el ATR multiplicado o cambiado a un número fijo de puntos de parada
  4. Añadir más indicadores de tendencia, como el MACD
  5. Optimizar las ventanas de juicio de los altos y bajos durante el año, etc.

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.

Resumir

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.

Código Fuente de la Estrategia
/*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)