Home/Rulers Before Models/Rulers Before Models

Series 2 · Episode 01 · PROBLEM · Discount (equity book) · L01

Silent rate conventions and the two marks nobody reconciled

A rate is not a float, simple, compound and continuous are three different rulers, and the quiet swap between them prints two defensible marks on the same trade

Same 6% rate, three PVs: lock DISCOUNT_FRAME or refuse silent convention swap / midpoint peace.

s2ep01 concept diagram
flowchart TB
  subgraph ASK["Same cashflow, undeclared rate"]
    Q["Discount 100 in 10y at 6pct"]:::input
  end
  subgraph FRAMES["Three legal rulers"]
    S["Simple PV 62.50"]:::process
    A["Annual PV 55.84"]:::process
    C["Continuous PV 54.88"]:::process
  end
  subgraph FAIL["Production traps"]
    MID["Silent average / 1.80 peace"]:::risk
    SWAP["Silent convention swap"]:::risk
  end
  subgraph GATE["Harness"]
    CARD["DISCOUNT_FRAME card"]:::artifact
    DENY["FRAME_UNDECLARED / SILENT_CONVENTION_SWAP"]:::gate
  end
  Q --> S & A & C
  S & A & C --> MID & SWAP
  CARD --> DENY
  MID --> DENY
  SWAP --> DENY

  classDef input fill:#CCFBF1,stroke:#0F766E,color:#134E4A,stroke-width:2px
  classDef decision fill:#FEF3C7,stroke:#B45309,color:#78350F,stroke-width:2px
  classDef risk fill:#FEE2E2,stroke:#B91C1C,color:#7F1D1D,stroke-width:2px
  classDef gate fill:#DCFCE7,stroke:#15803D,color:#14532D,stroke-width:2px
  classDef process fill:#E0E7FF,stroke:#4338CA,color:#312E81,stroke-width:2px
  classDef artifact fill:#F5F5F4,stroke:#57534E,color:#1C1917,stroke-width:2px

Problem in one line: a rate is not a number until it carries accrual, compounding, day count, and an as-of clock. Silent conversion between those rulers prints two defensible marks and invites midpoint peace. Everything below is the trench and the minimum lock.

I keep meeting stacks where the rate is the least governed number in the building.

Everything else has an owner. The volatility surface has a committee. The credit assumption has a memo. The rate arrives as a column called rate holding 0.06, and it travels through ingestion, feature tables, an agent that drafts a mark, and a report that goes to the desk, without ever saying what kind of six percent it is. Nobody lies. Nobody checks. Two teams then produce two different marks on the same structure and spend a week arguing about the model.

The model was fine. The ruler was missing.

The problem (named)

Undeclared discount frames. Multiple legal conventions hide under one float field. Each consumer is locally correct. The composition is globally incoherent. Series 1 called the sibling failure Bertrand / dual marks on CEH-001. Part II starts where the cash itself is measured: the rate ruler.

What a rate owes you that a float does not

Six percent is not a quantity until you say how it accrues and from when. Take 100 due in ten years and discount it three legal ways at the same six percent. The answers are not “close enough for desks.”

Convention (same 6%, 10y, face 100)Formula (check by hand)PV
Simple100 / (1 + 0.06×10) = 100 / 1.6062.50
Annual compound100 / (1.06)1055.84
Continuous100 × e−0.06×10 = 100 × e−0.6054.88
Span (simple − continuous), ~7.62 of face

Same instrument, same rate, same date, three answers spanning almost eight points of face. That is not model disagreement. That is three rulers sharing a column name.

The compounding frequency has the same property. Six percent nominal compounded monthly is 6.17 percent effective; compounded semiannually it is 6.09 percent. A pipeline that stores "6%" and lets each consumer assume its own frequency has not stored a rate. It has stored an opinion and thrown away the units.

Everything downstream inherits this. Present value, net present value of a cashflow stream, the equivalence of two streams, the internal rate of return that solves for the rate setting a signed stream to zero, all of them are statements relative to a declared convention and a decision clock. Two streams are equivalent under an ideal bank at a fixed frame. Change the frame and the equivalence quietly stops holding, but no exception is thrown, because nothing in the type system knew there was a frame to break.

So the object I want is not a better rate. It is a rate that carries its own metadata: accrual convention, compounding frequency, day count, and the as-of clock it was observed under. In the language this series keeps using, that is a DISCOUNT_FRAME card, and a job without one is untyped.

Why the silent conversion feels like rigor

Because the conversions are all correct. That is what makes this failure mode so durable.

Whoever wrote the continuous-compounding path was not sloppy, continuous discounting is the clean choice for anything that wants smooth calculus downstream. Whoever wrote the annual path matched the term sheet, which quotes annual coupons. Whoever wrote the simple-interest path was pricing a short money-market leg where simple accrual is the market standard. Each conversion is defensible in isolation. There is no bug to find. The failure is that the composition was never declared, so the system contains three rulers and calls all of them rate.

Silent conversion also survives review because it hides inside utility code. A helper named discount(cashflow, rate, t) is exactly the kind of function nobody reads twice. It compiles. It has a unit test with a round number. It becomes the shared floor two frames are built on, and the frame it encodes is whatever its author was thinking about that afternoon.

How this shows up in production

  1. Two teams, two marks, one structure. Research quotes off a continuous curve because their calibration code wanted it. The pricing service accrues annually because the term sheet does. Both are internally consistent. The marks differ, and the difference is attributed to "methodology" in a meeting where nobody names a convention.
  1. The agent inherits the ambiguity and sounds confident anyway. An LLM-driven analyst reads both feeds, sees two numbers, and writes a paragraph that reconciles them narratively. It has no field to check, so it does what text models do: it produces fluent agreement. Fluent agreement is the worst possible output here, because it removes the only signal that something was wrong.
  1. IRR as a free-floating number. Someone reports an internal rate of return without the accrual convention it was solved under. Comparing that to a quoted yield on another basis is comparing a metre to a yard. The comparison is what drives the ranking, and the ranking drives the trade.
  1. Frame drift across pipeline stages. The training table is built continuous. The live feature service is built annual because a later engineer matched the coupon calendar. Backtest and production now disagree by a wedge that grows with tenor, small at two years, most of a point at ten, and monitoring reads it as regime change.
  1. Midpoint peace. When two marks are both defensible and nobody can adjudicate the frame, the organisation averages them. That is the worst outcome, and it is the most common one, because averaging ends the meeting.

A walkthrough on CEH-001 (checkable)

Take the never-traded family again. CEH-001 has no tape, so every mark is a construction: frame plus model. Dual honest marks from Series 1 still apply; Part II asks whether the rate ruler inside each frame is itself locked.

ObjectNumberReading
Spread frame mark (annual accrual / coupon calendar)~1.50Honest under declared annual frame
Curve frame mark (continuous zeros)~2.10Honest under declared continuous frame
Frame gap (centers)0.60What the desk calls “model risk”
Funding leg only: 100 @ 10y, 6% annual vs continuous0.96 / 100 faceConvention wedge alone > dual-mark gap
Silent midpoint shipped Friday1.80In neither legal frame then deny

The funding-leg convention choice is worth about 0.96 per hundred of face, larger than the whole 0.60 the desk has been arguing about for a month. The gap they are calling model risk is, at least in part, ruler risk sitting in a shared helper nobody has opened.

Then Friday arrives. The report needs one number. Both frames are defensible, both owners are tired, and 1.80 is right in the middle. So 1.80 ships. Notice what just happened: 1.80 is not the output of either allowed setup. It is not a mark. It is a negotiated absence of a mark, and it is now the number that limits, P&L attribution and the next model's training labels will inherit. The midpoint is the only value in the room that no legal frame can produce, and it is the one that gets governance.

That is why this series denies 1.80 as a hard rule rather than a preference. Averaging two frames does not resolve a frame dispute; it launders it into a number that looks decided.

What stacks quietly assume

They assume a rate is a scalar. They assume conversions are lossless because they are reversible. They assume the tenor structure will keep the error small, true at the short end, false exactly where structured products live. They assume that if two independent teams agree to within a point, the number is probably fine, when in fact two-frame agreement to within a point on a ten-year leg is roughly what you would get from pure convention mismatch with no modelling skill at all.

And they assume the model will surface the problem. It will not. A model consumes whatever ruler you hand it and reports its own precision, not yours.

Solution (minimum lock: before S2-02 deepens it)

If silent conventions are the failure, declaring conventions has to be structural, not cultural. A real fix makes the frame a first-class field on the instrument, not a comment: accrual, compounding frequency, day count, as-of clock, all inside one hashed object. Two stages using different rulers become a comparison failure at the boundary, not a meeting. Carry the cashflow schedule and credit assumption in the same hash. Let an agent propose a frame and still refuse spend when frames do not match. Make the midpoint unreachable by construction: “both frames are defensible” resolves to two marks and an escalation, not one invented number.

The full object is the cashflow contract as an as-of hash, that is S2-02. This essay still ships a gate you can enforce Monday without waiting for the twin.

What to lock (now)

Clearance coupling: a mark job without DISCOUNT_FRAME is untyped spend. Inconclusive is two marks and an escalation, not an average.

Research trench: silent unit conversion is measurement-geometry failure (Bertrand’s spirit from Series 1 Ep01–Ep02), local care, global incoherence. Specification search shows up when teams retune the helper until marks agree; that agreement is not evidence.

S2-01Open on YouTube ↗

Next. Open S2-02: Cashflow contracts as as-of hashes. Rulers Before Models index.