- How sensitive are optimal-f values to the method used to construct the joint probability table?
- Is there an optimizer better suited for this problem (e.g. CMA-ES, or adaptive differential evolution)?
- How accurate are the estimates of the probability of drawdown, ruin, profit, etc.?
- What could be learned from ruin theory (see the actuar package)?

## Sunday, April 18, 2010

### Thoughts on LSPM from R/Finance 2010

I just got back from R/Finance 2010 in Chicago. If you couldn't make it this year, I strongly encourage you to attend next year. I will post a more comprehensive review of the event in the next couple days, but I wanted to share some of my notes specific to LSPM.

## Sunday, April 11, 2010

### Historical / Future Volatility Correlation Stability

Michael Stokes, author of the MarketSci blog recently published a thought-provoking post about the correlation between historical and future volatility (measured as the standard deviation of daily close price percentage changes). This post is intended as an extension of his "unfinished thought", not a critique.

He suggests using his table of volatility correlations as a back-of-the-envelope approach to estimate future volatility, which led me to question the stability of the correlations in his table. His table's values are calculated using daily data from 1970-present... but what if you were to calculate correlations using only one year of data, rather than thirty? The chart below shows the results.

The chart shows the rolling one-year (252-day) correlations for the diagonal in Michael's table (e.g. historical and future 2-day volatility, ..., historical and future 252-day volatility). You can see the shorter periods are generally more stable, but are also closer to zero. The rolling one-year correlation between historical and future one-year volatility swings wildly from +/-1 over time.

This isn't to argue that Michael's back-of-the-envelope approach is incorrect, rather it is an attempt to make the approach more robust by weighing long-term market characteristics against recent market behavior.

For those interested, here is the R code I used to replicate Michael's table and create the graph above. An interesting extension of this analysis would be to calculate volatility using TTR's volatility() function instead of standard deviation. I'll leave that exercise to the interested reader.

He suggests using his table of volatility correlations as a back-of-the-envelope approach to estimate future volatility, which led me to question the stability of the correlations in his table. His table's values are calculated using daily data from 1970-present... but what if you were to calculate correlations using only one year of data, rather than thirty? The chart below shows the results.

The chart shows the rolling one-year (252-day) correlations for the diagonal in Michael's table (e.g. historical and future 2-day volatility, ..., historical and future 252-day volatility). You can see the shorter periods are generally more stable, but are also closer to zero. The rolling one-year correlation between historical and future one-year volatility swings wildly from +/-1 over time.

This isn't to argue that Michael's back-of-the-envelope approach is incorrect, rather it is an attempt to make the approach more robust by weighing long-term market characteristics against recent market behavior.

For those interested, here is the R code I used to replicate Michael's table and create the graph above. An interesting extension of this analysis would be to calculate volatility using TTR's volatility() function instead of standard deviation. I'll leave that exercise to the interested reader.

require(quantmod)

# pull SPX data from Yahoo Finance

getSymbols("^GSPC",from="1970-01-01")

# volatility horizons

GSPC$v2 <- runSD(ROC(Cl(GSPC)),2)

GSPC$v5 <- runSD(ROC(Cl(GSPC)),5)

GSPC$v10 <- runSD(ROC(Cl(GSPC)),10)

GSPC$v21 <- runSD(ROC(Cl(GSPC)),21)

GSPC$v63 <- runSD(ROC(Cl(GSPC)),63)

GSPC$v252 <- runSD(ROC(Cl(GSPC)),252)

# volatility horizon lags

GSPC$l2 <- lag(GSPC$v2,-2)

GSPC$l5 <- lag(GSPC$v5,-5)

GSPC$l10 <- lag(GSPC$v10,-10)

GSPC$l21 <- lag(GSPC$v21,-21)

GSPC$l63 <- lag(GSPC$v63,-63)

GSPC$l252 <- lag(GSPC$v252,-252)

# volatility correlation table

cor(GSPC[,7:18],use="pair")[1:6,7:12]

# remove missing observations

GSPC <- na.omit(GSPC)

# rolling 1-year volatility correlations

GSPC$c2 <- runCor(GSPC$v2,GSPC$l2,252)

GSPC$c5 <- runCor(GSPC$v5,GSPC$l5,252)

GSPC$c10 <- runCor(GSPC$v10,GSPC$l10,252)

GSPC$c21 <- runCor(GSPC$v21,GSPC$l21,252)

GSPC$c63 <- runCor(GSPC$v63,GSPC$l63,252)

GSPC$c252 <- runCor(GSPC$v252,GSPC$l252,252)

# plot rolling 1-year volatility correlations

plot.zoo(GSPC[,grep("c",colnames(GSPC))],n=1,

main="Rolling 252-Day Volitility Correlations")

## Friday, April 9, 2010

### Maximum Probability of Profit

To continue with the LSPM examples, this post shows how to optimize a Leverage Space Portfolio for the maximum probability of profit. The data and example are again taken from The Leverage Space Trading Model by Ralph Vince.

These optimizaitons take a very long time. 100 iterations on a 10-core Amazon EC2 cluster took 21 hours. Again, the results will not necessarily match the book because of differences between DEoptim and Ralph's genetic algorithm and because there are multiple possible paths one can take through leverage space that will achieve similar results.

The results from the EC2 run were:

Specifying an initial population can give DEoptim an initial set of parameters that are within the constraint. This guarantees a starting point but it can slow optimization if the f (and/or z) values are too low. Therefore, experiment with the initial population to find a set of f (and/or z) values that produce a result within, but not far from, the constraint.

These optimizaitons take a very long time. 100 iterations on a 10-core Amazon EC2 cluster took 21 hours. Again, the results will not necessarily match the book because of differences between DEoptim and Ralph's genetic algorithm and because there are multiple possible paths one can take through leverage space that will achieve similar results.

The results from the EC2 run were:

iteration: 100 best member: 0.0275 0 0.0315 -0.928 -1 best value: -0.9999

The book results (on p. 173) were:
iteration: 100 best member: 0.085 0.015 0.129 -0.76 -0.992 best value: -0.9999

Specifying an initial population can give DEoptim an initial set of parameters that are within the constraint. This guarantees a starting point but it can slow optimization if the f (and/or z) values are too low. Therefore, experiment with the initial population to find a set of f (and/or z) values that produce a result within, but not far from, the constraint.

# Load the LSPM and snow packages

library(LSPM)

library(snow)

# Multiple strategy example (data found on pp. 84-87, 169)

trades <- cbind(

c(-150,-45.333,-45.333,13,13,13,13,13,79.667,79.667,79.667,136),

c(253,-1000,-64.429,-64.429,-64.429,253,253,448,-64.429,-64.429,-64.429,253),

c(533,220.143,220.143,-500,533,220.143,799,220.143,-325,220.143,533,220.143))

probs <- c(0.076923076923,0.076923076923,0.153846153846,0.076923076923,

0.076923076923,0.076923076923,0.076923076923,0.076923076923,

0.076923076923,0.076923076923,0.076923076923,0.076923076923)

# Create a Leverage Space Portfolio object

port <- lsp(trades,probs)

# Number of population members

np <- 30

# Initial population

initpop <- cbind(runif(np,0,0.01),runif(np,0,0.01),runif(np,0,0.01),

runif(np,-1,-0.8),runif(np,-1,-0.8))

# DEoptim parameters (see ?deoptim)

DEctrl <- list(NP=np, itermax=11, refresh=1, digits=6, initial=initpop)

# Create a socket cluster with snow to use both cores

# on a dual-core processor

cl <- makeSOCKcluster(2)

# Drawdown-constrained maximum probability of profit (results on p. 173)

res <- maxProbProfit(port, 1e-6, 12, probDrawdown, 0.1,

DD=0.2, calc.max=4, snow=cl, control=DEctrl)

Subscribe to:
Posts (Atom)