Chiến lược giao dịch sai lệch chuẩn cân nhắc

Tác giả:ChaoZhang, Ngày: 2023-11-24 13:54:58
Tags:

img

Tổng quan

Chiến lược này sử dụng chỉ số lệch chuẩn cân kết hợp với trung bình động để thực hiện giao dịch xu hướng trên tiền điện tử. Nó tính toán một kênh giá lệch chuẩn cân dựa trên giá đóng cửa và khối lượng trong một khoảng thời gian nhất định. Khi giá vượt qua kênh trên hoặc dưới, các vị trí dài hoặc ngắn được thực hiện. Điều kiện dừng lỗ và lấy lợi nhuận cũng được thiết lập để hạn chế lỗ cho mỗi giao dịch.

Chiến lược logic

Mã xác định hai hàm tùy chỉnh để tính lệch chuẩn cân nhắc từ chuỗi thời gian và mảng.

  1. Tính toán giá trung bình trọng số dựa trên giá đóng cửa và khối lượng
  2. Tính toán sai số bình phương của mỗi nến so với giá trung bình
  3. Tính toán biến thể dựa trên kích thước mẫu, trọng lượng và trung bình điều chỉnh
  4. Lấy gốc vuông để lấy độ lệch chuẩn

Điều này cung cấp cho chúng ta một kênh tập trung vào giá trung bình cân nhắc, với giới hạn trên và dưới cách nhau một độ lệch chuẩn. Khi giá vượt qua kênh dưới từ dưới, đi dài. Khi nó vượt qua đỉnh từ trên, đi ngắn.

Phân tích lợi thế

Lợi thế lớn nhất của chiến lược này là sự kết hợp giữa trung bình động và phân tích biến động. MA đánh giá hướng xu hướng thị trường trong khi phạm vi SD xác định một dải hợp lý - cả hai đều xác minh lẫn nhau để có độ tin cậy cao hơn. Ngoài ra, trọng lượng khối lượng giúp lọc các đột phá sai để có khả năng thành công cao hơn trên các đột phá thực tế.

Các điểm dừng lỗ và lấy lợi nhuận tiếp tục giúp giao dịch theo xu hướng và tránh thua lỗ quá mức khi đảo ngược.

Phân tích rủi ro

Rủi ro chính là do biến động thị trường dữ dội. Điều này có thể khiến kênh SD cũng dao động điên cuồng, làm cho việc đánh giá khó khăn. Ngoài ra, việc chọn thời gian quá ngắn có nguy cơ bị đánh lừa bởi tiếng ồn và lỗi.

Cách khắc phục là làm mịn các thông số và cài đặt thời gian một cách thích hợp.

Hướng dẫn tối ưu hóa

  1. Tối ưu hóa các thông số thời gian - thử nghiệm 5min, 15min, 30min vv cho kết hợp tốt nhất
  2. Tối ưu hóa tỷ lệ dừng lỗ / lấy lợi nhuận để có lợi nhuận tối đa
  3. Thêm bộ lọc ví dụ như âm lượng để tránh vỡ sai
  4. Thêm các bộ lọc nến trên giá đóng cửa, mèo vv để cải thiện độ chính xác

Kết luận

Chiến lược này sử dụng thành công chỉ số lệch chuẩn cân bằng cùng với MA để theo dõi xu hướng tiền điện tử. Các thiết lập dừng lỗ / lấy lợi nhuận hợp lý cũng giúp nhịp thị trường giao dịch và tránh tổn thất đảo ngược quá mức. Tăng cường hơn nữa thông qua điều chỉnh tham số và xác nhận đa chỉ số có thể cải thiện độ tin cậy cho một chiến lược giao dịch algo vững chắ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)

Thêm nữa