Skip to content

fix(chart): lines for every closed trade, closed_alpha for cancelled - #625

Merged
guyverino merged 1 commit into
mainfrom
fix/chart-closed-trade-lines
Sep 18, 2026
Merged

guyverino merged 1 commit into
mainfrom
fix/chart-closed-trade-lines

Conversation

@guyverino

@guyverino guyverino commented Sep 18, 2026

Copy link
Copy Markdown
Collaborator

What & why

Three defects of the "Trades: Moonbot lines" style (#624), found on its first live day.

  1. Cancelled orders lit up like trades. To draw closed trades in full colour, the style swapped closed_alpha for active_alpha across the WHOLE live order pass — so every cancelled order lit up too and the "closed/cancelled visibility" slider went dead in that style. Now a runtime-only ChartGraphicsCfg::bright_closed_trades (serde-skipped, like hide_entry_fill_arrow) tells build_order_geometry to lift only a closed order that became a tradeRetainedOrder::traded(): Filled verdict, entry fill percentage, or a stepped Sell line (the last covers a listing-sell closed by the backstop). Cancelled orders stay under the slider, in every style.
  2. A trade closed this session lost its exit line until the next launch. It draws from the live store, and that pass still obeyed the tab's hide_closed_sell_line (default on) while the archived pass beside it did not: one line today, two after a restart. The live pass lifts the switch in the lines style too. A cancelled order gains nothing: the store steps a Sell line only while the order holds a position, and the core keys the sell side's server trace by the exit leg's own id, which exists only after the entry filled.
  3. A trade the core archived nothing for kept both arrows. The core archives a line only once its chart gave it a point, so a trade that closed within a second answers empty (AMC on OKXf, 1 s, line_count = 0; every 0-line answer of that core is a 0–1 s trade; across all cores 260 of 1 071 trades ≤2 s have lines). No archive is not no line: the report row states the exit price, when the exit order was placed (SellSetDate — new ChartTradeRecord::sell_set_date/sell_set_ms, optional at the source like the ms columns) and when it filled. ReportExit::of_record lifts that through the report axis, and both store builders (OrderLineStore::archived / append_archived) add the straight Sell line when the traces hold no OWN exit line; an archived own exit, with its repricing path, wins. The exit never waits for the archive — it draws from the first frame; only the entry keeps its arrow until the core archives its own entry line (Moonbot lines on the chart: a trade whose buy order never moved has no entry line — the core's archive does not serve it #623: the report dates the entry's completion, not its placement).

Notable decisions

  • The synthesis lives in the one store builder (session/order_lines/archived.rs), so the live chart, the trade window's subject and its neighbours all get it through the same path. The trade window's neighbours are selected once — the NEIGHBOUR_CAP nearest — for both the ask and the store.
  • line_ends (was archived_line_ends): exit is always a line, entry only with an own archived Entry line; the arrows pass draws the arrow of the end that has no line.
  • The archived store's per-pane cache keys on a signature of the live twins (twins_signature) instead of the live store's revision, which moved on every order message of the core and would now rebuild a store of up to HISTORY_LIMIT orders each time.
  • SellSetDate < BuyDate (570 of 605k rows) is drawn as stated: the exit order is genuinely placed on a partial fill before the entry is recorded complete. A placement stamp raised past a millisecond close collapses to the close.
  • The trade window's "no traces" caption now says the archive holds none and the exit is drawn from the report, the entry as an arrow.

Known limitations

Issues

Refs #621 — fixes to part 2 (the lines style); the tracker's remainder is unchanged.
Refs #623 — the entry still keeps its arrow; this PR extends the exit line to trades with an empty archive as well.
None of the other 20 open issues is touched by this change.

How to verify

cargo fmt --all -- --check                                                                    # exit 0
cargo build -p moon-ui-gpui --bin moonterminal --target x86_64-pc-windows-msvc --all-targets  # ok
cargo clippy -p moon-ui-gpui --bin moonterminal --target x86_64-pc-windows-msvc --all-targets -- -D warnings
cargo test -p moon-core --target x86_64-pc-windows-msvc                                       # 2038 passed
cargo test -p moon-ui-gpui --target x86_64-pc-windows-msvc                                    # 1968 + 350 passed

clippy: 82 findings, all pre-existing debt — the 2 inside touched files (layout.rs mem_replace_option_with_some) sit on lines this diff does not touch (same lines on origin/main, shifted by insertions). FireTest not run (no chart/render/input path changed beyond geometry inputs; per the developer's rule).

On a chart in the lines style: a cancelled order dims with the "closed/cancelled visibility" slider while closed trades stay bright; a trade closed this session shows both lines; a 1-second trade (AMC/OKXf, 22:07:23) shows the entry arrow plus a straight exit line.

Three defects of the "Moonbot lines" trade style (#624), found on the first live day.

- The style lifted `closed_alpha` to `active_alpha` for the WHOLE live order pass, so
  every cancelled order lit up with the trades and the "closed/cancelled visibility"
  slider went dead in that style. The swap is replaced by a runtime-only
  `ChartGraphicsCfg::bright_closed_trades`; `build_order_geometry` lifts a closed order
  only when it is the frozen viewer's subject or the flag is set AND the order became a
  trade (`RetainedOrder::traded`: Filled verdict, entry fill percentage, or a stepped
  Sell line — the last covers a listing-sell closed by the backstop). Cancelled orders
  stay under the slider.
- A trade that closed this session draws from the live store, and that pass still
  obeyed the tab's `hide_closed_sell_line` while the archived pass beside it did not:
  one line until the next launch, two after. The live pass lifts the switch in the
  lines style too. A cancelled order gains nothing — the store steps a Sell line only
  while the order holds a position, and the core keys the sell side's server trace by
  the exit leg's id, which exists only after the entry filled.
- A trade the core archived nothing for kept both arrows. The core archives a line
  only once its chart gave it a point, so a trade that closed within a second answers
  empty (AMC on OKXf: 1 s, 0 lines; every 0-line answer of that core is a 0–1 s
  trade). No archive is not no line: the report row states the exit price, when the
  exit order was placed (`SellSetDate`, new `ChartTradeRecord::sell_set_date` /
  `sell_set_ms`, optional at the source) and when it filled. `ReportExit::of_record`
  lifts that through the report axis, and both store builders (`archived`,
  `append_archived`) add the straight Sell line when the traces hold no own exit line;
  an archived own exit, with its repricing path, wins. The live chart walks every
  visible non-twin trade, answered or not; the trade window's neighbours (the
  NEIGHBOUR_CAP nearest, one selection for the ask and the store) and subject get the
  same. The entry keeps its arrow until the core archives its own entry line — the
  report dates the entry's completion, not its placement.
- The archived store's per-pane cache keys on a signature of the live twins instead of
  the live store's revision, which moved on every order message of the core.

Refs #621
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant