Chiến lược sóng Bollinger

Tác giả:ChaoZhang, Ngày: 2024-01-15 15:16:27
Tags:

img

Tổng quan

Chiến lược Bollinger Wave là một chiến lược giao dịch định lượng kết hợp Bollinger Bands và đường trung bình động. Nó tạo ra các tín hiệu giao dịch bằng cách tính lệch chuẩn của Bollinger Bands và chéo của đường trung bình động để xác định xu hướng thị trường và khu vực mua quá mức / bán quá mức.

Chiến lược logic

Chiến lược này đầu tiên tính toán một đường trung bình động theo cấp số nhân (EMA) trong một khoảng thời gian được chỉ định như đường cơ sở. Dải trên (EMA + n lần độ lệch chuẩn) và dải dưới (EMA - n lần độ lệch chuẩn) sau đó được tính toán dựa trên EMA này. Một sự phá vỡ trên dải trên cho thấy tín hiệu mua quá mức, trong khi một sự phá vỡ dưới dải dưới cho thấy tín hiệu bán quá mức.

Ngoài ra, chiến lược kết hợp các chỉ số khác như RSI để lọc tín hiệu giao dịch và giảm tần suất giao dịch để giảm thiểu tổn thất không cần thiết.

Cụ thể, các quy tắc tín hiệu giao dịch là:

  1. Tín hiệu dài: Gần > Dải trên và RSI ((14) > 60
  2. Tín hiệu ngắn: Gần < Phạm vi dưới và RSI ((14) < 40

Khi các tín hiệu giao dịch trên xuất hiện, hãy có các vị trí với số lượng cố định hoặc tỷ lệ phần trăm tài khoản.

Ưu điểm

Chiến lược kết hợp xác định xu hướng và đánh giá mua quá mức / bán quá mức để tránh giao dịch không chính xác trên các thị trường giới hạn phạm vi.

So với các chiến lược trung bình động đơn giản, Bollinger Bands phản ánh tốt hơn sự biến động và mức độ rủi ro của thị trường hiện tại. Khi chiều rộng dải nhỏ, tín hiệu giao dịch đáng tin cậy hơn. Khi chiều rộng dải lớn, tần suất giao dịch sẽ tự động giảm. Sự điều chỉnh thích nghi như vậy có thể kiểm soát rủi ro chiến lược dựa trên các điều kiện thị trường khác nhau.

Ngoài ra, sự xác nhận hai lần từ RSI và các chỉ số khác giúp lọc ra một số tín hiệu sai và tránh giao dịch không chính xác xung quanh các điểm chuyển hướng xu hướng.

Phân tích rủi ro

Những rủi ro chính của chiến lược này là:

  1. Rủi ro tối ưu hóa tham số. Nếu các tham số trung bình chuyển động hoặc độ lệch chuẩn được đặt không phù hợp, nó có thể tạo ra các giao dịch ồn ào hơn hoặc bỏ lỡ cơ hội giao dịch. Các tham số này cần thử nghiệm và tối ưu hóa lặp đi lặp lại.

  2. Rủi ro tín hiệu đột phá sai. Khi giá đột phá ngắn ngủi trên hoặc dưới các dải và sau đó nhanh chóng đảo ngược, nó có thể tạo ra các tín hiệu không chính xác. Giao dịch mù quáng trên những điều đó sẽ làm tăng tổn thất. Điều này có thể được kiểm soát bằng cách tăng thời gian trung bình động hoặc đặt dừng lỗ.

  3. Rủi ro tần suất giao dịch cao. Nếu các dải có khoảng cách rất hẹp, nó có thể làm tăng số lượng giao dịch và hoa hồng được trả, do đó ảnh hưởng đến lợi nhuận cuối cùng. Điều này có thể được giảm thiểu bằng cách tăng một cách vừa phải thời gian trung bình động.

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

Có chỗ cho việc tối ưu hóa thêm chiến lược:

  1. Thêm cơ chế dừng lỗ. Sử dụng dừng lỗ sau hoặc dừng lỗ thời gian giúp nhận ra tổn thất trong thời gian và kiểm soát số tiền lỗ giao dịch duy nhất.

  2. Thêm các quy tắc kích thước vị trí. Ví dụ, kim tự tháp vào các giao dịch thắng và giảm thua. Điều này có thể cải thiện lợi nhuận chiến lược.

  3. Kết hợp với các chỉ số khác để lọc tín hiệu. Các chỉ số như KDJ và MACD có thể phục vụ như các công cụ đánh giá phụ trợ. Điều này giúp cải thiện thêm lợi nhuận chiến lược.

  4. Tối ưu hóa cài đặt tham số. Các phương pháp có hệ thống hơn như thuật toán di truyền có thể được sử dụng để kiểm tra các kết hợp tham số khác nhau và tìm các cài đặt tốt hơn.

Kết luận

Chiến lược sóng Bollinger tích hợp xác định xu hướng của các đường trung bình động và đánh giá mua quá mức / bán quá mức. Nó điều chỉnh tần suất giao dịch dựa trên sự thay đổi chiều rộng băng tần để thích nghi với các điều kiện thị trường khác nhau. Trong khi đó, lọc tín hiệu bởi RSI và các chỉ số khác tránh giao dịch không chính xác. Chiến lược xem xét cả việc theo dõi xu hướng thị trường và kiểm soát rủi ro. Với tối ưu hóa liên tục, nó có thể trở thành một chiến lược giao dịch định lượng có lợi nhuận ổn định.


/*backtest
start: 2023-01-08 00:00:00
end: 2024-01-14 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
//@FiboBuLL

strategy(shorttitle='FB Wave', title='FiboBuLL Wave', overlay=true, pyramiding=1, currency=currency.NONE, initial_capital=100000, default_qty_type=strategy.percent_of_equity, default_qty_value=100)

src = input(close, title='Source')
length = input.int(55, minval=1, title='EMA length')  // 20 for classis Bollinger Bands SMA line (basis)


mult = input.float(1., minval=0.236, maxval=2, title='Standard Deviation')  //2 for Classic Bollinger Bands //Maxval = 2 as higher the deviation, higher the risk
basis = ta.sma(src, length)
dev = mult * ta.stdev(src, length)

Show = input.string('Both', options=['Longs Only', 'Shorts Only', 'Both'], title='Trade Type')
CC = input(true, 'Color Bars')

upper = basis + dev
lower = basis - dev

//Conditions for Long and Short - Extra filter condition can be used such as RSI or CCI etc.

short = src < lower  // and rsi(close,14)<40
long = src > upper  // and rsi(close,14)>60

L1 = ta.barssince(long)
S1 = ta.barssince(short)

longSignal = L1 < S1 and not (L1 < S1)[1]
shortSignal = S1 < L1 and not (S1 < L1)[1]

//Plots and Fills


////Long/Short shapes with text
// plotshape(S1<L1 and not (S1<L1)[1]?close:na, text = "sᴇʟʟ", textcolor=#ff0100, color=#ff0100, style=shape.triangledown, size=size.small, location=location.abovebar, transp=0, title = "SELL", editable = true)
// plotshape(L1<S1 and not (L1<S1)[1]?close:na, text = "ʙᴜʏ", textcolor = #008000, color=#008000, style=shape.triangleup, size=size.small, location=location.belowbar, transp=0, title = "BUY", editable = true)  

// plotshape(shortSignal?close:na, color=#ff0100, style=shape.triangledown, size=size.small, location=location.abovebar, transp=0, title = "Short Signal", editable = true)
// plotshape(longSignal?close:na, color=#008000, style=shape.triangleup, size=size.small, location=location.belowbar, transp=0, title = "Long Signal", editable = true)  


p1 = plot(upper, color=color.new(#ff0000, 75), display=display.all, title='Upper Band')
p2 = plot(lower, color=color.new(#008000, 75), display=display.all, title='Lower Band')

p = plot(basis, color=L1 < S1 ? #008000 : S1 < L1 ? #ff0000 : na, linewidth=2, editable=false, title='Basis')

fill(p, p1, color=color.new(color.teal, 85), title='Top Fill')  //fill for basis-upper
fill(p, p2, color=color.rgb(217, 161, 161), title='Bottom Fill', transp=85)  //fill for basis-lower

//Barcolor

bcol = src > upper ? color.new(#8ceb07, 0) : src < lower ? color.new(#ff0000, 0) : src > basis ? color.green : src < basis ? color.red : na

barcolor(CC ? bcol : na, editable=false, title='Color Bars')


// //Alerts ----  // Use 'Once per bar close'

// alertcondition(condition=longSignal, title="Long - BB Filter", message='BB Filter Long @ {{close}}') // Use 'Once per bar close'
// alertcondition(condition=shortSignal, title="Short - BB Filter", message='BB Filter Short @ {{close}}')  // Use 'Once per bar close'

Notestart1 = input(true, '╔═══ Time Range to BackTest ═══╗')

// === INPUT BACKTEST RANGE ===
FromMonth = input.int(defval=1, title='From Month', minval=1, maxval=12)
FromDay = input.int(defval=1, title='From Day', minval=1, maxval=31)
FromYear = input.int(defval=2018, title='From Year', minval=2015)
ToMonth = input.int(defval=1, title='To Month', minval=1, maxval=12)
ToDay = input.int(defval=1, title='To Day', minval=1, maxval=31)
ToYear = input.int(defval=9999, title='To Year', minval=2010)

// === FUNCTION EXAMPLE === 
start = timestamp(FromYear, FromMonth, FromDay, 00, 00)  // backtest start window
finish = timestamp(ToYear, ToMonth, ToDay, 23, 59)  // backtest finish window
window() =>
    time >= start and time <= finish ? true : false

if window() and (Show == 'Longs Only' or Show == 'Both')
    strategy.entry('AL', direction=strategy.long, when=longSignal)
    strategy.close('LongAL', when=shortSignal, comment='AL KAPA')

if window() and (Show == 'Shorts Only' or Show == 'Both')
    strategy.entry('SAT', direction=strategy.short, when=shortSignal)
    strategy.close('SAT', when=longSignal, comment='SAT KAPA')














Thêm nữa