스파이럴 브레이크 이동 평균 전략

저자:차오장, 날짜: 2024-01-15 11:45:23
태그:

img

전반적인 설명

이 전략은 나선 채널 지표와 변화율 (ROC) 지표를 결합합니다. 가격이 상단 대역과 이동 평균을 넘어서면 구매 신호를 생성하고 가격이 하단 대역과 이동 평균을 넘어서면 판매 신호를 생성합니다. 나선 채널은 트렌드 방향을 결정하고 ROC는 가격 동력을 감지합니다. 두 지표 사이의 동의를 요구함으로써 전략은 거래 신호의 신뢰성과 승률을 향상시키는 것을 목표로합니다.

전략 논리

이 전략은 두 가지 주요 지표에 기반합니다.

  1. 나선 채널: 트렌드 방향을 결정하기 위해 상부 및 하부 대역을 그래프화합니다. 상부 대역 위의 가격 파열은 상승 추세를 나타냅니다. 하부 대역 아래의 파열은 하향 추세를 나타냅니다.

  2. 변화율 (ROC): 가격 가속도를 감지합니다. 긍정적 인 임계 이상의 ROC는 상승 가격 움직임을 가속화하는 것을 암시하며, 부정적인 임계 이하의 ROC는 하락 움직임을 가속화하는 것을 나타냅니다.

바이 신호는 스파이럴 채널과 ROC 모두 상승 시선을 나타낼 때 생성됩니다. 즉, 상위 밴드 이상의 가격 경류와 가속화 상승 동력을 동반합니다. 판매 신호는 두 지표 모두 하향 시선이 될 때 유발됩니다.

결합된 신호는 트렌드에 반대되는 거래를 피하고 신뢰성을 향상시킵니다.

장점

  1. 트렌드와 추진력 사이의 합의를 요구함으로써 높은 승률을 가진 신뢰할 수 있는 신호입니다.

  2. 매개 변수 조정을 통해 거래 주파수를 조정할 수 있습니다. 예를 들어 ROC 매개 변수를 조정할 수 있습니다.

  3. 개별 거래에서 하락 위험을 제한하기 위해 손실을 중지하십시오.

  4. 트렌드를 타개하고 수익성을 더 높이기 위한 메커니즘을 재입입시합니다.

위험성

  1. 일부 거래 기회를 놓치고 신호 신뢰성 요구 사항으로 인해 수익 잠재력을 제한합니다.

  2. 트렌드가 뒤집어지면 큰 손실을 초래할 수 있습니다.

  3. 패러미터 조정이 제대로 되지 않으면 신호가 너무 적거나 너무 많을 수 있습니다.

  4. 고정된 스톱 로스 비율로 엄청난 불리한 가격 변동에 심각한 손실을 방지할 수 없습니다.

더 나은 기회

  1. 최고 성능을 위해 ROC 매개 변수를 최적화합니다.

  2. 위험과 보상을 균형을 맞추기 위해 다른 스톱 로스 레벨을 테스트합니다.

  3. 부피, 변동성 지표와 같은 다른 필터를 추가하여 신호를 정제합니다.

  4. 다양한 시장의 성과를 평가하여 가장 적합한 것을 찾습니다.

  5. 다른 시장 조건에 따라 동적 위치 크기를 도입합니다.

결론

이 전략은 트렌드 방향과 동력을 평가하기 위해 나선형 채널과 ROC를 결합합니다. 재입구 및 매개 변수 조정을 통해 수익성을 유지하면서 신호 신뢰성을 목표로합니다. 위험은 주로 고정 비율의 스톱 로스로 제어됩니다. 전반적으로 기준량 거래 전략으로 가치가있는 비교적 완전한 프레임워크입니다.


/*backtest
start: 2024-01-07 00:00:00
end: 2024-01-14 00:00:00
period: 45m
basePeriod: 5m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy("SSL Chaikin BF 🚀", overlay=true, precision=2, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.075)

/////////////// Time Frame ///////////////
_0 = input(false,  "════════ Test Period ═══════")
testStartYear = input(2017, "Backtest Start Year") 
testStartMonth = input(1, "Backtest Start Month")
testStartDay = input(1, "Backtest Start Day")
testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay, 0, 0)

testStopYear = input(2019, "Backtest Stop Year")
testStopMonth = input(12, "Backtest Stop Month")
testStopDay = input(31, "Backtest Stop Day")
testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay, 0, 0)

testPeriod() => true

/////////////// Chaikin MF /////////////// 
_1 = input(false,  "═══════ Chaikin MF ═══════")
length = input(20, minval=1, title = "Chaikin SMA Length")
upperThreshold = input(0.04, step=0.01, title="Upper Threshold")
lowerThreshold = input(0.02, step=0.01, title="Lower Threshold")
ad = close==high and close==low or high==low ? 0 : ((2*close-low-high)/(high-low))*volume
mf = sum(ad, length) / sum(volume, length)

/////////////// SSL Channels /////////////// 
_2 = input(false,  "═════════ SSL ══════════")
len1=input(title="SMA Length 1", defval=12)
len2=input(title="SMA Length 2", defval=13)

smaHigh = sma(high, len1)
smaLow = sma(low, len2)

Hlv = 0
Hlv := close > smaHigh ? 1 : close < smaLow ? -1 : Hlv[1]
sslDown = Hlv < 0 ? smaHigh : smaLow
sslUp = Hlv < 0 ? smaLow : smaHigh

///////////// Rate Of Change ///////////// 
_3 = input(false,  "══════ Rate of Change ══════")
source = close
roclength = input(13, "ROC Length",  minval=1)
pcntChange = input(4, "ROC % Change", minval=1)
roc = 100 * (source - source[roclength]) / source[roclength]
emaroc = ema(roc, roclength / 2)
isMoving() => emaroc > (pcntChange / 2) or emaroc < (0 - (pcntChange / 2))

///////////////  Strategy  /////////////// 
long = sslUp > sslDown and isMoving() or crossover(mf, upperThreshold)
short = sslUp < sslDown and isMoving() or crossunder(mf, lowerThreshold)

last_long = 0.0
last_short = 0.0
last_long := long ? time : nz(last_long[1])
last_short := short ? time : nz(last_short[1])

long_signal = crossover(last_long, last_short)
short_signal = crossover(last_short, last_long)

last_open_long_signal = 0.0
last_open_short_signal = 0.0
last_open_long_signal := long_signal ? open : nz(last_open_long_signal[1])
last_open_short_signal := short_signal ? open : nz(last_open_short_signal[1])

last_long_signal = 0.0
last_short_signal = 0.0
last_long_signal := long_signal ? time : nz(last_long_signal[1])
last_short_signal := short_signal ? time : nz(last_short_signal[1])

in_long_signal = last_long_signal > last_short_signal
in_short_signal = last_short_signal > last_long_signal

last_high = 0.0
last_low = 0.0
last_high := not in_long_signal ? na : in_long_signal and (na(last_high[1]) or high > nz(last_high[1])) ? high : nz(last_high[1])
last_low := not in_short_signal ? na : in_short_signal and (na(last_low[1]) or low < nz(last_low[1])) ? low : nz(last_low[1])

since_longEntry = barssince(last_open_long_signal != last_open_long_signal[1]) 
since_shortEntry = barssince(last_open_short_signal != last_open_short_signal[1]) 

//////////////// Stop loss /////////////// 
_4 = input(false,  "════════ Stop Loss ═══════")
sl_inp = input(2.0, title='Stop Loss %') / 100

slLong = in_long_signal ? strategy.position_avg_price * (1 - sl_inp) : na
slShort = strategy.position_avg_price * (1 + sl_inp)
long_sl = in_long_signal ? slLong : na
short_sl = in_short_signal ? slShort : na

/////////////// Execution /////////////// 
if testPeriod()
    strategy.entry("L", strategy.long, when=long)
    strategy.entry("S", strategy.short, when=short)
    strategy.exit("L SL", "L", stop=long_sl, when=since_longEntry > 0)
    strategy.exit("S SL", "S", stop=short_sl, when=since_shortEntry > 0)

/////////////// Plotting /////////////// 
p1 = plot(sslDown, linewidth = 1, color=color.red)
p2 = plot(sslUp, linewidth = 1, color=color.lime)
fill(p1, p2,  color = sslDown < sslUp ? color.lime : color.red, transp=80)
bgcolor(isMoving() ? long ? color.green : short ? color.red : na : color.white, transp=80)
bgcolor(long_signal ? color.lime : short_signal ? color.red : na, transp=30)
bgcolor(crossover(mf, upperThreshold) ? color.blue : crossunder(mf, lowerThreshold) ? color.orange : na, transp=30)

더 많은