Estrategia de inversión de la media móvil doble

El autor:¿ Qué pasa?, Fecha: 2023-12-25 13:24:14
Las etiquetas:

img

Resumen general

La estrategia de inversión de promedios móviles dobles es una estrategia de negociación cuantitativa que utiliza promedios móviles dobles para identificar tendencias a corto y largo plazo. La estrategia combina el promedio móvil simple de 10 días (SMA) y el SMA de 200 días para capitalizar los retrocesos a corto plazo dentro de una tendencia alcista a largo plazo subyacente.

Estrategia lógica

La estrategia de inversión de la media móvil doble se basa en los siguientes supuestos:

  1. La SMA de 200 días identifica la tendencia a largo plazo del mercado. Cuando el precio está por encima de la línea de 200 días, indica que el mercado está en una tendencia alcista a largo plazo.

  2. La SMA de 10 días señala retrocesos a corto plazo en el precio.

  3. En una tendencia alcista en curso, cualquier retroceso a corto plazo puede considerarse como una oportunidad de compra para atrapar eficientemente el repunte al alza.

En base a las suposiciones anteriores, las señales comerciales se generan de la siguiente manera:

  1. Cuando el precio de cierre cruza por encima de la SMA de 200 días y simultáneamente cruza por debajo de la SMA de 10 días, activa una señal de compra, ya que muestra que la tendencia a largo plazo sigue siendo positiva pero se ha producido un retroceso a corto plazo.

  2. Si el precio rebota por encima de la SMA de 10 días cuando está en una posición larga, la tendencia a corto plazo se ha invertido por lo que la posición se cerrará inmediatamente.

  3. Siempre que se produce una recesión importante (que excede un umbral predefinido), presenta una oportunidad para comprar la caída como una señal contraria.

Con este diseño, la estrategia tiene como objetivo capitalizar de manera eficiente los retrocesiones al alza durante tendencias alcistas sostenidas, controlando el riesgo mediante el uso de pérdidas de parada.

Ventajas

La estrategia de inversión de la media móvil doble tiene estas ventajas clave:

  1. La lógica de la estrategia es sencilla y fácil de entender.
  2. Los dos filtros de media móvil identifican eficazmente las tendencias a corto y largo plazo.
  3. Ofrece una buena eficiencia temporal al capitalizar las reversiones a corto plazo.
  4. El mecanismo de stop loss incorporado controla estrictamente el riesgo de las posiciones individuales.
  5. La parametrización flexible hace que esta estrategia sea ampliamente aplicable a índices y acciones.

Los riesgos

Aunque es eficaz en general, la estrategia tiene estas limitaciones:

  1. La estrategia debe desactivarse durante consolidaciones extendidas.
  2. La dependencia únicamente de las medias móviles tiene limitaciones de precisión de la señal.
  3. La metodología de stop loss fijo carece de flexibilidad.
  4. Los parámetros óptimos deben calibrarse para diferentes mercados.

Oportunidades de mejora

Entre las mejoras adicionales a esta estrategia se incluyen:

  1. Prueba de otras longitudes de media móvil para encontrar la combinación óptima.
  2. Añadir indicadores de apoyo para generar señales más fiables, por ejemplo, volumen, métricas de volatilidad.
  3. Explorando otras técnicas de stop loss como el trailing stop loss, stop loss basado en el tiempo.
  4. Construir capacidades de adaptación en las reglas de entrada y los parámetros de stop loss que permitan el ajuste a la dinámica cambiante del mercado.
  5. Incorporar algoritmos de aprendizaje automático para optimizar aún más los parámetros aprovechando más datos históricos.

Conclusión

En resumen, la Estrategia de reversión de promedios móviles dobles es un enfoque muy práctico. Permite un desvanecimiento de retroceso rentable durante tendencias alcistas sostenidas utilizando el análisis de promedios móviles combinado con pérdidas de parada. También ofrece capacidades de detección de régimen de mercado y control de riesgos. Con una mejora continua, la estrategia ofrece un fuerte potencial para ofrecer un rendimiento diferenciado.


/*backtest
start: 2023-11-24 00:00:00
end: 2023-12-24 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/
// © Gold_D_Roger
//note: spreading 1 statement over multiple lines needs 1 apce + 1 tab | multi line function is 1 tab
//Recommended tickers: SPY (D), QQQ (D) and big indexes, AAPL (4H)

//@version=5
strategy("Davin's 10/200MA Pullback on SPY Strategy v2.0",
     overlay=true,
     initial_capital=10000,
     default_qty_type=strategy.percent_of_equity,
     default_qty_value=10, // 10% of equity on each trade
     commission_type=strategy.commission.cash_per_contract, 
     commission_value=0.1) //Insert your broker's rate, IB is 0.005USD or tiered

//Best parameters
// SPY D
// Stop loss 0.15
// commission of 0.005 USD using Interactive brokers
// Exit on lower close 
// Buy more when x% down --> 14%
// DO NOT include stop condition using MA crossover

// Get User Input
i_ma1           = input.int(title="MA Length 1", defval=200, step=10, group="Strategy Parameters", tooltip="Long-term MA 200")
i_ma2           = input.int(title="MA Length 2", defval=10, step=10, group="Strategy Parameters", tooltip="Short-term MA 10")
i_ma3           = input.int(title="MA Length 3", defval=50, step=1, group="Strategy Parameters", tooltip="MA for crossover signals`")
i_stopPercent   = input.float(title="Stop Loss Percent", defval=0.15, step=0.01, group="Strategy Parameters", tooltip="Hard stop loss of 10%")
i_startTime     = input(title="Start filter", defval=timestamp("01 Jan 2013 13:30 +0000"), group="Time filter", tooltip="Start date and time to begin")
i_endTime       = input(title="End filter", defval=timestamp("01 Jan 2099 19:30 +0000"), group="Time filter", tooltip="End date and time to stop")
i_lowerClose    = input.bool(title="Exit on lower close", defval=true, group="Strategy Parameters", tooltip="Wait for lower close after above 10SMA before exiting") // optimise exit strat, boolean type creates tickbox type inputs
i_contrarianBuyTheDip = input.bool(title="Buy whenever more than x% drawdown", defval=true, group="Strategy Parameters", tooltip="Buy the dip! Whenever x% or more drawdown on SPY")
i_contrarianTrigger = input.int(title="Trigger % drop to buy the dip", defval=14, step=1, group="Strategy Parameters", tooltip="% drop to trigger contrarian Buy the Dip!") 
//14% to be best for SPY 1D
//20% best for AMZN 1D
i_stopByCrossover_MA2_3 = input.bool(title="Include stop condition using MA crossover", defval=false, group="Strategy Parameters", tooltip="Sell when crossover of MA2/1 happens")

// Get indicator values
ma1 = ta.sma(close,i_ma1) //param 1
ma2 = ta.sma(close,i_ma2) //param 2
ma3 = ta.sma(close,i_ma3) //param 3
ma_9 = ta.ema(close,9) //param 2
ma_20 = ta.ema(close,20) //param 3

// Check filter(s)
f_dateFilter = true //make sure date entries are within acceptable range

// Highest price of the prev 52 days: https://www.tradingcode.net/tradingview/largest-maximum-value/#:~:text=()%20versus%20ta.-,highest(),max()%20and%20ta.
highest52 = ta.highest(high,52)
overall_change = ((highest52 - close[0]) / highest52) * 100

// Check buy/sell conditions
var float buyPrice = 0 //intialise buyPrice, this will change when we enter a trade ; float = decimal number data type 0.0
buyCondition  = (close > ma1 and close < ma2 and strategy.position_size == 0 and f_dateFilter) or (strategy.position_size == 0 and i_contrarianBuyTheDip==true and overall_change > i_contrarianTrigger and f_dateFilter) // higher than 200sma, lower than short term ma (pullback) + avoid pyramiding positions
sellCondition = close > ma2 and strategy.position_size > 0 and (not i_lowerClose or close < low[1])  //check if we already in trade + close above 10MA; 
// third condition: EITHER i_lowerClose not turned on OR closing price has to be < previous candle's LOW [1]

stopDistance  = strategy.position_size > 0 ? ((buyPrice - close)/close) : na // check if in trade > calc % drop dist from entry, if not na
stopPrice     = strategy.position_size > 0 ? (buyPrice - (buyPrice * i_stopPercent)) : na // calc SL price if in trade, if not, na
stopCondition = (strategy.position_size > 0 and stopDistance > i_stopPercent) or (strategy.position_size > 0 and (i_stopByCrossover_MA2_3==true and ma3 < ma1))


// Enter positions
if buyCondition 
    strategy.entry(id="Long", direction=strategy.long) //long only

    
if buyCondition[1] // if buyCondition is true prev candle
    buyPrice := open // entry price = current bar opening price

// Exit position
if sellCondition or stopCondition 
    strategy.close(id="Long", comment = "Exit" + (stopCondition ? "Stop loss=true" : "")) // if condition? "Value for true" : "value for false"
    buyPrice := na //reset buyPrice

// Plot
plot(buyPrice, color=color.lime, style=plot.style_linebr)
plot(stopPrice, color=color.red, style=plot.style_linebr, offset = -1)
plot(ma1, color=color.blue) //defval=200
plot(ma2, color=color.white) //defval=10
plot(ma3, color=color.yellow) // defval=50






Más.