Estrategia comercial cuantitativa de aprendizaje automático de kNN basada en VWMA y MFI/ADX


Fecha de creación: 2023-12-22 14:13:27 Última modificación: 2023-12-22 14:13:27
Copiar: 0 Número de Visitas: 762
1
Seguir
1623
Seguidores

Estrategia comercial cuantitativa de aprendizaje automático de kNN basada en VWMA y MFI/ADX

Descripción general

La estrategia es una estrategia de comercio cuantitativa experimental que combina un indicador de promedio móvil y un algoritmo de aprendizaje automático para generar señales de comercio. La estrategia utiliza el cruce de las medias VWMA de dos períodos diferentes para determinar la dirección de la tendencia y combina dos indicadores MFI y ADX para filtrar la señal a través del algoritmo de KNN para mejorar la fiabilidad de la señal.

Principio de estrategia

El indicador central de la estrategia es el promedio VWMA de dos parámetros diferentes, la línea rápida y la línea lenta. Cuando la línea rápida atraviesa la línea lenta, se genera una señal de compra, y cuando la línea rápida atraviesa la línea lenta, se genera una señal de venta. Además, la estrategia introduce dos indicadores auxiliares, MFI y ADX, para juzgar la fiabilidad de la señal en las condiciones actuales del mercado a través del algoritmo de clasificación KNN.

La idea del algoritmo kNN es comparar los nuevos datos con los datos históricos y determinar los resultados correspondientes a los datos históricos más cercanos de k, clasificando de acuerdo con este resultado histórico de acuerdo con la mayoría de los votos. Esta estrategia utiliza MFI y ADX como los dos parámetros de entrada del algoritmo kNN para determinar el movimiento histórico de los precios en la combinación de estos dos indicadores: subir o bajar, para filtrar la señal actual y mejorar la calidad de la señal.

Ventajas estratégicas

  • Utiliza la capacidad de seguimiento de tendencias de VWMA para generar puntos de compra y venta en combinación con el cruce equilátero
  • Aplicación de indicadores MFI y ADX para extracción de características multidimensionales para ayudar a determinar la dirección de la tendencia
  • Optimización dinámica y filtración de señales de transacción con el algoritmo de aprendizaje automático de kNN
  • Estrategias experimentales, con un gran espacio de desarrollo, para ser validadas y optimizadas con más datos

Riesgos y contramedidas

  • El problema de la línea media VWMA es fácil de retrasar
  • Las MFI y ADX tienen cierta retraso y pueden malinterpretar la situación del mercado
  • La configuración de los parámetros del algoritmo kNN (como la selección de los valores de k) puede tener un gran impacto en los resultados
  • Estrategias experimentales que podrían no funcionar bien en el mundo real

Las respuestas:

  • Ajuste de los parámetros de la línea media para reducir el retraso
  • Mejora de los algoritmos de los indicadores para mejorar la precisión de las tendencias
  • Optimización de los parámetros del algoritmo kNN para mejorar la adecuación
  • Verificación de estrategias mediante retroalimentación y simulación en el mundo real

Dirección de optimización

La estrategia tiene mucho espacio para ser optimizada:

  • Aumentar los indicadores de línea media y construir una combinación de línea media
  • Prueba con diferentes indicadores auxiliares, como el MACD, el KDJ y otros.
  • Mejoras en los algoritmos de KNN, como el uso de diferentes métodos de medición de distancias
  • Intentar otros algoritmos de aprendizaje automático, como SVM, bosques aleatorios, etc.
  • Optimización de parámetros para encontrar la mejor combinación de parámetros

Se espera que la introducción de más indicadores y algoritmos de aprendizaje automático mejore aún más la estabilidad y la rentabilidad de las estrategias.

Resumir

La estrategia es una estrategia de comercio cuantitativo experimental basada en el indicador de línea media VWMA y el algoritmo de aprendizaje automático de KNN. Tiene una gran capacidad de seguimiento de tendencias y filtración de señales a través del aprendizaje automático. El espacio de la estrategia es amplio y se espera que produzca un mejor efecto mediante la introducción de más características y algoritmos de optimización.

Código Fuente de la Estrategia
/*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)