Chiến lược này là một hệ thống giao dịch định lượng dựa trên Bollinger Bands breakout, sử dụng 3 sai lệch tiêu chuẩn cho dải trên và 1 sai lệch tiêu chuẩn cho dải dưới, kết hợp với trung bình động 100 ngày như dải giữa. Chiến lược chủ yếu nắm bắt xu hướng dài hạn bằng cách phát hiện sự đột phá giá trên dải trên và sử dụng dải dưới như một tín hiệu dừng lỗ. Khái niệm cốt lõi là nhập vị trí trong các sự đột phá mạnh và thoát ra khi giá giảm xuống dưới dải dưới, đạt được xu hướng theo rủi ro có kiểm soát.
Nguyên tắc cốt lõi dựa trên các tính chất thống kê của Bollinger Bands. Dải trên sử dụng 3 độ lệch chuẩn, có nghĩa là theo các giả định phân phối bình thường, xác suất giá phá vỡ trên mức này chỉ là 0,15%, cho thấy sự hình thành xu hướng quan trọng khi xảy ra sự phá vỡ. Dải giữa sử dụng trung bình động 100 ngày, một khoảng thời gian đủ dài để lọc hiệu quả tiếng ồn thị trường ngắn hạn. Dải dưới sử dụng 1 độ lệch chuẩn như một đường dừng lỗ, một thiết lập tương đối bảo thủ giúp thoát kịp thời. Chiến lược tạo ra các tín hiệu dài khi giá phá vỡ trên dải trên và thoát khi giá giảm xuống dưới dải dưới.
Đây là một chiến lược theo xu hướng được thiết kế tốt với logic rõ ràng. Thông qua các đặc tính thống kê của Bollinger Bands và các đặc điểm theo xu hướng của đường trung bình động, nó có hiệu quả nắm bắt các cơ hội đột phá thị trường đáng kể. Mặc dù có rủi ro rút tiền, chiến lược duy trì giá trị thực tế thông qua các thiết lập dừng lỗ hợp lý và kiểm soát rủi ro. Tiềm năng tối ưu hóa hơn nữa nằm trong xác nhận tín hiệu, cơ chế dừng lỗ và các khía cạnh quản lý vị trí.
/*backtest start: 2024-11-12 00:00:00 end: 2024-12-11 08:00:00 period: 1h basePeriod: 1h 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/ // © MounirTrades007 // @version=6 strategy("Bollinger Bands", overlay=true, initial_capital=100000, default_qty_type=strategy.percent_of_equity, default_qty_value=200) // Get user input var g_bb = "Bollinger Band Settings" upperBandSD = input.float(title="Upper Band Std Dev", defval=3.0, tooltip="Upper band's standard deviation multiplier", group=g_bb) lowerBandSD = input.float(title="Lower Band Std Dev", defval=1.0, tooltip="Lower band's standard deviation multiplier", group=g_bb) maPeriod = input.int(title="Middle Band MA Length", defval=100, tooltip="Middle band's SMA period length", group=g_bb) var g_tester = "Backtester Settings" drawTester = input.bool(title="Draw Backtester", defval=true, group=g_tester, tooltip="Turn on/off inbuilt backtester display") // Get Bollinger Bands [bbIgnore1, bbHigh, bbIgnore2] = ta.bb(close, maPeriod, upperBandSD) [bbMid, bbIgnore3, bbLow] = ta.bb(close, maPeriod, lowerBandSD) // Prepare trade persistent variables drawEntry = false drawExit = false // Detect bollinger breakout if close > bbHigh and barstate.isconfirmed and strategy.position_size == 0 drawEntry := true strategy.entry(id="Trade", direction=strategy.long) alert("Bollinger Breakout Detected for " + syminfo.ticker, alert.freq_once_per_bar_close) // Detect bollinger sell signal if close < bbLow and barstate.isconfirmed and strategy.position_size != 0 drawExit := true strategy.close(id="Trade") alert("Bollinger Exit detected for " + syminfo.ticker, alert.freq_once_per_bar_close) // Draw bollinger bands plot(bbMid, color=color.blue, title="Middle SMA") plot(bbHigh, color=color.green, title="Upper Band") plot(bbLow, color=color.red, title="Lower Band") // Draw signals plotshape(drawEntry, style=shape.triangleup, color=color.green, location=location.belowbar, size=size.normal, title="Buy Signal") plotshape(drawExit, style=shape.xcross, color=color.red, location=location.belowbar, size=size.normal, title="Sell Signal") // // ============================================================================= // // START BACKTEST CODE // // ============================================================================= // // Prepare stats table // var table testTable = table.new(position.top_right, 2, 2, border_width=1) // f_fillCell(_table, _column, _row, _title, _value, _bgcolor, _txtcolor) => // _cellText = _title + "\n" + _value // table.cell(_table, _column, _row, _cellText, bgcolor=_bgcolor, text_color=_txtcolor) // // Draw stats table // var bgcolor = color.black // if barstate.islastconfirmedhistory // if drawTester // dollarReturn = strategy.equity - strategy.initial_capital // f_fillCell(testTable, 0, 0, "Total Trades:", str.tostring(strategy.closedtrades), bgcolor, color.white) // f_fillCell(testTable, 0, 1, "Win Rate:", str.tostring(strategy.wintrades / strategy.closedtrades * 100, "##.##") + "%", bgcolor, color.white) // f_fillCell(testTable, 1, 0, "Equity:", "$" + str.tostring(strategy.equity, "###,###.##"), bgcolor, color.white) // f_fillCell(testTable, 1, 1, "Return:", str.tostring((strategy.netprofit / strategy.initial_capital) * 100, "##.##") + "%", dollarReturn > 0 ? color.green : color.red, color.white) // // ============================================================================= // // END BACKTEST CODE // // =============================================================================