베이비샤크 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 라인의 차분기를 도입하여 위험을 통제한다.
베이비샤크 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%