Estrategia de negociación algorítmica del patrón de ruptura y engulfamiento de impulso

El autor:¿ Qué pasa?, Fecha: 2024-01-30 17:20:59
Las etiquetas:

img

Resumen general

Este artículo presenta una estrategia de negociación algorítmica que identifica oportunidades rentables a través de patrones de engulfing y utiliza el cruce de precios con promedio móvil como señales de entrada. Combinando el análisis técnico con métodos de seguimiento de tendencias, esta estrategia tiene como objetivo obtener ganancias en puntos de consolidación e inversión de tendencias.

Principios

La lógica central de esta estrategia se basa en la convergencia de dos indicadores no relacionados:

  1. Patrón de engulfing: Un patrón de inversión de dos candelabros en el que el cuerpo de la segunda vela engloba completamente el cuerpo de la primera, utilizado para identificar oportunidades de inversión.

  2. Cruce de precios con promedio móvil: Una señal de compra se genera cuando el precio cruza por encima de la línea promedio móvil desde abajo; Una señal de venta es cuando el precio cruza por debajo de la línea promedio móvil desde arriba.

Al juzgar el momento de la posible inversión del mercado con patrones de engulfamiento y al utilizar el cruce de precios con la media móvil como señales de confirmación, se puede mejorar la probabilidad de obtener ganancias.

Específicamente, esta estrategia rastrea tres tipos de patrones de engulfamiento: alcista, bajista y sin engulfamiento de sombra para determinar posibles consolidaciones e inversiones.

Ventajas

La mayor ventaja de esta estrategia es utilizar la convergencia de indicadores no relacionados para mejorar la eficacia de la decisión. Los patrones de engulfing juzgan el momento y la probabilidad de la inversión del mercado; mientras que el cruce de precios con el promedio móvil verifica la dirección y el impulso de la inversión. Los dos se validan mutuamente y pueden reducir eficazmente las pérdidas comerciales causadas por señales falsas.

Otra ventaja es la flexibilidad de la configuración de parámetros. Los usuarios pueden establecer parámetros como el período promedio móvil y el rango de stop loss para optimizar la estrategia ellos mismos.

Los riesgos

Aunque el uso de múltiples indicadores mejora el juicio, todavía hay algunos riesgos de señales falsas en esta estrategia. Los patrones de engulfing no son señales de reversión 100% confiables, y también existen escenarios de fracaso en el cruce de precios con el promedio móvil. Todos estos pueden conducir a pérdidas por posiciones de apertura prematura.

Además, al igual que la mayoría de las estrategias de análisis técnico, también se desempeña mal en mercados de tendencias conflictivas como el rango y la consolidación.

Para controlar los riesgos, se pueden ajustar en consecuencia parámetros como el período promedio móvil y el rango de stop loss.

Direcciones de optimización

Las siguientes áreas pueden optimizarse para esta estrategia:

  1. Pruebe más tipos de promedio móvil para encontrar conjuntos óptimos de parámetros, como promedio móvil ponderado, promedio móvil doble suavizado, etc.

  2. Añadir indicadores de tendencia para evitar la apertura de posiciones en los mercados laterales.

  3. Optimice los métodos de stop loss para mejorar la eficacia.

  4. Aumentar los métodos de aprendizaje automático para juzgar los patrones de velas y mejorar la precisión del reconocimiento de engulfing.

  5. Añadir funciones de optimización de parámetros para el ajuste adaptativo.

Conclusión

Esta estrategia identifica el tiempo de reversión con patrones de engulfing y verifica la dirección utilizando el cruce de precios con el promedio móvil. Al mejorar la eficacia de la decisión a través de la convergencia de indicadores, es un enfoque de análisis técnico. Las ventajas incluyen indicadores complementarios y parámetros flexibles. Las desventajas son los riesgos de señales falsas y debilidad en los mercados laterales.


/*backtest
start: 2023-12-30 00:00:00
end: 2024-01-29 00:00:00
period: 3h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
//@author=Daveatt

StrategyName = "BEST Engulfing + MA"
ShortStrategyName = "BEST Engulfing + MA"

strategy(title=StrategyName, shorttitle=ShortStrategyName, overlay=true)

includeEngulfing = true

includeMA = true
source_ma = input(title="Source Price vs MA", type=input.source, defval=close)
typeofMA = input(title="Type of MA", defval="SMA", options=["RMA", "SMA", "EMA", "WMA", "VWMA", "SMMA", "KMA", "TMA", "HullMA", "DEMA", "TEMA"])
length_ma = input(32, title = "MA Length", type=input.integer)

// ---------- Candle components and states
GreenCandle = close > open
RedCandle = close < open
NoBody = close==open
Body = abs(close-open)


// bullish conditions
isBullishEngulfing1 = max(close[1],open[1]) < max(close,open) and min(close[1],open[1]) > min(close,open) and Body > Body[1] and GreenCandle and RedCandle[1]
isBullishEngulfing2 = max(close[1],open[1]) < max(close,open) and min(close[1],open[1]) <= min(close,open) and Body > Body[1] and GreenCandle and RedCandle[1]

// bearish conditions
isBearishEngulfing1 = max(close[1],open[1]) < max(close,open) and min(close[1],open[1]) > min(close,open) and Body > Body[1] and RedCandle and GreenCandle[1]
isBearishEngulfing2 = max(close[1],open[1]) >= max(close,open) and min(close[1],open[1]) > min(close,open) and Body > Body[1] and RedCandle and GreenCandle[1]

// consolidation of conditions
isBullishEngulfing = isBullishEngulfing1 or isBullishEngulfing2
isBearishEngulfing = isBearishEngulfing1 or isBearishEngulfing2

//isBullishEngulfing = max(close[1],open[1]) < max(close,open) and min(close[1],open[1]) > min(close,open) and Body > Body[1] and GreenCandle and RedCandle[1]
//isBearishEngulfing = max(close[1],open[1]) < max(close,open) and min(close[1],open[1]) > min(close,open) and Body > Body[1] and RedCandle and GreenCandle[1]

Engulf_curr = 0 - barssince(isBearishEngulfing) + barssince(isBullishEngulfing)
Engulf_Buy = Engulf_curr < 0 ? 1 : 0
Engulf_Sell = Engulf_curr > 0 ? 1 : 0


// Price vs MM


smma(src, len) =>
    smma = 0.0
    smma := na(smma[1]) ? sma(src, len) : (smma[1] * (len - 1) + src) / len
    smma

ma(smoothing, src, length) => 
    if smoothing == "RMA"
        rma(src, length)
    else
        if smoothing == "SMA"
            sma(src, length)
        else 
            if smoothing == "EMA"
                ema(src, length)
            else 
                if smoothing == "WMA"
                    wma(src, length)
				else
					if smoothing == "VWMA"
						vwma(src, length)
					else
						if smoothing == "SMMA"
						    smma(src, length)
						else
							if smoothing == "HullMA"
								wma(2 * wma(src, length / 2) - wma(src, length), round(sqrt(length)))
							else
								if smoothing == "LSMA"
									src
								else
								    if smoothing == "KMA"
								        xPrice = src
                                        xvnoise = abs(xPrice - xPrice[1])
                                        nfastend = 0.666
                                        nslowend = 0.0645
                                        nsignal = abs(xPrice - xPrice[length])
                                        nnoise = sum(xvnoise, length)
                                        nefratio = iff(nnoise != 0, nsignal / nnoise, 0)
                                        nsmooth = pow(nefratio * (nfastend - nslowend) + nslowend, 2) 
                                        nAMA = 0.0
                                        nAMA := nz(nAMA[1]) + nsmooth * (xPrice - nz(nAMA[1]))
                                        nAMA
								    else
								        if smoothing == "TMA"
									        sma(sma(close, length), length)
						                else
							                if smoothing == "DEMA"
							                    2 * src - ema(src, length)
							                else
							                    if smoothing == "TEMA"
							                        3 * (src - ema(src, length)) + ema(ema(src, length), length) 
							                    else
		    							            src
		    							                

MA = ma(typeofMA, source_ma, length_ma)

plot(MA, color=#006400FF, title="MA breakout", linewidth=3)

macrossover  = crossover (source_ma, MA)
macrossunder = crossunder(source_ma, MA)

since_ma_buy = barssince(macrossover)
since_ma_sell = barssince(macrossunder)
macross_curr = 0 - since_ma_sell + since_ma_buy
bullish_MA_cond = macross_curr < 0 ?  1 : 0
bearish_MA_cond = macross_curr > 0 ? 1  : 0

posUp = (Engulf_Buy ? 1 : 0) + (bullish_MA_cond ? 1 : 0) 
posDn = (Engulf_Sell ? 1 : 0) + (bearish_MA_cond ? 1 : 0) 

conditionUP = posUp == 2 and posUp[1] < 2
conditionDN = posDn == 2 and posDn[1] < 2


sinceUP = barssince(conditionUP)
sinceDN = barssince(conditionDN)

// primary-first signal of the trend
nUP = crossunder(sinceUP,sinceDN)
nDN = crossover(sinceUP,sinceDN)


// and the following secondary signals

// save of the primary signal
sinceNUP = barssince(nUP)
sinceNDN = barssince(nDN)

buy_trend   = sinceNDN > sinceNUP
sell_trend  = sinceNDN < sinceNUP

// engulfing by
barcolor(nUP ? color.orange : na, title="Bullish condition")
barcolor(nDN ? color.yellow : na, title="Bearish condition")

isLong  = nUP
isShort = nDN

long_entry_price    = valuewhen(nUP, close, 0)
short_entry_price   = valuewhen(nDN, close, 0)

longClose   = close[1] < MA
shortClose  = close[1] > MA

///////////////////////////////////////////////
//* Backtesting Period Selector | Component *//
///////////////////////////////////////////////


StartYear = input(2017, "Backtest Start Year",minval=1980)
StartMonth = input(1, "Backtest Start Month",minval=1,maxval=12)
StartDay = input(1, "Backtest Start Day",minval=1,maxval=31)
testPeriodStart = timestamp(StartYear,StartMonth,StartDay,0,0)

StopYear = input(2020, "Backtest Stop Year",minval=1980)
StopMonth = input(12, "Backtest Stop Month",minval=1,maxval=12)
StopDay = input(31, "Backtest Stop Day",minval=1,maxval=31)
testPeriodStop = timestamp(StopYear,StopMonth,StopDay,0,0)

testPeriod() => true


//////////////////////////
//* Profit Component *//
//////////////////////////

input_tp_pips = input(600, "Backtest Profit Goal (in USD)",minval=0)
input_sl_pips = input(300, "Backtest STOP Goal (in USD)",minval=0)


tp = buy_trend? long_entry_price + input_tp_pips : short_entry_price - input_tp_pips
sl = buy_trend? long_entry_price - input_sl_pips : short_entry_price + input_sl_pips


long_TP_exit  = buy_trend and high >= tp
short_TP_exit = sell_trend and low <= tp

plot(tp, title="TP", style=plot.style_circles, linewidth=3, color=color.blue)
plot(sl, title="SL", style=plot.style_circles, linewidth=3, color=color.red)

if testPeriod()
    strategy.entry("Long", 1, when=isLong)
    strategy.close("Long", when=longClose )
    strategy.exit("XL","Long", limit=tp,  when=buy_trend, stop=sl)


if testPeriod()
    strategy.entry("Short", 0,  when=isShort)
    strategy.close("Short", when=shortClose )
    strategy.exit("XS","Short", when=sell_trend, limit=tp, stop=sl)


Más.