> # Pull S&P500 index data from Yahoo! Finance
> getSymbols("^VDAX", from="2000-01-01")
[1] "VDAX"
>
> # Calculate the RSI indicator
> rsi <- RSI(Cl(VDAX), 2)
>
> # Calculate Close-to-Close returns
> ret <- ROC(Cl(VDAX))
> ret[1] <- 0
>
> # This function gives us some standard summary
> # statistics for our trades.
> tradeStats <- function(signals, returns) {
+ # Inputs:
+ # signals : trading signals
+ # returns : returns corresponding to signals
+
+ # Combine data and convert to data.frame
+ sysRet <- signals * returns * 100
+ posRet <- sysRet > 0 # Positive rule returns
+ negRet <- sysRet < 0 # Negative rule returns
+ dat <- cbind(signals,posRet*100,sysRet[posRet],sysRet[negRet],1)
+ dat <- as.data.frame(dat)
+
+ # Aggreate data for summary statistics
+ means <- aggregate(dat[,2:4], by=list(dat[,1]), mean, na.rm=TRUE)
+ medians <- aggregate(dat[,3:4], by=list(dat[,1]), median, na.rm=TRUE)
+ sums <- aggregate(dat[,5], by=list(dat[,1]), sum)
+
+ colnames(means) <- c("Signal","% Win","Mean Win","Mean Loss")
+ colnames(medians) <- c("Signal","Median Win","Median Loss")
+ colnames(sums) <- c("Signal","# Trades")
+
+ all <- merge(sums,means)
+ all <- merge(all,medians)
+
+ wl <- cbind( abs(all[,"Mean Win"]/all[,"Mean Loss"]),
+ abs(all[,"Median Win"]/all[,"Median Loss"]) )
+ colnames(wl) <- c("Mean W/L","Median W/L")
+
+ all <- cbind(all,wl)
+ return(all)
+ }
>
> # This function determines position size and
> # enables us to test several ideas with much
> # greater speed and flexibility.
> rsi2pos <- function(ind, indIncr=5, posIncr=0.25) {
+ # Inputs:
+ # ind : indicator vector
+ # indIncr : indicator value increments/breakpoints
+ # posIncr : position value increments/breakpoints
+
+ # Initialize result vector
+ size <- rep(0,NROW(ind))
+
+ # Long
+ size <- ifelse(ind < 4*indIncr, (1-posIncr*3), size)
+ size <- ifelse(ind < 3*indIncr, (1-posIncr*2), size)
+ size <- ifelse(ind < 2*indIncr, (1-posIncr*1), size)
+ size <- ifelse(ind < 1*indIncr, (1-posIncr*0), size)
+
+ # Short
+ size <- ifelse(ind > 100-4*indIncr, 3*posIncr-1, size)
+ size <- ifelse(ind > 100-3*indIncr, 2*posIncr-1, size)
+ size <- ifelse(ind > 100-2*indIncr, 1*posIncr-1, size)
+ size <- ifelse(ind > 100-1*indIncr, 0*posIncr-1, size)
+
+ # Today's position ('size') is based on today's
+ # indicator, but we need to apply today's position
+ # to the Close-to-Close return at tomorrow's close.
+ size <- lag(size)
+
+ # Replace missing signals with no position
+ # (generally just at beginning of series)
+ size[is.na(size)] <- 0
+
+ # Return results
+ return(size)
+ }
>
> # Calculate signals with the 'rsi2pos()' function,
> # using 5 as the RSI step: 5, 10, 15, 20, 80, 85, 90, 95
> # and 0.25 as the size step: 0.25, 0.50, 0.75, 1.00
> sig <- rsi2pos(rsi, 5, 0.25)
>
> # Break out the long (up) and short (dn) signals
> sigup <- ifelse(sig > 0, sig, 0)
> sigdn <- ifelse(sig < 0, sig, 0)
>
> # Calculate rule returns
> ret_up <- ret * sigup
> colnames(ret_up) <- 'Long System Return'
> ret_dn <- ret * sigdn
> colnames(ret_dn) <- 'Short System Return'
> ret_all <- ret * sig
> colnames(ret_all) <- 'Total System Return'
>
> # Create performance graphs
> png(filename="20090606_rsi2_performance.png", 720, 720)
> charts.PerformanceSummary(cbind(ret_up,ret_dn),methods='none',
+ main='RSI(2) Performance - RSI steps = 5, Size steps = 0.25')
> dev.off()
null device
1
>
> # Print trade statistics table
> cat('\nRSI(2) Trade Statistics - RSI steps = 5, Size steps = 0.25\n')
RSI(2) Trade Statistics - RSI steps = 5, Size steps = 0.25
> print(tradeStats(sig,ret))
Signal # Trades % Win Mean Win Mean Loss Median Win Median Loss
1 -1.00 88 53.40909 5.2745572 -7.5531197 4.2143812 -4.9583045
2 -0.75 84 54.76190 4.5101721 -2.7175500 3.4976644 -2.1517287
3 -0.50 86 53.48837 1.7966237 -1.6279009 1.4357783 -1.0054476
4 -0.25 75 53.33333 1.0926200 -1.0269003 1.0851092 -0.7834309
5 0.00 820 0.00000 NaN NaN NA NA
6 0.25 99 43.43434 0.8825651 -0.8701899 0.6996132 -0.6661582
7 0.50 108 47.22222 1.9479694 -1.5961592 1.0807337 -1.1223559
8 0.75 110 58.18182 2.3548429 -2.4669566 1.7238949 -1.8080330
9 1.00 93 59.13978 3.9157417 -2.4094268 2.5807884 -1.9412818
Mean W/L Median W/L
1 0.6983283 0.8499642
2 1.6596464 1.6255136
3 1.1036444 1.4279991
4 1.0639982 1.3850732
5 NaN NA
6 1.0142213 1.0502209
7 1.2204104 0.9629154
8 0.9545539 0.9534643
9 1.6251756 1.3294249
>
> # Print drawdown table
> cat('\nRSI(2) Drawdowns - RSI steps = 5, Size steps = 0.25\n')
RSI(2) Drawdowns - RSI steps = 5, Size steps = 0.25
> print(table.Drawdowns(ret_all, top=10))
From Trough To Depth Length To Trough Recovery
1 2011-06-30 2011-08-17 -0.5885 142 35 NA
2 2008-09-05 2009-01-28 2009-07-02 -0.4246 207 99 108
3 2010-04-29 2010-05-07 2010-06-04 -0.3366 27 7 20
4 2008-01-03 2008-02-01 2008-06-02 -0.3246 104 22 82
5 2011-03-11 2011-03-16 2011-06-23 -0.2317 71 4 67
6 2006-11-20 2007-01-10 2007-02-27 -0.2206 69 35 34
7 2007-02-28 2007-03-14 2007-05-24 -0.2184 59 11 48
8 2010-06-11 2010-07-09 2010-08-19 -0.1418 50 21 29
9 2007-06-06 2007-06-07 2007-07-19 -0.1059 31 2 29
10 2009-07-14 2009-07-17 2009-10-22 -0.1048 72 4 68
>
> # Print downside risk table
> cat('\nRSI(2) Downside Risk - RSI steps = 5, Size steps = 0.25\n')
RSI(2) Downside Risk - RSI steps = 5, Size steps = 0.25
> print(table.DownsideRisk(ret_all))
Total System Return
Semi Deviation 0.0231
Gain Deviation 0.0328
Loss Deviation 0.0346
Downside Deviation (MAR=210%) 0.0254
Downside Deviation (Rf=0%) 0.0420
Downside Deviation (0%) 0.0420
Maximum Drawdown 0.5885
Historical VaR (95%) -0.0326
Historical ES (95%) -0.0662
Modified VaR (95%) -0.0325
Modified ES (95%) -0.0325
>
> # Calculate signals with the 'rsi2pos()' function
> # using new RSI and size step values
> sig <- rsi2pos(rsi, 10, 0.3)
>
> # Break out the long (up) and short (dn) signals
> sigup <- ifelse(sig > 0, sig, 0)
> sigdn <- ifelse(sig < 0, sig, 0)
>
> # Calculate rule returns
> ret_up <- ret * sigup
> colnames(ret_up) <- 'Long System Return'
> ret_dn <- ret * sigdn
> colnames(ret_dn) <- 'Short System Return'
> ret_all <- ret * sig
> colnames(ret_all) <- 'Total System Return'
>
> # Calculate performance statistics
> png(filename="20090606_rsi2_performance_updated.png", 720, 720)
> charts.PerformanceSummary(cbind(ret_up,ret_dn),methods='none',
+ main='RSI(2) Performance - RSI steps = 10, Size steps = 0.30')
> dev.off()
null device
1
>
> # Print trade statistics table
> cat('\nRSI(2) Trade Statistics - RSI steps = 10, Size steps = 0.30\n')
RSI(2) Trade Statistics - RSI steps = 10, Size steps = 0.30
> print(tradeStats(sig,ret))
Signal # Trades % Win Mean Win Mean Loss Median Win Median Loss
1 -1.0 172 54.06977 5.6400869 -5.6151757 4.4680089 -3.9771323
2 -0.7 161 53.41615 2.7683257 -2.5567712 2.6039167 -1.8396178
3 -0.4 134 57.46269 1.5828935 -1.7327681 1.2381627 -1.1485039
4 -0.1 127 48.03150 0.4202959 -0.4784686 0.3746662 -0.2700018
5 0.0 246 0.00000 NaN NaN NA NA
6 0.1 145 48.27586 0.4256790 -0.3975987 0.2854013 -0.3650601
7 0.4 168 47.61905 1.8159699 -1.4675602 1.6329793 -1.2041778
8 0.7 207 45.41063 2.6100623 -2.3355773 1.8571666 -1.6712777
9 1.0 203 58.62069 3.4984234 -2.8912486 2.3045289 -2.3105522
Mean W/L Median W/L
1 1.0044364 1.1234247
2 1.0827429 1.4154661
3 0.9135056 1.0780657
4 0.8784189 1.3876432
5 NaN NA
6 1.0706247 0.7817928
7 1.2374074 1.3560949
8 1.1175234 1.1112257
9 1.2100043 0.9973932
>
> # Print drawdown table
> cat('\nRSI(2) Drawdowns - RSI steps = 10, Size steps = 0.30\n')
RSI(2) Drawdowns - RSI steps = 10, Size steps = 0.30
> print(table.Drawdowns(ret_all, top=10))
From Trough To Depth Length To Trough Recovery
1 2011-06-30 2011-08-17 -0.6565 142 35 NA
2 2008-09-04 2008-11-04 2009-06-22 -0.5067 200 44 156
3 2008-01-16 2008-02-01 2008-06-25 -0.3734 112 13 99
4 2010-04-29 2010-05-07 2010-06-04 -0.3455 27 7 20
5 2007-02-28 2007-03-23 2007-05-31 -0.2791 62 18 44
6 2011-02-22 2011-03-16 2011-06-21 -0.2548 82 17 65
7 2010-06-10 2010-07-09 2010-11-16 -0.2429 114 22 92
8 2006-11-16 2007-01-10 2007-01-22 -0.2077 45 37 8
9 2007-09-06 2007-09-24 2007-11-26 -0.1744 58 13 45
10 2006-06-19 2006-07-04 2006-07-12 -0.1557 18 12 6
>
> # Print downside risk table
> cat('\nRSI(2) Downside Risk - RSI steps = 10, Size steps = 0.30\n')
RSI(2) Downside Risk - RSI steps = 10, Size steps = 0.30
> print(table.DownsideRisk(ret_all))
Total System Return
Semi Deviation 0.0319
Gain Deviation 0.0314
Loss Deviation 0.0309
Downside Deviation (MAR=210%) 0.0327
Downside Deviation (Rf=0%) 0.0380
Downside Deviation (0%) 0.0380
Maximum Drawdown 0.6565
Historical VaR (95%) -0.0472
Historical ES (95%) -0.0826
Modified VaR (95%) -0.0481
Modified ES (95%) -0.0481
>
>
No comments:
Post a Comment