Stop Chasing Phantom Balances: A Reconciliation Blueprint for MT5 vs. Your Ledger
A broker’s back office usually has two “truths” that drift apart: the cash ledger (what finance can settle and pay out) and MT5 balances (what traders can use to trade). The drift gets ugly when you add bonuses, payment fees, chargebacks, and reversals—because those events don’t behave like clean deposits and withdrawals.
This post lays out a practical design for a ledger-to-MT5 reconciliation that holds up under real-world edge cases, and gives ops, risk, and compliance a single place to point to when numbers don’t match.
1) Define the Golden Source of Truth (and what MT5 is allowed to be)
If you don’t explicitly define “truth,” your teams will improvise:
- Finance treats the payments ledger as truth.
- Dealing/risk treats MT5 as truth.
- Support treats “whatever the client sees” as truth.
A resilient model is:
- Golden source of truth = your internal double-entry ledger (client liabilities + broker assets/contra accounts).
- MT5 = a trading sub-ledger / execution wallet that can contain both cash and non-cash trading credit (bonuses), and is therefore not always equal to “withdrawable.”
Make this explicit in policy and UI:
- “Withdrawable balance” comes from the ledger.
- “Trading balance/credit” comes from MT5 (or a derived view).
- Any “available to trade” number must be explainable as cash + eligible credit – holds.
This one decision prevents the most common reconciliation failure: trying to force MT5 to behave like a bank account.
2) Model balances as components (cash, credit, holds) instead of one number
A single “balance” field can’t survive bonuses and reversals. Design your ledger so every client has components that map cleanly to operations:
- Cash (settled): funds you can pay out (after fees/chargebacks/AML holds).
- Cash (pending): deposits not yet settled or still in risk window.
- Trading credit (bonus): non-withdrawable credit with rules.
- Holds/locks: compliance holds, chargeback reserves, manual review holds.
Then define a few derived numbers you reconcile and report:
- Withdrawable = cash(settled) – holds
- Tradable = cash(settled + pending if you allow) + trading credit – holds
- Exposure-relevant = what risk should consider for margining (often tradable, but policy-based)
Why this matters for MT5: MT5 has its own concepts (Balance/Equity/Credit). Your goal is not to mirror every MT5 field, but to ensure each MT5-affecting event has a ledger entry and a mapping rule.
3) Use an event-sourced ledger with reversal-first mechanics
Reconciliation breaks when systems “edit history.” The fix is to treat every balance change as an immutable event and handle mistakes with reversals, not updates.
Minimum event types you should support:
- Deposit initiated / deposit settled
- Withdrawal requested / approved / paid / rejected
- Fee charged (payment fee, admin fee, conversion fee)
- Bonus granted / bonus revoked / bonus expired
- Chargeback received / chargeback reversed
- Manual adjustment (with reason + approvals)
- MT5 transfer in/out (if you move between wallets/platforms)
Design rules that keep you sane:
- No destructive edits to posted entries.
- Every event has:
event_id,client_id,amount,currency,timestamp,source_system,reference,performed_by, and links to the original event if it’s a reversal. - Post in double-entry: client liability account + corresponding broker account (cash, fees revenue, bonus expense/contra, chargeback reserve, etc.).
This is what lets you answer the real questions auditors and partners ask: “Show me the chain from payment provider transaction → ledger posting → MT5 change → current client state.”
4) Design the MT5 mapping: what posts to MT5, what stays in the ledger
Now the practical part: decide which ledger events must produce an MT5 action, and which must not.
A robust mapping typically looks like this:
- Deposit settled → MT5 balance increase (or wallet credit) for the amount you allow to trade.
- Payment fees → ledger-only (recommended), unless you explicitly charge the client inside MT5.
- Bonus granted → MT5 credit increase (not balance), and ledger entry to a bonus liability/contra account.
- Withdrawal approved → MT5 balance decrease (or lock funds before approval, depending on policy).
- Chargeback received → immediate MT5 restriction + ledger move to reserve/negative balance workflow.
Two key decisions to document:
Do you trade on pending deposits?
- If yes, you need a pending component and clear rules for what happens if settlement fails.
Do you allow MT5 negative balances?
- If no, chargeback handling must include account locks / forced closure rules.
Your reconciliation should assert invariants rather than chase numbers:
- If ledger says “bonus credit,” MT5 must show corresponding credit (unless expired/revoked).
- If ledger says “withdrawal approved,” MT5 must reflect funds removed or held.
- If a chargeback event exists, MT5 must be restricted per policy within an SLA.
5) Reconciliation checks that actually catch bonus/fee/reversal edge cases
A good reconciliation is not one giant “MT5 balance equals ledger balance” query. It’s a small set of checks that isolate failure modes.
Here’s a focused checklist that works in production:
- Population check: every active MT5 account must map to exactly one CRM/ledger client (no orphans, no duplicates).
- Currency check: ledger currency and MT5 account currency alignment (or explicit FX conversion entries).
- Component check:
MT5 Creditequals ledgerTrading credit (bonus)minus expired/revoked bonuses.MT5 Balanceequals ledger cash posted to MT5 (not necessarily withdrawable).
- Movement check (by day/hour): sum of MT5 balance deltas must equal sum of MT5-posting ledger events for the same window.
- Reversal integrity: every reversal links to an original event; net effect across original+reversal is zero.
- Fee leakage check: fees are posted exactly once (common bug: fee applied in PSP and again in CRM).
Operationally, run:
- Near-real-time checks for “must-fix-now” issues (e.g., withdrawal approved but MT5 not debited).
- Daily close checks for accounting accuracy and reporting.
When a check fails, the output should be a recon case with:
- the exact event(s) missing,
- the system-of-record that should have produced them,
- and the recommended corrective action (post reversal, post compensating entry, or trigger MT5 adjustment).
6) Worked example: deposit + fee + bonus + chargeback (and why naive recon fails)
Consider this realistic flow (single currency for simplicity):
- Client deposits $1,000 via card.
- PSP charges $30 in fees.
- Broker grants $200 bonus credit.
- A week later: chargeback for the $1,000.
A naive approach tries to keep MT5 balance equal to “ledger balance” and collapses immediately.
A resilient posting approach:
Deposit settled
- Ledger: client cash liability +$1,000; broker cash asset +$1,000
- MT5: balance +$1,000 (if you allow trading on settled)
PSP fee
- Ledger: client cash liability -$30 (if client-borne) or broker expense -$30 (if broker-borne)
- MT5: no change (recommended) unless your product explicitly deducts fees from trading funds
Bonus granted
- Ledger: trading credit +$200 (non-withdrawable component)
- MT5: credit +$200
Chargeback received
- Ledger: client cash liability -$1,000; broker cash asset -$1,000; optionally move to chargeback reserve / receivable if you pursue recovery
- MT5: enforce policy (lock withdrawals, reduce balance if possible, or move account to restricted state)
Now your reconciliation logic can explain the “weird” state:
- MT5 might still show credit $200 but the ledger shows cash negative / held due to chargeback.
- Withdrawable is not MT5 balance; it’s ledger cash minus holds.
This is exactly why the golden source must be the ledger: it is the only place where fees, reversals, and legal settlement reality can be represented cleanly.
The Bottom Line
A ledger-to-MT5 reconciliation survives real-world edge cases when you stop forcing one number to mean everything.
Use an immutable, double-entry ledger as the golden source; model balances as cash/credit/holds; map only the right events into MT5; and reconcile via component and movement checks—not a single equality.
If you want a practical implementation path using Brokeret’s CRM + MT5 integrations, start here: /get-started.