이 전략은 Ehlers Elegant Oscillator, Ehlers Decycler, Ehlers Instantaneous Trendline 및 Ehlers Spearman Rank Correlation Coefficient를 하나의 전략으로 결합하여 트렌드, 오스실레이션, 모멘텀 및 가격 및 볼륨 특성을 완전히 포착하는 양적 거래 전략을 형성합니다. 전략 이름은
이 전략은 판단을 위해 4가지 주요 지표를 사용합니다.
먼저, 에일러스 우아한 오시일레이터 (Ehlers Elegant Oscillator), 즉 기하급수적인 이동 평균에 의해 평평화된 원래 라인과 신호 라인의 차이는 현재 트렌드 방향과 강도를 결정할 수 있다. 둘째, 에일러스 디사이클러 (Ehlers Decycler), 즉 주기의 낮은 지점을 효과적으로 식별하고 주요 트렌드가 역전되는지를 결정할 수 있다. 다음으로, 에일러스 즉각적인 트렌드 라인은 단기 트렌드 방향을 판단하기 위해 빠른 이동 평균을 추적한다. 마지막으로, 에일러스 스피어먼 순위 상관 계수는 잘못된 브레이크오트를 효과적으로 필터할 수 있는 가격-용량 관계를 판단한다.
구체적으로, 전략의 네 가지 입시 조건은: 우아한 오시레이터 신호 라인과 디사이클러 신호 라인이 동시에 0을 넘기며; 원래 라인이 디사이클러 라인을 넘기며; 원래 라인이 상승하는 즉각적인 트렌드 라인보다 높으며; 긍정적 인 스피어만 순위 상관률.
출구 조건은 훨씬 간단합니다. 원래 라인이 즉각적인 트렌드 라인 아래에 떨어지면 출구입니다.
짧은 조건은 긴 조건과 비슷하지만, 역전된 조건입니다.
이 전략의 가장 큰 장점은 각 지표의 강점을 효과적으로 활용하고 상호 검증하고 거짓 긍정적 인 결과를 피하고 많은 잡음을 필터링하고 더 신뢰할 수있는 신호를 생성 할 수있는 적절한 지표 조합에 있습니다.
특히, 우아한 오시레이터는 트렌드 방향과 강도를 판단할 수 있으며, 디사이클러는 사이클 전환점을 판단할 수 있으며, 즉각적인 트렌드 라인은 단기 트렌드를 판단할 수 있으며, 스피어맨 랭크는 가격-용량 관계를 판단할 수 있습니다. 네 가지의 조합은 트렌드, 사이클, 추진력 및 가격-용량 측면에서 시장 특성을 포괄적으로 판단하여 매우 신뢰할 수있는 거래 신호를 생산할 수 있습니다.
또한, 중장기 가격만을 기준으로 하는 이 전략은 단기 시장 소음의 간섭을 피하고 불필요한 반전 거래를 줄인다. 또한, 희박한 신호와 간단한 출구 규칙으로 거래 빈도를 크게 줄여 과도한 거래 문제를 피할 수 있다.
이 전략의 가장 큰 위험은 스톱 로스 메커니즘의 부족입니다. 폭력적인 시장 움직임의 경우, 시간적으로 손실을 멈추지 못하는 것은 더 큰 손실로 이어질 수 있습니다. 또한 도
이러한 위험을 완화하기 위해, 손실이 특정 수준을 초과할 때 자동으로 손실을 중지하도록 보호 스톱 로스를 설정할 수 있습니다. 또한, MACD와 같은 지표는 잘못된 브레이크의 위험을 피하기 위해 2차 확인을 위해 추가 될 수 있습니다.
이 전략은 다음과 같은 측면에서 최적화 될 수 있습니다.
리스크 관리 스톱 로스 메커니즘을 추가합니다. 적절한 스톱 로스 수준을 설정하기 위해 최대 역사 마감량을 계산합니다.
더 많은 필터를 추가합니다. MACD, 볼링거 밴드 같은 지표를 추가하여 더 많은 필터를 추가하여 잘못된 신호를 감소시킵니다.
더 많은 시간 프레임을 포함. 현재 하나의 세트 매개 변수만 사용됩니다. 안정성을 향상시키기 위해 멀티 타임 프레임 검증을 위해 더 많은 시간 프레임을 추가 할 수 있습니다.
동적으로 매개 변수를 조정합니다. 적응력을 향상시키기 위해 변화하는 시장 조건에 따라 지표 매개 변수를 동적으로 조정하기 위해 매개 변수 최적화를 추가합니다.
크로스 자산 중재: 다른 자산에 대한 전략을 적용하여 위험을 더 잘 제어하기 위해 중재 기회를 찾습니다.
이 전략은 트렌드, 사이클, 모멘텀 및 가격 부피를 모든 측면에서 판단하는 전략을 형성하기 위해 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')