Estratégia de combinação baseada em indicadores osciladores quantitativos


Data de criação: 2024-02-27 16:46:42 última modificação: 2024-02-27 16:46:42
cópia: 3 Cliques: 653
1
focar em
1617
Seguidores

Estratégia de combinação baseada em indicadores osciladores quantitativos

Visão geral

Esta estratégia combina o Enles Elastic Vibration Indicator, o Enles Cycle Indicator, o Enles Instantaneous Trend Line, e o Enles Spielman Level Related Coefficient Indicator para formar uma estratégia de negociação quantitativa que capta a tendência, oscilação, a dinâmica e as características do preço. A estratégia é chamada de estratégia de conjunto de indicadores de vibração quantitativa.

Princípio da estratégia

Esta estratégia é baseada em quatro indicadores-chave:

Em primeiro lugar, o Elastic Vibration Index, que recebe uma linha de sinal depois de suavizar a média do índice, com o diferencial da linha original, pode determinar a direção e a intensidade da tendência atual. Em segundo lugar, o Elastic Cycle Index, que identifica efetivamente os pontos baixos do ciclo e determina se a tendência principal está sendo revertida.

Especificamente, as quatro condições de entrada da estratégia são: a linha de sinal do indicador de vibração elegante e a linha de sinal do indicador de ciclo atravessam simultaneamente para cima; a linha original atravessa a linha de ciclo para cima; a linha original está acima da linha de tendência instantânea ascendente; o coeficiente de correlação do grau de Spielman é positivo.

A saída é muito mais simples, apenas quando a linha original atravessa a linha de tendência instantânea.

A condição de “fazer” é semelhante à condição de “fazer mais”, apenas que a condição de “julgar” pode ser invertida.

Análise de vantagens

A maior vantagem desta estratégia reside no fato de que o conjunto de indicadores é adequado, e pode efetivamente aproveitar as vantagens de cada indicador, verificar-se mutuamente, evitar falsos positivos, filtrando assim um grande número de ruídos e tornando o sinal mais confiável.

Concretamente, o indicador de vibração elegante pode determinar a direção e a intensidade da tendência, o indicador de ciclo pode determinar o ponto de viragem do ciclo, a linha de tendência momentânea pode determinar a tendência de curto prazo, o coeficiente de correlação do nível de Spielman pode determinar a relação de preço. A combinação dos quatro pode avaliar completamente as características do mercado em termos de tendência, ciclo, volume e preço, resultando em um sinal de negociação altamente confiável.

Além disso, a estratégia só tem como referência a linha média, evitando a interferência do ruído do mercado a curto prazo, reduzindo o retorno desnecessário. Ao mesmo tempo, os sinais da estratégia são escassos e as regras de saída são simples, reduzindo significativamente a frequência de negociação e evitando o problema da sobre-negociação.

Análise de Riscos

O maior risco desta estratégia reside na falta de um mecanismo de parada de perdas. A falta de uma parada de perdas em tempo hábil pode levar à expansão dos prejuízos quando o mercado muda drasticamente. Além disso, a falta de filtros adicionais, como o filtro do sistema marginal e o indicador de energia, pode levar a um certo grau de falsos positivos nas negociações.

Para minimizar esses riscos, pode-se definir um ponto de parada de emergência, que é automaticamente interrompido quando os prejuízos excedem uma certa proporção. Além disso, pode-se adicionar um indicador de volume dinâmico, como o MACD, para uma segunda verificação, evitando o risco de falso rompimento.

Direção de otimização

A estratégia pode ser melhorada nos seguintes aspectos:

  1. Adicionar um mecanismo de parada de risco. Calcular a retirada máxima com base em dados de retrospectiva histórica e definir o ponto de parada correspondente.

  2. Adição de filtros. Adição de MACD, Brinks e outros indicadores para filtragem em várias camadas, reduzindo ainda mais os sinais falsos.

  3. Combinando mais períodos de tempo. Atualmente, há apenas um conjunto de parâmetros, mas é possível introduzir mais períodos de tempo, usando o método de validação de vários eixos de tempo, para melhorar a estabilidade.

  4. Parâmetros de ajuste dinâmico. O módulo de otimização de parâmetros foi adicionado para ajustar dinamicamente os parâmetros do indicador de acordo com as diferentes condições do mercado, tornando a estratégia mais adaptável.

  5. Arbitragem multi-variedade. Aplicar estratégias para diferentes variedades para encontrar oportunidades de arbitragem e controlar ainda mais o risco.

Resumir

Esta estratégia usa uma combinação inteligente dos quatro principais indicadores de Enel para formar uma estratégia de negociação abrangente para avaliar tendências, ciclos, momentum e preço. Sua capacidade de filtrar o ruído é excelente e pode produzir um sinal de alta qualidade.

Código-fonte da estratégia
/*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')