Aprendizaje automático en el trading: teoría, práctica, operaciones y más - página 261

 
¿Y cuáles son los resultados en la predicción? me atrevo a preguntar.
 
mytarmailS:
¿Y cuáles son los resultados en la previsión? me atrevo a preguntar.
Si me preguntan, probablemente no pueda responder de forma inequívoca, hay muchas cosas que se prevén y todo es diferente. Pero, por término medio, entre el 60 y el 65%.
 

Aquí está la hoja de cálculo preparada para el entrenamiento del modelo.

Los precios se convierten en deltas por columnas; se eliminan las columnas sin cambios o con NA.

Se han incluido 3 rezagos en cada fila para cada columna (fila actual menos la anterior; anterior menos la preexistente; preexistente menos la preexistente)

Objetivo - aumentar/disminuir el valor en la siguiente fila (la siguiente fila menos la actual, redondeado a +-1, o 0 si no hay cambios; 3 clases en total). Todos los objetivos tienen el prefijo "target_"

*No se puede utilizar ningún otro objetivo para predecir un objetivo, o sería una mirada al futuro. Todas las columnas que llevan el prefijo "target_" no pueden utilizarse como predictor o intu.

Archivos adjuntos:
 

El problema.

Dividir el archivo csv en dos partes por filas, en una proporción de 10:1 para los datos de entrenamiento y el fronttest. He entrenado el modelo para target_SiH7.bid (de la tabla anterior) y he obtenido una precisión de clasificación del 62% en los datos de entrenamiento y del 74% en los nuevos datos. Estaba feliz, pero volvió a comprobar, resultó que la clase 0 es muy desequilibrada en relación con los demás, y sólo por la cantidad tiene 60% y 74%. Es decir, el modelo ha aprendido a detectar bien el 0, pero se ha atascado en las clases -1 y 1.

Se necesita una puntuación diferente. Para dos clases desequilibradas esta métrica es genial -https://en.wikipedia.org/wiki/Cohen's_kappa, pero en nuestro caso hay tres clases desequilibradas, no dos, ¿hay un análogo de Kappa para 3?

 
No lo he hecho:
Si me preguntan, probablemente no pueda responder sin ambigüedades, hay muchas cosas que se prevén y todo es diferente. Pero, por término medio, entre el 60 y el 65%.

Interesante, ¿puede describirlo con más detalle...

Es que ahora estoy en un área de previsión completamente diferente y no puedo permitirme el lujo de estar disperso por lo que no puedo hacer experimentos contigo en esta fecha de marzo, pero es muy interesante leer y observar, escribe más por favor....

Dr.Trader:

resulta que la clase 0 está muy desequilibrada en relación con las demás, y sólo en términos de cantidad tiene el 60% y el 74%. Es decir, el modelo ha aprendido a detectar muy bien el 0, pero ha renunciado a las clases -1 y 1.

Tuve el mismo problema cuando entrené mi bosque aleatorio para los giros en U, naturalmente había muchos menos giros en U que no giros en U. Cuantos más árboles hacía, más puntuaba el modus operandi en las clases de turno y se concentraba más en las clases de no turno.

Hay varios métodos en caret para equilibrar las clases, pero todos ellos son triviales: o bien se duplica la clase que tiene menos observaciones para alinear la suma de las observaciones en todas las clases para obtener lo mismo, o viceversa se eliminan las observaciones superfluas de la clase que tiene más observaciones.

Ninguno de los métodos es más rentable que sin equilibrar en absoluto (pero eso es sólo en mi caso).

 
mytarmailS:

Interesante, ¿puede describirlo con más detalle...

Justo ahora estoy trabajando en un área completamente diferente de la previsión y no puedo permitirme el lujo de perderme por eso no puedo hacer experimentos contigo en este mart, pero es muy interesante leer y observar, por favor escribe más...

Tuve el mismo problema cuando me entrenaba para los giros en U, los giros en U por supuesto eran mucho menos que los que no lo eran. Cuantos más árboles hacía, más se atascaba el modus operandi con la clase de giro en U y se concentraba más en la clase de no giro.

Existen varios métodos en caret para equilibrar las clases, pero todos ellos son triviales: duplicar la clase que tiene menos observaciones para que la suma de las observaciones de todas las clases sea la misma o eliminar las observaciones innecesarias de la clase que tiene más observaciones.

Ninguno de los métodos es más rentable que sin equilibrar en absoluto (pero esto es sólo en mi caso)

En caret puedes cambiar la función de fitness en la función de entrenamiento a través de algún parámetro. Para la clasificación puedes usar precisión o kappa: y para la regresión algunas dos variantes propias, como r^2 y algo más. Aprendí kappa sólo de ahí, me ayudó a entrenar un modelo correctamente en clases muy desequilibradas, sin ninguna operación adicional.
 
Si estamos hablando de retrocesos, entonces deberíamos equilibrar las clases de manera significativa: no una barra para un retroceso, sino varias barras antes del retroceso y varias barras después del retroceso. Si las clases están desequilibradas de todos modos, pero no tan fatal y puede ser equilibrado por caret
 
tóxicos:

Todo es negociable. Sugerí los futuros de los fuertes, por ejemplo Si, RI, BR etc. los más líquidos en general. Sugiero señal (-1,0,1)(corto, efectivo, largo) como resultado, la señal es inequívoca que la probabilidad y no distorsionadapor MM como órdenes. El postprocesamiento, las señales y la focalización dependen de usted, o del libro.

Después de pensarlo un poco he llegado a la conclusión de que al menos habría que añadir un vaso más{precio:vol,...||..., precio:vol } tal y como está, un último por segundo, para cada instrumento previsto, entonces el delta no es necesario y bid, ask también, es IMHO obligatorio, si con la cinta por segundo los volúmenes divididos y el desplazamiento de OM, más o menos informativo, entonces para el vaso un delta es muy poco, al menos hay que ver diferentes "platos" de distribución, etc. y eso es suficiente como comienzo. Añade un vaso y publica un conjunto de datos de entrenamiento durante un par de días, jugaremos. :)

 

Finalmente se decidió por la métricaPi de Scotthttps://en.wikipedia.org/wiki/Scott's_Pi

Aquí están mis resultados con esta estimación, entrené el modelo en el primer 91% de las líneas, y luego hice el fronttest en los últimos datos restantes (ratio backtest : fronttest = 10:1)
columna "class_0_rate" en la tabla - relación entre la clase 0 y las clases -1y1, para poder filtrar en Excel los resultados en los que este valor es demasiado alto.

Las dos últimas columnas son la métrica Pi de Scott para el entrenamiento y la prueba, el valor será de -1 a 1; donde 0=el resultado es aleatorio y el meodelo es inútil, y 1 = todo está bien. Un resultado negativo no es bueno, la correlación inversa, puede intentar invertir el resultado de la predicción. La correlación inversa a veces funciona bien con dos clases cuando se negocia exactamente lo contrario de la predicción. Pero con tres clases es difícil encontrar el opuesto, cada clase tiene dos valores opuestos y en este caso el valor negativo también es malo.

Creo que hay que elegir la divisa cuyas predicciones de compra (o venta) tengan valores similares y altos en el backtest y el fronttest, por ejemplo el xagusd. Aunque una puntuación de 0,18 en una escala de 0 a 1 es pequeña. Y predecir con un tick de antelación en el comercio real también es malo. En general hay un resultado, pero no es aplicable :)

Código R para el Pi de Scott

ScottsPi <- function(act, pred){
  if(length(act) != length(pred)){
    stop("different length")
  }
  
  n_observ <- length(act)
  
  all_levels <- unique(c(act,pred))
  n_levels <- length(all_levels)
  
  marginal_matrix <- matrix(NA, ncol=n_levels, nrow=n_levels)
  colnames(marginal_matrix) <- all_levels
  rownames(marginal_matrix) <- all_levels
  
  for(i in 1:n_levels){
    for(j in 1:n_levels){
      marginal_matrix[i,j] <- sum((act==all_levels[i]) & (pred==all_levels[j]))
    }
  }
  diagSum <- 0
  for(i in 1:n_levels){
    diagSum <- diagSum + marginal_matrix[i,i]
  }
  diagSum <- diagSum / n_observ
  
  marginalSum <- 0
  for(i in 1:n_levels){
    marginalSum <- marginalSum + ((sum(marginal_matrix[i,]) + sum(marginal_matrix[,i]))/n_observ/2)^2
  }
  p <- marginalSum
  return((diagSum - p)/(1-p))
}
Archivos adjuntos:
 
Dr.Trader:

Finalmente se decidió por la métricaPi de Scotthttps://en.wikipedia.org/wiki/Scott's_Pi

Aquí están mis resultados con esta estimación, entrené el modelo en el primer 91% de las líneas, y luego hice el fronttest en los últimos datos restantes (ratio backtest : fronttest = 10:1)
columna "class_0_rate" en la tabla - relación entre la clase 0 y las clases -1y1, para poder filtrar en Excel los resultados en los que este valor es demasiado alto.

Las dos últimas columnas son la métrica Pi de Scott para el entrenamiento y la prueba, el valor será de -1 a 1; donde 0=el resultado es aleatorio y el meodelo es inútil, y 1 = todo está bien. Un resultado negativo no es bueno, la correlación inversa, puede intentar invertir el resultado de la predicción. La correlación inversa a veces funciona bien con dos clases cuando se negocia exactamente lo contrario de la predicción. Pero con tres clases es difícil encontrar el opuesto, cada clase tiene dos valores opuestos y en este caso el valor negativo también es malo.

Creo que hay que elegir la divisa cuyas predicciones de compra (o venta) tengan valores similares y altos en el backtest y el fronttest, por ejemplo el xagusd. Aunque una puntuación de 0,18 en una escala de 0 a 1 es pequeña. Y predecir con un tick de antelación en el comercio real también es malo. En general hay un resultado, pero no es aplicable :)

Código R para el Pi de Scott

ScottsPi <- function(act, pred){
  if(length(act) != length(pred)){
    stop("different length")
  }
  
  n_observ <- length(act)
  
  all_levels <- unique(c(act,pred))
  n_levels <- length(all_levels)
  
  marginal_matrix <- matrix(NA, ncol=n_levels, nrow=n_levels)
  colnames(marginal_matrix) <- all_levels
  rownames(marginal_matrix) <- all_levels
  
  for(i in 1:n_levels){
    for(j in 1:n_levels){
      marginal_matrix[i,j] <- sum((act==all_levels[i]) & (pred==all_levels[j]))
    }
  }
  diagSum <- 0
  for(i in 1:n_levels){
    diagSum <- diagSum + marginal_matrix[i,i]
  }
  diagSum <- diagSum / n_observ
  
  marginalSum <- 0
  for(i in 1:n_levels){
    marginalSum <- marginalSum + ((sum(marginal_matrix[i,]) + sum(marginal_matrix[,i]))/n_observ/2)^2
  }
  p <- marginalSum
  return((diagSum - p)/(1-p))
}
Los datos son muy pocos, mi amigo cuelga un conjunto de datos normal, pero en algún lugar se perdió. Dr. Trader: No hay muchos datos, pero se pierden en algún sitio. Y si no se concreta, desde luego para el tick por delante es realmente inútil, al menos un minuto por delante, en los pases un minuto es pura MM, limitadores a ambos lados, a una distancia proporcional al spread, aquí "espuma cuántica", no tiene sentido hablar de dirección, porque es mucho menor que el spread.