Egis Daily Technical Journal — 09/02

Today was one of those days where the system looked correct on the surface, but the truth only showed up once I forced myself to follow the evidence all the way down.


What I worked on

I deep-dived into a strange inconsistency in Egis:

a position (ID 101) was clearly closed, yet both realised PnL and commission were missing.

At first glance, this smelled like a data bug or a sync race condition. But after building a dedicated debug command and inspecting positions-debug.log, the picture became much clearer.

I traced the entire lifecycle of the position:

  • Opened correctly
  • TP/SL orders existed
  • Closed timestamp was set
  • But no closing order was ever matched, so no closing trades were picked up
  • The system silently fell back to a “minimal close” path

That fallback marked the position as closed, but intentionally left:

  • realized_pnl = null
  • commission = null
  • close_exchange_order_id = null

So the system was honest… but dangerously quiet.


The real root cause

The bug was not in Egis’ core logic.

It was a Binance Futures edge case that slipped through our assumptions:

  • When TP or SL triggers on Binance Futures, the executed order type is not MARKET
  • It is TAKE_PROFIT_MARKET or STOP_MARKET
  • Our closing-order matcher explicitly filtered those out

That single filter caused a chain reaction:

  1. Closing order not detected
  2. Closing trades not matched
  3. Realised PnL + fee never computed
  4. Fallback “manual_or_other” close triggered
  5. Position ended up closed but incomplete

The quantity-matching logic then made things worse by trusting a stale position_amt, guaranteeing the fallback path would also fail.


What I learned (important)

  1. Silent fallbacks are dangerousA system that “keeps going” without screaming is worse than one that crashes.
  2. Exchange semantics matter more than documentationBinance UI was correct. My assumptions about order types were not.
  3. A closed position without PnL is not “done”Closure must be treated as an invariant:closed ⇒ realised_pnl + commission + close_order_id must exist
  4. Debug commands are first-class toolsBuilding egis:debug:position paid off immediately.Logs beat intuition every time.
  5. Backfill must be intentional, not accidentalAny time the system cannot fully reconcile a close, it should:
    • mark the position as needing backfill
    • log structured evidence
    • be repairable later in a deterministic way

Direction going forward

From this investigation, I defined clear prevention rules for Egis:

  • Accept TP/SL market order types explicitly
  • Resolve expected close quantity from reliable sources (open fills first)
  • Never silently close a position with missing financials
  • Persist “closure incomplete” state and backfill it via commands
  • Treat evidence logs as part of the system, not a debugging afterthought

Today wasn’t about adding features.

It was about earning trust in the data.

And that’s the kind of progress that actually compounds.