Estrategia de seguimiento de tendencias con filtro de rango doble


Fecha de creación: 2024-02-05 11:15:28 Última modificación: 2024-02-05 11:15:28
Copiar: 1 Número de Visitas: 585
1
Seguir
1617
Seguidores

Estrategia de seguimiento de tendencias con filtro de rango doble

Descripción general

La estrategia de seguimiento de tendencias de filtro de doble rango es una estrategia de negociación cuantitativa que utiliza un filtro de doble rango de EMA para identificar la dirección de la tendencia y seguirla. La estrategia, combinada con un filtro de doble rango y el cálculo del rango de ATR, puede identificar eficazmente la dirección de la tendencia de la línea media y larga y utilizar el seguimiento de las paradas para bloquear los beneficios.

Principio de estrategia

El núcleo de la estrategia es el filtro de rango de doble EMA. Calcula el rango ATR de la línea K y lo suaviza, y luego combina los dos EMA para ubicar la línea K dentro del rango y determinar si está actualmente en una tendencia.

Concretamente, la estrategia calcula el tamaño del rango ATR de la línea K y luego lo suaviza combinando dos EMAs. El rango ATR representa el rango de fluctuación normal de la línea K. Cuando el precio supera este rango, significa que hay un cambio de tendencia. La estrategia registra la dirección en que el precio rompe el rango EMA.

Después de la entrada, la estrategia utiliza un stop loss flotante para bloquear las ganancias. Durante la posición, en tiempo real, determina si la línea K retrocede fuera del rango, y si se produce una reversión, abandona la posición actual. Esto puede bloquear efectivamente las ganancias de las operaciones de tendencia.

Análisis de las ventajas

La estrategia de seguimiento de tendencias de doble rango de filtración combina las ventajas de la filtración lineal y el cálculo de rango para determinar con precisión la dirección de la tendencia y evitar entradas y salidas frecuentes en situaciones de crisis. Las ventajas específicas son las siguientes:

  1. Utiliza el principio ATR para determinar el rango de fluctuación de la línea K y evitar entrar en el campo sin dirección en un mercado convulso
  2. Filtros de doble EMA para mejorar la precisión de los juicios y reducir las señales falsas
  3. El bloqueo de pérdidas flotantes en tiempo real es una herramienta eficaz para bloquear ganancias de tendencia.
  4. La lógica de la estrategia es simple, clara, fácil de entender y optimizar

Análisis de riesgos

La estrategia también tiene algunos riesgos, que se centran en los siguientes aspectos:

  1. El salto en alto puede romper el rango de ATR, lo que lleva a una entrada anticipada.
  2. Los paros pueden ser prematuramente activados en una tendencia fuerte.
  3. La configuración incorrecta de los parámetros también puede afectar el rendimiento de la política

Para estos riesgos, se pueden abordar métodos tales como la optimización adecuada de los parámetros, la prevención de falsas rupturas y la determinación de la intensidad de la tendencia.

Recomendaciones para la optimización

Las estrategias de seguimiento de tendencias de filtración de doble alcance también tienen potencial para ser optimizadas aún más, y las principales direcciones de optimización incluyen:

  1. Optimización de los parámetros ATR para suavizar el rango de fluctuación de la línea K
  2. Combinado con un indicador de volumen de transacciones, evita falsos brechas
  3. Evaluar la intensidad de las tendencias y distinguir entre brechas únicas y tendencias sostenibles
  4. Optimización de los puntos de parada, seguimiento de las tendencias altas con garantías de ganancias

A través de estas optimizaciones, la estrategia puede obtener ganancias estables en un entorno de mayor mercado.

Resumir

La estrategia de seguimiento de tendencias de filtro de doble rango integra las múltiples ventajas del filtro de línea media y el criterio de rango ATR para identificar eficazmente la dirección y el momento de entrada de tendencias sostenibles de línea media y larga. Solo entra en juego cuando la tendencia cambia y utiliza los límites de pérdida flotante para bloquear las ganancias. La lógica de la estrategia es simple y clara, ideal para el comercio de tendencias de línea media y larga.

Código Fuente de la Estrategia
/*backtest
start: 2023-01-29 00:00:00
end: 2024-02-04 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy("Range Filter [DW] & Labels", shorttitle="RF [DW] & Labels", overlay=true)

//Conditional Sampling EMA Function 
Cond_EMA(x, cond, n)=>
    var val     = array.new_float(0)
    var ema_val = array.new_float(1)
    if cond
        array.push(val, x)
        if array.size(val) > 1
            array.remove(val, 0)
        if na(array.get(ema_val, 0))
            array.fill(ema_val, array.get(val, 0))
        array.set(ema_val, 0, (array.get(val, 0) - array.get(ema_val, 0))*(2/(n + 1)) + array.get(ema_val, 0))
    EMA = array.get(ema_val, 0)
    EMA

//Conditional Sampling SMA Function
Cond_SMA(x, cond, n)=>
    var vals = array.new_float(0)
    if cond
        array.push(vals, x)
        if array.size(vals) > n
            array.remove(vals, 0)
    SMA = array.avg(vals)
    SMA

//Standard Deviation Function
Stdev(x, n)=>
    sqrt(Cond_SMA(pow(x, 2), 1, n) - pow(Cond_SMA(x, 1, n), 2))

//Range Size Function
rng_size(x, scale, qty, n)=> 
    ATR      = Cond_EMA(tr(true), 1, n)
    AC       = Cond_EMA(abs(x - x[1]), 1, n)
    SD       = Stdev(x, n)
    rng_size = scale=="Pips" ? qty*0.0001 : scale=="Points" ? qty*syminfo.pointvalue : scale=="% of Price" ? close*qty/100 : scale=="ATR" ? qty*ATR :
               scale=="Average Change" ? qty*AC : scale=="Standard Deviation" ? qty*SD : scale=="Ticks" ? qty*syminfo.mintick : qty   

//Two Type Range Filter Function
rng_filt(h, l, rng_, n, type, smooth, sn, av_rf, av_n)=>
    rng_smooth = Cond_EMA(rng_, 1, sn)
    r          = smooth ? rng_smooth : rng_
    var rfilt  = array.new_float(2, (h + l)/2)
    array.set(rfilt, 1, array.get(rfilt, 0))
    if type=="Type 1"
        if h - r > array.get(rfilt, 1)
            array.set(rfilt, 0, h - r)
        if l + r < array.get(rfilt, 1)
            array.set(rfilt, 0, l + r)
    if type=="Type 2"
        if h >= array.get(rfilt, 1) + r
            array.set(rfilt, 0, array.get(rfilt, 1) + floor(abs(h - array.get(rfilt, 1))/r)*r)
        if l <= array.get(rfilt, 1) - r
            array.set(rfilt, 0, array.get(rfilt, 1) - floor(abs(l - array.get(rfilt, 1))/r)*r)
    rng_filt1 = array.get(rfilt, 0)
    hi_band1  = rng_filt1 + r
    lo_band1  = rng_filt1 - r
    rng_filt2 = Cond_EMA(rng_filt1, rng_filt1 != rng_filt1[1], av_n)
    hi_band2  = Cond_EMA(hi_band1, rng_filt1 != rng_filt1[1], av_n)
    lo_band2  = Cond_EMA(lo_band1, rng_filt1 != rng_filt1[1], av_n)
    rng_filt  = av_rf ? rng_filt2 : rng_filt1
    hi_band   = av_rf ? hi_band2 : hi_band1
    lo_band   = av_rf ? lo_band2 : lo_band1
    [hi_band, lo_band, rng_filt]
 
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Inputs
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------

//Filter Type
f_type = input(defval="Type 1", options=["Type 1", "Type 2"], title="Filter Type")

//Movement Source
mov_src = input(defval="Close", options=["Wicks", "Close"], title="Movement Source")

//Range Size Inputs
rng_qty   = input(defval=2.618, minval=0.0000001, title="Range Size")
rng_scale = input(defval="Average Change", options=["Points", "Pips", "Ticks", "% of Price", "ATR", "Average Change", "Standard Deviation", "Absolute"], title="Range Scale")

//Range Period
rng_per = input(defval=14, minval=1, title="Range Period (for ATR, Average Change, and Standard Deviation)")

//Range Smoothing Inputs
smooth_range = input(defval=true, title="Smooth Range")
smooth_per   = input(defval=27, minval=1, title="Smoothing Period")

//Filter Value Averaging Inputs
av_vals    = input(defval=true, title="Average Filter Changes")
av_samples = input(defval=2, minval=1, title="Number Of Changes To Average")

// New inputs for take profit and stop loss
take_profit_percent = input(defval=100.0, minval=0.1, maxval=1000.0, title="Take Profit Percentage", step=0.1)
stop_loss_percent = input(defval=100, minval=0.1, maxval=1000.0, title="Stop Loss Percentage", step=0.1)

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Definitions
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------

//High And Low Values
h_val = mov_src=="Wicks" ? high : close
l_val = mov_src=="Wicks" ? low : close

//Range Filter Values
[h_band, l_band, filt] = rng_filt(h_val, l_val, rng_size((h_val + l_val)/2, rng_scale, rng_qty, rng_per), rng_per, f_type, smooth_range, smooth_per, av_vals, av_samples)

//Direction Conditions
var fdir = 0.0
fdir    := filt > filt[1] ? 1 : filt < filt[1] ? -1 : fdir
upward   = fdir==1 ? 1 : 0
downward = fdir==-1 ? 1 : 0

//Colors
filt_color = upward ? #05ff9b : downward ? #ff0583 : #cccccc
bar_color  = upward and (close > filt) ? (close > close[1] ? #05ff9b : #00b36b) :
             downward and (close < filt) ? (close < close[1] ? #ff0583 : #b8005d) : #cccccc

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Outputs
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------

//Filter Plot
filt_plot = plot(filt, color=filt_color, transp=0, linewidth=3,  title="Filter")

//Band Plots
h_band_plot = plot(h_band, color=#05ff9b, transp=100, title="High Band")
l_band_plot = plot(l_band, color=#ff0583, transp=100, title="Low Band")

//Band Fills
fill(h_band_plot, filt_plot, color=#00b36b, transp=85, title="High Band Fill")
fill(l_band_plot, filt_plot, color=#b8005d, transp=85, title="Low Band Fill")

//Bar Color
barcolor(bar_color)

//External Trend Output
plot(fdir, transp=100, editable=false, display=display.none, title="External Output - Trend Signal")

// Trading Conditions Logic
longCond = close > filt and close > close[1] and upward > 0 or close > filt and close < close[1] and upward > 0 
shortCond = close < filt and close < close[1] and downward > 0 or close < filt and close > close[1] and downward > 0

CondIni = 0
CondIni := longCond ? 1 : shortCond ? -1 : CondIni[1]
longCondition = longCond and CondIni[1] == -1
shortCondition = shortCond and CondIni[1] == 1

// Strategy Entry and Exit
strategy.entry("Buy", strategy.long, when = longCondition)
strategy.entry("Sell", strategy.short, when = shortCondition)

// New: Close conditions based on percentage change
long_take_profit_condition = close > strategy.position_avg_price * (1 + take_profit_percent / 100)
short_take_profit_condition = close < strategy.position_avg_price * (1 - take_profit_percent / 100)

long_stop_loss_condition = close < strategy.position_avg_price * (1 - stop_loss_percent / 100)
short_stop_loss_condition = close > strategy.position_avg_price * (1 + stop_loss_percent / 100)

strategy.close("Buy", when = shortCondition or long_take_profit_condition or long_stop_loss_condition)
strategy.close("Sell", when = longCondition or short_take_profit_condition or short_stop_loss_condition)

// Plot Buy and Sell Labels
plotshape(longCondition, title = "Buy Signal", text ="BUY", textcolor = color.white, style=shape.labelup, size = size.normal, location=location.belowbar, color = color.green, transp = 0)
plotshape(shortCondition, title = "Sell Signal", text ="SELL", textcolor = color.white, style=shape.labeldown, size = size.normal, location=location.abovebar, color = color.red, transp = 0)

// Alerts
alertcondition(longCondition, title="Buy Alert", message = "BUY")
alertcondition(shortCondition, title="Sell Alert", message = "SELL")