Chiến lược này là một hệ thống giao dịch dựa trên Bollinger Bands và phân tích mô hình nến, được thiết kế để nắm bắt sự đảo ngược thị trường bằng cách phân tích biến động giá và đặc điểm nến trên khung thời gian hàng ngày. Phương pháp cốt lõi kết hợp các kênh biến động Bollinger Bands
Chiến lược này sử dụng 20 giai đoạn Bollinger Bands như là chỉ số kỹ thuật chính với nhân lệ lệch tiêu chuẩn là 2.0. Bằng cách tính toán tỷ lệ giữa bóng và cơ thể nến, hệ thống tạo ra tín hiệu giao dịch khi tỷ lệ này vượt quá ngưỡng thiết lập (bên định sẵn 1.0) và giá chạm vào ranh giới Bollinger Band. Thời gian vào có thể được lựa chọn linh hoạt tại đóng hàng ngày, mở ngày hôm sau, cao hàng ngày hoặc thấp. Chiến lược bao gồm một hệ thống quản lý rủi ro dựa trên số dư tài khoản, kiểm soát rủi ro thông qua kích thước vị trí động.
Đây là một hệ thống giao dịch toàn diện kết hợp Bollinger Bands và phân tích nến để nắm bắt các cơ hội đảo ngược thị trường. Sức mạnh của chiến lược nằm trong khuôn khổ phân tích toàn diện và hệ thống quản lý rủi ro mạnh mẽ, trong khi phải chú ý đến điều kiện thị trường và tác động lựa chọn tham số. Thông qua các hướng tối ưu hóa được đề xuất, sự ổn định và độ tin cậy của chiến lược có thể được tăng thêm. Đối với việc thực hiện giao dịch trực tiếp, việc kiểm tra kỹ lưỡng và tối ưu hóa tham số được khuyến cáo, với các điều chỉnh được thực hiện theo các đặc điểm cụ thể của công cụ giao dịch.
/*backtest start: 2023-11-29 00:00:00 end: 2024-11-28 00:00:00 period: 1d basePeriod: 1d exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=5 strategy("Trade Entry Detector, based on Wick to Body Ratio when price tests Bollinger Bands", overlay=true, default_qty_type=strategy.fixed) // Input for primary analysis time frame timeFrame = "D" // Daily time frame // Bollinger Band settings length = input.int(20, title="Bollinger Band Length", minval=1) mult = input.float(2.0, title="Standard Deviation Multiplier", minval=0.1) source = input(close, title="Source") // Entry ratio settings wickToBodyRatio = input.float(1.0, title="Minimum Wick-to-Body Ratio", minval=0) // Order Fill Timing Option fillOption = input.string("Daily Close", title="Order Fill Timing", options=["Daily Close", "Daily Open", "HOD", "LOD"]) // Account and risk settings accountBalance = 100000 // Account balance in dollars riskPercentage = 1.0 // Risk percentage per trade riskAmount = (riskPercentage / 100) * accountBalance // Fixed 1% risk amount // Request daily data for calculations dailyHigh = request.security(syminfo.tickerid, timeFrame, high) dailyLow = request.security(syminfo.tickerid, timeFrame, low) dailyClose = request.security(syminfo.tickerid, timeFrame, close) dailyOpen = request.security(syminfo.tickerid, timeFrame, open) // Calculate Bollinger Bands on the daily time frame dailyBasis = request.security(syminfo.tickerid, timeFrame, ta.sma(source, length)) dailyDev = mult * request.security(syminfo.tickerid, timeFrame, ta.stdev(source, length)) dailyUpperBand = dailyBasis + dailyDev dailyLowerBand = dailyBasis - dailyDev // Calculate the body and wick sizes on the daily time frame dailyBodySize = math.abs(dailyOpen - dailyClose) dailyUpperWickSize = dailyHigh - math.max(dailyOpen, dailyClose) dailyLowerWickSize = math.min(dailyOpen, dailyClose) - dailyLow // Conditions for a candle with an upper wick or lower wick that touches the Bollinger Bands upperWickCondition = (dailyUpperWickSize / dailyBodySize >= wickToBodyRatio) and (dailyHigh > dailyUpperBand) lowerWickCondition = (dailyLowerWickSize / dailyBodySize >= wickToBodyRatio) and (dailyLow < dailyLowerBand) // Define the swing high and swing low for stop loss placement var float swingLow = na var float swingHigh = na if (ta.pivothigh(dailyHigh, 5, 5)) swingHigh := dailyHigh[5] if (ta.pivotlow(dailyLow, 5, 5)) swingLow := dailyLow[5] // Determine entry price based on chosen fill option var float longEntryPrice = na var float shortEntryPrice = na if lowerWickCondition longEntryPrice := fillOption == "Daily Close" ? dailyClose : fillOption == "Daily Open" ? dailyOpen : fillOption == "HOD" ? dailyHigh : dailyLow if upperWickCondition shortEntryPrice := fillOption == "Daily Close" ? dailyClose : fillOption == "Daily Open" ? dailyOpen : fillOption == "HOD" ? dailyHigh : dailyLow // Execute the long and short entries with expiration var int longOrderExpiry = na var int shortOrderExpiry = na if not na(longEntryPrice) longOrderExpiry := bar_index + 2 // Order expires after 2 days if not na(shortEntryPrice) shortOrderExpiry := bar_index + 2 // Order expires after 2 days // Check expiration and execute orders if (longEntryPrice and bar_index <= longOrderExpiry and high >= longEntryPrice) longStopDistance = close - nz(swingLow, close) longPositionSize = longStopDistance > 0 ? riskAmount / longStopDistance : na if (not na(longPositionSize)) strategy.entry("Long", strategy.long, qty=longPositionSize) longEntryPrice := na // Reset after entry if (shortEntryPrice and bar_index <= shortOrderExpiry and low <= shortEntryPrice) shortStopDistance = nz(swingHigh, close) - close shortPositionSize = shortStopDistance > 0 ? riskAmount / shortStopDistance : na if (not na(shortPositionSize)) strategy.entry("Short", strategy.short, qty=shortPositionSize) shortEntryPrice := na // Reset after entry // Exit logic: hit the opposing Bollinger Band if (strategy.position_size > 0) // Long position strategy.exit("Exit Long", "Long", limit=dailyUpperBand) else if (strategy.position_size < 0) // Short position strategy.exit("Exit Short", "Short", limit=dailyLowerBand) if (strategy.position_size > 0) // Long position strategy.exit("Stop Loss Long", "Long", stop=swingLow) else if (strategy.position_size < 0) // Short position strategy.exit("Stop Loss Short", "Short", stop=swingHigh) // Plot daily Bollinger Bands and levels on the chosen time frame plot(dailyUpperBand, color=color.blue, linewidth=1, title="Daily Upper Bollinger Band") plot(dailyLowerBand, color=color.blue, linewidth=1, title="Daily Lower Bollinger Band") plot(dailyBasis, color=color.gray, linewidth=1, title="Daily Middle Bollinger Band")