feat: afterquote v1.0.0#5
Merged
Merged
Conversation
info() and pricing() now accept as_of: pd.Timestamp — resolves to now() when omitted. Enables backtest-safe historical reconstruction without look-ahead bias. Also fixes __get_schedule mutable default (was frozen at import time) and tightens is_exchange_open to schedule only the timestamp's own date. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
When base and underlying trade in different currencies, pricing() now fetches the FX rate (e.g. USDGBP=X for 3TSL.L/TSLA) and applies it as a 1x multiplicative leg alongside the leveraged underlying return. Decomposes FX into gap/intra via _candle_returns() — same structure as the underlying leg. Same-currency pairs (ccy_pair_yf=None) are unchanged. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
afterquote BASE UNDERLYING [--as-of TIMESTAMP] [--pricing] Defaults to info() summary; --pricing prints full synthetic OHLC bars. Wired up via [project.scripts] in pyproject.toml. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
portfolio_pnl(path, as_of=None) reads base/underlying/quantity columns, builds a SecurityPair per row, and returns per-position P&L plus a TOTAL row. pair_factory is injectable for testing. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
_fetch_history is a module-level lru_cache(maxsize=128) function keyed by ticker + start + end + interval. get_history on YFinanceSecurity is the injectable seam — fakes override it in tests. Explicit start/end windows are deterministic so safe to cache unconditionally. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
benchmark(pair, days=30) walks each base trading session, applies the leveraged+FX daily return to the prior close, and compares synth_open to the actual next open. Returns base_close, synth_open, actual_open, residual, direction_correct per session — NaN where the underlying had no data (e.g. US holidays) so gaps are visible rather than silently dropped. metrics(results) computes RMSE, MAE, direction_correct rate, tracking error over valid rows only. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
info(confidence=0.95) attaches lower_bound/upper_bound from the benchmark's empirical residual percentiles — no Gaussian assumption. Benchmark routed through get_history to ride the existing lru_cache. Fake security dispatches on interval so one pair runs both paths.
pair.correlation(days=90) returns Pearson daily-return correlation between base and underlying. Emits UserWarning when |corr| < 0.5. Standalone method — benchmark() and metrics() stay clean.
README adds confidence band, correlation, benchmark, holdings, CLI sections and demo pairs table. CHANGELOG [1.0.0] covers all 8 features. AGENTS.md bumps architecture from 3 to 7 modules.
Junaid2005
marked this pull request as ready for review
June 22, 2026 20:34
Owner
Author
|
Made with opencode and glm 5.2! (and sonnet for the first half) |
--confidence 0.95 attaches lower_bound/upper_bound to info output. --benchmark runs daily backtest and prints results + metrics summary.
…ample outputs Rewrites README to open with the concrete problem (LSE closes, TSLA keeps trading), documents all CLI flags, and shows real truncated output for every feature -- info(), pricing(), benchmark(), metrics(), correlation(), portfolio_pnl(). Numbers consistent with live test run (RMSE 74.1, direction hit-rate 71%, correlation 0.76). AGENTS.md CLI line updated to reflect --correlation, --holdings, and mutual exclusion. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
v1.0.0
Major feature release — point-in-time queries, cross-currency pricing, empirical validation, and uncertainty quantification.
Features
as_ofparameter —pricing()andinfo()accept point-in-time timestamps for historical queries. Fixes an import-time mutable default bug in__get_schedule.3TSL.L/TSLA) multiply in the FX return as a 1x leg alongside the leveraged underlying. GBp normalised to GBP.afterquote BASE UNDERLYING [--as-of] [--pricing]portfolio_pnl(path)reads CSV/JSON, returns per-position P&L + totallru_cache(128)on historical yfinance fetches (live paths bypass)benchmark(pair, days=90)daily backtest of synthetic vs actual next-day open.metrics()returns RMSE, MAE, direction hit-rate, tracking error.info(confidence=0.95)attacheslower_bound/upper_boundfrom empirical residual percentiles. No Gaussian assumption.pair.correlation(days=90)Pearson daily-return correlation, warns when|corr| < 0.5.Other
3TSL.L/TSLA(leverage + FX on one pair)requires-python>=3.8 → >=3.10(matches CI matrix)0.3.0 → 1.0.0Test plan
pytest tests/— 62 unit tests, no network, ~0.4spytest tests/ --runlive— 64 passed in 3.7safterquote 3TSL.L TSLA— CLI returns synthetic quoteafterquote 3TSL.L TSLA --as-of "2026-06-18 14:00:00-04:00"— historical query workspair.correlation(days=90)on3TSL.L/TSLA→ 0.76 (high, no warning)pair.info(confidence=0.95)→ attacheslower_bound/upper_boundbenchmark(pair, days=90)+metrics()→ RMSE 74.1, direction hit-rate 71%