Đây là một chiến lược tạo ra thị trường sử dụng Bollinger Bands làm đầu vào, trung bình động làm đóng cửa và mức dừng lỗ đơn giản.
Chiến lược này sử dụng các dải trên và dưới của Bollinger Bands như là các khu vực cơ hội để nhập vào các vị trí. Cụ thể, khi giá dưới dải dưới, nó sẽ mở các vị trí dài; khi giá trên dải trên, nó sẽ mở các vị trí ngắn.
Ngoài ra, chiến lược cũng sử dụng trung bình động làm điểm chuẩn để đóng các vị trí. Khi nắm giữ các vị trí dài, nếu giá trên trung bình động, nó sẽ chọn đóng các vị trí dài; tương tự như vậy, khi nắm giữ các vị trí ngắn, nếu giá dưới trung bình động, nó cũng sẽ chọn đóng các vị trí ngắn.
Đối với việc dừng lỗ, nó sử dụng một tỷ lệ stoploss đơn giản dựa trên giá nhập cảnh. Điều này có thể ngăn ngừa thiệt hại lớn trong các thị trường xu hướng.
Những lợi thế chính của chiến lược này là:
Ngoài ra còn có một số rủi ro với chiến lược này:
Để giảm thiểu những rủi ro này, chúng ta có thể xem xét thêm các bộ lọc khác, tối ưu hóa cài đặt dừng lỗ hoặc hạn chế đúng kích thước vị trí.
Có chỗ cho việc tối ưu hóa thêm:
Nhìn chung, đây là một chiến lược tạo thị trường tần số cao rất có lợi nhuận. Nó tận dụng các băng Bollinger cho các tín hiệu giao dịch và kiểm soát rủi ro. Nhưng chúng ta cũng cần phải nhận thức được những khiếm khuyết của nó và xác minh cẩn thận trong giao dịch trực tiếp. Với các tối ưu hóa hơn nữa, chiến lược này có tiềm năng tạo ra lợi nhuận thậm chí ổn định hơn và lớn hơn.
/*backtest start: 2023-12-24 00:00:00 end: 2024-01-23 00:00:00 period: 1h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=3 strategy(shorttitle="BBL", title="BB limit", overlay = true) length = input(200, minval=1) src = input(hlc3, title="Source") xmult = input(44, minval=0.001, maxval=5000, title = "bb mult (0.1%)") s = input(title="Trend source", defval = "sma", options = ["ema", "sma", "rma", "wma"]) basis = s == "ema" ? ema(src, length) : s == "sma" ? sma(src, length) : s =="rma" ? rma(src, length) : wma(src, length) sd = input(title="Dev source", defval = "stdev", options = ["stdev", "dev"]) mult = xmult / 10 dev = sd == "stdev" ? mult * stdev(src, length) : mult * dev(src, length) diff = input(0.5, title = "Spread") LongPrice(p) => LongPrice = diff == 0 ? p : floor(p / diff) * diff ShortPrice(p) => ShortPrice = diff == 0 ? p : ceil(p / diff) * diff pyr = input(1, title = "Pyramiding") useStopLoss = input(true) stoploss_xmult = input(15, minval=0.001, maxval=5000, title = "StopLoss 0.1%") stopLoss_mult = sd == "simple" ? 1 + stoploss_xmult / 10 / 100 : stoploss_xmult / 10 dev2 = sd == "stdev" ? stopLoss_mult * stdev(src, length) : sd == "dev" ? stopLoss_mult * dev(src, length) : (stopLoss_mult - 1) * basis upper = basis + (1*dev) lower = basis - (1*dev) plot(basis, color=fuchsia, linewidth=2) plot(upper, color=green, linewidth=2) plot(lower, color=green, linewidth=2) strategy.cancel_all() if strategy.position_size > 0 and close <= basis + diff * 2 strategy.order("Close long", strategy.short, strategy.position_size, limit = ShortPrice(basis)) else if strategy.position_size < 0 and close >= basis - diff * 2 strategy.order("Close short", strategy.long, -strategy.position_size, limit = LongPrice(basis)) stopLossPrice1 = na stopLossPrice2 = na add = na openOrderCondition = close > lower - 2 * diff and (strategy.opentrades < pyr or (strategy.position_size < 0 and strategy.position_avg_price > lower * (1 + stopLoss_mult / 100))) if openOrderCondition add := strategy.position_size > 0 ? -strategy.position_size : close >= basis - diff * 2 ? 0 : -strategy.position_size strategy.order("Open long", strategy.long, strategy.equity / pyr / lower + add, limit = LongPrice(lower)) if useStopLoss and (strategy.position_size > 0 or openOrderCondition) add = openOrderCondition ? strategy.equity / pyr / lower : 0 posPrice = strategy.position_size <= 0 ? lower : strategy.position_avg_price posSize = strategy.position_size <= 0 ? 0 : strategy.position_size stopLossPrice1 := posPrice * (1 - stopLoss_mult / 100) strategy.order("StopLoss open short ", strategy.short, posSize + add + strategy.equity / pyr / stopLossPrice1, stop = ShortPrice(stopLossPrice1)) openOrderCondition := close < upper + 2 * diff and (strategy.opentrades < pyr or (strategy.position_size > 0 and strategy.position_avg_price * (1 + stopLoss_mult / 100) < upper)) if openOrderCondition add := strategy.position_size < 0 ? strategy.position_size : close <= basis + diff * 2 ? 0 : strategy.position_size strategy.order("Open short", strategy.short, strategy.equity / pyr / upper + add, limit = ShortPrice(upper)) if useStopLoss and (strategy.position_size < 0 or openOrderCondition) add = openOrderCondition ? strategy.equity / pyr / upper : 0 posPrice = strategy.position_size >= 0 ? upper : strategy.position_avg_price posSize = strategy.position_size >= 0 ? 0 : -strategy.position_size stopLossPrice2 := posPrice * (1 + stopLoss_mult / 100) strategy.order("StopLoss open long", strategy.long, posSize + add + strategy.equity / pyr / stopLossPrice2, stop = LongPrice(stopLossPrice2)) plot(not useStopLoss ? na : stopLossPrice1, color=red, linewidth=2) plot(not useStopLoss ? na : stopLossPrice2, color=red, linewidth=2) // === Backtesting Dates === testPeriodSwitch = input(false, "Custom Backtesting Dates") testStartYear = input(2018, "Backtest Start Year") testStartMonth = input(1, "Backtest Start Month") testStartDay = input(1, "Backtest Start Day") testStartHour = input(0, "Backtest Start Hour") testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay,testStartHour,0) testStopYear = input(2018, "Backtest Stop Year") testStopMonth = input(12, "Backtest Stop Month") testStopDay = input(14, "Backtest Stop Day") testStopHour = input(14, "Backtest Stop Hour") testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay,testStopHour,0) testPeriod() => time >= testPeriodStart and time <= testPeriodStop ? true : false isPeriod = testPeriodSwitch == true ? testPeriod() : true // === /END if not isPeriod strategy.cancel_all() strategy.close_all()