Today was not about adding flashy features. It was about tightening truth.
1. Strategy Report: From Snapshot to Lens
I refined Admin > Insights > Strategy Report into something more analytical instead of decorative.
- Aligned the page heading to match Average Metrics for visual consistency.
- Introduced a new filter layer:Strategy → Signal Key → SYMBOL.
This turned Strategy Report from a broad summary into a controlled lens.
Now I can zoom into one symbol inside a signal scope instead of blending everything together.
The most important realization here:
Filtering is not UI behavior.
Filtering is data scoping.
Everything must be scoped at the backend. No dedupe in React. No frontend masking.
2. Symbol Deduplication – Trust the Query, Not the Array
When I added the SYMBOL selector, it showed:
BNBUSDT, BNBUSDT, BNBUSDT, BNBUSDT
Classic mistake: returning raw rows instead of distinct values.
Fix:
- Enforced DISTINCT at query level.
- Sorted deterministically.
- Kept DB as source of truth.
Lesson reinforced:
If the database says something four times, the UI should not pretend it says it once.
Deduplication belongs in the query layer, not in array_unique().
3. “All Symbols” Mode – From Cards to Table
Originally, “All Symbols” rendered multiple symbol cards.
That was visually heavy and cognitively noisy.
I converted it into a proper data table:
- One row per symbol.
- Comparable metrics side by side.
- Overview-first mindset.
- Mobile-friendly horizontal scroll.
Now Strategy Report feels analytical, not narrative.
It answers:
Which symbol performs better inside this signal scope?
Instead of:
What happened symbol by symbol?
Design lesson:
If the question is comparative, use a table.
If the question is descriptive, use sections.
4. Enforcing Net PnL (The Real One)
This was the most important correction today.
Strategy Report must show:
net_pnl = realised_pnl - commission
Not gross PnL.
And absolutely not:
- Assuming commission = 0
- Including positions with incomplete closure reconciliation
I enforced:
- Exclude closed positions where:
- realised_pnl is null
- commission is null
- closure_backfill_needed = true
- Log structured warnings instead of masking errors.
- Keep money formatting consistent ($0.00).
This aligns with the invariant:
A closed position without financial reconciliation is not financially closed.
That’s a discipline shift.
We are no longer building a dashboard.
We are building a financial truth surface.
5. Bigger Realization
Today wasn’t about React.
It wasn’t about Tailwind.
It wasn’t about UI.
It was about integrity of numbers.
If:
- PnL is wrong
- Commission is ignored
- Missing data is silently accepted
Then everything else becomes decoration.
Egis is slowly becoming what I intended:
- Backend-first
- Evidence-first
- Deterministic
- No silent fallbacks
- No UI illusions
And I learned something subtle today:
Debugging improves the system.
Invariants protect the system.
But clarity in metrics defines the system.
Today Egis became clearer.
