[R-SIG-Finance] Hasbroucks Information Share in R

R. Michael Weylandt michael.weylandt at gmail.com
Wed Jul 11 21:02:55 CEST 2012

Hi Drew,

In addition to Brian's comments, a few stylistic / performance notes
below. I can't check content, but hopefully you'll find the resulting
code a little clearer and more idiomatic.

On Tue, Jul 10, 2012 at 10:25 PM, Drew Harris <drew.harris.nz at gmail.com> wrote:
> Hi all,
> I am a recent R converter so please bare with me if I ask any stupid
> questions. I am open to both constructive criticism and blatant mockery. I
> have been working on converting the Joel Hasbrouck Information share code
> originally for SAS and Implementing it into R. I have a working code but
> for some reason I am about 10% of the actual values, if there is anyone
> more experienced in this area I would much appreciate any advice availlable.
> I know there is a better method in a previous post by Niddhi Aggarwaul with
> a very coherent code for calculating a 2 dimensional case but I really need
> an n dimensional case which should be represented by my code being ideally
> the same as Hasbrouk's. My code is below, x refers to a matrix of parallel
> midpoint stock quotes of n markets.
> #find the optimal lag length
> lags <- VARselect(x, lag.max=100)$selection[1]
> #Johansens Cointegration test is applied and then estimates the VECM with
> the estimated Beta
> cointest <- ca.jo(x, K=lags, type="eigen", ecdet="const",
> spec="transitory")
> #summary(cointest)
>     vecm <- cajorls(cointest)
> #Breaks the VECM down into VAR by levels as in Hasbrouck
>     var <- vec2var(cointest)
> #covariance of forecast error response
> FER <- fevd(var, n.ahead=ImpulseResponse,cumulative=TRUE, boot=FALSE)
> #covariance matrix of innovations
> d <- dim(FER[[1]])
> for (i in 1:n) {
> errvar <- FER[[i]]
> if (i == 1) {CovIn <- errvar[(d[1]),]}
> if (i != 1) {CovIn <- rbind(CovIn, errvar[(d[1]),])}
> }

It's generally going to give you worlds better performance to make a
list of objects and then rbind() them all at once. (Consider the
equivalent C level operations of malloc()ing and free()ing on each
iteration, with all the work that entails) You can also avoid an
(explicit) for loop by doing something like:

do.call(rbind, lapply(FER, function(x) x[d[1],]))

> #long run cumulative response functions
> CRF <- irf(var, n.ahead=ImpulseResponse, ortho=TRUE, cumulative=FALSE,
> boot=FALSE)
> #matrix of long run cumulative response functions
> d <- dim(CRF$irf[[1]])
> for (i in 1:n) {
> lrcrf <- CRF$irf[[i]]
> if (i == 1) {LRCoeffs <- lrcrf[(d[1]),]}
> if (i != 1) {LRCoeffs <- rbind(LRCoeffs, lrcrf[(d[1]),])}
> }

As before, something like

do.call(rbind, lapply(CRF, function(x) x[d[1],]))

>  Cdiag  <- diag(CovIn)
> sqrtd <- sqrt(Cdiag)
> sd  <- diag(sqrt(sqrtd)

Are you sure you mean to sqrt() twice in here?

> cor   <- sd %*% CovIn %*% sd
> cd  <- t(chol(cor))
> VarContrib     <- LRCoeffs %*% cd

Probably a little easier to use the tcrossprod() function:

VarContrib <- tcrossprod(LRCoeffs, chol(cor))

> VarTotal       <- colSums(VarContrib)
> VarTotalMatrix <- VarTotal
>  for (i in 1:(VectorCount-1)) {

See below, but this sort of syntax is sometimes fraught with peril
because it gives a loop of length 2, not 0 if VectorCount = 1;
specifically, it loops for i = 1 and then i = 0.

> VarTotalMatrix <- rbind(VarTotalMatrix,VarTotal)}
> PC <- VarContrib / (VarTotalMatrix)
>  if (j == 1) {
> PropCont <- colMeans(t(PC))}
> if (j != 1) {
> PropCont <- rbind(PropCont, colMeans(t(PC)))}
> }

I'll let you modify this one like above, but note there's also a
rowMeans() function which will be faster than colMeans(t(...))

> rm(InformationShares)
> colnames(PropCont) <- InputVectors
> InformationShares  <-colMeans(PropCont)

I'd recommend you wrap this all up in a function: then you don't have
to worry about freeing memory with rm() [It just happens when the
function call ends] and your code will be more reusable. If you do so,
it's not totally necessary, but it'll be easier to read if you add
return(InformationShares) at the end. [Some prefer just
InformationShares without a return statement but I find that
marginally less obvious: you actually wouldn't need either here
because of some subtleties about <- being a function as well, but
don't worry about that here.]

Disclaimer: I did the do.call(rbind, ...) bits real quick: they might
not be quite perfect.


>         [[alternative HTML version deleted]]
> _______________________________________________
> R-SIG-Finance at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-sig-finance
> -- Subscriber-posting only. If you want to post, subscribe first.
> -- Also note that this is not the r-help list where general R questions should go.

More information about the R-SIG-Finance mailing list