Portfolio trading comparison example - part 1
In the previous post, I reworked the tradingPortfolio() procedures to handle trading signals produced by both quantmod library based model and custom ones. As custom trading signal, I mean any trading signal whose syntax is a sequence of {-1,0,1} values respectively indicating {sell,hold,buy} action. That can be build by any user procedure following any criteria which makes sense.
In this post, first I build a quantmod based model which forecats next week close price to next week open price gain by taking into account last two weeks gains. The trading dates are chosen so that both trading strategies at the end determine a sell action. Signal thresholds are set to 0 to evaluate trading strategies signal issuing at their core. Also buy.all and sell.all flags are set to TRUE for the same reasons. The output portfolio will be referenced as machine learning based portfolio.
suppressPackageStartupMessages(library(quantmod))
suppressPackageStartupMessages(library(rpart))
suppressPackageStartupMessages(library(rpart.plot))
suppressPackageStartupMessages(library(knitr))
ticker <- "YHOO"
getSymbols(ticker, src='yahoo')
## As of 0.4-0, 'getSymbols' uses env=parent.frame() and
## auto.assign=TRUE by default.
##
## This behavior will be phased out in 0.5-0 when the call will
## default to use auto.assign=FALSE. getOption("getSymbols.env") and
## getOptions("getSymbols.auto.assign") are now checked for alternate defaults
##
## This message is shown once per session and may be disabled by setting
## options("getSymbols.warning4.0"=FALSE). See ?getSymbols for more details.
## [1] "YHOO"
ticker = to.weekly(YHOO)
training.dates <- c('2012-01-01','2013-12-31')
trading.dates <- c('2014-01-01', '2015-02-20')
q.model <- specifyModel(Next(OpCl(ticker)) ~ (Lag(OpCl(ticker), 0:2)))
model.data <- modelData(q.model)
head(model.data)
## Next.OpCl.ticker Lag.OpCl.ticker.0.2.Lag.0
## 2007-01-19 0.006822298 -0.074966535
## 2007-01-26 0.025668486 0.006822298
## 2007-02-02 0.037321242 0.025668486
## 2007-02-09 0.089450287 0.037321242
## 2007-02-16 0.009433931 0.089450287
## 2007-02-23 -0.072560947 0.009433931
## Lag.OpCl.ticker.0.2.Lag.1 Lag.OpCl.ticker.0.2.Lag.2
## 2007-01-19 0.063176893 0.073114120
## 2007-01-26 -0.074966535 0.063176893
## 2007-02-02 0.006822298 -0.074966535
## 2007-02-09 0.025668486 0.006822298
## 2007-02-16 0.037321242 0.025668486
## 2007-02-23 0.089450287 0.037321242
model <- buildModel(q.model, method='rpart', training.per=training.dates,
control=rpart.control(minsplit=15))
rpart.plot(model@fitted.model)
signal.threshold <- c(0.00, 0.00)
control <- list("initial" = c("portfolio" = 0,
"own.shares" = 0,
"average.price"= 0,
"buy.first" = TRUE,
"sell.first" = FALSE),
"available.funds" = 6000,
"single.buy" = 0,
"buy.all" = TRUE,
"single.sell" = 0,
"sell.all" = TRUE,
"signal.threshold" = signal.threshold)
res <- tradePortfolio(ticker, model, trading.dates, control)
portfolioTradingHistory <- res[[1]]
filt.col <- c("portfolio.Open", "portfolio.Close", "portfolio.Gain", "action",
"own.shares", "available.funds.Close")
portfolioTradingHistFilt <- subset(portfolioTradingHistory[,filt.col], action != "hold")
kable(portfolioTradingHistFilt, caption="Machine learning based portfolio trading history")
portfolio.Open | portfolio.Close | portfolio.Gain | action | own.shares | available.funds.Close | |
---|---|---|---|---|---|---|
2014-01-10 | 0.000 | 6176.779 | 0.0000000 | buy | 149.8127 | 0.000 |
2014-01-31 | 5394.756 | 0.000 | -10.0873935 | sell | 0.0000 | 5394.756 |
2014-02-07 | 0.000 | 5588.391 | -10.0873935 | buy | 150.1045 | 0.000 |
2014-03-07 | 5809.045 | 0.000 | -3.1825805 | sell | 0.0000 | 5809.045 |
2014-03-14 | 0.000 | 5654.157 | -3.1825805 | buy | 150.3765 | 0.000 |
2014-03-28 | 5398.517 | 0.000 | -10.0247097 | sell | 0.0000 | 5398.517 |
2014-04-11 | 0.000 | 5202.265 | -10.0247097 | buy | 158.2679 | 0.000 |
2014-05-30 | 5483.982 | 0.000 | -8.6002962 | sell | 0.0000 | 5483.982 |
2014-06-06 | 0.000 | 5678.427 | -8.6002962 | buy | 158.0854 | 0.000 |
2014-06-13 | 5839.674 | 0.000 | -2.6720938 | sell | 0.0000 | 5839.674 |
2014-06-20 | 0.000 | 5681.169 | -2.6720938 | buy | 166.8478 | 0.000 |
2014-07-25 | 6026.544 | 0.000 | 0.4423964 | sell | 0.0000 | 6026.544 |
2014-08-01 | 0.000 | 5925.075 | 0.4423964 | buy | 166.3413 | 0.000 |
2014-08-15 | 6066.466 | 0.000 | 1.1077642 | sell | 0.0000 | 6066.466 |
2014-08-22 | 0.000 | 6271.046 | 1.1077642 | buy | 164.9841 | 0.000 |
2014-08-29 | 6353.538 | 0.000 | 5.8922980 | sell | 0.0000 | 6353.538 |
2014-09-05 | 0.000 | 6466.235 | 5.8922980 | buy | 163.3300 | 0.000 |
2014-10-24 | 7104.856 | 0.000 | 18.4142603 | sell | 0.0000 | 7104.856 |
2014-10-31 | 0.000 | 7554.343 | 18.4142603 | buy | 164.0465 | 0.000 |
2014-12-05 | 8364.733 | 0.000 | 39.4122196 | sell | 0.0000 | 8364.733 |
2014-12-12 | 0.000 | 8318.373 | 39.4122196 | buy | 165.5727 | 0.000 |
2014-12-26 | 8421.028 | 0.000 | 40.3504677 | sell | 0.0000 | 8421.028 |
2015-01-02 | 0.000 | 8337.931 | 40.3504677 | buy | 166.1936 | 0.000 |
2015-02-20 | 7330.799 | 0.000 | 22.1799786 | sell | 0.0000 | 7330.799 |
Afterwards, I build a portfolio based on the 10-weeks moving average indicator. The difference between the weekly closing price and its MA-10 moving average is used to trigger buy/sell actions. When such difference changes sign from negative to positive, a buy signal +1 is determined When on the contrary such difference changes sign from positive to negative, a sell signal -1 is determined. The output portfolio will be referenced as MA-10 based portfolio.
adj.trading.dates <- adjustTradingDate(ticker, trading.dates)
trading.window <- seq(from = adj.trading.dates[[1]], to = adj.trading.dates[[2]], by=1)
ticker.ma10 <- EMA(Cl(ticker), n = 10)
ticker.signal <- Cl(ticker) - ticker.ma10
ticker.trade <- ticker[trading.window]
len = nrow(ticker.trade)
signal <- rep(0, len)
trading.signal <- ticker.signal[trading.window]
for (i in 2:len) {
if (trading.signal[i-1] <= 0 && trading.signal[i] > 0) {
signal[i] <- 1
}
if (trading.signal[i-1] >=0 && trading.signal[i] < 0) {
signal[i] <- (-1)
}
}
portfolioMaTradingHistory <- tradePortfolioWithSignal(ticker.trade, control, signal)
portfolioMaTradingHistFilt <- subset(portfolioMaTradingHistory[,filt.col], action != "hold")
kable(portfolioMaTradingHistFilt, caption="MA-10 based portfolio trading history")
portfolio.Open | portfolio.Close | portfolio.Gain | action | own.shares | available.funds.Close | |
---|---|---|---|---|---|---|
2014-02-14 | 0.000 | 6036.316 | 0.0000000 | buy | 157.8947 | 0.000 |
2014-02-21 | 5887.895 | 0.000 | -1.8684184 | sell | 0.0000 | 5887.895 |
2014-02-28 | 0.000 | 6115.629 | -1.8684184 | buy | 158.1492 | 0.000 |
2014-03-14 | 5946.410 | 0.000 | -0.8931703 | sell | 0.0000 | 5946.410 |
2014-04-17 | 0.000 | 6448.000 | -0.8931703 | buy | 177.2402 | 0.000 |
2014-04-25 | 6111.243 | 0.000 | 1.8540564 | sell | 0.0000 | 6111.243 |
2014-05-02 | 0.000 | 6499.035 | 1.8540564 | buy | 176.2689 | 0.000 |
2014-05-09 | 5950.839 | 0.000 | -0.8193557 | sell | 0.0000 | 5950.839 |
2014-06-06 | 0.000 | 6161.837 | -0.8193557 | buy | 171.5434 | 0.000 |
2014-06-20 | 5841.051 | 0.000 | -2.6491514 | sell | 0.0000 | 5841.051 |
2014-07-03 | 0.000 | 6043.389 | -2.6491514 | buy | 167.2216 | 0.000 |
2014-07-18 | 5573.497 | 0.000 | -7.1083889 | sell | 0.0000 | 5573.497 |
2014-07-25 | 0.000 | 6036.423 | -7.1083889 | buy | 167.1213 | 0.000 |
2014-10-17 | 6425.816 | 0.000 | 7.0969342 | sell | 0.0000 | 6425.816 |
2014-10-24 | 0.000 | 7265.999 | 7.0969342 | buy | 167.0345 | 0.000 |
2015-01-16 | 7762.092 | 0.000 | 29.3681962 | sell | 0.0000 | 7762.092 |
2015-01-23 | 0.000 | 8120.419 | 29.3681962 | buy | 165.8921 | 0.000 |
2015-01-30 | 7297.594 | 0.000 | 21.6265674 | sell | 0.0000 | 7297.594 |
Saving both portfolio datasets for later analysis.
write.csv(portfolioTradingHistory, file = "portfolioTradingHistory.csv", row.names=TRUE)
write.csv(portfolioMaTradingHistory, file = "portfolioMaTradingHistory.csv", row.names=TRUE)
In my next post, I will comment on and perform graphic comparison of the results.
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.