Chiến lược giao dịch VWAP của BabyShark dựa trên các chỉ số VWAP và OBV RSI

Tác giả:ChaoZhang, Ngày: 2024-03-08 16:39:28
Tags:

img

Tổng quan chiến lược

Chiến lược giao dịch BabyShark VWAP là một chiến lược giao dịch định lượng dựa trên Giá trung bình cân nhắc khối lượng (VWAP) và Chỉ số sức mạnh tương đối khối lượng cán cân (OBV RSI).

Nguyên tắc chiến lược

Nguyên tắc cốt lõi của chiến lược này là sử dụng các chỉ số VWAP và OBV RSI để nắm bắt xu hướng thị trường và thay đổi động lực. VWAP là một đường trung bình động dựa trên giá và khối lượng, phản ánh các khu vực giao dịch chính của thị trường. Khi giá lệch đáng kể từ VWAP, nó thường chỉ ra điều kiện mua quá nhiều hoặc bán quá nhiều trên thị trường.

Cụ thể, chiến lược sử dụng 60 nến làm thời gian tính toán cho VWAP, với giá đóng là dữ liệu đầu vào. Sau đó nó xây dựng các vùng mua quá mức và bán quá mức dựa trên độ lệch giá của 3 độ lệch chuẩn dương tính và âm từ VWAP. Đối với OBV RSI, nó sử dụng 5 nến làm thời gian tính toán và đặt ngưỡng 70 và 30 làm tiêu chí để xác định điều kiện mua quá mức và bán quá mức.

Về mặt logic giao dịch, khi giá ở trong vùng bán quá mức dưới băng tần dưới VWAP và OBV RSI dưới 30, chiến lược tạo ra tín hiệu dài. Ngược lại, khi giá ở trong vùng mua quá mức trên băng tần trên VWAP và OBV RSI lớn hơn 70, nó tạo ra tín hiệu ngắn. Ngoài ra, chiến lược đặt tỷ lệ lấy lợi nhuận và dừng lỗ 0,6% và giới thiệu thời gian làm mát 10 nến sau các lỗ liên tiếp để kiểm soát rủi ro.

Ưu điểm chiến lược

  1. Kết hợp nhiều yếu tố thị trường như giá cả và khối lượng để nắm bắt toàn diện xu hướng và động lực thị trường.
  2. Sử dụng các chỉ số RSI VWAP và OBV năng động để thích nghi với những thay đổi trong các chu kỳ thị trường khác nhau.
  3. Đặt tỷ lệ lợi nhuận và dừng lỗ hợp lý và thời gian suy nghĩ để kiểm soát rủi ro một cách hiệu quả trong khi nắm bắt cơ hội.
  4. Logic rõ ràng, dễ hiểu và thực hiện, với một mức độ giải thích nhất định.
  5. Các thông số có thể điều chỉnh, phù hợp với các nhà giao dịch với các phong cách khác nhau để tối ưu hóa và cải thiện.

Rủi ro chiến lược

  1. Đối với các thị trường dao động hoặc lặp lại, các tín hiệu giao dịch thường xuyên có thể dẫn đến giao dịch quá mức và tăng chi phí trượt.
  2. Trong các thị trường xu hướng, chỉ dựa vào VWAP để kiếm lợi nhuận có thể khiến chiến lược rời quá sớm, bỏ lỡ lợi nhuận xu hướng tiếp theo.
  3. Các thiết lập tham số cố định có thể không thích nghi với những thay đổi trong điều kiện thị trường, đòi hỏi phải tối ưu hóa cho các công cụ và khung thời gian khác nhau.
  4. Chỉ số OBV phụ thuộc nhiều vào dữ liệu khối lượng; khi dữ liệu khối lượng không chính xác hoặc bị thao túng, sự biến dạng của chỉ số có thể gây hiểu lầm về phán đoán.
  5. Chiến lược thiếu tính đến các yếu tố bên ngoài như kinh tế vĩ mô và tin tức, và có thể thất bại trong điều kiện thị trường cực đoan.

Hướng dẫn tối ưu hóa

  1. Thiết lập nhiều điều kiện lọc hơn cho các thị trường dao động, chẳng hạn như chỉ số xác nhận xu hướng và chỉ số biến động, để giảm giao dịch thường xuyên.
  2. Tối ưu hóa các điều kiện thoát, chẳng hạn như sử dụng các điểm dừng sau hoặc kết hợp với các chỉ số theo xu hướng khác để nắm bắt tốt hơn các thị trường xu hướng.
  3. Thực hiện tối ưu hóa thích nghi của các thông số VWAP và OBV RSI, điều chỉnh năng động các khoảng thời gian tính toán và cài đặt ngưỡng.
  4. Thiết lập các cơ chế xác minh xác thực khối lượng để cải thiện độ tin cậy của chỉ số OBV RSI.
  5. Xem xét việc kết hợp phân tích dữ liệu kinh tế vĩ mô, chỉ số tâm lý, v.v., để tăng khả năng thích nghi và vững chắc của chiến lược.

Tóm lại

Chiến lược giao dịch BabyShark VWAP là một chiến lược giao dịch định lượng kết hợp giá trung bình cân nhắc khối lượng và chỉ số sức mạnh tương đối khối lượng trên cán cân để tạo ra các tín hiệu giao dịch bằng cách nắm bắt các điều kiện mua quá mức và bán quá mức và thay đổi động lực xu hướng. Chiến lược có logic rõ ràng, tích hợp nhiều yếu tố thị trường như giá và khối lượng để nắm bắt toàn diện xung thị trường. Đồng thời, các thiết lập lấy lợi nhuận và dừng lỗ hợp lý và các cơ chế kiểm soát rủi ro cho phép chiến lược theo đuổi lợi nhuận trong khi xem xét quản lý rủi ro. Tuy nhiên, chiến lược cũng có các vấn đề tiềm năng như khả năng thích nghi không đầy đủ với các thị trường dao động và xu hướng và tối ưu hóa cố định.


/*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%



Thêm nữa