Continuous Double Auction Model

Needs["StableM7`"];
LogReturn[data_] := Differences[Log[N[data]]];
AutoCorrelationF[data_,lag_]:=Module[{dataf,dataf1,n},n=Length[data];dataf=Fourier[Join[data-((Plus@@data)/n),Table[0.`,{lag}]]];dataf1=Take[Chop[Fourier[dataf Conjugate[dataf]]],lag+1] N[(Sqrt[n+lag])];(dataf1/(dataf1[[1]]))];
absecf0=Compile[{t,{s,_Real,1}},Abs[Mean[Exp[I t s]]]-1/E];
ABSECF0[t_?NumericQ,s_]:=absecf0[t,s];
QkScale[s_]:= Module[{c0,cc},
c0 =QuartileDeviation[s] ;(*this is best for alpha>1,not a reliable starting point as alpha -> 0*)
(*Absolute value of result is taken in case negative root is found*)
Abs[cc/.FindRoot[ABSECF0[1/cc,s],{cc,c0}]]];
EmpiricCDFList[data_] := Block[{prob,sel,del},
					
					prob= Table[(i-0.5)/Length[data],{i,Length[data]}];
					Transpose[Join[{Sort[data]},{prob}]]];
Clear[DisplayLogStableFit];
scdf[x_?NumericQ,parm_,type_:1,opts___]:=SCDF[x,parm,type,opts];
DisplayLogStableFit[data_,parm_,type_Integer:1]:=Module[{clist,lt,rt,trt,lp1,lp2,lp3,lp4,lp5,nmn,nstd},
clist=EmpiricCDFList[data];
	lt = Select[clist,#[[1]]<0&];
	rt= Select[clist,#[[1]]>0&];
	trt=Transpose[rt];
lp1=ListLogLogPlot[Abs[lt],PlotStyle->Blue,PlotRange->All];
lp2=ListLogLogPlot[Transpose[{trt[[1]],1- trt[[2]]}],PlotStyle->Red,PlotRange->All];
lp3= LogLogPlot[scdf[-x,parm,type],{x,0.0001,-4 Min[data]},PlotStyle->Blue,PlotRange->All,PerformanceGoal->"Speed"];
lp4= LogLogPlot[1-scdf[x,parm,type],{x,0.0001,-4 Min[data]},PlotStyle->Red,PlotRange->All,PerformanceGoal->"Speed"];
nmn=Mean[data];
nstd=StandardDeviation[data];
lp5= LogLogPlot[1-scdf[x,{2,0,nstd /Sqrt[2],nmn},1],{x,0.0001,4 nstd},PlotStyle->Green,PlotRange->All];
Show[lp1,lp2,lp3,lp4,lp5,PlotLabel->"Log Log Left Tail Blue, Right Red, (Normal Green)",AspectRatio->Automatic,PlotRange->All]];

In a simple continuous double auction model, limit buy orders and sell orders are accumulated in order arrays.  Market orders also come in as buy and sell orders.  For simplicity only an order of a unit volume is considered.  As market orders come in within some small unit time interval, they are matched and executed at the last market price.  When there is an excess of buy or sell orders within the order matching time interval they are executed through the limit sell and buy order books respectively.  For the model the number of buy and sell orders coming in during each order matching interval is assumed to be a Poisson random variable.  To keep the model as simple as possible, we consider only the net of buy or sell orders and do not include the orders that are matched at the market price.  Log prices are used in the algorithm and converted back to prices rounded to the nearest penny.  The rounding process, creates a significant number of sequentially equal prices.  The limit order books are refreshed for each matching interval.

For the model the arrival of market buy and sell orders is assumed to be governed by a Poisson distribution.  We match when we have 200 orders.  Since we are primarily interested in price changes we bother only with the difference of buy and sell orders and go to the appropriate order book with that difference.  The histogram shows how orders will be distributed.  We can create skewness by adjusting parameters so that the expected mean will not be zero.

poissondist=PoissonDistribution[200];
mktnet:= RandomInteger[poissondist]-200;
Histogram[RandomInteger[poissondist,1000]-200,Automatic,"ProbabilityDensity",PlotLabel->"Difference between Buy and Sell Orders in a Matching Interval"]

We use a heavy tailed Pareto distribution for limit order prices.  For the example alpha for the limit order book is 1.8.  A scale factor of 1/1000 is used, and the number of orders in the order book are set at 30 for each refresh interval.  The buy and sell order books are considered to be identically distributed but differ only by sign, so the refresh is only done once.  The model may easily be changed to different distributions for the order book.

lmtlen=30;
paretodist=ParetoDistribution[1,1.8];
Histogram[RandomReal[paretodist, lmtlen]/1000, 
 {0, 0.005,0.005/10},PlotLabel-> "Distribution of Limit Order Book Returns"]

Do a run of 10,000 matching intervals.
The algorithm is simplified so that large order books are not refreshed.  If the limit order book isn't big enough the excess is ignored and the next cycle started.  This short cut is not problematic unless parameters are selected so that the differences in the orders regularly exceed the limit book.  On the other hand if the limit book in this model is too long relative to the number of orders in the matching period, then extreme events at the tails will not occur, and the summed distribution will be normal.  Only unmatched orders mktnet are considered in this version.  Matched orders don't change the price in the model.  lmtlen needs to be closely matched to the maximal expected absolute values of mktnet or the fat-tails won't occur.  The Mathematica algorithm is shown below.

mktprice=50.;
pricelst={mktprice};
Do[lmtn=mktnet;
If[lmtn≠0,lmt =Sign[lmtn]Sort[RandomReal[paretodist,lmtlen]]/1000.;
pricelst=Flatten[{pricelst,Round[Exp[Take[lmt,Min[Abs[lmtn],Length[lmt]]]+Log[mktprice]] 100]/100.}]];
	mktprice=Last[pricelst],
		 {10000}];//AbsoluteTiming

A plot of all the prices.

ListPlot[pricelst,Joined->True]

Sum the log returns of prices at intervals of 50 prices then calculate stable parameters of summed log returns.

ret=LogReturn[pricelst];
ret1=Plus@@@Partition[ret,50];ListPlot[ret1,PlotRange->All,Joined->True,PlotLabel->"Log Returns"]

The system outputs true stable tails, as expected by the generalized central limit theorem.

parm=SMLFit[ret1];
CellPrint[TextCell["Stable parameters\n"<>(ToString[AccountingForm[#,6]]<>",  "&/@parm),"Text"]];

Stable parameters
1.50834,  0.13257,  0.00262663,  0.000301686,

Quiet[DisplayLogStableFit[ret1,parm]]

We have created a simple model of a continuous double auction.  It has heavy tails generated by a Pareto distribution, but other distributions could easily be used.  Research by Farmer, suggests that limit order books do indeed have heavy power tails.  The model was designed to yield the output of a stable distribution.  Adjusting some of the parameters can change things dramatically.

Follow the link to take a side tour exploring how power tail distributions might arise in financial markets.

txcolor=RGBColor[181/255,18/255,27/255];
t1 = Graphics[Text[Hyperlink[Framed[Style["Financial Home", {txcolor, Bold, Larger}]], "../map/Overview.html"], {-5, 0}]];
t2 = Graphics[Text[Hyperlink[Framed[Style["Next", {txcolor, Bold, Larger}]], "../r06/MarketData.html"], {0, -0.5}]];
t3 = Graphics[Text[Hyperlink[Framed[Style["Download Notebook", {txcolor, Bold, Larger}]], "../s07/CDA.nb"], {5, 0}]];
t4 = Graphics[Text[Hyperlink[Framed[Style["Previous", {txcolor, Bold, Larger}]], "../s06/GCLT.html"], {0, 0.5}]];
Show[ t1, t2, t3, t4, ImageSize -> 500]
CellPrint[TextCell["\n\n© Copyright " <> ToString[DateList[][[1]]] <> " mathestate    " <> DateString[DateList[], "DateShort"], "Text"]]

© Copyright 2008 mathestate    Fri 19 Dec 2008