Ini adalah strategi perdagangan kuantitatif eksperimental

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

img

Gambaran umum

Ini adalah strategi perdagangan kuantitatif eksperimental yang menggabungkan indikator rata-rata bergerak dan algoritma pembelajaran mesin kNN untuk menghasilkan sinyal perdagangan.

Prinsip Strategi

Indikator inti dari strategi ini adalah dua garis VWMA dengan parameter yang berbeda, yaitu garis cepat dan garis lambat. Ketika garis cepat melintasi di atas garis lambat, sinyal beli dihasilkan. Ketika garis cepat melintasi di bawah garis lambat, sinyal jual dihasilkan. Selain itu, strategi ini memperkenalkan dua indikator tambahan, MFI dan ADX, untuk menilai keandalan sinyal saat ini di bawah kondisi pasar saat ini melalui algoritma klasifikasi kNN.

Ide di balik algoritma kNN adalah untuk membandingkan data baru dengan data historis untuk menentukan hasil yang sesuai dengan k data historis yang paling mirip, dan mengkategorikan berdasarkan suara mayoritas dari k hasil historis ini.

Keuntungan

  • Menggunakan kemampuan VWMA untuk mengikuti tren dan menghasilkan sinyal perdagangan melalui crossover rata-rata bergerak
  • Menerapkan indikator MFI dan ADX untuk ekstraksi fitur multidimensi untuk membantu menentukan arah tren
  • Manfaatkan algoritma pembelajaran mesin kNN untuk mengoptimalkan dan menyaring sinyal perdagangan secara dinamis
  • Strategi eksperimental dengan ruang yang luas untuk perbaikan melalui verifikasi dan optimalisasi data yang lebih banyak

Risiko dan Pengurangan

  • Garis VWMA cenderung tertinggal
  • MFI dan ADX memiliki beberapa ketinggalan, yang mungkin salah menilai kondisi pasar
  • Parameter algoritma kNN (misalnya nilai k) dapat berdampak signifikan pada hasil
  • Strategi percobaan mungkin kurang baik dalam perdagangan langsung

Pengurangan:

  • Sesuaikan parameter MA untuk mengurangi lag
  • Meningkatkan indikator untuk menilai tren dengan lebih akurat
  • Mengoptimalkan parameter kNN untuk meningkatkan kebugaran
  • Memverifikasi strategi melalui backtest dan perdagangan kertas

Arahan Optimasi

Ada ruang besar untuk mengoptimalkan strategi ini:

  • Tambahkan lebih banyak indikator MA untuk membangun kombinasi MA
  • Cobalah indikator tambahan yang berbeda seperti MACD, KDJ dll
  • Meningkatkan algoritma kNN misalnya menggunakan metrik jarak yang berbeda
  • Cobalah algoritma pembelajaran mesin lainnya seperti SVM, Random Forest dll
  • Pengaturan parameter untuk menemukan set parameter optimal

Memperkenalkan lebih banyak indikator dan algoritma pembelajaran mesin dapat lebih meningkatkan stabilitas dan profitabilitas strategi.

Ringkasan

Ini adalah strategi perdagangan kuantitatif eksperimental berdasarkan indikator VWMA dan algoritma pembelajaran mesin kNN. Ini memiliki keuntungan kemampuan mengikuti tren yang kuat saat menyaring sinyal melalui pembelajaran mesin. Strategi ini memiliki ruang yang luas untuk perluasan dengan memperkenalkan lebih banyak fitur dan algoritma pengoptimalan untuk hasil yang lebih baik.


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