이 전략은 OBV 지표의 이중 EMA 라인의 크로스오버를 사용하여 OBV의 트렌드를 결정하고 트렌드 방향에 따라 긴 / 짧은 포지션을 취합니다. OBV 지표는 가격과 부피 사이의 관계를 더 명확하게 반영하고 시장 참여자의 의도를 판단 할 수 있으므로 시장 트렌드를 캡처하는 데 사용할 수 있습니다. 이 전략은 이동 평균의 지표 평형을 결합하여 시장 소음을 효과적으로 필터링하고 주요 트렌드를 캡처 할 수 있습니다.
이 전략은 주로 OBV가 상승 추세에 있는지 여부를 결정하기 위해 긴 엔트리 타이밍을 사용합니다. 구체적으로 OBV의 6 일 EMA와 24 일 EMA를 계산합니다. 6 일 EMA가 24 일 EMA를 넘을 때 긴 신호가 생성됩니다. 마찬가지로 6 일 EMA가 24 일 EMA를 넘을 때 짧은 신호가 생성됩니다. 또한 전략은 3%의 스톱 로스를 설정합니다.
이 전략의 트렌드 판단의 핵심은 OBV 지표에 있다. OBV 지표는 큰 돈의 집단 의도를 반영하고 시장 참여자의 태도를 효과적으로 반영할 수 있다. 이동 평균 라인 처리와 결합하여 신호를 더 명확하고 신뢰할 수 있도록 약간의 소음을 필터링할 수 있다. 이 전략은 빠른 EMA 라인과 느린 EMA 라인을 사용하여 거래 신호를 구성하여 가격 데이터를 부드럽게 할 수 있으며 트렌드 변화를 보다 민감하게 포착할 수 있다.
이 전략은 다음과 같은 장점을 가지고 있습니다.
거래량에 기반한 OBV 지표는 시장 참여자의 의도를 명확하게 판단 할 수 있으며 신호는 더 신뢰할 수 있습니다.
이중 EMA 라인 프로세싱은 신호를 더 명확하게 만들기 위해 약간의 소음을 필터링할 수 있습니다.
빠른 EMA 라인과 느린 EMA 라인의 조합은 가격 평형화와 트렌드 변화를 모두 고려할 수 있습니다.
전략 작전은 간단하고 실행하기 쉽습니다.
이 전략은 또한 몇 가지 위험을 안고 있습니다.
OBV 지표는 어떤 시점에서 잘못된 신호를 발산할 수 있습니다. 그 시점에서 전략은 손실을 입을 수 있습니다.
폭력적인 거래에서 EMA 라인은 지연 효과를 가지고 있으며 최적의 입구 지점을 놓칠 수 있습니다.
고정 스톱 로스 설정은 시장 변화에 적응하기에는 너무 딱딱할 수 있습니다.
대책:
잘못된 신호를 피하기 위해 다른 지표로 확인합니다.
EMA 라인을 더 민감하게 만들기 위해 매개 변수 설정을 최적화합니다.
동적 스톱 손실 설정
이 전략은 다음과 같은 측면에서 최적화 될 수 있습니다.
EMA 매개 변수 조합을 최적화하여 더 잘 일치하는 이동 평균 매개 변수를 찾습니다.
신호 정확성을 향상시키기 위해 MACD, RSI 등 신호 확인을 위한 다른 지표를 증가시킵니다.
동적 스톱 손실을 설정, 시장 변동에 따라 실시간으로 스톱 손실 지점을 조정할 수 있습니다.
가장 좋은 파라미터 조합을 찾기 위해 파라미터 조합 최적화
일반적으로, 이 전략은 상대적으로 간단하고 신뢰할 수 있는 트렌드 다음 전략이다. 트렌드를 판단하기 위해 OBV 지표와 이중 EMA 라인을 결합한다. 장점은 간단한 동작, 명확한 신호, 그리고 트렌드를 효과적으로 추적하는 능력이다. 단점은 가능한 잘못된 신호와 EMA 라인 처리의 지연이다. 다른 지표와 최적화는 더 나은 결과를 얻을 수 있다.
/*backtest start: 2024-01-01 00:00:00 end: 2024-01-31 23:59:59 period: 1h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=4 strategy("OBV EMA X BF 🚀", 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 /////////////// OBV /////////////// src = close atr = atr(input(title="ATR Period", defval=3, minval=1)) atrmult = input(title="ATR Mult", defval=1, minval=0) obv = cum(change(src) > 0 ? volume * (volume / atr) : change(src) < 0 ? -volume * (volume / atr) : 0 * volume / atr) e1 = ema(obv, input(24)) e2 = ema(obv, input(6)) /////////////// Strategy /////////////// long = crossover(e2, e1) short = crossunder(e2, e1) 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 /////////////// sl_inp = input(3.0, title='Stop Loss %') / 100 tp_inp = input(5000.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) 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 /////////////// plot(e1, color = e1 > e1[1] ? color.lime : e1 < e1[1] ? color.red : color.white, linewidth = 2, offset = 0) plot(e2, color = e2 > e2[1] ? color.lime : e2 < e2[1] ? color.red : color.white, linewidth = 1) bgcolor(strategy.position_size > 0 ? color.lime : strategy.position_size < 0 ? color.red : color.white, transp=90) bgcolor(long_signal ? color.lime : short_signal ? color.red : na, transp=60)