Chiến lược Bollinger Band Momentum Burst

Tác giả:ChaoZhang, Ngày: 2023-10-31 15:54:41
Tags:

img

Tổng quan

Chiến lược này sử dụng Bollinger Bands để đánh giá xu hướng bằng cách so sánh biến động bên trong và bên ngoài các dải, và sử dụng các chỉ số động lực để theo dõi xu hướng. Nó thuộc về các chiến lược theo xu hướng. Nó tạo ra các tín hiệu hướng xu hướng mới khi biến động bên trong dải ít hơn bên ngoài, và mở các vị trí.

Nguyên tắc

Chiến lược bao gồm các phần chính sau:

  1. Cài đặt Bollinger Bands: Các dải lớn có chiều dài 40, các dải nhỏ dài 20, chiều rộng dải là 2 độ lệch chuẩn.

  2. Phán quyết nổ dải: Nếu dải lớn phía trên nằm dưới dải nhỏ phía trên, và dải lớn phía dưới nằm trên dải nhỏ phía dưới, nó cho thấy sự biến động tăng và tạo ra các tín hiệu hướng xu hướng mới.

  3. Chỉ số động lực: 240 khung thời gian 14 EMA đánh giá hướng xu hướng.

  4. ATR dừng lỗ và lấy lợi nhuận: ATR 14 lần cho khoảng cách dừng lỗ, lấy lợi nhuận là 1,5 lần khoảng cách dừng lỗ.

Chiến lược đầu tiên đánh giá nếu dải nổ, sau đó xác định dài hoặc ngắn dựa trên hướng động lực. Sau khi nhập, sử dụng ATR nhân để dừng lỗ và quản lý lợi nhuận.

Ưu điểm

  1. Sử dụng hai dải Bollinger có thể so sánh biến động qua các khung thời gian, để xác định các điểm bùng nổ xu hướng.

  2. Sử dụng các chỉ số động lực tránh bị đánh bại bởi các thị trường dao động.

  3. ATR dừng điều chỉnh khoảng cách dừng dựa trên biến động thị trường.

  4. Tỷ lệ rủi ro và phần thưởng hợp lý, không quá hung hăng hoặc bảo thủ.

Rủi ro

  1. Có thể bị mắc kẹt trong các thị trường không có xu hướng rõ ràng. Có thể tối ưu hóa các thông số động lực để giảm tín hiệu sai.

  2. Các phương pháp dừng ATR có thể quá bảo thủ. Hãy xem xét các phương pháp dừng khác như dừng lại.

  3. Các nhân ATR cố định có thể không phù hợp với tất cả các sản phẩm.

  4. Không chứng minh hiệu quả của Bollinger.

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

  1. Kiểm tra các thông số động lượng khác nhau để tìm kết hợp tối ưu.

  2. Hãy thử các phương pháp dừng khác nhau như dừng lại, ATR thích nghi.

  3. Làm cho ATR nhiều lần có thể điều chỉnh dựa trên sản phẩm và điều kiện thị trường.

  4. Kiểm tra các chỉ số kênh khác nhau để ổn định hơn.

  5. Xem xét thêm quản lý hợp chất để kiểm soát lợi nhuận tốt hơn.

  6. Chế độ lọc tín hiệu vào bằng cách dao động, thời gian vv để cải thiện tỷ lệ thắng.

Kết luận

Chiến lược logic là rõ ràng, sử dụng hai Bollinger để xác định xu hướng bùng nổ là điểm nổi bật lớn nhất. Nhưng vẫn cần tối ưu hóa trên dừng, kênh, quản lý rủi ro vv để làm cho các thông số thích nghi hơn trong các điều kiện thị trường khác nhau.


/*backtest
start: 2023-09-30 00:00:00
end: 2023-10-30 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © kasaism
//@version=4
// strategy(title="[EURUSD60] BB Expansion Strategy", shorttitle="[EURUSD60] BBEXP",overlay=true, max_bars_back=5000, max_labels_count=500)

// === INPUTS === //
////BB
largeBbRes = input(title="Large BB Resolution", type=input.resolution, defval="", group="BB")
largeBbLength = input(title="Large BB Length", type=input.integer, defval=40, minval=1, group="BB")
smallBbRes = input(title="Small BB Resolution ", type=input.resolution, defval="", group="BB")
smallBbLength = input(title="Small BB Length", type=input.integer, defval=20, minval=1, group="BB")
multi = input(title="BB StdDev", type=input.float, defval=2.0, maxval=10, minval=0.01, group="BB")
validLen = input(title="BB expand valid length", defval=14, group="BB")

// 3 each EMA settings. EMA directions are as each time frame directions. 
resFirstTime = input(title="EMA Trend t/f", type=input.resolution, defval="240", group="SMT")
// resSecondTime = input(title="Second t/f", type=input.resolution, defval="30", group="SMT") 
// resThirdTime = input(title="Third t/f", type=input.resolution, defval="", group="SMT")
emaLen = input(14, minval=1, title="Length", group="SMT") 
smooth = input(3, minval=1, title="Smooth factor", group="SMT")

//Lisk Management
var riskManagementRule1 = "ATR"
var riskManagementRule2 = "Bracket"
riskManagementRule = input(riskManagementRule1, "Detect Risk Management Based On", options=[riskManagementRule1, riskManagementRule2, "No detection"], group="Trade")
atrMulti = input(3.0, title="ATR Multiple", type=input.float, minval = 1.0, group="ATR")
riskRewardRatio = input(1.5, title="Risk Reward Ratio for ATR", type=input.float, minval = 0.01, group="ATR")
stopLossPoint = input(100, title="Stop Loss Point for Braket(tick)", type=input.float, minval = 1.0, group="Bracket")
takeProfitPoint = input(200, title="Take Profit Point for Braket(tick)", type=input.float, minval = 1.0, group="Bracket")
// === /INPUTS/ === //

// === CONSTANT === //
//For barmerge.lookahead_off
index = barstate.isrealtime ? 1 : 0

//For Entry
NOENTRY=0
LONG=1
SHORT=2

//SMT color
int up=1
int dn=2
int up_HL=3
int dn_HL=4

//label color
color_bearish = color.red
color_bullish = color.blue
C_label_color_bearish = color.red
C_label_color_bullish = color.blue
// === /CONSTANT/ === //


// === FUNCTIONS === //
//BB trade direction
bbTradeDetection(lrgUpper, lrgLower, smlUpper, smlLower) =>
    if not(na(lrgUpper) or na(lrgLower) or na(smlUpper) or na(smlLower))
        if lrgUpper < smlUpper and lrgLower > smlLower
            true
        else
            false
    else
        na
// === /FUNCTIONS/ === //


// === CALCURATES === //
////BB
//large BB
lrgBbBasis = security(syminfo.tickerid, largeBbRes, sma(close[index], largeBbLength))
lrgBbDev = multi * security(syminfo.tickerid, largeBbRes, stdev(close[index], largeBbLength))
lrgBbUpper = lrgBbBasis + lrgBbDev
lrgBbLower = lrgBbBasis - lrgBbDev

//small BB
smlBbBasis = security(syminfo.tickerid, smallBbRes, sma(close[index], smallBbLength))
smlBbDev = multi * security(syminfo.tickerid, smallBbRes, stdev(close[index], smallBbLength))
smlBbUpper = smlBbBasis + smlBbDev
smlBbLower = smlBbBasis - smlBbDev

bbTrade = bbTradeDetection(lrgBbUpper, lrgBbLower, smlBbUpper, smlBbLower)

//EMA Trend
base=security(syminfo.tickerid, resFirstTime, ema(close[index],emaLen))
sig=security(syminfo.tickerid, resFirstTime, ema(base[index],smooth))
emaTrend = not(na(base) or na(sig)) ? base < sig ? dn : up : na

////LISK MANAGEMENT
float stopLossLineForLong = na
float stopLossLineForShort = na
float takeProfitLineForLong = na
float takeProfitLineForShort = na
atr_ = atr(14) * atrMulti

if riskManagementRule == riskManagementRule1
    stopLossLineForLong := strategy.position_size > 0 ? stopLossLineForLong[1] ? stopLossLineForLong[1] : round(close[index] - atr_,3) : na
    stopLossLineForShort := strategy.position_size < 0 ? stopLossLineForShort[1] ? stopLossLineForShort[1] : round(close[index] + atr_,3) : na
    takeProfitLineForLong := strategy.position_size > 0 ? takeProfitLineForLong[1] ? takeProfitLineForLong[1] : close[index] + atr_*riskRewardRatio : na
    takeProfitLineForShort := strategy.position_size < 0 ? takeProfitLineForShort[1] ? takeProfitLineForShort[1] :close[index] - atr_*riskRewardRatio : na

if riskManagementRule == riskManagementRule2
    stopLossLineForLong := strategy.position_size > 0 ? stopLossLineForLong[1] ? stopLossLineForLong[1] : close[index] - stopLossPoint * syminfo.mintick : na
    stopLossLineForShort := strategy.position_size < 0 ? stopLossLineForShort[1] ? stopLossLineForShort[1] : close[index] + stopLossPoint * syminfo.mintick : na
    takeProfitLineForLong := strategy.position_size > 0 ? takeProfitLineForLong[1] ? takeProfitLineForLong[1] : close[index] +takeProfitPoint * syminfo.mintick : na
    takeProfitLineForShort := strategy.position_size < 0 ? takeProfitLineForShort[1] ? takeProfitLineForShort[1] :close[index] - takeProfitPoint * syminfo.mintick : na
// === /CALCURATES/ === //


// === CONDITIONS === //
//BB
bool isBbEntry = na
for i=0 to validLen
    isBbEntry := bbTrade==true ? true : bbTrade[i]==true ? true : false
//plotshape(isBbEntry, style=shape.circle, location=location.bottom)

isBbLong = isBbEntry and open[index] < smlBbBasis[index] and close[index] > smlBbBasis[index]
isBbShort = isBbEntry and open[index] > smlBbBasis[index] and close[index] < smlBbBasis[index]  

//SMT
isEmaLong = emaTrend == up 
isEmaShort = emaTrend == dn

//ATR
isAtrLongStop = low[index] <= stopLossLineForLong
isAtrShortStop = high[index] >= stopLossLineForShort
isAtrLongLimit = high[index] >= takeProfitLineForLong
isAtrShortLimit = low[index] <= takeProfitLineForShort
// === /CONDITIONS/ === //


// === TRADE === //
//ENTRY
if (isBbLong and isEmaLong)
    strategy.entry("LongEntry", strategy.long,  comment="LongEntry")
    if riskManagementRule == riskManagementRule2
        strategy.exit("LongEntry", loss=stopLossPoint, profit=takeProfitPoint, comment="bracket")
if (isBbShort and isEmaShort)
    strategy.entry("ShortEntry", strategy.short,  comment="ShortEntry")
    if riskManagementRule == riskManagementRule2	        
        strategy.exit("ShortEntry", loss=stopLossPoint, profit=takeProfitPoint, comment="bracket")
//EXIT
if riskManagementRule == riskManagementRule1
    if(isAtrLongStop)
        strategy.close("LongEntry", when=isAtrLongStop, comment="ATR Stop")
    if(isAtrShortStop)
        strategy.close("ShortEntry", when=isAtrShortStop, comment="ATR Stop")
    if(isAtrLongLimit)
        strategy.close("LongEntry", when=isAtrLongLimit, comment="ATR Limit")
    if(isAtrShortLimit)
        strategy.close("ShortEntry", when=isAtrShortLimit, comment="ATR Limit")
//  === /TRADE/ === //


// === PLOTS === //
plot(lrgBbBasis, title="Large BB Basis", linewidth=2, color=color.gray)
plot(lrgBbUpper, title="Large BB Upper", linewidth=2, color=color.gray)
plot(lrgBbLower, title="Large BB Lower", linewidth=2, color=color.gray)
plot(smlBbBasis, title="Small BB Basis", color=color.white)
plot(smlBbUpper, title="Small BB Upper", color=color.white)
plot(smlBbLower, title="Small BB Lower", color=color.white)
plot(base, title="EMA Line", color= emaTrend==dn ? color_bearish : emaTrend==up ? color_bullish : color.gray)

plot(stopLossLineForLong ? stopLossLineForLong : na, title="S/L Line For Long", color=color.yellow, style=plot.style_circles)
plot(stopLossLineForShort ? stopLossLineForShort : na, title="S/L Line For Short", color=color.yellow, style=plot.style_circles)
plot(takeProfitLineForLong ? takeProfitLineForLong : na, title="T/P Line For Long", color=color.purple, style=plot.style_circles)
plot(takeProfitLineForShort ? takeProfitLineForShort : na, title="T/P Line For Short", color=color.purple, style=plot.style_circles)
// /=== PLOTS ===/ //

Thêm nữa