Friday, August 31, 2012

Testing the significancy of correlations on the financial markets

The current one year EURPLN - USDPLN daily changes correlation is at amazing 0.9024.

And I'm not talking about the nominal values of these currency crosses, but about their daily changes, which in aggregate seem to apparently resemble random walk:

Fig. EURPLN - USDPLN n=250 changes correlation

Meanwhile, the historical average correlations over 250 days is 0.3996 for them - still pretty high, but far from the current level.

The historical correlation mean is at the far right of the simulated correlation based on the stable distribution fitted to the changes of these currency crosses, and pretty much above the theoretical correlations based on N(0,1) changes.

Fig. Theoretical correlations based on fitted stable distribution to EURPLN and USDPLN changes,
as well as N(0,1) distributions

Still, the current level of the correlation between these two currencies may be an outlier for the historical distribution of the n=250 correlation is rather flat, i.e. pretty uninformative.

You can find some other assets with much more stronger correlations, though,

Take for an example two companies listed on the Warsaw Stock Exchange: PKO and PEO.

Their current one year correlation is 0.7366. While this is still a little over the average of 0.6705, the historical distribution of correlations points to a stable and strong relation between these companies:

Fig. PKO - PEO n=250 changes correlation

On the basis of the analysis of correlations of random data, you can clearly say, that the relation between PKO and PEO is hardly an accident:

Fig. Theoretical correlations based on fitted stable distribution to PKO and PEO changes,
as well as N(0,1) distributions

The strong connection between PKO and PEO is additionally confirmed by their cross correlation:
Fig. Crosscorrelation and Average Mutual Information for PKO and PEO

Nevertheless, predicting market movements with correlation, may not be an easy task...

Tuesday, August 28, 2012

For Dummies: Intro to Generalized Method of Moments


While researching various concepts from statistics and econometrics I constantly find, that many of the materials describing the concepts I'm researching are often too obscure.

Before I get through history, definitions, derivations of formulas, proofs and lemmas to applications and examples - things that I'm really interested in when I'm just starting to research something - I'm usually too bored to care... :(

In addition, many authors of the research papers and article assume, the reader knows everything the author does, and sometimes some authors are simply reluctant to reveal all the details of their approach. As a result, descriptions of the methods or experiments sometimes lack crucial parts, while the examples are not very informative for being as unclear as the description of the method itself.

Hence, I decided to write a couple of posts that will try to present some concepts in layman's terms.

Hope, you will enjoy :)

*   *   *

Generalized Method of Moments (GMM)  is a method of estimating parameters of a probability distribution (such as mean and standard deviation in the case of normal distribution), by checking what possible values of distribution parameters lead to the best fitting moments of the sample drawn from the distribution.

Moments are some measures describing the shape of the distribution. In case of the normal distribution, the four first moments are:

1. mean
2. variance -> standard deviation
3. skewness
4. kurtosis

So let's say, we have n=100 observations x drawn from the normal distribution which has some unknown parameters:

x ~ N(mean, standard deviation)

> x <- rnorm(n,x.mean,

Fig. Density of the sample

We would like to find out, what these parameters are.

Since, we are dealing with the normal distribution, it is very simple to find mean and standard deviation of the sample:

> mean(x)
[1] -7.176239

> sd(x)
[1] 6.105964

However, the sample parameters may not equal the distribution parameters.

Here we can use the before mentioned Generalized Method of Moments. It uses not only mean and variance (-> standard deviation), but also other moments of the distribution, to find better parameters.

You can use the sample estimates as starting points in searching for distribution parameters:

> t0 <- c(mean(x),sd(x)) # starting points <- sample estimates

> coef(gmm(g2,x,t0)) # GMM 2 moments

 Theta[1]  Theta[2] 
-7.176255  6.075357 

> coef(gmm(g3,x,t0)) # GMM 3 moments
 Theta[1]  Theta[2] 
-7.099134  5.981886 

> coef(gmm(g4,x,t0)) # GMM 4 moments
 Theta[1]  Theta[2] 
-6.995580  5.838024

In this case the more moments GMM uses, the value of mean increases while standard deviation decreases. As a results, the parameters estimated by GMM are getting closer to the true values of the distribution parameters, which are:

> x.mean
[1] -6.701526

[1] 5.493381

And that's Generalized Method of Moments in a nutshell ;)

BTW: You can alternatively use the Maximum Likelihood Method for the same task.

The results are very similar to GMM with 2 moments:

> o <- optim(c(0,1),objFun)

> o$par
[1] -7.176543  6.072980

But that's a totally different story :)

GMM portion of the R code based on Pierre Chausse, "Computing Generalized Method of Moments and Generalized Empirical Likelihood with R"

[ R source ]

Thursday, August 16, 2012

A simple way to simulate volatility clustering

Nearly a year ago I have mentioned an important characteristic of financial markets returns, i.e. volatility clustering.

This phenomenon was analyzed by Benoit Mandelbrot and presented in a work he co-authored: "A Multifractal Model of Asset Returns".

Volatility clustering is closely connected with heteroscedasticity (existence of periods of different variance) of financial times series. It can be said that volatility clustering is a special case of heteroscedasticity of time series. In presence of volatility clustering, variance is not only variable, but tends to cluster in time.

As I've mentioned in my previous post, volatility clustering needs to be addressed by risk management. But that's not all. It is also important in development of quantitative investment models, which should recognize and adapt to changes in volatility.

The simplest solution is to get rid of hetorscedasticity by normalizing the data:

But is is even more important, to understand what is really going on under the hood. For that you can generate a time series demonstrating volatility clustering behavior. Since you have full control over the simulated data, you can easily experiment with it and look for effects you can trade on.

MMAR is definitely a superior approach to simulate behavior of financial data, but sometimes a much simpler approach may be enough:

[ R code ]

Friday, August 3, 2012

Knight Fall or how to profit from a HFT computer glitch

On August 1st, a glitch in trading software at Knight Capital caused unusual behavior of various stocks listed on the NYSE.

At least one trader was able to profit from market disturbance caused by Knight Capital, by taking a short-time position in some affected asset.

Since, brief and limited in scope mini flash crashes and jumps are pretty common these days, it seems potentially profitable to create a high frequency strategy that identifies and trades such mispricings caused by other HFT algorithms.

Even that the Warsaw Stock Exchange has not implemented a HFT trading platform yet, unusual short-time disturbances are not total strangers here.

The chart below presents one such situation: the price of PZU, the largest Polish insurance company, decreased by 2.76% in one second on substantial volume on 27. July 2010.

Since PZU was a constituent of WIG20 index at that time, such a move should be reflected in the price of FW20 index futures. And in fact, the price of FW20 changed. But only after 5 seconds. It is a very long time in HFT terms...

Chart: PZU vs. FW20 futures contract, 2010-07-27, 10:47:39 -60 / +200 seconds
the blue bars represent volume

Wednesday, August 1, 2012

Random in, random out or how NOT to use artificial neural networks for prediction

In May last year I experimented a little with Google's machine learning tool - Google Prediction API.

One - I must admit stupid - experiment was to try to make Google Prediction API to forecast stock prices.

Quite unsurprisingly, all I received from Google Prediction API was a "flat line" at the level of the average stock price - meaning that the Google's machine learning engine was unable to estimate how the price will change.

The stock price returns/changes follow a random path which distribution is concentrated around zero, with fat and long tails (see: "Comparing probability distributions" and "Characterizing financial assets by Power Law alpha exponent")

Chart: Density of FW20(*) price changes
(*) FW20 - futures contract based on WIG20 index of the Warsaw Stock Exchange

There is a lot of noise that makes forecasting difficult.

I recently performed another experiment that confirms that observation. I tried to use artificial neural networks to find predictive patterns in raw returns series.

To simplify the task, I was trying to predict the direction of the changes, only.

In some cases, the proposed prediction model was able to correctly forecast between 70% and 100% of the changes. Pretty good, isn't it?

Chart: Actual (black) vs predicted changes (red)

Unfortunately, when you increase the number of tests, the performance rapidly deteriorates.

Ultimately, it settles at the 0.5 efficiency level - i.e. it is indistinguishable from random guesses:

> summary(
     Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
0.0000000 0.4285714 0.4285714 0.4957143 0.5714286 1.0000000 

> summary(fit.ratio)
     Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
0.0000000 0.4285714 0.5714286 0.5085714 0.5714286 0.8571429

Chart: Change direction match - ANN vs random model

It does not necessarily mean, that neural networks are worthless in modeling financial markets.

But the described here approach is incorrect.

One have to pre-process financial market data before feeding them into models such as ANN.

[ R code ]