Agent-Based Market Simulation · 2003

Doctoral dissertation · Chapter 2 · 2003

A market made of people who disagree

Four hundred traders watch each other, change their minds, and push a single price around. Nothing schedules them. Ten competing clocks decide what happens next and when — so the market trades in bursts, the way real ones do.

Try it yourself the same model, with the dials exposed

Chapter 2 of a doctoral dissertation defended in 2003, presented as it was, with the model re-implemented so its figures can be regenerated.

the exchange rate, tick by tick price fundamental value

who is holding which strategy optimists pessimists fundamentalists

every event, as it happens

what the market maker sees

Two hundred traders, running live. All four panels share one axis of simulated time: the price steps only where the raster shows a price event, and the imbalance decides which way the next one goes. Live in-browser run of a 2026 re-implementation of the 2003 model, at a reduced population. Not a figure from the original paper.

The problem

One average investor cannot do this

Real markets do something that textbook models do not. They have quiet weeks and frantic weeks, and the frantic ones arrive in clumps. Prices occasionally move further in an afternoon than they have in the preceding month. Enormous quantities change hands — far more than any account of who needed to buy or sell would predict.

The standard framework explains price movement through a single representative investor who responds rationally to news. On that account, the market moves when the world does. But studies of intraday data find that news produces spikes in volatility — the size of the price swings, regardless of their direction — without accounting for most of the volatility observed. A large residue is left over. Something other than public information is moving the price.

So the question becomes whether the turbulence comes from outside the market at all, or whether a crowd of ordinary traders, watching each other and changing their minds, produces it by themselves. The way to find out is to build the crowd and see what it does.

The population

Three ways to be wrong

The market holds a fixed number of traders. At any moment each of them is following one of three strategies, and each can change to another.

Optimistic chartists read the price history, expect it to keep rising, and buy. Pessimistic chartists read the same history, expect a fall, and sell. Fundamentalists ignore the chart and ask instead what the currency is worth — its fundamental value — buying when the price sits below that and selling when it sits above.

The paper is careful about what to call the first two. The microstructure literature would say noise traders, a term Black [1986] coined for people who "trade on noise as if it were information." The paper declines it. Technical analysis is the plainest method professionals use to forecast short-horizon moves, and in foreign exchange it dominates everything else; Frankel and Froot [1990], Taylor [1992] and Lui and Mole [1998] all document that chartist and fundamentalist methods are both widely used, and — the part that matters for this model — that their relative weights shift over time.

The three strategies and the six ways a trader can move between them. Every switch has its own rate, written β₁ to β₆. Point at an arrow, or move to it with the keyboard, to see what drives it.

How a trader changes their mind

Traders meet each other at random. When two meet, they compare how the other's strategy has been doing lately, and one may switch. Two forces decide it.

The first is herding. Among the chartists there is an opinion index — a single number saying how lopsided the crowd currently is, running from everyone bearish to everyone bullish. The more lopsided it already is, the more strongly it pulls the next switch its own way.

The second is profitability. A chartist's case is the recent trend: if the price has been climbing, expecting it to keep climbing has been paying. A fundamentalist's case is the gap between price and fundamental value: the wider the gap, the more there is to collect when it closes. That prospective gain is discounted, because the correction is not immediate and nothing says when it arrives.

What is absent matters as much as what is present. There is no learning and no evolution. An agent can tell which strategy is winning now; none of them accumulates any knowledge about how the market works. There is no budget constraint either, so a trader can persist in a losing strategy indefinitely. Herd behaviour is possible in this market. Learning is not.

The mechanics — force terms

Write n+n_+ and nn_- for the numbers of optimistic and pessimistic chartists, and nc=n++nn_c = n_+ + n_- for the chartists in total. The opinion index is their normalised difference, so it is scale-free and sits in [1,1][-1,1]:

x=n+nn++nx = \frac{n_+ - n_-}{n_+ + n_-}

The force term driving a switch between optimism and pessimism adds to that a momentum signal built from the price τ days ago:

U1=α1x+α2ν1p(t)p(tτ)τU_1 = \alpha_1 x + \frac{\alpha_2}{\nu_1}\cdot\frac{p(t)-p(t-\tau)}{\tau}

where τ is the chartists' look-back horizon in calendar time. It "typically reveals the chartists' time horizon, whether they are trend followers or contrarians."

An implementation reading. The momentum term is written in the source in absolute price units. At the Table 2.1 values and a fundamental of 100 it reaches magnitudes above twenty, the exponential rates overflow, one chartist camp empties to its floor within a simulated day and the internal clock stops advancing. The re-implementation reads it as a rate of return instead — divided by pp, exactly as the same momentum signal is written inside the two force terms below, and as the scale-free opinion index it is added to requires. This is recorded in the project README.

Switching between a chartist strategy and the fundamentalist strategy is driven by the difference between the two strategies' gains. With RR the domestic risk-free rate, rr the foreign rate, and ss the discount applied to the fundamentalists' expected gain because the correction is not immediate:

U2,1=α3{r+1ν2pp(tτ)τpRspfpp}U_{2,1} = \alpha_3\left\{ \frac{r + \frac{1}{\nu_2}\frac{p-p(t-\tau)}{\tau}}{p} - R - s\left|\frac{p_f-p}{p}\right| \right\}
U2,2=α3{Rr+1ν2pp(tτ)τpspfpp}U_{2,2} = \alpha_3\left\{ R - \frac{r + \frac{1}{\nu_2}\frac{p-p(t-\tau)}{\tau}}{p} - s\left|\frac{p_f-p}{p}\right| \right\}

A chartist who becomes a fundamentalist leaves the market and so earns the domestic risk-free rate, giving up the foreign rate and the market return over the period. The wider the mispricing, the more negative both force terms become, and the more the population drains toward the fundamentalists.

The chapter notes that these transition probabilities are not derived from an explicit intertemporal optimisation, but that, as Lux [1997] observed, they can be obtained formally from a maximisation programme for rational agents whose utility includes social-interaction terms and extreme-value error terms. Brock and Durlauf [2000] review that discrete-choice literature.

The distinctive contribution

Time is not a grid

Almost every market simulation of the period advanced in fixed steps. One tick, one minute, one day; compute everything, move on. The length of the step was a dial the modeller turned by hand until the results looked right. The chapter is blunt about this: Lux and Marchesi [1999, 2000] and Chen et al. [2001] "must adjust the length of time increments arbitrarily in order to obtain realistic results."

This model does not have a step. Ten things could happen next: any of the six strategy switches, the price moving up or down, or a piece of news pushing the fundamental value up or down. Each of the ten carries its own waiting time, drawn independently. At every moment all ten clocks are running at once.

Only the shortest one runs out. That event happens, the market's internal clock jumps forward by exactly that interval, and the other nine waiting times are thrown away and drawn again from scratch against the new state of the market.

The consequence is the point of the whole construction. When the market is agitated — a lopsided crowd, a wide mispricing — the rates are high, the waiting times are short, and events pile on top of each other. When it is calm, nothing happens for a long while. Trading time comes out irregular and bursty without anyone having imposed it. It is a property of the mechanism, not a setting.

Ten waiting times, drawn fresh. The shortest is the only one that happens; the market's clock advances by exactly that much and the other nine are discarded. Draw it a few times and watch how rarely the same event wins twice — and how unevenly the clock below moves. Rates taken from a 2026 re-implementation of the 2003 model, settled after forty simulated days; each draw is made live in this page. Not a figure from the original paper.
Business time against calendar time Each step up is one more event recorded by the market; each step across is however long the winning clock happened to take. The staircase on the left is drawn from the eleven event times of the chapter's Figure 2.1, whose lower panel records which event won each race and when. The one on the right is the same construction taken from an actual run over a few simulated hours. Steps of visibly unequal width are the whole idea: the market's own clock and the wall clock are not the same clock. The right-hand panel was produced by a 2026 re-implementation of the 2003 model. The left-hand panel is built from the event times of the chapter's Figure 2.1; the chapter's own Figure 2.2 was not among the pages available for this presentation, and is not reproduced here.
The mechanics — waiting times and the clock

Each event jj has a jump rate βj\beta_j that depends on the current state of the market. Its waiting time is drawn from an exponential distribution whose parameter is that rate scaled by the population size:

dtjE(nβj),j=1,,10dt_j \sim \mathcal{E}(n\beta_j),\qquad j = 1,\dots,10

Only the minimum is realised, and business time advances by it:

ti+1=ti+dtmint_{i+1} = t_i + dt_{\min}

The chapter runs this for i=1,,12×106i = 1,\dots,12\times10^6 events. The daily price is whatever the price happens to be when the internal clock crosses a day boundary — the closing rule is written in the chapter as

if (t_i > day + 1), record (market price …), and set day = day + 1.

Because these events are Poisson by construction, the process is close to a continuous-time Markov chain, though the chapter is careful to say it is not Markovian in the strict sense: the momentum term carries a lagged price, so the process has non-zero but finite memory, bounded by the strategy horizon. Delahaut [2003] gives the formal treatment.

One consequence of working in continuous time: the probability that two events coincide is formally zero. Every strategy switch in this market is asynchronous, however small the interval between two of them may be.

The chapter connects the irregularity of durations to the autoregressive conditional duration literature begun by Engle and Russell [1998], in which an observed duration combines an autoregressive model of expected duration with residuals following a Weibull distribution — which for γ=1\gamma = 1 is the exponential distribution used here.

Price formation

One market maker, one tick at a time

Every order in this market goes to the same place. A single market maker stands ready to take the other side of anything, at no transaction cost. That makes liquidity permanent and removes the gap between what you can buy at and what you can sell at: there is no bid–ask spread here, and no inventory to manage. The chapter is explicit that this simplification is not innocuous, and notes what other simulations do instead — Jefferies et al. [2000] bolt on a spread that shrinks as volume rises; Chakrabarti [2000] derives one from a risk-averse market maker's optimisation.

What reaches the market maker is the imbalance. Chartists contribute their net position: if optimists outnumber pessimists, the excess is buying pressure. Fundamentalists contribute a push proportional to how far the price has strayed from fundamental value, and in the direction that closes the gap.

The market maker's impatience rises with that imbalance. The bigger it gets, the shorter the expected wait before the price is revised — and when the price-revision event wins the clock race, the quote moves by exactly one tick, in the direction of the imbalance. Nothing moves the price by more than a tick at a time. Large moves are many ticks arriving quickly.

Orders accumulate into an imbalance; when the market maker acts, the price moves one tick toward it and the imbalance shrinks. Step through it to see the two panels move against each other.
The mechanics — excess demand and the pricing rule

Total excess demand is the sum of the two classes' contributions, with tct_c the chartists' unit order size and γ\gamma the fundamentalists' reaction strength:

ED=(n+n)tc+nfγpfppED = (n_+ - n_-)\,t_c + n_f\,\gamma\,\frac{p_f-p}{p}

and the price moves by a single tick of ±0.1\pm 0.1 in the direction of that imbalance whenever a price-revision event has the shortest waiting time:

P(ti+1)P(ti)={+0.1if ED>00.1if ED<0P(t_{i+1}) - P(t_i) = \begin{cases} +0.1 & \text{if } ED > 0\\ -0.1 & \text{if } ED < 0\end{cases}

Order flow, as an aggregate, is signed trading volume and is a variant of excess demand. The chapter distinguishes them: order flow measures transactions actually done, whereas a change in demand need not imply a transaction.

An implementation reading. The chapter gives the market maker's behaviour twice. In the list of jump rates it appears as a rate linear in excess demand, β7=βED\beta_7 = \beta\,ED and β8=βED\beta_8 = -\beta\,ED. In the pricing-rule section it appears as P(ED)=exp(βED)P(\cdot\mid ED) = \exp(\beta ED), which is not a probability — it exceeds one for positive excess demand — and which diverges at the excess demands this population generates. The re-implementation uses the linear rate from the list of jump rates, with only the rate in the direction of the imbalance live at any moment. This is recorded in the project README.

Reference

Ten events, written out

Everything above reduces to this table. The state of the market is four numbers: how many optimists, how many pessimists, the price, and the fundamental value. Ten events can change those four numbers, each by a fixed amount, and each at its own rate. This section is the reference; it is more technical than the rest by design.

The state vector and the ten transitions

Market activity at any moment is a vector in R4\mathbb{R}^4:

Y(t)={n+(t)n,  n(t)n,  p(t),  pf(t)}Y(t) = \left\{\, \frac{n_+(t)}{n},\; \frac{n_-(t)}{n},\; p(t),\; p_f(t) \,\right\}

with the two chartist fractions taking values in {0,1/n,2/n,,1}\{0, 1/n, 2/n, \dots, 1\} and the fundamentalist share following by difference. Transition probabilities take the standard form

P[Y(t+h)=Y(t)+liY(t)=y]=βi(y)h+o(h)P[\,Y(t+h) = Y(t) + l_i \mid Y(t) = y\,] = \beta_i(y)\,h + o(h)

where βi(y)\beta_i(y) is the instantaneous jump rate. The ten transition vectors and their rates:

The ten events. Table transcribed from the chapter.
iEventTransition vector lil_iRate βi\beta_i
1pessimist → optimist(1/n, −1/n, 0, 0)ν1nnncneU1\nu_1\frac{n_-}{n}\frac{n_c}{n}e^{U_1}
2optimist → pessimist(−1/n, 1/n, 0, 0)ν1n+nncneU1\nu_1\frac{n_+}{n}\frac{n_c}{n}e^{-U_1}
3fundamentalist → optimist(1/n, 0, 0, 0)ν2nfnn+neU2,1\nu_2\frac{n_f}{n}\frac{n_+}{n}e^{U_{2,1}}
4optimist → fundamentalist(−1/n, 0, 0, 0)ν2nfnn+neU2,1\nu_2\frac{n_f}{n}\frac{n_+}{n}e^{-U_{2,1}}
5fundamentalist → pessimist(0, 1/n, 0, 0)ν2nfnnneU2,2\nu_2\frac{n_f}{n}\frac{n_-}{n}e^{U_{2,2}}
6pessimist → fundamentalist(0, −1/n, 0, 0)ν2nnnfneU2,2\nu_2\frac{n_-}{n}\frac{n_f}{n}e^{-U_{2,2}}
7price up one tick(0, 0, 0.1, 0)βED\beta\,ED
8price down one tick(0, 0, −0.1, 0)βED-\beta\,ED
9fundamental value up(0, 0, 0, 0.1)ν3\nu_3
10fundamental value down(0, 0, 0, −0.1)ν3\nu_3

The chapter derives the first of these explicitly, and the rest follow the same construction. Let AA be the event that the selected agent is a pessimistic chartist, with probability n/nn_-/n; BB that they meet another chartist, with probability nc/nn_c/n; and CC that they switch, with probability ν1eU1\nu_1 e^{U_1}. Then

P(ABC)=P(CB,A)P(BA)P(A)=ν1nnncneU1P(A \cap B \cap C) = P(C \mid B,A)\,P(B \mid A)\,P(A) = \nu_1\frac{n_-}{n}\frac{n_c}{n}e^{U_1}

Rates 7 and 8 reflect the market maker's relative impatience to revise the price. Rates 9 and 10 govern the arrival of information about fundamental value: the fundamental is the difference between two Poisson processes of the same constant rate, which makes the normality — and hence the independence — of unanticipated news hold asymptotically.

Results

What comes out

The chapter sets out six things real speculative markets do, and asks the simulation to do them too. They are the target the model is aimed at.

  1. A unit root in prices. The martingale hypothesis cannot be rejected: no exploitable linear correlation survives beyond a few minutes of trading.
  2. Fat tails. Returns are nothing like normal. The unconditional distribution decays as a power law with a tail index between 2.5 and 5 — which also rules out the stable Lévy laws, whose index lies between 0 and 2.
  3. Volatility clustering. Turbulent periods bunch together. This is the ARCH effect, and it is everywhere in financial data.
  4. Long memory in volatility and volume. The autocorrelation of volatility — how much today's turbulence tells you about turbulence some number of days later — decays as a power law rather than dying out, over horizons from a day to a year.
  5. A strong volatility–volume relationship, with a shared long-memory signature in both series.
  6. Multiscale behaviour. Bursts of volatility belong to no single time scale, which points toward a multifractal signature.

What follows is one run of the re-implemented model over two and a half thousand simulated days, about ten years of trading, held to those six standards. The original paper's own tables of estimated tail indices, long-memory parameters and test statistics are in sections that were not available for this presentation; every number below comes from the re-implementation and is labelled as such.

The mechanics — how these series are measured

Returns are daily log differences of the recorded closing price, in per cent. Volatility is measured by the absolute return, a standard proxy the chapter itself uses. Volume is the gross size transacted against the market maker over the day: at each price revision, every chartist's unit order plus every fundamentalist's order, which scales with the mispricing. The chapter distinguishes order flow, which measures transactions actually executed, from a change in demand, which need not imply a transaction, so volume is accumulated at the moment of a transaction rather than continuously. Autocorrelation at lag kk is the ordinary sample correlation of the series with itself shifted by kk days.

The chapter's own results sections estimate the tail index and the long-memory parameter formally, using Robinson's [1994] semiparametric estimator, and apply BDS and variance-ratio tests to the simulated samples. Those sections were not part of the material available here, so no estimate from them is reported on this page.

Text alternative — the five figures as tables

Calibration

Thirteen numbers, found by hand

A model like this has no closed form to solve and no likelihood to maximise. The parameters were found by trying them. The chapter says so without embarrassment: no formal method existed for the job, so the values were arrived at by trial and error, in two steps.

The first step was graphical. Candidate parameter sets were run and the resulting price paths were looked at, and those producing pathological dynamics — explosions, collapses, a market that freezes — were discarded. The second step was statistical: the surviving sets were judged on the kurtosis of their returns, a measure of how fat the tails are, and on the long-memory parameter of volatility estimated with Robinson's [1994] semiparametric estimator, against a benchmark panel of nine real currency series.

Table 2.1 — calibrated parameter values, transcribed from the chapter.
SymbolValueWhat it sets
NN400number of traders
PfP_f100fundamental value at the start
tct_c0.1chartists' unit order size
tft_f3.0strength of the fundamentalists' response to mispricing
β\beta4market maker's impatience
ν1\nu_13.0rate at which chartists meet chartists
ν2\nu_20.5rate at which chartists meet fundamentalists
ν3\nu_30.005rate of news arrival, each direction
α1\alpha_10.7weight on the opinion index — the strength of herding
α2\alpha_21.0weight on the momentum signal
α3\alpha_30.5weight on the chartist-versus-fundamentalist gain
ss0.75discount on the fundamentalists' expected gain
RR0.0004domestic risk-free rate

Three values the model needs and Table 2.1 does not give. The chartists' look-back horizon τ, the foreign rate rr, and the floor imposed on each strategy's share of the population are all used by the model and none appears in the published table. The figures on this page use τ = 3 days, a foreign rate equal to the domestic one — so that the interest differential is zero — and a floor of 10% of the population per strategy. These were chosen for illustration by the chapter's own first step: they are the values that gave non-pathological dynamics across every random seed tried. They are not the authors' values, which are not recorded in the material available here.

The mechanics — implementation notes from §2.3
  • The original was written in C++, so that wide parameter ranges could be tested.
  • The fundamental value is the difference between two Poisson processes of equal rate ν3\nu_3.
  • Exponential waiting times were generated by the transformation method, following Press et al. [1993].
  • A minimum was imposed on each population fraction, to prevent the absorbing states in which the entire population holds one strategy.
  • Twenty samples were generated with different seeds.

One sentence of the chapter's calibration passage carries an unresolved citation placeholder in the source translation, rendered 444. It has not been filled in here.

The honest ledger

What worked and what didn't

The chapter reports its own difficulties, in its own words. They are set out here without softening, because a model that says where it falls short is easier to trust than one that does not.

WorkedLong memory in volatility and volume

For the chosen parameter values, long-term dependence in both volatility and volume is well reproduced by the simulation.

WorkedA multifractal signature

The scaling functions reveal, in the chapter's own phrase, highly convincing multifractal behaviour.

ProblemThe parameters had to be fine-tuned

Generating realistic price patterns required substantial fine-tuning, which the chapter flags as an issue often neglected. It raises the question of whether real markets converge on such values despite their diversity, and follows Giardina and Bouchaud [2002] in arguing that some underlying self-organising mechanism must be doing that work.

ProblemA trade-off between tails and memory

Surprisingly, a trade-off emerged during calibration between reproducing fat tails and reproducing long-term dependence in volatility. Getting the autocorrelation function of volatility right meant avoiding tails that were too fat — and very fat tails are almost absent from the reference currency series in any case.

ProblemThe simulated market was too predictable

Measured against the panel of nine currencies used as a benchmark during calibration, the simulated trajectories remain too predictable. The chapter states this as its clear conclusion.

ProblemLinear structure the first fact rules out

The first of the six stylized facts asks for a unit root: no exploitable linear correlation in returns beyond a few minutes. The run shown above does not deliver it: its daily returns have a first-order autocorrelation of -0.35, which a discrete quote moving one tick at a time toward the imbalance will produce. That is a property of the re-implementation, measured here; the chapter's own verdict on its samples is the entry above.

ContextOthers' estimates run high

The chapter notes that Lux and Marchesi's [2000] long-memory estimates regularly exceed 0.5, while the exchange-rate series they set out to reproduce are more regular than that.

Two citation placeholders, rendered 44 and 444, remain unresolved in the translated text. They have been left as they stand rather than guessed at.

Try it yourself

Turn the dials

Four of the model's parameters, with the rest held at their calibrated values. The upper panel is the price against the fundamental; the lower band is the population, showing what share of the traders is currently following each strategy. Push the herding dial up and watch the band swing.

price fundamental optimists pessimists fundamentalists

A simplified version of the model running in this page, at a smaller population and a watchable speed, so that the effect of each dial can be seen directly. The published figures above come from the same equations run at the full calibrated population for two and a half thousand simulated days. Live in-browser run of a 2026 re-implementation of the 2003 model. Not a figure from the original paper.

Provenance

What this is, and what is missing

This page presents Chapter 2 of Nicolas Boitout's doctoral dissertation, defended in 2003 and written in English with Thierry Delahaut. The chapter covers the introduction, a review of stylized facts, the market model, and the implementation and calibration of the simulation.

What was available, and what was not

The source for this presentation is an English translation of the chapter's manuscript pages. The translation carries a gap: the original pages 69 to 71 were not supplied, and the text resumes mid-sentence on page 72. More importantly, the chapter's results sections were not part of the material. The estimated tail indices, long-memory parameters, BDS statistics and structure functions the paper reports are therefore not available, and no number attributed to them appears anywhere on this page.

Every figure here was produced by a re-implementation of the model written in 2026 from the chapter's own equations. Where the chapter's text is ambiguous, or silent on a value the model needs, the reading or the value used is stated on the page and recorded in the project README. Two citation placeholders in the translated text remain unresolved and have been left alone.

Reproducing the figures

The engine, the build script that turns its output into the data this page plots, and the page itself are all in the project repository. Every published figure comes from a single run at a fixed seed, regenerated by one command, which is recorded alongside the data.

Files
PathWhat it is
engine/model.mjsthe model — the only place the equations live
engine/generate.mjsthe build step that produces every published figure's data
engine/build-site.mjsrenders the mathematics at build time and assembles the page
data/*.jsonthe generated series, committed so the site builds without running anything
source/the translated chapter and the original Figure 2.1
README.mdhow to regenerate, and every reading taken from an ambiguous passage

Works cited in the chapter

  • Arthur, W. B., Holland, J., LeBaron, B., Palmer, R. and Tayler, P. [1997]
  • Black, F. [1986]
  • Brock, W. and Durlauf, S. [2000]
  • Chakrabarti, R. [2000]
  • Delahaut, T. [2003]
  • Ding, Z., Engle, R. and Granger, C. [1993]
  • Engle, R. and Russell, J. [1998]
  • Frankel, J. and Froot, K. [1990]
  • Giardina, I. and Bouchaud, J.-P. [2002]
  • Goodhart, C. [1988]
  • Kirman, A. and Teyssière, G. [2002a, 2002b]
  • LeBaron, B. [2001b, 2003a, 2003b]
  • Lux, T. [1997]
  • Lux, T. and Marchesi, M. [1999, 2000]
  • Lyons, R. [2002]
  • Müller, U. et al. [1997]
  • Robinson, P. [1994]

Listed as they are cited in the chapter. The chapter cites further works — among them Andersen and Bollerslev [1998], Blake et al. [1992], Boitout and Piatecki [2003], Brock et al. [1996], Chen et al. [2001], Christoffersen and Diebold [2002], Jefferies et al. [2000], Johnson et al. [2001], LeBaron [1992], Lo and MacKinlay [1988], Lui and Mole [1998], Orléan [2001], Press et al. [1993], Schleifer [2000], Taylor [1992], and Turiel and Pérez-Vicente [2002]. Full bibliographic details belong to the dissertation's own reference list, which was not part of the material available here.