Course contents
The broker is the source of truth
Your program's idea of your positions and orders can drift from reality, through a missed message, a restart, or a manual trade, and trading on a wrong picture is how automated accounts blow up quietly. This chapter teaches reconciliation: on startup and periodically, compare your record against the broker's and trust the broker. A tested example detects and reports a mismatch.
- Explain why the broker, not your program, is always the source of truth
- Reconcile the program's positions and open orders against the broker's on startup and on a schedule
- Detect and surface an orphaned order or a position mismatch
A trading program keeps its own record of what it holds and what orders are working. That record is a convenience, and it is also a lie waiting to happen. The moment your program's memory and the broker's actual account disagree, and they will, one of them is wrong, and it is never the broker. Reconciliation is the habit of regularly checking the two against each other and correcting yourself to match the broker. Skip it, and your program will eventually make a confident decision based on a position it does not really have.
Why your record drifts
Your program's view can fall out of step with reality in many ordinary ways. A fill confirmation arrives while your program is briefly disconnected, and it is never recorded. The program crashes and restarts, its memory blank, while the account still holds a position. You place a trade by hand in the app, which your program knows nothing about. A cancel you thought succeeded did not. None of these are exotic. Every one leaves your program believing something false about the account, and a program that trades on a false belief about its own positions can sell what it does not own or double a position it forgot it had.
The broker is the truth
The principle that resolves every such disagreement is simple: the broker is the source of truth. Your program's record is a cache, a convenient copy, and when a copy disagrees with the original, the original wins. This is not a matter of trust in the broker's goodwill; it is that the broker's record is what actually settles, what you are actually liable for, and what the exchange sees. So a safe program never assumes its own memory is right when the broker says otherwise. It asks the broker and believes the answer.
Reconciliation puts that principle into code. You read the broker's real positions and orders, compare them against your own record, and where they differ, you correct yourself. Here is the core of it.
# Your program keeps its own idea of what you hold, and that idea can drift from
# reality: a fill it missed, a trade you placed by hand, a restart. The broker's
# record is the truth. Reconciliation compares your view against the broker's,
# reports any mismatch, and corrects your view to match. Never trade on your own
# record when it disagrees with the broker.
from paper_broker import PaperBroker
broker = PaperBroker(cash=1_000_000, prices={"RELIANCE": 1400, "INFY": 1500})
# What our program THINKS it holds, from what it remembers sending.
local_view = {"RELIANCE": 10}
# What actually happened, recorded by the broker: a fill our program missed
# (Reliance is really 20, not 10) and a trade placed by hand in the app (Infosys).
broker.place_order("RELIANCE", "BUY", 20, "MARKET")
broker.place_order("INFY", "BUY", 5, "MARKET")
def broker_view(broker):
return {p["symbol"]: p["quantity"] for p in broker.get_positions()}
def reconcile(local, broker):
truth = broker_view(broker)
mismatches = []
for symbol in sorted(set(local) | set(truth)):
ours, theirs = local.get(symbol, 0), truth.get(symbol, 0)
if ours != theirs:
mismatches.append((symbol, ours, theirs))
return truth, mismatches
truth, mismatches = reconcile(local_view, broker)
print("Our view: ", local_view)
print("Broker view:", truth)
if mismatches:
print("MISMATCH (symbol: ours vs broker):")
for symbol, ours, theirs in mismatches:
print(f" {symbol}: we thought {ours}, broker says {theirs}")
print("Action: trust the broker, and correct our view.")
local_view = dict(truth)
print("Reconciled view:", local_view)Our view: {'RELIANCE': 10}
Broker view: {'RELIANCE': 20, 'INFY': 5}
MISMATCH (symbol: ours vs broker):
INFY: we thought 0, broker says 5
RELIANCE: we thought 10, broker says 20
Action: trust the broker, and correct our view.
Reconciled view: {'RELIANCE': 20, 'INFY': 5}Read the mismatch. The program thought it held 10 Reliance and nothing else. The broker's record shows 20 Reliance, because a fill was missed, and 5 Infosys, from a trade placed by hand. Reconciliation finds both discrepancies, reports them plainly, and corrects the program's view to match the broker's. Had the program not reconciled, it might have bought 10 more Reliance thinking it was topping up to 20 when it was already there, or ignored the Infosys position entirely when sizing its risk.
When to reconcile
Do it at two times at least. First, on every startup, before the program places a single order, because a program that has just started has no idea what happened while it was down. Reconciling first is why the reliability of a restart matters, and why a later chapter insists a system check the account before it resumes trading. Second, periodically while running, and especially after any disconnection, so drift is caught in minutes rather than discovered as a nasty surprise. Reconciliation is cheap, it is only reads, and it is the difference between a program that knows what it holds and one that merely believes it does.
What to carry forward
Your program's view of the account is a cache that drifts from reality through missed fills, restarts, and manual trades, and when it disagrees with the broker, the broker is always right. Reconciliation reads the broker's true positions and orders, compares them to your record, surfaces every mismatch, and corrects you to match, which you saw catch both a missed fill and a manual trade. Do it on startup, before any order, and periodically thereafter, especially after a disconnection. With orders placed, tracked, and reconciled, you have a dependable execution layer. The next part puts a strategy on top of it, turning the backtest you trust into a program that runs itself.