
Este artículo presenta una estrategia de negociación algorítmica que identifica oportunidades de ganancias y el cruce de precios con la media móvil como señal de entrada. La estrategia combina análisis técnico de precios y métodos de seguimiento de tendencias para obtener ganancias de balanceo y reversión de tendencias.
La lógica central de la estrategia se basa en la fusión de dos indicadores no relacionados:
Formato de engullición: un patrón de reversión de dos líneas K, en el que la entidad de la segunda línea K engulle completamente a la entidad de la primera línea K, para identificar la oportunidad de reversión.
El precio cruza con la media móvil: genera una señal de compra cuando el precio se cruza hacia arriba desde la media móvil por debajo de la media móvil; genera una señal de venta cuando el precio se cruza hacia abajo desde la media móvil por encima de la media móvil.
Al determinar el momento en que el mercado podría revertirse a través de la absorción de formas, se puede aumentar la probabilidad de obtener ganancias, combinando el cruce del precio con la media móvil como una señal de filtro para determinar la reversión.
En concreto, la estrategia determina la probabilidad de corrección y reversión mediante el seguimiento de tres formas de absorción: absorción múltiple, absorción sin cabeza y absorción sin sombra. La estrategia se combina con el filtro de señales de forks dorados y muertos de los precios y las medias móviles para decidir la dirección de la posición.
La mayor ventaja de esta estrategia es que utiliza la combinación de indicadores no relevantes para mejorar la eficacia de la toma de decisiones. El patrón de absorción determina el momento y la probabilidad de una reversión del mercado; y el precio se cruza con la media móvil para verificar la dirección y la intensidad de la reversión. Ambos se verifican mutuamente y pueden reducir eficazmente las pérdidas de operaciones causadas por falsas señales.
Otra ventaja es la flexibilidad en la configuración de los parámetros. El usuario puede configurar por sí mismo los parámetros como el ciclo de la media móvil, el stop loss, etc., para optimizar la estrategia.
A pesar de la utilización de varios indicadores para mejorar la eficacia del juicio, la estrategia sigue teniendo un cierto riesgo de señales falsas. La forma de la absorción no es una señal de inversión confiable al cien por cien, y la cruz de los precios con las medias móviles también puede ser ineficaz.
Además, al igual que la mayoría de las estrategias de análisis técnico, la estrategia también tiene una mala eficacia en el mercado en situaciones de conflicto, como las fluctuaciones de precios. Las fluctuaciones continuas pueden desencadenar un stop loss o acortar el margen de ganancias.
Para controlar el riesgo, se puede ajustar adecuadamente el parámetro de la media móvil para optimizar el stop loss. También se puede considerar la participación de la estrategia de ajuste dinámico en combinación con otros indicadores para identificar tendencias y situaciones de crisis.
La estrategia se puede optimizar en los siguientes aspectos:
Prueba más tipos de promedios móviles para encontrar la combinación de parámetros óptima. Por ejemplo, promedios móviles ponderados, promedios móviles que se suavizan sucesivamente.
Aumentar los indicadores de tendencia para evitar posiciones en el mercado de la oscilación. Por ejemplo, ADX, Bollinger Bands, etc.
Optimización de los métodos de detención de pérdidas para mejorar el efecto de la detención de pérdidas. Se pueden considerar estrategias de detención de pérdidas como el seguimiento de las detenciones y la salida de Chandelier.
Aumentar el método de aprendizaje automático para determinar la forma de la línea K y mejorar la precisión de la identificación de tracción.
Se añade la función de optimización automática de parámetros para la adaptación de los mismos.
Esta estrategia utiliza el momento de reversión para evaluar la forma de absorción y la dirección de reversión para verificar la dirección de reversión cruzando el precio con la media móvil. Para mejorar la eficacia de la decisión a través de la fusión de indicadores, es una estrategia de análisis técnico. La ventaja es que los indicadores son complementarios y los parámetros son flexibles; La desventaja es que todavía hay riesgo de señales falsas y es débil para las condiciones de oscilación.
/*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)