정량적 오실레이터 지표를 기반으로 한 조합 전략


생성 날짜: 2024-02-27 16:46:42 마지막으로 수정됨: 2024-02-27 16:46:42
복사: 3 클릭수: 653
avatar of ChaoZhang ChaoZhang
1
집중하다
1617
수행원

정량적 오실레이터 지표를 기반으로 한 조합 전략

개요

이 전략은 앵글러스 우아한 진동 지표, 앵글러스 순환 지표, 앵글러스 순간 트렌드 라인 및 앵글러스 스필먼 등급의 관련 계수 지표를 조합하여 전면적인 추세, 진동, 동력 및 수량 가격 특성을 포착하는 정량 거래 전략을 형성한다. 전략은 정량화 진동 지표 조합 전략이라고 한다.

전략 원칙

이 전략은 4가지 주요 지표들을 통해 판단됩니다.

첫째, 넬러스 우아한 진동 지표, 지수 평균을 평형화 한 후 신호 라인을 받아 원본 라인의 차이는 현재 트렌드 방향과 강도를 판단할 수 있습니다. 둘째, 넬러스 순환 지표, 주 트렌드가 반전되었는지 판단하기 위해 주기적 주기 저점을 효과적으로 식별 할 수 있습니다. 다시 한 번, 넬러스 순간 트렌드 라인은 빠른 이동 평균을 추적하여 단기 트렌드 방향을 판단합니다. 마지막으로, 넬러스 스필먼 등과 관련된 계열 지표는 가격 관계를 판단하여 가짜 돌파를 효과적으로 필터링 할 수 있습니다.

구체적으로, 전략의 네 가지 입시 조건은: 우아한 진동 지표 신호 선과 회전 지표 신호 선이 동시에 상향으로 통과하는 것; 원시 선이 상향으로 회전선을 돌파하는 것; 원시 선이 상승하는 순간 트렌드 선보다 높은 것; 스필먼 등급의 관련 계수는 양수이다.

출전 조건은 훨씬 더 간단하며, 원본 라인이 순간 트렌드 라인을 통과했을 때만 평행한다.

공허 조건은 다중 조건과 비슷하지만 판단 조건은 반전할 수 있다.

우위 분석

이 전략의 가장 큰 장점은 지표의 조합이 적절하고, 각 지표의 장점을 효과적으로 발휘하고, 서로 검증하고, 거짓 긍정적 인 것을 피하여 많은 잡음을 필터링하여 신호를 더 신뢰할 수 있다는 것입니다.

구체적으로, 우아한 진동 지표는 트렌드 방향과 강도를 판단, 순환 지표는 순환 전환점을 판단, 순간 트렌드 라인은 단기 트렌드를 판단, 스필만 등급 관련 계수는 양 가격 관계를 판단한다. 이 네 가지의 조합은 트렌드, 순환, 양 및 양 가격 측면에서 시장의 특성을 종합적으로 판단하여 높은 신뢰성 거래 신호를 얻는다.

또한, 이 전략은 중간선만을 기준으로 하여, 단기 시장 소음의 방해를 피하고, 불필요한 반전 거래를 줄일 수 있다. 또한, 전략 신호는 희귀하고, 출전 규칙은 간단하며, 거래 빈도를 크게 줄여서, 과도한 거래의 문제를 피할 수 있다.

위험 분석

이 전략의 가장 큰 위험은 상쇄 장치가 없다는 것입니다. 시장이 급격하게 변할 때 적시에 상쇄 할 수 없으므로 손실이 확대 될 수 있습니다. 또한, 경계 시스템 필터링 및 에너지 지표와 같은 추가 필터가 없다는 것은 약간의 거짓 긍정적 거래로 이어질 수 있습니다.

이러한 위험을 줄이기 위해, 피난 손실 지점을 설정할 수 있으며, 손실이 일정 비율을 초과하면 자동으로 중단된다. 또한, MACD와 같은 동량 지표가 추가되어 2차 검증을 할 수 있으며, 가짜 돌파의 위험을 피할 수 있다.

최적화 방향

이 정책은 다음과 같은 부분에서 최적화될 수 있습니다.

  1. 피난 손실 메커니즘에 가입하십시오. 역사 재검토 데이터에 따라 최대 회수를 계산하고, 그에 따른 중단점을 설정하십시오.

  2. 필터를 추가한다. MACD, 브린 띠 등 지표에 다층 필터링을 추가하여 가짜 신호를 더욱 줄인다.

  3. 더 많은 시간 주기를 결합한다. 현재는 하나의 매개 변수만 있고, 더 많은 주기 매개 변수를 도입할 수 있으며, 다중 시간 축 검증 방식을 채택하여 안정성을 높인다.

  4. 동적으로 조정하는 매개 변수. 매개 변수 최적화 모듈을 추가하여 다양한 시장 조건에 따라 지표 매개 변수를 동적으로 조정하여 전략을 더 적응시킬 수 있습니다.

  5. 여러 품종 중개. 다양한 품종에 전략을 적용하여 중개 기회를 찾아서 위험을 더 제어 할 수 있습니다.

요약하다

이 전략은 넬스의 4대 지표의 교묘한 조합을 통해 트렌드, 사이클, 동력 및 양값을 판단하는 전면적인 거래 전략을 형성한다. 이 전략은 소음을 필터링하는 능력이 뛰어나고, 고품질의 신호를 생성할 수 있다. 그러나 중지 손실 및 보조 지표 필터링이 없다는 것은 약간의 위험을 초래한다. 중지 손실, 필터, 더 많은 시간 주기 등을 추가함으로써 효율적으로 최적화하여 전략을 더 안정적이고 신뢰할 수 있다.

전략 소스 코드
/*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')