이 전략은 스토카스틱 RSI와 가격 변화율 지표를 사용하여 진입 트렌드 방향을 파악하고 리스크 관리를 위해 슬라이딩 스톱 로스를 조정합니다.
첫째, 전략은 길이 5의 RSI 지표와 길이 7의 Stochastic 지표를 사용하여 스토카스틱 RSI를 계산합니다. 스토카스틱 RSI K 값이 D 값보다 높으면 상승 신호입니다. K 값이 D 이하일 때 하락 신호입니다.
둘째, 전략은 가격 변화율 지표 EMA ROC를 계산합니다. EMA ROC가 임계 절반 이상 또는 임계 절반 미만인 경우, 활성 가격 움직임을 식별합니다.
그 다음 스토카스틱 RSI 신호와 가격 변화율을 결합하여 트렌드 방향을 식별합니다. 스토카스틱 RSI가 상승하고 가격이 적극적으로 움직일 때, 길게 가십시오. 스토카스틱 RSI가 하락하고 가격이 적극적으로 움직일 때, 짧게 가십시오.
마지막으로, 전략은 위험 관리를 위해 좌표 슬라이딩 스톱 로스를 사용합니다. 포지션을 열고 나면 최고/최저 가격을 계속 갱신하고 최고/최저 가격에서 특정 비율 거리를 스톱 로스 수준으로 사용합니다.
이 전략의 장점:
스토카스틱 RSI 지표는 트렌드와 과잉 구매/ 과잉 판매 상황을 효과적으로 식별합니다.
가격 변화율은 잘못된 신호를 피하기 위해 시장 범위를 필터합니다.
조정된 슬라이딩 스톱 손실은 위험을 통제하면서 최대 규모의 수익을 확보할 수 있습니다.
이 전략은 다양한 제품에 기반한 매개 변수 조정에 대한 큰 최적화 공간을 가지고 있습니다.
전략 논리는 간단하고 명확하고 이해하기 쉽고 실행하기 쉽습니다.
이 전략의 위험은:
스토카스틱 RSI는 잘못된 신호를 생성할 수 있습니다. 다른 요소로 확인이 필요합니다.
좌표 슬라이딩 스톱 손실은 너무 공격적일 수 있습니다. 밤새 틈으로 멈출 수 있습니다.
단기 반전은 스톱 로드를 유발할 수 있습니다.
매개 변수는 다른 제품에 최적화되어야합니다. 그렇지 않으면 성능이 좋지 않을 수 있습니다.
거래 비용은 전략의 수익성에 영향을 미칩니다. 합리적인 거래 빈도가 필요합니다.
이 전략은 다음 측면에서 더 이상 최적화 될 수 있습니다.
잘못된 신호를 줄이기 위해 스토카스틱 RSI 매개 변수를 최적화합니다. 다른 K와 D 값을 테스트 할 수 있습니다.
필터링 효과를 향상시키기 위해 변화 매개 변수의 가격 비율을 최적화합니다. 다른 길이와 임계 값을 테스트 할 수 있습니다.
트렌드 인디케이터를 추가해서 이동 평균과 같은 반전으로 막히지 않도록 합니다.
포착 될 위험을 줄이기 위해 중지 손실 비율을 최적화. 다른 중지 손실 폭을 테스트 할 수 있습니다.
단일 거래 위험을 제어하기 위해 포지션 사이즈 관리를 추가하십시오. 고정 스톱 손실 금액과 같이 또는 계정 자금에 따라 포지션 크기를 동적으로 조정하십시오.
적응력을 향상시키기 위해 다른 제품에서 매개 변수를 테스트하십시오. 여러 시장과 시간 프레임에서 확인하십시오.
요약하자면, 이 전략은 명확하고 간단한 논리를 가지고 있으며, 스토카스틱 RSI로 트렌드 방향을 식별하고 가격 변화율로 신호를 필터하여 중장기 트렌드를 효과적으로 파악할 수 있습니다. 수익에 슬라이딩 스톱 로스 잠금을 조정하고 위험을 제어합니다. 추가 최적화로, 이 전략은 전략을 따르는 매우 실용적인 트렌드가 될 수 있습니다.
/*backtest start: 2023-10-02 00:00:00 end: 2023-11-01 00:00:00 period: 2h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=4 strategy("Sto2", overlay=false, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.0) /////////////// Time Frame /////////////// 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 ///////////// Stochastic calc ///////////// smoothK = input(1, minval=1) smoothD = input(7, minval=1) lengthRSI = input(5, minval=1) lengthStoch = input(7, minval=1) src = input(close, title="RSI Source") up = sma(max(change(src), 0), lengthRSI) down = sma(-min(change(src), 0), lengthRSI) rsi1 = down == 0 ? 100 : up == 0 ? 0 : 100 - (100 / (1 + up / down)) k = sma(stoch(rsi1, rsi1, rsi1, lengthStoch), smoothK) d = sma(k, smoothD) ///////////// Rate Of Change ///////////// source = close, roclength = input(14, minval=1), pcntChange = input(2, 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 = k > d and isMoving() short = k < d and isMoving() 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]) sl_inp = input(2.0, title='Stop Loss %') / 100 tp_inp = input(9.0, title='Take Profit %') / 100 take_level_l = strategy.position_avg_price * (1 + tp_inp) take_level_s = strategy.position_avg_price * (1 - tp_inp) since_longEntry = barssince(last_open_long_signal != last_open_long_signal[1]) // LONG SL since_shortEntry = barssince(last_open_short_signal != last_open_short_signal[1]) // SHORT SL 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 // Strategy if testPeriod() strategy.entry("Long Entry", strategy.long, when=long) strategy.entry("Short Entry", strategy.short, when=short) strategy.exit("Long Ex", "Long Entry", stop=long_sl, limit=take_level_l, when=since_longEntry > 0) strategy.exit("Short Ex", "Short Entry", stop=short_sl, limit=take_level_s, when=since_shortEntry > 0) ///////////// Plotting ///////////// bgcolor(isMoving() ? long ? color.green : short ? color.red : na : color.white, transp=80) p1 = plot(k, color=color.gray, linewidth=0) p2 = plot(d, color=color.gray, linewidth=0) h0 = hline(100) h1 = hline(50) h3 = hline(0) fill(p1, p2, color = k > d ? color.lime : color.red, transp=70)