Похоже, ты почти у цели.Вы подгоняете модель к тренировочным данным и обязательно выполняете тестирование на тестовом наборе, что является правильным решением.
Некоторые вещи, которые вы хотите соблюдать осторожно: не устанавливайте prefer = low
в add.rule
для входных сигналов;вы никогда не узнаете заранее, где был минимум в реальной торговле, для заполнения на следующем баре.
Я позволил логистической регрессии здесь прогнозировать 1 бар впереди от текущего бара, потому что это то, что выделать, если вы делали эти прогнозы "онлайн" / в режиме реального времени.Это нормально, при условии, что мы используем только прогнозируемые вероятности, и, очевидно, никогда не используем direction_fwd
в качестве торгового сигнала, потому что это приведет к смещению в сторону ожидания .
, чтобы упростить повторный запуск кодаЯ также храню рыночные данные в среде .data
, поэтому вы можете восстановить данные в GOOG
для applyStrategy, не запрашивая данные снова у Yahoo, если повторно выполнять части кода.
Также вы, вероятно, захотитеОграничьте количество раз, когда вы войдете в позицию.Вы можете сделать это с addPositionLimit
.И вы, вероятно, не хотите покупать каждый бар, когда вероятность> 0,6, а скорее только в первый раз (крест), поэтому я ввел код signal
, чтобы справиться с этим.
Помните,по умолчанию в quantstrat, ордер заполняется на следующем баре данных (здесь, цена открытия на следующем баре, начиная с prefer = "Open"
), который по умолчанию делает заливки более реалистичными (это более применимодля внутридневных данных баров, или отметьте строки данных), но это то, что вы хотите здесь, я думаю, так как вы не знаете значения RSI и импульса для текущего бара в то время end текущего бара, поэтомузаполнение следующего открытого бара имеет смысл.
rm(list=ls())
require(quantstrat)
require(PerformanceAnalytics)
set.seed(1234)
#setting up some initial parameters for the quantstrat trading model
initDate="2007-01-01"
from <- "2017-01-01"
to <- "2018-12-01"
init_equity <- 1000
adjustment <- TRUE
.orderqty <- 10
.txnfees <- -10
currency('USD')
Sys.setenv(TZ="UTC")
#Collect the data
symbols <- c('GOOG')
.data <- new.env()
getSymbols(symbols, from=from, to=to, src="yahoo", adjust=TRUE, env = .data)
colnames(.data$GOOG) <- c("open", "high", "low", "close", "volume", "adjusted")
mdata <- .data$GOOG
# create the dependent variable for a logistic regression
mdata$direction <- with(mdata, ifelse(close >= open, 1, 0))
#create two basic input variables - lagged
mdata$rsi <- RSI(mdata$close, nFast=14, nSlow = 26, nSig = 9, maType = SMA)
mdata$momentum <- momentum(mdata$close, n = 12)
mdata <- mdata[complete.cases(mdata), ]
mdata$direction_fwd <- lag.xts(mdata$direction, k = -1)
# create a training and test set
train_date <- nrow(mdata) *0.8
train <- mdata[1:train_date,]
test <- mdata[-c(1:train_date),]
#Run a simple logistic regression and obtain predicted probabilities
lm.fit <- glm(direction_fwd ~ rsi + momentum, data = train, family = binomial)
summary(lm.fit)
pr.lm <- predict(lm.fit, test, type = "response")
test$pred_prob <- pr.lm
#Add out predictions to the TEST data if its greater than 0.6
test$prediction <- ifelse(pr.lm > 0.6, 1, 0)
paste0("Accuracy: ", mean(test$direction_fwd == test$prediction, na.rm = T))
# Simple way to run applyStrategy is to make sure the data for the symbol is in a variable with its name, like so:
GOOG <- test
stock("GOOG", currency="USD", multiplier=1)
strategy.st <- portfolio.st <- account.st <- "LogisticRegressionStrategy"
rm.strat(strategy.st)
rm.strat(portfolio.st)
rm.strat(account.st)
initPortf(name = portfolio.st,
symbols = symbols,
initDate = initDate,
currency = 'USD')
initAcct(name = account.st,
portfolios = portfolio.st,
initDate = initDate,
currency = 'USD',
initEq = init_equity)
initOrders(portfolio.st,
symbols = symbols,
initDate = initDate)
strategy(strategy.st, store = TRUE)
nMult_orderqty <- 2
addPosLimit(portfolio.st, symbol = "GOOG", timestamp = initDate, maxpos = nMult_orderqty * .orderqty)
# Buy when prob exceeds 0.6 for the first time, using cross= TRUE
add.signal(strategy = strategy.st,
name = "sigThreshold",
arguments = list(threshold=0.6, column="pred_prob", relationship="gt", cross= TRUE),
label = "longSig")
#exit when prob drops below 0.5 for the first time
add.signal(strategy = strategy.st,
name = "sigThreshold",
arguments = list(threshold=0.5, column="pred_prob", relationship="lt", cross= TRUE),
label = "exitLongSig")
# Adding the rules, enter at the low price when "prediction" = 1, taking transaction fees into account
add.rule(strategy = strategy.st,
name = "ruleSignal",
arguments = list(sigcol = "longSig",
sigval = 1,
orderqty = .orderqty,
ordertype = "market",
orderside = "long",
osFUN = osMaxPos,
prefer = "Open", #Never kknow the low in advance. Use the open, as it is for the next day (be aware that the open price for bar data has its own problems too)
TxnFees = .txnfees,
replace = FALSE),
type = "enter",
label = "EnterLONG")
# As soon as the Logistic regression predicts a "0" we dump all our shares in GOOG
add.rule(strategy.st,
name = "ruleSignal",
arguments = list(sigcol = "exitLongSig",
sigval = 1,
ordertype = "market",
orderside = "long",
orderqty = "all",
TxnFees = .txnfees,
replace = TRUE),
type = "exit",
label = "Exit2SHORT")
applyStrategy(strategy.st, portfolios = portfolio.st)
updatePortf(portfolio.st)
updateAcct(account.st)
updateEndEq(account.st)
chart.Posn(portfolio.st, Symbol = "GOOG",
TA="add_SMA(n = 10, col = 2); add_SMA(n = 30, col = 4)")