Alpaca's rebalancer CronJob has been suspended with 401'd keys since Task 4's
venue consolidation; IBKR paper is already the live forward-track venue for
the multi-strat book. This removes the dead code/config/manifests instead of
leaving them to rot, and relabels the multistrat/multistrat_exec registry
venues from the vestigial "alpaca-paper" to "ibkr-equity" (they execute on
IBKR paper, not Alpaca — exec_venue itself is still computed dynamically at
runtime).
- Delete src/fxhnt/adapters/broker/alpaca.py, AlpacaSettings + the `alpaca`
config field; move the one real setting it carried (min_order_notional,
a generic "skip sub-min-notional dust" floor for any future
fractional-capable broker) onto ExecutionSettings.
- Remove the `--broker` option and its alpaca branches from `execute` and
`execute-multistrat` (cli.py) — IBKR is now implicit; IbkrBroker was
already the module-level import, so the branch was pure dead code once
Alpaca is gone.
- Delete infra/k8s/jobs/fxhnt-alpaca-rebalancer.yaml and
infra/k8s/secrets/alpaca-credentials.yaml; delete the superseded
infra/k8s/services/multistrat-rebalancer.yaml (PVC + NetworkPolicy +
CronJob), replaced by fxhnt-ibkr-rebalancer. Drop the now-invalid
`--broker ibkr` argument from fxhnt-ibkr-rebalancer.yaml and
fxhnt-ucits-rebalancer.yaml (the flag no longer exists).
- Delete tests/integration/test_alpaca_broker.py (tested the deleted
adapter directly); add tests/unit/test_no_alpaca.py as a standing guard
(no "alpaca" substring anywhere in src/fxhnt + IbkrBroker still imports).
- Update test_registry_multistrat_exec.py + test_cockpit_ssot.py (venue
label) and test_cli_execute_helpers.py (drop the broker_name kwarg and
AlpacaBroker fake, use IbkrBroker instead) to match.
MANUAL cluster ops (not run by CI, record only):
kubectl delete cronjob/fxhnt-alpaca-rebalancer secret/alpaca-credentials -n foxhunt
kubectl delete cronjob/multistrat-rebalancer networkpolicy/multistrat-rebalancer pvc/multistrat-state -n foxhunt
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The paper-envelope-refusal test calls execute_multistrat() directly; the new --venue
validation guard receives the typer.OptionInfo default unless venue_kind is passed
explicitly, so the direct call now passes venue_kind='us' like its other options.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Two execute-CLI gaps from the C3 port:
- `execute_multistrat`'s generic `except Exception` caught the ValueError `plan_and_record` raises
when a paper-envelope is refused (account not paper) and printed it as a connectivity failure
("broker error: ... reachable? ... creds/gateway set?") — misleading for a deliberate safety
refusal. `execute_bybit` had no try/except at all, so the same refusal from `run_bybit_testnet`
surfaced as a raw traceback. Both commands now catch `ValueError` distinctly, print
"paper-envelope refused: <msg>", and exit 1 — same exit code and zero orders placed, just an
honest message.
- `_resolve_paper_envelope` silently fell back to the config default whenever the flag was <= 0.0,
so `--paper-envelope -5` looked identical to "unset" and hid an operator typo. A negative flag
now raises `typer.BadParameter` instead of falling through.
Extends test_cli_execute_helpers.py: the negative-envelope rejection, and two new tests (no live
broker — YahooDataProvider/AlpacaBroker faked, run_bybit_testnet faked) proving each command's
refuse path prints the distinct message and never reaches order placement.