Markets II: Rates, FX and Credit · Markets
30Market-Making Games
An interviewer points out of the window: make me a market on the number of windows in that building. You say 200 at 400. She says: I buy. You have just sold her windows at 400, and you have learned something: she thinks there are more than 400, or at least she is willing to bet so. Your next market should be higher. Trading firms train and test people with games like this because every market maker’s problem is in it: estimate a value you cannot see, quote around it wide enough to survive the people who know more, narrow enough to trade with the people who do not, and learn from every trade. This chapter plays the game seriously: how to make a market, how to update on trades, how adverse selection sets the width, and what firms say about the games they use.
30.1 Make me a market
Definition 30.1 (Make-me-a-market, width)
Make-me-a-market is a request to quote, on some uncertain quantity, a bid at which one will buy and an offer at which one will sell, for a stated size, before knowing which way the other party will trade. The width of the market is the offer minus the bid.
The language is that of an open-outcry pit, and Jane Street’s public guide to its trading interviews spells it out: “I’m 2 bid for 10” offers to buy 10 at 2; “I have 10 at 4” offers to sell; “2 at 4, 10 up” does both; the other side says “sold” to hit the bid or “take ’em” to lift the offer, and the order stands until it trades or its maker says “I’m out”. The guide’s advice for a contract paying the roll of a die, worth 3.5 on average, is to buy below and sell above the expected value, to weigh the worst loss against one’s capital, and to balance the chance of trading against the profit per trade; it suggests “3 at 4, 10 up”.
A market has a centre, the maker’s estimate of the value, and a width. The centre is a statistics problem; the width is an economic one. Quote too narrow and anyone who knows the value better trades against you when you are wrong; quote too wide and no one trades. The card game of this chapter makes both precise.
Definition 30.2 (Inventory)
A market maker’s inventory is the net position it holds from the trades done against its quotes, long after net buying and short after net selling.
30.2 Updating on trades
Definition 30.3 (Bayesian update)
A Bayesian update revises a probability distribution over an unknown value after an observation, in proportion to how likely the observation would be under each value: posterior prior likelihood.
The contract of the chapter’s game pays the sum of five cards dealt face down from a 52-card deck, aces 1 to kings 13. Before any trade the sum is worth 35 on average, with a standard deviation of 8.03, and it lies between 6 and 64 (Figure 30.1). Each round a trader arrives: with probability 0.2 an informed one, who knows the sum and buys if it is above the offer, sells if below the bid, and otherwise passes; otherwise an uninformed one, who trades on a random side with a probability that falls with the width, , and otherwise passes.
Example 30.4 (The first trade)
The maker opens 30 at 40, a width of 10. An uninformed trader trades with probability . If someone buys at 40, it was an informed trader with probability 0.31; the maker’s expected value of the sum rises from 35 to 38.13, and its next market is centred there. After a sale at 30 it falls to 31.87; after a pass it stays at 35, since a pass is equally likely from a high or a low sum.
Over a game the maker’s centre drifts towards the true sum as trades reveal it (Figure 30.2); how fast depends on the share of informed traders and on the width, since a wide market filters out the informed trades that carry the information along with the uninformed ones that pay for the width.
30.3 Adverse selection around a table
The guide’s definition of adverse selection matches the one in One Quant Book 1, chapter 1: the trades you get to do are worse than they would appear, because someone else is selecting into the trade against you. Its practical form is a question to ask before every quote: conditional on this order being filled, what is the thing worth, and would I still want the trade? Glosten and Milgrom turned it into a model in 1985: a specialist facing informed and uninformed traders sets its bid and offer at the expected value conditional on a sale and on a purchase, and the presence of better-informed traders produces a positive spread even when the specialist is risk-neutral and makes zero expected profit.
Definition 30.5 (Winner’s curse)
The winner’s curse is the tendency of the winner of an auction among bidders with noisy estimates of a common value to have overestimated it: winning is itself evidence that one’s estimate was too high.
A market maker is always the winner of such an auction: its quote was the one someone chose to trade on. The width is the price of the curse, and the best width balances two effects (Figure 30.3). A wider market loses less to the informed, who trade only when the sum lies outside it, but trades less with the uninformed, who pay half the width each time.
Proposition 30.6 (Width against the table)
With no informed traders, the maker’s expected profit per round is with patience , maximised at . Informed traders make every width cost more and the narrowest widths cost most, since they trade only against quotes on the wrong side of the value; learning from trades lowers the loss to them, and so allows a narrower market.
Proof. An uninformed trader trades with probability and, the centre being the expected value, earns the maker on average; the product is maximised at . An informed trader’s expected cost to the maker is , which falls as the quotes move apart; a better centre shrinks it for any width. ∎
Example 30.7 (The best width)
Over 2 000 seeded games of 20 rounds with a fifth of the traders informed, the maker who updates earns most, 16.4 per game, at a width of 11.5 points, against 14.1 at 8 points and 15.1 at 15. A maker who never updates does best wider, at 14 points, and earns only 12.0. Without informed traders the best width would be the patience, 8 points, earning about 29 a game (29.4 by the formula, 28.6 in the simulation).
30.4 The training games firms describe
Firms rarely publish their games, but some describe them. Jane Street’s guide sets practice markets: on the roll of a twenty-sided die, the maximum of three six-sided dice, a die with the option to reroll once, the temperature in an hour, and a million times a die roll, with the question of how one would feel if one’s bid were hit and the roll came up one. Its trading internship lists mock trading, in teams, on scenarios built by its traders, and classes that range from financial products to poker. The common thread is the chapter’s: the value is uncertain, the other players know different things, and every trade is information.
The games also teach inventory. A maker who has sold three times in a row is short, and if its sales were to informed traders the value is above where it sold. Shifting both quotes up, or skewing them, protects it, at the cost of trading less on one side; the card engine can be extended to do so.
30.5 Tutorial: the card-sum market
Goal. Compute the exact distribution of the card sum, play the market against a table of informed and uninformed bots with and without Bayesian updating, and find the width that maximises expected profit. End state: Figures 30.1, 30.2 and 30.3, Examples 30.4 and 30.7 and the numbers of the weekend problem.
The deck and the update: the exact distribution of the sum, the table’s parameters, and Bayes’ rule after a trade or a pass.
def card_sum_distribution(k: int, copies: int = 4, values: range = range(1, 14)) -> dict[int, float]: """Exact distribution of the sum of k cards drawn without replacement from the deck.""" ways: dict[tuple[int, int], int] = {(0, 0): 1} # (cards, sum) -> count for v in values: nxt: dict[tuple[int, int], int] = {} for (n, s), w in ways.items(): for j in range(min(copies, k - n) + 1): key = (n + j, s + j * v) nxt[key] = nxt.get(key, 0) + w * math.comb(copies, j) ways = nxt total = sum(w for (n, _), w in ways.items() if n == k) return {s: w / total for (n, s), w in sorted(ways.items()) if n == k} @dataclass(frozen=True) class Table: cards: int = 5 rounds: int = 20 informed: float = 0.2 # share of arriving traders who know the sum patience: float = 8.0 # uninformed traders' tolerance for width def mean(post: dict[int, float]) -> float: return sum(s * p for s, p in post.items()) def update(post: dict[int, float], action: str, bid: float, ask: float, t: Table, width: float) -> dict[int, float]: """Posterior over the sum after observing `action` ('buy', 'sell' or 'pass') at these quotes.""" q = math.exp(-width / t.patience) lik = {"buy": lambda s: t.informed * (s > ask) + (1 - t.informed) * q / 2, "sell": lambda s: t.informed * (s < bid) + (1 - t.informed) * q / 2, "pass": lambda s: t.informed * (bid <= s <= ask) + (1 - t.informed) * (1 - q)}[action] new = {s: p * lik(s) for s, p in post.items()} z = sum(new.values()) return {s: p / z for s, p in new.items()} if z > 0 else postListing 30.1. The card-sum distribution, the table, and the Bayesian update. code/firm/mmgame/firm_mmgame.py The game: dealing and playing one game.
def deal(t: Table, rng: random.Random, prior: dict[int, float]) -> tuple[int, list[tuple[float, float, float]]]: """The sum and, for each round, the uniforms that decide who arrives, whether an uninformed trader trades and on which side; dealing once lets every width face the same table.""" value = rng.choices(list(prior), list(prior.values()))[0] return value, [(rng.random(), rng.random(), rng.random()) for _ in range(t.rounds)] def play(width: float, t: Table, value: int, draws: list[tuple[float, float, float]], learn: bool = True, prior: dict[int, float] | None = None) -> tuple[float, list[float]]: """One game: (maker's P&L, the maker's mid before each round and at the end).""" prior = prior or card_sum_distribution(t.cards) post, pnl, mids = dict(prior), 0.0, [] q = math.exp(-width / t.patience) for u_who, u_trade, u_side in draws: m = mean(post) mids.append(m) bid, ask = m - width / 2, m + width / 2 if u_who < t.informed: action = "buy" if value > ask else "sell" if value < bid else "pass" else: action = ("buy" if u_side < 0.5 else "sell") if u_trade < q else "pass" if action == "buy": pnl += ask - value elif action == "sell": pnl += value - bid if learn: post = update(post, action, bid, ask, t, width) mids.append(mean(post)) return pnl, midsListing 30.2. Dealing and one game. code/firm/mmgame/firm_mmgame.py The widths: the expected P&L of each width against the same deals.
def expected_pnl(widths: list[float], t: Table, games: int, seed: int, learn: bool = True) -> list[tuple[float, float, float]]: """(width, mean P&L per game, standard error) for each width, every width facing the same seeded deals.""" rng, prior = random.Random(seed), card_sum_distribution(t.cards) deals = [deal(t, rng, prior) for _ in range(games)] out = [] for w in widths: xs = [play(w, t, v, d, learn, prior)[0] for v, d in deals] m = sum(xs) / games sd = math.sqrt(sum((x - m) ** 2 for x in xs) / (games - 1)) out.append((w, m, sd / math.sqrt(games))) return outListing 30.3. Expected P&L by width, over common deals. code/firm/mmgame/firm_mmgame.py - Run
mmgame_demo.first_trade(),mmgame_demo.problem()andfig_mmgame.py.
What to change next. Let the maker skew its quotes with its inventory, and find whether it earns more; then give each bot one of the five cards instead of the sum, so that every trader is partly informed, as around a real table.
30.6 Build: the market-making game engine
Purpose. The miniature firm trains its quoting logic, and its people, on games whose answers it can compute.
Interface. card_sum_distribution(k, copies, values); Table(cards, rounds, informed, patience); mean(post); update(post, action, bid, ask, table, width); deal(table, rng, prior); play(width, table, value, draws, learn, prior); expected_pnl(widths, table, games, seed, learn).
Rules. Five cards from one deck; one trader a round; informed traders trade only when the sum is outside the quotes; uninformed ones trade with probability on a random side; quotes centred on the maker’s current expected value; every width faces the same seeded deals.
Acceptance tests. code/firm/mmgame/tests/: the distribution sums to one with mean 35 and the right extremes; a buy raises and a sale lowers the estimate; without informed traders the profit matches the formula; updating beats not updating; games are reproducible.
Stretch. Inventory skew; several makers competing on width; traders with partial information (one card each); the Glosten–Milgrom zero-profit spread; a live version for people to play against the bots.
Sources and further reading
- Jane Street, “Probability and markets guide”; trading internship page.
- L. R. Glosten and P. R. Milgrom, “Bid, ask and transaction prices in a specialist market with heterogeneously informed traders”, Journal of Financial Economics 14 (1985).
30.7 Exercises
Exercise 30.1 ★
Make a market on the roll of a six-sided die, and explain your width.
Solution
Solution of Exercise 30.1.
Around the expected value, 3.5: for example “3 at 4, 10 up”. The value is known, so no one can be better informed; the width is a small profit for the risk of the roll and a width at which the other side still wants to trade.
Exercise 30.2 ★
You quote 200 at 400 on the number of windows and the interviewer buys. What do you do with your next market, and why?
Solution
Solution of Exercise 30.2.
Raise the market: the buyer may know better, and at least thought 400 was cheap. Move the centre up and perhaps widen, for example to 300 at 500, and think about why she bought: if she might have counted the windows, move a lot.
Exercise 30.3 ★
Why does a pass leave the maker’s estimate at 35 on the first round of the card game?
Solution
Solution of Exercise 30.3.
An informed trader passes when the sum is between 30 and 40, and an uninformed one passes with the same probability whatever the sum; the prior is symmetric about 35 and so is the set of sums that produce a pass, so the mean does not move. Later, when quotes are off-centre, a pass does move it.
Exercise 30.4 ★★
With no informed traders and patience 8, what width maximises the maker’s profit per round, and what does it earn over 20 rounds?
Solution
Solution of Exercise 30.4.
A width equal to the patience, 8 points: a round, 29.4 over 20 rounds.
Exercise 30.5 ★★
In the first round at 30 at 40, what is the probability that a buyer is informed? Why is it so much higher than the 20% of informed traders at the table?
Solution
Solution of Exercise 30.5.
0.31. A quarter of the sums are above 40, so informed buyers are 5% of arrivals (); uninformed traders trade only 29% of the time at this width and buy half of that, 11.5% of arrivals (). The width filters the uninformed more than the informed, so a buy is informed more often than the table’s 20%.
Exercise 30.6 ★★
Explain the winner’s curse in a market maker’s terms.
Solution
Solution of Exercise 30.6.
The market maker’s quote is traded against precisely when someone thinks it is wrong in their favour; conditional on being filled, the value is worse than the maker thought. Quoting the unconditional estimate means losing on average to those who choose to trade.
Exercise 30.7 ★★★
Coding. With expected_pnl, find the best width for a table with 30% informed traders on the grid 8 to 15 in half points, over the same 2 000 seeded deals.
Solution
Solution of Exercise 30.7.
12.5 points, earning 13.8 a game: more informed traders push the best width up and the profit down (11.0 points and 20.6 with 10% informed).
Exercise 30.8 ★★★
Find the flaw. “I quote tight so I trade more: more trades means more spread earned.” Correct it.
Solution
Solution of Exercise 30.8.
More trades earn more spread from the uninformed, but a tight market is also traded whenever the informed know it is wrong, and those trades cost more than the spread earns. Below the best width, profit falls; at zero width the maker loses 22 a game in the chapter’s table.
30.8 Problem: The Card-Sum Market
Problem 30.1
Weekend problem — the width that pays
You make markets for 20 rounds on the sum of five cards dealt face down from a 52-card deck. Each round one trader comes: a fifth of the time one who knows the sum; otherwise one who trades on a random side with probability at a width . You quote around your current expected value.
Part I — The contract.
- What are the mean, standard deviation and range of the sum?
- Why are the extremes 6 and 64 rather than 5 and 65?
- At a width of 10, how likely is an uninformed trader to trade?
- Quote your first market at width 10.
- What do you earn per round, on average, from an uninformed trader?
Part II — Learning.
- After a buy at 40, what is your new expected value? After a sale at 30?
- Why does a pass teach you nothing on the first round, but something later?
- In the chapter’s example game, how does your estimate move, and why does it first go the wrong way?
- What does updating earn you, at the best widths, against not updating?
- Why does the maker who does not update prefer a wider market?
Part III — The width.
- Find the best width and the expected P&L per game.
- What do widths of 8 and 15 earn?
- Without informed traders, what would the best width and profit be?
- How does the best width change with 10% and 30% informed traders?
- How likely does an uninformed trader trade at the best width?
Part IV — Judgement.
- How would you know, at a real table, what share of traders is informed?
- How should you adjust your quotes after three sales in a row?
- What does this game teach about quoting real securities?
- State the named result: the width that maximises expected P&L against this table, and that P&L.
- In one sentence: what does the width pay for?
Solution
Solution of Problem 30.1.
1. Mean 35, standard deviation 8.03, from 6 to 64. 2. A deck has four cards of each value: five aces or five kings are impossible. 3. . 4. 30 at 40. 5. Half the width when it trades: per round from an arriving uninformed trader. 6. 38.13 after a buy; 31.87 after a sale. 7. On the first round the quotes are symmetric around a symmetric prior; later the centre has moved, and a pass says the sum is probably inside the current quotes. 8. It rises from 35 to about 39 after early buys, then falls towards 31 as sales come in; the early buys were uninformed noise, or informed buys against a market still centred too low, and the maker cannot tell which. 9. 16.4 a game at 11.5 points against 12.0 at 14 points without updating. 10. Without learning its centre stays wrong, so it must keep more distance from the value to lose less to the informed. 11. 11.5 points, 16.4 a game. 12. 14.1 at 8 points and 15.1 at 15. 13. 8 points, about 29 a game. 14. 11.0 points with 10% informed (20.6 a game), 12.5 with 30% (13.8). 15. . 16. From the mark-outs of its fills: how far the value moves against it after trades, by counterparty and size; persistent adverse moves mean informed flow. 17. Raise the centre, since the buyers may know the value is higher, and consider skewing: a higher offer to sell less while short, a bid closer to buy back. 18. That the centre is an estimate to be revised with every trade, the width a price for adverse selection set against how much the uninformed will pay, and that learning from flow is worth as much as a wider spread. 19. Named result: the card-sum market: against a table with a fifth of the traders informed, a width of 11.5 points maximises the expected P&L, 16.4 a game. 20. It pays for the trades made with people who know more.
30.9 Interview questions
Interview question 30.1 ★ trader
Make me a market on the sum of two dice.
Solution
Solution of Interview question 30.1.
The sum has mean 7, from 2 to 12; with no one better informed, quote around 7, for example “6.5 at 7.5” for size, wider if the size is large relative to the risk one can take, and think about who would want to trade it.
What the interviewer is looking for: the centre, a reasoned width, and who is on the other side.
Interview question 30.2 ★ trader
I buy on your offer. What do you do now?
Solution
Solution of Interview question 30.2.
Ask why: the buyer may know more. Update the estimate upwards by an amount that depends on how likely the buyer is informed; move the market up, perhaps widen, and consider the inventory I now hold short.
What the interviewer is looking for: conditional expectation and inventory.
Interview question 30.3 ★★ trader, researcher
Why does a bid–ask spread exist even with no costs? Explain with a model.
Solution
Solution of Interview question 30.3.
Glosten and Milgrom: a risk-neutral maker facing informed and uninformed traders sets the offer at the expected value given a buy and the bid at the expected value given a sale; since buys are more likely when the value is high, the offer is above the bid even with zero costs and zero expected profit.
What the interviewer is looking for: conditional expectations on trade direction.
Interview question 30.4 ★★ trader
You are short three contracts after three sales. How do you move your market?
Solution
Solution of Interview question 30.4.
Move the market up, both because the sales may have been to informed buyers and because the short position is risk: raise the bid more than the offer to attract sellers and discourage buyers, until the inventory is back within limits.
What the interviewer is looking for: information and inventory both push the same way.
Interview question 30.5 ★★ researcher
How would you estimate the share of informed traders in a market from its trades?
Solution
Solution of Interview question 30.5.
From the relation between trades and subsequent price moves: estimate how much prices move after buys and sales (the permanent impact), or fit a Glosten–Milgrom or PIN-type model to the sequence of buys and sales and the spread; mark-outs by counterparty give a direct measure.
What the interviewer is looking for: price impact and mark-outs as evidence of information.
Interview question 30.6 ★★★ developer
Design a multi-player market-making game server for training, with bots and humans.
Solution
Solution of Interview question 30.6.
A server holding each game’s hidden state and order book, with a message protocol for quotes, trades and cancellations; bots as clients with the same interface as humans; time-stamped logs of everything for replay and scoring; rooms and scenarios defined as data; fairness checks on latency between players; post-game analytics of P&L, width and adverse selection.
What the interviewer is looking for: authoritative state, same interface for bots and humans, replay.