Đây là một chiến lược theo xu hướng dựa trên Bollinger Bands và phân tích mô hình nến. Chiến lược chủ yếu xác định các điểm đảo ngược thị trường tiềm năng bằng cách quan sát các mô hình nến khi giá chạm vào Bollinger Bands, kết hợp với mối quan hệ tỷ lệ giữa nến và cơ thể. Ngoài ra, chiến lược sử dụng một mô hình rủi ro cố định để kiểm soát rủi ro cho mỗi giao dịch và sử dụng phân tích khung thời gian đa để tăng độ chính xác giao dịch.
Lý thuyết cốt lõi của chiến lược dựa trên một số yếu tố chính: Thứ nhất, nó tính Bollinger Bands trong 20 giai đoạn để xác định phạm vi biến động giá; thứ hai, khi giá chạm vào Bollinger Bands, nó phân tích tỷ lệ giữa các nến trên / dưới và thân của nến, xem nó như một tín hiệu đảo ngược tiềm năng khi tỷ lệ vượt quá ngưỡng đặt; thứ ba, nó tính toán các mức hỗ trợ và kháng cự chính cho việc đặt dừng lỗ; Cuối cùng, nó tính toán kích thước vị trí cho mỗi giao dịch dựa trên một tỷ lệ phần trăm cố định (1%) số dư tài khoản, thực hiện quản lý rủi ro năng động. Chiến lược cũng cung cấp các tùy chọn thời gian khác nhau, bao gồm giá đóng, giá mở, giá cao và giá thấp hàng ngày.
Chiến lược này kết hợp các công cụ phân tích kỹ thuật cổ điển với các phương pháp quản lý rủi ro hiện đại để xây dựng một hệ thống giao dịch tương đối toàn diện. Những lợi thế cốt lõi nằm trong việc kiểm soát rủi ro nghiêm ngặt và cơ chế nhập cảnh linh hoạt, trong khi cần chú ý đến những thay đổi môi trường thị trường và xác minh độ tin cậy tín hiệu trong các ứng dụng thực tế. Thông qua các hướng tối ưu hóa được đề xuất, có chỗ để cải thiện hơn nữa, đặc biệt là trong các khía cạnh lọc tín hiệu và quản lý rủi ro.
/*backtest start: 2024-01-01 00:00:00 end: 2024-11-26 00:00:00 period: 12h basePeriod: 12h 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")