Esta estrategia combina el Oscilador Elegante de Ehlers, el Desciclador de Ehlers, la Línea de Tendencia Instantánea de Ehlers y el Coeficiente de Correlación de Rango de Ehlers Spearman en una estrategia, formando una estrategia comercial cuantitativa que captura completamente las tendencias, oscilaciones, impulso y características de precio y volumen.
Esta estrategia utiliza 4 indicadores clave para el juicio.
En primer lugar, el Oscilador Elegante de Ehlers, donde la diferencia entre la línea original y la línea de señal suavizada por un promedio móvil exponencial puede determinar la dirección y la fuerza de la tendencia actual. En segundo lugar, el Desciclador de Ehlers, que puede identificar eficazmente los puntos bajos del ciclo y determinar si la tendencia principal se está revirtiendo. A continuación, la Línea de tendencia instantánea de Ehlers rastrea los promedios móviles rápidos para juzgar las direcciones de la tendencia a corto plazo. Por último, el Coeficiente de correlación de rango de Ehlers Spearman juzga la relación precio-volumen, que puede filtrar eficazmente las falsas rupturas.
Específicamente, las cuatro condiciones de entrada para la estrategia son: la línea de señal del Oscilador Elegante y la línea de señal del Desciclista rompiendo simultáneamente por encima de 0, la línea original rompiendo por encima de la línea del Desciclista, la línea original siendo más alta que la línea de tendencia instantánea ascendente y un coeficiente de correlación de rango de Spearman positivo.
Las condiciones de salida son mucho más simples: salir cuando la línea original cae por debajo de la línea de tendencia instantánea.
Las condiciones cortas son similares a las condiciones largas, sólo invertidas.
La mayor ventaja de esta estrategia radica en la combinación adecuada de indicadores, que pueden aprovechar eficazmente las fortalezas de cada indicador, verificarse mutuamente, evitar falsos positivos, filtrar mucho ruido y generar señales más confiables.
Específicamente, el Elegant Oscillator puede juzgar la dirección y la fuerza de la tendencia, el Decycler puede juzgar los puntos de inflexión del ciclo, la Instantaneous Trendline puede juzgar las tendencias a corto plazo y el Spearman Rank juzga la relación precio-volumen.
Además, con solo precios a medio plazo como referencia, la estrategia evita la interferencia del ruido del mercado a corto plazo y reduce las operaciones de reversión innecesarias.
El mayor riesgo de esta estrategia es la falta de un mecanismo de stop loss. En el caso de movimientos violentos del mercado, la incapacidad de detener la pérdida a tiempo puede conducir a mayores pérdidas. También carece de filtros adicionales como los canales de Donchian e indicadores de energía que pueden conducir a cierto grado de operaciones falsas positivas.
Para mitigar estos riesgos, se puede configurar un stop loss protector para detener automáticamente las pérdidas cuando las pérdidas superan ciertos niveles.
La estrategia se puede optimizar en los siguientes aspectos:
Añadir un mecanismo de gestión de riesgos para detener pérdidas.
Añadir más filtros, añadir indicadores como MACD, Bandas de Bollinger para más filtrado para reducir aún más las señales falsas.
Incorporar más marcos de tiempo. Actualmente solo se utiliza un conjunto de parámetros. Se pueden agregar más marcos de tiempo para la verificación de marcos de tiempo múltiples para mejorar la estabilidad.
Ajuste dinámico de parámetros. Añadir la optimización de parámetros para ajustar dinámicamente los parámetros de indicadores basados en las condiciones cambiantes del mercado para mejorar la adaptabilidad.
Arbitraje entre activos: aplicar estrategias en diferentes activos para buscar oportunidades de arbitraje para controlar mejor los riesgos.
Esta estrategia combina inteligentemente 4 indicadores principales de Ehlers para formar una estrategia que juzga las tendencias, ciclos, impulso y volumen de precios en todos los aspectos. Tiene excelentes capacidades de filtrado de ruido y puede producir señales de alta calidad. Pero la falta de una pérdida de parada y filtrado de indicadores auxiliares lo expone a algunos riesgos. Al agregar pérdidas de parada, filtros, más marcos de tiempo, etc., se puede optimizar eficazmente para una mayor estabilidad y fiabilidad.
/*backtest start: 2024-01-01 00:00:00 end: 2024-01-31 23:59:59 period: 2h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ // This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © simwai //@version=5 strategy('Ehlers Elegant Oscillator + Ehlers Decycler + Ehlers Instantaneous + Ehlers Spearman Rank', 'Ehlers Combo', overlay=true, margin_long=100, margin_short=100) // -- Inputs -- inp = input(title='Source', defval=close) res = input.timeframe(title='Resolution', defval='') bar = input(title='Allow Bar Color Change?', defval=true) src = inp length = input.int(title='Length', defval=20, minval=2, maxval=300) rmsLength = input.int(title='Rms Length', defval=50, minval=2) decyclerLength = length // -- Calculation -- // Ehlers Elegant Oscillator a1 = math.exp(-1.414 * math.pi / length) b1 = 2 * a1 * math.cos(1.414 * math.pi / length) c2 = b1 c3 = -a1 * a1 c1 = 1 - c2 - c3 deriv = src - nz(src[2]) rms = math.avg(math.pow(deriv, 2), rmsLength) rms := rms != 0 ? math.sqrt(rms) : 0 nDeriv = rms != 0 ? deriv / rms : 0 iFish = nDeriv != 0 ? (math.exp(2 * nDeriv) - 1) / (math.exp(2 * nDeriv) + 1) : 0 ss = 0.0 ss := bar_index < 3 ? 0 : (c1 * ((iFish + nz(iFish[1])) / 2)) + (c2 * nz(ss[1])) + (c3 * nz(ss[2])) ssSig = ta.wma(ss, length) slo = ss - ssSig sig = slo > 0 ? slo > nz(slo[1]) ? 2 : 1 : slo < 0 ? slo < nz(slo[1]) ? -2 : -1 : 0 eoColor = sig > 1 ? color.green : sig > 0 ? color.lime : sig < -1 ? color.maroon : sig < 0 ? color.red : color.black hline(0) plot(ssSig, title='EO', color=eoColor, linewidth=2) // Ehlers Decycler pi = 2 * math.asin(1) twoPiPrd = 2 * pi / decyclerLength alpha = (math.cos(twoPiPrd) + math.sin(twoPiPrd) - 1) / math.cos(twoPiPrd) dec = 0.0 dec := ((alpha / 2) * (src + nz(src[1]))) + ((1 - alpha) * nz(dec[1])) decyclerSig = src > dec ? 1 : src < dec ? -1 : 0 decColor = decyclerSig > 0 ? color.green : decyclerSig < 0 ? color.red : color.black plot(dec, title='Decycler', color=decColor, linewidth=2) // Ehlers Instantaneous Trendline getItrend(src, alpha) => Price = src Smooth = 0.0 ITrend = 0.0 Trigger = 0.0 ITrend := (alpha - alpha * alpha / 4) * Price + .5 * alpha * alpha * Price[1] - (alpha - .75 * alpha * alpha) * Price[2] + 2 * (1 - alpha) * nz(ITrend[1]) - (1 - alpha) * (1 - alpha) * nz(ITrend[2]) if(bar_index < 7) ITrend := (Price + 2 * Price[1] + Price[2]) / 4 Trigger := 2 * ITrend - ITrend[2] [ITrend, Trigger] itrendAlpha = 2 / (length + 1) / 2 [iT, Tr] = getItrend(src, itrendAlpha) iTColor = Tr > iT ? color.aqua : color.maroon plot(iT, 'Instantaneous Trend', iTColor, 2) // Ehlers Spearman Rank priceArray = array.new_float(300, 0.0) rank = array.new_float(300, 0.0) for i = 1 to length array.set(priceArray, i, nz(src[i - 1])) array.set(rank, i, i) for i = 1 to length count = length + 1 - i for j = 1 to length - count if array.get(priceArray, j + 1) < array.get(priceArray, j) tempPrice = array.get(priceArray, j) tempRank = array.get(rank, j) array.set(priceArray, j, array.get(priceArray, j + 1)) array.set(rank, j, array.get(rank, j + 1)) array.set(priceArray, j + 1, tempPrice) array.set(rank, j + 1, tempRank) sum = 0.0 for i = 1 to length sum := sum + math.pow(i - array.get(rank, i), 2) signal = 2 * (0.5 - (1 - ((6 * sum) / (length * (math.pow(length, 2) - 1))))) spearmanSlo = signal - nz(signal[1]) spearmanSig = spearmanSlo > 0 or signal > 0 ? spearmanSlo > nz(spearmanSlo[1]) ? 2 : 1 : spearmanSlo < 0 or signal < 0 ? spearmanSlo < nz(spearmanSlo[1]) ? -2 : -1 : 0 // -- Signals -- bool enterLong = ta.crossover(sig, 0) and ta.crossover(decyclerSig, 0) and ta.crossover(src, dec) and (src > iT) and iT[1] < iT and spearmanSig > 0 bool enterShort = ta.crossunder(sig, 0) and ta.crossunder(decyclerSig, 0) and ta.crossunder(src, dec) and (src < iT) and iT[1] > iT and spearmanSig < 0 bool exitLong = ta.crossunder(src[100], iT) bool exitShort = ta.crossover(src[100], iT) barcolor(bar and strategy.position_size > 0 ? color.green : bar and strategy.position_size < 0 ? color.red : color.gray) // -- Long Exits -- strategy.close('long', when=exitLong and strategy.position_size > 0, comment='EXIT_LONG') // -- Short Exits -- strategy.close('short', when=exitShort and strategy.position_size < 0, comment='EXIT_SHORT') bool isStrategyEntryEnabled = true // -- Long Entries -- if (isStrategyEntryEnabled) strategy.entry('long', strategy.long, when=enterLong, comment='ENTER_LONG') else strategy.order('long', strategy.long, when=enterLong, comment='ENTER_LONG') // -- Short Entries -- if (isStrategyEntryEnabled) strategy.entry('short', strategy.short, when=enterShort, comment='ENTER_SHORT') else strategy.order('short', strategy.short, when=enterShort, comment='ENTER_SHORT')