Stratégie de trading quantitative d'apprentissage automatique kNN basée sur VWMA et MFI/ADX


Date de création: 2023-12-22 14:13:27 Dernière modification: 2023-12-22 14:13:27
Copier: 0 Nombre de clics: 762
1
Suivre
1623
Abonnés

Stratégie de trading quantitative d’apprentissage automatique kNN basée sur VWMA et MFI/ADX

Aperçu

Cette stratégie est une stratégie de trading quantitatif expérimentale qui combine des indicateurs de moyennes mobiles et un algorithme de kNN basé sur l’apprentissage automatique pour générer un signal de trading. Cette stratégie utilise l’intersection des moyennes VWMA de deux périodes différentes pour déterminer la direction de la tendance et combine deux indicateurs MFI et ADX pour filtrer le signal via l’algorithme de kNN afin d’améliorer la fiabilité du signal.

Principe de stratégie

La stratégie a pour indicateur central une moyenne VWMA de deux paramètres différents, soit une ligne rapide et une ligne lente. Elle génère un signal d’achat lorsque la ligne rapide traverse la ligne lente et un signal de vente lorsque la ligne rapide traverse la ligne lente. De plus, la stratégie introduit deux indicateurs auxiliaires, MFI et ADX, pour juger de la fiabilité du signal dans les conditions du marché actuel grâce à un algorithme de classification KNN.

L’idée de l’algorithme kNN est de comparer les nouvelles données avec les données historiques et de déterminer le résultat correspondant aux données historiques les plus proches de k, en fonction de ce résultat historique de classement par vote majoritaire. La stratégie utilise MFI et ADX comme deux paramètres d’entrée de l’algorithme kNN pour déterminer l’évolution des prix historiques lorsque ces deux indicateurs sont combinés (haut ou bas), afin de filtrer le signal actuel et d’améliorer la qualité du signal.

Avantages stratégiques

  • Utilisez la capacité de suivi des tendances de VWMA pour créer des points d’achat et de vente avec des croisements équivalents
  • Utilisation des indicateurs MFI et ADX pour l’extraction de caractéristiques multidimensionnelles, pour aider à déterminer la direction des tendances
  • Optimisation et filtrage dynamiques des signaux de transaction à l’aide de l’algorithme d’apprentissage automatique de KNN
  • Stratégie expérimentale, avec un grand espace de développement, à vérifier et à optimiser avec plus de données

Risques et contre-mesures

  • Le problème de la facilité de retard de la moyenne VWMA
  • Les MFI et les ADX sont un peu arriérés et peuvent mal interpréter les conditions du marché.
  • Les paramètres de l’algorithme kNN (par exemple, la sélection de la valeur de k) peuvent avoir une grande influence sur les résultats.
  • Stratégies expérimentales qui pourraient ne pas fonctionner correctement dans le monde réel

Les réponses:

  • Ajustement des paramètres de la moyenne pour réduire le retard
  • Amélioration des algorithmes d’indicateurs pour une plus grande précision dans le jugement des tendances
  • Optimiser les paramètres de l’algorithme KNN pour améliorer l’efficacité de la correspondance
  • Validation de la stratégie à l’aide de la rétroanalyse et de la simulation en direct

Direction d’optimisation

Il y a encore beaucoup à optimiser dans cette stratégie:

  • Ajout d’indicateurs plus homogènes pour construire un portefeuille homogène
  • Essayez différents indicateurs auxiliaires, comme le MACD, le KDJ, etc.
  • Amélioration des algorithmes de kNN, comme l’utilisation de différentes méthodes de mesure de la distance
  • Essayez d’autres algorithmes d’apprentissage automatique comme le SVM, la forêt aléatoire, etc.
  • Optimiser les paramètres pour trouver la meilleure combinaison de paramètres

L’introduction de plus d’indicateurs et d’algorithmes d’apprentissage automatique devrait améliorer encore la stabilité et la rentabilité de la stratégie.

Résumer

Cette stratégie est une stratégie de trading quantitatif expérimentale basée sur l’indicateur de ligne moyenne VWMA et l’algorithme d’apprentissage automatique kNN. Elle est caractérisée par une forte capacité de suivi des tendances et un filtrage des signaux par l’apprentissage automatique. L’espace de la stratégie est large et il est probable qu’elle produira de meilleurs résultats en introduisant plus de fonctionnalités et en optimisant les algorithmes.

Code source de la stratégie
/*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)