The VRP exec twin previously opened a NEW full-envelope spread every run, overwriting the
single-slot book-state and never closing the prior one -- armed weekly it would stack N x
notional. plan_and_record_vrp now maintains a 5-rung ladder (mirrors VrpStrategy.advance):
closes rungs at 50% profit-take or DTE<=1 first, then opens at most one new rung sized at
envelope/ladder (never the full envelope) only when a slot is free. Ladder decisions are
factored into a pure, unit-tested plan_vrp_ladder helper.
Also: IbkrBroker.place_combo used the wrong parent-order action for a net-credit combo (SELL
with a negative limit); switched to BUY with a negative limit per IBKR's combo convention.
fxhnt-opra-backfill.yaml's git-sync cloned the feature branch instead of master (this Job is
applied manually post-merge). Added tests/unit/test_vrp_exec_helpers.py for the previously
untested pure P&L helpers (compute_spread_exec_return/compute_ladder_exec_return/build_pos_state).
Removed the dead --live flag from execute-vrp (plan_and_record_vrp never consulted allow_live;
the paper-envelope refusal guard is the real safety mechanism).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Freezes puts (spread band) + near-ATM calls (for the strategy's parity forward) into
xsp_option_bars, then recomputes the vrp track off the frozen table. _xsp_forward_estimate
uses min(sorted(...)) for cross-process determinism. Wires vrp_nav into the nightly job,
Definitions.assets, and cockpit_forward deps. (Controller committed after self-verifying:
subagent completed the work + augmentations but returned the malformed monitor-wait status.)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The brief's test supplied only 2 loss values but cvar_daily averages the worst
ceil(0.10*n) returns (5 slots at n=42), diluting CVaR with positives -> ratio 1.69
< 1.755, unsatisfiable. Rebuilt as a genuinely fat-left VRP-shaped series (45x +0.06,
5x -0.5 at n=50 -> cvar/std ~2.98). VrpStrategy code unchanged (was already correct).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds VrpStrategy.advance() recomputing the daily book entirely off frozen
xsp_option_bars rows (parity forward -> IV inversion -> ~20-delta short
strike, real-mark daily P&L / (n_open * margin)), plus the trading_days()
helper on XspOptionBarsRepo it depends on.
Known issue: test_fat_left_tail_triggers_cvar_floor is a pure-arithmetic
assertion independent of VrpStrategy; with the merged cvar_daily's
ceil(alpha*n) discrete tail count (n=42, alpha=0.10 -> n_tail=5), the given
2-loss-day series structurally cannot exceed the 1.755 threshold (max
achievable ratio ~1.694 by brute force). Left as-authored per no-silent-
change directive; needs a follow-up fix to the test's series shape or
threshold.
Whole-branch Important: dashboard showed the stale hardcoded ceiling while the engine sizes against
the resolved (paper $1M / live $35k) ceiling. Task-5 Minor: ruff I001 import-sort.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The 'combined' crypto-momentum book was retired; its legacy forward-tracking path is
now dead (the fxhnt-forward-cronjob was long since replaced by the Dagster deterministic
engine, and is already gone from the cluster). Removed: the 'forward-track' CLI command +
_FUTURES_UNIVERSE, the combined_book / combined_book_factory / combined_book_source
modules, CombinedBookStrategy + CombinedBookForwardTracker (KEEPING the load-bearing
ForwardTracker base used by the recompute engine + bybit tracks), the combined_book_*
config fields, and 5 combined-book-dedicated test files. MomentumVrpStrategy kept (a
tested strategy primitive, not a combined_book module).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The broad-Binance-universe momentum book (venue binance+glbx) was a survivorship/
microcap mirage superseded by the isolated crypto_tstrend edge + bybit_4edge. Removed
the combined_forward_nav Dagster asset (+ its cockpit_forward/paper_book_snapshot deps),
the registry entry (DB registry row auto-prunes via _seed_registry), the dashboard
headline preference, and the dead migration builder. CombinedBook modules retained
(still used by the forward-track CLI). Test fixtures repointed combined -> crypto_tstrend.
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.
Task 7 deleted tests/integration/test_bybit_testnet_job_wiring.py wholesale, taking with it the
regression tests for 4 named past bugs the ported `run_bybit_testnet` code still contains but was
left untested: unlock-tier misclassification on the bare-vs-USDT-suffixed symbol (FIX 1),
mean_timing_drift dividing by the wrong denominator when a fill has no book_mark (FIX 2), the
recorded fill ts using the record-step wall clock instead of the exchange fill time (FIX 3), and
the open-orders resting-guard not aborting placement (FIX 4) — plus the per-day NAV-marker
idempotency no-op and the normal-path fills+NAV happy path. Ports all of them onto
`run_bybit_testnet` directly (not the deleted Dagster assets), patching the module's own
`fxhnt.application.bybit_testnet_run` seams instead of `adapters.orchestration.assets`. Also adds
a new run-level test for the paper-envelope refuse (non-paper account + paper_envelope>0 raises
ValueError before any order is placed) — the case the CLI-level Minor fixes in the next commit
need to stay distinct from a connectivity error.
Deliberately does NOT port `test_job_exists_with_two_assets_and_not_in_combined` or
`test_schedule_registered_on_its_own_job_stopped` — those tested the deleted Dagster job/schedule
and their absence is already asserted in test_orchestration_definitions.py.
Adds two test cases:
1. Test that latest_testnet_nav() returns the most-recent row by run_date
2. Test that the Executed reality detail block renders with exec/modeled return figures
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds the per-edge lifecycle blocks (funding health, allocation, executed
reality) to the strategy detail page, plus a minimal latest_testnet_nav()
reader on BybitTestnetRepo to surface mean exec slippage for the bybit
executed twin.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Critical: a held symbol absent from PRIOR marks (rotated out of the crypto
universe then back in) was booking its FULL notional as P&L in
compute_crypto_exec_return, since a missing prior mark fell back to price 0.
Fix falls back to today's mark instead, so a missing prior mark yields 0 P&L
for that symbol this period. Also: document the accepted re-entry-day fee
gap, advance the funding cursor to the reconcile's funding-query timestamp
(no gap to the next period's funding_since), and strengthen the flatten
test to use a nonzero sleeve weight with equity=0, pinning that equity=0
alone flattens.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Task 5 review fixes: update the stale observed-track invariant pin (Task 3
added bybit_4edge_exec), move funding_since off the kill-switch dry-run
path so it doesn't make a wasted network call, and add unit coverage
proving plan_orders flattens a held position when equity=0 (de-funded/
killswitched edge).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
bybit_testnet_reconcile now sizes plan_orders to the B2a/B3 envelope
(min(current_allocation, equity)) instead of raw equity (prior commit).
These pre-existing fixtures never seeded a bybit_4edge allocation row, so
the envelope collapsed to 0 and 6 of these tests started asserting on a
flattened (zero-order) book. Seed an allocation well above the fake
equity by default so envelope == equity, preserving the sizing these
tests were written against.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace exact-match side check with case-insensitive comparison and explicit
ValueError on unrecognized fill side. Prevents silent misclassification of
differently-cased sides on a capital-accounting path.
- apply_fills now normalizes f["side"] to uppercase before checking
- Raises ValueError with fill side repr on unknown side (not BUY/SELL)
- Added test_apply_fills_case_insensitive_side: lowercase/mixed-case sides
- Added test_apply_fills_rejects_unknown_side: ValueError on garbage side
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>