양적 오스실레이션 지표 조합 전략

저자:차오장, 날짜: 2024-02-27 16:46:42
태그:

img

전반적인 설명

이 전략은 Ehlers Elegant Oscillator, Ehlers Decycler, Ehlers Instantaneous Trendline 및 Ehlers Spearman Rank Correlation Coefficient를 하나의 전략으로 결합하여 트렌드, 오스실레이션, 모멘텀 및 가격 및 볼륨 특성을 완전히 포착하는 양적 거래 전략을 형성합니다. 전략 이름은 Quantitative Oscillation Indicator Combination Strategy입니다.

전략 원칙

이 전략은 판단을 위해 4가지 주요 지표를 사용합니다.

먼저, 에일러스 우아한 오시일레이터 (Ehlers Elegant Oscillator), 즉 기하급수적인 이동 평균에 의해 평평화된 원래 라인과 신호 라인의 차이는 현재 트렌드 방향과 강도를 결정할 수 있다. 둘째, 에일러스 디사이클러 (Ehlers Decycler), 즉 주기의 낮은 지점을 효과적으로 식별하고 주요 트렌드가 역전되는지를 결정할 수 있다. 다음으로, 에일러스 즉각적인 트렌드 라인은 단기 트렌드 방향을 판단하기 위해 빠른 이동 평균을 추적한다. 마지막으로, 에일러스 스피어먼 순위 상관 계수는 잘못된 브레이크오트를 효과적으로 필터할 수 있는 가격-용량 관계를 판단한다.

구체적으로, 전략의 네 가지 입시 조건은: 우아한 오시레이터 신호 라인과 디사이클러 신호 라인이 동시에 0을 넘기며; 원래 라인이 디사이클러 라인을 넘기며; 원래 라인이 상승하는 즉각적인 트렌드 라인보다 높으며; 긍정적 인 스피어만 순위 상관률.

출구 조건은 훨씬 간단합니다. 원래 라인이 즉각적인 트렌드 라인 아래에 떨어지면 출구입니다.

짧은 조건은 긴 조건과 비슷하지만, 역전된 조건입니다.

이점 분석

이 전략의 가장 큰 장점은 각 지표의 강점을 효과적으로 활용하고 상호 검증하고 거짓 긍정적 인 결과를 피하고 많은 잡음을 필터링하고 더 신뢰할 수있는 신호를 생성 할 수있는 적절한 지표 조합에 있습니다.

특히, 우아한 오시레이터는 트렌드 방향과 강도를 판단할 수 있으며, 디사이클러는 사이클 전환점을 판단할 수 있으며, 즉각적인 트렌드 라인은 단기 트렌드를 판단할 수 있으며, 스피어맨 랭크는 가격-용량 관계를 판단할 수 있습니다. 네 가지의 조합은 트렌드, 사이클, 추진력 및 가격-용량 측면에서 시장 특성을 포괄적으로 판단하여 매우 신뢰할 수있는 거래 신호를 생산할 수 있습니다.

또한, 중장기 가격만을 기준으로 하는 이 전략은 단기 시장 소음의 간섭을 피하고 불필요한 반전 거래를 줄인다. 또한, 희박한 신호와 간단한 출구 규칙으로 거래 빈도를 크게 줄여 과도한 거래 문제를 피할 수 있다.

위험 분석

이 전략의 가장 큰 위험은 스톱 로스 메커니즘의 부족입니다. 폭력적인 시장 움직임의 경우, 시간적으로 손실을 멈추지 못하는 것은 더 큰 손실로 이어질 수 있습니다. 또한 도 채널과 에너지 지표와 같은 추가 필터가 부족하여 어느 정도 잘못된 긍정적 거래로 이어질 수 있습니다.

이러한 위험을 완화하기 위해, 손실이 특정 수준을 초과할 때 자동으로 손실을 중지하도록 보호 스톱 로스를 설정할 수 있습니다. 또한, MACD와 같은 지표는 잘못된 브레이크의 위험을 피하기 위해 2차 확인을 위해 추가 될 수 있습니다.

최적화 방향

이 전략은 다음과 같은 측면에서 최적화 될 수 있습니다.

  1. 리스크 관리 스톱 로스 메커니즘을 추가합니다. 적절한 스톱 로스 수준을 설정하기 위해 최대 역사 마감량을 계산합니다.

  2. 더 많은 필터를 추가합니다. MACD, 볼링거 밴드 같은 지표를 추가하여 더 많은 필터를 추가하여 잘못된 신호를 감소시킵니다.

  3. 더 많은 시간 프레임을 포함. 현재 하나의 세트 매개 변수만 사용됩니다. 안정성을 향상시키기 위해 멀티 타임 프레임 검증을 위해 더 많은 시간 프레임을 추가 할 수 있습니다.

  4. 동적으로 매개 변수를 조정합니다. 적응력을 향상시키기 위해 변화하는 시장 조건에 따라 지표 매개 변수를 동적으로 조정하기 위해 매개 변수 최적화를 추가합니다.

  5. 크로스 자산 중재: 다른 자산에 대한 전략을 적용하여 위험을 더 잘 제어하기 위해 중재 기회를 찾습니다.

결론

이 전략은 트렌드, 사이클, 모멘텀 및 가격 부피를 모든 측면에서 판단하는 전략을 형성하기 위해 4 개의 주요 Ehlers 지표를 현명하게 결합합니다. 우수한 노이즈 필터 기능과 고품질 신호를 생성 할 수 있습니다. 그러나 스톱 손실과 보조 지표 필터링이 부족하여 일부 위험에 노출됩니다. 스톱 손실, 필터, 더 많은 시간 프레임 등을 추가함으로써 더 높은 안정성과 신뢰성을 위해 효과적으로 최적화 할 수 있습니다.


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



더 많은