Chiến lược giao dịch độ lệch chuẩn có trọng số trung bình động


Ngày tạo: 2023-11-24 13:54:58 sửa đổi lần cuối: 2023-11-24 13:54:58
sao chép: 0 Số nhấp chuột: 773
1
tập trung vào
1617
Người theo dõi

Chiến lược giao dịch độ lệch chuẩn có trọng số trung bình động

Tổng quan

Chiến lược này sử dụng chỉ số chênh lệch tiêu chuẩn có trọng lượng, kết hợp với đường trung bình di chuyển, để thực hiện giao dịch xu hướng đối với tiền điện tử. Chiến lược tính toán kênh chênh lệch tiêu chuẩn có trọng lượng của giá dựa trên giá đóng cửa và khối lượng giao dịch trong một chu kỳ nhất định.

Nguyên tắc chiến lược

Có hai hàm tùy chỉnh được định nghĩa trong mã, tương ứng với chênh lệch chuẩn cân nặng tính toán từ chuỗi thời gian và mảng. Các bước chính là:

  1. Tính giá trung bình cân đối dựa trên giá đóng cửa và khối lượng giao dịch
  2. Tính bình phương của sự sai lệch của mỗi đường K với giá trị trung bình
  3. Tính chênh lệch theo số lượng mẫu và trọng lượng trung bình đã điều chỉnh
  4. Bảng mở có chênh lệch chuẩn

Do đó, chúng ta có một đường dẫn trung tâm ở giá trung bình trọng lượng, với khoảng cách từ trên xuống là một chênh lệch chuẩn. Khi giá từ bên dưới phá vỡ đáy của đường dẫn, hãy làm nhiều hơn; khi từ trên phá vỡ đỉnh của đường dẫn, hãy làm trống.

Phân tích lợi thế

Ưu điểm lớn nhất của chiến lược này là kết hợp giữa trung bình di chuyển và phân tích biến động. Trung bình di chuyển đánh giá xu hướng thị trường, chênh lệch chuẩn xác định khoảng cách hợp lý, cả hai đều được xác minh lẫn nhau và có độ tin cậy cao. Ngoài ra, trọng lượng giao dịch có thể lọc các đột phá giả mạo và xác suất đột phá thực tế cao hơn.

Chiến lược này cũng thiết lập điểm dừng lỗ, giúp nắm bắt xu hướng và tránh đảo ngược dẫn đến tổn thất quá lớn. Đây là một điểm quan trọng mà nhiều người mới bắt đầu không nắm được.

Phân tích rủi ro

Rủi ro chính là thị trường có thể biến động mạnh. Khi đó, kênh chênh lệch tiêu chuẩn cũng có thể biến động mạnh, không có lợi cho phán đoán. Ngoài ra, nếu chu kỳ lựa chọn quá ngắn, dễ bị nhiễu loạn bởi tiếng ồn, tỷ lệ sai sót cao.

Ngược lại, các tham số chu kỳ có thể được điều chỉnh thích hợp, và đường cong được làm mịn. Các chỉ số khác, chẳng hạn như RSI, cũng có thể được xem xét để tăng hiệu quả xác nhận đột phá.

Hướng tối ưu hóa

  1. Các tham số chu kỳ tối ưu hóa: có thể thử nghiệm các chu kỳ khác nhau như 5 phút, 15 phút, 30 phút để tìm kiếm sự kết hợp tốt nhất
  2. Tối ưu hóa tỷ lệ dừng lỗ. Kiểm tra các điểm dừng lỗ khác nhau để đạt được tỷ lệ lợi nhuận tối ưu
  3. Thêm các điều kiện lọc, chẳng hạn như kết hợp khối lượng giao thông, tránh phá vỡ giả tạo dẫn đến Loss
  4. Tăng các chỉ số chiết khấu, như xác nhận thực thể K-line bằng vị trí giá đóng cửa, chiều dài đường bóng, giảm tỷ lệ lỗi

Tóm tắt

Chiến lược này đã sử dụng thành công các chỉ số chênh lệch tiêu chuẩn có trọng lượng, hỗ trợ định hướng phán đoán bằng đường trung bình di chuyển, để theo dõi xu hướng đối với tiền điện tử. Đồng thời, thiết lập dừng lỗ hợp lý sẽ giúp nắm bắt nhịp độ thị trường và tránh bị tổn thất do đảo ngược quá mức. Có thể tối ưu hóa hơn nữa và hình thành chiến lược giao dịch định lượng đáng tin cậy thông qua điều chỉnh tham số và xác minh đa chỉ số.

Mã nguồn chiến lược
/*backtest
start: 2023-11-16 00:00:00
end: 2023-11-23 00:00:00
period: 45m
basePeriod: 5m
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/
// © rumpypumpydumpy   © cache_that_pass

//@version=4
strategy("[cache_that_pass] 1m 15m Function - Weighted Standard Deviation", overlay=true, pyramiding=0, default_qty_type=strategy.percent_of_equity, default_qty_value=20, initial_capital=10000, commission_type=strategy.commission.percent, commission_value=0.075)

f_weighted_sd_from_series(_src, _weight, _n) => //{
//  @function: Calculates weighted mean, variance, standard deviation, MSE and RMSE from time series variables
//  @parameters:
//      _src: time series variable of sample values
//      _weight: time series of corresponding weight values.
//      _n : number of samples
    _xw = _src * _weight
    _sum_weight = sum(_weight, _n)
    _mean = sum(_xw, _n) / _sum_weight
    float _sqerror_sum = 0
    int _nonzero_n = 0
    for _i = 0 to _n - 1
        _sqerror_sum := _sqerror_sum + pow(_mean - _src[_i], 2) * _weight[_i]
        _nonzero_n := _weight[_i] != 0 ? _nonzero_n + 1 : _nonzero_n
    _variance = _sqerror_sum / ((_nonzero_n - 1) * _sum_weight / _nonzero_n)
    _dev = sqrt(_variance)
    _mse = _sqerror_sum / _sum_weight
    _rmse = sqrt(_mse)
    [_mean, _variance, _dev, _mse, _rmse]
//}
// -----------------------------------------------------------------------------

f_weighted_sd_from_arrays(_a_src, _a_weight, _n) => //{
//  @function: Calculates weighted mean, variance, standard deviation, MSE and RMSE from arrays
//  Expects index 0 of the arrays to be the most recent sample and weight values!
//  @parameters:
//      _a_src: array of sample values
//      _a_weight: array of corresponding weight values.
//      _n : number of samples
    float _mean = na, float _variance = na, float _dev = na, float _mse = na
    float _rmse = na, float _sqerror_sum = na, float _sum_weight = na
    float[] _a_xw = array.new_float(_n)
    int _nonzero_n = 0
    if array.size(_a_src) >= _n
        _sum_weight := 0
        _sqerror_sum := 0
        for _i = 0 to _n - 1
            array.set(_a_xw, _i, array.get(_a_src, _i) * array.get(_a_weight, _i))
            _sum_weight := _sum_weight + array.get(_a_weight, _i)
            _nonzero_n := array.get(_a_weight, _i) != 0 ? _nonzero_n + 1 : _nonzero_n
        _mean := array.sum(_a_xw) / _sum_weight
        for _j = 0 to _n - 1
            _sqerror_sum := _sqerror_sum + pow(_mean - array.get(_a_src, _j), 2) * array.get(_a_weight, _j)
        _variance := _sqerror_sum / ((_nonzero_n - 1) * _sum_weight / _nonzero_n)
        _dev := sqrt(_variance)
        _mse := _sqerror_sum / _sum_weight
        _rmse := sqrt(_mse)
    [_mean, _variance, _dev, _mse, _rmse]
//}


// -----------------------------------------------------------------------------
// Example usage : 
// -----------------------------------------------------------------------------

len = input(20)

// -----------------------------------------------------------------------------
// From series :
// -----------------------------------------------------------------------------
[m, v, d, mse, rmse] = f_weighted_sd_from_series(close, volume, len)


plot(m, color = color.blue)
plot(m + d * 2, color = color.blue)
plot(m - d * 2, color = color.blue)
// -----------------------------------------------------------------------------



// -----------------------------------------------------------------------------
// From arrays : 
// -----------------------------------------------------------------------------
var float[] a_src = array.new_float()
var float[] a_weight = array.new_float()

if barstate.isfirst
    for i = 1 to len
        array.unshift(a_weight, i)

array.unshift(a_src, close)

if array.size(a_src) > len
    array.pop(a_src)

[a_m, a_v, a_d, a_mse, a_rmse] = f_weighted_sd_from_arrays(a_src, a_weight, len)

plot(a_m, color = color.orange)
plot(a_m + a_d * 2, color = color.orange)
plot(a_m - a_d * 2, color = color.orange)
// -----------------------------------------------------------------------------


series_text = "Mean : " + tostring(m) + "\nVariance : " + tostring(v) + "\nSD : " + tostring(d) + "\nMSE : " + tostring(mse) +  "\nRMSE : " + tostring(rmse)
array_text = "Mean : " + tostring(a_m) + "\nVariance : " + tostring(a_v) + "\nSD : " + tostring(a_d) + "\nMSE : " + tostring(a_mse) +  "\nRMSE : " + tostring(a_rmse)
debug_text = "Volume weighted from time series : \n" + series_text + "\n\nLinearly weighted from arrays : \n" + array_text

//debug = label.new(x = bar_index, y = close, text = debug_text, style = label.style_label_left)
//.delete(debug[1])

//test strategy
if low <= (m - d * 2)
    strategy.entry("LE", strategy.long)
if high >= (m + d * 2)
    strategy.entry("SE", strategy.short)

// User Options to Change Inputs (%)
stopPer = input(3.11, title='Stop Loss %', type=input.float) / 100
takePer = input(7.50, title='Take Profit %', type=input.float) / 100

// Determine where you've entered and in what direction
longStop = strategy.position_avg_price * (1 - stopPer)
shortStop = strategy.position_avg_price * (1 + stopPer)
shortTake = strategy.position_avg_price * (1 - takePer)
longTake = strategy.position_avg_price * (1 + takePer)

if strategy.position_size > 0 
    strategy.exit(id="Close Long", stop=longStop, limit=longTake)
//    strategy.close("LE", when = (longStop) or (longTake), qty_percent = 100)
if strategy.position_size < 0 
    strategy.exit(id="Close Short", stop=shortStop, limit=shortTake)
//    strategy.close("SE", when = (shortStop) or (shortTake), qty_percent = 100)