Estratégia de combinação de indicadores de oscilação quantitativa

Autora:ChaoZhang, Data: 2024-02-27 16:46:42
Tags:

img

Resumo

Esta estratégia combina o Oscilador Elegante de Ehlers, o Desciclador de Ehlers, a Linha de Tendência Instantânea de Ehlers e o Coeficiente de Correlação de Classe de Ehlers Spearman em uma estratégia, formando uma estratégia de negociação quantitativa que captura totalmente tendências, oscilações, impulso e características de preço e volume.

Princípios de estratégia

Esta estratégia utiliza 4 indicadores-chave para o julgamento.

Em primeiro lugar, o Oscilador Elegante Ehlers, onde a diferença entre a linha original e a linha de sinal suavizada por uma média móvel exponencial pode determinar a direção e a força da tendência atual. Em segundo lugar, o Desciclador Ehlers, que pode identificar efetivamente os pontos baixos do ciclo e determinar se a tendência principal está se revertendo. Em seguida, a Linha de Tendência Instantânea Ehlers rastreia médias móveis rápidas para julgar as direções da tendência de curto prazo. Finalmente, o Coeficiente de Correlação de Classe Ehlers Spearman julga a relação preço-volume, que pode filtrar efetivamente falhas.

Especificamente, as quatro condições de entrada para a estratégia são: a linha de sinal do Oscilador Elegante e a linha de sinal do Desciclador quebrando simultaneamente acima de 0; a linha original quebrando acima da linha do Desciclador; a linha original sendo superior à linha de tendência instantânea crescente; e um Coeficiente de correlação de classificação de Spearman positivo.

As condições de saída são muito mais simples: sair quando a linha original cair abaixo da linha de tendência instantânea.

As condições curtas são semelhantes às condições longas, só que invertidas.

Análise das vantagens

A maior vantagem desta estratégia reside na combinação adequada de indicadores, que podem aproveitar eficazmente os pontos fortes de cada indicador, verificar-se mutuamente, evitar falsos positivos, filtrar muito ruído e gerar sinais mais fiáveis.

Especificamente, o Elegant Oscillator pode julgar a direção e a força da tendência, o Decycler pode julgar pontos de virada do ciclo, a Instantaneous Trendline pode julgar tendências de curto prazo e o Spearman Rank julga a relação preço-volume.

Além disso, com apenas preços de médio prazo como referência, a estratégia evita interferências do ruído do mercado a curto prazo e reduz as negociações de reversão desnecessárias.

Análise de riscos

O maior risco desta estratégia é a falta de um mecanismo de stop loss. No caso de movimentos violentos do mercado, a incapacidade de parar a perda a tempo pode levar a perdas maiores.

Para mitigar esses riscos, um stop loss de proteção pode ser definido para parar automaticamente a perda quando as perdas excedem certos níveis.

Orientações de otimização

A estratégia pode ser otimizada nos seguintes aspectos:

  1. Adicionar um mecanismo de gestão de risco de stop loss. Calcular a retirada histórica máxima para definir os níveis de stop loss adequados.

  2. Adicionar mais filtros, adicionar indicadores como MACD, Bollinger Bands para mais filtragem para reduzir ainda mais os falsos sinais.

  3. Incorporar mais intervalos de tempo. Atualmente, apenas um conjunto de parâmetros é usado. Mais intervalos de tempo podem ser adicionados para verificação de vários intervalos de tempo para melhorar a estabilidade.

  4. Ajuste dinâmico de parâmetros. Adicionar otimização de parâmetros para ajustar dinamicamente os parâmetros do indicador com base nas condições de mercado em mudança para melhorar a adaptabilidade.

  5. Arbitragem de ativos cruzados: aplicar estratégias em diferentes ativos para procurar oportunidades de arbitragem para controlar melhor os riscos.

Conclusão

Esta estratégia combina habilmente 4 principais indicadores de Ehlers para formar uma estratégia que julga tendências, ciclos, impulso e volume de preço em todos os aspectos. Ele tem capacidades de filtragem de ruído excelentes e pode produzir sinais de alta qualidade. Mas a falta de uma perda de parada e filtragem de indicador auxiliar expõe-o a alguns riscos. Adicionando perdas de parada, filtros, mais prazos, etc., pode ser efetivamente otimizado para maior estabilidade e confiabilidade.


/*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')



Mais.