Ini adalah strategi perdagangan kuantitatif eksperimen

Penulis:ChaoZhang, Tarikh: 2023-12-22 14:13:27
Tag:

img

Ringkasan

Ini adalah strategi perdagangan kuantitatif eksperimen yang menggabungkan penunjuk purata bergerak dan algoritma pembelajaran mesin kNN untuk menjana isyarat perdagangan. Ia menggunakan persilangan dua garis VWMA dengan tempoh yang berbeza untuk menentukan arah trend, dan menggunakan penunjuk MFI dan ADX untuk menapis isyarat melalui algoritma kNN untuk meningkatkan kebolehpercayaan isyarat.

Prinsip Strategi

Indikator teras strategi ini adalah dua garis VWMA dengan parameter yang berbeza, iaitu garis pantas dan garis perlahan. Apabila garis pantas melintasi di atas garis perlahan, isyarat beli dihasilkan. Apabila garis pantas melintasi di bawah garis perlahan, isyarat jual dihasilkan. Di samping itu, strategi ini memperkenalkan dua penunjuk tambahan, MFI dan ADX, untuk menilai kebolehpercayaan isyarat semasa di bawah keadaan pasaran semasa melalui algoritma klasifikasi kNN.

Idea di sebalik algoritma kNN adalah untuk membandingkan data baru dengan data sejarah untuk menentukan hasil yang sepadan dengan k data sejarah yang paling serupa, dan mengkategorikan berdasarkan undi majoriti k hasil sejarah ini.

Kelebihan

  • Menggunakan keupayaan trend berikut VWMA dan menjana isyarat dagangan melalui persilangan purata bergerak
  • Menggunakan penunjuk MFI dan ADX untuk pengekstrakan ciri pelbagai dimensi untuk membantu menentukan arah trend
  • Memanfaatkan algoritma pembelajaran mesin kNN untuk mengoptimumkan dan menapis isyarat perdagangan secara dinamik
  • Strategi percubaan dengan ruang yang besar untuk peningkatan melalui pengesahan dan pengoptimuman data yang lebih banyak

Risiko dan Pengurangan

  • Garis VWMA cenderung terlambat
  • MFI dan ADX mempunyai beberapa ketinggalan, yang mungkin salah menilai keadaan pasaran
  • Parameter algoritma kNN (contohnya nilai k) boleh mempunyai kesan yang ketara terhadap hasil
  • Strategi percubaan mungkin kurang berprestasi dalam perdagangan langsung

Pengurangan:

  • Sesuaikan parameter MA untuk mengurangkan lag
  • Meningkatkan penunjuk untuk menilai trend dengan lebih tepat
  • Mengoptimumkan parameter kNN untuk meningkatkan kecergasan
  • Memeriksa strategi melalui backtest dan perdagangan kertas

Arahan pengoptimuman

Terdapat ruang yang besar untuk mengoptimumkan strategi ini:

  • Tambah lebih banyak penunjuk MA untuk membina gabungan MA
  • Cuba pelbagai penunjuk tambahan seperti MACD, KDJ dll
  • Meningkatkan algoritma kNN misalnya menggunakan metrik jarak yang berbeza
  • Cuba algoritma pembelajaran mesin lain seperti SVM, Random Forest dll
  • Penyesuaian parameter untuk mencari set parameter optimum

Memperkenalkan lebih banyak penunjuk dan algoritma pembelajaran mesin boleh meningkatkan kestabilan dan keuntungan strategi.

Ringkasan

Ini adalah strategi perdagangan kuantitatif percubaan berdasarkan penunjuk VWMA dan algoritma pembelajaran mesin kNN. Ia mempunyai kelebihan keupayaan mengikuti trend yang kuat semasa menapis isyarat melalui pembelajaran mesin. Strategi ini mempunyai ruang yang besar untuk pengembangan dengan memperkenalkan lebih banyak ciri dan algoritma pengoptimuman untuk hasil yang lebih baik. Tetapi sebagai strategi baru, terdapat juga risiko yang memerlukan pengesahan dan penambahbaikan lanjut. Secara keseluruhan strategi ini mempunyai potensi inovasi yang besar.


/*backtest
start: 2023-11-21 00:00:00
end: 2023-12-21 00:00:00
period: 1h
basePeriod: 15m
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/
// © lastguru

//@version=4
strategy(title="VWMA with kNN Machine Learning: MFI/ADX", shorttitle="VWMA + kNN: MFI/ADX", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=100)

/////////
// kNN //
/////////

// Define storage arrays for: parameter 1, parameter 2, price, result (up = 1; down = -1)
var knn1 = array.new_float(1, 0)
var knn2 = array.new_float(1, 0)
var knnp = array.new_float(1, 0)
var knnr = array.new_float(1, 0)

// Store the previous trade; buffer the current one until results are in
_knnStore (p1, p2, src) =>
    var prevp1 = 0.0
    var prevp2 = 0.0
    var prevsrc = 0.0
    
    array.push(knn1, prevp1)
    array.push(knn2, prevp2)
    array.push(knnp, prevsrc)
    array.push(knnr, src >= prevsrc ? 1 : -1)
    
    prevp1 := p1
    prevp2 := p2
    prevsrc := src

// Sort two arrays (MUST be of the same size) based on the first.
// In other words, when an element in the first is moved, the element in the second moves as well.
_knnGet(arr1, arr2, k) =>
    sarr = array.copy(arr1)
    array.sort(sarr)
    ss = array.slice(sarr, 0, min(k, array.size(sarr)))
    m = array.max(ss)
    out = array.new_float(0)
    for i = 0 to array.size(arr1) - 1
        if (array.get(arr1, i) <= m)
            array.push(out, array.get(arr2, i))
    out

// Create a distance array from the two given parameters
_knnDistance(p1, p2) =>
    dist = array.new_float(0)
    n = array.size(knn1) - 1
    for i = 0 to n
        d = sqrt( pow(p1 - array.get(knn1, i), 2) + pow(p2 - array.get(knn2, i), 2) )
        array.push(dist, d)
    dist

// Make a prediction, finding k nearest neighbours
_knn(p1, p2, k) =>
    slice = _knnGet(_knnDistance(p1, p2), array.copy(knnr), k)
    knn = array.sum(slice)

////////////
// Inputs //
////////////

SRC = input(title="Source", type=input.source, defval=open)
FAST = input(title="Fast Length", type=input.integer, defval=13)
SLOW = input(title="Slow Length", type=input.integer, defval=19)
FILTER = input(title="Filter Length", type=input.integer, defval=13)
SMOOTH = input(title="Filter Smoothing", type=input.integer, defval=6)
KNN = input(title="kNN nearest neighbors (k)", type=input.integer, defval=23)
BACKGROUND = input(false,title = "Draw background")

////////
// MA //
////////
fastMA = vwma(SRC, FAST)
slowMA = vwma(SRC, SLOW)

/////////
// DMI //
/////////

// Wilder's Smoothing (Running Moving Average)
_rma(src, length) =>
    out = 0.0
    out := ((length - 1) * nz(out[1]) + src) / length

// DMI (Directional Movement Index)
_dmi (len, smooth) =>
    up = change(high)
    down = -change(low)
    plusDM = na(up) ? na : (up > down and up > 0 ? up : 0)
    minusDM = na(down) ? na : (down > up and down > 0 ? down : 0)
    trur = _rma(tr, len)
    plus = fixnan(100 * _rma(plusDM, len) / trur)
    minus = fixnan(100 * _rma(minusDM, len) / trur)
    sum = plus + minus
    adx = 100 * _rma(abs(plus - minus) / (sum == 0 ? 1 : sum), smooth)
    [plus, minus, adx]

[diplus, diminus, adx] = _dmi(FILTER, SMOOTH)

/////////
// MFI //
/////////

// common RSI function
_rsi(upper, lower) =>
    if lower == 0
        100
    if upper == 0
        0
	100.0 - (100.0 / (1.0 + upper / lower))

mfiUp = sum(volume * (change(ohlc4) <= 0 ? 0 : ohlc4), FILTER)
mfiDown = sum(volume * (change(ohlc4) >= 0 ? 0 : ohlc4), FILTER)
mfi = _rsi(mfiUp, mfiDown)

////////////
// Filter //
////////////

longCondition = crossover(fastMA, slowMA)
shortCondition = crossunder(fastMA, slowMA)

if (longCondition or shortCondition)
    _knnStore(adx, mfi, SRC)
filter = _knn(adx, mfi, KNN)

/////////////
// Actions //
/////////////

bgcolor(BACKGROUND ? filter >= 0 ? color.green : color.red : na)
plot(fastMA, color=color.red)
plot(slowMA, color=color.green)

if (longCondition and filter >= 0)
    strategy.entry("Long", strategy.long)
if (shortCondition and filter < 0)
    strategy.entry("Short", strategy.short)

Lebih lanjut