kNN-Maschinenlern-Strategie für quantitativen Handel basierend auf VWMA und MFI/ADX


Erstellungsdatum: 2023-12-22 14:13:27 zuletzt geändert: 2023-12-22 14:13:27
Kopie: 0 Klicks: 762
1
konzentrieren Sie sich auf
1623
Anhänger

kNN-Maschinenlern-Strategie für quantitativen Handel basierend auf VWMA und MFI/ADX

Überblick

Die Strategie ist eine experimentelle quantitative Handelsstrategie, die eine Kombination von Moving Average Indicators und Machine Learning-kNN-Algorithmen verwendet, um ein Handelssignal zu erzeugen. Die Strategie verwendet die Kreuzung von VWMA-Gleichlinien aus zwei verschiedenen Perioden, um die Richtung des Trends zu bestimmen, und kombiniert MFI und ADX mit zwei Indikatoren, die die Signale durch die KNN-Algorithmen filtern, um die Signalzuverlässigkeit zu erhöhen.

Strategieprinzip

Die Kernindikatoren der Strategie sind zwei VWMA-Mittellinien mit verschiedenen Parametern, die Fast- und die Slow-Linie. Bei einer Überschreitung der Slow-Linie auf der Fast-Linie wird ein Kaufsignal erzeugt, bei einer Überschreitung der Slow-Linie unterhalb der Fast-Linie ein Verkaufssignal. Zusätzlich werden zwei Hilfsindikatoren, MFI und ADX, eingeführt, um die Zuverlässigkeit des Signals unter den aktuellen Marktbedingungen durch die KNN-Klassifizierungsalgorithmen zu beurteilen.

Die Idee des kNN-Algorithmus besteht darin, neue Daten mit historischen Daten zu vergleichen, um die Ergebnisse zu beurteilen, die den nächsten k historischen Daten entsprechen, und nach diesen k historischen Ergebnissen in einer Mehrheitswahl zu klassifizieren. Diese Strategie verwendet MFI und ADX als zwei Eingabeparameter des kNN-Algorithmus, um die historische Preisentwicklung bei der Kombination dieser beiden Indikatoren zu beurteilen (aufwärts oder abwärts), wodurch das aktuelle Signal gefiltert und die Signalqualität verbessert wird.

Strategische Vorteile

  • Nutzung der VWMA-Trend-Following-Fähigkeit zur Erzeugung von Kauf- und Verkaufspunkten in Kombination mit Gleichgewichtskreuzungen
  • Anwendung von MFI- und ADX-Indikatoren für mehrdimensionale Feature-Extraktion, um die Richtung von Trends zu bestimmen
  • Dynamische Optimierung und Filterung von Handelssignalen mithilfe von kNN-Machine-Learning-Algorithmen
  • Experimentelle Strategien, große Entwicklungsmöglichkeiten, die mit mehr Daten verifiziert und optimiert werden können

Risiken und Gegenmaßnahmen

  • VWMA-Durchschnittslinien sind leicht rückläufig
  • MFI und ADX sind etwas rückständig und können die Marktlage falsch einschätzen
  • Die Einstellung von Parametern des kNN-Algorithmus (z. B. die Auswahl der k-Werte) hat einen großen Einfluss auf die Ergebnisse
  • Experimentelle Strategien, die in der Praxis nicht gut funktionieren können

Gegenmaßnahmen:

  • Anpassung der Mittellinienparameter zur Verringerung der Rückstände
  • Verbesserte Indikator-Algorithmen zur besseren Trendbestimmung
  • Optimierung der Parameter des kNN-Algorithmus zur Verbesserung der Anpassung
  • Validierung von Strategien mit Rückmessungen und Simulationen in der Realität

Optimierungsrichtung

Es gibt noch viel Optimierungsmöglichkeiten für diese Strategie:

  • Erhöhung der Gleichgewichtsindikatoren und Aufbau einer Gleichgewichtspalette
  • Versuchen Sie mit verschiedenen Hilfsindikatoren, wie MACD, KDJ, etc.
  • Verbesserungen der kNN-Algorithmen, z. B. die Verwendung einer anderen Methode zur Messung der Entfernung
  • Versuchen Sie es mit anderen Algorithmen, wie SVM, Random Forest, etc.
  • Optimierung der Parameter und Suche nach der optimalen Parameterkombination

Durch die Einführung von mehr Kennzahlen und maschinellen Lernalgorithmen wird die Stabilität und die Rendite der Strategie weiter verbessert.

Zusammenfassen

Die Strategie ist eine experimentelle, quantitative Handelsstrategie, die auf dem VWMA Mean Line Indicator und dem KNN Machine Learning Algorithmus basiert. Sie hat eine starke Trendverfolgungsfähigkeit und Signalfilterung durch maschinelles Lernen. Die Strategie hat einen breiten Spielraum und wird durch die Einführung von mehr Features und optimierten Algorithmen zu besseren Ergebnissen führen.

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