VWAP와 OBV RSI를 기반으로 한 베이비 샤크 거래 전략

저자:차오장, 날짜: 2024-03-08 16:39:28
태그:

基于VWAP和OBV RSI指标的BabyShark交易策略

전략 개요

베이비샤크 VWAP 거래 전략은 거래량 가중화 평균 가격 (VWAP) 과 에너지 파동 지표 (OBV RSI) 의 상대적 약점 지표 (OBV RSI) 에 기초한 양적 거래 전략이다. 이 전략은 가격의 VWAP 편차 정도와 OBV RSI가 특정 문턱을 돌파하는 정도에 따라 잠재적 인 구매 및 판매 신호를 식별하기 위해 고안되었다.

전략적 원칙

이 전략의 핵심은 두 가지 지표인 VWAP와 OBV RSI를 사용하여 시장의 경향과 동력의 변화를 포착하는 것입니다. VWAP는 가격과 거래량에 기반한 동적 평균선으로 시장의 주요 거래 지역을 반영합니다. 가격이 VWAP에서 크게 벗어날 때 일반적으로 시장이 과잉 구매 또는 과잉 판매가 발생한다는 것을 의미합니다. OBV RSI는 전통적인 RSI를 기반으로 거래 요소를 도입하여 거래량 변화의 강도를 측정하여 시장 추세의 안정성을 판단합니다.

구체적으로, 이 전략은 60개의 K선을 VWAP의 계산주기로 사용하며, 닫기 가격을 입력 데이터로 사용한다. 그 다음, 가격의 편차인 VWAP의 양적 - 3 표준차이의 범위를 기준으로 오버바이 및 오버셀로 영역을 구성한다. OBV RSI의 경우, 5개의 K선을 계산주기로 사용하며, 70과 30의 두 개의 문턱을 오버바이 및 오버셀로 판단 기준으로 설정한다.

거래의 논리적으로는, 가격이 VWAP 트레킹에 있는 오버셀로 부지에서 OBV RSI가 30보다 작을 때 더 많은 신호를 발송하고, 가격이 VWAP 트레킹에 있는 오버팔로 부지에서 OBV RSI가 70보다 큰 경우 빈 신호를 발송한다. 또한, 전략은 0.6%의 중지/손실 비율을 설정하고, 연속적인 손실에 따라 10개의 K 라인의 차분기를 도입하여 위험을 통제한다.

전략적 장점

  1. 가격과 거래량과 같은 여러 시장 요소를 결합하여 시장 추세와 동력을 포괄적으로 포착합니다.
  2. 동적 VWAP 및 OBV RSI 지표가 사용되며, 다른 시장 주기의 변화에 적응할 수 있습니다.
  3. 합리적인 손해배상률과 침착기를 설정하여 기회를 잡으면서 위험을 효과적으로 통제하십시오.
  4. 논리가 명확하고, 이해하기 쉽고 구현하기 쉽고, 어떤 종류의 해석성이 있습니다.
  5. 패러미터는 조정 가능하며 다양한 스타일의 거래자에게 최적화 및 개선됩니다.

전략적 위험

  1. 불안한 시장이나 시장이 반복되는 경우, 빈번한 거래 신호는 과도한 거래와 슬라이드 포인트 비용의 증가로 이어질 수 있다.
  2. 트렌드 시장에서 VWAP에 의존하는 것만으로도 트렌드 수익을 놓치는 전략의 조기 탈퇴로 이어질 수 있다.
  3. 고정된 파라미터 설정은 시장 환경의 변화에 적응할 수 없을 수 있으며, 다양한 품종과 시기를 위해 최적화되어야 한다.
  4. OBV 지표는 거래량에 대한 의존도가 높으며, 거래량 데이터가 진실하지 않거나 조작되었을 때 잘못된 지표가 잘못된 판단을 일으킬 수 있습니다.
  5. 이 전략은 거시적 경제, 뉴스 등 외부 요소에 대한 고려가 부족하여 극단적인 시장에 대처하는 데 실패할 수 있습니다.

최적화 방향

  1. 추세 확인 지표, 변동률 지표 등 불안정한 시장에 대한 더 많은 필터링 조건을 도입하여 거래 빈도를 줄입니다.
  2. 트렌드 추적 지표와 다른 트렌드 추적 지표와 결합하여 모바일 브레이크를 사용하거나 트렌드 시장을 더 잘 파악하는 것과 같은 출구 조건을 최적화하십시오.
  3. VWAP 및 OBV RSI의 매개 변수에 대한 적응적 최적화, 동적 조정 계산 주기 및 문값 설정.
  4. 트랜잭션의 진실성 검증 메커니즘을 도입하여 OBV RSI 지표의 신뢰성을 향상시킵니다.
  5. 맥로 경제 데이터 분석, 감정 지표 등을 포함하는 것을 고려하여 전략의 적응성 및 안정성을 강화하십시오.

요약

베이비샤크 VWAP 거래 전략은 거래량중량화 평균 가격과 에너지 유동 지표의 상대적으로 강한 지수를 결합한 양적 거래 전략으로, 시장의 과잉 판매 상태와 트렌드 동력의 변화를 포착하여 거래 신호를 생성한다. 이 전략은 명확한 논리를 가지고 있으며, 가격과 거래량과 같은 여러 시장 요소를 결합하여 시장의 맥박을 포괄적으로 파악할 수 있다. 동시에, 합리적인 손해 방지 설정과 위험 통제 메커니즘을 통해 전략은 수익을 추구하면서 동시에 위험 관리를 고려한다. 물론, 전략은 불안정한 시장과 트렌드 행보에 대한 적응성 부족과 고정 가능한 잠재적인 문제도 존재한다. 미래에는 입구 필터, 자동 상태 차단, 매개 변수 적응, 외부 분석을 강화하는 등의 측면을 개량하고 전략의 건강성과 안정성을 향상시킬 수 있다.


/*backtest
start: 2024-02-01 00:00:00
end: 2024-02-29 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/
// © GreatestUsername

//@version=5
strategy("BabyShark VWAP Strategy", overlay=true, margin_long=100, margin_short=100, calc_on_every_tick = true)


// VWAP
ls = input(false, title='Log-space', group = "Optional")
type = 'Average Deviation'
length = input(60, group="Strategy Modification")
source = input(close, group="Strategy Modification")
_low = ls == true ? math.log(low) : low
_high = ls == true ? math.log(high) : high
src = ls == true ? math.log(source) : source

//weighted mean
pine_vwmean(x, y) =>
    cw = 0.0
    cd = 0.0
    w_sum = 0.0
    d_sum = 0.0
    for i = 0 to y - 1 by 1
        cd := x[i]
        cw := volume[i]
        d_sum += cw * cd
        w_sum += cw
        w_sum
    d_sum / w_sum

//weighted standard deviation
pine_vwstdev(x, y, b) =>
    d_sum = 0.0
    w_sum = 0.0
    cd = 0.0
    for i = 0 to y - 1 by 1
        cd := x[i]
        cw = volume[i]
        d_sum += cw * math.pow(cd - b, 2)
        w_sum += cw
        w_sum
    math.sqrt(d_sum / w_sum)

//weighted average deviation
pine_vwavdev(x, y, b) =>
    d_sum = 0.0
    w_sum = 0.0
    cd = 0.0
    for i = 0 to y - 1 by 1
        cd := x[i]
        cw = volume[i]
        d_sum += cw * math.abs(cd - b)
        w_sum += cw
        w_sum
    d_sum / w_sum

vwmean = pine_vwmean(src, length)

//consider using Average Deviation instead of Standard Deviatio if there are values outside of 3rd upper & lower bands within a rolling window
dev = if type == 'Standard Deviation'
    dev = pine_vwstdev(src, length, vwmean)
    dev
else if type == 'Average Deviation'
    dev = pine_vwavdev(src, length, vwmean)
    dev

basis = ls == true ? math.exp(vwmean) : vwmean
plot(basis, color=color.new(#b7b7b7, 60), title='Basis')

upper_dev_2 = vwmean + dev * 2
upper_dev_3 = vwmean + dev * 3

lower_dev_2 = vwmean - dev * 2
lower_dev_3 = vwmean - dev * 3

fill(
     plot1=plot(ls == true ? math.exp(upper_dev_2) : upper_dev_2, color=color.new(#B20000, 0), title='Upper dev 2'), 
     plot2=plot(ls == true ? math.exp(upper_dev_3) : upper_dev_3, color=color.new(#FF6666, 0), title='Upper dev 3', display=display.none), 
     color=color.new(#FF4D4D, 80), title='Upper band'
     )
fill(
     plot1=plot(ls == true ? math.exp(lower_dev_3) : lower_dev_3, color=color.new(#00CC00, 0), title='Lower dev 3', display=display.none), 
     plot2=plot(ls == true ? math.exp(lower_dev_2) : lower_dev_2, color=color.new(#008000, 0), title='Lower dev 2'), 
     color=color.new(#006600, 80), title='Lower band'
     )


// Input to enable or disable the table visibility
table_visible = input(false, title="Show Table", group="Deviation Cross Monitor")
// Input for the number of candles to look back
table_length = input(300, title="Table Lookback Length", group="Deviation Cross Monitor")

// Custom count function
count_occurrences(cond, length) =>
    count = 0
    for i = 0 to length - 1
        if cond[i]
            count := count + 1
    count

// Count occurrences of prices above Upper dev 2 and below Lower dev 2

above_upper_dev_2 = count_occurrences(close > upper_dev_2, table_length)
below_lower_dev_2 = count_occurrences(close < lower_dev_2, table_length)

// Create table in the bottom right corner
var table tbl = table.new(position=position.bottom_right, rows=2, columns=2)

if table_visible
    if barstate.islast
        // Update the table headers
        table.cell(tbl, 0, 0, "Above Upper Dev 2", bgcolor=color.gray, text_color=color.white)
        table.cell(tbl, 0, 1, "Below Lower Dev 2", bgcolor=color.gray, text_color=color.white)
        
        // Update the table values
        table.cell(tbl, 1, 0, str.tostring(above_upper_dev_2), bgcolor=color.new(color.green, 90), text_color=color.green)
        table.cell(tbl, 1, 1, str.tostring(below_lower_dev_2), bgcolor=color.new(color.red, 90), text_color=color.red)
else
    table.delete(tbl)

// RSI
obvsrc = close
change_1 = ta.change(obvsrc)
obv = ta.cum(ta.change(obvsrc) > 0 ? volume : change_1 < 0 ? -volume : 0 * volume)

src2 = obv
len = input.int(5, minval=1, title="RSI Length", group="Strategy Modification")
up = ta.rma(math.max(ta.change(src2), 0), len)
down = ta.rma(-math.min(ta.change(src2), 0), len)
rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - 100 / (1 + up / down)
higherlvl = input(70, title="Higher Level", group="Strategy Modification")
lowerlvl = input(30, title="Lower Level", group="Strategy Modification")


plot_color = rsi >= higherlvl ? color.red : rsi <= lowerlvl ? color.green : color.new(#b7b7b7, 60)
// plot(rsi, color=plot_color)

//plot(rsi, color=color.white)



// Count occurrences of RSI crossing higher level and lower level
cross_above_higher = ta.crossover(rsi, higherlvl)
cross_below_lower = ta.crossunder(rsi, lowerlvl)
above_higher_count = count_occurrences(cross_above_higher, table_length)
below_lower_count = count_occurrences(cross_below_lower, table_length)

// Create table in the bottom right corner
if (table_visible)
    var table tbl2 = table.new(position=position.bottom_right, rows=2, columns=2)
    if (barstate.islast)
        // Update the table headers
        table.cell(tbl2, 0, 0, "Higher Level Cross", bgcolor=color.gray, text_color=color.white)
        table.cell(tbl2, 0, 1, "Lower Level Cross", bgcolor=color.gray, text_color=color.white)
        
        // Update the table values
        table.cell(tbl2, 1, 0, str.tostring(above_higher_count), bgcolor=color.new(color.red, 90), text_color=color.red)
        table.cell(tbl2, 1, 1, str.tostring(below_lower_count), bgcolor=color.new(color.green, 90), text_color=color.green)


// Entries

// Long Entry:
// Price is in the shaded GREEN area of [Hoss] VWAP Deviation
// and the [Hoss] OBV RSI is GREEN.
longCondition1 = close <= lower_dev_3
longConditions = plot_color == color.green and longCondition1 and strategy.position_size == 0

// Short Entry:
// Price is in the shaded RED area of [Hoss] VWAP Deviation
// and the [Hoss] OBV RSI is RED.
shortCondition1 = close >= upper_dev_3
shortConditions = plot_color == color.red and shortCondition1 and strategy.position_size == 0

var int lastEntryBar = 0


shortEMA = ta.ema(close, 12)
longEMA = ta.ema(close, 21)
uptrend = shortEMA > longEMA

if longConditions and lastEntryBar < bar_index - 10 //and uptrend
    strategy.entry("Long", strategy.long, stop=close * 0.994)
    lastEntryBar := bar_index

if shortConditions and lastEntryBar < bar_index - 10 //and not uptrend
    strategy.entry("Short", strategy.short, stop=close * 1.006)
    lastEntryBar := bar_index


if strategy.position_size > 0 and (ta.crossover(close, basis) or strategy.opentrades.entry_price(strategy.opentrades - 1) * 0.994 > close)
    strategy.close("Long", immediately = true)
if strategy.position_size < 0 and (ta.crossunder(close, basis) or strategy.opentrades.entry_price(strategy.opentrades - 1) * 1.006 < close)
    strategy.close("Short", immediately = true)

// Stop Loss:
// 0.6%
// After 1 Loss => NO more Trades for 10 Candles (10 minutes) (usually a breakout will happen, and it takes average 10min till it ranges again. So basically wait for range to form again)

// Take Profit:
// Grey line on [Hoss] VWAP Deviation or 0.6%



더 많은 내용