One Cent Decides What I Own on Monday
Suneet Malhotra
Jul 28, 2026
In a backtest, expiration is a row in a loop. The contract reaches its date, the code marks it to intrinsic value, the position leaves the book, and the P&L line moves by whatever the mark implied. No order is sent. No counterparty is involved. The position closes because the loop said so.
That is not what happens. Expiration is the one event in my system where a position changes without my code asking for it, and my reconciliation logic did not have a concept for that.
One cent
The mechanism has a name and a number. It is called exercise by exception, and for equity options the threshold is one cent in the money, measured against the closing price of the underlying. A long contract that finishes a penny in the money is exercised by default. A long contract that finishes at the strike, or a penny out, is not.
Two things about that sentence matter more than the number does.
The first is that one cent of price difference is a discontinuity in what I own. Below the threshold I own nothing on Monday. Above it I own a hundred shares per contract, bought at the strike, in cash I did not plan to spend. Nothing else in my engine has that shape. Every other rule I run is monotone in price. This one is a step function, and the height of the step is the full notional of the contract.
The second is the word exception. This is not automatic exercise, though nearly everyone including me has called it that. It is an administrative default, and the clearing member is permitted to override it in either direction: to decline exercise on something past the threshold, or to exercise something that never reached it. The broker carrying the account may apply a different threshold entirely.
So the rule I would have hardcoded is not a rule. It is a default, applied by a party I do not control, to a decision in which I have no vote. Had I written a comparison against one cent and moved on, I would have shipped a number that is right in the common case and unfalsifiable in my logs, because I never record what the clearing decision actually was. I only record what showed up in the account afterward.
The short leg is not mine to decide
Long contracts at least have the courtesy of being my problem. Short contracts are worse in a specific structural way. American style equity options can be assigned on any business day before expiry, and the choice belongs to whoever is long. I do not receive a request. I receive a notification the next morning describing something that has already happened.
That inverts the direction of every other data flow in the system. My engine sends intent and receives confirmation. Assignment hands me a confirmation for an intent that was never mine. The trigger is not in my data at all: it lives inside the exercise logic of an anonymous holder. The moment it fires most predictably is the moment I am least likely to be watching, which is the day before a dividend goes ex on a short call far enough in the money that the dividend exceeds the remaining time value.
There is no column for what a stranger decided. That is not a gap in my dataset. It is a gap in the concept of the dataset.
The window where nothing quotes
Near the strike, both problems compound. The option stops quoting at the close. Whether it finished in the money is settled on the closing price, and the underlying keeps trading after the bell. Through that window I hold a claim whose value is still being determined and which I have lost the ability to hedge, because the instrument I would hedge it with is the one that stopped trading.
This part is not an engineering problem, and I want to be clear about that rather than imply I solved it. No code fixes this. The window is a property of the market structure, not of my stack.
What the backtest cannot see
Here is why this sat unnoticed, which interests me more than the mechanics do.
Measured in P&L, exercise by exception is close to free. The intrinsic value my loop marked and the actual proceeds of exercising and selling the shares differ by a spread and one overnight of gap risk. Averaged across many expirations that difference is small and roughly centered on zero. A backtest scored purely on returns will report, correctly, that marking expiration to intrinsic is a good approximation.
The defect is not in the return. It is in the inventory. On Monday morning the account holds an equity position, at full notional, that no strategy rule generated, that no stop is attached to, and that the sizing logic never approved. Everything downstream that reads position state while assuming positions arrive through the order path is now reading something false. That includes the exposure cap, the sizing check, and the reconciliation step whose entire job is to flag discrepancies, and which will dutifully report that the account matches nothing it expected.
A metric that scores only the P&L column is structurally incapable of detecting a defect that lives in the position column. The approximation is accurate exactly where I measured it and wrong exactly where I did not.
The fix I actually trust
The tempting fix is to model expiration properly: encode the threshold, estimate an assignment probability, simulate the overnight. I do not trust it. It amounts to writing a model of a decision process that belongs to other people and is unobservable in my data, then treating the output as a risk input. That is how a guess acquires a false precision.
The fix I trust is cruder. Do not hold to expiration. Close on a schedule, before the final session, as an ordinary order down the ordinary path. That converts an event I cannot model into a trade I can price, and the price is the spread I pay to leave.
It is not free, and the honest version states the cost rather than pretending the fix dominates. Closing early forfeits the last of the time value and pays a spread on every position, every cycle, including the large majority that would have expired without incident. I am paying a certain, recurring, measurable cost to remove a tail that is rare and that I cannot size.
If the tail were merely expensive, I would happily take the other side of that trade. I take this side because the tail is not so much expensive as unmodelled. It produces a state my risk logic was never written to describe, and the downside of waking up holding an unaccounted equity position is not bounded by the premium I collected for the option.
The general version of this, which I keep rediscovering in different corners of the same system: the events worth engineering against are not the ones with the worst expected value. They are the ones that leave the system in a state it has no vocabulary for.
Share this post
You Might Also Like
A Retry Is Not a Trading Decision
A rejected order is a decision. Retrying it without preserving the reason can turn a risk control into a duplicate trade.
Quantitative TradingThe Market Is Closed Is Not a Trading Rule
A backtest can know the exchange hours and still schedule a trade into a holiday, an early close, or a stale session. Calendar state is market data.
Agentic AIThe Log Is Part of the Agent's Interface
An agent that can act but cannot leave a useful decision record is not autonomous. It is an opaque process with write access.
Agentic AIThe Agent Did Not Need More Context
When an agent edits a shared checkout, the dangerous variable is not context length. It is the boundary around what the run is allowed to write.
Latest Blog Posts
A Retry Is Not a Trading Decision
A rejected order is a decision. Retrying it without preserving the reason can turn a risk control into a duplicate trade.
The Log Is Part of the Agent's Interface
An agent that can act but cannot leave a useful decision record is not autonomous. It is an opaque process with write access.
The Market Is Closed Is Not a Trading Rule
A backtest can know the exchange hours and still schedule a trade into a holiday, an early close, or a stale session. Calendar state is market data.
Related Tools & Demos
The QA Field Manual to Language Models
A free 24-chapter book. Start at βwhat is AI, really?β and finish with a small language model you built yourself β one that reads a failing Playwright test and proposes a fix you can run. Read it in your browser, or download the PDF or the Mac app.
View Source Code βMulti-Model LLM Harness
One interface to call any AI model β capability routing, fallback chains, budgets, circuit breakers, and a quality feedback loop. A practical architecture pattern write-up.
Automated Trading System
Multi-engine trading platform with real-time risk management, regime-based strategy selection, and automated order execution.
View Source Code β
Stay in the Loop
Get weekly insights on AI-driven QA, engineering leadership, and automation strategies.
No spam, ever. Unsubscribe anytime.