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

 
interesante artículo https://geektimes.ru/post/144405/, tal vez alguien entienda como simular esto en R
Прогнозирование финансовых временных рядов
Прогнозирование финансовых временных рядов
  • geektimes.ru
Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста. Пометьте топик понятными вам метками, если хотите или закрыть
 

Empecé a experimentar con grupos, basándome en los motivos que mencioné antes. Me encontré con un problema - cuando traté de pegar el precio de las piezas que corresponden a una agrupación, los lugares pegados eran huecos de precios (y esto es lógico, pero no se me ocurrió)) ) La cuestión es cómo arreglar estas lagunas

#  типа какая то цена
dat <- cumsum(rnorm(1000))+1000
plot(dat,t="l")


#  фун. матрицы хенкеля для имитации скользящего окна
hankel<- function(data, r=10) {
  do.call(cbind,
          lapply(0:(r-1),function(i) { data[(i+1):(length(data)-(r-1-i))]}))}
#  делаем аналог скользящего окна глубиной в 50
glubina <- 50
D <- hankel(dat,r = glubina)


#  скалирую и центрирую дату, проще сказать нормализирую
DC <- t(  apply(D, 1,    function(x) {  scale(x,T,T)  }    ))


library(SOMbrero)
#  тренирую сеть кохонена на данных чтоб получить кластера
TS <- trainSOM(DC,  dimension=c(3,3))

#  край матрицы будет вектор нашей цены без первых значений
dt <- D[,glubina] 
#  полученые кластера
cl <- TS$clustering

#  график цены , график кластеров этой цены
par(mfrow=c(2,1))
plot(dt,t="l")
plot(cl,t="l")
par(mfrow=c(1,1))


#  пробую посмотреть склееный график только одного кластера 
one_clust <- dt[cl==3]
#  график с разрывами в местах склейки
plot(one_clust,t="l")
 
Dr.Trader:

Yo también tengo este problema. Por lo general, sólo tienes que ejecutar attributes(KZP) para obtener una lista de variables disponibles y luego sólo tienes que ir a través de ellos, por ejemplo, KZP$window etc y encontrar los números que necesitas. Pero aquí estos números se generan en la propia función Resumen y no se guardan en ninguna parte.

Aquí hay un código fuente: https://cran.r-project.org/web/packages/kza/index.html, debemos ejecutar algo así:

Por cierto, puede ser útil para usted si usted utiliza los indicadores, esta función detectar en un muy ruidoso componentes periódicos de datos, el período en definitiva, este período está en constante cambio en el mercado.

La idea es identificar constantemente este periodo dominante y ajustar los indicadores a él, no sólo con parámetros fijos como hace todo el mundo. Probé este enfoque muy superficialmente en una cita al azar, y el resultado fue positivo en comparación con el enfoque habitual. Tomé el indicador RSI, perdió con parámetros fijos, y ganó con los adaptativos. Si quieres usarlo, puedes usarlo y me interesaría mucho leer el resultado de tu investigación

 
mytarmailS:

Empecé a experimentar con grupos, basándome en los motivos que mencioné antes. Me encontré con un problema - cuando traté de pegar el precio de las piezas que corresponden a una agrupación, los lugares pegados eran huecos de precios (y esto es lógico, pero no se me ocurrió)) ) La cuestión es cómo arreglar estas lagunas

Logaritmo de la serie de precios, luego convertir a una serie de diferencias. Para pegar la serie, deja sólo los intervalos que corresponden a la condición encontrada. A continuación, haz una nueva serie a partir de esta serie mediante la suma. Y, si se desea, exponerlo después.
 
Anton Zverev:
Logaritmiza la serie de precios y luego conviértela en una serie de diferencias. Para pegar la serie, deja sólo los intervalos que corresponden a la condición encontrada. A continuación, haz una nueva serie a partir de esta serie mediante la suma. Y, si se desea, exponerlo después.
Gracias, así es como me lo imaginaba, vamos a probarlo
 

Aprendí un par de cosas más interesantes:

La función para filtrar los predictores (designTreatmentsN$scoreFrame) publicada anteriormente claramente no da el conjunto final de predictores. Ni siquiera elimina el 100% de los predictores correlacionados, además de que puede eliminar algo que quieras, además de dejar basura. He complicado un poco su método de cribado - al principio estoy cribando los predictores de la manera antigua, a través de designTreatmentsN$scoreFrame (he aumentado el umbral dos veces - 2/N, para cribado de menos predictores potencialmente buenos). Luego elimino todos los predictores que correlacionan >0,99 (tengo muchos después de la generación aleatoria de deltas y sumas. Y miro la correlación de los predictores entre sí, no con la variable objetivo). Luego busco genéticamente el mejor conjunto de predictores restantes.

Intento usar algo más del artículo sobre componentes principales. La función siguiente construye el modelo de componentes principales y devuelve R^2 para el caso de que haya utilizado todos los componentes principales encontrados. No tiene "escala Y" como otro ejemplo del artículo, pero esta forma es más rápida. Ahora lo utilizo para estimar el conjunto de predictores (probablemente para nada, aún no lo sé :) ). La última columna del parámetro srcTable es la variable objetivo. Puede haber errores si el predictor tiene muy pocos valores, la función puede no ajustarse a algunos datos.

library('caret')
GetPCrsquared <- function(srcTable){
        targetName <- tail(colnames(srcTable),1)
        origVars <- setdiff(colnames(srcTable), targetName)
        # can try variations such adding/removing non-linear steps such as "YeoJohnson"
        prep <- preProcess(srcTable[,origVars], method = c("zv", "nzv", "center", "scale", "pca"))
        prepared <- predict(prep,newdata=srcTable[,origVars])
        newVars <- colnames(prepared)
        prepared$target <- srcTable$target
        modelB <- lm(paste(targetName, paste(newVars,collapse=' + '),sep=' ~ '),data=prepared)
        return(summary(modelB)$r.squared)
}

Mientras que antes tenía un R^2 de alrededor de 0,1, ahora he conseguido un 0,3. Todavía no es suficiente, recomiendan utilizar al menos 0,95. Otra cosa extraña es que con R^2=0,1 tenía un error del 37% en el fronttest, mientras que con R^2=0,3 este error ha crecido hasta el 45%. Quizás el problema es que he añadido más barras y más indicadores al conjunto de predictores. Un paso adelante y dos atrás, ahora tengo que analizar todo el conjunto de indicadores y eliminar los innecesarios. O el modelo de componentes principales simplemente no es aplicable a forex (difícil de comprobar, primero tengo que conseguir R^2 > 0,95, y ver cuál será el resultado en fronttest, con un modelo no entrenado es demasiado pronto para sacar conclusiones).

También he comparado el paquete GA (genética) y GenSA (recocido de gradiente, del ejemplo de Alexey). Ambos paquetes obtuvieron el mismo resultado. La genética sabe trabajar en multihilo, por lo que ganó en tiempo. Pero GenSA parece ganar en un solo hilo. También hay un truco para almacenar en caché los resultados, creo que Alex lo agradecerá:

fitness_GenSA_bin <- function(selectionForInputs){
        testPredictorNames <- predictorNames[ which(selectionForInputs == TRUE) ]
        #do  the fitness calculation
}

library(memoise)
fitness_GenSA_bin_Memoise <- memoise(fitness_GenSA_bin)

fitness_GenSA <- function(selectionForInputs){
        selectionForInputs[selectionForInputs>=0.5] <- TRUE
        selectionForInputs[selectionForInputs<0.5] <- FALSE
        return(fitness_GenSA_bin_Memoise(selectionForInputs))
}

library(GenSA, quietly=TRUE)
GENSA <- GenSA(fn = fitness_GenSA,
                                lower = rep(0, length(predictorNames)),
                                upper = rep(1, length(predictorNames)),
                                control=list(smooth=FALSE, verbose=TRUE)
                                ) 

La cuestión es que la función intermedia fitness_GenSA_bin_Memoise toma los datos de la caché si ese conjunto de predictores ya se ha encontrado al menos una vez. El archivo fitness_GenSA_bin debe contener los cálculos de la función de fitness en sí, y sólo se llamará una vez para cada conjunto único.

mytarmailS:

Por cierto, puede ser útil para usted si utiliza indicadores, esta función detecta los componentes periódicos en unos datos muy ruidosos, período en definitiva, este período está cambiando constantemente en el mercado.

La idea es identificar constantemente este periodo dominante y ajustar los indicadores a él, no sólo con parámetros fijos como hace todo el mundo. Probé este enfoque muy superficialmente en una cita al azar, y el resultado fue positivo en comparación con el enfoque habitual. Tomé el indicador RSI, perdió con los parámetros fijos, y ganó con los adaptativos. Si te interesa puedes usarlo, me interesará mucho leer el resultado de tu investigación

Por ahora sólo estoy usando parámetros estándar para los indicadores. Si voy a utilizar un indicador, será más útil utilizar los parámetros estándar para el comercio de acciones en D1, pero hay que ajustarlos. No soy capaz de cambiar los resultados de D1 a H1 en absoluto, cuanto más uso los indicadores, más me atasco en D1. Resulta que los parámetros del indicador deben cambiarse en función del marco temporal, y del tiempo, sí.

 
Dr.Trader:

Aprendí un par de cosas más interesantes:

La función para tamizar los predictores (designTreatmentsN$scoreFrame) publicada anteriormente claramente no da el conjunto final de predictores. Ni siquiera elimina el 100% de los predictores correlacionados, además de que puede eliminar algo que quieras, además de dejar basura. He complicado un poco su método de cribado - al principio estoy cribando los predictores de la manera antigua, a través de designTreatmentsN$scoreFrame (he aumentado el umbral dos veces - 2/N, para cribado de menos predictores potencialmente buenos). Luego elimino todos los predictores que correlacionan >0,99 (tengo muchos después de la generación aleatoria de deltas y sumas. Y miro la correlación de los predictores entre sí, no con la variable objetivo). Luego busco genéticamente el mejor conjunto de predictores restantes.

Intento utilizar algo más del artículo sobre componentes principales. La función siguiente construye el modelo de componentes principales y devuelve R^2 para el caso de que haya utilizado todos los componentes principales encontrados. No tiene "escala Y" como otro ejemplo del artículo, pero esta forma es más rápida. Ahora lo utilizo para estimar el conjunto de predictores (probablemente para nada, aún no lo sé :) ). La última columna del parámetro srcTable es la variable objetivo. Puede haber errores si el predictor tiene muy pocos valores, la función puede no ajustarse a algunos datos.

Mientras que antes tenía un R^2 de alrededor de 0,1, ahora he conseguido un 0,3. Todavía no es suficiente, recomiendan utilizar al menos 0,95. Otra cosa extraña es que con R^2=0,1 tenía un error del 37% en el fronttest, mientras que con R^2=0,3 este error ha crecido hasta el 45%. Quizás el problema es que he añadido más barras y más indicadores al conjunto de predictores. Un paso adelante y dos atrás, ahora tengo que analizar todo el conjunto de indicadores y eliminar los innecesarios. O el modelo de componentes principales simplemente no es aplicable a forex (difícil de comprobar, primero tengo que conseguir R^2 > 0,95, y ver cuál será el resultado en fronttest, con un modelo no entrenado es demasiado pronto para sacar conclusiones).

También comparé el paquete GA (genética) y GenSA (recocido por gradiente, del ejemplo de Alexey). Ambos paquetes obtuvieron el mismo resultado. La genética sabe trabajar en multihilo, por lo que ganó en tiempo. Pero GenSA parece ganar en un solo hilo. También hay un truco para almacenar en caché los resultados, creo que Alex lo agradecerá:

La cuestión es que la función intermedia fitness_GenSA_bin_Memoise toma los datos de la caché si ese conjunto de predictores ya se ha encontrado al menos una vez. El archivo fitness_GenSA_bin debe contener los cálculos de la función de fitness en sí, y sólo se llamará una vez para cada conjunto único.

Hasta ahora, sólo estoy usando parámetros estándar para los indicadores. Estoy de acuerdo, en general, si los indicadores han sido desarrollados principalmente para D1, serán más útiles con parámetros estándar sólo en este marco de tiempo. No soy capaz de cambiar los resultados de D1 a H1 en absoluto, cuanto más uso los indicadores, más me atasco en D1. Resulta que los parámetros del indicador deben cambiarse en función del marco temporal, y del tiempo, sí.

Genial lo del caché. Intenté escribirlo yo mismo. Pero hay una solución lista. Cueru. Gracias.

¿Y qué función de aptitud se utiliza cuando se sobrepasa el límite? Me lo perdí. ¿Dependencia lineal o estadística de algún tipo?
 
Dr.Trader:

No hay "escala Y" como en otro ejemplo del artículo,

Creo que ese es el objetivo del artículo. Lo he releído y lo dice explícitamente.

Pero volviendo al esquema general de preparar una lista de predictores.

El cribado del ruido es sólo una parte del problema y no resuelve el resto de los problemas y recomendaciones en este ámbito.

Si todo esto se cumple, entonces el siguiente algoritmo de trabajo está en un bucle, como sigue.

1. Tomamos un conjunto de predictores seleccionados y procesados. Esta lista es constante.

2. Para la ventana actual, seleccionamos los predictores mediante uno de los algoritmos. Por ejemplo, hay dos algoritmos en caret.

3. Ajuste del modelo.

4.

5. Desplaza la ventana y ve al paso 2.

¡El número de predictores de ruido fue de más de 80 de esos conjuntos iniciales de predictores que tenía en mis manos!

A continuación, el algoritmo estándar selecciona aproximadamente la mitad de los predictores restantes que el algoritmo no clasifica como ruido. A medida que la ventana se mueve, la composición de esta mitad cambia constantemente. Pero siempre el error en el conjunto de entrenamiento y el error fuera de la muestra son aproximadamente iguales. De lo que concluyo que mi modelo no está sobreentrenado y esto es consecuencia de los algoritmos de selección de predictores descritos anteriormente.

 

¿Y qué función de aptitud utilizas cuando haces fuerza bruta?

He utilizado para entrenar el bosque, y devolver un error en la muestra de validación. En principio, funcionó: si el bosque se sobreentrena aunque sea un poco, el error tiende al 50%.

Ahora uso GetPCrsquared(), ese código de arriba. También tengo tu ejemplo de feature_selector_modeller.txt, pero tengo que resolverlo y conseguir el trozo de código adecuado, así que aún no lo he probado con mis datos.

 
SanSanych Fomenko:

Creo que de eso trata el artículo. Lo he releído y lo dice explícitamente.

También probé la escala Y, R^2 en ambos casos (con y sin escala Y) salió igual (¡aunque en estos casos se utilizan paquetes diferentes!).

Supongo que la escala Y puede dar el mismo buen resultado con menos número de componentes principales. Pero, si incluso utilizando todos los componentes el resultado sigue sin ser satisfactorio (como en mi caso) - no hay diferencia. Además, funciona más rápido, lo que es más importante para mí ahora. Pero no he comprobado ni por la teoría ni por la práctica si este método es adecuado para la selección de predictores... Al principio tenía la idea de hacer el modelo de componentes principales sobre todos los predictores y seleccionar los predictores mirando los coeficientes de los componentes. Pero luego me di cuenta de que con la adición de basura - R^2 del modelo cae. Lo lógico sería probar con diferentes conjuntos de predictores y buscar los que tienen mayor R^2, pero aun así es solo una teoría.