Chiến lược giao dịch nhiều khung thời gian P-Signal là một chiến lược giao dịch thuật toán tiền điện tử dựa trên các nguyên tắc thống kê và phân tích nhiều khung thời gian. Chiến lược sử dụng hàm lỗi Gaussian và chỉ số P-Signal để mô hình phù hợp với biểu đồ hàng ngày, hàng tuần và hàng tháng của Bitcoin, và đi dài trên các đường chéo chỉ số trên 0 và thoát ra trên các đường chéo dưới 0, để giao dịch biến động.
Chỉ số cốt lõi của chiến lược P-Signal là chính P-Signal, kết hợp sai lệch chuẩn thống kê và trung bình di chuyển đơn giản và lập bản đồ nó vào phạm vi -1 đến 1 bằng chức năng lỗi Gauss, để phát hiện xem thị trường có phù hợp với phân bố bình thường hay không.
fErf(x) = 1.0 - 1.0/(1.0 + 0.5*abs(x)) * exp(-x*x - 1.26551223 + ...) # Gaussian error function
fPSignal(ser, n) = fErf((stdev(ser, n) > 0 ? sma(ser, n)/stdev(ser, n)/sqrt(2) : 1)) # P-Signal indicator
Chiến lược tính toán chỉ số P-Signal trên khung thời gian hàng ngày, hàng tuần và hàng tháng cho Bitcoin, đi dài khi chỉ số vượt trên 0, và thoát khi nó vượt xuống dưới 0.
Lợi thế lớn nhất của chiến lược P-Signal là việc sử dụng nhiều khung thời gian để cải thiện sự ổn định của chiến lược. Biểu đồ hàng ngày nắm bắt biến động thị trường ngắn hạn, trong khi các biểu đồ hàng tuần và hàng tháng lọc các đột phá sai.
So với một khung thời gian duy nhất, nhiều khung thời gian cho phép sử dụng các điểm dừng hàng ngày để kiểm soát giảm trong thời gian biến động, trong khi giảm tần suất giao dịch bằng cách sử dụng các khung thời gian cao hơn trong các thị trường dao động.
Rủi ro lớn nhất của chiến lược P-Signal là chỉ số chính nó là một hộp đen cho các nhà giao dịch lượng. Chúng tôi không có cách nào để xác định khả năng thích nghi của chỉ số này với các thị trường cụ thể, cũng không thể xác định phạm vi tối ưu của các thông số của nó. Điều này có thể dẫn đến hiệu suất kém của chiến lược trong giao dịch trực tiếp.
Ngoài ra, chính chiến lược có một số hạn chế. Ví dụ, không có khả năng xử lý các động thái bạo lực, tín hiệu chậm từ giao thoa chỉ số vv. Tất cả những điều này có thể trở thành những rắc rối ẩn trong giao dịch trực tiếp.
Để giải quyết các vấn đề này, chúng ta có thể điều chỉnh các tham số chỉ số, tối ưu hóa stop loss, giới thiệu nhiều chỉ số phụ trợ hơn vv Nhưng tiền đề là để kiểm tra sự ổn định trên các khoảng thời gian kiểm tra ngược đủ lớn.
Có một số hướng để tối ưu hóa chiến lược P-Signal:
Thay đổi các thông số chỉ số P-Signal: nIntr_D, nIntr_W và nIntr_M, tìm kết hợp thông số tối ưu
Thêm các phương pháp dừng lỗ: dừng lỗ theo dõi, dừng lỗ thời gian, dừng lỗ ATR vv, tìm lỗ dừng tối ưu
Đưa ra các chỉ số phụ trợ: cải thiện đánh giá các điều kiện thị trường cụ thể, ví dụ: sử dụng MACD để xác định xu hướng
Tối ưu hóa kích thước vị trí: đặt kích thước vị trí động dựa trên hiệu quả sử dụng tài khoản
Tối ưu hóa học máy: sử dụng mạng thần kinh, thuật toán di truyền để tìm các thông số tối ưu trên toàn cầu
Chiến lược giao dịch đa khung thời gian P-Signal nói chung là một ý tưởng chiến lược rất hứa hẹn. Nó kết hợp các nguyên tắc thống kê và các chỉ số kỹ thuật, và sử dụng phân tích nhiều khung thời gian để cải thiện sự ổn định. Nếu chúng ta có thể giải quyết một số hạn chế thông qua kiểm tra và tối ưu hóa rộng rãi, thì hoàn toàn có thể biến nó thành một chiến lược giao dịch thuật toán tiền điện tử thực tế, có thể sử dụng.
/*backtest start: 2022-11-21 00:00:00 end: 2023-11-27 00:00:00 period: 1d basePeriod: 1h 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/ // P-Signal Strategy © Kharevsky // A good strategy should be able to handle backtesting. // @version=4 // ********************************************************************************************************** strategy("P-Signal Strategy:", precision = 3, pyramiding = 3) // // Parameters and const of P-Signal. // nPoints_D = input(title = "Number of D Bars", type = input.integer, defval = 9, minval = 4, maxval = 100, group = "Parameters of observation.") nPoints_W = input(title = "Number of W Bars", type = input.integer, defval = 4, minval = 4, maxval = 100, group = "Parameters of observation.") nPoints_M = input(title = "Number of M Bars", type = input.integer, defval = 6, minval = 4, maxval = 100, group = "Parameters of observation.") int nIntr_D = nPoints_D - 1 int nIntr_W = nPoints_W - 1 int nIntr_M = nPoints_M - 1 bool bDValveOpen = true bool bWValveOpen = true bool bMValveOpen = true // // Horner's method for the error (Gauss) & P-Signal functions. // fErf(x) => nT = 1.0/(1.0 + 0.5*abs(x)) nAns = 1.0 - nT*exp(-x*x - 1.26551223 + nT*( 1.00002368 + nT*( 0.37409196 + nT*( 0.09678418 + nT*(-0.18628806 + nT*( 0.27886807 + nT*(-1.13520398 + nT*( 1.48851587 + nT*(-0.82215223 + nT*( 0.17087277 )))))))))) x >= 0 ? nAns : -nAns fPSignal(ser, int) => nStDev = stdev(ser, int) nSma = sma(ser, int) fErf(nStDev > 0 ? nSma/nStDev/sqrt(2) : 1.0) // // Signals for the strategy. // float nPSignal_D = sma(fPSignal(change(ohlc4), nIntr_D), nIntr_D) float ndPSignal_D = sign(nPSignal_D[0] - nPSignal_D[1]) // float nPSignal_W = sma(security(syminfo.tickerid, "W",fPSignal(change(ohlc4), nIntr_W)), nIntr_W) float ndPSignal_W = sign(nPSignal_W[0] - nPSignal_W[1]) // float nPSignal_M = sma(security(syminfo.tickerid, "M",fPSignal(change(ohlc4), nIntr_M)), nIntr_M) float ndPSignal_M = sign(nPSignal_M[0] - nPSignal_M[1]) // // P-Signal plotting. // hline(+1.0, color = color.new(color.orange,70), linestyle = hline.style_dotted) hline(-1.0, color = color.new(color.orange,70), linestyle = hline.style_dotted) plot(nPSignal_D, color = color.blue, style = plot.style_line) // // Multi Frame Strategy // ... Day if(nPSignal_D < 0 and ndPSignal_D > 0 and bDValveOpen) strategy.entry("long_D", strategy.long, 1) bDValveOpen := false if(nPSignal_D > 0 and ndPSignal_D < 0) strategy.close("long_D") bDValveOpen := true // ... Week if(nPSignal_W < 0 and ndPSignal_W > 0 and bWValveOpen) strategy.entry("long_W", strategy.long, 1) bWValveOpen := false if(nPSignal_W > 0 and ndPSignal_W < 0) strategy.close("long_W") bWValveOpen := true // ... Month if(nPSignal_M < 0 and ndPSignal_M > 0 and bMValveOpen) strategy.entry("long_M", strategy.long, 1) bMValveOpen := false if(nPSignal_M > 0 and ndPSignal_M < 0) strategy.close("long_M") bMValveOpen := true // The end.