Files
com_r35157_nenjim-hubd-impl…/openspec/changes/101-phoenix-twap-progress/design.md
T

3.7 KiB
Raw Blame History

Design

Context

See proposal.md for motivation. Phoenix account reads already fetch one mark per held market and are published atomically per wallet/venue. A failed read retains that venue's complete previous snapshot. EMC reconciles immutable snapshots and has no exchange dependencies.

Goals / Non-Goals

Goals: Attach precise, optional TWAP observations to existing positions and preserve their observation time through the service/UI boundary.

Non-Goals: Order placement, rows for unfilled orders, group summaries, new polling loops, live countdown timers or Ticker changes.

Decisions

  1. Read one TWAP snapshot per wallet with held positions, through the existing paced HTTP adapter. Validate authority/PDA/subaccount/asset identities against market metadata and trader state. Attach only orders with positive filled base lots and remaining children; never synthesize a position. A TWAP/schema/HTTP failure fails the complete venue read rather than masquerading as order disappearance. Independent partial TWAP refresh/cache would require a larger status model.
  2. Keep dedicated immutable Phoenix and Evelyn TWAP domain records, with exact integer counts, decimal quantities, a nullable mark and observation/estimated instants. Existing position constructor overloads remain convenient for consumers without TWAP data. A valid absent mark yields unknown price-dependent metrics and still exposes quantities; invalid prices and HTTP failures remain errors.
  3. Anchor dueSlot - snapshot.slot at response receipt and use nominal 200 ms per slot. Completion is dueSlot + (remaining - 1) × cooldownSlots; expiry is never used as completion. Already-due schedules, expiry before completion and unrepresentable estimates yield unavailable timing. These estimates require no new RPC client, network dependency or sampling cache. The current nominal 200 ms is documented by the Solana Foundation, updated October 2026 (400 ms is obsolete). Measured slot duration is deferred; nominal estimates and observation age are explicit in tooltips/docs.
  4. Decode snapshot counts as total children including dust. Explicit dust subtracts its count from total; legacy positive dust size with zero count replaces one final regular child. Missing dust metadata makes sizes unknown, never silently assumes an equal split. The next child switches to dust once regular children have executed.
  5. Append a graphic TWAP column using a ProgressBar and overlaid duration label. Counters measure execution count, with fills shown separately. Duration uses integer total hours and updates only with new snapshots. Failed venues show Retained instead of a fresh countdown. Tooltips show approximate USD values from the same mark already used for the position and state snapshot timing limitations.

Risks / Trade-offs

  • Nominal slot speed, API lag and delayed child execution → label estimates, show observation time, do not imply actual execution or advance counts locally.
  • More sequential reads → retain shared pacing/cooldown, skip TWAP reads without held positions; preserve 60-second post-cycle pause.
  • Nullable marks affect valuations → propagate unknowns into affected totals rather than publish partial totals or hide held positions.
  • Completed orders can disappear from the active endpoint → no historical completion claim or synthetic completed-order cache.

Migration Plan

No persisted data or configuration changes. Build and inspect focused temporary harnesses/JavaFX previews, update existing documentation and sync the three delta specs. Leave the running Hub untouched; rollback is reverting the source change before a normal owner-controlled deployment.