Strategi perdagangan deviasi standar tertimbang

Penulis:ChaoZhang, Tanggal: 2023-11-24 13:54:58
Tag:

img

Gambaran umum

Strategi ini menggunakan indikator deviasi standar tertimbang dikombinasikan dengan rata-rata bergerak untuk menerapkan perdagangan tren pada cryptocurrency. Ini menghitung saluran harga deviasi standar tertimbang berdasarkan harga penutupan dan volume selama periode tertentu. Ketika harga menembus saluran atas atau bawah, posisi panjang atau pendek diambil. Kondisi stop loss dan take profit juga diatur untuk membatasi kerugian per perdagangan.

Logika Strategi

Kode ini mendefinisikan dua fungsi khusus untuk menghitung penyimpangan standar tertimbang dari deret waktu dan array.

  1. Menghitung harga rata-rata tertimbang berdasarkan harga penutupan dan volume
  2. Hitung kesalahan kuadrat dari setiap lilin vs harga rata-rata
  3. Menghitung varian berdasarkan ukuran sampel, bobot dan rata-rata disesuaikan
  4. Ambil akar kuadrat untuk mendapatkan standar deviasi

Ini memberi kita saluran yang berpusat pada harga rata-rata tertimbang, dengan batas atas dan bawah pada satu standar deviasi jauhnya.

Analisis Keuntungan

Keuntungan terbesar dari strategi ini adalah kombinasi dari analisis rata-rata bergerak dan volatilitas. MA menilai arah tren pasar sementara kisaran SD mendefinisikan band yang masuk akal - keduanya saling memverifikasi untuk keandalan yang lebih tinggi.

Stop loss dan take profit point lebih membantu trading dengan tren dan menghindari kerugian yang berlebihan pada pembalikan.

Analisis Risiko

Risiko utama adalah dari perubahan pasar yang keras. Hal ini dapat menyebabkan saluran SD berayun liar juga, membuat penilaian sulit. Juga, memilih periode yang terlalu pendek berisiko tertipu oleh kebisingan dan kesalahan.

Ukurannya adalah untuk meratakan parameter dan pengaturan periode dengan tepat. Pertimbangkan untuk menggabungkan indikator lain seperti RSI untuk meningkatkan konfirmasi pecah.

Arahan Optimasi

  1. Mengoptimalkan parameter periode - uji 5min, 15min, 30min dll untuk combo terbaik
  2. Mengoptimalkan rasio stop loss/take profit untuk hasil maksimal
  3. Tambahkan filter misalnya volume untuk menghindari pemutusan palsu
  4. Tambahkan filter candlestick pada harga penutupan, sumbu dll untuk meningkatkan akurasi

Kesimpulan

Strategi ini berhasil menggunakan indikator standar deviasi tertimbang bersama dengan MA untuk melacak tren cryptocurrency. pengaturan stop loss / take profit yang wajar juga membantu ritme pasar perdagangan dan menghindari kerugian pembalikan yang berlebihan. optimasi lebih lanjut melalui penyesuaian parameter dan konfirmasi multi-indikator dapat meningkatkan keandalan untuk strategi perdagangan algo yang solid.


/*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)

Lebih banyak