Chiến lược này xây dựng một phong bì biến động năng động dựa trên phương pháp hồi quy hạt nhân Nadaraya-Watson để tạo ra các tín hiệu giao dịch mua thấp và bán cao bằng cách theo dõi các tình huống chéo giữa giá và dải phong bì. Với một khuôn khổ phân tích toán học, chiến lược có thể thích nghi với những thay đổi của thị trường.
Cốt lõi của chiến lược là tính toán phong bì động của giá. Đầu tiên, bằng cách sử dụng cửa sổ nhìn lại tùy chỉnh, nó xây dựng các đường cong hồi quy hạt nhân Nadaraya-Watson của giá (gần, cao, thấp) để có được ước tính giá mượt mà. Sau đó nó tính toán ATR dựa trên chiều dài ATR tùy chỉnh, và tạo thành các dải phong bì trên và dưới với các yếu tố gần và xa. Khi giá phá vỡ phong bì từ dưới, một tín hiệu mua được tạo ra. Khi giá phá vỡ phong bì từ trên, một tín hiệu bán được kích hoạt. Bằng cách theo dõi mối quan hệ năng động giữa giá và các thuộc tính thống kê liên quan đến biến động, chiến lược điều chỉnh các quyết định giao dịch của nó một cách thích nghi.
Tối ưu hóa thích hợp, kiểm tra hậu quả đầy đủ, hiểu các yếu tố chính và định giá vị trí thận trọng trong giao dịch trực tiếp có thể giúp giảm thiểu những rủi ro này.
Chiến lược này kết hợp phân tích thống kê và phân tích chỉ số kỹ thuật để tạo ra tín hiệu giao dịch bằng cách theo dõi động mối quan hệ giữa giá và biến động. Các tham số có thể được điều chỉnh dựa trên điều kiện thị trường và nhu cầu cá nhân. Nhìn chung, mặc dù nền tảng lý thuyết vững chắc, hiệu suất thực tế của nó vẫn cần xác minh thêm. Người ta nên xử lý nó một cách thận trọng và giao dịch thận trọng.
/*backtest start: 2022-12-04 00:00:00 end: 2023-12-10 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ // © Julien_Eche //@version=5 strategy("Nadaraya-Watson Envelope Strategy", overlay=true, pyramiding=1, default_qty_type=strategy.percent_of_equity, default_qty_value=20) // Helper Functions getEnvelopeBounds(_atr, _nearFactor, _farFactor, _envelope) => _upperFar = _envelope + _farFactor*_atr _upperNear = _envelope + _nearFactor*_atr _lowerNear = _envelope - _nearFactor*_atr _lowerFar = _envelope - _farFactor*_atr _upperAvg = (_upperFar + _upperNear) / 2 _lowerAvg = (_lowerFar + _lowerNear) / 2 [_upperNear, _upperFar, _upperAvg, _lowerNear, _lowerFar, _lowerAvg] customATR(length, _high, _low, _close) => trueRange = na(_high[1])? math.log(_high)-math.log(_low) : math.max(math.max(math.log(_high) - math.log(_low), math.abs(math.log(_high) - math.log(_close[1]))), math.abs(math.log(_low) - math.log(_close[1]))) ta.rma(trueRange, length) customKernel(x, h, alpha, x_0) => sumWeights = 0.0 sumXWeights = 0.0 for i = 0 to h weight = math.pow(1 + (math.pow((x_0 - i), 2) / (2 * alpha * h * h)), -alpha) sumWeights := sumWeights + weight sumXWeights := sumXWeights + weight * x[i] sumXWeights / sumWeights // Custom Settings customLookbackWindow = input.int(8, 'Lookback Window (Custom)', group='Custom Settings') customRelativeWeighting = input.float(8., 'Relative Weighting (Custom)', step=0.25, group='Custom Settings') customStartRegressionBar = input.int(25, "Start Regression at Bar (Custom)", group='Custom Settings') // Envelope Calculations customEnvelopeClose = math.exp(customKernel(math.log(close), customLookbackWindow, customRelativeWeighting, customStartRegressionBar)) customEnvelopeHigh = math.exp(customKernel(math.log(high), customLookbackWindow, customRelativeWeighting, customStartRegressionBar)) customEnvelopeLow = math.exp(customKernel(math.log(low), customLookbackWindow, customRelativeWeighting, customStartRegressionBar)) customEnvelope = customEnvelopeClose customATRLength = input.int(60, 'ATR Length (Custom)', minval=1, group='Custom Settings') customATR = customATR(customATRLength, customEnvelopeHigh, customEnvelopeLow, customEnvelopeClose) customNearATRFactor = input.float(1.5, 'Near ATR Factor (Custom)', minval=0.5, step=0.25, group='Custom Settings') customFarATRFactor = input.float(2.0, 'Far ATR Factor (Custom)', minval=1.0, step=0.25, group='Custom Settings') [customUpperNear, customUpperFar, customUpperAvg, customLowerNear, customLowerFar, customLowerAvg] = getEnvelopeBounds(customATR, customNearATRFactor, customFarATRFactor, math.log(customEnvelopeClose)) // Colors customUpperBoundaryColorFar = color.new(color.red, 60) customUpperBoundaryColorNear = color.new(color.red, 80) customBullishEstimatorColor = color.new(color.teal, 50) customBearishEstimatorColor = color.new(color.red, 50) customLowerBoundaryColorNear = color.new(color.teal, 80) customLowerBoundaryColorFar = color.new(color.teal, 60) // Plots customUpperBoundaryFar = plot(math.exp(customUpperFar), color=customUpperBoundaryColorFar, title='Upper Boundary: Far (Custom)') customUpperBoundaryAvg = plot(math.exp(customUpperAvg), color=customUpperBoundaryColorNear, title='Upper Boundary: Average (Custom)') customUpperBoundaryNear = plot(math.exp(customUpperNear), color=customUpperBoundaryColorNear, title='Upper Boundary: Near (Custom)') customEstimationPlot = plot(customEnvelopeClose, color=customEnvelope > customEnvelope[1] ? customBullishEstimatorColor : customBearishEstimatorColor, linewidth=2, title='Custom Estimation') customLowerBoundaryNear = plot(math.exp(customLowerNear), color=customLowerBoundaryColorNear, title='Lower Boundary: Near (Custom)') customLowerBoundaryAvg = plot(math.exp(customLowerAvg), color=customLowerBoundaryColorNear, title='Lower Boundary: Average (Custom)') customLowerBoundaryFar = plot(math.exp(customLowerFar), color=customLowerBoundaryColorFar, title='Lower Boundary: Far (Custom)') // Fills fill(customUpperBoundaryFar, customUpperBoundaryAvg, color=customUpperBoundaryColorFar, title='Upper Boundary: Farmost Region (Custom)') fill(customUpperBoundaryNear, customUpperBoundaryAvg, color=customUpperBoundaryColorNear, title='Upper Boundary: Nearmost Region (Custom)') fill(customLowerBoundaryNear, customLowerBoundaryAvg, color=customLowerBoundaryColorNear, title='Lower Boundary: Nearmost Region (Custom)') fill(customLowerBoundaryFar, customLowerBoundaryAvg, color=customLowerBoundaryColorFar, title='Lower Boundary: Farmost Region (Custom)') longCondition = ta.crossover(close, customEnvelopeLow) if (longCondition) strategy.entry("Buy", strategy.long) exitLongCondition = ta.crossover(customEnvelopeHigh, close) if (exitLongCondition) strategy.close("Buy")