Chapter 12 Analyzing Results

portfolio.st <- "Port.Luxor"
account.st <- "Acct.Luxor"
strategy.st <- "Strat.Luxor"
cwd <- getwd()
setwd("./_data/")
load.strategy(strategy.st)
setwd(cwd)
rm.strat(portfolio.st)
rm.strat(account.st)
initPortf(name = portfolio.st,
          symbols = symbols,
          initDate = init_date)
## [1] "Port.Luxor"
initAcct(name = account.st,
         portfolios = portfolio.st,
         initDate = init_date, 
         initEq = init_equity)
## [1] "Acct.Luxor"
initOrders(portfolio = portfolio.st,
           initDate = init_date)

12.1 Apply Strategy

# Results hidden to save space
applyStrategy(strategy.st, portfolios = portfolio.st)
checkBlotterUpdate(portfolio.st, account.st, verbose = TRUE)
## [1] TRUE
updatePortf(portfolio.st)
## [1] "Port.Luxor"
updateAcct(account.st)
## [1] "Acct.Luxor"
updateEndEq(account.st)
## [1] "Acct.Luxor"

12.2 Chart Positions

for(symbol in symbols) {
    chart.Posn(portfolio.st, Symbol = symbol, 
               TA = "add_SMA(n = 10, col = 4); add_SMA(n = 30, col = 2)")
}

12.3 Trade Statistics

tstats <- tradeStats(portfolio.st)
kable(t(tstats))
IWM QQQ SPY
Portfolio Port.Luxor Port.Luxor Port.Luxor
Symbol IWM QQQ SPY
Num.Txns 23 21 23
Num.Trades 11 10 11
Net.Trading.PL 2501.460 1070.748 2251.207
Avg.Trade.PL 211.1204 101.8385 200.5545
Med.Trade.PL 51.52684 -45.13684 -120.63947
Largest.Winner 2109.166 1287.017 2927.862
Largest.Loser -428.1350 -355.5896 -891.9164
Gross.Profits 3724.335 2463.680 5705.846
Gross.Losses -1402.011 -1445.295 -3499.746
Std.Dev.Trade.PL 732.3649 515.1777 1149.6862
Percent.Positive 63.63636 50.00000 45.45455
Percent.Negative 36.36364 50.00000 54.54545
Profit.Factor 2.656424 1.704621 1.630360
Avg.Win.Trade 532.0479 492.7360 1141.1692
Med.Win.Trade 152.6189 351.7958 909.5703
Avg.Losing.Trade -350.5026 -289.0589 -583.2910
Med.Losing.Trade -352.4492 -300.4438 -726.2925
Avg.Daily.PL 211.1204 101.8385 200.5545
Med.Daily.PL 51.52684 -45.13684 -120.63947
Std.Dev.Daily.PL 732.3649 515.1777 1149.6862
Ann.Sharpe 4.576179 3.138017 2.769194
Max.Drawdown -1691.308 -1343.709 -2942.752
Profit.To.Max.Draw 1.4790094 0.7968602 0.7650008
Avg.WinLoss.Ratio 1.517957 1.704621 1.956432
Med.WinLoss.Ratio 0.4330239 1.1709206 1.2523471
Max.Equity 2961.741 1893.009 3482.502
Min.Equity -678.91818 -52.69256 -2053.06787
End.Equity 2501.460 1070.748 2251.207

12.3.3 Averages

tab.wins <- tstats %>% 
    select(Avg.Trade.PL, Avg.Win.Trade, Avg.Losing.Trade, Avg.WinLoss.Ratio)

kable(t(tab.wins))
IWM QQQ SPY
Avg.Trade.PL 211.120398 101.838522 200.554528
Avg.Win.Trade 532.047851 492.735974 1141.169162
Avg.Losing.Trade -350.502644 -289.058929 -583.291000
Avg.WinLoss.Ratio 1.517957 1.704621 1.956432

12.3.4 Performance Summary

rets <- PortfReturns(Account = account.st)
rownames(rets) <- NULL
charts.PerformanceSummary(rets, colorset = bluefocus)

12.3.5 Per Trade Statistics

for(symbol in symbols) {
    pts <- perTradeStats(portfolio.st, Symbol = symbol)
    kable(pts, booktabs = TRUE, caption = symbol)
}
kable(pts)
Start End Init.Pos Max.Pos Num.Txns Max.Notional.Cost Net.Trading.PL MAE MFE Pct.Net.Trading.PL Pct.MAE Pct.MFE tick.Net.Trading.PL tick.MAE tick.MFE
2008-02-27 2008-03-07 100 100 2 13261.463 -881.91636 -881.91636 0.00000 -0.0665022 -0.0665022 0.0000000 -881.91636 -881.91636 0.00000
2008-03-07 2008-04-02 -100 -100 2 -12385.273 -725.99029 -725.99029 168.92951 -0.0586172 -0.0586172 0.0136395 -725.99029 -725.99029 168.92951
2008-04-02 2008-06-03 100 100 2 13144.834 99.74852 -395.16121 575.47610 0.0075884 -0.0300621 0.0437796 99.74852 -395.16121 575.47610
2008-06-03 2008-08-06 -100 -100 2 -13235.450 807.57595 -267.13716 1572.93130 0.0610161 -0.0201835 0.1188423 807.57595 -267.13716 1572.93130
2008-08-06 2008-09-08 100 100 2 12392.260 -151.38610 -436.70758 207.19458 -0.0122162 -0.0352404 0.0167197 -151.38610 -436.70758 207.19458
2008-09-11 2008-12-17 -100 -100 2 -11759.376 2937.86161 -394.74462 4444.47045 0.2498314 -0.0335685 0.3779512 2937.86161 -394.74462 4444.47045
2008-12-17 2009-01-21 100 100 2 8921.423 -706.59467 -1046.72109 214.09136 -0.0792020 -0.1173267 0.0239974 -706.59467 -1046.72109 214.09136
2009-02-05 2009-03-24 -100 -100 2 -7823.378 -110.63947 -689.54812 1166.48465 -0.0141422 -0.0881394 0.1491024 -110.63947 -689.54812 1166.48465
2009-03-24 2009-06-26 100 100 2 8100.427 991.08945 -344.57932 1258.95869 0.1223503 -0.0425384 0.1554188 991.08945 -344.57932 1258.95869
2009-07-06 2009-07-23 -100 -100 2 -8804.437 -863.21910 -863.21910 97.01343 -0.0980436 -0.0980436 0.0110187 -863.21910 -863.21910 97.01343
2009-07-23 2009-11-04 100 100 2 9516.246 919.57028 0.00000 1403.96276 0.0966316 0.0000000 0.1475333 919.57028 0.00000 1403.96276
2009-11-16 2009-12-31 100 100 1 10978.893 165.10760 -94.49099 293.10750 0.0150386 -0.0086066 0.0266974 165.10760 -94.49099 293.10750

12.3.6 Performance Statistics

tab.perf <- table.Arbitrary(rets,
                            metrics=c(
                                "Return.cumulative",
                                "Return.annualized",
                                "SharpeRatio.annualized",
                                "CalmarRatio"),
                            metricsNames=c(
                                "Cumulative Return",
                                "Annualized Return",
                                "Annualized Sharpe Ratio",
                                "Calmar Ratio"))
kable(tab.perf)
IWM.DailyEndEq QQQ.DailyEndEq SPY.DailyEndEq
Cumulative Return 0.2317202 0.1002049 0.1306882
Annualized Return 0.1095999 0.0488073 0.0632089
Annualized Sharpe Ratio 0.5363315 0.4537899 0.1979763
Calmar Ratio 0.6821284 0.3825050 0.2385090

12.3.7 Risk Statistics

tab.risk <- table.Arbitrary(rets,
                            metrics=c(
                                "StdDev.annualized",
                                "maxDrawdown",
                                "VaR",
                                "ES"),
                            metricsNames=c(
                                "Annualized StdDev",
                                "Max DrawDown",
                                "Value-at-Risk",
                                "Conditional VaR"))
kable(tab.risk)
IWM.DailyEndEq QQQ.DailyEndEq SPY.DailyEndEq
Annualized StdDev 0.2043511 0.1075549 0.3192751
Max DrawDown 0.1606735 0.1275992 0.2650170
Value-at-Risk -0.0194849 -0.0103564 -0.0310188
Conditional VaR -0.0266399 -0.0163183 -0.0522518

12.3.8 Buy and Hold Performance

rm.strat("buyHold")

# initialize portfolio and account
initPortf("buyHold", "SPY", initDate = init_date)
## [1] "buyHold"
initAcct("buyHold", portfolios = "buyHold",
         initDate = init_date, initEq = init_equity)
## [1] "buyHold"
# place an entry order
CurrentDate <- time(getTxns(Portfolio = portfolio.st, Symbol = "SPY"))[2]
equity = getEndEq("buyHold", CurrentDate)
ClosePrice <- as.numeric(Cl(SPY[CurrentDate,]))
UnitSize = as.numeric(trunc(equity/ClosePrice))
addTxn("buyHold", Symbol = "SPY", TxnDate = CurrentDate, TxnPrice = ClosePrice,
       TxnQty = UnitSize, TxnFees = 0)
## [1] "2008-02-27 00:00:00 SPY 75 @ 131.917425267632"
# place an exit order
LastDate <- last(time(SPY))
LastPrice <- as.numeric(Cl(SPY[LastDate,]))
addTxn("buyHold", Symbol = "SPY", TxnDate = LastDate, TxnPrice = LastPrice,
       TxnQty = -UnitSize , TxnFees = 0)
## [1] "2009-12-31 00:00:00 SPY -75 @ 111.440002"
# update portfolio and account
updatePortf(Portfolio = "buyHold")
## [1] "buyHold"
updateAcct(name = "buyHold")
## [1] "buyHold"
updateEndEq(Account = "buyHold")
## [1] "buyHold"
chart.Posn("buyHold", Symbol = "SPY")

12.3.9 Strategy vs. Market

rets <- PortfReturns(Account = account.st)
rets.bh <- PortfReturns(Account = "buyHold")
returns <- cbind(rets, rets.bh)
charts.PerformanceSummary(returns, geometric = FALSE, wealth.index = TRUE, 
                          main = "Strategy vs. Market")

12.3.10 Risk/Return Scatterplot

chart.RiskReturnScatter(returns, Rf = 0, add.sharpe = c(1, 2), 
                        main = "Return vs. Risk", colorset = c("red", "blue"))

12.3.11 Relative Performance

for(n in 1:(ncol(returns) - 1)) {
    chart.RelativePerformance(returns[, n], returns[, ncol(returns)], 
                              colorset = c("red", "blue"), lwd = 2, 
                              legend.loc = "topleft")
}

12.3.12 Portfolio Summary

#' Error
pf <- getPortfolio(portfolio.st)
xyplot(pf$summary, type = "h", col = 4)

12.3.13 Order Book

ob <- getOrderBook(portfolio.st)

12.3.14 Maximum Adverse Excursion

for(symbol in symbols) {
    chart.ME(Portfolio = portfolio.st, Symbol = symbol, type = "MAE", 
            scale = "percent")
}

12.3.15 Maximum Favorable Excursion

for(symbol in symbols) {
    chart.ME(Portfolio = portfolio.st, Symbol = symbol, type = "MFE", 
            scale = "percent")
}

12.4 Account Summary

a <- getAccount(account.st)
xyplot(a$summary, type = "h", col = 4)

12.4.1 Equity Curve

equity <- a$summary$End.Eq
plot(equity, main = "Equity Curve")

12.4.2 Account Performance Summary

ret <- Return.calculate(equity, method = "log")
charts.PerformanceSummary(ret, colorset = bluefocus, 
                          main = "Strategy Performance")

12.4.3 Cumulative Returns

rets <- PortfReturns(Account = account.st)
chart.CumReturns(rets, colorset = rich10equal, legend.loc = "topleft", 
                 main="SPDR Cumulative Returns")

12.4.4 Distribution Analysis

chart.Boxplot(rets, main = "SPDR Returns", colorset= rich10equal)

12.4.5 Annualized Returns

(ar.tab <- table.AnnualizedReturns(rets))
##                           IWM.DailyEndEq QQQ.DailyEndEq SPY.DailyEndEq
## Annualized Return                 0.1096         0.0488         0.0632
## Annualized Std Dev                0.2044         0.1076         0.3193
## Annualized Sharpe (Rf=0%)         0.5363         0.4538         0.1980

12.4.6 Performance Scatter Plot

max.risk <- max(ar.tab["Annualized Std Dev",])
max.return <- max(ar.tab["Annualized Return",])
chart.RiskReturnScatter(rets,
                        main = "SPDR Performance", colorset = rich10equal,
                        xlim = c(0, max.risk * 1.1), ylim = c(0, max.return))

12.4.7 Notional Costs

#quantstratII pp. 67/69
mnc <- pts$Max.Notional.Cost
pe <- sapply(pts$Start,getEndEq, Account = account.st)/3
barplot(rbind(pe,mnc),beside=T,col=c(2,4),names.arg=format(pts$Start,"%m/%d/%y"),
        ylim=c(0,1.5e5),ylab="$",xlab="Trade Date")
legend(x="topleft",legend=c("(Portfolio Equity)/9","Order Size"),
       pch=15,col=c(2,4),bty="n")
title("Percent of Portfolio Equity versus Trade Size for XLU")