Automated Day Trading using Mathematica

Dr Michael Kelly

Finance Consultant

Introduction

Modern financial exchanges are now equipped to handle trading data with turn around rates of 5 milliseconds. These new conditions mean that only automated pre-programmed trading can hope to succeed in such hyperkinetic conditions. Human beings with slow reaction times, limited calculation skills and an inability to correctly interpret fractal patterns such as time varying trade prices, are hopelessly equipped to deal with such novel situations. We had evolved to pick berries, evade predators and mate, and not to intuit complex mathematical relationships between rapidly varying stochastic processes. The recent financial disaster that sent markets reeling is testament to our hubris in trying to deal with these mutivariable phenomena. That is why computers are necessary to trade and why Mathematica, with its advanced programming language is uniquely capable of providing algorithms to analyze and react to huge quantities of trading data. This short paper will show how Mathematica code was capable of identifying hidden patterns in the dense data and how the Manipulate function was used to illustrate to traders how the program operated throughout the day, including estimates of profit and loss.

Basic Setup

In order to trade it is necessary to have two components in additional to the actual Exchange. First there must exist a Fix Fast protocol engine, usually in C# or Java but also possibly in Mathematica  with a corresponding API that communicates with the exchange and sucks the relevant data from it. This data usually takes the form of bid/ask prices with their associated time stamps. This data is then fed via MathLink, NetLink or Jlink to a Mathematica program which tracks the data, identifies patterns and initiates buy/sell signals which are then handed back to the Fix engine and onto the exchange. There are a number of Fix engine providers such as Aegis, Onix and Trading Technologies or you can write your own. Mathematica Solutions should investigate writing their own version using Mathematica's transform rule paradigm, which is the simplest method to provide a comprehensive technical solution for electronic trading.

The essential component of the analysis is the development of a Mathematica program that can spot hidden trends in the intra-day trading data and decide on an ongoing basis when to buy and sell and at what prices.

Difference bewtween Day Trading and End-of-Day Trading.

End-of-Day Trading

The first thing to understand is the enormous difference between day trading, using the continuously updated prices from the exchange and the previous notion of trading based upon end of day prices. This is especially important since all academic financial models for stochastic prices assume that we are only considering daily prices. The most common model for this is a lognormal ditsribution for equities. For asset prices, indicated by a variable S, we shall assume a traditional type of random walk, where the fractional change in S, d S/S, in a small time interval, d t, is given by a relation of the form

((d S)/S)=μ d t +σ d W

where μ is a mean drift rate parameter and σ is a volatility parameter. The term d W describes the randomness of the process, and satisfies two conditions:

(a) d W is a zero-mean normally-distributed random variable;
(b) E[d (W^2)] = d t.

Unfortunately none of this applies to intra-day trading. One possible comparison between daily and intra-day prices is between molecular dynamics and subatomic particles. Daily prices satisfy the Black-Scholes PDE, which is a special case of the Heat equation and aptly descibes the transmission of heat along an insulated bar by the excitation of molecules. Whereas associated with each open and close daily price there is a corresponding vector of intra-day prices, in exactly the same way that molecules are made up of individual atoms and their subatomic constituents. The trick therefore is to try and find those "atomic" patterns which will indicate buy and sell signals.

Daily Prices

Daily prices can be accessed either directly from the market or using Mathematica's own FinancialData[.] function.

DateListPlot[FinancialData["^DJI",{2007,1,1}],Joined->True, PlotLabel->Style["Dow Jones Index daily prices from 2007 to present",Brown]]

There are a number of known techniques in the literature for dealing with such structures that are called Technical Trading. These are described adequately at http://en.wikipedia.org/wiki/Technical_analysis  For instance we can easily define in Mathematica the Moving Average Convergence/Divergence indicator. The standard periods recommended back in the 1960s by Gerald Appel are 12 and 26 days:

The standard periods recommended back in the 1960s based upon daily prices by Gerald Appel are 12 and 26 days:

MACD(price, 12,26) = ExponMA(price, 12) - ExponMA(price,26)

A signal line (or trigger line) is then formed by smoothing this with a further ExponMA. Sometimes, SMA is used for signal. The standard period for this based upon daily prices is 9 days

Signal(price, 12,26,9) = ExponMA(MACD(price, 12,26), 9)

The difference between the MACD and the signal line is often calculated and shown not as a line, but a solid block histogram style. This construction was made by Thomas Aspray in 1986. The calculation is simply histogram = MACD − signal . When the more responsive 12-day ExponMA crosses up over the slower 26 day ExponMA we buy and when it crosses down we sell.

There are a large number of such trading techniques, but they all suffer from the fact that they were developed in response to early daily trading and not intra-day trading. Especially the parameters used above for periods of 12, 26 and 9 are still used in many day trading programs today, despite the fact that they were developed to describe daily trading many years ago. Much of the literature on automated trading suffers from this inappropriate reference to out of date methods that do not apply to recent intra-day prices.

Load Data

July2009ZNZBTimeBidAskPrices=ReadList["July2009ZNZBTimeBidAskPrices.txt"]//N;

July2009ZNZBDates=ReadList["July2009ZNZBDates.txt"]

ZNZBTimeBidAskPrices=July2009ZNZBTimeBidAskPrices;
ZNZBDates=July2009ZNZBDates;

ZNZBBidAskPrices=(ZNZBTimeBidAskPrices[[All,2]]+ZNZBTimeBidAskPrices[[All,3]])*0.5;

Hedge Ratio for ZN/ZB process

The Minimum variance Hedge Ratio β changes from day to day. We need to obtain a value for β that reflects the past month of values while still maintaining minimum values for the average SD and the average Range

Here we see that average SD and Range are minimized at β=0.5

With β=0.5 we get individual SDs and ranges comparable to the actual values

Using this value of the hedge ratio β we can find the bid/ask prices for the hedged instrument ZN - β*ZB

BetaZNZB=0.5;multZN=TickZN$;multZB=TickZB$*BetaZNZB;{multZN,multZB}

ZNZBBidPrices=ZNZBTimeBidAskPrices[[All,2,1]]-BetaZNZB*ZNZBTimeBidAskPrices[[All,3,2]];
ZNZBAskPrices=ZNZBTimeBidAskPrices[[All,3,1]]-BetaZNZB*ZNZBTimeBidAskPrices[[All,2,2]];
ZNZBBidAskPrices=(ZNZBBidPrices+ZNZBAskPrices)*0.5;

Intra-day prices

The following graph represents 54,000 trading values in an actual hedged trade ZN - β*ZB between ZN, the 10 year note and ZB, the 30 year treasury bond on July 6 this year. Despite optimised hedge ratios (β) that have been chosen to minimize the difference between these two bond prices, the hedged price difference displayed below manifests high volatility. In comparison with the daily prices above, two main differences are apparent: intra-day prices are both more volatile and more highly fractal. At the very least it suggests that the brownian motion random walk suggested for daily prices is now totally inappropriate and that some other fractal random walk with fractal Hurst coefficient > 0.7 is required. At the moment the only mathematical technique for representing such phenomena requires the Heda calculus, developed by one of Ito's disciples.

To get a further insight let's look just at one of the components of the above hedge and its distribution. The most disturbing thing here is that it is not either normally or lognormally distributed. So traditional approaches based upon gaussian distribution theory will break down.

Here we see the distributional properties of the hedged spread on a particular day using a trending filter:

Module[{ma=400,threshold=15,beta=BetaZNZB,width=10,bidaskprices=ZNZBBidAskPrices,dates=ZNZBDates,k=Length[ZNZBBidPrices]},GraphicsRow[{ListLinePlot[#,PlotLabel->"ZN/ZB cumTrend("<>ToString[ma]<>","<>ToString[threshold]<>") with β="<>ToString[beta],PlotRange->All],Labeled[Framed[TableForm[Quantile[#,{.005,.01,.02,.03,.05,.1,.15,.2,.25,.75,.8,.85,.9,.95,.97,.98,.99,.995}]//Chop,TableHeadings->{{"0.5% Quantile","1% Quantile","2% Quantile","3% Quantile","5% Quantile","10% Quantile","15% Quantile","20% Quantile","25% Quantile","75% Quantile","80% Quantile","85% Quantile","90% Quantile","95% Quantile","97% Quantile","98% Quantile","99% Quantile","99.5% Quantile"},None}]],"Quantiles for Trend("<>ToString[ma]<>","<>ToString[threshold]<>") on "<>ZNZBDates[[k]]],Histogram[#,{width},PlotLabel->"ZN/ZB Trend Histogram "<>dates[[k]],PlotRange->All]},Spacings->0]&[CumTrendAdjustment[bidaskprices[[k]],ma,threshold,2]]]

Here we have the average distributional properties over a period of several weeks for different parameter values of the indicator variable. The idea is to identify quantile levels which will trigger buy/sell signals.

In transferring the ideas of technical trading from daily to intra-day prices it becomes necessary to study the underlying distributions and after searching the sample space of possible parameter values, to find those that based upon the previous history of the particular trend are most likely to result in positive profits. The following table gives the result of such a PNL analysis for the ZN/ZB hedge trade.

The result of this analysis is to suggest a particular strategy based upon generalized ideas taken from the MACD model. The following graphs represents intra-day trading values in an actual hedged trade ZN - β*ZB between ZN, the 10 year note and ZB, the 30 year treasury bond. Here the red dots indicate sales and the blue dots indicate buys, structured so that it never exceeds a maximum position of 2. The graph underneath is the behaviour of the corresponding MACD indicator variable. As it passes down through the statistically determined barriers we buy and as it passes up through the barriers we sell. The values for the barriers depend upon the previous history of the underlying instruments ZN and ZB in this case.

The above pictures were special instances obtained from a Manipulate model. This takes in a large data base of values for a particular trade and analyses what happens when we change the parameter values of the model. This can be used to both suggest new approaches to trading and to explain the trading startegy to traders. Here are further results on a different date:

Filter/Trend Trading

Filtering Methods

After trying a number of different technical trading techniques, it becomes apparent that the best approach is to look for new patterns in the data using Mathematica's capability for pattern matching while also drawing on ideas taken from Filtering and Spectral Analysis. In particular if one wanted to only exercise a few trades a day it was necessary to try and identify underlying trends. The following pictures show the actual data collected on one day for the ZN/ZB hedged trade, the trend indicator variable as it was evaluated in real time throughout the day and the corresponding estimation of the same variable determined from the data set at the end of the day. An important property of any indicator variable is that it is not only non-anticipatory, but that it can be evaluated from the entire original data set without having to estimate it in a forward pass as it was constructed during the actual trading times. The reason for this is that optimal estimations of the indicator variable's parameters can only be done in reasonable times if we can determine the variable efficiently and quickly from the very large set of daily data prices.

The following graphs represents intra-day trading values in the hedged trade ZN - β*ZB between ZN, the 10 year note and ZB, the 30 year treasury bond. The red dots indicate sales and the blue dots indicate buys, structured so that it never exceeds a maximum position of 3 and never buys or sells when the price difference is less than $50. The indicator variable sends buy/sell signals when it crosses the barriers in a continuous down/up movement.

Here are further results on another date for a different indicator variable that uses a trailing stop-loss mechanism. Here buy/sell signals are generated when the indicator variable crosses up or down respectively over its continuously updated minimum or maximum values.

Here are further results using an indicator variable that is a combination of both of the two previous variables. The indicator variable here sends buy/sell signals when it crosses low barriers in a continuous down/up movement and when it crosses up/down over its continuously updated minimum and maximum values respectively.

Conclusion

The traditional approaches favoured by earlier texts on technical trading are virtually useless in today's electronic intra-day trading environment. In particular the use of fixed parameters for any trade ignores the particular distribution of the indicator variable associated with that trade which changes with time. The purpose of modern statistical electronic trading is to discover the distribution properties of the indicator variable which best describes the time varying trends inherent in that trade. Mathematica because of its pattern matching capabilities is the program most likely to achieve that goal.