VWAP 및 OBV RSI 지표에 기초한 BabyShark VWAP 거래 전략

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

img

전략 개요

베이비 샤크 VWAP 거래 전략은 볼륨 가중 평균 가격 (VWAP) 및 밸런스 볼륨 상대 강도 지수 (OBV RSI) 를 기반으로 한 양적 거래 전략입니다. 전략은 특정 임계 수준을 넘어서 VWAP 및 OBV RSI의 오차에 따라 잠재적 인 구매 및 판매 신호를 식별하는 것을 목표로합니다.

전략 원칙

이 전략의 핵심 원칙은 시장 추세와 동력 변화를 포착하기 위해 VWAP 및 OBV RSI 지표를 활용하는 것입니다. VWAP는 시장의 주요 거래 영역을 반영하는 가격과 부피에 기반한 동적 이동 평균입니다. 가격이 VWAP에서 크게 벗어날 때 일반적으로 시장의 과잉 구매 또는 과잉 판매 조건을 나타냅니다. 반면 OBV RSI는 거래량 변화의 강도를 측정함으로써 시장 추세의 강도를 결정하기 위해 전통적인 RSI 지표의 기초로 부피 인수를 도입합니다.

구체적으로, 전략은 VWAP의 계산 기간으로 60개의 촛불을 사용하며, 닫기 가격은 입력 데이터로 사용된다. 그 다음 VWAP에서 긍정적 및 부정적인 3개의 표준 오차의 가격 오차를 기반으로 과소매 및 과소매 구역을 구성한다. OBV RSI의 경우, 계산 기간으로 5개의 촛불을 사용하며, 과소매 및 과소매 조건을 결정하는 기준으로 70과 30의 문턱을 설정한다.

거래 논리 측면에서, 가격이 VWAP의 하위 대역 아래의 과반 판매 구역에 있고 OBV RSI가 30 미만일 때, 전략은 긴 신호를 생성합니다. 반대로, 가격이 VWAP의 상위 대역 위의 과반 구매 구역에 있고 OBV RSI가 70보다 높을 때, 짧은 신호를 생성합니다. 또한, 전략은 0.6%의 이익과 손실을 멈추는 비율을 설정하고 위험을 제어하기 위해 연속 손실 후 10 촛불의 냉각 기간을 도입합니다.

전략적 장점

  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 거래 전략은 거래량 가중화 평균 가격과 밸런스 부피 상대 강도 지수를 결합하여 과잉 구매 및 과잉 판매 조건 및 트렌드 모멘텀의 변화를 포착하여 거래 신호를 생성하는 양적 거래 전략이다. 이 전략은 명확한 논리를 가지고 있으며 시장 펄스를 포괄적으로 파악하기 위해 가격 및 부피와 같은 여러 시장 요인을 통합하여 시장의 동력을 파악합니다. 동시에 합리적인 수익 및 스톱 손실 설정 및 위험 통제 메커니즘은 전략이 위험 관리를 고려하면서 수익을 추구 할 수 있습니다. 그러나 전략에는 변동 및 트렌딩 시장 및 고정 최적화 장치에 대한 부적절한 적응성 및 잠재적 인 문제도 있습니다. 향후 개선은 진입 어댑터, 동적 수익 취득, 역동적 매개 변수, 외부 데이터 분석 향상 및 전략의 안정성 및 수익성을 더욱 향상시키는 데 초점을 맞출 수 있습니다. 전반적으로, 베이비샤크 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%



더 많은