2017-02-26 5 views
0

J'apprends R et Quantmod et construit une prédiction de modèle de stock très simple. Je possède un xgboost et le modèle caret, voici l'exemple tout:Comment obtenir la prévision de stock réelle de xgboost, caret et Quantmod (R)

library(quantmod) 
library(xts) 
# get market data 
Nasdaq100_Symbols <- c("AAPL", "ADBE", "ADI", "ADP", "ADSK", "AKAM") 
getSymbols(Nasdaq100_Symbols) 

# merge them all together 
nasdaq100 <- data.frame(as.xts(merge(AAPL, ADBE, ADI, ADP, ADSK, AKAM))) 
# set outcome variable 
outcomeSymbol <- 'ADP.Volume' 

# shift outcome value to be on same line as predictors 
nasdaq100 <- xts(nasdaq100,order.by=as.Date(rownames(nasdaq100))) 
nasdaq100 <- as.data.frame(merge(nasdaq100, lm1=lag(nasdaq100[,outcomeSymbol],-1))) 
nasdaq100$outcome <- ifelse(nasdaq100[,paste0(outcomeSymbol,'.1')] > nasdaq100[,outcomeSymbol], 1, 0) 

# remove shifted down volume field 
nasdaq100 <- nasdaq100[,!names(nasdaq100) %in% c(paste0(outcomeSymbol,'.1'))] 

# cast date to true date and order in decreasing order 
nasdaq100$date <- as.Date(row.names(nasdaq100)) 
nasdaq100 <- nasdaq100[order(as.Date(nasdaq100$date, "%m/%d/%Y"), decreasing = TRUE),] 

# calculate all day differences and populate them on same row 
GetDiffDays <- function(objDF,days=c(10), offLimitsSymbols=c('outcome'), roundByScaler=3) { 
    # needs to be sorted by date in decreasing order 
    ind <- sapply(objDF, is.numeric) 
    for (sym in names(objDF)[ind]) { 
    if (!sym %in% offLimitsSymbols) { 
     print(paste('*********', sym)) 
     objDF[,sym] <- round(scale(objDF[,sym]),roundByScaler) 

     print(paste('theColName', sym)) 
     for (day in days) { 
     objDF[paste0(sym,'_',day)] <- c(diff(objDF[,sym],lag = day),rep(x=0,day)) * -1 
     } 
    } 
    } 
    return (objDF) 
} 

# call the function with the following differences 
nasdaq100 <- GetDiffDays(nasdaq100, days=c(1,2,3,4,5,10,20), offLimitsSymbols=c('outcome'), roundByScaler=2) 

# drop most recent entry as we don't have an outcome 
nasdaq100 <- nasdaq100[2:nrow(nasdaq100),] 

# use POSIXlt to add day of the week, day of the month, day of the year 
nasdaq100$wday <- as.POSIXlt(nasdaq100$date)$wday 
nasdaq100$yday <- as.POSIXlt(nasdaq100$date)$mday 
nasdaq100$mon<- as.POSIXlt(nasdaq100$date)$mon 

# remove date field and shuffle data frame 
nasdaq100 <- subset(nasdaq100, select=-c(date)) 
nasdaq100 <- nasdaq100[sample(nrow(nasdaq100)),] 

# xgboost Modeling 
library(xgboost) 
predictorNames <- names(nasdaq100)[names(nasdaq100) != 'outcome'] 

set.seed(1234) 
split <- sample(nrow(nasdaq100), floor(0.7*nrow(nasdaq100))) 
train <-nasdaq100[split,] 
test <- nasdaq100[-split,] 

bst <- xgboost(data = as.matrix(train[,predictorNames]), 
       label = train$outcome, 
       verbose=0, 
       eta = 0.1, 
       gamma = 50, 
       missing = NaN, 
       nround = 150, 
       colsample_bytree = 0.1, 
       subsample = 1, 
       nthread = 4, 
       objective="binary:logistic") 

predictions <- predict(bst, as.matrix(test[,predictorNames]), missing = NaN, outputmargin=TRUE) 

library(pROC) 
auc <- roc(test$outcome, predictions) 
print(paste('AUC score:', auc$auc)) 

Question 1:
En ce moment, elle forme à 70%, prédit 30%, et je peux imprimer un score AUC à la fin . Dites-vous que je m'entraîne à 100% et que je veux prédire ce qui se passera demain? C'est à dire. obtenir les symboles dont le volume pensera que le modèle remonte demain.

Question 2:
Idéalement, je veux continuer à ajouter les données de fin de journée d'aujourd'hui dans le modèle, et ensuite faire prédire les symboles de demain. En ce moment, il semble que je devrais utiliser getSymbols() pour tirer à nouveau l'histoire entière. Une façon de simplement extraire les données du jour et de les ajouter à l'objet xts de ce symbole?

Répondre

0

Il n'y a pas de réponse unique à la question 1, et vous ne savez pas très bien ce que vous voulez dire quand vous dites «choisir les symboles boursiers de demain» (dans quel but?). Je spécule que votre objectif est probablement d'essayer de prédire quels titres vont surperformer/sous-performer au cours d'un horizon futur (par exemple, la séance de négociation de demain) et d'agir sur ces prédictions.

La réponse à votre question dépend vraiment de la façon dont vous définissez votre modèle et de la façon dont vous choisirez vos stocks en fonction des prévisions que vous obtiendrez. Peut-être que choisir un modèle qui a optimisé les AUC est un bon choix pour classer les signes de rendement boursier ... ou peut-être que d'autres mesures pourraient mieux fonctionner (il n'y a pas une seule bonne réponse).

Le modèle que vous utilisez implique de prendre de nombreuses décisions. Vous pouvez utiliser la classification des signes de retour comme vous l'avez suggéré, ou vous pouvez estimer les rendements en utilisant une approche de régression au lieu d'utiliser un modèle de classification. Vous voudrez peut-être filtrer vos prédictions que vous obtenez de votre modèle d'une manière ou d'une autre avant de décider de "choisir les symboles boursiers de demain". Les options sont infinies ... le plus difficile est de trouver ce qui fonctionne réellement. Et je doute que quelqu'un ici va vous dire ce qui ne fonctionne pour des raisons évidentes;)

Question 2,

Utilisez les from et to arguments pour getSymbols si vous voulez collecter des données via Yahoo en utilisant quantmod. Plus précisément, regardez ?getSymbols.yahoo et/ou imprimez le code source (c'est-à-dire print(getSymbols.yahoo)). En outre, vous pouvez trouver end comme dans end(xts_object) utile pour donner l'horodatage le plus récent dans votre objet xts, avant de faire la requête getSymbols pour mettre à jour les données que vous avez déjà stockées.

getSymbols(Symbols = "AAPL", from = "2014-01-01", to = "2014-12-31")

Mise à jour:

# Get data for 2014 
sym <- "AAPL" 
md <- new.env() 
getSymbols(Symbols = sym, from = "2014-01-01", to = "2014-12-31", env = md) 
last_date <- end(get(sym, md)) 
new <- getSymbols(Symbols = sym, from = last_date + 1, to = Sys.Date(), auto.assign= FALSE) 
assign(x = sym, value = rbind(get(sym, md), new), envir = md) 
head(md$AAPL, 3) 
# AAPL.Open AAPL.High AAPL.Low AAPL.Close AAPL.Volume AAPL.Adjusted 
# 2014-01-02 555.68 557.03 552.02  553.13 58671200  74.11592 
# 2014-01-03 552.86 553.70 540.43  540.98 98116900  72.48790 
# 2014-01-06 537.45 546.80 533.60  543.93 103152700  72.88317 
tail(md$AAPL, 3) 
# AAPL.Open AAPL.High AAPL.Low AAPL.Close AAPL.Volume AAPL.Adjusted 
# 2017-02-22 136.43 137.12 136.11  137.11 20745300  137.11 
# 2017-02-23 137.38 137.48 136.30  136.53 20704100  136.53 
# 2017-02-24 135.91 136.66 135.28  136.66 21690900  136.66 
+0

Pour la première question, disons que le scénario est de savoir si le volume va augmenter demain. Donc, le modèle d'entraînement est le jour, et chaque symbole qui a son volume augmente le jour suivant obtient un 1, sinon il obtient 0. Juste la question éditée pour inclure l'équation. Donc maintenant, au lieu de m'entraîner, je veux savoir, en fonction de toutes les données, quels symboles obtiendront un 1 demain (ie le modèle pense que leur volume augmentera.) – Alteredorange

+0

Pour la question 2, je savais que je pourrais spécifier une date pour getSymbols, mais il a juste écrit sur les xts précédents Je vais devoir chercher à le combiner avec 'end' donc il ne fait que l'ajouter – Alteredorange

+1

@Alteredorange Ce que vous demandez pour la question 1 est soit trivial ou je ne comprends pas ce que vous voulez dire. Vos prévisions vous indiquent quels stocks peuvent avoir un volume plus élevé demain Pour la question 2, bien sûr, vous devez ajouter vos nouvelles données à vos anciennes données, où les anciennes données que vous stockez dans une variable avec un nom différent et/ou idéalement dans un environnement différent, vous ne l'avez pas vraiment précisé dans votre question, comment cela devrait être simple, juste 'rbind (old_OHLC_xts_data, new_data)'. – FXQuantTrader

0

Je travaille sur les mêmes problèmes, mais je suis en train de trouver la confiance d'une stratégie de négociation en utilisant le paquet de caret (à travers les fonctions « GAF » il a).

Pour répondre à la première partie de votre question, en formant vos données sur 100% des données historiques, vous allez exécuter "Overfitting", ce qui fait que vos prédictions futures seront très peu fiables. Vérifiez ce link pour une compréhension détaillée sur le suralimentation. Je vous recommande d'explorer Investopedia.com plus loin pour comprendre ce concept.À mon grand étonnement, le paquet caret vous offre non seulement des méthodes pour diviser votre ensemble de données, c'est-à-dire les données historiques, en un seul bloc de 70% et 30%, mais propose plusieurs blocs de validations croisées en un seul passage. disons, la fonction de l'algorithme génétique.

+0

Merci Abdul! Je regarde dans les gafs, avez-vous des tutoriels préférés? J'ai aussi appris un peu plus sur la validation croisée. Mais il semble aussi que Gafs ne cherche qu'un résultat, alors que dans ce scénario, j'aurais des résultats multiples (c'est-à-dire, cependant, beaucoup de symboles que je mets dans le modèle). Les gafs peuvent-ils gérer ça? – Alteredorange

+0

rien beaucoup frère. Mis à part quelques vidéos sur YouTube, j'ai pris ce didacticiel Datacamp sur Machine Learning: - https://www.datacamp.com/courses/machine-learning-toolbox –