L'Apprentissage Automatique dans le trading : théorie, modèles, pratique et trading algo - page 213
Vous manquez des opportunités de trading :
- Applications de trading gratuites
- Plus de 8 000 signaux à copier
- Actualités économiques pour explorer les marchés financiers
Inscription
Se connecter
Vous acceptez la politique du site Web et les conditions d'utilisation
Si vous n'avez pas de compte, veuillez vous inscrire
Un autre exemple pour une simulation.
Nous construisons 20 000 modèles linéaires (1 000 observations partout, nombre de prédicteurs de 1 à 20 (1 000 modèles pour chaque nombre), plus une variable indépendante). Données i.i.d., N(0,1).
Le but de la simulation est de s'assurer que la statistique F ne dépasse pas la valeur critique lorsque la régression MNA est construite sur des données indépendantes (ne contenant pas de dépendances), satisfaisant ainsi aux exigences du modèle lin. Il peut donc être utilisé comme un indicateur de la formation du modèle.
############### simulate lm f-stats with random vars
rm(list=ls());gc()
library(data.table)
library(ggplot2)
start <- Sys.time()
set.seed(1)
x <- as.data.table(matrix(rnorm(21000000, 0, 1), ncol = 21))
x[, sampling:= sample(1000, nrow(x), replace = T)]
lm_models <- x[,
{
lapply(c(1:20), function(x) summary(lm(data = .SD[, c(1:x, 21), with = F], formula = V21 ~ . -1))$'fstatistic'[[1]])
}
, by = sampling
]
lm_models_melted <- melt(lm_models, measure.vars = paste0('V', c(1:20)))
crtitical_f_stats <- qf(p = 0.99, df1 = c(1:20), df2 = 1000, lower.tail = TRUE, log.p = FALSE)
boxplot(data = lm_models_melted, value ~ variable); lines(crtitical_f_stats, type = 's', col = 'red')
Sys.time() - start
gc()
Temps de fonctionnement du code : 1,35 minutes.
Code utile. Visualise les séquences de transactions en trois hypostases.
##########################
rm(list=ls());gc()
library(data.table)
library(ggplot2)
library(gridExtra)
library(tseries)
start <- Sys.time()
set.seed(1)
x <- as.data.table(matrix(rnorm(1000000, 0.1, 1), ncol = 1)) #random normal value with positive expectation
x[, variable:= rep(1:1000, times = 1000)]
x[, trade:= 1:.N, by = variable]
x.cast = dcast.data.table(x, variable ~ trade, value.var = 'V1', fun.aggregate = sum)
x_cum <- x.cast[, as.list(cumsum(unlist(.SD))), by = variable]
monte_trades <- melt(x_cum, measure.vars = names(x_cum)[-1], variable.name = "trade", value.name = 'V1')
setorder(monte_trades, variable, trade)
monte_trades_last <- as.data.table(monte_trades[trade == '1000', V1])
quantile_trade <- monte_trades[, quantile(V1, probs = 0.05), by = trade]
RF_last <- monte_trades[, V1[.N] / maxdrawdown(V1)[[1]], by = variable]
p1 <- ggplot(data = monte_trades, aes(x = trade, y = V1, group = variable)) +
geom_line(size = 2, color = 'blue', alpha = 0.01) +
geom_line(data = quantile_trade, aes(x = trade, y = V1, group = 1), size = 2, alpha = 0.5, colour = 'blue') +
ggtitle('Simulated Trade Sequences of Length 1000')
p2 <- ggplot(data = monte_trades_last, aes(V1)) +
geom_density(alpha = 0.1, size = 1, color = 'blue', fill = 'blue') +
scale_x_continuous(limits = c(min(monte_trades$V1), max(monte_trades$V1))) +
coord_flip() +
ggtitle('Cumulative Profit Density')
p3 <- ggplot(data = RF_last, aes(V1)) +
geom_density(alpha = 0.1, size = 1, color = 'blue', fill = 'blue') +
geom_vline(xintercept = mean(RF_last$V1), colour = "blue", linetype = 2, size = 1) +
geom_vline(xintercept = median(RF_last$V1), colour = "red", linetype = 2, size = 1) +
ggtitle('Recovery Factor Density + Mean (blue) and Median (red)')
grid.arrange(p1, p2, p3, ncol = 3)
Sys.time() - start
gc()
Fonctionne pendant environ 45 secondes. Le tirage au sort dure environ 1,5 minute.
Le but de la simulation est de s'assurer que la statistique F ne dépasse pas une valeur critique lorsque la régression MNA est construite sur des données indépendantes (ne contenant pas de dépendances), satisfaisant ainsi aux exigences d'un modèle linéaire. Il peut donc être utilisé comme un indicateur de la formation du modèle.
Comment interpréter correctement le résultat de cet exemple ?
Je comprends que le premier prédicteur peut être considéré comme plus qualitatif que le premier + le second. Et 1+2 est mieux que 1+2+3. C'est vrai ? Est-il raisonnable de sélectionner par la génétique l'ensemble des prédicteurs qui donneront la fstatistique la plus élevée ?
Je n'ai pas tout compris au sujet de la statistique F. Ici, les données sont aléatoires, mais le modèle a appris quelque chose, vous pouvez donc en conclure que le modèle est adapté et surentraîné. Ce qui signifie que l'évaluation du modèle doit être mauvaise. En d'autres termes, je m'attendais à un fstatistis négatif, ou à une autre indication que les choses vont mal sur le graphique.
Comment puis-je interpréter correctement le résultat de cet exemple ?
Je comprends que le premier prédicteur peut être considéré comme plus qualitatif que le premier + le second. Et 1+2 est mieux que 1+2+3. C'est vrai ? Est-il raisonnable de sélectionner par la génétique l'ensemble des prédicteurs qui donneront la fstatistique la plus élevée ?
Regardez le tableau de distribution F.http://www.socr.ucla.edu/applets.dir/f_table.html
La statistique F est une valeur qui dépend des degrés de liberté. Elle est toujours positive, car nous avons une distribution unilatérale.
Mais le modèle n'apprend rien, parce qu'un modèle entraîné doit avoir une statistique F élevée (supérieure ou égale à la critique à un alpha donné - comme cela se présente lorsqu'on teste l'hypothèse nulle).
Dans tous les cas, ne pas dépasser la valeur critique à alpha = 0,01, mais vous pourriez la fixer à 0,0001, par exemple.
Cela dit, je voulais m'assurer (je n'ai pas étudié cela à l'université) qu'en ajoutant des variables de bruit, le modèle linéaire ne montrerait pas une augmentation de l'apprentissage. Comme vous pouvez le voir...
Code utile. Visualise les séquences de transactions en trois hypostases.
En ce qui concerne le code ci-dessus. Veuillez écrire au moins de brefs commentaires dans le code. Surtout lorsque vous utilisez des expressions complexes. Tout le monde ne connaît pas et n'utilise pas le paquet "data.table", il n'est pas superflu d'expliquer ce que fait dcast.data.table, fondre ce que sont .N, .SD. Vous ne postez pas le code pour montrer à quel point vous le connaissez. À mon avis, le code publié devrait aider les autres utilisateurs (même avec un niveau de formation élémentaire) à comprendre le script.
C'est bien que R vous permette de programmer l'action de plusieurs façons, mais il est souhaitable que vous ne perdiez pas la lisibilité du code.
Quelques suggestions sur le code :
- Les variables intermédiaires x, x.cast, x.cum ne sont pas nécessaires aux calculs et ne font qu'occuper de la mémoire. Tous les calculs ne nécessitant pas la sauvegarde des résultats intermédiaires doivent de préférence être effectués par l'intermédiaire du tuyau
Par exemple
rm(list=ls());gc()
library(data.table)
library(ggplot2)
library(gridExtra)
library(tseries)
#----
require(magrittr)
require(dplyr)
start <- Sys.time()
monte_trades <- as.data.table(matrix(rnorm(1000000, 0.1, 1), ncol = 1)) %>%
.[, variable := rep(1:1000, times = 1000)]%>%
.[, trade := 1:.N, by = variable] %>%
dcast.data.table(., variable ~ trade, value.var = 'V1', fun.aggregate = sum)%>%
.[, as.list(cumsum(unlist(.SD))), by = variable]%>%
melt(., measure.vars = names(.)[-1], variable.name = "trade", value.name = 'V1')%>%
setorder(., variable, trade)
monte_trades_last <- as.data.table(monte_trades[trade == '1000', V1])
quantile_trade <- monte_trades[, quantile(V1, probs = 0.05), by = trade]
RF_last <- monte_trades[, V1[.N] / maxdrawdown(V1)[[1]], by = variable]
Sys.time() - start
#Time difference of 2.247022 secs
Bien sûr, il faut beaucoup de temps pour construire des graphiques.
Ce n'est pas une critique.
Bonne chance
Je n'ai pas tout compris au sujet de la statistique F. Ici, les données sont aléatoires, mais le modèle a appris quelque chose, vous pouvez donc en conclure que le modèle est adapté et surentraîné. Ce qui signifie que l'évaluation du modèle doit être mauvaise. En d'autres termes, je m'attendais à un fstatistis négatif, ou à une autre indication que les choses vont mal sur le graphique.
Comment puis-je interpréter correctement le résultat de cet exemple ?
Je comprends que le premier prédicteur peut être considéré comme plus qualitatif que le premier + le second. Et 1+2 est mieux que 1+2+3. C'est vrai ? Est-il raisonnable de sélectionner par la génétique l'ensemble des prédicteurs qui donneront la fstatistique la plus élevée ?
Et voici un exemple où nous supposons que le modèle entièrement entraîné comprendra 20 variables, avec des poids croissants (1 variable - poids 1, la 20e variable - poids 20). Et voyons comment la distribution des statistiques F va changer après l'ajout successif de prédicteurs au modèle :
############### simulate lm f-stats with non-random vars
rm(list=ls());gc()
library(data.table)
library(ggplot2)
start <- Sys.time()
set.seed(1)
x <- as.data.table(matrix(rnorm(20000000, 0, 1), ncol = 20))
x[, (paste0('coef', c(1:20))):= lapply(1:20, function(x) rnorm(.N, x, 1))]
x[, output:= Reduce(`+`, Map(function(x, y) (x * y), .SD[, (1:20), with = FALSE], .SD[, (21:40), with = FALSE])), .SDcols = c(1:40)]
x[, sampling:= sample(1000, nrow(x), replace = T)]
lm_models <- x[,
{
lapply(c(1:20), function(x) summary(lm(data = .SD[, c(1:x, 41), with = F], formula = output ~ . -1))$'fstatistic'[[1]])
}
, by = sampling
]
lm_models_melted <- melt(lm_models, measure.vars = paste0('V', c(1:20)))
crtitical_f_stats <- qf(p = 0.99, df1 = c(1:20), df2 = 1000, lower.tail = TRUE, log.p = FALSE)
boxplot(data = lm_models_melted, value ~ variable, log = 'y'); lines(crtitical_f_stats, type = 's', col = 'red')
summary(lm(data = x[sample(1000000, 1000, replace = T), c(1:20, 41), with = F], formula = output ~ . -1))
Sys.time() - start
gc()
Graphique avec axe des y logarithmique :
Apparemment, oui...
> summary(lm(data = x[sample(1000000, 1000, replace = T), c(1:20, 41), with = F], formula = output ~ . -1))
Call:
lm(formula = output ~ . - 1, data = x[sample(1e+06, 1000, replace = T),
c(1:20, 41), with = F])
Residuals:
Min 1Q Median 3Q Max
-19.6146 -2.8252 0.0192 3.0659 15.8853
Coefficients:
Estimate Std. Error t value Pr(>|t|)
V1 0.9528 0.1427 6.676 4.1e-11 ***
V2 1.7771 0.1382 12.859 < 2e-16 ***
V3 2.7344 0.1442 18.968 < 2e-16 ***
V4 4.0195 0.1419 28.325 < 2e-16 ***
V5 5.2817 0.1479 35.718 < 2e-16 ***
V6 6.2776 0.1509 41.594 < 2e-16 ***
V7 6.9771 0.1446 48.242 < 2e-16 ***
V8 7.9722 0.1469 54.260 < 2e-16 ***
V9 9.0349 0.1462 61.806 < 2e-16 ***
V10 10.1372 0.1496 67.766 < 2e-16 ***
V11 10.8783 0.1487 73.134 < 2e-16 ***
V12 11.9129 0.1446 82.386 < 2e-16 ***
V13 12.8079 0.1462 87.588 < 2e-16 ***
V14 14.2017 0.1487 95.490 < 2e-16 ***
V15 14.9080 0.1458 102.252 < 2e-16 ***
V16 15.9893 0.1428 111.958 < 2e-16 ***
V17 17.4997 0.1403 124.716 < 2e-16 ***
V18 17.8798 0.1448 123.470 < 2e-16 ***
V19 18.9317 0.1470 128.823 < 2e-16 ***
V20 20.1143 0.1466 137.191 < 2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 4.581 on 980 degrees of freedom
Multiple R-squared: 0.9932, Adjusted R-squared: 0.993
F-statistic: 7123 on 20 and 980 DF, p-value: < 2.2e-16
Merci ! Je ne savais pas encore comment faire. Mais en réalité, vous devez garder les calculs à l'esprit autant que possible. Ce sera plus rapide. Bon kung fu...
Avec vos modifications :
#---variant-------------
rm(list=ls());gc()
library(data.table)
library(ggplot2)
library(gridExtra)
library(tseries)
#----
require(magrittr)
require(dplyr)
start <- Sys.time()
monte_trades <- as.data.table(matrix(rnorm(1000000, 0.1, 1), ncol = 1)) %>%
.[, variable := rep(1:1000, times = 1000)]%>%
.[, trade := 1:.N, by = variable] %>%
dcast.data.table(., variable ~ trade, value.var = 'V1', fun.aggregate = sum)%>%
.[, as.list(cumsum(unlist(.SD))), by = variable]%>%
melt(., measure.vars = names(.)[-1], variable.name = "trade", value.name = 'V1')%>%
setorder(., variable, trade)
monte_trades_last <- as.data.table(monte_trades[trade == '1000', V1])
quantile_trade <- monte_trades[, quantile(V1, probs = 0.05), by = trade]
RF_last <- monte_trades[, V1[.N] / maxdrawdown(V1)[[1]], by = variable]
p1 <- ggplot(data = monte_trades, aes(x = trade, y = V1, group = variable)) +
geom_line(size = 2, color = 'blue', alpha = 0.01) +
geom_line(data = quantile_trade, aes(x = trade, y = V1, group = 1), size = 2, alpha = 0.5, colour = 'blue') +
ggtitle('Simulated Trade Sequences of Length 1000')
p2 <- ggplot(data = monte_trades_last, aes(V1)) +
geom_density(alpha = 0.1, size = 1, color = 'blue', fill = 'blue') +
scale_x_continuous(limits = c(min(monte_trades$V1), max(monte_trades$V1))) +
coord_flip() +
ggtitle('Cumulative Profit Density')
p3 <- ggplot(data = RF_last, aes(V1)) +
geom_density(alpha = 0.1, size = 1, color = 'blue', fill = 'blue') +
geom_vline(xintercept = mean(RF_last$V1), colour = "blue", linetype = 2, size = 1) +
geom_vline(xintercept = median(RF_last$V1), colour = "red", linetype = 2, size = 1) +
ggtitle('Recovery Factor Density + Mean (blue) and Median (red)')
grid.arrange(p1, p2, p3, ncol = 3)
Sys.time() - start
La durée du film est de 47 secondes. Je veux dire, le code est plus joli et plus compact, mais il n'y a pas de différence de vitesse... Dessin, oui, très long. 1000 lignes avec transparence - grâce à elles...
Merci ! Je ne savais pas encore comment faire. Mais en réalité, vous devez garder les calculs à l'esprit autant que possible. Ce sera plus rapide. Bon kung fu...
Durée : 47 secondes. Je veux dire, le code est plus joli et plus compact, mais il n'y a pas de différence de vitesse... Le dessin, oui, est très long. 1000 lignes avec transparence - grâce à elles...
Mon calcul prend
# temps d'exécution en secondes
# min lq moyenne médiane uq max neval
# 2.027561 2.253354 2.254134 2.275785 2.300051 2.610649 100
Mais ce n'est pas si important. Il s'agissait de la lisibilité du code.
Bonne chance
PS. Et paralléliser le calcul de lm(). C'est exactement le cas lorsque vous avez besoin
J'ai un calcul qui prend
#Temps d'exécution en secondes
# min lq moyenne médiane uq max neval
# 2.027561 2.253354 2.254134 2.275785 2.300051 2.610649 100
Mais ce n'est pas si important. Il s'agissait de la lisibilité du code.
Bonne chance
PS. Et paralléliser le calcul de lm(). C'est exactement le cas lorsque c'est nécessaire.
Non. Vous donnez le temps pour une partie du code avant les graphiques. Je l'ai indiqué, ainsi que les graphiques.
J'ai 1,5 seconde avant les graphiques. Votre méthode est de 1,15 seconde.
rm(list=ls());gc()
library(data.table)
library(ggplot2)
library(gridExtra)
library(tseries)
start <- Sys.time()
set.seed(1)
x <- as.data.table(matrix(rnorm(1000000, 0.1, 1), ncol = 1)) #random normal value with positive expectation
x[, variable:= rep(1:1000, times = 1000)]
x[, trade:= 1:.N, by = variable]
x.cast = dcast.data.table(x, variable ~ trade, value.var = 'V1', fun.aggregate = sum)
x_cum <- x.cast[, as.list(cumsum(unlist(.SD))), by = variable]
monte_trades <- melt(x_cum, measure.vars = names(x_cum)[-1], variable.name = "trade", value.name = 'V1')
setorder(monte_trades, variable, trade)
monte_trades_last <- as.data.table(monte_trades[trade == '1000', V1])
quantile_trade <- monte_trades[, quantile(V1, probs = 0.05), by = trade]
RF_last <- monte_trades[, V1[.N] / maxdrawdown(V1)[[1]], by = variable]
Sys.time() - start
rm(list=ls());gc()
library(data.table)
library(ggplot2)
library(gridExtra)
library(tseries)
#----
require(magrittr)
require(dplyr)
start <- Sys.time()
monte_trades <- as.data.table(matrix(rnorm(1000000, 0.1, 1), ncol = 1)) %>%
.[, variable := rep(1:1000, times = 1000)]%>%
.[, trade := 1:.N, by = variable] %>%
dcast.data.table(., variable ~ trade, value.var = 'V1', fun.aggregate = sum)%>%
.[, as.list(cumsum(unlist(.SD))), by = variable]%>%
melt(., measure.vars = names(.)[-1], variable.name = "trade", value.name = 'V1')%>%
setorder(., variable, trade)
monte_trades_last <- as.data.table(monte_trades[trade == '1000', V1])
quantile_trade <- monte_trades[, quantile(V1, probs = 0.05), by = trade]
RF_last <- monte_trades[, V1[.N] / maxdrawdown(V1)[[1]], by = variable]
Sys.time() - start
Il s'avère que votre méthode est plus rapide...