Repository navigation
Open
Labels
component:cliCLI/terminal interface and REPL featuresCLI/terminal interface and REPL featuresenhancementNew feature or requestNew feature or requesttradingTrading execution, order management, and broker integrationTrading execution, order management, and broker integration
Description
Decision (owner, 2026-11-01)
Build design 2 from the research: software targets, opt-in per position, after the paper order test (#660). The research (#654, docs/08_research/03_strategy_research/partial_exits.md) found no gain. No design beats the live trailing exit by more than noise, and with SELL exits off every design lowers CAGR. The owner chose to build it anyway, knowing that.
The listing part of the original report is fixed: /partial reads saved plans (#588). What's left is registering plans and acting on them.
What it does
/partial set SYMregisters a plan on a held position: half the shares (whole shares; a 1-share position gets no plan) sell at the mode's first target over the entry, and the rest keeps the trailing stop./partial remove SYMdrops a plan.- The morning and evening routines check each plan: at or past the target, they sell the target shares at market.
- A sale goes through
plan_closeandclose_position(feat(cli): sell a held position whatever the signal says #641). They cancel the stop, wait for Alpaca to release the shares, sell, and place a stop on the rest at the same level. For those few seconds no stop covers the position, because Alpaca refuses a sale of shares a stop holds. A failed sale puts the stop back. - Each sale goes in the report and the daily records. A failure raises a notice. A dry run sells nothing.
To settle in the plan
- A plan registered when the price is already past the target would sell at the next routine.
/partial setshould say so and ask. - At 09:20 the market is closed, so a morning sale is a market order queued for the open. Decide whether the morning check sells or only the evening one does.
Fix on the way
PartialExitManager.from_mode_managerignores the mode'starget_1_pct(4%, 5% and 6% intrading_modes.yaml) and always uses 4%.
Done when
- Unit tests cover registration, the check, a sale, a failed sale (stop back in place) and a dry run, with mocks only.
- A dry run of both routines with a plan registered is clean.
- One real paper sale runs with the owner watching.
Original text
What happens
Every /partial subcommand (list, summary, active, levels, modify, <symbol>) prints [ERROR] Could not access PartialExitManager.
Causes
- The manager can't be built.
_get_partial_exit_manager()insrc/cli/tools/partial_exit_tools.pycallsPartialExitManager(), but the constructor requiresorder_manager. TheTypeErroris caught and logged, and the function returnsNone. - The tools read the wrong attribute. With a manager in hand, the tools would read
manager.positions, butPartialExitManagerkeeps its plans inexit_states. - Nothing shares or saves plans. Each call would build a fresh, empty manager, and
PartialExitManagerhas no persistence. Nothing outside these CLI tools constructs aPartialExitManager, so no trading path registers plans to begin with.
Also, modify_exit_target only changes the stored price. It doesn't replace the limit order at the broker or save the change.
Proposed design
- Add a module-level
get_partial_exit_manager()(likeget_gtt_manager()), built with the session's order manager. - Persist
exit_statesin the shared state dir (astate/user.dbtable orstate/partial_exits.json) throughsrc/utils/state_paths, so tests stay isolated throughAUTOTRADER_STATE_DIR. - Register a plan where bracket entries are placed, or on demand from
/partial, and point the CLI tools atexit_states. - Make
modifyreplace the live limit order at the broker as well as the stored target, then save.
Acceptance
/partial,/partial <symbol>,levels,active,summaryandmodifywork against saved plans and survive a restart.- Unit tests use a temporary state dir and mocks, and place no paper orders.
Related
- [CLI] Add /partial command for partial exit management #508, the
/partialcommand. - Found in a hand review of the parts of Draft: CLI integration, trading refactors, GEX research and regime look-ahead fix (#576) #577 the automated review skipped, and noted in fix: follow-ups from the #577 review #583.
Metadata
Metadata
Assignees
Labels
component:cliCLI/terminal interface and REPL featuresCLI/terminal interface and REPL featuresenhancementNew feature or requestNew feature or requesttradingTrading execution, order management, and broker integrationTrading execution, order management, and broker integration
Activity
iAmGiG commentedon Oct 14, 2026
Overlaps #524, which reported the constructor bug (cause 1 here) in Dec 2025 and proposes a
get_partial_exit_manager()singleton. Causes 2 and 3 and themodifygap are only described here. A fix should close both.iAmGiG commentedon Oct 20, 2026
Status 2026-10-20: #588 fixed most of this issue.
Done in #588
/partialbuilds its manager with an order manager, and the views readexit_states.state/partial_exits.json(which honoursAUTOTRADER_STATE_DIR) and survive a restart. The CLI re-reads the file on each call.modifychanges an unfilled limit target and saves it.Still open
/partialonly shows plans saved some other way. This is the main remaining work.modifywith a live broker order: it refuses the change instead of replacing the broker's limit order, as the proposed design here intended.Design question to settle first
Registering a plan places a partial limit sell. Alpaca rejects it while an existing stop holds all the shares (the stop counts against
qty_available). That's true of every position the scheduler manages today. Options:Remaining acceptance
modifyreplaces a live target order, or the design records why it can't.Nothing depends on this yet. The current positions exit by trailing stop only: their take-profit legs lapsed and aren't re-placed (accepted 2026-10-20).
[-]/partial commands fail: no PartialExitManager is reachable from the CLI[/-][+]/partial: register plans in the trading flow, and modify targets that have a live order[/+]iAmGiG commentedon Oct 28, 2026
Retitled 2026-10-28. #588 made
/partialwork and #508 is closed; what's left here is the two items in the 2026-10-20 status comment above: nothing in the trading flow registers a plan, andmodifyrefuses a target that has a live broker order. The design question stands: a partial limit sell is rejected while a stop holds all the shares.Merge pull request #654 from iAmGiG/research/partial-exits-584
[-]/partial: register plans in the trading flow, and modify targets that have a live order[/-][+]Partial exits, design 2: opt-in software targets sold by the routines[/+]Merge pull request #671 from iAmGiG/feat/partial-exits-design2-584