Skip to content

Agent-based model simulation of Order Book liquidity dynamics

License

Notifications You must be signed in to change notification settings

jonathanmfung/leyval

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

83 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

leyval

  • Agent-based model simulation of Order Book liquidity dynamics
  • Focus on procedural fairness of various matching systems
  • Written in C++20

./scripts/img/book.gif

Usage

This helps clangd (in emacs/eglot) find system and lib includes.

nix-shell
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1

Build with cmake:

cmake --preset release
cmake --build --preset release
build/release/leyval

Or build with nix:

nix-build default.nix
./result/bin/leyval

Overview of Different Matching Systems

An Order Book is a collection of Bid and Ask limit orders:

BidAsk
PriceQuantityPriceQuantity
258314
2773255
295347

If an Agent places a Buy Market Order with Q=2, this gets matched with the current best Ask Price P=31. The Order Book after this transaction looks like:

Ask
PriceQuantity
312
3255
347

Now, consider multiple Ask Limit Orders from multiple Agents (1, 2, 3) sitting at the current best price level. Agent 1 placed their order before 2, and 2 before 3. The Matching System is responsible for determining how an incoming Market Order is allocated to these Limit Orders.

Q_120
Q_250
Q_330

These Limit Orders have a total Q = 100. The incoming Market Order has Q_m=25.

FIFOPro-RataRandom
Q_120-20 = 020-5 = 15(0,20,20)
Q_250-5 = 4550-13 = 37(50,25,50)
Q_330-0 = 3030-7 = 23(30,30,5)

Under FIFO (First-in Last-Out), the Market Order gets allocated to the earliest order (Agent 1). This first Limit Order is not enough to fulfill the Market Order, so the remaining Q=5 overflow to the next-earliest order.

Under Pro-Rata, the Market Order gets split up proportional to the quantity weight of each agent. E.g Agent 1’s order constitutes w_1 = Q_1/Q = 20/100 = 20% of the total quantity at this price level. Agent 1’s allocation is thus Q_m * w_1 = 5. However Pro-Rata can never be pure, as seen in Agent 2 and 3; their allocations are 12.5 and 7.5, respectively. Quantities must always be integer values, so Agent 2 is rounded up due to FIFO priority.

Under Random, the Market Order is allocated similarly to Pro-Rata, but instead w_1 is interpreted as the probability of 1 share of Q_m being allocated to Agent 1. The two extreme results of this is all of Q_1 being fulfilled or none of Q_1 being fulfilled. The remaining (5 or 25) gets split across Q_2 and Q_3.

Sources

An Empirical Analysis of the Limit Order Book and the Order Flow in the Paris Bourse

https://sci-hub.ru/10.1111/j.1540-6261.1995.tb05192.x

Investors can submit limit orders at any price…

The orders are stored and executed in the sequence that they are received by the market. Transactions occur when a trader on the opposite side of the market hits the quote. The limit orders for a specified quantity and price are stored and executed using time priority at a given price and price priority across prices.

“Market orders” in the Paris Bourse are not handled in the same way as in the NYSE. They are executed against the best price on the opposite side of the limit order book, but any excess that cannot be executed at that price is converted into a limit order at that price rather than being executed at less favorable prices by walking up (down) the book.

Market Simulations with a Matching Engine

https://open.uct.ac.za/items/574390a1-2466-4128-8920-6261505220e0

Julia ABM Logic: https://github.com/IvanJericevich/IJPCTG-ABMCoinTossX/blob/main/Scripts/ABMVolatilityAuctionProxy.jl ./.notes/ABMVolatilityAuctionProxy.jl

The matching algorithms decide the efficiency and robustness of the order matching system. Exchanges aim to prioritize trades in a way that benefits buyers and sellers equally so as to maximize order volume — the lifeblood of the exchange.

We define limit order imbalance ρ(t){…}

The market consists of N_LT Liquidity Takers (LT) that only submit market orders and N_LP Liquidity Providers (LP) that only submit limit orders.

liquidity providers will on average provide liquidity to the side with less liquidity and thus stabilise the order book.

Calibration for values of \(N, δ, κ, ν, σ\)

Agent-based model implementation

For Any Agent

Sample from power law distribution: https://stats.stackexchange.com/questions/173242/random-sample-from-power-law-distribution

\[ \text{Volume: } f(x) = \begin{cases} \frac{α x_m^α}{xα+1} & x \geq x_m
0 & x < x_m \end{cases} \]

\(x_m := \text{lower bound of the volume size}\) For LTs, is from a function. For LPs, is fixed at 10.

\[ \text{Shape Parameter: } α = \begin{cases} 1 - ρ/ν & \text{Sell MO, Ask LO}
1 + ρ/ν & \text{Buy MO, Bid LO} \end{cases} \]

\(ρ := \text{OrderBook Imbalance [(bid size - ask size) / total]} \)

TBD: \(ν := \text{ABM parameter — scaling factor for power-law volume order size}\)

NOT EXACTLY SURE \(m := \text{mid-price}\) \(m = (\text{best ask} + \text{best bid})/2 \)

For Liquidity Takers (MarketOrders)

Fundamentalist

\[ \text{Decision: } D^F = \begin{cases} \text{sell} & f < m
\text{buy} & f > m \end{cases} \]

\(f := \text{fundamental value for agent} \) \(f = m_0exp{x}, x ∼ \mathcal{N}(0, σ^2) \)

\(m_0 := \text{mid-price at start of day}\) \(σ := \text{fundamentalists’ value perception uncertainty for the trading day}\)

\[ x_m^F = \begin{cases} 20 & |f - m| \leq δ m
50 & |f - m| > δ m \end{cases} \]

Chartists

\[ \text{Decision: } D^C = \begin{cases} \text{sell} & m < \bar{m}
\text{buy} & m > \bar{m} \end{cases} \]

\(\bar{m}(t) := \text{Exponential Moving Average (EMA) of mid-price} \) \(\bar{m}(t) = \bar{m}(t’) + λ(m(t) - \bar{m}(t’)) \) \(t’ := \text{time point of when agent made last decision} \) \(λ = 1 - exp{(-Δ t / τ)} \) \(Δ t = t - t’\) \( τ := \text{time constant for agent’s mean inter-arrival time of decision time} \)

\[ x_m^C = \begin{cases} 20 & |m - \bar{m}| \leq δ m
50 & |m - \bar{m}| > δ m \end{cases} \]

For Liquidity Providers (LimitOrders)

\(θ := \text{Probability of Placing Ask}\) \(θ = \frac{1}{2}(ρ + 1)\)

\(p := \text{placement of limit order}\) \[ p = \begin{cases} \text{best bid} + 1 + ⌊\eta⌋ & \text{asks}
\text{best ask} - 1 - ⌊\eta⌋ & \text{bids} \end{cases} \]

\(p := \text{placement of limit order}\)

Investopedia

https://www.investopedia.com/terms/m/market-price.asp

Since $30.02 was the last traded price, this is the market price.

https://www.investopedia.com/ask/answers/042215/what-do-bid-and-ask-prices-represent-stock-quote.asp

That’s because they can sell shares at the higher ask price and buy them at the lower bid price, profiting from the difference.

Linking Agent-Based Models and Stochastic Models of Financial Markets

https://www.pnas.org/doi/pdf/10.1073/pnas.1205013109

technical trader
seeking arbitrage and making decisions from price patterns
fundamentalist
attempt to determine the fundamental value of stocks

We consider here only technical traders, assuming that fundamentalists contribute only to market noise.

demand
number of buy trades
supply
number of sell traddes

On the other hand, the individual strategies used by different technical traders differ in their parameterizations of the buy/sell time, amount of risk tolerated, or portfolio composition (15). So when the input signal—the previous price change rt−1—is small, every agent acts independently. When the input signal is large, the agents act more in concert, irrespective of their differences in trading strategies

Fast, High-Quality Pseudo-Random Numbers for Non-Cryptographers in C++

https://www.youtube.com/watch?v=I5UY3yb0128

clang-tidy

cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON .
clang-tidy -checks='bugprone*, cppcoreguidelines* ,clang-analyzer* ,modernize* ,readability* ,\
	   -modernize-use-trailing-return-type, -readability-avoid-const-params-in-decls, \
	   -readability-identifier-length' \
	   src/*
clang-format -i --style=mozilla src/*

run-clang-tidy.py

https://github.com/llvm/llvm-project/blob/main/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py

python run-clang-tidy.py \
       -p . \
       -checks='bugprone*, cppcoreguidelines* ,clang-analyzer* ,modernize* ,readability* ,\
	   -modernize-use-trailing-return-type, -readability-avoid-const-params-in-decls, \
	   -readability-identifier-length' \
       -j 4 \
       -style "Mozilla" -format

About

Agent-based model simulation of Order Book liquidity dynamics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published