Skip to content

fix(trade): switch the core's manual strategy off ahead of a bare order - #541

Merged
guyverino merged 1 commit into
mainfrom
fix/ms-off-clears-core-switch
Sep 13, 2026
Merged

fix(trade): switch the core's manual strategy off ahead of a bare order#541
guyverino merged 1 commit into
mainfrom
fix/ms-off-clears-core-switch

Conversation

@guyverino

Copy link
Copy Markdown
Collaborator

What & why

A manual order placed with the terminal's manual-strategy mode OFF goes to the core with StratID = 0. On the wire zero is not "no strategy" — it is "attach whatever the core's own use_manual_strategy / manual_strategy_id names", and moonproto has no value for "deliberately none". With Moonbot's own checkbox left on, three bare orders on BB1 (2026-09-13 03:37) were attached to a Manual strategy nobody selected in the terminal and followed its hook: sell and trailing came from the strategy, not from the TP/SL the terminal had just confirmed.

The exit barrier a bare order already waits behind (ClientSettingsSequence::enqueue_order, sync_exit == true) now queues a private SettingsMutation::NoManualStrategy that writes use_manual_strategy = false into the SAME full-snapshot ClientSettings packet as the group exits. It is confirmed by the core's echo like every other mutation and abandoned after the same MAX_EXIT_ATTEMPTS, so it costs no extra round trip on a core whose switch is already off, and one echo on a core whose switch is on.

Orders that name a strategy (mode ON) are unchanged: an explicit id is honoured regardless of the core's switch (checked live), so Moonbot's own screen is left alone there and two terminals on one core can still sit on different strategies.

Notable decisions

  • Only the switch is written; manual_strategy_id is not touched, so the seed that adopts a never-seen core (tick_manual_strat_seed) still finds the selection and keeps it (mode off, strategy kept).
  • Applied to pending orders as well, although moonproto documents a bare pending as one the core does not hand its manual strategy to: that sentence has not been checked against a live core, the pending waits for its trigger anyway, and one echo is the cheaper side of that trade.
  • When the core refuses the flip three times the order is still released (a click that silently does nothing was judged worse, as for the exits) — but the abandon log now names the affected order's market and says outright that it WILL be attached to the core's strategy. The old pre-order log::warn that only guessed at this is gone.
  • Queue mechanics untouched: a core contesting both the exits and the switch holds the order for two retry budgets, each abandoned in turn. Documented on sync_exit; a shared counter would drop mutations queued later (TempBL during the wait) before their budget.

Known limitations

  • A core whose strategy feed is off never seeds its manual-strategy state here, so its toggle reads OFF and every bare order from the terminal clears Moonbot's checkbox on it. Consistent with what the screen shows; noted for anyone who runs such a core with Moonbot's manual mode on.
  • Not verified live in this PR — a bare order on a live core is a real trade. What to look for: serialized client settings sent BEFORE place order … strat=None, Moonbot's checkbox going off, the order living under the terminal's TP/SL rather than the strategy's hook.
  • The proper fix is on the wire — Start needs a "no strategy" reading, as StartPending already has. Write-up for the core/moonproto team is in docs-internal/proto_bare_order_manual_strategy.md (not tracked).

Issues

None of the 16 open issues is touched by this change.

How to verify

cargo fmt --all -- --check
cargo build -p moon-ui-gpui --bin moonterminal --target x86_64-pc-windows-msvc --all-targets
cargo clippy -p moon-core -p moon-ui-gpui --target x86_64-pc-windows-msvc --all-targets -- -D warnings
cargo test -p moon-core --target x86_64-pc-windows-msvc
cargo test -p moon-ui-gpui --target x86_64-pc-windows-msvc

fmt --check exit 0 · build all targets green · clippy: 107 pre-existing locations on the branch, 107 on origin/main, per-file counts identical — zero new findings · tests: moon-core 1947 passed, moon-ui-gpui 1799 passed + theme_contract 330 passed, 0 failed · FireTest not run (no chart/render/window/input surface). Three new unit tests in feed/live/client_settings/tests.rs: the switch travels off in the exit packet and the order waits for its echo; an order with a strategy leaves the switch alone; a core that keeps its switch on does not strand the order.

🤖 Generated with Claude Code

A manual order placed with the terminal's manual-strategy mode OFF goes out
under StratID=0, which the core reads as "attach whatever my own
use_manual_strategy names" - there is no "deliberately none" value on the
wire. With Moonbot's own checkbox on, three bare orders on BB1 (2026-09-13)
were attached to a strategy nobody chose here and followed its hook.

The exit barrier a bare order already waits behind now carries
use_manual_strategy=false in the same ClientSettings packet as the group
exits (SettingsMutation::NoManualStrategy), confirmed by the core's echo
like any other mutation and abandoned after the same retry budget - with a
log line naming the order and the consequence when the core will not hold
it. Orders that name a strategy are unchanged: an explicit id is honoured
regardless of the switch, so Moonbot's screen is left alone there.

The stale pre-order warning is gone and the docs that promised the switch is
never written now say when it is.
@guyverino
guyverino merged commit 55bf65c into main Sep 13, 2026
6 checks passed
@guyverino
guyverino deleted the fix/ms-off-clears-core-switch branch September 13, 2026 08:06
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