Estrategia de trading de reversión a la media de la EMA


Fecha de creación: 2023-10-26 15:33:50 Última modificación: 2023-10-26 15:33:50
Copiar: 2 Número de Visitas: 1006
1
Seguir
1617
Seguidores

Estrategia de trading de reversión a la media de la EMA

Descripción general

La estrategia de negociación de retorno a la media de la EMA es una estrategia de negociación que utiliza la diferencia porcentual entre la distancia de la media de la EMA y el precio actual como señal de apertura de la posición y utiliza el seguimiento de la pérdida para administrar la posición.

Principio de estrategia

La estrategia utiliza la EMA como indicador de la media y calcula el porcentaje de diferencia entre el precio actual y la EMA. Cuando el precio está lo suficientemente lejos de la EMA (el 9% por defecto), se abre más posiciones; cuando el precio está lo suficientemente cerca de la EMA (el 1% por defecto), se cierra. Una vez abierta la posición, se utiliza el stop loss operativo para bloquear ganancias, aumentando gradualmente la línea de stop loss a medida que aumentan las ganancias.

En concreto, la estrategia incluye los siguientes componentes:

  1. Cálculo de la línea media de la EMA. Se puede configurar el ciclo (el 200 por defecto), la fuente de datos (el precio de cierre) y el método de cálculo (EMA, SMA, RMA, WMA).

  2. Calcula el porcentaje de diferencia entre el precio actual y el EMA. Tenga en cuenta el tratamiento de los valores positivos y negativos.

  3. La apertura de posición en función de la diferencia. El límite de apertura de posición en exceso es del 9% (configurable), y el límite de apertura de posición en vacío es del 9% (configurable).

  4. Soporta la apertura de la escalera. Se puede configurar el número de escaleras de la escalera y el grado de cada escalera.

  5. Tras la apertura de la posición, se puede configurar el umbral de inicio de la parada de pérdidas (el 1% de ganancias predeterminadas) y el margen de seguimiento (el 1% predeterminado).

  6. Según la diferencia de la tasa de liquidación. La tasa de liquidación de la tasa de liquidación de la tasa de liquidación de la tasa de liquidación de la tasa de liquidación de la tasa de liquidación de la tasa de liquidación de la tasa de liquidación de la tasa de liquidación de la tasa de liquidación de la tasa de liquidación de la tasa de liquidación de la tasa de liquidación de la tasa de liquidación de la tasa de liquidación.

  7. Cancelación de pedidos pendientes. Cuando los precios se acerquen a la EMA, se cancelarán los pedidos pendientes.

  8. Porcentaje de detención de pérdidas configurable.

  9. Apoyo a la retroalimentación y al comercio en tiempo real.

Análisis de las ventajas

La estrategia tiene las siguientes ventajas:

  1. Utilizando el concepto de regreso de la línea media, se abre una posición cuando el precio se aleja de la línea media y se cierra una posición cuando regresa, de acuerdo con la teoría de la negociación de tendencias.

  2. Los parámetros para abrir, detener y cerrar posiciones se pueden configurar con precisión para adaptarse a diferentes entornos de mercado.

  3. La construcción de un almacén en escala permite reducir el costo individual.

  4. El operativo Stop Loss puede bloquear ganancias y administrar riesgos.

  5. El espacio de optimización es amplio, se puede ajustar el parámetro de la línea media o abrir la brecha de posición cerrada para adaptarse a diferentes situaciones.

  6. Soporta el lenguaje de programación principal Pine Script, que se puede usar directamente en TradingView.

  7. La presentación gráfica es intuitiva y facilita el análisis.

Análisis de riesgos

La estrategia también tiene los siguientes riesgos:

  1. Riesgo de ajuste de los datos de retroalimentación. La optimización de los parámetros puede ser excesivamente ajustada a los datos de retroalimentación, y la eficacia en el disco real es dudosa.

  2. Riesgo de falla de la línea media. El precio puede alejarse de la línea media de manera significativa durante mucho tiempo, sin posibilidad de retorno.

  3. El stop loss es perseguido por el riesgo. La situación es dramática y el stop loss puede ser superado.

  4. Las transacciones son frecuentes y las cargas de transacción son elevadas.

  5. Se requiere un ciclo de observación más largo, con una mayor incidencia de emergencias.

Gestión de riesgos correspondiente:

  1. Se realizan ajustes en los parámetros para garantizar la solidez de los parámetros.

  2. La configuración de un ciclo equilíneo razonable, no demasiado corto o demasiado largo.

  3. La extensión de la suspensión de pérdidas debe ser adecuada para evitar que se bloquee.

  4. La liberalización adecuada de las condiciones de apertura de posiciones y la reducción de la frecuencia de las transacciones.

  5. El objetivo de este proyecto es mejorar la capacidad de adaptación ante emergencias, combinando con otros indicadores.

Dirección de optimización

La estrategia puede ser optimizada en los siguientes aspectos:

  1. Se han añadido condiciones de filtración para reducir las señales falsas, como el volumen de transacciones, las bandas de Brin y el RSI.

  2. Aumentar las líneas medias compuestas, como el sistema de doble EMA, para mejorar la probabilidad de operaciones en sentido contrario.

  3. Optimización de las estrategias de detención de pérdidas, como la detención de pérdidas adaptativas, la salida de Chandelier, etc., para limitar aún más el riesgo.

  4. Se añade la función de optimización automática de parámetros para buscar automáticamente la combinación de parámetros más adecuada.

  5. Aumentar las predicciones de aprendizaje automático para ayudar a determinar la probabilidad de que el precio se salga de la línea media.

  6. Considere la posibilidad de negociar a través de períodos de tiempo, aprovechando la información de la noche o antes de la hora.

  7. La integración de los fondos de acciones, la selección automática de acciones y el comercio, la ampliación de la capacidad de la estrategia.

Resumir

La estrategia de retorno a la media es una estrategia de seguimiento de la tendencia basada en la característica de retorno a la línea media de los precios. Utiliza razonablemente las características estadísticas de la línea media para juzgar la reversión de la tendencia y controla el riesgo con un alto de pérdida. En comparación con la estrategia de negociación de la línea media tradicional, se centra más en el seguimiento dinámico de los paros, en lugar de en la apertura de posiciones estrictamente cerradas.

Código Fuente de la Estrategia
/*backtest
start: 2022-10-19 00:00:00
end: 2023-10-25 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/
// © jordanfray

//@version=5
strategy(title="EMA Mean Reversion Strategy", overlay=true, max_bars_back=5000, default_qty_type=strategy.percent_of_equity, default_qty_value=100,initial_capital=100000, commission_type=strategy.commission.percent, commission_value=0.05, backtest_fill_limits_assumption=2)


// Indenting Classs
indent_1 = " "
indent_2 = "  "
indent_3 = "   "
indent_4 = "    "


// Tooltips
longEntryToolTip = "When the percentage that the price is away from the selected EMA reaches this point, a long postion will open."
shortEntryToolTip = "When the percentage that the price is away from the selected EMA reaches this point, a short postion will open."
closeEntryToolTip = "When the percentage that the price is away from the selected EMA reaches this point, open postion will close."
ladderInToolTip = "Enable this to use the laddering settings below."
cancelEntryToolTip = "When the percentage that the price is away from the selected EMA reaches this point, any unfilled entries will be canceled."

// Group Titles
group_one_title = "EMA Settings"
group_two_title = "Entry Settings"


// Colors
blue = color.new(#00A5FF,0)
lightBlue = color.new(#00A5FF,90)
green = color.new(#2DBD85,0)
gray_80 =  color.new(#7F7F7F,80)
gray_60 =  color.new(#7F7F7F,60)
gray_40 =  color.new(#7F7F7F,40)
white = color.new(#ffffff,0)
red = color.new(#E02A4A,0)
transparent = color.new(#000000,100)


// Strategy Settings
EMAtimeframe = input.timeframe(defval="", title="Timeframe", group=group_one_title)
EMAlength = input.int(defval=200, minval=1, title="Length", group=group_one_title)
EMAtype = input.string(defval="EMA", options = ["EMA", "SMA", "RMA", "WMA"], title="Type", group=group_one_title)
EMAsource = input.source(defval=close, title="Source", group=group_one_title)

openLongEntryAbove = input.float(defval=9, title="Long Position Entry Trigger", tooltip=longEntryToolTip, group=group_two_title)
openEntryEntryAbove = input.float(defval=9, title="Short Position Entry Trigger", tooltip=shortEntryToolTip, group=group_two_title)
closeEntryBelow = input.float(defval=1.0, title="Close Position Trigger", tooltip=closeEntryToolTip, group=group_two_title)
cancelEntryBelow = input.float(defval=4, title="Cancel Unfilled Entries Trigger", tooltip=cancelEntryToolTip, group=group_two_title)

enableLaddering = input.bool(defval=true, title="Ladder Into Positions", tooltip=ladderInToolTip, group=group_two_title)
ladderRungs = input.int(defval=4, minval=2, maxval=4, step=1, title=indent_4+"Ladder Rungs", group=group_two_title)
ladderStep = input.float(defval=.5, title=indent_4+"Ladder Step (%)", step=.1, group=group_two_title)/100
stop_loss_val = input.float(defval=4.0, title="Stop Loss (%)", step=0.1, group=group_two_title)/100
start_trailing_after = input.float(defval=1, title="Start Trailing After (%)", step=0.1, group=group_two_title)/100
trail_behind = input.float(defval=1, title="Trail Behind (%)", step=0.1, group=group_two_title)/100

// Calculate trailing stop values
long_start_trailing_val = strategy.position_avg_price + (strategy.position_avg_price * start_trailing_after)
long_trail_behind_val = close - (strategy.position_avg_price * trail_behind)
long_stop_loss = strategy.position_avg_price * (1.0 - stop_loss_val)
short_start_trailing_val = strategy.position_avg_price - (strategy.position_avg_price * start_trailing_after)
short_trail_behind_val = close + (strategy.position_avg_price * trail_behind)
short_stop_loss = strategy.position_avg_price * (1 + stop_loss_val)


// Calulate EMA
EMA = switch EMAtype
    "EMA" => ta.ema(EMAsource, EMAlength)
    "SMA" => ta.sma(EMAsource, EMAlength)
    "RMA" => ta.rma(EMAsource, EMAlength)
    "WMA" => ta.wma(EMAsource, EMAlength)
    => na
EMA_ = EMAtimeframe == timeframe.period ? EMA : request.security(syminfo.ticker, EMAtimeframe, EMA[1], lookahead = barmerge.lookahead_on)
plot(EMA_, title="EMA", linewidth=2, color=blue, editable=true)

EMA_cloud_upper_band_val = EMA_ + (EMA_ * openLongEntryAbove/100)
EMA_cloud_lower_band_val = EMA_ - (EMA_ * openLongEntryAbove/100)
EMA_cloud_upper_band = plot(EMA_cloud_upper_band_val, title="EMA Cloud Upper Band", color=blue)
EMA_cloud_lower_band = plot(EMA_cloud_lower_band_val, title="EMA Cloud Upper Band", color=blue)
fill(EMA_cloud_upper_band, EMA_cloud_lower_band, editable=false, color=lightBlue)

distance_from_EMA = ((close - EMA_)/close)*100
if distance_from_EMA < 0
    distance_from_EMA := distance_from_EMA * -1

// Calulate Ladder Entries
long_ladder_1_limit_price = close - (close * 1 * ladderStep)
long_ladder_2_limit_price = close - (close * 2 * ladderStep)
long_ladder_3_limit_price = close - (close * 3 * ladderStep)
long_ladder_4_limit_price = close - (close * 4 * ladderStep)

short_ladder_1_limit_price = close + (close * 1 * ladderStep)
short_ladder_2_limit_price = close + (close * 2 * ladderStep)
short_ladder_3_limit_price = close + (close * 3 * ladderStep)
short_ladder_4_limit_price = close + (close * 4 * ladderStep)

var position_qty = strategy.equity/close
if enableLaddering
    position_qty := (strategy.equity/close) / ladderRungs
else
    position_qty := strategy.equity/close
    
plot(position_qty, color=white)
//plot(strategy.equity, color=green)

// Entry Conditions
currently_in_a_postion = strategy.position_size != 0
currently_in_a_long_postion = strategy.position_size > 0
currently_in_a_short_postion = strategy.position_size < 0
average_price = strategy.position_avg_price

bars_since_entry = currently_in_a_postion ? bar_index - strategy.opentrades.entry_bar_index(strategy.opentrades - 1) + 1 : 5
long_run_up = ta.highest(high, bar_index == 0 ? 5000: bars_since_entry)
long_run_up_line = plot(long_run_up, style=plot.style_stepline, editable=false, color=currently_in_a_long_postion ? green : transparent)
start_trailing_long_entry = currently_in_a_long_postion and long_run_up > long_start_trailing_val
long_trailing_stop = start_trailing_long_entry ? long_run_up - (long_run_up * trail_behind) : long_stop_loss
long_trailing_stop_line = plot(long_trailing_stop, style=plot.style_stepline, editable=false, color=currently_in_a_long_postion ? long_trailing_stop > strategy.position_avg_price ? green : red : transparent)

short_run_up = ta.lowest(low, bar_index == 0 ? 5000: bars_since_entry)
short_run_up_line = plot(short_run_up, style=plot.style_stepline, editable=false, color=currently_in_a_short_postion ? green : transparent)
start_trailing_short_entry = currently_in_a_short_postion and short_run_up < short_start_trailing_val
short_trailing_stop = start_trailing_short_entry ? short_run_up + (short_run_up * trail_behind) : short_stop_loss
short_trailing_stop_line = plot(short_trailing_stop, style=plot.style_stepline, editable=false, color=currently_in_a_short_postion ? short_trailing_stop < strategy.position_avg_price ? green : red : transparent)

long_conditions_met = distance_from_EMA > openLongEntryAbove and close < EMA_ and not currently_in_a_postion
short_conditions_met = distance_from_EMA > openEntryEntryAbove and close > EMA_ and not currently_in_a_postion
close_long_entries = distance_from_EMA <= closeEntryBelow or close <= long_trailing_stop
close_short_entries = distance_from_EMA <= closeEntryBelow or close >= short_trailing_stop
cancel_entries = distance_from_EMA <= cancelEntryBelow

plotshape(long_conditions_met ? close : na, style=shape.diamond, title="Long Conditions Met" )
plotshape(short_conditions_met ? close : na, style=shape.diamond, title="Short Conditions Met" )
plot(average_price,style=plot.style_stepline, editable=false, color=currently_in_a_postion ? blue : transparent)

// Long Entry
if enableLaddering
    if ladderRungs == 2
        strategy.entry(id="Long Ladder 1", direction=strategy.long, qty=position_qty, limit=long_ladder_1_limit_price, when=long_conditions_met)
        strategy.entry(id="Long Ladder 2", direction=strategy.long, qty=position_qty, limit=long_ladder_2_limit_price, when=long_conditions_met)
    else if ladderRungs == 3
        strategy.entry(id="Long Ladder 1", direction=strategy.long, qty=position_qty, limit=long_ladder_1_limit_price, when=long_conditions_met)
        strategy.entry(id="Long Ladder 2", direction=strategy.long, qty=position_qty, limit=long_ladder_2_limit_price, when=long_conditions_met)
        strategy.entry(id="Long Ladder 3", direction=strategy.long, qty=position_qty, limit=long_ladder_3_limit_price, when=long_conditions_met)
    else if ladderRungs == 4
        strategy.entry(id="Long Ladder 1", direction=strategy.long, qty=position_qty, limit=long_ladder_1_limit_price, when=long_conditions_met)
        strategy.entry(id="Long Ladder 2", direction=strategy.long, qty=position_qty, limit=long_ladder_2_limit_price, when=long_conditions_met)
        strategy.entry(id="Long Ladder 3", direction=strategy.long, qty=position_qty, limit=long_ladder_3_limit_price, when=long_conditions_met)
        strategy.entry(id="Long Ladder 4", direction=strategy.long, qty=position_qty, limit=long_ladder_4_limit_price, when=long_conditions_met)
    
    strategy.exit(id="Close Long Ladder 1", from_entry="Long Ladder 1", stop=long_trailing_stop, limit=long_trailing_stop, when=close_long_entries)
    strategy.exit(id="Close Long Ladder 2", from_entry="Long Ladder 2", stop=long_trailing_stop, limit=long_trailing_stop, when=close_long_entries)
    strategy.exit(id="Close Long Ladder 3", from_entry="Long Ladder 3", stop=long_trailing_stop, limit=long_trailing_stop, when=close_long_entries)
    strategy.exit(id="Close Long Ladder 4", from_entry="Long Ladder 4", stop=long_trailing_stop, limit=long_trailing_stop, when=close_long_entries)
    
    strategy.cancel(id="Long Ladder 1", when=cancel_entries)
    strategy.cancel(id="Long Ladder 2", when=cancel_entries)
    strategy.cancel(id="Long Ladder 3", when=cancel_entries)
    strategy.cancel(id="Long Ladder 4", when=cancel_entries)
else
    strategy.entry(id="Long", direction=strategy.long, qty=100, when=long_conditions_met)
    strategy.exit(id="Close Long", from_entry="Long", stop=long_stop_loss, limit=EMA_, when=close_long_entries)
    strategy.cancel(id="Long", when=cancel_entries)

// Short Entry
if enableLaddering
    if ladderRungs == 2
        strategy.entry(id="Short Ladder 1", direction=strategy.short, qty=position_qty, limit=short_ladder_1_limit_price, when=short_conditions_met)
        strategy.entry(id="Short Ladder 2", direction=strategy.short, qty=position_qty, limit=short_ladder_2_limit_price, when=short_conditions_met)
    else if ladderRungs == 3
        strategy.entry(id="Short Ladder 1", direction=strategy.short, qty=position_qty, limit=short_ladder_1_limit_price, when=short_conditions_met)
        strategy.entry(id="Short Ladder 2", direction=strategy.short, qty=position_qty, limit=short_ladder_2_limit_price, when=short_conditions_met)
        strategy.entry(id="Short Ladder 3", direction=strategy.short, qty=position_qty, limit=short_ladder_3_limit_price, when=short_conditions_met)
    else if ladderRungs == 4
        strategy.entry(id="Short Ladder 1", direction=strategy.short, qty=position_qty, limit=short_ladder_1_limit_price, when=short_conditions_met)
        strategy.entry(id="Short Ladder 2", direction=strategy.short, qty=position_qty, limit=short_ladder_2_limit_price, when=short_conditions_met)
        strategy.entry(id="Short Ladder 3", direction=strategy.short, qty=position_qty, limit=short_ladder_3_limit_price, when=short_conditions_met)
        strategy.entry(id="Short Ladder 4", direction=strategy.short, qty=position_qty, limit=short_ladder_4_limit_price, when=short_conditions_met)
    
    strategy.exit(id="Close Short Ladder 1", from_entry="Short Ladder 1", stop=short_trailing_stop, limit=EMA_, when=close_short_entries)
    strategy.exit(id="Close Short Ladder 2", from_entry="Short Ladder 2", stop=short_trailing_stop, limit=EMA_, when=close_short_entries)
    strategy.exit(id="Close Short Ladder 3", from_entry="Short Ladder 3", stop=short_trailing_stop, limit=EMA_, when=close_short_entries)
    strategy.exit(id="Close Short Ladder 4", from_entry="Short Ladder 4", stop=short_trailing_stop, limit=EMA_, when=close_short_entries)
    
    strategy.cancel(id="Short Ladder 1", when=cancel_entries)
    strategy.cancel(id="Short Ladder 2", when=cancel_entries)
    strategy.cancel(id="Short Ladder 3", when=cancel_entries)
    strategy.cancel(id="Short Ladder 4", when=cancel_entries)
else
    strategy.entry(id="Short", direction=strategy.short, when=short_conditions_met)
    strategy.exit(id="Close Short", from_entry="Short", limit=EMA_, when=close_short_entries)
    strategy.cancel(id="Short", when=cancel_entries)