Today was a truth alignment day.
Not feature-first.
Not UI-first.
But data-first.
1️⃣ Order Audit: Facing Missing Fee Reality
I ran:
php artisan egis:audit:order 669 --exchange=binance_real --sync-missing --no-dry-run --force
At first glance, it looked fixed:
- filled_size_usd successfully backfilled.
- No Binance call.
- Evidence source: db_raw_payload.
But then the deeper truth surfaced:
fee_usd was still null.
Why?
Because the DB snapshot had:
- trade_count = 0
- commission_total = null
Which means:
- We did NOT actually have persisted trade-level commission data.
- Earlier “commission evidence” came from somewhere else.
- The system didn’t lose fee — it never truly stored it.
That was the key realization.
💡 Lesson:
If commission evidence is not persisted at trade level, fee cannot be deterministic.
Estimating fee from size * fee_rate is wrong.
Audit must be evidence-based, not assumption-based.
2️⃣ Position Sync Integrity
We reviewed position sync to ensure:
- Hedge Mode separation (LONG / SHORT always isolated).
- Positions never marked CLOSED unless Binance is flat.
- Filled orders must materialize:
- filled_size_usd
- fee_usd
- Sync must auto-repair missing fields when DB evidence exists.
- Raw payload merge must never downgrade richer payload into poorer payload.
The subtle bug wasn’t arithmetic.
It was evidence lifecycle.
If you overwrite a rich payload with a poorer one,
you silently erase audit truth.
That’s more dangerous than a math bug.
3️⃣ Admin Dashboard Performance Bug
Dashboard Performance card was wrong.
We fixed it conceptually:
Performance = SUM(realised_pnl) - SUM(fee)
But even after implementing that logic, it was still off.
Why?
Because Dashboard was using a slightly different query than Admin > Positions.
The Positions page was correct.
The Dashboard was not using the same aggregation path.
💡 Major takeaway:
Metrics must share a single backend source of truth.
We decided:
- Extract Positions aggregation logic.
- Reuse it for Dashboard.
- Never duplicate financial aggregation logic in two places.
Finance logic duplication = guaranteed drift.
4️⃣ Positions Fee Fix
On Admin > Positions:
Previously:
- Fee displayed only 1 order’s fee.
Now:
- Fee must equal sum of all filled order fees for that position.
- No double counting.
- No N+1.
- No frontend summing.
This reinforced something important:
A position is a container of executions, not a single event.
Fee is cumulative reality.
5️⃣ UI Refinement: Currency Standardization
Formatted PnL on Positions page as:
$0.00
Small change.
But presentation consistency builds trust.
If numbers look inconsistent,
traders subconsciously distrust the system.
What I Learned Today
1. Evidence > Estimation
If the system does not persist commission evidence,
it cannot truthfully report fees.
Never fake financial data.
2. Sync Is Not About Fetching — It’s About Materializing Truth
Pulling data from Binance is easy.
Persisting it deterministically,
without losing or corrupting evidence,
is the real engineering challenge.
3. One Financial Formula, One Source of Truth
If two pages compute financial aggregates separately,
they will diverge.
All financial math must be centralized.
4. Missing Data Is a System Design Smell
When something is null,
it’s rarely just “forgot to fill it”.
It means:
- Either evidence wasn’t stored.
- Or a later sync overwrote truth.
- Or aggregation logic drifted.
Missing data is a design problem, not a display problem.
Strategic Direction After Today
Egis must evolve toward:
- Trade-level evidence persistence
- Deterministic materialization layer
- Idempotent sync passes
- Shared aggregation services
- Auditability over convenience
Today wasn’t about adding features.
It was about making Egis more honest.
And in trading systems,
honesty is survival.
