20 min

The treasury desk

Every bank and large company runs a treasury desk that decides where the cash sleeps, trading off safety, liquidity and yield; stablecoin issuers run the same desk under a new name.

Where you are. Three lessons have stocked the shelves. Lesson 11 laid out where money sleeps at night and put the T-bill in the benchmark corner; lesson 12 unmasked the repo as a secured overnight loan; lesson 13 priced the credit risk in everything else and ended on a weekend when a badly parked cash pile made the news. What you hold is a menu. What you do not yet have is the chooser: given real cash and real dates, who decides where the cash sleeps, and by what rule. This lesson sits you at that desk. The rule turns out to be one sentence long, and yield is not the subject of it.

The month on one screen

The treasurer you met in lesson 11 is in early, and the problem has grown up. Back then it was one pile and one night: park it somewhere safe and have it back by morning. This morning the screen shows the whole month. Payroll lands on Friday. A supplier invoice falls due early next week. The quarterly tax instalment goes out in three weeks. A debt interest payment falls due at month end. Beside the calendar sits the menu the last three lessons stocked: overnight repo, a 7-day T-bill, a 30-day T-bill, each rate a little higher than the last.

The phone rings. A salesperson has noticed what the treasurer has: the 30-day bill pays the best rate on the screen, and the company is sitting on a month of idle cash. Why not put the lot there and collect the difference? The treasurer looks at the calendar and asks the only question this lesson teaches: not which rate is highest, but which need dates each instrument can keep.

The idea in one paragraph

A treasury desk is the function, inside a bank or a company or anywhere a large cash pile lives, that decides where the cash sleeps. Its whole craft compresses to one rule: never park cash past the day it is needed. Take the calendar of needs; for each dated need, keep only the instruments that mature on or before that date; among those survivors, and only among those, take the best yield. The time an instrument runs before it pays back is its tenor, and the rule makes tenor the first-class constraint; yield is a tiebreak among instruments that already fit. Lesson 11’s triangle of safety, liquidity and yield thereby becomes an ordering: safety decides what is on the menu at all, liquidity - cash back on the day it is needed - filters the menu per need, and yield chooses among whatever is left. The desk that runs the rule in the other order is the desk whose cash pile turns up in loss stories.

Tenor first, yield as tiebreak

The exercise flattens the treasurer’s month into four dated needs, all round and stylised so the arithmetic disappears: 400 needed on day 1, 250 on day 3, 300 on day 7, 500 on day 30; 1,450 in all. The menu is three spots with stylised rates: overnight repo at 4.0%, the 7-day T-bill at 4.2%, the 30-day at 4.5%. Safety has already happened, off stage: only names the desk trusts made the menu, which is lesson 13’s filter applied before this lesson begins.

The rule, as code, is the exercise’s park function, and its heart is two lines:

fits = [s for s in rates if tenor(s) <= day]
plan[day] = max(fits, key=tenor)

The first line is the constraint. tenor parses the leading number from a spot’s name, counting overnight as one day, and a spot survives only if it matures on or before the need’s day. The second line is the tiebreak, wearing a disguise worth pausing on: it takes the longest surviving tenor and never reads a rate at all. It is still the yield-maximising choice, because this rate table, like the usual one, pays more for longer: 4.0, then 4.2, then 4.5. When yield rises with tenor, “longest that fits” and “best-paying that fits” are the same instrument, and one max does both jobs. On a table where short paid more than long, the tiebreak would need to read the yields; the filter above it would not change by a character. (The rule needs only the dates; the amounts in the calendar ride along for you and for the figure.)

Run the rule down the calendar. Day 30’s 500 goes to the 30-day bill: everything fits, so the tiebreak picks the best payer. Day 7’s 300 goes to the 7-day bill for the same reason. Day 1’s 400 has one survivor, overnight repo, so no tiebreak is needed. Day 3 is the interesting row.

Two desks, one pile

The figure parks the same 1,450 under both regimes. The yield-first desk takes the salesperson’s advice: 1,200 piled into the 30-day bill, the remaining 250 into the 7-day, nothing overnight at all. On paper it has the best blended yield on the screen. It also has nothing maturing before day 7, while day 1 wants 400 and day 3 wants 250. The needs-first desk parks to the calendar: 650 overnight, day 1’s and day 3’s needs together, then 300 in the 7-day and 500 in the 30-day. Read the needs-first bars against the calendar and they are the calendar, drawn as money.

image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ overnight repo 7-day T-bill 30-day T-bill 0 200 400 600 800 1000 1200 cash parked (stylised) chasing yield parks past the need date; the desk parks to the calendar
The same cash parked under two rules: the yield-first bars pile 1,200 of the 1,450 into the 30-day bill and leave nothing overnight, while the needs-first bars mirror the calendar with 650 overnight, 300 in the 7-day bill and 500 in the 30-day

What happens to the yield-first desk on day 1 is not a fine; it is a sale. Lesson 11 gave the T-bill a price at every moment of its life, so the desk can sell 400 of its 30-day holding before maturity and cover payroll. In calm markets that early sale costs a sliver, and there lies the trap: the sliver is usually small, so the yield-first plan usually gets away with it, and a plan that usually gets away with it hardens into a habit.

The same desk, everywhere

The desk is not a bank curiosity. A bank runs one at scale, with the reserve balance you met in lesson 10 among its parking spots and the repo market from lesson 12 on speed dial. A company runs one from the moment its cash outgrows the insurance cap, which lesson 13 showed is the moment a deposit stops being boring. And the newest name on the corridor is the issuer of a tokenised dollar: a company whose entire business is a cash pile and a redemption promise, which makes its treasury desk not a support function but the product itself.

Check yourself

1. The 7-day bill pays 4.2% and overnight repo 4.0%, yet the desk parks day-3 cash overnight. Why is it not leaving money on the table?

Because the 4.2% was conditional on holding to day 7, and the cash is needed on day 3. Tenor filters before yield is consulted: day 3’s only surviving instrument is overnight repo, so there is no tiebreak to win. What looks like 0.2% left on the table is the price of the cash existing on the day it is needed; the alternative was not a better return but a breach of the calendar.

2. park receives the rate table but never reads a single yield. In what sense is yield still the tiebreak?

The code takes the longest tenor that fits, and on this table, as on the usual one, yield rises with tenor, so the longest survivor and the best-paying survivor are the same instrument; one max keyed on tenor silently maximises yield too. The design survives the shortcut: the filter is written in tenor and would hold on any rate table, while the tiebreak is the only part that would need to read yields if short ever paid more than long.

3. The yield-first bars in the figure earn a higher blended yield than the needs-first bars. What makes needs-first the better plan, and when does the difference stop being academic?

Yield-first’s earnings assume the calendar is fiction: nothing it holds matures before day 7, so day 1 and day 3 force sales before maturity. In calm markets those sales cost a sliver and the plan looks vindicated; that is the trap, not vindication. The difference stops being academic on a stressed day, when everyone sells at once and the early sale prices at a real loss: lesson 13’s stories. Needs-first pays a small, known yield give-up for cash that arrives without any sale at all.

4. A stablecoin issuer promises redemption at par, any day. What does the one rule say its reserve list must look like, before you have read it?

Every day a redemption may arrive, so every day is a need date, and the tenor filter passes almost nothing: overnight lending and bills within days of maturity, in the safest available names, rolled continuously. A published reserve list showing long tenors or weak credits instead is a desk running the rule in the wrong order, and lesson 13 showed what that reads like from the failure side.

Do this

Ten minutes, standard library only. Open code/treasury_desk.py: the month as NEEDS, four dated round amounts; the menu as RATES, three spots with stylised rates; and one TODO(you) inside park. Unmodified, the starter raises NotImplementedError the moment a plan is requested. Implement the rule exactly as this lesson stated it: parse each spot’s tenor from the leading number of its name, counting overnight as 1; for each need keep the spots whose tenor is at most the need’s day; return the longest survivor for each, as a dict of day to spot name.

python code/treasury_desk.py

The assert at the bottom pins the whole plan - day 1 and day 3 both on overnight repo, days 7 and 30 on their matching bills - so a wrong ordering fails loudly instead of printing something plausible. A correct run prints one line per need with its stylised rate and ends with exactly

never park past the day the cash is needed; yield is the tiebreak

Then break it once, deliberately. Replace your allocator’s choice with pure yield-chasing, plan[day] = max(rates, key=rates.get) for every need, and run again: every need lands on the 30-day bill and the assert refuses the plan, because day-1 cash parked thirty days out is exactly the breach the rule exists to forbid. Restore your version. The completed function is in solutions/treasury_desk.py.

What you can now do. You can take a cash calendar and produce a parking plan that never parks past a need date, and defend every line of it: safety chooses the menu, tenor filters it per need, and yield only orders the survivors. You can say precisely why the plan with the lower blended yield is the better plan, and name the day on which the difference gets paid. And you can read an unfamiliar cash pile - a bank’s, a company’s, a stablecoin issuer’s - by asking the desk’s question of every holding: which need date does this respect? That is the last idea this module needed. Lesson 15 is the milestone: everything the module built, assembled into miniledger v1, the ledger library every later module imports.

What you can now do

You can park a cash calendar without ever parking past the need date, and say why yield is only the tiebreak.