Egis Technical Journal – 2026-01-29


🛠️ Technical Journal — Today

What I have done

Today was a deep stabilization and UX-cleanup day for Egis. The work wasn’t about adding flashy features — it was about making the system honestoperationally safe, and pleasant to use.

1. Hardened position auditing & reconciliation

  • Expanded the audit command from a narrow TP/SL check into a full position audit (egis:audit:positions).
  • The command now audits both OPEN and CLOSED positions, instead of exiting early when nothing is open.
  • Covered the most painful real-world edge case:
    • Internal position marked CLOSED
    • Position was manually closed on Binance
    • TP/SL existed but were not the closing mechanism
  • Implemented logic to:
    • Search Binance for the actual manual close market order (same symbol, opposite side, matching quantity)
    • Pull trades from that order
    • Backfill realised PnLfees, and close metadata
  • Made the audit idempotent and evidence-first:
    • It never assumes TP/SL caused the close
    • It always tries to prove closure via trades
    • Clear statuses: present / missing / partial / unavailable
  • Added an --open option to focus only on OPEN positions when needed.
  • Scheduled the open-position audit to run every 5 minutes, turning it into a living safety net instead of a manual tool.

This made Egis much closer to a self-healing system.


2. Removed legacy “Paper” trading remnants

  • Fully removed:
    • Paper-related tables
    • Paper-related commands
    • Paper options from exchange selection in User Dashboard
  • This eliminated migration errors, FK failures, and conceptual confusion.
  • Reinforced the rule:Internal positions are the only source of truth.

No ghosts left in schema, commands, docs, or UI.


3. Introduced bot performance calculation (profit system)

  • Created a command to calculate performance for all bots:
    • Net Profit
    • Net ROI
    • APY (annualized)
  • Ensured:
    • Calculations are derived only from internal positions
    • Binance is never queried
    • Capital base is handled conservatively (no guessing)
  • Added persistence support (idempotent) so performance can be reused by UI.
  • Scheduled this calculation to run hourly, making performance data always fresh.

This laid the foundation for performance-driven UX without runtime cost.


4. Fixed signal validation logic (LONG & SHORT)

  • Added strict TP/SL validation at signal-hook level:
    • LONG:
      • TP must be > price
      • SL must be < price
    • SHORT:
      • TP must be < price
      • SL must be > price
  • Handles numeric values even when inputs arrive as strings.
  • Prevents invalid trades from entering the system instead of repairing later.

This reduced downstream complexity significantly.


5. Fixed User Dashboard 500 error on duplicate signal_key

  • Diagnosed that a normal validation case was bubbling up as a 500 error.
  • Reframed duplicate signal_key as:
    • A proper 422 validation response
    • Displayed inline / toast on the User Dashboard
  • No stack trace, no error page — just a helpful message.

Small fix, huge UX win.


6. Major UX cleanup on User Dashboard Bot cards

  • Simplified Bot cards to focus on what matters:
    • Removed realised / unrealised / orders / fees
    • Removed strategy info entirely
  • Introduced APY-only performance display:
    • Green badge for positive
    • Red badge for negative
    • Neutral for missing
  • Added Open positions count as a second 2-tone badge next to APY.
  • Improved layout:
    • Bot icon moved before title
    • Budget on the left, Available budget on the right
    • Delete button moved to card footer and only visible when expanded

Result: cleaner, calmer, more readable cards — especially on mobile.


7. Improved Bot Detail position cards (OPEN positions)

  • Redesigned OPEN position cards into:
    • Above the fold: side badge (long/short) + Unrealised PnL
    • Folded section: everything else
  • Removed the redundant “Open” badge.
  • Moved the Close button to the card footer.
  • Collapsed details by default to reduce noise.

This made the most important info visible instantly, without losing depth.


8. Admin UX enhancement

  • Made “Positions Count” on Admin Dashboard clickable.
  • Linked it to a new Admin Positions insights page:
    • Summary stats
    • Filters
    • Paginated table
  • Admin now has visibility across the entire system in one place.

What I have learned

  1. Audit ≠ Repair — but good audits naturally lead to safe repair
    • The moment the audit had enough evidence, repair became obvious.
    • The key was separating detection from action, then carefully allowing action only when evidence exists.
  2. Manual closes are the hardest truth
    • TP/SL logic is easy.
    • Manual closes require humility: the system must admit it doesn’t know, then go searching for facts.
    • Trades never lie — orders sometimes disappear.
  3. UX debt is as dangerous as logic debt
    • A 500 error for a validation issue erodes trust instantly.
    • Extra badges and numbers dilute meaning.
    • Removing information is often more valuable than adding it.
  4. Scheduled audits change the nature of bugs
    • Once audits run every few minutes, bugs stop being “incidents”.
    • They become temporary inconsistencies that self-correct.
  5. Single source of truth only works if everything respects it
    • Removing Paper trading wasn’t cleanup — it was architectural enforcement.
    • Anything that violates the truth model will leak bugs forever.
  6. Good systems feel calm
    • After today, Egis feels calmer:
      • Fewer numbers
      • Clearer states
      • Predictable recovery paths
    • That calmness is a signal the architecture is aligning.