diff --git a/.github/dependabot.yml b/.github/dependabot.yml index c7edbf1..c0c3f8f 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -8,15 +8,21 @@ updates: schedule: interval: monthly open-pull-requests-limit: 5 + cooldown: + default-days: 7 - package-ecosystem: github-actions directory: "/" schedule: interval: monthly open-pull-requests-limit: 5 + cooldown: + default-days: 7 - package-ecosystem: docker directory: "/" schedule: interval: monthly open-pull-requests-limit: 5 + cooldown: + default-days: 7 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f4d7006..60e39f1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,8 +10,54 @@ on: branches: [main] jobs: + test-fast: + # Fast feedback: unit tests and light orchestration tests only (`slow` + # deselected). Runs in parallel with `test` below rather than blocking + # on it, so a regression in the common-case code paths surfaces well + # before the slow, walk-forward-heavy suite finishes. No coverage gate + # here -- `test` already enforces it over the full suite; gating on + # this narrower subset alone would risk a spurious failure merely + # because the slow tests are the ones that exercise most of + # `quantlab.validation`. + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest] + python-version: ["3.12", "3.13"] + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + + - name: Install uv + uses: astral-sh/setup-uv@ae62891fec2bb8e7d6c99fc78c9fec3a63790f8d # v10.0.0 + with: + version: "0.12.3" + + - name: Set up Python ${{ matrix.python-version }} + run: uv python install ${{ matrix.python-version }} + + - name: Install dependencies (locked) + run: >- + uv sync --locked --python ${{ matrix.python-version }} + --extra dev --extra dashboard --extra yahoo --extra docs + --extra notebooks + + - name: Lint (ruff) + run: | + uv run ruff check src tests scripts + uv run ruff format --check src tests scripts + + - name: Type-check (mypy) + run: uv run mypy src tests scripts + + - name: Test (fast offline suite) + run: uv run pytest -m "not network and not slow" + test: - # Exercise both supported Python versions on Linux and Windows. + # The authoritative, coverage-gated run: the full offline suite, + # `slow` included (real multi-fold walk-forward selection, + # multi-invocation CLI scenarios, ...). Exercise both supported Python + # versions on Linux and Windows. runs-on: ${{ matrix.os }} strategy: fail-fast: false @@ -19,10 +65,10 @@ jobs: os: [ubuntu-latest, windows-latest] python-version: ["3.12", "3.13"] steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - name: Install uv - uses: astral-sh/setup-uv@v10.0.0 + uses: astral-sh/setup-uv@ae62891fec2bb8e7d6c99fc78c9fec3a63790f8d # v10.0.0 with: version: "0.12.3" @@ -43,7 +89,7 @@ jobs: - name: Type-check (mypy) run: uv run mypy src tests scripts - - name: Test (offline suite, with coverage) + - name: Test (full offline suite, with coverage) run: >- uv run pytest -m "not network" --cov=quantlab --cov-report=term-missing --cov-report=xml --cov-fail-under=82 @@ -59,10 +105,10 @@ jobs: os: [ubuntu-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - name: Install uv - uses: astral-sh/setup-uv@v10.0.0 + uses: astral-sh/setup-uv@ae62891fec2bb8e7d6c99fc78c9fec3a63790f8d # v10.0.0 with: version: "0.12.3" diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml index 8290dd6..e695ad5 100644 --- a/.github/workflows/semgrep.yml +++ b/.github/workflows/semgrep.yml @@ -5,8 +5,6 @@ on: branches: - main - master - paths: - - .github/workflows/semgrep.yml schedule: # random HH:MM to avoid a load spike on GitHub Actions at 00:00 - cron: 34 7 * * * @@ -17,10 +15,15 @@ jobs: runs-on: ubuntu-latest permissions: contents: read - env: - SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }} container: image: semgrep/semgrep steps: - - uses: actions/checkout@v6 - - run: semgrep ci + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 + # Standalone mode (no Semgrep AppSec Platform connection, no + # SEMGREP_APP_TOKEN): `semgrep ci` requires that token to actually be + # configured as a repo secret, and fails outright for a fork PR or a + # Dependabot PR either way (GitHub withholds secrets from both for + # security). `p/ci` is the same ruleset pre-commit's own semgrep hook + # already runs locally (see .pre-commit-config.yaml), so CI enforces + # exactly what a contributor's pre-commit run already checked. + - run: semgrep scan --config p/ci --error --skip-unknown-extensions . diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6a5d0db..421b8cc 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,6 +7,13 @@ repos: - id: trailing-whitespace - id: end-of-file-fixer - id: check-yaml + # mkdocs.yml uses MkDocs' own YAML tags (e.g. !!python/name:... for + # markdown extension config) that a plain, generic YAML loader + # can't construct -- check-yaml's default safe_load rejects it even + # though the file is valid MkDocs config; `mkdocs build --strict` + # already validates it with the loader that actually understands + # those tags. + exclude: ^mkdocs\.yml$ - id: check-toml - id: check-added-large-files args: ["--maxkb=1024"] @@ -15,12 +22,23 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit # Keep aligned with the Ruff version pinned in uv.lock and used by CI. - rev: v0.16.1 + rev: v0.16.2 hooks: - id: ruff args: ["--fix"] - id: ruff-format + - repo: https://github.com/semgrep/pre-commit + rev: v1.173.0 + hooks: + - id: semgrep + # p/ci is the Semgrep-recommended starting ruleset for pre-commit/CI: + # broader packs like p/security-audit surface more findings but also + # more noise. --error makes matches fail the hook instead of only + # warning; --skip-unknown-extensions leaves non-code files (YAML + # configs, notebooks) alone. + args: ["--config", "p/ci", "--error", "--skip-unknown-extensions"] + - repo: local hooks: - id: mypy diff --git a/README.md b/README.md index ff8881c..e3d902d 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,9 @@ sensitivity and bootstrap. > results. The goal is **not** to claim a profitable strategy. It is to demonstrate a -rigorous, reproducible research process with no information leakage. +rigorous, reproducible research process, designed to prevent common +look-ahead leakage through delayed execution. Custom strategies remain +responsible for causal feature and signal construction. --- @@ -27,9 +29,12 @@ rigorous, reproducible research process with no information leakage. interface. - **Realistic costs** — explicit commission, spread and (constant or volume-based) slippage; every result reports **gross vs net**. -- **Look-ahead-safe engine** — signals are strictly shifted before returns; the - separation between *signal at t*, *position at t+1* and *realised return* is - enforced and unit-tested. +- **Delayed-execution barrier** — signals are strictly shifted before returns; + the separation between *signal at t*, *position at t+1* and *realised + return* is enforced and unit-tested. This prevents the common look-ahead + leak of acting on a signal the same period it was formed — a custom + strategy that reads future rows directly remains responsible for its own + causal construction. - **Risk analytics** — Sharpe, Sortino, Calmar, max drawdown, VaR/CVaR, exposures, benchmark alpha/beta, and more, implemented from first principles. - **Walk-forward validation** — expanding/rolling windows, parameter selection @@ -141,14 +146,39 @@ already covers the requested period. ## Command-line interface ```bash -quantlab download --config configs/momentum_sp500.yaml -quantlab backtest --config configs/momentum_sp500.yaml -quantlab walk-forward --config configs/momentum_sp500.yaml -quantlab report --experiment cross_sectional_momentum_etfs +quantlab download --config configs/momentum_sp500.yaml +quantlab backtest --config configs/momentum_sp500.yaml +quantlab walk-forward --config configs/momentum_sp500.yaml +quantlab stress-test --config configs/momentum_sp500.yaml +quantlab bootstrap --config configs/momentum_sp500.yaml +quantlab permutation-test --config configs/momentum_sp500.yaml +quantlab sensitivity --config configs/momentum_sp500.yaml +quantlab robustness --config configs/momentum_sp500.yaml +quantlab report --experiment cross_sectional_momentum_etfs quantlab dashboard quantlab --help ``` +`stress-test`/`bootstrap`/`permutation-test`/`sensitivity` each run one +robustness technique (with a matching `--n-iterations`/`--block-size`/ +`--param-x` etc. override); `robustness` runs every technique enabled under +a config's `robustness:` block in one pass. All five branch on +`validation.method`: with `walk_forward`, each starts from the same +walk-forward-stitched out-of-sample result rather than a single backtest, so +the evidence never silently comes from a different validation method than +the one configured. `stress-test` and `sensitivity` re-run the whole +walk-forward selection process per scenario/candidate, since each one +represents a different cost/methodology assumption or parameter to +re-optimise under. `bootstrap` and `permutation-test` do not: they resample +or permute the walk-forward's already-realised out-of-sample return series +statistically, without re-running the selection process itself. + +`walk-forward`, `stress-test`, `sensitivity` and `robustness` show a live +progress bar with an ETA in the terminal, and checkpoint their progress to +disk as they go — an interruption (Ctrl+C, a crash, closing the terminal) +resumes automatically on the next matching run instead of starting over. +Pass `--fresh` to discard a checkpoint and start clean. + Each backtest, walk-forward or report run writes a structured artefact folder under the generated-reports directory. In a source checkout this is `reports/generated//`; after a regular package installation it is @@ -183,6 +213,18 @@ Regenerate them (after `quantlab download` for each config) with streamlit run src/quantlab/dashboard/app.py ``` +A **Backtest** / **Walk-forward** mode switch sits above the sidebar. +Walk-forward mode runs the same train/validation/test parameter selection as +`quantlab walk-forward`, with its own sidebar (windows, expanding mode, +optimization metric, parameter-grid picker) and Results/Trades/Robustness/ +Report tabs built from the stitched out-of-sample result, driven by a live +progress bar with an ETA while a run is in flight. Both modes' Robustness +tab includes stress tests, block bootstrap, a Monte Carlo permutation test +and a 2-parameter sensitivity heatmap, +individually or via "Run all robustness tests" — in Walk-forward mode, +stress tests and sensitivity re-run the whole selection process per +scenario/cell rather than a single backtest. + ![QuantLab dashboard results](reports/figures/dashboard_results.png)
diff --git a/configs/btc_trend.yaml b/configs/btc_trend.yaml index 2f234b3..1115e17 100644 --- a/configs/btc_trend.yaml +++ b/configs/btc_trend.yaml @@ -3,9 +3,10 @@ experiment_name: btc_trend_following data: - source: binance - symbols: - - BTCUSDT + instruments: + - symbol: BTCUSDT + source: binance + calendar: "24/7" start_date: "2018-01-01" end_date: "2025-12-31" frequency: "1d" @@ -34,7 +35,10 @@ execution: backtest: initial_capital: 100000 - benchmark_symbol: BTCUSDT + benchmark: + symbol: BTCUSDT + source: binance + calendar: "24/7" risk_free_rate: 0.0 periods_per_year: 365 # crypto trades every calendar day @@ -45,3 +49,20 @@ validation: reproducibility: random_seed: 42 + +# `quantlab stress-test|bootstrap|permutation-test|sensitivity --config +# configs/btc_trend.yaml` each run one technique regardless of `enabled` +# below (only the `robustness` orchestrator reads it). validation.method is +# holdout above, so every technique here evaluates a single plain backtest. +robustness: + stress_test: + enabled: true + bootstrap: + enabled: true + permutation_test: + enabled: true + sensitivity: + enabled: true + parameters: + fast_window: [10, 20, 40] + slow_window: [50, 100, 200] diff --git a/configs/default.yaml b/configs/default.yaml index f565cff..11be7e1 100644 --- a/configs/default.yaml +++ b/configs/default.yaml @@ -3,10 +3,13 @@ experiment_name: default_buy_and_hold data: - source: yahoo - symbols: - - SPY - - QQQ + instruments: + - symbol: SPY + source: yahoo + calendar: XNYS + - symbol: QQQ + source: yahoo + calendar: XNYS start_date: "2015-01-01" end_date: "2024-12-31" frequency: "1d" @@ -31,8 +34,12 @@ backtest: initial_capital: 100000 # symbol | equal_weight | first_asset | cash benchmark_kind: symbol - # Used only by the symbol benchmark. - benchmark_symbol: SPY + # Used only by the symbol benchmark. Matches the SPY instrument above + # exactly (same source/calendar), so its already-loaded data is reused. + benchmark: + symbol: SPY + source: yahoo + calendar: XNYS risk_free_rate: 0.0 periods_per_year: 252 @@ -43,3 +50,15 @@ validation: reproducibility: random_seed: 42 + +# `quantlab stress-test|bootstrap|permutation-test --config +# configs/default.yaml` each run regardless of `enabled` below (only the +# `robustness` orchestrator reads it). No `sensitivity` block: buy_and_hold +# has no strategy parameters to sweep. +robustness: + stress_test: + enabled: true + bootstrap: + enabled: true + permutation_test: + enabled: true diff --git a/configs/demo_offline.yaml b/configs/demo_offline.yaml index 8be7a5f..5e22f60 100644 --- a/configs/demo_offline.yaml +++ b/configs/demo_offline.yaml @@ -4,18 +4,24 @@ experiment_name: demo_offline_momentum data: - source: csv - symbols: - - SPY - - QQQ - - TLT - - GLD + # The synthetic symbols model US equity ETFs. + instruments: + - symbol: SPY + source: csv + calendar: XNYS + - symbol: QQQ + source: csv + calendar: XNYS + - symbol: TLT + source: csv + calendar: XNYS + - symbol: GLD + source: csv + calendar: XNYS start_date: "2019-01-01" end_date: "2023-10-30" frequency: "1d" missing_value_policy: "drop" - # The synthetic symbols model US equity ETFs. - market_calendar: XNYS # Allow the installed package to use its bundled synthetic demo files. use_bundled_demo_data: true @@ -46,7 +52,10 @@ execution: backtest: initial_capital: 100000 - benchmark_symbol: SPY + benchmark: + symbol: SPY + source: csv + calendar: XNYS risk_free_rate: 0.02 periods_per_year: 252 @@ -60,3 +69,23 @@ validation: reproducibility: random_seed: 42 + +# `quantlab stress-test|bootstrap|permutation-test|sensitivity --shipped-config +# demo_offline` each run one technique regardless of `enabled` below (only +# the `robustness` orchestrator reads it). Since validation.method is +# walk_forward above, stress-test and sensitivity re-run the whole +# walk-forward process per scenario/cell (slower, still fast offline on +# this small bundled dataset); bootstrap and permutation-test just resample +# the already-realised OOS returns. +robustness: + stress_test: + enabled: true + bootstrap: + enabled: true + permutation_test: + enabled: true + sensitivity: + enabled: true + parameters: + lookback_period: [126, 189, 252] + top_fraction: [0.25, 0.50] diff --git a/configs/mean_reversion_etfs.yaml b/configs/mean_reversion_etfs.yaml index 1513668..c233618 100644 --- a/configs/mean_reversion_etfs.yaml +++ b/configs/mean_reversion_etfs.yaml @@ -4,13 +4,22 @@ experiment_name: mean_reversion_etfs data: - source: yahoo - symbols: - - SPY - - QQQ - - IWM - - EFA - - EEM + instruments: + - symbol: SPY + source: yahoo + calendar: XNYS + - symbol: QQQ + source: yahoo + calendar: XNYS + - symbol: IWM + source: yahoo + calendar: XNYS + - symbol: EFA + source: yahoo + calendar: XNYS + - symbol: EEM + source: yahoo + calendar: XNYS start_date: "2010-01-01" end_date: "2025-12-31" frequency: "1d" @@ -38,7 +47,10 @@ execution: backtest: initial_capital: 100000 - benchmark_symbol: SPY + benchmark: + symbol: SPY + source: yahoo + calendar: XNYS risk_free_rate: 0.02 periods_per_year: 252 @@ -49,3 +61,16 @@ validation: reproducibility: random_seed: 42 + +robustness: + stress_test: + enabled: true + bootstrap: + enabled: true + permutation_test: + enabled: true + sensitivity: + enabled: true + parameters: + lookback_period: [10, 20, 40] + entry_zscore: [1.5, 2.0, 2.5] diff --git a/configs/momentum_sp500.yaml b/configs/momentum_sp500.yaml index fd62051..70f3c01 100644 --- a/configs/momentum_sp500.yaml +++ b/configs/momentum_sp500.yaml @@ -7,16 +7,31 @@ experiment_name: cross_sectional_momentum_etfs data: - source: yahoo - symbols: - - SPY # US large cap - - QQQ # US tech / Nasdaq 100 - - IWM # US small cap - - EFA # Developed ex-US - - EEM # Emerging markets - - TLT # Long US treasuries - - GLD # Gold - - VNQ # US real estate + instruments: + - symbol: SPY # US large cap + source: yahoo + calendar: XNYS + - symbol: QQQ # US tech / Nasdaq 100 + source: yahoo + calendar: XNYS + - symbol: IWM # US small cap + source: yahoo + calendar: XNYS + - symbol: EFA # Developed ex-US + source: yahoo + calendar: XNYS + - symbol: EEM # Emerging markets + source: yahoo + calendar: XNYS + - symbol: TLT # Long US treasuries + source: yahoo + calendar: XNYS + - symbol: GLD # Gold + source: yahoo + calendar: XNYS + - symbol: VNQ # US real estate + source: yahoo + calendar: XNYS start_date: "2008-01-01" end_date: "2025-12-31" frequency: "1d" @@ -50,7 +65,10 @@ execution: backtest: initial_capital: 100000 - benchmark_symbol: SPY + benchmark: + symbol: SPY + source: yahoo + calendar: XNYS risk_free_rate: 0.02 periods_per_year: 252 @@ -69,3 +87,21 @@ validation: reproducibility: random_seed: 42 + +robustness: + stress_test: + enabled: true + bootstrap: + enabled: true + n_iterations: 1000 + block_size: 5 + permutation_test: + enabled: true + n_iterations: 1000 + sensitivity: + enabled: true + # Signal timing vs selection breadth — distinct from the walk-forward + # grid above (lookback_period/skip_period), not a repeat of it. + parameters: + lookback_period: [126, 189, 252] + top_fraction: [0.10, 0.25, 0.50] diff --git a/configs/pairs_trading.yaml b/configs/pairs_trading.yaml index 91d52ab..3d0c587 100644 --- a/configs/pairs_trading.yaml +++ b/configs/pairs_trading.yaml @@ -4,10 +4,13 @@ experiment_name: pairs_trading_ewa_ewc data: - source: yahoo - symbols: - - EWA - - EWC + instruments: + - symbol: EWA + source: yahoo + calendar: XNYS + - symbol: EWC + source: yahoo + calendar: XNYS start_date: "2010-01-01" end_date: "2025-12-31" frequency: "1d" @@ -39,7 +42,11 @@ execution: backtest: initial_capital: 100000 - benchmark_symbol: SPY + # SPY is external here (not a tradable instrument above). + benchmark: + symbol: SPY + source: yahoo + calendar: XNYS risk_free_rate: 0.02 periods_per_year: 252 @@ -50,3 +57,16 @@ validation: reproducibility: random_seed: 42 + +robustness: + stress_test: + enabled: true + bootstrap: + enabled: true + permutation_test: + enabled: true + sensitivity: + enabled: true + parameters: + formation_window: [126, 252, 504] + zscore_window: [21, 63, 126] diff --git a/docs/architecture.md b/docs/architecture.md index 37883de..f57145d 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -56,9 +56,16 @@ src/quantlab/ costs or accounting. - **The execution model computes costs** from weight *changes*, independent of which strategy or allocator produced them. -- **The backtest engine is the only place** where signals, weights, costs and - returns are combined — and it does so in one fixed order, with the - weight-shift step as a hard, tested barrier against look-ahead bias. +- **Signals, weights, costs and returns are combined in one fixed order**, + with the weight-shift step as a hard, tested barrier against look-ahead + bias. `BacktestEngine.run()` is that assembly for a single backtest. + `WalkForwardValidator._build_oos_result()` (`quantlab.validation. + walk_forward`) independently assembles the same stitched-OOS-series case, + reusing the same underlying accounting/trade-log/benchmark/metrics + functions in the same order rather than calling `BacktestEngine.run()` + itself — a fix that touches how that assembly step works (e.g. which + execution-model fields the trade log or metadata reads) currently needs + applying at both call sites, not one shared entry point. ## Data flow shapes diff --git a/docs/backtesting.md b/docs/backtesting.md index 64af105..ed2b8b3 100644 --- a/docs/backtesting.md +++ b/docs/backtesting.md @@ -79,3 +79,26 @@ rebalance dates (daily / weekly / monthly / quarterly) and holds it constant between them — trades, and therefore costs, only occur at rebalances. Turnover is `sum(|held_t - held_{t-1}|)` (`w_{-1} = 0`), directly matching the manual example of capital 100k, turnover 0.5, 10 bps → cost 50. + +For a mixed-calendar portfolio, `rebalance_and_cap_turnover` is +tradability-aware: a closed instrument (per its own calendar, see +[Data pipeline](data_pipeline.md#verified-closures-vs-missing-data)) never +trades on a closed date, and its rebalance target becomes a pending debt that +keeps retrying — at every following tradable session, not only the next +scheduled rebalance — until fully executed, even if `maximum_turnover` spreads +that execution across several sessions. Portfolio constraints (gross/net +exposure, max weight, long-only) are enforced on the actually-executed +holdings after accounting for frozen/closed instruments, not just on the +theoretical fully-open target, since freezing one instrument while others move +can push the real portfolio out of its mandate even when the target was +compliant. For a single-calendar experiment this machinery is a proven no-op: +behaviour is byte-identical to the plain rebalance/turnover-cap path above. + +`rebalance_and_cap_turnover`'s output — including a pending target resolving +there on a reopening day — is still only a *decision*, dated that day. Every +decision, on a reopening day or an ordinary rebalance date alike, is subject +to the same one-period (tradability-respecting) look-ahead shift applied by +the accounting layer before it affects executed weights, turnover or costs — +a target that resolves in `held_weights` on a symbol's reopening day therefore +does not reach the accounting layer until that symbol's *next* tradable +session, not the reopening day itself. diff --git a/docs/data_pipeline.md b/docs/data_pipeline.md index 1208d7b..7542851 100644 --- a/docs/data_pipeline.md +++ b/docs/data_pipeline.md @@ -20,29 +20,82 @@ assumed to already represent UTC and are not shifted. `DataQualityReport` (duplicates, missing values, invalid prices, OHLC consistency, coverage gaps). +## Instruments + +`DataConfig.instruments` is a list of `InstrumentConfig` entries +(`symbol`/`source`/`calendar`), each fully explicit — no global source or +calendar for the whole experiment. A single portfolio can freely mix sources +and calendars, e.g. US equities from Yahoo (`XNYS`) alongside crypto from +Binance (`24/7`). `ExperimentConfig.benchmark` is itself an `InstrumentConfig`; +if its symbol duplicates a tradable instrument it must match that instrument's +source/calendar exactly and is never re-downloaded, and it never contaminates +the tradable universe's own timeline (an external 24/7 benchmark cannot inject +synthetic weekend bars into an all-equities portfolio). + ## Sources -- **Yahoo Finance** (`quantlab.data.yahoo.YahooFinanceDataSource`) — Yahoo - tickers on either the XNYS or 24/7 calendar. Adjusted close is retained when - Yahoo supplies it; a warning is logged when raw close must be used instead. +- **Yahoo Finance** (`quantlab.data.yahoo.YahooFinanceDataSource`) — Adjusted + close is retained when Yahoo supplies it; a warning is logged when raw close + must be used instead. - **Binance** (`quantlab.data.binance.BinanceDataSource`) — crypto OHLCV, handles the 1000-candle pagination limit and 429 rate-limit backoff. No - corporate actions, so `adjusted_close == close`. -- **CSV** (`source: csv` in a config) — reads `data/raw/.csv`, already - in canonical schema. Used for fully offline experiments and tests. + corporate actions, so `adjusted_close == close`. Always `calendar: "24/7"`. +- **CSV** (`source: csv` on an instrument) — reads `data/raw/.csv`, + already in canonical schema. Used for fully offline experiments and tests; + neutral with respect to frequency compatibility (its real frequency is only + known after reading the file, checked by `DataValidator` post-load). + +## Verified closures vs. missing data + +A verified closure — a date that is a non-session day on an instrument's own +calendar (`quantlab.data.calendar.is_session_day`) — is distinguished from +genuinely missing data. `quantlab.data.closures.insert_verified_closure_bars` +fills a closed instrument with a flat synthetic bar (open/high/low/close and +adjusted_close each carried forward independently from the last known value, +volume forced to zero) whenever another instrument in the same tradable +universe has a real bar that day, so return is exactly zero and the instrument +is excluded from that day's rebalancing (see +[Backtesting](backtesting.md#rebalancing-turnover) for the tradability-aware execution +side). This is a no-op for a single-calendar experiment and for non-daily +frequencies. A gap that is *not* a calendar closure (e.g. a genuinely missing +trading day) is governed entirely by `missing_value_policy`, as below — but, +unlike a closure, it is never assumed to have zero return; the policy decides +whether it's rejected, dropped, or filled. ## Cleaning -`DataCleaner` never silently fills every gap. The missing-value policy is -always explicit, from the config: +The missing-value policy is always explicit, from the config, and applies at +two levels — a missing *value* inside an existing row, and a (date, symbol) +combination with *no row at all* for a real trading session are structurally +different problems, handled by different code with the same policy: + +- `DataCleaner` (`quantlab.data.cleaner`) handles a missing value inside a row + that exists. +- `DataLoader.load()` separately applies the identical policy to a genuine + gap — a real session, on a symbol's own calendar, with no row whatsoever + (`quantlab.data.loader._apply_missing_value_policy_to_genuine_gaps`), + scoped to the tradable universe only (an external benchmark's own gaps are + its own concern). Left ungoverned, such a gap would silently produce an + incomplete panel — caught only later, confusingly, by the backtest engine's + "asset return missing while held" error. + +Both levels honour the same four policies: -- `drop` — remove rows with any missing price. +- `drop` — remove rows with any missing price; for a genuine gap, remove the + *entire date* from the tradable universe (every symbol, not just the one + missing), so the resulting panel stays dense. - `forward_fill` — carry prices forward within each symbol, never backward, - for at most `data.forward_fill_limit` consecutive bars (default: one). - Any unresolved or newly OHLC-inconsistent row is dropped. + for at most `data.forward_fill_limit` consecutive bars (default: one). For + a genuine gap, a filled row is synthetic and flat (open/high/low/close and + adjusted_close carried forward independently, volume forced to zero — the + same shape as a verified-closure bar, but this is not one: it still counts + toward the fill limit and is not exempt from rebalancing). Any unresolved + or newly OHLC-inconsistent row, or a date where the fill limit is + exceeded, is dropped the same way as under `drop`. - `raise` — fail if any canonical field is missing, including volume, - timestamp, or symbol. -- `none` — leave gaps for the caller to handle. + timestamp, or symbol; for a genuine gap, fail at load time naming the + affected (date, symbol) pairs, rather than later inside the engine. +- `none` — leave gaps for the caller to handle, at both levels. ## Storage @@ -52,9 +105,11 @@ checks. Remote gaps or forced refreshes are downloaded and merged. `DataLoader.load()` is the entry point used by the CLI and dashboard: download-or-cache → discard bars that have not settled → slice to the requested -range → inspect raw defects → clean → validate the final frame. Slicing before -forward filling prevents extra history in a wider cache from changing the -first requested observation. +range → inspect raw defects → clean → validate the final frame → insert +verified-closure bars → apply `missing_value_policy` to any remaining genuine +gap → trim to the tradable universe's common start/end coverage. Slicing +before forward filling prevents extra history in a wider cache from changing +the first requested observation. ## Universes diff --git a/docs/index.md b/docs/index.md index 882af00..f91a37c 100644 --- a/docs/index.md +++ b/docs/index.md @@ -4,9 +4,11 @@ QuantLab turns a financial hypothesis into a reproducible, bias-aware experiment: download data, clean and validate it, build features and signals, run a -look-ahead-safe vectorised backtest with realistic costs, measure performance -and risk, validate out-of-sample, and generate an honest research report — all -driven by one YAML config. +vectorised backtest — with a delayed-execution barrier that prevents common +look-ahead leakage — with realistic costs, measure performance and risk, +validate out-of-sample, and generate an honest research report — all driven +by one YAML config. Custom strategies remain responsible for their own causal +feature and signal construction. > This project is for **educational and research purposes only**. It is not > investment advice, and historical performance does not guarantee future diff --git a/docs/limitations.md b/docs/limitations.md index 3487f22..22303e1 100644 --- a/docs/limitations.md +++ b/docs/limitations.md @@ -15,12 +15,47 @@ result. them implicitly assume today's constituents existed throughout the period, which can overstate results. - **Single venue** for crypto data (Binance): no consolidated tape. -- **One market calendar per experiment**: Yahoo experiments must choose either - the XNYS approximation (for US-listed equities and ETFs) or the 24/7 calendar - (for continuously traded instruments such as crypto). Binance uses 24/7. - Futures, foreign exchanges and instruments with other trading schedules are - not modelled accurately by either choice, and mixed-calendar universes are - not supported. +- **Per-instrument calendars are an approximation, not a live feed**: each + instrument declares its own source and calendar (any name recognised by + `pandas_market_calendars`, or `24/7`), and a mixed-calendar portfolio (e.g. + US equities alongside crypto) is supported at daily frequency — closed + sessions are detected per symbol, valued at the last known price with zero + return and zero volume, and never traded. Weekly/monthly bucket settlement + and Yahoo's daily timestamps resolve against each instrument's own + calendar rather than a UTC-midnight approximation — but weekly/monthly + **rebalancing** only does so when every instrument in the portfolio shares + one calendar; a genuinely mixed-calendar portfolio (e.g. equities + alongside crypto) still buckets rebalance dates against the raw UTC + boundary, the same documented approximation used elsewhere for a + mixed-calendar universe. This coverage is deliberately narrower than "fully + supported" for two reasons: it does not extend to every calendar detail + (e.g. an official intraday session break, like XHKG's lunch recess, is + handled for hourly cache-coverage and gap-detection checks but not modelled + anywhere else), and it has not been exercised against every calendar + `pandas_market_calendars` recognises — only the ones this project's own + test suite covers (XNYS, XHKG, XASX, XSAU, 24/7). But the calendar is + still a static, + best-effort schedule (holidays, weekends), not a real-time venue-status + feed, so an unscheduled closure (an exchange halt, an outage) is not + detected as a closure and instead falls under the ordinary + `missing_value_policy` handling for gaps. Intraday (`1h`) frequency does + not support mixed calendars at all yet and is rejected at config load — + verified-closure handling only operates at daily frequency. +- **Rolling-window features are diluted in a mixed-calendar universe**: a + verified closure's synthetic bar is exactly flat (zero return, zero + volume), but momentum lookbacks, volatility windows, ADV windows and + technical indicators all still count it as one more *period* — for a + session-bound instrument sharing a combined timeline with an always-open + one (e.g. equities alongside crypto), a "252-period" window therefore spans + *more* than 252 real trading sessions, and the flat bars pull volatility/ADV + estimates down. QuantLab warns about this at config load + (`DataConfig._warn_if_mixed_calendars_dilute_windowed_features`) but does + not correct it: doing so properly would mean computing every instrument's + features on its own native calendar before aligning signals, a + substantially larger redesign than today's shared-timeline architecture. + Prefer a single shared calendar per experiment when window-based estimates + need to be precise; treat mixed-calendar results as directionally + informative rather than exact until this is addressed. ## Execution @@ -49,13 +84,24 @@ result. - **Historical results are not predictive**. Positive backtests, walk-forward, bootstrap and stress-test outcomes describe the past under stated assumptions; they do not guarantee future performance. -- **Long calculations are not checkpointed**: interrupting walk-forward, - sensitivity, bootstrap, permutation or stress analysis requires restarting - that calculation. Downloaded market data remain reusable through the cache. -- **Interface scope differs**: the dashboard currently exposes holdout and - stress analysis, while walk-forward, sensitivity, bootstrap and permutation - are available through the CLI, notebooks or Python API as documented in the - validation guide. +- **Checkpointing covers fold-level progress, not every stage**: the CLI's + `walk-forward`, `stress-test` and `sensitivity` commands persist progress + after each completed fold, scenario block or grid cell (never a partially + computed one) so an interrupted run resumes instead of restarting from + scratch, gated on the run's config/data/code/dependency provenance still + matching. Checkpoint files are pickle and trusted-local-file-only (see + `quantlab.validation.checkpoint`) — never point one at a file from an + untrusted source. Downloaded market data remain separately reusable + through the cache regardless. +- **Interface scope**: the dashboard's Backtest mode covers a plain backtest, + chronological holdout, bootstrap, permutation test and sensitivity; + Walk-forward mode covers walk-forward validation itself plus its own + walk-forward-OOS-aware stress tests and sensitivity, and also exposes + bootstrap and permutation test — mode-agnostic techniques that resample + already-realised returns rather than re-running selection, so the same + functions apply directly to the walk-forward OOS series. The Python API and + notebooks expose the same underlying functions directly for anything the + dashboard doesn't surface. ## Reproducibility diff --git a/docs/validation.md b/docs/validation.md index fb37bbf..0b1e7b7 100644 --- a/docs/validation.md +++ b/docs/validation.md @@ -19,11 +19,16 @@ strategy and its parameters were fixed without consulting that block. `WalkForwardValidator.run(data, parameter_grid, train_window, validation_window, test_window, expanding=True)` performs these steps: -1. Evaluate candidate parameters on each validation block. +1. Evaluate candidate parameters on each validation block -- each candidate is + its own fresh backtest, restarted from cash on that block alone, not + chained to any other candidate or fold. 2. Select the best finite score using `validation.optimization_metric`. 3. Apply that choice to the untouched test block. -4. Preserve portfolio, turnover and accounting state across fold boundaries. -5. Stitch all test returns into one OOS curve. +4. Stitch every fold's test-block returns into one continuous OOS curve, + preserving portfolio, turnover and accounting state *across fold + boundaries only* -- the OOS curve is one simulated run, but candidate + selection within a fold never sees that chained state. +5. Report the stitched OOS curve as `WalkForwardResult.oos_result`. The Python API accepts an explicit `parameter_grid`. A YAML experiment can set the same candidates under `validation.parameter_grid`. The CLI and momentum @@ -59,7 +64,16 @@ quantlab walk-forward --config configs/momentum_sp500.yaml ``` This writes the walk-forward CSV artefacts and incorporates compatible evidence -into the generated HTML report. +into the generated HTML report. Progress (and an ETA) is shown live in the +terminal or dashboard while it runs. An interruption (Ctrl+C, a crash, closing +the terminal) is resumed automatically the next time the same command runs +against the same experiment, config, data and code — only *completed* folds +are skipped; whichever fold was still in progress at the moment of +interruption is discarded and recomputed from its start, not resumed +mid-fold. Pass `--fresh` to discard all saved progress and start over +instead. +The same applies to `stress-test`, `sensitivity` and `robustness` in +walk-forward mode. ## Parameter sensitivity diff --git a/notebooks/01_data_quality.ipynb b/notebooks/01_data_quality.ipynb index 6c8caa5..6346ba6 100644 --- a/notebooks/01_data_quality.ipynb +++ b/notebooks/01_data_quality.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "71804c70", + "id": "40a6f9df", "metadata": {}, "source": [ "# 01 — Data Quality\n", @@ -19,13 +19,13 @@ { "cell_type": "code", "execution_count": 1, - "id": "c4092783", + "id": "57a8a355", "metadata": { "execution": { - "iopub.execute_input": "2026-08-17T13:34:52.601121Z", - "iopub.status.busy": "2026-08-17T13:34:52.600643Z", - "iopub.status.idle": "2026-08-17T13:34:57.984116Z", - "shell.execute_reply": "2026-08-17T13:34:57.982002Z" + "iopub.execute_input": "2026-08-25T17:00:15.680817Z", + "iopub.status.busy": "2026-08-25T17:00:15.680451Z", + "iopub.status.idle": "2026-08-25T17:00:17.783976Z", + "shell.execute_reply": "2026-08-25T17:00:17.783093Z" } }, "outputs": [ @@ -58,13 +58,13 @@ { "cell_type": "code", "execution_count": 2, - "id": "f6db82df", + "id": "fe90d389", "metadata": { "execution": { - "iopub.execute_input": "2026-08-17T13:34:57.989233Z", - "iopub.status.busy": "2026-08-17T13:34:57.988513Z", - "iopub.status.idle": "2026-08-17T13:35:24.000963Z", - "shell.execute_reply": "2026-08-17T13:35:23.998652Z" + "iopub.execute_input": "2026-08-25T17:00:17.786816Z", + "iopub.status.busy": "2026-08-25T17:00:17.786432Z", + "iopub.status.idle": "2026-08-25T17:00:32.406673Z", + "shell.execute_reply": "2026-08-25T17:00:32.405717Z" } }, "outputs": [ @@ -85,7 +85,7 @@ }, { "cell_type": "markdown", - "id": "78c2d8c4", + "id": "90b5bd90", "metadata": {}, "source": [ "## Coverage per symbol" @@ -94,13 +94,13 @@ { "cell_type": "code", "execution_count": 3, - "id": "e614996a", + "id": "b06d871b", "metadata": { "execution": { - "iopub.execute_input": "2026-08-17T13:35:24.005821Z", - "iopub.status.busy": "2026-08-17T13:35:24.005139Z", - "iopub.status.idle": "2026-08-17T13:35:24.038674Z", - "shell.execute_reply": "2026-08-17T13:35:24.036195Z" + "iopub.execute_input": "2026-08-25T17:00:32.408736Z", + "iopub.status.busy": "2026-08-25T17:00:32.408421Z", + "iopub.status.idle": "2026-08-25T17:00:32.423814Z", + "shell.execute_reply": "2026-08-25T17:00:32.422875Z" } }, "outputs": [ @@ -213,7 +213,7 @@ }, { "cell_type": "markdown", - "id": "091c522c", + "id": "7b7b5d58", "metadata": {}, "source": [ "## Adjusted close price series" @@ -222,19 +222,19 @@ { "cell_type": "code", "execution_count": 4, - "id": "cdd9da8b", + "id": "66c62244", "metadata": { "execution": { - "iopub.execute_input": "2026-08-17T13:35:24.043616Z", - "iopub.status.busy": "2026-08-17T13:35:24.042812Z", - "iopub.status.idle": "2026-08-17T13:35:24.980327Z", - "shell.execute_reply": "2026-08-17T13:35:24.977848Z" + "iopub.execute_input": "2026-08-25T17:00:32.425826Z", + "iopub.status.busy": "2026-08-25T17:00:32.425548Z", + "iopub.status.idle": "2026-08-25T17:00:32.799662Z", + "shell.execute_reply": "2026-08-25T17:00:32.798389Z" } }, "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA1wAAAG4CAYAAABRr+Z5AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvctoD+AAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzs3QV4U2cXB/B/3d0o7u7uQ8ZgY86AGTDGBAZzZW6M6TffmAGDbQzGDAZjw3W4u1ModXdLvue8aaxJ21Rp2v/veUJubm6Tm9uk3JPzvuc4aLVaLYiIiIiIiKjSOVb+QxIREREREREDLiIiIiIioirEDBcREREREVEVYcBFRERERERURRhwERERERERVREGXERERERERFWEARcREREREVEVYcBFRERERERURRhwEVG1ufHGG9GnTx+7O+IzZ86Et7f3FXmeiRMnokOHDrBXlXns7OFYTJ8+Hddcc82V3g2qZMuXL0fPnj3h5+cHd3d3ZGRk1LpjXJHP14QJE3DbbbdV+j4R1RYMuIjIqi5duqgTC7l4eHggICAAvXr1wkcffYSCgoJyHbXc3Fzk5OTY3RHPy8tDdnb2FXme6jhm48aNU7/vmn7savr75/Dhw/jqq6/w4osvmq2Xz8uaNWvwwAMPICwsTH2mNm3aVOzjREZGYtKkSahfvz6CgoIwfPhwbNmypcLbXmlV+T6ryse/dOkSxo4dqwLpixcvIjk5GV5eXqhtKvL5ki9Wfv/9d6xfv77S94uoNmDARURWyX+8LVq0UCcXSUlJOHjwoDrhePzxx9WFqsfChQtx9OjRKn2Omh7I2IvZs2ejY8eOGDx4sNn6H374AW+//bb6wuKhhx5Sx1qj0Vh9jMTERAwcOBCnT5/GunXrcOzYMfWY1gKpsmxbE1T1+6yqHn/btm3qce+++274+vqqgJnMtW/fHsOGDcOsWbN4aIisYMBFRMVycHAwZLkaNWqk/jPt0aOH+hY/KyuLR64auLi4wNXVlce6houPj8evv/6qhlYVJRkoyXDdf//9KgtVkvfee09lUX766Se0bdsWoaGhKqvcpk0bPPbYY+XelsovLi5OXXt6evIwlkACUgn8T506xeNEVAQDLiIqEzmZk2+So6Ojzdbv2rULt9xyC8LDw+Hv74++ffvit99+s/oYly9fxq233org4GA0adIEzz33nMU3008//bQh2JMTHRkyJY+/b98+i2FcMtxHHkcer3///pg7d67FsEdb92/+/Pno1KmT2qZfv37YvHmzzcfG1n0uy/NYm1chQa8cP2vPL49XluMjc+pkfsrJkycN+170G/zqOHb655F5IA0aNFD7Kpma1atXl/pzsv9XXXUVAgMDERISguuuuw7//fdfmY5DWV9rUf/88496D8s+V8TSpUvV71f20/SLD/l979mzB2fPni3XtlWtou8zWz87+nmg8vfn9ttvV0M09etKex+X571jGrzKsjzmvffeW+7jUJ7XGhUVhTFjxqjHa9eunfq9mw51lP1u1qwZPv/8c4v90T+GLX9zi2PrZ+Lqq6+GVqvFsmXLbHpcojpFS0RkRZs2bbQdOnSwWN+7d2+ti4uLNiMjw7BuxYoVat2ECRO0R44c0UZFRWk/+ugjte67774zbDdy5Eht+/bttdddd512zZo12piYGO1PP/2k9fHx0d52221mz5OXl6fNyspSl7S0NO2BAwe0t956qzYwMFAbGRmptklNTdWGhoZqb7nlFu3x48e1SUlJ2p07d2rvu+8+7fr168u8f5999plW/iy+9NJL2osXL2oPHTqkvf7667U33HCD1snJqdT3iS37XNbnGT9+vLZFixZm6+T3Mnr0aIvnf/TRR7Vubm6G27Ycn5ycHPW8rVu3Nuy7XKr72C1btkw95pgxY7R79+7VxsXFqX285pprtNnZ2cUei2+++UY972OPPaY9d+6c9tixY9px48apx/r3339tPg5lea3WTJ06Vevu7q7eAyX59NNP1f6aPq9eenq61sHBQTtx4kSL+xYvXqx+7vfffy/ztsV577331PvFloscj+JUxvvM1s+O/m+IvP/l93vp0iX1uynt8a2x5b0j770PP/xQbSevTR4zNze33MehPK9V7tu4caM2Ojpa+8ILL6jP06ZNm7SjRo1Sjyt/R19++WW1j7KdqbL8zbX2+SrrZ6J+/fraG2+8scTjTlQXMeAiIpsCLjmZmD17tvpP/eGHHzY7eWjYsKF2wIABWo1GY/YY06ZN0wYHBxtOUOQ/f2snm/IfuKzfunVrib8NOUFxdXXVfvDBB+r2li1b1M+tW7eu2J+xdf/ksf39/bU33XST2TbJyclaPz8/m4IGW/a5rM9TkYDLluMjZF/k932ljp08Rnh4uArmiz5PScdCnjcg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", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA1wAAAG4CAYAAABRr+Z5AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvctoD+AAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzs3Qd4U2UXB/B/996Lsvfee8sQQXGgiLgAEQcI7ol7Ic7PrbgAQUUQFwii7Cl7702hdO+9ku85b5rVpG06adr/73lCbm5uk5vbpNyT877nOGi1Wi2IiIiIiIio0jlW/kMSERERERERAy4iIiIiIqIqxAwXERERERFRFWHARUREREREVEUYcBEREREREVURBlxERERERERVhAEXERERERFRFWHARUREREREVEUYcBFRtbnxxhvRp08fuzviM2fOhLe39xV5nokTJ6JDhw6wV5V57OzhWEyfPh3XXHPNld4NqmTLly9Hz5494efnB3d3d2RkZNS6Y1yRz9eECRNw6623Vvo+EdUWDLiIyKouXbqoEwu5eHh4ICAgAL169cJHH32EgoKCch213Nxc5OTk2N0Rz8vLQ3Z29hV5nuo4Zrfddpv6fdf0Y1fT3z+HDx/GV199hRdffNFsvXxe1qxZgwceeABhYWHqM7Vp06ZiHycyMhKTJk1C/fr1ERQUhOHDh2PLli0V3vZKq8r3WVU+/qVLlzBu3DgVSF+8eBHJycnw8vJCbVORz5d8sfL7779j/fr1lb5fRLUBAy4iskr+423RooU6uUhKSsLBgwfVCcfjjz+uLlQ9Fi5ciKNHj1bpc9T0QMZezJ49Gx07dsTgwYPN1v/www94++231RcWDz30kDrWGo3G6mMkJiZi4MCBOH36NNatW4djx46px7QWSJVl25qgqt9nVfX427ZtU4979913w9fXVwXMZK59+/YYNmwYZs2axUNDZAUDLiIqloODgyHL1ahRI/WfaY8ePdS3+FlZWTxy1cDFxQWurq481jVcfHw8fv31VzW0qijJQEmG6/7771dZqJK89957Kovy008/oW3btggNDVVZ5TZt2uCxxx4r97ZUfnFxcera09OTh7EEEpBK4H/q1CkeJ6IiGHARUZnIyZx8kxwdHW22fteuXbj55psRHh4Of39/9O3bF7/99pvVx7h8+TJuueUWBAcHo0mTJnjuuecsvpl+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", "text/plain": [ "
" ] @@ -255,7 +255,7 @@ }, { "cell_type": "markdown", - "id": "f9cab6eb", + "id": "d6cac569", "metadata": {}, "source": [ "## Daily return summary statistics" @@ -264,13 +264,13 @@ { "cell_type": "code", "execution_count": 5, - "id": "3c84ea18", + "id": "819408fb", "metadata": { "execution": { - "iopub.execute_input": "2026-08-17T13:35:24.985632Z", - "iopub.status.busy": "2026-08-17T13:35:24.984832Z", - "iopub.status.idle": "2026-08-17T13:35:25.411993Z", - "shell.execute_reply": "2026-08-17T13:35:25.409721Z" + "iopub.execute_input": "2026-08-25T17:00:32.802329Z", + "iopub.status.busy": "2026-08-25T17:00:32.801884Z", + "iopub.status.idle": "2026-08-25T17:00:32.903061Z", + "shell.execute_reply": "2026-08-25T17:00:32.902068Z" } }, "outputs": [ @@ -279,78 +279,78 @@ "text/html": [ "\n", - "\n", + "
\n", " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", "
 meanstdminmaxmeanstdminmax
EEM0.00030.0175-0.16170.2277EEM0.00030.0175-0.16170.2277
EFA0.00030.0138-0.11160.1589EFA0.00030.0138-0.11160.1589
GLD0.00040.0110-0.08780.1129GLD0.00040.0110-0.08780.1129
IWM0.00040.0157-0.13270.0915IWM0.00040.0157-0.13270.0915
QQQ0.00070.0142-0.11980.1216QQQ0.00070.0142-0.11980.1216
SPY0.00050.0126-0.10940.1452SPY0.00050.0126-0.10940.1452
TLT0.00010.0097-0.06670.0752TLT0.00010.0097-0.06670.0752
VNQ0.00040.0189-0.19510.1701VNQ0.00040.0189-0.19510.1701
\n" ], "text/plain": [ - "" + "" ] }, "execution_count": 5, @@ -365,7 +365,7 @@ }, { "cell_type": "markdown", - "id": "7b4f05a6", + "id": "1a2df1ff", "metadata": {}, "source": [ "## Takeaways\n", @@ -397,9 +397,9 @@ "version": "3.13.7" }, "quantlab": { - "code_hash": "51c6d2bd9d6fdae1a9aaf52e138fda7161dc9177754dc9b1a96c98498d377105", + "code_hash": "01f453a13e89b4a77bb5e85538cd9963479ca9a60745ac9d35d77a2a58d5c3ba", "config_hashes": { - "configs/momentum_sp500.yaml": "7a9f43ca4e4fd9975d3abc542f60e55a1b02fce5be00efc2da339f3156e59178" + "configs/momentum_sp500.yaml": "e2be7ba15eca4cf73930a4a991a252549c7a921d2c09d50bedc7c5c8f6552a7e" }, "generator": "scripts/build_notebooks.py" } diff --git a/notebooks/02_momentum_research.ipynb b/notebooks/02_momentum_research.ipynb index 73b2dd3..ccbfd6e 100644 --- a/notebooks/02_momentum_research.ipynb +++ b/notebooks/02_momentum_research.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "dd956f34", + "id": "c8f87181", "metadata": {}, "source": [ "# 02 — Cross-Sectional Momentum Research (Example)\n", @@ -26,13 +26,13 @@ { "cell_type": "code", "execution_count": 1, - "id": "c13678dd", + "id": "727bb76a", "metadata": { "execution": { - "iopub.execute_input": "2026-08-17T16:06:06.199637Z", - "iopub.status.busy": "2026-08-17T16:06:06.199231Z", - "iopub.status.idle": "2026-08-17T16:06:19.033258Z", - "shell.execute_reply": "2026-08-17T16:06:19.032357Z" + "iopub.execute_input": "2026-08-25T17:00:38.494118Z", + "iopub.status.busy": "2026-08-25T17:00:38.493845Z", + "iopub.status.idle": "2026-08-25T17:00:56.254000Z", + "shell.execute_reply": "2026-08-25T17:00:56.253108Z" } }, "outputs": [ @@ -62,7 +62,7 @@ }, { "cell_type": "markdown", - "id": "8ab62aa1", + "id": "b8aa2a64", "metadata": {}, "source": [ "## Run the backtest" @@ -71,13 +71,13 @@ { "cell_type": "code", "execution_count": 2, - "id": "a2655546", + "id": "59e9a1ea", "metadata": { "execution": { - "iopub.execute_input": "2026-08-17T16:06:19.035101Z", - "iopub.status.busy": "2026-08-17T16:06:19.034838Z", - "iopub.status.idle": "2026-08-17T16:06:35.836815Z", - "shell.execute_reply": "2026-08-17T16:06:35.836126Z" + "iopub.execute_input": "2026-08-25T17:00:56.256165Z", + "iopub.status.busy": "2026-08-25T17:00:56.255862Z", + "iopub.status.idle": "2026-08-25T17:01:14.120228Z", + "shell.execute_reply": "2026-08-25T17:01:14.119367Z" } }, "outputs": [ @@ -114,7 +114,7 @@ }, { "cell_type": "markdown", - "id": "873aa9c6", + "id": "8848883f", "metadata": {}, "source": [ "## Equity curve vs benchmark" @@ -123,19 +123,19 @@ { "cell_type": "code", "execution_count": 3, - "id": "a86e6bb9", + "id": "0ccdfa2c", "metadata": { "execution": { - "iopub.execute_input": "2026-08-17T16:06:35.838815Z", - "iopub.status.busy": "2026-08-17T16:06:35.838557Z", - "iopub.status.idle": "2026-08-17T16:06:35.996903Z", - "shell.execute_reply": "2026-08-17T16:06:35.996311Z" + "iopub.execute_input": "2026-08-25T17:01:14.122002Z", + "iopub.status.busy": "2026-08-25T17:01:14.121801Z", + "iopub.status.idle": "2026-08-25T17:01:14.293194Z", + "shell.execute_reply": "2026-08-25T17:01:14.292370Z" } }, "outputs": [ { "data": { - "image/png": "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", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA1oAAAHBCAYAAABwnMo3AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvctoD+AAAAAlwSFlzAAAPYQAAD2EBqD+naQAAqEJJREFUeJzs3Qd4U1UbB/B/96CDUSijZe+9kb33kiVDZYgCigPBhaICCjhARQURQUXFBYLAx56y996bsjdtGd35nvfcZjVpm5a0Tdr/73ny3HVy781N0t4355z3uOh0Oh2IiIiIiIjIblzttysiIiIiIiJioEVERERERJQBWKNFRERERERkZwy0iIiIiIiI7IyBFhERERERkZ0x0CIiIiIiIrIzBlpERERERER2xkCLiIiIiIjIzhhoERFlA3Xr1sWAAQPgKBztfMhxlStXDi+99BIcmTOcY3Y4Z6LshoEWEWWqCxcu4M0330Tt2rVRqFAhlCxZEs2bN8dHH32Eq1ev8t1IQdWqVTF48GCr2yIiIvDgwQOHuX6Odj7O+r7mBOHh4Xj48CEcmTOcY3Y4Z6Lsxj2rT4CIco758+erWo569eqpwEpuMOPi4rB582ZMmDABv/76K06ePJnVp+mwUgpedu3aBTc3t0w/J3p8DEqJiLInBlpElCn27duHp59+Gl26dMFff/0FV1djhXqxYsXQs2dPjBkzhu9GOvn7+/PaERERORA2HSSiTCE1WAkJCZg6dapZkKXn5eWFzz//3LD8/vvvIygoCNHR0XjrrbdQunRpVKpUybB99uzZaNCgAYKDg1GqVCk8//zzCAsLM9vnpk2b0LlzZ9U8sUSJEmp+w4YNaS6THFufu3LlSnTo0AFFihRRjyeffFIFnkmtWrVK7aNo0aJqn/369cOJEyfUtty5c6vXt2DBAjUvj8aNG6faJ8qW66TvyyG1iXJ8adIptY0//fSTxf46depkOH6+fPlQvnx59dxr164hPfTHPnz4MNq3b4/ChQujWbNmhutz8OBBde1kfZ06dbB27Vqr+0nL63zcY9nyftp6TVN6X+Pj49Wy1PZaex9at26dIa/PVNu2bVUzX2v69u2r3n/5Xj/ud0kcOnQI7dq1U9eqZs2a6j3N6Otvy3fPlC37s8f7YOv3TH+so0ePqh+x5LzGjRuX7DWeO3eu+rsqzbf17xsRZSAdEVEGi42N1eXKlUtXr149m58zatQonZubm27w4MG62bNn686ePav74osv1LaRI0eqbZ988olav3nzZl316tV1BQoU0J0/f16VOXLkiM7Ly0v3yiuv6E6ePKm7ePGibtmyZboWLVrobt26ZXOZ5Nj63K+//lrn6uqqe/vtt3VHjx7VHT9+XDd06FCdj4+PbufOnYZy8tpcXFx0L7/8sm7fvn3qdfzxxx+6J598Um2/e/euLjQ0VNe9e3c1L4+IiAjD88uVK6fr0aOH2Tnacp1EcHCwrmPHjrouXbrotmzZojt37pzu9ddf18m/iPXr15vtMzIy0nD8a9eu6VavXq2rVq2arlatWrqYmJgUz8caOXb79u3VseV6nDp1Ss0HBQXpDhw4oGvXrp1u+/btutOnT+u6deum8/X11d24cSPdr/Nxj2Xr+2nrNU3pfZXvjZR/7733LK5b06ZNLb5P9nh9Sc2cOVOdw9atW83WX79+Xefh4aF76623Hvu7JOct59a6dWt1reQ9HDdunPo+fPbZZxl6/W357qV1f/Z4H2z9numPJddu06ZN6n34/fffDdsGDBhgKPvhhx+qa/fpp5+m+H4Qkf0w0CKiDHflyhV1Q9K7d+80BVryHH1wpSc3cXJT9Oqrr5qtv3TpkrrR69+/v1qeNm2aev6dO3eSPYYtZR7nuZcvX9Z5enrqhgwZYrGtbt266iZUhIWFqZvWQYMGpXjMYsWKJXsNkwY2tl4n/Q2Z3OzJDZ1eXFycrkiRIrpevXrpUrN7926LG860BFpJbzQvXLig9le4cGHd1atXzc5d1k+ZMuWxXmd6j2Xr+5nWa5rc+5qeQOtxXp81EvTJjyTyg4cpCYDk+SdOnHjs75Kct1xXub6mnnnmGRVASbCRUdff1u9eWt7PjHgfkvueybHk/GU/1s5ZAq2oqChd37591TktWLAg1eMQkf2w6SARZThpAiWsNRlMTY8ePcyWV69eLT8QoU+fPmbrpQlRkyZNVLMifZMaIc1q9uzZo56TlC1lZJu+CY88pImerc9dtmwZYmJiVDMka02yNm7ciNjYWCxfvlxNBw0aBHux9Trp1a9fXzW705PEGlWqVMHp06fNykkztxdffBEVK1ZUTZDkmrRo0UJtO3XqVLrOVY6dP39+w7I035I+Z2XKlEHBggXNzj1Pnjxmx0nP60zvsWx9P9N6Te3pcV6fNfLcp556Cn///bdZIhZpMidNHMuWLWvz9yG185amdKbkuI8ePVJNEjPq+qflu5eW9/Nx34e0fM+eeOIJtR9rbt68qbK6ShNOuT7dunVL9XUSkf0w0CKiDFegQAF4enri0qVLaXqei4uLxc2X3DiIpOv1627cuKHmW7ZsiWnTpmHHjh2qj4nczMhNhml/CFvKSHpkSZOsf0iGOFufe+XKFTWV9XKzJH0t8ubNqx6TJ09WGRfv3r1rSGsfGhoKe7H1OpmuSyowMFCdn969e/fUDeTOnTvx9ddf48CBAzh//jz+++8/tV3606WHtWMHBAQku17Ow56v09Zj2fp+puWapldygczjvL7kSOr5yMhIFWyJrVu34tixY2Yp6W35PqRE+hYlt07/HmbE9U/Ldy8t7+fjvA9p/Z6FhIQke86S0XXbtm3o378/atWqleprJCL7YqBFRBlOgqymTZuqFOS23NjpSQ2Yu7t5clT5Zdf0BtuU3JDJDZ6e/Lp+9uxZnDlzRiXhkI7krVq1UrUgtpaZPn26upHSP+Q12Ppc/bkuWbJE/eot5aS8POSmUfYnv3rLDaNIb0IJa9JynVKqbTS9oV+6dKk6b7km8jrlV3Q5zuMGDskd25ZzstfrTMuxUns/07LPlMhn38fHx2pK/+Q+K4/z+pLTsGFDVKhQAT/++KNalqnUzvTq1cusnC3ft+RYe//06/TvYUZc/7R899JyDR/nfUjr90z+viZHgtLx48fj008/xXvvvZdsOSLKGAy0iChTjB49Wv0S++GHHyZ7oyE3Z6mRgE1/M2JKArgtW7YYtpuSLGKSkU//nDVr1thcxtfX16zpoLU06sk9V5ozSa3cunXrzPZh+pDtkj1OpvPmzUvxtcu5mDaNsvd1So3+2PIrvqk//vgDWSUjXmdybH0/0yql97V48eKq9siUPsjITFJ7JbUje/fuVcMzSMZBOW9rbPm+JSU1YUl/hJFmfRJsSjbJjLr+tn73MpO9v2eSwfXbb7/FpEmTVDDMbINEmYeBFhFlCukn8OWXX6p/+M899xyOHz9u6L8lTZHkhuebb75JdT/Vq1dXfTckFbwMgCw3JZcvX1b9NmReH8hJ0PbJJ5/g3Llz6sZC+nbIgMhCBky2tUxybHmu9FuR1PQff/yxagKkv5GUX89/+eUXvPLKK4Zyr7/+unr9X3zxhSonzaDk5nP48OGGY0qK5/3796smjPa6TmkhQYu3t7dKHy1NyaSmRc7ZnjVxaZURrzM5tr6faZXS+yp9h6RG6N9//1WfM0kv/vbbb6u+QZlJmp55eHigd+/euH//vlmzwcf9LunfxyFDhqimfPJcSUM+c+ZMvPzyy4Y+TRlx/W397mWmjPieyWuR9+OHH37As88+q14jEWU8BlpElGlee+01VcsgNw/SHEnGzpIaIrkpll/u5ZdyW8gNg+xLbqzkV3V5blRUlOrDUK1aNVVGf0MoAVyuXLnUr8M///wz5syZg+7du9tcJjm2PlduPmfNmqVuBKWZkjQFk74S0jl96NChhnJTpkxRN49SVvqcSHOpUaNGmTXPkhtMuV6yn6TjaKX3OqWFjI0kv/xLrYacnzRpkrGGJIDOSvZ+nSmx9f1Mi5TeV3ldMiaY1CDJsSTgkXG1ktZ2ZDRpkifjNEltWuXKlQ1JYfQe57sk9GOfSZAhz5cAa+TIkarvVUZff1u+e5kpo75nMmD8woUL1ZhtMvaYJBohoozlIqkHM/gYRERWyc2w/Eou2busbZOmhqndUMrNggRsKWU0lF/I5TgpNSuypczjPldq7+SXZDnflEhNjLwea9dFfzx53VJG35RRglcpn1xzrpSukyT4kCZaSZ8riUDkfKWzflLy3uhfh/wbkdoYeb6+v0hq55PasdO6/nFeZ3qPldL7mZ5rau191ZNaIvlc6I8lQY3w8/PLsNdn7T3XX18JcOz1XUp6HvLdlxqd1Nj7+qf03UvL/uz5PqT2PUvpucltkxoyeZ3y2UnaB5aI7IuBFhERERERkZ2x6SAREREREZGdMdAiIiIiIiKyMwZaREREREREdsZAi4iIiIiIyM4YaBEREREREdkZ83raQNLqXrlyRaXbTU/qZyIiIiIiyh5kuAUZxqRw4cIpDi/DQMsGEmSFhoba8/0hIiIiIiIndvHiRYSEhCS7nYGWDfQDR8rFTG6QQyIiIiIiyv4iIiJUJUzSweWTYqBlA31zQQmyGGgREREREZFLKl2KmAyDiIiIiIjIzhhoERERERER2RkDLSIiIiIiIjtjHy07poCPiYmx1+6I7M7T0zPFFKREREREZD8MtOxAAqxz586pYIvIUUmQVaJECRVwEREREVHGYqBlhwHLrl69Cjc3N5XmkTUG5MiDbstntWjRohx4m4iIiCiDMdB6THFxcXj48KEaGdrX19c+7wpRBsifP78KtuQz6+HhwWtMRERElIHYYeMxxcfHqymbY5Gj039G9Z9ZIiIiIso4DLQyacAyoqzGzygRERFR5mGgRUREREREZGcMtHI4SeZx584dNU3q3r17apu92Ht/RERERESOioFWDhUeHo7nn38efn5+KFOmDPLkyYN+/frh+PHjhjLvvPMOhgwZYrdj2nt/RERERESOioFWDvXSSy9h27ZtOHz4MG7fvq3Sfnfr1g1Lly5V2yMiIvDgwQM8evQIly5dUo/o6GjcvXtXPYRsv379upqPjIw0lJP5pJLbn2n68Vu3blmtWdO7f/++er5+f1Jev/7atWsW5SUbpGTZIyIiIiLKbEzvnkOtWbMGr7/+uhrAVvj4+KBXr16G7d9//z0WLlyoAqAnnnhCrfvzzz8xa9YsFZS5u7tj8+bNqFq1KjZt2oSffvoJn332maGJYKFChTBt2jS0adMmxf01bNgQEydOxJQpU9S62NhYDBo0CJ9//jm8vLwMAdPAgQPxzz//wN/fH5UqVUJISIiqlVuxYgUOHDiApk2bIiwsTKXZ1xs5cqSqoduwYUOmXVciIiIiIsEaLTuTGpmHMXFZ8kipNigpGVx5yZIlydb4vPnmm3jmmWfQoUMHQw1Uo0aN1LZVq1ahe/fuKqCSIEu8+uqrZjVab7zxBp566ilVW5bS/iZPnozffvsN27dvV/23Tp48qfY5fvx4w7l89NFH2LVrl9omxxw+fDj+/vtvw3YJ1sqWLYs5c+YY1knNlwRygwcPTse7SEREREQOIS4GmNkcWPEunA1rtOzsUWw8Kn6wElnh6Pi28PW07S2dMWMG+vTpo2qGpIaofv36ePLJJ1UglJpatWolG8BIjZQ06evYsSM+/PBDbN26FZ07d7ZaVgJDCbSkXEBAgKopk3VSe/Xtt99iwoQJqtzMmTPVfKlSpdSy9CWTGjJT0t9MXtPo0aPVstR+yb569Ohh0/UgIiIiIgeTkADcPAZc2as92nwEuLrBWbBGK4eqXbu2qiGSflrSVO/y5cvo1KmTClhSU7p0aYt10tercePGyJUrl2pOKM0DpTZLaq6Sc+PGDfUYN26cOp86deqgbt26qtmgflBdqeWSR5UqVcyeK8cw1b9/f1y4cMFQw/bjjz+qQNLX19fma0JEREREWejhHSA+1ri8/mPg+ybafIUuMioonAlrtOzMx8NN1Sxl1bHTwtXVFfXq1VMP6c8k/aSkyd/YsWNVTVdypH9WUlLL1KBBAyxfvlxlMtQ3T9QHTNa4uWnnO3v2bBXkWePp6ammMTExZutNE2mIoKAgdO3aVQVYcu7SL2vSpEkpvn4iIiIichARV4EvygM1BwBdvtbW7f7JuL10S7l5hTNhoGVnLi4uNjffy0oSAOkDHb3y5cubBTWSjCIuLs6mfR05cgRff/21Icg6ffq0qiUzlXR/EhxJ7di///5rEWhJ0gwJBGV/xYsXV00QmzdvbtguNXFFihQxe84LL7ygMidKqvqKFSuqAJKIiIiInMDF7dp07xwt0Aq/BDwyGX/VxQ2IfQR4+MBZOH5EQBlCmuhJlkFJSFGwYEGcOHFC1WZJrVTJkiVVGRlfa9GiRTh48CDy5s2L/PnzW92XBGw1atTAl19+iQIFCuDmzZsYMWKERTlr+5NMhZI0Izg4GL1790ZUVBTWrl2LM2fOqAyH4u2331YP6aMlTQhl/dGjRy1q3Vq1aqX2+dVXX6m+X0RERETkJKLCjfPxccBXJt1GfIO0QCy0HpC/LJwFA60cSjIOfvfddyp5hIxBJQGSBDqmAZIkpdi3b5/q6yTjVkkWPwmQrNVyyTbJLNilSxfky5cPQ4cOVev0NVzJ7U9qoCTVvDRb/Ouvv1QtV+vWrc0CpWHDhqkxuCQhhoeHB5o1a6b2JX23ktYmSl8taTL47LPPZti1IyIiIiI7K93KOL9jBqBLMC63Hg/UeNrpLrmLLi05wXMoCQoCAwPVuE2SHc+U1MCcO3dOjUfl7e2dZeeYnclHVIIoU5JsQwKuTz75xGy91I5JU0bJOkjm+FklIiIih6XTAQteAA7N05ZzFwXuhQG++YDGbwD1X4IzxAamWKNFDk8yGk6fPl1lR5R+XpLwYv/+/WbjZklzRRlrS/p7cYBiIiIiIicT8wBIMEmiVqUXEFwZOP4/YNcPDhVo2YqBFjk86ZdVs2ZNjBo1SqWMr1ChAnbs2IFy5coZysi4XtLPTGq4pJ8ZERERETmRteOAIwuMy5umAE3eAu7f0NK+OyEGWuQUJKOgPJKzePHiTD0fIiIiIrKjqAjLdZ6+wHltjFRnxECLiIiIiIiyxq1TwKnVQLS1QMuYVM0ZMdAiIiIiIqKs8W3t5Ld5+WvjZ7maj/3qLBhoERERERFR5kswSX6hV7kHkLcksPFzwDMX8O4Vp31nXLP6BIiIiIiIKIeJfQSMz2e5vuePQIGKWnp3n7yAh7f2cEIMtIiIiIiIKHO5SsO6JMP5dvkWiIsBbp8G2kwAijd06neFTQeJiIiIiChzuXloyS7cPIFHienb3b0AFxdg/QRteWy4U78rrNEihzBmzBiMHj0a2eG84uPj0b59ezWocmbR6XTo2LEjdu7cmWnHJCIiIkq3exeBmPvGIEvfZ0sCML3o+059gRlo5VDffPMNKleubHg0bNgQQ4cOxcmTJ7PkfC5duoSLFy/C0aTnvL7//ns8evQI1atXN6ybP38+unXrhrp166JHjx745ZdfEBcXZ/X9qFatGjp06IBvv/0W4eHhaN68Ob788kuL4/zzzz+oXbs2rly5AhcXF7X/V1999TFfMREREVEm+L6J5bqSzcyX42Oc+q1g08Ec6vr164iIiMCyZcvU8p07dzB58mQ0btwYJ06cQO7cubP6FJ1SQkKCuo6ffvqpYd2kSZPUQ9bpAyMZYHnfvn2GAMr0/ZAasT179uD111/H8ePH8corr6Bv375o0aKFCsLEtWvXVGD89ttvo3Dhwmpdv379MHLkSGzcuBFNmlj540VERETkKB6Z1GS5ewMlmgABhbTlIrWAy3u0rINOjIFWDubp6alqUPQKFSqEsmXLqiZvzZoZf1HYvn27CgjOnDmD0NBQPP/886qZmmnzOqmdKV68OBYtWoT79++jc+fOGDVqFNzcjOMe7NixA1999RVOnTqljvP++++jQoUKZs3fZsyYkew+5DjR0dEoUKAA1q5dq2p7evXqhZdfflmd35IlS9RrGjJkCPr06WPY78yZM/H111+r+cDAQNSsWVPtKzg42Ow1xMbGIiQkBPPmzYO/vz+WLl1qcc3CwsLw7LPPolOnTnjzzTcttv/333+4fPmyOnfTGq4RI0bgxRdfNKzr2rWrei3JvR8SUF24cAFTpkxRtV3yeuS4u3btgpeXF1544QVUrFhRXR89X19f1WRxzpw5DLSIiIjIcd06bZwfuAz4uQPgFWBcF1BEC7Sk/5YTY6BFBhK8yM1+mTJlDOtWrVqlbvLHjRunbuqPHTuG/v37Y/r06ejdu7ehed3vv/+ualTee+89VWMjwY6fnx9eeuklVWb58uWGpm0SGMlzJPDYsGGD4VgS4Hh4eCS7D3nO3LlzMWDAAHzwwQc4evSoqtX58ccfVWDx2WefqVqip59+GuXKlUONGjXU8+S4DRo0MNTcSZM8CSQPHToEd3d3s9fQs2dPTJw40SwI05PX3qZNGxXcvfHGG1Y/OfJ6JEjy9jamIZVmfdaaH0rAlJJ8+fIhKioKMTExKlCsWrWqCk7ltUlAd+DAAbi6mrf+rV+/PqZOncpPNRERETmu2IfatN4wIEBrmYPbp4zbjy3WppIYw4kx0Moo0+pZX9/ndyBfKeD2GeDPftbLDN+hTU+vAVa+Z7k9Twmg35/a/M4fgF2zjM9JA7n519eg3L17Fw8ePFB9iYoUKWIoIwGF3NxL8zUhfYyk7CeffGIItESpUqXw008/qaBCbN68WdUI6YMkCdIGDRqkgiG97t27m51PavsQEgT+8MMPqowET7/99puq2ZLAT8g62ceKFSsMgVb+/PnVQ0/KSK2YBCstW7Y0rJcmeNJ3Sh98mZIkE9JvSprzSSCYnHPnzhma8ulJ+WHDhqkgsHXr1ioYkuNK7Vpy5BpLzZRcbwnI5CGvq23btmpegqkSJUpYPE/eO6l1k+aHprWJRERERA6jUFVjRsGIq9q0YBVkNwy0cjCptfnzTy1gi4yMVDU60iRNApzSpUvj3r17qtZn2rRp6qZfmvbJQ/oS3bx502xfUoujD5CEBBvbtm0zBA1SGyR9l0xJ7ZWt+9CTWh3TMgULFlRNFk3Juhs3bhiW5bVJjZDUNsl6CUIkqJSgyJQ0KbQWZEmAJIGRnL/UoKVEap+kVtCUNLWU4E5q7LZs2YLvvvtOvQaZPvPMMxaBr5yfNBuUZBo///yzYbv00ZImiadPn8bgwYOtHl+CMOknJs0gGWgRERGRwwsoBLx9AfDyN657eQ8QdQ/OjoFWRkmthklqtVIrU7qV9khJ3Re0hx36aElNy8qVK1V/JwmuJHOekPTm9eqZ19CZBjvCWoAiQZmQ5m/6PkQpSWkfKZVJ7XnS1FGaIr7zzjsoWrSoCkbatWtnOC+95M5PmgFKUCh9r1IjQZ406UtK+lN9+OGHal6uqwRf8pDASV+zpQ98JUCSINNajVdAQIB6JEcCYElkYtp0kYiIiMhhPLoHbJgERFwG2n0CBIYAPkmSsAWVRnbAQIvMyE36rVu31Lw0r5Ob/atXr5oFZGklAYTsV2qGTJNsZAapHZJMftJHTGqE9DVcpjVeqZGEHdJcsVWrVirAlP5qyZGmftL8UAK9pMGono+PDwYOHKhqECV40wdUSQPf9Ni7d68KmImIiIgc0peVgZhIbb7tRGRnHEeLDDZt2qQyDjZt2lQtS82KJK+QJnOyTU8CJskeaPOHzNVVJb6Q/ln6QXwl457088po8hry5s2rmkMKaVL32muvqWlaSLPC1atXqyaI+popayTrn9SUmQ4cLMczHbxYMirOmjVLBbKmiUfsQc4xad83IiIiIocQ+8gYZInAUGRnrNHKwUyTYUgtj9RkSVBgmoZcggqpFZJEEJLyXAKkkiVLqrTjaTF+/HjVZE5qWyQxhQQb0pQvM0hfKKlBkuBGPwCwNCFMq1q1aqlARhJaSG3V2LFjLcrkyZNHNVWUTIj65pbymqXvm4xPJsGV1GJJfzRJ9JG0n9rjkP5fklVRsj8SEREROZRzm4A5nYzLJZs7fVbB1LjoknaCIQuS/EGad8lNetL+MVJ7IUkVJAOcM/WLkaZzps3nJI26jCFlrb+TPsmDZLMLCgqyGMxYAgf5GMnz9SRok+slmQRNPXz4UPWXKlasmFmQYcs+rJWRtOxSY2aa6U/OU5rhSX8pPQkQJbCU2i15yFhekj5d5pPbd3LrZbBgOTdpUmgt4YQMPlylShU15pW8Tj0JLmWbNKWU621K3gt5ranVcMn5yHthLeOgZCSUVPaS4dAaZ/2sEhERUTawbgKw0Zh9Gq0/Ahq+iuwWG5hioPWYF5M3r2SNBHtSAyg1XJlBgkEZV0yCv6Rja+nxs0pERERZZsf3wPK3tPkKXYAOkwF/y3FLs1OgxaaDRBkgPU0TH4c0ZaxUqVKmHpOIiIjIZjEPjPP1X3baICstGGgREREREVHGuHkSWPIq4JvPuM4tZ4QgzDpIREREREQZ48xaIGwbcO0QEFxFW/fwTo642mkOtCRznKTplvGQJHubjC+U1LZt21SKacnS1qdPHxw+fNjhyxARERERkZ1FhWvTexe0QYobvwGUapkjLnOaAi3J3NayZUs10Oobb7yhxkGS8YHmzZtnNsaSBGClS5dWYy1JdrVGjRrh/PnzDlvGHpi8kRwdP6NERESU6R7dNZm/A7R8XwZZzRFvRJqyDkpN1oQJE1RqbBkPSE8Gf9Wn6u7Ro4cay2f9+vVqWXZfvnx5NfbQt99+65BlHieziLz206dPq/TiUobIUcnnV1Lry48O9hy/i4iIiChZm6YAa8dr814BwOiLTn+xMiTroNRkPfnkk2ZBljC9aZOAZvTo0WbZ0GSw21WrVjlsmcch4075+vri5s2b6jokl1qbKCslJCSoz6h8VpMbK42IiIjI7hqPAu7fAHbMALxzVqVEmu64jh8/rvo4vfXWWyqAkYCrZ8+eGDhwoApgHjx4gLt376JQoUJmz5NlGSxWOFqZ5JpIysM0ak2OvG7ZnwwEe+HChWTLEWU1+RFA0s7LZ5aIiIgoQ906DSx+BQitCxz5V1v31JwcddFtDrSkyV1MTAw+/vhjjBw5UjW7kwFSX3/9dRVgjB07FnFxcaqsp6en2XO9vLxUEzvhaGWsmTRpEsaNG2frpVH7L1OmjLo+RI5KPqescSUiIqJM8W0tbRq21eRmxD9HXXybAy35FTxfvnyoUqUKxo/X2lnWq1cPYWFhmD59ugq0/P391c3c7du3zZ4ry0FBQWre0cpYI00NJZg0rdEKDQ1N8frIDay3t3eKZYiIiIiIcizPXMhJ0tShqE6dOirYMiUBy/3791WNlwQb1atXx44dO8zKbN26VaVWVwd0sDLWSI2XdGwzfRARERERUToUrqlNTQctzgHSFGi99NJLWLlyJQ4dOqSWJZvf7Nmz0a5dO0O/j6FDh2L+/PnYs2ePWpakExs2bMCQIUMM+3G0MkREREREZEf5ywPFGwNjw4HBq4DRlwCPnNX6K03JMDp16qSaCMo4VFKzde3aNbRq1QozZswwlHnuuedw4sQJNGzYUJWRZBTS50ky/TlqGSIiIiIisqPhJi3K3Dy0Rw6TpnG09KKionDp0iUULFhQDQBsTWRkpArEihQpolJKO0OZx82VT0RERERE2ZutsUG6Aq2choEWEREREZGNji8F9vwMtBoHBFfMsbEBR9clIiIiIiL7uXUKOLUKiH2Uo68qAy0iIiIiIrKUkACsfA+4tDttVyfmvjb1st7FKKdgoEVERERERJZksOFt3wKzWqbt6sQ80KaeDLSIiIiIiIjMbf1Wm/rkSduViY7IkQMUP1Z6dyIiIiIiysbiYoATy4CgMkD4JW1dj1lp20dUYqDl5Y+cjIEWEREREVFOdXkPcPY/oNHrgIsL8PA2MG+AcXuRWkDpVrbv78d2QK4goPV4wNUNORkDLSIiIiKinOj4MuDPvtp8xa5AvlLGZn96gaG27+/qASBsmzbfaSpyOibDICIiIiLKiW6fMs6v+RC4fUar0TJ19F/g99627c+/kHH+/jXkdAy0iIiIiIhyoiP/GuePLQHmDwLunLUs9+iebfvzK2Cc/9uk+WEOxUCLiIiIiCinCb8MXNmbZN0lrVbLVP7yxqQYqZkYYpy/ew45HQMtIiIiIqKcIiEe+LkTMP0J47pciTVRwZW1BBZ5imvLgUWBIrWBiEvAg1vJ73P7d8DM5kBMpHFdmwnI6ZgMg4iIiIgop7h5HDi/SZtvPgao0Bn4rbu2HBcFtBijPeLjtCyEy9/Stl0/DJRsZn2fK94B/IKNyx/cyfEZBwVrtIiIiIiIcopHd43z1foABcoDEZe15Ys7gGVvApu+ANzctWApNkrbFrYj+X26ewP3rwMurkC7TxlkJWKgRURERESUU+QrDfjk1ea/qmy5fedMYO0443L94dpUl2B9f3HRWk2YvkzdF+x+ys6KgRYRERERUU7hXxB46yyQtyRQoJK2ztUj+fJxj4xp3q1JmpFQXztGDLSIiIiIiHKciCtAQGFtvkxr8236ZBjizjlj3y5rwi+aL+cuatfTdGas0SIiIiIiykljZ43LrTX3c/M0Nv8zJYkw9G6fTnl/kgTDPzFgq/ikvc/WqTHQIiIiIiLK7qIitIdpUOWfmCnwzFrzsvEmZSr3SHm/uUOBRq8n7q+Q3U43O2B6dyIiIiKi7O6TUAAuQNdvteV8ZYDW47X5F7cBUeFaMosdM7SU73pBZYzzkde0Pl5JhdbVpr6JSTZIYaBFRERERJSd6XT6GWBRYhbBDp8BXv7afHBFY9niDZPfT4JJk0K940uB+YO1+dtn7HbK2QGbDhIRERERZWfxsZbr9P2z0kLG1Dq12nzdg5taZsLOU4EuX6f/HLMhBlpERERERNmZDDxcqXuSdSmkdE+qSi9tOrcHMLcncGadcZt+QOOgsoC7lz3ONttg00EiIiIiouxs/+/AkQVaMBQYCjR/D8hf1vbn3zyhTe+eN/bVSjrOFoMsC6zRIiIiIiLKriTL4Pbp2nz7z4BnFwAhtYz9s2yhzyqo5xVgWaPl7mOPs81WGGgREREREWVXa8cDN45q824ewJLXgM1fmY+VlRoPX5MFF6BcB8saLQ9vO51w9sGmg0RERERE2TXb4LbEdO7CwwfY87M2X7k7kLuobfvxTAy02n8OVOsNuJrU1VTtDRSsqg1cTGZYo0VERERElB2tfNd82dOkuaB37rTXaC1/E/iiErDFJLtgcCWgSk/AM9fjnm22wxotIiIiIqLs6Pxm82XvQKDik0CeYoC3ST+r1EhNmF5MJLD6faB6P+DcRmD+IG392HA7nXT2wUCLiIiIiCg7KtkUuHYQ6DUH8M0H+AcDT81J+37ylba+/vKexz7F7IyBFhERERFRdh6oOLQuEFA4/fuxmrrdBUiIT/8+cwD20SIiIiIiclYnVwJ/Pg3cPKktx8UAYdu1RBjFGwN9/gB88j7eMRISLNfpEoCY+9q8m+fj7T+bYo0WEREREZEzkjGsfn9Km683TBuEeO0480yDnac+fup1nbWaKx0Q80CbHZU4oDGZYaBFREREROSMrh4wzscmjmdlGmSJBzcf/zgy/pZe3lJAkzcBvwJajZa7N+D7mDVm2RQDLSIiIiIiZ5S3hHE+9qH1Mp5+9j3mq3uN8xW7AoWq2Xf/2QgDLSIiIiIiZySZBPVunwLioi3L2Gt8q+E7gagI4PJe4OZxLciq8Yx99p1NMRkGEREREZEzunEUqPOCNr/uYyD8kjYfXNlysOHHlb8cEFoHOPwP8O+LwD/Pa320JOkGWcVAi4iIiIjIGS0ZAez6wbgcdQ+oOwSo1ifjmg66uGjTE8uAiYUt+4SRAZsOEhERERE5o8irQIFKwI0j2vIPLYCx4UDkNeDwAqBUC6BYffse0yVJPY0kwyCrGGgRERERETkbabIXFa416ZPHkQXGbf4FgSHrM+a4SQMt04yEZIZNB4mIiIiInMmh+cC43Fp6de/cQIsxxm0/tgMubAPuXgDunLU+2PBjSWw6qOfKepvk8MoQERERETmTteON8w9vazVbemHbtABsalVt+b3rgKsdm/cFFDZfdmWNVnJYo0VERERE5EwCQ4zzHT4HTq/V5qsmJsFw9zJu97BzH6q6LwBBZY3Lrm723X82whotIiIiIiJn6pslTQIlCcZLW7V16z/WprI+MxJU3DqpTWsOAMq2zdhjOTEGWkREREREziL2EZAQBxSqZrnt0k5t6uYJFG0A+Afb//hnTJJsePlrD3r8QCsyMhLh4SZtQKW20NUVhQsnaasJIC4uDnfv3kW+fPlUGWscrQwRERERkUPz9AXePG2+rv1nwPK3jMtSo/Xc8ow5/qVdxvkbx4CoCMA7IGOO5eTSFHFMnToVpUqVwhNPPGF4tG7d2qLcpEmTkDdvXpQoUQL58+fHDz/84PBliIiIiIicUr2hQLV+2nybj7X07hlFP2CxOLMWuLw7447l5NJctVOjRg1cunTJ8DhyJHGAtER//PEHxo8fj3///Rf379/Hd999h2HDhmH9+vUOW4aIiIiIyCksGg58VVUblNiUu6c2rf404JM7A08gaXp3Zh1MTrra0N27dw+PHj2yum3atGno1q0bWrRooZafeuopNGrUCNOnT3fYMkRERERETmHfb8C9C4BLkmx/+gQY98Iy9vhJByzmOFr2C7R27dqF0NBQBAYGolq1ali3bp1hW0JCAnbv3o2GDRuaPadx48bYuXOnQ5YhIiIiInKajIMSYMkgxX75zbfpU7rPG5Cx52DadFC4sUbLLoFWmTJlsGHDBkRERKikGC1btkTHjh1x7NgxQ7KM6OhoBAUFmT1Plm/evOmQZayR58hrNH0QEREREWUJSTgxNhAYlxvQxQOFa1iWqTVIm+YumrHnUqCi+TJrtOwTaPXu3VvVBrm4uMDHxweTJ09GwYIFMWfOHG1nidn8JMOfqdjYWLi5uTlkGWskeYbU2OkfUoNHRERERJQlIq6YL3vmsiyTp7g29Q7M2HORcbPGmmQhZ6CVrMfKcy6BTPHixXH+/Hm17O/vj4CAAFy7Zt457/r16yhSpIhDlrFm9OjRqsZO/7h48WKarw0RERERkV3oEsyXy3eyLBOdyS2wQuoCfgWBgpUz97jZNdCSPk+mJIvf4cOHUbJkScO6Jk2aYPXq1WblVqxYodY7apmkvLy8VIBm+iAiIiIiyhJxUcZ533xAmTaWZXZ8r00v78vYczm+TGvGKIMjR5mPr0uPMWCx9Ml64YUXVIr3W7duYdy4cdDpdHjxxRcNZd59910VxEycOBGdO3fGzz//jHPnzuGff/5x2DJERERERA6R7GL6E0CZ1tp4WHox97Vp+8+BekNSHkg44lLGnqNpVsO4R8DDO4Bv3ow9Zk6o0ZKBfteuXYtevXph1KhRKF++PA4dOmTWh6l+/fpYunSpqkV68skn1Thb8pxy5co5bBkiIiIioiwnzf9uHge2fqPVGukVqg4MWgGU75j8c70SW2CVapm56d0f3s7Y4zkxF51USVGKJOugJMWQ/lpsRkhEREREGeLuBWBqVfMAa+h/wIPbQK58KT935w/AsjeAthOB+sMz7g3SH0d0mAzUfQE5TYSNsUGamg4SEREREVEGuXXSfPnqfiAhHvitGzBwKeDln/xz6zyvBWYhtTNvHK0cGGRlWtZBIiIiIiKyk7k9tWnuYuap3a8e0JoTphYAhdaxHFA4o5sOUrJYo0VERERElNWiI43zHj7aNLAocPecNu/jIAknitQG3H0ytnliNsFAi4iIiIgoq60YbZzvvwg4sw6o3g/4d7j5gMRZrVBVYIz5GLVkHQMtIiIiIqKstu9X47x3oDZ21o/tgbCtxnXkVNjIkoiIiIgoKx2cZ5wfcUhrOhh+2RhkCQ9vOIS4aC31vGn6ebKKgRYRERERUVZa8LxxPndRbepXwLyMbxAcgqtHVp+B02CgRURERETkCJq9a5zPld98W+5QOARXhg+2Yh8tIiIiIqKsci9Mm5ZsBjR727g+aY2WjKfl6gaH4O4NlGuf1Wfh8BhoERERERFlhUt7gFkttPln/zXflitJoBUf6ziB1nvXMn68rmyAdX9ERERERFnhxDLzQMpUQGHj/LDNjpMMQzDIsgkDLSIiIiKirBBz3zi/6wfzbV5+QI/ZQNO3gYJVMv3U6PGx6SARERERUVaICjfO+wVbbq/SM1NPh+yLgRYRERERUWaLeQhU7wfU7A+E1AXceFue3bDpIBERERFRZjv0NzCnM3B+C4OsbIqBFhERERFRZlvymja9fZrXPptioEVERERElJl0OuN8riBe+2yKgRYRERERUWa6f904H1yJ1z6bYqBFRERERJSZ7p43zrs70PhYZFcMtIiIiIiIMlNoPaDR69p8fAyvfTbFPJJERERERJnJxQVoNhoIKgdU6cVrn00x0CIiIiIiykxn/wPiooDqfXndszEGWkREREREmZFpUGqyIq8Dv3TR1o0N53XPxthHi4iIiIgoo51cCcxqDVzezWudQzDQIiIiIiLK6NqsQ/OASzuBG8d4rXMIBlpERERERBlJgqvD87X5dR9p07wlec2zOQZaREREREQZ6e/+5ss+eYCX2YQwu2OgRURERESUkfKVNl/2zQe4uvGaZ3MMtIiIiIiIMpJvXm06dCNQtj3Q53de7xyAgRYRERER2S4+Flj8KnD/Bq+araIjtWlwFaDfn0D+crx2OQADLSIiIiKy3cbJwN45wIzGvGq2avIm0PcvwJW33jkJBywmIiIiItvFPtSm96/xqtmqUFXtQTkKw2oiIiIist2Dm8b5izt55VJzajVwfCkQG8VrlcMw0CIiIiIi28Q8BKLCjcuP7vLKpWZuT+DPfsDO73mtchgGWkRERERkXVw0cOAv4OsawLH/ARMLASeWAT1/1LZHXs05V05qpHS69D/fhenccxoGWkRERERk3YxGwMIhwJ2zwF9Pm9xBemjTJa/lnFqteQOBcbmBB7dsD1LHBhqXvU3mKUdgoEVEREREluJigFsnrV+Zu+eM8+GXcsbVO7lcm17db1v5qweN891nAdX7Zcx5kcNioEVERERElh4kjpNVqgXQdpL5tv2/AwWraPMRyTQfPDgPmBQKPLzj/Ff36CLj/G89tOmt08DdC8k/5/ohbdptJlC1F+DKpoM5DQMtIiIiIrIUeV2blmgCrBxtvs03CGjxQcpp3hc8D0RHAGfWOf/V/bu/+fLJlcC3tYCpKaRsv7hLm5ZulbHnRg6LgRYRERERWYq5r039Clpuyx0K+Ceuj7wGxMcCMQ/My5TvpE2v7HP+TItJrRpjnJd+WMeXWXlepGTAAHzzZuz5kcNioEVERERElqQmq49JE0FT7t7GQOv+deDXbsDEwkBCvGWgte1b5766Ufe0afVnjOuS9l0L22r5PGlyWed5wMUlg0+QHBUDLSIiIiKydGwxkK80ULAy0O9v822H5gG58gNvnwdKNgfOb9LWx8cYy7h7Ov9VlZq6TV9o84FFgOG7AL9gy3Jbv7FcV/s5oOPkjD9HclgMtIiIiIjI3M2TWr+kaXW1ZReTW8YqTwH9/tJqanzyaDVaeqaB1sJhzn9VjywEdv2gzXsFAPnLAvWGmdfsWRMfByx/G7h7PnPOkxwSAy0iIiKinOxeGHDzhPm6RcPNl+OijPM9fgCKN9Lmz6wHlo40bnP30aYysG9CnDbvnRtOS/qf6ZVqrk29/I3r6g8HKnbV5k2bTUrTwh0zgDmdM+tMyQEx0CIiIiLKqSSBxVdVtJqr+4np3E1rpt65aAycrFk41Djf5C1jc0FJpKFL0OZjH8EpLXwRWP2+Nv/0P0BwJcvAsWZ/wNPfeC2jIoD7N4Ere7V1xRpm9llTdgi0bty4gRkzZmD16tUW2xISErBu3Tr89NNP2Lx5s9XnO1oZIiIiohznROIgvPqxsfTcPLW+SN4B2nLJpkDuokCvOebPd/cyzt88Ljdd2vzeX4zr46O1caisZe9z5L5ZEZeNy9JkUE/GxJImk/qMjF5+xuDyq8rA5NLGTIvXEsfSohwpXYGWTqdD//79MXLkSHz//fdm2x4+fIhmzZph4MCBWLFiBXr27Iknn3wScXFxDluGiIiIKEcy7UMkSR/0tU9tJwJdpxu3eQcCIw4BlZ40f76+qaA+eYY++97Kd83LSX+vhUPgNK4eAM79Z1z2L2S+/c2zwIf3AA9vIKgMkK+MNl5YVLi2XYJSEWQSoFGOk65A6/PPP4ebmxtatGhhse2zzz7DmTNnsHfvXvz111/Ytm0b1q5di9mzZztsGSIiIqIcJ2w7sH+uFkRUfBKIDgf+elbbFloHKGPDQLsSaJia00WbFm+sTRuZ9N+6tAdO49Fd47wkv3DzMN/u6mpM2161D/Dgpnm/tvzlgWp9gc5fZdIJU7YItHbu3Imvv/5aNcOz5s8//0Tv3r0RFBSklkuUKIGOHTuq9Y5ahoiIiChHkZqrH9sCd84CIbWBo/9q60+vBq4eBO5dtK2pX9KsezqThBDSl6mGydhTrcfDaZj2VyvWIOWykvRDP9aWeG4V8HtvrSmh1ARSjpWmQCsiIgJ9+/ZVfbMKFChgsT02NhanTp1CxYoVzdbL8pEjRxyyjDXR0dHqtZo+iIiIiLKFuBhgyWvG5fwVzGuezm/W+hodSjJ2ljXSRM43CKg10Hy9JNOQIMyvgPX+XI7u9iltOnynMaugLcFmcBWgUDWJOAEP34w9R8pegdaQIUPQrl07dOqUONJ3Evfv31eJJ3LnNk/jmSdPHkOw4mhlrJk0aRICAwMNj9DQ0FSvDREREZFTBFkf5wcO/mVcd/8a8MSLxmV9MzlbAoUW7wONRgDlOhjXjQ3Ugqpi9c1ToUsNj7O4fVobOyxPidTLmgaQ1w8BE4JTHmOLcgybA63169dj4cKFKF26tKrRkkdYWBjOnj2r5iMjI+Hjo3WIlHlTEtT4+mpfVkcrY83o0aMRHh5ueFy8mJjalIiIiMiZXT9suS5vKa3mqUJi/6p9v2pTD5NEF8mRpoerxgAXtgAlmhjXS4DS62dt/t0r2vTcJjgNaTrpX9iYrj4l0ldLf+1M2XL9KFtzt7Vg3rx5MWjQIJw4YRzQToIQd3d37N+/H7169YK/vz9CQkJw7tw5s+fKsgRowtvb26HKWOPl5aUeRERERNnG5T3AhW3G5b5/Ag9va0kbhL6fkWTcS5pRMDleienft0wFyrY3rjftsySp4kVCrO3nKuNRXdgKlGuHTLf3V22A5i5f2/6cJm9qWRdNMdDK8Wyu0apWrZqhJkv/qFKlCmrUqKHm8+XLp8p16dIF8+fPR0xMjKH2aPHixWq9nqOVISIiIsr2fmgBrHpPm+82EyjXXktW4eqmrTu3MeWMgtaYNg3s9KVxXsbN2pIYqLgm/q4vwYsM6muLn9oDf/QGrh9Fpgu/pI0JljSle0p880rVFlCymck67d6Yci4XnQyKlU7SV0tqjSSQ0bt69Srq1auHkiVLom3btliwYIEay0rSqgcEBDhkmdRIcCZ9taQGz9bnEBERETkMud0bl9hnvUxboMPnQJ5i5mVOrwV+667NS/+k929racxTy144oSBQ5wWg42RtAOQ/+mjbijUEBi0z9tvSk/26pdKoSl9+xGEgdyb3lV/8ijbg8msHgDzF0/bc2Chg/cdAxW5ASK2MOkPKYrbGBukaR0uvQ4cOaNOmjdm6QoUKYd++fejcuTOuXbuGAQMGYMeOHWYn4WhliIiIiHIMScGeNMgSpVsa5594KfUgS988bmy4FmQ9vKOte+oX8yaDScVHp75fNy+gUHXAJw8y3dkN2jQ9WQOlFlBSuh9bZPfTohxWo5VTsEaLiIiInNqDW8ChecCKd4CCVYFhySSmGCu1XjrgmX+A0jYMWGzqxAqtuZ9esUbAoKWWNVrvhKU+vpS+vIy91dAkFX1GO7YE+Ctx7K/Rl8ybRtpKf+6jTgD+Be17fuRUsYHNyTCIiIiIyAlJv6jvGgKxiQMQXzuoDchrOsaV3th7QOR1wD8xRXlayMC9Zsc1yfocEAJEXNLm41NJipFgMuhxVDgyJQiV/mtPzwMu7tDW1R2SviDLlCQaYaCVoz1W00EiIiIicmAJCcCu2dpYWfVfNq7XJ6iwJj1Blj7NuSldgnHetAmgDGacmg6TtemmKVpQ+DgOzQc2fm4ewOmt/Qj4vBRw74I2iPPWb7T1AYXx2NKSTIOyJQZaRERERNmVNBVc/b42L0kl+v2t1dZkRN+nks2Bog2My6bz+syG+v5XKZGytQaZDx78OP2t/hkMrPsYmFrNfNvtM8CmxIBOhJmkvo+8lv5jPjkDqPJU1vQvI4fCQIuIiIgou9r5vXE+qBxQNjHjYNLaJ3vw9AWeW249uYbUGOnlygesm6D1ZZJU6taCoyt7jcuPE7CcWWecD79onJfmi9/UTP55pVqk/5jV+wI9fsiYa0xOhYEWERERUXbpi7VmrJb978Ft4Kuq5tsL18jc85GgTq9aP+P8o7vAxs+0+S8rWTZ1/KUrMLu1fc4hoIj1gO3WSZMyIcb50CeA59eanztROjHQIiIiIsoONnwCbP4S+KwE8HlJ81okr0Db0rXbQ8cpQOM3zNfVNmkKeDxxbC1rKeAlM2JSkqBi0xfpOxfTBB1dpxnno+8b51t9aJxvMQYIqZ2+YxElwayDRERERM5ORuu5sNVy/ct7gHvngTwlMu9c6jxvuS4u2rxGK7nEGNcPGee7z9Iy90mSCn2wZq0ZoexbUrLXHgyUa2e+TZoo6hWoCMTFaH3AQuoAoy9r8xd3Gsvkym/zyyRKDQMtIiIiIme3fy5webfl+qDS2iOrFawMVO4JHJ4PHP+fcX2RJLVHXoljEg3boj1HrHhbmyY39Ou9MODUKu0hgyebin2gTesNA35qD0ReBcp1APr+AXj5adtKNtXGzLpxHChQ3h6vlkhh00EiIiIiZya1NIuGW64vWAUOpUwby+x+CbHWa77cvY3rag1MLGslPbtprZhvPvP1MYnjhqltQVqQpU/Sce8icGq11pdNyJhZoXXS8aKIksdAi4iIiMiZ7Z5tnC9Syzg/bDMcimcuy3XxSQY5jovSpu6ewLH/AZ+XAU4kZjLUJRNo/dhem7q4ASvfM64/u16blu8E5C9nXH9+M/BVZWBuT+Dagcd5RUQpYtNBIiIiImemr6npNQeo9KSWNt0RmQZa3WYCHj7m42uZ1k7JWFsFKgAPEgcrrveiVutkTXRic0Epu+1boM3HWmr1S7u09SWbAT65jeWPLDTOe/ja45URWcVAi4iIiMiZ7f7JfNwqSaXu7YDBVr7SQKFqwNUDgJs7ULGLZZmqvYGCVbXzl0BMLzrSskYsKhz4pKjlPqT5oYc34F8YqNQNqNxDS6IhzQcf3kq9lo3ITth0kIiIiMiZ1RqgjRflmZjcodt3QPtP4HByhwJ3E1POz39Oa8KXlKRWr/msFijpX48wDbr0dAnWjyPND/f9Bix/Uzueb16thqvGM47fj42yFQZaRERERM6s1TjglT1aMOHIJGtg1D3j8s8dzQdVfnALmPuUMSW76bhfu34Abp8x35+1VO/qOAnAuU2W6eMbJqaJ1wsy6bdFlAEYaBERERE5q4QErZ+TtRofR2MtEIxJTL8utk8HTq0ENn5m/flh282XI64AuYsZm0uKdp9oNViP7mjL1w8by8v6xqOMy0MSk2UQZRAGWkRERETO6tgi4NMSwOk1cEqm6d39gi23919knL99ynzbnXPAvQtAu0+BzlOBvn9q42VJzZmMqWWVSbDH/lmUwRhoERERETmra4e12pvkxphyZCWaAtH3gb+eBc6sAyIuW5YxHRsrXxnj/OJXgZ87aPOSWEPSwfvkBTZ+bt73q/Eblv3Z9JkIiTIYAy0iIiIiZ7VpsjZ184BT6Pe3Ni3XQWvuKGNjHVsM/NoN2DJV29Z1mnk/KkntLpaY9LHaO8c475qYRDtsK7B+AnDrhLbc4FWg5fvmx89dFBgbbl5TRpRBGGgREREROZubJ4CZJrUyRWrDKZRqCQSGAv6FAHdvbZ0smypa3zgvNVWSQbFQdSCgkLZOmgaack0MMvX7W5rYD6tIzQx6EUS24ThaRERERM7k4DytT9aVfdpyrgKAdwCcgjTze+2AlsDj1mmg8UhgyQgg/KKxjLuX5fNkYGF908KEOPNt+hqtwBDz9Zd2a+NoEWURBlpEREREzuB/I7Xmdtu+NV+fNG25o5MgSwSVBh7cBq7sNW7LU8J6Ugx53bGPtHn9VE8/CLEMhmwqV377njdRGrHpIBEREZGjkzTou2dbBlnFGwMVu8IpRUcCR/81X3f3nPX+ZirQeqg1G5QBiU2F1DH2v+r4hXF9tb4ZcdZENmOgRUREROTobhy3XOcVAAz8H5A7SR8nZ7H7R2DpSNvKStNBGYg4Lhp4cDP5cuU7adMWYwB/KzVjRJmIgRYRERGRI9v8FTCrhTbf5mPjei9/ODVPP+N8+8RBiit1t15WxseSsbJmtdKuR/4Kxm36vmpCgqsxN4BGJgMTE2UR9tEiIiIiclQyztSaD837MOnFx8CpSe2Unpsn8NY58+DLVEgtbXr9kJaJcMASYHJpbZ13bvOy1pJpEGUB1mgREREROaI7Z4FJRczX+eQxzjd5C07t+mHjfP5ygG9eLYiyRvpm3T6tzV/eo/VX06v6VAafKFH6MNAiIiIickSP7lquM+2PdXYDnFq59sb50Hopl900BVg4xLi8YZI2bfIm4OKSQSdI9HgYaBERERE5oiKJzeVMSWY9fTY9SQ7hzEKf0Ka1BxtTvidHsg4mNXSjlvSCyEEx0CIiIiJyRJf2ADWeNS5X7aNNW40DSjYHOiQmkHBWMnixuH0q9bK5i1mui3lo/3MisiMGWkRERESO5uEdLdPgvl+BrtO0dQf/NGbW6/+vVrvlzFwSa7HObUy9bHAly3VJBygmcjDMOkhERETkSC7uBA78YVwuXBPZkmQYrNAZKGvSVystNVqevhlyWkT2wkCLiIiIyFFs+BTYMNF8nV8BbRropAMTJ8fVFej9m+1lSzSxrfaLyEEw0CIiIiJyBJLCPGmQVakb4JNXG2Mqp48P5e6d1WdAlCYMtIiIiIgcwYOb5svP/guUaq7NyxhTOZ2+Zs+WdPBEDoCBFhEREZEjuH3GOF93iDHIIk37z7VBmo//D6g7lFeFHB4DLSIiIiJHcP+6Nu0wGaj7QlafjeOR5BeexYD6w7P6TIhswkCLiIiIKCslJAARlwFdvLZcvDHfD6JsgIEWERERUVaKvAp8VVmbb/AKUKA83w+ibIADFhMRERFltEPzgXObrG87s844H5nYfJCInB5rtIiIiIgy2j+DtenYcMttGz83zhd9gu8FUTbBGi0iIiKijB4fKyUVu2pTdx+g1iC+F0TZBGu0iIiIiDKSiwuQuxjgHWh9e8QVoEwboNfPgCt/AyfKLhhoEREREWWkE8uBexfM1/31rNY3a8Bi4PB8wK8g4JmL7wNRNsJAi4iIiCgj7ftNm+YrbVx3bLE2PbFCm1bozPeAKJth/TQRERFRRvL006ZD/rPss3XtYGIZ1mYRIafXaK1fvx6LFi3CrVu3ULZsWQwePBhFihQxK3P+/HlMnz4dFy5cQJkyZfDqq6+iQIECDl2GiIiIKMPGyfIKALwSA67Yh8ZtJxNrtDx8ePGJcnKN1rvvvosvvvhCBStt27bFrl27UKVKFZw8edJQ5ty5c6hVqxbOnj2Ldu3aYefOnahdu7YKzBy1DBEREVGGuX0GiI4AVozWlqMjLcu4e/ENIMpmXHS61HKOGklwEhQUZFhOSEhA4cKFVQ2RBGFi0KBBOHjwoArCXF1dER0djdKlS+PZZ5/FxIkTHbJMaiIiIhAYGIjw8HAEBASk5foSERFRTvbwDvBZCeNy9afl9gvYn9hvS6/vn0C59pl+ekSUdrbGBmmq0TINssTVq1cRGRmJUqVKGdYtX74c3bp1U0GN8PLyQufOndV6Ry1DRERElCGu7AMGLgMKVtWW9881BllFamvTqr0ZZBFlQ2lOhhEWFoYnn3wSrVu3Ro0aNTBhwgT07t1bbXv06BGuX7+O0NBQs+fIsjThc8Qy1kitl0Sqpg8iIiKiNLl2GPitO7BlKlAoMdAy1ed3bRofywtLlA2lOdDKkycPBg4ciKeffhp169bFV199hdOnTxsCFOHr62v2HD8/P0RFRTlkGWsmTZqkqgP1j6SBGhEREWVTe34GxgYCl/c8/r5+aK5Nz/0HuHlabvdLTMx1ZAFwcefjH4+InDvQ8vf3VzVaEmwtWbIE+fPnx/jx4w0BjJubG+7evWv2nNu3b6sAzRHLWDN69GjV5lL/uHjxYlovExERETmjZW9q023TH39f8THatHxHIK+xm4VS/RnAxcW4/ODm4x+PiLLPgMUuLi4qsYQ+EHF3d0fFihVx4MABs3L79+9H1apVHbKMNdKPSx5ERESUg9w5ZwyO2k16/P29dx3Y+BnQ4BXAOzcQ8wDYkJiIq2JX87IcR4soZ9do/fTTT4iPjzcsS1r3VatWoWnTpoZ1ks3v77//Vn25xKFDh7By5Uq13lHLEBERUQ4WtkNrLvh1deO6Ve8//n49vIGWHwA+ebTaq0YjLJsN6gWVffzjEZHz1mhJYFWyZElViyWJJqRmqF+/fnjnnXcMZUaMGIHt27ejWrVqqtZoz549KqiRPl2OWoaIiIhysGOLjfMNRwBh24GDfwJdvgHcrfStSs3RxcDfzwI1ngFajQNyBVmOlaWvwSrdCji9BvAv9LivgoiceRwtIf2dpCmeh4cHypYtq/poWXPkyBFViyRBmQxw7AxlksNxtIiIiLKx7d8BKxJ/NB60HDj4N7DnJ+DNs0CufGnf39TqwN3E7MYvbgWCKxm3LX8H2PEd8PoRIDAESIgHEuI4YDGRE7E1NkhzoJUTMdAiIiLKps7+B3gHAGvHA2fWaetqDdSyD766D8hbMvV9nFgOhNTVgjK5rRqX27jtnYva/vWiI7WmiiWbAW6P1VWeiLLTgMVERERE2UbEFeCXLsDMZkCgyVAuvom1WFE2jKMpQdMffbSmgmp5u/l20yBLePkDZVoxyCLKARhoERERUc5056xx3jRRhb6/VLQNgdbtU9o0KLFbwv1r2lTSuQ9cZr9zJSKnwzprIiIiynkirwG6BG2+XAetiWDVPkDh6kDhmkCj14GAIqnv5/4NbVqzv9YscN5Abfmlbex3RZTDMdAiIiKinGdOF+DWCfNkFd2/N24PqWXbfuKitamHLxB937jeNMMgEeVIbDpIREREOYvUQt0+DRSoaJ4RMD3iEwOt6U8APiZJMIgox2OgRURERDnHkteAyWUAXTxQb6j1Mhe2AtOeADZ8kvr+pNmh3oSCQKXuwNsX7He+RDlcVGw8Sr27DE/N2AZnS5bOQIuIiIhyhvs3tbTtevnLWy8X+xC4eQzYMAk4vyXlfYbWNV8+sgDwSj7dMxGlzZ87wxCfoMPO83dw+0EMnAkDLSIiIsr+7oUBk0ubr5OkF9a4eRrnZTDhlPw73HKdK2+viOzlemRi81wAf+26CGfCvwRERESU/QWEAMUba/Ov7AXGhgPuJgGVKTeTRBbxqfyCHrbNjidJlDNFRMWi9/fb8NOWc7h45yFWHrmmmgnuPn8H3204Yyh34OI9OBNmHSQiIqLs7eIu4Pj/gF4/A7dOAflKpVzeNACTmrDkXD0I3DHeBCpegY95skQ5z3cbzmDHuTvq8fnKE3gYE49qobnNAqu2lYLxeuuycCYMtIiIiCh7WzMWuLBZq9Eq0yr18qZNB28cS77cf58a5wOLAuFhQJWej3myRDnPdya1VhJkCdMgq3xBf8x4phZcXFzgTNh0kIiIiLIvGdtKgixhS5AlTAcqjotKvlxwZW06dBPQ/19tPjAk3adKRJYmdKuMFSOaOF2QJVijRURERM4nIQE49DdQqiXgl9+4PjZKGyxYf1N2ZGHa9206HlbJZsmX880LFKoG+OQBcocCb5wCcpmcCxGl6vcdyTfPfalZKTxdrxicFWu0iIiIyLns/lEbIHjfb8CCF8xrryYEA+NyA6fXauuOLtKmb51L37Eq97C+/sZxYPlbQJm2WpAl/AoYAzwissm7Cw8lu61fvaJwZqzRIiIiIufyv9e16a0TgE9e4/pbJ43zv3UHGrwCnF6t1UpJ7ZOtYh8lvy0uBri6H9gyVVu+uCPNp09Emtj4BJg6Nr4dDl8JR41QrVbZ3c2564Sc++yJiIgoZ9HpgKByxuVHd7R1omAV4CWTwGfrN9q0399pO4aHD1DneW1+42TzbavfB2a31rIYiiv70vEiiEgsOXAFeu91qAAfTzfUKZ5XBVjOHmQJ538FRERElP1JMLVqjNYsUDL7Ve0D+BfStt0+rU3dPIAC5YG+fxqfJzVe0mcrreoO0abxxsFSlXObzJf7zE37vokIMl7WyL8PqCvRt24oXmhSMttdFQZaRERE5FiiwoE/+pnXFt09b6yhkrGtun8PVOmlLX9bGxgbqD22TQeKNzI+r2b/9J2DPsV70maEbia9LtpOBEo0Sd/+iXK4DxcfMcz3qJk9s3Uy0CIiIiLHsmsWcGIpMNMk419AYeO8f0Ft6pvP8rnrJwIeuYzLUsuVHvpasG3fGtf9Oxy4qv0Cr5zfkr59E+Vwdx/EYN3xG2rezdUFtYrlQXbEQIuIiIjSRlKoH/gLuLIfiHlov6t3aL5WK7V2vOW2m8eBZxZo6dT1zfqsZQTsMQtwNbm90TcvTCs3K80N9/9mvizBIBGl2YyNxgGKN7zRzCnHyLIFsw4SERGRbW6fAR7cBG6eAJa8qq2r1B3o9dPjX8Fbp4F/BhuXXVwBXQJweIEWLP3UTguyhm40lrFWo1WunTZ9bhUQ9wgo0TR95+Oe2HRQ79G99O2HiMyEP4rFT5vPq/nZA2ojNK8vsisGWkRERGSb7xpqwUvoEyYrEzP+PY7oSOC6yVg6798CFg4FDv8DzB8ENH7DGNSZenjbOC8ZB+uYjKlVtN7jnZNp80OREGeclwGKH90F8pd/vGMQ5QAJCTrE63TwSMwiuPbYdcTEJ6BoXl+0KF8A2RkDLSIiIkqdBBYSZImL27XpkA1A4RqPf/UmhQAubsB714CEeK1fVcsPtUDLtJ9UrQHmz4szyQhYrZ/l9sdh2vxQxMcY56Vmre9fgKub/Y5HlE3ciIhCdFwC8vl5wtfTHe/9ewiL919B8aBcOHIlwlCuQal82bbJoB4DLSIiIkrZvt+ADZ9o841HAQ1HAFH3gNxFtbTr8kgamKSVLh5w9dDGsBLXDhq3xUVp27y1QUwNgkoDo05ozQxz5c/Yd9E00AquDHh4Z+zxiJxoLKxCgd6oXTwvpqw6gW/WnTZ+VQK8cD1C+0HENMgSL7cojeyOgRYREREl79JuYNFw47I03/MO0B5nNwC/dAU6fQnUfi59VzHiqnH+547A4JXafGCoZVlrv37rMxBmRiZEvYAimXNMIge358IdvPKHNgxD2WA/nLx+32z79cQgy5qQPNm3b5Yesw4SERFlJ3cv2G9fJ1cBS0cal4fvBApWthxratmbQJxJjY+Ij01536fXao8vTPo5lW1jnC9cHRi82hhwJaSyv4x255zJvDFjGlF2tvHkTVT5cCX+2hVmse1mZDR6fLfNsJw0yErJ1ndaICdgjRYREVF2EXEFmFpVm+/7J1Cuffr39Xsf4ORy43LZdoBfAesp0CVRxJ6ftDGmClXX+i5JgPbiNiC4ouW+T60B5iZJzf7SdqBABfN1oXW1por/GwF0mIxMJ8fMFaTNxzzQEmR0/gqo2DXzz4UoE209cwsF/L3R/8edavntfw6hV61QuLoaa5VnmqRoN/V2u/IonNsb7y08jA86V0SZAn6Ytv40zt58gGWvNYa3R87p28hAi4iIKLvY+Llx/tQqY6AVfR/wzGW96Z1p+nLph1WpG5CnuHmQVf1p4MnpyQ/qq44RCRz8C3h4Bzi7Xlt3aaf1QMu0KaI+TXvSIEuvWh+gbFvrqdwzmozdtWwWUKErEPsQ8PIDqj6V+edBlMHp1u88iEGJIC3T5pEr4ej3ww6Lcgv2XUb3GkVU0LTuxA3sC7Mc8uDTHlXQu05RNd+1urGJ7awBdVT2QdNALSdgoEVERJQdSKCz+0fjsoxBde+iVht0cRfw4mYteUVyFgwBTq3UAqP8ZY3rx4Yn/xzTQGvdR9rUNEDzS6b/1P1r2vT5dcCsFkCrsckfQ5Jj6BNkZDZ9vywZmFgGZvbI/n1KKGeR4KfexDWIik3A30PrY+WRa5i92aSZrIlJy47hjXkHLNaPal0W3288i951Qg1BljWuOSzIEgy0iIiIsoNzJgP5itgo4NduwO1Tids3ATWeTrnZoVj8qjZI8Mu7LbP8JaXvo5Uc0/5celK7JiToC6kFjLlhHrA5oqhwIPaBVitI5OR0Oh2WH76mMgX+vPW8CrLEU98b+1tZc/tBkn6YAF5rWQavtCyDYc1KGcbJIiMGWkRERNmBjGdV/2UgtB7wd38tMNAHWULSkcu4U6ZBTdgO4EeTBBTS9+joIq3p3/oJQK+fUz6mfyGtH9aDm8AvXYzr23wM1BumjYdlSpoVflZCmy9aX5s6epClv7ZS6yZp5Imc3OIDV/Dan/ttKvt13xrwdHPBsN/2Wt3er55Wg8Ugyzr+xSAiIsoOAgoDbScAFbsAXv5aU8K8pYzb5z8H/NFXmz80H7i0B9g+zXwfppkDjyxM/ZjunlpTQ9MgS8jxJeugNLczdfOEMaDr9j2cxs4fgLDtQPlOWX0mRI/t5PVIm8qd/6QjulQrjHaVC6mEFnrF8xmb0AYHcDy5lDDQIiIicna3TgP/vKA1DxQNXtEyAt6/YV7uxjGtVuufwcDqD4AqiYkdijfWsgp2+Rro84e2btjmtJ9H8/e06ZLXgImFgOn1pBOIsTbrp3bavGQmTCkxh6ORjIrbpzvXORNZIQMKT1tvni1w57stUTK/1iz2qdoh6FUrBD/0r21WZt6w+qhZNDfeaFMWQX5OUAvtINh0kIiIyFlJEDM+j3FZsvPpa6NuHDWuD64CRFwG8pUCds3W1l3YDDR42TLZRfkOKSfASEm9oVqTQ717YcCRBUCVnsDaccb1zhKwyODMcv56i18BunyTlWdElG6/bjuPb9adNls3f1h9FAjwxqoRTeDq4pJsworcvp5Y8FJDNb/l9G2+CzZijRYREZGzurzHfFkfaJkGWSWbA81HA4/uAOc3AStHG7f90ceyeV96jDoBvLQD8A603BYdoU0fJt6c1XsRqPMCnEKFzubLtzlQMTmfradv4dMVx/H+oiNm67/pWwO1i+dV8+5urjZnBaxUOCBDzjM7Yo0WERGRM9rwKXDrJND6I8C/oJYEQ/pGmZLmg/3/TXk/m78AWox5vHOR48tDvHsFuLxXy2K4cIg2yO+dc8CxJdr29p/AaVzanbYsi0QO5szN++g3y3JMrJJBudC0XP507fPlFqVV1sLKRRhwpYaBFhERkbNJiAc2TNTmm7xhOdhvwxHAlq+ST+fe/jPg7H9A+EWgzvP2PTdJgV6isXaOMrivNBNcn3iuziZpshAGWuSAtp+9jd93hOH9ThWR398Lc3dcwIeLjmDFiCYY9pt5rff4rpXQv37xxzqeNCPc9FZzp2kBnJUYaBERETmbbdNSvvkv3kgLtApVM657bpUxlXuVXlp/qozk6macl2x9Vw9o6eedmQzoTORA9obdRZ+Z29W8u6uLCrbeW3hYLbf64j9DuY5VC+HFpqVQuYiV5r3pkBMHH04PBlpERETOQPpSrXgH2DvHuK7rNC3BhUXZxEGBPY0pmVG0HuBfGIi8kvpAxPZydLGW5bBqL6DfX3B6pVpk9RkQmRkwe6dhfsG+y7jz0HJQYf3AwmWDkzQtpgzHQIuIiMjRXT8CfNfAfF1gUaB6Mk0DizYAqvYGSrc0Xy8p2x/dlZ+jkSk2fKINnBwdDpRuDeQpBqfSY7aWCl+v45SsPBsig7XHruOVP/bhYUy82VXZcOKmxVXqUTOEQVYWYaBFRETk6Fw9jPPPLAACQ4E8xZNPk+4fDHSfabk+Vz7tkVkCCgGn1wBLR2nL6U0bn1WK1jfOO9u5U7YVFRuPwXOSJGpJol+9oqrflnijbdlMOjNKioEWERGRo5JBfi9s0fo4df4a8M1rWUvlyLycPCuZjAOmJ2OTVeqWlWdDpKw5dt3sSsjgwi/8Yh541S+ZD60rBMPP2x2FAn145bIIAy0iIiJHdG4TMKeTNv/0fKDWADgdyUDozKSZpd6DW1l5JkSIjovHpGXH8fPW8+pq1CiaG1N6VUPJ/H74vGdVvDn/oOEq1S+VD0F+XrxqWYwDFhMRETmaG8eNQZYMAuysSRhMk3G0+xROp0QT61kUiTLZ+VsPUG7MCkOQJT7tUVUFWaJX7VCz8gyyHAMDLSIioqwiY02tfA8YGwj80hXY+i1w/waw5FVte+GawFO/Ou9NflBpbRpSF3hiGJyOlx/Qb55lPzmiDOp7tf/iPRR/Z6nhMXHZMbXth01nzcpWKRJokeCicZkgvi/OHGgdOXIEAwYMQPHixVGkSBE8+eSTOHxYy9Vv6u+//0bVqlURGBiI2rVrY9WqVQ5fhoiIKFNERQAH/gR0OmDJa8C2b7X1ZzcAq94DJpcB8pQAXN2B59cAJZs67xsjmQ9FkBN3xj/4pzZ1Y6BFGWfPhTso//4KPDlti9n6mRvPYv2JG5ibmNgiyM8Tw5qWwp9DnrDYx8+D6uKbvjVwdHxbvlXOGGiNGDECrVq1woYNG7B9+3YEBASgWbNmuHr1qqHMmjVr8PTTT+Pll1/G8ePH0b17d3Tu3BkHDhxw2DJERESZIi4G+CQUWDgUGJcb2Pertn7QcmPNiShSC3jtgPPWZOlF33f+vlqH/9GmEvjmMDqdDs/O3oFmn6/H8WsRZtuuhUfh1PXILDu37EKuY78ftqPHd9uSLTPop12G+bWjmuGd9uWRy8vy8+jm6oLO1QrD1zPnfVYdlYtOvkXpFBUVBX9/f8yaNUvVdIm2bdvC29sbixYtMpSTWqRKlSphzpw5DlkmNREREao2LDw8XAWXREREaSL/anfNAoo3AuY+BYSbZLOr2R/o8o3WjPDTEtqYU29fAHwyaVDhzEjoUbgGMGQDnNLU6sDdc8Cr+4C8JeHMiRTCH8WigL+3zc+ZvfkcPvrfUePygNpoWSFYjeGkTy++YkRjlC/Ie6P0iIlLQNkxy61us5ZJ8JUWpTGqTbl0HYvsy9bYwPVxDxIfHw8/P60jnsRsW7ZsQfPmzc3KtWzZUq13xDJERESPLbnfLGV9bBRwYSuw7A1g+hNA/3+BPr8DtZ/Taq3aTNDKSu3Vm6eB929ljyBLhNTWUtO3/wxOq1A1+V0aCAiBszpyJVwlUqg7YS0OXrpnsf2vXWGYtemsum/Si4iKNQuyhARXDT9ZZzaG08FLHF8sPR7GxFkNso6Nb4fzn3RE64rB+OW5umbbyiTpk0WO77HqFkeNGoXChQurWiMRGRmJBw8eoECBAmblZPnatWsOWcaa6Oho9TANKImIiKy6dQr4tjZQtj1QuDrQ9G1tIOGrB4HvGwPFGmpjYQkZCytfKe1RvqPlvtw9s9dF9vAB+syFUwsoIhEzcP8akLsonEl8gg6l3l1mtq7Lt1uw9Z0WKJxbG1tp9/k7ePufQ4ZMdU/WkNcLPG8STJUp4IdTN7RmoJfvPTLb31vzD6JHzRDVbC0lhy+Ho0RQLqtN3nKi1/7cb7Ys1176V/l4GpsLly9kDKwGNSyOTlUKZeo50uNL96d9/PjxWLBgAVavXm2o0dJzdXW1WE7aQtHRypiaNGkSxo0bl+x2IiIiRf6X/Jo4iO3J5dpjwySg/yJg3cfa+rLtjIGWM46FldNd2adNjy/L8syJJ69HYu72C6ofTu3ieVMt/9qfieeeRINP1uGjJysjKiYeExKz2okRf+3HrM1n0bNmCHaeu2NYv2JEE4uAzdTKI9fQwUoQ8N/Jm/h23SnsOn/XkBXv18H1kFNduP0A7/xzCKUL+GH1UeOgwwMbFMfYLpUsykszT2mu6e/tgbolUn+/KZsEWp988gk+/fRT/O9//0ODBg0M66W/lq+vL27evGlW/saNGwgODnbIMtaMHj0aI0eONKvRCg01H5+AiIgIy94Ewi9qF8LNC4hPbA1x9j/gUmIH9ideAs5t1JrRkfPp9RPw32daX7os9vY/B7Ev7B7mbLugmpiZ1n7ITfxnK0+o8ZaerF4E3WoWwf8OGpOVJfX+v5ZZo8XhyxE4fNnYZPCPF55ItbZKgjJrgdaAH3eaLW86dUv90O0iNb45jCQTaffVJjW/7extw/ovnqpm9drpSZ84cl5p7qMlAZbUZi1evNii75N8cerVq4f//vvPbP369etRv359hyxjjZeXl+rYZvogIiKyqM3a/7s2/8peYPQl47bYh8Z5N3fgmflAs3d4AZ2Rf0Gg0xeAp2+WnoYkoJAgS2/72dto/Nk6zNx4Bp+vPI6mn2/A0oNXceRKhKqlaj7ZmHxkap/q2PhmcwxtkrZkHt8/Wwv1S+VT85WLGO+FJnSrjO2jW2JWf+3HAxlEVz/u0/3oOEOiB2uG/roHjmTL6VtYcfgawh/GYtWRa9hx9rbVVk8/bTmHkqOXqj5qUt4WCQk6vDX/gLou+iDLlNRMdq8ZAm8PJ88uSvap0ZoyZYoKsqQmq0UL66PUv/766+jRo4cau6pTp04qs9/u3bsxdepUhy1DRESUJnfPA4/uaTfhZVprfa7E2MTEADdPaoMNV0scR4ooHb5ZewpTVp+Et4cromLNA5dBP2s1phOXHbf63MgoLeB5r0MFdK2u9bsa3aECjl6NUDVLpioVDsD/XmmEcUuOqqBJr2nZ/Ib5t9qWR/8fd6Jj1UJ4ul4xtU4nfdeS+HXbBbzYrJRZoofJvarhjXnasDqrjl7HvYcxyO2b9f0RN5y4gYEmqdP1An08sOPdlhjx537ULp4HbSsVVNdG30dt2G97cGZih1Rr+kYvOIS/d5v8AGOif/1iGN+1sp1eCWWL9O4+Pj6IiYmBh4f5oH1jxoxRD72ZM2fio48+wuXLl1GyZEnV1LBnz55mz3G0MilhenciIlJiEmuqZFBhyUT39nktW2AObApFtpOaje83nkXVkEA0LB2UYlm5LTt0ORxj/j1sNaNfAX8v3Ig0JuxKzbbRLVAoUEt8IaJi4/HjlnOIj9ehe60QzNhwRiVaKJlf628vNTrRcQloYhJk6UmQUTDA2xBgWEu2YY1k0fti9Ul8vfaUWh7TsQKea1gCrqkEKvYgNWzymhqVCYKXu7Hm6FFMPCp8sOKx9i39pvR92cZ2roiBDUuYbZearKRkMOH7UXHI7++VI5tQZhe2xgZpCrQkE5+14u7u7uqRVEJCgkUiCkcvYw0DLSKiHOzQfOCfwZbrPf2B0RcZZFGKN/kJOh2+/+8Mpq0/Ywg6xNXwR7hyL0rVJj0zaweqhATiw86V8Mny45jxn1bWmmn9amL473st1kvN1bP1i+HMzfvo+PVmte7PIU/giZJa07+MYi2YMLVyRBOUK+ivEnm0+XKjWte9ZhEs2HtZzb/fqSIGNzIPUOxl3fHreO7n3RZjUEmzxoofrEBcgvk9bc9aIZi/x3oNlAjN64OLd8yzLpqSMcXm7b6E4c1L47+TN/D6X1ot3rpRTbH7/F00K58/TeOYkeOyNTZIU9NB6buUFrYENY5WhoiIyCAu2jzI8grUBhQWXaYyyMqmroVHwcvdFXlypb95W1x8AlpM3mBR+yTBl5+Xu0oUcfL6fbSpGIzdF+6qx7Yzt3H8WqShbK1iebDngpaxT0imwKblLGuahKROl74+pfL7oXCgN0Ly+GZ4kJU0aLJGgix9ing90/IyVlfSQEtqyp77eZd6TVL75e6W9vu3Hzefw3iTccC+WXcaXaoVVu/p8Ll7DUHWux3K4/lGJQ21ax2rFDI0y/R0dzXrayZJRiT9fcsp5n3/9fT9sGSgZ1PF8+Uy1BhSzsLBDIiIiJIjrTgqdQOOLAQ6TwVqDQQS4oH4GG2MKMp25CZZbv7LBvup2pj0Nu86f/uh1SZ+lT9ciSdK5lVBlr7Pkp5pkCW1J/OH1cfDmHhVG1Q9NHeK59KygjZmqARbG95sDvdMaJYnBtQvrgKn8gX9VUCx4ogxUUQjk2aScu6vtyqLL9ectNiHNGfUJ4SQAFUCJEkNL48qRQLRo1bqg0Wfu/UA/t7uajwqfcr5pFon1qiZ6lu3qFkTxublC+D4R+3g6eaq1su5yXlcufcI/eoVVc0PR7Qqg6/WnDI0GVx84Ar2miQqMfXzoDqZ0kSSHBMDLSIiImtOrQHm9gCeWwX0+tm4XvpkuTLIyo4km5wEWUICoVv3Y1RfmrSSZoGDfjZPbW5q+1njGFXWtK4YjC97V1fBiQzwW6NoHrPtU3pVw6h5B1Asny/e71gRNYqaB2FSE5NZqoXmxurXm6BgoLfq93TvUQzqlsiHIrm9VVY9U2WCrdfq9J+9UwUxUls0de0p/LLtgmGbvE6pxdMHUElJlxYZTLntVxvV7yKTuldRNWE7EvtOSWbEdxceshr0HhnX1uoAyqZZAGVekmEkDS5lf6F5fDGgQXEUy5fLUAtmqm7xvGhWTguAKWdioEVERDmH3IlFXgW8c6ecrvv6US3IEpf3AEVz7iCrzkCami05cEUNuDuydVm82lKSldhOAoTGn63HrfvmN+PXI6LSHGiNX3JUJZtISpJLbDxpPq5nUsObl1I1YZ90r6KaFyZHanhaVQhGoK95crKsUiZYax4oA+v+OST54XNMmw+KIrl9VIKNnefvqIfUSP28xZj1UK/2x2vQsnwBfNOvBnw9jdfl7M37aJGkGZ9k+kta07ezYis1QPALv2j9tcSbbctZDbJsIc0PJ3arYlYLNqp1WZUh0lTh3OyPldMx0CIiopwhbDvwY1vj8lvnAN+8wOm1wNF/gQ6TAXcvrWngdyY3i6WsD2fiqCKiYhEdm5CumhhndPHOQxUk6Ul2u6J5ffHP3ku4+zAGc59/QqXrTkmLKRssgixxNTwKlYsEWvSxkv5bHlb6Dck+rAVZfeqEYkK3Kli0/zJG/q0lSBAHPmyDauNWqfnFLzdE1ZDcNr5qOEyQlRalC/ipmqvfd4SpQOV/B6+oQEtv8BxjICR9p0xT1689fkMFqu0qGwf33XzaPE19UpIhUV/TJ7WEswfUVglCq4XkRr5kasjS65WWZTCsWSnExesM2Qw7VTWv0aOcJ01ZB3MqZh0kInJi8wYCt04BBSoAh+YZ17t7A3FR5mWL1AYqdgFWf6Atf3BXMinBmeizwC1/rTEqFApQtTVzd1xQ/WdaVQxGdiOD9qaUCU5Skb/YtBRi4xPwVrvyalmuiY+nm2p29tH/jlkER9IvSFKsi4+6VsKz9YursjLmkvTXER2qFMSyQ9fwdd8aaFspGFvP3MagJGMySf+cvLk8Ub5ggKE53+Cfd2FP2F0sHt4IRfP54kF0HB7ExOXIbHQpZSw88XE71e/KdKBfSbzRoFSQCpokeH5+zm6sOWbs45aU9LXKisGA5TMiY4Xpxy+j7CdD0rvnVAy0iIicVHQkMCmxI32e4kD0fWDUceDmcWBGo+SfN2i5Fpj5mPeNcXTbz95Gn5nbzZpHfb7yhGF553stH+uGftr601i47zKmP11T9YOxVquTmeQWpsTo1MdxslWp/LlUs8O9F+5ijkk/Ial9kX4+tkoprbqMqfUwNj7FpoE5RfPJG1QwJSTZx/6LWkKJb/rWMPTvevWPfSrZRGpp1vVp83efv6MGd65eNDevMWV5bOBcP9MRERGl5sp+4KTWHAu7f9Sm7T8Hhu8CRh4F3DyAgsb+FajzAjD6EvDkd8Z1p1Y5XZAltTSmQZYwDbJE3QlrLZ6n/7213VcbVQ3D4cSaHP02ybommeCk2Zbs7/SN+2o8pDLvLVflZYyorCIp0fV+f6Geqn1KrzUjm2DtqGaqFiJpdr+0BFm/Dq6bYlp1yUDHIEvz91CtiW7v2qFY8GIDDG1SUo0HZppEY2qf6pjxTC2za5g0yJLBj/VqF8+rBifmNSZHwBotG7BGi4jIgTMD+hcEClbWli/tBma11OaHbTbWWr1xGvBLMv5QzEPg1gmgYDWteaD0zYp9qNWAeeQC3jP/Fd2RSfOzSh+utKmsZKyTAXGl+ZU8z7TmRk/Smnf+drPZGEIp0dcmZCQJ+CYsPYa/dl1ETHyCSo4Q4OOhath61QrB572qqTKD5+xSWeCkFuphTBzmbL2AT1cY+/ok9WqL0qp/jWntnGQfHPbbHqvlN7/dHOuP31ApyP944Qn0nLHNbjWGlLymn6/HhdsPs+zzR5ThAxYTEVEOFB+rBSEPbwFfJtYYjDgEbJsO7J4NjDgM+AdLmyjgzlkgqLQWxCSX1U8GAV4wBKjWByjTBlg7DqjWV2uqlxZHFwN/P6vNl++kjXf1yFjDYdY00NdKDYOcX+Ea5mnbvfyBukOAKGOtjjPQ9xsS+XJ54vaDGLPtQX6eKlW5Pl22kJTYyZFU2WkZoPbQpXBUCTFPGvE4lh68iqlrT+Kd9uXRorzWr2z6hjP4dfsFs+QIer1qh6qp9MeR5Bd6kqHuxWalMKRJSby/6DAeRsfhkx5VU+23I1kMrdn7fmvV50r6bMlDSLAlfeAk2yGDrIzTp05Ri4A5t68H3u2Qxr8bRJmINVo2YI0WEWV7t04D39aWxmLAm2cAD19joDQ2lRvo1h8BeUsCN48B6z7W1uUuCjyzUAu6kpJ06T9YyeT39Hzg7AagSk/zACip2EfAhILJn4v0xdIHYPnKAN2+B0LMmx5lJxJkDfhRG7MpOMAL295piZLvGvst/Ta4HioU8ketj9ekuq9m5fJjw4nkU5B/1bu6GutIr8XkDTib2MdGanpk0NamZfKnOSOeNFEc8+9hzN0RZjUl+MTuVdRrlMF7k5IU4XLs9A4sbE1kVCxaf7ER1yKMyVLaVy6I75I0YaPMI33bpqw+oUZokGyDPWqGoH/9YnZ934lsxWQYdsRAi4iyjdgo4PxmoERjLZW5CL9krKkyJcGT1FClV5dvgZqJAY/exV3AT+21fUuzPUmdfmad5XPHJlOjJGV/7Wa+rmh9IGyb+XOPLQH+egao+CSinpyN6Hgd5u2+iDYVC6pMb9mBpMaeuz0M287eNqz7d3hDlVTANJubvllVyykbcOamFhSZWjS8IcoV9Fep0AsF+pg9d8e7LVUCDEmX/nzjkhbP/WbtKYuxgyRRwdd9aqjmieO6VFYD2aZm0rJj+H6j7Z+1T3tUUbVH+y7ew0vNSmVIZjnpl1b6veWG5c97VjXUnBFRzhbBpoNERKQ8uKWlN5f+R+s+Aq7s08aMqvM81KAyRxdp5fwLAx0nA3/205b1QVbZdsDJFUD7z4DyHYHAEODhHa32Kl8pYOW75hc6f3ktq9+jO5ZvwKmVQEIsUKUXsP5jIKSu9UArObokfYb0Y2FdO6Q1FWz4mra+XGKfjaP/oubeLngI7Wb/46XH8PGTlfF0vaJYeeSa6ssjKdCdhdT8xCXo8MysHdhxzvz6NiiVTwVZps0HpbZHTxI9SB+msDsPUTq/n5oWzu1jSDsuQZYY37USPlh0BJN7VUNwgDfGd03s/2bF/Zg4i3WSqKDb9K1qPrePJz7tWdWiWd5Xa07im3WnUTbYTx1j06mUx0PSk2Z60gxSP0CuDBSbUdzdXFUK8fBHsWq5TvG8GXYsIsqe2HTQBqzRIiKnJU3xfukK9JsH/N7LfFvr8Vpgsuhl4NB84PXDwOelzMvkKQG8tj/lY3wcrI1HJQknYh9ofbqkGWLjN4CW71tv8td9FrDgeW1+8BpgditjuWbvAk3f0oJAU1JLlRAH+BcCIq5ofbJSajaU2OSxeNRc+XeX4kuQwGTP+63hyIMQ34yMRssp/1ndvvr1JobgQ0jmwKlrT+GttuXM1ttbSkkjko5lJE2/rkdGof4k64F1Hl8P7PugjVmN0uzN5zBpubFfzrHx7dT4V5ll65lb6PfDDjV/8uP2hqCUiHK2CNZoERHlcGf/04IscXq15XYZlFc/MG+hakCuIKD6M8D+34COXyA+VzDiyrRDeEQUouMSEJo3mSZ3rx0AYh4kZvXLD0QmDiAqCSWkQ4U065Oaq3sXjc8p2RSo/zJQsrnWH0v6dBVrBHQzSbFu6u55rSmgeHk3UNSY8CA5EwtOxbUwadaWeh8Oqf2R4KRyEfsldHhcEmhExSVgztbzFmnahdS2DGxQXCWnkJo5U/I6fugvfe4ylgzUO/PZWhjya/LB1i/bzmNIk1KYuOwYZm02HxjYNKnBr4PrWdQoDW1aCoMalsDIv/erQYQzM8gSVUNyw8vdVdUMMsgiorRi1kEiouzgxnEtWNEnsLi0B/ilizZfsKrWnE+4uAHtPwWWvWH+fGlKKDpPxVSXfvjyH23gUMCYMnzGMzXRtlJBlfygRL5cajwgxb+gqm15+fttqjmbF2Jwwltir7vwPLdRO4+SzbTaNdF2EuBXAGg7wXj8Vw8YU6zfv6H1H5MmgaavT8/K+Fax8QlwdXGBm6sLLt19iEafrteCPuTH/15pZBZADf99r8pql5RkjpvU3byZmz1Jjc6KI9fg7eFqyKQnY1L1+G6rap7WqHQQpj1dE0cuh6PfLK0WJTlNyubH5F5VszzLnSQiaFMpmcQkib5acwp5c3mZBVnyPp2e0B4z/juLkvlzqc9VciTA+bZfTWQFGYtp95hW8HLP3ACPiLIHNh20AZsOEpFDunEMyFcaWDMW2Pattu6DO1qa8r/7a32vqvXTaomiI7XxoUo0BQYsBma3AS4ab+Z179/C1cg4FAzwNstYl5yaRXPjq941kKDTqZquUkme84vHJHgWq4Mnrvyq9cnSkxqsZxZoQZUV987tQ+45zYAKnbWmjdJPrFAN4PPERAxP/QJUTKylS3Tu1gPVZ+nyvUcY0aqMurHXk9ezbXQLq5nJftpyDuOWHLV6Hq+1LIPXW5eFPWqlLt19hJ3n7+DHzedw/FrkY+2vVP5cKuGFv3fasvplNBnMeOTfB/D9s7VU4CikBuqQyeDHenVL5FXJMmxJkkFE5IiYdTALLiYRUYaJigA+Scx4Jk3uJJnEX88CXb8xNg8UFboAHT4H7oUBRxYCrcYaswt+lB+IjwHeuw48vI09v3+A6ReLqUQR2xKsZB18DF1dN2Oq53SL9Wtar8SEbVEqOFozsikexcSrgXEliYOvpxtOnzmNnd7DtcLSFysySc3T0E1AIa3Wac+FOxj00y5ERFkmZNCnOp/WryZqp5LEYG/YXXRPTN5gSp/BL72OXAlHx683wx4WvNQANYta1uQ5Iqm5kwyG0rTRNGufWDuqKUrl98uycyMisgf20SIiyg6p2PfPBZaOBELqGNfvmqWlaA8P0zIKymC/UjsltT/HFmuPUSeBdpPM99d/Me4dW49Fu66p/jLRcd2TPbQ0b5Mmd9L351p4FBp/Jk3xUlaneB7MG9ZADSp753/zDevjKnZHdIILch3/B8OXXEU0PNX6Vl8YEzvsv6g1VXSHSeKGpEGW1GYVqorTNyLR6ovkB9S1Nt5TSqom0y9r+aGrqQZax65GqP5T0nSyV+0Qla1PtChfAOtMBtRNyaCGxTG6fQWUHWMMSqRmbkSrsmq/Ir9/YrDsBKRJaT4/7XwleDYd+4pBFhHlJOyjRUTkiK7sB2Y2NS4HhgKXdmnzw7YA3yYOnFq5hzbArxiXx5j+fEpZYOhGleTCdEBboJrUtaR6+L+G1EfpAlrQI00D977fGvP3XFTJAST4GPjTTmw/ewc+Hm54FKvdSH/eU/YNFArwxrPuCwz7qrS3CzZ4jUQuFxiCrOTEwR1b4yuigZt5kz5dSF1scm+AXatOqLTgSTUtmx8lgnJhzbHrWPpK4zQNmCtJF2SsqZi4BDyMicNnK0/g9x1hOH/bcswpvdv3o1VwOHjObsM602ZypkHW8Oal8MvWC6rJ3OyBxoD5+LUInL35AB2qFFLLZyZ2wLYzt1WfJCnrbAFWapa/1jirT4GIKFOxj5YN2HSQiDLdzRPAtLravFcA8MYpwMNby+I3LrGWpdU4xNV/VTXDK5nfD273r2p9s/QB2Ztn8eXW2yrNd3JmPFMLZ27eV8FUs3L5VV+nZmXzY2Sbcuk+dZW974eiar5B1Ne4gdw47d0fMTo3/Np6j6r5OXEtEv1+2K4GwpWEAwcuaUGKJEbId2sP5nmNN9vn6uDn8cKFFhYp2Ze80kj1D+pUrbDaj71Tlr/TvjyGNC5pSPwRGRWLT1ccx2/bw2zalwRMfw+tr8a/StBpSSBykqe+34adieN96QdOJiJyduyjlQUXk4josUkCC+9ALUvflqlaTVblJE38EmuuRlVYj3/2ac3r2lQMxkxJ5y3NDScE46FPIVS8OyXFZn7Tn66VITUm0XHx2D++Aeq5Hkf5qJ9QoWgw3C5uR9GQUEx5qZchMcX1iCiV1lsyukkNUYCPB1YfvY6X5u7FePefUMf1BD6Oexrj3OdgUlxfrE3QavFaVQjGO+3LGWrc7E2aSj4xaa3ZOknvPf3pmug6bYtF+S+eqqYSQYjyBf2x7NXGKng9di0SnaoUMmZnzIGu3HuEV//Yh4ENi6NT1cJZfTpERHbBQMuOGGgRkd1J36rIa0BAYW1exrD6rIRxe58/gPIdDDerk1edwIK9l9WypE9vXjoAK05HWez2+0rH0PbMR7ikC0Kj6K8N61eOaKLSmks68cxISFDunYXwxyN8NbgNGpUJUjU61jL/JWVMzW7d131roEu1jL9hX7T/Ml77M5WBmgEVfLWvrKUmvxYRhUKBPhl+bkRElLWYDIOIyAFtX/qzSiv+vedX5hsajjBbTLiwFYf9GmDX+bv46H/m/ZWkn5MEWVJR8mpL83TmnxzNjbZewAexA9XydxIIJPYB+mdYA9x5GKP6MmW01W+2xcnrkWhYOp9atiXIEiF5khkUWVpCti2HzlW115LRulYvglrF8lgN+vrUCVXBXoPSQWbrGWQREZEp9tGyAWu0iChNbp0Cfu8N3DmD+265sbT5MvSoWQRXpjRB0fgLyT/vlb1A2Hasf1gczy25Ax2sjzWl16lqITWQ66ZTN/HsbH2yC6O8uTxVEgtnI/2gWk75DzcSM+6J0Lw+2PSWeR+tzLL7/B30mbkdcQk6vNisFN5ulzj4MxER5UgRNnYrYqBlx4tJRCSZ6+ZPH4N+d6YZLkaFqB/xXshBPHNLq8WSZn0doiehndtO1HA5jb7u63FPlwvVo3+Ah5sLYuN1ZhcyJI8PPuhUUdWgxMYlqAFhg/y9MGdQXfh4uqkyUbHxWHboqqGvkFj1ehOUDc6YfkyZpd1XG9Ugv6Y1c1lB0qxLn7LKyaSCJyKinCPCxtiA6d2JiNJJBrrN6+uJa1cvIvCfvqiAs4jQBWBK9Kd44N4BL7gvU+VGus9H7uu3ATfgw9gBeOntzzD54j0M+TUXtqAySrlewfuxg1RZ0yCre80ieLl5aZVR0MALWPdGM4tz8fZwQ/eaIZi47Dhu3Y9W2e3KFPDLFinBpe9TwQDvLD0PSRqSnVKtExFRxmONlg1Yo0VEZn8TomJRdewqGd0JXohFeZcwFUw1dTuotsfpXFE6+jd4IA7fe3yBFm5aUoWSUb/h8Pj28PXUfuNKaeDd5uXy46dBiend00ASZ4z4az9eb1UW9Utp/aOIiIjIflijRURk56Zjk5YdUwPiRkTFwRvROO6t1UKJulHTMBZz0MFtJz6N64PdY1ohyM8Lj66VB2ZoAVPVIgGGIEtIenIZY+m9hYfwQpOSqBoSqAbKlfTljZIkWrBV4dw+ap9ERESUtVijZQPWaBHlHKMXHMQfOy8alv8d3hBlg/1Q8YOVZuXquRzDX14fGZYPPHMI1UoXxdlz5xBcsBBy+RibukXNbAfvK9twf/Bm+IVWyaRXQkRERBmBNVpERMmYu+MCPlx0RGWRm/t8PXi5u6JMAX8M+20Ptp29bVb2ycQBaovgJqZ7TsW42P44piuKGLgjfMQFBJxZBJfgSqgWUlSVK1nCZCysRN5PzwXOrodfSGW+J0RERDkEa7RswBotouwjuYFoKxUOwJErEWowYBmnaojbEjznvgKtoj/Hffhiovss9HNfZ/6kvn8B5dpl3skTERGR08QGKQ/SQkSUjVy4/cBqkCUkyCrqch0nvAfi/BA/vOvxBwq63MWH7r8gEPeNQVZIHeOTClXLpDMnIiIiZ8NAi4iyvQlLj6L4O0vR9PMNarmV6x6cDhiGE35D4YeHKOFyFZ6IxXvuc7UnXNgCPD1fzfZy34jtjfZp66s8ZQyuXN2BgKwb14mIiIgcG8fRInLSQXGFp7vlbyVHroTj332X0axcAZX1rlxBf6eqcYqMikv3oLAJCTrcfRgDFxcXzN58FtPWn7FarnPBe3C/E6H+AB72fl6tWxjfEE29TwPueYGmbwOu2kDAwmf3d4BXANB5KuDmASTEaUEXERERUTIYaBE5mYcxcWjy2Xp4ubth8csNkc/PC7HxCfBwc8WD6Dg8PWsH7j2MxQ+bzsHTzRVLX22EMsH+uBEZhbsPYuHh5oJb92NQp3geFZDcfRCDf/dfRq/aofDzSvlPQnyCDq4uUM+T8ZpkEFlXWZEGOp1ONdN7Y94BRMclYM3Ipmpw3R82nsWEZcdUmfc6VMCz9YupQXhTci08CtvP3lbjRtnq+VL30KltX2DNUSBsm2F9N7ctQKwMYDXBGGS9cRr4dxjw1C/AjeOAp6+2XgIuIiIiohQwGYYNmAyDskp0XLwKqPTi4hPQ8NN1uB4RbVjn7+WOyOg4NT+saSnM+M+8FqdXrRB81rMqGn26HpfvPTKs/3FgbQT6eOCV3/fhSniUxbE3vdUcoXkTAwsAyw9dxYtz96r5mkVzY2/YPfSsFYLJvVLvpyTB3JhFh7Hz3B01HlVS3WoUwcJ9l60+V/YvxzF14lokxvx7CLvO34Ut6hT2xIBCYQjMmx+NNz0LBJUFXt4FbP0GWDXGvPA7YYB3+mrUiIiIKPuLsDEZBgMtO15MovQ2d9t94a4arFZqcKTGp8u3W3Docrjani+Xpxr8dsy/hzF3R5jdLnLD0vmw5bR5KvOkPn6yMp4omRdDft2DszcfWC3TonwBfN6zKjacuKlqpO48iFHr21QMxqqj1+12vmM6VsAPm86aBZkpaVepIGY8UxO4fRr4tTsQbnLtKj4JPDVHm4+PA24cASKvAaH1AJ/cdjtnIiIiyn4YaGXBxSRKLaC69SAa+f28VNM7cebmfbSc8p+hTN+6RbFg7yXVpC4l0jdL30/Lmm/61kC9knlRd8Jah3xTJnWvgvaVC+KzlSfwe2Lw+EabshjevDRu3o/GtHWnsebYDbMauORM7FYF/eppY1jpSa1Z0JZxcNk+zfqT3joH+Oa1z4shIiKiHCWCNVqZfzGJUvLqH/uw+MAVFRQMaVwSzSZrGfDSSmpp2lYqqPo5Xbj9UCV/6FS1EKqPX20Iwg6NbaOaHPb8bquqLdMb1bosShfwMzQB1JvWryY6Vi2katPEr9sv4INFRyzGmRrYoLjqy6XvK1bxg5UW5+fj4YZHsfFm6/rUCcWABsVRLtjfok/X6RuRiE+A1aQd5289QL8ftltt2vhO+/Kqj1jX6oUNgavBxZ3A7NbG7ICSvELv9aNAYBGL/RERERHZgoGWHTHQovSKio1H+fdXpPl5E7pVRpMy+VXtTvfpWw3rT37c3mqmQdNaM9NA5rsNZ/DpiuNq/vhH7eDl7qpqy0zP6dj4dvDxtEw6cfhyOC7dfQiJvdpVLmgZzJgM/hsc4IVcXu6Y0qsaahTNo7ZJ0BYTn2DWxyw9ZD8dv96Mo1cjUK9EXvw1tL5lobgY4JeuQNhWLVHFkte09S+sBwpW0TIF3j4DRFwBSjR+rPMhIiKinC2CNVqZfzHJ+d17GIM2X27EDZOEDQfHtkGAt0ea9qMPMsqNST3Imj2gNlpWCFbPuRoehQL+XnB3MwZTW0/fwsZTtzCyddkUgyxrJHnG1LWnUKtYHpXu3fR1ztl6QfULa17euN5RSQAp/b3ql8yHQN8k70V8LPD7U8CZxAGF3byA+GgtHfvoi1lyvkRERJR9MdDKgotJzq/uhDVmQZbe9tEtUTDQ26aAQJr0df52c6plZzxTS9UUkdkFlDDVbAyrVF0/AnzXwLg8bAvwW3eg+w9Ayaa8vERERJQlsQHH0aIcQTLhSVM4GWuqbLCfGnvKlIzpNH/PpWSf//Y/B/HzoDq4/SAGHq6uFrUqkphCxqf6fuNZQ1M9vf71i2F818pqXs7h951heLVFGZsCtxxnbk/g/GagWH2g7SRjwJS0ud+p1cCaccDQjUBQOaBYI6DfX4CXn7b9jZNZcvpEREREekzvbgPWaDknGfdp3p5LWHf8hsW2PWNaGYKthfsu4fW/Dphtz+/vZXW8J70ve1dDp6qFVQBXb2Lymf06VimEaU/XfKzXkWMcmg/8M9i4XLwxcH6TNt/3T6BceyD6PhB1D/iykrFc37+Acu0y/3yJiIgoR4rIyBqtmzdv4siRI6hQoQKCg4Otlrl8+TLCwsJQqlQpFChQwCnKUPYQG5+AnjO24cDFe8mWOXDpHpqXK6D6RJkGWT1qhmB810oqscMHiw7jl20XrD5fnpM0ODP17/CGqB6aQ8ZjkmwZB/8GJFlGlV7a1FYPbgF/9gMu7gA6famtC64CXD8EtP/U2CTwjz7ASzuA6fWA/BWAhq8BW6Zq20wzChIRERE5iDT1rD927BiefvppVK9eHc2bN8fq1Vo6aVMJCQkYPHgwSpcujWHDhqFo0aJ4++23HboMZR/RcfEo895yiyBLmgsuf83Y/Oy5n3erpBcNPtESKOTydMPpCe0x5alqKsgSo9qUU4GXLTzdXBHgrT1vUU4KssT274CFQ4AFL2gB1ze1gbGBwA3zJpQWrh0CPi+lBVmiYFXg7QvAi5uBseFAcCXgqV+1bdI8cEYjbd43H9B6vNakUGq9SrfM4BdIRERElHZpqtE6deoU2rdvjx9//BHe3tb7l0ybNg0LFizAgQMHULZsWezYsQONGzdGnTp10LNnT4csQ9lHt2nGVOji1ZZlMLRJSUPw9Fa7cvhsxQk1f+rGfUO5yb2qmWX6E4E+Hirw+mevse+WZARsUja/WX+uhqXzYe7zTyBHkVqsdR8DFToDe38xrpeAS2/F20D/RcZlafZ3YjlwaB5wLwy4eUxbX7Y9ULUXkL+8sY+VXsUuWtA1szmQEKut6/uHNq36lPYgIiIiyk59tGRMnV9//RXPPPOM2fqaNWuidu3amDlzpmFdx44d1XTp0qUOWSY17KP1eKQfk5+Xe5pTk9vqy9UnVQpzGUz3563nDetPTWivkl8kVfydpVYH602ODKh792GsSoUuSfHkdQyeswtnbt7Hslcbwz+Nqd+zXV+qwWu0AOl/rwNh24zrpdZJmviZDiCsbxZo6rUDQJ7iKR/z3CZgTieg4Qig9Th7vhoiIiIix886GB8fj0OHDmHo0KFm62vVqoVZs2Y5ZBlroqOj1cP0YjqCyKhYTF55Armjr+CeV2E4opA8vhjcqITqpnM/Og5Vxq5S64vm9cWnPapi25lbqFEsD6oUCURQksx/tpIxoKZvOIOZG8+ardcHWf7e7jj4YRurA+yKI+PaotKHK9X830Pro26JvCker3QBf4t1Pw2so6bJHSNTHFsC7PgeeOoXIPwSUKiqtl7Gk5Japi7fAF6W555uj+5qNVmX95ivv7IXqDdUC6qK1geKNQQCCgP5y2kDB+/52VjWNMgacRjIFQR4+KR+bMk6OOIQEGBbU04iIiKirGbXQCsyMhJxcXHIm9f8xjUoKAh37951yDLWTJo0CePGOd6v5o9i4/Hf9u34yeMzNI9JTBxgg6Iu11EQd/Cux1z8ENcJSxMytpnbhGWJTcJMhN15iL4/bDcslwv2x5hOFVA4tw9KBuXCxTuPcPtBNPL4eqJ4UC6L50vQ5uPhpmqRpG9VSt7vWDHFAEiaEUp/LKmlkuyC6ZHhAdbGycB/nwGdvgCKNQDylgSWvw3cOasFJp7+wP7ftLKflQCCKwP9FwMe3sCv3bT1RxYCI48DAcnX1tksbAfwYxvAvzAwYAkQGArUeAY4thio1k8rI1kB5aF3+B/zIEtv6Cbg4W0gd2jaziF30cd8EUREREROGmh5enqq6aNHj8zWP3z40LDN0cpYM3r0aIwcOdKsRis0NI03hRnA19MdswsuRIm713Heux+m1VkNj4RHiPRKftDb4ne3osex1w3L0zy/Rt/QaOwINWn6ZSd7w+5iy+nbNpU9cT0Sz87eaXWbNONbevCqzcf9pm8NdKpaCLvO38XV8EfoWr1Iqs+R/ljpDbIy3LxBwJEF2vyi4dpUkkLsmGFeruUHwNrx2nx0JOCTB7h9Gnj9iDH9+cKhWj+plAJDaQ8ZfhHIU8z6dqkh0wdvkVe0Y9R/SVuWYCs5e+YkOd8PgYJVjDVvRERERNmYXQMtX19fVVskqdRNyXKxYsUcsow1Xl5e6uFopJ+TX/ESwN3Nann4tTGApx/wzD/Asje0rG21BmiF9/6qJQ/Yagyy4B0IRIWj0cXv0ah8iNbcy91+rzMqNh69v9+GA5fCDetcXYA/XngCvWdqtVluri6IT0i5W6AtQdYrLUrjxWalVPCpl1oTQIcWFwNMrabV2lw01vwZ/P0sMHwnsG0asHcOUP1poPEo4ImXtKx/8jkYn0crW3MAkEc+J+eAvCWAle8B7SYmf2zZ3/9GaPMDlwHFGwIJ8YAuQat50gdZJZsBz/5re/r2nj8CV/cD/zyvZQdsbPzxgoiIiCi7s3syjH79+uHcuXPYtk3rFC9N98qUKYPu3btjypQpDlnGqZJhxEUDP3UAitQCdn5vuf3De8DiV4B9v2r9ZfTJCV7ars1v/UZrfiYK1wCGbMjc85es3uFR+G37BXi5u+LrdacQG69Dy/IFsO3sbTyMiU/2eRK0vdC4JN5qV14FbNlCfCxwZj3wey9tudm7wIaJQLtPgWq9gYd3gG8SBzyW1Oc+ubWxp6TvlWmQvHQUsCux36F8Nl7Q0tarNOvi/VuAWzJJO/RlDMvhwA8tgcu7gRbvAzeOAf4FgbYT0vcaYx8Bru7JH5+IiIjIidgaG6Qp0JJ+TZImXcg4Wu+++y5at26NQoUKoVy5cmr98ePHVer0p556Cp06dcJvv/2GzZs3Y//+/aqcI5ax18XMVB8VAOKNCTuUp+drtRtn1mrL5TtpfXeavgW4uhnL/dEPOLHUmDEuVEvsYCY+DnCza4WnTRISdLgeGYX8fl4W6dazHbnGH+UzX/fmGcA7N+DiCrgmvv55A7X+Vq8fBQKLJB/M/NJVG7y39UdarZRpEPXKXiBfKcvnSdAmY1mZkuevft+4/NY5wNeJawuJiIiI7MjW2CBNd7Jnz57F2LFj1aNp06bYsmWLml+8eLGhTPny5dVYVa6urpgxY4YKZmTZNKhxtDJOqWBlbRpUVqvBeHk3MLenMcgS0rSs+WjzIEt0/VbrK6Mf60hfUyb9fXb+oN2cSwBgLZFBBnN1dUGhQJ/sH2Tps/jlyq/N95un1SRJFj4JcPVBlnjyOy3jXnJBlpAEGYNXaTVZ+iBLtPlYm0oTQHHzJHDzhLE2zTTIqv6M1s/LNMgSDLKIiIiIMq/pYE7ikDVaUsMhTc66fG29CdhLO4AC5ZN/vrzt0gRR+vFIk66y7YCdxrHGDCQAKNsGOc7qD4Ht04FnFmipxR+X/msmAe2EYMArEBh5FDi7ASjbNuOa1R34U0uI0e174OZxYHNitsrus7S+YPrmhlKTJkHetHpauTJttWaKofWAOvZPnEJERETkrDKk6WBO5ZCBljVSAyXjFkl2N1sTDyTtn2NN5Z5Az9nIEaRPlD5lut67VwFP3/Q3D5xWF7hzxvp2qcXKSBKM//pkymX0CTCEJL6QLINp+QwRERER5SARGdF0kBxcrYHajXtabpDrmgzm3PgNoOdP2j4kqYbe4fnA1YPI1sK2a0GnBFirxphvm1gIiI1K2/4kZfqje8D3TYxBljTLa5rYVFOflS+jlWqeepmQ2uZNDeu8ANQelKGnRURERJTdMdDK6dpN0qbFGgEt3wcqd9eWJYV34cRsd2LNWDi9TVO0YOpHk0F1xfGlwI9tjculWmjB5mta4hfl6KLk93v9qFaTqK8NEwteAKaUBx7e0pY7TgHePAs0f1fbtzwq90Cmk9ckzUr1ijYwz14YXAnoOFkLComIiIgo3TI/rRw5FkmUIWnD3b0ttw38HzC1OvDghtZ0TlqZ2jqGUlaTc5VxoGQqg+zu/x3YkBhUhm3VBviVFOli2ZvG8ac6TzW+RjeTAOTcRi0dvow5dfUA0GMW4Besbfu7P3D7FHD/JtBtBjCnk1ZG9F4MhNZFlur7J3BhC1CwGpCnuLZu9GXg7HrA3Sdrz42IiIgom2IfrezURyuj6PtxjTqhjafkDMbl0QItUa6jFiSt/9jYfE8GdK7aC6j/MnDrJHBhK1D3BfN9hF8CvqwE5CsN3D5tvq3uEODcJuDmMaDHbOCfxIQRASFAxCVtftByIPQJ8wyCRERERJQjYgPWaJHtHtx0zEDr9hktEUiFzlrK8txFjUGWiHsE1OyvNYuUsaQk096NI8CaI0DYDqDfn1qTuaQCQ4A3TgOn1wD/DjPfZpqhUYIsaQZ4+B9jkNXlG6BYg4x6xURERETk4BhoUeqK1AYu7wbCLxvH33IUP3cCzm/S5rd+bRxbTAZvlsF7pQZLxhlT6dMTm/rFPDQ+P7VmfX75gZJNtXmPXMCre4FV7wOH/jaW6fM7UKYNULQ+kLeENghwlV72fZ1ERERE5FTYdNAGOb7p4MVdwOoPgCZvAKVbIkud3wKcXK71KSvVEvipnbbeOxCICrc9bfq+ucD1w0Dbic7T74yIiIiIshzH0cqCi0kZ6MRy4J8XgJhI4zoZVFcG2d0/F+g2U2vq92c/YPAqIH85vh1EREREZHfso0X27wf1R1/gqTla8og8JYBCVTPnKp9eC/zRx3J9q7FAgQpAs9FA7lBt3TsXMueciIiIiIhSwD5aZJtvEsfUmv6E7c3z7EEG/v2tu7Gv2KBlWpO/iCtAcEVtvT7IIiIiIiJyEMw7TekjCSesiYtJ+75koF8Z7+rYEmB6Ay2ZRFw0cPOENvCvOl45rUmgDK4ryS0kwyARERERkYNioEXpI80HZdBfUxs+BT7ODxxdZPt+Tq4CPisB/NIV+OsZLe36tmnAxwWAaXUBF1dtLKoX1mqDKxMREREROQEGWpR+RxcDGydrAxpf2q0FSOLv/rbv4/fENOjn/jOu2/yFcV7Gpur7B+Dlz3eKiIiIiJwG+2hR+i16yTg/yyTte9XewIG/tPGtCtcA6gw2f540E7y0C7gXZlxXrR9w4Heg1xygZDNgyavaeFcy8K9vXr5LRERERORUOI6WDZjeXWqWFgDrJwC3T2vB05V9lhcqd1GgylNAg1eAT4sZ1486CfibDBb87zDz5oVSvvVHQEI84MbYn4iIiIgcF9O7k31V7g5U7AqsHacNFPxLF+O22s8BbT4Gou9rtU8fBZk/d/9vQONRQHwcMLGQ+bZcBYBGI7VBgxlkEREREVE2wT5alIZPixvQejxQsinQ+Wvjekm17plLq7Vy8zCu7/a9Nj2zXpvu+9V8f6/sBd48xaaBRERERJTtsJ0WpY8EVqLhCKDRCPNtT/0C3L0AVOujNTk8vUZL4f6/xHIVumhlpBaLiIiIiCgbYqBF6fPwtjaNfQj45DHfJk0M9Wr2B/KVAs5vBtpMAFa9B7QYwyCLiIiIiLI1Nh2k9CnZXJuWbp1yuQqdtKDs72e1+bHhQP5yvOpERERElK0x0KL0yV9WC5rKtrG9meHUakDEVV5xIiIiIsr2GGhRxntiuHFemhoSEREREWVz7KNFGS+otJalUMbeylOCV5yIiIiIsj0GWpQ5ag3QHkREREREOQCbDhIREREREdkZAy0iIiIiIiI7Y6BFRERERERkZwy0iIiIiIiI7IyBFhERERERkZ0x0CIiIiIiIrIzBlpERERERER2xkCLiIiIiIjIzhhoERERERER2RkDLSIiIiIiIjtjoEVERERERGRnDLSIiIiIiIjsjIEWERERERGRnTHQIiIiIiIisjN3e+8wO9LpdGoaERGR1adCRERERERZSB8T6GOE5DDQskFkZKSahoaG2uO9ISIiIiKibBAjBAYGJrvdRZdaKEZISEjAlStX4O/vDxcXlyyPoCXgu3jxIgICAvju8Lrx8+ag+F3ldePnzTnwu8rrxs+bc4hwoHtgCZ8kyCpcuDBcXZPvicUaLRvIBQwJCYEjkQ9YVn/InBGvG68bP3POgd9VXjd+5pwDv6u8bjn1MxeYQk2WHpNhEBERERER2RkDLSIiIiIiIgZaOZuXlxc+/PBDNSVeN37eHBe/q7xu/Lw5B35Xed34eXMOXk54D8xkGERERERERHbGpoNERERERER2xkCLiIiIiIjIzhhoERERERER2RnH0coCt27dwt69e1VnvurVq1vNwx8fH4/t27fj5s2bqFatGkqUKJGuMvfv38eePXsQHh6O4sWLo2rVqnBWMTEx2Ldvn7p+FSpUQMmSJa2WO336NA4fPozg4GDUq1fP6kBy169fx3///YcyZcqgRo0a6d6Pszhy5AjOnj2rBvqTz5w1cl23bdsGb29vNGrUCD4+PhZlHj16hFWrVqltbdq0SfexnIV8TuQz5+vrqz4nMmh5UnFxcdi6dSvu3r2LmjVrqtdtjXxXz58/j44dO1rdj55cu507d6rvtHzOnZH83ZG/cfJ5kb85hQoVslruwIED6vXKd1lerzVnzpzB7t27Ubt2bZQqVcpqGTmOfHblb2KDBg2QK1cuOCMZAFP+5sjnpFixYsn+vb5x44b6PMnrbNiwofrOJvXgwQOsXr1afdZatmyZ7N+448ePq+fLdzUoKAjO6sKFCzh06JB6DfI99PT0tCjz8OFDbNmyBdHR0ahfvz7y5cuXYftxpgFg5bsaGxurPm/y/84aKSPXRv5nVq5cOV37sfVYzkBeg/z9unbtGsqVK6euizXnzp1T5fLnz48nnngCbm5u6dqP3sKFC9W0W7ducFbnzp1T9wlyTeQ75uHhYfXv1+bNm9X/V/mbnidPnnTtR8j/GPm7Kv9nrH12M5yOMk1MTIzuueee0xUuXFjXpk0bXb169XSBgYG633//3azczZs3ddWrV9cVLVpU17JlS52vr69u/PjxaS6zfPlyXZ48eXQ1a9bUdenSRRcUFKRr0qSJLiIiQudsfv31V12JEiV0devW1XXo0EHn5+ene+aZZ3RxcXFm5d5++21drly5dK1bt1bX+YknntDdu3fPsP3y5cu6Pn366IoUKaKu/WuvvWb1eKntx1ns2LFDV6NGDV2lSpV0nTp1Uq+lTp06umvXrpmV+/vvv9XrbdiwoSor5Q4cOGDYHh8frxsxYoSuUKFCupCQEF2tWrXSfSxn8ODBA/X5ks9J27ZtdbVr19blzZtXt3DhQrNy8nmqWLGi+my2aNFC5+Pjo5s8ebJZmX/++UdXpUoVXZkyZXTyJ/fYsWPJHvf+/ftqf+7u7rpJkybpnNHEiRPVdWvcuLH6/sg1GTNmjFmZ2NhYXc+ePdXfJ/lbKFNZlvV68vmTa1+qVCl1Pb777jurx1u0aJEuX7586jPZuXNndf327t2rczabN2/WVa1aVX1W5HUULFhQV79+fd2tW7fMyv3222/quyrXt0KFCrrQ0FDd0aNHzf7PvPLKK+q7Ku+DfKeTkr+bTz/9tPo72rFjR12jRo3U/5AZM2bonM2lS5d07du31xUvXly9lvLly+uKFSum27lzp1m5ffv2qWsi11euibx2+W7aez/O5P3331d/p5s2bWr4+yXfX1NRUVHqesj9g3xX5f9m//791f+EtOzHljLOYt68eervkvxfkGsTEBCg69Gjhy46OtqsnNyTyfdK7tHkeyr/H+XeLa370fvqq690np6e6u+dMzp//rz6n1CyZEl1jyD/E2VevlOm5DtXoEABXbVq1dTfQH9/f92SJUvSvB/57D777LPq+XJ95Z67b9++uszGQCuTb95mz55tdjPx2Wef6by8vHQ3btwwrBswYID6hys3XWLFihXqBm3btm1pKlO2bFkV2OnJMeQD98UXX+iczZ9//qm7cuWKYfnUqVPqZmPatGmGdatXr9a5uLjotmzZopYlMJI/Yi+//LKhjNyQSGArf8jkxsxaoGXLfpzFunXrdPv37zf7DMoNgukfG/lcyM3C559/rpYTEhJ03bp1U4G86c2bfG5u376trpm1QMuWYzmLO3fuqODeNJD/4IMP1D9N0x8q5J+iBP/yB13/j1M+OwcPHjSUkc+bBA27du1KNdAaNGiQbtSoUbrg4GCnDbTkb1x4eLjZ50Je99q1aw3rvvnmG13u3Ll1586dU8tnzpxRNxnffvutoczGjRt1y5YtUzd08l23FmgdOnRI3XhMnTrVsE7+TiS9OXYG8ndHXo+efM7kZl8+E6avTW5Q5foJuTbyw5P8EGT6vZPrcffuXd3QoUOtBlpyXeU9Mf0xRT5vci31n2VnId8n+VFRT66J/JgmN1+mKleurOvdu7dh+aOPPlKfOfmbZs/9OJOZM2ca7iHE4sWL1edi+/btZp8LuemVH5X0/0PlM/jzzz+naT+2lHEW8+fP14WFhRmWL1y4oH4s+vTTTw3rtm7dql6ffK+FvHb5EXLgwIFp2o+e/Hgkwdobb7zhtIHWoUOHDNdD/x2Tew25TzBdJ985ucfVe++999QPnfr/vbbsR7z44ovqml28eNHsh7nMxkAri8kNhnwZ//vvP7UsAYD8ETMNIIT8Squ/0beljJBf40xrueQGWn7h/OSTT3TZgfzS8cILLxiW5Ysp60zJL2byh0tee1LJBVpp3Y+zefPNN9Uv4Xo//PCDztvb2+yfoNzkyufy8OHDFs9PLtCy5VjOTG5K5Zrs2bNHLcsffalpmTNnjlk5+d698847Fs9PLdCSgEx+wZMbXWcOtKyR786UKVMMy/LLomkAIeRXctOAwVRygZZ8V+XvXnYlNVPyK7ieBFjyo4hpMLRq1Sr1uZIfn5JKLtCSmln5QcA0IP7rr7/U5zkyMlLn7OS1yDXR/02TX7plWWrd9eQHNAksTQOGjNqPM5HX8v333xuWJTiQz6Gp7t2761q1apWm/aS3jLOQGhbTHxWHDx9uceP/9ddfqx/rkquxsrYfId/JcuXKqVod+UHUWQMta+T/p6urq6ECQioLkv4IJD8Gu7m5qR/cbd2PPMfDw0MF+FnNeTudZBNr1qxRbXbLly9v6I8g/Q2StiOtUqWKajduaxnxzTff4Mcff8SECRPw008/oVevXihdujSGDh0KZyf90g4ePGh2DeS1W7sm0nfm8uXLNu/bXvtxRPLjyrp16yyum/TvM+3XIq9Xv82ex3L276r0q9S3oZe+LdJ+POnrk+W0Xjf5To8YMQJz5851qoEYbSF9MuS7Y8t3Na3XbePGjaqvoPRZWrx4seo3I38bswPpb7ZhwwaL6yafP9PPiP67Kn0QbNWpUyf1/6Br166YPXs2vvzyS4wZMwZTp06Fn58fssN31fRvmv5zZXotpW+09KdM6TNnr/04C/k+SV9o/euTv2/Hjh1L83c16X7SW8ZZ3Lt3T/UjteVvnPTvkz5Dtu5HvPTSS2jRooX63mY3a9asUX3T3N3dDdfNxcUFlSpVMpSRPlgFCxZM9btquh/psyv93+T/w65du7BkyRKcPHkSWYHJMLLQiRMn8Pbbb2PUqFEoUKCAWidJK0TevHnNykpnW7mxs7WMkI5/8g9g3rx5aiodLvv16+e0HcVNb0D69++PwoULY/DgwYb1cl2sXRP9H7CQkBCb9m+v/Tii8ePH4+jRo5gzZ06Krzd37tzqBwB5vfY8lrOS784HH3yA9957z5DIIqXvoQROtpJ/Bn369FE3uqb/XLID6fz+7LP/b+/cXataojg89x+wsxLEyiK9dr5AMQhKUNFCxbf4FkVFbRJQRHyAhW+7KL6IEiG+Ixba2KUU7VS0UZuAWnkv34J1mLOzdzInbOOZ6++DiJ6zzxz3ZGb2WmvW+s0aE2NYsGBBw3jD2CjrNwqged8flmOBg8U6OnPmTDNi6HeEOO7evRtmzJgRcobxQLF3X19f8tqUCv2LiAMOFu0PDw+bIEZHR0fIHQwqnMebN2829RuiFojaFPuuqt/qaicXvn79GjZs2BCWLFli4gPAXPr161fpmKu637J2xnNNLhBQxA7huYBDFI8VD4KkzNWqdq5fv26OAgGr/xt9fX12f/39/U39NmnSpBGiIaONubJ2eDbgsB04cCC8e/fO7EWce8bctWvXJlTcTI7WHwJVKQwPfo4fP9543SOVLHAx/NuVpVKuIVLU2dkZli1bFs6ePdtY3FD6QTGuu7s75AiL/tq1a203C9XA2GmkX8r6BMpUuaqoq5124/z58zbWMEJjg77sfn/+/GkO7Xjvt+q7cgRDnrnEDgDGr5MyD1P76vPnzxa1u3XrVqP/GeMoTOWqLoXThMIihinBHh56buTzEC3rN95LdbKAfn79+rXt5qBsyPqwYsUKM+Jy3mE4c+aMrdvs0k2fPr32tenGjRvh0KFDpqjpypYXL1603xdKhFUqke0OO4ArV64Mx44ds3EQ9xvPRIIasTJZ1Vytq51cwLhljUNpEYN1vGtcVTutXpMLOEdbt24NL1++DC9evLAA5XjmalU77M5v27bNHK/79+/ba0NDQzYGeVaghlymNp0DT58+DatXr7a1Ducn7jeeHUWqxlxVO1xLvzLO7ty503iWo67K7mAcpP/dKHXwD4BE6ty5cy0KywMv9tyZNBgk79+/H/EZlzNPuYbI7sePH804jCMC8+bNs4mcIxhR69evt3Q07oE0yBikn8v6BMNt6tSpyd9TVzvtBEbUvn37zOAtph9wv4wV+jcOBECVhP54vys3SDVgUSYgQnTbnQVwqfHR5mEKRNqQ0yca5z/IRiNb++jRo5Czk8WOFikdRWle+qes31o1GvgdEBF3x4AoJY4pfYezmiM4WDj0ONm+CzjW2gStjDmCVETb4+MDeFaw04jjmiPcE+vNkSNHwuHDh5ve87n64cOHxmsEkkgFL/ZbXe3kAnOU9CrmzpMnT5qOniAoy9xKWeNGa6eVa3IBI37Hjh3h3r174fnz5yMCilVzlWdIvM6N1g7vsY7yOX82sLbxfODvxfZz4dmzZ6GrqyscPXo07N27d0S/kdXw6dOnxms4lsjfF8fcWO0Amw0OqYWkZXLk0YTyp4vE/jZQlUE+FrWyWH0whuJlpI5j2VmKlJH1Tb2GImeKnRE6cBByQMQAWd/cQFWGwndkdd+8eVN6DcXyFJrG6k8UlnZ2dpZeXyWG0Wo77Q6SzShb9vf3l76PQh5LweDgYOO1np4eU/kpK9odTQxjrO/Kibdv35ocMfKwsZRxDOIVsYoUggTMu7L7T1EddHIWw0D1DglnVFFjKePiGEJZCjVLYJyh7MkRAq2IYaD4RpF4/PtBoQqVtBxBLRBhGlQBy/AxhBS8g/AKUvDFoy5GE8Og3yZPnvzv9+/fRwjg8B25wf+dMVI84sT58eOHqVzGQlADAwM2V+P5WFc7uYCdgDANyqlVx5ds3LjR1jkfX4wZ1sX4yIaUdlKuyYnt27eb5H0s2hCDai1iDLFacldXlx2l0Eo7RXIXwxgcHDQxNxS3y0D4A8EfpOxjdUaELhCPS20H+5p1MVayZeyy7k30sQL/8MfEunZ/L+TBs21JNOLEiRNNKTJEZX23hCI+dp7YDuWQ1EuXLlnBLZE23/1KuYZdBaLwePrUaA0MDFgUic9WHQ7arnAvRHp7enqaUmmmTJkSZs2aZX+nXz3fm21hDpEl6sOhd35wLikfpLMB9TZEOKj3IuK+cOHC5HZygXslUk1tXry7RDrX0qVLG/9GIIXUBPKZv337Fk6dOhUuX75sO4jO48ePLUe6t7fXtuARWYHly5fbWE79rhygD5gjpAeRPhTnc8+ePdt2oYDdVdJgNm3aZLsD586ds3lMOoPvflFM7gfzMuZIceDz1BBVHcBL4S/iGKR35caiRYtsx/n06dNNB7ki+OPzh+gkBxATvSUiye4N9XwUgnPvnupMxBLWrVtna938+fPtIF/qi3xNJX2GSCc7WeTiI+hAOibpgzlBdsOqVatszsWHgbOrgGiFQ+o0kW9qezlQm/FEHSTzznnw4IH1Des/uy+sm0A6HOOSz/G7YPyx/rHTwPrKmOc5Ee/ctjuMG8YAO3S7d+9ueo91yMU9rl69Gnbu3BkOHjxoz8qTJ09aWiBzts52coK1jPRR5ir34hD1d0EGdk2Yq/QNc/v27dv2GnPVa7dS2km5Jheo12UXhV3PuA6LWnsyIIBdmTlz5tjcIi2QGivEjkhL5eDi1HaK0H/Yj1++fAm5MTQ0ZAesM55IiYxhjWOtcyE35hcaBtRDcr+s59x7K+2QVbN582azgbEVqc1i7LKjVaw7/J3I0Zpgpbxdu3aVvrdnz56G8QBsD6MYiLGBI4UhXMxPTbnm4cOHlrqDgcx2NQYLTlduYCjEQh8Op4EzIeOUJVLXqM/g1HkmWXzSOqkxZQbYtGnTbDKntpMLFHJ7bncMtW0YYQ7xFgw9HAdypDEcSG+NwQmLU2YcjDw+k/pdOUAq5f79+0vfY/Fnvjks+vQByno4T4wVnEuHOhv6tgjOGY5DGTyYMWrinPNc2LJlixkXRRYvXmyOhIOxzxzDAcVR4oHJXHOoFYpr4hyCILEhzHcRFGA95PM4/jkKYRDAYL0uQr0GgTSHFF8MBoJqGCEIqZB6GoOTjjNbhHHoQQPGK88P1lWeGxh/tFUsQm93SHVE1KMMnO54TLG+UThPMI25x/26U1lXOzmBk01aVhHmED8OqZGMQYxUnoPM1TiIktJO6nflALYC634RxGRwnhzSl1mbcDDpLwK3seBMajsxBEJ4ply5ciXkxqtXryoDEhcuXGhyfghWkk6Jw0oQPC6DaaUd5jXrHjYdgT2euxOdsipHSwghhBBCCCFqRmIYQgghhBBCCFEzcrSEEEIIIYQQombkaAkhhBBCCCFEzcjREkIIIYQQQoiakaMlhBBCCCGEEDUjR0sIIYQQQgghakaOlhBCCCGEEELUjBwtIYQQQgghhKgZOVpCCCGEEEIIUTNytIQQQgghhBCiZuRoCSGEEEIIIUTNyNESQgghhBBCiFAv/wGkwHxkIoHVMgAAAABJRU5ErkJggg==", "text/plain": [ "
" ] @@ -163,7 +163,7 @@ }, { "cell_type": "markdown", - "id": "a217b4e9", + "id": "851e1be0", "metadata": {}, "source": [ "## Performance by year" @@ -172,13 +172,13 @@ { "cell_type": "code", "execution_count": 4, - "id": "f66a0237", + "id": "bcf0cda6", "metadata": { "execution": { - "iopub.execute_input": "2026-08-17T16:06:35.998924Z", - "iopub.status.busy": "2026-08-17T16:06:35.998720Z", - "iopub.status.idle": "2026-08-17T16:06:36.070355Z", - "shell.execute_reply": "2026-08-17T16:06:36.069487Z" + "iopub.execute_input": "2026-08-25T17:01:14.295380Z", + "iopub.status.busy": "2026-08-25T17:01:14.295092Z", + "iopub.status.idle": "2026-08-25T17:01:14.363387Z", + "shell.execute_reply": "2026-08-25T17:01:14.362377Z" } }, "outputs": [ @@ -217,12 +217,12 @@ " \n", " 0\n", " Full sample\n", - " 1.729542\n", + " 1.729543\n", " 0.057462\n", " 0.443716\n", " -0.158208\n", " 0.089985\n", - " 67.055794\n", + " 67.055796\n", " 277\n", " \n", " \n", @@ -241,10 +241,10 @@ " 2009\n", " 0.092668\n", " 0.092668\n", - " 0.801377\n", - " -0.056492\n", + " 0.801381\n", + " -0.056493\n", " 0.090761\n", - " 1.801409\n", + " 1.801406\n", " 15\n", " \n", " \n", @@ -252,10 +252,10 @@ " 2010\n", " 0.093298\n", " 0.093298\n", - " 0.615135\n", - " -0.091069\n", - " 0.125197\n", - " 4.190301\n", + " 0.615134\n", + " -0.091070\n", + " 0.125198\n", + " 4.190302\n", " 28\n", " \n", " \n", @@ -263,18 +263,18 @@ " 2011\n", " 0.004023\n", " 0.004023\n", - " -0.109155\n", + " -0.109156\n", " -0.073369\n", " 0.100413\n", - " 6.713499\n", + " 6.713500\n", " 25\n", " \n", " \n", " 5\n", " 2012\n", - " 0.020650\n", + " 0.020651\n", " 0.020817\n", - " 0.041285\n", + " 0.041289\n", " -0.065115\n", " 0.063776\n", " 3.600000\n", @@ -283,9 +283,9 @@ " \n", " 6\n", " 2013\n", - " 0.168490\n", - " 0.168490\n", - " 1.773836\n", + " 0.168489\n", + " 0.168489\n", + " 1.773823\n", " -0.043644\n", " 0.078258\n", " 6.600000\n", @@ -296,8 +296,8 @@ " 2014\n", " 0.067877\n", " 0.067877\n", - " 0.611582\n", - " -0.057081\n", + " 0.611583\n", + " -0.057080\n", " 0.079898\n", " 3.000000\n", " 10\n", @@ -307,7 +307,7 @@ " 2015\n", " 0.020909\n", " 0.020909\n", - " 0.049575\n", + " 0.049578\n", " -0.072616\n", " 0.082531\n", " 4.800000\n", @@ -316,9 +316,9 @@ " \n", " 9\n", " 2016\n", - " -0.050046\n", - " -0.050046\n", - " -0.820586\n", + " -0.050045\n", + " -0.050045\n", + " -0.820584\n", " -0.124595\n", " 0.082768\n", " 4.800000\n", @@ -329,7 +329,7 @@ " 2017\n", " 0.138595\n", " 0.139184\n", - " 1.773050\n", + " 1.773051\n", " -0.026354\n", " 0.063363\n", " 4.200000\n", @@ -343,7 +343,7 @@ " -0.653702\n", " -0.148574\n", " 0.119488\n", - " 1.481820\n", + " 1.481822\n", " 12\n", " \n", " \n", @@ -351,18 +351,18 @@ " 2019\n", " 0.114516\n", " 0.114516\n", - " 1.315083\n", - " -0.044112\n", + " 1.315085\n", + " -0.044113\n", " 0.069060\n", - " 2.947271\n", + " 2.947272\n", " 12\n", " \n", " \n", " 13\n", " 2020\n", - " 0.084729\n", + " 0.084728\n", " 0.084380\n", - " 0.584590\n", + " 0.584587\n", " -0.117249\n", " 0.115865\n", " 4.223959\n", @@ -373,7 +373,7 @@ " 2021\n", " 0.063758\n", " 0.063758\n", - " 0.461813\n", + " 0.461815\n", " -0.059802\n", " 0.101710\n", " 4.233533\n", @@ -382,9 +382,9 @@ " \n", " 15\n", " 2022\n", - " -0.108014\n", - " -0.108420\n", - " -1.090872\n", + " -0.108013\n", + " -0.108419\n", + " -1.090869\n", " -0.155209\n", " 0.117235\n", " 4.264002\n", @@ -406,7 +406,7 @@ " 2024\n", " 0.180563\n", " 0.180563\n", - " 1.778602\n", + " 1.778603\n", " -0.055256\n", " 0.084094\n", " 4.200000\n", @@ -429,40 +429,40 @@ ], "text/plain": [ " Period Return CAGR Sharpe Max Drawdown Volatility \\\n", - "0 Full sample 1.729542 0.057462 0.443716 -0.158208 0.089985 \n", + "0 Full sample 1.729543 0.057462 0.443716 -0.158208 0.089985 \n", "1 2008 0.000000 0.000000 0.000000 0.000000 0.000000 \n", - "2 2009 0.092668 0.092668 0.801377 -0.056492 0.090761 \n", - "3 2010 0.093298 0.093298 0.615135 -0.091069 0.125197 \n", - "4 2011 0.004023 0.004023 -0.109155 -0.073369 0.100413 \n", - "5 2012 0.020650 0.020817 0.041285 -0.065115 0.063776 \n", - "6 2013 0.168490 0.168490 1.773836 -0.043644 0.078258 \n", - "7 2014 0.067877 0.067877 0.611582 -0.057081 0.079898 \n", - "8 2015 0.020909 0.020909 0.049575 -0.072616 0.082531 \n", - "9 2016 -0.050046 -0.050046 -0.820586 -0.124595 0.082768 \n", - "10 2017 0.138595 0.139184 1.773050 -0.026354 0.063363 \n", + "2 2009 0.092668 0.092668 0.801381 -0.056493 0.090761 \n", + "3 2010 0.093298 0.093298 0.615134 -0.091070 0.125198 \n", + "4 2011 0.004023 0.004023 -0.109156 -0.073369 0.100413 \n", + "5 2012 0.020651 0.020817 0.041289 -0.065115 0.063776 \n", + "6 2013 0.168489 0.168489 1.773823 -0.043644 0.078258 \n", + "7 2014 0.067877 0.067877 0.611583 -0.057080 0.079898 \n", + "8 2015 0.020909 0.020909 0.049578 -0.072616 0.082531 \n", + "9 2016 -0.050045 -0.050045 -0.820584 -0.124595 0.082768 \n", + "10 2017 0.138595 0.139184 1.773051 -0.026354 0.063363 \n", "11 2018 -0.062911 -0.063154 -0.653702 -0.148574 0.119488 \n", - "12 2019 0.114516 0.114516 1.315083 -0.044112 0.069060 \n", - "13 2020 0.084729 0.084380 0.584590 -0.117249 0.115865 \n", - "14 2021 0.063758 0.063758 0.461813 -0.059802 0.101710 \n", - "15 2022 -0.108014 -0.108420 -1.090872 -0.155209 0.117235 \n", + "12 2019 0.114516 0.114516 1.315085 -0.044113 0.069060 \n", + "13 2020 0.084728 0.084380 0.584587 -0.117249 0.115865 \n", + "14 2021 0.063758 0.063758 0.461815 -0.059802 0.101710 \n", + "15 2022 -0.108013 -0.108419 -1.090869 -0.155209 0.117235 \n", "16 2023 0.085133 0.085842 0.896149 -0.066147 0.072519 \n", - "17 2024 0.180563 0.180563 1.778602 -0.055256 0.084094 \n", + "17 2024 0.180563 0.180563 1.778603 -0.055256 0.084094 \n", "18 2025 0.175104 0.176622 1.573983 -0.064234 0.093412 \n", "\n", " Turnover (x) Number of Trades \n", - "0 67.055794 277 \n", + "0 67.055796 277 \n", "1 0.000000 0 \n", - "2 1.801409 15 \n", - "3 4.190301 28 \n", - "4 6.713499 25 \n", + "2 1.801406 15 \n", + "3 4.190302 28 \n", + "4 6.713500 25 \n", "5 3.600000 12 \n", "6 6.600000 22 \n", "7 3.000000 10 \n", "8 4.800000 16 \n", "9 4.800000 16 \n", "10 4.200000 14 \n", - "11 1.481820 12 \n", - "12 2.947271 12 \n", + "11 1.481822 12 \n", + "12 2.947272 12 \n", "13 4.223959 20 \n", "14 4.233533 19 \n", "15 4.264002 19 \n", @@ -484,7 +484,7 @@ }, { "cell_type": "markdown", - "id": "3da366d8", + "id": "f9f03cae", "metadata": {}, "source": [ "## Out-of-sample validation (walk-forward)\n", @@ -499,13 +499,13 @@ { "cell_type": "code", "execution_count": 5, - "id": "f09fa226", + "id": "e4cd3c88", "metadata": { "execution": { - "iopub.execute_input": "2026-08-17T16:06:36.072174Z", - "iopub.status.busy": "2026-08-17T16:06:36.071916Z", - "iopub.status.idle": "2026-08-17T16:39:15.132934Z", - "shell.execute_reply": "2026-08-17T16:39:15.132081Z" + "iopub.execute_input": "2026-08-25T17:01:14.365438Z", + "iopub.status.busy": "2026-08-25T17:01:14.365147Z", + "iopub.status.idle": "2026-08-25T17:35:08.180540Z", + "shell.execute_reply": "2026-08-25T17:35:08.179616Z" } }, "outputs": [ @@ -551,90 +551,90 @@ " 0\n", " 189\n", " 21\n", - " 0.407711\n", + " 0.407720\n", " 0.002839\n", - " -0.133095\n", + " -0.133096\n", " \n", " \n", " 1\n", " 1\n", " 252\n", " 21\n", - " 0.377448\n", + " 0.377440\n", " 0.086610\n", - " 2.145038\n", + " 2.145034\n", " \n", " \n", " 2\n", " 2\n", " 252\n", " 21\n", - " 1.499172\n", + " 1.499158\n", " 0.033276\n", - " 0.583151\n", + " 0.583157\n", " \n", " \n", " 3\n", " 3\n", " 126\n", " 21\n", - " 1.792581\n", - " 0.037069\n", - " 1.118923\n", + " 1.792590\n", + " 0.037070\n", + " 1.118928\n", " \n", " \n", " 4\n", " 4\n", " 189\n", " 21\n", - " 1.279039\n", + " 1.279034\n", " 0.008293\n", - " -0.007808\n", + " -0.007815\n", " \n", " \n", " 5\n", " 5\n", " 189\n", " 21\n", - " 1.389658\n", + " 1.389653\n", " -0.043895\n", - " -0.978853\n", + " -0.978858\n", " \n", " \n", " 6\n", " 6\n", " 252\n", " 21\n", - " -0.151709\n", + " -0.151705\n", " 0.065673\n", - " 1.240999\n", + " 1.240997\n", " \n", " \n", " 7\n", " 7\n", " 126\n", " 21\n", - " 0.271636\n", + " 0.271631\n", " -0.050807\n", - " -1.400646\n", + " -1.400648\n", " \n", " \n", " 8\n", " 8\n", " 126\n", " 0\n", - " 0.805470\n", + " 0.805464\n", " 0.052652\n", - " 1.356490\n", + " 1.356497\n", " \n", " \n", " 9\n", " 9\n", " 189\n", " 21\n", - " 1.404679\n", + " 1.404681\n", " 0.079879\n", - " 2.206576\n", + " 2.206585\n", " \n", " \n", " 10\n", @@ -643,52 +643,52 @@ " 21\n", " 1.805294\n", " -0.006467\n", - " -0.232788\n", + " -0.232787\n", " \n", " \n", " 11\n", " 11\n", " 189\n", " 0\n", - " 0.957851\n", + " 0.957852\n", " -0.061822\n", - " -1.261399\n", + " -1.261396\n", " \n", " \n", " 12\n", " 12\n", " 189\n", " 0\n", - " -0.318595\n", - " 0.043413\n", - " 1.135971\n", + " -0.318594\n", + " 0.043414\n", + " 1.135982\n", " \n", " \n", " 13\n", " 13\n", " 189\n", " 21\n", - " 0.403092\n", + " 0.403091\n", " 0.008597\n", - " -0.019317\n", + " -0.019312\n", " \n", " \n", " 14\n", " 14\n", " 189\n", " 21\n", - " 2.000378\n", - " -0.049932\n", - " -0.422045\n", + " 2.000383\n", + " -0.049931\n", + " -0.422043\n", " \n", " \n", " 15\n", " 15\n", " 252\n", " 0\n", - " 0.623382\n", + " 0.623380\n", " 0.077301\n", - " 1.298622\n", + " 1.298620\n", " \n", " \n", " 16\n", @@ -697,15 +697,15 @@ " 0\n", " 0.924852\n", " 0.071764\n", - " 1.128255\n", + " 1.128256\n", " \n", " \n", " 17\n", " 17\n", " 126\n", " 21\n", - " 1.697380\n", - " 0.041612\n", + " 1.697381\n", + " 0.041611\n", " 0.756638\n", " \n", " \n", @@ -713,9 +713,9 @@ " 18\n", " 189\n", " 21\n", - " 1.116372\n", - " -0.114932\n", - " -2.123307\n", + " 1.116374\n", + " -0.114931\n", + " -2.123303\n", " \n", " \n", " 19\n", @@ -723,42 +723,42 @@ " 189\n", " 21\n", " -0.830122\n", - " -0.041381\n", - " -0.945298\n", + " -0.041382\n", + " -0.945299\n", " \n", " \n", " 20\n", " 20\n", " 252\n", " 0\n", - " -0.994462\n", + " -0.994465\n", " 0.055433\n", - " 1.417779\n", + " 1.417782\n", " \n", " \n", " 21\n", " 21\n", " 252\n", " 0\n", - " 0.500975\n", + " 0.500976\n", " 0.021741\n", - " 0.340015\n", + " 0.340016\n", " \n", " \n", " 22\n", " 22\n", " 126\n", " 0\n", - " 1.234342\n", + " 1.234343\n", " 0.080233\n", - " 1.802895\n", + " 1.802894\n", " \n", " \n", " 23\n", " 23\n", " 252\n", " 21\n", - " 1.492339\n", + " 1.492340\n", " 0.077561\n", " 1.438909\n", " \n", @@ -767,7 +767,7 @@ " 24\n", " 252\n", " 21\n", - " 1.842030\n", + " 1.842031\n", " 0.043352\n", " 0.578693\n", " \n", @@ -776,9 +776,9 @@ " 25\n", " 252\n", " 21\n", - " 1.094990\n", + " 1.094989\n", " 0.125760\n", - " 3.414157\n", + " 3.414156\n", " \n", " \n", "\n", @@ -786,60 +786,60 @@ ], "text/plain": [ " fold param_lookback_period param_skip_period validation_score \\\n", - "0 0 189 21 0.407711 \n", - "1 1 252 21 0.377448 \n", - "2 2 252 21 1.499172 \n", - "3 3 126 21 1.792581 \n", - "4 4 189 21 1.279039 \n", - "5 5 189 21 1.389658 \n", - "6 6 252 21 -0.151709 \n", - "7 7 126 21 0.271636 \n", - "8 8 126 0 0.805470 \n", - "9 9 189 21 1.404679 \n", + "0 0 189 21 0.407720 \n", + "1 1 252 21 0.377440 \n", + "2 2 252 21 1.499158 \n", + "3 3 126 21 1.792590 \n", + "4 4 189 21 1.279034 \n", + "5 5 189 21 1.389653 \n", + "6 6 252 21 -0.151705 \n", + "7 7 126 21 0.271631 \n", + "8 8 126 0 0.805464 \n", + "9 9 189 21 1.404681 \n", "10 10 252 21 1.805294 \n", - "11 11 189 0 0.957851 \n", - "12 12 189 0 -0.318595 \n", - "13 13 189 21 0.403092 \n", - "14 14 189 21 2.000378 \n", - "15 15 252 0 0.623382 \n", + "11 11 189 0 0.957852 \n", + "12 12 189 0 -0.318594 \n", + "13 13 189 21 0.403091 \n", + "14 14 189 21 2.000383 \n", + "15 15 252 0 0.623380 \n", "16 16 189 0 0.924852 \n", - "17 17 126 21 1.697380 \n", - "18 18 189 21 1.116372 \n", + "17 17 126 21 1.697381 \n", + "18 18 189 21 1.116374 \n", "19 19 189 21 -0.830122 \n", - "20 20 252 0 -0.994462 \n", - "21 21 252 0 0.500975 \n", - "22 22 126 0 1.234342 \n", - "23 23 252 21 1.492339 \n", - "24 24 252 21 1.842030 \n", - "25 25 252 21 1.094990 \n", + "20 20 252 0 -0.994465 \n", + "21 21 252 0 0.500976 \n", + "22 22 126 0 1.234343 \n", + "23 23 252 21 1.492340 \n", + "24 24 252 21 1.842031 \n", + "25 25 252 21 1.094989 \n", "\n", " test_return test_sharpe \n", - "0 0.002839 -0.133095 \n", - "1 0.086610 2.145038 \n", - "2 0.033276 0.583151 \n", - "3 0.037069 1.118923 \n", - "4 0.008293 -0.007808 \n", - "5 -0.043895 -0.978853 \n", - "6 0.065673 1.240999 \n", - "7 -0.050807 -1.400646 \n", - "8 0.052652 1.356490 \n", - "9 0.079879 2.206576 \n", - "10 -0.006467 -0.232788 \n", - "11 -0.061822 -1.261399 \n", - "12 0.043413 1.135971 \n", - "13 0.008597 -0.019317 \n", - "14 -0.049932 -0.422045 \n", - "15 0.077301 1.298622 \n", - "16 0.071764 1.128255 \n", - "17 0.041612 0.756638 \n", - "18 -0.114932 -2.123307 \n", - "19 -0.041381 -0.945298 \n", - "20 0.055433 1.417779 \n", - "21 0.021741 0.340015 \n", - "22 0.080233 1.802895 \n", + "0 0.002839 -0.133096 \n", + "1 0.086610 2.145034 \n", + "2 0.033276 0.583157 \n", + "3 0.037070 1.118928 \n", + "4 0.008293 -0.007815 \n", + "5 -0.043895 -0.978858 \n", + "6 0.065673 1.240997 \n", + "7 -0.050807 -1.400648 \n", + "8 0.052652 1.356497 \n", + "9 0.079879 2.206585 \n", + "10 -0.006467 -0.232787 \n", + "11 -0.061822 -1.261396 \n", + "12 0.043414 1.135982 \n", + "13 0.008597 -0.019312 \n", + "14 -0.049931 -0.422043 \n", + "15 0.077301 1.298620 \n", + "16 0.071764 1.128256 \n", + "17 0.041611 0.756638 \n", + "18 -0.114931 -2.123303 \n", + "19 -0.041382 -0.945299 \n", + "20 0.055433 1.417782 \n", + "21 0.021741 0.340016 \n", + "22 0.080233 1.802894 \n", "23 0.077561 1.438909 \n", "24 0.043352 0.578693 \n", - "25 0.125760 3.414157 " + "25 0.125760 3.414156 " ] }, "execution_count": 5, @@ -870,13 +870,13 @@ { "cell_type": "code", "execution_count": 6, - "id": "0745e179", + "id": "0f90c07f", "metadata": { "execution": { - "iopub.execute_input": "2026-08-17T16:39:15.134763Z", - "iopub.status.busy": "2026-08-17T16:39:15.134505Z", - "iopub.status.idle": "2026-08-17T16:39:15.146585Z", - "shell.execute_reply": "2026-08-17T16:39:15.145758Z" + "iopub.execute_input": "2026-08-25T17:35:08.182410Z", + "iopub.status.busy": "2026-08-25T17:35:08.182211Z", + "iopub.status.idle": "2026-08-25T17:35:08.195239Z", + "shell.execute_reply": "2026-08-25T17:35:08.194346Z" } }, "outputs": [ @@ -900,19 +900,19 @@ { "cell_type": "code", "execution_count": 7, - "id": "38dd63f3", + "id": "938b43e2", "metadata": { "execution": { - "iopub.execute_input": "2026-08-17T16:39:15.148415Z", - "iopub.status.busy": "2026-08-17T16:39:15.148153Z", - "iopub.status.idle": "2026-08-17T16:39:15.248421Z", - "shell.execute_reply": "2026-08-17T16:39:15.247636Z" + "iopub.execute_input": "2026-08-25T17:35:08.197065Z", + "iopub.status.busy": "2026-08-25T17:35:08.196849Z", + "iopub.status.idle": "2026-08-25T17:35:08.310244Z", + "shell.execute_reply": "2026-08-25T17:35:08.309278Z" } }, "outputs": [ { "data": { - "image/png": "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tmPHDu2PP/7Qzj77bG3w4MFaSkpKuevslVdeUa//wAMPaFu3btX+/vtv9fiYmBjtr7/+si7XuHFj7brrrnN6/I033qjVr1/f4/XkysaNG7X4+Hj1WKy/7du3a48++qj6bM8++6xaJicnR30+vN/XX39dPTdez5URI0ZoDRo00ObNm6cdPHhQrUes7zFjxliXKS4utr5P/GAdPPPMM1pwcLD2ySefWJfD9sHrYntMnTpV+++//9R2iI2NVe8TP3hu3P/DDz9ocXFx2t133233fvTnuOGGG9RrYHv9/vvvWteuXbWGDRtqhw8fti777bffqmWN2wDrsVOnTlrbtm3Va+zdu1ebO3eu1qxZM23o0KFu16+nj921a5f6Dp122mnaihUr1HYYP368dv3116v389VXX1mXfeqpp9R9WVlZdq+1fPlydT8+g6vPk5+fr73zzjvqviVLlljXf2Fhofr7ySefrPYhR6NGjdLCwsLs1pWj1NRUrUOHDuqz4f3ie7Zy5Urt3nvv1T799NMKv3d9u2Ffx+OwTqZPn67eb+vWrbUzzjjD6T089NBDdu/zRLbd4sWLnda9rkuXLtqFF15ovT1//nz1ncFrf/3119b7r776aq158+YV3u/N9kN9fWzevFndxn7csWNHrX379mrduJOXl6eWx+Mfe+wxu+MD1gmOJdj22CfwXXrhhRfUMW/06NHlbg88T1WvD3evjX0Lr4Xv/ZYtW9SxdMiQIdoVV1yhHoPP7gr2w2HDhmmNGjWyex86HCeio6O1iy66SG0LfE+nTZumhYeHq9fXz3/4TDh+47VxzMPjhg8frvY5T17HzOWXX661bNlSu/jii9X+gO8T1gmO17jPCK9lPB8A1jvWI9YZjvPr169X50ls1x9//NFuP4+KitLOOeccbenSpWp/wHkSt48dO2Z9L/jO6fB+cK7C9tTXryfrwRVP3yveB9oZ1157rTpX43w/c+ZMtRz2C3frBOdyvAbO2UYlJSXqOfv27ev0vnDcOOuss9y+d/IPDLTI76FRjQAjJCRENdpxgv7iiy9U48sRgiAEPmYcAy13yyMAQON00KBBbt8bHosTMRr8jvf37NnTejs3N1erW7eudu655zo9x5VXXqkOxoCTO06+aAQb7d+/X4uIiCg30MLjcZLCydvx89SrV8+uAelpoFXeenUFDRKcuB1P+vhs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", + "image/png": "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LVumbqMR0Lp1a+2OO+7w+vOQezimrV692no7NzdX6969u3b55Zdb78P3DxcxjN+Zyy67TAVcFXkeT5Yh93D8M55rcC7DxUAcp3Q4fuGig/GC1JgxY9RxT2+DePI8xu2Ei8AvvPACA60KSk1NVecn4wWixx57TAVCevsCLr30UnVRST/3fPXVV+rYhjZhRZ4H7RtcSETbRPfnn39qBw8e1KoTAy2qUn///bc6GOlXwdPS0lTDEAGZ8Qo8DnoTJkxwenx5gdaHH36oes5wYGSgdeLQKMf6Rg+V3rhGo2LKlCl2y2Gd33zzzU6Pdxdo4WrtiBEjvPAuyQhX/R599FHrbVzhu/jii+2WGTt2rAqWzbgKtEaOHKmdfvrpThc10AChysNFplGjRllvX3/99eo+o+eee05ddcexsaqfh9wbP368uuCge//997Xw8HC7Bt0ff/yhjnv//POPx89T2WXIvVdeeUVlZujmzZunts2uXbus9+3YsUPd99NPP3n8PDp852699VZt06ZNDLS8YO3atWo9oq0I+F4hOwkXFY2QffHQQw95/DzQokULdcGwpjF5m6rUggULJDIy0jqmZ9OmTVJSUqLGluiQk47b69evr9BzI5/6/vvvl08++YTjfLy4vZC/3KlTJ3V79+7d1rFARhinVZHtlZ2drcYVnXPOObJjxw6ZPXu2GlOHfYEqD98BbCPj9sF2MdtemzdvVuN8PDV+/Hg1DuX222+XmTNnyrhx49QYh+eff56brJIwVmDdunUebS+MTdi/f3+VPg+5h4vRv/76q9N6bt68ud14EKxn/W+ePk9lliHPzmGO2wvbCttM17JlSzWG3N05zPF54KuvvpLffvtNpkyZwk3hJQsWLFDjHNu2batuY4wcxmc5rvvy2oiOz4PxxxhDhzYHzn3fffedGs+F71l1YzEMqjJoWD/55JPy2GOPqYMaZGRkqP8xKNEIg0kr0hhAg/GKK66QJ554Qjp06ODldx6YEADde++9cscdd1iLk7jbXihk4ikM4McBbt68efLMM8+ohgkOenieH3/8URo3buzlTxMYRTGuueYa6dmzp1xyySXW+7HNzLYX1j+CZldFShzVrVtXDRyeO3eu+m7iIgmKZjRq1MjrnyUQ4KLC//73P7X+Ro4cWe72AnzHHAsFeet5qHzPPfecrF27Vt5++2236xmFfVAk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", "text/plain": [ "
" ] @@ -932,7 +932,7 @@ }, { "cell_type": "markdown", - "id": "fb78e891", + "id": "a6022e64", "metadata": {}, "source": [ "## Conclusion\n", @@ -965,9 +965,9 @@ "version": "3.13.7" }, "quantlab": { - "code_hash": "51c6d2bd9d6fdae1a9aaf52e138fda7161dc9177754dc9b1a96c98498d377105", + "code_hash": "01f453a13e89b4a77bb5e85538cd9963479ca9a60745ac9d35d77a2a58d5c3ba", "config_hashes": { - "configs/momentum_sp500.yaml": "7a9f43ca4e4fd9975d3abc542f60e55a1b02fce5be00efc2da339f3156e59178" + "configs/momentum_sp500.yaml": "e2be7ba15eca4cf73930a4a991a252549c7a921d2c09d50bedc7c5c8f6552a7e" }, "generator": "scripts/build_notebooks.py" } diff --git a/notebooks/03_mean_reversion_research.ipynb b/notebooks/03_mean_reversion_research.ipynb index e37cd7f..7ebec20 100644 --- a/notebooks/03_mean_reversion_research.ipynb +++ b/notebooks/03_mean_reversion_research.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "54f3136e", + "id": "5c1da949", "metadata": {}, "source": [ "# 03 — Mean Reversion Research (Example)\n", @@ -15,13 +15,13 @@ { "cell_type": "code", "execution_count": 1, - "id": "2225c90e", + "id": "23e21402", "metadata": { "execution": { - "iopub.execute_input": "2026-08-17T14:37:10.536369Z", - "iopub.status.busy": "2026-08-17T14:37:10.535755Z", - "iopub.status.idle": "2026-08-17T14:37:31.523044Z", - "shell.execute_reply": "2026-08-17T14:37:31.520849Z" + "iopub.execute_input": "2026-08-25T17:35:11.296482Z", + "iopub.status.busy": "2026-08-25T17:35:11.296101Z", + "iopub.status.idle": "2026-08-25T17:35:32.461383Z", + "shell.execute_reply": "2026-08-25T17:35:32.460597Z" } }, "outputs": [ @@ -52,7 +52,7 @@ }, { "cell_type": "markdown", - "id": "51258c30", + "id": "d03f23c1", "metadata": {}, "source": [ "## Comparing indicators on SPY" @@ -61,19 +61,19 @@ { "cell_type": "code", "execution_count": 2, - "id": "8225507c", + "id": "570ee0a5", "metadata": { "execution": { - "iopub.execute_input": "2026-08-17T14:37:31.527552Z", - "iopub.status.busy": "2026-08-17T14:37:31.527068Z", - "iopub.status.idle": "2026-08-17T14:37:32.405733Z", - "shell.execute_reply": "2026-08-17T14:37:32.403384Z" + "iopub.execute_input": "2026-08-25T17:35:32.463517Z", + "iopub.status.busy": "2026-08-25T17:35:32.463286Z", + "iopub.status.idle": "2026-08-25T17:35:32.912694Z", + "shell.execute_reply": "2026-08-25T17:35:32.911773Z" } }, "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA94AAAMWCAYAAAAH1l7yAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvctoD+AAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzsXQeYJUXx77f59vIdOarkoOQgSRHJQclKUBEQkKikP0mCIIJIFAEFBRWQnJGMSM4553zAxb29zbvv/1XP1Ex1TXVPz3tv9/bu+vd9d7v73kxPd093deUqlcvlsgoICAgICAgICAgICAgICBgU1A1OswEBAQEBAQEBAQEBAQEBAUHwDggICAgICAgICAgICAgYZASLd0BAQEBAQEBAQEBAQEDAICII3gEBAQEBAQEBAQEBAQEBg4ggeAcEBAQEBAQEBAQEBAQEDCKC4B0QEBAQEBAQEBAQEBAQMIgIgndAQEBAQEBAQEBAQEBAwCAiCN4BAQEBAQEBAQEBAQEBAYOIIHgHBAQEBAQEBAQEBAQEBAwiguAdEBAQEBCglNpiiy3UmmuuWdFnAUOPL7/8Uo0ZM0bddNNNs3X6W1pa1GGHHZb8/emnn6oRI0aou+66a7b2KyAgICBgeCEI3gEBAQEBcxwWWmghVSqVkn+tra1q1VVXVeeee64aGBiY3d0LGAIcf/zxapllllE//OEPk896enrUNddco7beemu1yCKLaMF89dVXVxdeeKHq7e0V27nyyiv12gEBGtbV/vvvr6ZNm1ZxvxZddFHdxuGHH676+voqbicgICAgYO5CELwDAgICAuZIrL/++qpcLut/77//vtp0003Vr371K3XccccN6nPBkvnMM88M6jMC3Pj888/V3//+d3XQQQdpxQvi2muvVbvvvrtaaaWV1OOPP64++eQTvSaOPPJItcsuu2TaufTSS9Uee+yh9t57bzV16lR13333qf/9739qs802q0poPvDAA9Vrr72mbrnllvAqAwICAgI0guAdEBAQEDDHY8EFF1RnnnmmWm655bR1M1i9525cdtllqqGhQe20007G52PHjlX33nuvXgtLLrmktnjvueee2vp88803GwqTrq4uddRRR6kdd9xRHXzwwdprYuWVV1Z/+ctf9HVXXHFFxf1beuml1TrrrKMuvvjiqsYZEBAQEDD3IAjeAQEBAQFzBcDyudRSS6mZM2eqGTNmGN+BEAUuxxB7C8LZ5ptvrp588smKniPFeK+77rrqu9/9rvrwww/VVlttpUaOHKndlo855piMEgAs9CAYfv3rX9f9AQHtscceU/vss4+ab775nM8GCy11saf/QNjLA1iBYezzzz+/Gj16tFprrbW05Zj38f7779fXjR8/Xguv3/nOd7Q1uOic4ry8++67asstt9TP/NGPfqS/A9fv008/Xa244orazXvChAlq1113VR988EHuOG677Tbdd2iPYtttt1Ubb7xx5nqcG/CMQDz44IPapXz77bc3rt1ggw3UAgssoK677jrj8y+++EJbx8eNG6f//eQnP1FtbW3WPn7ve99T//3vf/V6DAgICAgICIJ3QEBAQMBcARBo3377bS2MgWCE+N3vfqf22msvtcMOO6iPPvpIPf/881ow3mijjdTDDz9cs+fPmjVLuzWffPLJ2hX6t7/9rfr973+vLagUJ5xwgnaH//Wvf60Tcf3jH/9QZ5xxhhba8wDCObrX479bb71V1dXVaWutC5MmTdLC8WKLLaZeeOEFnZwM+vboo4+qF198MbkOBHFw2wfFAAjS0MdTTz1VnX/++RXNaXt7u3YJP+mkk9R7772nfvCDH2hBHwTes88+W5144om6b0899ZQWUtdbbz3dNxs6OzvVc889VyjB3e23365/gkcE4qWXXsp8hlh++eXVyy+/bFjHN9lkE60gAaEfxgyWcojltmHttdfW7upwT0BAQEBAABzaAQEBAQEBcxQWXHDB8vrrr5/8PWnSpPKvf/3rMsjfv/3tb5PPp0yZUm5paSnvsssuxv1dXV3lRRddtLzOOuskn22++eblNdZYw7jO9zNop66urvz6668bn2+44Ybl1VZbLfl78uTJ5ebm5vK+++5rXAf9HDlyZHnixImF5uGZZ57R96288srl6dOnO6+9/fbb9fw8++yz1mva2trKY8aMKW+11VbWa4rMKfwOz3zhhReMa6+55hr9+XXXXWd8DmMYN25c+eijj7Y+/5133tH3nnnmmWUf3Hbbbfr6LbbYwvj8yCOP1J+//fbbmXu22267clNTU/L3JZdcoq998MEHjesuvvhi/fmhhx6aaeOJJ57Q38G9AQEBAQEBweIdEBAQEDBHAiy16GYNbt1gPT3llFN0tmsEWBvBWgmWWYrm5ma1zTbb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oosuEosv7tf+1dDW5i0Ira2qhbRXr17Bdyace+65on///sE/XXGvB2QXWD3F0cTaF9kQ1JJExhxvxeNdP4p3pD516xCRn/Wd8VkLaRTvCud4538erQrLZQXdtAvegloFj3dSfpKOwqxxyt/ZIeuLhpX+JbKD1ym2BfRq8fcutvSH6V4O86cAgperd125ni08G5m3O1N5dIHtPwc8CKlqDHvCXSDEuKwX/ryVzNPyfG8uG3M9a27DLZXkLwHl8MRWKm1FQ+eEF7xfkowFqY0VZTB4yTb5Qn4wH8J5XZibssa4awuAm0JyIaTI8TaNcTROLXNA+RRv07oniR27MPedrA953yje+dProu6gj+liFZVcsyi0+0agbKPILrp99BhdztHGS0Fnes5kwxrSiYq34fsUsogk9mxZEE90OCFbObmSzCnkJQmcLWBgIpEKhTkTKyoHKYb0kp61XOt3yGoO5K6AbL+lrffr/ObeMt2XUQy6TOt67rnnxLfffivuuusuyWYO/956662A3fynn34Sffr0kfncQL5GAURrAwfaS5BA2Pr06dODf+PHkzJddYLsgmu4H4wT3VTLWnq8aUiO4RUr5Gq1Jvj68MNTEU2b3hI9pGmgt8CaNkvaLzbBEY+vMKu5hOLxLt+0K0wfQ/5AcrWuz/G2Mra6nt/QIprWPruE6xQRal4slCnjMH8gXNf1uRxyvFGBlQp9MUgVBusLgjiWHdaLQvsshSncMxACmYtJAagxw18wd2pX8VYrJFSwXJRfzzVSolKDnrrQFTneXh1j9b65xXYSDUBylGsW7R94JEJlB3oAE54hkfSuwooJQipoZSI3i71136WibcA9j+599QItiiOosVyMZ9RfD0ERNM6Vtunx1/DrcGcHr+23LRdGbRWjeHemCDVv6CV67eMZUDKBAh53Qq6C49tOrha8H/q8UHqtUsjR+6QXX4bfAAEAAElEQVR71sb1LyUVeMojfxcwx1vuz/7vA1coy7UZ5UeXucbWX3998fDDDyufnXrqqaKpqUkcdthhol+/flLpBsI1nekc/l511VWt125ubpb/6hppJm9gVWy0eLzjw9zUxb/GBF+EUp8RDBNrmo9RmJgtOd5x95CnVWaBziiGACp8VMjYoTN79iSkCDVvWP4g0U65Acp1XxvSeJ3I3MwO38p8DOZM0jqiaZDW4512jqCg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mNdee01cffXVUvmuBObOnSsV/r///e+ipaUl+PzJJ58Uq666qvjqq6+kx/aWW24Ra6yxhvjtb38r/vznP0eu8+KLL0plu3///uLOO+8UJ554olRSd9xxx4ormGnbWgxgLMN4nzp1asnXAqX7gw8+KKthgMFgMBhdj4Yq3JPBYDAYPRS9evWSnkDEKqusIn788UdxxhlniLffflt6ciuBTCaj3LcegQoiGg/+9a9/iWuvvVYcffTR8u/58+eLv/zlL+K0006r2LOCsWT69OniD3/4Q8SbftVVVymGDfAkz549W5x77rnib3/7m1h77bXl5+Cl/+tf/yqf5brrrpPvBhRhCIEHA8wdd9wh/vjHP1ak/WnbWgsYOXKkWHfddeW71qMMGAwGg1E/YI83g8FgMKqKgQMHBgqR7jUExWyrrbYSK6ywggy5BW8rKJhpYcrxpjnP4FHcbbfdxEorrSQ9yu+++27kGhAGfeaZZ8o83DXXXFN6aaEttlxj8FDiNUGRAy805Oya7g9h17vvvrt8zscff9z4DN99951Yaqmlgr/h3O+//z4INwfjRZ8+faSHNAlvvPGG2GmnnWTboI1g9HDBgw8+KJZbbjkZuUABnmpTNMFaa60lf3766afBZ9C34G2GMHNQuhGbb765GDZsmLjrrruUa0Afn3322ZF+LxZp2mrDs88+Kz3koLBvtNFG4rDDDpMGJIxMAKMCACISMLWCRiGkfaZtttlGphmA0YPBYDAY9Qn2eDMYDAajagDF8cYbbxRLLrlkxMu4zz77iEcffVSGVW+88cZSOT7yyCPFY489Jp577jnR2NjofB9TjjfmPI8ePVr873//E//85z9Fa2urOP7446XnFfJtIccWAMotKMYQyn3xxRdLZQnOA8+tKdf4mGOOEZdffrk47rjjpFIOedUnnXSSeOihh8Rbb70lBgwYENz/lVdeEffee6/MOYZcd6qMUiy44ILi22+/Df4GJX7QoEHy+A8//FDmykObcrlcYn4zKI7Ql9CHYMyA/oU+BSXSBuiDUaNGGb2u2azZjg/9BVhkkUWCz9577z35E5R+HfAZGCHoPUHBffnll6USC8oxXPOggw4SxSJNW02ANAlQ3uG9wj8wEL355ptyvMK7BOPIAw88IJXvAw44QBx88MHyvH79+hX9TBAJAveB/od7MxgMBqMOUWAwGAwG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9juL23N9S5b3fj33InH3S29Gngnm0zn/2E/8SKJrYT49+49jxP+tvGRENlrn3bcia0TadQ/G3hvLriKOmfyNaH/zDadnmj5yWTF1y80ja/mmu+8sRvzrb4nvCZ5pyXffE/m336rI2Ptu4y3EljddK57faFPlPU3Z/wCxzonH1YQc0dpFstGHq64qVvvoIzF9+nTRr18/UTeKN4QetLS0iCuvvFISqyFOPfVUSdQ2YcIEZ4/3oosuKqb++GPYAXXs+QFv5C33PSa+/PRLcf6ph4cstxV4Jgh1Pu2cK8QuO20lVl9nDXHCGZdIz/X5Zx4ThCKbnuneBx4Xoz76QvzzL/uK66/9t/xs9122ERust2aiFerIo86QH110znHWZ3r6pdHi8Rdfl5a1S84+tsvf05FHnCbD+y4469jgPX360Wfi5pv+I3r1ahFnnHSYs2UNiIZOPetysfU2m8pn2nnzDcTWm60vjj/tItHe1hHxeF9x7b/F9+MnSo/3sUf/TQzr18f5mQ498jTp8V56yRGSfOn4o/4qBi+2iDL2jjrhPFHICNHe0CituuussrzYd8+d5XdPPj9KPPnKm+KYf/xJDB3UXxx/ykVijdVWEPvuu7t17M3tzIsTjjtb7LDVxmKrzTcwvicICQTvMzzTfr/fXay13FJBWwDHnnCoGDJ0sDjyXyfLv0869u9iQP9+8plefuUN8cgDj0uP99577pRqPsH185mMuMz3ktD39PEXY8WNd/8vsFSffeoR0lN6+32Pi3c++UKce/whondLc+zYg1y5ex57XpxxyhGif2OubGsEtLultVmcdcoRNWXVreS699gzL4tnXntHegouPSs0tIz57gdx5a33iI3XWkXsufPWic902MkXiHw2J64446iinwn6H7wku+ywpdhyvdWV4w899WLp+dl6wzXFS694gtnqa6wk9vvT3tb39K/DTpEeb7nmwdp31W3i+8lT5Ng77tC/iKFDFgieacz3P4prrrxFehTweP094by5+JLTxBdjx4kbr75V/OVPvxPLLbOk/K69ISe9WZeffqQ4+sTz5bE7bre52HSbTUXbvPnyPZ18Zpgq9H//OEAst9SIojwK2JaLLjhJjr1/HXaynE+nn/Qv0btXa+Q9QYjxMSddIFZcbQWx0UbrieuuvkWssuIy4o/77i5OPftyMW1em7jy0tPLMvba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0CQVhSLBGf/+97+Lo0ePLo4fP744Y8aMYrdu3Yo777xzcfny5cpzv/71r4utW7fmvw0bNqw4ePDg4gcffCB+X7VqVfH73/9+sWfPnvy/adOmGeuLK4dgxgUXXFDs3bt3cZddduH/wRhee+21yjNr1qwp7rHHHnwOd99992L79u2LxxxzTLG+vl4889xzz/H3hw8fXoSt8uc//zlVXYQwVq5cWTzkkEOKffr04fOwxRZbFLt06VK8//77lecWLVpUHDlyJF/7ML51dXXFG2+8UXnm7rvv5vty6NChfJ7ee+8965B/9913vLxmzZoVf/zjH9PUxOCpp54qjhs3rjh27Nji3nvvzc+rbbfdtvjVV18pz/3xj38stmnTpjh58uTiZpttVuzXr1/xzTffFL+vX7++eNpppxV79erF53z77bc31vf5558Xt9tuO/7crFmziqNGjaL95IDbb7+9OGjQoOLWW29dnD59erFt27bFww47rLhx40blublz5/J5mjp1Kj+3Jk2aVPz222/F75999lnx4IMP5nPUoUOH4umnnx6qa9myZbweWAv77LMPXxtdu3YtPv7447SfIrB27driUUcdxccW7nwYw44dOxbvuusu5bkvvviC77kBAwYUp0yZws+8H/3oR5mXQzDjk08+4eMK+2mvvfYqjhgxgv/94osvKs/B5x49evAxhjOrXbt2xfvuuy9ROa51EcK45557ikOGDCluueWWfOyAhtt///2L69atU5677LLLOF0GewDupQkTJhSXLl2auBwE0B8tWrTg9AohHnDmwFkFtAHcO3V1dcWLLrpIeWbDhg3FAw44oNipUydOj8O/8Bm+T1IO4G9/+xufm4kTJ3KaBWiIl156qaKmihjvBPj73/9efPvttxUCZODAgZygRABj3Lx58+Lvfvc7/hkWDjDOu+22m/LezTffXFyxYkXx0EMPNTLeLuUQilaBBQg3EH/5y184QyZfZpdffjknHBcvXsw/v/7668WWLVtyBgLxyCOPcGELjL2N8XapixAGXHx/+tOfips2bVKEGMAUyOM5c+ZMzujhJQhzUFNTU3zjjTfEMzBnr776avHZZ5+NZbwPP/xwznzAwUyMdzweffTR4muvvSY+w5kFgoujjz5afAd7CC7Bn/3sZ/wzzCkwf8DUIWBOf/KTnxS/+eab4oknnmhkvEHotc02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", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA94AAAMWCAYAAAAH1l7yAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvctoD+AAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzsXQeYJUXx77f59vIdOSo5KTlIUlByEIn+CSoCApIlSZIgQRCJIqAgoIISJalkJOeco2QOuLi3t3n3/b/qmZqprqnu6Xnv7d7eXf++725335vp6e7prq5cpXK5XFYBAQEBAQEBAQEBAQEBAQGDgrrBaTYgICAgICAgICAgICAgICAI3gEBAQEBAQEBAQEBAQEBg4xg8Q4ICAgICAgICAgICAgIGEQEwTsgICAgICAgICAgICAgYBARBO+AgICAgICAgICAgICAgEFEELwDAgICAgICAgICAgICAgYRQfAOCAgICAgICAgICAgICBhEBME7ICAgICAgICAgICAgIGAQEQTvgICAgICAgICAgICAgIBBRBC8AwICAgIClFJbbrmlWmuttSr6LGDo8eWXX6oxY8aof/7zn7N1+ltaWtThhx+e/P3pp5+qESNGqLvuumu29isgICAgYHghCN4BAQEBAXMcFlpoIVUqlZJ/ra2tarXVVlMXXHCBGhgYmN3dCxgCnHjiiWrZZZdVO+ywQ/JZT0+Puv7669U222yjFllkES2Yr7HGGuqSSy5Rvb29YjvXXnutXjsgQMO6OuCAA9S0adMq7teiiy6q2zjyyCNVX19fxe0EBAQEBMxdCIJ3QEBAQMAciQ022ECVy2X973//+5/abLPN1BFHHKFOOOGEQX0uWDKfffbZQX1GgBuff/65uuqqq9TBBx+sFS+IG264Qe2xxx5q5ZVXVk888YT65JNP9Jo4+uij1a677ppp54orrlB77rmn2meffdTUqVPVfffdpx5++GG1+eabVyU0H3TQQer1119Xt912W3iVAQEBAQEaQfAOCAgICJjjseCCC6pzzjlHLb/88tq6GazeczeuvPJK1dDQoHbeeWfj87Fjx6p7771Xr4Ull1xSW7z32msvbX2+9dZbDYVJV1eXOuaYY9ROO+2kDjnkEO01scoqq6g//vGP+rprrrmm4v4ts8wyat1111WXXXZZVeMMCAgICJh7EATvgICAgIC5AmD5XHrppdXMmTPVjBkzjO9AiAKXY4i9BeFsiy22UE899VRFz5FivNdbbz31ne98R3344Ydq6623ViNHjtRuy8cdd1xGCQAWehAMv/71r+v+gID2+OOPq3333VfNN998zmeDhZa62NN/IOzlAazAMPb5559fjR49Wq299tracsz7eP/99+vrxo8fr4XXb3/729oaXHROcV7ee+89tdVWW+ln/vCHP9Tfgev3WWedpVZaaSXt5j1hwgS12267qQ8++CB3HHfccYfuO7RHsd1226lNNtkkcz3ODXhGIB588EHtUv6DH/zAuHbDDTdUCyywgLrxxhuNz7/44gttHR83bpz+96Mf/Ui1tbVZ+7jpppuq//73v3o9BgQEBAQEBME7ICAgIGCuAAi077zzjhbGQDBCnHnmmWrvvfdWO+64o/roo4/UCy+8oAXjjTfeWD3yyCM1e/6sWbO0W/Opp56qXaF//etfq9/85jfagkpx0kknaXf4X/ziFzoR11/+8hd19tlna6E9DyCco3s9/rv99ttVXV2dtta6MGnSJC0cL7bYYurFF1/Uycmgb4899ph66aWXkutAEAe3fVAMgCANfTz99NPVRRddVNGctre3a5fwU045Rb3//vvq+9//vhb0QeA977zz1Mknn6z79vTTT2shdf3119d9s6Gzs1M9//zzhRLc3XnnnfoneEQgXn755cxniBVWWEG98sorhnX8u9/9rlaQgNAPYwZLOcRy27DOOutod3W4JyAgICAgAA7tgICAgICAOQoLLrhgeYMNNkj+njRpUvkXv/hFGeTvX//618nnU6ZMKbe0tJR33XVX4/6urq7yoosuWl533XWTz7bYYovymmuuaVzn+xm0U1dXV37jjTeMzzfaaKPy6quvnvw9efLkcnNzc3m//fYzroN+jhw5sjxx4sRC8/Dss8/q+1ZZZZXy9OnTndfeeeeden6ee+456zVtbW3lMWPGlLfeemvrNUXmFH6HZ7744ovGtddff73+/MYbbzQ+hzGMGzeufOyxx1qf/+677+p7zznnnLIP7rjjDn39lltuaXx+9NFH68/feeedzD3bb799uampKfn78ssv19c++OCDxnWXXXaZ/vywww7LtPHkk0/q7+DegICAgICAYPEOCAgICJgjAZZadLMGt26wnp522mk62zUCrI1grQTLLEVzc7PadtttEytrLQBu7mAppQArNFh5aX+6u7u1SzQFuFlDsrgiAKsrjAFcwf/1r39pd28AWJapCzq4cQNWXHFF1djYqK3PYLWVxv3oo49q9+ndd9/d+tyicwqx1quuuqpxLTy/qalJbb/99sbnMAawZD/00EPW50+fPl3/5G7mEsCSD+7hkGkc4sIl0ORsts/B9R6eB27zFDSjOge8F9rfgICAgIB5G0HwDggICAiYo7Oa9/f3axdzKCEFLtsg+CGmTJmif4JgzgGfwf2QzboWWHjhhUXhi8abY38ghphD+swGaBNiyUHABTfqJZZYIveepZZaSl8LAiW4eUP8NsRgQ9w4zAMAXbxBULWh6JxKbYFrOZT+goRmkCStvr5eu8tD3yCWHJ8hAcMIXPHVgDfffFNnJ4cY9AceeECXF6OYOHGi/imVDgNhGZQhdMyQwE96Z9BvCdg/mOeAgICAgIAgeAcEBAQEzNEAwQeSZ0H9ZhCmwMIJQh0AhSdIjMUBn4GgRwWsamCznErCnhTD7IprpoCkZBBfDILlP/7xD53gjAIs3jQGHKzTCBBEwVMABGOwkoM1er/99tOZ4AGQdA0Acd02FJ1TsLJzQBI5UErAe4I4aFCeQNw39vntt9+2Ph8EaBDWQXi34d1339XJzaAvIHQvt9xymWu+8Y1v6J9vvfVW5juY229+85vGe7O9M1sGfYjzB8AcBwQEBAQEBME7ICAgIGCuACT3giRgYP3GMk5gFQdX63/+85/GtSDwgfUXEmD5uCzXCpA4DFyyQeilAKurbxKu/fffX7s+X3DBBdq1uxKA0AuJ1kBwB4ss1K4GbLTRRvq76667znpvLeYUXO3BIgw10YsCLNhrrrmmtZY6JKmDRGggzIPQDS72EkAwB+s5Hwe424NATUuVwbXQX+4C76rTDZ4XoCD41re+VXCEAQEBAQFzI4LgHRAQEBAw12CPPfbQ5anOOOMMnU0bLK/HH3+8uuGGG3TpqsmTJ+uSUhDDDNZZKOs1lADL6VFHHaX+/Oc/qz/84Q9a4Abr7j777KPdvvPw+9//Xmcdh+zpEKtdBJA9/ec//7l68skntas6CJLQD+gDluACgRkE+v/85z86YzcoMWAeQRjFeOxazCmUFAOlwU9+8hPdL7Beg9s8ZCv/5S9/qc4999xcwf2ZZ57JxKmDlRmEbrDyQ7kwWAs2gPIAss7ffPPN6uKLL1YdHR3q1VdfVT/72c+0F8GPf/zj5FooHQYCPLwn8BiA50KcOgjioEiRAEI/xIQPpWInICAgIGD4IgjeAQEBAQFzlds5JFgDiyUIkFi+609/+pMWFKGUFiT6AqETaixD+auhBpQZA8s8CKgQFw6u8SCMQ3y0TYhDgGAIOP/88wvX8d5ll13Uaqutpo488kjt/gz/YF5AkD/wwAOT66BMGFiiQegGyzLEaEPCukMPPTS5pto5hfd066236rJqF154oU5Mt/jii2trPrihg/u7CyAAg0X7pptuMj6HcAOoGQ7vf+WVV87MESguKOB5IPhDnDtY/sGyDXW87733XsNFHuPEoXY4xNbDmMFbAJQnNld3KMXmKjcWEBAQEDBvoQSJ3Wd3JwICAgICAuZ1gNUZhNfnnntudndljgAItWD1Ho7zBR4J99xzj86qDu7mAQEBAQEBweIdEBAQEBAwm/HZZ5+pJ554Qn3729+e3V2ZYwCeDWBZvuWWW9Rwe5eQY+B3v/tdELoDAgICAhIEi3dAQEBAQMAQ4pFHHlF33323djEH9+rXXntNHXLIIdq1Gyyk8FlAQEBAQEDA3IVg8Q4ICAgICBhCrLvuumrUqFFq11131eW7ttpqKx1HDUm7gtAdEBAQEBAwdyJYvAMCAgICAgICAgICAgICBhHB4h0QEBAQEBAQEBAQEBAQMIgIgndAQEBAQEBAQEBAQEBAwCBirqxxMTAwoLOKjh49WtftDAgICAgICAgICAgICAioJaAy98yZM9Uiiyyi6urq5j3BG4TukKAmICAgICAgICAgICAgYLDx8ccfq8UWW2zeE7zB0o0TMGbMmNndnYCAgICAgICAgICAgIC5DG1tbdrgi/LnPCd4o3s5CN1B8A4ICAgICAgICAgICAgYLPiEN4fkagEBAQEBAQEBAQEBAQEBg4ggeAcEBAQEBAQEBAQEBAQEDCKC4B0QEBAQEBAQEBAQEBAQMIgIgndAQEBAQEBAQEBAQEBAwCAiCN4BAQEBAQEBAQEBAQEBAYOIIHgHBAQEBAQEBAQEBAQEBAwiguAd4MRdz3arz6f2h1majXh/Up96+9O+8A4CAgICAgICAgIC5lAEwTvAiUMvm6n/Bcw+bHnidLXtydPDKwgICAgICAgICAiYQxEE74Bc9PSWwywFBAQEBAQEBAQEBARUiCB4B+QiiN0BAQEBAQEBAQEBAQGVIwjeAbkoB8l7nsXAQFnNmDUwu7sREBBQwz3d3hX2dEBAQEBAwFAjCN4B+QiC9zyLy//dqdY+bOrs7kZAQECNcPl/OtUaB4c9HRAQEBAQMNQIgndALoLcPe/i1Q9DNvWAgLkJL70f9nRAQEBAQMDsQBC8A+YIV/P/TepXO58RMnsPNeoDhQgImKtQKs3uHgQEBAQMPcrlsrrlsS4dbhMQMLsQ2OqAXAwHGnXrE13q5f/1qf7h0Jl5CHWBQgQEBAQEBATMBd4+v7yqXT3zdu/s7krAPIzAVgfMERbvhvrITNPVM7t7Mm+hvi6YxwIC5iYEi3dAQMC8iL44p2Rf/+zuScC8jCB4B+RiGMjdqiFeqd3DqKY4ZPs++a/tc7XbUrB4BwTMXQiqtICAgHmZ9s29HFvAnIAgeAfkYxhQqYb64Sd43/ZEt/r7Q12qrWNo+vToa0Nv7o8dDXRsVEBAwJyPae2R2eehV4L7UEBAwLzn7RPYmYDZiSB4B+SiPAwk72Hpah4T8aEyeP/0/DY11KiPFR79oexvQMBcAaShk2eETR0QEDAPCt6zuyMB8zSC4B2Qi4FhwJ81NAw/i/ecFP787md96sk3eyqO8Q6Cd0BA7fD6R33qi+mzN9AwxHoHBATMTnz0Zb9abt/JqrO7PLSu5sOHjQyYBxEE74BcDIdEFMMxxhsZ1+GgmMjD1r+arn50blvFMd69/cNn3gMC5nTscNp0tdPpM2bPw+cghWHAvIHH3+hRPcPobA8YGjz7TpRd/Ku2oWGigqt5wHBAELwD5gjBGy2vXT3D53CeFxJ1JDz63DzIgIDZgC+nD8wTFu+7n+tWk6YNg0MkYNjiJ79rUxfe1jG7uxEwxGiMPRl7+4bI4h1czQOGAYLgHZCL4WDtxDjq7j41bIDW4IG52G8pserPvUM0AB4VfcNgvQfMOXjwpR71/qRhRJjyUB5awfuQS2eqwy+bOTQPC5hj8cW0OcB1LGBQcvcMVShbQvPCET/b0dFdVodc2jasjGlDhSB4B8wRFm8s2TWcNmkppuLlgbk3FhMfPSe409cC3zhwitrvwqFPYhcw52L/i9vUbmfOJrfxOSRHRVdwIw7IQecwOtsDhgaN9bOHxwxVWmY/nn+3V939XI964+M5SGldIwTBO2DOsngPIwZuqJSnGN8+OzCvWbwBj70exZ0FBPiiZ4hcJQeT6WzvHFD9g7TRQ3LGgFoqZz6Z3K+2O2XaoK3XgKG1eA+VqzmSvqF4GqzNIODnv4uSmvcQBO+AOcLijYRyOJUTQ1fzwfY0x+fMDoRkJAEBkcIPvW4kzEn8P3aV0601DpmqzvjHrMF55hw0PwGzB0W8qu56tlu99Ul/sJLPLTHeQ8RjJoL3ENCjFX82RZ1wTbua1zGlbUA0mJXn4eoaQfAOmDME72Fs8R5spru+rjqiN7NjYNiP0YaB2aA1boqZgYAAGoLgSv6ES/SZt3udAvpwgMvqA/Hqg/lMH1z/cJea1TW85zBg9npF4LXzSgjU3IrGIbZ4I2keKuryn2drS0+BFxqquaoVvvWLqeowIcdHeYhzjQwnBME7YI7AsBS8Y4Ix2DUoMaN7pURvu1OmV/7wxNV89sz7d4+bpnY7a2jjZ5sa58GTICAXj7xmD0GA7dHeNaD2OGeGuuzfncN6NhPmU9jS02fNXldzYCxP+ku7uuLukOGaKk+h1vHnU4eBBnwQUSSpJQrcRYwCMI9vfzr3xpNCOTZQWM1JghnyUENl3BmoQmFz2xNdasasYjfWQgn72Os96qsZ0XOvvLtTrXzAFDWn4cX3s2dnOQjeAcMdU2cOqAdfHlo/66GyNP735R719FvuuFrsynB0Nf/dLYPLJNbHCUgqxWdTq7d4D3YCORs+nTKgXnx/aJmlYPEOkPDqB/Z1CPzV1JkRkXru3eGdI8DlbjlYlmbfowRdTj/6ciA5g+b1ON73J/UbP4c7jv3zTPX9U6cV5jMKWbzLxXMr7PnbGWrbk6tQQg9zrHLgFLX6wVN0FYE5BUgXuLIA1gQKm7VENaTk6Cvb1VnXFwvFoWv68Mvb1J/vKa6U3fu8Nn0v4Ik3h/fZUmTey+V512slWLznEJz4l3a1/0VDm215qPidn13Upg9Fn74MK4s3UYoMJmJvrEEHZIwHq52UuX2o1gKUl7jw1sGJM/VFcxUWb2AWDrqkbdi7GwfUFsBETIvpwBLzV6kpqwHe/cyuJJgwOjr2mxqGzrPD12OmN+72HU91658H/2GmjpWcl4HJTYfyffkAzr1bn+jKfP7Px7vVGx/7KwmQVBaxeqIypsg9k6pQQM9JeOiVYWSd8KQLPMb7tie71QZHTq398+J1w8kRnNtQ3ioPbZ3FznXKBvz7mR71mxsq423Q4DQ7E+1SnPzXdnXx7QUMTuXaKNzmFgyT1xiQh47ZEPM2nDRRuEmHY1mawY5RqcbVvAh2PWu6WuPgqbM1qzmUl7jkzs7ZusamtVe+8MEd7d4XelTnnMP7BNQA2uLdXjZK5NQK/5vUr12NwTPIB+A9tPWvpuvMzxK+t1qT/jlqxFAK3pW5G8NemteByohar6tqceq17eqYK9tr6P47uK7mjY1qnsBw0fm+9H6v2ujoqU7PybLFcwFoHqDWCmxsjjcLQv5eOcafSsrZ1kqobIrXbn1shZndiv2/P9RVSPCWlsBABQq3uQVB8J5DMDsyWw/HTLTIhAwHIMEYbPa1WldzX7wpWCkGM7kaeC+AQDFc4u56+qoPZ0iywA9Z+hY1V8csvvBe1rUOmA5g6oYb0OJd6wy978TWa/AM8gF64Njcxm1ZzQcT3q7mw4MUDCugJY7yAJBXxMdCN5jortEWxFH0FRBS8DwqEs/cNFSuY7MZw4VvA7foL6YN6HCxvPfY0yufo7W2hiaCt9DuK45QokoF71q9C0xCh8q3jjms5r3U235Ung0XTdEQIgjecwiGyOhpoJr98Jf7O2vqgo2Ecji6pbS2lIYsq/lQZ/hOBMlBmPcZcSKn594pzsFNGoREQ7ZDFYS8o6/0i5tD1/zZFRM/N+H3d3SIifXADXGXM2cMelLDokBPiVpr8Ec0FaMveV4qSWzdENISX+8pdKsOSIEZgenZ9/3Tpqn1f1EbF/zL/92h9r+oeALLWsXe4zIscrbjeiqi5EKr4dyIWvAFdzzVpa7KiUGGULSPv4omHaqlQMI6G5ZcIJISX/6fQ6DNidWvtUyWrrXKGi5XqECuVd4ZDINrL+jyPpS4+t7OTCUdaXn2xns3WLyHAT755BN15JFHqrXWWkutuuqqat9991UffPCBmtcxO1LuV0r01jxkijr977PUH+6sXdKxRCs+jBizhcZHEvF3vhm5bg6F0mWoidRgupqjVbjo2gZBeONjpqm//7e2LumdFsH7/H92qNueiGJOfd/V8Fmlcy6mxa7bHG0d5cKJlWoFngOBAvdmrWnUiOZiGwQto+VcwVsNGXyTtnFBaigVzoORzKmWoLT/gy8gJrU27UJy0Adf7vVSLJ1946yax2YmwlCBsy11Uy0XthrOjajFuzjyT+3qrJwYZFACQaURwLanTNdVU6rZ+4nFu29oLd6VtluJQv0/z1a+UXF9Y6WVlqbhLXiDF+OZ189Sf3vQzP0wU+hvb3x+F9n3cwuGncV7l112UYsttpi67LLL1NVXX62+/PJLteGGG6rJkyereRmzw+JdqRIVN1ljDZPBDMd4kPIQxcJjXI90QA2V4mYwXKfTchLFOvfF9GjCT/5bbZOw2VzMi7j6J4qK4c3DzxGw1a/Hz19yWVIGCX+5L5tMqhornA98Yntf/6hP/fuZblP5YxO8lXuNuhKz+QA8nbj3yIxYWZIH7jpsWwO1BtRfhzjPwRS+j796ZkXePYjBzu5+5d0dztjRax/s0uWM8Ax2WjIrOdsLjA/ngoYmgFKsjVnaJKuhyz393he658ga8pXyRaBEAQOJS6EoxV4DPs9JVufjpYivfPoss2oPcgT9NVZi5vUpz3OgPMQ5epDfw7XbGithJUF2OIVbjRSUxdxDra9/3vVyGnaC96OPPqqOOOIIbfFeffXV1XXXXacmTZqk7rrrLjUvo242SN5F3JeAIL/2oXkQt9TQtQu7cqun5bHW2Pu8GerBl3rEPlVj4ZrswehR5rPSrO5pCaFi91cqSD7yak8uo4hdKbq0B8tD1uZqXoT5H+pkdHMzcC6xlAqiIVZEXXHX0Cfhc+mI+qukByD8Qc4Dvkd91vsOp01Xh18+k+VlkG/8MlZc0a/pM6stR7TeEVPVT88v7rosxXgPVW4TqJULGEyh66ZHu9VvbqxcWTjYlqGzb+xQj71uVwygUA4MMygo0POkWuA6LTI+vJbutc2Pn6bWOtRugW2MrYY2Og974KBLZlo99XY/e7o68/r8ZHIgxNbCvbgIKqU5IMBdcGuHuvHh7ppX/EjLRWX79sX0fvXPx7uSay65o1Os2rP/xbWt5IN9OeGadpGuUy+So/40Uz32msnzVXKuN8ZCcyVAfg8rGjTHPPXsFLyp8vCjOOwAlHbAH2PeB2nMnB/sRYv3PGikGHaCdz0zL/X29mqC2DivpKTMFYCGMC6vwKN2PXO6+sGvzRqZ6B5TE8xmQQYYkvP+OUvsUqV1soEQrX/k1MQVCZiZ9yf1OQW/at1rXRZziVgmdbwLPBYYj30uaFO3PGY/zGEdn3tzx5CHUUDfbIyXXfCO47Y9JiGJiQ+Cd9VoqE/LsEif20IDONY9fIrO9D3Y1udKShxR/OvpbjFpVVGSX4rXq01ZhrVkaTIryvwUSVhlw7PvFLOG3v5kl1YI4Nx9N868PlQW7z/ElRQq0W+D0HPpnR1ewk81c0vfF+6BWsNlxU5qLveXk7VaUytkufg59kFc7x0wuc3dQFNCN+Tvcd/ZBAFY01ffa/d4QUBlkEoVT5WiUk84hO8ZjIJfIYWK8FpO+ku7OvbP7dZzEr3gitKR/D6lv9PzHI1E1LBx+1Pd6uBLZxpeMJWc69XQsO74jOO82cwaKb0qAfU0Oz/miUFpB0oS7JW0h/i52DtIoVlzAqrQxQwNTjzxRDV+/Hi1+eabW6/p7u7W/xBtbZGWbKC9XQ2gyryhQdW1tKiBri6l+tKFU2pq0v8GOjoMTiX5fNYsY7eVWlpUqaFBt01RGjFCq+fLcD39fORI3W6507TO1I0apcp9faoM/UkuLqm6kSNVuadH/0svrtMMQeNAj+ppa0/reQ7CmGATbHfKdPXHw8aoMeNb9XWt/R2qf2ZzQgylMY2v61Az1AjV09WrWvuiOWjtK6uBWWX7mFpb9Wd4/UB7i3VM5dgU0tzfacz9UL0n6GNfW50aaG8k7yka64uvdKmBdnNMxljZmIBBP+yyNvXLPSborz/6sF0NrNCr/u+kaWpy24B64Y8LG2Nq7Z+lWvv6VVd9sz5gi4yprtyvWvq71HKL1au3P+lXHVObVPOCY4y19+QbPaq9p6SzvkK/e2bMTKyKDb3RNQPdPWqgnaxVx9oDsgLvadaUATXQ3ie+p8+n9qv7H5uu6uqb9drGMeFaKPeP12My1kY8pt7efv35DzZoSu7z3U8bHjxFLblwo7rtrEUy76kzdpNq6u9WfW0zEy+TpoHomp6ZHaqxruxce41dnXrO4eCpJY0ASxwwPQ0Ndbn7ybX25iS619gL95Y03aPP7e+MxtE/C2hBQ+6YZrb1aOvKWov1VDwmWG8d9a1KDfRnrtfjKvepuo521drXpR59epZ6/btltdLyY63vCcbUONCbrOuu/npd/gvW3qwpM1VTXGsbxtM/UNL7qb48kO4D9p6SfdM3Tu8n+Ls8qz6iV6C8eLVOTZul1B7rDiTX9s6AW5v0XPW2dSSft+ucXROKnU9k7SV7tmuUXnswpoZyX7bv5D396rIpav3VRqn9thujWvo7VEsPvPM6NXKgQ3VBH+PzPO89Vbr2GgZ69T4vdzSqqZNKatyYBu/99MI7ver3t3Sq1ZdpUOss0WfdTzAv9V3RO6lk7fX3whxGfZlQ16Hau8uqXJ6ozb+VvCcEvJ+e+mb9s74L1tiA+J7qOmEMXaq3a5S65fEu/Z7qyuX0vcZjytDsnPe08c8/Ua2adpbUQHuTfk+ff9Wt7n28Te353RHimAbaZ6rWvh51+lWdareNF8/lIyAfyJtvAf1u1C6vEt2b2dmgxzRa7/E4/wh5T7T9vDP31ddnGbSpML9XkJZ399YnNCLpowct758V0YP6zrKqA/qi6rJrkuynMeWYF5nWHHVV7+t2cUxK08NZSrXDfJeNMTV0wXd9SnVH9InTiPr+2vB75eYWNbm9pOZvjGhBeVZ3sp8G+vpVqTt6H6PLHarUB3zJODV+xIB+T5qGtiu11ZGz1LNXLBHRiO6u9L2y93Tuze1qk1Wb1ZorjDDoXv9MWNe9mub31hU7c7t7S7ofIwdgbkqqvnOWAhakvXPA+Z4Ak6b16/CWK09YVNUN9Nds7TV0wruLjCZ18TJMz6fGaN56gWaPSOgeoK+tSZVbWpP3VG6HMwfeL/B7jYMrP80G3siFUnmo0yQXwCWXXKLdzu+8806n4H3KKaeoU089NfP5C0svrUbHFvTRO++sFjjjDPXlCSeomTfdlFwz/uCD1YRDDlGf7bOP6nz00eTz+U8/XY3ZZRf10TbbqN53300+X/iKK1TrRhup99dYw1gki995p2pYeGH1vzXXNPrw9eeeU32ff64+3nZbYzEt9fzzquORR9Tn++6bfN64zDJqiX/9S7XdeKP66sQTk89HbLihOnPN89X8/7xU7fnRn5PPB3tMY66/XW12QYu6+YnNc8fU3ThS7bDePeq2rV5VTcfv7zWmRa68Uk29+GI17fe/zx3TO5vtrw7t+pE6/ZUj1JrTnx4W7+mZ8/+uJlx2SsVjenfz/dUhnT9Sf/3iKDXf20/kjumEVc5Tp1+8harbdh3vMW2+3+vq8uf3Sj9sHamWfiE7pg9bv6YOWPNatcWk29Xh75ydfP7lsuupHy/0O3Xn165V9X/9g9faa9r3IPXv7/zY6z3BmHb9xXfVaoesb4yp7prb1JKrLCaO6c47PlArn7KT93via++5ceuoXZ/6a+Y9tW+6o9ql90h12NtnqS2/uDP5/Kn19lOnNP5E3d93jOp54jGvMV1wxZaq47trDymNKLL25gS698Uy66mfLPw7tceHVxp0b8pGP1B7qqPUKZ/9Rq373h25Y7pg2WPV3Qttr+77/MdVjWmnb92jfrFhm9rgtzsbY9pyjXvUGtOeUme8+ovk86/Gf12t9+Rd1vd06mZnG2N6bZXvq6PGH5NZezCmdzc/QH3wo596073nJ6yrxu6yrlaYIvZf469qcvOCXrQcmNLme59Ri73/RE3W3iUbH5kZk/Se7trkBLX2Ef+n2n+4rVqy4wNjP/3j5m0Gbe1BO4dud5VB99q/sb5a9aarvPfT35b4qfreBUeor5934KDsJ1h7h63fpjb+3c7Ge1r2xefVwFOPVvWe7lpwW3XhcseJa096T03HnaaubtpGbfDbnYz3BGOCZ7y68hrG2qvkPf322LvVjrceWjEtd72n3f58pBpzyv6Z9/TVhj9QH269TWZMRekeP3OHgpbP2OXn6pnv/6Qq3qgIjVAjR6qtBLpXdEwzN/mB2rXvqMzaQ96oWn7v6eNuUmf/d0xmTLCfnjiuW322/XbGfvrVDx9Q127yaoY32vSFu9Uh2/7ZoBFF6R6svWuX3Ef9u/NoVXr2ca8xfbLUt1T3ZmtnaPmeu31NbXTsRrnvCcYEa6/0zKODsvaAN9r9mqPUDevuZbynt3f/ldrq5D2GBR8xYoh4o5dWXVWt9vLLasaMGWrMmDFqjhS8//jHP6pDDjlEXX/99WqHHXZwXitZvBdffHE17dNP0wmYgy0/X81U6tCr+9Sr73SoZ84dnWQ2HIwxQXIEyFp59M6taosNxqn1j5quN/3TF05IrKDSmE69dqb6+zON6urDW9XPz/1Kf3b8D1vVzhu15mqhVv/Z5/qj5y6eoEqNjeKYLr2nT1347z6tWXvp4vFD/p5W3/dTHW/47EUTk/f03+dmqcMvnqzGjiypB8+e4K1ZmzFrQG1y7DS1z3Zj1MX/6VdHblVS+23RrDY8cqquzcot3j8+d7p65YPI4n3LyfOpFSZ0eY9pxX2/1BbvtZdvUM+81aduO2WcWvJrY421t8bBU9RAqaS66lu1VvcHayn16x+N1t/94d9d6qJ7lPrnsa1q6fn71XqHT1VrLFOvrjhqPuvaa+ttUBse/Kk6ZNtmte8WreJ7+nJ6v9ryxOl6TL/Zd5za/ht9SV8At565sLZMr773R/rvG44fq5ZZpEGP6Zp7ZqkL/j5Fbbtukzptr9GF9hO031+qU69ctXjmPT3wWr/6+Z96E031w+eOV6Na6tQxf+lWtz9fVk+c2aLACcS19m56tFP96sZ+9cA586uFmjtrRiOg36NGlNTD504cVlrdwaR7F97RpS69P/L0eeWi9CB76t0B9ePf96g91lfqpF1bcse0yqEzVV9do3rzwhEVjwnmH5iYE3YbofZa37hcrXB4l7b87L9JSV0TJ1/bZr0WdcYBC1rf08o//UxbvJ///UT98c6/malendSo196tx49USy0cWVVgPE+9r9R+Z3+hLQp4PX9PuG9euGJR9eibA+qQcz9XF/98tNpgpSb9XVd9i7ZmvXpei1rnsCgO9rAdRqidN5+ops7oV+Pqu9S3j4myFQMuOXphtf7ydRVZFLAvz1+2oF57q+z9qd5P9581Xo0fXZd5T+BlBX36zlqj1C6bjlYH/naS+t43G9S5+41Rmx47VU3qalJvXrlQTdbetOk9qnNmp1pofOx3DHSvoVWtdeAkbfG++aSxaqdfz1C7bdKqjvvx/F776ZX/9ardz+9UfzhiPrXR0naL9xoHTVaLTKxTd5463mvtwTyuvGS9Gt1aUg+83QS2SPX6hSP1ddufMk19MnlA3X/R4mpC60BF7wlw+t/b1Q2P9ycW7wO2aFA/3zZ6Bn9PF946S6/vf56+gHr6/ZI646ovtcU7WZMtLaq3XK/W2S+i2cnnjvd06R3t6o+3ROtR07ffTtDvab/zpqhnXm5P2uBjOuKPbeqhl3vVhHEN6oELFjX4CH0Pe09n39iurn+oW/XWNaq/nTC/WnXh3sx7evmTktrr15+rY3caof7vO5GlHd9T21dtauOjpyXt+5y5Sd8ddK/U2qp+cNJXavUl+9VJ/ze6Ylr+5hd1atdffZ5YvHUfPWj5lBkDarMTpqkjd2xVZ9wWWbw1nbTsp4P/MEM9/nqfuu3kcWqzM3o13Xv9wlHi2rv1oTZ16rWz1KHfH6F+ssUoY0yQt+PhV3rVuQeOM85cnLPL7+tT599ZPb/3qxv71A2P9iZjuvf5bu3iDrT81T+MTzz6ID8AeBt2NIxUb102LjlzAcAbvXzVEmqln36uvrlov7ru2HGZ93TvkzPVMX9uV19fqF7dfMp8Bt078f9GqpmdA+rc2/u0xXvdJXvVNUeM9hrTq5+U1V6nfKb23rxFHbL9SHXx7bP0mXj4jqPUz75dVt/75VQ1tT3ag5zuXXFXhw6hefTSxdXIxuI04vg/TVH/eaYn2U+vTapX/3fql+qXOzYlYYKbrj1SnXfQfOobe3+s197NJ45VO50+Qx2263i199ZjErqHeOTihdXo0ZGnIpQxvPzfneq43VrVrptPEPfTO9Oa1bhWpeZv7h72Fu/pn32mxi+6qJfgPSxdza+44gotdP/973/PFboBzc3N+h8HvBz4Z3zWkjJqxuetrfLnsJilz1m7iJL0eX29+Dm8LPHz+AUjfnTWNPW/L/qVqmtSpZGjVB3LGFjNmKa3D6jX3upTG6wcj2kAiE+PKreOVOW6er2YgRgpeC7NUk7GBOWd/v5MtAHKdQ3R9aAQaRqp6kaOEMdEx4rX948YlbjR8zH11cOG7FNjJrSKcz/Y7wn7SNsrNzbqz0EhQT+3jTUdUzTHvSW4plP1NY1QdaNaVd3oHtXRP5Dci2PqbelTHQ19SYxgkTENlOp1H0sjoa+9qqdxZGbtdTRE7w5cmbt7G1X96JbkGf16rXWqciOsPWirWz36QToWae0N9Ayo7voRqrcJ3pW5BnFMdX0wB71JmRd8XmdjlHAF1h6ENuC8b3tOn3r7iujA6+it0593NTSb8+6xn3Cs/PMn3+xR70/tUyOb+9Ss7mbVo5rV9PJINWZUveopAfHtUb0N8J7qnWtvYESDGii161iyWtII6HdHb/os135yrz32+TCme6UR0doDZsV4bjMcnj1qeh/7XCl13wvd6ueXdKi3r5hP/w1upX11XVWPqWFMt1IdZbXEQvBMPr9daqDUoLqbRqiOOPh23HxuugdjouMaaIK9EAlAsLbrRqXBlP0DPXo/SX3FMeG61rSqu1u30VEP7TQba/6i+6K9A2iva1UH/H6meubtPvXUBRM0TUoH7/+e+Of4PFxzMCbYT7PqR6qJZP/g2uucBbSgWzU0N+nkaqAA7GyM5qa3pVsNxNlwa7H2Nj6uTcezvvyHsen8dgxoxQz8K4+AvdanJvc0+++nkb2qt65fKxBc+6mjoVNN6TfPCteYYB57mhtUN+RKKfWqAVWvr4ewk7end2nuDX6fOKay9wT421NdStU3JO+pqxFoXLpPIPzhtQ/r1RZrtqruJqDH9erif/eptZdr0O+Jj6G7IxJepLFhHyEh00Lj6lRTqaT+9SycbfHz6tJ7ugeiMzfTRtz3maV+1dnYq8bNlyqopOfieyqNhL43JLkhpvS2aFqx4wYtScKwmZ09ekww/rpRpvB560uNYvuuMzfTd2E/wXn++qQ6/e/k/eSx+tDynt7ehEZk5sBB98DdGvb9r2+HB9bb12S8nxrHRLwL7GWlpmu6J10P/e5rgTWsVE9za7IvcEy9zVE7/Q0wlt6ERoDwCOd+QzMIdn16TNXwew2N7UqV+pJ2+1rgPcZCU329qmuOru9r6VEdcUZ8euYiwD4J9KGzIeWN6FgP/ktZqYaRqrOhPkP3OhtHqhse7VK9cdhraYSbh/3tTbPUn+7qVG9fMUp19fTGaynipfpaSmqg1KkGykBHRqru5m7V0UV4QkL3Ohthzdfp2OrSiAbtpQAlOifEYUz0fUjv75lP4OxoTNq+/8VZekz9I4CWRXtm2SWj94prr9wa0c+BmKYg3UMM1MWfjxqlOhui/vW3jFSl2DOZ74/tDp+s5h9bUo/9bmK2jxWeT0PNG4nXqmGGq666Sh100EFa6N5xxx3VvAYoh7HnOdON1Pta6I5Ra/eE465uV3ufn2aOxKQIECdoZr21t7HLmSSRCLnON0spJorBRBIikgyZfm2KTZTLOnOwLyAWe4Mjp6j7X+x29qloVkacF37fqBY5w4mZXE1VBFRodDmyrW6zdrM1GzKUE/Ode7zOVR6GPqOJJGzJy8hMMw/XsgzFj85t01pc2pepbdFA7nqux3vu64ZROTFYv7REy5wGW6KrsiPBzKMsK/OqB0VWi2qRVAWI1zRUcOB0gSa+HNNasPY2yW7Ey64U9Un7xR9nWpMFPvduOj/w/esf9Yu0upraszbYaA/uZ9h7mGgH57LW1TwggRYvG0jp8L4XtCU1q32RJgnKv3bGrIJVJdj7h3kBjynELLZWqgU/kyDTNGa5b41tG3c+3W0keqPwoZHfO26aOv0fcdwnaQfmD7IjQwLRvOod8P18Y0pqlmd2Z7qM3vioT932RJcuR/nKB2mHMVO0NLaFJhRjlX2X7eyuflH0nCpSRzqpmd3vn3AM19/EMXXepRRdwKRkWC3BoKVl/+RyOJYirwtLgEGG+wmjS96JEW99IhX4MTs+LxGJ81RKOKYscMx4LVQBgYoTvuAZ7NPKOOlnPf2QZyL9gPePg37e1+83p1/NGJZO2VVh2AneIHSDZurQQw/V9bzx33nnnafmBcBB8PTbfepVVpoLUevAgC+mmTsEGR8gRFT4oQQaSmqcbSmLQg8S37qjzbFQaMs2StutRtaCcgd7nDNDTZra782kwaa//8W0YyaRMZlEX6BAygVHcLWTMpfTOpCVlilBwZtnTKYoC+86EYQhWZjno/E6XhrIeJbBTKa/Yy5EF0OA2ayrzeQqgTIEUI+YwqeUm6ucGIQRDCUgqzwwzjMdtW2HA0AAlOrv2uqf4tqRSqogk1fr6g/J3oh/gQoOB/5+ppWpKMrQUsavoycS/HCvFx0KCoJdwl6PPVGTfYS0pp8dLDdYygtBqaVKM1rbqga0x4I3eL5g36kCeLBB5xcrVEyPk2v5ADOVu+id9CzfdUFvgczddJ2h0gLWiis7MJzFPmdHpuQPaZOezzalOtLIvEzOWHqU9hnoOWRH/s8z3Uk7tn0MyhMQzsCF1wd0XPc835MKCOT5WJ6QeJ0mwHW4wFg/ltm3DB59l9WcD5wvBB7noVfyla6VVmCA5F6+fZL4wERBzb4CuvnplP7k3gXHVyeiYHgkrifaF/psCOdwQRI68zCiKeW5JhIrc54ygSobcXlynjDZF6V8uoT85tMFjE5UcZA8M37kwrESapWvNagepsjk5yQHPRd7Uck698nVc57g/c4776h3331XPfnkk8a/fUkQ/dyMcSOjV3LHU906I6FkeRxMK8TFt2OJp5IpHJHfoaTGlXdHh9RnU0zKTVuDQ9QHWCnOxpiZFidVMdA64BLwJeJGyxZNEUqWFLZ4D8iHHlq8Vzlgiq5zWUuLNzICLq+CRLlhGQ9VOjxPLGfZdlKroA2GkEI1z8JnHDhvgyFQ0kMPYqcAG6zUWNjizZkNWEurHTRF3f1cdZbEIuXksAzKYNbJBOVEtULu3ufPEOvvWplXl+BdZUkvBDCtUhkZ10iBjxgdK89e/qBPu+n6go4VLN7rHj5VHRFbrun780nJsuemcab0HtMagX1EwPeJVcSzq1DzF/vlu1YTjyYLyUDhsaUpZRZxSQ1WObFv/nxycnZJShIUgl7/qE89/Kr9wPjfpP6ELviWt6vG4g3WbknwXuXAKWrv8+w1j6F8E1wDFmUXXOsAXFqT6yx7vs9TYYJnvbRPYT6RmbftYxDYgVfyrWdM53CjVZqSfUyt22j9lhQY5YI1mX3Lc1HBH86HWmHnM2ao/S7Mr4FdVEGIr91n3hPDRNm/7Oabn/Tp/DfwsxZnVyOjPWY5Mfn3WgjekDthRuyRBXSQCvaoDLCBfo3jv/RfcVZ2xqO59hkqMfEdF/W2aYyNNXi+47OBnsNzFxpfpxUaZbF2u9wmNDWrC7wnQVFo3jMvYdgJ3osuuqhh6cZ/ecHqcwuQIP3joS5106MCk17jRUqteM++06tujmsvRxZv8ljL7uB1PytxsUVrrItxwW8qtXhDLDta0Hwt8UgYqEZvBhH28rR7NqDrXltMmLE2Jlq8ARf8s6O2dbzj21yu5qkVIP0MS8jBGOk4f/ibGWpK7IrNgWvgVeLGl7mGtGUcrongqnIFezzYaokGKgCxGpqFLN6s/8jgPVVBPWm693ysapwpr1YIdQFc1353i5+CzYaX35cHZRO6cDYk5u/DL/sNpqNSANO6wZFTUythDkMBeOTVHrXhyo1aUQNeMluckCYrywNlttDV/KV4XtC9XT/fY8mjUBMJ3uZ3tP+U3krutS6B0wcoqOGesFlc0W0VGFJcq7j/ayl4030ENB3DMKQ5RUXIDqdNT9zPOUBA2+LEaeqmR7sKCd6SdwcHtWjRd/jljAHjDMA9nkdbnnyz10sZzs9X6spK3dptNAUV43kzgXMlCfowPhyjbR/Dt5DUFAQqnzPR9EYpJ+9c2s/S2JIa5n1+a8x33dZKKcpnANYJIE8pSj1dsM8u5R6+Xx/66lLkIy+Ghp6kP/G1b34cK8WqPOJReMQ1Ygjb9ELyx3L7Ts6EJF51b6dXf/Drv9zflViNozWaXrPYfHXeSljb+0tczR2CN65j/FmUX0r5HpUR+uG5UU4gWYFht3iX1eoHT1G/v6MjnfIgeAfMbuQJrrXWDnUT3mpS7GYH0LWVLVZJCr7xef8mE6uRDc0eFm/sSyUWb7DKrXP4VPXie72FBBEcMzDCaLXp7M6OtahggwLpx19FNzbHLkn0sKbzTTWkPsKfBLzL6WqOhJVmbCSaab42L/+PzMRh321xgPoaxgglzxO+t9371if96gOS/6AWoIceMlnIJMDhDbGBGEPrAn9LyGDalBXOtkhjaBH0AQo0LhfUavDy/6LF9LCHS6ML40fVFRO8y2mYDFgcKSBRWC3HfOsT3Yayx0V/P/4qUu4hrSgi/JfIWDtiOoifGUoqjzZRGNOCN/uOzgulZdJ+O+Ea/7qkEpJ+5zBj6GoOfUMGFfuDHii1KL5ChVR8X9Gzsm37uLgj3f8IlT2eexMy+eYB1452NSdjB6v2c++YcfpfTs+nKb45BzLrS1AIOb2iLOsJ7qW8AHoUSHk6wH0VzznbPgY+AL1LisQbA+57sScVSuIuUQ8zqU/4CkCgfe9zu/SNZ8ZgxXhb58PSjuu85+8bBa3XPrQTmeRsLyJ4k2vbu+IEZvH8vPe53BB6C1Xj4Sh529D5pqGUfPrO+6cZSomC9Luf9RfiwWDfwfXU03DR+dy+5nTt0H1mc5O3AekRttFGckP4APlOVJINcMG7IRqbEX6ZpzCIP37u3b7k3QZX84DZDldSKUCl7Me1D3ZqTR7XtlMLaDNJ+AdueLY43CL9n+qRpAZi+3RfPCwGefMjAQ/5q+NSP75a5sTi3VtOEk3QOCzak0rcbVFowJgyqsSgbkG1cDXHacM5BmXET343w7AWcDeh9yf1qcdfT61CfIg21yWcXxezTN8jfR9pjLRD615OmYRK401tcHkXwOF92nWzdHIhCsiI/ubHbs8PPDQhq2hR0PkpIsylSehUzXDmP9oTSy64MwLihKQVY3yceIbvIZpwjIJeBRmSJfB3VCnwvTEZ0mppAMUNWlmKgFq8kR6kYQvkOwvtwv5Af1GQffjV3gxD3m+zeIsCkP9a3fbkaeqVD0wun7vn2+gurlP4HoUenHfcj9V4bQDNA9dPHiaEik+XxduFJIayPxUYfWALQQDh9C/3d2pr230v9KSu5iBwb5Zm3oWkYMk9PWW14VH5CZPGtPqZYF3eYPTssykZbHR7nwtmqPWPnJoR4qX3CmsABSXbe4dujo3D8nC9u0DpMVhTMQwKaA6cUxsdlXqn/OvprCKRDsvl4YNCGXqK1dLiDXt0pf2naM8aX+R5YUhng4t24vr41V/zlXIoWOE99zzfrdY4eKqec9v04Pv+dEqsFKtS4Za6msfCI51vwVKLeO4dxmiR78+9Wc5vJGH0iMgd2/A0zPBRAwavRGkPej1xz8sk+aQzxtuk7YUt3vXmGqIekfBY4IlhbJL7fvqznBtiWB4cu8CwxrBzNZ/XMVgWb6inCJjEkqmhIPajc2cYWQwvuRNKFpB+Cc+FTcUJKL/O52Apk6RC1muItq0a9+Ei1jAkbs+/2ydqw+m7KNKvzVaPNBypOx0e1uk1Ky/ZYGhtv/+tZvX1BesrTq6Gtq/jr25PYlgff6PXWA94yP3n2ehFbH/KdPVsfADpEl/s0bbMvzc+EpeWK+evc/B2oNf5ZAWHuca16pvEppIYb54JFQ4ZHuMH1i7IiL79qdOdydWQoeAJ23xA28qzqsGawvWNrqG1dDUH5RWtslCLzNNo8d78hGnqB6dNS7wCbAI9XS80WyzF1Jm1Oc05I4HrktMUBExFJZl4R5ASkbgPUeikzDGNCaWgAioKsjRjM4KuBWqFQfp13K4jCyd7Ajr59qf96p+Pp2FK0Tjw+/Q6CWixhD4kVhB0NfcIPckDKA/BYgWhVBQfxwIw0iuKvDhM+l6QfkOYg2ZEY2HOBttXl/27Q53+91k6ASjG0WPI12iL4OyjrAagdRjx1Js9WhHPYZvnWx7rMizetrWReKaxz/EcQWCeFYnOw3hxXPS8Bav0KX+Lzq8yyYnCPRnEfpXtShOe5Z7TNz6epRayb3BUGHi7mhfwzElCuITcKbY1lVf5g1pvfc4J6TmTpsk3Jvu/bBoaIOkjT9yF4PxN1THezNXcGuOd0w5k70Z8FisFJHAaNyYOhzCEZvawtQ+bqq59sEtUOENZMQQNHUoiUZwx3ildLcoHQGhmYvGO9zqeS5Csjbqa0z2MShZ8Jn9/yJuUtSHHbHdeQhC8hxn4QuUb+cDft1kFHnDj2en06Rmr9j8eSjcv55FxzUMMWDMjhnn7ARh7fg13/fRxg0MmxSUQwzSAAFrJHqVunIUs3kISG1tCjntjC0WRkhzcVZ3G0/GSQq1NJV1up1KLd8L8xs3egMKxkbiJZcElz4oIpZ9w80wca1gmRJy/W2wLiLts8XaMpQwZQ6uMebeAMkzwzqHWKx4MMB+cIf/rA/luowAcIzI6kBWWlg3xudcnxnDtQ6fo+HvA9Ni1bLBczRE2IdQHMMcjYwb6o68G1Gsf9avbnuxWp1zbbhzoUskSiXHHjKsrL1GlGT7GKdfO0kIGt97aFD6wftCDpwjAMsLHhHuBKltsFm9kZCE2nQoinF5uvEoU13PY91vV8+/1ZdbYjhs0e7upIvB5+B55SUDsAl2Gn0/t14IUuO1+EZ8R0AdevQLnWSpNCPdyK7sEtD5yyyh6n/xXKLk3kihCbEC6jXvylse7tcC8ws+mJIpuCRINf+uTviSBEg+dAOubrTe+iUIhHpqCC28//l6LGAuN5/kvr2o3YrxhLseNKlWdhGq9FRuzbQykc0SFhWvu7VLX/bcritEeSNf8e5/lSxRwnq1EaAK2i8me8gDjwZA419rojveqd1bzGpHmcoWGHKq4KeI+TnHQJTO9YrxbiaJkgXHyBPE9Wq1MlnE1t7hrw3O+JaxFBK1ywM9TejbxvCPzjanLVBwwecg0iSPCprSh3gs+PCzuoUqUFxCa+cBLPabnXNzep5MH9NnUJFi8ealczq/cFRt1Jk0zPWrnNQTBe5iBEzZ+sILm+AFS3orHDoOVA+pUUvzmhpQJ4BoyGl8JG8nsCyFSA3J8OK9JCLWQKXwya+ImdR0SQKCAIFVCRFzulhLAKnnHU3DAZ78Di4SUNOzwy/0y/QJSTZ+yWrwlZgCS0NVK0ERXKpuAyw9hmH+umbQpgNBSifMMRPzX15mMKH4HFmRD8I5ZTOkdJW6/ZaU2XDmSvJdf1DPNrCeozHTdfzvVzy+ZaZTs4dZMvrbsydXMC9c4ZKo65sp2r/dJmYV3PnNL3kAvMOEhKkZq6WqO+50yEtW4mkOiFVquD+nVdQ92GYoJbp1A5uTy/3SKQnktxwyxqfgEfFaDxcoPDHdenVapXja1SPKM3pR5sVUlmBCXqwEFqi0cBrDYfPXqawvWZSxOuLdAsXTPGeP9B0DKlnEFDAhQMF9SpttvHzNNu/duddL0pEIGrClIKhr1J7ouSYgpvE+4d6fTIyWTC7gnaVZuWhVBcguGRGXXP+xWjKGCm661h2Ih/pbH7fdKe/5xVn/eNgYKSOLHFbQ2tDJhEQQCivVXalK7bdxiuJo/xvpEnzWzo6yVwRzSeeLy8hkrxJ7bchogDZ0+K1pTaM38xZ88cm6UlVqWnBWJRY54iOTdD4ql9VZoVFNmDlgrdqBi1dcJqAg/k/RS6K5NiMlrn5YcXH3paH5WXtJOwKT3a3NnR1qJ7xAVFjDfEyx5PbjgWm38L74H3HNAG/EM50aUrzs8GVy8EZ1j7oGiBe8+ni8pvUY6p3DMdz5luvzTnB2JR5AjIV7q1VHdJN7+ZLcxtj/d1aHpERiQohhv8kyWqZw/GyuF1NelVZPmRQE8CN7DBGABO/JPMzOuNpIrmc19CGp8Uouqj+WCtmWzhlNiQK3pELdSi03j40YO1wCzWwkhzghBOYTotzfNUkf+qV09Hydjo3h/Ur+uYQ5uev9+prsm1ufU4p2CMwORhrH6GO9MX6hyxSCg2QPwtzeZShVbvDIyy1RgeOQ1U7jCx8IhaHh1lMzEXdIBD+8PBPbxo0q5LmKX/qtD/d/ZkRu4D0BwOnaXVuM9fTJ5IHHPx9gzBF+P3NqHQOaDvwef5HDo+g8ARYAvcD9fHWdkrQVQqIR6zogKDLxeoHTLmOdyynBALCww4uSrmrvXw17gwqPd4l0qFOONOQpoRYPU4h3vo/6ymm9M9Ps0S14FFGBWWbJB047vxeEsXDDTiXFUKdN/XJ8wr2jZ8wW3bCdtlk0akScEwLiBvka/lw2lTjXvE4VWXtFBykVB3YihBJcN4Omy9a+mZ2OfhUoYHFJypjy3fhjDvluMyIQn+LqaczrFY75BKIJ3b3iZOPoIFTnQgknnTzqf9/ptqhzh61F6r7QNKtTheQK0B9acj4IL5hrOa+g75W9oLgFqybcBroDbQWEFYQs/+PV0UdjB9+7ral6kCgz3uvFBXjJGqsjD8C08v337W8q5FpO1ovJHryPLTaDQMdqokr/E+yERa+JhFdNadqR4K0u4sEzX8CITzUUZZd4vWz0bpP27yMQ6kWeiNAVpFz5P8j6k5cSoQq1oosqnYw9GVIpAaJmO8Y4ztpsVatJ9RfuAwDYGiAdlSK4WMNsAlgqo3Q0uJ1S7Lbmj2oQvzFrIBW0jOQ/bCHRj8P1INwRmo9z0l9PMOrAWwn7tMWOVD8DdEAUbp8XbsKQWIxy2eFsb8IAAi6QEcAsEPPFG8dJQFJIlCEGZAbxOW7yrzGouWY34c2iCJ3o/aj4RtmyyX1uwPqPh5AcqtbBxoQrL3nAmrT1uAwTRGx7u1oxXnhIFylZkEqU4AEzHPlu0asEFFVifx9n+qQCM4O/OVp/Ulr1125On52ZJxRJZRYEWSMzMXQugZZbGuVUb420DnRe+h/MyntfSvR6yf2O7KAjYrPwwFVRw/fM9ner2J7tyXYCpIJy4WSeu5kpNjC3akMldAtwDZWrAsgPMJeSDwPjBjJBcyiauQxf2SPDOf5+GlwHzWKJeH9TamUe2qRt9oggo2V3NfYH94sItnpPU4m07W/g7vPDWVPGEsca+kM7vPKsrdJHnlxjRVPIuYYbzue06zSLzPaI5evf0bOQKNZoFv62znJyTtrhZxDvEFfwZEmcPvE1bZ3Y9Q99w7UNStkx5RO1J4ReHD3kHwKMCslFTmkHL1vG5F2O4y9EepbzVZ6QKDALPZ1+aWISXqcTIQSuUSKDKqNQAUtYx/e8K3lVF4nFxaCAwAh3APBZ6voVmWptBMDPntNqs5tgH9PqEZ+MZZoRBEmVuHrjHCp41h2zfqhMn0r2FVmEzhCP9HfcvpQnf/HqDGB4C19J3BEDPJcmLBvsF+4We10XWEfBYGD6BHo7AV0Qx3hE/StcEr80N5UYpkIfs709d1IPFO2C2AV2/gJgDATh+t5HWupu2BEvIP7gOY1uyAwBuhFWXatCHPCUQ6A6ItacBcAjZGFzXuQPKBUgkA6CugrmZrFHwLiiH8LMNiJQrCzm4Y7qAFrZKE3/wpEMwts1PmKpuJ65FGaEWLN4NtbF42+pr0ynJupr7P2vV+OAAQPktZNSMZ2GSKm3xJs8hJzKPQzyfMLu87q8N4+PMt74KCxSAYA/StW4Dv8YWo75PXAsY4pg58vrGGW5fSMIhCB+HXdbm7aLKsdD4qNHXSRb3Iq7VRcBzDNiSOtI1kOaLqF0/aIz3r/4aMXA2nh9oArVeA8N31BV2y+m4eH1K5fVSV/OyaoyF4Z9dJIfuwP1gtYS+Al22lY+C6+CbrMW7XEjwlhJv8jUPc4bvEHIy5NYUJt/jsYL5OYrSfApkSiXh9jGo2mBZS1IdbN4mwLe8EO4TVIoUsngTiyQCFDw0kzpddzYBDDNW81fRihbvsp1+YJk79NBDwduW90QCKpBQsf3fl7PK69/f0Zms/a9mlDO0Fhh/zPmS553w0vtp+5Rm4HqH/crjiiUhBngTsPPRWum8kkUlruZFzlXX9rF6tOXGeMu0E2L68czKa8+W4AuvBWELBDCcE5hvqbujWuoyfI+kOICcMTc/6pcfJWMs6ConirLtTpme1vdW9kzrHJyOII1beuF6PZ9YQ53W8aZJ9OjdXd3pmPgFnBZR63jKP2W9C3m/4NnUhT9P10PpNCj3kMag9xLsTVBW6hjvvrKhHEms7HnPKFfmwTG3ILiaDxPgpgfrFhwGyy1m52ZtZUtwIbvqWnKhnTI0eP8BW4/Qu4FuHimmESz0NguMK7nIqde2q/Nu6dCEntb2dAmy0BeMQbdZ2aE8DJSsyNzL2oVDGhLgVItKrWrc1Rx+fvDFQG78dDUx3vRd7nh61vUaiCm8/43i5EvZBCL+z6LvEd3WbN4UkIiKl5hYJE6QxRlJXjrKJ+YfD8FJHkn+sM0ijBP2EX9ijLqL4ZHcf1245I58V/EHX+4xmMyoL1mA0gUs9y+ya32x0Pi6pCQPwtdSUBR0rdM5KrNEhFLiGh4rmH5fVo8yF748ALPNW6uPGR5uOYS++CTm4llrJUEWaSj87ZpjKEcD8wOuv1jiDxOdccBUwVnD6TPQ1OjzkperuVQWhlu83/i4L1EqgbXLx9UcgfclFu8qBG8UhiTBG2rQ05myJa/jz6dncJESgUsuUCcqxvOUfJhFmALeoeGV5jj36TkP80DDMxLBWysy08+pyzEkUqNLHfqLCS7p53nJ7nwtvDzfDGDBOCHX8os16GdSGm2Lx6f1wul48H2CASAjSAlD0GNkXUJPPYruRNixjy3TrvG3w/gQUyHpEtt9efuGKo2Qr4IEdjY36GoUBfgn5Frg7UB8OdAsrgSRzlEo53ZcXJ0lD1iOCy3D8K4pX4F8VrSe/Og232c4xxAjDk189GXa6cQqbElii8osut7LlncXWbxjhVF8UVr5Ivti8P1xmpa3BSl/DWcKto37b7WlG/U44R/wrS/FOWV0v1gmdRv6Y6+VWng1zIkIgvcwAS7UR1+Laq+6MuPS0gYU+KmrrmXG4j2QdWmFAwo2H1oraXmr1ZZqUMstWp9Ywc9hcb8IFwlDV657nu8x3GncydVSDbft8N73gjZ18B+yMbDcko6x8BKOuXKmevptP6GEE0aqKQQG5pI7OkTvBN59ydIP5XlOuCYaC34bxXhXJnjnHZhgVY0yt0bv4wPm3kzvP2+/0frnonEskjQ+ZBJtygl81zrGmyXHOnj7VnENfW+1powFyaX8oJlCfbLrmxZvv0N4ifnrDIEU4Zrur+JyWYhaWGf3v6hN7XKmmWhKtCrETAcKpnA48yoIvmWvEL5zVRTUE4CvEbo4eLjMuJElHY8vMeGQyO2n57epT6f4T/rFt4OS0PwMGZ5TWdJAsDwstbDbBYAzyRFjllUy4LS61hKsa3Anh1AGcGtEQcNmtdYW71LWYg8MOIYm+LjwSlbOpMRN/DkkVETGHgQRVDjZhARDsIvXJyo4qnE1R/dgSfCGmPLN10jpSp+FvmZofQXdgfGBtY0neXvxvd7cuvOwFrgwCsonX9dfes5vedK0pKwkFbzhGZQ/oNua9xliSpEW0G/QI8QGXy8xiaTgmTJxtH+ul0Tw7jPbxPn4+KuBjCBFLfsITXJYn6SzHdc7uEz7nNXlIvNTJl4ansibJypcY99RWJU8OaT+2fPHyNfBPuT3XH/cOC14c4UpWG3XO8I0kvhapinmH1tHXM3TsxoVlVyR4wJfLyiYQv9bGk3+W5fc6otivI/YoVUntqTzgvNPk13i3PyTJWik7wqFVSkBJyKhvUTIpe37nLtAF1ARhe8eXPVhqpD3uvf5dD3iNaCYu/bB1GBw6Pcjno5eN2DJDTIvIAjewwScoLksHLaSQqnF2069KQMR1RtN/wb3Iip8XHVvV9IXFJDhwNpm7bTkjA0u4rhQbNE85NKZiatlbnK12DrKx0Bhc/krksAE4mF5lmUbuOWd9h9qf194W4cR02bXcsvt3/hIyoxFiV2impC+4HVrXYiyTJaTA+Cu58w5oIfF2ss3qLN/Osr6vmBdQdKPXTduVs+RGuhSexlX83IaY8/fM4ydJiNzuZpDuYodTpteuF4qyhy+hzAycMlhZYnxdlm8JSHRBd/6yrJlxPwbyh+tdagZh+WCpPSqtA4nlJRyoYPIIkbZO0ZfgAGAmMQo3kypFZdoEAXrc2+elbhW+ialwoRlFJBUEenzXXFWcsqErbWs22TMp2ty24Bp8U4E79RbBH5bc9kGnVCQgsZEwt7FPWmzWkfJ1bIWb2CeuGuxK4TA8EBAwZtJ3uBtAqFT0K8ZHWVdmg1g27NUMG6bFSkj6mvgan7CNe3WffPQK71i7C9HLXIGwPSMGlGXSeZFLUZOizdJ2rfG0g2aRvG1ZMsnQOdP8lIDIRret1G6kIxZCnFKMqXnTM0qX2sorGSEuQIrO303KBCXUVDK4V5BcQ3vNxG8jfecdnpWnL+G0meuHMI9mMeH4TxDdYl9zs+v6MLfn2t+8FpeE11/R36nlTfyPAxojDfnLSReQ2rOyndZzgWgvdJ3WvAWPD9AyUMVkzi+Ivlu8F3B3qPeQIkysIBAD7SMAvPhQL9AUQi8Bli/T91zZJyXJ9pXsJ51NndyO3q//PuZlAfAocL8b7lmk1pjmQat4Ic1VWYu+EkiW4E+YUUkWJOFBG+yvFqbsqE60D86V7RcL/Jn4A1LSyru/p2oXCGiH2K8meenC0UTwg13BMF7mIDHv7kFb4vFwMPljFoObIITN3joeO/4tvJAlFG6GlDXWcPi7dhbwHjjc21Z3ctkLm96NKr3mdduLUEPzcQ6L2ZtLVekGODJ1aBm+0GX2A/33c9OLaB5dAsIKQiRNmaK3g8CAReYKeD1wPpdZuEGa9ZufDcNDSUj46f29miQmYa7n+tWm58wLdfVHNre+OhpmT757D1MiuNdh7XfdDHE1eyKZ+X781+e2fFvOmGsN8Nxw8Nd6g3iDs4ZTqQvUAsZ8JmnBZjWM03bVBUBFG++4AmcKImaNrOslYY3Ptqlly1YHSSmEawptuR3FFLiKYp3Pu0jZdWyTMtYokzMGwsmIDQUovH3dA1Cv7/9jSa1xAL1Vm8Dmk3davGO4+N5CS3IpwD0BfGr3UeqJdmzeDu28VBAUiXeF9u5Q122oU1g9HB4UQUN97qHEk+u0lWSwMKZXqureQ3cIbXFe0TqlZC0TYgTJJiygSpTNlylSTO8fEps+QTyBDB497DeqILyqD+53XmTGG/L9/hMOj7vZGJlpXbeAMqbpfSuoysVKEB4y1OOYsUAAAgPhsWbud6b/c4K1dwiuvZyDaJFm65tGg/unfjVMT++Md5UYZaf1Zz8bsn6b3uOVJKMX4vhCPRe2zAkizfijH/MyigL/h6XHvQBeIne+0K3+mBSv1FaD5VgVJFDFUU+QH4UDEPgNRRZmCM6C7RPJ1frL0e8Rcl8j12CMpDOcXNTSeeEgFhrKcYb6bCkBMK2YU3RqPq8LUjXNXjZ4PWoJIBnx0PRKLEwAAm80pLhau5BEmqZs2U4IAjewwRUMACmx+XuZ4txzotv5Ey/jQGiGiwA9CUph1RAMwjut5TwSqBJgFzCSpkwlv0543/x/T7tSofW1iIW72pAmQobYy71J48Q4rh4cjWo2X7vC37WUh+NIRBvdEXml9NDGYguCN82JgHGB8s36q9NG566vPISNujZwK0sXJCE6yRL1EOvZjkB1xowY9LNn3nA5+P8JMof1i2wViLzTBOTRePwexZq6n1qVJ9Ikg1tFpeWivprWlPRBc9FMyh4bV/aZlFIXghrxfOUK3gTGoRrTPejHB3yNuVEYkHNCWuhQDdbVAgBPcT547TIxzLK18YUsHgPmH8DEkY/2f/ZcdF1St0V8b1mnh1bvDPu7n2ptwsAGUbrGIwYb3PtU8A8c+u7bY54XguwLOH4IAkn1vi2AUo8/fz3WUXkzhu6PbToOG2CYbUWb5xv2MPcbVuKl+cARQlVYACJhL985VifPQprmrZHk0RJkJKrUaAwQPeIr+cCrKmJcQk9jEfHyiq/+ONM/Rn095e7jrQqK5ZaKF3Q3OJNzyWa8RnBlSOc5sC7uOLuTu1pw/tdBPxy1/w4lYXKFNaS9vKSq5G1b8sdlDc+WpLMuHYAYrcbMxV6oAlpLDrGm5xD9FykZyZ6LfmcWVBmccf1m7Vl+6BLZqopM03DEfU+K5rfBYHnMfB8WnmVCJVRvgxQymOeDlhDtNcdPVmDGp2btz+Jqhy1NMcVDMrme0UeSTLGUUGZtpm3RqkQH5V7je8bIGsmjvGmn7sAynCKfuhTEd40CN4BgwG6eIFxpFrLlial7jljfP4h6iF40xho3Lxn/mSUcQ0nPLD5UMiKDqB8ygSXQHmFiXG2dgnAEBmu5o79B8QCGUPb+FMXHSQ48c/qeKYKLd52F6Byzt+UkcAxJOUbKo3x9rgG2kbhjl9/N3E9h75ot0TLe4B1BQcQaEttWdhRa4oHFf08z7MBAa6x0loAy5fUJxuMuEY8fH0F74HUEgyl8XDi+Jr71gqNap3lGtSO67cYlhjAd1fLD91QRPFUdA1gxQTd33hOk3GiAFmhcgrKruW9JxukkjvrLi/7SPOzuUToVpLUK553YDiAwZJCbnDcrjksk5KIJ+0+MrGKgNUBAGsf6TMfuy0MyDUWsPRSJRaWf8O+amUnxgsy5piuU2rxXmBcnaFwQej3LLgoLzC2zrB485rOHLZkQQD6VuFdQLvf/1azZoBdTBQXvGEfU2WbzWLN3fZdfUXQ85UKH3ZXc1UV8PVCjDfGlSLOvTm1Etl40KhMXcl475KruQ0++5sLBXnAGG/b+Yp7jO41X88BWCN4FqFw9ClPZlZSavlF663hV4vH+TcAsIcfICFkNFv6LY9nPY54AjxucACeCJ6L4XmISumol6u5Zxs0c/wUhwcIVzr5ZOeXxkf3DwWsC0qfsBwnzWhNESVXGxDzidBQow1Xjs4ITMLqAjwLkvHRNSJ5PlDFStFkoXimAv2FJMSgvMP2dObvuJxYvbBnqaKBJzwEAP2DdrjFG98DfoZu5cm4B8oJ79XHXc1z1ijdr0+/3Zcp+3XfC1FCyvksyl2fs34AYrzjfkhrYZczp6sf/mZ6rpfvnIpg8R4moAQNGCy6+UHAMTKv5iVX87ReoXY/L4stEJRkk+QkTkNoa6bFFRhjJoEgjDIs3vb2aMI5qztWmcVIxpv9mvvys0JHzygbMXQ+oPSEjhW1tdJBmonxZuOmDDBNCgbJ1XwYewl8br/B3KkWHl+n2wYCH5WV4YxH2RizfreW1xDFZpb0HPTkHMrcslYm7eeN1ba+JEuqa23R9ZRqvf3U3vT9vv1JvzXzbDTekq61DPH/FC4hn65JVDwVXQN0fHi4Y7M4zEoPNqg5WumalGKI6dqn74MLetDvrdZqFq3hL77XJ5ZuK3laltIYa4hxKyVzhpmnx4+qIwK8Ksx487UIjI7UH4NX0R4kWcUbbYtarMHlcdk4CSa/HuaOk9DPpw1o+pI827K/sU95tZsRYN2FPa6Vt/3uuacx/fAcCEWYROKRfZRhVPmAkMYBa+fb34gGDEz5/GNLgyp44xyBcgEs+RBeIAHm9aFzUiU7ImLi07/ReuZv8c6/MPKEcF+zwUqN3hZvtKBSV2Rf7zOYb2wfY7v5O9D7s8WeLX9Mq7lgpFKONkgW77x1Vol3XSbG2+X1Z+w5e/+oopUreVxtYr3mIv3V9zlczekxuvh8dUnfy5bzgJ4lNBbbKHNXZ+dzgT5CLW0USsEItcjEOoOfpnQVFDyY7A3PfJ+jn3rGYJ8bqcUblaUN0few//SeZRZnqijEMBk+x9AvML6Bpb/MDDKojOJlJume4148+a7m5t9p9Z30RpgjTHZrq6CRhwEU6IXvIMEf5ZMqLaM7XBEE72ECk4EyLYVY6kW6lgL3hauON8WDL/WIzC4/yCjTxImpCzarKFo0oU1sagJkKs0TvOP7PvxywMiYmFzDtjASHN8kY3TcY0jsuQuUiG189FS/ZFQ5ruaU8EIG9tTV3O5Cy8EFKfhr3y1GJH9Dog+acRLGC9Y7eAYoYiBu1tYnOFxAsLYlLNMJnEoRc2LTomurOLhQMU0urq/oELaP9VsrNmpFjGRtlawqrthCTI5CY2Z9td4wB9/5ZsSMfjF9wBq3hBb+cZBchT/fJQSSdpoqtHjTPYhx1WXGhFRqqYGET5V6YUhzTIULeg2t56p/I65u9Onw+4++N0JUKEIZMRynq8dUKQHrE5nX3TZuyVWA+QiHfClqxkyY/ySrebL/swwIXWdUGIAkP6AgkPZBlJHW/ByyO3813VRASZYRyb2Qj4euJRCmYb7oXvURAqU65D4uoFL+EVGpUReV/0nif0njZ/x4lFYoUeR5dWB1AxtwjiBO31YuErwU/njoGLXwhKzCJPJ4oBbvKAu5L+D56HFgg363Oa/m3H1Hq4O3G2F4gMhiVEqn6BlQJDs9Ct5o8ebKYO4FwFFNLppOZgTHcwnXjG3upTwvLuCYIIlWEVfzzDSSv9FFX7zO0aZP4tYi3oN4xiOwQgF/LlUW8goVye9CnyXPzrNvmKU2/WWU3wV5RBDQsRSWBukT1M9e/eApOgkk9tVnX1EXdXzn6AmFyczQS1Ff3xPvWW3yTtuhvE8ieEsVDRgvBXML1Uj+Z8mhQ9sFDzvn2mHgPGYUGhAlLkXAqMDzdaUl6ivyeCursvoorpzj47UTLN4BgwJ6IAGztzB3oyHEwLZO0+yyfs88+srITSpzeLEH6ERaJDMGMl8uVx8oOKCFM2GXI2OmXXKUUlus2aQtrq7YE/gKBY9T/tZuZEyk19DuYyzQZqvnu/LO7DDjLCvR4tFDw0Xc8sqJ0b+QSS1ZGG8JkPxp5QNYnXKmMKFCD1o6QAAAZgXco3jsuJlcLXbztqwz6CMIPdCWSxsOfdAuVBgfHT8E+gMuW664np02aI4s3v1R2TCoZYyQE9rZ25JK6BRxNYd1CS7SUEc+1Q5nnw9t8qzU9B2fcm27+s0Ns6zzjhbNlz2yIPM+ckCSRDpOH4uelIMBNPE0QU8RSHksuCUJLFqcEcbkahmlAfA0A5H3hjQmUGJh/LRPvKS2qDWn9Yt/uvkIXUIP1pctiZePwgYFlaN3ak0t3gNlvaZP/1Ea9oPCoLaexG6LGYu3sD6QZkNZNSpM4vU6kaLALNFs28BUSfQYaQhVhPDzhgo8EAML54tWpPX7x+tVLHgLa0o6g6CtJJcEKaWG85jNwut+7mZrNKu/HR0lPxQRdwHPdam02f5bj1AbrNSUW6IR8OSbPVGiJja25ReTpT3YC1BNBEoB2eAhd2t6gefqaHxHlptQOUVjgB8R8m/YgLQA93FGQZ2zJqpJhCy5msOzbj1pnHruogliSEPUx/Q+moU+r49YbslFh2l5TK4oLQuu5tBfV94cfP5GqzR6z1cRiz7MBU3+iGteC3LC9SCYUwFrmUXStSwp+qQymFCGlSdrBJoFVm8xFIbQPOyqT3lMOldRjfiIXsNPPG+RZqPwn3hvUYVC2czejp/RkCvIuYRhIFSx/7BjL9H18eDLvaLiwgaJPvO4fFp29aZH/ZLDUnxtwXr1zmfRgy79V2eiVAA+7iSSnwYRLN4BgwJKWOCABWvFeT+L6iUDSh4bBz8uet5wyxC/n5Zt0kxg/PmusQVIQhIHLGadJhs8zhYKRCsv4RFqkNNyU1nNnG4//ombGdx7XYDyQGseOtUQUFocmnQf+GYgzfubEkGs0/vCe706Q6cNl/9b8gYwQV2p0dIBhx4woy4rQnR97I5ueV+gbYW+gkBqmwdteUMXqm5z3LAW4F27MhTj+oJ1CWXDoI61y6pS1NXcP7ladC3EE370VX9mDdLnQ58lKyTurese7FJ/vsd8d7QdZER5Dd48SGPncVs+lihJgIe14uth4+dqbv49Jqk7ztzGdYI/U4kQMSdp8hyJiUUa41SMEcaJZjQHyy0KkLb1sfEqOdkkSWjJBitH155zU4f619M9ei5pxl1q8Ua3RW6NoEIlFTpBwFp20XQyUeGDydWo0kMSxjTTLswRXkmt4XwtUQ8qmCt4pzSkxMe7Aq2pRp98XM2FNSWNI7IiRb+DcpC2DQIAt5bmKabguS5PMOwDhvJIgjcV/jngrKN0OfKgKRl0fZeNmtVy5J3zdWITKCD3hIbHkUf7jsoRq6t5X/Z95yXI4/MRhRylAglXhrjodKWCN6yLrKt5lKUa4o5Ht9ZZS8DRsXLvHVcfc8PolFL7XNDmNTY0GkQGk5zna29Df8dXSZDfYxOZD+TekYbgLfRLv2uyz2C9/2LHVsHNPvr58eQBtcmxU41cHpQeJglPyyB4p4SBerdQgQ6TCtM+b7+ebLSh0wAKJjzLoG0s0xt5qZjj02dUWW5nauwFA2sNzh3IX6DbxAziZXOdQZLBSnlMF+gZg56R0E/KR0SVvP28Oji+vlB9xssWSxzuec4Mdf3DWRoRLN4BQxDjXcowET7u3WgxLHrgcEErG2NCMxBGB/QT501QB2ydui7bYrwlZh0OF2gTmAkkPHAtxFC6SqUhM4TEjNdDxr+S7IuW2DBbMi7qOu1by/vAbUa43VUFbiavnBjMydtXzBcfRKkjH7gpg4vibmfN0Bk6bRATurFEJ7ieIKkSWjrg0IM5BgbfhSTGOy6bITFcOq7T0Q5m+QQBPcm+SZoCi7rk1ZBRCMU3vUISqknWKRuzDzH0D73cm5kX33AKWMPANAHzAsJTopEW4qpgvNTFP+2bfd3Tteub/Vxqn4Nb5n0s3tK8AiNKk+tETIcfAZLkAH4gAxMJ12F8tRSfzi0I2MadT3dn5tsWCkCB7WFSG9q3SAlZNtwmERAz/OPv2ZWRUvsUsD4oI8P3KyhepDJHSf8aaTvgBphuwMQ7IE6OSdeS5IURWcuEzpN2bOBzC7QAqiXM6vR3Nec1xQF87NIe5R4TwETSxJD03qRKRpz4iAp83BuD01TIlnzxgaMT5ThYtnysr/BcSLCGQoiZVdnegLZ4k7FByTod421UZJCrPOgx9kfjkgT+Q78/MtNPG6CL6BmRCN6Wa0GoAVde+AnnTGFgyBEJc8soE+prL3iD8ivDW2hBKp1/SYEa9Sn93ZVYliMpoemb9Z1bvNnZqdustyu+6X1FQxbylKW0j3WS4J38ZwLeNR2HEV5JQ43iXx97rUd9OmVAvfd5vzj/6JkBfQZPJYneUQ8i3PL0ucsSq7sxtjLjAeK92RDzvNzVXLePydUsZzPWMIf/QamGigAteMeKUJtiP9s/2SjFf5dAlRFn/zSib59PHdDu+AlKcq4gHzTVZ8uLId6OreAcIat5wBBYvLPaJEoM8s4T28aCjb9g7IZJwTcBv11r6WhytVJ0qIB2b4dv2d24gTm1JboC4RmzLWrrVZ1Sf/xPpzrqClmgBEKDWmHUWGYyOTKmGhNM5DF6+L2xueMpkQSlX/9olNp01chaBUyU2F9XRmCujbT0Bw5jZDZhjiAOXsp8ySERNe1iqpR2ZUU37ejz6IvI1Tw6QKQkNFKMtzQWPPC0q7mjJB4eyqaredy+ZrhKzsM9CmVIGRXaP9HLQtgUP7tohtrwqKlG6a00s6kfN6KZ9nqIke03ym1lLd5R+Rtp/8G6Q+GAC9fXPtDpzAKeh0jBlf2cC6A+DJ8kwMN76SUeb2seMlXtfZ69tnye4MQFb+g/CG00kU6s+xMFb00n4rVy5d2dmpbiXqVjcLuaR1/C+6IMNowVvSwk62REy0qGa7cE7C9/nbCOKM2H54CiDRUZmh70KzVpan8SIyzlAJCAa+fhVyIX5fVWbHQKCLDHXRZvw/UzJ2eFFrx1xmKBzhYIQ6DhJLQvADpHFE+/HS3O5ViiORgf3Wt0v0f0DT+PfvI9hKEjuA4wsZINB/8h2hNwDSiTUAihWafnp3GoFjrjYuKjpJjy/X3x/aL1n1j68k4XWEdoDcZ35LJ4Iy3Oy64tPis+B/A8lMJ36i0aUjjLKvXEQc8yCjQ4pB/I98JeAHf/zddoSpKJuYBjwrl8i7hKu0BDPXh3Uj4pP4M1Dsv3aJHWz1X3dkUVPYRrpT0BXZfa4WcuVYYZytX4J+f/+NkPHmiSxRssrpDAcIXFzYz4yT4g7dnmhXslIt2uxxhvgSbD3uHKsrJQvu+jLwci5W7JFLxNHidPo2L+SRXXeaDKCAxX+u5xUdw8Arfduit4uHUwNMXJNuV9YOmTZ26jOQUhudowAd1IaNGlzIcPXUy1YfIijQQVmXmW2kmezSzetC/n7DNavXrpRF06jAO1f3Jt18h9HZhc6jb6xJu9Tldz7WJcl00gEV1kjh9jy+5+vse5qZERlKyLW6/dnNQiPysuX7T0wuAqE33GLV/4Ht/+1B6Hy+eX01A8DECAve2JNDHGhFF1Xlp8yU0TFRwQHnDW3qONeCN8vzrG2zJH9EBDbwb9ucAngCANrvo2TbiZ1Tx9j9QqxNcpdcFFoBDEIbnrTZ6RtSr/l1i66dhUAUYEXc1xzlEgyihT4hJro1rq1NrLNagffrvFaOPqOPM+LaECmBrHqVUKG7ONn+F69UmQIs01z7QN1rDH30jn9dMp/VpQlCCtZS44gSALTAMmhYtuZK7muG4SOiHvyeh3vMc+XmRW4X3RMBUYK9aOl1xc6TyvtpR98VMF08+2Sj1mdCUAwqg9+WavWvfwqQlzjEzcxsdMUzudHpVaoUwcWnLoXkXahf39ZPKAevWDPl3j+KkLJujPsOwY3fs2V3NkTqU63ukAs++UKk9cSh5gip88f4Ko2OCeWVTmwrXJ6VeSGZsJUtB/6hHALd4Yb4lzyZW3mn7FuS6iMbot3o+81psoDKmXDx3Td+Is6xJgimncOz2Pv7ZgnS7XZqOHehyWNUvHjvvHBbh2k282mUoYm+DdmyYGPeIHWf4gD5FXQno+8+dEcbXyvftf3JaU5aO44bixuaFnQIPFcmKOe2B9XHjrLHXXc926X2Bh9aHciat5vBRd7sPGfQ6BOnmfcI7mCd7E8AFYSFAMS/3l2OioaeK10p6AJqRmeMw2vdcIbWFjsiUefiOu/Q3rZjFi8Yb8MZDAEHgUShekMrl8fcH64c+JvN6i3+HooeXEOF3hj4B2NomTs0KoGbjNP/BSj47fprHiUVhJ6v2Y+17Z3/QMzLd4pxfYaFqJzCWA8jMcvFzx6BFZT4wkTMlirAkW74BBgVmKKnY1b7BYvC0bJ8+N0lZ+CRNA2Nqnboc8bgfv54K3JjqWrOZABJqboiy3EXGOErHp++SuJ30C5gKZnQwzVTZ/oiUVShMA/nt2xGhyILNCmStg3v979nh10v+NTIQhtEhAXxLXIsbo4Xh5fU9pLMnfDiL69Fu9xOLtpyezufHQ93bYDq2GJVxbvOOs5hJosjV0NQdIihVQeEAfbCVXuMUbNdfgGoztQx1mCi6QRm6Iqau59A5oZuKzbpilzrje7boeNVvyivFGwQ1dzTEJGAoX9GCG9f63B7p0/UvAtceMU6ftNcpgijHbMS0FEw+zKmjllyX0wBTA89sSaUfMGNuS+Gxy7DQtKEqQ6FRm7YqMW6SsSxJ9UQsCYRaAwebWFVuiJgr6HfUyoDHeEsNP+wGCprV9wlCZVle7clC7h5PzAARo3ldJOXXQdtE+l/qLQt8SC9RnrTPEy8noh2SBYueOlH06qtGb7hkbwIUb6JzkQsxpE6Vn6B7JlS4Y58mTYb0/qV/H2EN1BN1HFuONcaOQ+BOQdfGPPFjwefBuskx1dpxoaZc8dSTGn64tKI+F8fgYOgQ/QZkH8aCRNa1st3hbuGj8mFvVJMA1u2zUokOhkqoCwj24T/CrInHEab+wDJ2pmKXf2+j047HnEcdqSzeqNZd1W+lademmrMXb9nqgaspdz/aoS+7s1CWQIstmmpSxiODtC/qaQVCi5w3SkIj25VtGKS3NSypbJKs5KvUzj7TEeF9znxnbq/sldzlznVg6M1Fal9VSC9MY75RG09whdB8kY2A0EPc7j/FGnh1oHMSea0VNCUJCTE+akuChRflvULYi3vqk32opz0ty5/KqzHuFMJ4xcSiNTbGVeATF07rFGk3W/cHJTklQCOE6tVq8Qx3vgMEA3SiJuytZsMbatQneQlsUwFBIG5YnEpMIG26MPM0v7S9ow6KkDOWsxbuBlF1g7m7i2GIiDgcxatn44ZgkTmIx3pAhcr0VGnW5Fsl1HJN48VIg4J4EzAoytPR9JBZvRphsmb4pJJc5CWsu26B+SLLrSrGYEiBhGQf3VACLl/48TvoF3wPzamMAaIwedQX/XLBmgsKDWrIlRPF5JdXSXEo8E9BNW1oDkhUf3hFm1IZ3h+Up4B1A6RwICaAAjXIeEot3ruCdPhcOn6S2KEkgk4w1x3sQGFSaCKaWgPcE1ju+B5OwDItFjwLiHSHrvyR488zDRVD2SPQoMl5xvCUKKjRmGunEPluMUEtB6R/G5CWJmlz9IhZpCqAF0Pb5/+xQH3yRnQzqpeFiYBNXc3BpJkQF1rOo+ELmnFwr1TeXFG74iRT2AXTtgd+MV5uv0ZwNbYJkl8JiTJUdZSeTd95+o40M25ABG5RSILCi9QKYO54jA9uXXM0x5pFfS98rp18Y53n8bmkcMwBrxKIrJX0cKKv22GSEuvCA0er/YvrLGT8smZi6moPFm3taZIYQPYtUhLCV4uLA/XvdsWMNeh7FfaLXmJlszbxfjpu3udjaYFTDcNygK3D0Qg6XqEe2spIuROd9mteAe6lE+0e+d1HBqo1lH11J7HTfoXoAk9upQi/6O+3L7mfPMPZDyVOJAcDbXGFZEujaWuWAKepXf00V/TQMzEPuju/xE7yLlJ2Ed8/3hH5mvGbzAOOQruL30th7MZEoVLqYUK9O/L+RmbFSF2zuQRWNwWwLaSRVaFBXcyh1C3wG7k+gY1ANA5/L1wX3CpAsu3o9kett7+GcG2fZvSoLvDegdRDWuMWazeL7AySu9Qm9Tud1u3XN8FOJlxpgEwsKB3iuXfBWcxWCq/kwAd1Ii88fZzOkO9KDLiebzdjY6R+wSSTBMOMSTO4Hq5Gx+TzreFM3m8Mvn6mO/NNMFuMdu5rHkjx1dxPHpiIijswvoIMJdriZccjosg0MHibJkM43qL/M3W1RuAeMjAVvZPygfWSQOXOeEWCE52VjIuVDiJcDASHHL8me9BmTvJNnpxZveB82V3OquaWuaVudFLm8UsC8w/tdeckG53oHBgiUPujWxz0YKHi/oDewZm5/KnUnPPD3bWm22/rKMtPjHXmu5mU2DmR2Eos3Fbzj9/33mGnmgO+xVnSuhaIg4CB75YM+XbLD6H/Z7KetLjVgpzOm66z/cox3qWKNNN8Hj/9uQkbgsllM8EXpaWeMTCmmaeCup93zDOtQfJ1HDgbp2VgCRQLd+m7Bu5wwjHR/wxqScgCg9YRmScb2paRDFDgGSRkHWGy+dGNRIcaWXA2ZXMninYwPrLMjI8u1bkuHWERKWKjrjesIPpesIQBbDL3Zl+x75V42QFuAifzht1MBHxRyfzpsjKHQo2ctzAN42Gy1VnPyDM74YagMzhmsN85g2rKp6woeaMX1ZIixreUXa8hYvMt5CfFiZaRN4KSWcGkXn0+qq0gsibTuohCUdHxYxq8oaHI1PrYo27O8zybFWZIBoHAH7LuF3fuDnzU9vGJKrGix4aLbOzKW2iIUsWh2aD7ndLwbf6NR1wVfcoE6f1fzUupx4r7eb1RQ0vSr6VFt7NP2GmkqLVg5MfAslJRjxnyz+22QxouXQ6geAHlNoEmY0Mzg74R7JW8CKbkaTdqK64yWKYtCeEylpcvCnlwT7/X0uuwkXHF3p3WO7onDLaXvOEDphOe6bc3zcxoUyOk4zWulJvrjPmDYByTSvfDWDtVg8ZIMWc0DBgXSRlp96YZko/skV5Ms3qbbpPwcTjSQuIKmTh+61NU8dvP0Afb9rud61B1EQAImAAQzdDWnrk62trEcE7SJiRa6mKCWxG/Gf9PyNWmynPQB730ecVNomX3hvT7xIEQ351QjWk6YYN5fH8sfJ3y2w5FaMPAxPmWuxGRarIQYJ/woOPGwA6mPYGnkTBwIzS//r9dwNYd3bIuno7HROP+YSRbW6SUHpcweAEIT8ok/9hXq8sLzVcXIS66G71DX8KxPXR4xaZK0B23lZeDghvg2sNbxtWD3ACmrR1/rUe9+5lYF4zp+/j3ThIP7GZ/nYtDejYVNMca7sXKNNHfHnm9sXUbBYosRpJ4JPH4NmBSMh4X3MWCxeEPsOax7mMPtTs66w0vPpkneOKhng47XtjHTxKJOaQHsqUXiOs8SkHGkgrevnkbyGHHtJ1jPoiAvxnhHP8tM+YHjB+EI33V7FyQOws+zCQMT5k2aOy54G5ai2OLN7gPawse+28YtSWgHeglQek/3Pj6DK5ZgjDBdqKBFaxa/hgOt5KgAx7mTFC4U2brN0TmMbrtAk11W1ijGW14Dxtkr3E9pOHWHd7maY+4H/AqsZ7VOrgYu45LHwIvv9YqKxDR/h30vvPD7ifoMzIQW5Ng+PiYJSTEZlo/kTfNTFIGLXkPowUUHjtHnb34OLgzbiXqwzvKNapt17CUR6b6HOtsTR0f3Qd4Sim1Onq7rRwN9BqXXYXGd8uiZ5txg4jNegz4po8X74KADkuCKc4zKR9wHQENnEnqO5M+wSLP2kD/iruaS4oQrhSIaYWYw5F4BknJbl15FD4b4sxlCsjRXOCrlv/MA+xYFbxu/mVr+42eTz/hc0H4hr98fnwGUJEH4j20fBIt3wKBAIqRw6Lx22UT9j25i2ESS5jGJtSOfGbX3LFlL+UbBa8BlZNWlGrPlxDyOicjiLV8Hwj/UKQTBGA80mhAE3WagvrbRZuyS1RNvWltW88TVPBG8ywmDRxm6e+JM0iig0xqjdE7Q1Rw155AFONUIFjsyYeyvktJXLmFdYqR8HicdtnA4yNbD6OBFxtLm8gZEkYIzxqde2652PmOG4WpuqxEMwJJMuo53LBOixRvWOnVt/91+o9Rxu2a14dxyge8JMwC7YsytIAKdzxzDu8Ns16arOdFqo4XP8vLAogPZ6sFC6OsSBmP86fltautfZT0OJGGKM5LYf7CGR+PI5xJFV/P6yi3eaL2joNlnXRZv/BgZEvo7/NxgpYjLAgurYfEmsbUQe/7r62apfz7ebWQTpjHYHK5YTO5NZLNiJf1lOTd0lmxh/2H/qdcJCt70fjELOVqQPVxZeflK2t4zb/eqbU+eJsZ449pJFJPx77j/oC30PunqTi2Y1x4z1m7xluaB/U3vRddg7qoPgjdPykaBdIrud8PlPv6Z2T+gCDayn7uTq9E+69wnTEl83TGyNwyCruE9N23ROVWi9Z6eobZM9IlnjmU90rM3LUlKBJIcgV16JCjkYM6wPzRHx/oko76P1xxYwyDXCX0OJCWc31KijApTFDgMm2UO9xXsA25ho142yd+Ofutr7JeQduIzr6TU4Tu0qjWW8Qv2tsXy837kuprHYTt0bvbcxF4mlj7236eNV0vG+SFs9EVSpHGLt22d+WQUd8V48z5jH6mrOc22L2Zgz/RRWZKrCZ0tmcp44E84D85LrkkCJvAYXEmLOT7+clTkuUMTaep+O957XnjL6x/1J7yu7R3geJF3BgUm8tg+Xmv9A0I1CYvHTmtzyGoeMEiwMdxRUp2sizG6Rxtggqf+yGCQ5A3JN1eihSXEOLFq+LqaO4QX2HRQpgfiazDGJU2uVkrcZsBFnbvbAAHvjTc7zzyKm/nWJ7rMOo6GxTu9Ht3J8Dpau5MSD2QaIC766QsmqGUWaUjc821zl35g/jm5LfsCpNqq2Db0nbbpw9xJmethbC7tMTKuvkleeBkXcK1CwHyiJQkSArlcH1sEizcXqrdbt0WMzW9wCN6RG7sqDMxKnjvPaPGOS7ChRYcnmuIxvRJA+wulkiCG3zd5jW+sXZJ9njXM1ykVGsECLCn2uHD+k81aqrJ4S88AZvqgbVPGD17DZQdH3g+pUGBa6SRGbHxsieFMKjLU+BFUH5AyVmM7HI+eKydo5M9xMaPJemDCLQpGKy1hSkipV1BW8DY8KxxrwodmGzXEWd/+en+nevvT/qQd+qw0Bpd8RxLHaQEKvVHKZU2fwAIOdJTvCVROebmaCxZvLlzCGWFzswcgnaKvyoxjLsnu9PG5RT3S6rwt3qmruU3JA4mNDt5uhLjff7X7KH0WAaObWryziZuyydXk78zY5ezzbHQrWQvCQLWCHCzeZK0jIHbeB/SeF97rNayP2O74kXJohthenfnTloQU6DmPtfXlewCVxHjDOou8d/ye4Wo6LYeYnwyNu5q7PLN0f1n/cJ5s3j0413TtAR0X+VD2KrWuA/slnKd5/YN9Dx5E31/P9LagruZpAjbZiML7KcWBwxxIfBO29k7slQYJ3qQkaTR3hZQLAfNJ6HGzr9dYOn1ZdD0XV4OneOKNniSppN3VPPqJRhNQYCLNzriaUy+Z+F9//BJp+3CflMcIFKe1zn0zuxFivIcJ8gguX46iJYj95EQKBBu+gIGBs1m8rXW83V1N7rFafIjgPcAJv4UBSpNVpEx+puRH/OdDr/QaRIwyHdQigpZmvI62Rw8Smi14XOzuSa05xtgyDJr5gSTQffCFbPIGgWAaHgwOLT0XHG98JOtWBPHw0pqJXPjTklDegjdfM2SYMJ9o4aLuxHScIGzCu4TDAt4DCERQigrbwlI/849FLXVWi8oZJ3QpRWv66NY6ddEBo9VGK/tL4I+82psbb677SA/d+qi/EFeHkGK8bcJ85Gpe1nsiz+KN9Yh9GTTcg9yrIiN4x3sKXIHBio51xSnwmSB8ghfO8buNSmO8GcPgEwtIr7jvrCjOD3DYDsS7oQSJueqyCSjjn9TKh3VQdb30cfVqo1Wi907lai4kwk/JjRfb4YB3hF4cYHmk4En0bAmlDMGbPBvXuJQbgfcE1zpP1JO5Lx4D/L/Dt9zuvlRRgBaWJHs/c42mihyeKV6yeKOiDsZL66Dz/CJIhyRXc26poV5gqeLQnCmdtyL+DGjBSbubnjP4nZnkruS0XuKc0GocOmMxF7wdVtw0uZpMG0CRt+YyKd2iZefS8afMOCorna7mNqtkYvFOGVw8Y288PuuVkD5fVkokydWIxZvOjU/YA96D64B7YOAzbaFRcn8j4Hhs3lg6rlxwNTeEU5c3lVB3GfDUmz1q7/NmZNrFuYlKUfmNxWnRJPQlt95zPC94FXgZusbGm0tCPCz3JGNjeQSkbkm8TVIr3kMYBvD5O3nPUWpsrJzBdV625OGQ1jlfI6myKf0MeBfR1Ty+dok4ZxPMK/UexXZgiBfsHymjpIS0wB/YQhcov0b3lStXTN7RDDwNzo01q3k83lXjyjGQvA6vzbia099L5nsyBG9ILtpYUkftZFZIgs/mMrk7CN7DBXlJlXwWXsJMxlQBLDB/uDNN+vGDDUzGC5LOnPHjUfrA3X2TFu3SQdsxrErkGTYtGNSupLAJicB0wLOBKQIBh1o4uQaMjg1jvpDY8xhvDiRi1OJN78DDNRG8SXtQTxbBLVAAX4u3Kx4JABo+mhiF4um3+9T1D/MSG25G47J/dWgBFuoI77xhc67FG/uLlnjf7KqceSrzGKGYZ6S1Z6krP2Y1x3bgXdH5x4Ma+yMdALwP6JlAY/q3XKu5EHOGeDEuQWcDCkxo8eZ9lEp/2PZDb7wP4JC3MUrH7BwdRmf/dLTo1QD7qairObXQ4nNRgEEhlgIPS3BpwzGjgopbiHxzHazytQZdtxmZEw6qlJNKGpbI53+4s9M4+NeKBRdqKUPagese3jPNbEuvtwkc+DlnULmruc0LgLZPXzcyM9wFn/Zuq7XMmtv0HUqZnGmJnDylHbUyo9tgImjH85YkBStnhWWqzKCK1yihWNwOCt7xd9wNHPNsSO7NGYa7Lj/Gmz4LaMFem5oCLJI7OjdiXgHB4kbPLTpGW3+j60pGmU1cCxJZx/Yg87tUjgsTC5Y9rKwuizcqRWgX0DMEaKftPskaiWjUmcFTn2KcU7BAFimdRZUghuDtuMfmGUHzQrgEb1h7nB/TIVnk763XtiuxMDaZ9xESXGLlDtrXxM3bkoNHguuqcYmgmW8pxL2KZy/Qfdf7yVi8kzJ+8vWovDT2hiXbOs7DfGPSmd5jkxZdnYLSWpfni1Ftga15/rZ9BG/gA//z63GZ8dD1ESWlzd6M/TrtR6PUMxdOEBVImKQR49sxIbCU30jr2MomD0r5QUpLne89Z02AoJ8qRuU9guOFRNBQWhDmUsqjJMV403VEL9X7DvjCOqUO2HpEsqaAphfJyj4nIFi8hwnyGFUfF+My+wlxuZf9O2JGbzlxnC4bw7Vt2O4pe4xSyy2aZkwF4CM5sbDJfg+ePcGwLtLM4BSwucByBAAXWzo+egcl5mgZB4KAwkFe6S5qnUm0/WQc6GKKseLU4o11rgF7bzZCPRhn3kTQrI8Lk4RISJDxs7wY7bykOrTcGSCPeUbtLswdZSw6u7PleKL+prXC8T4flzpubeYhDUh8qeBtHFaxOzgqMEBIQSuzFIOUiQUVMjWjZwJltvW1wniuuCtVSElAxnOJ+evEmMSykFiFWkgLuZoPRJ4f0I4t1HrF2AMgdR1nbVjoR1pv3WwY/qT7hwvO0pwlsbzkZaBSg1u8fVzPYY5gjbpq/KJAgdfz/sGcc14Vq0JALgbA91ZPF4pUmujWJ7rFTO+2fYD7iCfv82UOaIw3ZbSR2dlr0xZd/hBBFQ2YhTx13U7bXX3pxowFmVsUXKB7BseGNBHXCp5T/cLaAYUftQYjA//y//qMdQtrEQUqq7uvZPEu2+Ity8l75WO0xl+yd0npS16GaerBgusexsGTKUl0DN4HMMhYkQOvkNZablx+fC5j/HG0F2QCois92FzNyedvfNyvbn60K9m/EXNvfbwxBh+L9ze/3uCdF0VnjafVTihNdQioNqGDK/ehxJ0ESYER7cH0erDKvXTJROv9YhuWvlKrcLUWbxCCcE+5stwbfSqlexjOUCpsrf+LKQZ/wM8RPBPywhgWJ9UTuACJSLxHSHgH7JVdN27JZAK3C972Ul30cym5p21ZLr1wSlS5EpiXE1tr2fRabA7mE/kyvo7x/eOcoxHoX6emwj7QXrjmqxkDanrML+t2mdKS8kPVuGbr8cT9QT6dQ6KR+P74WshUQiil5wk3tEUySRR2gVV2uJfA3IAgeA8T5BFIYCIf/m0q/EllNHh8KWxUhHaF01/aS2Qgo4TCUlJqhRwiNmKWtCm4iVH8b1K/TniEsRwQYxMdsKkgi5A0Z5GreWx9yTukEsGbZKwkE4BMJI6NJmujzBoIGouypE80q/lD55C4T+HApqAeCABbghiKD79Msz3mKWCwPRpzjUyxdCsQOpoYC+b8qB1NVx8JNJFHpk2iaabCP13jWPILLafQB5x/+VCW+lAS+6QVLTQzsdDHc27KEbzjtXHfWRPU1UdmEx9hH8HSJnk/mLG3qTAiQa9DcDkDCwWZo/0unKE+nYKLVLkFb8vJZCshBAISCuvQ//P/2aH+82y3kw7hd/TQpYoTCp9ka5gIzQVq8eaKRf29dq81n8XzOYCweu8Z441+SXx7QuPIsyVgf3i5OimxT245MXILKjR0vCdXNCHDl6yDmDll7+tfp45Paj2bDWTzMnBQV2RMroN0BGllUtqpnFVSvftpnyFooeD43uf9RsUB0+Jt64vKBQpSwMTh3PMRUqZYfE5JyuhOaIeDcYf1hQk8QWDJCL0Wqx5Y8GCujLUgPCdRLNgESbSCEWHPdi3sXRst4ALpcVe3k7ro2XhnBFeI0X0IggTQRjo+SAR11t5+8d1I32megLzSecl3Ksf6Gv/Es+kgEksffZ/lx1C5kVxTVzISxtmUhXnAELqoTX/lnY9gBevHxSPBuQQhRW1xKUsAWC6p4A2ecLc8lnqq8f7lGYxQsYU11F19T9ahILiZYQb2wfNqC5K11WbxlngMfo+kBKblxK47dpxaKDamSGuAK2Qwqzny3mDxBiv7srERLEkOXCrpWtf/eTZlUpu5kpX8Xsn+SJ5HaCZ6wVIvBLvgrTJleW3zMCDQ60TwJmE78BxXCM2ciiB4DxN4JBVWC42vz2EITKZyMqmdmWhhyfW4yLmwCdYWiO1acsHoefApHnq+yZ/QOs1xzJ9nGrHSoMGjWTX5RkzHhsJ8SWeABuTFL+G3cPjgOE1NpXl/kc2duEDHHUZmN8mszn4i/nK/6TruyriLoEJNXrZtFIQkV2G+ZiBuEOIeudbRNg2rLNmgM4xH/SglBxeWZUPAtKbufNQbgLszpQfORbe5BWHpAOSMT5JcjVl38uZMQp5nASpwwNKGa4EyDNydzNUPTHqoGSVyH+QqwIMW5zoVYPIT6gFQc41rG8u/wD7A/YNr8LDLZloFGN1PwWUeyyjxveQjeGslXs48UyaWuprT7/lc8AoJSPsMi7fjmYkbXI4Vhych8mWaf/XXdjm5GnkejfWj401qYDNBHAE0e61l046VyE+XMAuMMWRVRkDiIfSU0c91vF+cU6hxjsocbcWhJbqMGO80JtJG/yRvKT7WRAnVT1y3C2TzlhJu6XaFrOZGP4i1BuKwj9yxVZf+9Hr/pSgfBFiWdX+RNggHupRB2eh7HBOMwhvPfEwB+9oW440f0y5Qi7cUd4pj0WOI/6SWUaDrEPrx4Zdp3oX1Vmhy1rfnWEi7pacKeZurOZSqOusno9KxWmhh6iVjnk2gCKGQkpIxudsJXdrNk59Ai7OPoAzv4rS9onH6sCqw7l3VKpCPuvPpNCcMnKnc1dxmUQagUsY21nRtEQW8xdUc1zvf+npdWxIGc/AqDy6LN1ecSkI1D9GSYrw1f8l4KBsyrubxvajsAEUetpWU7AIDmdAWWrz/HvOeY0iiQXzE5ms4LCRKFoihfwlPEw8YaAd4U/h44/zlPpPHNRCHYfQjDWV8GvL52LpOLK0gZGLukryD4D1M4JMEIw9JC2jB7RbijphAQAkGElzYbFBGLLmX+Hq4Yrz1veR36aCfGLuV6s2tD/V4o+XEeIPgX2IuiDb3WlHbH99HZxmI6hSinDDGkXPK8rgxtBAlVjkUvHOYMZ+63DRJU57FGwkaZmpXRj1dE0ftNFIn8eHKDhuNA9csyDCO2HWj5sQqZqyruI42YAMSemBoiWOrOL6XZ98RgpuMfpVyLd7oYgdZ4mlCPJ8wDY4LfjY6U0ucAhkBLXgLFm9TWHL3A5gjuBzmAjXBeNAgo7panL0UBRhOL2wMGxc60P1au5r3Z13UpKQnyXeCWyHQCmAI//tyj1pu38nJ5xgO4mvtcSFRmgk0SGKSEwaO7q2S7OVi9If0i9yS7U/8cO7qlxf6gnjm7b6kfxut0iQLfDwzbPzzWys0ORV79lI6blrzx0PHqg1XTvuCAnHias5oLX2/qHQBYQ1pFU2upseWifEuuQVvD1dz9BCAvcDLPyF0okUHAcB3SefGZhmWFGkwxv23bo3qTUtW0szzIm+vtOxg9LnUQ1e/8fmQzyVhVl11vJ0W75jJFhQrIBB8LVbAS2OhY6AKYhQkrr43CnVzjcQVH0y/M8+Y9PeDtmtN6rIDpBre0pmNFm/wwDOeK5RlsykJd9qgWS29cH4JRBuoB2Fk8bNvaFTO6t89aA3wXy5BXlpeIIw6k6tlYrzdBhmxRJe1nJjZr6RiAHsfUhgA7x9mTjfcnJnQbFOsrrh4+j7RoyUZT9zGDOIlwNeGlK8ovR8ShZVNqzzQkfiRELqCz0iTxcptobcQ1LOH3B/UexLn5OQ9UoUU/04C0nl+VnBW3lV1whUKUHLwRA1xqEWULyP6Qs+LZ4WAOQlB8B4mAIIBmtf/slhiG0TSyBY+Xat6I7EFzBOGuDJT0jZdBws2D1oqidFbLE4ANGlqv968wLShth6flfa5xIibeRDnuZrjWEHbT+OGKJG594VsBnAfpId4SWRCuPeBDe9+lq89iAgvPsd9qkvPQ+HN6jrLLJhlz4ManwXrhmokdd3JuE3IGwD1ejPCaOzOlGpWncOSXc2ZxRv7B5ngpbIURbDQhHq12er2BDqPv9GblKTDfWNaKbMWy8xhVsct3imjhPe0d0all5J7bBZvy17g8a3UnRrvocJPYrEU2kJlCY/RBPe4q+/tqsjinSd5R9Yj3LuxsEItuYKiiO9JqkFHRtHpipdYIW2din40M3pp8zqwAfq1yTeb1HdXa8pYeelro/O0yapN6ufbjkhKEOYp9mid1SICAaxpeNfdLMYb8bcHI4GKCzqmq3n6OdIDsIpHOSCiv20l/6T9nonxJsqUA34fl55k12DVARukckeGAkS0mKFywfwy457sCJ3QwgcpqyQJAdgPu6t5FKqAy8NWPgqeo+fcKuBi51TmnYJSzRbnKVn/kr7XmQy6y7PFJniXjFwqZqKwAVeivb4oQRNWgcBhUQGXxnh3sHKekgLDFhYDSgluxdfzQmqiIySaM1Agxhtu52E3LsDcu1zBba7QrjwRUA6QQsr5QMErzwCitW8/q/Dd4rrj61pSiiT9SRTXKpOPBNu3JQHDsUDenfvOHO88A35/R+qhlxHw45+SAkPz0izxKlVSgsGEC95YTozj0ylpQ8AjcDf7aMyqENCDge9JTjski3ce3wghrLt/JzLcJAp++oxYwQI/E+WLkAl+bkAQvIcJYCFCQq5FWCwxh4/Qyy03NldzrSknFGP/rUaIpZdK3NrkMR7OeCEwkdK26zRHVgKmzftkMkkkxpOrMa26y40K+6rvtWR0vfu57iRZUaXgCgM6T9FPdx8h/rHQ83J2rHQAooCalyQnLxMqvx+fxYk7Ek8OfkDC+088ERwabVvfIXO70T4R+mjSpkpczTkwmzTiudhCH7maR5/R+CvuiiaN4V+njVNrL9eg94CeM7B4l6OyM1TQ4YeTbrOfxWtbGB/+HpL1SeJiqeDtilOGvefjoYHXuoTBx9/osboCciRlYCwWb5ureRoznV7f47J4M8UlWp2hTBxNmmNzNXcxzRKt4mOn9I57C5VY1uJpccLFvGoY+B6AiUNB0VcAB+sXWnx4/7HsHoBamz/6qt9p8T7pL+1GwjO7xTufsaOZ0m3XRG7tJQ/BO72GKkDE+ESiXKAYx5R9Nos3zRjvSuSXegnI7ziJCSYlOSVFDM0L8IsdW7WVlrfDkZaXtM9d8o3QPXwneYnqAPPFXjg8GSeMiXprubKa0/lDxe+Ll0xUN584LmNJxfGiQhPqK1OISeosnn6SkB7L3X7CAuGntKu5gx3QQhqjhS5EXhjFRBZo1/XOOI3jFQ04bnhYNmxIfBEqMFBZiJU6MjHevC2VlsLErODSvgIaDlV8ICxEWvc4FlDyLD5/nbr80DFa0UmB69NWOhTw0VfRJC25QHYi+RJCXimN8Y5yHtHzBfY/HQe+H6rwjJQ2WWW/6HGQ/SjtT9wGp5m4h7CEZhGeCvv+7EUT1fE/hCpKqZKaKvEjb8ty4kUHgP3vyl0xpyII3sMElKj6wJX0hbrb0MNEHwZMc0ibAffyK4/IJuYxkhvkuJon/bO4ygHhBgIItXmB0UTBm5aSQhhMfvzcl0iZp1yLN7kOmVojfie2NEqwZdtNxscE7mSojHmvFcHIPMcCmu0VYuroWGzZZKlWmB66mCSE9yF9lhKZMxpTb3xOJhvjsJHxxrrdNnCBD/oCmULPJLF99Pm0r3leAj6ga23d5RsTJoGWE6MwNfTRH3w/LLVQg1p/xaaIOQKGBzxA+pTa69w2deMjqQVZ8gKhDJVrHyTzxhRCcDsyeTTBFY3R5bjm3k4vRlrKck5x8e0d6ie/a4sP2fy2spa19D6Ye25dpyWeeBsu18h0bmKmIKaOFx04RifNSdqP2+JCo2ssEn2TYhnF/BbsPmBKpCRnEpCJhXeM/Wv1raNMXDxxXfDEdQDoCzJKO52e1ik2KwtQ5Q5JrtZUhat5fCvdC1J9emeMNxPGAK4SRK7QEZ6A06bcoZmREwFBeE7iVmyzeMc5IcB11eVqju8O5uGArVt1dRPpOXT9IlOPgi+U99mEJMii10vPvP/FHkOBZDu3rj9ubLKP7jhlnPrTYWOM9q0x3ozm0eaxYgaEG0Hb6fln9huueeXSiYabOvZV8l6QhiAJ2NG7yC/lpdslNBDfp5/FO79xWrZOgo0GurLO83lJBN0CjA484yrmIWUI3j2mxTta12SPW0I6rn2AJIFDwZPyAXUltctGLWncMuMpQDm54cqNapt1mvQ14I3ErdbQBiQaG9NqunVL/A4tSassHlqoRIZzHZM1Yp8vOSjaC5pHpn0QXg9PQJYXLmWDTRGIfMduG0eCN3pcUeAzRzJPRJGGlrNfwtyiBwBW+4livIOrecAgIcrEnH9dsqEcgrdk8dYx3iU/yyQHXfh4yPtAYniiOn0lww0N2pvZmd3IRnyXMOa8mErsM51bQZFtYMkF6nSZEBojLAG/5UnhshZvVVMUsXiDthYSYmCSI5/XJsX8I0oOq0aZvF/tNi1ZimhW85j5BsYIaliuEddctsEW7yjFVfN1XQO5W/1q91TAp54juuSFoDOgzIFUsxKByifYV7TPNIasJOwJqAaAoMoojsRCIswR7h/T4m1tSk2ZOSC+h41XaSxk8YYs/dinImvS9LoppUIoexa3cKEFCvDWJ2ZSq0pczXFOuacHzzlAITEqPI6b0rsTfjjS6I9tDee5mu+zxQidNI1mSh9hj6Aw+0fmAgV9mFtwjYf6ughJ+fTx5AHRzRG8VKjbszWruce5lCihHMIFFfIlJO7HgkUp75zNo8XSEoN9Qa2WrrbQ8m5bq/UkuZreEYJ7M93TOFa+FqXEpm9/2hdnFI4+/cWOI9Xlh5pKeaZrdlrtbXMFJfDw+VC/fuxI2eL92ZR+b1dzsKZRjxHcl6nyOv1b8riQFBi2sBjdlKAQ4t6F9PlGu0QppV1tHQIshiMl/clBFMpn/15UDMU/rzjcVIDYlLyQ2K6ogeGKu9MwFQrMNQIVWEzB21RilD144txwIUnxWafUn48YqxYclyUY263bnFh7o3dbZvmHPJWZglIe1yPwEZA7A71QV1y8IZlzTIRH6dNPvtdibddHTgBAqOVuZ03PVSriPkbvlLaO7MEzaVr02Tn7jrIadrBP/f2yshkTPmMiadgP+ppg8Q4YDETCQv7mdWmZU+Y6+o1eItVwdjF0/JmGm6eDyCQbntTgtFlD8XCE/yXBm1oqdWZHLnh7xlRGCRviA8vSXwRcZisT4gLOLxe4a00v8i3e2c+SJCWWe02LKjBDZs3o9ELzzx/HhJ9m00XCLSXWe+7dVEKC2H6qgKHvUlrbvHxZYrUQLWPpYcbHVykgeR7NEAp9xPrbUp1gydVcYj6Bsezri5UV5OVSBse03kc/X/swncsr75EZGQnIMNByYkbeBAejBkyqtKd5krG8GG8oYQOgSbY4sIwJtQhdc1+nTuBGmWCY+4zFm1m20A2Xwk0/3cKCzfvE5bWBzKTRTjwIGuMp1Y6l10h9BZdZW01hYF5/vm2r0YYvfTMZbvTayGZfBuaeC9BrLN2QEcZBwbbFmk1aMEKhEi1KUN+Zgq4LiAuE2uYSrc6GXRR1NY+FHiMe3T0/LkVaHqA/eF8qNMsKKJ5UMPt9lFsDz3Gppr1+TkxbcR5W+Zo51zQkA3HadbMysb4ZOHgRhFGH29YM+ZLyFvAbrqGr40zJmMiMu4LTd6FzUZC/0WU3LSeWMyxbVnOL4J1RdgiJbH1ivKF/Nu8lfIaL/+OA9+1K2ivxCtgu7NXs9dm2ILHdfluOqIlnHyogIGRjs9Wb1DrLN1pjvPOEbFp5wAbOb7vm9Hf7jU6U71GWbfM+X1pAeSXsZx05y7SrOWsL3uEdT6Uu+0niMUJfs+cDrpdsx+jzL/1Xp3rhvT7vfDToPeJSdmIC5bS/2WsGLHW8cS4h7BYwdWbklhtczQMGBbwkQR5cMYqStVVrYZPrkPn2E0polk+b5leK+7UJ3vg5rdE5s8PD4k3ifvj4JFDXeymWWPrbW3OJh2XCWJQMhqAaSzevKxq1b8YP2SAd3Eig88ojRddEZV/AUs4PJr4+USOtLTeZeEK5hnvST2L1gmfmhQ3YmGEjAR/pgySsVgt6wMPvNAGR7VrsT9TX7HWYDbnMcxrQk4b0HxMCUUXVfS+QFPYMPKkgLcmFTBlVHOBn0oEN4xTHIMaIqlzQes4clx48JvP+bnksYj4oCQKmmru1J8nVKNNvYUzYhxp5h3wq2KeNnv6jUersfUxN/47rp6ZlSJLHFYV8XdrmgjP23AIF78VHmC7qah49O30OKtQygncf1LJP2xzbWtK5SrjFO0rCaCpfccx8DRlzoctI2ucBXM0xQV25wBozE26l/ad9ccV451q8SWdgLr63epMWHPG+ts60GoSkGE8UR46+a+E9vkbKxm28u7o0IRh1G7cJxy6FBe1fqsxLv0PlLSpYpPEl7Qht4u/83WHJu6wShtAwnkiOCWbpz5KXcITP8z1HShZLuITIkKGIxTu/OgHelwf0prLBReeweoah4LL0zRbiUDHKkZs1up7z9wG/0z2aCpnZsDbXHvXNV5KB0B/X+jZuzdQkT/utq/z0Zj1fuTIcx85zjHCBHp/nAlRFMJ5luQ/pI3oluDwpeP+lfdOfhHOR++IcN/BsFN6Bz6n5+hoGCDHewwS2BGBFQN1I6U8ad8Sv87J4U4EyR3uNpWXg0JaYd5pQibqEzuzMUnVKNDGO5iebjSggeEcXgGDDXW6Ta9jfvtZRbvVKYq/Y3BclGHtv1qIO+37qZloUUrIlPKxtjINtzDYLE/+bXia5KklzAO8EGXPonytBkthnS6137INR3qNGgjc/PDFeWI7xLvu5mseZZzkzYZG79QEItbhp6ZC8vlJQ5QQyZdRV3lZOBADCleTJIGVLBmF4puCOZma/t1sjaagHj/E2mBVt8c4XkDNhNq7swYIFxWy3lFG4QDzfqBZz0n7z07Qc3T4XtKmV9p9itsMEHhv9d9HcyFNCeQHbaPWspUyvwnUBa5Qn8qEx3jRpFd8XaLmCOxO391gJgGXuxFKScR1bThcSy3G/0smQZIu3W/CWXKHzsprj3i6SOwIuhfjIyOU/uu+SOzoz+QRcnhtS32FucD/oOXII3nQewG18/rEl53Py8jlIlUIwvOE732wSFdMI41mOc4mH8dDaxrb2NF0RFLJJyVIhpt0Yl6DAwHKmEsosnhfu95S7DYFex3jbBG/mNVWLrOauxIx0P+C7+4xk0TauFRJcIngiPx90MO8gfd4aGbshlECi1yXhzLXvUX5u+fJqUL3k6Cvb1asf9Dkz3kvgChnKq8D5CvHteSGVeD0NbbI9X/qcDlNa51wRCR5HJ/7fSBbeY5+sjMGG5+dRqTJhCZKADu5D+YDue614UXMXguA9TGBLSGXDcVfPtLfV7z6cygW1uDTTdZ6VXHJfNb4n8dbJBoXkaoLRzjg8Y+L2ZFzGqQiiuPK0HQM5wmUe8HLuApY0m0Mxjt6plT2/OikRD0CwwCFQuLELEn5tu5j/1KKaJdzmtWWyDqJrPp86oM7/Z0dFgrKtTiiV52rhak6BGljU+kqxrKbFG7Xv2Y5Emf0jl3Uq1NpczfHvvGzWCC6UUcVQypBnnyu7lMvWbeldgzfAj85NE20hqKUe5i+PuTeEZqZITOLiLG7teFtzk58nC/fasNFjnHvqYp9XPq1N8Ojh9NgVapShC8l7jLLAFgFPmmh/JlVm4b4m2bTJu6axsmip4u8WBW/qXgkJEm8+cazafj2TQcccBxATvu+WI8RqC9jGNidPtzLNoAiWQkHoGHVfLYo6dPlfZpF6b8UMv07/zkIfUDmFyamktvJeKxUQteBtsXhj8jm+vrgwx+HKaK6fGf9MrPZEof6j745whmXQMnKmqzkZn47xNm/EMfC54a7mdEw80Rb/mRmXZGGzJB3D+OPlF03Xh75KKN0qJZyk/BTMmxRyFz/e6HPKj5UrdjUXnX4ca/u+F7vV14Wa7ugiLOGsvVPloy+4IjWjCCFnl9Fn8s5R4eB0Nc9RbOXR8g++SPOFePNQJaVuf6pbPfN2b8YQBWeZ5GqOJXiTfteltJPCmCJPr5xMEkHh/Z+y56hMDh5XSJprbyb3D0ThSb/ea5TxPiA3DvSZJ7jMqw40pyEI3sMEVBDxwUOvZAVQXJtodbbR3EhQyrp62AAlFKA2sr43h1Chds5WPzDK3m4yZnxjJXVSDWtm5HLy5icePqx4j+Hezrhc9qzCFm+Mz2SMQKLUQJfenHYWm98uefz1qDG58dkcMFZgVneNs0/Sd1G0rFZW4JOtFnoKibXZx2pE3QExKQfE9UIsNY/3dPXNaDsR/v1dvypByaPkjhGT5rB4w7vRc8Ysl3RZ8tu4BcAFfCYIMkBjyrScWEwnqLXSVX4GvU78XM3L6j0SWoCY3DaQqeUuwQwViP74ckZ0L+0hWAlsFm9UjIBlwGf/8BAd2y3I1BnzVqwqoPFu8F1aLdcO5aBvSTZ635E7enrUCJYGUA5pSxpZf6991JdkTweMigVvLjRpywXGNZOvvvG1xkyegI8nRxP6l6PGqiXmj2oxZ5YmuUUKr6LVE4pYvCmdA88LSCBFy1y5SoBRGH0RrGKw/fY4J1JO2eKHXc9BSyMqMiQXaf2cfouFz5HV3KcGsC3eGNoD5QsIozYBiIYm0PVrupqn5SZ5nzJ9ZXvRCFMTFAPRB/K4pHJiNr5H8y4WZWGZVXJ4nsTS0naxH29/Gk3Wy/+z83bIO/EQEAnoTVWRq7kQbgH0dMzIkrru2LHqSpZ8rUhW8zxwQVOK8ZbGVSqYhwHn0sIa5gI9Rnw9R/Uz4oc88mpP5kyVYrz/8+tx6syfjDbmBPsNIT0IeD6EnB34+7akT/pzsRPpr9xwbXM153AlYbW5qaffl3T/IOyGhkiViSKZ0mDfCgFzEoLgPUxAY59dcO2H9jhbKWRGBFBiSDWr1EKZl0gGAIkOvoiFI4mBoEBm3uZCSseZCpVmjC91a0RExA0OYrJRDeFG1iZz5ovGdmI2bih/APVNdV+UJ5Apwj8ZEy3FvUlx3Jy5oURr3RWadOmqasvS0XmWkJdEyvp3/JPI3aLFlAooOB9Y8oUC3vv/fTst9+GDbNKsyHpca/dyAyzGW8pqfu7NqQUfhRJpnoEZ1mXt2Hp3WryVnERJ7Gp8Lwitl9zRYYShpPkY0gec/Nd2a1u8TBsdA2DbdZoNwXtCnAPAaIMwTLSeMweuk4+/6hcTo+FHUSbYdDJ+t1+qQUfFiBa8efuWZ34yOc2ebFPe9EvZ4D0TPVLguFKaKV/nUnZS63EesA3wAPC6XqBfDYLFG1wuae4JtHhnqiIk5a+yfcbKC4hFJkQfGKWgHAoIGyMIMZO2WuFUqeP2Nsi6hxbNal6WzgjSZ6mtPDKoXTNBmZaMxWbxjn5yepsKpMkpZnyf740St2P5HMaEa5tPL30nbn7C/NumiDYTU5rCC7fi5SVZ0/NosQTarOP0a8nt/4k3U2H6zyQZJqVlaElFLwjp+VxIdClgYf89+lqvev7d3gLlxPCsyk4O9nWtZRvVRqs0mWWgaiQY3XfWeHXTCWnpRt2+FrzSB+hwFSaIc3qNCmSfGO+iBgkEKgvzvEApkHaULVnNu3rNuQePG1D+3XLiuMQrCL8eHYf0SGX8/nJ/vMZy+sXXjysfDYXrvMvjGxHSGpN4N9EDZQ5HELyHCYBJ5MkSiuLBl3vURis3JhZvrg2lglIRQgmuicAAQ0xrta7mNJaduo1hf5aYv060miLjQgVVuhklzW8iDBKtIt/AaH2hpc2KgNcMTgmq/DzuRu+bwKaasnR5ruY2N1zvGG+JKSXXUgt28k50VnMzYzkIoP4eB+xnbGGQ4r3yErcVBfLh6A6LFj6bC+9RV7bb3UmpezxZC9TiIs2J7/alTMWrH/ZZXM3Taz78MrYqS5azONaWQ3L/vPXxbvXZ1OzEU7rjcjXHLODQRmb8hAZxi/cyi6RrrSsOXwHGxWdd/fuZbrXpL6cl9NO2L5Ia1IbgrQojEcQSZsd/s6O4heVXCj23QALJ1PofC6g6aabbhTURvLmbcGwZg38ZCygTjiGJ1pPnTzA+40803Ivjd8bXLcSLYn9sY9R980z+pZ+B55PQLHgb0TI/UlUO3NuQYAiSwoHlh9cLjp4b7ytLvzAmOInxZgJKrsU7h77nnU22dhBAz3Bv8ra3WjsV3AxFK7vuZ1uNEPsk7edLD47cmiEDNKWlZcu7ttEEidG3uROjUsbwUIrLiU2eMaAeez22bBJS+JsbZontooJaStbJBSI/i3fU8FnkeVKbxjglLwTypTRnNoVPJQDvlgksKzb38IKxS3wg7bOfxdu8pqhwR71sfGkwd9E2Xc3lrOaAcaPq1CJxpu+O2MCGuTQA/L28Esef04/BqEH7zX8vUrGhyHlna6teUATaBO+Q1XwIAIfH448/rv7+97+rZ599Vs0LACu1dPgWwZS2AV0LEw87W/ZE/Bvgw+stOL5eM8C7njk9l+FH7bqNkQFmg2e0pS5yYOGQYtLwgOKZzl2EgMYd22qiokBvix2zAS/jiWm4y6Ntvmy1gDlDW6pBWbq85GqVxnhL6ymNBaWHgvkeeSkpPECo9t8X6OqPcWZSfG4e0X7gN+PVUiQ5jg0JUxI/66sZAzrLJ8ZaXXZI6n5Hgd4i1uRZMeOGpXLws2SMfFYKuJrTezF5SdR+WQuYeu1LMerkd3SzlbwpACRVQwLJrTJ6rvJKrkYZFCm8GT8CJpXGV9NL0dMAaIrPvsb64khLbPsCBUpaQsuV5dUG3BdJQjtrVvPMnfoeYOwLWbyLdzFzM9BR6Cdl+OcbUzIyuKP7ILd4Y5x2ZPE2e8OFDWBCKQMuCUO0BfQ+4VMFTCpN1MeRKoGtl2TalSxsiBuOH6d2kxhc4YyANQ7vbv0VZY173nuFPkMIGITqoLAn0YWEJrM553SRP87b4k2UeYBVv96YKRPJ99/xu41Ub/wxLoFnl7szcaxpeFp2cpZbNFpEH381YFr3mTKWC1x+ydXcruY8NAj+Ac+093mR66/tCKJ82U83H2EVAG0xu5gdWkJiTLA9O8dNXfJskNoqEvpUCbjgBUNeb4VGdXl83kq8rI/LNE3uWwnSde9fxxt5WxryRRUvQNfzPBDRsxUrnEjAtUTD4A7cJl5f5DpUAj79Fsacx/vVQQ9P2WOkUXWEgy9JSZAG8KNf7yPBq46HbcwNGHYW766uLrX55purnXbaSf3jH/9QW2yxhdptt91Uvyuaf26xeFcpeAPxAzdC2LwgbFJhlGZApBpaH4YULZKvfRS5YbruSQ/akt3iHX9H6wciodSWOCGzMgpldhd2u/qWErNMfc64XWR6vQVvJmxwrSkVcCQkJdXYO88s81L1ZelQULCOreCY+W3U1S6JV80RIrSreXyNwRizZ3Dtd9oX0xpUsiTS0c/MYQoWmy9b+siFUnxA8bwMeQe4nJwnWqfQbxDksH61YckoVRHjTbM1w+9EMaRjrMF1WOgXXbbzxRmngWkQGQz+Ehyg+8+VcZoK05KrOT4L1jYKXboLpazgDXNaKtA3tHjnMUCUXkO4SqVIExLK30s095PJA2r9I6dWZvEuIKhnrIVg8WZZjEePqFNjR2b3AX+3yEBL48lN5CUI3nwtSZjV5WfxxncJNYSzF/HnxuvDMpGpoJJ2kCoVabiHKz407z1xQ7Et+6/kQYZ9coEmNxWfj+1Q/qNRqU1WTTOa25RYQAuRdo4naycPLqGZzoepeMX35Wfxliy4Vr7H5mou0SwBsEZKzHVYylmBfASyP0j/XecA3X/grYhxxW5Xc3fSUjXIFm8JPHcBvosNV44UPK4178pqnq6lUmUWb9IfX+GdlvPUf5NSZEiD8vY9etbhuSwB+GTwHgUcuWOrOmZnM4kvn6c9fztDn7kJ/+boxO6bjFArLZGfh4c/g6POZvFmn9tyV8zJGHaC97nnnqteffVV9eKLL6rbbrtNPfnkk+rOO+9UV199tZqbAcRWcjEqAli0eFjC7+jmBJhvbJ2huZRcimygl1DNvYQ8/YiUvZ0yVbDxpRg6JPqHbN9qsZ5lnwVfT5rWr+dWikcrESKepx22Ct4sUUviIpxDKGzMqS08wBeZGqbU4m3Z7UVjRPnfNGdAnseDElzNjXg/8ox//HKs+uOhds2q7nsSux+HUAiuUi6rQHpN7iXErT3icHlehkpixTjzjMI5LwXI+8GT/3z7G7LVjN47vX0guU8nqImVH6IrO2k+uccS4029PhYU3O1t3gSwZ20KD8p8ijHeJbmON+0feOokFm/H+BC4dpCGlXKUi9Ti/R1SF5mCejHkrT3bnvnrA13WvkRu28WoRCEahwra+DNg/Hm9YVBAUYUodkdKrmYTvPPOPqoEkAVv05JEXc1d5dNwzvH50+MkohySe2Ze6A5eh2WHEldzXGc5bp3JHJX8rJLW5GqWGO+MxZs9J4+e8fAt6lmGz/PJLv3bfUera46M6HzeUkYhKe86KeEj3pPGltoVJ9I8inI3C3HCz3j/XIlucf9Cv4AeSxUSUk+ueG3Fu4HyC/tuYbrlo7s93HLNfZ26pKHZZvY5El9Iz1hp3jU9GETBiL8PVFZxjwua5wENMS7eBoXLShOxwnM/n9qv/vNsjzUbPQf2kYYKJK7m9e5zAMe79nKN6tmLJqgxrcQjyOiXGRK6/9atat8tW5OLjLm0xHhXGvdeRPCuZy9H5+cRDEfIp89NGHaC93XXXact3AsuuKD+e9lll1Vbb721/nzuj/Gu3GrCM4HDBnr3s35ZQx2XdNGf+Qje1FXYEufpk+2wvXNATCLHXZal5GowOtiQm62exob5uJr/55mepPZi5iZ8PjmkCvKwmYQt3OJtQ8kieKO1DQGltor0S4zxbvBk8HKQuUyw7KQaU7kNvDIS+qKL6Lqnt0EJC1AYuTpj8zSgY7JZBTZdtUlnDaX3u0Ctf1rIZ9rZSncvzl9U4zf+jCZX82AMfeIxwWNlclsqeGvlR336TLNP2YMT9pjN3RJ/Sr0wrE+0DJXD1Xzx+Uh5Hq4ZJ8/BTLDJs0hz26zdpP579nj9DJ81jm6AecKClFzNJvz+59fjc63hOCd5Fsb0WeTeAnW8pfvzrkvXJrF4xyXwbH1IBO+G1DUR6wCDECrVvW2qxOJtrKWshxHQQihT6Zr/hH67YryZJTkvq3nyeXzdjqdPjz4X3NulePdMO7a+G+E8dk8YfFc07ll3j00oPg+VZ3nrivITAHgM3avQvyRfgmMw4NX0rRWbCln5RTpEPjNivNn7ynMxjuYxnZs3Pu5T1/23SyRuIr0TPrTxA9zjAfgBV9gcP+/oK6SKQN0WMQokFSHIDW6X9rRT9JlW5cMgSt7c9R/GAH3ia4AafRL+1pVcrYCXmw3otUmrdbjAPQKptRy9flxWegB8TYVuDps3q9SsoeAvEONdBLZ8ICX2jIinglDUrOQdBO9BRG9vr3rrrbfUyiuvbHy+yiqraCu4Dd3d3aqtrc34NyfGePu4u9r2JK7thNjqrMtlsQQHdY3yE7zNpEeue1zZDk/52ywxThSa2/07UVwcbDzOKGx54jT10vt9kWXaklzNVgaJP+vXpL41RWGLt+VnJsbbMh1IXLngwT0G3mHKk0pivNHyZCPoFVu8iWWHx3hbs+WjdppkmqfWrqKKDzrvkatSvHbI8208AcRnY53ewm5mscXbSEJTwWGlM5QTJRjOCbXSSxZvrkW20Y4Sc7tFoGcJrPs8izeuSZuQ4GKGeVtUSQMu4jZX81W+li4Kbq/G0oIo3Nniq4HZX2Ri9AAf4RTfQ56reVK/vUoPJURejHce3fdmkgrvrbSMSyo0RooaXi5PKh+ItG1MHKf7vy/61WOv94rJiPLmUhq/WQkjtniT7zvjBH2uGG+kUzAuqCd+/XFj3R2hTL1NcLOchyh8rrpUNNg1l2lMqnWIfcN9Zes7pT2qJMYmF7F44zqcODo+L/IEb6701GFkWSGyErqY98z1V8p6mNDH1HvU8ba7mpeMdXTgxW2adlqPNEmZL0kVlnuNfusKL2Xv5GpUSOdnAs0A391j99zI62f6nmX6H5VfU4MGTm/QS4ArIei8oQHIafEuyPNxwHPBowbgCmehQP4E3w0VNJEG+tAV15dZSsj6TQ0lxtlcG4s3X1c2i/eTJNM/7Q9/Z7YQmjkZw8ri3d7ergYGBtS4cWY5gQkTJqgZM6J6lxLOOussNXbs2OTf4osvruY0ALPnE+NtExASTRWxeCNR5owHapYqEbz136oyV/MpMwfEeuXQ51P2HKXO+PGoxAWWMgrvx/WAIy2n/HRXVnOKLdZsVgfHpbz0NbHGOYnx9uRiE5csktyL9iMvqzlPMJcXq8iHjcyRX4y33Iat7Ypczcnz80ojAbp7ykneAbruCys+qKs5uFgJYQo+rk5FBG906YTnSZa+oqCPxjaMuGXJIuNp8XYJw6j8kK8hlkNi0ZK2BxUQ8rTqWYu33D+pfQr8KMpqbldS2GKIXS65icXb0h9UaHq7eOdchtY1yT02acIQslLk5dzIa8t9YdZ6Au8L1gzdU7AuqLUeFSWoUAPPCopyJRZv4Z3lhRrN8mCKacww1BNffWlZoOOurniPC2VWGipVUJXUiovX58aH5r0nQ5kUl7CSBKDdzpohKna4dXz6rOiDiXFeDd+cFTR8hdJduB8UD0WsZ3mXQltvXzGf2mz1ZqE/lrlhwkSexRs+B0+zL6cPGOvHpnSkimf8jF8quXVL+5cnLqTXSX2gtI/fR13Noayebsfok/JCcs47PJoGV/A2s/XrfhBeEBWlQAOQ5nhlNWeKmKLKd9gvmGHcd42nSjDcOzS5Wvq+ROQo4hAw9ojGmldK+VmMMrzlwbF4c9pcsrXtymo+l6U1H1aC94gRkUA0a5ZZ/mDmzJnJdxKOO+44LZjjv48//ljNkVnNqygnhkQDGXBYp2iZwSyzhoY6YR7yd1iW8S9V5GqukzcI1g5sDTYcZCTd9uRp0d8Ol3QNyniJCUnkftBDTP+qY7xLiTu8D7KuvukY+SEhgY6ZwiceGfueV64t7ZvbglGx4E1+R1ezk/9mL52lr4uH19lTTmr0NtbI4k2tujSZoG1KTZddf8KOgm+Ur6CU2/evuzKmE/dQuB+bo+7TksLDtv6E5jOAZGNfTI+VYDZXc0NYLidKNXGIyMBYk4PJcwvKBVsd77wkLEiDYO1Iwg2HjzcRvgdbJubBKk+HcqnVS8R17yBmNTeE/fh3oC1aOKCu5nodZa9FusPnS1IW+Fi8+R6lYTmJoopcgrSgNVvdK0G9p6u5hDyBOQrpsnhixeNxKU5Sy6x8AQ9z0X87yJiYpJBg2szoRU2IkzbllbeTSlvRW+D9w3spJHjnCvt+7UgCZppczS5I43WQvHDDo6bqvzFHgHS5VsowGodu/0Z/PN8LlojLjCexeJeMv6ngnVHGEosuhtpJCiT0wNDfi/1LJW9bglCkncvtOzmTxK1acEUzzTWy0hL16ok3ogMA5g3PE58Y7yRBa4VC5sF/mJko93yRcTUvEOPtgsGL4XvO4cH0M4nCkxrkKjmLpPYBvkJz2aKI5B4ocwOGleDd0tKiFllkEfXBBx8Yn8PfSy+9tPW+5uZmNWbMGOPf3JrVPM/VHA9jyhihxTuln5EA7GrP+cwKXc0hYZKO8Y7vX3NZ9K0xn4P1d/NiHumTJFdzm1sVTd6G1hckhB98UUzwTmMES5pwwhhz3bkcLj15ygKESyjgbeaVE/M33MkXXvqvTvVpHIv+/uf9ue6d+I5HxEYLw+JdUAlAxwRTBAIlYP5xpdwYI+PeApQdFTbctdKmxNp2nWa19nKyZFFijCG+uzxhkg/JJrhI944fVadd5PqSrObZayRrot43wrV03NIM2PYDWI59LN7itBIrgZFczbJGOSMhvW+cU3SPtQk8lMZBXOX8Y92LljZz1vXt2efmeInoNiyfR14XfpumaBI23T77G56l63ijAq27rL6aUTbCGEpsTfJQAEn5mpejIKpRbX6GruT6GbEAUmbKbIDrXEWPmVzrteC1YZ3OVE4xhChTwIpCTFxZzfM0JXTKcL1y5YQpEJacNATPXbTw5s0JCghIH/hahO/1d5Xz8Bk4BSnye5ckEDEli9UDjK1NtKK6qlLwp/FLfWO8ecWAbOx1/Ddb49I5R+kJnifSOsayXPx7RGIRzkmuBsk7AU/FpalqBW1Rp3W8SZ8g0RjmMgK6jDQnKSfmI+GQ8RUFupr7klbsFwrZNKs5CsF5ruZ5z4I9p/Mt8PuF+0Yxb6BaWLzRlX2x+erU1xesV6sxL6KS7b7Y4s7fmWRomNMxrARvwLbbbqtuvvlm1RebMMH6fccdd+jP52ZUm9Wcx3jTrMCJ4E2WfLHkauxvx7UuaxAwR9Qi+5PvjTDay5QRyJQVsDPPea7mouAdb2iqsfVFWegjJAkDIcB4ruV+PCR9CQplMiUm4LHXetRHX/ZHGYYZ1czLam4TVvh7t3kgPPBST5INeIdvNauVl6jPJAqEz+l4waKLDHGRUl7ZPprPgdrawDiOaqnLL2fBhHbvZ8Y3cCWHbV9EdT7toB4YKCDmWbw5kwWa/r8fO1b961QzTAdL1GQZGSiHFiucJMGb9j8Jn5DdRlMXWg9Xcyp4k1ruLpScGnsIYbHPlQ1yLGw5Fbw9XeeeumCiuu/MCX4PVUpddW+XtT2XpUOyPrsyzbtQxENeUvjBK8M1AXHbgBfeTZlt6pZOlcAHbTtCrb50g1j3tiXH2yvxTiIAr5lscrViLuFUcWp9Nvs7ofA5DHKUc8IcQ/LcWFhxuZrneaNxbxseC2srTYXg16IHQVPOeYHg4VWcHsL3vTV2Nfe9GRJJZs7qeD59yolRoBVV8tyJ1mXkuZA8TxB6fBXq4IHEQzOkGG/Yfx9/1W9k0+Y8TJowtpRavAUFIniH3XZynGRU6KPhKSkA1x2GBIKwVUsgnyYpK+Dd4Dh0zpJ6/3JitVhzVOGIgAz9N1hyRaSlI6OnUtdqVBpUm1F87UOnqF9fN8sZZoagnkqUXtUiqzmsq7vPGG8tCcuBz88zBMwNqFF6mNrhpJNOUuuss47aZptt1JZbbqluvPFGNXr0aHX44YeruRnVZjXnLiJoAQBgbeAEREPrcyj6aM7yYpSjPkbMLY+Lxr95s1IdWBtE4crC8Kfa48iFBZqVSng4IfBeoDgBRsfQzlqaxRqMrrhFirb4gF1/xUa14hIN6s6nu43v9z6/Tc03pqTWX7EpE7KQJleT2/ZNGgPJyPLeB7x/TGhFsccmLerWJ7qNrOZSLXNfqxwV9tIOKx2XtwDLhJ4XZ++6xvZsTK5mxHjbzhdt4bMrNxLvE/IuTCsuu8cS6rDmslnpZb0VGtXV95nCHvQ5ssZFSpq8Ot7IB+ZmNfdYR0Us3hfsP1orIDJeIdSqygR3XwoqCd7U1dzFeFAal+fZ4dOnJCFgBfxqRXW8C67zfzzUqV1v8TPoJ85BEsdN55MwxTT8CBVtojthzkHE1zwwsB3dfp5W7gRLbiuTS4mbW8e7rNT9L/aI/ejrK6u7nu1Wo1vrHApRN8zkatF/Axb38SJJkPBd5PEGcJ2O444fyksB4ToppBjKfaYqDG7Fc9UClz5HgUhWYmQ9MeBvDO/LU/5mYrwtruZp0tD4PqXUd4+LQvJsYX6JqzmJ8aYLOanvXqfUiovbk4zSsnEi/Y9jsD+ZHBGFV+LyeYPlaq7PU6LcQ1oUGa80pShkua00xhuAMd4UmKHfHVakMnsGDRB2umKnVZRvQiWkj8GM5mT69jFT1cUHjqne4l1Wuob4TzYbUew+JY8fDCk8R8ucjmFn8V5sscXUCy+8oDbeeGP15ptvqh133FE988wzmYRrcxt6Ica7CjUIJpVKLN6UOWTJQWgykIos3hXuAbiNWrwTpif+npc7yYvxlspYUYAQhq5AayydTq4R/xMfJtS11we8zE5i8YYYb/NCA2NbS+riA0cXJiTtseB99ZFj1bG7jBSJaGe3HLKQupq7GUWOw3dIa6YDmlm70m3dfWWjzBJ/Bq47HRcav//VyLtxzcph3zf7Qy26oFyCpqe2l9WEMWYrNm8GOu6ih245HoNhdbJcmxviRC3ecSPdfe79x8ckWY63WadJrbREg5yFdiBOrmar401+RwuMtq66lCCWGZCskEmMt4Pmbb12s/rB+i25dbylvuRBsl4hUwSMi6udWud5ScsnFiesUt3TWlq8Ab/6q5lzBctgAZDWUAbuoZd7DEYSv8P4VVf8obPPZN6hTBhF6u6sCnl1eZ9/gvKo5NHmLY93iZ+DRRb+ucqJ5blES3W8+Xmz52/tSWk5eBk9n1jTKN4/+n1a+4D+l3xXiqyRtUzUZKMxTsWfYjHektLW0Q6e1ZJyHpVT8G+NZVJiNn6U2YhNMQSfGsoKW6Iyxq/Rdb7AuFiJ78xqHtPw+L6HX+1JrLVU4beUkI/EcDUXugbfw77G9aNLrw2i4E1/j5Q75cQDBnldVAb57O9qyDnyl77gNEl7/8R/oOGtVjW0Mwr7kluJPK09DRmqds/ed9YEtctGcnKNkqVtG72+9OAx6uDtsrzfnIxhZ/EGQA3vE044Qc1LqCbGGwTJv9zfxWK8U4vX0TuNNIm2EKNcBNXsSeqOxhkL7nLMGVG87q0/TVQn/22WausYcMbxQu3K8//ZoRUaC02oF10QQUyGdgtbvFmfov5G8373c5EpJk+g0X97PnYmGautbXgxUsgCCmVFYwm/+XWzoYxALdwHCgxeT5Q+O1JLQMmU9P3vuUmLdo1y9hFcVbdrVVfd26naOlLX7RUWb1A3Hj9W/e6WjkRI5FZQm6BEFRFFhCnMDcDdolwWXxeTR+My8bo8V/NsVnO5fWREZIt39LvLtWvqzIFEyInq9JaqcjWncNXxNh/A+mbQDA+1voByjsW7lvr1TMhGSalF56uzVqSQQMsKGq7mBSzelbikZ1zN432DckTKQGYtb6hIRdocCexu92prXxjt/PM9nbLgXcAlHPuU+2xB8SN9zlFmjK30nqSa5slzC/ZLogsffeUfQ5UkFYz/9kmwBGcevu+zb4xoMBWKQLnmEpY58ubUHeOdfrnkAtSdyWw79bCTG+MK6iaHxRvXZZlVJcDEoVxxzsFLdCVx8VZX82yfl1m4XhsZeGLWxNUcYt5JjDfwEvte0KY2+WZ0UGOT9501Xi0YC/E2i7D0fnBfDxa4q7mmH3XE1XwgjetHD6RE2eex9ICfwHaLwlbK0gZ8j3+7v0vNP6YuLv/KLd7yvUUViD4eaDw3Ev5dTXK1StE/CBnVhyuGncV7XgRovWED+9SFlYjDk2/0qgtviw69NMYluvBXu49Uyy5qNsxjz/KQm13cE0CcH3+jV738vz6xjiJ3tedMUcrglzJz8d/YyjJupF0wQCSuXBjjrcwETT6Q3A1hnqBO7ZF/SjN7S4I23LLhyo3q299oVEsuUF/I1TwZk3ANKhC4Nb2hwtgh/gwuUEt9uO2JbvE5nMmhBw51k8pbW9LXqy4VdQzdv7PvuzbJ1VJLV5TEiGeQt7rs5xwmNNEhtod1V6PPmQJKcG+UBG+4ZkxrnXrk3PFq+cXqM4oDYLRtdbxx4f7prlTAAaWGzeIR9UsGdxE2Y7wtNxntmy3TGEpOM31JE10S6ElBY7xrZXWw1RWmsfcoxLrKiWECoarqeBe1eFvqp1IrJ77b3TZuyVj7kF5giS5g5mCOnQnFrJ0x19HFt3eI8clSWIMrztN37qRKFVYGmVwILuXps0qyx0JOQ7YuUiEMLd7VeGOgYJkIqB5zo9+pxZqLQqRXgqsYeUK677qB0nA277TcGG/S32fe7k3OU6oMzfSHhRNxukbzUFAg/0HfqZQFmq85us6XXrheLOVKy4hi38tEWARhPSonGTW6xPz1orea0Vfha/RkGayKT7hvcAw6XDH+jCoqtMUbBW8PZSbg59uOUGf9ZFTFfSviOUr7BbkxDr1spqGETKrP1EjwLPkY7fqr96DiWGExtyDzzqeWsywR+tVcj3lgiMMfSAgrreNNDwQkSElWR8EiR13NfRZ5th5gdePkgneSoTgnpjsT00bw+zsiAeGPh2Yz2nNCkhwQOA8lpdZdoVgtNykJBVjojXcRCziIyTMGEmsdCER/OmxsRtlgO7u4xlzUcMaxwdkY77g/FTC7FLyvtsPmnucc5UTiYWAN6ZxHZr9PlC/y55IgYmMIKENYrsASmEmuZum8KwFWyfDASOOtqQdGZp6EzLeueVtwXH3GqpLEqNeXnJ4ZE2IhauEJdWLGfNc7QQaUZ6RFgDXMx+KdWbfU1ZyHP3iucbomvv2NJmbxrq3WHZri7+t1kvwpZTiKPzRKeOd3H15VzdBQOYTjAa8iwApxXWpayg+ECKi5jLkHEot3BbTIpgRASFbCPJfwamOGrcnVyDlL+yUyvs7kavb79PeCqzl3Ny6CHTdoNvLB+HgDaC8vyzPh/RdOrpaneC1o9VOCd19uVnPy+x7nzEjOT5pBnLdP1zT8nVdpABU5Uow3WnCBX9jn/BlaQcq9YqgiaNH56sV69VTBgEoVyo+AFdxn/dN9J40KafxgWb1xfrY4IYpph7GgUg+ejYofU/D2E+IO32GkWnf5WHGvBh9cqUJ5A9c5qj/P4f38PmRhZGzQtjO+CPJyVX30lSx4B4t3wJACE6F5Cd7CZ9QFypXVkShnE/dWHzewzEavkHPjCUL44cQttZKbo7VPMaQERZwxxQMCD0z4mmrIKwUQLPooavGGbNvrHzlVC9Cu6bNZXjljaRs/HNqZhFPxxZV6KiC4NrxIe5QZ5Zk9zQvzGrJ/hQqlTDIun6zmBU7dElnPvKSP9R4Hk0615pKrueRNnak7LgnPZUcpIxC8PcqJwbqDTNQTx0SCtzSM5H7B1RyYVurOlimD5mXxNv9+9PUeu8Xbc03SNZGE5xiu5vaGzv/ZaHUEy39QDVwJKSXQnhXJal7J/pf2hbbKxV/sfvaMjFDiSmYIjB7MfWG395w9KpUT81Eu49mQ1x3ThT3tk62veB1NeCXtM1veBN1OTqeMGO+YzmfoQgFstnqzevGS+YhLdv492vvBJnhjcjVVOzhprOVzXjo1z+Jts9BLnlNcaAaUPegaZAA/+a/t2XJiRFF513Pd6pHXerUrNLd4066AK/wVh49RR/wgCilEoFIzOhdxf6RCPJwxLi8bBC4pW24G2ENA44tYvBeZ4C/d4Zg/i0uWauNCzCvCGJF+Qjm8jMXbh9BUsUClXCEu8DmioULp+izVLFQoD9xbpRYW7zw0sjN7u3UjbV+REsdzOoLFexgABWduqZQg7XN0szOZyFjjZxMMmBbYBZt1UYKrlAR3/0kO9rgvea72hmBuqe3nI8wlpbyY22oRSDHy3G0XLYsYK5t0J0d4lGBzl+aQLMn4uMIEtVzc1RwguQ8ngneOG5ivq7mkC8K2+ThtCY9NwbuY5J1avEu5fXfFcUbPTu+X6nhzZRJc98J7fRXrK3Bd6szy9ULsPunTfS/2aMZPJ9CxJR1DTb1lz1LB0sdF3tl57f6pA0c1ZsbxeZZLrTAS9NSZn+nkao6TcZt1mtWB2/oL3rmxwFWYWv7xUJeXZbJIf+h1Gf1ObPHmyoIFx9eprwuJmSiwRjEqO4v22TVPSX/INbRagKvd/GfLCmHrvUTJSJNqSe9Jnz+W95ebVZyd7XleAb5IXc3zJwe8vCCb9ZNv9mSqXuiyc47xic9WVcR42yx8yfuKLsizRvOvZ8wqWxVkqBDilus8T55L7uhUf3+oK7MXoj0iuJqT+Ff+noGGbrxKU8biTY0wiTWahBlCpQKepNApeOdYvIusvgfPHu99LecTaB4bVOahxXtEc3HrKZS7+tqCdWrjVYobX4ruN+4VQD30fPk00eJdwIZhxHizNf30272D7urdwPbG7/YbrTZapZFkop/7Je8geA8DYHyxj8WbYrl9JycumzwhWZIh0HLYV6Ndct1y80lj1ZPnT/ASVjnDyy21nKj5xMCLMUgludwD1lGtxhLEtdUlocwGdx2uhKzwJB424gsaTFsZtqKCNz//fS3eDY51TNdeNa7mts+lWtM+dbyLuMlRV3M6BsjiK0GywtvmGfuUlH8R+g+Peen9YiVbaFK0RPDujzLLS8nw8OlQGua9z/sj92KWCChpm/Sdfw2Wn36n4J2/KEVdWsk+Nz6g/Ujbij60WfYHC9UI3pCJtnA1DF/BW6DBJUsyJXAvxxrytuFoTwttGZPX0bG7tKpLDx4t38sE7/22NEvVIANJldDJ9Y7x+iot5Nhx+Vo6tlxXcx2vamsnR0BkFu864b2AQqQobn+yu5DF+9ybO9SPzm3TpSx/sllLRmFYZC9V42rui8RqbKH5nKZMjTO1S4m08CyAf0jLdO6PHIUintFc8a/rePPnzxxQNz8WZwqPaSxdjzZFQlrzO7VGR15+xQhO2SPGG5S4fD5ttaz1MEpyiJMEPjxaepfSBUiuNjJj8c5vH/jue86YoBYmCXiLwndZ8nerK6Mwj0SboqrapU+9Dm0l6LQid5AF3wYL35cmdlNzPeaBIc5BFu8Kc8xLmVPxM5vFu1xI4+/+m2JUS53WILr6OSrWzHK3qTyLPxXMJaYQP+fgxHfbdZrVHw4a7RUDmAfuwpuxeMe/U1dMF0NlOxJ5Egyb4REIKRdmUpfLYiPlfclYvC3jkNzs6KWuQ9HX4m1zrY6EXDZ+i7eAtB98gCEEUWKk9HNJgAVoQaOgxZsq0976pD//3edMnMHc6ZI1Zb0fG6wWb2ZJdli8kyzBkqt5QxTnmbZbvas5HU+GNik/GJnk45//fTnapLUugZTXqaJytzTHgwFqZb7myCh3xiarNsVKmOy1UuInCowNj9yrs33eZ4tW9d3Vmh19SRuGs2Kd5dIDE9fYi8QThLvnVhJHrb/LuLCX/TwZwK23XHlW8zyYydWimtp87rda015T2IbPY5der3Jidaa7Pz2j0QhQZC/lKaF8w3mocMnbpC7hErCkEgJirWk4Q6bP8T/k34B+NHoK3jyfhN4j7Kw/6/pZ6rJ/RzlsQEjT4yznew0hH6DDO2hfC8Zi4/xBJYGHXskGusN7psI9YuzI2ogX/J2DizzONXyFz+3QFm9Ufvjt0aFWmkoWb24YybV4e1IMn7NRSuRXxEOlEpQsfF+R2utzOoLgPQyA1tCiFm+XNunu57uzgreicbbxZx6P5BuhSC9P2yuNO0KL0tk/jawaiYY4pl4ZizejCVQwt7keervhCJL7/luPMGpxFrV4c02enrf4OqNcWQ1czSkT1941kPRFcjUvomRx9cWV8ZTCxbDlxXhXa/Eu4mpOnw/WGl/gYc8TufH56ewuq+fe6Y2Tgckdpx+XBvHQMRVCUVZ07L/Pe9Wu5rY63sIzEMAgGa7mqrjF27WnM8xFBRZM3kaeq/nsYN6gZJ4NPp5AxnsqwLihkImJ0vbcdIT+/YtpJgeJLrB5grdOwgTJpyowLpUd2cDhnYHiq50ITZC1Gcdhg1dy0ZKNnlr2dDy/MA/fXa3JI6u5+/krLi6/YOO+eP6lGNJK4UOLwF2ZvgNqPMhLYiYhr7vVeKfxftnCi3htZqerObF4I/+mQ3jY5PEQPLy2C+prM8G7u6+cCPvc0i6FFNgEbzyHQZBHYZt6nNWKPtmymueFEfm+Sj6X2tU8PrMoHwdziTHeieGpbngJ3tuv1+yo7pLDPxVc+7bLaZelNT3Ygm+zwG9oxb5nJvq5AfPAEOeuGO+8jYSL9oaH47relLEnjJGPNYDfl/7tvzN/+O3UJRA31gJxrcj0APSM8XYI5nivr+ANTBBoxan71JE7jlT/+GXkLpkHSZjViVEsDD1NgMe7s/j8dWqz1d2CXya5GmkF3PyogG61eA+Z4G0XqMtkLBLz7etqKF2XCJOeydVoG+fsE5UUgTJvefh4cr966JUerUCgY+Xr95ybZqn/O3uGM6aVfg799olv8l3j1uRqMYM+Y9aAvk90NefManyPtIZc5cTAGquVFPHG4Bp/nxhvF71ZisUV+wqV7njhGtfxzuuLRxuLxZmLJWRqmef1x/NymEt0RaR76sX3I6vXO5/2MYEgFjgt7WE8pg7RKMpE6rCd9G8M80BBT3u6MGXs4ZfPjJ7rErw9J4O7mvtYXmGtP/BiGkQr9SMqf2hv7PmLJ6ht4+RD2b6TZyq34I01m4ugKAPMS1ni3i4Ss5kr5FUgefMmkWbbnsUt3jTpIgd0Z9K0AfXZlP6E/oOgC1UgKEaNKKndv0Pc8JNcHryOd0n99f4unYiVuocrFs5DP3vtw37nOEAYpW3VuuxXUuWgAm8mH5ihG2X1/uf9qjleZ5ESInowxKsnFu8KeZ6iKDqVB23XqlZaIp0YKdFkrcItMmVILfSHY3YIviXPnBxzC4LgPQwAGa+BaKMLdjVAoauj2xHjTYQRL1dz/neF3USmGw/kNAZJFlw4UaPf8y78+LsjNBMuWuQsZjod412lFp0yAjD1hts/0UwbMd7sefefNUGdv78c22jVTJI2Xv0AC7BG19mEmaKHEE/WYnOllpJPcVCljzPGO+/QiQeeWZPxT1jXvuXEjFJw9SX1yqUT1eWHZMvRcUByr+ntZaGcmPlgTKjnm3kamWef64qCh0DAwrzp0W7tOuhKrpZ1J5ek/vRn1g06+okCXNbi7df/E35oZuzFx6yxjLkoffeyi/ns6xtadzcfq4krDMnX4o0oMjSkzXSvzoxLG9IEgMZ8OS3eUVblwgnhMu7e0d6776zxTJkq3OtYFD79QKvmH//TofOx5LmH43d3Pt2dZGLGdhA7b4iZfN1hDaNG1Hn1PVLaZdcSzPWWazapyw+1e0zY2y+2CSA8hgpbiUKuwLvOy8runPeS315Hmj3gKXgnZQYFIQUf+dFXA6nFu7+sWuKSejQUgp6fb3zcZ3U1x/2VVl8pOy3etsSrq3wtIgzfWrExFbwrsNLmXZ+EkJQHJwSGzs8f7uzQ85MaqVKFHIQC4FmWltMd3mKcmdW85FQuJUYHx3fmh/IzuQKTY3YpK/pixZaPF9ycjiB4DwNAZt6xraWK6rjmwSgnJli8vRj9gho5G1D4xAOdx3jnWW6oKz4/fACLzVeX9I3WI7XFiKKLWDUwLd6QwbmccenlTKpsgY9+2vqzHqszXrIQZLk+dmXxThCr//jv0kR5vqEQ3/+WXfDOT3ySK3k7P4cEYFxj65NcDQCHdhFmgSdXswFm35pAScgYnQuH7Gu9hVygkzCRdSYK3szC4/I0cDEEKTMat8u4M19rbTaxn4U58WotHf/fjh6bGZNmhmt4Mubuuypp0DjfWMqidFsr8qLOiZ4OVOlEfre58MJZBHtGJxQreNbx0CIMKVlofL32GMI+FI1f9aWJH37Zr5OI3QaJxzwt3lyAo/O128YthcvB5SZXQ48DMlGSB5B3+wX7BcKlafGWlaROeLg122B7ji3G25ZcjbuaY9Inm6t5RskYX3fxgaMTPgSUErS+8bPv9CVzRvtN6b8kT4OiEuNhMZGYbdxAe1dZsiFOphk1VgnPk2chRz6HKwDylKp/OmyMOnLH/OoQdE7+90W/cR5QZRN124Yks0OiPEUrbYFn0UupF5l3jLfnszLGCfaBjU4XVYoWRVlSYEFJOocn5NyGIHgPA1TCiFBr+Ul/aXe6iPKNt+FRUxMiWcmhXyk9Q3drJMg0C6ho1WFjod9TRuypN3vUFXd3GnW0qbVWOjhobFZ1Fm/B5QqfQcqJYeZ6/bnQXqoUkYnhHw8d44wNRsB75cJMarWSB7pg7PovYb6xdYWtk3lLGdee6JKecy/GbU6dmZ0nzF2QqdtuFQRURTh6p1ZtTbC5XnPwWq0u+IZ+oLBBP8u7x6zDnP5tczWXLJoupdEX0wcyrt4pMxo98F/PmPVrfA9ZPi/Pv5tN8mPrH4LSBFwSE0ZnbwBG29dlvRbwyTJs7HfWtdWWLmbyLsK4IT3LL8GU32gS412JxVtrStO/aZgHJvECslc0Y7NXjDf5/YRr2p2KtKSvSqm/3N9lPqtUHW3IU6onLu50nrRFXX7AfGNy3mnBd6Qt3kKMdxE6myfk+Sg8AAbJd/BEEtZZ3iSIqeXZfR8qHdAyThXVYHSQFJy6zjn1miP0EHkBnqAPjQ54Hn/7G44wNUGhXzzG230D7mWumMizXG60SpPaf+t8wVt650lyNRJeUaaCdxUKpyKoRGdK3zdY6WlyUoCt36UahJ9RQLWSvP4NBgaE9QSPTARvw4tQzZUIgvdsxjNv96rn3u2rWMv0+kd9udmIEbRMACbvqCSmtNLNwDOtc5evPIuqzRq5VxzjDIyYJHhLd6EbuHY1LzoQGo/CBG96+ESMYBrLlfTHIbzYCDnVlvM26O+QiIULM9imjaDz0jzVxte5slDTxH6VlBNDTItLvEjt83FiwpXMsypcx3gfKBC89q1DQOfv0ccts+RZKoiuJfp4mJ+yh8WbrllXHDd+9m8mVANQCYT74o6n4hgY1m4e+LuSSvtI11HcT9ySaXJEyeJdy+RqeUP0skA5Gll6YT/thctrwXY9Zlime+pnW43IZHmm77Gck4SJh2h49YW1S9tIXDXZuvZtt6jiStP+KhnCREgWQmN8YTCorE2Eq/07Tx2vHviNvZ5yUZ4km9U87lstBW9VHFwZgwob27P22nSEl8eU7k8pKwyCtRU7i88ApUSzoB/TdJEpRTloP0HJpK+IQ7YuOWi02mBld34YGt5VicU773Kb4F2rGG+JViCvaOxLotCrxpNkKAHGqMXniz124s9yeYUKz0x+270vyEXcB9tTYMCyoFA5j+/wh99uUWf/NMq9M7chCN6zGXucMyOqnVfhm+CbKxPPRL5vIIS/Ow0LLixwVUvQeIw3/9ya1dwR4x31M40BRjcsG6q1eNN2qIaXlk6iAg4k/nD1PUlM5HkolhyMsm0ebeP0jampxmpLwxxc2SuLCAUcZUtW88sOHqP+fEQ2druq0I6yUm9/0q8mt9lfmGSBylxD+xOXBMoDuLB+/NWAkUU/rxQh98ygZURsMd7opXHtMak7tvTOeHZlCu5+yeH7BmrBDNA20uQ7QDHMxnncZa2w0wbNOqSIw0/utnfIe/96XcWsEIKSbMkF6rMJI23WRp6gD7OaFz3vuKs5aQPfFTDj1YYO2Z5Noc+MCpqRanpXY/E2QMu5eWZNh1AiV9K+ov0CZRi1eKMQWaSdPOW709Xccqu1nJjnWkFacZlQY57uS9yH+J61sojGH7O47+ha0yXaoFGCpR36HvEuUa6B/NJTcelLInjnxdFX6v5PeZ8iHnJ5kOpK45lF5zgKq8B3MDSu5o++JnteOcHO4iVieoqf5yklfYdluw7na6UlGoaN4F0iWc3Rg+m0vUapHb6VJiScm1Bh5eiAWqPSxc5vKzsTSKW/F0ndn40NUVUBD2TOL2bqL7P7DBdqIZFM5OpdJklp+u1uOMk4zKyi/sjGPsLvz8WxW/h3EuMNZUPowz1x66/GibFoksW7hFnNLfNYLUH1nifHdSgcS+XXijwjU+Iunmt4/Y2s3YUm1Ot/eW34Avv4+BvuQzdlrrNx57brfRIaQSIfABVe9vqu22uBuo/p0mBkOUpJHR96uUc9/npvkjsB+1+05CFNOCR3zK+dahQyCPoOkPnkscNS3GW1wD6tvGSDjhXG+E5EYSttaWhi8pCe8GekFi7Zi8c2HFjbkINBh1YVnGCaqFI/gyjY8NkQMjHLouCxwUvpEWeSRmimvgIB0AhDilusxuLNzwApT4hWUFTYfvHkamaMNy+T5AOseGJDqYLvfJKrbb12k1p0Yr1TabapVGNeOIdpJQAM14lKrWV7qEsXGsr7bL8HuOANCcVi78Y8LzSq8K44uRqETdwX1RGXgAoHsOpT1CpnkeR9RF3NIwNK2eApqtlXgw3arYXG1yXrwhXORe+z8bOZzwQeSVFFxUDklcC9x2hCyMFA2dJ8iPEOGHIUPeRsm4u7HRoWb/IHtXjlPoP97XK98gG6QhclzLzcmuRW3xkLuDwjdwbU4l0Bm43CsDG/7NymzFlXjqs5gh+KoJXE7KTG8wU5HtoVXc2FePRKIPX78B2yMVoSM4Af/e2BTvVSXI5Iev/esr3jUPF1Y63G0oRrb9Wl8nWXwHxh+ZNsH9LPSwX7BMn8MPEetVq/eMnEuI/0OUwAIoftkgvWq8sPHaPGEGvs8+/1qafeit4TtI3vVMqgzccgMUhwqFLXdalfLvB3et7P5CoAruakzNvaS2aQk6u5EkLqrniQYtc8DVYSWBp3x7P387HU+Vi8iat50fNOx3KSc4cmUcS5AQYWqg1AqT9prVUDOv9dPZUJgDSfALb35Qwo6Vfh2c9+x2aefac3yZqtFRRDlVyNZTVPzvkars9KQkB8LN4X7D9GHb3zSPtzc4QhClRWYRjgx1/16xjv8aOyV9/2RHcmDCgjeJN1r89MomT2WTo0vKsiV/OyUqf/Y5b1e3y/VuVqlZC8AGgdb2rRr6Mx3nOAr7lRqSfubh5trNj+wc85XXpWDTkGhGUCexKTL0sGmbkN88AQ5wzUitEb0VRSh2zfqkbEYT/0UBct3qUK3NmrLASJBx/2x5a8g39MLd7wG79LJ42KxzVupHtgSYx3tfF6Jfs71OVtEldzIng7mvOdWcMKXnK7mleSeZPi+N0ihkS6XbK2udbUpf/qVEdf2V5xOTFyZeaTcmJN82ukKEP4tQXNif36gvXaEmLvYfQAcNn2qYFOrVY+QCY3Y/23tM0FIIpNvmmPEwThGe+XspDj83++7YjM+0sTDpXVf1/OxpT5Kr34VeMt+9v16iktTEhYyVLHexB4Nk2zBKVllSHeiQLGF0UY7yQfAw83Yu34lxOLBe+CDB+n9zqeM+5TKnhH73W/C9t0pZBagY8VaIx7ncmfj2mtc3osFYWpDEn/3vu8NvX9U6dHffX0tslr3wfdfWXDqpuGAtRuM7nohdXV3DKuvKRhFDZhyHiP8U9UVi2/aEPyNyglbOViuVKUg/NbOmQDE4nmuSUzwRTi3YsnV3N/j/yGLZyoWlA+AcNbeHI1njemv8Z5OmoJc+9nldbIu9vuEy3epeI5D0DpQ0MghwoDwnoC/girQBQ9z+ZEDNOlOe/B113whuPGOjccWnAkwZrGAiKh8tqwXPCukqfxLZvg1g4KAkCdUt/8eoNOOLI6qe9rI1RYVq2SbZ66b1NGw2yJHor3Pt9TkcU77/kUGD9pdTWvcLfPN6au0P2+sdvVKJsyFm9FLN6+VtSCL/4XP2hV9505PpnT9q4Bp2cF9lFbvBv9zFZF+pQwtnVulzL+GNAoS7VfbWsPrAv4LNniHf38puCZQS3eI4S8C5VavG1Mla9AlCRHlDx6gGlTtQNlmMQpLmjxLlV4dmy6apNW1vjW/S6RUkriGrN4VNiGY1i8C04wf56RXA0Fb6LcwlrIecDEi5jgyIYB9uxKBEAbKrUIg5I9eaZFKKUKiqIoGsIAngBU6ZuchzXcTM65omvQiEswL8P5KKKA8k2OCUDX3W/E9BBCV2DN8ASpQrfNORdczfE5mCslbx+VHInWfFHOMWTgPhwswVtSQiTeLmxMuOYqCWfxRbVWYkMJLqwfXgPedb/7Qv6n+cE9hCcdUpSzH7U0peUXg8U7YMjgK4Rwq1vW5TbaXtz1BtBYqcVb1U7wjupQlrwOdtDMvfVJn72Od1lSOpTUZqs35571pYK1mDN9E6zInGC0d5bVn++JYqM+nZKaulx983WRpFrwEo+dr7O5mld3EpUKJlIz781+WI3FW2KaULNfjYLABbDeQiIUXL/wfke12BspkXfqw3SVWJ9GjXBPBmqGpXh3DtquZPF2AegGMhsuwVvSVNOs5lLCQ28eQrC4itc52pDcoWkJQkTvYLqaW9ZtNfClX8su2qBeu3w+fzdvktWcP4MrEej7QZfBTD9LpMZu0azmcakwcNv96Mt+I0FbSUgw2Nbht8DHj6pTT54/Qa27gt3jA61qCJ0xuYbro1IBAejRAVuPSOZfmtOKMsiXiiXtM/tUvYLdBadizbL7+Z7DNorwMVZFn/A7ZjVHr47OuC440NEL9s+GyPQQgfXDuE417V9G8I7pqUuYp+BKiEpczZMEYAJQ0U+Tq31twdptEHpWdXSbvAwq5NCQhOeUb6nPSvD65fNlPquUJzYF7+iPFhuv4NBjFbGCD0oCygIYEDrQYli81VyPYPEeJqjUu4K7LnKLt+HGZCTuiBa5DwPBD+5qNi5l4HxivLc7JXKZk5h+6AeNKypS/w+JHBxglWz01OJtn6dJ0wY0QeYuba5xg9XAB9wCA2iNE0DasppXehCha5IvcfcVxqvJas7d7/T7jK0A/iWqKj+ZQSABNy0uHO+5aTYLZ7enqznMB+17Xp1dVPRwBhn/MgQjxWK8CwjeME/4DO5NEX2f9odPKeZliBIvSW379YE/lv79u/1GebUnCd7S5ZGree24NhQIoE2JQas6xnuwkqtRzylJ8C4Xo2FpxuFKcppEYTvfPW6a+t7x0ww321LcFt1jU2f6H1KQ3TsPpqt5ZTHexjWCpasSJBETQq6CSgWQSw8aXbFlj75Xl2tspajkDJMsxtLnFCssbs+VI7UFQD4Ck6uhoQPDzEBRssqSWSJIE69Cbg3eb0lxgAp6sBQW8RRJwusKAK5fZEKdR1bz9LPlF6td3mYaVod5R2h+B+o+T63vQxniXSSnBO1WJRZv74Sk/O8hnA8XBuKpOmbnVtPVPFZQDdekeLVEELyHCXwTjfHtjUQ+bceMSTPLCKV/3P9ij3eMZS0t3lJ2XBv4AUEFDDxPaNIyHvOWXmsXFkAgqESzL1q8Le0Ao7aw4+Ci6KLZzx0wEg0NmATb1o9qCW9VgrfQHhXifvy9SGAtVclMFUmuVk0lATwkuKv5r3ZPhcDb45rVLldz7kJM6cDE2MXfBmSMM+PNeU+w7z4XMpfilEoJ41w1efEjSYGFFm9YoxLD57smJc8exHbrEmWHyyImlhPL3qOZNlV7ULpcWPCmv3MlxCBxKtqylmQ1zyp3bMobSpMpkN73VmrxZnHWidVL8IjqiPdnLcDHCkrrSmK8eZtFrveBtAxobWNfYEhIJXWYpT7UdHlWMO+ZGG9JM8mw0wYthcfA61njnumMrbSgeJT6aNtHqLDH7yHzukYp5RPyFLr820rKieWVXBWrHKjaQQrnSjOAl1hW89JsyWruazDJuJpTnjX+matM8f1s2Fq8lca+W7YavAzkQYjK5c39kncQvIcJfA9HXlqK/63XLN3YljX872d6/A8UdgBL5a18QRm4JLuox30brWxKLrg3u7rltvOGReOxKoopEQRvGzMJ80UFahtd2XiVRnXo97NZwsU2y/aYv4yreU7/8pBXB5zD5zp4VVQYRauTv8Vb6GdsCfeO8a6C+oGbOcCWMIeiSHI1Ov5xI/MEb/l95x3CtnHje5Zc3ZAGSO+nTPYf/5rW8a5GYefjTh9dZ59nI2MwCfLmd9Q8q3mpBq7mjuXTMJgWb4eruZQnAD7fft1mt+AdM1hVJ1djOQ6oq3nhWsWFhH7/WGNXm4hqBASqYJeFOlByFHuAK5FiHiTldy3ZaNdQbF9V4mrO2/KZQqTH6GrewCze8LdEV2zdwM+xn9h+ibRpq5Zhax8y3ldSTsx1D/JdNMb7rudqFz8MCujdvyMrQuCHTq7GLN5X3N05pEm68srg2VDE4o0Cqa9gyq8aLuJsWVhLSMsHy3truGEeGebwhy+jxw8LGlcjHcD5Ltf5z1xwXL361e5pqY1KeRrQoFMhPtlklvboc874ySjhAjNbuETEbMCvQUtbjat5yYMB7ueCt6XNKw4fq7ZY054lm7dpE7yzrua1ceHxzkAtTD7/CLTYRsZ9h0VVgo1pimIa/Rqppn4uWrylhGFStl9vi7fHGj7iB60sa7Clbctz8g436bk3PtLttKql+Rtk93mgU3n16Iv0yXafqzna96vu7RLbwb4OBpMSCXDZhVttHe/BiEfXz6E1iYX5l5IpvfWn+dSJ/zfK7ZJaieAtCb+ZGO9SzUpeuqCVEU4B0E/JVov3h+9AC3WWvVmJkgPbLArR26mG67MiY1hZPidXFty+0weZf9rOFImu0neCXnW6DYjDlxSXOVVd/jepP1PFAuuDN+dYR2EctHkwuBQ1nEBOhbaOstrkm43q/rOi5KIUfNyDgXGsFBsNY6Dl0uhar8Rjo1Cf4oRzUNrytL1kmpd7LpMFgYpMW4x38TNTnrPZjQFh/SWhbPNAfDcgCN7DBAt6asz4IcoZjLjMI7GglWoifHxv9aaqrQljR5YM4VQ6zLZaq8mZfZZCu5pTwbvAak5dzeW41aLtSO/mwgNGJyVdunrleyqFdFijdXGwXM19IU4n+4zHRqdMtF8nbbGyg5nV3Hi+cNC73NCoUGBFyWzPts2WWaTe0Izb3O5Nq1opf9wVxhpLNe3pc+EwBTqF/aT1wn1fgSvGO69/6XfZL8GqZ4aLxBbvGu4Vavmr1A7r6s7gxXin9d75M2B+igq3aBmD2tUfflnsZv7qaHK1NKs5+X4gikt9+4psIqSi4M/OjfEuuHZ8aZ4EdO+F+GFbjHfR/uC5XInFUFL6V7uXFhhb52fxLrlzlCAgIRmsi7WXs5WayMKH3iRltZL8OlE1CIx9prwZhU0Q/sOdUWJWXpoRnplYvD2ENE5zaCy2Dx5/o1f/W3S+erX4/FnJCPehLaliLWBVtLJyaUVCGavBFms2qfVXitbPsovUi/ypFca5nP6OyhSbMj/h63PanFNczWWL9zDRDgwyguA9TOAqS0QBLrkrLZESP2SMJHdVrzXsuc4XGl+vbjphbEUb95x9Rqk1lm7QB1KeNRIykueVTuGu4rnJ1USBAO8v1yyrOScayDB097DSTjWgLdJhzTXt/Nqqs5r7CrRS0rSc9V609Ay3ICea70HMak6fVcRtGmJebQwSt0oXiQ/FdcvzAuTF4uflNHAKr8JnqIiT2oW2tDDbBxbv6LpbThrn9SxXn1yMWBEAw8SZZ12neZCymlfqbm8b1zbrNA1aTFxk1Y6tdZkY75K6+bHIa8AXtInPpvQXvpfSPCOkJBG80wcUoQNFAeu9eu+hFJLLvi+Q5oObvUTfK63aUWkIA+2DU1AogDtPpfTC3hr9ip63lQgalXjY4Bm2wmL1LHa1nNL3Aq7mHHiuQztI83Oto+zv/77ck/GStAHzriBsa34oLN4l1+ckUzvlwSrJ3VOkPy6Fs/Neq+BdIGFeDZTmYPz4/c+zWfZnBxritT0vZDQHBMF7mKAIk7DBSunOxOQ3vJyYb5tFiAZqXIvyCTt8q0WNH12nlQTSYb7xN9Lx2PqMz+aCFmVaCrmal4jbYwWbndYBRvB20AKTlElgrpHVgL4DGkcL4HOcxuBW9qxqXWGlz3hsdBJD7PmMXTcymQK8b6iymheJewcmyXaYcqt0EeUIvk+elTlheEsFY7wxez35DBRm1L1dekHU+s+/hncBDBAoyND6tvD4tAOVvgIf9/pKFDiNcV9rybKVamxtoBbSaqyleYB1gsxgJiN9SalHXo1MNKftlYYhuUDpD1ek+qBsCSlJLN6kj0XoQD7MhvIyJnvpuwucVS6gEAXrVnY1ryyRXcWu5lKMd5Uvwrf/9ClUIV+JXiNDx2zlxAzFu1IP/3a8uvaYyEABAG+6nj4adpOdC1+akAjeqpQk86JeHjbQ9mEuwBDggxN+OEptR/I12F5jWq1g8EypGcVfKatwj65LrxlMt2WqRC26fyfPSDWIdFh5yhTXc3CN+VyPbwnK3HFLPZ73Q436eCLmhRregNkzywEZVGqN5BZvQBGLd5HHYnuVMI/ghjSzs5yJ1eGugD6utvR7agWpJLsvMFGVJJHxcTXHdjHDLjD5UIeyNq7m6e9QH3l6XznRrHMXwaLJ0Wzwvd3nNWQs3uQg9QFXxNAkMEPhal6kDWCSvJKrsfZs6z/Z33VK3XLiOPX1heqtrs20bZWjgHGtk0UnxsnvhPvS5D9KLb1IvXrr05QoQVsQH/ji+31qw5UbY0Fc7pcL3K3Zuk5KlbtTA6Bv3X2DkxEX3lelgnetLPxFAHOAITI8XpI+d9Wl/Fx2KVPcUsQ1kzDYrjJZNJwDBM7BclsERao7pKFYe9W8Q1S2gmJEsjiCLFR0HvDqWrmaV/sWKrkfElrW0uLto+gD2gGegRSGxdvSjrfgTbzCwNVc58zJebdSXgmaFycPRuuWRyUu9oNo8bYl10RXc0xoR+nUYMcL20ot5oGG2VAPCHQ1zysnJtELXGPGdZa/dztrhrrx+LGiN8y1x0afzz6Ld0nNC5hH9AvDH5W6xfFyYkUF7yJn8sTYsibF+eQBrSN58dS+VtmSkG3TsHh7WmD7KnY1z5q8+SGIVqLEalRDomKWt4l+9lhczXGKKuVDXce0b4koyc2JAglupUwo3qfdQAc7uZrw3Dz4upr70AG854V3+9QqX2vIKDHS7KdyP/PGLY0pKd0kfJlavEvqrJ+MVodsn2bmx8uvvLszUYrQNnznz5aZONN3VRyLz59OekNDKarjXUOhzYjxrlTwLvh5rfoNNYbBkpxJ1EN+96WfRapOSH3hFm98LtLCjMW7RtwNX2uX/bvT2+W5mmuKCd5yjHe5Ass/tlOzcmJVvgfvuSrJFsBKtlzJO8Y7/UI6d8CTC7zqsA3xHRW1eMd1vJs9vEakK2ho0sHbjXDfT97d6x8KZlUjbE8NGko5lueOeEzUgjvY8cIYOlVNCB9lCTFG3p7V3PyZZ/G23Q947PW4HjprC+bMKx+NgKN3alWXHFSZ63pDvLbnFYv3PDLM4Y8iNMLYQK/Z/YZ8CEIRd9v5xtap1y6bqFZaonJHibxDmBJL14GE3aYCqDXGW+pHfIFOrlaFZpS6enKigWNBokgPzmpB6xDjHKCrV8bVXHDDGkyImW3Z31wJUQs3/Cj0oIireRUPwzY8r/NZY9AfsArnZbvFPfuZUIvbBjondI9RV2spUz/+kSS/EwacJLapjxLDLEEEWfpcnZTKpobPga8WvpJ3SmkgCBtgAR8Mlo0Lj0XvTf+w/D4oFu+yETuNAO8lep1Xe0Y5t2J94UoLYFLTuuBZ5VYl2bxdz8585hizz3TUSvBGSxesW4m+w5FQqat5JfNnKr9jZV3xZlh//FqgVxmJvmph8fYweUtCA4TZYF9AiBUFb88+JcnVYuG52ZMNKzMlyi+vak9+X2IB98FEu/vRVwPedby/vmBtzc08Np6uLaALHV1ZhX7jULmaV9EOXVeJxdtWAYX9pJAS2/G1Rr0EMUQFnn+fkKm+Euy3Vas1R1Me6jFsaB6RSOeRYQ5/VKqck+olJhavQXi7kotvEeRptHzjrXlsTyZbsqdVL0quVnxM6FJGBSpONPBvtHiDNc2nb0W0rTBfKKChZj3jrkOE9KGATzmxO58mBdhJ36qxeOe5mp/901FGnfSKiTxlLn0TuXmaLLdfr0Xdd2Z0ENYyYs4nxtvWp7zSZZhnIVGeGMy3nIm6KHicpk1wq3ZvadfQGtfxThgmliBsuEML3j35DKzvXNF3XzTuVr9Xcs9z7/QlTCu6mRqu5oOYXE33p8CX4JFyzZFjHJdXvmhR6dCgk6tlv9eeAUUt3lUkp5IURFUnoovv34goJfNw9M6k/GkVzywCiXeBvYOKd3jPYhy+xWuPA3kN3Jd5Lsn6mfHBWKn7MJ0H256FfQjXUVfz/2N1twfT1ZyWlaUW7yGL8a6CztD5RU+ESkImJYu3dNaiFybyivD8IWILnaiP+1pNhaE5CUHwns048YcjKy6FZf0+/imt4QO2drsWDTbyBGt61pcLCKCARSbWWxIQuVzNK0uutvXaTeqeM8YbVhZK6C89eHRCTFJX82zfKgUOW1voBkzrh83VvNrsx9XcnndrtYcktH/dg13qhfeAIZev+cH6Lerg7YjgXROLt18jRRId4jwvGVsjqAtt/FC/vpUsgrflfiF6Qrzfdp8keNNxl3Um6lJF88fnwMZIFnmlPN8EFTYG4/yHsVZu8S4NfYx3XUnTLsniTVHv2YlmIhivXjCJTyQ/mLOH7yjJ7N1oKoNq9Q7l0Av/+/fYpEV9a0Uzu2KtkuKh0quJlcWrJrka7q2qk6vhzyq5zCS3TM51OP7VlmpQay2bLobKlF0lK59hgHwsCQ1ROTF0SZaFIerJ4VJMotECxgmCZt6+xGuheVv3MfGr9X6jn2Vn32icca3pZ8lh/QW68O5nfRll0WDHC1ea1Zyi0L0u44TwaqS1hEktkWbawh+GGg0hq3nAkCLRCpcqJ0IWbaAoeG+TCh6zA3nj9LZ4Y3I1QnDmJ/U+ffkaOBQrcUkCRvhrzJ2Kju27qzUnSgR0IRoMV3Ow1uPvtqzmaf8qe9Zg1H3kWb5Ry1uLuckb5+6xNr7S2CybQOvuk3zhx1+Zicj0tfH7W3Bc9MsicWKz5Loq+0lfp/G5I7maJFRnkqvhO7T0UGc15y6DFcbIWwXvAq/0lD1GZT5797P+micKSvpErLYLkszuhduz/F5rRJa1KMbbeZ3nUCaOSXv7g/WLuSSCdQ/dSflz34nfmZlcrTLLkS+KuJr75LyoFLSEpG1vFqVzuLcqczXPPqvaofp2v5YCBG/LFr9MhVGJd9EVHUhWc6lGM23DtZdQqIS+aVdzTwcAl+KhbVaO4E2667KaQ78NmlnjrcfnZczIeC7qSvrcOvlvszL3DKrFW5XS5Go1Erx/uetIdd5++THSvuEKEv3DjOmoJBkugnd93NfBrL0+nDCPDHP4AvdGNQvOdtBXq6kfDNQqxhsHTQ+V5Un9zLxh1tFyYjWaFH7wIuHDrOb04KwWSUKrOCYVlQjwSE5waxbjXapCKGf3Xrj/GG/Bzqt5i5VVwgKxQDsUQn5en+j65QqzVBAuVcaIWspO0Yy/vtZtl2IkYdRx/ZNrqAUCMmRnXAaVHxZigqqt9nERrw7XpVYLVxUokZrn98fhBFW3OagW7+id5SXb8S73RDpb1Ptmifnr1ayYjiL4mUkFkSibt6oJigrOGUW4dE3eBZ5IhbpsKcKZHQMVxbpjiVIfV/MJo81rpJKeVbuae541tsfUIrmaTeikZEKa5yh0hQjnwmTYEsRm2mpgJSo9LN55AvOEMXVVu5rjdTRpW80t3qQjay7boMaPSqts2Po1mIm6orChVHitph0ElAXdlpRvs10rPU7aG9J6RK8gVJIMB6EbEJKrBQwpXEJy3j02xsd14NF7wV16qJHn9kWJxa1PmHHAkqYYaB/ErUBZsjGt/vWBq3U1l5BNrhb9PP7q9tw42aJIrYzp772WsaSu5pU9qya1h0s55cRqWOPc18JTqSLCsDh6W7z9283kCqiFMoL8PnqEPHAxuRq733Xoy8mF0t9/8ceZGSuE7/wtv1iDevDsVFitRcmToeI5qCcDzlWmLnalbdemGbntOHtynsV7KCrASJU0OGPJLd6zqzKNz5quFcNLhTpOJ9Y8dGpF2d2pFT0P//jlOHXez0Y7vWxqFeJU6TlUi3JiNkUf/dhG/3p63XTciPF2EHtc31rI7fUsUUmSr3Lce8b4Qp4nkCHfBog5nzKTKHQHce+ttHiD6UpvE7wHkQAYAn8Vj6lIOViqvG3MC5AmVxteMd71oZxYwFAAF/1gWLylA5deu9ValWUgrAZS9kUK33kA4WqgYBZraY6AANVKM8oPTT7/CXGpwfO4WzAIsjpDuyOGbHZ6O3D3Yz4H1Vq8KfIYzUTArcGzaip4Jwoz82L+Tv0t3tk/IMHcwhPkCfrFD1rVGss0iOW+XO8ntXjHjCHte31JrbNcgzUOssj7XpTkcKhFkjJn3Hr1zTuZtWqEkUpCHSoBvCoQwvJiSQfTpRsBSZPGs5j8TL4AnkF/ELOau4ZsO49zG60A1L1XjvEuTuf6CwjeEG713VWb5MoiQ1xObDD3As6JMz5bEBq0qzkRciTM7Egb2Wx1uzEkzRFT1NVcpmZLLlif681i7KkCRLHWJIFmTKf0CGPYJQx2He+0skzlgy1CO/FKUfktzIKkeMBM+Bg6AX0fDlbv+rivoZxYwJAAiXGl5cTEv5OfpapccgcDmGjMBl+3byCqwFzBwScJsnnMqelq7vVIrz5R0Hbh0HTF0FaK6e1Ro8ssUq/jdiRiizFklR6GqCWtJVHkc5XUiR4KYcShmCr8rAruoTB2QyJ4p9/9br9R6pKDTbd87zkSLN7jRtZZ+7LPFq3agkW/B0uzvt8Z4x27pgrXwLpfZtFU8OYeGZW+71pYvIcag8HgDLbgDcjNal6wD5XSW27h4/uXJooCRr1WxhO6ZlH4L+RqLlxLPyrVSCCx7c2iihEUFH3PYjo/kqt5nsdE7QTv2m2GrMU7X/AWLd51+RZvGj9+0LatuWcmWJbbOsqqnZT0swEe2Rf3fUQFDo5UqHRZvDPPFcZ67C6tNVEw0fWkH2PNtq4GD6RCRTXLrpJ7XeucelLRDO8IrP2OdAOaGgZyt8K9Uyvv0+GOEOM9m5HG35aqclPfZp2mJMYZP29t8Xc/HSqAi5QLvsQSmEEQmoGxEMtXefanvUsWVisBn086Fjg0aUK0WgEPbaibaXObR+Gp0gNiizWb1EUHjDayxhcFf3ZmDpK1XP3c5DH2rlipQbN4e2U1LxnXAm3Ybt0WHd9ayTNlt0//+7daq0kdv1tcdcExZzyHgCF4N5j3ZN5NhS9hxSUqW4vbrpN6+Ujz4Cr7VAsMRtjGYAHPpFrFeFfbf+6ez59LBRGghbWyxNPzYacNokP1wy/9pZBcPWANYrwB0nChn0UVHShk+iYdpddJXgaVlCClY/HNal5LlCxx784YbzG5GgkHKOULwK61gElaUcH02dQBP1fzmEf48xFjc6939UeyqtrvK4mK3RUXr686pIKuJ1gbNqWIb7WFSgBNY4KyauqFFyFRrpDBJISJ9KW12a68HK4x3vWzOwnVECEI3rMZT70VUdP/TfJPo1timw3cjM//2Rh1xynjje9pzHNyr3GglYadxdvXPQiILxBjm6t53tCw7iHMe61ckjIWb9IJzbwNoss3lIkAJkDSum+xZrN67qIJFQu1QAy3tIQlVJhbLZuILnXTqAhFFEr4daXxRPQu33dpYwKoIFYaREYzmd6Sx/yU0szbKHS5DkSeBZleCeue3vrJZJNLquQN7Llpi1pwXGWb1haPyoWsWmbyp0qPIjnbKmVSa4XEYpnj0lpUsKv02OEKUvwTlI4ASEyEv2uLd608mepkC7MNnM5KCoBaHb1ozdTPsbRZ9LxJygP6VhihoSnCjm6stixZ3P5gVNfwtnj3+yRXy44dzpgkAV7cqJTZ3PZcihVJbDPAx9X8/9m7DjhJiqr/etKGywHujuPgyDnnJDmDSEYMYAQVUFQMYA4figlBFBVRkCBBlCRBguSccw7HAQfH5dud2P39XnVXd1V1VYeZntnZ3ffnd+zuTIeqruqqF/8Pr8eNBnHvsfZ84ffN1kh+AVM3mp33ooFJiqCIWFOzSjXRXltweoikd2mR5t285n6X80gksQsr3sEF+xUeHUSvN4Q3PVIN7t8Fum5hlOR2c5DiPcTgzJTzl6SPneSCGWdpVhe3Cf3RnuChsHaJjMqtLETMklw3h5qL0F1yyUDwvLMS0NSNN2/weLcjBIpvMvOX6J/vOI0RppMIe7zb6YWOvgr/OovQ+cTe51yaHG+IFDStZgwEgjc6qWFCZ2DQNUnNWxafianMkX+vJgY8K24K3a35vGxLjncEEZAOa65U6IpQ81iPd8o2NGt4LBmqRtz000mMXBNZgX/2abdEXDOkYiaICmiU0mQ8PyYVCrIKNTeVkUz5HPbYrASnHTXGN2I0a3zmfWzG490tnjidgcNUCkxnwGfkakLpJl0IsBiCbRqry749ATacLa8HSVnNeUh03HscNQ7Yxj8oKU9RMPWj2WEVvdqichk1T9qty3FjQKmFG6WZ5zzSIcp5JUYFjdUo3qF0na4pJwZtqybSjSDFe4jB980zPhOuKWuEJXvs1AWVv0i81qHuO8Rb8zMsVpsQcYJnUssXLr4odDASHSt6odY5Kdb1wq/T3DOtgCVuPthe3ox21CrsgrWzNcXbcFzi6wtPIOnzbTafSA7htrInV0uoGX9it95E11PbkdQwIbaDz2UdqVkU0Znq8U7SxiiggrXV2k24bmLuvdMGxba/m/gzjViRxPDSFYp3Sk26eY+3/LdurPhnGNGUVWSRSAjI+S7SII7kNLtQc/2F0s5pHO9j9uhrKkJKp3g3k+M91BGnatdNa5z4ubacWC4YI8ugeGMItn/fFM8jjvSQX4/LQk1F9nm3wPJdaea+0ePd5MDK5Grx92l3jjcLNffa1ErEZJrQam5oQQZ5014hOl7UyjE6I1g3KN2S4j069G5SvIcaPIRp+qTkby9/V7jHLuy5c4+YoA01D960l+Z2XvGOg26x3H3TkiF3yn1RdRue+ALrrGgTx+ZgokeUk5nH2xvCLx7QF7outred7OLdsoAmhcpu7ecQN6t4W01ETXRQujPdSpyZlnqsSfHyvt9xw2i2HEuzwVsJ0k100Qe8TbqN0RS94IeZRineMHSwNEIsF0yyDGt9831X8l1lxXwqgiJOWhcFXWhvVkiqOKVdP5t97VShka/fIriRAMMxs8oXFPekJCWcVOjsulmt1x/eVuAsGELWeQ7dMxc9lEmh89YlRRbPVr2GKcXAidlPGKu55/E2Kd4iTPnKuj4lYjUXcqCbeR+aNYibjm92aORQ82Qe73bKRJZn3MO1r5X3K82pvd52P6gJNef45WfHwqE79BjnmfpM3HJiQy88Frw1IotqJcMB5PEeYpjqQ6bBo6/U9R5vTai5iE/uEe0xGwrown91JTZw8cXNEJVqnfIgKtsiI6Z0DV7CIKNUSt4K7pETjRxyqHn2C52pj92KkLdZo+w1i7gNV81Jzvr6qRRvjead1FKfphm+8qSElkV548TjuNCm0wVPPriflSkzKd5RXBJDaTASvS/8+bTD482x1kp5LUEREr5toCGLS6L8t9XjnUsWKpyeXK25Rqv32U0oY6UqxiicZuXxEvekZtJT4jzereDrh45hUSCm+7DPO/iOSURr/LOUHu+/njweLjt1YtNtUN+bXTZOHyFjJVSIJY+3kVxNHoeodAWTzKZXvOMHFo0e1z5Q8cehWT6GpK/sUTv3tsXbLJOrCe2LOKfdHEZuFZnWrpEmDx15fBCDFU2Ot/dzt01LcPx+bgTFjMnhxr0wR9YVuqacWM79SR5vQkfQTFkcXS6l9L33c4Im1Bzxmb37jORr7UacLKlbsMf26SzJnNVcf474ApueMV/Aswo1V3N05XtZfj5YO4T7AaGUTieR1DOozlVTbermQ80DxD1fLiy1u85nog3WMXv9nRa9EDOm5EIeXbyHOD+j8k91CrpuvHEdOXj73kSh5ud8ySU3O/JDvZmXAEoLSyPE+s+jDa8T9lVn0UfCt399zyXGTBRqLjS8nU+PC65xHu9O5Xir0HnweBgqCqdZRzI1q1DEeRqzGkPTq4QGn04hn0GO9w4blEKVHFqJQsHc5GfOndKix7vJcmJ5y8/xjpIPOCaMycFjvwu3VZRR+PlJFO8p44Njpk/KpX73+OFJz+OGA3P0BWRQTkx4FhENa6cRFccSPd7N8BeISDMefA+PIldD7zXWZ//39yZqU7JeUKJc8bwu0LuBy2KPvyobBkYqyOM9xGilHq2RwML3eEcPbzsXpmahC9fS56q4luTT/rYM3l0YfoiigBuneGf1HKIUIjHUvB26xnKNFbSboHZZZRSPKleVFnGbO48y6WTpiiSlTRKTqyUwUlz7g4nwxf2D3EGuPOE5co56fHvENiWxSIuXVMnVePpLN1jZxTYEind7G5YqxzvBMe18jlzAi8sl7VSoeZK+iqHm7VDwm7mmdj1qw7iZ2rbWzBYLaTfZBt/jnZHeLxKZpeMTsVIrSM2EmuuMq7j+YU6uSGoZN49134vGL27cSBJqvuKEnPQc+LW/fFCymtppDeJjPG++aQ/eZaNStqzmGkweF+2YyizHOwOPdzPriS7UXJUt118l2TtfjiE77hTyQ03q0GF0oeo1utAMi1+c5TRpqPlQKN5xe6fW491rzp3iYVwqxMdq2jR57lnWnk+xtV/Yv8+/V1DHGzIHZ7wc7uRqTQukkjIZfRF/HJoe9+jrf24fd8xFmAQRXY43Ppu1Z+Zhf6HmdNpWYO12Udjkv1sJ8uF1Od4+23eSvGPhRLyvpHh7UTi5rlO8W50T0eDXT+O1S3RsG5/jfx9zWXwWLI22DqeNWmhnmR8ulJdrGbKaC9dp5po6T2g7lALdO3VSQgWrVey/dSk0F/jeHFdCNCmGcofbeh29lisa+HW5sjh3BioOe//9SMWYe2mJ1IS1nM+nJMaEFQTFm7cHsXNCBTgwFiSbsLyElSlvGPlvnv9TuugDNSVT7LfYrFtPd6OG/v71CR2Rb3F+t2pUSrMO8P0gKtQ87bJSqTpdYQTPD23lzI6DFO8hBuZoHdtkrjV/X04/dmy6fKFu9njnk4Wao0KIkqgAAQAASURBVLc6Kq85ncc725VH3KQmjsmFPN7teO7LukTxTvoo1eNaDTmW85Gjj+XzJotyYjrM1pThSdK9wLtgwXU/nKS9Dvs+xTXV9wpD82JzvC1dLV33Z1pdUPV4+yGkXbDZWxrBls+JrN+muCgGHYY6343vH8sGzQ0RSyElRQa2NSN45AIjV8tIopTXk/TXXEEp9+leJfsXQNfdRoK641lgXF+4j2+85y60D7xQg+EGdT/SGVPVd1T3/NHgjkbxHlFJbsbjXQxHiyXZv6Z6ijf3cPPQ7MSvhsYIq8M+W5RCkVXay1lWUxw3ooNF9Hhbmmek27+yBl4b1/JmiAPV66Ql2xzUsJpzpF3yNlqt0BWKd6ELdZF2ouu6+/bbb8M3v/lN2HbbbWGLLbaA448/HubMmQMjFRgGdupRKUqJSYK35Xu3RKCF1bQZDhXbaUseb53iLXiQdUiW483DSyFTiAsZ3wxQAWmFXVQHMQR/qD3eV542IWbDjR5n//sMuhH3eLlRJotyYkmRpIZqUuNDUs9JHOmRaQ3gSoHs8U6ueYv9wPdUvAUnFuqCvV4ax0m8woH3nLJkNRfvlYXHWxL2oX3g62LU+njQtumNxu0NNXd/vji3kR25miBcrzEj3aKBLMN7aKpyJE33SAPd+tFKKlsafHH/Pvj8vn3a5zYUckarCHOQ6PsgRgDpQqBxPcExEPOx456G7nvRUMONqEn2Ly4jYN4vOyeXbs7xw+LeJR7VwJ9T1kqvWFPexGrOlWB+73aSq/GUyFajJdMYB32Pd0SoedpXrVtCvAvtLrreZeg6xfvggw+GqVOnwplnngnnnnsuU7p32GEH+OCDD4a6aV0H0zvLPRTdGGreTI732N5wQ+NCfMQN0STA8mu0k2TL96TlLVjqjQsvC9EK7jxjkh9aZSLc6AT4Xfkml7SMSNjjnfyem68ZlnCsVKzmXv3NDm46aZl9o9CMPOGHmqsGEM21/GM0UQSJvLDCefhu6e7RJfu9j2P27IM/nDCubXOCC6Rp3tJNVy/ERvO08znydTFqvnGPWhq01xNlZb6/iet12hry681Cj5LOuNUZdErxnj45z6L3dMprVuOQtTEsizkqrodIjGZ6h6Ta097gTzSQ3+ret3GC84HLLUm8rfwYPgb89Ui6bviKdMzxSDTmHh9ubxb4ykf64ZO794b2Uh1RKJdF2inf8mu3Sq6WJu2Gz7U/nTQ+4oIwLNFJottuQOdYNxLinnvugUIhaNY//vEPmDRpEtx4443wsY99bEjb1i2Iy/HmL6jOU9ztirduw+vXpLrGkUckURD4opm1tU3yeHvNfPntum8QyYLJGQWdbgpLjRNU1C73eqUx/O8T3ufBMyeHzlURy2reYo631YSAmBXBUKqGaO4fZwARj9EZM9KSq5nqeHdDeJtqINt90x4/nznr1ynN8xPDWx96sQZ3Pi2H6oqXiHsXWldisyvLxdHs+pf2rKzavcaM5sWkoZ7nQ7kv8Oef1fbaya4klY3ini/3KEoeb+/Xc740Ht7+oJFozoglyNxrJiP24sf4HtG0Hm8ua8Y8jxMO7Ifx/YO+5zvO6ZMWKKvNmMzT9vQeb76fJyWxy2J+dJJcjY+hGuEqfmcNwzWqW3WRdqLruisq3YhGo8G8l/nRln0fASvmhdlpg2Iiq2M3TnY9EU24H8i0q/N8prH0c2Uk81Bz4XfOCDx/SXvFBsfr77brpq9ZmpQtNAp8iIx598JD+ctXxoeMHUlziCeOzWmVDZkwzGprHe846PpgDlWEjoB7AlVBIYpxWec9TFtb2i0nFu67TnjoBrTLg9xMjjc+f11FB3GCJWE2bhZBpYFsH0rzoebpTmx3Hd8kSJp60y6IpFSdhu+B7EI5Iw5Jw+P5vmu8jmXOS8boiYO2C6dqxN3aDzVP8Fz5sXwa8PUnqcLImxIXCbTFWkX47fHjYekAV7yzH/Q4jhzeRv5utdXj7ckvrXq8TVEPOuhKUWaxrgz9KgmjjlytO6UfAd/73vdg4sSJsNdeexmPqVQq7B/HkiVL2M+l1QGwqm4XC7k89BV6YLBegbodaAelfBF68kVYXi+DLcxs/Ay/W14b9EkNEHgNvBZeW0R/oQdyVg6W1Qalz8cW+8B2bBioB+1DjCv1s3Zge0RBYUyxD6qNGlQagZcjl8vBmEIv+wy/KzsD4OQHwbGwXRZUGhVYWg0YF9ZdtQgvnjeV9alcDfep6pTZ+bytneiTY9UBcjVo5N1xUfvEge1AODmswdGA3TctsuN147S4shwcKw+WUwiNU83TrrCfCN43qU+FQXDyNahCHhyn1PI4Ddru7zWnBkur7u/lRoX1xbJLfp94W7KYe6x/jR6o2+7v55zU73+fZpwu/U4PTB/XHzv3xHHC9tScCrvvYKPktsV23ze1TzXbG9d8GcpOAZZ6sWm8T8vr7pweaLjfpZ17zAdgNQByVRi03WuYxqlil9lP26nD0mpwnaRrRNl7f8B2tR51nBre73zuIXBMdH3abQsbfnoZHu+E3j/T3LOsAnufBhoD/nOMG6e6N05luwTLGzY4Vg0spwiQL0v3xX7i5o3jhNkLS71lxfa2ioqD9wwkGl2fBhpVcJh26EDZHoAqeM/LA/Zp720asM0Gve5akHDdixqnqLmnvk+8LbbjhsaK/WfPBvBfLjQeza7lbK3OWex6DQvnXk+iPiEaUAv1aaBRZuOP6x4UcPwC0SnLtTyXa7B5UGNrVj7UJ/7sUo9Tzo3dTrvu1S1cI4K6Qg27oe0Tn3uNnDxXW9lzeX/5ubiWi89YXSP48XU2x8L7UwPfPe95DDZwvBqZ7LnufS2wGr1sjpQbwTNIM066PiUdJ/5cyjbur4NgWWOY86QVOQLnoeOMTTRODSsPg/W+lvpUcaremlICyzG/T7NmuOsqAo9R+1Rjc7YMPcVxfp9q4M5jvJdu7vlpKRZS89f9a/Nxwj0O5Za6hXtGLrJPaPjE+w/W3Tlm51BuLLIQ9CRrRBXbyh50ILdEjdOCQffc3l55b81i7uF+h3MaFWo+TgP83bRL7HNs4wA66/KDUMM1wO5ti1zO1qJcFYr5Quo+ObkKgOX2qafPgmqjlOh9YmORr2vXvaqzHGMgwHZwnKrGPuVLg55zxF0jsN3LasEcxufd7jUCgfcT51MOSu66rcgj7dCfONqtE0bBcpIWR2wSv/rVr+Dss8+OPAbDyZFMTQXmeJ900klw9dVXw7777ms8/wc/+AH88Ic/DH0+9U97Qq7P3eCOXmMv+M12X4aT7/stXPLKzf4xX9/oaDhlk4/Bkbd+F/73zqNBu7c5CT6+1t7woWu/AC8sfjNo624/gl1X2gLWuOwwaeLfccDvYWb/CrDm5YdLbXj5iCtg7sD7sPN1X5Qm0ytHXgm3v/0IHHXb9/zP15mwCtx54B/gopdugq89cJb/+S4zNofLdv8x/OKJi+GXT13if75KeRdYfP+nYIcj/w7/mXdL4j5t86/j4fXlczrap1Nuug4ufP8PsX3Ccbr+Lx+DgXX+ArUZd8b2qe+FT0HpnV1g+kHflcbpUxO+A1ddvRYs3vE4Jpx2Ypw2GrspvHndyXDAx/8DF791mf958Z0PQf8Ln0ncp7Rzb+yDP4XJhanw5ubHZd6nqHHC92nfK34Fj1Zu8z/vef0j8OZ3Phfq0+lbnAg/+9WWsHSrb4M95u1Qn2ZfchgM2s3PvcOX/xUue+5hGNjkl7F9mulsDMvu+Bp8/Lgb4ZwXLg31KekagXPv9R8fFhqnL6zwHbjkiuRzb/xd54Ld8wEs2/q0ROP0q3XOgsP/fjUMrvPXxON08L9/Dfcuu1Uap1UWHQp9O/4Knlz2uDT3nrxze/h7/avSOJ279Q/hm2fMhoGdj4eaNdhUn6DeC/OO/Wdmc08dJ9PcM71P313je3DCdtto36c1Jq0AT6z1+czfp9LCDaHviVPgcyfelKhPG1QPhbfu/TBs9tHfate93j1Og3n1t9qylm/9k//BG7N/kfk4rT1wCNz1+c+kXvdWuvAwaOSam3tZrnu4P62+1wXwWPW22DXi1PVOgC9vsW+oT3/e7ofw9dNnt2V/yi1fCcY9dDpUZ/wv1RrRLtloh/lnwAVfXK3lPu288BdwwKEPtDT30vZpg3e/CR9ecws4u3JM0+8TrnsT7v4j/PFHbySee49d+mUoz/4XVGb/O9Sn9X53BiyYeEeiPm3dvzvsfN0XpLW8/4mvwz3f+hDsdMuRifqE79OPPleBrzz/5dhxmuisDM4dP4XTTnkYvvHQ2ZmPE657t3/pYDjmoROkccI+vXrGLqztnZLLCws2hF3L34ZN9r4+VZ/WPe9bsLD3qcx1DRyna37WgF2u/1LiNeJ733yko+8T9unFx9eDnyz4JFQh6NOt+54DB5+ahyU7HZ/5OHVq3VvtrwfB65++BhYvXgzjx48fWsV70aJF7F8Upk+fDr29csjN+eefD1/4whfg4osvhsMOOyzyfJ3He9asWfDW++/4D2Akebz/8t8BOOeaQfjQBr1w15MW/OPUPlhrZavr+7TBF99lIU4Pnjkl0gq1yfFLfe/wh7ctwQ8+Nk7bp81P/IB5HdHz89gfxkh9uvS2BvzyysCS9+jZU0J9YuezXKtxsOdGE1oeJ8zFPPn3Nbjom/2w3qruZ0+9XoNjfrlc8njztmQxTqwPjR4Wgr1ocNC/dqeshWddtxDOvnYZYzU/7KeLmdfxpT/PCPWp0SjA1icuYdb3R8+eHOrTHc8ths+euQTOPXEcbL12KfXc+7+LG3DlvQPMG/D7L42DbdctGfv0o0uWw9V3W3Dvb8ZBT0+wFiRdI/59fxl+dPFyNvde+vP00Dhde58DP/i76+3hwHEx9WnzLy5nHrpHfz820Tg9+1oBjv7FB/CHL/fCNmuXEo3TZXcvhu/8fQkbp/lLbDj+t4NwySlTYf3VG6G5990LynDVA4vhiwf2wmf3csvQDAwUYaevL4ZDd7bh1CODdur6dO9zVTjhbGyDA/edNQb+fusg/P469/uX/jirLZZqdy3Qzz31feLv/V9OnAof2rBP9nhXHNjp5OWw+vQCXPm93szWPQwpvO1nk2H7ry6ESrkHnvrjhETW92+fPwg3P+zAY+eO9ft07YNl+P4FVbbunfaxPByyQ09b1vI9Tn0f3vigDPtuWYKfHjMu1Cc+r9OM01sfNGD6hB6Y1F9Kve7t8b258MY8G848bhzMnJKDjWaNiXyfPro7wCmHjs1k3eNz5slzVoQClKAO1cg1gh9/4w9XgDWm94b6VC4XYYevLoYN1qjChV+b2NI4iX1y7xt4vA/9UA5O897XTnt+Lr9rEH52+QB84+CJ8Nm9x7YkR2x+4gLYYrWxcOEpY2LHaePV8nDR16e01KeHXqrCcWctheP3ngBfO2R85PvExxrfBbVPf/jPcvjzDWWwGn3w7J8msfac/KclcMdTNXj8d1ONc2+z45dJHm+8Nh+nPb87D15/r5pIjnh5rgUH/fRd+MVnxjAOi12/tQAWLy3CPb9YAfr6y8Y+cZx1zXL4240Af/vaWNh4DSd2nL55/jK45eEcPP3HCZl7Hc+7eQB+f3Udbv3pCjBlUpWN03Nz6vCxM1DuKMFLf57Gxmneogbs+91F8IX9++DLB0xqi1x+7n+Ww5/+U4VNZ4+Bi745JlWfllYH4R93DsAZVwzAt47oh0/sMj7R+3Tc2YvhoRfr8PwfVgr16cRzF8M9Txbg+T9NjuzTjQ9X4NQLlvlrBI7T+8sqsMs3FrJjHz9nhSHxDvfmSrD+8QuZx7vTMmxWfZo7/11YeYUZiRTvtoeaY5g4/kuDv/71r0zpvuiii2KVbkRPTw/7pwIHB/+J4KEOKnBgtJ8X9fUb1etGfZ638trPcbB0n+Pg4j8VOPD4byzWxm3g4OExNegt9MA4TYJut/UJNx8MehO/532SsZQpqoiVJ/ZJx4t9shoDxj5Zjvsd3lPXB/ybnz8ef7eslsepF0OIoMb6M86jMd1+bYwqqrHw3Vt+Mo39HFfKZzZOvA+OjQup/KzaMfdUFK0esBoN73lWjX0a9Erc4WKvu29fDs+vwdgCvrOlJubeUhYSCI0+6M/L11D7lGOLbAX6SyXo1+SLx60RfbkcWAKJgDpOOShLcw/JAcX2qm23AMfQSjFOGCZeCPUzapx68jhOfTChZwwszzfAcurGuWcBCoq9bEz4veteykoJwmuq2qeikwcL8PoWTOrth748zs3s5544TtJaEPM+8WNxHoXaDg5YMMjymrNc9wqOez2nPpC4T+x+7DlWpT71WjmwvOTS8T34zve2ZS3PWwXW9hL0SN/zPqnXS9Kn9WY0v+69Mw/nMMAeG02QyKpM71NfLrzWNDv3+JzhfSlC9BrBjy9611T71PDep/VmjIt9n9LMPfE9wDUib8tjJ/ZJRdayUQ+mxTQc+PC27v7ayvvE+uUkG6eCU/D70myfxhXxWnWwILxGqH3lz5wfI/YJK7paDQuO26/P71MR6myv5PfS92kZSwVac1ovvPy2u7/6z8wpgdUIPzddn8b3N9havtmq45nckWsMoreNOUCSrBE9lrselvIFX6aJGqdP7VaEBQuXt7SWm/rU68l1mA/Mn93YovssxbaXe2ywGhXoL/RD3ktdzFouH1NAuc6CJ16tp+7TuFIfjC+57wbu4f41Y96nXx7bA/c9V9P2qYAyJrjfRfWpL59n8prYp3FF/KwsPe9OrREiGJfIEMiw7dYJh0WO94UXXshqd6PSffjhcigFASRCh+FYHzNteEWzjOONFDfqFYS4VuAzSxqYoldZsX0MEkPOah7D6hFH+sEtiE0zHgunxT0KrjPriPwS3Svt8V1A8pSG3Is3V2x1mqWm7BmVr/7+RMbAy8/ddeM2MoE1A02fUpQrTwVOMJX2unHj1V5Wc+gq1Dx5UVS6o9AN+2NcE9q9NEwaO3SDyKduVuR8Sd+dLO6W1Trgl53KNzfmF39jgl9poRmsPDUPz/1pis+uzteTpFU2uMMvKVEZEsb949vpHG1JwcciTiQMCO3a93K1StzmVxlJ0cSVpuTh0B1blCEjqpgQOocu21qBKd0oqJ5yyikwe/Zs/x/W9SY0/9IOVyRZ4I7etTc126iInoyFV924tLtOYZr+tgOtyrhRRou0iGO094WJDjFptus9tZowjLjEUzHX5azmYqmWFGVoeE35Pu+94qdst14GBeyH7Vhlp9GLRraeNprOu0BvbQo//PiYrmn/ULOan/jh5F6YrOGXsOqCcUiLNFUcosDHmVc3YZ+lNJy0Us4OwZVuhJPSoeGX3uwCTcEvT2coJ6ZCrPedNVqV53jbsjLKtzJNR4Me0W3oOo/3c889xxgwVaQNVx/J4IvmcNzQkgIXelSgkiz4VpMe4FMO7Ydf/HMgM4930J7w9bRlgTKEmHMyJGjRs8PHK4s5HTf2vMRO82WN4o6QG5D1yDdjpJg9zZUUxvfl4N2Fyaw0Uom2FA+L13LtLckCUyvl6toCJ8LLm/HrZHnXPeMz4+CRl+W63GkhvupZGw272eOdFDMm57tHWRhixTtpdEBboNSObvlyHdziuFG21XvyOSh6X6dNGrqJucQr95W0DCGfv6LyPlTo8Z6h+F7rWlWrOx3weLvXRv6LZoCs8ojMWphwnmrvN/RDO+rQbaIQrLqqx0pFSGAtG34PKclGtsdmJdhyrSL87PLliRRo3XNIUr8US3BlWQvXMbRni7UKcLCmXmdWwPYPWag5VwJjDrPa7PGWQs1jHgb3iLdqbV51xWQCVDe8pxvOLsCTv5/CQpNfCghuIyHXRucfxp836KXccY93VygBEcqwCN7PrJVO3vP9t+5h/1qBOL2zNhqK6AJZu6XauGXPADSUMD3CYfpoM9kPhwO4YtXqvqqr4/2Nw8bAR7ZrbQ1oFUkNqTttWITzbpLJpIYKXE4TI9p06/SEMe6H26zTvtQmft/N1ii2JMNnZpTK5jKEDqELbMKEZq1lK03OSYLGSMHvvzQetl+vKIWtRkHX+yN26oW9No+2Rrr1DLPPk1QFjUu/ORGO+FD7FO/ZK+Zhny2HZiOfPJ7XiI05sIMe77j8/rhQ9KT4wcdlFnIOVUbplreTz3MnaY63MJHTCAhqqDkPc9dw8wwpdHON9zlrpbPZ662xUj7a402Kdwirz3CfGZJSdaNxh33eLYtCG+EbU7O6HnQO/H21W9S8uYLLeXn4Orzxal22GBqw7bpFOP/k8bDhqkPvo9tl4xKrZjChPzpsv6/HghfPm+pHebUDnB+m2ZDzoYpaFdede381OVMOBkJyDP3bREgN/rLj4n3/b/ph8rjhYz9Jajgd22dJbNhR0Akx0yfn4XdfHA8PPF81KtY8JKnbPHFpcMWpExiByuRxFvz8U3pFsJ04fMceWHflfMs5TzzvOguPt1ABwnCvbES4ZsnZWkWbK0BqydXShO1+eNseuP/5Wigyp52hf1kTAmatGDV7vRMO7GdGRBnB+PNw/nagG0gBm8H4fneyVrvC422KNYcRDz/He/iIJ+Ecb8je4z2U+M+PJqZah3EN2HGD7uDmQHKx238elCJFDNUSxfPMm5V7ss4/b0YkmDrBneTDdJkf1uiS5YCQBj75UQ6GldKdBmO9nOiBJB7viIVjm3VLsR7vrELNhwKbrB40figWULToYxveXdgY0lBzceNx2uzx9r3zCc3V7Qp5tdqsLOhCzZPcEw1BF359QuhckWCoGxA117JuabPzGkNeec6yzrDUVmNGdw1XKvz7exNhRU+wHM2s5kOJgNU8o+t10I6SFddDwG/RHQO95kok8mfr8bZailrNCkl9CSN5vRlOGPqdiTCqcvCS7mOBxzv+2GYfAyc5aXbxJCQf2LgFn3tx48qSmc9Pvgm16vD2y5EltHZXWuPSMra/XR5JHat5K/fi4bbd4vVJsn6aQoSbwSHb98B3j84uGsXpULWE4bwqrr9KwffodCWr+bB+usnA1/SslqlOKt6FjHO8s/RwYkQRAaS5tdXahaFhWM+1VpmIO39aBY/ejIPuVRz5K1H3octEIUKal34kW6+4MjyYwOPNmTrT4uO79fq55ITWwAWUzdbQLylxc3X29HxmjK9xm2Grmx0PVTcpbu0WEHn6RX9PmxTv0C+tgXtou8XrwxEVApulUfNnnx6X3cWU+dWpkniE4VVODPe2e57J2OLXLLrrtU+1NthtYDVPApRL7n1OP35fPKCf/SME79Eh27ePQ0cHbvAUc/fTgJ+XhAQ4Car1dMf/5Svj/d+7RY+4/eeT2l52t1tAivcwBH9PuqFcSruRRLlYniAP3BTGudZMegWyAB+Bw0P5qC7iRnH16QVGiNL0/b0GHLVzL2PFb2eOd+Dx1veq3Y6ZAS8KpK9Njo+AXM38XRoEXArQVYhSrpuNvOgExOnLPXPtQBc/gmEDs8e7vfhehhEWrZOrWaO2jve4vlxTxJInHdQP4/sHW7v5KAA36naap4ez3nPPdVpwBZNX1umYx9t7TCtOzHXdOj9zyijRuknxHp4IQkG75I1pEy7+xgRG3BWHrMJ1WkUXVNwYMQy2zeLg7Xtia45uukYRHnwxpYlYs9kPFWkQZ21uWw5rRD73Gt6906DW6E6PdxS6emkVPd65DjyDbn4WXY6hruM9lGiVt0PFGI/3JRYZ3C+XleLtMXCnzendfM0i+0dI5unt6TD/G193m1W8eepBHBFs2j02KUazrNoNIHffMARXuIfj5p3mhd9q7WQbTz2uflSHMRzHpd1CVrufSRrF/+SD++H4/fpa93jnhi5/tZXogDhYBqXhnl9Nhqnj0w9kt1YPiDKcdJt33ujxbqOTYDhyiHQbhmo97Ab0e4pyFvMIQ2PXm5VQXM1AHODG21YVlKzZqwn6tCteunLYhJp7hpisZFc0wjdbPnEULEVdB1oWhiMEVnNCdlbDVjGarYhOrKBpDen9VaGKk/c1A5sTwQ3T92/dlQtMsVxTUyM6KtR8hSY97L7Hu8uUWVPE0GlHjYGdN+qOEjqxOd7tDDVv25VHPtAjhga6WFbzEfyUsQzejEk5YznPNNhpw9KQeDRbzvG2si1hSZAxY7I7UKt7HDGdQlCfvTvI1X57/Dh4e0GTgvDIXYK6FqR4D0OYPFKjFWnDbNqN0TgsTot1uLstrDGZx9uQ4y3IWEg2V2s+qr0twBKET/3B7DH3I4wzepa8/90Wam7q3zF7NB8N0QmIInxbydX48yGdITVwaWDb0hDleHcD0Bu426ZDwMBtZal4O5koaF0WlDdigLW92xn9ZYTTWlmwgFwtm+ZMGJNj/5KmPnRb9NloAynewxCjgdU8Dbot1Hw0os8jwRNJO3RYZ2Z+yD3erYJvlkk83pd9eyIMNwQe72we5nAkVxsOZZrane5A+0vzYGtDI4KHZZjOvdGCrMjV1p6ZhzE9FosyIowccINMoVVytQ7LrtutW2TcSasJEQK0FHUetBoMQ5DHuzvJ1UYzUOG++aeTYPa0fCJisHahE4SDPLXBtOkOdzOQr3hn/H52m8d7uKYKiKk13KPWDvArH7Qd1Q1OCz4sptHprjeBoCKr9wq9kI+dM4Ue8AgDN8iYKpt02uOdFGhMV7mT+H4/GqokdQvoUQ9rVvOhbkl3oJqwlAKhvYhTutup7HQ21Hx453jHIfNQc8+qX+oyM2+n8wKzAl/tHjhzclvvw8e/0/m1I0lxM60RFE3Q3fBDzbuEP4bQXUgT9daJHO9WQIp35zFCRceRDa5ktNPb0Q7suVkJvnPUmMyut++WrkDYbTm0BDPy7ZI4O6h4c56cLGsobzi7i7TSjA17vORLt61XzXorumb9H57NH1WKm9HjbSAwJHRZqPlQN4QwItdgHi3XaY93FNpZIYMgo4ukPUI35rNmiXO+NL4t1+UetW7BcBuXTqJdZFD+OwFDb+1Omxd47J69cPiOvdAtyJ5crbvez+EOu0OKNy1j7edhoWfcnciK1ZwwMtHqGsz5U7pB2bU6UCGDIIMU72EMyslwQR7v4YN2z9mOeLzt6L6s5ZXpejxhbt+pR46FbkLWpd9Gc5m9tkZ3tP1dIkGs5Rxv4lYbluBzn1frIBCyTm37zefHwa6blLon1LwLjACjBaR4D+eXHkY3uNWRFO/hg3ZZVTsZfht3r+3WK8ET50zxmd6HLYdERorddz46FnbcoJrNxQiCt6W98yvq8itNzsGma5D4YAI3ypnWCLJptA9ZPluyGRJ0WNMzrmNpzmax/9bdRVrZzgoZBBm0cw5DdJJIajig2mWh5oTOe7wdT0TqZI53lEdwuCrd7aiagIz3R3yoe0Lphzs6mVZhwv/OaC+x23CHy2fgmD3ebVqojtuvD559c3STnmQZYUPROgQd1lm5MDT1w9sAvhblhynnyXAEKd7DEKR4y8+hVhvK0SCkwYzJ7dG8edRDsQObB6/hOVJTPYKqCbQRdze5ZnvvQ8PfPPgy1Olw/a8dkh15KSFY6wmEkQ7yeHcOpHgPQzjeZjDaBWO+J267nlyXkNCd+Pf3JsLaM/NtLSlX6sBUGC2s0qN8eel6ZaDd4/PF/ftG/BxvF0ZqqcHRBtK7CaMFI9WR0I0gxXsYgkdWj/bNfcIYVyo86/hx0A2gTToa66/SvuWGe7xLhQ54vO2RrZhmneNNyBgdMvxss26J/SOkBxksRkiOdwKH9xWnToBX3+2CgswEQgugUPPOgRTvYYiRLvgnxalHjYEPb9sDxQ4oWyO5zNtIAC9ZVSp0Lsd75Ieaw7ABlmWpjxLZN+AYGOqWjB6ccmg/PPBC8pympEYrGsPuxoQx8QO5yepF9o9AGM6gUPPOgRTvYYzhJBi3A2N7c7BtF3pkRvmwDAmqnse7p9j+pz/SORayruPdCUybmIO5H4yO2j+jJdWhm/C5ffvhc/smP360p4GNBFx0ygTYYFUSkQmjA1ROrHOgVWUYouHJlyR4EQiyx7vYQY/3SK1zPBw93hd/YwK8Nm90uLyDyJphNECjDCM1GmY0Yet1yItNGD0oDKcNf5iDFO9hCAo1JBD0Hu9OKCMjPZd/OCreK03Js3+jKdWI0L0YTu/OSMM2pDATCKlBHu/OgRTv4QgiV+tKrDjBdXOM7SOpq9OodbCW+0gvMROEmtM87kZsu24R/nzj4FA3gxABIiYcGjz5+ykd4fkgEEYaKEqnc6AlahiCC/6UR9Zd2GKtItz2s0kwY/Lo8Lx1EzireScwwvVuX/Mmvbs7sdOGJXjxvKlD3QxCBMjjPTToLZGxkEBoBkSu1jlQJtIwDjWnzb37sPJUUrqHAryOdycw0kN9uehKXjsCoTnkkm7OpCcSCIQuAJUT6xxI8R6GmL2iq9yN66ddm0DotMebG75GKniIORn2CITmQGGbBAJhOIE83p0DhZoPQ2y6RhEeP2cK9PeQ4k0gdNrjvdq0kR3VwEPMKdScQGgOSaNF1ptFIhiBQBh6ELla50Cr/jAFKd0EwtB4vD+/Xx98eLuekR9qTnY9AqEpJHl3Hj5rMowjIk4CgdAFyNOG3zGQ4k0gEIY9ao3OblAzR3DpquFYToxAGG5C7Ph+yvQjEAjdgcLIFWm6DrTyEwgEAiHE2p6YIIpAIEigNA0CgTCcQLwUnQMp3gQCYdhjpw2LQ92EEQOeLU/KA4HQHEiIJRAIwwkFMrR3DBRqTiAQhj3+dNJ4aIzwMl+d9niTv5tAaA5Uio9AIAwnELla50CKN4FAGBE5leRlygYfLHUtGBPGkOpNIDSDEw/sh97iID08AoEwLDBtIgVAdwqkeBMIBALBx0tzXYr42SO8bBqB0M6Sn+d8idJfCARC9+OKUyfAequQOtgpkImDQCAQCD7WmOFuwIU8ebwJBAKBQBjJ2GT1IpQKtN93CqR4EwgEAsHH944eA4/9bgo9EQKBQCAQCIQMQbEFBAKBQAg2hbxFNT0JBAKBQCAQMgZ5vAkEAoFAIBAIBAKBQGgjyONNIBAIBAKhq/HVQ/rBoZKBBAKBQBjGIMWbQCAQCARCV+P4/fqHugkEAoFAILQECjUnEAgEwqjCzhtRqScCgUAgEAidRVd7vBcuXAjXX389rLrqqrDTTjsNdXMIBAKBMMzx5O+nEHkcgUAgEAiEjqOrFe9PfepTcOONN8IBBxxAijeBQCAQWkZvieqVEggEAoFA6Dy6NtT87LPPhmXLlsHuu+8+1E0hEAgEAoFAIBAIBAJhZCnejz/+OJx++ulwwQUXgGWRd4JAIBAIBAKBQCAQCMMXXRdqvnz5cjjqqKOYx3vmzJmJzqlUKuwfx5IlS9rYQgKBQCAQCAQCgUAgELpI8X7iiSfgqaeeijxmzz33hGnTprHfv/SlL8H2228Phx56aOJ7oHf8hz/8YcttJRAIBAKBQCAQCAQCYdgp3i+99BIjSIvCFltswRTvO++8Ey699FL47W9/CxdddBH7bu7cuVAsFtnfBx98MIwZMyZ0/re//W346le/Knm8Z82a1YbeEAgEAoFAIBAIBAKB0GWK92GHHcb+JQEq1Ycffjjcfffd/mfvv/8+5PN5przvs88+WsW7p6eH/SMQCAQCgUAgEAgEAqHbYDmO40AXA0uJ9fb2wpVXXpn4nMWLF8PEiRNhzpw5MH78+La2j0AgEAgEAoFAIBAIow9LvEjrRYsWwYQJE4YXuVoWWLp0KftJ4eYEAoFAIBAIBAKBQGi3/jnsFe9dd92V5XinwUorrcS83ePGjeuqcmTcIkKe+O4GjdPwAI1T94PGaHiAxml4gMZpeIDGqftBYzQ8sGSY6E0YPI5KN+qfceh6xftrX/ta6nNyuRysvPLK0K3AydPNE4jggsZpeIDGqftBYzQ8QOM0PEDjNDxA49T9oDEaHhg/DPSmOE83R67tLSEQCAQCgUAgEAgEAmEUgxRvAoFAIBAIBAKBQCAQ2ghSvDsILHn2/e9/n0qfdTlonIYHaJy6HzRGwwM0TsMDNE7DAzRO3Q8ao+GBnhGoN3V9OTECgUAgEAgEAoFAIBCGM8jjTSAQCAQCgUAgEAgEQhtBijeBQCAQCAQCgUAgEAhtBCneBAKBQCAQCAQCgUAgtBGkeBMIBAKBQCAQCAQCgdBGkOJNIBAIBAKBQCAQCARCG0GKN4FAIBAIBAKBQCAQCG0EKd4EAoFAIBAIBAKBQCC0EaR4EwgEAoFAIBAIBAKB0EaQ4k0gEAgEAoFAIBAIBEIbQYo3gUAgEAgEAoFAIBAIbQQp3gQCgUAgEAgEAoFAILQRpHgTCAQCgUAgEAgEAoHQRpDiTSAQCAQCgUAgEAgEQhtBijeBQCAQCKMUL7/8Mpx99tnQaDSGrA1PPPEEnHnmmbBs2TL/s+uvv579IxAIBAJhpKAw1A0gEAgEAmE04eGHH4a7777b/7tQKMC0adNgxx13hBkzZhjPe/bZZ+GZZ56BRYsWwezZs2GrrbaCiRMnaq999NFHw4orrhjbluOPPx6mT58OJ554Yui7xYsXM+X3vffeg7322gvWX3/92Ou9+uqrcM0110CpVIIvfvGLkAR33XUXnHzyyXDYYYfB2LFj2We2bcORRx4JL7zwAsyaNSvRdQgEAoFA6GaQx5tAIBAIhA7illtuYYrmgw8+CK+//jo8/fTT8JOf/ARWWWUVOP3000PHo+K77777wqabbgoXXnghPPLII/Dd734XVlppJTjuuOO0137zzTdj23HjjTfCrbfeyq4lAtt00EEHwdprrw2/+93v/LbGoV6vw0c/+lF2/De+8Q1oBQceeCCss846obYRCAQCgTBcQR5vAoFAIBCGAF/96ldhyy239D286PE99dRTYY899mDebI7Pfe5zcOeddzJv9sYbb+x/fvXVV8OXvvSlpu9/1llnwQ477MAUXBEYdv6Zz3wGLr/8cvjvf//LlOAk+OlPf8oU/m222YYZE1rFscceC9/85jfhl7/8JUydOrXl6xEIBAKBMJQgjzeBQCAQCEOMXC4Hn/zkJ9nv6IVWPdPbb7+9pHQj0Ct98803N3W/d999F2666SY4/PDDQ9+tscYa8OEPfxh6enoSXw+NAui1P+ecc0Lh7yIcx4HbbrsNzj33XNYvNDiYgIaISqUCl1xySeJ2EAgEAoHQrSDFm0AgEAiELkA+n2c/VaKzyZMnw9tvv82UVhVJ8q51+N///seU3u222w5axeDgIDMaoCHgkEMOMR63dOlS2G233dhxqHz/+c9/hr333hsGBga0x8+cOZOF36uGCAKBQCAQhiMo1JxAIBAIhC7Av//9b/YTSdZEIEnZ9773Pdhvv/1Y2Dkqy1EkbEnw6KOPtqS4i/jWt77FPOioTEfhlFNOgfvuu4/li3PvPf59xBFHGM/ZcMMNmTedQCAQCIThDlK8CQQCgUAYAlx66aWMgbxcLjNmbwwbxxzvnXfeWToOCcZWXXVV5iE+6qijoFarwcorrwz7778/fOc732G/p8W8efMY8zhnEW8WqGxjObK//OUvjB3dBAwZv+CCCxj5mhgyj0YEzAl/6623tOdNmTIF3n///ZbaSCAQCARCN4BCzQkEAoFAGAK88847jEH8pZdeYrWsV199dfj4xz+uPRZDuVE5x1rXeCx6wS+77DLmEX7ttddS3xvD1i3Laqn9WG4MCdB23313+NSnPhV57CuvvMIMDJtssknoO91nYu47hsTrwuwJBAKBQBhOII83gUAgEAhDzGqOSiwyjGPO85NPPmkkKEMvNXqM8d9mm23Gyoyhx/nXv/51qnuvsMIKzAuN+dX9/f1N54nPmTOH5XWfeeaZ/udvvPEG88rjZ1hv/CMf+YhPosbz2EVgHXMTPvjgA8Zo3qqRgEAgEAiEoQZ5vAkEAoFAGGJMmDAB/vjHPzJF9vvf/770nSkMm3uK8Zy04OHeL774IjQL9NB/+ctfZr+j557/Q7I19FDj7xjSjlhttdWYgv3888+HrvPcc88Z74HHR3nECQQCgUAYLiCPN4FAIBAIXQD0eB9wwAGs1NbJJ5/MvMWInXbaCf70pz/BnnvuKR2PdbYR2267bep77bLLLuznAw88AJtuumlT7d1oo40kT7eoLM+fP1/6bsyYMXDwwQfDxRdfDKeddhqstNJKfgi6qSQaertffvll+OxnP9tU+wgEAoFA6CaQ4k0gEAgEQpcAa2Fff/318IMf/AD+9re/sc/WXXdd2GeffRjbOZbjQiAz+A033MCU2RNOOCH1fZCsDa/3r3/9C4477jjpOyxnhuHriGeffZb9ROV40aJF7HdUhJshZfvtb3/LiOO22morlsuO90FW8y984QusvyqwbRiafvTRR6e+F4FAIBAI3QZSvAkEAoFA6CBQ8cQQ7WnTpoW+w7Dq3/zmN/Dmm28yMrLe3l6mYGO4OTKIv/rqqywvG73fqKRjnnfSa6s48cQTmVI7d+5cVjObg4eJIzD/Wwwn19UZV4HGAF14OJZAe/zxxxmbO4a4Y6g6MrY/9dRTsHDhQhg3bpx0/IUXXggHHnggzJo1K7YvBAKBQCB0OyyHqEIJBAKBQBh1wO0fFXUs6cU93N0CZHBH7z4yuGdRa5xAIBAIhKEGkasRCAQCgTAKgUzhmE+OXu04L3angR7/3//+96R0EwgEAmHEgDzeBAKBQCAQCAQCgUAgtBHk8SYQCAQCgUAgEAgEAqGNIMWbQCAQCAQCgUAgEAiENoIUbwKBQCAQCAQCgUAgENoIUrwJBAKBQCAQCAQCgUBoI0ZkHW/btuHtt99mNUGRtZVAIBAIBAKBQCAQCISsS3MuXboUVlppJcjlcqNP8Uale9asWUPdDAKBQCAQCAQCgUAgjHDMmTMHVl555dGneKOnmz+A8ePHD3VzCAQCgUAgEAgEAoEwwrBkyRLm8OX656hTvHl4OSrdpHgTCAQCgUAgEAgEAqFdSJLeTORqBAKBQCAQCAQCgUAgtBGkeBMIBAKBQCAQCAQCgdBGkOJNIBAIBAKBQCAQCARCG0GKN4FAIBAIBAKBQCAQCG0EKd4EAoFAIBAIBAKBQCC0EaR4EwgEAoFAIBAIBAKB0EaQ4k0gEAgEAsHHwN9XhNrjP6cnQiAQCARChiDFm0AgEAgEQoD6ANRf/Bs9EQKBQCAQMgQp3gQCgUAgEAgEAoFAILQRpHgTCAQCgUCQYVn0RAgEAoFAyBCkeBMIBAKBQJDhOPRECAQCgUDIEKR4EwgEAoFAIBAIBAKB0EaQ4k0gEAgEAoFAIBAIBEIbQYo3gUAgEAgEBsdu0JMgEAgEAqENKLTjogQCgUAgEIYXGm/9F+z5D7PfHbsy1M0hEAgEAmFEgRRvAoFAIBAIUPnvwcFTqC6lJ0IgEAgEQoagUHMCgUAgEAgS8rMPoidCIBAIBEKGIMWbQCAQCASCIh2U6IkQCAQCgZAhSPEmEAgEAoEgw67TEyEQCAQCIUOQ4k0gEAgEQoZovPcg2ItfGt7P1KkNdQsIXQynuhgac24c6mYQCATCsAIp3gQCgUAgZIjK9btB+arNhvczJY83IQLV+0+Byi2H0TMiEBKg8dbNYC94mp4VYWgU7zfffBMefvhhePvtt43HvPvuu/DQQw/BBx980NG2EQgEAoEw6kGKNyEK1UX0fAjDEk55fsfvWfnvIVC+etuO35cwyhVvVLi32mor2GyzzeD444+HddddF3bddVdJubZtG4477jiYPXs2HHvssTBz5kw47bTTOtlMAoFAIBCGPeqv/wucejnRsY23b5c/cBrtaRRhRMAhwwxhGKL+6uUweOnsoW4GYRSjo4r3KaecAvV6Hd566y3m8X799dfh1VdfhR//+Mf+MX/4wx/gsssug8cffxyeeeYZuP322+EXv/gFXHXVVZ1sKoFAIBAIqVF7+uyueGqO40D19k9A/Zlk7Wm8ca18PilWhMgJRuR7hOEHHu6N6yOBMOIV7/fffx823XRT6OvrY39PnjwZ1ltvPfY5x/nnnw+HH34484YjtttuO9h9993Z54TOw6ksBKe2nB49gUAgJEDtoW93x3NybPdHfSDZ4bVlygekWBGiJgxFRBCGIeyq9wsp3oRRoHhjyPgNN9wAZ599Ntx6663wf//3f/Dkk08yTzii0WjAU089BVtssYV03tZbbw2PPfaY8bqVSgWWLFki/SNkg8FLZkH52g/R4yQQCIQYdIMXxbFrUHvmHACbs5Ina5Mz+K78AXm8CVGg+UEYjmh4incXrNWE0YlCJ2+GCvQBBxwA3//+91kON4aZf+5zn4P111+ffb906VKo1WowZcoU6Tz8e8GCBcbrnn766fDDH/6w7e0frXAWvzDUTSAQCITuR23pULcAGm/+B2oPfhNyK26T6jz7g8flD8jj3VVovP8IWPkeyE3esCsMTPa8e4a6GQRCatRf/Kv3GynehFHg8T766KPh+eefZyRrjz76KLzyyitw/fXXw0knncS+LxaL7Ge5LJPBDA4OQqlUMl7329/+NixevNj/N2fOHBhpcBoVqL96xVA3g0AgEAgRqTlDD0cJqUyIimLctimUuJtQuW7nrmFFdpa/NdRNIBBSw8H0m5SRQJnCogrOhA4q3hhGjmHmxxxzDIwdO9b3ZH/0ox+Fa665hv09ZswY9tncuXOlc/HvVVZZxXjtnp4eGD9+vPRvpKH+1G+gesenmAJOIBAIhC6EqrwOBbhwxwXMJkIqCxt/HZO+M24YYcSAFAjCcITIYzEUoeZWvvP3JIxexTufzzMyNWQ0F4He6RVWWMH/e88994Rrr71WUtjRK46fj2Y4y+d2fV5K0rI1BAKBMBJRe+LnQ90ElO5a9lhbpUnEak4wI200BYHQBQgRSHYaZLAidDrHG0PKf/aznzGP9MYbbwz3338//PWvf2UlxDi++93vslxwrOWN+eB///vfWe731772tVE9YI4fFuN07YI2eNF06Nn7OsivtMtQN4dAIBAyhTPwLkDfNLAsT7HVoPHmdd3n8W5mz8iXiDyLYEaDjOyE4W4wGgpZmkLNCR2eBd/5znfgggsuYAzlZ5xxBsvxvu666+Czn/2sfwwSrd13331QrVbhzDPPZF5yVNBnzpw5usery0t3NN650/tlcKibQiAQCJmTSQ1etiY0hgHPhuUp3k5ar2TvVCjtfD707HsTQK5A5GqEeGZoAmG4ytFDEmpOijehwx5vxKGHHsr+RWGjjTZinvDRDAdLddSXg1WawD/g30C3YfDq7QMLeL53qJtDIBAI2cJj+HaWvjIMniwPNU9ZNgf3nHwv5KfvAM7iF4lcjWCEU6OSrYRhCF+OZn+0/XbVB0+FwjrHQm7C2u4Hhb6235PQ/SDzS5ei9uC3YPDimeEFowtzvJ0FT7qCWpe2j0AgEFoCD9u2Om6rbp7Ap7bc+8DR1vrWKt68f8zjTeRq3YJuqA8vwil/AKMZ3TYehGYiR9s/hvUXzgd7/qPgDL7H/s6Nnd32exK6H6R4dyns+Y/JHwyxxzv5RkMbEoFAGFmo3ndyoJDGIDdzDxhauGtw9Z4var0sTmURDF4wCRrvPQj20jegMfcW74s6WH7/LDKiDjEqtx4Fjbm3sd+dhc9AV6E+OKqjEQf/Ng5qz5831E0ZMWi8/xAM/nubERVq7iC5ZX0ZiwZtzL2VfWaNmUmklQRSvLsWakjKkOd4k+JNIBBGJxovX5yoHIw1bnUorHoQDHmakgCrMFb+vrbU/bnoeajcsA9Ubv6I+wWelyvys8iIOsRAor7aYz9hv9vzH5aMQPWXLobKrR8d8tSL0Qj7vQfYT6plnh3qz/+lM8YlSdlus5MIlW6v2g+fK403robaQ6e2976ErscwiJsbpfAUbadRBQsZZoc6xxvvryGGCHnCKQSrPY+/soCVlMtN3qg9NyAQCK3XYcUQbl95HSKoYeQhoy1nZbfBKb/vHoLrNipTvH/I3E5r+dDDGw97ccAtUH/+zwC9/wIozx+6dinGnVEFryQVltwjZARNpQi2Jtko//YMy1Bzp+oaOKFRAac+4H9uf/A4jDTU37gOcmNmQm7qZkPdlGEBCjXvVngLxOBF08AZnAf24he8z4dQ8dbAfucO9cCONGe0oXLb0VC+eruhbgaBMLoRo3gzJvFcCYYUgpCn9U5yAyruJZwUk6/vYqg5reVdVBpOZhG3ih7p6hDBGcUeb8d/Z0bvM8geYcW79ugPYfDCKZnexekkq3mdK95ludpPnPF2mKD+6hXMIYSo3nYUlK/daaibNGxAine3ggtCdg0G/7W1EIYzVIqtk6yep7CYsRCbyqI2t2t0wBmYl921HBsG/joWyv/ZM7NrEggjGtzrElcukXm8hzaQzKlzUrVo76SvQLgnuT85uRrzQJERdShgD7wDlVuOkIV0tTRcaVzmJF+YooB7QzqywaEVIRtzboTGWzd39qZ2pUvS/0ae4i3O57aMa4THG3Oy7WVzMvd4s3VW5EQY4v0hK1Tv+BRUH/jWUDdjWIIU726FuEBUuoBB1LQhh8qHBYtZ5aYDYfCSlWGkoHzTQWAvfX1obp5huFXjzf+wn/a8+zK7JiEd7OVzmXBN7LjDA/mVXMI0a8I6CRTvIfZ4+2zmBu+kt5bXn/19WJHyhcIchZoPEepP/hoac9w1GnL5gIVemFdWcbz7S3VxZvcdvGAi1O79crKDkTgKkR/a8kiVWw6Dyn8P6exNG6R4d0Tu1VVeyFKOVYxW9afPhPIV62V3r5oYai56vIc4FSlLqEZeQiKQ4t2tMCm6XRZqrjnQ/81+b+Qodui9t9++FRqvXDYk97eyrI8+xF6K4YD6q1dC49172nb98uXruMK16skidCUcSO4JRE6O/FrHQH51z2vZaYQ83qpnzu2LIxoRPa+45Xu8U/SZ0L6IBT4eqOwV+oOPS67i7Sx7M9N7+wz38Y3kv8Bog+Mp3iqJISGDHG/xmbZF8TZHKdiL3HTOrIzhfq17FmoepP8ElSNGABLqBZguW/7vYfTOeCAJvEsh5aLI33S4JTH35dZfftRIJeThngUvxK/jKLiKd+JQwAhYRZnluJnSHwN/nw4jFUhoWL3jWKje9Xn2d/31q2HwsrXac7NRXJZnWMEXAmPWN5bjXRzSUG2RyMf7QPmb7y1O+BgqJ9YFEMZFCDW3BMUbSm6Od/ma7bO9tXfdWIxmpZM83u2D00nF29E7JLLy4vqh5qrHe/jneLNSae4viY6vv3I52G/dCMCNEaMcpHh3K7pN8Ta8YA7Pdwo+gZEIp7ZYDvHjnw++xxaVtoOH9KlCdTNoMTetgf2tL2P5dSMR9vtuuZjc9B3Zz/oLfwFn4J323EzlSCB0J7gwFmFYZMIIrpO5IljMZTxEHmNRcERlTVWSdO3ighSRqw09hAgFiwvpjark8fY94RkaG9lleyYmbKOnFI1UQ3sixZsiQjKHqGxnrHgPXr09NF77p/CJWpGnnumezMs2Ml4QUfH2nCjDGt7YoIPQV8IjHENcftaR6I1GkOLdrQiFB3ZpqLni8ebtsxe/CCMJDvd4F2WPd+XuL0L1zk+3/f5+SQ0lf7MptLyhOX5+3YiE94wtPtZtLA8lEVwRuhaO/95FCNs8bQBzcYewHFfQVm+9Mnq8hY905GqjUakSYC97E2pPnQn1VztgWDWNj+eFYznehb72eQM9duKkbOndsG7xUngdB+97l3v97SVBCbpuBzNUKvOazfkM4Sx4EurPn+f/PXjJKiyazYe/bma07omh5sIabPWPAN4jn2DQDn6Peieq3rMgQkIGUry7Ft1mTTWFmqs5qp7iveBpGElovHEt+6nWlHSWv9WZBng53iHG4ha8G7lpTYYpjnBLv5+75/XTamdd5jiWbEJ3gAtlUcqo926ykGCmMA2R4lpfDrlZ+7Jfc0gGl8jjrQk1H6HRS0lR/d8xUHv4O1C9o/2GVQmicMrHg9UzFjzejquU5Fc7NJtb8prgSUPNMfKK7YVDN0cw2mxI7ssNbF2sRDTevh3K/9wEnIF3YVjAk6skg047Qs0V2AsDObXxpivjZWVwdLx674wTQIxi6Z8Gwx7iOyDuL4Z3wvEV75EtOyYFKd7dimEQao61pRvz7tG2TyLuGQGoP/Vr7zcHGvPuZeW4WFgNF1jaDe7tyCL/yBPapNDFVOdnJ3DYS9+ArgN/Ptz45Qm/WVngJR6EupqqQehKJCCT8j3NjENh6ELNMccbFe7+Ty0Dq3cyI7aJNRb65aHEcmJDA3yOnMBqSDFk0WWCICuWEyv2ty3Umxt0VcOy+fhBgMKYoVW8h6pUqV/Hu3sVb/u9BzPjhOkIuHFblG86QDyaGzMz9JlT+SDMk9EMqnqP90gIt3YafP3B9CqxNrrJ4+29q8NlPrYZI4heb4TBNk3Qzm10MlFauD2NN64JfVZFZXyVA8AaMwtGInAjs+fe6v1hs0W6E+ACEbeitgQv38ieewvbYJzlb7PNITd5w0SnZ8XmilbQ8pUbQM8eV0De89B1BRSPdyAUDAKUMvB+CxuVQx7v4QE+F6IEB8HjjYz4zqJnO9S4cDs4EVfj9X+Hvq7e//XwOZ7AZHnlq1zDwdAoVYMXTYPc1M2h98A7YUgxVOzDYpqZn+Ndk8PA/TU4I0HWW5OcpPJFY4DNsSwisJpF/ZVLh+bGwyDH2176WtcbB3QeUSlNpgMebxCjSDyU/7UVWGNXgb7Dn80ox7siy0xdPG+aqmUvlYCrR4+vY48As0PrII93FwInp7PcUCakk8KQZMlKvlg03rwO6s/9AUYk8Pk3xDAbTjLR5nHhAlgGllgxRI+VebhqUyhfvW3yC2S1IXrCvi8kpDnVcVjUQePt/0H7FG9vTHn93KwYyMXn1wW5koQE8Ne/CI83fzeLY4dO6ebtYN5I5XM/nFxjPOLfWd0Ram7PfxSGHEPFPizleOs93n70TVb7Dr9n0uvVcI71DS0PgJeXnhQo/NvLWk8NC6IxujcVw1n6yrBSvP12Sh5vd45Xbj2qtUvXloK95FXDl3VtZEAWZfqY4m3l3PB5yRPcvfMmMXwZ2Fb0BMN84w6G4TIf2wxSvLsQ9rt3dcbaZ1Boas/9idWtFq1X9sKhEyS7AVb/DO83JJMQFh2Odi8o3liEQ/vTQwo9bUZwyiwETFO7M63S3o5a8d61G/MfZsq9b1zJyDvdEMmaSPEeJrDj3xcWjWKxCgSFjTVe5U4BvUZFWfEe/MeaMHjBRNfjoEsx4esXV8qHsBxa12CIPN5yKVGHhXXbS18Fq2eq/6n91k3+99nclO9lCevyNvTGnU4ibepP5ZbDoXzFuq2nDA0Dj7cz+P7wUnS4YqpxLKAjpxWg4l7+58b6L7ns0Y6ynkiu1jOFpfZIVVFGAGmls3wu+2nPuwcab/03ASm093mj4uoXI+AZtAJSvLsQ0blLbZ6w1UVQu/+rUH/xb9KiXX/5ErkVo+zF8S2iGI3glxYSQ2xqHRHG6k+c0fq1pJzPZhTvrDzejeav55/ThiXM24w5T4H9jhfympHiXXviF21jbiW0B4FHxI71NFuWBbnJGwP0TB7CUHNZKXIGPZIlx4H8Wp8wE0b5ymZuRAiISYElceqvXqmv6xt3br0Mlbu/BPb8x6D+cmvhz6w0j5jfbtdcob26GPIz99CckLHindQIWh/0DDhDOEdCxK7RcLzIqurtn8gox7t7FW8fw0Xx9saSp9LZGZbvtN+5Q/5AXBv9EmJtULwbVbBKE10eICk6Y/ivq7VHf+D/juVWQ9UxDPtn/dXLmH7hLJ8DoxmkeHcjoohl2v3Oei9I7YGvKyQvylQxkSiMVPBNtj4ADW6EkBTvNhOBcIbt/pWyZYNtyuNdz1jYqzUvdPk5qdkhCONsyEoLRoFkcoP4nChCl4ELDs+fF+Tuqagv88OBLQzDHaJoBtcAYCJOtLUEWvXn/qgpJzYMFIsmUXv+PBbNYi98hv3dePMaqN5xLNgiKWjCtdFe8CQ0XroAytfuBNW7PtdSu/Aa9jv/k/dZ7gXU1tjOONQ84VpsSmdoFpXbPw51DR9BJIQyRolIxHqnsB8NVRFLCW6kSpwPP5QYLoo3l5+8ud5Ax0+bYPWtGEq/YWSBGuBab/oukbNEuw4Pg3kTg9xKuwl/WfHzjb+fnuxp5ZKROI5UkOLdjYgQ2KoPn5YNwZYRtl4pUPPdUlqbhz28BaV61+f9TQJLdvhoo+cSc9McXhfdKys2lB7vtF7a2lO/1ZeX8xZj1UqKNdMHr9gAnKgcPs483o48TEPYWyZMp+L11d8JPhrv3NkVjLyVOz4FlVuO8OeqPe9eqD31G/3BdSScGhu8p/XBoYkMQo+3F2peWP+L8ncsJ09DlPnKP0ZVObH6C+ezn+V/bwP2/MeDUFOMaLIbruc5Yf+t0vhMaw1LsOv+upPlfULgIaJOGo93djneSAJYe/BbKU8SZJAERi6r1wvVb9Ug5p2PzOH2gqegK8HHxRT622UIFGBeGaJ9c93qXTGxx3vw0tlsjWgKdh0ssRKBf8/s9jVMAa2/chl0HJWF+s9NjgTuxPDOc7quXHJnQYp3FwLJGKwJ60Bph99pBaTG6/9q383FhVoieckZrc0jGVjftHLn57RRCNX7v+b/3s4NuHLLYWC/dz8LXfXrrbYAtbyQ9F1tGdS498uElN792sOnQUVTC9ekWKGS7ix7A+wPnjC30yeDaoPibRJWMvJg+go8kraRxzv8fCqLoHLjftAYCoFCQePVK6Ax5z+yEmaYt4yRl3s48lj+z0n1rjjl96F670ktKevMKIb/vHbkJm2gHIDXNl/f8tZ5DJfvhOKNRrahKB3mLH7J/91e+FSgqFgWlK/eBirX75ZcqWyjgYh5zZgyYgHovESZGXaShZo35t3nrssZe7yb8c766RGIBMZgq2dKNkZyb74igWL56u2gq9EFxstmPN7WuNVCERFZwepbIXmONzKSLzUQsxnyye3FL7t/MI+3Z4iVkN26Wr7pQKje+RnoNIwypMZwZy+bA44XWeQ7U2rtdB52P0Z0OTF72TKwc57CWChArrcX7HIZoB5MDqtUYv/sgQGphJf/+fLl0uZm9faCVSiwa4uw+voAcjlw8Hjx8zFj2HWdQfnFzo0dC069Dg62xz/YgtyYMeCUB8CulcCu9YFdsdw9t4QkK/guW9BYuhRyeP829Mletti9J1uTquwwp2pBHqb6fcY+OdUyO66w3vEsB63xxtWQ63Fch0pNCD3xfnWqVfYveAA5yPX3hz/vsnEqXzFb6JPXGT4ey+aBU3c/G7zmw9D/yXlt6VN93vMAFQty41YAWPoCNBYvACtfaqpPDnoJKgv8PtlLl/lzDFF74iyoPnw65GYeCRZ6vzTjZA9UmMPZKkKiPuH1c/xcYZzsZUtYOyzISeOEx7D2gRUeP69PldtPZte1B+vsmMj3Ke3cGxz03wF2mbzDInAbSxeBJbSn2blnL8PjLVZjGX9nilbaNaJL3qfydVtCfrWDoLjBd7XjlLZPjQ9eBnv+I+z5NxbOZRvUUK4R/jzgZVBwqAYb0jm8T/bSpeDgur1sGVsz2eGDS8CBvkTj1Hjlcqg9fT7k1/4qDF65ERTW/Rz0bP+zVH2CvKu8YBtxruK7in2wig57x/Gds5cH89sq4QIfrNlBvyxwGo78bNow9wYuXBlyM3aF3t0vCT7HZ4fPme83Ge+59uAA2AM4/7x1D/OoG3l3PVm2HBrzXgjtuf69NX2yl2E4qhulj20X25l27jE9CbvvzR9YXmHrvZMfA069Kq1LbLgZ+VrrawTz8tcAGssrwXPXvE+D/9oLrIIDVv9kcOpFZn/PYpzcfqVby+3lZcit8nFw3rwInEoZnKpghNWMk2OPDcaphTUC3x9xnKTxbnLdy3ott8tYfcVV/oZEhk3ZJz4HGosXQv3GTwLUXc+ovxa8cDUUt1rW1FrOZVi/KTDZtz/aS5Hpfhl7x5icIsiwTB4WZKO4PiG/Q+2l68HpWRV6d/w5ONU6QKknWGs9OcIerLa0Rojj5JQtcNi6tayjc6+xcB7YsAJY9fflcVq6FCAvj1Pt2cuDdWvALb9bvv0k6N3jCm2fpL52yfvUzDhFwXJGIEvWkiVLYMKECfDYGmvAuLy7GI877DBY8ac/hfdOOw2WXhmQqEw64QSYfOKJ8PZnPgODd9/tf77CT34C4w8/HN7cf3+ovexZsABgxnnnQf9OO8Grm28uTZJZ110HhRkz4LUttpDastojj0D9nXdgzgEHSJNp9UcfhYG77oJ3PvtZ//PimmvCKtdfDwt//RlY8MegLaXVyjDlyA9g6V3jYNk9QQhOu/s08/K/QP2+fWHeb1YK9an6yqMw94ggn80q2TD9q+9A5dUeWHB5wL5amFqDVe95FZZccQW8/53v+J/37bgjrPSXv8CCs8+Ghb8LPPvdNk7TT3xR26cVPvseDDzRD4tvmNSWPo350Mrw1pHHQ/2dYGGZctwMKE16GN49ey1wlg802ad+mH7iS1B5a0VYcFExNE4Lf/VpWPCne2L71Lfxcpi43yJY9vKXE/VpwkEAU894ITROk4+YD2MP/TrM+fQV0jhN/cw86D/0cnhzvxNbfp/Szr13v3AgLL/NC+0HgLE7LIFxOy2FhTfvDOVHX+6KNaJb3iccp/x4G+b9ZkbmferdeCbMvOK2rlkjpp38NjSW5GH+X6bF92m1WTD1yPuhVjwT5v/4F4nGafLnt4H3vv5FGHxyTNN9mn7ub8F6/TB496w1wRkYVMapEVrLTX1a9erTYcl5x8KCf4zv+Nx7Y4fVoT4/WJum/eJkGPvh49vyPuG6t9J534RltzwPC36HkQ3N7bl8jfjgsilQfa23xfdJM07fqkJx23/DWx85IuhTbw5W+tWGYPec1PIaMenjq8L73/tRork3Yd+F0L/JALz/93WhPnfpkK57vRtOhUkHPAGDi74Li849P/E4LbxtXyg/+GTm49RNazmO04RjvgLvfOeert+f3vnEJjDwYDnz9wn7VL1zZ5h3xrj4dS9Ghl3woz1g4cVzYvs0ZpfVYfofb4B3PrY+DDzcCM+9G7aG8hNzm+7TzH/8AYqrrgOvb7fbkM+9tOOE8l7P6hV49zczwRECnUaCbPTEJpvApk8+CYsXL4bx48ePXsV74dy5wQPoMk9qlMWm8uAPoDH3fiiudzxU/veJkPW9uPn3obj+8Zn1CUpFsJzlrrdm8cuM4AXRd9TjUL5qE2YtLO1wNhRWO8zvk73wRRi8fEvoPfhRsPqns7IC9YdPAHv5u773pLTtr6H6+P/B2GNfi7RCle/4Eguh7//4O103TuUrpmu9+Gw8nKJr1fSQpce7+tBXofb0BdC7z01Qvu0ollNTWPtQsN+4Ekp73Aa5Ses31ScME6zetjfAhI3Afu9psCau79YctgDGHrcUBv6xIdiL3oC+Q590Q7IUayGGh2M4LLbD6u2B3iPmGvtUvvXjYM91S01Yvf0w5th5ssd7yWtQuWE7KG1xGuTXPFHK763eeQT07H8T5MZuou3T4D8/xEiNSjv9CQqrHpipBbT8wA+h/tgvg8t4lurCFmdCYfWgpmhT1ndoQOX2k8DB8KuBuZCbugX07nnesLXqDl42nRHc9R0+VztOafpkDyyEgQtXCZq+0Vegd4cfD6nHe+Aiz6BQHAuWtZRZ9Qvrfh2Km3w91Kfqgz+Fxrt3Qe9e/wZ7YC5Ur98Ceg56FKzSSsm8jvPvhPJ/DoHidudA9Z4TGJFi/1FPJe6TvfwdaMy5FBpPneGvEViNAlNiuMe79yMvQv31q6D24Le1Hm+2BrMw2nuhfMtHoe+wN9rs8Z7G0kX6P/YW+wyKBVj+pwlg9UyDvsMeh4F/rAGWtRzGfGZZZntuY/7LUP73Vt7BAD07/gycRg6q934Deg+4HcrX7SrvuTa2b66xT435j0D1v/v7Hu/+j73T1NzDtbV8+UqSxzs3bQcorHYI1F/8LVuTK3d/0yfCK6x3HED1dejZ9R8trxHlS6e6UUwr7uR7otT3ySkvgMErN3A93nmA3DonQ/2ps/xn08qey96z4jjoP/LFxOve4FVutI398jnQe+gLALkJkXOv+sA3oPHqhe5avs25UFjlI6nHCcXlwSs3BAuWMJ4RHCf+ziSZe51aywf/vR1A+TWwesdD78EvtUU2qj1yEjTmPw29e9/Wcp8GLtsM7IUvQ27admDPuy/wDnueVGvShtC3/3/Tex1LORi8aEUo7XI1SxmqP/cnKGxwEjRe+i27bn7N46G0xQ+gPudmqN5xjOTxxnEduHhlfMNhzOeXwMBfxoGTmwT9Rzyn7RPfK4qbfwN6tv4uDFyyAeSm7wL1Fy9kn/fscRE0XvgdWFM+BMUNT25ujaiXofzP2ZBf5xgobfpz/569H74X8jM2zHzuDVy2NkBtKfQf+7409wav3dlt6/IXpXHq3fcmyE3ZWPZ4P/4LqD31K/e2RYdlrTqFVaDv4AebnnvdKBstevttmDRzZiLFe0SHmuPg4D/ps149ORUOjPZzHHjDtXWwdJ/n89rPcbC0n1t1yI3ph9y4sWwhCI7Hfw7keuX7t9qn6qM/hvoTP4f+Ty0DqJX8e+ILgql+aFnP9Rake7I29jiQnzAJrN5xkB+3D9Qfsdxz8PyeyZCbMAVypYY0aUN9LZUgZy0BpwfD13rd8OYuGSeeR+z3Sb1GTz9Y1uJQ20x9TdWn6iIm+Fn9JfYTV7Vc/wosE88qlLX9StSn5W7qRa53PAD2yZnn9o3npg6+zlIJrb68PN5en2rPnAPO21eCVcLV047u0/ybg7REZ3l4nBo43uzq0r2c/h5v7uWh/syPWC5haYvvy30qDLL5l8Pn451rfJ8i5p52nDDCXjfexYb2uaeZe9W7TwBnzkWQX+UAaCx8GZy5LwPUfwsWKnZp1oi0fWrT+8TGDze2DNY9gLL03HPFOhN0nfoHkBsre9Q7tUb47SnYGAnrKmRjesPPAfuE70xfkX1n5ScF62TC8Ws4DZa+YeWWsftafUX/mCR9QsWRG7py48a7+x++H+IzHTvGbaM4v3GN9/7mbW0sssCynMRtj/o8apzcdgTvFTIIs3XPe8a5/PLM99zcmB65/3YV6o98l61Vuf4ezZ4bHm8WHotK2GVrQmnz7/pk8Nj2ZteI+mv/9KlU/PHAeVBCkqYxYOXzUvvwd7vqZLZG4NzLlexwX72511j2hPRs8mMnga07volxYtctBPMgSZ+sUhVyY8ayPdF+/27ITd0cchPWMs49q8fyxyk/YUZT44Ss9zn4AHIrbgf2e/excQpdJ62814a1HGVENx1sTNtk2Marlxuvk3ruwQBbl/ja57eRyT4og8oyQtI+YVkylGHzU2YBLJ0Gticz2F7mYK7krs+5YrD3cHmPfc7kV5STsBqE6xUPrf1en/j5+Ymu8dgq2JAbNzF4X3t6oYH3VGTpuD6BM58xsWP5vsa8p1n7cqUJbvv4tcehYdjKfO7lcliLPJhz/s9inVXw4F5rf5xwfVLGyeoNy1M57/kO/G0ClHb4PRTW+lh2+lOXyEZRIHK1bkRj0Cv5YhiejBm0MacyuLdYQ9SzAmFbBOITFI58pkehXIJTdvM3EKzGJ65USQIqPLZWJBfqKsSR/rSTuIQTfOEYMKIjttq5u0Ur92V9wgXaW2w4WRuXSDhM5TUWPe+1RZ4TTUHTDxRmG3Nu8NpkQf3Z30P9ySBUN2jfQPvKpZiumUE5MWTvReRXP9z/rPakaw0ebmjMvSVVvePU71ujzMa/fJksTHcKEvmf+LupPje+q5wVHBmfPaLMxPfj6y2ffz7DeMLzxfWTv8/q+qthNc/p6kN3iFzNa1TwK2cXzhcDAsJ2kycK7Njaig2m9Rbd4YPzoP6Kq4BkWubR/xDJ1QZ9lnqpdE+re4G+Feav1LlsLFkXDXvxS3pCvRQVHuwlr7DSRGicRSDBVPnaDyVf19lemh6sukiuBNbYWdDdcNdk5IkYDmCEo1guzyRzNTvPPZmUEetxLwDfr3Il5kFG2ItfBGtsEG0VVD7g74OTvB28XCMaUkUCQrae4zubbl0tX7khi4CS1kdvf4G+aW2vqqOFUwNLqLCTX/Nj5ndYu6Y23P3VaUDjLU/eG0UgxbsLwSj3eyZJNYp7D31SJshq0zSQSibxlyjXEwiFzLoshIiIm6/IMooLA4spiVeMrKKXfzPg1UvuFsQJAkrf2lL+CNvABXD82apAjIsgErOpgofKDm5YyHntUlZPvNX++s/PkuZW/blzle9xY3xZmoP+PG1HpoxpE8tCyfdqQKPHxL+sx/g53FC5mYdqtkfxRoZ9+4PHYMgg1eu2JQVXm6HFmALzAqt5BFtu1Pzi75WieNeePpuleRgxKCjeJqWdXVtue37mnpoDce3ufBaar5BxhVtTczyDm8h/ivuWureyvcmwzvmMyBmVGfTmSmHDL0ttZSWWvPnkLH9LOKEdxhHz9VRl2d3709+/fNVmUP3fMeEv7DpUH/kBY0FObPQT97G4cZDKOAqOBMdhNd0b8+6Pva9TXcQUxCFdl5KA989kJOw2sBKIE6S9F5nNi9uc4f3V3DxnxkiUQ1GeLvTKindxrK/IokPBmriedK601vI1OYkM4PWBlUkVFW/mMs81Vf/dWeIyq/s1xb21Jz9jZ+meHUOjKj2vwuxD/HbZS1/zDRoIZ+lr4fMdOzDk5Zsz4A1nkOLdZcDyKlguzOqfAbnJGwVfcK9nO14ybyFiiqOkeNuB90FYcOov/T3+mrjgMI93goXKExKjylwNCWKes9U3XTk+y5rMvA5nHSwuhLpxvS0JxEzIRIu9omhbPZMkwUoSRkXwBX/2Qe5xrSjf/FxxbkvzL5g75as2hdoj30/t8cYc1/JNbltbH3f9c8cSbyi4VR/4plf/NwKeIoHvt3/+cCn5YkJWHm91zqHiiyW6hgiyETIYo/rjp0PjVU2pM5yL3nvFUmbw9zSlsry5XHvYI4YR3tH6i3+D2kPf9utPa0+vCKUG1QiW4Khk6wd7J4dgXnqCpb/mZezxtpe9FS79KBpHlDKZ+dkfifB4e7Vpa0syapx777wYgYDrbXk+q4DA7lXxosrQg4djlJFxJL/WJ9xfnBTvZ5Meb0Tjzev833HtdO/dgPqTv4T607+NPd8ag7m3APlVDxQ+jCktKe7P4u9eiSMMHY+DU13iKYjdu2bjfuIse53/Bd0OZlC3q2CVxsl7r7iGNblHOriHFMexMok5r0SZ5Rn6meHIUxBxDxf3ZG2kA6I+IO8LOvC5hbKAUH0m8Hg30Rfu4ebKKn9OfO9tZK94a6N//O+qbJ1Cjh23fZ5Rw2lA+cqNoP7sOf6xjTeuCZ8PouLdhqimLgcp3l0GZ+Bt9lIV1j4GLMyTnrq5942oeGfs8eaKT6MMtlCzsPyfvd2vUfgRF4vqEmnz016ygPnP+USLDF/IjMqeh9oTZwSbdCcQo0iLBGdpQ+US1W9lvzQCqz7+bFUgZoo3JvMpiveYlaVUAe75acx/lD1z9D4y1JfJUQoGxbcxVyBcMUE3N8TrKc8fSVfc0xrBoh0zv2qP/xzst29lBq3Wa1Qa6jd7ghtuNjb3xOiO887v2eOfXp1kF/kVtoThhsZbN2eueIfCslkoYEbexGagKN7Fzb4jRyWpQCOZKPyjoJVmTVDfJUHwrL9+dfz5gpLPuTJCgrcm1NyosHTQ4z34z03dPnpzgHsUxbKJWaD8ry2hesex7PfeI71a3sI9nKoY5QCQn7ZjvOKthIg3y1eLSl1u5X0gv9KuwrXq4AzMA6vPUwo8Q1R+2nbZerzjDIa6aIAWFO8kqWex72bv1CBlKsk6JL5foscbZS4exRWD2n1fAWfJS3IETLfxE4vjNByMuqxOvRtdIsmAKKP4z7bJZyxGIXE5iu+9hTHg8NBtzOGOMNxU/ntIIP7edXykI4Z5utkvDSbDBwd4ineKvvhzi0dQ8TWePydvfONk56agGL3RQNJ4924hrarIHDYMqCPg8/NkNil9VQcbI3nctd5Nqx1dIMW72+BtgDyEu7TdWVDYOGDQbUteK7dsYb7FG9eCNWkD929uyWcLlhMmHYtQvF2Pd7JQc3/hjTm28eb10EmIoc0SLCR7WCVkESxfuXF2N/etpu4Cx27LWD9aDAFt1FxDirDJFDbA/CFHVjQ874vzwRPuT09xdWoDSh6THbtRmeBw75IYLijl1Tb0Oaye8h91f47cJDccyk4Yzs1yzF//l+lb7afVO4M8On8jNyn0jQpY41aVv+hdAYYb6q9dFfzRrhxvVB6bULzRy1G+Yd/AWNQsfE+o66XIrbit/5W49pWv2w1qT58lebzdgwpgL3qeeVmTNVyey4HynMCbp8IzrIWUAl7A1gPuLYW1XUVURrZhzFipINKDsuRl5u3UGV8yhbB2YP5lftZ+rGKEPr3AC0eNUbyRCFP5oqmmYRizhXmuqoCKSh4fT94+XH+zzMP3BfeI6ynRABb3wiVA7dlzoXxzeE/QRggliRKpD7j5s+Lag46DqHdNTFUS1mlnucfKXpoIjbf/B7VngpJDRohzIgWPQ2dg4KboUnDjKjPmSx7vfOv94AXXpet5Hm/kTRAU76g1lhtnEPb8R/XH8PWA9wG5mnomQWHdzwf3Sxul4r2X/rvmPQeM5GN/Ln29baHmqixTf/5PULlhH9eBgBEKaBjn76+veFdC4+XrE/LVIeDz0JObjWSQ4t118F5KbxHITd2UlTsQPd5+nkdW4C8tvkSYa6OGUDMBUFgskC4Twb2eGgTkakks6dyKF3dshy3LvJ8Keva5ziXr4ERl/PDBDHPUPasps576iqlHxZliE2q8/zAjDpEW8nwJilv9VBFuHVmwUkOZ+D398KCAQCSq/ZHgSpUoXEt53UK7hTZJXqmY+eUbTxKmATjL3oi6mPZjybobZXnmkSKloPZ77DldCmRZzTzFIsRd4QTRMDoiPrsOdY2RxMY5/+5drHReK2C5tf5ajDVtgu3SEoxFyEtQe/SHXnSK7PGuPXQqlK9YN9kNbbPHW7yftq2qMBcZah48SxQKkbU7BDH9o0Wgwl25cT9WyifyOFSKBSWGjbnnjW6LVxHHtdDnR6yw+yiRMW5kjwON9x8Kn2+a9822lRFpFsLrKM4LrhSoxiReSg4JywZaSNXyPWhROd7K++m1KcnY1B5Exv2bw1EzjbBhjYea11+6CBrv3qNvC64LzDkhi7CR75qwV1Rv/4RGqXKgcvNBUHvwW7H9Ed8h+7343PCOQtoTu8wbH+VZLY6X9wD2LnB5uElVhSnUOa3iDYWxAmGqcFzcJQffMd+L/XS8qLyKu754cqEbyp7SWMb3IN/I5d2jtoStj/Yir7RZWzze8lrDIyJZ5CHKYmxPsoP9KVfQk4k6DShu+ZPQZ8D1mHYQaHY5SPHuNvh5rzmzIJS1FdMTIJDUCjfXUOgH1hkRN1e+OEYsVI03rva8s3YKgTPm2E6HdClWxNLOQn4lWulw4UjJPJx2TGqPny7neLNnnvw5VK7bBcpXbS4T5OSw5IPA4ImLJj5bkd2XG0MUxRvrbLKfU7eUN4ZmoGEJx1wrjtoD35C/5GFbPBKjNCE+P5p7sxK+Mw7fyLRW2ATPPUoJ5ZujGj6b0FqNAm6rymRbFO9W5oCA0KYtck5oDCyNVy5lArQ4Z2SjUUovsQr/3nXNeueE7xnyeKe8v2qsEpV4wchZve8rUHv2D0pblTEwKOouk6zgjZAMBeK8tLJTeLlimyj6qSy/u5yJuB3kQbh2F/oDLzJCzdf23tX6C38Nn29cU5r1zinzx78H/vN4WPy2ekZYbx4iYdngZWtA9cFTm7t1VDRCowIOEp8qHu9UxhnNs8KoKFPYLqJ69/FQucFNd0vk8Y5rgmH+OZ7ix1mW0/ancpOQZ94NkKLGulvxtpfPZfwtCCypKUWksFQd3v5mDYFhxTs3dTMobv0zyK+yv+/VZWOfdL2OZV53JOIw3yDGeBmSz9fyDftBw08xkuUwa8qm4Cx7M4jQaYfH23dCyM+ecTzheyJyPzHZVOA0USMX/aoM3uE9U30Zk0LNCd2reEuT32mPkvfYT8BZ8EQ4XJYJZ6LirShlJnhKYpzwFuQzRwsszbBBtgRViRK9EfkecNBa36pwHyOEs/ByXyB2ha2WyLh4jncopNUOlG20BHMlkfdPyFvKrbSrHwY7eKlLWNIM2PNTiatevMB4PE+/4CHEVmlCvMebW6eTKt64YZYmQWH9L4a/S3KNiDBJ//mqhq2E1urGa/+E8jU7yIrCEMFC70TWUAV7XDf8NBSNx5tb5BVPMU9z4ARDtef+2BQ3RCiySFjvQnMBCY1EzyQirVEuIsfbGhcYyurPnwe1B06JLkVlReR4i58pa1rwOd9vWl9zMdyeXbJfjqSqqEoXOuNFj3f5vUAoi0jhaBqYMoS5k14kihpN03fMYoG8SGMkNKw99WfPNacpRQFzQr379R72DBS3/LG7BwmRFJwgym1/OGy1/sxZ0BR8wT083tV7vsTqlZsJnJrIWRUN9HFN06QJsWgUxiOTwndkGhM+t9T1R72ntM50Zwg3KkX2vHvbWG4uW4jRYnWVsDITj7cjzBF+rQIUNzjBU/Q5V0wjAycK93jbPuEi3sP3eLM1NfmY2O/eCbUnfs5+b7xyiTf/eK3xHqje5Yawu7dsg+LN91f+/Pxyl7zaUSnYe3F9wvHyZBxpf7TD+fP51Q4RQs0px5swxAg284iFJmsrphJSHfaqyRs8z83l7JBG+EpbjBWZv8hxoeYt9hsXg8bbtyf34qgbNV+Y8XwM/cFFu12Kt/cs8rP2De6LC3dKj7cI1m9U2kKERTi+ggLIcp+UqAY/b6nieoMjNkKxlEQk/E1PWKRN18UyHHwjwD7gIo+KeMQmhpZmZhVmfyT0ZGC/8flo2xF+7qqAHUVyUn/uj+4v3IuX1uPNGY2HkOnbh/g8M8jxRqOEGP7pwg6UX934+cQyFe14VO/8LPvZePniptpUu/9r8gdiFERlUTiflHkskzPxYirF4BXrQ+O9B/WKnCgIxqyN1XtPVM41haY7cnUAiXU37PHOYq/hpIhqFEnj5YvCB6MwVsI8Zwsab/4nEMyTrimpQ837pfByZ+krwddM2TUr3iZFDtnnG3OaqE0rKdirgtW7ovuZkKfas/e1/OBs8/Bx3RMVHQG2T6gUvGd9H32jKS+kI5C3Rh5nN8Aav5b7uxrRwqNReM5s4psH41VYLzD6+GuMkOuvM7I2Xruy6z3J1bu/AJVbDtenCHYh2BznUAlQJXK1Jj3ebByVdDk+Z/J9ErlaGllOa1jja7RjQ/mqLdxb9a3A0vrya3w0uHeCueMbisU1Ezlu/HlpBwYWdEC0I9RcIXALDFSevCKEmrNnl8sHhlOVyFB4ttbYVZU1Nbu0puECCjXvNviLQ75jHu+QtUz12qnKHn9hYj3eXPGOCyEXGLyjD4z5PubsD55gYWFJc7J8dkoOcfFAKx0LRc1+0WjMuzeolY6LtC8c51qyYiNpWO3RH7HyNNrIBFRsC2PcvvkLuWLtRMIQRuwTZRhK6O3xvVh2/BijZ8pTvHmJkDgOgbIYApj0mSH5GbPAasZVc436M2e7vzBlwaxEM6PPK5eGw3vZtE+4afKcyqzKF7UASTDFnLZWjWJCnm1Sj7c/9qJSpKxdqNSayHBi27RcricshsRV7z4unE+q5njrFAYlFx0NQ5Xrd/M+MHu83dA+wWCDwpYItcay3w6dx9tFYdNvBdUJlP7Zi15Ixk6bAM7AO8kMRthmfP8whLh3imQgiCItbAb5VQ5wPVCFXnAWvxDcR/B+S6U2dYp/1H7VzBrN1thcmBUfr+WNp0S+1oIRNnzvmtHz5Idii6z5vVOEA1J4vBPU6HbbUwmWYN2zrC13oxWaNhbmWfoAU7q99UNagzSkjtU7PxNcKmOPd/2Na6B880cyvaa7P3a3xzvScMK5NbLK8VbfFeS2qCxwq7ZgVEWae2hJPwOPd5AONwkKsz8CPR/6s3dMSmOZ8E5iuoe/70pVhhZD49UrIHP4ES6OvDZ68grL6/bffR5q7n5nz/2vOYUmX1IiyrrbONQOkOI9HHO8s4ZivWNeVg+5aTu4nm2JxTOpopBLplD794/bJFr1eHv3SRCqywiBrv2QzIIphm/me11hUBmnLHIiq/d+ObgeY7QttezxZvnB7z3g/r5cZX71xrey0Ct/YYG99DX/K1GhtJe+DtaYVWIU74Rh3b43M0FOWnFMEGJdW+rW/LRyLDoDoxi01xfI7kxhoeGmYyh+2LCQm7GLtm289BgLe496NyJzv5N5vLGUja7kUVcQ+GRdaYFd1mVPDd9PeaaiUqRY/n2lNgvke6Hv6DlmbzKuL2kiYARvBhP6lT5KrOZM8e43hvrnpu+Y6JYiY39JKI+merzzK+8FWYF7Qap3Bez/OmCf2JpQ6HPJK0VkoHjLa7O6pnsw5TEbSINMsN+5o6na1vUXzhPunWNGCyQKtEKimiXty5EVRhLdvOyOv2795Xm3obVNn45Qffj7ULnlSK2RLmmaDEYhOItfMq6PbO9Fj3earVAwbCGhGkaJMIXFm1sNcczieCsyVmjRIB5VirIpGCIYugpRz1Hy2GeQ461cixluJBZ197jcClu1WApV4NBQ5fYE8ptYqtLCtD8pbc7R3l9XKzvLSFhcOx1PJrTGrxEuv2fl3LVUWD8Hr9wIakioqSreOY/M14826PI52gaQ4t1tEMkKOpzjzYE1xDnyq344VLbEDyeJUL4K6342dai5trRIpvC8Fwny73wvDcKvVZhXyNUGws8gAwUkN9EtgWXhT5ajJLJxorDVkLwPSUPQsM40orCREkLrja9TXcj6iqQa9SfO8Prj/eBhvYtfhNzEtaMVjMRh3RrF26CEMi+YJwwxy6vn8cbcp0TkNik83tpQc2PpHs6Q6ilFdlU/v6KiAJKGiXmKWuW6nWHIoY5xqzlmmvHhtZxN32truSc1CsY1R/d+5XvduqWCMCQBw2PTKN7CnKjc8VlNjrdYTqchs4+rtY5x7RRrxvrnyXO29rCrbFtjZ4ePFcLOrTEz3V+y8DRrqnBoc+4xagQFNzRsqOkwWYSai8oUX8vV8WpUIb/G0dB35Mv8QPM7qirjwpqBpXeagjiXDeXkcG8tbvpteU2KqDCSyCi79DWvzKFmjePvdn1pImdA/alfQWNOUPpT8sYlNTI+9tPo/FX0eGOaQBrPszBe9pKXfZJIHs1gCwZc7uVXoySCA4aBssA8ku33eGtTAXSGFJ2XOEpWkIxirdTx5g4gxXuuVnPg75j4rqmlfH3oFG+NNzqE+IjFyq1HBX8U+2WZlMthHTCoSJF4dhXseffIa2FpAuRnHwzFrX8OFnJPiKHmeP7S16D+7O9dp4cULdrn/uLvsV0eldEGkOLddTCRq0H7Fn3DZlj60F+guMGXQjneXLjNz9rfeMn8aocFQmjc4m/bsYswLgLOgqegNTjJFUOhlALW92TgAjeSuqASxBYZRfjIoLQSLrDFTU91maPx2XlKXWHdzzBhp/bID2HwQsUjFAM/n7I4Dkpb/jD4gi2Cbm1wLBfBFAsP9RcvFDY8JI+qs9BYtshGKt4eA/rUgE1de5jPGi14ROyaW1tXBT6DRhlqT5/teryL49IR6yQ1BmB9ynyPhr/AkJvFa5B6Y9SYewsMXjAxrLhFCZwJhVGsHd81wDHrWxF69vNKBLWaY6YJNRcjM3Rs7rpQtcxK+qn5hmIotin6SMdKHQXR0FiZH56jao636PFWQ82Zd8LsFVK9OD17Xx0Z1sjeLVwbmqijrqLxulDzPQLMsMDCqgshT3QWoeZOZVGkkM2Owfe/NC4ggvPGWlcmR/Te5lc/AnoP9HKhs4LEkB+sdaXtzoTcxHUCbg634U3fhpXTqi6C3KQNo49Tw/CDbxIrZj7nRmyjoo2xbjmxMbFl9uyBd5iRx17yCthC6ojjpVKwOa+bW5p5b/VNC35XWJpbRxsiGpNWlWkCIpljJcTNIRxXWwa1J38JgxfPhPK1GoOxsOaVdvi9/F2uALmJ64ejf7LK8VbKWPlrjri+m9Zz5bmyaBpvnta9lDKtIdRowBeuxWtzq7XnsbJAIuWeH1LTlttMDOG9a7x2lbZqiIWlaTf4UkAcFyIk9tIBRVmtNE6JeBwGRqyMQYp3t4GHjkWGmmc3UdGyy9l/jRuNJse7Z48roLDWxyKuzMOik3u8oxaTxls3QcvwF614JUwSEDzvUm7FrRm5DSulxa12qhCegcebhZ32ThWeuwOFtT/l5WNa4HjW+qYQCvVzvD64pZvE0KbqPV8MiIdQ8OeLagy5Gn8G+dWDcEMtxBqaHHYVciuFw4O5YovERViz1s/xTowUHm9NqDn+jZ6cgYs9T6BiPMivepCcE6vW240wyHCPDnpeeOi6vgsZ1cvOAo4NVt/0IOS5BY83RrqUr3bL1JlQuekAY7kTMZRVx4DcFHRzyw8Nt/RegbSKt+DxRuWkwUmsOKRQ87qc38sjLDjQYOWV+lNuwv5f3MaLYOE90HjtQ5/lih2IQhLAhFfvGSqCduX2j4O94OnWLr/EC11G+CWGvJ8+e3pVX1dWF2ouekUZ70XzypM2SkY0PmjnlRepVFng16LGdzItGm+63ukcCyGNqONdXcI8XL0fFlizk0DoG4+4iINv7Mbx0a0tbK/qBwv3yQg4C591fy55VeZc4IZCbJuurKW6fiue957dL4eePVtQajqBFsjV2JyKWNN9Aje2dr1vPG7woulQe+QHcqlO6UZCWPY4OQoHHTf5WXu7Xmc1JSQh3DJhJsJW5Z3SRMEYI5hCVS2EtdxLkShudlr4liYDvqFOuO9l9slV9aHmOqDjhJXbNBrMYiAY01k0pP85r7ijcU6ECIm9qAuJ18YyR6yNEpDi3W0wLBSxDOLN3o4zJevgt0MJj8FwQG2dY+XchIp3UE7MfBzzMLcK3ockoebCYsXKTnjGkDyW0mKkPNw7pCreGShHdQyjQ4u6t0jjP77IZcAgLcMR7lNXFkgxPFOocYqbUdR4eBsLPqtIeOXEpA0eBW+tdVvod6PseRzSlJJx215/6WKov/kf42H1ly5ylWdTqofiCcWaoIjChl+G/CpByHvI4x01LzzlDZXLwX+sEdGHNtQybhas9BEqSMWWjQJcaUAUt/xJwnPmCZ5UQZDBd7U0Aaz+GdAaNMIAn/OCwCHmLdtorFPfHwMac26Ehse5wA19NhoXxdxtUdi063Iebyg3Gd9ds/fP5W4QgFUZBJR2Ph9Ku/xNc2brRl5rzCz5isa54gTzSu3f4HtQvlETCZMGUj6nImRzZds2Kd7h1AOJbIyd0/wezZVfEZLQr1v3PYZkzKVkBtXiOMhN3yH1vWv3f9X9RSJL0h24GHKT1ofclI3lz2MUiforl6RuExJI5lbe2zUkaOYLi4BIQK7GlUKTQdNe9kY4mgKfuy7SQ5g/uckbQn7lPVnUnzq/m0P28h3z4Dap1AxesgpU7zRzMvgcMO6dtMckSoeTKpooa6f3tyt/NbsOoTxtSSl8uQlru9c13E+SK4yKt9IeXYqT9p2Nz/G2xq3u/py8kcJ/gzJYcsU7SOVr0njK+mSF+RFMXCZsPZLfVZeATWOQdpA4lcjVCN0CMTRGQps83roNSc2FEZgYmXDJLFhh4aS060Vg9XOPoBUIobGh5vEe72w8yR8kX7TEBUSTP+cbAtqQ4+34pVICj7c//lmT7DGlPufmDGkWyNrD3/WOa/h9ww0rFOoqXZLXdixCfraZqdVnChY3aPTs5QrQe+iT8sFCv1nYJ86/XIziLW6O3pgjG3X11iPMp2D0Bwrfyrjab99qOMEGa/LGLos0++e9F4rgFuk59CzLcWz7Ksv2kIKXX+EMpa2EmnPyJtRt1zgS+o4VojIw3SLWYOjIwrFVgNIuf2++Pew64TUiCHcM5qI9LxgzZ8GTiT0zlVsOg8aLYUVXMhh497OXz4X6i3+V1hZVaHRMijdfWxUPuaXkiBdWPwJyPK87uEk2ew0q02NXcSOFECaBnBn/uMdbI9jpmO9TtiOseHvvOX92jOOhmMzjLRpn4io9xMAPXTbVgY/weHNjIPMStxQVE723uNwa4rxJthcxxui0QKJP3GNwXHQGRzbf4981HubOoqQ0ijojrFQV78IYt0546J5VyK92KPQdFZScy03blpWM6kowVvzmvYlS+bTQl/HrfSitQBedEFVKVOS2aTYcWXBkWf3ToP9Ty5RIThFKFAz73WBUUA2z2v3PsB7EjElhjSPBmryJ5p13pHJi8eBKc3N7s4PpS1zOFeVhtscaDBLqu4rvb6PK6o6r7XLI403oGoTCMnTHZKd4h2rVivDD8YKFr3yFm3Oj83hi2QTciIJzldwaE3yPd0RNZkFo0tXYTILqrTz0OcH5wgIiltzx4Yeaq4p3BmEztWWCxxuvF3i8RXbbuDBQkcU3P/sQ01HBfXiYp/Yw1ePdl6wknqCIiO3BUD4/71wkX/IE79z41eWNWtwAUThm100j6KYdFzWSwXA+lj/yjVBW8PxUQd3buHoPe7opT3bj/Yehq8Dztqxi66HmQsguzm8xhC3EOi3e3/9djMZBw00xpFiyw6LC+NVjuZFpyqbhL6MUrFTpD5r7Ln4B8msdI1+r7BoZCusKHqjQumNQvL15iIbC4uZueS7L8/jEozmBFyNYGm/9V/KQoLfeqfG0lYpRmK09fZarJMXk7jYDab1UQ809Jc6R3mfh3LhyYrr0FA2wbnv9xQvMoc3ivZN4vEXDCCqqTRh+WY1hbz2PJG2qLtG+V+1gznaqizzFu6Q36ql5ozGKN75XLnmcBsrYMiOITvFGBaJ3qpTr3ZJSKN20PTnezZBwJarMIj17K5HiLbFg+we587X3iBciKvm0YABk108Zah6Bnn3+o5cHNHNUz0ET7kv1/q9DFcu8+m12vDmoRF1wWZD/nu+FwvpfDL42lGtMXK5UV07MS8GpPfy94ONX/mE0BDbeUpj5WYkxjE5RSxU6QRm/bmfebwMo1Hy4eLylta2JxXTwPa3wnpumK0OjlHDQeD4sgW3R6C3ndYc1wgDWWK4+9B0lxzuqLmoju1zXJKHmYljZNE34nreQhFMA0o2Nqjyz++IiLnq8HYPHO4ZwqHKzm3ccqrsq3ZAr9ViL2fNi6hsqMe6jclTa7ZKgfrV0rHCcuNmKxhOhZIYUkiYq/xJbqqJ4o6CcxsOUIlc1v8ZRyb3LnAWdNTEXz/otKJLFrX/mfxfHtN94CYnuugiegcQnN2olDF7Mp1SjGIT5KAqEtSd+IbRF9HhX2XhgSGxhveOkS2EYv0k4CcEbv9J2vwl9Jb7zzsBc5csstlTO88HXT3du5FbcBgobnOgeonr7PE+/Ct+rgIqV6uWNRXPKQPXer0DlvwcH7ziyvfdOFf6umdcYzCXEf5q+aI0gCcHqkoteGyXU3BINSILy64+1tpyY6PHWVEIwKCO1J34e/sJLbZIIKWMVAVnpQw6ApGUTpasUx7nl4wQDu46QDsO/5VSIZPMjt8LWqdvE7ssU74J+viTlU+DC/cC7YPXqPdNS9QTu8dasE+w9DBllrGwUh3YQTLE9O70jIFHVjCRzXcmT10XJsflaGOtG25jSu1qJvPEi+rQIlfrSRGiq48IVSOW5Inlf+Prm9BAR9efODarIcEUUjSaLXwz3xecp4ul8u/tfV27YJ3w/1rgmFW9vL+WtkvuhV7ydpepzcMKpTZb3DDy5r/HaPzMpwzucQIp318FEBtGaRbR8zU5QuW6XENECslizXBIJmlBzTvrmlaGxxq9luJOTKNQcS3fUnz7T+yMB6Znk4WpV8U6wEHFFqG9FKKzzaeg7+i09w7GKFBsdKrqDF0yQvEOcsMclOrK8xUlQvMVXNqbWqP32bQnbxXO8E3q8vXFlHsTqIlbbW7mzd9k8FDf9VqBgSm0wGBCMbRCOtyteHqiolEU/92pUZIeI0kRWNsZGMh5Ujrf4EZR2+F1M3W/B4+3N/5AizQlJBIWpuMEJUNjoq+41RPISDRrvPQi56byu/NACiXdqj/0E7AVPBGG5rXi8pXkcJrUTjjQwZauh5kVzPVaDtzXcKM/jLXm3eJsi1uKEOd5RyE3aQBHyhEgTU11bu2Zg/nWEUGhNDmMs0gtEPsGgQJrJSLAqi9x6sCYjmKmUVlTkUQI03n8Iyv/aImCyFr1RPrkaz/H2ypmFLhLt8XZTjxKGXmsY8xlDeu8K0LPnVYYcf837xdoukFMV0ePdhADLjA0FbftFEi2jxzuOLCpl6UuGBpKnjfFCzYO1tP7q5a5SHGUklq5TDdK3cJ1OModY6UpNjjcj3ivGKlJNAY0aWYOlhyWXR+ov/BWquK7PfzT+YHFd1qZhCO8Hf2ZS1KK3DkgRnt41OR+F6PFu8hnXHvwmOAsNpIzGHG/zvfyQabWO9qtXuNVe5IN1V5CuLyqcVe5VNjjf3HRAr5wYzhd87kKaQ8iA5DeuiffPr/DSm3yf0+2LfB+VrmNJ36GBwVnkkiByVG7/JPs3UkGKd5eBhYVoNn7fc4GbRzPhf55nRmX9RaHXZyb2P1RLmglW3Z6JUNzypxHlHRxBsEnLah6leMvhpK0giq1TZcDNjVmFeXclRmH3G71wn2ZsuMXv/Qd9q2n1oW+z360xM8CeewuzhtqLXxbI1QRvm6Y+rrE/xmfreby5Ym1SHBwbao97nhruiVvqsUpLRCuCdxk93qXxzFPnHmhog1j7USBDMed4hz3etQe+KTd3YJ6kzOam6yI7AlRu+xjUnvsjE4CYZd6bY8WNvwqFtY+Vji3fdJAsjPllpkSPtzJH+d/qe4N/Y6m85R6TqS6CgOcXCvnyzaZbZAHfUMSE2aL0TmGYMJbwSQXRu2QUhiKMRzg3nz2XvQ+sHf4zzjW95TVeuUzfnhTXaAbFLX7AwgcZsz9fS/h6h2W2+ngOuJ0o57W44VegtOMf3fB9VdmMQ7OeJi7o+QbVOkDPFPcnGlmM66/gvdU9d5Z+0wQ8r63EvszzPn1yNe/ZsbVFF+buxHi8e5Ibx6uLwwztSCY2YU25TJU093Ws53l5HWBKcTOhxQ2hz/L5zLgWHOl6oYMGJLtBMyXpMMwVU0asPKtkgdF6qKRU7/g01J7+jcsbkMDI5YepMwNpAfqOfJFFNEWBRfMJvBM+bJ3iLRs/EINXbqKvUx/VTi+dJFPPHysNmvx61XtPhPrjnpE8FsJ+HKqUAvJ+z993Ya7Wnz2HOR3EUPCQMcy/R0ZRBSpCew2/r3gv1ePNjexKObHBeZCfGXifXSQgVxPejfpTv/YuJjvfsDoMqxAjhpp7aVNSFIeOFJI1te5H/VTuOh4Sg+kiBgdTnHNEuXe4Iogjy6RK6iIa1vFf9b6vQOXOz8JIQ8cV73nz5sHnP/95WHnllWHWrFnwzW9+E8pl2WJ2+eWXw8YbbwwTJkyALbfcEm6+2asVOxrQGARLYZxFYI4c1nbOr44W6OYXIbRqhoRe1YrtvxBCjrefWxIRuiO3WAjdiVO83e9rT5wBjXfvijwmE3bnGMUdBbQ6KmEouG7nLYYqOFOmotCl2iB8oaAG5f8eBuV/bgKNl/4eLKiesOVaAzWs5mkEGuOGzr3pHqt5hMe7/vyfvDYo46ou+AIJm3dA2DIuWr/FHDtjnrmw0S98RmKEZpd+89rg+9pyGLxMZgfPTVxX3y9+/htXu3wHuLmhISpizkpEa+h95/1ndVMVZUnsFztGVo7YuU4NbM8qbyyP4+UuB53sYJmnUFuE989ng3Y/K1+1GZT/mTIkWBRyNQQ7Pfve4P3hRROo4bDVRVB74OtQR7IyRsrESxF5c0byciV7P2uP/di7RELLfgZGwdz0naC48deZAOpyPAiKK7tvHgobnAC5aduHUifcMNiwwoiMwH7ZR5Gzo53w3nOs38sUQ1SSvHnNQohNEUtxHm/NvpgIfv52OazE+yHnwbPD2rSJILUXz0m+9td4tBe/VBVZycdH1HE3eLxFrzvu480Y5Hiags7Qouwx+qiDmH4rihlWgEjUJqH/9jv/A/udO7zbxURnieD5rVgJAxX54riwo0EFCzUfiF+DGTTh+aFw2wTwo75aVDCL46G081+h75jFYPWu2L5STVaCyDu11nX5A6g99n9s/bZ56URRyfR/5tsTVaBC3Wu4wVC6V7JQc+YEUcsxmjze4rmasnWuM0Q8lz8jkVzNu5poCAsZJvl+6a63tSd+FvDqJAA7zxTZmdB463vhpYoglveluA/ox7f+/HluTvkIQ0cV78WLF8OOO+4Ic+bMgVtuuQUef/xxmD59Olx/fVBKAz//2Mc+BieccAI8//zzcMghh8CBBx4ITzwhWl5HMPAF1hBXoTBW3OxUT/hofhFqKKU9MARL3Uy5FT0gh8jJbIqRNZyFMHVDqHmIqIa/gHaVeR7117UzDDWPVtzFvLa8mHMnIVCEkSlT284Uirf91o3BlbWlkESiERfVe04MvNDxN9N/7BtS3Bq6prqVknWSK4++J04VRnjEhEcI512z9tRv9GMgKeSmEEJZWUAGaTFvXRSqG6//W9OB5OPiCrAJFVvm8RZDzRVlid/e6PEuMe8OcjDEC6LF1Dnr1Qe/BfU3ros8Jk3khHdC8Luf411NnAIRupzk8daEmnPl3s9vU6MJ+LNwWNWFgETJnTP5mXsKx6YURNOm/Yi1fvf4p9DEBOktEou1IGzie8Z4FXLMy5fDXGehHw1kVhdC7E3w654veCq+Lf5JzZCruX2tP/cHcJa87Cre3JOLodwm44QohOpI9ZolrhMZyz0U1vqkntWc/Z5U8RZDzXtCa0aU91JV/jB0VN2HxbVYG6XFalyLXqP+5hVvQ6h5CKIg7htwYkLNBcXbmrAWlLb6aTJGZWYMCIy3dc6yjc9ZMdDmVvCiqgRgVEHD21fdlKCC+Z3GiAzeRhZqbvJ46+aGvv9Vr351KrSqKLOc6TFelQ3Mj8+gvKl4+XqZ7VWSnFAfgPrLl2oOVuS+JS9B7fH/c0nXPCOaPe/ekMLtX1tTVSc1eqZAaWddmUTdesLvIVZDURVvzvJtRxqKkuZ4s5DxuJLC7F48KtE2vo9Y116+Dt8/as2FnCOZoFHx1hmkzZeyCmGPN5gIUkcBOqp4/+xnP4MlS5bAlVdeCeuuuy5MmTIFTj75ZDj00EP9Y37xi1/Afvvtx7ziM2bMgFNPPRU22mgj+PWvDZ7HEQaWixRZszpjb0WdM2hHhJqLiwVbFKLawBVvpKXRh5pz76Q1fk336yRKjiBg2PMfh4G/rxjL6i13SawVHSMEc0Ugahz80G93ASrteK53o+QbhIPhdKw9qiKhuYamjrf9/gO+Zy4W3rMq7fB7tRXCoh6T4+23hR9jG4iexJxU4RJiOSBReVI94Zo2WL2Tw59hjVcOwZhjY0mwcAcgleKdUGBxBToh1Nw3IqnkatxrqTyrvMva6yvepg3IU7xL25/lHZds7tef+R1UI0K1GvPug8G/rwD2suSlysT8dWacE/vdDCSPtybUnM95/mxUJcR/FhZTLrF0lfsnP09sW1rFWydgmLfNPIaI899n7R000WBYkbx/0tywGCMzM1KyNbcg1eTG+sMI5Feo/GcPlpaChk4kIOPragipx6hZgVcQLJfPdd8FPzeyYTR8SoSGulSmZoUz/uyEdcYav4Ys7EuKdzFZBJMaah5axyMUcTXKDI1VrF6xYe7pxg6/l5jVRQ6AFEBvsK9QBOcP/mtLzT2jS3hpjQ2SIc5KFWouKstcCWDyirBP9H3ifejZ7eLQJco37BuUoEPDF2+77v0VZYJ8j9bQwT5ToyEivLH1J3+ZqKvSM2tZ8bZ9hwmb061GB2q4Ugb/sXroGVbv0tT8NuxRKLdw7gzM2Q8UbVmmkr2kTbKzY9lJU0qC0ZAn3Evh+PCrbOjIU3X5/+GbymuKzuOt5nhzBn82T5TnIN5TVbz5sd7akZrdnJGrCYq3YBjUO2gi3m0x1NziOd7xHu+Rio4q3v/617/g4IMPhjFjxhhflHvuuQd23XVX6fPdd9+dfT4agGHORgZq/6DsJqlfM1r+1Gxx5Na32LYhuZp7fv3ZP0gvvbP8bfYzN3kjqN5/CoCYe2e6trDQ1V/+uxsCZ8otUk+tLobBCyYFfw/OA/uDJ83He1ZIPzdZC3mTCELO4zdOfBaYA2bP91jmlc1RL+yFPd7pYEN+rU9CYe2AsCK38j5Q3PrnwcbGS3lpvfxiWKUcaq6G3zGyNYza8POVxbkDIW+5E6N49+x1NRS31BgYRMOIWmdSQf2Zs1kqQyIUJwQe6jSs5jg2/N5qG/jfIas4eiWq4JTfixRWeO5yboo3Nob2oXeJvdPSPaz41BMN4ZP2+vWyW/tWbhzY8w3ELgmv6UMVitlcUxRvby3B+Sx9jkLN8rfB4vWo+bVEIwiS+qRZP1MIGLmV99bk+Xm3HdTkvashr0r5KJbjdu8J4fxt3B+4oiB6MXJF6D3wTug9xECOlKDucdYhntV7viSXOsO+CIaS4uZBmRrH4wYobvFDg4LXSkkhAPu9B5lRAhU1n6PEF/Jb83i73CuGSgb+31VzyHZ9MExkJIyXnuQvH95vEihuuD7bC5+VQoADmUMwmix6PuxVk+YQF6BFxVGJ9FHWlRBTs3gdqZFY+1dQvJFf3jO0WpPWd431XMFE76loLPHaY/UJaTti7r5O8RbfI6bkaJ4jjl9oXoZzvNMCS51l6vEWeQswciBD8JKMzsDbydqivcb7kPNKGrJ5Zwg1D+Z8c+tQ4/V/ufeTqqMIMLGoC7fKjVuVrRfBIfwYO0EaginHG4webzZ3dR5vZDkfeFvhqcjLJctUxdt3AtSaI/Bjhqbg3S996LzgOy0PhvtsMB3KXH5XWDOkfdmOJp8cYaznHVW8X331VZg2bRoLH580aRKss846cNppp8HgoBvquHTpUli+fDmsuOKK0nn497vvvmu8bqVSYZ508d9wBS5K2k3WR3rrn65uqOTdVV5Y//48f0SzCJgRLidWf+EvcvgvZxbGeq9Cbq57XoTirRA0yGzIES0SSlex9jz3Ryhfs735eM8K2bPz+RFX9cKofWuqYUHWwet/4zXOYKuMp+4aGo93KmjqnvbueSUUN/iSl0rg3TeXh/zqR+jP95viEctN2UyvnGC+WnGsL6T5EQ0axbu42XdCrOaSNbV3KlNmVEEVDQah0Cr/2npho/FmdMi126kSC4vKJy2BwwREsZyYnFelCgHqs2L5pHadvffMum4kEPOUFy6IGoSawYtmQPka1wjklw+MMFDFKfwq/H4oqD0SKFCpoSowIiThwmN0RS8GI777WlhIFplYvfPEiBokfxv82ziwl8lVCozQRb1472KIpCnq3SwvkA/tn+GWKhPfK1F54GWQBt9z55IpLFL4HL0xLBzdWD4npeKdQXQVT9vB6hnuB3YQMYH9VdrKuExwXLP0eHOujIG5LPRdyhX311V9jne4XKRwWYkcqCfssVbX9YhIKzbeaooZV0AmbwyF9cKkSGycOYGdjrjJgPKVG0L53+76htUb7PfuY+usce8VCZYkgduKX3s9hZaRQ5mgC2flRGa+smz57702OktDRJebvIlwPZE0T6/oBzAo3twLn7FxqnLTh4Nm4Fg0CUyzcY0DQfpEXJnKtMAyjYkRQejK3x1n8UuBEq+EmFv9QkRbMx7v5W/JXmoFprQ6+V6Wsl6459gfKKmvaODQEu+F7iormarH26m77RajwDxnF/IccO4hca9khkq2vKuKd01e/zD6iK1bdgqi5+DdzE1YJ9G+qDNcBmsqz/H2OIWCu/m/VW4OSGRbZmbvUnRU8W40Gizc/CMf+Qi8/PLLcN5558Hf/vY3+OpXvyo3Sqnlin9HWTxOP/10RsTG/yFp27AFbsAmhaLJhb72rBpeLABZzZVQ8/yK20Dv4c9BjodsSotFQnI19hIKxwnCTO3RH7lXsmuQW3Fb9UTt5dhCzTdovsBpiSkgfXic3fDJuqr3nQzVW49gZcQiDSC+A1rNR0owNt6ztD943P1bJeXQLowteryFELTQlT1Wc7YJsDC+GAZfr8/5VfbjXyrHIuOs8Mz93Fxhw+GLLirU4qJqYlZXBXQUFKX3RGiDIaSKlwiLhLfJFrc5I1RCzrg5efPS5oou+0MWeJCdnrVbFW5xk/I83my+RYSaM8XM9+KaBSruVXJ0tUVDB3vKbMKQRFv0zqjfhcrKJYTQZ/X5uGXjZI8397q4IeXCesjZ+VVSP5HIz2Pg5/nOcQhy00R4hqeJshDqp9YIKO36d+07wgRiFiosjLcg4DmLXvSjgtwcb8XTyC8nvitaL4TY7LSKd7jdlXtOgNpTZ8acIoZSLpHZd8VQc2yPyprrKeiRpdHSIkr58D3egrAoCo68moVuTxbnbb4Hcjx83f9eaS9f53DNU5USRs6kPAseTTVpAz2DtxdqjmWMsARiiLgpAbDMmkTqqFv7RU9ZHOO7uvZy77PPu6CBjrCNRfjgux94vB1uvMLvWOi4HCESKt0oRg6y/S9hHXuDx1sfjaiWh7KTv48ajo3KTQdCsyhfsb7iOU4Wal5/6e9Qe/rsZDdJYfg3phDyMmIqkKNAMKz6qWRNGjdUh0sIBkNTbvLG4kHa/ofIEb1Q876jXmVlAcVjw/eMCDVHZ9TrVwXkc+7F9W315lduxoe06SuO7+DyFG80zCQ0srMoNGbE9tI7+ldiVRd8aNMwrfh5z6prWEG/gsb6v9oLNNGo9WTRrcMFHVW80du95557wic/+UmW373TTjuxHO/LLnNLt4wbNw76+/vh/ffF0GOA9957j51rwre//W1G3Mb/IXnbsGY1j8otdhphL3HsNSMs7WzDD5O55cYKxgspxxt/JiBXw2NEYUEn/KAy0edGN/gKuGlh1yjeIWthk0ClqHL97sy4U3/+z24zVGU4BCUfKZXH21sIkXhIuxBGhJo3y0is8XiL13Zqiz2CH0NJGm2OtybUUJfv5PVPIvbjwlFxrC94YL6xSxKVj3jOBkt0oyLkSRuEjWpAmmeE124U/KUScka28Yo/L6ValElD1bFf+CzK811BwyisKDmPSeZZIiuxjmE0AhGCHHrSmkOUUCWUwVINOGxOCIR2TPEQ5jmvPDBhreBOXIlI8B75+fQheOSTISE83I/C7IM9pS1snHJDQe3I1AkW6RGqdCG0PY2gn5acTJNb2Xjxb1B7+DvprsOE6BUDYdwnGiyGvJ2+d8rK0OOdRPE25HjnUKld8+NBdI/flLpbBSEyPF0hl+LvDo6l2iaWZ633eBvXbS/UHHP+WVqUKUQ6Cl6bLEYuliCaTnxO2rq9wfrgVJe45SHZH+Z2GSs5IAu56PH2Qoar//uk6xE0ebx9T1/D0PYEirc6dhi5gSXfxq4a/Y6IRJUaklwtuIKUFUTCwASKd/XuL7CSbVhVoVlZEqMyQjBy8GhIwjxZgP3snwm5lXaH/Iyd+TfNGd3i0qf890upNDJmJeg54Hb2u5QGxz6ww2W8EHgcRhyhw8avQ27yeDt63hvBSy99hkYjncPFm8/5FbZiUYp+NQ8OTz4OjOqGiisaDP59KvOwc0OomloQVWHCjwDUQaiD3njzOsivdpjb1Ed/zNLVWCi9Rm7JStYflYr3DjvsAPm8vPnj335OjmXBNttsA3fc4ZWN8HD77bfDdtttZ7xuT08PjB8/Xvo3XMEsTRGTuv7qP4M6xUnBQ3lLkwD4ooAfv3uPW9/bVKvPh5zjbQxldA/wThHKieEaeIdcC5kBw6KcBuRXOdDffI2hfcyL2iMvlDrmUcO5kV/73i9hcQ+FDapQFEJfOUji8Y4m4YkkV2vB420SvFm+HxI5LXjaY/TWKd6N5AKh6qGTPN18HtWC5+wttH6+sXhd3m/V44SfK5EalTs+7TVVFjascYonKgLhPC0X+Rm76E9g4VjFWKEjv9Yxhhu67xarLlAaHwiqAtgz80v+eDXUE2yePB/MEkMutfdPYSjImKzHvXeEsiCWHwlFTnhKua+Ic4+f7OnOzz4YevbzSlJWPcU77vnh3PI8Lj17Xwu9Bz8UfMcFA4EJmd3OuM5Y4Ygt7x0ReSREBtlAsHNcPosY4hyGuLrGCeoeq+1umfMG13UUxLg3RvR4YxqBYmQ2sv8nQOV/x0D99atDn0fyNaj1vNm9ZcHRjfxSvdfl+HBpZV7bb93k3ivfF5orLK9RNbiH6hlr2u57D3mKQYqSZkKVCXf/FUo2mvaxGI+3uPYyD5v3DAqrHqS9XN/H3zEbhNBjKxh5Q3nF0j6hU7yVdSUqx1u9rsrI7XkLLdEh4V5U3i9FmSRpWbqsw2h9wsBCuvU6yTtnSJfQO4tssCZtEP6YGd80a74gc/XufbUri7hXl+dYZRGr7Ry3B9o+WaOTzOjmy1gBWahfjYGf4hlbC2seHbQHeUOWvBYYYnk1F6NXWGiP4pW30fmgwpDeKZU9xP1BXVO4surUwV76RlNVgXLjZru/qNGfJrZzxsGkL1nWs8eV0HvA7UzGtz2nUwOVey8NsPrAKVC+XqhAIkKsfDIC0FHFG0PKsSb3NddcA/V6HZ566ik466yz4IgjgpxS9IDj91jLe2BgAP7whz/Aww8/DCeddBKMCqCSHOXx9pRonYBugm+18/JJOSo37M2sgijwYUms/CweOqxA2tCjWc0DYrCceXr5tX/rfl5xrDcGj+PPxVv8pTJEkefG1O3mVkcxdDBO8VZzrv1n4oXDYt3rFy/Q5tOEPgsJ7FGh5k1CZcoUv+ICDT4nFvYX3qgac3gt5Xgvv1tTuKD3aPjM1HXPa90fzGmew6djNdfVT1UNVPw5CsIBzuvc5GhPrLSBm7yGinDkj6EQjhU151B4D6dVeP1AwY2lmKAnTKO8+fXSBUFUo+Q15riCPfu6ssCPAGDhyiaY6o6boDkOFduojTgWmnektMPvwh5v33uGfbfcsHSmbAus5qLH2xszVHQwVI6dyr0gceF2QmhqfqVdITdxveArfl3V4218hhqPjYNkPAUorH54sO6KHjJP0cZwSTUqyU0NcTT58dEeb3NOo6nVred4s2ePxl7PEFd/8ldym1XFm5c603q8o5XKxmv/hNpDp4W/iFI+fOFbEGJ1zNXK+NUe/q58jHYNUM556rfu5ZD8T3gGjXfuDKKfpPvG1F33Qs3ZWsSOTReSK/bBr7O+6Dmo3HoU2O8/qL+loABo54fwrBlZHu8njx4SDP/sGrjfGPrnkqsJSlGo7KEjpYQUNjjRa0Md7OVvQ/0FhaPFJ9TzFKNxq4XuicSErF/qnoZ9wTFWjG38XWzMu5cRpjKuDn47nRdYh6SlK6MuIY677/FOWU4sydwxvUsmwxOWwd3q/6CwgSC/68picUMBQkcOKrSt+tCprLZzJHcR3sYjEDQakXSlBL375VbYGorb/BJy0zhpLsjlXsW1FOUXXM+5ksrJQpW57t9TdESocoVQylY4SG8sEtrN1nZ1HnFuFxwzMdovzZzwuC/43lHc5hfGaA5cO8R0Lo7itr9yT5m1D+Qmenni/rssvPuliZp10ONzSkikPFzQUcUbvdaXXHIJnHLKKdDb2wt77bUXYzn/zW8CyyvW7P7d734HX/va12Ds2LHwq1/9Cv7xj38wT/iogFjaQwsnvVDkLQQsjE+nhHqChjXF5BkTNqK4UHP/FGQ11wt6TBHARQkXBK4QxnpRMdS8JCtWST3eMQuNz7QqHqfLO4vweAel09zxsd+7nzH6ai2YMWVnonK8JQbUNOAGDh1EYYoR6jkxtZYVxTtEIuR5Zz34i637pRBqi6Gmvex4Vhqu/IFmDpiETk9pFz/iZCyqcBAXVix6r0xhUpwcioPnGysEJJFjbAg9Y0a0RsULNdUICX5OLCreAbla/ZXL3RrOnnBRuSUoy4j55j4DalT5PJ/4rgWPN7arJa+NRgjzFd1A8UYllBHG+bXnve/Vcjy+4u31G/O0/WssSCjsRpBIes/TDyn07224pi5HUWQq9/OMg3nEWfzryM+Be4I0xywD6WGhDdu92+7GWzfDwEUzEp5iywoLYy7OBwSH3JuE/TUZbDTet0TGZi1Rl3lu+4qkKMSG1oCw57/+qltTurDu5w3nsBsrf1ahtOMfXKOKYGCrYOi0tnHxHm/3mXhzNaXHWwIzjlj+GGHqVWIYWM2ZUiGlhfD9xZAzr0JhNY+LDCus8yn3Y7ChcnNAWGaNW11R6DzFWw0bZ2kpa+s93syYXApzdHhGtcp/9mJ/2UtfDSKcmq073wx0EWlIrpZkXffXjfi5Y+QC0cmsXq314oYnQWnr/xMvErn+Oo2BaMMlV8JMbOVRkYzSZbnMyY3ZgdMIORWK6x+v51ZQDTPevOKpIo5XzhTTVMKnKn1xGkzJ9/8UZVrfyGPr+yCuORrF2/d422icExnEUyjevNqD9x7mJq7r3c5saC+sj4S9UakklmAU75UNL6Y9l0LNWwMq2i+88AJUq1V45513WH1uzOsWgTW8MU8bveJIwnbYYW4ewGiAKedaW64rKbhiYSKp8CZ/cZNvQe+RL8UsFjGs5mK9YsPGg4s3Kk2sfjFXSOKEDAw15y87F/Kz8nhXuWUwUB5Ctc1VqDUnFY+3/fb/zEpPKNQ8QUmYlLndtleax78kW3hNuYLC54z4J+b+fDMSS0NIN/eUah3EWsy40HpzjzEO+xtpkr5akFtxO+lYn4wl9MzN18Oa8IMXTY8Ntytt8/OgPrTkXRfZcoWv1RJxbJ5rrm0J85kR29nmPEwmiHrPvjEI1Ts/zWo4IwYvmRUWyn3FO8Lj5/cjYd1y3buUmi1bvajNyKH6PvmBeFHvR7A2YCpB5ToM+RfSJpiQHHi8JfJH/j4zgSgnh/YZ8w+DNpn5Jmy9cS4i1Jyx1UokgmGmcjFvLr/CFkpbDKzmYj8SkjklLpclrPssDUTwOkQy40qkOXXP450LvRs9+9xgzhXU7R1JPHI6BSDKyKIlVyvErx+1xbKxTzdXNCWH3Lr0BZ8siHnj+Lqn3Dcg60sQas5TMiLGxV74DJRvPsRwKbx32ggHK/pZs1Qy3h4vpJ/noUqKt4lNHWUIUfFW1x5lPvgKlC2/F97YcP6WgDV7RuIcb+N6oCpS3vriRsx1sASSuOelIFdzjSN14/sVes+NoeY6jzdWKNEY0Eyh5hw1XTlMscaXx/GjesaNiFO8FQ4RzTiXdrsUevb6tz70nXtvVUeAtiywxlDcMymICBD65K+NqDjrZN04vgVf8eYOLn7P5POSM6H77yF/NhHOwfxqh8Su5Q7XSUTyUrY26vc58nhnBJW5vNljRhxYWZEoj3cTipi/YelJKrg3Ba17Oc1m5IZeCbWYoxRv74Vy2YANbUQBBJUMtuijoCwwFxv74CkuVt6vCZ6UcMFe+Fz0pTnhkiAYx7MeGxRvb4GrPf5/5kVOEfpDuaFe6HXvQfeH75cQobrKETneUkkillfltlmssSuFqSbweOtZiQPBzGV1LvgWz+pdnxdqVArKdJTHuzhGYI0WNjpfiYzOi689fRaUr1VCyQzKC4ZESnXdhZrSSULNjWztzPorbEI6JYELO0g25D372uM/iyaOw+P8fOZA+EKPMYZEYnhraDySQLiWxcuLJFX4NMDQbyYQY9/E5+gLj+wGSkqEuAZheLlHeMPDznkePLeqM4+3582b8x/3uzirf8Q6x4nCQuMe4fGu3v5xGLxwilKrVVk7TOu+2hZh7ZfWjoR50SFPvflIoQnV5F5kVQAtTZQ9hfjskRAMWXINnhOeWlLa+XzoPewZl4QnAXGYNlosQai5pCBoDROGko/cQKt9HhpCPSsP+Zm7Qf3lSyXvmNiW4G9IEGrOw3bjPd715/4E9lyP6yALaNmJGwJppCDw8/nrebx1zNGFTb4pExoy1ntB4FeecagWOo9qwRJVSwQHgvoec8XbM9QWsayf+r1qmDOmask53iyVhUdyJVBwMqtPLJKeCXW87bm3gL0oIkpOfK8bg5Bbee+Y8nCG6CnTHqg1oHlRGiaEysTKESf5mXtGk/KF7hcXau61ERXdnsksJFpFYdUDIT9zD58tHOUV2wut5u2NddbwvkjvqJvSVNzoK+6fKNP2TmUOsMK6n/WP8fdyEeq+q/STy7UoV9WfFolCk8+5xqtXePcqyPeMMmaGQvfVdc0SnIHiumt21oXSD4Y5RqFm271ovHs3OEtfD7ObZgVNrloiEhBknvZzI+MUb64k9GjCsjw4NbB6J3uLiRgmZ/AcsHM8gZrlLfEyCcnCW0P5eKEDPPZHYVOJLz3lhav5ypSJXM1u2uMt5SanMLQwsg9eOiIJq3nI4+31QdhIRAHfD8/02oR5/U75A6i/eb37N3rGTDnyfsqCF2rLrdc4F3R12Y39NrGdC0pCzJyqPXRq+KpRSqRkqRbyyZOEt3phd2EEXio3FUTDCSCWX+LPXIlo0HTEu5YlzWvXY4yh6B5ZGBcwTUzwoX4Fx3HCMf4OWF4YWhrUnz3XoLgI0RQqcaGieMus5ppQc1xP1TkQZ2jwnp0W/FzVW2v0oluGnH3Bm8faaTK46ng1+LOoJ4884NdQ0yaiwJ+5mkoQE0Uhhk9KLOEo2Ith9qY+c4W4OAFy41YFawxGdCTxeCcwgkn30ZTACdWSD0eK8VSIwrqfY+Hjlo5HIRSu7K7BWB7MX+uEFIJQDr5P/BbNau7P+RhWcywbFYm0FTN0fBP8HcB3jq3DfG3LMeZlXnO4Z7eLofeQx6T7ljb/LuR8JmvZ0MhYzYVxzE3bTj7W/TRszNCVouR7Nxpud78cCirxJbunZh/XPR/2mS3vKWh4Uj5vO1mloEDzSAm+l1XvOi5ZWkhlEeSmbsZKyXI03rpJ9iwb05YM0Q8655kakRA+QHNtjTe+GlMuLA5KmiDOtf6j35SqYGjhRaj4zg3f451Abg+Fmnvvru/FXw7WmJWZA6y48df9Yxpzrg9fSlqnNM/Ik2trj3yflSgL7gmJUdz6Z9Lewmt5M1JmUxdVtVIn99iKjMYuLpIpZlTRoktBineXABW9yg37uEKCtnas+tY0Yyk1hZpHEyMhCYk97x7XIxklkHrWQPeaEX2wG2D1TAUHvXRMIRGI2LzNzV7wlBQuHYSkF3yBWiWmMCE3TUdqJYALQVKoeV+ToeYGz0jUZpukruKy5CXyao/9BGoPfD3cDqPBRMjxxrngeawac28NDhFIY0LnOQ5U7zkBqrce6f6NhH08l49flwumaqg5F3gjiakiPhf7JF4bBbmd/ugdo1wjSkFJmJeHm5k/B3XKeigf0aB4+0zcnuVdrDld/sA1oniMpEz58IxyeqI28bo5953B8dQp1Xx+pww1lzzeimEjksTNgNpjbi6zwysvcHh5fsiVEKrjLaZNaFjN/XbxdTTfGxYGnAbzWOjCFV0vlJhHbngG6hqXlGBOTMcRYOL2CMiz/CObIlfzz1YZas1HBuuZauSMUGZxfArrfwEKa39Knh9Tt4D89B1Z/7mH2dhn7hHhXi3xPfGbMOAa7NjU4Apf+HqR0RyCdzD4SEPkGEryHoDSDucwZuHCWp+QjMy5lXblD0LtlBTd5c8z/zbqfEsQao7PiZUy4uRqEQJqFNdD1H1M4EZncS7w+Vjocw1+wrvZs/P5fgoFiyDyFBw5qkmIdkLjrT+nLUlZy624fdiwb6ws4n5e3M6rvSysW4VV9pPZofn3oRBrM0dH6H5cIWqFrCwlZIJQE1u37v7CeWwttKRInuptR0Pt0R8J96lJxKV+HrKWRNaQXhXh8S5scAKUdvi99JlEJsnOd+eB/cGTLqFdbIWfGI93itrkEjwZB5XlpLwFONdRlguqu7hEof5Y1ZaHjf/qPOJrlhTKHh5jc3h29LwU0wtyUzf3finIRltOIJfg+lpSz0Y53G4W0eqNRc/kgJuBvU+keBPaAJ/RGZHE452kalVtGVTv80JYECaLeEw5sdz4NRhT4eClq7ms5VELOVeGo4RQDEVGgYoJDQNKqLl77fLV20Hlut00Hu9iIEAk3LRyU7cM5wEzq528YNvvCUyusYuo6nE1bPoapToU+pVA6bE/UELHo46d/2j4wyiPtxgCne91vTi7XQKOX47D4GEV8tr9cH1miV7MGCpFlLb/XUjRYxbb2NClCKFTXdR9hu4qFDf7DhTWOEp/jagIj0ivoRPOfUrg8Wb14Z85Sx8uJgrLisd78NJV3VAvnr5RHOMKo33TAgZVAyo37AvOgiddRUQTHsjD4vzw/qTMulpPRa51O66qAItGNT9nuxomClQVMsHAUVjn09Cz51WuYK2uWU4dyv/aCqr3eEzI0ncyIVT4ay/nXvWkGUMfw/fWsSxHhppLz1a4niRwJws1L21zRqLjJE8vn0P8mcTxBuBx3nthv3u3vP+waBfvvfeOwRx/CR4Jnm8k0IRRl6/dBQYvXklKz9GmfSRRvCPKiekixZhhQGOc7TtmMZQ8Ft+gwgc/iacXCIYkMZJovCdoJmQ1Z2tfo8LSothcZGRr6Q3yuZXDobVuZ2IMNDylQ/SacuK8Qh8z1vvvcZRyY+pf/0wzuZrW+2yKDLAC4jTxuAhDdJjDwJSqFZ4brifSEF2oQnmPJB6RNJCMKmoUR8SzFw29WNISn4nyDnHjVvg+4t+6lDpzqLmp9GJp659BYW2VbDBMSMYu/94D7s/lSnRf6H76cVANx2nhp+ygxxuJ95Ksv5bFjMkNXnKL72XemsPWFVUGCdWjL0RzFHAYUjEj+TmU9ZI7oLgxgD+z5Pn1inzpXgV8p5nk8Q44f5jOwQ0HxXGBYXWEgDze3QKBWTnW28qWoXgLUOO1K6H+/HnCJ4Yc7ziPt/iCR5F0sZt6jL9RyjkKXrx8CZKRMKHBCuVWO2W3HJL7R1B2zH9pTflGoTYJQrwQZll74TxmNeWoP+eFvaZSvJXFO7So5eIVY9XbpwF6P5PClHNsLicktBG9g+jFWfXD8una0CIhHFgUvnQeb94moQwXCyVMkjOUONTc84gufzvwlInHJiGXitqEvQ08t8I2QVg15njrDFeiF8gTTuz3NAz37sFBX3yvrseOv+hZqN7Jc714b5J7ptCjiPPNUS3UvFwVf98SGrG0rLateg40G7ncXq+/fCOWFNFA8WblZXzvnyss5FfeS982/pyV0icuzCQ7XuO0H+vKE7lfKOPFlRNVwDJFOmmiVZzlb0H9tatkxS2px1spiRRxZHA/PyePK97yM6g++G2wl70ltFcQJgff9Y7yFG+P34GBrwtK2/l6Z/XxeubhtdVZ5JYLktZQreJdBctU2smfuxGKt86raVAqWNqFSPIV4fF2w8SD8ctP30nfNiMppsi7kcDjbUBpM16CzQrl6vfs8U/o/fA9LCS7uO2vlft7YygIxY03r/U60wuNVy+H2hPcyBO1NoheL/F3z9DOBX7Js65RprhSoCqHfi6vQhAVRTYaGjtHH/LPjlXawgx9ms91EKKRWKmmRHnCGoh9TuHxlhRg5rm1IurJa2Quvi7o5h2T2XQeb5lcTXSGJA7PRvih5nH7Ycw4cHk7TQqOcF22dyUcN65A2otelPcyPlbC/iWcJP/No4UkVnOLVSMY/LfLQ8OiTYwRLjHPQ9zj830slaa0y9/MlWDioPV4V7zvhGhLK894epBojqWRePu9yztEHm9COyAqh1GKMF/MEzB6h4VkU453T/IXxxhyxb+PD/9mrOa+4r3AVSR0L7Ko0Hg5sky49HO8kynechirsEjXlkueXJGsLXGevRJqHjKIaDY9KboBh/6Na+Lvk7R0GkJjuPENHDpIjOWiABy3oYnh9cK80ijekrDJNwaxXIwoyCfJNVRD/QVLLlroZe+jMiZRCkoSqzV6nX0DQkXvQRf7E8mqLD57IdTcz4W3BcVFOCepgI3vdmMQag9+I/y5qb0R0JIzCdEqUm5vGqj5/eJ6EJq3Qr6lwGru561rBWrTnNKshxHstu6NwsaH/CoHQnH9LxruAQaPt0xSaC4jqYS9s/GvQxXLUInzIJZdnj+zZM307y15vLlyI0R0VBZB/Zmzof7i+YrHWx/Cy/YlP2KBl6spaddI32AXQxzmG2p0oebVRYzgDYkYeU3ZoE2aMpah91mzb5rCaP3j9Yp3SDGP8uTEeLzl+dlCOTFfuVUjg3ohP2tvyE3ZhIVkF9f7vHL/cKh5/clfeuf2ycbziBQeOdpBUby9Z1y990RlTdWUIOTvPasMEyhCQdSEQgoayXmi413RKd6aXG6cywlzvKUQcV0t5qSQFGLV0JAw1JzJUxj2LM9/yeAQ4i6pRaTUGTzenJfAQ99Rmhr2cgtkArvQM4pe0PIhLgDl7N4VoWf/WyG/6kGQCrwPGCmQJL9bel41KYWSvXssgqWseWY25GftF/zp82OES0w6C59x/4yqex1nEBJl+EIfS6URS6PlZu4Bxc3NvEmhqJsQuaEVRPGJY8f4mxpgjV/D7Q8eg3ORpcuR4k1oA8R85Wilz53U5as2TXBRnVDZjOJtxZOM8MvH5F2zjaayCKxez5NRXsCEMCmcSdcugVwNWUsZEuZ4OxJRmvAC4+IkhsEIinfR9wIYr5ow1Fw3Buk31+Lmbk5xIq+tTvhEQhATS7PIah4xtli+S2Ja947FHDA/nNQTdHn+UzhcWMzxLgXhipyxOtw4Q2t0wpOQNyUZi5RwvqhnFzmnRM90w53LzKofvp7Emu0JK6Xtzzb3g18Xty02Z4R657pzxBDBqI2Uh/vyWvX+Sdh+8Ropanvq2sN+5MB+/0HJ6Dd41eZQvs7LeY2CUkImv8r+wuU1HgApt195RibPlHQNPlcyUrxXOxSsflNorurx5szPiuKWlNVcupY4bgmFk6SRCVZUjnctFK3g71tcwQyx23rKiBBq7odnKsouMvrKZH0xxqaoUHPcb0oToDD7YCiud1y84q2Oi46UlBFHGRRv/1oxOd6YrhK5FyTI8RZ/jzDIJVkjQpePq66iI1fzm1NIPOeKm5zi5gu7ByrniJ7OmLnOjd9oxMv3QnGr06H0ofOFUkgF85irbdURnibN8WZz2cCno4Lzkex8vhTxlBrimuT3TyFv1CG0dlrm3Hmds6PEvcR6OUcXZVd/5nfQeNOtLpEM+lBzsc360wrQs9c1kJu0fszlc5BfcZvoKM1Yj3eCuvTs4JqigHtVfRC5kluaTOSbGLcaFNb7ApR2vwwKG5/ifRgcb0RkBJuTXBfROCl69/q3kMaXANp0gwa/QfAZc6p5FXF8nhY0oEWTRg5HUKh5t0D08ESSq6WAMllzSGwTUU7MDNFLjBtklMc72gtdu/9r7gZaHOOGjbPc4ByAkCPs31USCGT2x6hcFRQyGnNuDIQN8dkK59Rf/KscIi14lXOTN4jsRygPVKnjDdywoGU1b0Lx3tCr8+ghqpSGVvjE0E1jObGEy0C+JDOte/PCfucO+Tj0OIcUb0/B5s8DF1gUULiwrpk3aOUtbvljfZN9j6fo+Qy8xLKwoCiV+ZKRcImReRnhyJ5p3mauNAjlbRoig7A33kgupemJ8KvgCeN90eVpCV5e/3gTvLkQKr2Hyp/4zBN4vI3Cuy7U3IvIcRa/KHiiI66tpFugB6Hvo69B35Eva4nRpBBhpe3OoIZsJ/RORJBUKrWHkwg1uRUjPP2KQOcbObiA5bOvp8/xFr0/Sckmk7u8A+UhdG3J+1jXGr5CBi5G+KeEmmN4J5bYUvKMUUnuO/hh4dyYnFnu8dZ5nnC8TMqlJtQ8LIBrnhcjiItZT7UEXYHiXXvq1/573PuRB8zXMSreyUPNaw99G4zwn02KlBxRuU4SLZPK2MN/z8uRMBKXg218HvXHT2dGg+KGJ0JhjSP8Z+y3NxRyHrqQIU1Ar3irHj5MIXE9eckVb0YWp5Br6tbf8s0fCVI6pO9Ez3mQasP/RqJUJCIL319fTSKoWc1aF9xH2ad7D7oPcivtbgg1N1XyUNJE4qAaQpRnZE69inYS+UiqNEd4vBNfg+8dvlFEkFVwvHCdFZ5Z32FPQWHNj7prkh8llAsbK6USk2i8T8Mar4CztGeFUGSQ5f9W3Pp0+ThulPX6g7w2Rm6qYQxSvLsy1DyrcmLBC8YsZrgJ6RDr8Va8S1GbaITwh9Y8+4MnvEt6pQOYEJbTe7yVUHMm6EgvsX4BcRY8BZVbDgP73bu8c2ssL7fngP9Fe6TF8JxYQUFgouZtxT7xsmvcGqoNwRLyMuNKV5gQNUe0hpQIlubEQlEu0XksH1SdU6owynK8S169d/UC7rPr2eNyKKx+uKkxyk9R8ZYt7WrKBeb1Vm4xXTce7No4hrxOtPe8e/e7WU9G55ePMrCa8199S3egeNdf+IuuBXKIaoS32vdahZj07dSKt3gNiVVdo3j7TK9JoTkeo2Ks/ukaYjTMt/RKwaCXQE1T0SmwxvfFHJFiLOMkoPfAu1gUSC6SFEmf483XMt5+U7hi4+1blXdNuJ4msiJTxdtvhEqqVAvf1yc35NFJquIW5HjzuY5Gwv5jF7Nw5uiW6IQvMQd90BztE+md5vMoJkxfR5qZSx9qzsJK+fe4fvBSgro81zjuBFXxjgg1t+eZDYq+gUR9z+Keib+ma4T8UF5qE6ImeiJnH6z/Tqt4C/cQ3yWxtrh0XEQkQVJyNc8glJvhlmn075M07J/zPfAaxlEKk11ldbkbr/4jen76HtGAEb7x9u3eYeo8ruuJ6KYIEZVS9Ji8DuTGrszK42nlHKZEJasSEg2LEb36kVNJa5/Hlb7lV29S8a6/fKkQap5U8eZGV17NpaEo3oMRaRmeMqqtCCHOZZlzJ4S45+dFMGFqTlMIsfwb+pPvgfy07YXjCq6sxgxXgse7lUiQLgUp3t1IrpaV4i0SWLBreqFYodCoFB5v9mdzinf1gVNcQZoL5kyBwRctLym9vB60ZNHjCr8kDER74HieIFppc9O2h/wKW2peYA1pB6JgqEOtHusLbkgMsWLAlC56X0PnCor32FWhKRjGAGvB1589R/6Qe59jFnQVuRDLbpidUguRtVhtr9d3ZjkXLPI+8j2Qw3GKhTonxdA+RUjSKCT23P8muIfp1p7H2fdUevPURLDihxabWHFB+p6F7cfVHpZq59bB6vfYnVWY3m3RY49CQ2PQF57qr/9LHxHghRsjC3Lv/rcIX+TC742BUdWIKG+tlmwmJ+Swy+fmeTkn8RIa5R2BxHP2klc010+mLGDdWzkKRNd+A6s5nw987TeMFRoSjUYAaR7EEOSpUSKJoIkaiuMw4Gu1qUyTZn1IVr5RzR0UDQMVs7KIczHOOx2554a9mqwPsRFEjqZEnXAOU7wTrA2JDKa8jrdecYs08JqqPMSR9fFnrSslFdqbk4qagiHSstzyc80o3mqamtheP+Q8ZY63MdTcZuXRgo/yyUPNxZBbbtA1HhulTNnRZHI+eaWGJFDtj98H3XtmINc0ORgSlueMBC8xyyOnEuR4OwnXcExnwdKHzYAzkzOjX0LF2/dEi0Z2IUIBnVMmI6BvsOPPVI0q9G8ikzZqDohso73kJdYf5C1pBpLRhl3QkBrQUPZ87ohjRijPyFDo94gVSfEmtAFSKF9EGHEkwYzjwMAlq0BjnoY9mZE3iGRYzSve0Z6giPYtfjFQvAfe9RZsz+MtCOq8HrRs0eNMucKiZHoZefv4NVFB8muzKmVhlGug5wHzzWIFQe6pEDcWfI48FzKh4p209m4IBuG5wY0W4qG9K3q/5FKNmRQGxM5XNlGTAM+YvlXFW2H6xQ2ce1qEY4ubftu48WCOeejeUhtEj1su81qpviDlCWYsl501rBQdAeALV4UYxdv9vnLTgS5DtxGK4u3U9WzjrG09Ro+dw4WofB/L06/89zDGJl29/RPQeMWz5ovw1qjSFj9QmuMJDujNQ+K5hB5vm5dki0NUjjemDaih5SnfqforqgcpupxYegieWZybauirX4IxIsVIJVfzmyrUNpZyoqPQRI53aN3Uh5q766mnYKqEacvmsLKIrldDebaxxmbcKyL6YZj/jXfugMbrV5nJhgSvcmnnv0JpZ4W9l32nkjt5HqU0oeaCgu0rpXYVao+fHhENkybU3DI8I4gvPeSPkxXJNG+8v85IF6o9nF7xjka04i2lOYSM5NGKtyvoy8oCm9faEmYWQHl+wObOr6vWnsYWL3wGqg8p3DFi22I83oNXrMd+Nt69V/NttMfbjwhR2qSmIDXevSfoA4f4LHWphKzd4TngPrNkJQ4job5nSXK8Y0pCcmA6i+R1bQbo8U7qLPPWa39+iusI83hrWM1V8Gghxvati4KKUbzjlNjaMpbKmKg8mgYsZUJEQhJk4PoAu68QBaAzhA1zkMe7WyARGkQsFlFW1Mp8Vv+08fIlGiuoZ4UVr2HloWfva+NDKpPkvCWAg3mfXn1nRs4ghn7pBCfRIOApU5JCZ3oWniDg1wFkhA3CQie3SrlndF5b6N6S4o1hr0KtYffm0ZEIccK9yZJqEho0nk+rNK45RUI5PtxWwzzgxGkSlLBEVv+aK6yFRHOrd///Bv1ThVIpx1tRvAUiqEzgeSY4G70fZmb0Sqos1uK1NDneeMrg+1ENUErroPda38fAeOXICio7pyK1HxnLK//1Qjs11/OV+1AagTAGntcfPckYfRGF6u1qvVYT1Ocq5sWVwkaCmNxU9b0P5Qj6Qpt+LmKde2N5Kg2k66Oxxg839HgP+DhEkllZBiFLULzjPO/+6elzvOUKBmqoOW+DIymYjMNBgLP0FRYq63o1FKUurhyPjjhMR/qkKjsLno4uxygwXWNaS2H1w3QHKZFRUV5qYbwNireYN48lgIzX8o0CyXK8dQqjD3zmJgO7kuPNy83FlqfjqRLeWtR4zyVWZJ8teELfl6zmplZ5EFJdpLWOp4UlJFdjBgxNDfak1RK8fHv7/Qegcsen/Y+rD3wT6k//Vu1IcA7jQIhQmJAg1VRZQpL1vDaJEWUmjzcjmA3eU3v+I5ryesH+HCrVxqZBn58XzKMpsVoNq8SShfFSVQANHm+sbOAbUeN4OrIEW88S9lOIdmKGCYyW8Ouulwys5pp9lsl1E8PfZeDxZmRxmaW7RkRVhOB4aUhFQTb00jaaZfvvUpDi3S1IUxfPgNpTZyreCNUKqghPScM3Eub2JgLmW8/cCywk1eFWWFMOh7AhMC9B0hxvLhRya66XT+z9oR6s3jRpRzSW4R5BAFTKQom3jPF45wXGyL4jXoS+o+do7m9QvHXRElwxNFkwDQaMUN6SMu46FlDXG8StltLB8r2wtq5fy1dQOGKNQCYvkCuYa0M6E+e+xsGRNk1rouuB4FEcxrmTJJyUnS58HxlqnpNDwfF3k1VZGKPBf6wht4kbiYRx9mvM6zwVfjivrtwS+8Ifn9p9X4HKDTJhlgqnITOZJ/d4B4YVHZFgpOEy0fWjwxRL2/0G+g66N8X1gzGov3QRS7lxP+ceb3MpLGMb/bY2I5A0keOtvL+1x3+uz/HmSji+/yYDiCY/OnbMdDmzwnOtPX0Wv7hyjGfc0JB3it9HrjtqmLtvODHljWsiyySeByEayl+bSwl4LNTbiFEQXqiyaU+3q5CfuaehvUo/eiZ7bYrxePl5qt5+iyUrTcgseiRZqLlUJcN/n5VQc9N6ncszks3yDfvFc9uYPvM+x1rmwkUi0pD4+DWrYOhIcwOPd0CYpXq8l7rlMfmR/HdJ8S5G76WFMSzCCb3ng38bx4jcBjHy8rV/JivPGQd1foYMcO77UX/+z1C987NgL387VbpQ64iIflHhjW/tsR9D5cb95HmFzyqCkC4wMAxEh5oLHDGWGvbNLhCjeC98pum8dx+5Iqv04TanmjBF0fFSTwtgcc4UXmaNQs0J7UCIIKgJcG+gM/iePu8nJBBEEG7JV1b+NJ+Tn30IWGNW1l/F82z7G4LP8GiwaIXKiaHCIbzEysuIm4iNpca86/IwKnZOPqHHO63FXWTDFfNNmww1L2z4Zej50HnBNXsmukYKFQnDxvs+Md/3JvmKbsw5/i16p0Lf0QKDapLNxffuqgYFZe41gjGRlSerecVbJBWRvGEZKd5ilAOOIf4zWZ0jyLSMEL+PFMCUUHNmKY726juLnpP/Zsp6LWAOVaETmDiZnIk4L205FuHd6D1U8ZDpri+el6SkSvTN/d9qj/0E7AVPCV/x77IS2gQF8eHTgioAaqh5VHqLMdS8ibndTI63f79qyOsmGRJFI5PJY+oJV+mgY+wO+uETaapCJd8vdOSdieeuEjYcmToiXDPG422/fSvkZ+wKhfW/qA3rDCo3JCBX841edqIoJIza4II7vw+PvHAWPp0wx1vZx7VEhUpfYhF9XG76h5LleEttUPJqeahulMebzak7k+V4hz4SnRwukNwsVP2DPZ5AjnAG32URi/biuLrWOpI0neOCe7ytQFlTz6stBas4Phx5Iobt6yJLRKCSVlsOjbduCkcbZKH4qvPQtDd6jpzy5Wvry1W1CwlJ3NT1mnG54NrPDa68n3Gkjd5aJleO0Xu8sfQXR94nqo1WvOtvXAu5Gd571iT6j1kIpa3PcFumcgU5hvHz+T8KkBu/pvsRkhVHlEkcriCPd7dAZY01wkmwEVYNHm8uEPBaweyLBPe0Ek+bnl0vhL4jnjdcJmcIy1EVCd5kNdQ8D84HjxufReW2o6F81WZBaLEQau4/mxDTbJMkMLocIiTHGJjL8ux9b77OuigKyyHhJmlInuE44drW2NmMNdzPV2/C64CKf/BHgvO5EKat4YvwQtFEQVBUnmI2MG5U8gUJ8TwxxCqC1bxlVJe4iprqBYkR/HRpBaJAKhlYohQqZSNinmxjH03WZazjzcnhNAqfTqlQy6eF+o3Cv7nZ4TYE70ZuvOCND7UlZ863jOWniL83onz1dhphOHvFW/5YZjWPUkYbr/9L/0VTHrLkYb+mfSI3ZTOhDV5qD/63fE6wdpuMIgKreWJoPd66fijHeM9WWzXDbWjCZxKuJ21OE9KEmvPcTnaOkC+uy3cXweqPH2K4jerxxv1VPx+YoU1YkzFqI7TGVDzOCo4YxZutXUI5Pz2zdUwVlPBFI78ubnaa+V7CfXwFXeJjCfL51eNN1xEuEsFqrjlf+bz2+P/p7yUoiDy9yFkSr3iHCQ3t6DQ4o8d7GQBPRWNG2HBamvSsNXIqky/wPfO5KnqSp9IlgJryEF0qi0PDwdMmuPtRUrlR4Q5ALhTP8O2n5sSFmnu53caSsmI5UrFdfjpPHKv5cshP3wlahdU/jfEl5SasLX3eeOd/hjM8x0mu4JMOO4wHhsjVCO1CBh7voFSTJsyZhWmLAoFIFBUDdXNJ69kKTpSVYA5T/cpQHW+VZEPefH2vFRcEuLDVMOR46zwEaT3eohEh3wON9x5gVmup3aFzhb6GhO2EpTIiFCqO3gP/Jy+4BmG3uNl3kt0ySQivtzFblsJaLBh9GETFWxznuPnIBenlb4XDMaUNRww1z0rxdtvemHO9m8OohIVJngPptIhyYiKLL4ZX8RAvJdS8RyhVxsrDhAjBDDDNZ3xOvqdV4/HWjIPPX6AoVCGBNiFyk9ZPeqRmDgQ53iK09ZDTQgz/bCeUOsjNeAVZWlFhDCtrlhiteh8LYxmbu+79cpa96Z45aYNAkOxdQT5fl4qSpC0RaUF+eTuVPIrP8dpiw2UTzN0QK73KTGy4poDBS2aFPN6x7OjoOfrYXMhN3TT+PjxU2ejxFqpI+J8pZRbVUPEkJIV4DL+OOD5eJJD7/JO/R+aazCDvFdo5LHhpReIpNUIhro637vMWPd5GtnJhv+KOhkSG4tAxAmeFSq6GKVgNk8d7SRBejuDlPSWOFLeN9sJn9SlQWNIRoyV0UX5ZhJqr11CfJe+T9F51JtQcDZMu14sy3lFpNiJqy8Hyowx4hEK0QS8/a1/oPfghRfFWPN6aSir+OEeEmjNDK8vxjuIbaRG5iEgo/p7yKDxW1zyG+2AYgjze3chq3vxFvF8EkilpMRa8jikWJl9pEj5pqnl2zRUU1VIyJouWWI9aazlXFpC6Z7zwFASfdVrI8fa9WTohiH2WklVVZTVPEgImjktoU0kW+WAKkxPZhvnCHHi8DWUqel0ynVjkE+T98GgDn0We34T/EtTxtvgxaULNOXzhSWQ3Fz3eouCQ7aKN6QAsnQLzvKWNTU8Q5YcOxuV44+98w1aEC4l5FT2RYg5jMxDKielrqWueGWfsD3mZY0JiDchN3oj97NnLJakzQrlu7cFvCTneJu97HByt58Il48qY1TyOHCt1GJ3Mam6NnSUrwrHnpQs1Z9whAks9CnCScsC5NFDAH5zHDEhsffLW+dIOv2M/CxufwhRyXqs1FVD4ikgLyq2wld9eCd6+ml/t8Jgc75hnIq7rfupIdKiyPK6ioVu8VozHOwri2uN5WbWeYH6fEEmVokTxKC3/mgnGKFeE+mv/hMqdn5eUfjSAWeNWd9eMDJWfSAJClWCK/2oqJ2YSf4X21l8437+eds81fmYw1qjQ7lcJ0kfUY7z5Wdr1YuZpVL40e7yrmOMdNhhLfeVlJp//s74tOCZCTXptTfFWEFLeTTKWLh2kvSqO/dbNzNHiLHnV/6z3yJfMUZ+qxxvfD76fevKQ0UvPS2yhxOzxy6jfIRrz7oHaU78KrxGcuyGKIZw7AFvN8Y6AZSrV6xv2kcm8IBsmKdSc0LUeb4U0zV78ojnH25/IVhMe71zzfdR5vE3Xk+p4azY+Qz6fLxSKNaO5khdiendY+TYUCr0Pm8/xZv1KongLQgGWVZP6kMDaXZoUEWquixzgBD6tbYLBwm2GT/plyvHWeLyl0i8JDR+hzUkJNZe+Ny3auOE1Ue7E6l2B/dMSoWisudXbP+Z9V4hhNbf8cZUsvCESFat16zJnQsdnr3sGwv3tpa+59emZEoNtLETk3adom9OA3ArbQH7mbtHHaYXbvMEIEJEGs6+bg2hC4+WLoXz1tkEkQJtDzf31LIFQUdrNEOHA5mAGXiVjsx2oPSxHxLDSRELIqU9chukLA++C1ecJ/kqUEbLwsnedkauF52Vp+7MijDA6VnPNO67uCY0K5Fc5AHp2/ovhsgIxoBEqq7nCkm26pjYcOi8rj145zaYQyvGOIOcSK3v491bap4aeJ/R4N165hP0Tr5cbM9M1rHkeq+SI83h7e4b2ODESRJdfn5TVPLhO9d6TUrOas70nlB4T7/H25ZbqkqCslwnCWLFqMTg/c0UozD5I40EsRrKa+x5Xt6G6RgYcQmr0CjfcsjUzXMkliExrAUL0HBtXlnaoIdmVxjyFfNsCfAO4oKjm+meA1bei/nj1HRMjKfwc75gUlpj3Ccvx+qlJwrH5tT7h3TMiqpIb45vmTmkBNo+WLATRX3adRcaZeKOGK8jj3S3g3qRWoIT6NObcpLfCcuZn//M4ZKV4V1wBICS452WSKv/jOI+3gaGce1390HshrFkNNWd/WzIDaAI4hjreWKtW2ybps2ATxrBlvy0JwsyQhAprT6ZiOS7ycletCehakrdmc7xRcPdDzcVFPt3zl8/zGNXZn/FGhvzsQ6H/WCWvMQK+QoF1UXnpJGWT7PtYhCc6iceb/y1t0LmmUz0K631B/wWr4+2NgW6jF55v+cqNYPCfG7ljm+8Jh0TzuWiqlWwCy+dKkuoS4WlSBYSIZ5NbcRuzZ5QZGF53f/GjjzLaHmPHKz69JC+S3YiOPYzqaVseY7gWsduWnaXIHOY1Q2BEE3q8+XvC12+hnB6LyNF5X3GurvNpsxFGl+PtXYOX5fFuJh8jepR0UPN/9TeXrusLz3HkarpxtfJKmH6KUkTG+3DDekQupM7grSCkHCZSvAvRintUeSQd4l4VbrTQvFPSuiQR/qWr4x1SmlFpNeSqWwlzvCMJpdyToOCxQGOt78oNe4cJ1ORG+b8OXjQNas+cE24fT2HJFYKxVVMx8HNp/41gXndsPRcHrsF2FRxNiiMvudkShHlY/vc27rMU3mk9t4AmFbAN8NMzkobU6xRvvs/EhppH7ScxUVXivI/ab+IqNmQBx8RDwWVH2ahS2uYMKK77GRhJIMV7RIWaKzk2YthyrvlQ88w83igEGTzevR++R6MkiGyarnfR6uOlmzSWO79GtMKyyhQM957Fjb6mHI+kKZZc8zIJdKFMGBofKlsTk+Ptf2YnItnDjc8NJYvP8eawfI93i4p3b7zHW7Kyy2eHyon57UmT483BPdtj3LITuXGrsWvbS15zPx+bwEKa8nkUtz4deg64Q/Bohb2Nfli/DjpBXXq3Ao+3FEoYeibJFO/87INlcjwR+D4xpQSFLkNOo4j6gLtGaS3h7vn1F/+qvVVu6hbaz11hsAnDH/vICzU31YvXXSVXgN4DbndDYHXg1RA65PH2kSSMziCM1R8/PTFRWWA4ay3Hm3m+pFBzV/HGGsX15871jaj+2PiKat6bd9F5zUmfk28sZeMlVOoQT2Frf5Ti7dNux5AZhsnVzH3gUSueAZwzrrOv8iFhs2kCKKWOdxQJkUtmyVN7DOHaIcU5gderHPCZVO84NnS+k7HH2/LHMsU7pUYo+J5vK5nijTXgxUoKce3VhZobc7zxc4sp8L5nD5mc40LOleu5VQaUe/K9iBGm6d+PsCdfp5QJRi3dM+PziUdtxpSraoVcjVXnUBRv3j4pFSXzyhR6+OmMiU9Q89MD431ArhbDaq7rU1w6k3h+pEGnAyH6jjkqp+1Kf5eAFO9ugbdoBZT/TcC3anIFtKonV0sbaq4t3dRM81DxDud440ueG7eqpoSBE2YV7RNDndQFxFHqymJdZxugvswXAosbfRmK2/wiOA4vi6+B/7KnDTUXCF10HgJFEKo99ZugVrL2uknzkQ2Lp7bOZn/ynL0oaELNi1sL9XwRnvcr/CxUQaQaCOa5ZhRvt5+5sSsz5kwLFW/cerEGJYZ6SW01lEvzNqXeg+5PNO5Y2zK/whZBZYC0CkSc4CaEmssEfM1yLBiYeFnz64x00M2nyiWbh6z0ScmcezZpQ33bTIqlUZhVL6/zbnltNpU2i4OuTXy99NbiaC9opxVvsS2qITTZHMyvdQz07PMffU6/uXGaC/UGRHusRNp3DGkAvMqGoKjivHOQ1TyBN1W6psb7ztcPU34pu7dhzvpNLSnRLNqj3LWFc4jEkqvx8bHBKc+Hyg37ijdU2tekEUK9FidXi/F49xzwP+jFiCkdVEUviQCsUQ4LG5wkeLyzzfH2I2Rio0g0incoxNx0DeXz8nyP3NVsAGRNm76j+bpGj7eyRrO9UBM6rZ6m2+eV55yf5lZqyE1azxwRopLG6ZQyyaGjWYv5GuxzBNixRtfeQx6DxAhxE9iywdVvsxCV0qlyYj4hYcI9Wd2vWNt59JaSCqEirryg7hTp2YXbaC96HmpPny20J2N+kxgeIiO52ggHKd7dgkaZlcro2fmvyU95/xHjAsnClKSw5VyQF5U21DwUNtVcXWS06DbeulGzgXneK5XQQSVIsXJgiaWPDBtT/XmvDrZjQ+PVy71fA0GxsN7xUNr5b95maDfp8TaQq6mHqYr3w9/V1l4Xzkh2f2XjxXx+B9nUuSfYq4PoNrGnjTneSkk3Uz6zFVXHO32oeciD4Anm9vI5YI2bnewa3pjnJm8I+dkfYb/n1/x4ghN5WHvaUjlxOYLo+fDGSIyAUc/D9wAZ0AVW0yCEGpIJzx65GpsbOgZzg2IaeJykm7D/Fzf+uv5WUcRCCZ9fyMADrSjeSEJlMCywn7y8V0b5gWmUhDYq3lYuL4esx56gDzV3mayr8f3103uCkFeXcbfehHClCzXnir3Z441jGqo7Lza1b0VmeMutvE9kf1CBHvz7VGig0dRnoY/2eOOzqz7wDf13mZCrKXMiItQcyzAi+WN+hS0hZ1oflT0l6rlFIe+FTDPyTLECQSLE7H/+vEnj8ea8H3xehude70H3Qe+hT2r5dip3fwFqj/00fv32jUmOUmM5yviorIEKr416L5+9X7tmhJ9JboWt3XdYx/ytu782Qk/wKOueAWdj92uFB9fo2ec6TTsBchPWSj7vQ4q30mad0a1TrOZVpRJADHp2v0y5gMBd5MugMTneCWUka/xa7Gdppz9D6UN/Cctg6Ce56/NQe+jbQXM05Vgzh+29j5M2UD4XyNVGOEjx7hYwRSQdhX/lup31CyTLeVOt10GouT3/kSC3rZlQT1PYlAY9B9weNAGZGB0b6i9fohzlLZKhMF1lIcXFIIEV3n7/Qf8cFJjCDO8WWP3Thb4IhFGJhW2N4UInqMR4s5BQKM3x/mHK+Jav2hzKNx7oepP6Z0LvAbdpSua0uJjqmC7VnLFlb7i/hHL2A2HUD9FCkrhQ3c9cKkbsADzvGueJsnCbQquEuYQbU9/H5kLPTufG39wSFe/kz1SfD6h4vL13zRHypVUB31n4NCvbJFr9GdlbnDdF+g4VIJ5nr5vzOsXbUAZKFRx05/lNcqAx91Y39DWhx1uqL+t/oJTMCb5IcDFdaaqgXFpQV7tbPd4K2pbHqJCK+U2JVrwDQbKkeDLcms9qTelkTTGTqzkYuWHw6MWGmnuGt+hSbpZfItLBCgWR5QGFscL9R60+oDw3Z/ELTa/L0rqAxjimeBvyJxnb/OxQGUlucHQPqvspKq0wG/tRQbgOszUyDeFinOKdh+JWp/v1vM3XEXO8VSNtONcV95Pc+NVlskB+1MKn+VEx6zdnYnbCERQmZ4WyBsrEe+p8t6Cw1if13yGEygPCSV4/DYYp5ngQlVhDG/2fulBz7/3yI0Js87otXzjiO7ELYcVb5sLR9a39nlt2R97nhHM8xypQiFEAIrlanIMkyuOtky3cH4U1PwqFNY4MyWDs11Bptpi1LQs47j16979F/phCzQmdBhP2kliYI5VzoYxYKFc4IPyo3HQg2Jgrk3TBCLGJJy9/kxc8cX54oifYFrf7jXQ9Pxc5OMM9/P2HwWEM7TmwxsxK0Q5howiVDeOlfNDjEJS+aSXUXJsTF9fGuFIZJmiMH86SV5jF0hq/ut473WqOd8JNLLfidsy7ppwsG4fK8/0yZvlZ+wnHJVN28ivtYr6+co3iNmdAfvUjIjd09LqHvBRGeJ5ARg6W3QbFIlJ423kN+qhnIq4XhT4o7fgH6NnjCuEAR89OyhSnhpezbQg11xnXTIYGX3CI8K7zX5e8BJWbD3I9SCkU79BxfjmxZkPNdeXS+PrEc7yzGtuIvEjWliTvvEik1ZzHOz0MayF65Xg+vF+myJx/L5GR4XNvpo63ldDjHWI1x321VYZegfRQKlkYExKKxwqRK4X1v+grd6Wd/tT6+InEhDzU3BQ9gc9ceVeKm34Lena9KPTOF9b7vNmQnAZ+zmpyA5axHJqoeG94olLDWHchHcO1Bz73TO+duPZK945eJ4P0CSc854z9UvYrySAlRvzx/Ya33YbydbtB7XkDW7/fKCvG461Wiwm+7ztmMeRn7S+sla7Hm6UUiQq1n+M9mGwMU0NDCCcasDrs8S5s4kax5Gbt22T6pUgCGIy/H/GZWai5gZRVejdUsrcOeLydht4o4+kHLadEDgOQx7tbwELi4j3e1oR1jN8FzJXozarFv/DsoyY83s3WRebM7Z5Alp+6pdwWzr7t38ddSCvX7QLO0teYklPa/rfB1zFKqr3wObA5sU3I6u15S9hzsuKZThVg7Vz3l2CjDNUUdlsRc6Fw/lIi+AQ/ikCuzRnk3vkWFzTtYqxhh56vyyEMwpzYM68u8oWngsRr0Gx4Lw+LDRPAFFbZD3p2Ph9yUzfP0BCBqRzpPN7aq3AiHQYrmJdJFG9RqS70Q2GtT0BeFAbwefRNY3WUrYnrBpfrX8mNTPDLiemur/EImxRlnuPNlPiY/EausA2+ly5U32T8M5Y2i7yY9j1rvHJpW1nNcRzQKBUOZ20x1FxMv8kauvWIkWZ50QGLXnBbJBpE1ZxF35Ph5Xg3FV4dDnv319tGRRD21XJJS1IY1KJuLxhwY4mbAs+SHz2Bw7TKAfqInaaVg+Sh5ijUxpUIKm79f1DYFMNOuVErXQReuHkp07eaMlQbLyT82tAbkE1h+UbFOzxnpZQVsW1qlIVofFQ9jsLz8aP1Qu1T9nDHZsfW7vuyvq0JPd6N1/6plF4LvmfGc/aOCR5vRoR7F/R91ItsE4yffK47g0qJ1FYR4m2oQW7a9mB5taxrT/ws3Df/eWev4pQ2/x6LCsmxNMEmiORC9ea9Nnpl3axmQs3joumk84Q2q1wBdidCzeuGz4lcjdAhYI1ce9mbriAWExKH6N3nOj+HKgTf8tfQK8fii+hvwglDM1tQvJHMheXQcYHWr1eo1NY2eLyDduTAKo4Vvo5Z9KqLoPHmdX4pIQm+UFiXcrz19UHDyK/6Eeg9/DmZqEgdP0Z246QmDkkEf4FUyDNEq7h6zVbZIpMKUDpFwJtDzFjiCTZagbhpIZSHf6ssrQF69vsv9Bx4p3BKs7mVAat5VBRA7fnzYOCvYxnZmwlO+X3hukH/nZqgkJvuIYboa4Vkh4XQFtY+VpqbaPBgtZi9HG/tnNfOWwPBED9fFz7MvZyh66LhAkm2Es5J5RnY7z/gXkUtYZZ0/kSly7Qr1BzHQGecS/DOR4VCRzLptwJtSL63Vnoep/K1O4bH3ie+C7Oau96q9ORqrldO3Q+8uSNGdyntdcoLDNwUae4dPPvqXZ8TjD7RrNi1R74PzkIvsgxhIjpqdp6J98dnHRFqzsYrxvOPFTNKGMJtIi6MQW6FbSCPa43/gbenplpn4z3eyS6j8MNIDQ2UVy0kY2gMxGvzfQ9DzdVnJykbSkh0VDqQ+rvf9oQyGJsiouItXNJLn/ANjrw90vmCMYet3W7pVcnJwPcWL8cbKy0kQWHdzwP0TInvghrdUF/O6sT3fsQ1UthvB+mMHSsnFlqPMvB4c8eT6b2L9HhH7MvK+TL7uz7UvOlKC0ngGOYuT5UgVnNCu4E1cstXrO+GfSbY6LAkjMvgHLVQ2/HkG35ISXpW87ShRLmJ67qClicglbb4viKI2HoBMhQe3mTIe76HLdTSpfjCwjZEgdU8qccby39wr7dwHwmcTCgKXDiZsLb3QUILqp+LU3TLnXBoPN5BzfHmFG8UqNwLJMzH1eYGiiH/UflXTXq8/bxrAwGMZ5mXlP1WFnjm+Yr2eNfu+wr7mV/rk5Dj0R2RMISaGwwJknCnNXYIuYNqSgQqnrzMXlJWc8U7I7VbuV/Qrh6j0MmU/6ReNdM6pShwiQxnVrTgmnWON4bX+9dLcc2+Y5fIaRimZ9FkLm48rPBzwvFk80fxWgj9Qv4BybjLBUovx9stoZP23dPleHtGKoykMuV4o3LRouIdvnc0MSlX1O337lfKAqrlvzSfp22Xf4leo8ebeVXTPPMmFW+8Rw7LYfmX4e9mChbmEDeIekAThFyGaDeTkl9Y97P6ayqka+61g/HlToFwbWxF+VeJ3wzzCNchNN66YebBfh/V9si0KPeqYqPCRJ6alDwpmiSCXM3P8U6I0ra/hP6j34jvQc9EKG53pv934/V/MycN4+qZsA7kpmwWbnsqDqNmgASddpOl0yx9qgGXz+Leu2ajxHRpl968wlz1+gvnB/O5rTnedenP3sOfhfwaR4G95GXv3kSuRugUmOKdVAgVhBzhJao/+cvA2htaEJQQXF2ocoL7NRtq3njzWmjMuZ79npu5p/SC+Qu7IkCqoeRcWS6s+zmPETEpOYcuPJYr3hj2GJCr2R+kKHOhIlQmDcll4kPNkdSr98A73L+TLuT+AlmE8n/28q7lCsohBbtFj3dhvc+Zn6OuvV7IlAzP2rr4BXAqi8xzrxWPN1fqI4mohNSApkPv05KrOWblSHx+bB5676iYwybmcoqn1gQyHW2ZLyUH1L+eS3rEmP65pyx0cd28NXhnJKFQDYPukTda0XuCgmxib61eoQ6FzyY2JEa8l5nX8ea3tdIpIXj/4pj44+LyXVuBRvFm3i6VXE147g0k7/QMQz17XQ2FtT/lfuGzmuOam0GON58TTCEK57CylBYMNW9V8VbmVKCIxBCyhT4qGEi5Wle82XvGDRGa0NzEdbnF6yaIwBPhoMdKVBr4/dKUPyqNj/4+IYlVSawOYyDlM+3N+Zm7J1e8RQMUNxowXgHViWBSvM37VePFC13jbWV+oEjGeetDEEhH2XmaevQCipt/N8LjbSgnhm1CBd0vJ5Y9Qh5Yb98orPVx4flpPLlZVaYINUi5Z5r7CMe66VuKJ9v4nqYMNTeWAQ4/p/qL50P13pOC1Lcm1iRc54vb/jr+QEeeu7mxq7BoG6gt8+5NOd6ETqFRTlFfNey5lvN0GoaapxqPdzN1vFskzwjyqRV20VjDg7swlbb7DeRX3rs1xZtb9NjmE+TWttK3UHgZ62f09VjYFnphC2ObKyeGGx4jnmN/uP0x5sM2qUjwuaRd3MPtzU3U8BB452L5isoth7dH8fZZzc3XkBS1pi2r7r14iTsVxf9n7yrg5Ciyfs3MajyBJEQgSIK7He7uchxyB3fc3Xeccrg7h7u7HHIcfrh7ILgEd0IgCYQQt5WZ7/eq+3W/qq7qrh7Zmdl9f35hd2daqqtLnv7f6sepH8R44aPhaqY+sdTinvFRQjMtijcoTn7Ir5yDroq39TkKVsU709Dbi+ah18BzOuanyCNVx1njWqf49zSTrqUJNW/ZzQtbjwrY5faWEMOKK4yGOI3DYHnfMFZuIGcEhe/tBo4A+l5zI7YxzjFQYsL13vN4y6oaqeeewePtKw4LH9/R7NHzQ2kzLWXweCtwWE8N36nKQ/h9hIjSFdRoJT3eOUv4qKd4J+V4h8d3FJfjDaHGpvW1wiWddGSAobw3KdMZkYWirOYuCMplKR8SBu9mX/HOLxSZPqOsx0m2+4UzRAd4buM83mjcoh7rID3PVfax53jLagCJRodQ8e744GKR//4p831grJiIFssFzWkQRNXlWsL3ouwzla7jra9HJYSa41pgIwyNnO54rwgJZ0yONz4LrUCREk0bXiYakZgxLXItxIDPijejqxCU9nGA4rn2B6u/6EH9ZrA8FjSFT25E9LwgRzibegJb64C6Ap9Ty/GOWLMjG2bOuvBFrPyJHm9vckvhEfrAZM1OixSh5kE4m/9MwbOnLCemElr5oaE2pvSSLYluC37jOmcaPiVRGhhSZFRsku6RCUhV1I/DkLrY8DKFAKfI/gjuZfZ4R4QuA+Fb+JWmeBvmY2HGJw5tCs/Ljtgq8pkq6PuKdyD0uZGrdU6CEnV2Zl9jBAGEXxKBNViXkHjKlRhMm9+yPq32XOa/DZDK39vkA82jiWtBucPtihICkxXvyoXmZYJ1pmXnsd4nuWbRCSHUMjroveDI3JK7hqehAqJfDcZHh+fVyE99o2SPt1JSKDAQEMUCFe+mMivegYCf0uNN1xtlDy8mXNV7F7mlfhn8HpK6qXM3P+WVdOMEny9lqLlUgBSPd3kV7+wwrZKFFQmcNISgLBWoYme4dpDGBES5+tpBjoOc6rY3TxBtz/3Gywe3Kjkx5bGcow41VnMwGHcsEPPvWl4UZn/lcHoMYR9FrrmiHm8gyjUanaSM5c99us+UoEAWZdBI5fEmvyuOgmzxOd6RKkb6jcj1aVSQ7oDrCnI1E/CZsSxiN0f3f8J6grOF2aB4d3qLjqzzCIRD1BLbb7T9vJR1vJu3vl9kF1lNlEPxTg6bspQAUxY+H0YW9xjvg5/z7dWdzogChrmUAs1wIgVNy7MFLMCR8HTHKYn1yTXlUZbu0RfNksnV4gRDU6i5nVzN9qxNm95oP46gdb+JomX7xxM83hm3d1RSiGdcOTG9ZAv87Wjgou8/TYgseZaWbf7n/xYfat7x4WUi/90TkTGXHbKekXwsP+Vls3cuSHuIji9ZMqRzQVgv1N/0O7+53zMWOkf5WMJFI+XEkgUgEDgx7cU7R3s35WY1p/cptiJE7GUrp3gHCi2+d9ijAoWKknU2JiuSNsXTtS36WkrXfGRUpus4tj1XYv/obXVJRUiM5qFzs4Rw2EBJ9nO8AdoYW/i0T8bqWlYNDU9FeLypt66YHO9YFB2xZalo4qp443OYFEsl1NxTvDESpHnr+8I+JG1oe+Uf4diNIQNVxjuunzohbSI0BRHmZvtMUZj7nbcGO65ZUP4zFh3zRWGmz2Xho2nDK0TFPd7SI+89m6L4BxGBlVJxfINEEUazwqyv6V/hXobrQDGh5jFlHcO/Dc6doJ9Q8a6wwcKCDM6THhBmDmDFu4bgGtqlWIT8iQNWzCDfDyx/ZEMAQjb/t8h5aep4yxIK6E0rBSgAGATG5u0eiVHqsvbyMnEea5PiDQs3hClBTgt0gSmMLC3054kjVwsWmLD/G9c6TTQREhEXwAaqsOzKvNleFSon5iYgmnOn4xXvTCPm9sXfA8L5sP63GeY8tABKKGQJHu/YcmLRWqn2vrN7vG0GrtCQRpuUEKKuMCAD4VlnzAYNf0fHrRdKGUPEZionhlUIAqEoH/4N6TXOHm9HxTvlltayO+QjZyrMah5fxiwWJsFO7+NKktHoaSrZppDwjay5GVJW0WoEpf2p13B1jTKhIPdBZSf/E+HoSCz75Qh9jLmkaZnGjmJ40PayIhGEIyuh5nkzD4RjRB32ZWLIqw7I8aZ54SkJSx1aVuRp6pwLKymkS1VDGUu9doehnrXXf4W533tGRyA/jZAREnZyW/8o410NNTcZDZo2uMzQdgO5Gj7P/B/M91XOz4rOr+4U8+9IiHKE9RxZqX1kh20iyoXGtU5VSYX9CjjSEKxFfabmMCoGfr9i+TfXajiRcmvU451Iamj3eJvSICJtkqVDIeqIHKvxVSwc++cqebxb/Day4s3oarhapA2e6/zP76uTlgo/SPqhkLKlCDX3J2du+ObO5CaxwE0n8HiT2pEtg91CzfVSN3GKt80qCQoqRAdkcrIuZMnQ+1IuJhZB2+Dtb1z1MJHptVhpbWifE2UVL9XjHWfVNX1nIgNL8HhHNp+iWc3dydWKN0R4z9LxwUUi//3T0a9NxIYuXg0txztDGIIpmn5xbrRFSh3lpBxvIDyLV7wjJXjkjfvH54PbPN4A3OypUgDCmiu5mo0ISWeLTzt+DEzjWKO6LGudcuF8yfwYRjiTZhWT4615QHJNomEJULzhO0sNY5tXnxyTRlA1hZpDZA+GkkvItIVmVfhPKvvlioB/I7x32CZrg90NYSUo3mGJziZifAvHmMx/T2mgybQO8X6JNXC6yDAlruk6Unl54zze5pB8+307rQYluk4GOfT4Tvz+kyUjNTLCzs//7V96gUM5MaI4B3uWoe3WihPU4x1eVzckmKrllBL2m9HKwzYs94fir5XJiNzSvyIXI5USAmbu+SK72Mbau6qU4g0ebyBv1MpZpoUir2TiDV7+mmF8J1DZwXJ8+GdG7uGFtul2IyKWN61WqHm2+zOaA9jj3Q1CzTunvinanvmVptB5wkHDSn8XTRtcGr1+YKlN3vQzPrNusKiViECgRS8J3QAVIdLCYmsSxGI93hZG5IZenscbvDiD10rzCJbb6Ip3sz2cLaGkSRKyg9fxflFqYWc8ZlmdVbzEcmL0+m6HuXq8DeV1SmY1jyMyU4mMnGtIl+p8SQp/DxoENVI1HgPzgeqfrUNEbvSvlY+yI7cTjSv9PfyAeJYhBBRzd/2jo9fH8L15xCtiKYcVCJ+mTdNXvEEo8g8OvwPBz9WrFiHW8u6ZXXT10hVvk8e7Ap4SLzqls25yvGXuqeY5CsKH9ZzrrIvHO2etWOHQGmUMAANvkG4DkFwdOXPZr1IUW7mc6QzVDnunMQKlofyh5r7ALfdUvCcxiOR/epM0yW2c5IZuIFr2/lxkew1L3RxFaYitO1xBZEpXvHNL+eH5gCAs3DCuqfHJNzqgLJIbur75/nFrjfKONMJcumcZ2x7Ddk1JLXFe+OmJgJa9PhEtO79oOL+Ed6fNm6YNLhFNm9xoNSgngkbIUcUb3wE8D0ZYEfLZyoAYJfHvYgBEfHobiwk1NzpHDJGe4ISjder9cSQJL5UDu3jO5lqqo/BXCax41xCcWUTppID8GxDogu8alIWnYcW/BfWmlU0xhccbvNC9Dpwjsv3HiLLCVJOSWswNNSWDX2WODdnQiiFHg42hbaY722siNAuj9Cz61uVCQbR/ckPwXXaIRw6V6aXWF08PTYADYpdIaCR6JO3vunmHp/ywW8MdINKhz5Ii0+rojXetz23MeSxWCHX0eFOUyGpuh6mUXzGs5pa+0HOyB64c8c62bH2PyA5aOTyFlqWSzNTtCaHmXrvm37lM+Dl4go0e71Dxzi1BPGzyvn00IY9GqQCruZvHOztya5FddE1yz9Bw0PpbIkik9qTmDDne88u6Nbbu8yXJrU+pcFq9WASV8hLAvXWPdzC3tYgjasSyKt4lGLqyDTJEE0PJ85NVJUFGT2icGoFyX6oQqfevy96ZJvWjJI93m7sxN8U+V4zS7Z1I954yK96OcycSTWFTvGPWcMrSHzeulTUJ+xe929gXRuIrEUYC0XGhOEeo4o2VI0iIug6jgk/KbOKcwGsRj3e2z0iSkqg8oSgahmimhmV+JVp/5UAWmuTYQG4Q4vGG54EqGl2R4y2VZcoKX6zxLNcrjLbE57AZowMZ13Qvh5Qk+KgZPN4zI/I2EP6FB+XKH+3lqvtk2ePN6Gq4euDIcZK0iBLK4HemhYcuhEHOUfVsL4F3jxLBxXm8qTcQJiplGY3b3GyCTa6XV1O6VPId232o4j3rC9E+7p/hka2LSWNGUt3S1CW+JOGXPo70MLUowDpvLAMG3d57uGjd6wNLuTtTqHmD2yZg8vqUGGru1cWMv0YWw5OLVATkphQrBEZzvK2htZE63i6eMP3zQrpwWekliBMaLLnIkrjPHmoOwkjTmicRxvEwxzv0eNNQc/B4tzgrAopHhnialCiBokLNKUlYk5fjWkZG80zrUNGyx7te2a+UHu+mdc8NI5YM7xvCLysnJGWj7MDBT83jTZ5LjaYgKMGbkRvpKUJ5n+G/QLx1En7IrlLNw6netgP0dvt7Z3y/m7xStiiTMuR4ew3CD0tMZSsBdC8tu8fbMToscT6gxzuuEorp/UXvn/MN6N4fzRo5nfe3Uk5Rv6RUvNX1h3wbtDOInDOQqwH3jvdRe4xBmlxLqGRkDasdbW1fKXO2/KSPNDIgZMHGOS/70le8gzWoUp5byeJeeiUcSC0MZED//WUU41WIji/vlD+VUPH4q0c/auovOr66J0iXMYa1V8PrnGsuLgWpTsEe71pCs2NOFV2cZT3etshiV8CwKCW3s8Vgta/+QFfKLynCgboxKgsShImTfL62V/6Z/r6NkOM9K+zP1qGiNOiGgubwM/KOskPWF5liPQo69I0FazMrzdKs5WWFd+2GVY8owuOtpw6UuCQFZVPir5GTOaqaIScVoN2egt+87UPmdih/2wnfsgOWV69Lw+lsQoPJ2JLUYurxhrEY6/G2rAlyDJvyy9RQc1pXOszxxrlKQ81T5Hj7aNr8Nv8yFgU2taCVVUl5oD1SoCrv1pjtP9oLE02Z453pNVQ0LPd79cOi68emBETI6Io3JcxSahgTb5lOJIXH0BxvV1I9PL6xr8j0XTpUatq03EosC2kKNS91j4tUiYCxlyktUkFZ+8qQ403bCfnvpnFWES4Are3GWuVd6/FORGMfOZaCfcCEIhS2SI534AG3K95y7SH3alhqj/A7NNq3TRedEx7wbxINNc9g9QuT4h0YiUmoOZ4LHu9so2ha88S4hxI1A9PeKKNyMNR8frjPBetW5RRvI8t9MddBYJstBjJcYwvzCDlbmpQkOXx6i8LP74mOT67zP0mIzOkq5DzdxMgt0w1RQ7OqZwPyXpw9F0o4tiYEaKHm1IKkWCDT1PGuIFp++YFoWOFPFqOCtpgQw4FcYAlja37qa+lvjuQffr+07vqKaNmD1vdNi0KUoRE3OSKMNqx8cOleqmDBVkMWpaVXV7AjxCzlR8OSRGAw3Mf4vDbyryLgjXM/pC7xWuiJKZ7VXIZrgSe7KRqeFxF6JXOtRfEesaXaLnKcvdyNT7LS34tQgDSANB5vEDoLs7+OGrQCZvmwRIvyGKB4G8uJaTnees6iJL2KerxBGU+tgGF+YLkUbxpOjQqhLaS+HCiHYBFHjFdWpAg1bxooI3jkNzbGciLQNa51UvrmQBUKVLw1oRfKiMlwRVN4bqlijsnjnbR+G95Ltu+osrOaq6Hm3jXn3zlaLHxk664RqCPXpGu6/6OoMWrqkyLJ1fRvsw2i9ZfjRdZAJhYi2uaGVQ6Pv22uSTSufpxo2vLOcM8DeQbeESWNJSj45K6Ixl+cJ1p292vc+2O57fVjRftrR/qNz0XnHoZXm9YWWH9pVASt6Q1zKMkYU1OKN41sIutRYEiYT3K8fe9xpdoP/RoTyVBMemlYocDs8cY68YV5k6JfmmQF07PjHt82wx6dVAXFO2Mou9edUUOzqocjxQKhhGPr3oUgfDuhXBiSdXTREGjd5yvj59m+S6qLY1yoOV2QINQnzpLsEMKKBB3YnxASmu2/rCgWkMcNaNroapFb9ne+AuNbrZX3VLqXqmnTm0TTZreoVmCZu2uo4x2UIqmA4h14013CfTMOOd5FgpZNSZpLQWmkEljNF/rhXsa8ON3jDe/eIWxczlXK32Aj5vPOaVr3LNGy2+uiab3znMd68zYPqN5vAH63xX9E62+mRCsGSGV9Gd+raOozLQySPhN4kCGlI2A11/rGuY63f4sBK4jMoFUDjoQo0s0tCFOH6yntrRC5GrXo2/gU3C7SRR5vmZKADO85kVvql6IRvWOS+Z60w++v5u2fEM3bP265Hlmr0pYTk2NYSy+iAAVGKt6FsrOaR0gY5TtMWmPihVdjmk0xaKL9mI01RFckJUE3xJnIIYuZSyXtVRrXyqBViriEeg2IOmla+9T4c7KNonGN40QD5bmQIckLZQlM4NvR0fm5voc3eCVh6fil0R0BwSUZ52gcM3i8M82LqOz/aJzGVJ+kcPAi18HcEjuJssNYBYWwmoPHmxohKmg0yERCzTNl8Hj7MqIl1DxQSuMUfsU4YbqfTwAYMPUbFO8yplml7oeCrnhXPyK3EmDFu1aQxspElNNC+yzR9so/yHeNbuQSgWIuugRBiZIk0I1AF/7pIiUtud4zLHgwyrauEIHZBA5kxixzLlKm75KiecPLRX7yc6LjA78uN7UslkEAgrxrCEujRgvZx3AffSxFvFUVACW+sz1f5HOTx7vYcMKMnAteeQ83b5QzmaERXjtd8t7j8s7VvtJyvBO9uhmRHbhitHycCegJkPfQxgE+Q67ZJ0PDfHnKWp2VVvKALI0iiJ7BMGQSZQOCEIRKTnwMH0p9lNQhx71lZEoQXhk5IMWW1thPGtuUdyC9qn7YciWA+fClpLUoCm8lFe8sEQazonmzm0UOqynokQJ+f+UW2zAg84xtdzGQ3kNP6GxY8a/qdyAEwzhW5kx5WM2FNtakETWh3yNMxZED6B/Fj7Xmre8LDR0GgbkiCpCrxztQvIvYd8g5oQfY9VyNaHKHJ0Xr3l+Upvi7PIPJKCmN4Qu9eWSt4JA1/t3xybX+35qBS6ZUEE4F2PfkYVGeG1D4ZR3x8OjQOAUKue/5tD+T27trXOME7bwKrJ82wsJAIW0LHS5ybaqgegPKMS3HVuw6bKgGkbFxMfjrZ9Pmtxq+w2hLA7kh/UTngKoRj7cI3lunuXpPNwMr3nWpeIeTNT/5JeN3HR9fgx8YLyHLscj71tYQoEJwAb2KCKVUSWOwUOWneUy3gIaVvOdyqYedKbvirbHo+u2TBHhl9ngbryUV786I0CBLym14eYXCrgopxm+Mx7vUtmUysqZ254QHk6+FCkDRircpN51ev5A+NDWN4l3E+Am83JLALWdWfilxlqw5TcZsEI5uULz94wKSM4XQ0ZtjnV/cbla+Unq8k+HeN00bXRk9W3q8QbmrcKh5KWuOMi4qq3iHkTpaf7TPFm2vHprueiXXMCfVBBr7RspbRkLNy8RqHjEkSONmtjSPrbL2ldC2XsNEbrGN8K/obXpbjCBlQsOY36r3M3ol0/c/rdkMUS6l1PGW/AAO8oB6UjGKd/QYqUSBHCAVb4tCpSvMen/RWuGyCoNaNg8j9vS63PI78J4vJGX3CMO5E2hbGvtaIxcLtLQfrPewD5cbBuJRr+Qh9k9e4TmoqGyr53gXvbaRNiaEmqOXOttnCdO3/uWaEwwVqHjHeLyr4GXOoDORjPXWvb80c+h0A9SW1tWTkcZiFrOpY63mzm8fdrxuDQ8BJURKy/GWHu9oaFXDMnu7e5QCxbu8pDOYV9+49hlGMquyhvxRjzfkkeU7I6GRYGBokKHv5Qd492tC8U5ShikwVCslsZd7KaBC+tBUU51sq2GgiPFDa7tHPN6tEU96x4eXigUPbRae4pMBGqMEIkKH5vFWD1b/TOnxTkLRcwvqmwYCFYSaV0j40NmJS7lGxT3eYai5cX7P/zHd9UrN35OPiuzMRMhGSC6BOWL+fWtqIbpl7iMprCZF1SSth0lrSBEwrnulGjviAWkurb/TQqGD34Mk71TXhOs1bXiF4ZsykasVw8jtsL9FUnhQEYL9Jt9uZauOlELV3qOa0uEbZ2X1kkZVjjGwXctQc+LxltweqUjqaNpQL2vkYmEh9apXCoY5A8Ze7B94Ll/2kbnLlfTc5qD6RfjezIzyDqBzA6+RFGpu/tJvF40Yjak4A2WIYVwSguLItboS2ajRHohFjXOqG6CGta4ehjSLhFPJIfMrjoRc1QCruQ06w6Ei9JNQcwU+iUl28Nr0TPMNUOEoV5mVYKHz7pcb7isuILwqz1LGaafkxwOZW4U3HA25pfYSLXt97Ga8yLjkeBcfah7+Fj+msbxLpqs83vKdOMwzzRudXWR1c7hVMYy76KmGc7WQ1Eiout9WYD8NPmoeYL+33o8Gj7dVSa8g4V8ywndCvYaFed9Xbg4FindDXXi8Q2GwDP2BY6j4BkklogAKvyl9wzfiFGZ+Jn8ufHpP/7Ty9lHnd0868EgkhZqXiVwt6Z5dQFakGLuMz5VNfT2zAc051lyUjCJCzZH8KqqgLfSqzNhCza11xvF7nUvB51cgpcVyYw4QDSuRlENEy6KKN7rjoyvTeWeVtsT0f8TAWgEYDfUk7B7IToNQ6vbK5nhLgwoxmBRLtEbaGEQXWSMjLGUa5cl+6htV2o2Ea6h4d5Co2ASHV5nRtMkNonH9i7V2EdLOHoBqSj09Hvk5E8M+SCXoERKVH8Yp30RYCrXFR4ZcSebe+bVveyl0ivyc78K/lRxvT8lU8lD93Gdg1+34+r7Ey6M3ruz1JlFoCDYBvXxTORcXGppcMJcTqyCkkNRncZGf+73L0eqfRFkvOQzeKvwZEIR0lUHxNmwUCntxwLbqUq89o16v0Cmat/mfyA5cOeb+jqAKcMRT6BugfEFCN1w0rnuOKPj1k03rReOaJ4js0PWM7YM5BsREhYVeLmHnd09pj1Ij6w++nyBNJEbIKQVIalnSc0dJzSoCuDayZpdhTQlYpA2VABwbJDo+vlqOodyoXaIpE9YIlvIKc/lJzyQrGonvpfzvzTimSg7vT92K6O/lGqOuntpy7K/6GlmsoQxkFrn/Q7WR+NxdcjP795BiF6QC+cpWr6GiiZbzjKTOkJBonZgtAUrEUsxYAqLP+Z/dLCoK5Z2QsRUYLgpqVZ+Khpo3qWUo44h+Y6DstQGRZbYEj3dz7PF5NKZD/1SJQbzBj0o1zq8OrzJGd0fVpJ6xY8eK7bbbTpxxhh+OS/D555+Lgw8+WOy6667iiCOOEN9/7yLU1x8WPLBByR7vzm8fit+cTJNYEcJr2MJU6BQL7iZ1jhWPd2i5C0CVG5fnqlSONwJzr6CuqhKKVM5Qc6qsASEW5HhXgRzDZZOjwktDbzUkHs8vulZr7YSa5xbfXuSW3D34u9AxXyUGdM7xzovciK2i+YnFhHCiACXrxubM8wAFCa3/csDS26QpprQ5jX1FA3leNS+wl0KA0/HxVeZnqTIy/vM1rollriqksJRBEZKcEV0AyJ8sdM5LNFI17/Rc2gsX2yD5ozD7y4C1uGmT68PvbWV4KjHGEj3eSaHoejWDyrQJw5QbVj6kPPdI0wbdAF0yqunxzpbgGfXI1ZJIs6z3ot/DNQJlMy8a1zol/t2CbKMo7mp+eGL7aZRKzHnFVCkoz9jKheOcpp8Yq7uUEVK2C8djboShfJ8TDKHmFjSM2T+GoA8bEu/xzk/y1+pCp8hgelUtIFMFmbWnKd4///yz+O1vfys+/fRT8c47ITEWKt3rrruumDZtmthnn33EJ598Iv/+8ceU+WT1AJqTk6acmJIH4eVeIrIDVxKZXiOIh8LAbEgJkmrF46TV9m5c69SoRU5RvJsjIT5KiSFFOC3Eb65lzvEO84/864LXiIYild3jTfIeu9jjjXAqS0f7WSfp6sIcb6yXWRqrefy9Mr2Gh3+A8uKieMsQy1xFvFUYTi7LetF7ZJvU70zINolsv2WCNibfjIaa91aZZ/VDayTiJnhfAclLhfLcDP0AJeGad3w2xTU6nNMqSkNGiHZv7MYprxmnaA7tusW2J0BezpWGZfYRmQG+cbYc87motiQLko1rntwFoeZmj3du6b1F0zr/Ks89UrUBq0eUh8chO3IbxzaU4Wb6HlrsegCKsp/jbY2SSFS8O1VFWn7vKZrZQatFy91RaE6FjFzHUzwLLZdZqTXREUZPMM4z2UcFtZxupcnVfLTs8Y5oXO2o4q5DK4BQmcGAhtH7iV4HWHLpMfqheRH6YeSwxnXO8g/vjKaBVRMZVrwrjj/84Q/iwAMPFCuttFLku9NPP12MGTNG3HbbbWLfffcV999/v2hoaBAXXHCB6M4oTHu3tJCb4M+saFj+D/GMrkrt4doQfCO1vaGNeXs5MSiTAVBKZShKC/GE2zxEeHylPN5o4dZDzcvq8VY9pJ4nqBoeb4djiMU/KqyX2CeJhGcEaAQpS4635V70c2CbLdLjXTbEeLwz/ZYWmf7LilwQLq6xAsN7C4Rnl/WChpqjxzu+Jnm1IZn/t7yLpJ1USvGO9gOUhMtZ65IbQMPgK9l/IMRKo1HCPEnr0SxaIKZpGCTH2x/PblElZULiM4RtBY9k42pHWr+vpMfbSELX1V7JMhhEWn83SzSuflzicY3rXSiaNrLkrqaBLhOYyi45XafJM/QWOgKZRUdBj66JvEfqsW4IQ81l+HpDqufoeP/CVGk0qlc0fj/KjtxOVBQmTpjAw40lLYnHu4JGSWWtKWl+hW2E6IWWXV8t8jq+4t3qcRxJGNbDgHS40CnaXgQ9oUaQ6VlZz12udV1++eVi6tSp4thjjzV+/8QTT8gQc7SwNzY2ip133lk8/rhfq5IRv+lLZmTiYTIcm+09suYE3whMXjLKau4vIIW5JAecPitVdC0hPOhdrFSOd2CJlhbvhRVSvOkffo532UL73KEwr9pAWJAzTVpoGp5f9HgsItS8WIEwjZKPnmQHpcBb8zTlokzA/NdCx9xIjWFQjlv3eDvclCOkVc2hAOegNCmeCVDYIWQZWFTn/2A6WNQCwLjQsMQOXRABVIZ3WrHShDqyMk0iMSIoreBZbB9HSu1pOcTEs+q0HhUD8CjJeZIpMRS9q8jVDCR0FYXhuYpN6aFXymSdUgYaV/iTyPZbugz30/bQWGU1pl2ySoLv8bYpF4k53qERUPaBJD3s8D28jW5lmihSMHBnaA37hDnVsvU9onGNE+XvDasdLcoPE2M+pqj578fvY2nsqOS4p/1ayn2oxzvXLLKDdD6XlJfDyDRAnEe7i9KVnJGpPQdgJdGlT/vee+9JjzZ4s3O56CYxb948GVK++OJq7cmRI0eKb775xnrdhQsXilmzZin/ujUoE6KJEZNuwKacTKp416DH2654E483bOZN/UVhdjguFIVCUbzb7PeoCKu5uji3jTtEFJCkyGtoee7n3STi8Y4IDV2BlKyeSqQCKUeibPQVJlcrPvczZSmgzgX2UjKJykWZ4HsuJFN6EgeA3i/Q9mCOuIeaN6z4N5GBOt3+XO7UiCD9i4uqwfT+K8yPEFmviwFdzypNrtY2IzklI+V6UzSxHH1fktU5p0UukXXcWCandORGbitrmCfncCcp1uFnWQyVr4jHu71rDbE0DQ4N0F0ZiVAu6H1WZLkoqfgiuVm2UTRtcGn6UHNN6ZfpObjfJjkNDO8eU62cQHO3XULN/bYXvY87XFtJsVQ83OHzdn5xe/kdKhTKmC5Bnisz8WDjqkeJxl+cb38HAR1QhchDi0SmRgzwXYUuk3rmzp0r9t57b3H++eeLJZf0a/9qaGvzFoTWVtVC2qtXr+A7E8466yzRv3//4J+uuNcDsouskeJoYu2LbAhqSSJjjrfi8a4fxTtSn7p1iMjP+cb4rAqZmW3TNAlsFcjxzv/4ql35Lxl00y54C2oVPN5J+Uk6CnMmKH9nh6wvGlb+p8gOXrfYFtCrxd+72NIfpns5zJ8CCF6u3nXlerbwbGTe7kzl0QW2fxnSnKrGsCfcBUKMy3rhz1vJPC3P9+ayMdez5jbcUkn+ElAOT2yl0lY0dE7y886TjAWpjRVlMHjJNvlCfjAfwnldmD+1yHsktAC4KSQXQoocb9MYR+PUsgeWT/E2rXuS2LELc9/J+pD3jeKdP7wi6g76mC5WUck1i0K7bwTKNors4ttHj9HlHG28FHSm50w2rCGdqHgbvk8hi0hiz5ZF8USHE7KVkyvJnEJeksDZAgYmEqlQmDe5onKQYkgv6VnLtX6HrOZA7grI9httvV/nV3eV6b6MYtBlWtfTTz8tvv76a3H77bdLNnP49/rrrwfs5j/88IPo06ePzOcG8jUKIFobONBeggTC1mfOnBn8mziRlOmqE2QXXdP9YJzoplrW0uNNQ3IMr1ghV6s1wdeHH56KaNr0xughTQO9Bda0WdJ+sQmOeHyFWc0lFI93+aZdYebn5A8kV+v6HG8rY6vr+Q0tommdM0q4ThGh5sVCmTIO8wfCdV2fyyHHGxVYqdAXg1RhsL4giGPZYb0otM9RmMI9AyGQuZgUgBoz/AVzp3YVb7VCQgXLRfn1XCMlKjXoqQtdkePt1TFW75tbYifRACRHuWbR/q5HIlR2oAcw4RkSSe8qrJggpIJWJnKz2Fv3XSbaBtzz6N5XL9CiOIIay8V4Rv31EBRB41xpmxl/Db8Od3bwOn7bcmHUVjGKd2eKUPOGXqLXvp4BJRMo4HEn5Co4vu3kasH7oc8LpdcqhRy9T7pnbVz/IlKBpzzydwFzvOX+7P8+cMWyXJtRfnSZa2z99dcXDzypurw3AAEAAElEQVTwgPLZySefLJqamsQhhxwi+vXrJ5VuIFzTmc7h79VWW8167ebmZvmvrpFm8gZWxUaLxzs+zE1d/GtM8EUo9RnBMLGW+RiFidmS4x13D3laZRbojGIIoMJHhYwdOrNnT0KKUPOGFf4k2ik3QLnua0MarxOZm9kRW5mPwZxJWkc0DdJ6vNPOERQ0AyXFj16pB493tvYVbyBjC9BCyHQqhETm+dSGvtLKiYX9mFWF7oZWkRu6oegYf6HILbah6PzyjuLuE9cENFqnCTU3et66qMQZrBFGg1d50TDm16L97dO05y5zKldXQl/vilS8IdQ878soUkkuwSie6evnrkMfBx7vhiJyvNMbnqFkoFNUW/D+KzG+vWs2rHBQ9H6B4k0rdlRQvVFSx9I9a+Py/yfPaR93SNlDzWVr+owSTVvc4ZUBZdQkukzrGjJkSODpxn+DBw8WQ4cOlb9jeDmUGbvrrrukdxzw9ttvS8I1+LxboxjFW4Zwavk/knwDFx8oT2QPc/NPEDUJ+WyhkJoxleKAtlPFW1F0XRRvJFcrl2BgEdYhF71i5cQ8NCz/x/CZexhDpIcUiveSu4nWX46v8L2oktDhyGoenifDwi1RMFgyJNOnyJSaxDBYk+Ld5Kw4AoGbvIyveEtDn/RQ+uOS5p5VNdXF9Oy5Li8nlhYNS+8V1M7O9q5gWhWuI0nvKIWAC6kkjasfW2yDzGzdfp/KdRxLLeUqVCrHV7yTjRHZhL0LjeflJNo0KHX5tuqxvQdySh06RSLlxErweCPfAMyTUowQeG4mKzo+v90t3ciU411EBEJu8Doi23tEdUPNMbUEyuUG9yPlw+Tf5Hm7KMe7GM6KTNnnv0rA1zBqZ0u74u9nNfYzyoqak9D/8Y9/iDfffFOsssoq0vv9/vvvi4MOOkjW9O5uABKE9teO8P9KM3lJKQWTghmE+9hKHcXngNcEYAGlBDlGZlSfdZf8nWqjLDe5WnBdQpwzYmvJIt8x/jx6QHnv518zCEGtQo53epS7D7pyHKckVwO4GndcWMObB4jW30wOFNvUoPPf6Ik3tCEojecigGbMHu9AaS+i/7oKlU7TKBNhXtb3fmWHbyYqBlhzgUgsZc3qOLTslKJeefRG4a+0bCINM8VSSxUKwQ/mXCZFnxj3ri7yeJPIgIrCn9uKsF+NMm9lQqQ2dpwhH8aCzVAH5cRQRoH+aOhTQpuQZyMnS5MVZn2ebHxNyPEuu6JVSY93EEFhyK82hZpXMsdbkRmLeNagnWXqpzIZipu3vDOMpmBUDFWV0E877TSRzaqbAoSbQx74l19+Kb799lsxevTouiRLS1PiRyJNeHCQm2x+feHml00mqahRj7fsG+olNpVGgLZDnVnDczWs+FepVLS/eWLMTdBAUcEFunWIgcyrQkKXLxxUhdU8JZq3f7RyF6+0FzVlOTEJx1Dz7MCVhItqVrTSLW9CxodJKDasCYHQ52DQgugLIHAMhJOAKNEXDmRpHV9BqqLHW1l/gw8r3J4ylbkCwRuiIioKmZ8624EFv4vWmwireaOqSAQe7+JDgxMRjJmkcRK2NTcsahwJ993y7QXmvbzQJVFtAdmXolhm6jjUPFcWVnNv7euIjUBsXOMExzY1hj9hDW8eJDJN/d3OoSAe7wYkwCwbNMLDcgLXGTqeAuNb1OlQUVZzGsVB872dz09BVuoER8XbMP6AG6Pz24e9r2HNr0NDWb2hqgm+a665plh99dWN3y2zzDJi880377ZKd1omZvPi1lAcwYX/fdPmfrhSLULLBzUvollRaJ9nDu9r6i8aVzm0Sz3emZYh3i9EKZK5vboFsSKCECje/oZaBXK1tMi0+uVAygay8VRcmUvHai4Pc9zMGlY+WLT86rNiG+bWFmp4MxoEYnK8HRQaeNaGJXeNEiWi0gk5hoECWr0tKDt8y8hnocBYu6HmXYZgfUwYu13GKUHHZWi0Kcz+OmynHnpabgQCc5LH2/vRssvLak5+paGv/dIT1gVzDFO+qDEL53jZq4ZUgVwtZt6q5VkNcyNQ2s1jpnH1Y1Iq3k2i0DbLjTeE9H3TRlerRhLZpDKPjS5gNVcZxbV0EzrWKxn5R9fEYhT8YHyVRxZ0NzKo92va5HrRuM6ZZWkDwx217xrr1ihOWQiEw2yxijeWI6tNbzctFxF/EJCMmBVvp3uUOccbCH1a9nhXZPssQT40KN6VIh4xEYx0IZo2vEJ0TnnJ7eAye0HoeEnMvyznfa1zSPvcUfGGuZ3pna40WyloMBmnTPMoyPEuQqHxy4kFgnjnQpEZsKIozPioqmuQmf+isuRqIPw6z5EqA8ZiwSVHt6sMffR95TsjXjVYxws64Vq54RMHFhLIGQs+E3WmdWj89co9/gkpaX76hx77exfMsezQ9YX46ErtneTd9/Jag6bIxO0pLTs+KwoLLOXrZDqgr7Tje4C1tJjyov4aDIbNwvwf3fYUamTFHG1FHqmQ4l0BGScI/6cGh4DVHPltaKpDJT3eRH4pRn4sc6h50waXiY4v1099XqZ1sZrWA7orapTSuqegSC9dYFW0KN6B4pWJLUFVmP6xqFkY8+JMyma+eMW731LyZ2HBNFEuZPtrtRMbWlULs3fnst2veduHRfMOT6s13asUat6w7G9F8ybXOx1bPkI7HzTkrtIebwehvmG536sf1JDXB4WU5q3u8RlWdRCOgiHrK+0vpKgdHl7OLydG1rvsIquG39USKkyu1rDM3qJ5w8tFfcCPrEoQ8CsSVmq6T8TjrSn8EPKJex8qNk0DytsI11KEHf6ajyX1ugrkXSz43y/8UPPKv5+GJXePpj74hra69Khpe2jTBpfaD+21mMgOWsX8nRZqLtFsL42LyC25m11ZyzWJQvssJ8VbMS7i8bQMZZmVriCaqqtCzYP53hF9norW8abs6dUPNc/0Gpoc4Wk8EfqrxvbgHgDu8WqC5vtJEpsiWM2NiA/3KSyc7v9U66XXFJys5GrJsbQCYKbfGNG47tkiN2qnIhroeA+0Tisflm+zyw3fTOSGric39UKQ61ibgSzQ3wHK7JUPakZ3ieLd7mSAad3nS7fnrWQumglBZIQtYqa0HO/oyarHu3nnF8nWk+lZdbzrCQGXiN1o1Pq7FPtWyVA93pF5nm0Kw2+hhF+/0aLXr78rcxMyKY/rYhErEmqer94cQ8I1l/rPtQZtbQTFpujrBAZx7z1kHBTvWFZ+mI9ts5x5QzJoFPAjVyghLYSs10+oedQQiDJf23O/xk/I8V0jBxXFau6aslJu6PeDtrPHu8vBincVUSBelXQLIIaKEyKJQatFy7/YFgQUqGrN25REfBQ5KKsqAoaQx5ZdXxUte6h14YPDMxnRuNLfkwlKSgFsjgt9j3rAiFuhTSnY4Gs0x1thIy2zskny6jsng2JXQbgqn0qIbsw7N5UbqiQKSZERVHjRCGSKCeGFHO+Zn4qFj20n/8wuskbtrkG11p5qwoEDo0vJOZV7FaLrHCgkvjJSgJzjirTN9Zqu5YLK3cZsVcjVjED5ph7nVLn2UMlvoXq8M00Dkw2upneG+ztE0ME1ncuCaQorjcBL4/CpOqt5Q7TfkOdh3mSDx7tG5SDFsNPVczNj+LvGjN89AHW4InYnUMV7hvtpgWIdLiwtOz4jSwy5hJonecRrAk51WDMaS3D0ebODVhbZ/sTT2tXItYiCnxdY9hISCkDxNtSyrCEo78HFsJIC1HiSn/x8Wa8dvZnjvKFkfzHndHUOJNZBzfQdZTmgvDnelMzN+5uGt9XYpl+rRquqIFtzaRKIAigM/jhtWPXIcH0NPN7A/VHF/c3R85cdtkll7uujMP3DKs6xfO3LGZU2KMkcby3UHA1ZKSOdcI/LT/9I/oRyYk7nBZErOe9dUI932RXvLjCo0jVaX6/pnlvL6k3w7qscWSX7q8b24B6AGh6ZPQFk0vnh307AxUYrCxR6iRM2/WCxquEJ5+jxjmMbrQXI0EdUvCvZ7zLfvc1cg7RG0LTRVTICofXX35e/titRvBvXOlVUFtkiBITa8Xhn+y0tWn87Q2T7LpXipDR1vDUowpHv9cGwwVoLc6twjnddwS/1WXY+hqIRjpXCvEnBu2pc8yTRuvcXcixlGojiXQHhP9N78bJ5/iAnGnKjK44qKb65xbf3yoslkfN1Z8hQcy3/OEgVjFO81XHTsMJfRMNK/1DPcww1F0jwB/Ml2yg6Prm28h7vSqzrQT/GKN5KtFaN7S0U/jtEEsbqIVPb/dRNwYp3NUG8tZh37YRAaKUetUwKVvMa9TalzJuRx9S44u0ZEAqVz+uhoeY1GmKVaewjIxAqEdqfXWR1kR2xjff7wJVFTQiyinEh5p2X2fvvgjjjjEpilb6cmJMBola9YJzjHe2LWnlXZN0szJtCympmJMGVhBJqXv5250ZskbKttbDHVqcN2QHLi177T1GJqHoalHQ4bUw4RKZlR2wtf+aW2EFkfE95YAhzNF7nILXHu1okxSuIxisXgsio8hsuC22ejJxpHuTk8a6ZdcsEfz/NT3ys+qHmNdJPLXu8LVp++YHoCaiNHu+poDneaYjOEiZKuNGZN9zc4l6uZW6JHUU9IDdmf+PnUrhSLIY16KVS6j022BWbMqCAOV89MFwWjDCNqx3RNePAtXY3VW7jQs1rLULB0FY07BUwfDQNFMFb8/rUGipdx7uuUEHvVVEg7SCh5gpyvhGrQoq3O6o0zo0l8mrl/fVAgHKt1/H2x0TLDo+Lpk1vtJznRwahQYmOfVTAcawnIDtsY/JHuNdkB68jGpb/oygncsM2lT8LyGtTzmuP3FY0rH6MyAxYIfzQwPMAz+V/KWoV7nW3KwwoX1oj/ZTtv6zI9l1S9ATUmMTX0+AJd41rnSJyw7dyPy3JYx14KiyK99D1o6U/ahjZRdc2fl7xXN4yQNkcA2tzhTzeuNnVaI53l4VvKXn/FapZmxZxwm+tGUpi2tow+jdFXM/ghai1Z/ZRc6Hv1USteSpNjLz6IaBYAKFVjeR4d/l4Mnoaa9TIVSeIKyWWKsdbi4LIDlhB/otD5+e3+qeQdxh4vN1CzXOLbSxadh3nlTolinfLTs+JciPTsoisWpH0XEVdu6GXaFrjBO1DdY0CxQ3e14IH1q9d4y6gSsb27EDtvcgxyXteV6OGR2ZPgLdJNix7oMguunqK85IU71oN58yI3NK/Sn+Ws/BS6x7veINISaCs+LXmQe0iZAKDQ2XHQbbPEiK39N7pToqdi7U3TxFN612k5aTuWmKouS90Dl5X1DQ4x7sGCfCSFW8JMHZ2zOuy+uK1PqfZmFRC3/VZQjQs9/viz5d7fiF9FIS+/tBzkJwtBU8K1hnvCk9rbtE13arSlAOmvqxZ+VdUrqpLCq+y9kntLO89CD1TQq8VFFtuI2lh8QXdWmN17HVgkUQerv1TMyRABNQqHUQilN+T1Pnjq+Q+PXRaB8RY+a67l8uYlKR32UQSq5oBskWv+DeZk1/evvKvvcyvRG7UzqVfO7hHQ3E1xhn2Ls3mPJWhZqIAMrFs+QFAISlzqDmU6yz8/F6KE6o0p42h5jW2vtQJmrb4T+kVUeherJOrxaHTYx7PLraJyE95UWXrzjbJeRnUrC+2Pd0BpjWgHhTvKoaa55bYWXR++1A4Jmu5n7opuMerCbRYFqt4J3m8u4vnMymXqXmQyC25m2hc9XBRa1A2xwqSFUmWX0R3ee9pgYJNFyjeOZo352IMinvnNRd2jQJiGUvqBL+H1yyrV6TsgkwNRs/0dPHAIdRcftzQWnZyNcjHBeZ0Z9SMsQJQS22pHzSM2qX0kGmy9mEurVNOrV/yq2Glv/sflObxDlArucWVjOYI+rzG1i/De8gtsVOX31ryCrQsSsYirw9djRoemd0fDWMOkJMgNctzUskGXHga+4nugOzQDWK/h/5r3vw2kcGyGbUE3CQr7PGGdIXgNj3WgpnpMqUpN/o3ovW301O8/zrK8dbZd0u+XK7yIdwpBcrsomtVph3dCTVX/UJXvG0e75ay1/HONPYlRFcuqKE1uMfuBzUAQylFl/eRHbKef2hDVNZDY24xhsueYJSvtWoMBuB7zQxYvuvv3dAqsn18EjOu410V1O7I7AGA8hANReU8Z92IXZrLX7apGgtotk9S7dRaEQwNUDzemYopWk1rnlj2a9YdcF50gcdbljByUPaCeuX15PEus8KlhgRX6N2kEChb9/lSNG/3SGXa0a2QqUuPN6y5lSon5oraMn7W2HvsqQSFKV5DwyqHitYDppnTp3zFO1NMffTuFmoO033J3epO8Q4MxdXiEgn2S67jXQ3U8MhkFO3xxgU516uuO7H119+L1l+TEGobanqBbS49p59Rc6Hmqd9/XSneZQ41p8Jn50JRCTSufqzMw3UBRMZATXlGPdWiBriGmvcWom1GdcO9a2mNr6W29DQYPN6ZgSu5GXbBaBso3iF/RaZ5QPHe624Wam5EXSneVZJVgkiKbA2t7z0HNTwyGXaoAlHjGqq3M9PUt1sssiAcZ5qSw+ULs1Lk3nUxMg3UKp2vTUWr26D2ajAXFvyYXMe7mFy9eg01rxAaV/yLaN315Yrfp2eh1gQyt1DzTN9RQhQ6a6OOd02gltrSw2AgV2tc/TjR8qtP3U7vt4z3s2lg8FnjKodH09hcm9OTQs1redwHsnm1FG+iG9SygaKbogfMwu4Mb2HJjdIIGhr79pxFttZh9Hiz4l0JZPouKbLDtxS5EVuKmoHMNQXYN7emDS4RnaOKKNNVL7m9vLHXJwL7S6bOQs1xza2QQAlcIvN/qJ8xX0tt6WHwyokFfwWfZXqPcDof0uxa9/9R1rAOPvMrTWSaBxXRoO4vEwZpHrU87qvt8cZyZlzHuyro/rOwW0ILWdbyRIAIRqKbK94Nqx8jOt49W9Q0FG+m/56UzZhRLoDnuGXbB2qzQ2OUFwh9bhi9r+gRrOaMOkK2PkPNUbmokODdussrIj/3u/iDakror5X31wNhIldLewmidCMaVvyraFj5kPQXq7XSleVAvtPMcVThOdiwwkGisNCBYNWAoG1VUrzzWH4W2lErhtUehO6tmXV7WCYM5Lh1g1DzJNDwq5oFrS3uG0hqrb46owtQU4J49ws1Z1QANSeQ6e3JOuQvVqAVvYaKXK+hNdp3pvJK1WgHw1rHuwxo+sW5xZ3YDdfiTO+RVcnxblrvgpKvkR2yrqgK2mf5v3A5sWqgnqRBhlbXOhuUItA83v4Cn1107e7dZzUnGCbVmUSPN0+7noLcsr+rP2NLEnlj6ut1P2GvZyAh8qGruQl0QdoWOVRhj7cbqnXvgrUmNKMKUMZgDcgr3XAtblz7dJFpJaX+MPe9lkhWDWj93SzRsNSe1W5GnTkFuge6tcd7dts8kWnzHrEhmxOtDc1ifsdC0UFCU5pyjaI51yjmdiwQ+Xw4UeEz+G5u+3yRJ6HccA24FlyboldDs8hmsmJOu7rJ9WlsFflCXszrUNl8+zb1ku2A9iCymYzo3dgq2jrbxcLO9vDzbFb0bmiRn8F3sKkX9v5aEjdlPrlWLGgeJDpJe6DdrftOEHNzvcQC8nltP5NI/Z7aOztEVmREkyjU9DO1i6xoEXmxoFAQbSInOjraRKZtXtnH3mzhbao4FmrlPXXHsef6TG1Ni4gO+c4XiN75zrp4JlC05oqsyHZ2iib/vZTynjoXTBcL/bHZV3TW5HvSAaKI/nmPm08FGAc5kcvnRVvbPOWZ2nd8QXKJwH267JkKBdHpjyNA/7Y5oqFQiDxTU6ZBwN3m5jOinfRDV76nBYWMyIucaOhs79J1b14hCzNX9BZ50SYyYqHIioZZX8t5XFdjr5vMp858h1z7vHUvr8hj1XimBYWsAHMZSMXd6T1leo0Q2flT5DMVCgUxH9atjjYxsE723K6eTwtwjehcKNra58v+AhRATqnTZ6q19xSHTAFGaTfDrFmzRP/+/cWi124tsq1euPV+y2wjLlr/n+LQcZeI/3z5ZHDsEavsJ45c7ddi72dOFM9Pfjv4/IJfHCx+M2ZbsclDfxGfzvw2+Py/W5wmNh++lljmzl8qg+SFna4UI3oNFqPv2ktpyxe/ult8P2+q2PThvyqD6cu97xHPTXpL7PPsScHny/VfQry481Xits+fEIe/dmnw+WbD1hR3bnm6OO+928X57/8n+JyfSYizOj4V+xSmiO0W3b9m39Ov8pPFOZ2fiWNa1hF3dob5Wjz2aus98Xzy1r1fzRontvjoefF5pnd531OhQ7zf8bJ4bdsXavo9PdH+hhgmFopVGzfq0WPviQd3FAdgRGItPNPtO4k5RFx5evGlxJLrnxt5po/GrC4mfnSd2LZxnR7xnvRnGlOYK57seFP8N7OYOLZhuW7xTHX9nvx179UtHxX7vnhO1Z/p5o7xYtPCdLFKr+26zXu6pdcCsfHM17rVM3XFGnHvGpeIIz64r1s803JVfk9L3bSr+Ob3D4qZM2eKfv369VzF+7upk4MOYItN97NCtX92k8i+cYz0eBd+M7Vmn6n99sWkx7tt+FZi4aTnROveX8has+W2Fv54s1ffs9evJ9fUe+qOY8/1mQr5haLjy/+KhjEHyHvWwzOJd88UM8dfILIrHyKaVjumLO9p3n+XEqJzgVhkg4uFGHNAzb0nBXcuLXKN/UXnHu/U9Huq9Hya89iOYu6UsSK35O6iecMrq/5MP9zUX23jyG1E61Z3RT3e488Vbe+fLxaO2F40b/bvqrynBU/vJfI/jBUDD/ipaz3edy0vsu0zAo+32OZBkR20isjketXV2Osu86nzp7fEwid2kh7vxn0nigWkykk1nmnhCweKpu8ekR7vzl//2G3eU+bxHUR22pvBM827fZhoWO4PYsB659XtM1XU4337YnKNyO74nGjrN1rMv2NJ7xr7/1C3z5St8nv6/qcpYuTgYax4u1geGPWL9k+uE+3jDpW/9zpwjqhVzLupj/zZ+pspIv/j6yI3YouK3qeW+4JR+2h7+3TR8d45smpA0xonlOWa824ZLETn/LoYmwVZAi4jMg0el0ZPRX72BLHgnpVEbpl9RfMm11W7OcH6hmjZ/S2RHRB6dBHt75wp2t89U+SW2Ek0b/lfUQ0seGIXkZ/0bJeP93m3jxSibUbwdz3Mt+6Mzp/eFgsf2kT+3vrrSSLTVF15tO3lf4iOz27qdmOj49ObRNtrR4leB0yVf3f+8IrILrK6kRGeEa6lzTs9L7KDVhXzbxnU7cZELeud3TrHm9HdUV+kEJnGPhVTuhmMsiEg0yofGVDLDk+J/IyPRD2AhTUP2b6jROP6l4iGUTuLWoRJ6fa+aKgBMqsaINJiVB0ZSmZWC2SwPht/w6pHiu6EhuUOlP8QuaEbVLU9dYN8B5OrVQH1pbkwGFbGcAaDUR548ypTRuUhu+jqomH0fmW7HqNr0Lj8H0SmdUh9dXctsJozUzCjTHW8ywlk/25YcvdqN4VRRTSuc5b86UVgVH9c9jSw4s2oY/CCwWCUfVaVu5wYg1EONKih5lZkG6uu/EJ+qWhepGr3Z9QIlJJ31V9PM61+/flCmNPK6HloXPkfomWPt0V24Iq8z1cBrHgz6hfsVVDQsOJfhWjyCNYYjBImlvaTwagBuBqCUNmppuI9aifRa78JVbs/o0ZQY6HmqHgX5qvEaoyeh2z/Zf3fqj8uexpY8WbUMXjBoGj6xbmi16+/q9rbYHQXsOLNqGPUgMebwahFeQUIx3Jjfiuyi21Y7aYwagScstn1YHI1Rv2iBizIDEa3A4eaM+oYGczx7pF+Bd4Tawrt82rq3WRyTaJ5oyuq3QwGo0ejJ+5MjG42fDMDV652QxiM7oMKsJozGF0GZDVnjzejysj0X4b8wespg8FgxZtRz/A3Mi4dwWCUdWIp84vBqAkUCm7Hcag5o0aQaewrsiO2xr+q3BoGg1ELYI83o37BIbEMRuXmFQuKjHomtOrJHu+GXtVuAcNHpmWw/wsr3gwGg3O8GXUNDollMMo/rTBHlgVFRh2Hmvdgv0LLbq+LwoKp1W4GQ3q9sQwer6cMBoMVb0ZdgxVvBqPsCEJ1WVBk1CEyPH6zfZcUAv4xqg9WvBkMBkHPNQkz6h+oGLCCwGCUb1rlmvE37lVGzSEzaDWR6TXc/r3v8c705FBzRs0gN3xz7xcejwwGgz3ejHpGpnWo90vnwmo3hcHoPsg2+b+w4s2oPbTs8lI80RqzmjNqTPHudeCcajeDwWDUCLiON6NukWkeJH8WOuZXuykMRvdBjkN1GbUL6cmOswn16DreDAaDwahl8M7EqF+gZ6PQUe2WMBjdB+zxZtQkXMuJsT+BwWAwGLUJ3qEY9U8ClW8XtYzmbR4QoqG12s1gMNLleDN3AqMegR7vQqfoceA5y2AwipGla1yO7k5gxZtR/565fG17vHMjtqx2ExgMd7DHm9ENDLKFnqh4x+W+MxgMhgGZvkuJwszPuG+6CBxqzqhbZAIBq7YVbwajLiNJGIw6RKahxfuls63aTWEwGIzaR1DJhNEVYMWb0Q1CzVnxZjB6WiQJg2FEQx/vZ+e8ntdBHGrOYDDSLhs531jJ6J6h5t98840YO3asaG9vF2uvvbZYZZVVIsfAd4899piYMGGCGDNmjNhmm21ENss2AkZ95ngzGHWZ451njyGj/pBp9BTvQnsPVLwZDAYjLZoX4T7rQnSpNvt///d/YuuttxaPP/64eP7558X6668v/v73vyvHzJ49W2ywwQbiiCOOEO+++67405/+JLbbbjvR1sZCIMPimeNQcwajfGCDFqOe0diDPd4MBoOREs0bXy2at7qH+607erx32203cc011wTe6z//+c9Syd5zzz3F5ptvLj8766yzxA8//CDGjx8vBgwYIL7//nux4oorimuvvTaipDN6OAIFoQeS6DAYlULOM2gVOJKEUVMopIvY6GDFm8FgMBLXzJZFRW7x7bijuqPHe8cdd1RCxtdbbz3R1NQkPv/88+Czu+++W+y9995S6QaMGDFC7LTTTuKuu+7qyqYy6gCZbM77hRUEBqN84BxvRjdAoX1utZvAYDAYDEbtlBN75JFHZAj5OuusI/+G37/88kux3HLLKcctv/zy4sknn7ReZ+HChfIfYtasWRVsNaPWwJ45BqOMQI9hgbkTGLWETLrDO+eLHocMc+EwGAxGLaNqqzQQp/3xj38Uv//978Uaa6whP5s7d64oFAqBtxsBf0Putw0Qnt6/f//g3+KLL17x9jNqCOzxZjDKXqaP5xWjntETPd7Z/qrTgsFgMBi1haoo3pMmTRJbbbWVZDW/6qqrgs979epl9FjPnDlT9O7d23q9Y489Vh6D/yZOnFjB1jNqDkyuxmBUINScPd6M+kW2zxKip6F5i/+I5u0fq3YzGAwGg1EroeaTJ0+WRGrLLrusuPfee2WON6K5uVmMGjVKhptTwN9QVswGOA/+MXoouN4wg1F2xZtTOBj1ipY93hWZlkGipyHTsojILbZxtZvBYDAYjFrweE+ZMkUq3aNHjxb33XefUVneddddJcHaggUL5N8///yzeOihh8Tuu+/elU1l1BPY481glJ3VnD3ejHpFtv9okWnueYo3g8FgMGobXerx3mabbWR5sP33319cdtllwedQUgz+AU444QRJurbpppvKcPQHH3xQesG5lBjDCvZ4MxhlQwYJmjjUnFGH5cQYDAaDwahVNHR1ObH29nYxffp05fM5c+YEvw8ePFi888474j//+Y/49ttvxeGHHy722Wcf0dLS0pVNZdQROCSWwagAWPFmMBgMBoPBqE/FG9jHXdC3b19x0EEHVbw9jG6CQme1W8BgdDuwQYtRS8gOWEHkf3qr2s1gMBgMBqM+63gzGGUBe+YYjPKD5xWjhtC87YOisPDnajeDwWAwGIyiwYo3o/7BCgKDUXZkF1mDe5VRM8g09Zf/GAwGg8GoV7DizahrNK55ssguuma1m8FgdCu07jdRiMZ+1W4Gg8FgMBgMRrcBK96MukbjakdWuwkMRrdDpnlgtZvAYDAYDAaD0a3QpXW8GQwGg8FgMBgMBoPB6GlgxZvBYDAYDAaDwWAwGIwKghVvBoPBYDAYDAaDwWAwKghWvBkMBoPBYDAYDAaDwaggWPFmMBgMBoPBYDAYDAajgmDFm8FgMBgMBoPBYDAYjAqCFW8Gg8FgMBgMBoPBYDAqiG5Zx7tQKMifs2bNqnZTGAwGg8FgMBgMBoPRDYH6JuqfPU7xnj17tvy5+OKLV7spDAaDwWAwGAwGg8HoxgD9s3///rHHZAou6nmdIZ/Pi0mTJom+ffuKTCYjaskiAsaAiRMnin79+lW7OQwL+D3VB/g91T74HdUH+D3VB/g91Qf4PdU++B3VB2bVid4EqjQo3cOHDxfZbLbnebzhoUeOHClqFTB4ankAMTzwe6oP8HuqffA7qg/we6oP8HuqD/B7qn3wO6oP9KsDvSnJ041gcjUGg8FgMBgMBoPBYDAqCFa8GQwGg8FgMBgMBoPBqCBY8e5CNDc3i5NPPln+ZNQu+D3VB/g91T74HdUH+D3VB/g91Qf4PdU++B3VB5q7od7ULcnVGAwGg8FgMBgMBoPBqBWwx5vBYDAYDAaDwWAwGIwKghVvBoPBYDAYDAaDwWAwKghWvBkMBoPBYDAYDAaDwaggWPFmMBgMBoPBYDAYDAajgmDFm8FgMBgMBoPBYDAYjAqCFW8Gg8FgMBgMBoPBYDAqCFa8GQwGg8FgMBgMBoPBqCBY8WYwGAwGg8FgMBgMBqOCYMWbwWAwGAwGg8FgMBiMCoIVbwaDwWAwGAwGg8FgMCoIVrwZDAaDwWAwGAwGg8GoIFjxZjAYDAaDwWAwGAwGo4JgxZvBYDAYDAaDwWAwGIwKghVvBoPBYNQt2traxOjRo8WVV16Z+rOehp9++kn2wc0331zSdRYsWCDWW2898d///ldUE+uuu6447rjjRHeC/kzTpk0TK620knj++eer2i4Gg8FglA5WvBkMBoPRJQAFAhQ//Ad/b7vttuLiiy8W8+bNK+qa+XxefPnll+Lnn39O/Vk94plnnpF9BorveeedJwqFQuSYo48+Wvzf//1f5POOjg7ZBzNmzCipDRdeeKH47rvvxG677aZ8Pn78eHHYYYeJzTbbTKyxxhpizz33FA8++KD1Om+++abYZ599xCqrrCI22GADceaZZ0ql3hVfffWV+PHHH4t6hrRtTYvZs2fLMX7NNdekOk9/pkUWWURsuumm4tBDD5VjmMFgMBj1C1a8GQwGg9ElAKVviSWWEI8//rj8d8cdd0iF56STThJbbLGF6OzsrNi9m5ubxeeffy7+9re/iXrFxx9/LLbbbjuxyy67iLPPPltcdNFF4vzzz1eOefnll8UVV1whle9KYP78+VLh/+tf/ypaWlqCzx977DGx2mqric8++0x6bG+88Uax5ppril/+8pfi97//feQ6zz33nFS2+/fvL2677TZx/PHHSyV1xx13rLiCmbatxQDGMoz36dOnl3wtULrffffdshoGGAwGg9H1aKjCPRkMBoPRQ9GrVy/pCUSsuuqq4vvvvxennXaaeOONN6QntxLIZDLKfesRqCCi8eCf//ynuOqqq8SRRx4p/164cKH44x//KE455ZSKPSsYS2bOnCl+85vfRLzpl19+uWLYAE/y3LlzxVlnnSX+8pe/iHXWWUd+Dl76P//5z/JZrr76avluQBGGEHgwwNx6663it7/9bUXan7attYAxY8aIX/ziF/Jd61EGDAaDwagfsMebwWAwGFXFwIEDA4VI9xqCYrbVVluJFVdcUYbcgrcVFMy0MOV405xn8CjuvvvuYuWVV5Ye5bfeeityDQiDPv3002Ue7lprrSW9tNAWW64xeCjxmqDIgRcacnZN94ew6z322EM+5yOPPGJ8hm+++UYss8wywd9w7rfffhuEm4Pxok+fPtJDmoRXX31V7LTTTrJt0EYwerjgvvvuE8svv7yMXKAAT7UpmmDttdeWPz/88MPgM+hb8DZDmDko3YjNN99cDB8+XNx+++3KNaCPzzjjjEi/F4s0bbXhqaeekh5yUNg32mgjccghh0gDEkYmgFEBABEJmFpBoxDSPtM222wj0wzA6MFgMBiM+gR7vBkMBoNRNYDieN1114mll1464mXcd999xUMPPSTDqjfeeGOpHB9++OHi4YcfFk8//bRobGx0vo8pxxtznseNGyf+97//iX/84x+itbVVHHvssdLzCvm2kGMLAOUWFGMI5b7ggguksgTngefWlGt81FFHiUsuuUQcc8wxUimHvOoTTjhB3H///eL1118XAwYMCO7/4osvirvuukvmHEOuO1VGKRZddFHx9ddfB3+DEj9o0CB5/HvvvSdz5aFNuVwuMb8ZFEfoS+hDMGZA/0KfghJpA/TB2LFjjV7XbNZsx4f+AowcOTL47O2335Y/QenXAZ+BEYLeExTcF154QSqxoBzDNf/0pz+JYpGmrSZAmgQo7/Be4R8YiF577TU5XuFdgnHk3nvvlcr3gQceKA466CB5Xr9+/Yp+JogEgftA/8O9GQwGg1GHKDAYDAaD0QVobm4u9OrVq7DMMsvIf8OHDy9ks9nCOuusU/j222+VYx9+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GzZsWHHw4MHFDz74QPy+evXq4ne+851iz549+X+77767sb64cghmXHTRRcXevXsXd9ppJ/4fjOH111+vPLN27driHnvswedwt912K7Zv37543HHHFevr68Uzzz//PH9/+PDhRdgqf/jDH1LVRQhj1apVxcMOO6zYp08fPg9bbrllsUuXLsUHH3xQeW7RokXFkSNH8rUP41tXV1e8+eablWfuvfdevi+HDh3K5+m9996zDvm3337Ly2vWrFnxhz/8IU1NDJ5++uni+PHji+PGjSvus88+/LyaNm1a8auvvlKe+93vflds06ZNcfr06cVRo0YV+/XrV3zzzTfF7xs2bCh+97vfLfbq1YvP+bbbbmus7/PPPy9us802/LnZs2cXR48eTfvJAXfddVdx0KBBxSlTphT32muvYtu2bYtHHHFEcdOmTcpzc+fO5fM0Y8YMfm5NnTq1uHz5cvH7Z599VjzkkEP4HHXo0KF4xhlnhOpatmwZrwfWwr777svXRteuXYtPPvkk7acIrFu3rnjMMcfwsYU7H8awY8eOxXvuuUd57osvvuB7bsCAAcVddtmFn3k/+MEPMi+HYMYnn3zCxxX20957710cMWIE//vFF19UnoPPPXr04GMMZ1a7du2KDzzwQKJyXOsihHHfffcVhwwZUpw8eTIfO6DhDjjggOL69euV56644gpOl8EegHtp4sSJxaVLlyYuBwH0R4sWLTi9QogHnDlwVgFtAPdOXV1d8ZJLLlGe2bhxY/HAAw8sdurUidPj8C98hu+TlAP4y1/+wudm0qRJnGYBGuKll16qqKkixjsB/vrXvxbffvtthQAZOHAgJygRwBg3b968+Otf/5p/hoUDjPOuu+6qvHfbbbcVV65cWTz88MONjLdLOYSiVWABwg3En/70J86QyZfZlVdeyQnHxYsX88+vv/56sWXLlpyBQDz22GNc2AJjb2O8XeoihAEX3+9///vi5s2bFSEGMAXyeM6aNYszengJwhzU1NQU33jjDfEMzNmrr75afO6552IZ7yOPPJIzH3AwE+Mdj8cff7z42muvic9wZoHg4thjjxXfwR6CS/DHP/4x/wxzCswfMHUImNNbbrml+M033xRPPvlkI+MNQq+tt966uMMOO4g1AGU99NBDtIVi8Mc//lGcZQDYA7CXfvKTnyhzWSgUis888wz/DAw3EJyn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", "text/plain": [ "
" ] @@ -108,7 +108,7 @@ }, { "cell_type": "markdown", - "id": "8eb1a932", + "id": "222f096d", "metadata": {}, "source": [ "The three indicators broadly agree on *when* SPY is stretched (their extremes\n", @@ -119,7 +119,7 @@ }, { "cell_type": "markdown", - "id": "fe1f999e", + "id": "fa2d57b8", "metadata": {}, "source": [ "## Full backtest: rolling z-score mean reversion" @@ -128,13 +128,13 @@ { "cell_type": "code", "execution_count": 3, - "id": "b34b9006", + "id": "b39b0f55", "metadata": { "execution": { - "iopub.execute_input": "2026-08-17T14:37:32.410541Z", - "iopub.status.busy": "2026-08-17T14:37:32.409827Z", - "iopub.status.idle": "2026-08-17T14:37:41.276654Z", - "shell.execute_reply": "2026-08-17T14:37:41.274719Z" + "iopub.execute_input": "2026-08-25T17:35:32.914696Z", + "iopub.status.busy": "2026-08-25T17:35:32.914481Z", + "iopub.status.idle": "2026-08-25T17:35:37.019726Z", + "shell.execute_reply": "2026-08-25T17:35:37.018906Z" } }, "outputs": [ @@ -155,7 +155,7 @@ "Calmar : 0.13\n", "Max drawdown : -34.61%\n", "Hit rate (non-zero periods): 48.91%\n", - "Total costs (currency units): 25981.13\n", + "Total costs (currency units): 25981.17\n", "Number of trades : 1180\n", "------------------------------------------------\n", "Beta : 0.51\n", @@ -172,19 +172,19 @@ { "cell_type": "code", "execution_count": 4, - "id": "3547e04e", + "id": "1983e527", "metadata": { "execution": { - "iopub.execute_input": "2026-08-17T14:37:41.281275Z", - "iopub.status.busy": "2026-08-17T14:37:41.280864Z", - "iopub.status.idle": "2026-08-17T14:37:41.810785Z", - "shell.execute_reply": "2026-08-17T14:37:41.808885Z" + "iopub.execute_input": "2026-08-25T17:35:37.022034Z", + "iopub.status.busy": "2026-08-25T17:35:37.021709Z", + "iopub.status.idle": "2026-08-25T17:35:37.264185Z", + "shell.execute_reply": "2026-08-25T17:35:37.263245Z" } }, "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA94AAAJOCAYAAABBfN/cAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvctoD+AAAAAlwSFlzAAAPYQAAD2EBqD+naQAAzJdJREFUeJzs3QeYXGXVwPEzZXe2b3pCQkIKoQUIvQWBAAGkiwoIiiCgIIKAlV4EQeUDFBREFKQpVZp0pHcIvUMKISE92d6mfM95Z+7snZk7szO70+f/e55Ndmfvztxpd+55z3nP6wqFQiEBAAAAAAA54c7N1QIAAAAAAAJvAAAAAAByjIw3AAAAAAA5ROANAAAAAEAOEXgDAAAAAJBDBN4AAAAAAOQQgTcAAAAAADlE4A0AAAAAQA4ReAMAAAAAkEME3gAAVKD9999ftthiC6lElXzfAQCFQeANAMi6Rx55RFwul/n661//6rjN97///eg27e3tPAsoqD333FO22WYbngUAQE4QeAMAcqa+vl5uvPHGhMs10L777rvN71EYDz74oLz11lsV+fBX8n0HABQGgTcAIGcOOeQQefnll+Xjjz+OufyOO+6Qvr4+OeCAA3j0AQBA2SPwBgDkzN577y3rrLNOQtb7hhtukAMPPFBGjhzp+HdLly6VE044QdZdd12prq6WSZMmyS9/+Uvp7u6ObvP0009HS9X1q66uTrbaaquE0vZrr73W/H7evHly3nnnmf3RbXXf9LJ0WNfx2WefyVlnnSXjx483P1v789RTT8mcOXOkublZampqTMnyPffcE/37Y445RhoaGhxL6k855RTzN2vWrIleNtD1qZ133tl86X3Yb7/9pLGxUb71rW+Z373yyivy9a9/XcaMGWMu17+//vrrJRAIDDjP+eabb5att95aamtrpampSfbaay956aWXHG970aJF5nq0cmHs2LHmObLfRirp3Ed15ZVXyrRp08z+bLvttvL888+b18awYcNitps8ebIcfvjhCX9/3HHHyahRo2Iui7/v66+/vjz55JPyxhtvRF9P+nyp448/3nzf0tKScN0nnXRSwnOX7L7us88+MmLECPN87LLLLvLYY48Nat+TPe+5eI0BALKHwBsAkDMej0e+973vmWAuGAyayz799FMTPB199NFJg+7ttttOXnvtNbnzzjtl9erVcuutt5rS9G984xvR7XbbbTcJhULRr4ULF5rr1GDolltuSbje3/zmNzJx4kT54IMPTCCpQfQRRxyR0f0555xzzCDAu+++awYTNED717/+ZeYHb7LJJvLOO+/IV199JUcddZQceuih5n5bAVRHR4fcfvvtMdfX09Mjt912m6kMGD58uLksneuz6HX+5Cc/kbPPPlvmz58v3/zmN2XFihUmWNZAWAPJ5cuXm6BbH88333wz5f37/e9/b+be66CIPp5ajq2B2a677moGOuw6Ozvl1FNPNY+JPmeXXHKJXHbZZXLNNdcM+Dimex/1Ofv5z39untMvv/zS/O7SSy819zWb9LWwxx57mAEH6/VkBbB62/o4//Of/4z5G/297o++Jq3nzoluo9etrz2t/liyZIn89re/lT/96U+D3l+n5z1XrzEAQJaEAADIsocffjikHzH/+te/Qh988IH5/pFHHjG/O/PMM0PrrLNOyO/3h0466STzu7a2tujfHn/88aG6urrQl19+GXOdTzzxhNn28ccfT3nbBx98cGjnnXeO/nzNNdeYv9Pbtfv73/9uLn/77bcHvD/WdZx22mkxl3d2doZGjhwZ2nfffRP+5uijjzb3MxAImJ832mij0I477hizzb///W9zvXrfMr2+WbNmmb99/fXXY7bTx1kvf+WVV1Lep/322y80c+bM6M9r1qwxj/shhxwSs11PT09o4sSJoa233jp6md62y+UKvffeezHbzp49O7TZZpulvN1076PuT21tbej73/9+zDYrV64M1dfXh5qbm2MuX2+99UKHHXZYwnUee+yx5vZS3Xe1xx57xNxHO33eNt54Y8fXRKrXY3t7e2jYsGGhOXPmJN0m031P9rzn4jUGAMgeMt4AgJzaeOONTQZbM8Sa9b7ppptMFlyz4U4eeOAB2WmnnWTChAkxl2vWtaqqSp555hnzs2Ylr7rqKpOl1BJbq0T43nvvNRnMeFqWa7fpppua/61y8wULFsSUruvXv//975i/0Uyw3YsvviirVq0ymcJ4mlHUTKJm+NWxxx5rMu0ffvhhdJt//OMfpsx49913z/j6lD5Gev/tNtpoI1Oer+XF999/v7S1tUk6NBurWWzNjNrpden91uz52rVro5frfs+YMSPhMR2ofD/d+6iPVVdXV8JjrtMTvva1r0k+adZbnzctz7ZoZl8fA81mp7qv+pgdeeSRWd0fp+c9V68xAEB2EHgDAHJOS8A1INbScS0ZTlZmrpYtW2bm23q9XhOc65fb7TZBtzZk06BBXXDBBXLaaaeZElsNFPx+vwnGv/vd75rt4uncbjudv6zsweRA4gcDtMRa/eAHP4jur+6rful+KGt/tYRb74MGQkrnRz/xxBPmbzXIz/T6nPZHrbfeevLf//7X3JYG0ToXevvtt5frrrsuWu7vxLrecePGJfzOusx+2/GPp/WYarmzPhfJpHsfrdvSkvl4Tpclo6+Jofr2t78to0ePjpbRv/DCC6ZEW+dVW8+dEy3zT/Y8DWXfk11fLl5jAIDsIPAGAOTcd77zHRNEnHjiiSYI1Cx4MprRPOigg0zwpo269EsDRmvu7V/+8heznWbO9913X3OdGgRaGfRk839TBUhKs4L2OeP6Fd/wSoMaO6vxlXZpt/ZX99W+v5q9Vxq4aRd3nUOr22qDOWUfhMjk+pz2x565fO6550wzrYcfftg0J/vRj36Ucl6xNv6yBj7iWZfZm+EN9Hgmk+59tG4r1f7Y6Vx0p+z+4sWLZag0668DPDp4pBlhfQ1qoJpqAMl6ztPZh0z3PdnznovXGAAgOwi8AQA5p1nXgw8+2ASCAwUrGjhoIy8rW5iKz+eL+VlLzLVkOl+0u7Tet/iGVslo8KZBo5aAa1CkTdC06dZgr28g2vFab0Oba2nA9eyzzybddscddzSdw//zn//EXK7VA1r+r6XN8Z3EByPd+6j7o9229bbttNmeNueLp4ML2jjPniXWbeM7siejndm1EVky2kldg1NtjHbXXXeZjuDaaC+VWbNmmfuqj38qQ933Qr7GAADpIfAGAOSFzpfWwEIDmFQuvvhikwHU5bD+97//SWtrqwnCdX6tZs6toEvn/mpQpgGGljdrwK2lsqnm3GabBmua/dSO6zoPWNcr13nJn3/+uemCHT+vXJcw0yBIu4HrnHKdkzuU63OiQZ4+xhq06RJY+vhpAKblw7Nnz076dxqMaYdyvW19DrQ7uu6jPqaaedWO59mQ7n3U/fn1r39tsrd//OMfTSCq2+rAjVNGVpf90v296KKLzP3WQFaDUA3g06Hz03Uf3n//fccSbw2ydd+uvvpq6e3tTXjukt1XrTJ4/PHH5Yc//KF88sknphu6lqrrkmbZ2vd8v8YAAIOQxUZtAAAkdDVPxamruVqxYkXo1FNPDU2bNi1UXV0dGjduXGjPPfcM3X777aYbuuro6AidcsoppguzduPeZZddTKfn+E7QVvfp+fPnx9zGhx9+aC6/4YYbBnzWkl2H5YUXXggdeOCBoVGjRoV8Pl9o+vTpZj/eeeedhG3POeccc126rXYMH+z1aXdr/YrX1dUVuu6668zvtPO3dtXebrvtQtdff/2Anb2VPh5bbrmlud2GhgbT7fu5556L2SbZbZ911lnmvvX19Tner0zvo/q///u/0OTJk802W221Vejpp58O/ehHP0roaq4uv/xy04Fdt91pp51Cb7zxRtpdzVetWhU64IADQk1NTeY+aOf0eI8++qj5nV5fsufOiXYU19dvY2OjuX59rep1DWbfkz32uXiNAQCyx6X/DCZgBwAAKATN6GsFRSaN8bJBqyo0C63Z5CuuuCKvtw0AKG2UmgMAAKTBmhetZeAAAGSCwBsAAGAAOvdb16LXJoHx65cDADAQ74BbAAAAVDDtrq7Lp+2yyy5y7bXXFnp3AAAliDneAAAAAADkEKXmAAAAAADkEIE3AAAAAAA5xBzvNASDQVmyZIk0NjaaOV4AAAAAgMoWCoWkra1Nxo8fL2536pw2gXcaNOieOHFitp4fAAAAAECZWLRokay77roptyHwToNmuq0HtKmpKTvPDgAAAACgZLW2tpoErRUvpkLgnQarvFyDbgJvAAAAAIAlnenINFcDAAAAACCHCLwBAAAAAMghAm8AAAAAAHKIwBsAAAAAgGILvLV725o1a1Ju093dbbqA9/b2lsw2AAAAAAAUNPC+++67ZeuttzYt06dOnSrrr7++PPjggwnbnXfeeTJixAjZYostZNSoUXLVVVcV/TYAAAAAAOREKAMnnXRSaO7cuaFgMGi+LrroopDP5wt9/PHH0W1uuummUG1tbeiFF14wP993330hj8cTeuyxx4p2m4G0tLSE9KHS/wEAAAAAaMkgTnTpP4MN2gOBgNTW1spf/vIXOe6448xlO+20k0ybNk1uvvnm6HazZ8+W4cOHyz333FOU26RTWt/c3CwtLS2s4w0AAAAAkEzixCE1V5s3b5709fXJhAkTzM/BYFDmzp0rO+64Y8x2O++8s7z++utFuQ0AAAAAALnkHewf+v1+Of7442XmzJkyZ84cc1lbW5v09PTIyJEjY7bVedUrV64sym2c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XSETeD8TF3SruIr0pLy25PUvvlU/9B0HKgiBNwAAKGpfLA/KRf/uiLmsIS7w1iBD1xbeYSPnrspAOau1LZOtAbayysgt40e6Y6ZraHV5put40yMNyGPgHQgE5L///a/MnTtXDjnkENl8880dt/vkk0/kscceM80bDjzwQJk4cWLM77u6uuQ///mPLFy4UKZPny4HH3yweL3egm0DAACKk5bIxhvdHBspnHJQnTz3fotMGpNmBAGUkWBkPW5138vd5n+d621X54trtDbcLV+tDmYUUKcboANIlNHb59FHH5X1119frrvuOrngggvknXfecdzu4osvli233FJef/11WbBggey///7y0ksvRX+/Zs0a2W677eTSSy+VpUuXyhlnnCG77babdHd3F2QbAABQXPyBkCxcFpAlqwLS0hFOy1XZ4ohJo2NPYRrrwpHD2gEaPwHlvB63+suD4Q7/O23SX2auauMCb19V7PztdKRbkg4gUUZp37Fjx8ozzzwjkyZNSrpUx8MPPyznnHOOPPHEE7L77ruby84//3xZtmxZdJvf/va30tHRYQL3hoYGOeuss2TDDTeUa665Rk477bS8bwMAAAo7h1uDhdbOoPT4RX4wp1aefa9XLrwttrx8l82q5cm3es337rhAYcwwtwkknnm3V5auCci44XRSRmVmvC0bToh9D9TGlZ7bS9HTjLvFle6GAIaW8d5iiy1M0J3KlVdeKXvssUc06Fb19fUyderU6M933323HHrooSYQVmPGjJEDDjhA7rrrroJsAwAACufDRQH5432dcsPj3XLbU92y55lr5L0F4S7lY4e7ZfeZ1fKtnX0yY73k+YKGGrcctKNPevposIbKE4gLvJ/63XBprHOnDLxHN/X/vjrN1ghbTA2/B4+Y3b+UH4D0ZH2i8yuvvCI///nP5eWXXzbZcQ109957bxk/frz5fW9vr8yfP9/MtbbTnx966KG8b+Okp6fHfFlaW1sH+WgAAICBXHlvbGZbLYnMPb3v3GEyojEcIPz5gc6U1zO8we0YhADlLmCvNdcBq2GJuTV7abnZZnj/NvVxZeip3mMf/HWkeKk5BzLmznapWEtLi9x///3y4x//WFauXGkyy1raraXnSsu+VXNz/xqDatiwYdLe3p73bZxccskl5m+sr/jGcAAAIHuedlje6JPFfhMoDG/oDwh6/ann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jH/ve9+TCy64wATlls8//9wE6CoYDMoHH3wgc+fONT8vWbLEbKtfL7zwgrzzzjvS3d0dc92aTdff9/T0RC/T7/Wyd999N2bbhQsXmusJhUIxl69evVpef/11c10D0et+++23zT52dHRkbV/iH4f33nvPfOn3AAAUCwJvAACK3Jlnnmn+/+tf/xq97A9/+IPss88+JjDVEvVvf/vbJkBXGpj++te/Nl+/+MUvZP/995eRI0fGZM3nzZsnX/va1+SJJ56IXqbf62V77rlnTJB96qmnyrHHHmvmnysNan/2s5/J2LFj5dBDD5Udd9zRzO12Cnb1ei6++GJz+7ofur1+r+XzfX19Q94X63HQ6oCtttpKjjzySLM/G2ywgXzyySdZegYAABgaAm8AAIrcRhttJCNGjJBXX3015nKdC37hhReaIPX99983c8WVBuFWxvvFF1+UL774Qv75z3/Kb37zG/nPf/5jttluu+2kqalJHnvssej1Pf7447LOOuvI8uXLTXZaBQIBeeqpp0wAbLn00kvliiuukFtvvdUEzfqlwf/f//73hH2/7LLL5Oyzz5bLL7/cNF377LPP5I477pCrrrpKfv7znw95X6zHQe+b/r1uq7ehQb0G6QAAFAMCbwAASsCoUaNk5cqVMZdpyfaPfvQjk3lWW265ZczvdXstBdcM+Lhx48x88QcffND8Trulz549OyHYPe6440xHcv1eabDf0tISbe6mWW0Noq3stUX/Tjux2+m2v/vd78zt/PCHP4xefuCBB5rM9DXXXGPK1Qe7L/bH4cQTT5QxY8aYn/XxOProo+Xhhx+Wrq6uQT7iAABkD4E3AAAlQNfGrqmpSbh81qxZCZdpxle7oWvG+KijjjLl5lp2vmbNGpN1tmgA+9FHH5nLdF64zhPXy/TLCoI16PV6vSYwtuZUr1q1SnbeeeeE242/TDPhuu0uu+ySsK3un2al33zzzUHvi8Xtdpusud2UKVPM//b7CwBAobCcGAAARU6ztrrW9w477BBzeWNjo9TW1iZs/81vftMEtfo3VjZcbbjhhjHzsK3MsQa2GtDq9eltLF68WI455hhzuxrsWqXgqrOzM3rb8Zqbm2N+traNv9x+mdVobTD7Yn8cqqqqYi6zBimsfQAAoJDIeAMAUOQeeOABM495v/32S8j0xtM50drFXDPd9qBbA1ftCG6n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", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA94AAAJOCAYAAABBfN/cAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvctoD+AAAAAlwSFlzAAAPYQAAD2EBqD+naQAAzJ1JREFUeJzs3QeUG9XVwPGrsqvt625jY+OCaQZMbyaAAQOhhyTUhECABEIgQCq9BAJJ+ICEJBBCAqEl1NBCJ/QOpndwwdi429ubynfuk0Y7kkZaaVdd/985sne1s9JIK43mvnvffa5QKBQSAAAAAACQE+7c3CwAAAAAACDwBgAAAAAgx8h4AwAAAACQQwTeAAAAAADkEIE3AAAAAAA5ROANAAAAAEAOEXgDAAAAAJBDBN4AAAAAAOQQgTcAAAAAADlE4A0AQAXaf//9ZYsttpBKVMmPHQBQGATeAICse+SRR8TlcpnLX//6V8dtvve970W3aW9v56+Agtpzzz1lm2224a8AAMgJAm8AQM7U19fLjTfemHC9Btp33323+TkK48EHH5S33nqrIp/+Sn7sAIDCIPAGAOTMIYccIi+//LJ8/PHHMdffcccd0tfXJwcccADPPgAAKHsE3gCAnNl7771lnXXWSch633DDDXLggQfKyJEjHX9v6dKlcuKJJ8q6664r1dXVMmnSJPnFL34h3d3d0W2efvrpaKm6Xurq6mSrrbZKKG2/9tprzc/nzZsn559/vtkf3Vb3Ta9Lh3Ubn332mZx99tkyfvx48721P0899ZTMmTNHmpubpaamxpQs33PPPdHfP/bYY6WhocGxpP7UU081v7NmzZrodQPdntp5553NRR/DfvvtJ42NjfKtb33L/OyVV16Rr3/96zJmzBhzvf7+9ddfL4FAYMB5zjfffLNsvfXWUltbK01NTbLXXnvJSy+95HjfixYtMrejlQtjx441fyP7faSSzmNUV111lUybNs3sz7bbbivPP/+8eW0MGzYsZrvJkyfL4YcfnvD7xx9/vIwaNSrmuvjHvv7668uTTz4pb7zxRvT1pH8vdcIJJ5ivW1paEm775JNPTvjbJXus++yzj4wYMcL8PXbZZRd57LHHBrXvyf7uuXiNAQCyh8AbAJAzHo9Hvvvd75pgLhgMmus+/fRTEzwdc8wxSYPu7bbbTl577TW58847ZfXq1XLrrbea0vRvfOMb0e122203CYVC0cvChQvNbWowdMsttyTc7q9//WuZOHGifPDBByaQ1CD6yCOPzOjxnHvuuWYQ4N133zWDCRqg/etf/zLzgzfZZBN555135KuvvpKjjz5aDj30UPO4rQCqo6NDbr/99pjb6+npkdtuu81UBgwfPtxcl87tWfQ2f/zjH8s555wj8+fPl29+85uyYsUKEyxrIKyB5PLly03Qrc/nm2++mfLx/e53vzNz73VQRJ9PLcfWwGzXXXc1Ax12nZ2dctppp5nnRP9ml156qVx++eVyzTXXDPg8pvsY9W/2s5/9zPxNv/zyS/Ozyy67zDzWbNLXwh577GEGHKzXkxXA6n3r8/zPf/4z5nf057o/+pq0/nZOdBu9bX3tafXHkiVL5De/+Y388Y9/HPT+Ov3dc/UaAwBkSQgAgCx7+OGHQ/oR869//Sv0wQcfmK8feeQR87OzzjortM4664T8fn/o5JNPNj9ra2uL/u4JJ5wQqqurC3355Zcxt/nEE0+YbR9//PGU933wwQeHdt555+j311xzjfk9vV+7v//97+b6t99+e8DHY93G6aefHnN9Z2dnaOTIkaF999034XeOOeYY8zgDgYD5fqONNgrtuOOOMdv8+9//Nrerjy3T25s1a5b53ddffz1mO32e9fpXXnkl5WPab7/9QjNnzox+v2bNGvO8H3LIITHb9fT0hCZOnBjaeuuto9fpfbtcrtB7770Xs+3s2bNDm222Wcr7Tfcx6v7U1taGvve978Vss3LlylB9fX2oubk55vr11lsvdNhhhyXc5nHHHWfuL9VjV3vssUfMY7TTv9vGG2/s+JpI9Xpsb28PDRs2LDRnzpyk22S678n+7rl4jQEAsoeMNwAgpzbeeGOTwdYMsWa9b7rpJpMF12y4kwceeEB22mknmTBhQsz1mnWtqqqSZ555xnyvWcmrr77aZCm1xNYqEb733ntNBjOeluXabbrppuZ/q9x8wYIFMaXrevn3v/8d8zuaCbZ78cUXZdWqVSZTGE8zippJ1Ay/Ou6440ym/cMPP4xu849//MOUGe++++4Z357S50gfv91GG21kyvO1vPj++++XtrY2SYdmYzWLrZlRO70tfdyaPV+7dm30et3vGTNmJDynA5Xvp/sY9bnq6upKeM51esLXvvY1ySfNeuvfTcuzLZrZ1+dAs9mpHqs+Z0cddVRW98fp756r1xgAIDsIvAEAOacl4BoQa+m4lgwnKzNXy5YtM/NtvV6vCc714na7TdCtDdk0aFAXXnihnH766abEVgMFv99vgvHvfOc7Zrt4OrfbTucvK3swOZD4wQAtsVbf//73o/ur+6oX3Q9l7a+WcOtj0EBI6fzoJ554wvyuBvmZ3p7T/qj11ltP/vvf/5r70iBa50Jvv/32ct1110XL/Z1Ytztu3LiEn1nX2e87/vm0nlMtd9a/RTLpPkbrvrRkPp7Tdcnoa2Kovv3tb8vo0aOjZfQvvPCCKdHWedXW386Jlvkn+zsNZd+T3V4uXmMAgOwg8AYA5NwRRxxhgoiTTjrJBIGaBU9GM5oHHXSQCd60UZdeNGC05t7+5S9/Mdtp5nzfffc1t6lBoJVBTzb/N1WApDQraJ8zrpf4hlca1NhZja+0S7u1v7qv9v3V7L3SwE27uOscWt1WG8wp+yBEJrfntD/2zOVzzz1nmmk9/PDDpjnZD3/4w5TzirXxlzXwEc+6zt4Mb6DnM5l0H6N1X6n2x07nojtl9xcvXixDpVl/HeDRwSPNCOtrUAPVVANI1t88nX3IdN+T/d1z8RoDAGQHgTcAIOc063rwwQebQHCgYEUDB23kZWULU/H5fDHfa4m5lkzni3aX1scW39AqGQ3eNGjUEnANirQJmjbdGuztDUQ7Xut9aHMtDbieffbZpNvuuOOOpnP4f/7zn5jrtXpAy/+1tDm+k/hgpPsYdX+027bet50229PmfPF0cEEb59mzxLptfEf2ZLQzuzYiS0Y7qWtwqo3R7rrrLtMRXBvtpTJr1izzWPX5T2Wo+17I1xgAID0E3gCAvND50hpYaACTyiWXXGIygLoc1v/+9z9pbW01QbjOr9XMuRV06dxfDco0wNDyZg24tVQ21ZzbbNNgTbOf2nFd5wHreuU6L/nzzz83XbDj55XrEmYaBGk3cJ1TrnNyh3J7TjTI0+dYgzZdAkufPw3AtHx49uzZSX9PgzHtUK73rX8D7Y6u+6jPqWZeteN5NqT7GHV/fvWrX5ns7R/+8AcTiOq2OnDjlJHVZb90fy+++GLzuDWQ1SBUA/h06Px03Yf333/fscRbg2zdtz/96U/S29ub8LdL9li1yuDxxx+XH/zgB/LJJ5+Ybuhaqq5LmmVr3/P9GgMADEIWG7UBAJDQ1TwVp67masWKFaHTTjstNG3atFB1dXVo3LhxoT333DN0++23m27oqqOjI3TqqaeaLszajXuXXXYxnZ7jO0Fb3afnz58fcx8ffvihuf6GG24Y8K+W7DYsL7zwQujAAw8MjRo1KuTz+ULTp083+/HOO+8kbHvuueea29JttWP4YG9Pu1vrJV5XV1fouuuuMz/Tzt/aVXu77bYLXX/99QN29lb6fGy55ZbmfhsaGky37+eeey5mm2T3ffbZZ5vH1tfX5/i4Mn2M6v/+7/9CkydPNttstdVWoaeffjr0wx/+MKGrubriiitMB3bddqeddgq98cYbaXc1X7VqVeiAAw4INTU1mcegndPjPfroo+ZnenvJ/nZOtKO4vn4bGxvN7etrVW9rMPue7LnPxWsMAJA9Lv1nMAE7AABAIWhGXysoMmmMlw1aVaFZaM0mX3nllXm9bwBAaaPUHAAAIA3WvGgtAwcAIBME3gAAAAPQud+6Fr02CYxfvxwAgIF4B9wCAACggml3dV0+bZdddpFrr7220LsDAChBzPEGAAAAACCHKDUHAAAAACCHCLwBAAAAAMgh5ninIRgMypIlS6SxsdHM8QIAAAAAVLZQKCRtbW0yfvx4cbtT57QJvNOgQffEiROz9fcBAAAAAJSJRYsWybrrrptyGwLvNGim23pCm5qasvPXAQAAAACUrNbWVpOgteLFVAi802CVl2vQTeANAAAAALCkMx2Z5moAAAAAAOQQgTcAAAAAADlE4A0AAAAAQA4ReAMAAAAAUGyBt3ZvW7NmTcpturu7TRfw3t7ektkGAAAAAICCBt533323bL311qZl+tSpU2X99deXBx98MGG7888/X0aMGCFbbLGFjBo1Sq6++uqi3wYAAAAAgJwIZeDkk08OzZ07NxQMBs3l4osvDvl8vtDHH38c3eamm24K1dbWhl544QXz/X333RfyeDyhxx57rGi3GUhLS0tInyr9HwAAAACAlgziRJf+M9igPRAISG1trfzlL3+R448/3ly30047ybRp0+Tmm2+Objd79mwZPny43HPPPUW5TTql9c3NzdLS0sI63gAAAAAAySROHFJztXnz5klfX59MmDDBfB8MBmXu3Lmy4447xmy38847y+uvv16U2wAAAAAAkEvewf6i3++XE044QWbOnClz5swx17W1tUlPT4+MHDkyZludV71y5cqi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XSETeD8TF3SruIr0pLy25PXPv1U/9B0HKgiBNwAAKGpfLA/KJf/uiLmuIS7w1iBD1xbeYSPnrspAOau1LZOtAbayysgt40e6Y6ZraHV5put40yMNyGPgHQgE5L///a/MnTtXDjnkENl8880dt/vkk0/kscceM80bDjzwQJk4cWLMz7u6uuQ///mPLFy4UKZPny4HH3yweL3egm0DAACKk5bIxhvdHBspnHpQnTz3fotMGpNmBAGUkWBkPW5138vd5n+d621X54trtDbcLV+tDmYUUKcboANIlNHb59FHH5X1119frrvuOrnwwgvlnXfecdzukksukS233FJef/11WbBggey///7y0ksvRX++Zs0a2W677eSyyy6TpUuXyplnnim77babdHd3F2QbAABQXPyBkCxcFpAlqwLS0hFOy1XZ4ohJo2NPYRrrwpHD2gEaPwHlvB63+suD4Q7/O23SX2auauMCb19V7PztdKRbkg4gUUZp37Fjx8ozzzwjkyZNSrpUx8MPPyznnnuuPPHEE7L77rub6y644AJZtmxZdJvf/OY30tHRYQL3hoYGOfvss2XDDTeUa665Rk4//fS8bwMAAAo7h1uDhdbOoPT4Rb4/p1aefa9XLrottrx8l82q5cm3es3X7rhAYcwwtwkknnm3V5auCci44XRSRmVmvC0bToh9D9TGlZ7bS9HTjLvFle6GAIaW8d5iiy1M0J3KVVddJXvssUc06Fb19fUyderU6Pd33323HHrooSYQVmPGjJEDDjhA7rrrroJsAwAACufDRQH5w32dcsPj3XLbU92y51lr5L0F4S7lY4e7ZfeZ1fKtnX2y6XrJ8wUNNW45aEef9PTRYA2VJxAXeD/12+HSWOdOGXiPbur/eXWarRG2mBp+Dx45u38pPwDpyfpE51deeUV+9rOfycsvv2yy4xro7r333jJ+/Hjz897eXpk/f76Za22n3z/00EN538ZJT0+PuVhaW1sH+WwAAICBXHVvbGZbLYnMPb3vvGEyojEcIPz5gc6UtzO8we0YhADlLmCvNdcBq2GJuTV7abnZZnj/NvVxZeip3mMf/HWkeKk5BzLmznapWEtLi9x///3yox/9SFauXGkyy1raraXnSsu+VXNz/xqDatiwYdLe3p73bZxceuml5nesS3xjOAAAkD1POyxv9MlivwkUhjf0BwS9/tTz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AECRmjhxognGv/vd78qFF15ognLL559/bgJ0FQwG5YMPPpC5c+ea75csWWK21csLL7wg77zzjnR3d8fctmbT9ec9PT3R6/Rrve7dd9+N2XbhwoXmdkKhUMz1q1evltdff93c1kD0tt9++22zjx0dHVnbl/jn4b333jMX/RoAgGJB4A0AQJE766yzzP9//etfo9f9/ve/l3322ccEplqi/u1vf9sE6EoD01/96lfm8vOf/1z2339/GTlyZEzWfN68efK1r31Nnnjiieh1+rVet+eee8YE2aeddpocd9xxZv650qD2pz/9qYwdO1YOPfRQ2XHHHc3cbqdgV2/nkksuMfev+6Hb69daPt/X1zfkfbGeB60O2GqrreSoo44y+7PBBhvIJ598kqW/AAAAQ0PgDQBAkdtoo41kxIgR8uqrr8Zcr3PBL7roIhOkvv/++2auuNIg3Mp4v/jii/LFF1/IP//5T/n1r38t//nPf8w22223nTQ1Ncljjz0Wvb3HH39c1llnHVm+fLnJTqtAICBPPfWUCYAtl112mVx55ZVy6623mqBZLxr8//3vf0/Y98svv1zOOeccueKKK0zTtc8++0zuuOMOufrqq+VnP/vZkPfFeh70senv67Z6HxrUa5AOAEAxIPAGAKAEjBo1SlauXBlznZZs//CHPzSZZ7XlllvG/Fy311JwzYCPGzfOzBd/8MEHzc+0W/rs2bMTgt3jjz/edCTXr5UG+y0tLdHmbprV1iDayl5b9Pe0E7udbvvb3/7W3M8PfvCD6PUHHnigyUxfc801plx9sPtifx5OOukkGTNmjPlen49jjjlGHn74Yenq6hrkMw4AQPYQeAMAUAJ0beyampqE62fNmpVwnWZ8tRu6ZoyPPvpoU26uZedr1qwxWWeLBrAfffSRuU7nhes8cb1OL1YQrEGv1+s1gbE1p3rVqlWy8847J9xv/HWaCddtd9lll4Rtdf80K/3mm28Oel8sbrfbZM3tpkyZYv63P14AAAqF5cQAAChymrXVtb532GGHmOsbGxultrY2YftvfvObJqjV37Gy4WrDDTeMmYdtZY41sNWAVm9P72Px4sVy7LHHmvvVYNcqBVednZ3R+47X3Nwc8721bfz19uusRmuD2Rf781BVVRVznTVIYe0DAACFRMYbAIAi98ADD5h5zPvtt19CpjeezonWLuaa6bYH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", "text/plain": [ "
" ] @@ -207,7 +207,7 @@ }, { "cell_type": "markdown", - "id": "ba6f732f", + "id": "b4bb7483", "metadata": {}, "source": [ "## Gross vs net performance" @@ -216,13 +216,13 @@ { "cell_type": "code", "execution_count": 5, - "id": "24c02cfe", + "id": "d14cbc71", "metadata": { "execution": { - "iopub.execute_input": "2026-08-17T14:37:41.814934Z", - "iopub.status.busy": "2026-08-17T14:37:41.814501Z", - "iopub.status.idle": "2026-08-17T14:37:41.850420Z", - "shell.execute_reply": "2026-08-17T14:37:41.848413Z" + "iopub.execute_input": "2026-08-25T17:35:37.266155Z", + "iopub.status.busy": "2026-08-25T17:35:37.265892Z", + "iopub.status.idle": "2026-08-25T17:35:37.284828Z", + "shell.execute_reply": "2026-08-25T17:35:37.283934Z" } }, "outputs": [ @@ -270,7 +270,7 @@ " \n", " 3\n", " Total cost (currency units)\n", - " 25,981.13\n", + " 25,981.17\n", " \n", " \n", " 4\n", @@ -291,7 +291,7 @@ "0 Gross total return 140.62%\n", "1 Net total return 99.03%\n", "2 Cost drag 41.59%\n", - "3 Total cost (currency units) 25,981.13\n", + "3 Total cost (currency units) 25,981.17\n", "4 Gross Sharpe 0.34\n", "5 Net Sharpe 0.25" ] @@ -309,7 +309,7 @@ }, { "cell_type": "markdown", - "id": "1994614c", + "id": "6547b644", "metadata": {}, "source": [ "## Takeaways\n", @@ -341,9 +341,9 @@ "version": "3.13.7" }, "quantlab": { - "code_hash": "51c6d2bd9d6fdae1a9aaf52e138fda7161dc9177754dc9b1a96c98498d377105", + "code_hash": "01f453a13e89b4a77bb5e85538cd9963479ca9a60745ac9d35d77a2a58d5c3ba", "config_hashes": { - "configs/mean_reversion_etfs.yaml": "8aeb00604191a1a5f894d8455192522bf7cddb236a5574d6a7827938c52e9dd2" + "configs/mean_reversion_etfs.yaml": "7a22a958b6bb28890ea951eeabacbc403d062452ba8458c23fc8b59d33e57284" }, "generator": "scripts/build_notebooks.py" } diff --git a/notebooks/04_pairs_trading_research.ipynb b/notebooks/04_pairs_trading_research.ipynb index ef0e149..a07e5ab 100644 --- a/notebooks/04_pairs_trading_research.ipynb +++ b/notebooks/04_pairs_trading_research.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "4418eb03", + "id": "50253b77", "metadata": {}, "source": [ "# 04 — Pairs Trading Research (Example)\n", @@ -15,13 +15,13 @@ { "cell_type": "code", "execution_count": 1, - "id": "7bcc1c51", + "id": "af3fdb5f", "metadata": { "execution": { - "iopub.execute_input": "2026-08-17T14:37:57.453812Z", - "iopub.status.busy": "2026-08-17T14:37:57.453078Z", - "iopub.status.idle": "2026-08-17T14:38:12.628649Z", - "shell.execute_reply": "2026-08-17T14:38:12.626355Z" + "iopub.execute_input": "2026-08-25T17:35:39.661804Z", + "iopub.status.busy": "2026-08-25T17:35:39.661290Z", + "iopub.status.idle": "2026-08-25T17:35:53.720738Z", + "shell.execute_reply": "2026-08-25T17:35:53.719847Z" } }, "outputs": [ @@ -58,7 +58,7 @@ }, { "cell_type": "markdown", - "id": "1357510a", + "id": "48551ad1", "metadata": {}, "source": [ "## Hedge ratio and spread" @@ -67,19 +67,19 @@ { "cell_type": "code", "execution_count": 2, - "id": "cd6a5612", + "id": "351fce04", "metadata": { "execution": { - "iopub.execute_input": "2026-08-17T14:38:12.634024Z", - "iopub.status.busy": "2026-08-17T14:38:12.633124Z", - "iopub.status.idle": "2026-08-17T14:38:14.166028Z", - "shell.execute_reply": "2026-08-17T14:38:14.163361Z" + "iopub.execute_input": "2026-08-25T17:35:53.722672Z", + "iopub.status.busy": "2026-08-25T17:35:53.722383Z", + "iopub.status.idle": "2026-08-25T17:35:54.447978Z", + "shell.execute_reply": "2026-08-25T17:35:54.447144Z" } }, "outputs": [ { "data": { - "image/png": "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8cWqRYsWnn+/ceNG/R+xapVcHIIgCIIgCIIgCKnSulVz/bVdm5ZyEMuD4/3SSy+pe++91/cxt956q+rbt6/zfYcOHdTHH3+s//3VV1+pYcOG6flxp512mvXvp0+frqZNm5bsWxMEQRAEQRAEQRAs1K1TW9109QUyxztHVIhEIlF5uyxywAEHqCVLlqg333wzcMa7devWauXKla5MuiAIgiAIgiAIgiDkAvipdevWDeSnZrzHe926dapGjRqun82bN0+1bdvW82/QA47/BEEQBEEQBEEQBKG8k3HHe+edd9bzu6FmDpG1hx9+WH3zzTfqpptuyvRLC4IgCIIgCIIgCELhO96vvvqquvHGG9U111yjKleurOd5//TTT6pNmzaZfmlBEARBEARBEARBKM4e70zWzguCIAiCIAiCIAhCPvmpFTP+bgRBEARBEARBEAShiBHHWxAEQRAEQRAEQRAyiDjegiAIgiAIgiAIglCexdXCgNrQUUMvCIIgCIIgCIIgCLmG/NMgsmnlwvFevXq1/tq6detcvxVBEARBEARBEARBcPmrEFkr96rmpaWlasGCBap27dqqQoUKuX47qtijOgiAzJ8/XxTmyzFyHss/cg4LAzmPhYGcx8JAzmNhIOexMFhVTnwOuNJwulu0aKEqVqxY/jPe+BCtWrXK9dsQGLgB8vkmEIIh57H8I+ewMJDzWBjIeSwM5DwWBnIeC4M65cDnSJTpJkRcTRAEQRAEQRAEQRAyiDjegiAIgiAIgiAIgpBBxPEWkqJq1arqwgsv1F+F8oucx/KPnMPCQM5jYSDnsTCQ81gYyHksDKoWoM9RLsTVBEEQBEEQBEEQBKG8IhlvQRAEQRAEQRAEQcgg4ngLgiAIgiAIgiAIQgYRx1sQBEEQBEEQBEEQMki5mOMthMvy5cvVF198oSpUqKB69eqlGjZsGPcYtP5/8sknauHChap79+6qc+fO1uf65ptv1A8//KCGDRummjVrltJrCamxaNEi9dVXX6maNWuqPn36qFq1asU9ZvPmzerDDz9UK1asUP369VOtWrWyPhce8+eff6px48ZZn4eYO3eu+vTTT/XrdenSRU5dCPz000/ql19+US1bttTHFfeK7T7COapUqZIaMmSIPucmGzduVK+//roqKSlRu+++u+fr4X7F62233XaqY8eOcg5DoLS0VH377bf6HurQoYPadtttrY/Deor7p3bt2mrHHXdUVapUiXvM6tWr1RtvvKHXyp133tn6PD///LOaM2eOqlGjhurbt6+qX7++nMcQWLt2rd6v1q1bp3r06KFatGjhue9hLWzfvr3q3bt3xp5HSA3sd59//rn+N+yORo0aWW0c3IsLFixQ3bp1s+5nQZ4nyGOE1Pjjjz/0uopjinXOtl7iHvvggw/0/jdo0CCrjRnkeQjYVNiThw4dqvdkIX1ov8I62KdPH1WxYkXrfYTzCBsHe6PNDg3yPODHH3/Uj8M+3KlTp/w7hRBXE4qHk08+OdKiRYvIiBEjIkOHDo3UrFkzctttt7kes2rVKv275s2bR0aOHKkfc+qpp7oe884770QGDx4c2WabbSDOF3nllVdSei0hedasWRM58MADIy1btozstttukb59+0YaNmwYef75512Pmz9/fqRr166RDh06RHbZZZdI9erVI9dff73rMU888URk2223jXTq1Emfx19++cXzdVevXq2fr1KlSpEZM2bIqUuTL7/8MjJgwIBIt27dIuPHj4+0bt060qtXr8iff/7petwLL7wQqV27dmTQoEH6902aNIl88sknrsecffbZ+l5r06ZNpEuXLtbXW758eWTUqFGRRo0aRSZMmBDp2bNn5Nxzz5XzmCZvvfWWvodwbsaNGxdp3LhxZNiwYZGVK1e6HnfnnXdGatSooX+HdRP35dy5c53fr127NnLcccdFmjVrpv8bPXp03Gtt2rQpsvfee0fq1KmjXwvXBNbVBx54QM5jmlx55ZWRVq1a6b0K+x7Wy8mTJ7ses2XLlsj+++8fqVevnr6XGjRoENlrr730eQn7eYTUgK2CtXDXXXeN7LTTTvr+uPnmm+P20J133lnfZzhHtWrVipx00klJP0+QxwjJ89dff0XGjBkTadeuXWTs2LHa7mjbtm3cvoc9FHZqjx49IjvuuKM+j08//XTSz0Ng78U1AVvomWeekVOXJt98801khx120Mcd+xXsk549e0bmzZvnetzLL7+s9zQ8tnfv3noP/eijj5J+nhUrVujzDXt4jz320HvymWeemXfnURzvIgOO74YNG5zv77nnnkjFihUjc+bMcX52xhlnRNq3bx9ZunSp/n727Nn6MS+++KLLGXj//fcjS5Ys8XS8g7yWkDw45g8//HBk69atzs+mTJmiN30Y7wScKxjmGzdu1N8/+uij+vh///33zmMeeughvahhkUvkeB9yyCGRc845Ry9q4ninz6xZs1wGAO4VOOJwwgk4b/Xr149ceOGFzs8OPvjgSOfOnSOlpaXOz66++mp9XZx33nmejjc2JGxq2JyI5557LoRPUtzAaPjpp5+c75ctW6YNPQQeCTjYlStXjtx77736+82bN2sHHEFJ/ne33nqrDnwedNBBVscbgbIKFSpEfv31V+dnOOcIzPD1QEge7E/83njvvff0mvjaa6+59jQYiHT8YfjBeeYBzbCeR0gNHNv169c73yMohX3vxx9/dH6GfQwO2L///qu//+yzzyIlJSWRZ599NqnnCfIYIXlw/LhNibVt0qRJOmDJ2W677XQAi7jkkkv0fUW2a9DnoWAYgmWwbcTxDocPPvhA+w/cxhk0aJC2RXhCBzYl9jHi8MMPj3Ts2NHZ04I8D4DtBIcce2k+2zjieBc5MOyxyPAoYdOmTSPTpk1zPQ7RXCxYJn6Od5DXEsLh888/18f266+/drKbMCTgoBNw1JAlnzp1atzfJ3K8YVAgs46MjDjemQP3HTLfBIIlOI9kSIAvvvhCn6uPP/447u+9HO+vvvpK/83rr7+ewXcvEEcccYQ24ojp06frSgMYd8TMmTO1E71gwYK4A+fleD/44IORKlWquAKad999t86qSrY0fJB5QQabQFYNAUjOkUceGdl+++2z8jxC8iAYjbXv8ccfd36GffD88893PW748OGRiRMnJvU8qTxGSA0cUxxbVCtQthvfc4cMAS+sj/fdd1/g5yFwPey5557adhLHO3NcdtllukqBePLJJ3WwavHixc7PkAzCOUByIujzfPvtt/pvEAjPd0Rcrch588039VfqSVyyZIn6559/dP8nB31q6JEJ87WE8MCxrVatmtOzix6XrVu3us4jeofxfbLnEf3AZ555pnr44YdV5cqV5bRlkLfeest1znCu0M/UoEED172Ic5nMeXz33Xd1Xxv61t5//3318ssv635kIXw2bdqk3nvvvbjziD5S9N/z84jg9/fffx/4uffdd1+12267qT322EPdc8896uqrr1aXX365uvXWW+XeDBn0X2M/NM9jsntjWM8jhGN3QC/j77//Tvr4B7FfxMbJHDi20EIgfRM6V/w81q1bV7Vu3TrheeTPA9555x117733qrvu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", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA94AAAJOCAYAAABBfN/cAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvctoD+AAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzs3Qd4U+X3B/CT3b3YUPZesvcSAVEBwQ36A/cfFRW3oiJuFPeeOBAUQRkCIkv2kL333qt7ZTTJ/zlvekOSJm2SZuf7eZ7SNiTNzc1Ncs/7nvccmdlsNhMAAAAAAAAA+IXcP38WAAAAAAAAABB4AwAAAAAAAPgZZrwBAAAAAAAA/AiBNwAAAAAAAIAfIfAGAAAAAAAA8CME3gAAAAAAAAB+hMAbAAAAAAAAwI8QeAMAAAAAAAD4EQJvAAAAAAAAAD9C4A0AEAaqV69ODzzwgFeXBVJMTAw98cQTAbmvjh07Uv/+/SkS+eN5LC4upmbNmtEbb7wRtOfMXXq9nurVq0fvv/8+RSp/H7/+ei+I5NcdAIA/IfAGAPCh8+fPk0wms/tKTk6mXr160R9//IF9DVYpKSn00EMPBWyPfPnll3T58uWABNkVfWxqtZrGjx9Pb775Jl26dMmrv2E2m2nJkiU0fPhwql+/PsXHx1PLli3F383NzS11/WHDhpV67fIXB7AV+bsAAAAMgTcAgB+MGTNGnKCbTCbatm0bValShW677TaaPn263wP/77//3q/3Af7n6+fRaDTSpEmT6O6776bExEQKB3fddZd1wMAbO3bsoGuvvZaUSiXNmzePLl68SB9++CH98MMP1KNHD9JqtaVu07BhQ/G6tf3i56KifzcY8F4AABBaEHgDAPgRz5g1aNCAfvrpJ3Gi/tlnn2F/Q8BxgHjmzBkaOXJk2Ox9ToG/9dZb6bvvvhMDB55SqVQ0efJkmjp1KrVq1UrMTA8cOFAEybt37/Z6EMxffxcAACIbAm8AgABISkqiqlWr0unTp0utu+V02qZNm5JGoxEz43feeScdO3bMZ+s6pTW8GzZsoK5du4rfeTCAAxpHhYWFNHbsWKpWrRolJCTQddddR8ePH/d4Xac798V4QKJTp04UFxcnZmJ5JnHz5s121ykqKqInn3xSPDbbbXLG0+135/6dkfbpqlWrrI/znXfeEf/Xtm1ba5oyD7bUqlWL7rnnHjp37pz4/+zsbPF/OTk59M0331ive/XVV5f5PFbkWOHAOy0tTWybK8uXL6f27duLx9K4cWP66quvnF6vrH3mzmMrb//Yuuaaa8SAwdatW8lTnP593333lbq8UaNG4ru3rzFP/64nx6+j22+/nZo0aWJ32YMPPij23dtvv229TKfTiefj+eef99l7gSfb7c6xWZHHAgAQEcwAAOAz586dM/Nb65gxY+wuz8rKMisUCnPPnj3tLr/tttvMcXFx5ilTppizs7PNW7duNbdr185ctWpV86lTp6zXq1atmvn++++3u627l2k0GvOgQYPMd9xxh/nAgQPmjIwM81NPPSW2c/369XbXHTx4sDk1NdU8e/Zsc05Ojvh/vm3Lli3N/fr1K/fxe3JfzzzzjLj+J598Yr5w4YL5zJkz5kceecQcExMj9oNk6NCh5uTkZPOff/4ptmnt2rXm6667zuk2ebL97t6/q8d5/fXXm4cNG2bev3+/+cSJE+Z58+aVul5hYaF53bp15rZt25o7d+5sLi4utv4fP6bRo0c7/fvOnkd3jxVnmjRpYh4wYIDLx8L7kx/LwYMHzZcuXTK//fbbZplMZv7www+92mdlPTZ39w87dOiQOHbef/99s6+8+uqr4m9OmzbN7nI+zlQqlTktLU18r1u3rngdX7x4scJ/193j19G3334r/ubRo0etl9WrV88cGxtr7tOnj/WypUuXiustWbLEZ+8Fnmy3O8dmRR4LAEAkQOANAODHwNtkMpmPHDlivvHGG81yudw8Z84c63U54ODrcpBj69ixY2alUmkXuFQ08K5SpYo5Pz/feplOpzNXqlTJfO+991ovW716tdieL774wu72//33n7jc3cDbnfvavXu3COwmTJhgd3veX1dddZUIDhif7PN9f/bZZ3bXW7NmTalt8mT73b3/sh5nUlKSOTc31+yOFStWiG3YvHmzV4G3J8eKMxwYjxo1yuVjSUlJKfVYbr31VvEYpefSk33mbuBd1v5hfN98+WOPPWb2hT179ogAsWHDhmatVmv3f88995x5+vTp5rNnz5ovX74sfq5evboIDnkwwpu/68nx6ww/v3y9r7/+2m4gYty4cWa1Wm19bp5//nnxHBcVFfnkvcCT7Xb32KzIYwEAiARINQcA8IMvvvhCpFDK5XJRsGnhwoU0Y8YMGjp0qPU6y5YtE99vvvlmu9tyG6UOHTpY/98XONWX16LaVo3mtM+jR4/apRqzIUOG2N22c+fOIk3el/c1f/58UbiKC87Z4n3G6cUrV64Uv0v74MYbb7S7Hhexqly5st1lnmy/u/dflr59+zotVLZz50665ZZbRIoup1LbplofPnyYvFGRY4VTd7ngV1lF1Zw9Fq7yzVW6pTRyX+wzT/cPH0cKhUKksFfUhQsXrMcRr8PmlGhb7777Lt1xxx1Uo0YNqlSpkvh52rRpIr26rLZmZf1dT45fZ/j55RT2xYsXi9+5mjrf7umnnxbp3StWrLBezp0TOHXcF69PT7bb3WPTH48FACCcIPAGAPBjVXPuR7xlyxax9vGpp56yq5CckZEhvju2K5Iu49ZPvsLBhLN157YBjbQ9zoJsTwJvd+5L2g9t2rQRwRcHVzxIwV8ff/wx5efni30nbROv2XbkeJkn2+/u/ZeF1yY7OnXqFPXs2VPcftGiRZSXlyeOAyl4NRgM5I2KHCscCHIQU1arq7L2r/S3fbHPPN0/BQUForBaamoqVQTvP17jf/bsWfrrr7/Emn938IACH7tr1qzx6u96cvy6MmDAAPr333/FfuCgtF+/fmJggO+Lf+fnhzsn8PV8/V7gyevOnWPT148FACCcIPAGAPAjroDMBatmz54tZsZGjx5t/T8udsX4ckd8mTszYu7iWcXy8Akw4/ZIjpxdVpH7kh7bkSNHxGwXn4hz6zX+kto48UyctE2u9pG32+/u/Zf33Dri55mDSS5MxgFqbGxshQp5+epYqVu3bqm2WI5/w9Vl0n71xT7zdP9IBdd4+73FASUXgOPZ9Llz54pgzxfc+bueHL+ucBDK97V+/XqR1cH3yfg7zx7zjDLve3eDVU/eC9zZbk+OTV8/FgCAcILAGwAgADjFkmfBeVaMK2Ez6USdgxFbJ06cELPkvgoQ3MXpxmzBggV2l2/atMmjwNsdgwcPFt9///33cmccparcttatW1dqlteT7Xf3/r3lmMY8ZcqUUtfhdF9OA3dHRY8VnmXm67nCab48C22Lg0lOP+cK5p7us/Iemzv7h23cuFF859Rjb3CQz9W49+7dS3PmzPE4oOPgkDMFOMXam7/ryfHrCv8Nzi546623RNAq3Rd/37dvH/3444+iijgPZPiKJ9vtybEZjMcCABAygr3IHAAgGqqaM66OnJCQYO7evbv1sptvvllcxpWQuRrwtm3bzB07djRXrlzZfPLkSZ8VVxs7dmyp7Rk4cKC5TZs2dpdxgSyu6jx37lxRbGvDhg3mIUOGeFTV3N37evbZZ8X1J02aJKqCc4VrLuD13nvv2e0/20rlvE1czIkrijvbJk+239379+RxcoVzLhQ1fPhwa9VvLtrFhcr4uPjll1+s17322mvNzZs3F8W8HDl7Ht09Vpzhon58/3wbZ4+Fnx/++1zwiguLvfvuu6IYIO8Lb/aZq8fmyf5hvA9q1apVqtr5Sy+9JK7PBfVc4W3jatm8vf/880+Z+4ercHOlby7yxoXUuNr3jBkzzDVq1BDVzW0rm3vydz09fl3p2rWreLzNmjWzXqbX68XxwJePGDGi1G0q+l7gyXZ7cmx681gAACIBAm8AgAAF3uzll18W/y+1nuITztdee83cqFEj0cKIqwtzAHD48GG72wUq8C4oKBAVpLnyMVdp5utwNeJWrVqZb7jhhnIfvyf3xbhydO/evc2JiYni/vh+XnjhBfPp06ftAp3HH3/cuk3cFosrxXfo0KFUAODp9rtz/548Tvb333+LVkrcJqlOnTrmt956y7xz585SgeWuXbvM3bp1E9fj/7NtqeTseXT3WHGGA9f09HTROsrVY+H2Tfwc8e9cnfvzzz93+rfc2WdlPTZ39w9XB+fq6NymyxFvL1dY54ECV/jx8N909WVbdd1oNJpnzZolBgz42OHBAd7PfD+O7cQ8+bueHr+ujB8/3ml1dw6O+fLJkyeXuk1F3ws82W5Pjk1vHgsAQCSQ8T/BnnUHAIDQxsWtuGrx5MmTKRyF+/b7wueff06vvvqqWE9dVoXzUMHPFVe8PnTokEg/ttWuXTtq0aKFqDoOAAAQDrDGGwAAysRViHk9Zp8+fcJyT4X79vvKQw89JALYjz76iEIdV0d/44036OWXXy4VdPMaY15b/frrrwdt+wAAADyFGW8AALDi4kaFhYWikBbPEq9du1YEbDxDyoWSHItihZpw334AAACITJjxBgAAq2HDhtHBgwdFb2KeaXzggQdEqx+u7hwOQWu4bz8AAABEJsx4AwAAAAAAAPgRZrwBAAAAAAAA/AiBNwAAAAAAAIAfKSkMmEwmOnv2rCiOI5PJgr05AAAAAAAAEOXMZjPl5eVRzZo1SS6Xh3/gzUF37dq1g70ZAAAAAAAAAHZOnTpF6enpFPaBN890Sw8oKSkp2JsDAAAAAAAAUS43N1dMEEvxatgH3lJ6OQfdCLwBAAAAAAAgVLizHBrF1QAAAAAAAAD8CIE3AAAAAAAAgB8h8AYAAAAAAADwIwTeAAAAAAAAAH6EwBsAAAAAAADAjxB4AwAAAAAAAPgRAm8AAAAAAAAAP0LgDeBjWw8b6MDp4lKXG01mMpvN2N8AAAAAAFEGgTeAD13MNtHwd3Jo1Ps5dpefumSkoa9l09Pf5SP4BgAAAACIMgi8AXxow369+J6Vf2V2e9sRAw17PZsOnjHS/I06mrVWh30OAAAAABBFEHgD+NDcDVeC6sw8S+D95m8FVKuynNZ+kEYt6yho6xED9jkAAAAAQBRB4A3gI2czjLR6t4FG9YsRv5/JMFKRzkx7TxbTnVfHUJVkOdWqrKCzGSbscwAAAACAKILAG8BHdhyzFFS7s68l8D6XaRJBt9FE1LqeSlxWs5IcgTcAAAAAQJRRBnsDACLF8QtGSo6TUf1qCkqKk9GOo8WkNZipcpKMmtRSiOukV1LQmQwtafVmilHLgr3JAAAAAAAQAJjxBvCRkxeNVKeqgmQyGd3aM4b+WKOltXsMdG0HDamUliC7d2s16YuJlmxDgTUAAAAAgGjhceB95MgReu6556h///60bNkyt25z4MABeuSRR2jQoEH0xBNP0KlTp7zZVoCQxmnl9atbZra7t1BRdoGZjl0wUss6VxJL6lVTiBnxnSVp6QAAAAAAEPk8CrwnT55MAwcOpLS0NBF0nzt3rtzbHDx4kDp37kwFBQV0zz330LFjx8Tv58+fr8h2A4SUw2eLad8pIw1opxa/t6p7JdiW0swlDWoo6Oh5Y8C3EQAAAAAAwiDwHjp0KB06dIheeOEFt2/z+uuvU7Nmzejnn3+m2267jf744w/SaDT0wQcfeLO9ACFpw34DqRREfa+yBN5piXJ68Y546nuVilraBOGsQXUFHUPgDQAAAAAQNTwKvCtXrizWr3pi8eLFImCXqFQqGjx4sLgcIFKcumQUFcvVqiuvj3sGxNI3jyeTUiErFXifyTBRvhZtxQAAAAAAooFfi6sVFhbSpUuXKD093e5y/v348eMub6fT6Sg3N9fuCyCUnb5sovTK9inlrnRrriIOxRds1Pt9uwAAAAAAIMIDb73eEljExsbaXR4XF2f9P2cmTpxIycnJ1q/atWv7czMBfFLR3N3Au2YlBbVtoKSNBwzY8wAAAAAAUcCvgXdCQgIplUrKzMy0uzwjI4NSU1Nd3m7cuHGUk5Nj/UIVdAhl5zONdOCMkTo0tl/LXZam6Uo6eBqVzQEAAAAAooHSr39cqaRWrVrR1q1b7S7n39u2bevydlx8jb8AwsHmw5YAuk9rS2E1dzRNV9DMNVrS6s0Uo/asbgIAAAAAAET5jPeUKVNo2LBh1t+5hdjMmTPp8OHD4vfNmzeLwmp8OUAkOJdhpPgYGaUmuP9y6tJMRcVGor826Py6bQAAAAAAEGaB97Zt26h///7ii73zzjvi5w8//NB6naNHj9KKFSusvz/66KM0ZMgQatOmDXXo0IF69epFY8aModtvv92XjwMgaM5nmahGmmdjWA1rKKl7cxUt247AGwAAAAAg0snMZrPZ3SvzWm3HtHFWq1Ytat68uTXw5jXZffr0sbvOiRMn6OTJk9SwYUOqWbOmRxvJVc25yBqv905KSvLotgD+9sgXuaQzmGnyE8ke3e7t6fm0creBFr3put4BAAAAAACEJk/iVI/WeKelpVlnu11p0KCB+HJUt25d8QUQac5nmqhFXfcqmtuqV01BU5drqdhoLtXrGwAAAAAAIodfq5oDRDpOGDmTYaQaqV4E3tUVYp33mcsmv2wbAAAAAACEBgTeABVwNtNEWflmalbb88C7SU0lyWVEG9DPGwAAAAAgoiHwBqiA7UcsrcTaNlB5fNvKyXLq3kJFi7egwBoAAAAAQCRD4A1QAacvGyk5TkaVkrx7KdWvpqAL2Ug1BwAAAACIZAi8ASrgYraJqqZ4/zKqkiKnizkIvAEAAAAAIhkCb4AKuJRTwcA7SU7Z+WbSF7vd1Q8AAAAAAMIMAm+ACs54V0n2/mXE67xZRi5mvQEAAAAAIhUCb4AKuFjRGe+SwJtnzgEAAAAAIDIh8AaoQA9vscY7ueKBN/8dAAAAAACITAi8Aby0/Wgx6YuJmqR73sNbUilRJmbM1+0z4HkAAAAAAIhQCLwBvLR6t55SE2TUuYnK+xegXEbXd1TTip16PA8AAAAAABEKgTeAlzLzzFQ9VS6C54poXU9Jpy+bKLcQ6eYAAAAAAJEIgTeAlzLzTJSWWPGXUPPaSvF9/ykjngsAAAAAgAiEwBsgyIF3/eoKilETbTmEdd4AAAAAAJEIgTeAlzLzzZSWWLE0c6ZUyOja9hqau0GH5wIAAAAAIAIh8AaoyIx3gm9eQu0bKunkJSOZTGY8HwAAAAAAEQaBN4AXOEDOzjdTqg9mvBm3FCs2EmXkIfAGAAAAAIg0CLwBvJBdYCaenE710Yx3tVTL37mQhcrmAAAAAACRBoE3gBcOnC4W3+tVU/hk/1VLsfydi9mobA4AAAAAEGkQeAN4YdNBA6UkyKhxTd8E3pWSZKSQE13Ixow3QKg7dKbYOvgGAAAA4A4E3gBeOHHRJIJuudw3a7wVcplY5336MgJvgEB4eUoeXT8+i6b+W0Rms/u1Ff7ZrKNBE7Lp5jeyac8JBN8AAADgHgTeAF64kGW0pof7SvtGSlq/D728AfxNqzfT3PU6On7BSK//WkBz1rvXyk9fbKZP5hZS63pKSq+ioHdnFvh9WwEAACAyIPAG8MLFHJOYofalLk3VtPtEsTi5BwD/+X2VlnQGovmvpVC/tmr67K9C0R6wPN8tLKITF4004a54uq2nhnYcNZARLQABAADADQi8ATzEaakXs01UzceBt1TZPCsf6eYA/pKdb6JJfxTQbb001LCGkp67NZ4u55pEynl5r/tFW3V0bXs1XVVfJWa9i/RE248g3RwAAADKh8AbwEMFWjMV6iy9t32pUklP8IxczHgD+AvPbptMRI8PjRO/16+uoB4t1LT5UNkB9NcLimj/KSPd1jNG/N6piYrqVpXT7PVaPFkAAABQLgTeAB46X9Jr2+eBd5Ll72XkYsYbwB941nrBJh2NvCbGrkYDB9HbjhjKTDdfuEVHgztrqEdLtfidCys2q62k05fwegUAAIDyIfAG8NC2I8XExcwb+aiVmKRSYkng7cZaUwDwrjZDZp6ZOjZR2V0+pIuGYtUy+mpBocssl4OnjdS1mf3taqTJ6VzJQBwAAABAWRB4A3ho3T49XVVfSakJvn35xKhlFK+RYcYbwE/W7bV0DeD12baqJMtpUGcNzVytpTMZxlK3m71OS1xDjTsP2KqRqqBzmUaP2pEBAABAdELgDeAh7rXdsIZvZ7slqYkyysrHSTyAP0xbrqWeLVVUI6306/e2XjGidsMbv5ZuEfbHGi1d31FNjWo6BN5pctLqibIL8JoFAACAsiHwBvBijXf1kgrkvpaSIHerrREAeGbLIQPtPFZM/+trKY7mqEUdJT05LI427NdTsfFKIK03mOmAkzRzKfBmZzPwmgUAAICyIfAG8ACfkF/iVmKp/pnxblxTQXtPoj0RgC/la0005stckanS5ypLcTRnerdWi1nvF37It1527IKRjCaixrXsZ7tZk1pKilETrd+nxxMGAAAAZULgDeCBU5dMYq2nNNPla+0bqUTLokIdUlcBfGXXsWJRVO2j/0skBVdGdKFlXSU9dmMczd+oE8E6+3eHnmRcTNHJ8pJYjYy6NFXR+v2WteMAAAAAriDwBvDAbyuKKDlORh0al5798oU6VeQisL+MlmIAPsNZJLFqnrUuP1NlQDu1eA3uOW7JPJmzXkc3d9eIZSDOcB9wtBQDAAAAvwTely5dom3btlF2drbbtzl79ixt376dLl686M1dAoQEntm6rqOGEmL8M2aVHG/5uzkFWDMK4AtccXzefzpq11BV5my3hNsE1q4ipye+yRP1Fk5cMIouBq6kV1bQ6QwjmThaBwAAAHBB7ukJzJgxYyg9PZ2GDx9O1atXpwkTJpR5m9OnT1O3bt2oRYsWdM8991CDBg1owIABlJWV5cldA4SEc5kmcVLuLynxlsAgp4JVkg3FCAIA2JFzRtp70kj3DIh1a4coFTJ65pZ4ysgzU9cnM8Xsd/PaZQTeleRkKLb0CAcAAItVu/XUb1ymyBQEAAuPIohvvvmGpk6dSlu3bqUDBw7Q0qVL6e2336Y5c+a4vM0zzzxDRUVFdObMGTHjffz4cXHb119/3ZO7Bgi6/CIT5RaaqaaTVkS+nvGuSHuij+cUUK9nM+kSAgEAOnzW0pe7rFlrR9d31NBbdyfQte3VdHf/GGrl0PfbllRo8XIOBrsAAFhuoYnGfJEr6uK8Nq2Ajp5H0VgAjwPv77//nm699VZq2bKl+L1nz57Ur18/mjx5ssvbXLhwgdq1a0fx8fHi98qVK4vb8+UA4TbbzfxVWI3FaYhUCu9TzaevLKIv5xeJQlI/LcEoM8Cx80ZRlyE1ofw0c8e+3p8/kkQvDU8Qs+CuJFuzVDDjDf7DSxnOZBgpO98ksg8BQtnmgwbSGYgWvJZCdasqaOxXeViOA8BZde7uBaPRSDt37qQHHnjA7vIuXbqUGXi/+OKL9L///Y+++uorkW7+33//ifXhf//9t8vb6HQ68SXJzc3FkwVBd7Yk8K5ZyX+Bt0wmEyfy3qSaF+nM9MovBeJn7jl8+CxGmAH2ny4WBdD4teUPVZLlYrDsyHkj9bCMSQP4DC8bmrlaS1/9XUQXsiyfQTyQ1KaBkm7uEUN9r1KL6voAoXa+xO+LXDPjjVEJ9L/3cmj70WLRuQUgmrkdeOfl5ZHBYKC0tDS7yytVqkQZGRkub9e9e3caOnQovfDCC1S3bl2Rav7www9T69atXd5m4sSJ9Nprr7m7aQABsf9UsejZyyfa/sTp5tlezJ5NWVZESgXRHy+l0Ox1Wlq9Gy2OILrxa/afLXp6/jZLxpU/aFQyattQSev3GWhUP/fWkQO469Vp+TRztY5u7KKhQZ01pDOY6eh5I63apRcFADlLqk9rNQ3tqhE96t0pIAjgb7xcLiVBJgY8OzZWUtVkOf26QovAG6Ke24G3SmUZpbKdiWa8flv6P2fuvPNOUQX91KlTlJSUJH7u3bu3COS//PJLp7cZN24cPfXUU3Yz3rVr1476JwuCa+l2vTjBKSvt1Be8nfHmlNpWdZXUoo6SVuz0LngHiCRLtukpIUZGo/rF+PV++DW3Zg8GusC3fvm3SATdr4+Mp+F97Ad1HhkcJ9bN/r1JT8u26eihz/OoblU5PXRDHF3fSUNxmAWHIMrKM1FKSc0auVxGY4bE0oSpBfTwoFhqWMM/7VgBwoHbU3e8Rptnt7ktmC3+nWeyXaWnc0r5vffeK4JuVqVKFRoxYkSZBdk0Go24vu0XQChUR27jQYEmb6UmyCnDiz7eGXkmqpRkeUknxclEIbhArwXk9ku8BhEg2Li44I9LimhgB/8PlvHrzpvXLIArRpOZvltYRIM6q+mO3s4HjhpUV9KjQ+Jo9iup9Pu4ZGpQXUHjfsqna17IpEkzC1BgE4I+4y25qXuMyBj8d7sezwpENY9yZrmQ2rx58+wC6wULFojLbduHbd68WfysUCgoJSVFVDR3DNa5yBpAuMgrNFF+kZlq+LGiuYRPnqRKzJ7gQJvX/jEeaS42EhXaJ6j4vYrpgBezqPMTmXTtS5miEBBAsGw9bBCv2bHD4vx+X1WSOMPETHq08QMf+WFREZ3PMtE9/WPdqk/Afeq/eTyZ/nkzhW7opKFfVxTRja9m0ay12oA8JzzIezbDSF/OL6RP5hTQ6t0IsKLZ2UwjVUu5cr4Uo5ZR9+Zq+n2VlvK1GKSE6OVR4D1+/HhRGO2RRx6hhQsX0siRIyk7O1u0DLOtfN6/f3/r748++ih98MEH9Mknn9Dy5cvF+u0ffvhB9AMHCBeBKKwmaVZbIe7P0yrJHHjzTDdLKqm0zMFwoPyxRkdavZle+188Xc4105SlqKoOwXP6spFi1STWFvqblGmSiVlv8FEQO+VfLd3SQ0NtGnhWjIpnwV+5M4EWvZVKnZuq6IUf8/36Xszp7re/nU2tHsqgq5/Pos/nFYq1vPd/nEv/bA7gyC+ElKPnjNSwhv1EBdfa4MGkmatwXED08uiMpFWrVrR27VqxPvudd96huLg4Wr9+PaWnp1uvwz936tTJ+vsrr7wignG+Hvfu3rNnD82ePZtGjx7t20cCEIDA25+txCT1q1nS2U9e8mzGmIPspJI1VdVTLd+5h2agzFilFf2PR1wdS7f15BkXLZ3y8DEA+MrpyyaqXcV/1cxtVS4JvHnACaCith4uFhXMh3XTeP03eLbx49GJdP/AWHpzegHd9nY2bT/i2zoEO48Z6KbXsykr3ySCKr6/Ne+n0YaP0qhXSxU9/nUe3fxmNlLeowwfD1n5ZmrgEHhzd4mr6itpxzGD0/OXvSfRiQUin8cLVtu2bUu//PKLy//ndmO2Lcf4pOeOO+4QXwDh6lyGUVQM93dFc5aWaAkUsvM9O4nngmzSjDenq/Ns367jBjHr4W+cYnv8gpHuGWApADRmSBz9vFRLG/YbRPADEIwZ7/TKgTn2KidbXneXMOMNPvDenwXUtJaCOjSu2Hs3n389d2scdWikpA9mFdKdk3JoeJ8YMUDKlaa9HZTilPJdx4vpw9mFYvnVtOeSrVkfkq8fS6K7JllaSN33YQ7NmZCCiutRgme1WU0nExWdmqhoyjKtqAeTlii3ZniM+zFfFMP86tFE6tfW+wEngFDn/ygCIEJmIBpWVwTkxCElwfKy9KQqOad464st/V0ZF5Nqkq6kg2cCM+O881gxmcxELetaAp2kODnVraagA6cxgg3BceIiB96B+YirVHICeSkbaxehYi5kG8Xnzf3XxfqkKCAH1/3baeivCSn04HWxtHirXgTEXI+D206a+I3bTbw298Wf8kRK+WNf5ZHRaKYP/y+xVNDNVEoZzXgxhb5/IokOnjXS5EVYehRNM94steR90dbIa2KpQGumtXuv1ADYdLBYBN3sqW/zUKAVIhoCbwA3rNylp/7t1AHZVzxTrVZyOw6zR+u7pYBXkpZgqWweCIu36CgxVibaKkk46JFS9AECidedHr9goi7N/J/tIQUZnEaJVEnwRVE1zq66urXa58fokzfF06pJqTT12WRqXkdJz/+QT7e8mU0b9pcuhGYoNoue4VKF9T/WaGnQK9n051odjbs9npa+nUp/v5Fq957vTO9WanpgYCy9/2ch/bYCwXc0kLL1+BzEUeVkuTg32HbkyqD835t04rK1H6SJAXwe1JGOPYBIg2Z6AG5UNM8pNFPDmoF5ufAMBY8UZ3kw482ze6y6TWpXYpyczmX6f8ab13FPXa6lMYPj7DICeD38nuOY8YbA215yUtezRWAGyxin7m45jF7e4D29wWwpTDYw1pr55GvcU5mXH/EXB9ycgj7q/Vwa0kVDz9wSRxqVjH5aUiRa8ekMJApkcTDES4k4Zf27sUnUpJZnn4X8d49dMNLMNTpRAwQif8abB4/iY5xnbFzbXkO/r9TSqH6x4jrz/tPRzT00Yinfpw8l0ejPcsVlt/Z03kYPIJwh8AYox7mS9Uo1SgqWBUJKvMyjNd57ThSLWfJGNsVMeL33gdP+HzX+74CBjCaiuwfYf0jyydnsdTrKLzJRQiySayBwLmSbRA/ZWI3/l4ZI6lVV0KItaKEE3uN10xzsDmwfmDWuXZupafoLKvpzjY7e+6NABDtMpSQa0SeGmtdWijXaWoOZ3r03gdo2VHk9mHx9RzU9/V2+yAopb5Ycwhufu6QmyFzWEHj0xlj6a4OWPpxVIAaAOPX8kcGWto9926ipXUMl/bpci8AbIhLe/QDKcS6AFc0lXHSEi4+4a/eJYmpWWynSCW0D70CkmvM6bk4TS4ix3z/XtFHTm78ViAJrvMYQIFAuZpuoWgAKITq+Zvn1xoUG1TavQwB3cIGp7xcVUUKsTLSUDBTOUrq9NxdcU9OyHXoymy3p4dK67Vt6+uZ+ruugoY/nFNLUf4vo7XsSffNHIWRnvFNKOqw4w+cKDw+Oozd+LaB/tuipZR0FpdpkeHCR1rFf54n38aopGLSHyIIjGsCNwJszqAP5AcApV9xOxpMZ71Z17cfReM21vwNvDjLmrtdRHyfrEWtVkotZeKzzhmDMeFcNYIYKSysJVKTCQgCe+HeHnpZt19Ord8X7pKiap3hp0rBuMXRT9xinxdIqigeFOfheuFlPh89iCVI0zHiXhYus/fZ8MvVqpaKHBllmuyWt61nOZfagvRhEIATeAOU4n2WkKinygJ4MtW9oSfFzZ4029788et5ILR0Cby60xilcxUazX1s2ZReY6dr2pQNvTjPjAYRLOQhEIAgz3gGeKZEKCWWgl3fU42ylk5fcr69xJsNIT36bR12aqujGrpG7rvXOvjEUr5HRyz/nB3tTwI+4Po07NQq4Xd7kJ5JpYAdNqUH7SokyUdQWINIg8AYox7q9BmoRwNQ/xoVuOFxeu7f8Yk1cEZRP+Xu3tl9/J/X0zi/yX+B95rIlqHbVL5mzBDgIAgikYKQoSrOEWR4sEYHIw8Umuz+VSYMnZImf3bHpoIG0eqLPHo7sFOxalRT0/O1xtPVIMe1G4c2IxAP9e08UU50q3p8z8aD9qP6x9NsKbUAKxAIEEgJvgHIqmvPMs+OIbCDS/pqmK0TqYXlW7jKIAiXVUhROA+9cPwbenNLLXM0uYsYbAi073ySOy4qc+Hm7xptlIPCOWhm53Oc6nxRyEoOhL0/Jd3twl9vR+auSeSjp31ZDDaor6J0ZmPWO1AKBGXlmGtihYh0lRl4TIyqjc995gEgS+e/yABVwOsMSWPKJQqD1b6umzQcNop9qWTiVm4ubOZJ6euf5cZ03z6Zz33Hbom6lAm/MeEMAcZV9LhDVNUA9vCVxGpl4LWTmof9stPphcZE4/t69P5GevjmeNh8yiDoY5Q3u/rNFRzd1j44ClNxpYGS/GNpyuJi0erxWIo2UBdewZsXOmbgTCteO+XFxEeV40FoVINQh8AYow9kMS5pTzUqBD7wHtNeI/uFcFby89YTOiuFIqbbupjt6g9eQu+rVKW2DNCsOEAhHzhlFYZ9gvGb5Pg+fQ+GoaMQDpFwg7cYuGhrcWSNqbhiKLcdjWeZv1JHeQFETeDMuBMotKA+ewWsl0uw8bhCf+45dTrzx8vB4Op9lwqw3RBQE3gBlOJNhEj1NKycFvspss3QFxWnKPznh9MZKJWmujrPNPBO+9XD568T9FXjXr6YQxddQYA0ChbsBVA9wRXNJz5YqWr3bf683CIxZa7XUdsxl+mRuAR09715wyCmxHGTzbC5rVDLjd+Rs2YH3zDXcFaL0UqFIxq0v0xJlNG25NtibAj60dq+eflqipZ4tVD4byGxYQ0E7j2GABiIHAm+AMvqqLtioo5Z1lCTnfmIBxgVGuBgNB/+uFOrMVKTnwk4ylzMLB84Eb8ZbqrTOfcYBAuFiTvB6v7aooxTtB5FCG744g+iDWQVUqCP6Yl4R3TA+m6avLCr3dtuOGKhuVTm1aWAJOpLj5SL4Xrpd5/I23FaLi4zd2ityK5k7o1HJ6LZeMbRuHwapIsnPS4uoeW0FvT4ywWd/s2NjFS3brkO6OUQMBN4ALvDsxbYjxfR/18cGbR/Vqiyns2UE3pdzLf+X5qIoT+VkOWWWXCcYgTfPuHP7mKNIv4UAznhXC9KMtxTwc/AP4enjOYUiRXzlpFTa+lka3dE7hl75pYBe/zVfBNc8IOsMDy62rmc/08cp51z80tVt9p2yDEh2bRrYegShoGm6UrxW0fc+MnBwvGKngUZcHUtqle8mKh4eFCuy5ub953oACyCcIPAGcEFam9e2ZAYjGDjVinu8urJ2j15U0G1ex76Ht4RT0P1ZZTmvyEQJZQTePGuPlmIQSBeyjUFL25Wq+6OgYHhavFVHM1Zp6d5rY6lGmkIUeHppeDzdd20s/b5KS3dMzKFP/yp0elteTlMjzf6UijtT8OCkq4GYY+eNYhkTd7GINryUih08jWyocHf6spE+mVtIjWsq6I7evq1VUD1NQd2bq+jHJUWiEGE4WL5TL5apcJtAV4NuEL2i793ez/hDFiLD0fNGSo6TuUzjDgQOnLPKqJK8aIueujVXWVsZlbp9kkxUWTaa/HNcnrpsolouenhLqiTL6FIOXhfgf1xB+nKu2WV7O3/DjHf44n7BE37JF++n9w64kuXEs3cv3B5P/32URv+7Joa+ml9UqmYFH3fcO57rathqUN0yIHrURYG14xdMVK9a9KzttsWPm7OlVqEmQth7+rs8MYj0xE1xYrDd1x67MY5OXTLR7PWhP+vN+2H0p7limcpdk3Lopjd4qYq23O40ED0QePvQP5t11OWJDMovCo9ROSh/xrtBDYVfPkjcxQVoOBWv2Fj6TZtHUveeLKYOjVzPyDesoSSOuQ/5YZ23yWSmkxeNVK9qOYF3ihzF1SAgthyytBLjtdbBkBgrI42KRBAG4YPfS8d+nUf8NvvGqASKUZd+z+fZ78dvjBMZRr8uLyp13OkMRJ0dUsZ5qY1KYRnEdWb/6WJqXDM4x2qwKRUyurWnhuZuCP1gClzj5RK8JO/9BxJpQDv/VObnugmt6ylFPYRQfx+Z9EeBOG/b/kUl+urRRNFx5pVf8um7f8qvEwHRAYG3D3EhKX0xldv+CUIfFy1bs0cv3uyDqUktJRmMRIecVMbl2RJe+yRVz3VVXE2tJL8UseE2YXy81ykv8E6WY80rBAT3UObU3ZZ1gzOLKC2t4LWrED64Ivn2o8X07n2JlF5GBk9KgpzuGRBLX8wvome+z7NmuHHV5YRYmTV9WqJSykQF7xU79U4/Y3gmXCpAGY04oOJBKvRpDl+/r9RS1WQ5XdNG7df74ermxy94NoEwZWkRdR6bQV/Mc748xNc4A3HZdj299r8EitPIqF9bDU1+Iplu760R/chP+rG1K4QPBN4+VLuKQpz07TkZ2qNyUL7NhwwiRXt4n+BWm+XAmWdYnLXTGP1ZjvjevLbrE7dYjUykTjo78asoDvoZj+6WhSuzcz90Z7P2AL7EAS8HTsHMUuHX7LIdeqztCxN6g5lem5YvAoc+rcqv5zF2aJyYqf1rg46mlcx8c+ZRoxoKp90vbuulEenUjsvQ9p0sFtlIrYI8uBtMvCaYORtYhtDHn+nch/7mHhoxyORPdataAm93l82duGCkN6cXiPOUn5cVieUg/jR7nZae/DaPrm2vFl+2nropnmI0Mnrj13yknAMCb39U6txyCIF3uOOCL9xDu0H14K6/48CZZ9B4/aFjShPPFNzVN6bcGWcOBFylOlaE1DLJWVqmYzsQTsNcucv3wT+ALV57y5X8g+nmHjFind/Ji5j1DnW8XObFn/NFXYBnb41zq20kr/l++55EGtZNQx/NLqRv/i6kJdv01K+t8xm/VnVVYvnDEYfODl8tsMzCccAerepXU4iB5UNncM4UjrgQYW6hmfr6ebab9WqlEkE0zyi7gwcEuKPKb88ni0GvV6fm+23bNh4w0PM/5NOgThr6eHRiqYFfrsHz7C1xosPB138j5TzaYcbbx3jkj1PNebQNwtfBM0ZqXCs4/bsd8Rohx2I+3Lub+8y2b6R0qzI6397XI77uBt6cSslrHTEgBf7G7fWqJAX3Y40Huhgyn0IXp3mfzzTSja9li5nrN0cliHoYnuDb8KDoB7MKqV1DpUhBd5Uiy+fhjnU2pKJivmy9FG74sfO++wutosLSjNVa6t1KRW0b+D9r46r6KqqZJnea/ecMp3U3qqWgDo1VojgbB+LSOYuvcfG0etXk9N4DCaJ2gTM3do2hkVyccUFhqRoREF0QePtYjxaWkb+9Jf05ITxx6qCUBhdsVZJklJFr/4GRW2AJxJPcaENTs5JczLic9/G6U23JwHOMGyeOPOKbEyatQCB8Xc4xB33GmwfKOCDj9xAILZl5Jnrp5zzqNDaDej+XJd4TpzyTRLf3jvEqaPzikSQa1S9GrOnUuHgf5Kyl2pXlGIhxYWi3GDEo66+gCPyjSGemA6eN1L+dOmBLezi775Sb66T5erVL6jUMbK8RWXc/L/V9wMsF3zioH9Uvttz98Pxt8TS0q4benVlA24+gFlS0QuDtYxxg8DpvTlXm9BZOQ8MLLLzwCTPPePu7WIi7qqWW7uWdW2Q5SeF2Z+WpmWb58Dlz2bdZGFqDZRti3dhNvJ05JWvCAfyB1/5xz3puXxdsHRopxZo/dLgIrVnu//s0l+b/p6PbesbQBw8m0OzxKdS1mffv87w+++URCdSonMrkA9praNZaLV0uyVySzgm4An60k5ZzcS9oCB+7jheT0WSZiQ4UzpzjFqbufBZwV5q6VS0hTv3qChHwLtikK7few9z1WlqyTed2jQ5+n+eB1hFXx7g1WPfS8HhqXkdJD3ySK5YkQfRB4O2ndd78pvTZX4UiDe2RL3Lp91VasZ4MQh+v1+EToj6t1SHT75TbdtkeP1IQm+hG4F2rslyso+PRaV+SZig05aSas+R4OQJv8KvsfO5XT1Q5yKnmUjEd7l3PVdYhNPy5VisGVX99PoVe/V8CDekSIwqiBgL3BeelQVsOW44H6bj48+UUinZ1SoKjExcRhIQTHkji1O+mDpX8/YkLtZ5zmIRwhjMosvLN1KvVlXM4XtJw+KyRdCUTBs68P6uAnp2cT2O+yKNxP+aL5SjltVKbuUZLQ7poSOHmskRuS/jd40nic4oL5DrW74HIF/wzlAg0sIOliukPi4uocxMlyWUyGj8lnz6ZG5iWBuA97pk9c7VWtBHzd5VOT9aM8pruDTYn8XmF7qeaq5UyUfxk1jqtzwNvDui5T215kuNlSDUHv9p9otg6UBVsdaspxEkpD+JBaFi9W0+dmqiC0r6LszA464dn4RgHBTwLx+0iox23ouKsqRMoRhhWePDo+k7uB5y+wMvmMvLM5WYScStYzjy1XXveoo6Sio1E+50sA+VzmXdmFNAvy7T0wMBYeufeBJq3UUfD3sgWy1Nc+W5hkQigHx0S59HjSIyT0zePJVFeoZke/CQXHTCiDAJvP+AWVEO7aUTQPen+RFrzQRrd3T+G/lijxQssxPEb6anLRnrlzgQKFZ2aKEXK1JKtV6p55hRaRm2T3JjxZj1bqMRor7utONxd483ru91Z3yUCb6Sagx+t26unGmlyUcwqFHRuqqIVuwx4zw8BPNO9do9BFIIKBn6P5PWpUjr1obPFlBATGgO7wcb7htPNdxzFIFW44GD0TIaJWtYJ7MBRl6aW1y93ESgLF5PltpK2xXG57WpqgkzMUNvilPInvskTE2XcevWhQbGiM8Xit1JFbRz+P1cz/ry2+3/XxFK8F69lHpz9aHSiWNb4wo/5YtIHogMCbz957/5Emvpciqgozbq3UIvUw/0+TvcF3+F07inLikRaYLMyemMH48SE1xBylU4Jt/DgdHhXBX0cpVdRiNFeXxZY41FijZvZ+MlxnGpuQhACfnPykoma1ApuD2/HDhe8hs/dKrzgP7xuMzVRTiP7Oa88Hqj1qdKM9+rdBrEcDa5UfOZgKl+L4CMcbDpoGSThzMBA4vPpRjUV5b52uNYHF7l0XF9977WxNHe9zu5cau4GHf27Q0+fPpRIPzyZbM0i5LT2CXcliC5FO4/ZDwrxrPnrv+bT1VepxKRaRQYSHhkcS0u36emOidmiDgVEPgTeAZy15HYDT36Th+AjhFtjJMTK6KEbPEsbCoTaVeR21Tx5dJTXTXty0sdOu1kR1N3iarFurO9mDWooxBrH4xdwYgX+cSHLRNVTQ2O2m0lFh46htWRIpMXybBYvuwkWXm+64yivPbW8B97YVRO0bQk1vASAB4aPnMXERDjg/vU8yCmtzw+kGqly8V5fFu4Ck5ZY+rU+vHeMmJ2++/0cMcizdo+enptsCaCv61j69TignVoE+g9/nktHzxdTdr6Jnvkuj259K1v8nRduj69Qqj0PEj8xLJ5mvpRM5zJNNO5HxAfRAIF3gCTEyGnc7Ql09LzROuoNoZeO2K6hSrR/CTV1qijozGWTNVX8+AUj1fPgQy+9koJUSqJtR303y1LEM95uzrh3aKwU68H/O1B2ihiAt85nGalaauh8pMVpZFQpUUan3ajCC/6z9bCB9p0yiuU2wcTFnfjtm/t5KxVE7RuGTlZVsFl7nSPwDnk8AcDnsdwbOxjZRfweX17mHqfCV0os/VmQkiCnqc8m08VsE93+dg49+mUetWmgpBfvcL60kOv8/PBkEukNRNe9nE2dn8ikZTv09OD1sTTv1VRqUN03r2H+Oy/eEU8LN+tF6jlEttA5S4kCXZupRMGHT1FkLeTwOp89J4qpee3QmTGzxWtXDUaiy7mWDxz+4KvvwZs+p1nd0iNGrGH3VXV9nd69VmLSwFOzdAXSbitg0RadGBHPRT/0UvTFZrqca6bqIRR4M66a7cssE/Ac11bhGhmDuwR3hplTV9mu4wYxu8vZVWDBg911qsjpwGmk34e6n5YUiUH8Hi2DM5BVLUVOF7JdB948OcHnSY6p5hJetscp5Dx7zY9h8hNJZRbk5CyqBa+n0pjBsWJmfMozSTR2aLxoHexLvK48Rm0pAgmRLbTOUqLgw+X23jG09Qg+XELNtiOW9hNcQTwUcWEQzmj6d7vlTfnURZNYuuAJrmyeV2QWo70+m/F2M9WcVU9TWAcOwDP8nHEBlj/X6mj2urJ7kUYjLqbDQi3w5gI/XKwRgoPrUCzfoadr2gS2+rIzMWqZGHh/d6alu0mPFqHRrjJU8P6YtVbns88n8L3DZ4vpl3+1NHZonBhMDwae8b6cY6Jio9nl+nOdgewqmjvi8/B1H1aizx9JcqszDPfpHjssnr59PJla1/PPgANnD/ZupaaflmqpQIu13pEstM5SokDdqgrxwYIiCqHl1xVake7WO0R6dzsrKsKBMxcC4dn5Ap1Z9IP0RO2Sdd6nfJT6qvNgjTfjNVc8KwnObTlkoD7PZdLVz2WKaqm2PppdIIrp8cAQF4IBe9LyHW43E0q4tsGB00YyFOO4D4aflxaJDhDcaSRUiojx8oNX7ox3OSMXrZ4YFicGc5duw8BiqOJCY9w+dOQ1wStSWC1VIZZscPDtDBcq41aOV9UPzUmUsnD6PscHnBUDkQvv/EEIvJltoSwIjfXdXZqpSKkI3fS/+tUUlJFrEqO5zN00b9vZN18eezybxLM47uJ+l5mY8XaKK76/9HO+aF/CLU+e+jaPth+xPNF8gjHvPx3dd20s/e+aGFq/z0ArdyH4tsWt9rgAIb9GQsk1bdSiA8HGkirAEDi8zvObhUU0ok9MSPR2Z1yMaf1HlUQLIii9/pYHFhdv1ftsORT4Ds8w80AWL5kMZh0cXrLGdrjoFsFp6JaaAaF7LucKF3Lj87q9JxEfRDIE3kEKvLk4FoQGzj44es4Y8J6UnpJ6YfOsAPMk6JWuXzVZ7rPU1yLu4+1B8M/FTjjVnGfswd4/W/Ri3f53Y5PoizFJotDQnZNy6P6PckQFVX7ubu4eQzd111DTWgqas96+F2m023eqmDo1VoXcyVbTdIUopIX3+8D7dmGRGMgaMyT0ulSAc3f2jaF1+wylMn4g+LgGzomLJnp4cHBfTzXSFGKZHc++O8PnSEnxofU54C5eDtM0XUl7T2A5aiTzOPA+dOgQPf744zR06FB65pln6MyZM+XexmQy0a+//kr/+9//aOTIkbRw4UKKVpxuy+tFXL1pgG/WIZ3JcD+4/GuDTqQulbUmKFQCb549Kyrp9ehJmrekcS0FbTnkmzd1HgCIcbOqOePUSn0xYf2SizRznu3hD11eVrD980p09VVqURG7eppcFICpnCwXgeWw7hpauElPa/di1lvKVuFe2c1DcOCMT6S4GFB5VXjBt/QGs2gPyRkivi6CBP4zrFuMKGD17swCu17LEHx/b9JRcpyM2oRACjdnNp11cY6XXeBZq9VQ07OlihZuse81DpFF7mnQ3blzZ8rIyKDhw4fT/v37xe8XL14sM+i+6aab6MUXX6SePXvSsGHD6Ouvv6Z58+ZRNOIT58GdNbR4K0Z0/WXY69nU9/kslzOr3Ef1/T8L6Pt/CsUo7q8riui6DmpqXCv4Hyhl4Q8THiCQCkl5OuPNhnTRiEEfTsOsqDOXjaLaursqJVm2F+u8S6fwcZ9hbrkm4VS+L8ck0aK3Umn6CynUpsGVgi6j+sVSs9oK+nhOoajmHe3emVEgZpbv6B0a63gd8cDJ2QwE3oHEM6b5RWbxWQvh5fWRCSSXy+jdGQVIOQ8RHARy0a/hV8eIFlvBVjXFUivJ1Yw3DxCEqweviyPeeqmQLkR54P3GG29Q48aNaerUqTRixAiaPXs2KZVK+uCDD1ze5ttvv6XFixfTv//+Sw899BDdcsstNHfuXOrTpw9FK+7neSnHbA2gwHfyCk1iVpVx71ZHHIw/+U2eSEOc9Ech3fRGNu0/ZaSBHUL/BI1nvJk0e+ZJmrftjDfzJCPA1X7mALp+dffXTtZItVwXLWPsLduup3OZJjHb4w4+8bm7fyztOFpMb/xaQNGOl4n0b6f2aiAqEBrVUNKhs0gdDCRe2z2gnVpkkEB44fZNz98aT0u26UXWAgTfur160VVl9A2hUZugahktxbhNWEoYz3jzoHvHxiqxnAxFOSOTR0fnokWLRIq5tI5OpVLRkCFD6J9//nF5mx9//JFuvPFGatCggd3lSUlJFK24NZS0LhF8n3Yq2e9k/3IwzmvIvhyTSHu+riRaU3CV2d6tgtOT0hPSh4kUeHuTai4Vnzp0pmKB9/GLltt7UrSobjUFta6nFKn9cMWhs0ZxDLb0oJXdTd1jaOQ1MbRsuy6qU/c5pfhijsnaIzkU8RKWg6eNdOgM3u8DgYtHHjtvpBu7hv5gKjjHPdc55XzmaksXDwhuDZyfl2qpVT1l0FqIOStCxgP/jpXN+bOQa89UTg7NQVh33XVNjCiwtnAzzpUikduvosLCQpFSXrt2bbvL09PT6fjx4y5vt2vXLurQoQN9+umnIuV89OjRYga8LDqdjnJzc+2+Ikl6ZTlVSZbRH+WM5p7PNNKLP+XR5EWF+PBx05q9BlEVmgPMdXsNTtcpcVsm7pfIM4eL30yltR+kUaIbvRyDjdeKSjN8Ut9HT3ELMj7+Dp+tYOBdUhywXkmxQE+CkGMoLFgqZb9WScV5T9zWK4aKdERvTc+naMWZAqHYRszWkK4aSoqT4SQqQL5ZWEgqJVH35qE/mAquDe8dQ7uOF4vgG4KHK5lzu8aHQmS2W8oaZU9+m2fXz5u7vrBwb9U3oJ1GnMNuP4rB2kjk9tGp11vWG8TG2r/44uLirP/niEcqtVqtSEXfvn27KK7GgTrPmn/xxRcu72vixImUnJxs/XIM9sMdr18aMzhOVDLmNkLO8EzWNeOyaNZaHb07s5AWbcF6D3dsOmCg7i1Uom/r35t1dCH7SoB55FyxSDHndc7qkqCV03r4+QiXwnw8qLD9qGVAISHWu+2ukiyv8BrvrDxuJUYeD1jUqaqgkxeNWLtn40wGz9h6fqLQrLZSrLlbvccQtQNz80qqH4daGzFbaqVMzBY5W/oCvsWfp/yZ+fiNcWExmAquXdNWI9rxTV+JdPNg2XTQQJ//VSiqzfdrqwmp5QgDO6hFbZQR7+aIgrrsREkmHndvCXdXNVCK5WQQedw+OhMSEsR67szMTLvLudBaamqq09twSjoHzvXr16cffvhBrO8eP368qIr+zjvvuLyvcePGUU5OjvXr1KlTFGm6Nbcs0N19vPQLi9ffPvNdPnVuoqLl76aKvonjp+SLtEpwjYOPoxeM1LCGkoZ201CxkWjzwWJr9sA9H+aKYPWVOxPCcjfy66lxTYX1BD4hxrvAm/tpny2ZKaxQRXMvUt3rVFGINfiuCqNEo9OXjdYe657i94gLWSbacyL6gjp+P+QCifcOiBEtZkJ9eZGzpS/gW3+u1Yn3fX7/h/B3cw8N7T5RTO/9gVoWwfDl/EJRF+bF2+Mp1Hz0f4k07blkOn7eSDe8kk1LtunojzVacY7UwIPaM6GqWzOVOPZ3HkMHpKgNvDnobtmyJW3bts3ucv69TZs2Lm/Xrl07qlevnt1lHIhfvnzZ5SyNRqMRa8BtvyJN3apykX64zcmI1l/rdWQmM30+JlGcUI4fEU85hWaauQYjv2Xhtc/Z+WZqXlshZobjY2R0PssSkMz7TydmQ2aMSw7ZIkzujvQyfmzeVhft0lRFWw4bKrQ2mANvb9aY16kqtxuZjnb5WpM4bjn93xudmirFspX3/oy+E9PNhw1UqOMgKzSrmdvijAYuBmTktgRR5OCZYp90UHAHp5l+MKuAhnXTWN8nIbxxgbwHBsbSD4uLxOwrBA5nXa7da6B7BsRaMwRDiVIho05NVLRiUhr1a6umV6fm05bDxdSntTpsshjLwoOHPLmC1sORx6OzvbvvvptmzJhBx44dE79v3bpVFFzjyyVc8fzWW2+1/n7//ffTsmXLrP2+ef3277//LlqLSUXaohG/MXAa1ZSlRaTVm+0Kw/y6UivePKRCFtzmime9X/+1ABWhy7D5kOWD+ar6KnFs1Sxp48MVuH9fpaVeLdXUqGZ4V7mNK5nl5iJl3mrXSEmGYhIFiLzFvcS9CryrKCglQUbLdmDpBFu8RU9GE4nXuzf4PeLeAVzh3BB1Qd3Uf7UixbxZeugHWfy+wzOxB05Hz4DTgo06Gjwhm579Ps/v98WVjF/6OZ8UcqIX7wi92TnwDn+OP3ZjnCg8+cKP9ut5wX+4487HswupfUMlDQ3xIoU8CTGqX4zoFMSZdF2aRUZtB4VcJmqXVDQ7EcI88H7sscfo+uuvp9atW1OXLl1E8MzF0rint+Tw4cO0dOlS6+933XUXjRw5klq0aEG9e/cW1c3z8vLou+++o2jHI4nZBWbRS5rpDGZ6dnIeKWREjw6Js7vu908kUVqCTKT+gHNr9hhEf2New8y4xzS/afFs9+nLJho7zH6fhiOpDdjDg7wvdJKWKLf2M/eWVs9V1T2/Hc/SX99BQ6t3Y/ZCaq1Wp4qcalagKjcPwvDMr1R0LxpsPGCgpdv09MB1sWExu8FFBfn1sn5fdAw4cbVhKT2YaxBwr3V/4ECM76fbU5m0Zo+e3hyVQCkJ4b++E67gOizc2/vUJRO9/HP0FpIMFB7AHft1rsjEenxYXFhMkLVtoBLp5Q9eF0u9WkZG4G09h61g61cIPR5Nm3G6+bRp0+jIkSN08uRJatSoUanCZ1xArVevXnaXffjhh/T000/ToUOHqEaNGtSkSZOweDH7W5NaClGgavFWHbVvpKSvFxTSrmPF9MOTSWKW27FAz9O3xNOLP+XTE+eNHvVPjhZbDxuo71VXokEOZnh9zOo9RB0aK6mJwz4NR/93XazIiujQyPsPlypJctGTU6oI7Y1CXuOt8e413KiWgv5YqxUf8Dyq628b9uvJaCRqXkdpHXQIFXxyU5Ggm7WspxRVnD+fV0ifPBR5y3IcceryA5/kiCUToT4bI+FUzdpVFCIDJxp8taCQ8rVmmvNKCk2aWUA/LimiR2+M9Wk7Il6qxhWXJy8qoocHx9LQrjEetTeE8NGijpJevSueXp1WQK3rK+muvqFTYTvScAHabUeK6fuxSdS9pBZROAzOLHwjJeLiihqpCtpWUkwXIodXkUjDhg3FlzMcjPOXo1q1aokvsNn5ChkN6qShH5doRdVynp3l3rxdmjl/s7u+o4Ym/JJP/2zR0cODwn/21pc4iOOTWu4VLWlYQyGKbRw8Y6Snb46M/cXHxuK30iocBHAKk9QSzBu8PCLOy7XynB7Mqe78fHEw4k8/Li6iiTazbe/cm0A394gJqYrmXAymIjiYGXd7vFiKMj7HRJUjoKJrWeb/Zymg9clDiSG59tAVHvTJCNB652C+D787o4B++VdLYwbHioDphdvj6cbXskWhy6ttBkY9ZTKZafOhYtGtggdZOa00M89Mt/fW0NihSC+PdCOujqGdx4rprekFYoC9ogOW4ByvpefXaY+W4RF0SyIt6GbV0+R0fnNkf2ZEo8g+QwsDb9+TQFOfTaaOjVWimMIjg+PKXMtyY1cNfTyn0LqeGSz4JMxg5CJGCrsP6kGdNaJ92Kh+GCF3DH6PX6zYGm9vi9RJs1IVCfzdYSg206dzC0XhlT9fTqZWdZU0/pd82nsyNKpL84wd7wPbwSJvcf0Cti/CK2fzbPenfxWKokuhlr1QnkpJMhEoRrIv5xfRT0u1dH1HNT14fZw1s+uq+krRc/dcplEUdfx2YaFYVmXb7tGV+Rt19NzkPOr1bCb9770cWr5DL17Lt/eKoR+fSqJX7wrPLhXgeWA1/s4ESoyV0dPf50VtC0V/457dPGkBwcfnSrwc1d/nShBY4Z97GwEfJp2bqsSXO968O4EOnDGKNTi/vZAiilUBt2SyjAraVofm9Pz37k/E7nGC065nrNKKmWtvAmiuap4SL/d63RKfPK3bZ6Berfw3qs7pcgU6Mz0yOJZa11PRT08niWJP3/9TRE/eFCeKwwVzdjgr30y5hWaf9KCuXUUuitb9tKTIr/s02LjCK++z528LvxlOrj2x+3hkr/HmDKO7+sbQBJtgmNfgc3B885vZdM0LWaKYoOTQmWKa8kwyJTnpuX3igpE++6uQ/vpPR03TFTSkC/cSVotlWYFYogKhhycf3nsgkR74OJdW7TZ4XZQSnONBMV6ChsA7NHAB5pR4Gc3doEVWTwQJrykDECccX45JFCczb/2WL9LvwLJOnt+gMBDhnpu6a8RI6rq93gUCRXqiGI33x/CtPTU0Z53Wb7MWPKDw6rR8EeRzuivjk/v7ro0VM2j9xmVRz2cy6fkf8ujIueDMEktV5X2xLpXfD14ZkSAKWW2J4GwYToOsV61ixeiCpVm6kk5ctHRZiEScScIn7c4GkVvVU9LmT9No3B3x9NANsTR7fAr99nyyWAZ0y5vZNPydbJq73lL34fDZYvpodgFdNz6Llm3Xi+Uhf01IESnr3D4IQXd04+JZbRoo6env8gLWqi5UzVmvFZMwvsrikgr9Nqrg8ifwDY1KRs1qK+nIWcx4RxIE3mGIe5S+cFs8Ld9poEVbI3sGxR0cvM1ep6PbesWE1ZrPYOIKoNz/2VkfeX+v8WYdGqsoI88sWoD443jgk7KTF42iQIztifrd/WNo4j0JokUNf/GJ/aj3c4KSysX3ycvS6lb1zUnO9Z24XZ6C/u/TXFFUMNLw0gF+vrq5qIER6jo2sQSka/YaIu55eerbPBr2ejZVTZaLonfO8MAXL/l56uZ40R6K3wO+fTyJujZTi2KPz07Op7ZjMuiGV7JpyjIt3dEnhla+lypqMkTi+k3wDh8LX41JEhXt3/69IConH7h93os/5dFzk/Np4WY93fpWNj3yRS79vUlX4YyVulXl1LJksBpC41ytIq1fIfQg8A5TvHaZizKt3o3AmytDc/pph0b4sPDk5IVbcGw64F0QkFtgFml/3mpe2/Jc7T/t+9lmHoRZsk1P796XWKo7AD/uW3rGiKB7zJA4+vv1VDGqzCcu3AIpkI6eN4pe896ulXfEAwxcL6JykpxuezuHPplTQPnayJkR2nLYIF7rPMAWjjgbh1OmI+09e+4Gncgi6dpMRV8/luTR2vueLdX0xqgEmvZcsmgFFqOSiZZA/32UJtLTnaWgA/ASoedujae/NuhoZRS2pnzr9wJRkHf8nfG09fM0enxoHGXkmuiJb/Lo6ucyxUDYlGVFohAlLymT2pCWZ/eJYvGaDIcWjdGCOxhxPR7OBoLIgE+1MNatuYpW7NRXqB9zJJDSrHjdMrjvuo5q2nqkmJZu82yUnD/gL+aYqEm69/ub1+LzOm9fp0XzutCXfs6n3q1UYnCqPFVT5DRjXIpY2/b5/EKfbAOf5HDxOXdmvH3d/oiDnrkTUkSbrS/mF9Go93MjJh2TR/2VChLBa7jilobHIqhQDmeXcLFPLnb389NJIqXcGzwgdnvvGNr0aSV69tZ4ZC5Bubh4Kh9v3K4uvygy3uNcmbVWKzranM80ip/nrtfR2KFxNPIaS4u+h26Io9/HpdB3Y5NoYAc1nb5sFN0Fnvouj16ekk/9XsgSRQnLojdYinhxMUQIHY1rKUhnINp3MnI+N6IdAu8wdmffGNFW54NZV9olRaMdR4tFYanqqTicPcHFinit3MzVWo9ut6dkoKMi6Wh8oj2sm4Z+Xa71aarg5MVFYgb504eTPJo94RmD6Su0dPKSsUJBCBc36/t8Fo18P6fctbwcgPmj7zA//kn3J9LMF5PFelkuJhfu+BjhGR4uRKdShu9sDKdx8uBQpOB2eNxR4taeSAeHwOLPEM6S4Myh+RsjK4vEFn+mvPBjPv22Uku9n8sSP9/QSS3O/xxxsblxdyTQjBdTaNvnlcTXlk/TqG1DJU2Ymk/ns4xlfh7x+aRjlhgEV+cmKrGEZ95/np2nQehCpBLGGlRXihOexVv1lFMQ2SO+Za0vnL5KS9d30GAdoBd6tlTRjmPFHgW/3H+bl1zWsqkg742+bdSUU2i2VqT3ReGt6Su1dOfVMRSn8Sw4u6d/rBi8mfh7gdOAmmfEeV27bTE4/p3Tue/5IIf+79McGvhyllhzyEtAuN/sVwuKyp1dqGgP77K0aaCi4X1i6PtFRWLtXjhbtkMvquBzga1wxgMtl3PNETNDx0G3YzcJgEDhwplcU4Df3/hcIBIU6sxiMoWLDnZ4LEN8pvDyi5WTUsX7+fO3xdHEexJJqSj7M47r3fBysMQ4OX3wYKL4uz8vdf05sHavgVScUYQZ75DCz3Pr+ko6fC5yBmyjHT4twxyn5xkM3D/VN2my4YZHabPzzW6lFUNpPVuoRW9hLtDiLk5dTk2QVbi6cNN0367z5vVsXMX8mVss/YM9EauR0bjb40XxrqPnLdvDg1mc3tdidAa1ezSDrnokg7o/lUn3f5Qj1tDxidF3/1hm2DkVjOsMPH1znKjYfHN3Da3e43qf8v/x7AIXmfKnZ26JFy2YPp5dKJYIhArex9//U0gLN+vK7eXMg0K8bp9ni8O9VZqU4cC9ciPB5ZJjqlISTiUgOEbfEEu7jhfTn2srVlgsFPDALqfO/7i4SHyW8WP7+tFE8ZlWI01Br49MoPsHxonPK0/UqqQQnUxmr9O6XHr0z2ad+KzgQB1C73ODK5ujd31kQE5JBLwgb+isFj0tx91BUWf38ZL13bWxLskbXFmY08054HR38II/uCt5UEDJlcpJMkpLlNG+k8V0bXvvBk70xWYyFBPtO1VMv6/S0kODYr3OfLiuo0YUrRnzRZ5YI/73Zr1IF+eTH+5rysH19qMG0TKJW5BxL/Mfn0oWLY4c9WylplnrdCI9jFP6HfGJVcfGSrqqvn/fgrmXPXdAuOOdbNFe7TMPUvD9Zck2nSgCxM8b43XbnKXAraacDebMWK2jpdv0YlAj3HFrmKQ4majNwRkJ4Y7fC/gpS44P3/R/CG89WqjF+/W05UU0qFN4B45r9hjo1xVaenl4PI3qH+vTv33/tbE0a61OpK5zZwFHnIHFWWgQenq0UNHkRUUiky4SPjeiXfi+Q4FV71ZqMYPCwUe02X60WKz7DOcP22DjdGeumumujDyTR5WLXeEAmY9dDpg5gPYUB8UPfJxLvZ7NpAc+zqEm6QpRrdxbXN18ytPJolbAil0GSomT0c9PJ9MTw+JF8MzLOt4clUiTn0imuRNS6d930pwG3ez6jmrq1ERJPywqnW6+/1QxbT5UTDd1D8y62LrVFPTiHfFijfR3C4ObGXPgdDGNn5IvKmDz+sN1H6SJNEpuH3XTG9n024oiMZgmjezzbPf8/7QinXT0DeEfePNACD+WbUci472al4lwgUL01oZgenhQnDgW3/2jIOzPZzibbGQ/33duqJ6mEIH1il16pwNo2QVmn7W2BN8XUubzkjnrwz+rAxB4R4Rr2qipdhU5/bwktIso8YjqE9/k0tR/i3xSUIt7WXKFT+5fDBXLmuCCT+6mMWXkmsVMta8q0/Ka10NnPE+9fXVaAW3Yb6BKiTKR7j1+REKFAwCekeRZ7EVvptK811K9Hl3m7RhxdSztOWm0ZmVIPplbKE5wuLhcoAzpoqF7+sfQZ/MKg9rj+92ZBZQQI6N37k0U6w+5sN2TN8XTj09ZZuLf+K2Abn4zmwZNyBaFgHiUf+PBYqeFhMIVr4c+mxkZqeYHzxSjCjIEXftGKhrVL4b+2awP6y4OPHnCrTb9NSDL3Qf2nzKKWW9b3H6TtW+IJNhQxOcTXGTNH+1XIfAwTRgBuMrv1a3VtNnHrZl8idsr3fZWNv29SU+v/1pAQ1+veN/kQ2eNpC8mGoz13RXC1cnzisw06Y9CtwZEsjjV3EdrOpulK0mlJFq317OqtNyfmtugPXVzHC15O43Wf+h69jlY+rVRU6OaChFsStv8w+IikdZ/S09NQKtz84kcV26vmaYQawj9jbMReHbbdjBn0RadSKXkrIQqyfJS6aJ/TUil7Z9Xou+fSBJ94ge+lEXv/VlIN3bV0PUdI6eGA6+35AKFvqzmHyw8YCbVagAIJh6c43fUbxeG9gSEK7mFJtFekwd//eXa9mq6pYeGvvm7kIqNlvcf/v7x7AKRpcWz4hCa0qvIfVaIFoILgXeE6NhERScvmURlZ3dxqyGudBkIXNSDK1gvfitVzG6duGgUl1UEtxHhCc46VfBhURHdW6hozOBYMbvY6uGMcgdEfJVqzrhIDPec/vSvQjqb4f4s4Od/FVlnclkgUra9eWyj+sXSfwcM1GL0ZWr/aCa9M8MS9AajSFhCrJz+d02M6N3Or31/WbxVR53GZtKQV7NpxLs5NPH3fPpwVoFIMee1mNJz5qoSLy8/+PWFZLq5Rww9PChWpMlHkpqV5GLAMCMv/ANvfi+oloLTCAi+aikKur6TRtSQCMciVFxAkgt03tbLf4OM/Dk5sl8sZeWb6YUf8sVlPGHD70X3XevbNeXgW+mVFaKLBHdEgfCGT8wIwTPereoq6bnJeW69MDnd9IZXsumm17OtI5/+winhE2cU0HUd1CKtmWe3+GvBJh0ZKzDrc/RcsUjb5JN1qNiH8dhh8fTZw4nl9oXnCtScGl7bh+2DXhzORbUsJx7u4JlCLlp2R+8YMXsYyji1LyFWJgaIJB8+mCjSCYOBC+hxmvtT3+X55eSU08Ofn5xPTdMVoko8nyjM36gTa9OqpcpFATW5G8sBeDBtwl0JIg3dV4M8oaJmyTHryUBTKOL2TVo9D+jg/RdCw3Ud1XTqksntz5JQcvSckRrXUlDDGkq/t2B75c54mreRM5D09NHsQqpXTe73Qp9QMXyuyx/ZZzIw6x3uIuuMJorx7Np7DySIE12eZZqyrKjMoPbfHXprO66nv8vz67bN3aATAd0rdyZYL7t3QCztPWmkef95/wF5+KyR6lcP7cArnAzsoKF7B8SIGVpXVuw0iCD56qt8N2ObECOnfm01oh+7O/3oOYi7lGOmazuEfvoxp+SvfT+NVr+fRhs+SqNV76XS4DJmfP0tNcES/FrW+fm+tzcXkzOaLdXe7702VhSgW/tBJVr1XhrNezXV7yeV4aBOFbnol+tJdpIn+DNg5motnfSgYKI38rWWzxcE3hAqujdXU/fmqgqdVwQL130I1EAyZxO1rqek+z7KpT0nimnSfYkhmTUGV9Quyew8VtLuFMIXAu8Iwie1Xz+WJHpavvlbQakCGrZ2HSumq69S0ZujEkQP55+XFvllBoxn37mHMBeS4kJKks5NVdSzpYrenVHgVdrrmQwjrd5jEB+04DvcV5rXEfF6M2f4ZJ77iybH+/atg9dqc4r735vKP2H6akGhKCjYoZEybAbFOODlmdvqqcEfKOrVUkXD+8TQOzMLxJpCX9lx1EA/LdXSY0PiIm6W2tcp/7xmnQckfY2XDt39QQ699HM+9X8xS6yr95f8IgTeEJoVoLk6eEWy6YLhfKZJVK4OBC5GOvXZZHr/gQRa9k4qtW0YWvVRoLSaaXJRRHlZyaQZhC+cHUUYXju64LUUUZ3yg1mFlJFrcpouvH6/QaR783oiXvf51vQCGvV+Ln27sJB0PlxDwlU6C3RmcaLviCsb82cj962UcPD1xxqty23gdkNDX8uivs9nid/LWi8K3qWhMT5xcbWu3h8tR3ikn/uJc5Xyshw7b6QTF010ey8NRui9xDMbE+6KF6mFL/6c77PXO8/gxmlIzHRD2To0VoqMHV/X2OAihdxa8ocnk8RnwLOT80TlcX/ggoyMq9QDhFKF8wKtmTb7KaPEX85mmkRwFSgcfN/YNUasjYfw+Nzu1VJN2yOkFWU0Q+AdgRrXUtJXjyWJCp9/by4947F6t4FMJqKbuluCF04B/+DBBOJMo4/nFNJjX+V61VfZmZ3Hi0XVamdrWrn/K1ckX7xFL05AuQ0ItxJ68ad8UdF470n7NxgOyidMLaB9pywplGOGxNrNokPFNaiuoBZ1LJWvnWVAcKVqf1Vd5arkq3YbRNs5Vz6ZW0Ap8TLqikyHCrcnefvuBDp92UgPfpJLy7ZXfGaUe1O3rqcipQKBWHm6NlOT0US01sNq/uXZeNAgTt57tlSL6vBJcXLRTYKfZ39UrmeJsXgPhtDBmVBcY2LKMt8vpfEXzvrjgayGNRAEg2tcI+nkJWNEdMSIZvjEjFCc2sqz31/OKz2DzTMitSrLxUmZZEiXGJryTDJ9+3gSrd1roJHv5dDc9doKvcA5cFuyVS9mUV0VQLulZwzlFpnovT8KaPRnuSIA//HJJFIoiEa8k01HbdazTF1eRElxMlo5KZUOfFeJxg6NrGrHoYALXz1zSzwdPGOkEe/kULcnM+iaFzLFiQHPaHIaOgfm/vB/18VScpyMnv8hT8xYOOLjeOk2PY2+IZbiNAjufDFA98UjSZSVb6KHP8+rUH9vy9IPPXVthpRFd3Axo+a1FWUuB/KmiCX3Me7UVGVNaZ89PkUMqM5Y5fsgJDPf8hqtlITXIoTWZxjPDO4+ET4zg0u360WtBB4wA3ClbjUF6QyWOh4QvhB4R7D/uz5WtIngXqu2eEaxnot0YX7j/25skmhr8ezk/AqNGvMHH6cOPzDQdeopB+Ujr4mlacu1tONoMX31aBL1aKmmWS+niCrIQ1/Lpt3Hi63r0js2VlGNNAXSjP2I19/zrBm3neLjh4Ntrhnw3T+FYiaBi7D5Q2KcnJ67LV4Ue3l1mqXVia1tRwyiDVP3Fjg58RUuksfBWWqCrEKVgDmLRm8guntA6SUlUBpnGnFVfs4SqGh7GO4P/9cGLT3wSa4YsOI19hLul35T9xixfIerkPsSL2PiInGJqGoOIYbPK85lmsSgYjjgjBQ+J0OHFihL3aqWkO24nwtngn8h8I5gnN7Nsx2cHmyLe2jXKWOdLhcs+/v1FLq5u4Y++6vQ6zWCXFmUT+j7tS07UOL+kXwdbjfWsbEljZmLd80enyqqlj/4SY5IQ995rJha1QuPglrhTK2U0fzXU2jzp2m0/N1U0WZs3T6DqGjO7aj4//3lhk4aen1kAs1drxPBgi2uws2F3ZrWQjqeL3FqOO93Hvx66ts8USTNU/tPF4s0OK5QD+7hJRvc7eHIec9PojiI5lTvt6fnU+exmfTM9/kiVXXS/Qml3ts5wOcWgKt3630eeKclyTEICiGnRV3La2Dr4fBY530uw0TVA7i+G8K3l7daSfRfObVwILThlR7BuJoyV8m0HR3jwmqcas6tJMqbkXnh9nhKjpfRF/MKPb7vQ2eK6eelWrqtV0y5az655RLPdH/6cJLdSVx8jEwUYONZ165PZlJOoZk6lQTm4F8cQPFSBC56xjPcb4xKEMcDF+ILRKsTHoBZtv1KoKDVm2nlLr3I4nCnDzR4ZvyIeBraTSN6bnM7Qt7fnuCslNboA+uRJiUDSPtPlR7Y5PfpR77IFSnivGRn8Vad+J0Ho5Zs09GAF7Oow+OZoor8g9fFioHSf95IEW35nAX4PGBVVptAb9eTS48BIJTUr6YQ5zi/Lg+Pdd7nsgJbWA3CE096jLg6hqb+6/sMJggcvNKj4AOIU7gl6/cZiGtmcTum8qQkyEWgw+3GuJq4JxZu1olqt48PvZL26G3K2O/jkkUF5idviqMuzZBmHAw8a8aZCYGa0ezSVCVSy6UCbxyccDGqNvWxhtgfeDBj0n0J9NvzyeL3P9e6f8K6bp9etDDk5wzcx2uwW9VV0tcLikrV4fhoVqGoZ/DyFMuM9qNf5omK/lx4cswXeZQUL6NX74qnP15KpidviqdGNTm7yfWAVP+2avp9lVasA/cF3t7Nh4rF3wUINfxa4HOcXSeK/dIm1ZeKdLycy0g1A9TDG8IbLx3iSSjbbkAQXjB9GOFu7RlDT32XRycuGEVhhjOXTVQpUSaCancDLk7xnjijgKqnKajvVeWfaF3KMdH0lVrq20btk7Tkdg1V9MdLKRX+OxA+OjRW0Rfzi2jlLoNYhyyq4yuuzBKCf05Web/3aKGiT+YUUp0qClGgsbz1xa9NKxCZKLw0BTwz/s54umNijujgwO9zjH/+6z8dPTEsjs5mGunkRZOY1e7ZUiXqZhiNJFrvlRVoO7p7QCz98q+Wdhwrpj6tKx4sc3Efjmf4GAEIRU3SFZSdb6aLOaaQbpnF2SxaPVH/dhjEgvJxUc67+lpaAPOs9wPXVWxyCwIPgXeE697CcjK352SxCLz5RM6TkVU+ueMq11xga/SnuaL/bLUUOcWoZNSopoJa1FVSp8YqUtkE2Jwema810zM34w0BvDxum6uocxMlvTPD0j7s6wWFIghE8Rn/4+UdY77MpXE/5dPLw+PFoBu3envn3oRSy0Y+nVtIF7NM9PnDyVgC4IWWdZSkVBDtKwm8uRgUH/O1KsnpgetiSw1ccrs2b9QWXSxk9Mav+dT4meQKz65JVXW5JSRAKGqabjm9PXDaGNKBNy8B4U4hGMQCd1haAFuWgU76o1BkTg3vg6Km4QSBd4RLS5SLdd6cCjqgnZrW7DGIqtWe/o0fn0qiP9boaNUuPWXlm6lAa6J/tuioUEcUr5GJ9Z3cP5OrofPMCs+U8ww5gLepz8/eGk93f5BDt0/MoarJcnpzVAJ2ZgBwzYWJ9ySKff/413miQCMXSuTv792fKK6jLzaL9ZP8dXf/WNGaDDzHA0lcBJPTBjkLiav5c8G1d+9L8GkRQz5Zu/PqGPr67yKa9EcBfTw6qUJ/j7OapKrpAKEovZJc1DaYtVZLvcvJ3AmmC9kmpJmDx+/nY4fGiQHQ16bliwk2DNyED5wtRQFOUeR+sev36UWLjUGdPE8JVcgt7W/4S2I0mWnfSaNY47nlkEFURTYUE93ZN4ZevB09tqFi2jRQ0aK3UmnhJj0N7KCmyjjJDxjuJvDnyyn05fxCMZrOhbTe+LWAbu9lKXz38Oe5ooUYX48Db/DeW3cn0I2vZdMT3+SJTI/3H0j0y7H+1M3xZDIT/b5SS7mFJlE80VuXuJWYkrtPoNAhhO7gLRei+mZBEZlM5pDNyOGMoY5NUB8DPA++Xx6RQH9v0omMQP4c8WT5EQQPAu8o8OpdCXTyopE2HiwWBbJ4zawvcDDO7b1Ei6/rffInAexwiuA9AxDYBQPPZk64y5JlwAE2V1K9a1IOpSXKKDPPLDIQbu6hKbdrAZSNq44/MDCWNGqihwfF+bVdH3cl+HZhES3foaeh3bxPT7ycY6IqaCUGIY6LFxbozHTqkkkstQvVGe9qqcgcAc/Fabj7UAK98ks+DWivcasGEwQfAu8oSWfk1MKFW3R0UzcUQAIAD99DlDL68+VkmrVGR8t26Kl3KxXd1kuDEXYfee62wGQIVU9VUHpluVj3WhGc4ogMFAh1zUrWee87ZalxE2q4bWN2gVnUzQHwBmekTV9ZJJZUIPAOD3i1Rwk+SRp5TawoxAAA4CluJTeqfyz9/HQy3T8wDkF3GBedOnC6dO9wV7YeNtCzk/Noo00fcK68jg4DEA7nPTzQxK35QhFXXGcoUggVMaSLRhzj249ceY+G0IUoDAAAIEo0TVfQ+v0GOnq+7OB70RYdvf5rPt3zYQ7NXa+jR77IpcNni8Us3cEzRrqqPtalQnjMCHK2X7Ex9Pp5c20c1rBG6M3GQ/jgOis1K8lpzgZdsDcF3IDAGwAAIEr8r28sJcTI6LcVWpfX4dTFx77KE+v6B3fW0Jr300Rbv49mF9KFLBMZTUT1quH0AUJfizpKUfT1bKZldjmUcIHKq+orxRIQAG9xnZXOTVS05aCBzObQG2ACe159cl66dIm2bdtG2dnZHt1Oq9XShg0b6NChQ97cLQAAAFQw/fb6jhr6d4fe6Ukad6uY+HsBtW+kpO1fVKK370kUqbDcV3zJNj3NXm8J2FPiEXhD6KtXsrb7+IWK1TXwh8w8E9WqhNcRVNy17TV04IyRlm0PzWUVcIVHr3j+kB4zZgylp6fT8OHDqXr16jRhwgS3b//kk09S9+7dady4cZ7cLQAAAPjI4C4aUel5/sbSqYkcoBTpiR4fGieq5kpu6RFDresp6cv5ReJ3ngEHCHXcy1utJDp+PvQC75wCEyVjAAt8oG8bNTWrraBFWxF4R1Tg/c0339DUqVNp69atdODAAVq6dCm9/fbbNGfOnHJvO2vWLFq/fj3169evItsLAAAAFdCpiYraNlCWmh3hNmNTllpmtJvXtm96olLK6IZOV9rVIGCAcMBtTxvVVNCmkvXUoSSn0ExJcRjAAt/o1VJNq3frqVCHdPOICby///57uvXWW6lly5bi9549e4pAevLkyWXe7sSJE/Too4/StGnTSKNBOysAAIBgattQSbuOWwqsnc80UvenMmj0Z7n020ot9WurptSE0qcHQ7rEiJ7D/BWDlrEQJm7uEUNLtuopvyi01nnnFpopGYE3+MjNPTRUpDPT9/8UYp9GQuBtNBpp586d1KlTJ7vLu3TpItZ7u1JcXEwjRowQ6eVSwA4AAADB06SWkk5fNlFWvonG/ZQvZkleHxlP13VQ0+jrY53ehtd6r5qUSivfTUU7OQgb7RoqyWQmOhZC67y5lkJekZmSkGoOPtKwhpIGdtDQP1uQbh7K7HPJypCXl0cGg4HS0tLsLq9UqRJlZGS4vN0rr7xCycnJ9Nhjj7m9UTqdTnxJcnNz3b4tAAAAlK17cxXFqWXU5YlM8fuPTyVRjxZqGt7HedAtkclkJEN2LISR+iUF1o6eM1LreqHRBi+v0Exc2xC1EsCXBrRX05z1OlqyTUcD2iHDOKxnvFUqy5uVbUDMioqKrP/niNeCf/TRRzR69GhRzZy/uBJ6Zmam+Nnxb0kmTpwognXpq3bt2p49KgAAAHCpZiUFffpwIjWtpaDXRyaIoBsgEiXEyqlqsjykKptfzrWkvTtb0gHgrX5t1NSxsZJ+Wea6XSSEyYx3fHy8mN0+e/as3eX8e926dZ3eJj8/n9q0aUPvvPOO9TIuyiaXy+mJJ56g2bNnU40aNUrdjtPSn3rqKbsZbwTfAAAAvtOrlVp8AUS6mpXkdCYjdNZ4Hz5rGQTgwm8AviKXy2hwZw29Ob1AtKtLS8TATqjx6BnhQmrz5s2zW/e9YMECu0rlp0+fps2bN4ufe/fubZ3plr569OhBffv2FT87C7oZF2BLSkqy+wIAAAAA8FSbBkpav99AJl7sHQIOnimmSokyBEbgcwPaayghRkbP/5CHvRvugff48eNFIbVHHnmEFi5cSCNHjhSp488884xd5fP+/fv7Y1sBAAAAADzSu5WaLmSZRP/6UHDwjJGapLuddArgtirJcho7LI7W7jWgtVi4B96tWrWitWvXikJrnD4eFxcnenOnp6dbr8M/O1Y+t9WsWTNq0qRJxbYaAAAAAMDNVHN2MSc0Au/zWSaqVbJNAL7WpamKio1Ey7Y7r6UFwSMzm7muYmjjNd5cZC0nJwdp5wAAAADg/nlkoYk6Pp5JH49OpBs6Bb/a88CXs+jq1ioad0dCsDcFIhCHdv/3aa4Y4Jn3amqwNyfi5XoQp2K4DQAAAAAiVmKsjDQqosshMuOdX2SixDicgoN/cNvHQZ01dOC0URRZg9CBVz0AAAAARHQgwmtfQyXVPLfQLAYDAPyla1NLq+d/d+ixk0MIAm8AAAAAiGiVk+QhMeOtLzaTzmCZhQfwl+ppChrQTk2fzC0kY4hU8wcE3gAAAAAQ4XjG+2xm8APv/CJLEJSAwBv8bPQNsaKa/8JNgZ/13nnMQMsx214KZrwBAAAAIOIrPW85ZAj6mte8QkvgjRlv8Ler6qvErPdT3+XRxN/zRdE1f9MZzDTvPy3d9nYOjf4sl6avLPL7fYYTNBEEAAAAgIjWr52a3pxeQDuPFdPVV6mDth15JTPeibGY+wL/+/D/EunzeYX0zd9FdGvPGGpcy3+h3++rtPTuzAKR1dG1mYpS4mX0yi8FNHO1juJjZOJ1l5Frok0HDVS/uoL6t1NTvzZqksujZ9kFAm8AAAAAiGg1UuUUoyY6dt5IV18VvO3IK7LMuCfFRU+wAcGjUcno0SFxNHlREW08aPBb4M21Cz6cVSAySx4fGkdNaymoQGumqimFdCbDJFr6vTOjgGLVRH1aq2nX8WKavU5HY4bE0tih8RQtEHgDAAAAQETjWbW6VRV0/IIxqNshzXhjjTcEMvhuWENBWw8X0119/XMfv63QUla+mZ66Kc4a3CfGyejlEZZe9ZzmfvCMkaqnyik53pLtwbPjX84vokGdNNSoZnSEpMhzAQAAAICIV7+ago4FOfA+m2EihRxrvCGwbuoeQ/M36uhCtu+P/yKdmb5bWEQ3d9e4nFHnln5N05XWoJs9OSxOpKD/syV6Wp4h8AYAAACAiNeirlJUW+YU2GDgtk5z1mtFqq1KiVRzCJzrO6qJa6vtPl7s0797JsNIL/2cL5ZQjL4hzqPbqlUyurq1mn5bUUSXQqDVXyAg8AYAAACAiMcprYU6orV7Az/DllNgorsm5dC+U0Ya2S8m4PcP0Y1TvFMTZLT3pJGOni+mueu1FervrdWbRaX0vs9niZn0CXcliIJpnnrmljhRjG3mai1Fg+hIqAcAAACAqJZeWS7aeHGBtUDK15ro+vFZlK8107ePJ1GPFsGrqg7RiVO9W9RR0to9elq6TScGgLQGojt6x3iVWn77xGxRL6FpukK0LLuxq8ar7apZSUHXdtDQn2u19MDAWDELHskw4w0AAAAAURF81KumoBMXAxt4L96ip4w8M819JVWkmQMEw4irY2jrkWIRdLNl23Ve/Z31+/R04LSRpj6bTPNeTaXHh8aTUuF9wPzgdbGi9sGsdZE/643AGwAAAACiQr0AF1jjlNzP/iqkni1UXqXiAvgKz0yrS3Kd+VjceMBAmXmer61evtNAdarIqU0DlU+2q0ktJXVqoqKl2yK/yBoCbwAAAACIChxwHD5jFH2HA2HvyWLRx3jsMM8KTwH4I+OjfztLxsWnDyUSL/GetdazWeaTF40iLXxYd9/WKejfVk1r9xpox1EDRTIE3gAAAAAQFa7roKacQjMt2x6Y2bUDp4tF+7Bm6SirBMH37n2JtOGjNNHai2eaD5/1LPtjxS49cVL5fdfG+nS7hveJobpVFfTD4iKKZAi8AQAAACAqNKqppFqV5D5vq+TKgTNGalBdEfFFoyA8aFQySku0hH/1qiroxCXPAu/1+wzUtqGS4jS+PZ7VKhkN666h5Tv1dC4zsDUYAgmBNwAAAABEjca1FLQrQIH3tsMGal4bs90QeupUlYvUcU+yN/7doafrOnpXwbw8t/WMEV0HPp1bSJEKgTcAAAAARFU/7w37/b+e9PRlo6gg3a9kXS1AqBUavJRjFj3m3bFmj14UZxvuRQsyd1RKktOwbjG0YqeeTBXoMR7KEHgDAAAAQNQY3EVDNdPktGCjd+2UPAm8WQvMeEMI6txURRoV0W8rtW717l6wUU8dGqlIpfTfson+7dSi9d50N7YpHCHwBgAAAICooZDLqGVdJR0849+1pDkFllm7pHis74bQUz1VIYLvHUfLX3bx1YJCOnKumB670b/V+ds1VIkCiL/8qyWzOfJmvRF4AwAAAEBUaZKuoINn/LvOO7ewJPCOQ+ANoYkL/x09X/4A1Pr9BurbRk0dGvumd3dZ7uobQ0fOGSNyrTcCbwAAAACIKtze63KumY5f8N+sN6+d5WJRPMMOEKqB96lLRjKU0dd+/T69mBW/pk1gahV0aaamBwbGitZi+UXurT8PFwi8AQAAACCq9G6lpqopcvp5qf/6BnO/8GSkmUOIB97FRqLD51wPQC3YpBPXG9zZP9XMnRnVP4ZeuD0+4gatEHgDAAAAQFSJ1cioe3MV7TxW7Nc13slIM4cQ1rahiqoky+j3Vc6LmfE663V7DdSxiZLkAQyCq6cqaMTVseJ1GkkQeAMAAABA1GlVVyl6E5eVZlvRVPOkeJxqQ+jSqGTUp7Wath8xOA26/+/TXDp92US9WqIlni/g3QAAAAAAok7r+krSFxOt2KX3W3E1zHhDONQ7OHzWSMVG+wGoD2cX0spdBhp/ZzwNQC96n0DgDQAAAABRp20DJXVtpqLv//HPOu/sfBMlY8YbQlzzOpYBqH932A9A/bNZJwLukdfEBjTNPJIh8AYAAACAqCOTyWhIF42o2Hwpx7fVk/nv7T9tpKbpCp/+XQB/DEB1aKykV6fm08mLRsotNNGFbCOduGiiQQEsqBYNEHgDAAAAQFS6+io1qVVE46fk+/TvbtivJ6OJ6IZOCFwgtKmUMnr3vkTKLjBT/xezqNuTmdTrmSxSK4k6NfF/3+5ogsAbAAAAAKJSlWQ5PXdrPC3fqafTl33X0/vIOSNVTZZTWiJOtSH01amioD9eSqG370kQqefs5RHx4vUBvmPZswAAAAAAUej6jhr67K9CevyrPPrz5WSRgl5RR88ZqUENpJlD+GhRRym+bumhobOZJqqZhqDb17BHAQAAACBqVUqSi1Tb3SeKad8p38x6H0bgDWGKB55qVVL4ZAAK7CHwBgAAAICo1rOliqqmyOn9Pwsq/LdW79aL9kzdmmF9LABUINX86NGj9Pnnn9OJEyeocePG9MQTT1D16tVdXt9gMND06dNp5cqV4udOnTrRAw88QDExMZ7eNQAAAACAzykVMnrlznh69Ms8mra8iO7qG+v139p6xECVk2Q0sAMKqwGAlzPeR44coY4dO9LZs2dp2LBhtGPHDvH7pUuXXN6me/futHTpUuratStdffXV9M0331DPnj1Jq9V6ctcAAAAAAH7DPYsHdlDTa9MK6OQl71POT1wwUf3qWN8NAPZkZrPZTG66++67ac+ePbRp0yaR96/X66lRo0Z055130jvvvOP0NhcuXKBq1apZfz9z5gylp6fTn3/+STfffLNb95ubm0vJycmUk5NDSUlJ7m4uAAAAAIDbCnVm6v5UBt17bSyNHRrv1Z67+Y1salZbQW/fk4g9DxDhcj2IUz2a8f7nn3/opptusi62V6vVNGTIEHG5K7ZBN6tcuTKpVCqxkQAAAAAAoSJOI6Pbe8fQ1wuKaN+pYo9vbzKZ6dgFI9WvhhlvAPAy8C4sLKSLFy+K2WpbtWvXpmPHjrn7Z+izzz4juVxO/fr1c3kdnU4nAnPbLwAAAAAAf+O+3hyAL9qi8/i2Ww4XU4HWTG0borAaAHgZeHNaOYuLi7O7nH+X/q88S5YsoRdffJE+/PBDEbC7MnHiRDFlL32VdV0AAAAAAF8WWhvSRUPfLiyi9fvcO8eVbNhvoNQEGXVo5HH9YgCIcG4H3gkJCaRQKCgzM9Pu8oyMDEpJSSn39lzVnAuyTZgwgR555JEyrztu3DiRJy99nTp1yt3NBAAAAACokJeGx1PD6gr6c41ns94ZeSbRlkwuRw9kALDn9nCcUqmkli1bikrmtrZv305t2rQp87arVq2iQYMG0QsvvEAvvfRSufel0WjEFwAAAABAoKmUMurVSk1zN2jFum13A+msPBOlJXpUQgkAooRH7wyjRo2iGTNm0PHjx8XvHIQvWrRIXC759ddfafjw4dbf16xZQzfccAM9//zzNH78eF9uOwAAAACAX/Rrq6ZLOWbaecz9ImtZ+WZKS8RsNwCU5tEClMcff5w2btxIV111FbVu3VrMdt933300YsQI63UOHjxoV+V86NChogr6f//9R4MHD7Zezi3I+AsAAAAAINS0rmc5TT5yzuh2sbTMPBM1ronCagBQwcCb24D9/vvvdODAATp58qTo4V2/fn2763Aw3a1bN+vvU6dOJaPRWOpvNWnSxJO7BgAAAAAIGLVKRlWSZXQ20+T2bTjwRqo5ADjjVcnFpk2bii9nOKC2Daqvv/56b+4CAAAAACCoaqQp6Fxm6QkkZ3gtOKeac1VzAABHqP4AAAAAAOBEjTQ5nXNzxjun0ExGE2HGGwCcQuANAAAAAOAi8HY31XzdXoP43qIuengDQGkIvAEAAAAAnGhaS0nHLxjp5KXy080Xb9WJgmx1qiiwLwGgFATeAAAAAABO3NBJQ2ol0bJt+nL3z5kMEzVNR9ANAM4h8AYAAAAAcCJWI6PGNZV08Ez5vbxR0RwAyoLAGwAAAADAhSa1FHTgTNmp5nqDmc5mmKg20swBwAUE3gAAAAAALjRNV9Lhs8VUoDW73EcHzxjJZCZqUB2p5gDgHAJvAAAAAAAXBnZQizZh01cWudxHczdoqUqyjNo2QEVzAHAOgTcAAAAAgAs1KynomjZq+nB2Ib33R4FIK3e0/5SROjVRkUopw34EAKcQeAMAAAAAlOH2XjFkKCb67p8imrVOV+r/z2QYqVYlpJkDgGsIvAEAAAAAytCrlZpWTkqlTk2U9OPiIjLxgu4SRpOZzmeZqGYlnFYDgGt4hwAAAAAAKEeNNAU9dmMcHbtgpCU2fb0vZJmo2EiY8QaAMiHwBgAAAABwQ8fGKmpdT0mfzyu0XnbgtNHadgwAwBUE3gAAAAAAblAqZDTi6hjRPiy/yCQu23eqmJLjZFQjDafVAOAa3iEAAAAAANzUrqGSzGairUeKrYF38zpKkslQ0RwAXEPgDQAAAADgpvrVFNS4poK+/8fS13v/qWJqVhtp5gBQNgTeAAAAAABukstldP/AWPrvgIFOXjTSiYsmal5bif0HAGVC4A0AAAAA4IHerdQi3fy1afni95Z1EXgDQNkQeAMAAAAAeKByspxu66Wh1XsMpFGRSD0HACgLhucAAAAAADw0fkQC7T1RTHddE4vCagBQLgTeAAAAAAAeilHLaPYrqdhvAOAWpJoDAAAAAAAA+BECbwAAAAAAAAA/QuANAAAAAAAA4EcIvAEAAAAAAAD8CIE3AAAAAAAAgB8h8AYAAAAAAADwIwTeAAAAAAAAAH6EwBsAAAAAAADAj5QUBsxms/iem5sb7E0BAAAAAAAAsManUrwa9oF3Xl6e+F67du1gbwoAAAAAAACAXbyanJxMZZGZ3QnPg8xkMtHZs2cpMTGRZDJZsDeHon1UhwdATp06RUlJScHeHPASnsfwh+cwMuB5jAx4HiMDnsfIgOcxMuSGSczBoTQH3TVr1iS5XB7+M978INLT04O9GWCDXwCh/CIA9+B5DH94DiMDnsfIgOcxMuB5jAx4HiNDUhjEHOXNdEtQXA0AAAAAAADAjxB4AwAAAAAAAPgRAm/wiEajoQkTJojvEL7wPIY/PIeRAc9jZMDzGBnwPEYGPI+RQROBMUdYFFcDAAAAAAAACFeY8QYAAAAAAADwIwTeAAAAAAAAAH6EwBsAAAAAAADAjxB4AwAAAAAAAPgRAm8AAAAAAAAAP0LgDQAAAAAAAOBHCLwBAAAAAAAA/AiBNwAAAAAAAIAfIfAGAAAAAAAA8CME3gAAAAAAAAB+hMAbAAAAAAAAwI8QeAMAAAAAAAD4EQJvAAAAAAAAAD9C4A0AEOJuu+02Gj58OEWq06dPU7169ej3338v97pGo1Fc94MPPgiZbYLy6XQ6sT8///xz7K4A+e6778Q+z8rKwj4HAAgBCLwBICS99NJL4qRR+mrSpAldffXV9O6771JRURFFk3PnztH58+cpUhUXF9OJEycoLy+v3OuazWZxXX8HE55sk6/k5ubaHfOOXzwAI12vQYMG9OSTT5b6G3/88Ye47t13313q/5YtWyb+77fffrO73GAwUNu2bcX//fvvv355bNLzlp2dXaF989VXX1EkmTJlinhc/nh95+TkiH3Og1XhsL1s27ZtTo9dVxYuXFjma+bjjz8W1/vnn3/E7/z6cPTEE0+I/+OBCkevv/66+L+TJ0+WOh4//PBDuu6666hly5bi9XPjjTfSpEmT6NKlS149dgCIfMpgbwAAgDMZGRnipHHr1q2UmppK+fn5tHjxYnrhhRfEydby5ctJJpNFxc5zdrIYSdLT0+nYsWNUuXJlimYmk0kc83fccQe98847pf4/JiZGfE9KSqLExESaNWsWffTRR3bXWbBgAZ09e5Zmz55NkydPJqXyysf8okWLxN9v166d3W3++usv2rFjB6WkpNDXX39N11xzjc8fm0ajEc8xv5Yrsm84mIwkHMDx4+KBnnDg7+3lzIgLFy64ff2CggKxPZ9++ikNGTKk1P/zMc3at28vgmf+7Lj11lvtrsOvIx5ImDdvHj344IN2/zdnzhzxWOvUqWO9bMOGDXTTTTeJY/nZZ5+ljh07is+ijRs30vvvv08TJ05ElgEAOIXAGwBCWu3ata0BWatWrejIkSP05Zdf0po1a6hXr14UDapXr06RjINDnlUCi4SEhHL3BwfHPJvHr4eGDRtaL+cBqfvuu4+++eYb2rx5M3Xt2tX6fzybXbNmTWrWrJnd3/r+++9FYMIB//jx48WMXZUqVXz6dHBggucYnFm3bp04Bl9++WXrZTxLP23aNFq7dq04lsvDx2tZx1fVqlXFzLRjRsehQ4fo1KlTNHr0aJo+fbq4X4VCIf6Ps2p4QOquu+6yXv/MmTM0ePBgatSokcggiY+Pt/4ffz7xdceMGYMnGgCcQqo5AIQVTuljhw8ftrucZ8Jee+016t69u0hL79u3L/3444+lbr93714RYHDw0adPH5o7d644GeOTNg5UJJzSypfx3+XZlC5dutgFLNu3b6d77rmHrrrqKmrevDmNGDFCnKTZ2rdvH91///1iRoSvx+u0+UTS0+u4WuPNM5hDhw4V28X75dFHHxUnkbYGDhwo/j4HUzyb06JFC7GPfv75Z7f2t3R7Tnfn2/PJJWcdSOnD/Hc43bJp06biMXDg5piePWPGDLrhhhvEiW/Pnj3FLNHFixfLXU/Ns2vPPfcctWnTRszSvvXWW07TZp09f7briqV0U9vLbJcw9O/fX6SZ8qxquOjXr5810JZwEM6zfyNHjhSp6LZBBh/HnMbrOJvNs4CcSfLII4+I55kDZE4nDsQabz4m+bIffviBtmzZImYs+VjmY4VnD21fs/zaYLzURHrunnnmmVIzl9Lf4OPl6aefpsuXLzu9v//++0+kBvPzzzOd0vHGx1jv3r2t2+GYbcLXeeONN+zeZzizwNna6szMTJGOzK8Lft1wSjNfJnn77bdpwoQJ4udu3bpZH5fj67+i+HVa1na4+9jK217pdchf9evXF693fu+yPUad4fvj99Lnn39eLDE6cOCAeE3yew4/3758zRw/flx8SXibeaCLjxV+jfBxKFmxYoV4T5Bea+y9994T2Vh8HNsG3baZHd9++63PthkAIowZACAEjR492sxvUZcuXbK7fPz48eLyBQsWWC/j6zRp0kR8/fHHH+Zdu3aZv/vuO3NSUpL5ySeftF5v79694rJevXqZly9fbv7vv//M9957r/nBBx8Uf3P16tXW606cOFFcNmbMGPPrr79u3rp1q/nll18W/zd79myzWq0233nnneZVq1aZN2/ebP6///s/c0xMjHnNmjXiOufOnTNXqlTJfPPNN5vXrVtn3rNnj9i23r17mw8dOuT2dViPHj3Mffr0sdsPn3/+udi+Rx99VNz/okWLzO3atTNXrlzZ7rYtW7Y09+vXzzxkyBDzrFmzzDt27BD7hG87f/78cp8Hvv0111xj7t+/v/nPP/8U++yrr74ym0wm8fgTEhLMH374ofi7CxcuNLdq1crcvn17c2Fhobj9Dz/8YFYqleaPPvpIPC8bN24U17/xxhut93Hs2DGxPfycSXQ6nblz587mqlWrmqdPny7+/rvvviueD77uSy+9ZL3uvHnzSj1/rKioSFw+YcIE62W83Xx/0tf27dvNH3/8sTk2Ntb86quvlrlNrrRu3dpct27dcr/uu+++Mv9OVlaWuM/777+/3PvMzc0V+3XEiBHWy7799ltzfHy8Wa/Xi/vi510yZ84c8bf5+bD1yiuvmFNSUswFBQXi95EjR5qbNWtm9jXpuXjjjTesl/Hxz5c98MAD4jWwYsUKcXz17dtXHFfSa5+PBX7++brPPfec9bmzfW/gY1qj0Vhfq//++6+5W7du5oYNG5ozMzPt7u+ee+4xDxo0SLwH8PvI33//bb548aK5adOm5tq1a5t/+eUX886dO8Xx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tWtX1a5dOzmHIVBcXKy+++47fQ+1bdtW7bLLLtbHYT3F/VOzZk21++67q0qVKsU9Zt26derNN9/Ua+WQIUOsz/PLL7+ouXPnqmrVqqnevXurunXrynkMgQ0bNuj9auPGjapbt26qadOmnvse1sI2bdqonj17Zux5hNTAfvfFF1/of8PuqF+/vtXGwb24aNEi1blzZ+t+FuR5gjxGSI0///xTr6s4pljnbOsl7rGPPvpI738DBgyw2phBnoeATYU9efDgwXpPFtKH9iusg7169VLly5e33kc4j7BxsDfa7NAgzwN++ukn/Tjsw+3bt8+/UwhxNaHscMYZZ0SaNm0aGTFiRGTw4MGR6tWrR+644w7XY9auXat/16RJk8jIkSP1YyZNmuR6zLvvvhsZOHBgZOedd4Y4X+TVV19N6bWE5Fm/fn3ksMMOizRr1iyy9957R3r37h3ZaaedIi+88ILrcQsXLox06tQp0rZt28iwYcMiVatWjdx4442uxzz55JORXXbZJdK+fXt9Hn/99VfP1123bp1+vgoVKkRmzpwppy5Nvvrqq0jfvn0jnTt3jowbNy7SokWLSI8ePSILFixwPe7FF1+M1KxZMzJgwAD9+4YNG0bmzJnjeszkyZP1vdayZctIx44dra+3atWqyKhRoyL169ePjB8/PtK9e/fIBRdcIOcxTd5++219D+HcjB07NtKgQYPI0KFDI2vWrHE97q677opUq1ZN/w7rJu7LefPmOb/fsGFD5OSTT440btxY/7fXXnvFvdbWrVsjBxxwQKRWrVr6tXBNYF198MEH5TymydVXXx1p3ry53quw72G9nDJliusx27dvjxxyyCGROnXq6HupXr16kf3331+fl7CfR0gN2CpYC/fcc8/IHnvsoe+PW2+9NW4PHTJkiL7PcI5q1KgROf3005N+niCPEZLnr7/+iowePTrSunXryJgxY7Td0apVq7h9D3so7NRu3bpFdt99d30en3nmmaSfh8Dei2sCttCzzz4rpy5Nvv3220j//v31ccd+Bfuke/fukfnz57se98orr+g9DY/t2bOn3kM/+eSTpJ9n9erV+nzDHt533331nnzuuefm3XkUx7uMAcd38+bNzvf33ntvpHz58pG5c+c6PzvnnHMibdq0iaxYsUJ/P3v2bP2Yl156yeUMfPDBB5Fly5Z5Ot5BXktIHhzz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", "text/plain": [ "
" ] @@ -103,7 +103,7 @@ }, { "cell_type": "markdown", - "id": "a0030495", + "id": "5a8c491d", "metadata": {}, "source": [ "## Stationarity of the spread (Augmented Dickey-Fuller)\n", @@ -133,13 +133,13 @@ { "cell_type": "code", "execution_count": 3, - "id": "3c372f9e", + "id": "13ec7fd4", "metadata": { "execution": { - "iopub.execute_input": "2026-08-17T14:38:14.171235Z", - "iopub.status.busy": "2026-08-17T14:38:14.170568Z", - "iopub.status.idle": "2026-08-17T14:38:14.880251Z", - "shell.execute_reply": "2026-08-17T14:38:14.878063Z" + "iopub.execute_input": "2026-08-25T17:35:54.449982Z", + "iopub.status.busy": "2026-08-25T17:35:54.449691Z", + "iopub.status.idle": "2026-08-25T17:35:55.135033Z", + "shell.execute_reply": "2026-08-25T17:35:55.134203Z" } }, "outputs": [ @@ -164,13 +164,13 @@ { "cell_type": "code", "execution_count": 4, - "id": "a40b2eb3", + "id": "c17fbd68", "metadata": { "execution": { - "iopub.execute_input": "2026-08-17T14:38:14.884803Z", - "iopub.status.busy": "2026-08-17T14:38:14.884073Z", - "iopub.status.idle": "2026-08-17T14:38:15.129085Z", - "shell.execute_reply": "2026-08-17T14:38:15.126451Z" + "iopub.execute_input": "2026-08-25T17:35:55.137113Z", + "iopub.status.busy": "2026-08-25T17:35:55.136652Z", + "iopub.status.idle": "2026-08-25T17:35:55.237022Z", + "shell.execute_reply": "2026-08-25T17:35:55.236142Z" } }, "outputs": [ @@ -207,7 +207,7 @@ }, { "cell_type": "markdown", - "id": "244bfea6", + "id": "415c15e3", "metadata": {}, "source": [ "The two p-values above can differ by orders of magnitude, and that is\n", @@ -226,7 +226,7 @@ }, { "cell_type": "markdown", - "id": "26ebfbc4", + "id": "356bb1ea", "metadata": {}, "source": [ "## Spread z-score and trading thresholds" @@ -235,19 +235,19 @@ { "cell_type": "code", "execution_count": 5, - "id": "9c5a45e5", + "id": "21a4e239", "metadata": { "execution": { - "iopub.execute_input": "2026-08-17T14:38:15.133658Z", - "iopub.status.busy": "2026-08-17T14:38:15.133179Z", - "iopub.status.idle": "2026-08-17T14:38:15.397536Z", - "shell.execute_reply": "2026-08-17T14:38:15.395813Z" + "iopub.execute_input": "2026-08-25T17:35:55.239189Z", + "iopub.status.busy": "2026-08-25T17:35:55.238851Z", + "iopub.status.idle": "2026-08-25T17:35:55.372202Z", + "shell.execute_reply": "2026-08-25T17:35:55.371218Z" } }, "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAzkAAAF0CAYAAAAAS/eCAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvctoD+AAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzsXQWYJMXZrplZPxc47HAP7hIsaHAPHhyCS3ACIYHgwTVYCPxoCBY8SHAI7g4H3B2c7K3b7PT/vNX99VTXVHdX93TPzO7V+zxwu7M93VXVJZ++X8ayLIsZGBgYGBgYGBgYGBgME2Sr3QADAwMDAwMDAwMDA4MkYZQcAwMDAwMDAwMDA4NhBaPkGBgYGBgYGBgYGBgMKxglx8DAwMDAwMDAwMBgWMEoOQYGBgYGBgYGBgYGwwpGyTEwMDAwMDAwMDAwGFYwSo6BgYGBgYGBgYGBwbCCUXIMDAwMDAwMDAwMDIYVjJJjYDCMMHbsWHbeeedVuxlDDi+99BIfu//85z/Vbsqwxa677so22WQT7es333xztu2226bapqGOWhujb775hq+jf/zjH4ndc/bs2fye1113ndb18803HzvttNMSff4iiyzCHnzwQVbLmDp1Kpt33nnZCy+8UO2mGBjUDIySY2BQRXzwwQf8AKf/xo8fzxZffHG2++67szfffDPy/dra2lhPT08qbR3OyOfzfOwGBgaq3ZRhi87OTtbR0eH5DAI6BHUVcC2+U0sIam81nllrYzQ4OMjXUV9fX2L3LBQKke45Z86cRPfAc845h40aNYptv/32gddBucAePmXKFK37nnvuuWy55ZYL7fuTTz7J9t57b7b88suzhRdemP3qV79id955J7Msy3PtAgsswHbZZRd2/PHH8+8ZGBgYJcfAoCaEgqOOOop9++237IsvvmB///vf+b+//OUv2euvvx7pfq2trezMM89Mrb0GBnHxz3/+kz3//POhik8toxrtHWpjNJwwc+ZMdsMNN7Cjjz6aZbPBNmEYSLCX6yoY9913H9twww0Dr7n77rvZr3/9azZixAh21113cY/zTjvtxA444AC23377lVx/zDHHsHfeeYf9+9//1mqDgcFwh/HkGBjUAJqamrgVcMKECWyDDTbg4R79/f3sr3/9a6T74B64l4FBrQGC2siRI6vdDAMDbdx6663cY/Kb3/wm0VGDQev9999nO+ywQ+B12MsRJnfjjTeylVdemXtyoHDBW3PHHXew9957z3M9PEOrrbYau/766xNtr4HBUIVRcgwMahC/+MUvWC6X4zHuwDLLLOOGtM0zzzz8wDvjjDNYV1dXYE4OLIv47PLLL+fhFMiJQNz2//3f/7nWdXw2efJk/ow999yTh9CFIex74nOR57L++uvzWHn8+9hjj3nuFdZGxMSffPLJbIUVVuCfo+8XXHABDzGTQ0Xw37hx43joxqabbsruv//+krajndtttx2bf/75+T0hQOgA4TJiaKH83//+979Qi/wf/vAHtsoqq/Bnr7nmmuyss84qsdKjv8gpQD8xZuuuuy4XWuD1I3z99dfcmovQRlwDr9/tt9/uuc/f/vY33q4ffviBjxfCXTA2dJ833niD58kg3wDtQUjUs88+G9iHSy65hM8/MUQKgiCec9BBB3muxXuE1dkvJ2ellVbilmmMG40h2iLjp59+YnvttRdbcMEF2bLLLssuvPBCpgudPlJeS9hzwtpL9/nxxx/5esDawJgcfvjh/Ofu7u6S9v3+979nkyZN4mtAhSTHyK99ALwPyHlZb731+HzCvDrssMPY9OnTPfeAlxlGmIUWWojPp/333599+eWXyrY/9dRTfO6if/BYvPzyyyXXYEzOPvts3k+s7RVXXJGvEXlf8wtLgwd80UUX5f/Bi+EXphal3SKgYKyxxhp83JPEQw89xBV+7FFB2HnnnZVhcjgfgM8//7zkb5ttthl7+umnlfPNwGCug2VgYFA1vPPOOwistv785z97Pv/mm2/459tvvz3/va2tzWptbeX//fDDD9Y///lPa8EFF7R23313z/fwnTPOOMP9HdfjM1y30047WW+99Zb1+uuvW48//rj16KOPWplMxrr44outb7/91vr666+te++919p0000D26zzPXrubrvtZu288868n5988ol1yCGHWNls1nrwwQe12jhjxgxriSWWsJZffnnriSeesL7//nvroYcesuaff35rjz32cO8xMDDgjs/s2bOtzz77zDrrrLN4O3E9AZ+PHj3a2mijjaw333zT+vzzz60TTzzR2nvvvXkb8Mwg0DPov++++85acsklrZaWFj4WQdhzzz2tyZMnW08//bQ1bdo0PibnnXeedfbZZ7vXTJ8+3VpsscV4nzFGU6ZMsV577TXriCOO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Ly/Tb4CIiIiIiFqdsE+RLF3RyFOSAgY5REREREQGufC4sky/Bd/jdDUiIiIiIsoqDHKIiIiIiCirMMghIiIiIqKswiCHiIiIiIiyCoMcIiIiIiLKKgxyiIiIiIgoqzDIISIiIiKirMIgh4iIiIiIsgqDHCIiIiIiyioMcoiIiIiIKKswyCEiIiIioqySJ4azLEv9d926dZl+K0RERERElEE6JtAxgm+DnPXr16v/VldXZ/qtEBERERGRITFCp06d2v17yOooDMqwpqYm+eGHH6S8vFxCoVCm345xkSyCv//9739SUVGR6bcTKDz3PP9BxvLPcx9ULPs890G1zqA2J0IXBDi9evWSnJwc/47k4M336dMn02/DaChsmS5wQcVzz/MfZCz/PPdBxbLPcx9UFYa0OWON4GhMPEBERERERFmFQQ4REREREWUVBjk+VlhYKFOnTlX/JZ77IGHZ5/kPKpZ9nv+gYtnn+U+U8YkHiIiIiIiIEsGRHCIiIiIiyioMcoiIiIiIKKswyCEiIiIioqxi/D452W716tXywQcfqP2AdthhB6msrHTcEPW9996TFStWyLBhw2Tw4MGOx/roo4/k888/l7333lu6d++e1GsFzZdffimLFy9WG0qNGDHCcVOpNWvWyNtvvy15eXmy6667SllZWZvn1NbWyiuvvKI2rD344INjvuZbb70l33//vRx44IFx5XnPVmvXrlXlEcsChw8fLl27dm3zHPxt/vz56nwNHTpUhgwZ4nisTz/9VBYtWiS777679O7d2/E52Dhs7ty5kp+fL7vsskvgE3Z89dVX8sUXX0iPHj1k5MiRkpub67j5G8o+oOw77Y1QX18v//nPf6Surk4OP/xwx3O/fPly9f3AtttuG/i9z3BeFyxYoM7d9ttv71hfA57z3XffqTof582r4wTNkiVL1L1yiy22UGUfdXu0DRs2qLq6sbFRlf3OnTsndZx4nhMkOK+o93HPRJlF/ePkww8/lKVLl8rAgQPV85I9jq77n3vuOXVvwD0iyL799lv55JNP1P0W5bGgoKDNczZt2qTKPup03Cud2orxHAfwHaLu79+/v2y33XaSdkg8QJlx2mmnWb169bL23Xdfa7fddrPKysqsGTNmRDxn7dq11i677KKeN3bsWKu0tNQ6++yzI54zZ84ca6eddrIGDx6MJBLWK6+8ktRrBcnHH3+sztmQIUOsQw45xOrbt6+1/fbbW0uXLo143vPPP29VVFSo5+6www5Wt27drLlz50Y854ILLrB69+6tjjFw4MCYr/v++++rc4/vadGiRVZQoQyjPO6zzz7WnnvuaZWUlFg333xzxHM2btyo/t69e3drv/32s8rLy1U5tnvrrbes3XffPVz2n376acfXe+CBB9T3iGvp4IMPtoYPH259/fXXVhB98cUX4XOGst+/f391HXz55ZcRz3v11VetLl26WKNHj7Z23HFH9f/xmN3ll19uVVdXW/369VPfkxNcH0VFRar+wg/+Px4LqksuuUSVfZR7lO/i4mLr6quvjnhOTU2NKqddu3ZVZb9Tp07WSSedZDU2Nrp+nCDBNb/33ntbgwYNUmUf9TWug08++aRNvVJVVWWNHDnSGjNmjDpvL730UkLHife1guSKK65Q98o99thDtUVQZi+77LKI59TV1VlHHnmkVVlZqcps586drXHjxlkNDQ0JHcfu+OOPtwoKCtS1EFTLli2z9t9/f1Xf4zxsvfXW6v/Pnz8/4nn4HXU52kO4X+K+O2vWrISPU1tba5188snq3+N5aEMdc8wxVroxyMmgO++8U92ENAQdubm51pIlS8KPnXnmmapyXL16tfr9nXfesUKhkPXiiy+Gn/PMM89Yb7/9tvXjjz+2G+TE81pBgvP17rvvhn/Hudl5552tAw88MPzY+vXr1Y3uoosuCj82YcIE9X3YGwk33HCD9dNPP1lTp06NGeSsW7dO3eSuu+66wAc5d999t7Vp06bwuXnsscdUubYHfjjvffr0sVauXKl+X7BggZWXl2fNnDkz/JwXXnjBeu2119R31V6Qg7/j2E888UREAySojQ0E2m+++WZEowINBQQ+9usBDWjUP9rkyZNVwwI3Lw2B6Q8//GBNmzbNMchZvHix+l6eeuqp8GNPPvmkegx/CyLUvRs2bAj/Pnv2bHU+5s2bF37smmuusbbYYgtr+fLl6vfPPvtMNeQQrLt9nCBZuHBhRKBeX19vHXTQQSqItz+25ZZbWpMmTYrolMF5RMdLvMeJ5zlBc++996r7oPbyyy+rMvv666+HH7vppptUgPPdd9+p37/66ivVMYh7RiLH0e677z7VWD/iiCMCHeR8+umnEYE62jAIOoYOHRp+rKmpSXV4nXDCCeHH0K5BoLlmzZq4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", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAzkAAAF0CAYAAAAAS/eCAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvctoD+AAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzsXQWYJMXZrplZv7s9BQ45CC7BXYIFDe7BgyYElwSXkEDw4Bo88OMECx7cCe4OB9wdnK7b7PT/vNX99VTXVHdX93TPzO7V+zxwu7M93VXVJZ++X8ayLIsZGBgYGBgYGBgYGBgME2Sr3QADAwMDAwMDAwMDA4MkYZQcAwMDAwMDAwMDA4NhBaPkGBgYGBgYGBgYGBgMKxglx8DAwMDAwMDAwMBgWMEoOQYGBgYGBgYGBgYGwwpGyTEwMDAwMDAwMDAwGFYwSo6BgYGBgYGBgYGBwbCCUXIMDAwMDAwMDAwMDIYVjJJjYDCMMGbMGHb22WdXuxlDDi+99BIfu//+97/VbsqwxS677MI23nhj7es322wzts0226TapqGOWhujb775hq+jf/3rX4ndc9asWfyeV199tdb1EydOZCeddFKiz19kkUXYAw88wGoZU6ZMYfPOOy97/vnnq90UA4OagVFyDAyqiA8++IAf4PTfuHHj2GKLLcZ222039uabb0a+X1tbG+vp6UmlrcMZ+Xyej93AwEC1mzJs0dnZyTo6OjyfQUCHoK4CrsV3aglB7a3GM2ttjAYHB/k66uvrS+yehUIh0j3nzJmT6B545plnslGjRrHtttsu8DooF9jDJ0+erHXfs846iy277LKhfX/iiSfYXnvtxZZbbjm28MILs1//+tfs9ttvZ5Zlea5dYIEF2M4778yOOeYY/j0DAwOj5BgY1IRQcPjhh7Nvv/2WffHFF+yWW27h//7qV79ir7/+eqT7zZ49m5166qmptdfAIC7uu+8+9txzz4UqPrWMarR3qI3RcMKMGTPYtddey4444giWzQbbhGEgwV6uq2Dcc889bIMNNgi85s4772S/+c1v2IgRI9gdd9zBPc477rgj23///dm+++5bcv2RRx7J3nnnHfaf//xHqw0GBsMdxpNjYFADaGpq4lbA8ePHs/XXX5+He/T397N//OMfke6De+BeBga1BghqI0eOrHYzDAy0cdNNN3GPyW9/+9tERw0Grffff59tv/32gddhL0eY3HXXXcdWWmkl7smBwgVvzW233cbee+89z/XwDK266qrsmmuuSbS9BgZDFUbJMTCoQfzyl79kuVyOx7gDSy+9tBvSNs888/AD75RTTmFdXV2BOTmwLOKzSy65hIdTICcCcdv/93//51rX8dmkSZP4M/bYYw8eQheGsO+Jz0Wey3rrrcdj5fHvo48+6rlXWBsRE3/88cez5Zdfnn+Ovp977rk8xEwOFcF/Y8eO5aEbm2yyCbv33ntL2o52brvttmz++efn94QAoQOEy4ihhfJ///vf/0It8qeddhpbeeWV+bPXWGMNdvrpp5dY6dFf5BSgnxizddZZhwst8PoRvv76a27NRWgjroHX79Zbb/Xc55///Cdv1w8//MDHC+EuGBu6zxtvvMHzZJBvgPYgJOqZZ54J7MOFF17I558YIgVBEM858MADPdfiPcLq7JeTs+KKK3LLNMaNxhBtkfHTTz+xPffcky244IJsmWWWYeeddx7ThU4fKa8l7Dlh7aX7/Pjjj3w9YG1gTA455BD+c3d3d0n7/vSnP7H55puPrwEVkhwjv/YB8D4g52Xdddfl8wnz6g9/+AObNm2a5x7wMsMIs9BCC/H5tN9++7Evv/xS2fYnn3ySz130Dx6Ll19+ueQajMkZZ5zB+4m1vcIKK/A1Iu9rfmFp8ID/4he/4P/Bi+EXphal3SKgYKy++up83JPEgw8+yBV+7FFB2GmnnZRhcjgfgM8//7zkb5tuuil76qmnlPPNwGCug2VgYFA1vPPOOwistv72t795Pv/mm2/459tttx3/va2tzZo9ezb/74cffrDuu+8+a8EFF7R22203z/fwnVNOOcX9HdfjM1y34447Wm+99Zb1+uuvW4899pj1yCOPWJlMxrrgggusb7/91vr666+tu+++29pkk00C26zzPXrurrvuau200068n5988ol18MEHW9ls1nrggQe02jh9+nRr8cUXt5Zbbjnr8ccft77//nvrwQcftOaff35r9913d+8xMDDgjs+sWbOszz77zDr99NN5O3E9AZ+3trZaG264ofXmm29an3/+uXXcccdZe+21F28DnhkEegb9991331lLLLGE1dLSwsciCHvssYc1adIk66mnnrKmTp3Kx+Tss8+2zjjjDPeaadOmWYsuuijvM8Zo8uTJ1muvvWYdeuih7ph9+eWX1rhx46zVV1/deuWVV/j4n3XWWXxcTz75ZPdel19+Oe/Tfvvtx9/VV199ZV100UV8rO6//36rrq7O2n///a333nuP3wPjhc/E8ZKB5+GeDz/8sPvZLrvsYjU0NFjzzDOPVSgU+Gd4B2jPOeec4163xRZbWKuttpr7O+b0euutx/tB4zlnzhz372uttRb/b4cddrCefPJJPtbnn38+f/5NN91khUG3j7rP0W0v+om5irl1/fXXWy+99BK/F34W0dnZaY0ePbpkDYtIcoz82od3hrWEdXHNNdfwvQdrY/311+dzEe8SuOWWW6xcLsevwbzEPPzXv/7l7lHAF198wZ/9u9/9jo/7Bx98wNc99oZRo0ZZM2fOdK/t7++3fvWrX/G5fNddd/G233vvvdaECROsddZZx+rr6+PXYQ/APS+++GLPd9dYYw2+Dzz00EP8uzfffLO17777Wo2NjdZRRx3lXqvTbhV6enr4vBbvFQSsa7QT4xeGjTfe2Np5552tuNh77735s/73v/+V/A1nA/6G9hgYzO0wSo6BQY0pOVBiNt98cy6gQ6Hww2233ca/C4E5TMmBMEBCA+GII46w5p133sht1vkePXeBBRYoeS6EEwhPJBAHtfGQQw6xmpubSxQICKn4DoTuIGy55ZYe5QsCJYQ5CI/ydTpKjggoC3hPstLmh7Fjx1rHHnts4DUHHnggF6wgkPsBAinG5KeffioZKwhzJGSRknPkkUd6ruvu7uYKCdouA0rpYost5vvsfD7PBXPMAWBwcJALqUcffTR/1ttvv80/v+eee0qEMFnJAaBsQvBWAZ9jDUBBkT/HHApClD5GeU5Ye9HnN954o+RvK620krXqqqt6Prv22mv59U888URgX5IaI7/2Ye7i81tvvdXzOZQLKCZQDElJh7EhCKTkrLzyyu76Fj+/9NJL3c+glOAzGEhU7bnuuut8lZwbb7yRfwZlTcQll1zCPxcVE512qwCjAO513nnnKf+Oe2It0H8jRozg12PMxM+33nprz/egNELRlsdbF8888wx/5xtssIHy76+++qpn/AwM5maYcDUDgxoAQswQEgEWH4SjzJw5kyembr311vzviL0Gw86SSy7J83ZwLcJJAJAUhAFhKg0NDZ7PEGb2888/85CZTz/9VLutUb6HsDD5ubvuuisPw5PDRVRt/Pe//81D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2SiHb3DULruwec8+m/18yims49573WvGHn44G3fEEWzKgQeynpdecj+f56yzWOuuu7LJW2/NBr780v18/uuvZy3rr8++XnVVz2SY9MgjrG7++dk3q63macOib73Fdj/2E3bO83sXPxwxgi3+9tus+8UX2dSDDnI/rl9iCbbwf/7D2u+5h00/9VT38+Zf/YotcMMNbNbll7PZV1zhfk59umaj49hmUx9xP2899DA2z1FHptqn/NSp7HshfBALYTFFn2aNX4zttdy/2D8WeJwte9fftPskv6fBfQ5lS516lLJPP6+3I/thm63ZpK5vQ/vUevdDbPziC5bVp+9afsEOWe12dkz9o2zzZ86O3Se/uXfJkiewyx85oKLvKe7cS2s9/WHVf7Grz1yKZbddS6tPtx77Avv038+zsz881v38+xGLst+vehv7+zyPs1Xu/1vF+nTK8v9gXy64NrvlmU1Z00B3Rd7TW2PWZKeucDHb67sb2N6Tbyzp00eHn8Sanro/8feUZJ+m/usu1n3W6bHf020LH8BuX+RA9px1Qs30SX5P1urrsp1HX8BO6b2ZrfbyP93PG7bfmU06/+9VOZ/kPnXnWtgKH79T8T0C+15+y13YwXf9lo3++euqvqck94gTftqC7XrDrmyR7vDz6U/r3caWWXUhdtDlG1W0T6NOP4vduNmf2JY/FeWIDzf6Pfvo139g+z15lKdPo8/4G5uw5241sZ4Kq6/Ltm6+QLnvbTr7GHbit+eytb56OJXzaUbjfOy+Vzev6HuqlgybHyZ96hgcZKt89RVra2tjra2trKpKzrvvvss22WQTttdee7HLLrss8FqVJ2fSpEls9o8/FjtSRU/OesdMZystMMBe/dh+7uNnjWETFxqdmBa88kE/evr02pUTWdOI6ntyLry3k7X1Ztg9/8uxI35Txw7boi6yZr/q4TZV6C0nTmArLTNC2aevZmTZ3mdOYa9cNI59/gO8Cm3slSsXYC0j6nmf7n6hh517ty1s/veSBdi40XVlWStWPmIW9+RsvmKGXXZAYyLWipNuaGNPvFX05Hx84/z8PV3zSCe77rHemvfk4D2ttUwdu+bYecpeT3hff7mvwB46cxxbYkyfVp9OuMtiD7/SxT6+dCR764sBdvCl7ayQyfD3tM8GOXbfM7Z3d4kFc+zuU8alZlXa/x9z2Ovf1bFCpo6t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g5BEwnr11VcTeq0g+eSTT9Q5Gzx4sHXwwQdbvXv3toYPH24tW7Ys4nkvvviiVVZWpp674447Wl26dLHmzZsX8ZyLLrrI6tmzpzrGgAED2nzdDz74QJ17fE+LFy+2ggplGOVx7733tvbcc0+rqKjIuuWWWyKes3nzZvX3rl27Wvvuu69VWlqqyrHd22+/bY0bNy5c9p999lnH13vwwQfV94hr6aCDDrJGjBhhffPNN1YQffnll+FzhrLfr18/dR189dVXEc977bXXrE6dOlljxoyxdtppJ/X/8ZjdFVdcYVVWVlp9+/ZV35MTXB8FBQWq/sIP/j8eC6q//e1vquyj3KN8FxYWWtdcc03Ec6qqqlQ57dy5syr7HTp0sE488USrvr7e9eMECa758ePHWwMHDlRlH/U1roNPP/20Rb1SUVFhjRo1yho7dqw6b3PmzInrOLG+VpBceeWV6l65xx57qLYIyuzll18e8ZyamhrriCOOsMrLy1WZ7dixozVx4kSrrq4uruPYHXfccVZeXp66FoJq+fLl1n777afqe5yH7bbbTv3/BQsWRDwPv6MuR3sI90vcd2fNmhX3caqrq62TTjpJ/Xs8D22oo48+2ko1BjlpdNddd6mbkIagIzs721q6dGn4sbPPPltVjmvXrlW/v/vuu1YoFLJefvnl8HOee+4565133rF+/PHHVoOcWF4rSHC+3nvvvfDvODe77LKLdcABB4Qf27hxo7rRXXLJJeHHJk+erL4PeyPhxhtvtH766Sdr2rRpbQY5GzZsUDe566+/PvBBzj333GNt2bIlfG4ef/xxVa7tgR/Oe69evazVq1er3xcuXGjl5ORYTz/9dPg5L730kvX666+r76q1IAd/x7GffPLJiAZIUBsbCLTfeuutiEYFGgoIfOzXAxrQqH+0KVOmqIYFbl4aAtOVK1da06dPdwxylixZor6XZ555JvzYU089pR7D34IIde+mTZvCv8+ePVudj/nz54cfu/baa61tttnGWrFihfr9888/Vw05BOtuHydIFi1aFBGo19bWWgceeKAK4u2P9enTxzr99NMjOmVwHtHxEutxYnlO0Nx3333qPqi98sorqsy+8cYb4cduvvlmFeB8//336vevv/5adQzinhHPcbT7779fNdYPP/zwQAc5n332WUSgjjYMgo4hQ4aEH2toaFAdXieccEL4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", "text/plain": [ "
" ] @@ -269,7 +269,7 @@ }, { "cell_type": "markdown", - "id": "e8fae980", + "id": "6f832f5f", "metadata": {}, "source": [ "## Full backtest" @@ -278,13 +278,13 @@ { "cell_type": "code", "execution_count": 6, - "id": "77f7401e", + "id": "3ab5f7f4", "metadata": { "execution": { - "iopub.execute_input": "2026-08-17T14:38:15.402683Z", - "iopub.status.busy": "2026-08-17T14:38:15.402244Z", - "iopub.status.idle": "2026-08-17T14:38:17.715344Z", - "shell.execute_reply": "2026-08-17T14:38:17.712911Z" + "iopub.execute_input": "2026-08-25T17:35:55.374323Z", + "iopub.status.busy": "2026-08-25T17:35:55.374033Z", + "iopub.status.idle": "2026-08-25T17:35:56.572737Z", + "shell.execute_reply": "2026-08-25T17:35:56.571824Z" } }, "outputs": [ @@ -297,7 +297,7 @@ "Symbols : EWA, EWC\n", "Period : 2010-01-04 -> 2025-12-31\n", "------------------------------------------------\n", - "Total return : 15.25%\n", + "Total return : 15.24%\n", "CAGR : 0.89%\n", "Volatility (ann.) : 3.05%\n", "Sharpe : -0.35\n", @@ -305,7 +305,7 @@ "Calmar : 0.11\n", "Max drawdown : -8.01%\n", "Hit rate (non-zero periods): 47.95%\n", - "Total costs (currency units): 4615.59\n", + "Total costs (currency units): 4615.58\n", "Number of trades : 1314\n", "------------------------------------------------\n", "Beta : -0.01\n", @@ -321,7 +321,7 @@ }, { "cell_type": "markdown", - "id": "a94b91c9", + "id": "b90a834b", "metadata": {}, "source": [ "## Takeaways\n", @@ -354,9 +354,9 @@ "version": "3.13.7" }, "quantlab": { - "code_hash": "51c6d2bd9d6fdae1a9aaf52e138fda7161dc9177754dc9b1a96c98498d377105", + "code_hash": "01f453a13e89b4a77bb5e85538cd9963479ca9a60745ac9d35d77a2a58d5c3ba", "config_hashes": { - "configs/pairs_trading.yaml": "21e41059208c1d37c1c62dd34b78cf51007c0a5f67e170c43d96df110bc1101a" + "configs/pairs_trading.yaml": "f312e13ab0ddb313e6987aa2bd11155db31090fd992757ee8317a3fa0aad76ff" }, "generator": "scripts/build_notebooks.py" } diff --git a/notebooks/05_robustness_analysis.ipynb b/notebooks/05_robustness_analysis.ipynb index 75ab978..44928d2 100644 --- a/notebooks/05_robustness_analysis.ipynb +++ b/notebooks/05_robustness_analysis.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "c4225ba5", + "id": "9bed088f", "metadata": {}, "source": [ "# 05 — Robustness Analysis (Example)\n", @@ -15,20 +15,20 @@ { "cell_type": "code", "execution_count": 1, - "id": "68833bfc", + "id": "1df1c1e5", "metadata": { "execution": { - "iopub.execute_input": "2026-08-17T14:38:33.519941Z", - "iopub.status.busy": "2026-08-17T14:38:33.519487Z", - "iopub.status.idle": "2026-08-17T14:39:42.945982Z", - "shell.execute_reply": "2026-08-17T14:39:42.943364Z" + "iopub.execute_input": "2026-08-25T17:35:59.104260Z", + "iopub.status.busy": "2026-08-25T17:35:59.103963Z", + "iopub.status.idle": "2026-08-25T17:36:32.806814Z", + "shell.execute_reply": "2026-08-25T17:36:32.805985Z" } }, "outputs": [ { "data": { "text/plain": [ - "(0.44371638942601943, 0.057474778471748866)" + "(0.44371649849802863, 0.05747479854942217)" ] }, "execution_count": 1, @@ -58,7 +58,7 @@ }, { "cell_type": "markdown", - "id": "73440d35", + "id": "80059699", "metadata": {}, "source": [ "## Parameter sensitivity: lookback period x top fraction" @@ -67,13 +67,13 @@ { "cell_type": "code", "execution_count": 2, - "id": "41c5a718", + "id": "07b9d419", "metadata": { "execution": { - "iopub.execute_input": "2026-08-17T14:39:42.950780Z", - "iopub.status.busy": "2026-08-17T14:39:42.950110Z", - "iopub.status.idle": "2026-08-17T14:53:37.734245Z", - "shell.execute_reply": "2026-08-17T14:53:37.731977Z" + "iopub.execute_input": "2026-08-25T17:36:32.808911Z", + "iopub.status.busy": "2026-08-25T17:36:32.808585Z", + "iopub.status.idle": "2026-08-25T17:42:33.432983Z", + "shell.execute_reply": "2026-08-25T17:42:33.432017Z" } }, "outputs": [ @@ -114,31 +114,31 @@ " \n", " \n", " 0.250\n", - " 0.282720\n", + " 0.282722\n", " 0.346163\n", " 0.443716\n", - " 0.420908\n", + " 0.420907\n", " \n", " \n", " 0.375\n", " 0.501479\n", " 0.553154\n", - " 0.688103\n", + " 0.688104\n", " 0.650963\n", " \n", " \n", " 0.500\n", " 0.526569\n", - " 0.484627\n", - " 0.686853\n", + " 0.484626\n", + " 0.686852\n", " 0.694514\n", " \n", " \n", " 0.625\n", - " 0.553918\n", - " 0.576571\n", - " 0.690521\n", - " 0.704115\n", + " 0.553919\n", + " 0.576572\n", + " 0.690520\n", + " 0.704114\n", " \n", " \n", "\n", @@ -147,10 +147,10 @@ "text/plain": [ "lookback_period 126 189 252 315\n", "top_fraction \n", - "0.250 0.282720 0.346163 0.443716 0.420908\n", - "0.375 0.501479 0.553154 0.688103 0.650963\n", - "0.500 0.526569 0.484627 0.686853 0.694514\n", - "0.625 0.553918 0.576571 0.690521 0.704115" + "0.250 0.282722 0.346163 0.443716 0.420907\n", + "0.375 0.501479 0.553154 0.688104 0.650963\n", + "0.500 0.526569 0.484626 0.686852 0.694514\n", + "0.625 0.553919 0.576572 0.690520 0.704114" ] }, "execution_count": 2, @@ -171,19 +171,19 @@ { "cell_type": "code", "execution_count": 3, - "id": "6af716f3", + "id": "69aa745b", "metadata": { "execution": { - "iopub.execute_input": "2026-08-17T14:53:37.738864Z", - "iopub.status.busy": "2026-08-17T14:53:37.738071Z", - "iopub.status.idle": "2026-08-17T14:53:38.145422Z", - "shell.execute_reply": "2026-08-17T14:53:38.143482Z" + "iopub.execute_input": "2026-08-25T17:42:33.434787Z", + "iopub.status.busy": "2026-08-25T17:42:33.434535Z", + "iopub.status.idle": "2026-08-25T17:42:33.591255Z", + "shell.execute_reply": "2026-08-25T17:42:33.590378Z" } }, "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjQAAAHVCAYAAADme2G5AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvctoD+AAAAAlwSFlzAAAPYQAAD2EBqD+naQAAWDlJREFUeJzt3QmczPX/wPH3rmOd6yYhtySFkHKUHKGSK4lURMW/lEJIRadcKZUOISUUkqQDyVHORAcqhFDum8Wy83+8P/2+08zszO6c392ZfT17fFv7ne985jvfmd157/vz/nw+cQ6HwyEAAABRLD6jTwAAACBUBDQAACDqEdAAAICoR0ADAACiHgENAACIegQ0AAAg6hHQAACAqEdAAwAAoh4BjQ22b98uVatWlTlz5tjxcDHj4MGD5rp9+OGHGX0qQFR69dVXzc/QhQsX0j128uTJ5tgTJ07Ycm6Z9RwQvQhoQnDu3Dl55513pF27dlK7dm1p2rSpPPzww/LDDz+4HXf27Fn5/fff5dixY6G+XjFnz5495hfYRx99lOq28+fPm+t25MiRDDk3RLe33nrLvLdOnz4tWdWBAwfMz5A/E8IfOnTIHOtP8BOp18Wuc0Bsyp7RJxCt9IexQYMGsmvXLnn66aflmmuukaSkJJk4caLUrVtXPvjgA+natWtGn2aml5yc7DNoKVasmGzevFkuuuiiDDk3RH+GT99bKSkpGX0qUeHee++VW265RRITEzPsdbHrHBCbCGhCSI1u2LBBZs6cKbfddptz//XXX29+IDUrg9Bky5bN/CUHIPIKFy5stqx+DohedDkFaefOnebrFVdckeq222+/Xbp06eL1fmvXrpW2bdtKzZo1pVOnTiYD4Uk/xK3tyiuvlJtvvtkEUK5pY9e6nJUrV0r79u2levXq8t1337ndtmzZMhNg6ePpOW3atMnrec2ePdt0ndWoUcNknp555hk5efJkmtcgrXPw53msWbPGdNOpYcOGOY8dPnx4mjU02hX1xhtvSPPmzU27+vXNN980+9Pjz7W16PPSYLVWrVrSrFkzGTNmjDNQTe+5a+aub9++Uq9ePXN/vfYrVqxwa//UqVMycuRIc/56jF7/999/3+0vV3+OSat2QjNgo0ePlmuvvdacy9ChQ1Ol+ufNm+e8JpdddpnUqVNHunfvLuvWrfPZ5rhx4+S6666T+vXrB93Gyy+/bO7fqFEjmTZtmrldn5deZ30P6vnq43ij3bcvvPCCNG7c2LyO+h7X97DlqaeeMo+ltDvYOreNGzf63UZ6z9mX48ePm/ewvrf1505/HyxevNjtGH/eH+G6Vtax6b0PvNWvWOegP1vjx483j6UZ6CFDhsiZM2fc7u/PeyC918VXDU0g18ufcw325wqZnK62jcB98MEH+gnoeOKJJxwpKSlpHrt582ZzbJ8+fRwdOnRwLFy40LF48WJHrVq1HCVKlHCcPHky1fHWtnr1asfo0aMduXPndjz99NOp2nzggQcct956q2PBggWOadOmOb799lvnbffff7+5bdGiReb2xo0bO/Lnz+/46aef3B6vd+/ejly5cjmee+45x6pVqxyfffaZ4/LLL3dcddVVjtOnT6f7vLydgz/P49SpU+bctI1hw4Y5j923b5+5/Z9//jG3vfbaa87HvHDhguOmm25y5M2b1+zXdseNG+fIkyePOQe9Pb3XIr1rq/TaZc+e3by+y5Ytc3zzzTeOAQMGmC295/7bb785ihQpYl7fzz//3Ny/a9eujvj4eMeHH37ofIw2bdo4ypUr55g5c6Zjw4YNjnnz5jm6d+/ueOWVVwI6xpshQ4aY83vkkUcczz77rHmukydPdhQuXNhx3XXXOc6fP+889tixY85rsmnTJvOa3H777Y6EhATHL7/8kqrNRx991LxeK1ascAwaNCioNvr37+8YMWKEOS9938XFxTnmzJljfkaGDx9u9r/44otm/6RJk9ye2969ex2VKlVyVKlSxTFjxgzH2rVrHWPGjDHv4eeff9753tHnro+1bt0657klJSX53UZ6z9mbv//+21GxYkVH2bJlHe+9955pd9asWY5mzZqZ56T8fX+E41oF8j4YNWqUOfbIkSOp7q9f9bH1/hMmTDA/b7169XJ7LH/eA+m9Lt7OIdDr5c+5BvtzhcyNgCZI+sHZvn178wOkvxg1KHjrrbccW7duTXWs9eGnQYLrB+769evNfv2hS4/+ktVfDNYvIKtNfWzXX0oaXFm3Va5c2e02/aVRsmRJR5MmTZz7vvjiC3OsnrurnTt3msfTXzC+pHUO/j6P7du3mzbefPPNVMd6C2j0F5jumzJlitux+kta90+fPt3nY/t7ThrQeT6u5dy5c+k+91atWjkSExMdhw8fdrtv06ZNHQUL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QpcTAACIemRoAACwrcsptDwC89D4RkADAIANqKGJLLqcAABA1CNDAwCADcjQRBYBDQAANiCgiSy6nAAAQNQjQwMAgA3i//dfqG3AOwIaAABsEGeGbceF3Aa8I9QDAABRjwwNAAA2oCg4sghoAACwgc4SHPpMwXSs+MKVAQAAUY8MDQAANqDLKbIIaAAAsAEBTWTR5QQAAKIeGRoAAGI4Q5OUlCQLFiyQAwcOSK1ataR27dppHr9w4UL5/fff3fZddNFFcttttwV0jN0IaAAAiNFRTrt375bGjRtLnjx5pFq1atK/f3+555575NVXX/V5nylTpsi6deukadOmzn1nz54N+Bi7EdAAABCjHnvsMSlSpIgsX75ccubMKd9//700bNhQ2rZtKzfccIPP+9WrV09ef/31NNv25xg7UUMDAIAtH7hxYdn8debMGZk7d6707NnTBDOqQYMGUrNmTfnoo4/SvO+ePXtk4sSJMmfOHPn777+DPiZLBTR6sTVlVb16dencubNs3bo1zeNPnDghL774olx//fWmH/Duu++Wn376ye2YGjVqSKVKlVJtQ4cOdR7z9NNPp7r9pptuitjzBABkbVYNTaibOn78uNt21kt3z7Zt2+TcuXNy2WWXue3X7zdt2pTmue7cuVOWLVsmr7zyivl8fOutt4I6Jst0OX3++eemgGjUqFFy7bXXytixY6VRo0ayceNGKVy4sNf79O7dW6pWrSovvfSSZM+e3VxATZ9t2LBBKlasaI7RaDElJcV5nx9//FE6deokdevWde7bv3+/VK5cWV577TXnvoSEhIg+XwAAwqFMmTJu3w8dOlSGDRuWKgGgChYs6La/UKFCaQY0jzzyiEkYxMf/m/MYP3689OnTx3w+X3755X4fk6UCGr34Xbt2lb59+5rv33//fSlZsqS8+eabMmTIEK/3ee+990wgY7nqqqvM/ZYuXeoMaCpUqOB2nzFjxkipUqWkVatWbvvz5s1rokoAAOxZbTs+LKtt79q1SxITE9P8gzx37txugY1FMzpaJOyL6x//ViJh4MCB8s033ziDFX+OyTJdTnqBNXPSokUL5z7t42vWrJksWbLE5/1cgxmry0pf4KuvvtrncLXp06fLvffeK9myZXO77bvvvpMrr7zSRJRPPPFEqhcdAIDM2OWkwYzrluAloNE/7jWDsn37drf9f/75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", + "image/png": "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sGFuCQHdevXqJZkpywc0b775prlItWvXlsTERHnggQfkggsukHfffdfr8Tly5JBJkyaZIEa7prS7SS/8gQMH0mVplAY52p0FAEA06QinHGFuwY6SmjNnjrRu3VouvfRS6d+/v6xbt06uuuoqOXXqlM/76Oel9mx8/fXX8n//939y1113yYsvvii//vqr85jNmzebEpBXX33VuWmwlJmydA3N3r17Zfv27dKoUSO3/Y0bN5ZVq1YF3I5eeHXeeee57deuq/nz50tKSorUq1dP3njjDbnssssidPYAAPwnIl1GQd7/sccek+7du8sTTzzh/PzUcoyJEyfKvffe6/U+Q4YMkdOnT5uAJm/evGafBkWef/yXKFHCZGayiiydobHSYsWLF3fbr98HkjJTJ0+eNFmd5s2bm6yNRQOYH374wXRLaVuVKlWSa665Rnbv3u2zLX2BNQ3nugEAkBXt379ffv75Z2nbtq1zn9aVaobGV4mFlm1MnjxZevTo4QxmlNXj4WrJkiXms7VTp04mIXD27FnJTFk6oNEuJuV5kVJTU03XUkY0mrzppptMUKMvkCvtxtLCYVWoUCEZO3asCVimTZvms73hw4ebY62tXLlyIT4zAEB2E8miYM8/rk+fPp3u8bSHQ51//vlu+/V76zZPWk967NgxqVq1qjz44IMmYLn99ttl8eLFbscVLFhQ7rjjDpMB0uyNdklprarD4ZDMkqUDmjJlyph/PbMme/bscd6WUTDzxx9/mGImz+4mTxqJahpu27ZtPo8ZPHiwyehY244dO4J6PgCA7D1sOxKb0j+oXf/AHj58eLrH0z/+lWdmRT/vrNs8WbU12rOhn4naVVW5cmVp0aKFfP75587jtGZG61O1Z+Puu+82tTqa9dF/M0uWrqFJTk42xcBa56Ijm6xszTfffCN9+/Z1Hnfo0CETwFhzyOgLpVXZGzZskEWLFpmh3p40inSdz+aff/4xEat2Pfmibwpvc9oAAGAn/YNaPyMtSV4+m4oWLWr+9Rzhq0W/WtDrjXWfdu3amelNlAYz69evl9GjR0v79u29Pt4ll1xiPoN/+uknueGGGyQzZOkMjdLoUIuX3nnnHdMXqNXWqk+fPs5jBgwYIC1btnTOW3PrrbfKihUrzGgnZQ3L1q4npam5hg0bymeffSa///67CZi0j1EDn27dumXK8wQAxDct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F8rq1asdEyZMcKSmpprvjx8/7mjRooX5Re7q8ccfdxQrVszx888/m+/T0tIcb775pk3PIr6u+aFDhxw5cuRwvPTSS859U6dO1aXpnNdXX5fExETHlClTnNf7oYceMsGNBpcI/j2sH5z6moTbDhyOs2fPOkaMGGGukfX+fPTRR80fPKdOnQr4ZyGQ1wUIFwFNnPH3C8Vb9kA/TK1f7IcPH3bkzZvX8corr0T5LLPHNde/+DV4+e6775z7duzYYfYtXLjQfP/iiy+aDIGrP/74wxyzePFiG84+tnm+h60PzhdeeMEELpqNCbUdeDd37lzz/vR2bTMKaIJ9XYBgUBScja1evdrUyFj94cuWLZOUlBRp27atWXRz7dq1ZoE/hEbrZe655x555JFH5PPPP5e5c+dKz5495YYbbpCmTZuaY4oWLSrHjx93u867du0y/65Zs4ZLH+R72PLcc89Jr169pHLlynLVVVeZGqZQ2sG/tm7dKkuXLpWpU6fKgAED5IEHHpBSpUoFfXmCfV2AYBDQZFOLFi2Sd955R5544gnnPg1itBj1zTfflHr16kn37t3NL62BAwdm6rnGsh49esiJEyfMh4BuGzdulPvuu8+5mm+nTp2kZMmS0qFDB5k9e7ZMmTJF7r//fsmbN68cPHgws08/5t7DSmfBPnDggKxbt062b99u9t18881y7ty5oNrBf2bNmmV+D2hwru/d2267LejLE+zrAgQtqHwO4qLL6YcffjAFkf369XPbP3HiRJNK7ty5szP1/v333zty5sxpaj8Q3DXftm2bI0+ePI7Ro0c7982cOdPU1Wi9gUXT7wMGDHC0bt3acdNNNzmWL19uiiufe+45LnmQ72Fvli5dat7XGzZsCKsd/FtDo0XCWty+a9eusLq8/b0uQCjI0GQzP/74o1xzzTUmczBy5Ei326zhk9otYqXedfjlpZdeatLNCM6CBQvMcNc+ffo49914441miPCcOXOc+zQL9uKLL8qXX34pn376qcnYHDp0SGrWrMklD/I97I3VNWJ15YXaDsRkcPv372+yjkuWLAnrkvh6XYBQEdBkI5rq1V/gt99+u4waNSrd7Q0aNJDChQu7/YLRuVP27Nlj5upAcPSaaTr9n3/+cZv7RLuSXK+n1i25euutt+S8886Ta6+9lkse5HtYP2g9zZs3zzm/T6DtwPf11PmS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", "text/plain": [ "
" ] @@ -205,7 +205,7 @@ }, { "cell_type": "markdown", - "id": "f01d8be5", + "id": "0d70001c", "metadata": {}, "source": [ "The goal here is a broad plateau of reasonable Sharpe ratios, not a single\n", @@ -215,7 +215,7 @@ }, { "cell_type": "markdown", - "id": "bb5cd8c1", + "id": "61222517", "metadata": {}, "source": [ "## Bootstrap distribution of CAGR, Sharpe, maximum drawdown\n", @@ -240,13 +240,13 @@ { "cell_type": "code", "execution_count": 4, - "id": "32c16b11", + "id": "94cee54b", "metadata": { "execution": { - "iopub.execute_input": "2026-08-17T14:53:38.149347Z", - "iopub.status.busy": "2026-08-17T14:53:38.148914Z", - "iopub.status.idle": "2026-08-17T14:53:43.239630Z", - "shell.execute_reply": "2026-08-17T14:53:43.237396Z" + "iopub.execute_input": "2026-08-25T17:42:33.593012Z", + "iopub.status.busy": "2026-08-25T17:42:33.592762Z", + "iopub.status.idle": "2026-08-25T17:42:35.818234Z", + "shell.execute_reply": "2026-08-25T17:42:35.817523Z" } }, "outputs": [ @@ -292,16 +292,16 @@ " \n", " 1\n", " sharpe\n", - " 0.440493\n", - " 0.089658\n", - " 0.809243\n", + " 0.440494\n", + " 0.089659\n", + " 0.809244\n", " 0.440895\n", " 0.216179\n", " \n", " \n", " 2\n", " max_drawdown\n", - " -0.181921\n", + " -0.181920\n", " -0.288049\n", " -0.124776\n", " -0.190264\n", @@ -310,11 +310,11 @@ " \n", " 3\n", " final_value\n", - " 270550.254300\n", - " 153970.405256\n", - " 482427.511529\n", - " 287009.369033\n", - " 103309.758005\n", + " 270550.906800\n", + " 153970.547350\n", + " 482428.885302\n", + " 287009.475263\n", + " 103309.798596\n", " \n", " \n", "\n", @@ -323,15 +323,15 @@ "text/plain": [ " statistic median p05 p95 mean \\\n", "0 cagr 0.056941 0.024305 0.091509 0.057132 \n", - "1 sharpe 0.440493 0.089658 0.809243 0.440895 \n", - "2 max_drawdown -0.181921 -0.288049 -0.124776 -0.190264 \n", - "3 final_value 270550.254300 153970.405256 482427.511529 287009.369033 \n", + "1 sharpe 0.440494 0.089659 0.809244 0.440895 \n", + "2 max_drawdown -0.181920 -0.288049 -0.124776 -0.190264 \n", + "3 final_value 270550.906800 153970.547350 482428.885302 287009.475263 \n", "\n", " std \n", "0 0.020172 \n", "1 0.216179 \n", "2 0.050865 \n", - "3 103309.758005 " + "3 103309.798596 " ] }, "execution_count": 4, @@ -350,7 +350,7 @@ }, { "cell_type": "markdown", - "id": "8fd159a4", + "id": "a353fc69", "metadata": {}, "source": [ "The median represents the typical result across the 1,000 synthetic histories.\n", @@ -372,7 +372,7 @@ }, { "cell_type": "markdown", - "id": "cbf1f0fe", + "id": "f2762934", "metadata": {}, "source": [ "## Stress tests" @@ -381,13 +381,13 @@ { "cell_type": "code", "execution_count": 5, - "id": "c4c30617", + "id": "76e10d58", "metadata": { "execution": { - "iopub.execute_input": "2026-08-17T14:53:43.244204Z", - "iopub.status.busy": "2026-08-17T14:53:43.243537Z", - "iopub.status.idle": "2026-08-17T14:57:29.514192Z", - "shell.execute_reply": "2026-08-17T14:57:29.511711Z" + "iopub.execute_input": "2026-08-25T17:42:35.820033Z", + "iopub.status.busy": "2026-08-25T17:42:35.819798Z", + "iopub.status.idle": "2026-08-25T17:44:19.355911Z", + "shell.execute_reply": "2026-08-25T17:44:19.355040Z" } }, "outputs": [ @@ -425,7 +425,7 @@ " \n", " 0\n", " baseline\n", - " 1.729542\n", + " 1.729543\n", " 0.057462\n", " 0.443716\n", " -0.158208\n", @@ -435,7 +435,7 @@ " \n", " 1\n", " commission x2\n", - " 1.693179\n", + " 1.693180\n", " 0.056673\n", " 0.435414\n", " -0.158825\n", @@ -445,7 +445,7 @@ " \n", " 2\n", " commission x5\n", - " 1.586944\n", + " 1.586945\n", " 0.054309\n", " 0.410480\n", " -0.160673\n", @@ -455,7 +455,7 @@ " \n", " 3\n", " slippage x2\n", - " 1.693179\n", + " 1.693180\n", " 0.056673\n", " 0.435414\n", " -0.158825\n", @@ -465,7 +465,7 @@ " \n", " 4\n", " execution delay +1\n", - " 1.681518\n", + " 1.681519\n", " 0.056418\n", " 0.432201\n", " -0.149058\n", @@ -475,10 +475,10 @@ " \n", " 5\n", " best 10 days removed\n", - " 1.057685\n", + " 1.057687\n", " 0.040967\n", " 0.274617\n", - " -0.168913\n", + " -0.168912\n", " ok\n", " None\n", " \n", @@ -498,12 +498,12 @@ ], "text/plain": [ " scenario total_return cagr sharpe max_drawdown \\\n", - "0 baseline 1.729542 0.057462 0.443716 -0.158208 \n", - "1 commission x2 1.693179 0.056673 0.435414 -0.158825 \n", - "2 commission x5 1.586944 0.054309 0.410480 -0.160673 \n", - "3 slippage x2 1.693179 0.056673 0.435414 -0.158825 \n", - "4 execution delay +1 1.681518 0.056418 0.432201 -0.149058 \n", - "5 best 10 days removed 1.057685 0.040967 0.274617 -0.168913 \n", + "0 baseline 1.729543 0.057462 0.443716 -0.158208 \n", + "1 commission x2 1.693180 0.056673 0.435414 -0.158825 \n", + "2 commission x5 1.586945 0.054309 0.410480 -0.160673 \n", + "3 slippage x2 1.693180 0.056673 0.435414 -0.158825 \n", + "4 execution delay +1 1.681519 0.056418 0.432201 -0.149058 \n", + "5 best 10 days removed 1.057687 0.040967 0.274617 -0.168912 \n", "6 reduced universe 0.758890 0.031919 0.229232 -0.105496 \n", "\n", " status error \n", @@ -528,7 +528,7 @@ }, { "cell_type": "markdown", - "id": "2372a3dc", + "id": "d498daae", "metadata": {}, "source": [ "## Monte Carlo permutation test\n", @@ -555,13 +555,13 @@ { "cell_type": "code", "execution_count": 6, - "id": "8bb48602", + "id": "e5064f61", "metadata": { "execution": { - "iopub.execute_input": "2026-08-17T14:57:29.518535Z", - "iopub.status.busy": "2026-08-17T14:57:29.518102Z", - "iopub.status.idle": "2026-08-17T14:57:30.242863Z", - "shell.execute_reply": "2026-08-17T14:57:30.240718Z" + "iopub.execute_input": "2026-08-25T17:44:19.357865Z", + "iopub.status.busy": "2026-08-25T17:44:19.357588Z", + "iopub.status.idle": "2026-08-25T17:44:19.675001Z", + "shell.execute_reply": "2026-08-25T17:44:19.674147Z" } }, "outputs": [ @@ -583,7 +583,7 @@ }, { "cell_type": "markdown", - "id": "2923f749", + "id": "8364b5f4", "metadata": {}, "source": [ "## Interpretation\n", @@ -622,9 +622,9 @@ "version": "3.13.7" }, "quantlab": { - "code_hash": "51c6d2bd9d6fdae1a9aaf52e138fda7161dc9177754dc9b1a96c98498d377105", + "code_hash": "01f453a13e89b4a77bb5e85538cd9963479ca9a60745ac9d35d77a2a58d5c3ba", "config_hashes": { - "configs/momentum_sp500.yaml": "7a9f43ca4e4fd9975d3abc542f60e55a1b02fce5be00efc2da339f3156e59178" + "configs/momentum_sp500.yaml": "e2be7ba15eca4cf73930a4a991a252549c7a921d2c09d50bedc7c5c8f6552a7e" }, "generator": "scripts/build_notebooks.py" } diff --git a/pyproject.toml b/pyproject.toml index 7ea7da4..94c6d96 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,8 +26,9 @@ classifiers = [ ] # Core dependencies are intentionally small. `pandas-market-calendars` -# supplies maintained XNYS sessions and close times that QuantLab should not -# duplicate with a local holiday list. +# supplies maintained sessions and close times for every supported market +# calendar (XNYS, XASX, XSAU, XHKG, ...) that QuantLab should not duplicate +# with a local holiday list. dependencies = [ "numpy>=2.5.2", "pandas>=2.1", @@ -40,13 +41,12 @@ dependencies = [ "pyyaml>=6.0", # YAML config loading "typer>=0.27.1", # CLI "requests>=2.31", # Binance REST client - "joblib>=1.3", # Caching / parallelism helpers - "pandas-market-calendars>=5.4,<6", # Maintained XNYS calendar + "pandas-market-calendars>=5.4,<6", # Maintained market calendars (XNYS, XASX, XSAU, ...) "filelock>=3.13", # Cross-process cache-write coordination ] [project.optional-dependencies] -# Streamlit 1.60 provides the iframe and lazy-tab APIs used by the dashboard. +# Streamlit 1.61 provides the iframe and lazy-tab APIs used by the dashboard. dashboard = ["streamlit>=1.61.1"] # Data downloads. Isolated so tests can run fully offline. yahoo = ["yfinance>=0.2.40"] diff --git a/reports/figures/dashboard_home.png b/reports/figures/dashboard_home.png index b97d435..a1a4f8f 100644 Binary files a/reports/figures/dashboard_home.png and b/reports/figures/dashboard_home.png differ diff --git a/reports/figures/dashboard_results.png b/reports/figures/dashboard_results.png index de7ea08..d7c5d23 100644 Binary files a/reports/figures/dashboard_results.png and b/reports/figures/dashboard_results.png differ diff --git a/requirements.txt b/requirements.txt index 06986db..9ca4925 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,7 +13,6 @@ pydantic>=2.5 pyyaml>=6.0 typer>=0.27.1 requests>=2.31 -joblib>=1.3 pandas-market-calendars>=5.4,<6 filelock>=3.13 @@ -21,5 +20,5 @@ filelock>=3.13 yfinance>=0.2.40 # Dashboard (optional) -# The dashboard uses Streamlit 1.60's lazy-tab API. +# The dashboard uses Streamlit 1.61's lazy-tab API. streamlit>=1.61.1 diff --git a/scripts/download_data.py b/scripts/download_data.py index d513265..c2c39ae 100644 --- a/scripts/download_data.py +++ b/scripts/download_data.py @@ -32,7 +32,7 @@ def main() -> int: config = ExperimentConfig.from_yaml(args.config) data = DataLoader().download(config, force=args.force) symbol_count = data["symbol"].nunique() - if config.data.source == "csv": + if config.data_source == "csv": print( f"Loaded {len(data)} rows for {symbol_count} symbols from CSV files " "(CSV input is not written to the Parquet cache)." @@ -40,7 +40,7 @@ def main() -> int: else: print( f"Cached {len(data)} rows for {symbol_count} symbols from " - f"{config.data.source.value}." + f"{config.data_source}." ) return 0 diff --git a/src/quantlab/backtesting/accounting.py b/src/quantlab/backtesting/accounting.py index cef88af..6b566cb 100644 --- a/src/quantlab/backtesting/accounting.py +++ b/src/quantlab/backtesting/accounting.py @@ -20,6 +20,7 @@ from quantlab.execution.orders import executed_weights as compute_executed_weights from quantlab.execution.orders import weight_changes as compute_weight_changes from quantlab.logging_config import get_logger +from quantlab.risk.exposure import average_gross_exposure, average_net_exposure logger = get_logger(__name__) @@ -48,6 +49,26 @@ class AccountingResult: equity_for_costs: pd.Series +def portfolio_metrics_from_accounting( + accounting: AccountingResult, periods_per_year: int +) -> dict[str, float]: + """Exposure and turnover metrics shared by every accounting consumer. + + Shared by :class:`~quantlab.backtesting.engine.BacktestEngine` and + :class:`~quantlab.validation.walk_forward.WalkForwardValidator` so a + single-backtest ``BacktestResult`` and a stitched walk-forward + out-of-sample ``BacktestResult`` report these the same way. + """ + turnover = accounting.turnover + return { + "annual_turnover": float(turnover.mean() * periods_per_year) + if len(turnover) + else 0.0, + "average_gross_exposure": average_gross_exposure(accounting.executed_weights), + "average_net_exposure": average_net_exposure(accounting.executed_weights), + } + + def compute_asset_returns(prices: pd.DataFrame) -> pd.DataFrame: """Simple returns of the adjusted-close matrix.""" return prices.pct_change(fill_method=None) @@ -205,6 +226,8 @@ def run_accounting( asset_returns: pd.DataFrame, execution_model: ExecutionModel, initial_capital: float, + *, + tradable: pd.DataFrame | None = None, ) -> AccountingResult: """Run the vectorised accounting loop. @@ -214,6 +237,14 @@ def run_accounting( asset_returns: Per-asset simple returns aligned to ``held_weights``. execution_model: Cost model. initial_capital: Starting equity. + tradable: When given, the mandatory look-ahead-barrier shift becomes + per-symbol tradability-aware (see + :func:`quantlab.execution.orders.executed_weights`): a decision + made right before a closure executes on that symbol's next real + tradable row, not the raw next row, so it is never misattributed + as trading during the closure itself (e.g. a weekend row that + only exists because another, always-open instrument shares the + same combined index). Returns: A populated :class:`AccountingResult`. @@ -258,7 +289,29 @@ def run_accounting( f"{list(missing_symbols)[:5]})." ) + if tradable is not None: + # Exact same *set* of dates and symbols, no missing values -- unlike + # asset_returns (which may legitimately come from a wider price + # matrix), tradable is only ever built internally from held_weights' + # own (date, symbol) grid, never user input. A mismatched set always + # means an upstream wiring bug, so it must raise loudly rather than + # silently default an unrecognized cell to "tradable" and risk + # trading a symbol that should have stayed closed. Axis *order* + # alone is not a mismatch: a caller may build tradable from a + # declared symbol list while held_weights comes from an + # alphabetically-pivoted price matrix. + if set(tradable.index) != set(held_weights.index) or set( + tradable.columns + ) != set(held_weights.columns): + raise BacktestError( + "tradable must have the same dates and symbols as held_weights." + ) + if tradable.isna().to_numpy().any(): + raise BacktestError("tradable must not contain missing values.") + held = held_weights.sort_index() + if tradable is not None: + tradable = tradable.reindex(index=held.index, columns=held.columns) asset_returns = asset_returns.reindex_like(held) try: return_values = asset_returns.to_numpy(dtype=float) @@ -272,8 +325,10 @@ def run_accounting( "asset_returns must not contain simple returns below -1.0 (-100%)." ) - # Shift weights so period-t return uses weights chosen at t-1. - executed = compute_executed_weights(held) + # Shift weights so period-t return uses weights chosen at t-1. `tradable` + # was already validated above to share held_weights' exact axes and + # sorted alongside it, so it needs no further alignment here. + executed = compute_executed_weights(held, tradable=tradable) result = _solve_accounting(executed, asset_returns, execution_model, capital) diff --git a/src/quantlab/backtesting/benchmark.py b/src/quantlab/backtesting/benchmark.py index 8709e1e..3301e22 100644 --- a/src/quantlab/backtesting/benchmark.py +++ b/src/quantlab/backtesting/benchmark.py @@ -7,8 +7,9 @@ import pandas as pd -from quantlab.constants import TRADING_DAYS_PER_YEAR +from quantlab.constants import SYMBOL, TRADING_DAYS_PER_YEAR from quantlab.data.base import price_matrix +from quantlab.data.calendar import is_session_day from quantlab.exceptions import BacktestError from quantlab.features.returns import simple_returns @@ -16,10 +17,20 @@ def buy_and_hold_returns(data: pd.DataFrame, symbol: str) -> pd.Series: - """Return series for buying and holding a single symbol.""" - prices = price_matrix(data, adjusted=True) - if symbol not in prices.columns: + """Return series for buying and holding a single symbol. + + Pivots only ``symbol``'s own rows, never the whole (possibly + multi-symbol) ``data`` frame: pivoting together with other symbols on a + wider or differently-shaped calendar (e.g. an external benchmark sharing + a frame with an already closure-filled, 24/7-inclusive tradable + universe) would reindex gaps into ``symbol``'s own dense series that it + never actually had, which then cascade into ``simple_returns`` (NaN + divided by NaN) on real trading days adjacent to those gaps. + """ + symbol_rows = data.loc[data[SYMBOL] == symbol] + if symbol_rows.empty: raise KeyError(f"Benchmark symbol '{symbol}' not in data.") + prices = price_matrix(symbol_rows, adjusted=True) return simple_returns(prices[symbol]) @@ -50,12 +61,75 @@ def cash_returns( return pd.Series(per_period, index=index) -def _align_returns(series: pd.Series, portfolio_index: pd.DatetimeIndex) -> pd.Series: - """Align returns, allowing only the expected first-period missing value.""" - aligned = series.reindex(portfolio_index) - if aligned.empty: - return aligned - aligned = aligned.copy() +def _align_returns( + series: pd.Series, + portfolio_index: pd.DatetimeIndex, + *, + calendar: str | None = None, +) -> pd.Series: + """Align benchmark returns onto ``portfolio_index``. + + A point-sample ``reindex`` would be wrong whenever the benchmark's own + calendar differs from the portfolio's: it silently drops any benchmark + session that falls *between* two portfolio dates (e.g. a 24/7 benchmark's + weekend moves get discarded entirely rather than compounded into the + next portfolio date, materially understating or overstating its real + return). Compounding into a cumulative equity curve first and reindexing + that instead fixes this unconditionally: for a portfolio date that is + also one of the benchmark's own dates, this reduces to exactly the + benchmark's own return that period (no approximation, no calendar + needed); for a benchmark session that falls between two portfolio dates, + it is correctly compounded into the following portfolio date rather than + dropped. + + Separately, any date whose price is missing (whether ``series`` never + had a row for it at all, or a wider shared price matrix reindexed it in + as NaN) is a *verified closure*, not missing data, when the benchmark's + own calendar has no session there (e.g. an equity benchmark reindexed + onto a mixed-calendar portfolio's weekend rows) -- exactly like on the + tradable side, it should read as flat (zero return), never raise. When + ``calendar`` is given, such dates are forward-filled from the + benchmark's last known level; a date calendar says *should* be a + session but still has no data is a genuine gap and still raises, same + as before (this is exactly why ``equal_weight``/``first_asset``, whose + series are derived from already closure-filled tradable data, never + pass a calendar here -- a missing value for them is never a calendar + closure, always a real defect, and must always raise). Without a + ``calendar``, any missing date raises unconditionally. + """ + if series.empty or len(portfolio_index) == 0: + return series.reindex(portfolio_index) + original_index = series.index + equity = (1.0 + series).cumprod() + # A returns series' own first element is *always* NaN by construction + # (pct_change has no prior value to diff against) -- a universal, + # expected artifact, never a data defect. Left as NaN, it would divide + # the equity curve's second pct_change by NaN and falsely flag that + # period as missing too. Treat it as the compounding origin (1.0): + # cumprod already computed every later value as if this were the case + # (a leading NaN is skipped, not zeroed, by cumprod's own semantics), so + # this only fixes position zero and changes nothing downstream. + if pd.isna(equity.iloc[0]): + equity.iloc[0] = 1.0 + combined_index = original_index.union(portfolio_index) + equity_on_combined = equity.reindex(combined_index) + if calendar is not None: + closure = pd.Series( + ~is_session_day(calendar, pd.DatetimeIndex(combined_index)), + index=combined_index, + ) + fillable = equity_on_combined.isna() & closure + equity_on_combined = equity_on_combined.mask( + fillable, equity_on_combined.ffill() + ) + aligned_equity = equity_on_combined.reindex(portfolio_index) + # `fill_method` must be pinned explicitly: older pandas releases allowed + # by `pandas>=2.1` default `pct_change` to forward-fill a gap before + # diffing (silently turning a genuine missing value into a 0.0 return + # instead of leaving it NaN for the check below to catch), while pandas 3 + # never fills. Pinning `None` makes this call's behaviour identical on + # every supported pandas version. + aligned = aligned_equity.pct_change(fill_method=None) aligned.iloc[0] = 0.0 missing = aligned.isna() if missing.any(): @@ -72,6 +146,7 @@ def build_benchmark( portfolio_index: pd.DatetimeIndex, *, benchmark_symbol: str | None = None, + benchmark_calendar: str | None = None, first_asset_symbol: str | None = None, risk_free_rate: float = 0.0, periods_per_year: int = TRADING_DAYS_PER_YEAR, @@ -83,6 +158,11 @@ def build_benchmark( data: Canonical long OHLCV frame. portfolio_index: Dates to align the benchmark to. benchmark_symbol: External symbol to track (if ``kind='symbol'``). + benchmark_calendar: The ``symbol`` benchmark's own calendar, used + only to distinguish a verified closure (flat, never an error) + from a genuine data gap (still an error) when aligning it onto + ``portfolio_index``. Ignored for every other ``kind``, whose + series are derived from already closure-filled tradable data. first_asset_symbol: Explicit universe symbol used by ``kind='first_asset'``. risk_free_rate: Annualised rate for the cash benchmark. @@ -100,6 +180,7 @@ def build_benchmark( f"{sorted(_BENCHMARK_KINDS)}." ) + calendar_for_alignment: str | None = None if benchmark_kind == "cash": series = cash_returns(portfolio_index, risk_free_rate, periods_per_year) elif benchmark_kind == "equal_weight": @@ -126,4 +207,5 @@ def build_benchmark( f"Configured benchmark symbol {benchmark_symbol!r} is absent " "from the loaded data." ) from exc - return _align_returns(series, portfolio_index) + calendar_for_alignment = benchmark_calendar + return _align_returns(series, portfolio_index, calendar=calendar_for_alignment) diff --git a/src/quantlab/backtesting/engine.py b/src/quantlab/backtesting/engine.py index e6745ca..147e886 100644 --- a/src/quantlab/backtesting/engine.py +++ b/src/quantlab/backtesting/engine.py @@ -25,6 +25,7 @@ from __future__ import annotations import hashlib +import inspect import subprocess import time from datetime import UTC, datetime @@ -36,33 +37,64 @@ import pandas as pd from quantlab.backtesting.accounting import ( - AccountingResult, compute_asset_returns, + portfolio_metrics_from_accounting, run_accounting, ) from quantlab.backtesting.benchmark import build_benchmark from quantlab.backtesting.result import BacktestResult from quantlab.backtesting.trade_log import build_trade_log from quantlab.config import BenchmarkKind, ExperimentConfig -from quantlab.constants import SYMBOL, TIMESTAMP -from quantlab.data.base import price_matrix +from quantlab.constants import ( + CALENDAR_DAYS_PER_YEAR, + CRYPTO_FREQUENCY_TO_PERIODS_PER_YEAR, + FREQUENCY_TO_PERIODS_PER_YEAR, + SYMBOL, + TIMESTAMP, + TRADING_DAYS_PER_YEAR, +) +from quantlab.data.base import price_matrix, volume_matrix +from quantlab.data.calendar import is_247, uniform_calendar +from quantlab.data.closures import DAILY_FREQUENCY, tradable_mask_for from quantlab.data.storage import ParquetStorage -from quantlab.exceptions import BacktestError +from quantlab.exceptions import BacktestError, QuantLabError from quantlab.execution.execution_model import ExecutionModel -from quantlab.execution.orders import validate_execution_frame +from quantlab.execution.orders import ( + shift_respecting_tradability, + validate_execution_frame, +) +from quantlab.execution.slippage import ( + ConstantSlippageModel, + SlippageModel, + VolumeBasedSlippageModel, +) from quantlab.logging_config import get_logger -from quantlab.portfolio.allocator import PortfolioAllocator +from quantlab.portfolio.allocator import PortfolioAllocator, build_allocator from quantlab.portfolio.constraints import constraints_from_config from quantlab.portfolio.rebalancing import rebalance_and_cap_turnover from quantlab.portfolio.volatility_targeting import apply_volatility_target -from quantlab.risk.exposure import average_gross_exposure, average_net_exposure from quantlab.risk.metrics import compute_metrics -from quantlab.strategies.base import BaseStrategy +from quantlab.strategies.base import ( + BaseStrategy, + build_strategy, + strategy_parameter_names, +) logger = get_logger(__name__) #: Numerical dependencies recorded in result metadata for reproducibility. -_TRACKED_PACKAGES = ("quantlab", "pandas", "numpy", "pydantic", "scipy", "statsmodels") +_TRACKED_PACKAGES = ( + "quantlab", + "pandas", + "numpy", + "pydantic", + "scipy", + "statsmodels", + # Directly drives calendar/session/settlement results (holidays, + # sessions, closures) -- a version bump can change backtest output the + # same way a pandas/numpy bump can, so it belongs in provenance too. + "pandas-market-calendars", +) def _git_commit_hash() -> str | None: @@ -109,67 +141,348 @@ def _dependency_versions() -> dict[str, str]: return versions -#: Cached source hash and the fingerprint used to validate it. -_source_hash_fingerprint: tuple[tuple[str, int], ...] | None = None -_source_hash_value: str | None = None -_source_hash_computed_at: float | None = None +#: Cached hashes and the fingerprints used to validate each, keyed by which +#: `_hash_source_tree()` caller computed them ("source" / "generator"). +_source_hash_cache: dict[str, tuple[tuple[tuple[str, int], ...], str, float]] = {} #: Maximum cache lifetime when file mtimes appear unchanged. _SOURCE_HASH_TTL_SECONDS = 60.0 +#: Never part of either hash: the dashboard UI is imported by neither a +#: notebook cell, the computational backtest path, nor CLI orchestration. +_DASHBOARD_TOP_LEVEL_PART = "dashboard" -#: Excluded from `_source_hash()`: neither the dashboard UI nor the CLI -#: entry point is imported by any notebook cell or by the computational -#: backtest path, so editing them would otherwise force spurious notebook -#: rebuilds and spuriously invalidate walk-forward artifact reuse. -_SOURCE_HASH_EXCLUDED_TOP_LEVEL_PARTS = frozenset({"dashboard"}) -_SOURCE_HASH_EXCLUDED_FILES = frozenset({"cli.py"}) +def _hash_source_tree( + *, cache_key: str, excluded_files: frozenset[str] = frozenset() +) -> str: + r"""Return a SHA-256 hash of a scoped subset of QuantLab's Python sources. -def _source_hash() -> str: - r"""Return a SHA-256 hash of QuantLab's installed Python sources. - - Scoped to the modules that actually affect computed results (excludes - `dashboard/` and `cli.py`; see `_SOURCE_HASH_EXCLUDED_TOP_LEVEL_PARTS` - and `_SOURCE_HASH_EXCLUDED_FILES`). POSIX relative paths keep the hash - platform-independent. A path/mtime fingerprint avoids rereading - unchanged files, while a short TTL bounds staleness when a - synchronisation tool preserves mtimes. + Always excludes `dashboard/` (see `_DASHBOARD_TOP_LEVEL_PART`); callers + additionally exclude specific files via ``excluded_files``. POSIX + relative paths keep the hash platform-independent. A path/mtime + fingerprint avoids rereading unchanged files, while a short TTL bounds + staleness when a synchronisation tool preserves mtimes. ``cache_key`` + keeps this cache and the differently-scoped one(s) other callers use + from colliding. """ - global _source_hash_fingerprint, _source_hash_value, _source_hash_computed_at root = Path(__file__).resolve().parents[1] paths = sorted( path for path in root.rglob("*.py") - if path.relative_to(root).parts[0] not in _SOURCE_HASH_EXCLUDED_TOP_LEVEL_PARTS - and path.relative_to(root).name not in _SOURCE_HASH_EXCLUDED_FILES + if path.relative_to(root).parts[0] != _DASHBOARD_TOP_LEVEL_PART + and path.relative_to(root).name not in excluded_files ) fingerprint = tuple( (path.relative_to(root).as_posix(), path.stat().st_mtime_ns) for path in paths ) now = time.monotonic() - ttl_expired = ( - _source_hash_computed_at is None - or now - _source_hash_computed_at >= _SOURCE_HASH_TTL_SECONDS - ) + cached = _source_hash_cache.get(cache_key) if ( - not ttl_expired - and fingerprint == _source_hash_fingerprint - and _source_hash_value is not None + cached is not None + and now - cached[2] < _SOURCE_HASH_TTL_SECONDS + and fingerprint == cached[0] ): - return _source_hash_value + return cached[1] digest = hashlib.sha256() for path in paths: digest.update(path.relative_to(root).as_posix().encode("utf-8")) digest.update(path.read_bytes()) - _source_hash_fingerprint = fingerprint - _source_hash_computed_at = now - _source_hash_value = digest.hexdigest() - return _source_hash_value + value = digest.hexdigest() + _source_hash_cache[cache_key] = (fingerprint, value, now) + return value + + +def _source_hash() -> str: + """Return a hash scoped to the modules that affect *computed results*. + + Excludes `dashboard/` and `cli.py` -- editing either changes nothing a + notebook or a plain backtest computes, so this must stay stable across + such edits: recorded as ``code_hash`` for informational/reproducibility + purposes, and compared against a notebook's own stored ``code_hash`` to + decide whether it needs rebuilding (see ``scripts/build_notebooks.py``, + ``tests/unit/test_notebooks.py``). Never use this to gate reuse of a + saved *artifact bundle* (walk-forward CSVs, robustness CSVs, a + checkpoint) -- that's what `_generator_hash()` is for. + """ + return _hash_source_tree(cache_key="source", excluded_files=frozenset({"cli.py"})) + + +#: Outside src/quantlab/ entirely (never reached by `_hash_source_tree`'s own +#: rglob), but this script makes the exact same save/reuse decision as +#: `cli.py` (see its own module docstring: "Compatible walk-forward +#: artefacts from an earlier run are reused only when ... provenance checks +#: still pass") -- must be covered by `_generator_hash()` for the same +#: reason `cli.py` itself is. +_GENERATOR_SCRIPT = ( + Path(__file__).resolve().parents[3] / "scripts" / "generate_report.py" +) + + +def _generator_hash() -> str: + """Return a hash scoped to everything that can affect a *saved bundle*. + + Unlike `_source_hash()`, includes `cli.py`: the CLI orchestrates how a + computed result becomes the files on disk (which CSVs get written, how + they're assembled, how reuse itself is decided) -- an unchanged + `_source_hash()` does not guarantee an unchanged bundle if only that + orchestration logic changed. Used wherever a decision reuses or resumes + a previously *saved* artifact rather than merely reporting provenance: + `quantlab.backtesting.result.load_previous_walk_forward_robustness`, + `load_previous_robustness_artifacts`, and + `quantlab.validation.checkpoint.compute_provenance`. + + Also folds in `_GENERATOR_SCRIPT`'s own content: it lives outside + `src/quantlab/` entirely, so `_hash_source_tree`'s scan can never reach + it on its own. Silently omitted (not an error) when absent -- e.g. an + installed wheel that doesn't bundle dev-only `scripts/`. + """ + tree_hash = _hash_source_tree(cache_key="generator") + digest = hashlib.sha256(tree_hash.encode("utf-8")) + if _GENERATOR_SCRIPT.is_file(): + digest.update(_GENERATOR_SCRIPT.read_bytes()) + return digest.hexdigest() + + +def _qualified_class_name(instance: object) -> str: + """Exact class identity (module + qualname), for verification. + + Distinguishes a subclass that overrides behaviour (e.g. a custom + CommissionModel subclass that always charges zero despite reporting the + same ``commission_bps``, or a strategy subclass that overrides signal + generation without changing any constructor parameter) from the exact + class ``config.yaml`` alone would build. Neither an ``isinstance`` check + nor a friendly type-family label (``"constant"`` vs ``"volume"``) can + tell such a subclass apart from its base class -- both pass identically, + silently missing the override -- but this always can. + """ + cls = type(instance) + return f"{cls.__module__}.{cls.__qualname__}" + + +def _hash_adv(adv: pd.DataFrame | float | None) -> str: + """Deterministic identity for a volume-based slippage model's ADV. + + A DataFrame is hashed via the same content hash already used for data + provenance elsewhere (``ParquetStorage.hash_frame``); a scalar or + ``None`` is hashed via its own repr. Either way this is compact and + deterministic, unlike embedding the whole ADV matrix into + metadata.json -- but still lets two differently-built ADV arrays (e.g. + a manipulated or stale one smuggled in via a custom ``ExecutionModel``) + be told apart for ``config_yaml_reflects_execution``. + """ + if isinstance(adv, pd.DataFrame): + return ParquetStorage.hash_frame(adv) + return hashlib.sha256(repr(adv).encode("utf-8")).hexdigest() + + +def _describe_slippage(model: SlippageModel) -> dict[str, object]: + """Describe a slippage model's own parameters, for metadata/reporting. + + Introspects the actual instance rather than ``config.execution``, for + the same reason ``_build_metadata`` reads commission/spread from the + real ``ExecutionModel``: a custom slippage model passed directly to + :class:`BacktestEngine` need not match the YAML-configured one. + ``slippage_class`` (exact class identity, see + :func:`_qualified_class_name`) is always included, even for a + recognised base class, so a subclass overriding behaviour without + changing any reported parameter is still distinguishable -- the + friendly ``slippage_model`` label alone (``"constant"``/``"volume"``) + passes identically for such a subclass, via ``isinstance``. + """ + identity = {"slippage_class": _qualified_class_name(model)} + if isinstance(model, ConstantSlippageModel): + return { + **identity, + "slippage_model": "constant", + "slippage_bps": model.slippage_bps, + } + if isinstance(model, VolumeBasedSlippageModel): + return { + **identity, + "slippage_model": "volume", + "slippage_bps": model.base_slippage_bps, + "impact_coefficient": model.impact_coefficient, + "average_daily_volume_hash": _hash_adv(model.average_daily_volume), + } + return {**identity, "slippage_model": type(model).__name__} + + +def _effective_component_parameters(instance: object) -> tuple[dict[str, object], bool]: + """Best-effort snapshot of a component's *actual* constructor values. + + docs/api.md documents using ``BacktestEngine`` directly with a custom + strategy/allocator instance -- ``config.yaml`` in the saved bundle is + still whatever ``ExperimentConfig`` the caller happened to pass + alongside it, which need not match the object actually used (e.g. a + strategy built with ``lookback_period=10`` passed alongside a config + whose own ``strategy.parameters.lookback_period`` says 252). This + mirrors ``strategy_parameter_names()``'s introspection of + ``__init__``'s signature, then reads each named parameter back off the + instance as an attribute -- the convention every built-in strategy/ + allocator follows. Only JSON-safe scalars are kept: a custom component + could store anything under a matching attribute name (e.g. a whole + ``average_daily_volume`` DataFrame), and dumping that into + metadata.json would be unserialisable or enormous rather than useful. + + Returns the best-effort snapshot, plus whether *every* constructor + parameter could actually be captured. A parameter with no matching + attribute, or a non-scalar value, is omitted from the snapshot -- and + makes the second return value ``False``. A caller comparing two + snapshots for verification purposes must treat ``False`` as "unverified + entirely", never silently pass on whatever subset happened to match: + two different uncaptured values (e.g. two different callables, or two + different DataFrames) would otherwise compare as equal simply because + neither made it into the dict. + """ + try: + signature = inspect.signature(type(instance).__init__) + except (TypeError, ValueError): + return {}, False + values: dict[str, object] = {} + fully_captured = True + for parameter in signature.parameters.values(): + if parameter.name == "self" or parameter.kind in ( + parameter.VAR_POSITIONAL, + parameter.VAR_KEYWORD, + ): + continue + if not hasattr(instance, parameter.name): + fully_captured = False + continue + value = getattr(instance, parameter.name) + if value is None or isinstance(value, (bool, int, float, str)): + values[parameter.name] = value + else: + fully_captured = False + return values, fully_captured + + +def _reference_strategy(config: ExperimentConfig) -> BaseStrategy | None: + """Best-effort reconstruction of the strategy ``config`` alone would build. + + Mirrors :func:`~quantlab.backtesting.runner.build_strategy_from_config` + (duplicated rather than imported: :mod:`quantlab.backtesting.runner` + itself imports :class:`BacktestEngine` from this module, so importing it + back here would create a cycle). Returns ``None`` rather than raising + when construction fails -- an unbuildable reference is "not verified", + never fabricated into a false positive or negative. + """ + parameters = dict(config.strategy_parameters) + accepted = strategy_parameter_names(config.strategy_name) + if "periods_per_year" in accepted and "periods_per_year" not in parameters: + parameters["periods_per_year"] = config.periods_per_year + try: + return build_strategy(config.strategy_name, parameters) + except QuantLabError: + return None + + +def _reference_allocator(config: ExperimentConfig) -> PortfolioAllocator | None: + """Best-effort reconstruction of the allocator ``config`` alone would build. + + Mirrors :func:`~quantlab.backtesting.runner.build_allocator_from_config`, + duplicated for the same import-cycle reason as :func:`_reference_strategy`. + """ + name = config.portfolio.allocator + kwargs: dict[str, object] = {} + if name == "inverse_volatility": + kwargs = { + "volatility_window": config.portfolio.volatility_window, + "maximum_weight": config.portfolio.maximum_weight, + "periods_per_year": config.periods_per_year, + } + elif name == "volatility_targeting": + if config.portfolio.target_volatility is None: + return None + kwargs = { + "target_volatility": config.portfolio.target_volatility, + "volatility_window": config.portfolio.volatility_window, + "maximum_leverage": config.portfolio.maximum_leverage, + "periods_per_year": config.periods_per_year, + } + try: + return build_allocator(name, **kwargs) + except QuantLabError: + return None + + +def _reference_execution_model( + config: ExperimentConfig, data: pd.DataFrame +) -> ExecutionModel | None: + """Best-effort reconstruction of the execution model ``config`` alone would build. + + Mirrors :func:`~quantlab.backtesting.runner.build_execution_from_config`, + duplicated for the same import-cycle reason as :func:`_reference_strategy`. + Unlike that function's simple, config-only construction, this one also + operates on ``data`` (pivoting, rolling ADV) for volume-based slippage -- + a runtime DataFrame whose shape isn't guaranteed by config validation the + way ``config.strategy``/``config.portfolio`` are, so a broad ``except + Exception`` (not just ``QuantLabError``) is deliberate: this is a + best-effort verification a direct-API caller's own custom ``data`` slice + must never be able to crash, only leave "unverified". + """ + try: + adv: pd.DataFrame | float | None = None + if config.execution.slippage_model.lower() in {"volume", "volume_based"}: + shares = volume_matrix(data) + price = price_matrix(data, adjusted=False) + bar_dollar_volume = shares * price + calendar = uniform_calendar( + instrument.calendar for instrument in config.data.instruments + ) + market_is_247 = calendar is not None and is_247(calendar) + frequency_table = ( + CRYPTO_FREQUENCY_TO_PERIODS_PER_YEAR + if market_is_247 + else FREQUENCY_TO_PERIODS_PER_YEAR + ) + days_per_year = ( + CALENDAR_DAYS_PER_YEAR if market_is_247 else TRADING_DAYS_PER_YEAR + ) + bars_per_day = frequency_table[str(config.frequency)] / days_per_year + window = max(1, round(21 * bars_per_day)) + adv = ( + bar_dollar_volume.rolling(window, min_periods=1).mean().shift(1) + * bars_per_day + ) + return ExecutionModel.from_config(config.execution, average_daily_volume=adv) + except Exception: + return None + + +def _effective_execution_summary(model: ExecutionModel) -> dict[str, object]: + """Return the same commission/spread/slippage snapshot recorded in metadata. + + A single dict makes the real object and a rebuilt reference directly + comparable with ``==``, the same pattern + ``config_yaml_reflects_strategy``/``config_yaml_reflects_allocator`` use. + Includes ``commission_class``/``spread_class`` (exact class identity, + see :func:`_qualified_class_name`), not just ``commission_bps``/ + ``spread_bps``: a commission/spread subclass overriding the actual cost + calculation while still reporting the same bps value would otherwise + compare as an identical match. + """ + return { + "commission_class": _qualified_class_name(model.commission), + "commission_bps": model.commission.commission_bps, + "spread_class": _qualified_class_name(model.spread), + "spread_bps": model.spread.spread_bps, + **_describe_slippage(model.slippage), + } class BacktestEngine: - """Vectorised, look-ahead-safe backtest engine.""" + """Vectorised backtest engine with a delayed-execution barrier. + + Weights are always shifted before returns are computed (see ``run``'s + step 7), preventing the common look-ahead leak of acting on a signal the + same period it was formed. This does not, by itself, make an arbitrary + custom strategy leak-free: a strategy that reads future rows out of + ``data`` directly, or otherwise builds a signal non-causally, is outside + what this barrier can catch -- causal feature and signal construction + remains the strategy's own responsibility. + """ def run( self, @@ -275,14 +588,48 @@ def run( constrained = constraints.apply(target_weights) # Apply the shared stateful rebalancing/turnover pipeline once over - # the full index so its state remains continuous. - held_weights = rebalance_and_cap_turnover(constrained, config.portfolio) + # the full index so its state remains continuous. A closed symbol + # (per its own calendar) never trades that date -- only meaningful at + # daily granularity, see quantlab.data.closures. Only bother computing + # a mask when the instruments actually span more than one calendar: + # for a single-calendar experiment this must be a provable no-op + # (tradable=None, byte-identical to a raw schedule/turnover-cap run + # with no tradability awareness at all), since a calendar library's + # real holiday set need not match every quirk of whatever data + # happens to be loaded for a lone calendar. + tradable = None + symbol_calendars = { + instrument.symbol: instrument.calendar + for instrument in config.data.instruments + } + shared_calendar = uniform_calendar(symbol_calendars.values()) + if config.data.frequency == DAILY_FREQUENCY and shared_calendar is None: + tradable = tradable_mask_for( + pd.DatetimeIndex(prices.index), config.symbols, symbol_calendars + ) + held_weights = rebalance_and_cap_turnover( + constrained, config.portfolio, tradable=tradable, calendar=shared_calendar + ) if delay > 0: - held_weights = held_weights.shift(delay).fillna(0.0) + if tradable is not None: + # A raw row-count shift would delay execution onto a date a + # symbol can't actually trade on (see + # shift_respecting_tradability's docstring) -- exactly the + # same bug the mandatory look-ahead-barrier shift below + # avoids, so the extra configured delay must avoid it too. + held_weights = shift_respecting_tradability( + held_weights, delay, tradable + ).fillna(0.0) + else: + held_weights = held_weights.shift(delay).fillna(0.0) # Accounting contains the one-period look-ahead barrier. accounting = run_accounting( - held_weights, asset_returns, execution_model, config.initial_capital + held_weights, + asset_returns, + execution_model, + config.initial_capital, + tradable=tradable, ) # Align the benchmark to the simulated portfolio dates. @@ -293,21 +640,28 @@ def run( benchmark_data, pd.DatetimeIndex(prices.index), benchmark_symbol=config.benchmark_symbol, + benchmark_calendar=config.benchmark_calendar, first_asset_symbol=config.symbols[0], risk_free_rate=config.backtest.risk_free_rate, periods_per_year=config.periods_per_year, kind=str(config.benchmark_kind), ) - # Reuse accounting's slippage model and cost-sizing equity so per-fill - # costs match the aggregate costs already charged. + # The actually-supplied execution_model is the single source of truth + # for what was charged -- not config.execution, which merely + # describes the YAML default and can legitimately differ when a + # caller uses BacktestEngine directly with a custom ExecutionModel + # (see docs/api.md's "Extension points"). Accounting already used + # this exact model; the trade log's per-fill breakdown must agree + # with it too, or the equity curve, trade log and report could each + # describe a different reality. trades = build_trade_log( accounting.executed_weights, accounting.weight_changes, accounting.equity, price_matrix(tradable_data, adjusted=False), - commission_bps=config.commission_bps, - spread_bps=config.spread_bps, + commission_bps=execution_model.commission.commission_bps, + spread_bps=execution_model.spread.spread_bps, slippage_model=execution_model.slippage, slippage_equity=accounting.equity_for_costs, ) @@ -320,7 +674,9 @@ def run( risk_free_rate=config.backtest.risk_free_rate, periods_per_year=config.periods_per_year, ) - metrics.update(self._portfolio_metrics(accounting, config.periods_per_year)) + metrics.update( + portfolio_metrics_from_accounting(accounting, config.periods_per_year) + ) metrics["number_of_trades"] = float(len(trades)) metrics["average_trade_size"] = ( float(trades["traded_notional"].mean()) if len(trades) else 0.0 @@ -351,35 +707,28 @@ def run( costs=accounting.costs.to_frame(), metrics=metrics, metadata=self._build_metadata( - config, tradable_data, calculation_elapsed, data + config, + tradable_data, + calculation_elapsed, + data, + strategy, + allocator, + execution_model, ), gross_returns=accounting.gross_returns, gross_equity=accounting.gross_equity, turnover=accounting.turnover, ) - @staticmethod - def _portfolio_metrics( - accounting: AccountingResult, periods_per_year: int - ) -> dict[str, float]: - """Exposure and turnover metrics.""" - turnover = accounting.turnover - return { - "annual_turnover": float(turnover.mean() * periods_per_year) - if len(turnover) - else 0.0, - "average_gross_exposure": average_gross_exposure( - accounting.executed_weights - ), - "average_net_exposure": average_net_exposure(accounting.executed_weights), - } - @staticmethod def _build_metadata( config: ExperimentConfig, tradable_data: pd.DataFrame, calculation_elapsed: float, full_data: pd.DataFrame, + strategy: BaseStrategy, + allocator: PortfolioAllocator, + execution_model: ExecutionModel, ) -> dict[str, object]: """Build metadata used to compare and audit runs. @@ -388,11 +737,95 @@ def _build_metadata( versions detect differences but do not recreate a full environment. ``elapsed_seconds`` measures calculation through metrics; metadata hashing and result serialisation are excluded. + + ``strategy``/``allocator``/``execution_model`` are read from the + objects actually passed to :meth:`run`, not from ``config`` -- + docs/api.md documents using :class:`BacktestEngine` directly with a + custom strategy, allocator or execution-model instance, which need + not match ``config``'s own YAML-derived settings. Recording + ``config``'s values here instead would let accounting (which always + uses the real objects), the trade log and this metadata each + describe a different reality for the exact same run. + + ``strategy_parameters``/``allocator_parameters`` are the same kind + of best-effort actual-object snapshot (see + ``_effective_component_parameters``), covering what commission/ + spread/slippage don't: `config.yaml` in the saved bundle is still + whatever config the caller passed, which may not match the real + object -- not only via a declared value (e.g. a config saying + ``lookback_period: 252`` alongside a strategy actually built with + ``lookback_period=10``), but also via an *undeclared* parameter + left at its constructor default (e.g. the config never mentions + ``lookback_period`` at all, defaulting it to 20, while the real + object was built with 10 -- comparing only declared keys would miss + this entirely, since the mismatched key is never even examined). + ``config_yaml_reflects_strategy``/``config_yaml_reflects_allocator``/ + ``config_yaml_reflects_execution`` each compare the *complete* + effective parameter set -- plus the exact class identity, see + ``_qualified_class_name`` -- against a reference object rebuilt from + ``config`` alone (mirroring the same factory each ordinary CLI/ + dashboard run uses, see ``_reference_strategy``/ + ``_reference_allocator``/``_reference_execution_model``). A subclass + that overrides behaviour without changing any reported parameter + (e.g. a strategy subclass that always stays in cash, or a + commission subclass that always charges zero) is caught by the + class-identity check even when every parameter still matches. A + reference that cannot even be built, or whose parameters -- or the + real object's own -- could not be *fully* captured (see + ``_effective_component_parameters``'s second return value) counts + as unverified, never as a silent pass on a partial match. A report + claiming the whole run is reproducible from config.yaml must + require all three (see ``render_html_report``'s footer). """ + strategy_parameters, strategy_captured = _effective_component_parameters( + strategy + ) + reference_strategy = _reference_strategy(config) + config_yaml_reflects_strategy = False + if reference_strategy is not None: + reference_strategy_parameters, reference_captured = ( + _effective_component_parameters(reference_strategy) + ) + config_yaml_reflects_strategy = ( + strategy_captured + and reference_captured + and _qualified_class_name(strategy) + == _qualified_class_name(reference_strategy) + and strategy_parameters == reference_strategy_parameters + ) + allocator_parameters, allocator_captured = _effective_component_parameters( + allocator + ) + reference_allocator = _reference_allocator(config) + config_yaml_reflects_allocator = False + if reference_allocator is not None: + reference_allocator_parameters, reference_allocator_captured = ( + _effective_component_parameters(reference_allocator) + ) + config_yaml_reflects_allocator = ( + allocator_captured + and reference_allocator_captured + and _qualified_class_name(allocator) + == _qualified_class_name(reference_allocator) + and allocator_parameters == reference_allocator_parameters + ) + execution_effective = _effective_execution_summary(execution_model) + reference_execution = _reference_execution_model(config, full_data) + config_yaml_reflects_execution = ( + reference_execution is not None + and execution_effective == _effective_execution_summary(reference_execution) + ) return { "run_timestamp": datetime.now(UTC).isoformat(), "experiment_name": config.experiment_name, - "strategy": config.strategy_name, + "strategy": strategy.name, + "strategy_parameters": strategy_parameters, + "config_yaml_reflects_strategy": config_yaml_reflects_strategy, + "allocator": allocator.name, + "allocator_parameters": allocator_parameters, + "config_yaml_reflects_allocator": config_yaml_reflects_allocator, + "config_yaml_reflects_execution": config_yaml_reflects_execution, + **execution_effective, "symbols": config.symbols, "start_date": str(config.start_date), "end_date": str(config.end_date), @@ -405,4 +838,5 @@ def _build_metadata( "git_dirty": _git_is_dirty(), "dependency_versions": _dependency_versions(), "code_hash": _source_hash(), + "generator_hash": _generator_hash(), } diff --git a/src/quantlab/backtesting/result.py b/src/quantlab/backtesting/result.py index 8a9160f..4652117 100644 --- a/src/quantlab/backtesting/result.py +++ b/src/quantlab/backtesting/result.py @@ -41,6 +41,9 @@ "walk_forward_oos_returns.csv", "walk_forward_oos_equity.csv", "stress_tests.csv", + "bootstrap_summary.csv", + "permutation_test.csv", + "sensitivity.csv", ) _SAVE_IN_PROGRESS_MARKER = ".quantlab-save-in-progress" @@ -50,9 +53,36 @@ "walk_forward_oos_returns.csv": True, "walk_forward_oos_equity.csv": True, "stress_tests.csv": False, + "bootstrap_summary.csv": False, + "permutation_test.csv": False, + "sensitivity.csv": False, } _VALIDATION_ARTIFACTS = frozenset(_VALIDATION_ARTIFACT_INDEX) +#: The four on-demand robustness techniques, each normally run and saved by +#: its own separate CLI command — the CSV filename each one's `robustness` +#: dict key round-trips through, used by `load_previous_robustness_artifacts` +#: to recover what a sibling command already saved. +_ROBUSTNESS_ARTIFACT_FILES: dict[str, str] = { + "stress_tests": "stress_tests.csv", + "bootstrap": "bootstrap_summary.csv", + "permutation_test": "permutation_test.csv", + "sensitivity": "sensitivity.csv", +} + +#: The subset of `_ROBUSTNESS_ARTIFACT_FILES` keys whose CLI command also +#: records its own effective run parameters (n_iterations/block_size/etc., +#: including any CLI override) in `metadata.json` -- stress-test has no +#: such override, so it has no entry here. Used by +#: `load_previous_robustness_artifacts` to recover a sibling command's +#: parameters alongside its CSV, not just the numbers with no record of +#: what produced them. +_ROBUSTNESS_RUN_PARAMS_KEYS: dict[str, str] = { + "bootstrap": "bootstrap_run_params", + "permutation_test": "permutation_test_run_params", + "sensitivity": "sensitivity_run_params", +} + def _bundle_lock_path(output_directory: Path) -> Path: """Return the persistent sibling lock used to serialize bundle saves.""" @@ -280,9 +310,13 @@ def _merged_robustness( holdout_meta["validation_period"], ) ) + # Labeled plainly "Test", not "out-of-sample": whether it's + # genuinely OOS depends on parameters having been fixed before + # looking at it, a property of the user's workflow this table + # can't verify (see quantlab.validation.holdout's module docstring). blocks.append( ( - "Test (out-of-sample)", + "Test", holdout_meta["test_metrics"], holdout_meta["test_period"], ) @@ -330,7 +364,11 @@ def save( already verified a file left by a *different* command still describes this exact config/result (e.g. ``quantlab report`` reusing a still-valid prior ``walk-forward`` run's CSVs) and - will not be rewriting it itself this call. + will not be rewriting it itself this call. Prefer + :func:`save_with_walk_forward_reuse` or + :func:`save_with_robustness_reuse` over passing this + directly — both already implement the provenance check this + parameter exists to make safe. validation_artifacts: Walk-forward and stress-test CSV values to write as part of this save. Their checksums are added to the metadata only after the atomic file replacements succeed. @@ -445,11 +483,18 @@ def _save_locked( out / name, index=_VALIDATION_ARTIFACT_INDEX[name], ) - if validation_artifacts: - self.metadata["walk_forward_csv_checksums"] = { - name: hashlib.sha256((out / name).read_bytes()).hexdigest() - for name in validation_artifacts - } + # Recomputed from whatever _VALIDATION_ARTIFACTS files actually exist + # in `out` now (freshly written above, or kept as-is via + # keep_artifacts), never merged with whatever this call started + # with -- otherwise a save that legitimately drops an artefact (not + # re-supplied and not kept) would leave a stale checksum in + # metadata.json for a file the pre-save cleanup above just deleted, + # even though nothing currently on disk matches it any more. + self.metadata["walk_forward_csv_checksums"] = { + name: hashlib.sha256((out / name).read_bytes()).hexdigest() + for name in _VALIDATION_ARTIFACTS + if (out / name).is_file() + } # Render once, then reuse the same images on disk and in the HTML. self.save_warnings = [] @@ -488,6 +533,20 @@ def _save_locked( logger.warning(msg) self.save_warnings.append(msg) + # Explicit, persisted methodology marker: different CLI commands in + # walk-forward mode save fundamentally different `self` objects to + # the same experiment directory -- `quantlab walk-forward`'s own + # `report` handler saves a full-sample result with OOS evidence + # only attached as metadata, while `stress-test`/`bootstrap`/ + # `permutation`/`sensitivity`/`robustness` save the OOS-stitched + # result itself (`wf.oos_result`) -- so metrics.json/metadata.json + # can mean two different things depending on which command ran + # last. Recording which one `self.metrics` actually is removes the + # ambiguity for anyone reading the bundle later, without needing to + # know the CLI's own save conventions. + from quantlab.reporting.research_summary import out_of_sample_scope + + self.metadata["result_scope"] = out_of_sample_scope(self) or "full_sample" self.metadata["save_warnings"] = self.save_warnings _write_text_atomic( out / "metrics.json", @@ -513,14 +572,46 @@ def _save_locked( return out +def _load_metadata_json(metadata_path: Path, *, exp_dir: Path) -> dict[str, Any] | None: + """Return a prior bundle's parsed ``metadata.json``, or ``None`` to refuse reuse. + + A hand-edited or partially-written ``metadata.json`` must never crash + reuse detection with a raw ``json.JSONDecodeError`` -- malformed + metadata is exactly the case reuse must refuse, the same as a missing + file or a mismatched config/data/code hash. + """ + try: + return dict(json.loads(metadata_path.read_text(encoding="utf-8"))) + except (OSError, UnicodeError, json.JSONDecodeError, ValueError) as exc: + logger.warning( + "Not reusing prior metadata in %s: %s could not be parsed as " + "valid JSON (%s).", + exp_dir, + metadata_path.name, + exc, + ) + return None + + def load_previous_walk_forward_robustness( exp_dir: Path, result: BacktestResult ) -> dict[str, Any] | None: """Load prior walk-forward tables only when their provenance still matches. - Configuration, data, source, dependencies and available Git identity are - compared before reuse. Required CSVs must exist and match any recorded - checksums; otherwise the function logs why and returns ``None``. + Provenance is config + data_hash + generator_hash + dependency_versions, + not git_dirty/git_commit -- same reasoning as + `load_previous_robustness_artifacts`: `generator_hash` already hashes + current file contents, uncommitted changes included, so it alone gives + the guarantee needed here. A separate git_dirty/git_commit gate on top + would be strictly redundant once generator_hash matches, and actively + wrong: `git status`/`git_dirty` cover the *whole* repository, not just + the files generator_hash is scoped to, so an unrelated uncommitted + change elsewhere (docs, configs, tests, ...) would refuse a `report` + regeneration even though the exact same generator code, config and data + produced it -- exactly the ordinarily-uncommitted development session + this reuse mechanism exists to serve. Required CSVs must exist and + match any recorded checksums; otherwise the function logs why and + returns ``None``. """ save_marker = exp_dir / _SAVE_IN_PROGRESS_MARKER if save_marker.exists() or save_marker.is_symlink(): @@ -535,8 +626,8 @@ def load_previous_walk_forward_robustness( metadata_path = exp_dir / "metadata.json" if not metadata_path.is_file(): return None - old_metadata = json.loads(metadata_path.read_text(encoding="utf-8")) - if "walk_forward_oos_metrics" not in old_metadata: + old_metadata = _load_metadata_json(metadata_path, exp_dir=exp_dir) + if old_metadata is None or "walk_forward_oos_metrics" not in old_metadata: return None old_snapshot = old_metadata.get("walk_forward_config_snapshot") @@ -561,38 +652,24 @@ def load_previous_walk_forward_robustness( ) return None - old_code_hash = old_metadata.get("code_hash") - new_code_hash = result.metadata.get("code_hash") - if old_code_hash is None or old_code_hash != new_code_hash: + # generator_hash, not code_hash: this gates reuse of a *saved bundle* + # (walk-forward CSVs/metadata), so it must also catch a change to the + # CLI's own orchestration of how that bundle gets assembled or reused + # -- code_hash deliberately excludes cli.py (see + # `quantlab.backtesting.engine._source_hash`'s docstring) and would + # miss exactly that. + old_generator_hash = old_metadata.get("generator_hash") + new_generator_hash = result.metadata.get("generator_hash") + if old_generator_hash is None or old_generator_hash != new_generator_hash: logger.warning( "Not reusing walk-forward metadata for %s: the quantlab source " "code that produced it no longer matches the source code used " - "to regenerate this report (code_hash differs or is missing), " - "even though the config and data are unchanged.", + "to regenerate this report (generator_hash differs or is " + "missing), even though the config and data are unchanged.", exp_dir, ) return None - if old_metadata.get("git_dirty") or result.metadata.get("git_dirty"): - logger.warning( - "Not reusing walk-forward metadata for %s: the working tree was " - "dirty at walk-forward time, at report time, or both — a commit " - "hash comparison can't be trusted when uncommitted changes may " - "not be reflected in it.", - exp_dir, - ) - return None - old_commit = old_metadata.get("git_commit") - new_commit = result.metadata.get("git_commit") - if old_commit is not None and new_commit is not None and old_commit != new_commit: - logger.warning( - "Not reusing walk-forward metadata for %s: the code that " - "produced it no longer matches the code used to regenerate this " - "report (git_commit differs), even though the config and data " - "are unchanged.", - exp_dir, - ) - return None old_deps = old_metadata.get("dependency_versions") new_deps = result.metadata.get("dependency_versions") if old_deps is None or old_deps != new_deps: @@ -618,32 +695,42 @@ def load_previous_walk_forward_robustness( ) return None - # Checksums detect edits or corruption after the original run. + # Checksums detect edits or corruption after the original run. Recorded + # unconditionally alongside walk_forward_oos_metrics at every save (see + # save()), so their absence here is itself a red flag -- an incomplete + # or tampered metadata.json -- not a free pass to skip verification. old_checksums = old_metadata.get("walk_forward_csv_checksums") + if not old_checksums: + logger.warning( + "Not reusing walk-forward metadata for %s: no CSV checksums " + "were recorded, so the required artefacts' integrity can't be " + "verified before reuse.", + exp_dir, + ) + return None stress_path = exp_dir / "stress_tests.csv" # Stress results are optional but checked when present. checksummed = [*required, stress_path] if stress_path.is_file() else required - if old_checksums: - # A recorded stress checksum means the file existed originally. - if stress_path.name in old_checksums and not stress_path.is_file(): + # A recorded stress checksum means the file existed originally. + if stress_path.name in old_checksums and not stress_path.is_file(): + logger.warning( + "Not reusing walk-forward metadata for %s: stress_tests.csv " + "was present when its checksum was recorded but is missing " + "now (the file was deleted since).", + exp_dir, + ) + return None + for path in checksummed: + actual = hashlib.sha256(path.read_bytes()).hexdigest() + if old_checksums.get(path.name) != actual: logger.warning( - "Not reusing walk-forward metadata for %s: stress_tests.csv " - "was present when its checksum was recorded but is missing " - "now (the file was deleted since).", + "Not reusing walk-forward metadata for %s: %s no longer " + "matches the checksum recorded at walk-forward time " + "(the file was modified or corrupted on disk since).", exp_dir, + path.name, ) return None - for path in checksummed: - actual = hashlib.sha256(path.read_bytes()).hexdigest() - if old_checksums.get(path.name) != actual: - logger.warning( - "Not reusing walk-forward metadata for %s: %s no longer " - "matches the checksum recorded at walk-forward time " - "(the file was modified or corrupted on disk since).", - exp_dir, - path.name, - ) - return None result.metadata["walk_forward_oos_metrics"] = old_metadata[ "walk_forward_oos_metrics" @@ -677,7 +764,15 @@ def load_previous_walk_forward_robustness( def save_with_walk_forward_reuse(result: BacktestResult, exp_dir: str | Path) -> Path: - """Save a result while preserving compatible walk-forward artefacts.""" + """Save a result while preserving compatible walk-forward artefacts. + + Also preserves compatible bootstrap/permutation-test/sensitivity + artefacts, exactly like `save_with_robustness_reuse` does for those + commands' own saves -- otherwise `quantlab report` (which calls this, + not that) would delete still-valid evidence a `bootstrap`/ + `permutation-test`/`sensitivity` run had just saved, since neither of + those techniques is itself part of "walk-forward" evidence. + """ exp_dir = Path(exp_dir) exp_dir.mkdir(parents=True, exist_ok=True) # Keep the provenance read and the following save under one lock; otherwise @@ -693,11 +788,220 @@ def save_with_walk_forward_reuse(result: BacktestResult, exp_dir: str | Path) -> } if "stress_tests" in robustness: keep_artifacts.add("stress_tests.csv") + # Sibling on-demand techniques (bootstrap/permutation-test/ + # sensitivity), each saved by its own separate CLI command -- + # `load_previous_walk_forward_robustness` only ever knows about + # walk-forward's own CSVs plus stress_tests, so a technique it + # doesn't recognise (e.g. bootstrap_summary.csv) would otherwise be + # silently deleted by this save's cleanup, even when still valid. + previous_robustness_artifacts = load_previous_robustness_artifacts( + exp_dir, result + ) + # `robustness`'s own keys (from walk-forward reuse above) win on any + # overlap -- same precedence `save_with_robustness_reuse` gives a + # freshly-computed technique over a merely-recovered one. + merged_robustness = {**previous_robustness_artifacts, **(robustness or {})} + validation_artifacts: dict[str, pd.Series | pd.DataFrame] = {} + for key, frame in previous_robustness_artifacts.items(): + filename = _ROBUSTNESS_ARTIFACT_FILES[key] + if filename not in keep_artifacts: + validation_artifacts[filename] = frame return result._save_locked( exp_dir, - robustness=robustness, + robustness=merged_robustness or None, keep_artifacts=keep_artifacts, - validation_artifacts={}, + validation_artifacts=validation_artifacts, + ) + + +def load_previous_robustness_artifacts( + exp_dir: Path, result: BacktestResult +) -> dict[str, Any]: + """Recover prior stress/bootstrap/permutation/sensitivity artefacts. + + Each on-demand robustness technique is run and saved by its own CLI + command; without this, running `stress-test` then `bootstrap` against + the same experiment would silently delete `stress_tests.csv`, since + `result.save()`'s pre-save cleanup removes any `_OPTIONAL_ARTIFACTS` + file the current call doesn't re-supply. Applies to holdout/plain + backtests; walk-forward has its own, longer-lived + `load_previous_walk_forward_robustness`. Callers merge the result under + their own freshly computed values, so a stale entry never survives a + technique actually being recomputed. + + Provenance is config + data_hash + generator_hash + dependency_versions, + not git_dirty/git_commit (unlike `load_previous_walk_forward_robustness`): + `generator_hash` already hashes current file contents including + uncommitted changes, so it alone gives the guarantee needed here, + without refusing reuse in an ordinarily-uncommitted working session. + Uses `generator_hash`, not the narrower `code_hash`, because this CSV + bundle's shape and reuse decision are themselves partly determined by + CLI orchestration code (`code_hash` deliberately excludes `cli.py`; see + `quantlab.backtesting.engine._source_hash`'s docstring). + + Returns an empty dict, rather than raising, whenever provenance can't + be confirmed to still match ``result``. + """ + save_marker = exp_dir / _SAVE_IN_PROGRESS_MARKER + if save_marker.exists() or save_marker.is_symlink(): + logger.warning( + "Not reusing prior robustness artefacts in %s: a prior bundle " + "save did not complete (%s is still present).", + exp_dir, + save_marker.name, + ) + return {} + + metadata_path = exp_dir / "metadata.json" + config_path = exp_dir / "config.yaml" + if not metadata_path.is_file() or not config_path.is_file(): + return {} + old_metadata = _load_metadata_json(metadata_path, exp_dir=exp_dir) + if old_metadata is None: + return {} + + try: + old_config = ExperimentConfig.from_yaml(config_path) + except Exception as exc: + logger.warning( + "Not reusing prior robustness artefacts in %s: %s could not be " + "parsed as a valid config (%s).", + exp_dir, + config_path.name, + exc, + ) + return {} + if old_config.model_dump(mode="json") != result.config.model_dump(mode="json"): + logger.warning( + "Not reusing prior robustness artefacts in %s: the config that " + "produced them no longer matches the config used for this run.", + exp_dir, + ) + return {} + + required_matches = ( + ("data_hash", "the data used to produce them no longer matches this run's"), + ( + "generator_hash", + "the quantlab source code that produced them no longer matches " + "this run's (generator_hash differs or is missing)", + ), + ( + "dependency_versions", + "the dependency versions (numpy/pandas/etc.) that produced them " + "no longer match this run's", + ), + ) + for key, reason in required_matches: + old_value = old_metadata.get(key) + if old_value is None or old_value != result.metadata.get(key): + logger.warning( + "Not reusing prior robustness artefacts in %s: %s.", + exp_dir, + reason, + ) + return {} + + # Checksums detect edits or corruption after the original run. Recorded + # unconditionally for every validation artefact at save time (see + # _save_locked) -- these robustness CSVs go through that same path -- + # so their absence here is itself a red flag, not a free pass to skip + # verification, mirroring load_previous_walk_forward_robustness above. + old_checksums = old_metadata.get("walk_forward_csv_checksums") or {} + recovered: dict[str, Any] = {} + for key, filename in _ROBUSTNESS_ARTIFACT_FILES.items(): + path = exp_dir / filename + if not path.is_file(): + continue + recorded = old_checksums.get(filename) + if recorded is None: + logger.warning( + "Not reusing %s from %s: no checksum was recorded for it, " + "so its integrity can't be verified before reuse.", + filename, + exp_dir, + ) + continue + actual = hashlib.sha256(path.read_bytes()).hexdigest() + if recorded != actual: + logger.warning( + "Not reusing %s from %s: it no longer matches the checksum " + "recorded when it was saved (the file was modified or " + "corrupted on disk since).", + filename, + exp_dir, + ) + continue + try: + recovered[key] = pd.read_csv(path) + except Exception as exc: + logger.warning( + "Not reusing %s from %s: the file could not be read (%s).", + filename, + exp_dir, + exc, + ) + continue + # Recover this technique's own effective run parameters alongside + # its CSV -- without this, e.g. bootstrap_summary.csv could survive + # a later permutation-test save while metadata.json's + # bootstrap_run_params (n_iterations, block_size, including any CLI + # override) silently disappears, leaving the surviving numbers with + # no record of what actually produced them. Never overwrites a key + # already present: when this technique is the one being freshly + # recomputed this run, its own fresh run params (set by the CLI + # command before this call) must win, exactly like `{**previous, + # **robustness}` already lets a fresh DataFrame win over a + # recovered one. + run_params_key = _ROBUSTNESS_RUN_PARAMS_KEYS.get(key) + if ( + run_params_key is not None + and run_params_key in old_metadata + and run_params_key not in result.metadata + ): + result.metadata[run_params_key] = old_metadata[run_params_key] + return recovered + + +def save_with_robustness_reuse( + result: BacktestResult, + exp_dir: str | Path, + *, + robustness: dict[str, Any], + validation_artifacts: Mapping[str, pd.Series | pd.DataFrame] | None = None, +) -> Path: + """Save a result while preserving compatible sibling robustness artefacts. + + Used by each individual robustness CLI command (stress-test, bootstrap, + permutation-test, sensitivity) instead of calling `result.save()` + directly, so that e.g. running `bootstrap` after `stress-test` on the + same experiment directory keeps the earlier stress-test evidence in the + regenerated report instead of silently deleting it. ``robustness`` and + ``validation_artifacts`` are this call's freshly computed results (using + the same `_ROBUSTNESS_ARTIFACT_FILES`/CSV-filename keys); a technique + genuinely being recomputed here always overrides whatever a prior save + left behind for that same technique. + """ + exp_dir = Path(exp_dir) + exp_dir.mkdir(parents=True, exist_ok=True) + new_validation_artifacts = ( + dict(validation_artifacts) if validation_artifacts else {} + ) + # Keep the provenance read and the following save under one lock; otherwise + # another process could replace the reused CSVs between those two steps. + with _locked_bundle(exp_dir): + previous = load_previous_robustness_artifacts(exp_dir, result) + merged_robustness = {**previous, **robustness} + merged_validation_artifacts = dict(new_validation_artifacts) + for key, frame in previous.items(): + filename = _ROBUSTNESS_ARTIFACT_FILES[key] + if filename not in merged_validation_artifacts: + merged_validation_artifacts[filename] = frame + return result._save_locked( + exp_dir, + robustness=merged_robustness or None, + keep_artifacts=set(), + validation_artifacts=merged_validation_artifacts, ) diff --git a/src/quantlab/backtesting/runner.py b/src/quantlab/backtesting/runner.py index 7747893..aa9c8db 100644 --- a/src/quantlab/backtesting/runner.py +++ b/src/quantlab/backtesting/runner.py @@ -20,6 +20,7 @@ TRADING_DAYS_PER_YEAR, ) from quantlab.data.base import price_matrix, volume_matrix +from quantlab.data.calendar import is_247, uniform_calendar from quantlab.data.validator import DataQualityReport from quantlab.execution.execution_model import ExecutionModel from quantlab.portfolio.allocator import PortfolioAllocator, build_allocator @@ -41,8 +42,11 @@ def build_allocator_from_config(config: ExperimentConfig) -> PortfolioAllocator: "periods_per_year": config.periods_per_year, } elif name == "volatility_targeting": + # PortfolioConfig._check_volatility_targeting_requires_target_volatility + # guarantees this is set -- never an implicit default. + assert config.portfolio.target_volatility is not None kwargs = { - "target_volatility": config.portfolio.target_volatility or 0.12, + "target_volatility": config.portfolio.target_volatility, "volatility_window": config.portfolio.volatility_window, "maximum_leverage": config.portfolio.maximum_leverage, "periods_per_year": config.periods_per_year, @@ -72,21 +76,29 @@ def build_execution_from_config( shifted once so a fill never sees its own bar's volume. The configured frequency and market calendar determine the bars per day; an explicit metrics annualisation override does not alter this physical conversion. + + When instruments trade on different calendars, this window falls back to + the equity (252-day, non-24/7) convention — a documented, accepted + approximation, since it only sizes a nominal liquidity window for + volume-based slippage rather than multiplying directly into reported + metrics the way ``periods_per_year`` does. """ adv: pd.DataFrame | float | None = None if config.execution.slippage_model.lower() in {"volume", "volume_based"}: shares = volume_matrix(data) price = price_matrix(data, adjusted=False) bar_dollar_volume = shares * price + calendar = uniform_calendar( + instrument.calendar for instrument in config.data.instruments + ) + market_is_247 = calendar is not None and is_247(calendar) frequency_table = ( CRYPTO_FREQUENCY_TO_PERIODS_PER_YEAR - if config.data.is_247_market + if market_is_247 else FREQUENCY_TO_PERIODS_PER_YEAR ) days_per_year = ( - CALENDAR_DAYS_PER_YEAR - if config.data.is_247_market - else TRADING_DAYS_PER_YEAR + CALENDAR_DAYS_PER_YEAR if market_is_247 else TRADING_DAYS_PER_YEAR ) bars_per_day = frequency_table[str(config.frequency)] / days_per_year window = max(1, round(21 * bars_per_day)) @@ -137,7 +149,7 @@ def run_backtest_from_config( holdout = run_holdout_report(data, config, result) if holdout is not None: - result.metadata["holdout_oos_metrics"] = holdout.test_metrics + result.metadata["holdout_chronological_metrics"] = holdout.test_metrics result.metadata["holdout_report"] = holdout.to_metadata() result.holdout_test_returns = holdout.test_returns result.holdout_test_equity = holdout.test_equity diff --git a/src/quantlab/cli.py b/src/quantlab/cli.py index 429e89c..b5c58f2 100644 --- a/src/quantlab/cli.py +++ b/src/quantlab/cli.py @@ -2,12 +2,24 @@ Commands: - quantlab download --config configs/momentum_sp500.yaml - quantlab backtest --config configs/momentum_sp500.yaml - quantlab walk-forward --config configs/momentum_sp500.yaml - quantlab report --experiment cross_sectional_momentum_etfs + quantlab download --config configs/momentum_sp500.yaml + quantlab backtest --config configs/momentum_sp500.yaml + quantlab walk-forward --config configs/momentum_sp500.yaml + quantlab stress-test --config configs/momentum_sp500.yaml + quantlab bootstrap --config configs/momentum_sp500.yaml + quantlab permutation-test --config configs/momentum_sp500.yaml + quantlab sensitivity --config configs/momentum_sp500.yaml + quantlab robustness --config configs/momentum_sp500.yaml + quantlab report --experiment cross_sectional_momentum_etfs quantlab dashboard +stress-test/bootstrap/permutation-test/sensitivity run one technique each, +applying any matching --n-iterations/--block-size/--param-x etc. override; +robustness runs every robustness.* technique enabled in the config in one +pass, with no CLI overrides. All five branch on validation.method: 'holdout' +(or unset) evaluates a plain backtest, 'walk_forward' re-runs the whole +walk-forward selection process (never a plain backtest standing in for it). + Commands display their main pipeline steps and convert expected QuantLab errors into non-zero process exit codes. Package logs are written to the configured QuantLab log directory. @@ -16,6 +28,7 @@ from __future__ import annotations import sys +from collections.abc import Callable from pathlib import Path, PurePosixPath, PureWindowsPath from typing import TYPE_CHECKING, Any @@ -24,13 +37,17 @@ from quantlab.constants import GENERATED_REPORTS_DIR from quantlab.exceptions import InsufficientDataError, QuantLabError from quantlab.logging_config import configure_logging, get_logger +from quantlab.progress import ProgressReporter if TYPE_CHECKING: # Only for type checking: the CLI otherwise lazy-imports heavy modules # inside each command so `quantlab --help` stays fast. + import pandas as pd + from quantlab.backtesting.result import BacktestResult from quantlab.config import ExperimentConfig from quantlab.data.validator import DataQualityReport + from quantlab.validation.walk_forward import WalkForwardResult app = typer.Typer( add_completion=False, @@ -63,6 +80,34 @@ def _echo_step(message: str) -> None: logger.info(message) +def _make_cli_progress_callback(title: str) -> Callable[[int, int], None] | None: + """Build an ``on_progress(done, total)`` callback for a live terminal line. + + Text/ETA come from the same `quantlab.progress.ProgressReporter` the + dashboard uses, so a walk-forward/stress-test/sensitivity run gives a + consistent, already-tuned estimate on both interfaces. Returns ``None`` + when stdout isn't a terminal (piped/redirected output, CI logs): a + carriage-return-redrawn line only makes sense on a real tty, and callers + already treat ``on_progress=None`` as "don't report progress". + """ + if not sys.stdout.isatty(): + return None + reporter = ProgressReporter(title) + + def _on_progress(done: int, total: int) -> None: + text = reporter.text(done, total) + # \r (not an ANSI clear-line code) plus padding for portability + # across terminals that don't interpret escape sequences; padding + # overwrites any leftover characters from a longer previous line. + sys.stdout.write(f"\r {text}".ljust(100)) + sys.stdout.flush() + if total > 0 and done >= total: + sys.stdout.write("\n") + sys.stdout.flush() + + return _on_progress + + def _resolve_config_path(config: Path | None, shipped_config: str | None) -> Path: """Resolve exactly one explicit or package-bundled configuration. @@ -187,6 +232,294 @@ def _echo_parameter_grid(strategy_name: str, grid: dict[str, list[Any]]) -> None ) +def _run_active_validation( + cfg: ExperimentConfig, + data: pd.DataFrame, + report: DataQualityReport, + *, + checkpoint_path: Path | None = None, +) -> tuple[BacktestResult, WalkForwardResult | None]: + """Run whichever process ``cfg.validation.method`` names. + + The single place every robustness command resolves "what result / returns + series applies right now": a plain backtest for 'holdout' (or unset), or + the full walk-forward process for 'walk_forward' — never a plain backtest + silently standing in when walk-forward is configured. + + Args: + cfg: The loaded, validated experiment config. + data: Canonical long OHLCV frame already loaded for ``cfg``. + report: Data-quality report from loading ``data``, attached to a + plain backtest's metadata. + checkpoint_path: Forwarded to ``WalkForwardValidator.run()`` when the + walk-forward branch is taken, so an interrupted run resumes + instead of starting over. Ignored for a plain backtest, which is + fast enough not to need it. + + Returns: + ``(result, None)`` for a plain backtest, or ``(wf.oos_result, wf)`` + for walk-forward, so callers can branch on the second element to + reach the walk-forward-aware variant of a technique. + """ + if cfg.validation.method == "walk_forward": + from quantlab.validation.walk_forward import ( + WalkForwardValidator, + resolve_walk_forward_windows, + ) + + grid = _default_grid(cfg) + train_window, validation_window, test_window = resolve_walk_forward_windows(cfg) + _echo_step("Running walk-forward validation") + _echo_parameter_grid(cfg.strategy_name, grid) + wf = WalkForwardValidator(cfg).run( + data, + parameter_grid=grid, + train_window=train_window, + validation_window=validation_window, + test_window=test_window, + expanding=cfg.validation.expanding, + on_progress=_make_cli_progress_callback("Walk-forward"), + checkpoint_path=checkpoint_path, + ) + if wf.oos_result is None: + raise InsufficientDataError( + "No walk-forward folds fit the available history and configured " + f"windows (train={train_window}, validation={validation_window}, " + f"test={test_window})." + ) + # WalkForwardValidator.run() has no data_quality_report parameter of + # its own, so the saved OOS result would otherwise never carry the + # data-quality warnings a plain backtest attaches below -- attach it + # here instead, so a walk-forward report can surface the same + # gap/frequency-mismatch evidence a plain backtest's report would. + wf.oos_result.metadata["data_quality"] = report.to_dict() + return wf.oos_result, wf + + from quantlab.backtesting.runner import run_backtest_from_config + + _echo_step(f"Running backtest '{cfg.experiment_name}'") + result = run_backtest_from_config(data, cfg, data_quality_report=report) + return result, None + + +def _walk_forward_validation_artifacts( + wf: WalkForwardResult, +) -> dict[str, pd.Series | pd.DataFrame]: + """CSV artifacts describing a walk-forward run, matching ``walk-forward``.""" + return { + "walk_forward_results.csv": wf.summary_table(), + "walk_forward_oos_returns.csv": wf.oos_returns.rename("return"), + "walk_forward_oos_equity.csv": wf.oos_equity.rename("equity"), + } + + +def _attach_walk_forward_evidence( + result: BacktestResult, + wf: WalkForwardResult | None, + validation_artifacts: dict[str, object], + robustness_extra: dict[str, object], +) -> None: + """Fold walk-forward fold evidence into a save, when the mode is active.""" + if wf is None: + return + validation_artifacts.update(_walk_forward_validation_artifacts(wf)) + robustness_extra["walk_forward"] = wf.summary_table() + # `result` (and its already-complete `.metrics`, computed via the same + # full trade-log/benchmark/metrics pipeline as any BacktestResult) *is* + # `wf.oos_result` at every caller of this function -- reuse it rather + # than wf.oos_metrics()'s separate M.compute_metrics(oos_returns, + # oos_equity) recomputation, which only has the stitched return/equity + # series to work from and so omits benchmark comparisons, gross/net, + # turnover and every other metric the full pipeline already derived. + result.metadata["walk_forward_oos_metrics"] = dict(result.metrics) + + +def _compute_stress_tests( + data: pd.DataFrame, + cfg: ExperimentConfig, + wf: WalkForwardResult | None, + *, + on_progress: Callable[[int, int], None] | None = None, + checkpoint_path: Path | None = None, +) -> pd.DataFrame: + """Stress scenarios for the active validation method. + + Walk-forward mode re-runs the whole selection process per scenario + (:func:`~quantlab.validation.robustness.run_walk_forward_stress_tests`) + instead of reusing :func:`~quantlab.validation.robustness.run_stress_tests` + plain-backtest variant — Robustness evidence must never silently come + from a different validation method than the one currently in effect. + """ + if wf is not None: + from quantlab.validation.robustness import run_walk_forward_stress_tests + + return run_walk_forward_stress_tests( + data, cfg, wf, on_progress=on_progress, checkpoint_path=checkpoint_path + ) + from quantlab.validation.robustness import run_stress_tests + + return run_stress_tests( + data, cfg, on_progress=on_progress, checkpoint_path=checkpoint_path + ) + + +def _compute_bootstrap( + cfg: ExperimentConfig, + result: BacktestResult, + *, + n_iterations: int | None = None, + block_size: int | None = None, +) -> pd.DataFrame: + """Block-bootstrap the active result's returns (mode-agnostic). + + Bootstrap resamples already-realised returns and optimizes nothing, so + the same function applies unchanged whether ``result.returns`` came from + a plain backtest or a walk-forward's stitched OOS series. + """ + from quantlab.validation.bootstrap import bootstrap_returns + + effective_n_iterations = ( + n_iterations + if n_iterations is not None + else cfg.robustness.bootstrap.n_iterations + ) + effective_block_size = ( + block_size if block_size is not None else cfg.robustness.bootstrap.block_size + ) + boot = bootstrap_returns( + result.returns, + n_iterations=effective_n_iterations, + block_size=effective_block_size, + seed=cfg.random_seed, + periods_per_year=cfg.periods_per_year, + initial_capital=cfg.initial_capital, + risk_free_rate=cfg.risk_free_rate, + ) + # Record what was actually used, not just what the YAML says -- a CLI + # override (--n-iterations/--block-size) would otherwise leave the saved + # metadata silently describing a different run than the one that + # actually produced these numbers. + result.metadata["bootstrap_run_params"] = { + "n_iterations": effective_n_iterations, + "block_size": effective_block_size, + } + return boot.summary() + + +def _compute_permutation_test( + cfg: ExperimentConfig, + result: BacktestResult, + *, + n_iterations: int | None = None, +) -> dict[str, float]: + """Random-sign Monte Carlo permutation test (mode-agnostic, see bootstrap).""" + from quantlab.validation.robustness import monte_carlo_permutation + + effective_n_iterations = ( + n_iterations + if n_iterations is not None + else cfg.robustness.permutation_test.n_iterations + ) + outcome = monte_carlo_permutation( + result.returns, + n_iterations=effective_n_iterations, + seed=cfg.random_seed, + periods_per_year=cfg.periods_per_year, + risk_free_rate=cfg.risk_free_rate, + ) + # See _compute_bootstrap: record the effective (possibly CLI-overridden) + # parameter, not just the YAML default. + result.metadata["permutation_test_run_params"] = { + "n_iterations": effective_n_iterations, + } + return outcome + + +def _resolve_sensitivity_axes( + cfg: ExperimentConfig, + param_x: str | None, + values_x: str | None, + param_y: str | None, + values_y: str | None, +) -> tuple[str, list[Any], str, list[Any]]: + """Resolve sensitivity axes: CLI options override the YAML config. + + Raises: + QuantLabError: If only some of the 4 CLI options are given, or if + none are given and ``robustness.sensitivity.parameters`` is unset + — sensitivity has no default grid, unlike walk-forward. + """ + from quantlab.validation.parameter_grid import parse_parameter_grid_values + + cli_given = (param_x, values_x, param_y, values_y) + if any(v is not None for v in cli_given): + if param_x is None or values_x is None or param_y is None or values_y is None: + raise QuantLabError( + "--param-x, --values-x, --param-y and --values-y must all be " + "given together, or all omitted to use " + "robustness.sensitivity.parameters from the config." + ) + return ( + param_x, + parse_parameter_grid_values(values_x), + param_y, + parse_parameter_grid_values(values_y), + ) + configured = cfg.robustness.sensitivity.parameters + if configured is None: + raise QuantLabError( + "No sensitivity axes given: pass --param-x/--values-x/--param-y/" + "--values-y, or set robustness.sensitivity.parameters (exactly 2 " + "keys) in the config." + ) + (x_name, x_values), (y_name, y_values) = list(configured.items()) + return x_name, x_values, y_name, y_values + + +def _compute_sensitivity( + data: pd.DataFrame, + cfg: ExperimentConfig, + wf: WalkForwardResult | None, + parameter_x: str, + values_x: list[Any], + parameter_y: str, + values_y: list[Any], + *, + on_progress: Callable[[int, int], None] | None = None, + checkpoint_path: Path | None = None, +) -> pd.DataFrame: + """Two-parameter sensitivity sweep for the active validation method. + + Walk-forward mode re-runs the whole selection process per grid cell + (:func:`~quantlab.validation.parameter_sensitivity. + run_walk_forward_parameter_sensitivity`) instead of the plain + single-backtest variant, for the same reason as stress tests above. + ``on_progress``/``checkpoint_path`` only apply to that walk-forward + variant — the plain one has no ``on_progress`` either (already judged + fast enough). + """ + if wf is not None: + from quantlab.validation.parameter_sensitivity import ( + run_walk_forward_parameter_sensitivity, + ) + + return run_walk_forward_parameter_sensitivity( + data, + cfg, + parameter_x, + values_x, + parameter_y, + values_y, + on_progress=on_progress, + checkpoint_path=checkpoint_path, + ) + from quantlab.validation.parameter_sensitivity import run_parameter_sensitivity + + return run_parameter_sensitivity( + data, cfg, parameter_x, values_x, parameter_y, values_y + ) + + @app.command() def download( config: Path | None = _CONFIG_OPTION, @@ -307,6 +640,11 @@ def backtest( def walk_forward( config: Path | None = _CONFIG_OPTION, shipped_config: str | None = _SHIPPED_CONFIG_OPTION, + fresh: bool = typer.Option( + False, + "--fresh", + help="Discard any existing checkpoint and start over.", + ), ) -> None: """Run walk-forward validation and robustness tests.""" configure_logging() @@ -314,8 +652,20 @@ def walk_forward( cfg = _load_config(_resolve_config_path(config, shipped_config)) from quantlab.backtesting.runner import run_backtest_from_config from quantlab.data.loader import DataLoader - from quantlab.validation.robustness import run_stress_tests - from quantlab.validation.walk_forward import WalkForwardValidator + from quantlab.validation.checkpoint import clear_checkpoint + from quantlab.validation.robustness import stress_test_checkpoint_paths + from quantlab.validation.walk_forward import ( + WalkForwardValidator, + resolve_walk_forward_windows, + ) + + out = GENERATED_REPORTS_DIR / cfg.experiment_name + wf_checkpoint = out / ".checkpoint_walk_forward.pkl" + stress_checkpoint = out / ".checkpoint_stress_test.pkl" + if fresh: + clear_checkpoint(wf_checkpoint) + for path in stress_test_checkpoint_paths(stress_checkpoint): + clear_checkpoint(path) _echo_step("Loading and validating data") data, report = DataLoader().load(cfg) @@ -325,9 +675,7 @@ def walk_forward( grid = _default_grid(cfg) _echo_parameter_grid(cfg.strategy_name, grid) validator = WalkForwardValidator(cfg) - train_window = cfg.validation.train_window or 500 - validation_window = cfg.validation.validation_window or 126 - test_window = cfg.validation.test_window or 126 + train_window, validation_window, test_window = resolve_walk_forward_windows(cfg) if not ( cfg.validation.train_window and cfg.validation.validation_window @@ -348,6 +696,8 @@ def walk_forward( validation_window=validation_window, test_window=test_window, expanding=cfg.validation.expanding, + on_progress=_make_cli_progress_callback("Walk-forward"), + checkpoint_path=wf_checkpoint, ) if not wf.folds: @@ -358,13 +708,37 @@ def walk_forward( ) _echo_step("Running stress tests") - stress = run_stress_tests(data, cfg) - - out = GENERATED_REPORTS_DIR / cfg.experiment_name + # Walk-forward-OOS-aware, matching the dedicated `stress-test` command + # and the dashboard for this same config -- never a plain full-sample + # re-run of the scenarios, which would silently mix a different + # validation methodology into the same "walk_forward" evidence bundle + # (see _compute_stress_tests). wf.folds non-empty is not itself a + # guarantee wf.oos_result exists (see its docstring: None only when + # no fold produced any OOS weights) -- run_walk_forward_stress_tests + # requires it, so fall back to the full-sample scenarios in that + # edge case rather than fail the whole command, the same graceful + # degradation the OOS-metrics fallback just below already applies. + stress = _compute_stress_tests( + data, + cfg, + wf if wf.oos_result is not None else None, + on_progress=_make_cli_progress_callback("Stress tests"), + checkpoint_path=stress_checkpoint, + ) # Attach OOS metrics to a fresh full-sample result before saving one bundle. result = run_backtest_from_config(data, cfg, data_quality_report=report) - oos = wf.oos_metrics(cfg.periods_per_year, cfg.risk_free_rate) + # Reuse wf.oos_result.metrics (built via the same full trade-log/ + # benchmark/metrics pipeline as `result` itself) rather than + # wf.oos_metrics()'s separate, less complete M.compute_metrics( + # oos_returns, oos_equity) recomputation -- `wf.folds` non-empty + # (checked above) is not itself a guarantee oos_result exists (see + # its docstring), so still fall back for that edge case. + oos = ( + dict(wf.oos_result.metrics) + if wf.oos_result is not None + else wf.oos_metrics(cfg.periods_per_year, cfg.risk_free_rate) + ) result.metadata["walk_forward_oos_metrics"] = oos result.metadata["walk_forward_parameter_grid"] = grid result.metadata["walk_forward_windows"] = { @@ -408,6 +782,451 @@ def walk_forward( raise typer.Exit(code=1) from exc +@app.command(name="stress-test") +def stress_test( + config: Path | None = _CONFIG_OPTION, + shipped_config: str | None = _SHIPPED_CONFIG_OPTION, + fresh: bool = typer.Option( + False, + "--fresh", + help="Discard any existing checkpoint and start over.", + ), +) -> None: + """Run stress-test scenarios (commission/slippage/delay/reduced universe). + + Re-runs the whole walk-forward process per scenario when + validation.method is 'walk_forward', instead of a single backtest — see + `quantlab robustness --help` for why. + """ + configure_logging() + try: + cfg = _load_config(_resolve_config_path(config, shipped_config)) + from quantlab.data.loader import DataLoader + from quantlab.validation.checkpoint import clear_checkpoint + from quantlab.validation.robustness import stress_test_checkpoint_paths + + out = GENERATED_REPORTS_DIR / cfg.experiment_name + wf_checkpoint = out / ".checkpoint_walk_forward.pkl" + stress_checkpoint = out / ".checkpoint_stress_test.pkl" + if fresh: + clear_checkpoint(wf_checkpoint) + for path in stress_test_checkpoint_paths(stress_checkpoint): + clear_checkpoint(path) + + _echo_step("Loading and validating data") + data, report = DataLoader().load(cfg) + _echo_data_warnings(report) + + result, wf = _run_active_validation( + cfg, data, report, checkpoint_path=wf_checkpoint + ) + _echo_step("Running stress tests") + stress = _compute_stress_tests( + data, + cfg, + wf, + on_progress=_make_cli_progress_callback("Stress tests"), + checkpoint_path=stress_checkpoint, + ) + + validation_artifacts: dict[str, Any] = {"stress_tests.csv": stress} + robustness_extra: dict[str, Any] = {"stress_tests": stress} + _attach_walk_forward_evidence( + result, wf, validation_artifacts, robustness_extra + ) + + _echo_step("Saving results") + from quantlab.backtesting.result import save_with_robustness_reuse + + out_dir = save_with_robustness_reuse( + result, + out, + robustness=robustness_extra, + validation_artifacts=validation_artifacts, + ) + typer.echo("") + typer.echo(stress.to_string(index=False)) + typer.echo("") + _echo_save_outcome(result, f"Saved to {out_dir}") + except QuantLabError as exc: + typer.secho(f"[ERROR] {exc}", fg=typer.colors.RED, err=True) + raise typer.Exit(code=1) from exc + + +@app.command() +def bootstrap( + config: Path | None = _CONFIG_OPTION, + shipped_config: str | None = _SHIPPED_CONFIG_OPTION, + n_iterations: int | None = typer.Option( + None, + "--n-iterations", + min=1, + help="Override robustness.bootstrap.n_iterations from the config.", + ), + block_size: int | None = typer.Option( + None, + "--block-size", + min=1, + help="Override robustness.bootstrap.block_size from the config.", + ), + fresh: bool = typer.Option( + False, + "--fresh", + help="Discard any existing walk-forward checkpoint and start over.", + ), +) -> None: + """Block-bootstrap the active result's returns (backtest or walk-forward OOS).""" + configure_logging() + try: + cfg = _load_config(_resolve_config_path(config, shipped_config)) + from quantlab.data.loader import DataLoader + from quantlab.validation.checkpoint import clear_checkpoint + + wf_checkpoint = ( + GENERATED_REPORTS_DIR / cfg.experiment_name / ".checkpoint_walk_forward.pkl" + ) + if fresh: + clear_checkpoint(wf_checkpoint) + + _echo_step("Loading and validating data") + data, report = DataLoader().load(cfg) + _echo_data_warnings(report) + + result, wf = _run_active_validation( + cfg, data, report, checkpoint_path=wf_checkpoint + ) + _echo_step("Running bootstrap") + summary = _compute_bootstrap( + cfg, result, n_iterations=n_iterations, block_size=block_size + ) + + validation_artifacts: dict[str, Any] = {"bootstrap_summary.csv": summary} + robustness_extra: dict[str, Any] = {"bootstrap": summary} + _attach_walk_forward_evidence( + result, wf, validation_artifacts, robustness_extra + ) + + _echo_step("Saving results") + from quantlab.backtesting.result import save_with_robustness_reuse + + out_dir = save_with_robustness_reuse( + result, + GENERATED_REPORTS_DIR / cfg.experiment_name, + robustness=robustness_extra, + validation_artifacts=validation_artifacts, + ) + typer.echo("") + typer.echo(summary.to_string(index=False)) + typer.echo("") + _echo_save_outcome(result, f"Saved to {out_dir}") + except QuantLabError as exc: + typer.secho(f"[ERROR] {exc}", fg=typer.colors.RED, err=True) + raise typer.Exit(code=1) from exc + + +@app.command(name="permutation-test") +def permutation_test( + config: Path | None = _CONFIG_OPTION, + shipped_config: str | None = _SHIPPED_CONFIG_OPTION, + n_iterations: int | None = typer.Option( + None, + "--n-iterations", + min=1, + help="Override robustness.permutation_test.n_iterations from the config.", + ), + fresh: bool = typer.Option( + False, + "--fresh", + help="Discard any existing walk-forward checkpoint and start over.", + ), +) -> None: + """Random-sign Monte Carlo permutation test on the active result's returns.""" + configure_logging() + try: + cfg = _load_config(_resolve_config_path(config, shipped_config)) + from quantlab.data.loader import DataLoader + from quantlab.validation.checkpoint import clear_checkpoint + + wf_checkpoint = ( + GENERATED_REPORTS_DIR / cfg.experiment_name / ".checkpoint_walk_forward.pkl" + ) + if fresh: + clear_checkpoint(wf_checkpoint) + + _echo_step("Loading and validating data") + data, report = DataLoader().load(cfg) + _echo_data_warnings(report) + + result, wf = _run_active_validation( + cfg, data, report, checkpoint_path=wf_checkpoint + ) + _echo_step("Running Monte Carlo permutation test") + outcome = _compute_permutation_test(cfg, result, n_iterations=n_iterations) + import pandas as pd + + summary = pd.DataFrame([outcome]) + + validation_artifacts: dict[str, Any] = {"permutation_test.csv": summary} + robustness_extra: dict[str, Any] = {"permutation_test": summary} + _attach_walk_forward_evidence( + result, wf, validation_artifacts, robustness_extra + ) + + _echo_step("Saving results") + from quantlab.backtesting.result import save_with_robustness_reuse + + out_dir = save_with_robustness_reuse( + result, + GENERATED_REPORTS_DIR / cfg.experiment_name, + robustness=robustness_extra, + validation_artifacts=validation_artifacts, + ) + typer.echo("") + typer.echo(f" real Sharpe : {outcome['real_sharpe']:.2f}") + typer.echo(f" p-value : {outcome['p_value']:.4f}") + typer.echo("") + _echo_save_outcome(result, f"Saved to {out_dir}") + except QuantLabError as exc: + typer.secho(f"[ERROR] {exc}", fg=typer.colors.RED, err=True) + raise typer.Exit(code=1) from exc + + +@app.command() +def sensitivity( + config: Path | None = _CONFIG_OPTION, + shipped_config: str | None = _SHIPPED_CONFIG_OPTION, + param_x: str | None = typer.Option( + None, "--param-x", help="First swept strategy parameter." + ), + values_x: str | None = typer.Option( + None, "--values-x", help="Comma-separated candidate values for --param-x." + ), + param_y: str | None = typer.Option( + None, "--param-y", help="Second swept strategy parameter." + ), + values_y: str | None = typer.Option( + None, "--values-y", help="Comma-separated candidate values for --param-y." + ), + fresh: bool = typer.Option( + False, + "--fresh", + help="Discard any existing checkpoint and start over.", + ), +) -> None: + """Two-parameter sensitivity sweep, scored on the active validation method. + + Give all four of --param-x/--values-x/--param-y/--values-y together to + override robustness.sensitivity.parameters from the config, or omit all + four to use that config section (there is no default grid — at least + one source of axes is required). + """ + configure_logging() + try: + cfg = _load_config(_resolve_config_path(config, shipped_config)) + x_name, x_values, y_name, y_values = _resolve_sensitivity_axes( + cfg, param_x, values_x, param_y, values_y + ) + from quantlab.data.loader import DataLoader + from quantlab.validation.checkpoint import clear_checkpoint + + out = GENERATED_REPORTS_DIR / cfg.experiment_name + wf_checkpoint = out / ".checkpoint_walk_forward.pkl" + sensitivity_checkpoint = out / ".checkpoint_sensitivity.pkl" + if fresh: + clear_checkpoint(wf_checkpoint) + clear_checkpoint(sensitivity_checkpoint) + + _echo_step("Loading and validating data") + data, report = DataLoader().load(cfg) + _echo_data_warnings(report) + + result, wf = _run_active_validation( + cfg, data, report, checkpoint_path=wf_checkpoint + ) + _echo_step( + f"Running parameter sensitivity ({x_name} x {y_name}, " + f"{len(x_values) * len(y_values)} combinations)" + ) + sens = _compute_sensitivity( + data, + cfg, + wf, + x_name, + x_values, + y_name, + y_values, + on_progress=_make_cli_progress_callback("Sensitivity"), + checkpoint_path=sensitivity_checkpoint, + ) + + # Record the axes actually used, not just that a sweep ran -- these + # may have come from a CLI override rather than + # robustness.sensitivity.parameters in the saved config.yaml. + result.metadata["sensitivity_run_params"] = { + "parameter_x": x_name, + "values_x": x_values, + "parameter_y": y_name, + "values_y": y_values, + } + + validation_artifacts: dict[str, Any] = {"sensitivity.csv": sens} + robustness_extra: dict[str, Any] = {"sensitivity": sens} + _attach_walk_forward_evidence( + result, wf, validation_artifacts, robustness_extra + ) + + _echo_step("Saving results") + from quantlab.backtesting.result import save_with_robustness_reuse + + out_dir = save_with_robustness_reuse( + result, + out, + robustness=robustness_extra, + validation_artifacts=validation_artifacts, + ) + typer.echo("") + typer.echo(sens.to_string(index=False)) + typer.echo("") + _echo_save_outcome(result, f"Saved to {out_dir}") + except QuantLabError as exc: + typer.secho(f"[ERROR] {exc}", fg=typer.colors.RED, err=True) + raise typer.Exit(code=1) from exc + + +@app.command() +def robustness( + config: Path | None = _CONFIG_OPTION, + shipped_config: str | None = _SHIPPED_CONFIG_OPTION, + fresh: bool = typer.Option( + False, + "--fresh", + help="Discard any existing checkpoint and start over.", + ), +) -> None: + """Run every robustness.* technique enabled in the config, in one pass. + + Reads only the YAML config (no per-technique CLI overrides — use the + dedicated stress-test/bootstrap/permutation-test/sensitivity commands for + that). Each technique branches on validation.method exactly like its + dedicated command, calling the identical underlying function. + """ + configure_logging() + try: + cfg = _load_config(_resolve_config_path(config, shipped_config)) + from quantlab.data.loader import DataLoader + from quantlab.validation.checkpoint import clear_checkpoint + from quantlab.validation.robustness import stress_test_checkpoint_paths + + out = GENERATED_REPORTS_DIR / cfg.experiment_name + wf_checkpoint = out / ".checkpoint_walk_forward.pkl" + stress_checkpoint = out / ".checkpoint_stress_test.pkl" + sensitivity_checkpoint = out / ".checkpoint_sensitivity.pkl" + if fresh: + clear_checkpoint(wf_checkpoint) + for path in stress_test_checkpoint_paths(stress_checkpoint): + clear_checkpoint(path) + clear_checkpoint(sensitivity_checkpoint) + + _echo_step("Loading and validating data") + data, report = DataLoader().load(cfg) + _echo_data_warnings(report) + + result, wf = _run_active_validation( + cfg, data, report, checkpoint_path=wf_checkpoint + ) + validation_artifacts: dict[str, Any] = {} + robustness_extra: dict[str, Any] = {} + _attach_walk_forward_evidence( + result, wf, validation_artifacts, robustness_extra + ) + + ran_any = False + if cfg.robustness.stress_test.enabled: + ran_any = True + _echo_step("Running stress tests") + stress = _compute_stress_tests( + data, + cfg, + wf, + on_progress=_make_cli_progress_callback("Stress tests"), + checkpoint_path=stress_checkpoint, + ) + validation_artifacts["stress_tests.csv"] = stress + robustness_extra["stress_tests"] = stress + typer.echo("") + typer.echo(stress.to_string(index=False)) + + if cfg.robustness.bootstrap.enabled: + ran_any = True + _echo_step("Running bootstrap") + boot_summary = _compute_bootstrap(cfg, result) + validation_artifacts["bootstrap_summary.csv"] = boot_summary + robustness_extra["bootstrap"] = boot_summary + typer.echo("") + typer.echo(boot_summary.to_string(index=False)) + + if cfg.robustness.permutation_test.enabled: + ran_any = True + _echo_step("Running Monte Carlo permutation test") + outcome = _compute_permutation_test(cfg, result) + import pandas as pd + + permutation_summary = pd.DataFrame([outcome]) + validation_artifacts["permutation_test.csv"] = permutation_summary + robustness_extra["permutation_test"] = permutation_summary + typer.echo("") + typer.echo(f" real Sharpe : {outcome['real_sharpe']:.2f}") + typer.echo(f" p-value : {outcome['p_value']:.4f}") + + if cfg.robustness.sensitivity.enabled: + ran_any = True + parameters = cfg.robustness.sensitivity.parameters + if parameters is None: + raise QuantLabError( + "robustness.sensitivity.enabled is true but " + "robustness.sensitivity.parameters is not set." + ) + (x_name, x_values), (y_name, y_values) = list(parameters.items()) + _echo_step(f"Running parameter sensitivity ({x_name} x {y_name})") + sens = _compute_sensitivity( + data, + cfg, + wf, + x_name, + x_values, + y_name, + y_values, + on_progress=_make_cli_progress_callback("Sensitivity"), + checkpoint_path=sensitivity_checkpoint, + ) + validation_artifacts["sensitivity.csv"] = sens + robustness_extra["sensitivity"] = sens + typer.echo("") + typer.echo(sens.to_string(index=False)) + + if not ran_any: + typer.secho( + " no robustness.* technique is enabled in this config — " + "nothing to run. Set e.g. robustness.bootstrap.enabled: true.", + fg=typer.colors.YELLOW, + ) + + _echo_step("Saving results") + from quantlab.backtesting.result import save_with_robustness_reuse + + out_dir = save_with_robustness_reuse( + result, + out, + robustness=robustness_extra, + validation_artifacts=validation_artifacts, + ) + typer.echo("") + _echo_save_outcome(result, f"Saved to {out_dir}") + except QuantLabError as exc: + typer.secho(f"[ERROR] {exc}", fg=typer.colors.RED, err=True) + raise typer.Exit(code=1) from exc + + @app.command() def report( experiment: str = typer.Option( diff --git a/src/quantlab/config.py b/src/quantlab/config.py index 1e37fdd..d6d1294 100644 --- a/src/quantlab/config.py +++ b/src/quantlab/config.py @@ -15,7 +15,7 @@ import math import re import types -from collections.abc import Mapping +from collections.abc import Iterable, Mapping from datetime import date from enum import StrEnum from pathlib import Path @@ -137,9 +137,17 @@ def _reject_non_json_safe(value: Any, *, path: str) -> None: """Reject values that cannot be represented safely in saved metadata. Accepted values are ``None``, booleans, integers, finite floats, strings, - dates, lists, and dictionaries with string keys. Array-like objects and - unordered containers must be converted explicitly by the caller. + dates, lists, dictionaries with string keys, and nested Pydantic models + (each validates its own fields recursively via + ``_reject_non_json_safe_fields``, so re-walking its internals here would + be redundant — this mirrors the same skip already applied to a model + stored directly in a field, generalised to one nested inside a list or + dict too, e.g. ``DataConfig.instruments: list[InstrumentConfig]``). + Array-like objects and unordered containers must be converted explicitly + by the caller. """ + if isinstance(value, BaseModel): + return if isinstance(value, _JSON_SAFE_SCALARS): return if isinstance(value, float): @@ -237,18 +245,6 @@ class DataSourceName(StrEnum): CSV = "csv" -class MarketCalendar(StrEnum): - """Market-hours model used for settlement, gaps, and annualisation. - - QuantLab applies one calendar to the entire experiment. Yahoo defaults to - XNYS but may be configured as 24/7, Binance is always 24/7, and CSV - experiments must choose explicitly. Other calendars are not supported. - """ - - XNYS = "XNYS" - TWENTY_FOUR_SEVEN = "24/7" - - class OptimizationMetric(StrEnum): """Metrics available for walk-forward parameter selection.""" @@ -340,13 +336,90 @@ def _reject_non_json_safe_fields(self) -> _StrictModel: } +def compatible_frequencies_for_sources( + sources: Iterable[DataSourceName], +) -> set[DataFrequency]: + """Return the frequencies compatible with every remote source in ``sources``. + + ``csv`` is neutral: its real frequency depends on the timestamps actually + present in the file, checked after loading by + :class:`~quantlab.data.validator.DataValidator` (``_check_declared_frequency``), + not known in advance the way a remote API's capabilities are. A + ``sources`` collection containing only ``csv`` (or empty) is therefore + compatible with every :class:`DataFrequency`. + + This is the single source of truth for frequency compatibility — both + :class:`DataConfig`'s validator and the dashboard's frequency picker call + it directly, so the two can never diverge. + """ + remote = [source for source in sources if source is not DataSourceName.CSV] + if not remote: + return set(DataFrequency) + tables = [_SOURCE_SUPPORTED_FREQUENCIES[source] for source in remote] + return set.intersection(*(set(table) for table in tables)) + + +class InstrumentConfig(_StrictModel): + """A single instrument: its symbol, data source, and trading calendar. + + The unit of configuration for a tradable asset or a benchmark. Each + instrument resolves its own source and calendar explicitly — nothing here + is inferred at run time; any auto-detection happens upstream (e.g. in the + dashboard) before this model is constructed. + """ + + symbol: str + source: DataSourceName + calendar: str = Field( + description=( + "'24/7' for a continuous market, or any calendar name accepted " + "by pandas_market_calendars (e.g. 'XNYS', 'XHKG', 'CME_Equity')." + ) + ) + + @field_validator("symbol") + @classmethod + def _normalize_symbol(cls, value: str) -> str: + """Normalise the symbol and make it safe as a CSV/cache filename.""" + sym = value.strip().upper() + if not sym: + raise ValueError("symbol must not be empty.") + _validate_path_component(sym, field_name="symbol") + return sym + + @field_validator("calendar") + @classmethod + def _validate_calendar(cls, value: str) -> str: + # Local import: quantlab.data imports quantlab.config at module load + # time (via data/loader.py), so a top-level import here would cycle. + from quantlab.data.calendar import validate_calendar_name + + calendar = value.strip() + if not calendar: + raise ValueError("calendar must not be empty.") + validate_calendar_name(calendar) + return calendar + + @model_validator(mode="after") + def _check_binance_is_always_247(self) -> InstrumentConfig: + if self.source is DataSourceName.BINANCE and self.calendar != "24/7": + raise ValueError( + f"calendar {self.calendar!r} is not permitted with source " + f"'binance' for symbol {self.symbol!r} — every Binance " + "symbol genuinely trades 24/7, so there is no real " + "instrument this combination could correctly describe. " + "Set calendar: '24/7'." + ) + return self + + class DataConfig(_StrictModel): """Data-acquisition settings (the ``data:`` block).""" - source: DataSourceName = Field( - default=DataSourceName.YAHOO, description="Data source identifier." + instruments: list[InstrumentConfig] = Field( + min_length=1, + description="Tradable instruments, each with its own symbol/source/calendar.", ) - symbols: list[str] = Field(min_length=1, description="Tickers to load.") start_date: date end_date: date frequency: DataFrequency = Field( @@ -361,63 +434,44 @@ class DataConfig(_StrictModel): "missing_value_policy is 'forward_fill'." ), ) - market_calendar: MarketCalendar | None = Field( - default=None, - description=( - "Market-hours model: 'XNYS' or '24/7'. Yahoo defaults to XNYS but " - "may select 24/7; Binance is always 24/7; CSV must set it explicitly." - ), - ) use_bundled_demo_data: bool = Field( default=False, description=( - "For source 'csv' only, use QuantLab's bundled synthetic demo " - "files when every requested symbol is absent from the local " - "raw-data directory (a partial match is always a hard error, " - "never a mix of local and bundled data). Must be enabled " - "explicitly." + "For a csv-sourced instrument, use QuantLab's bundled synthetic " + "demo files when every requested symbol is absent from the " + "local raw-data directory (a partial match is always a hard " + "error, never a mix of local and bundled data). Must be " + "enabled explicitly." ), ) @property - def effective_market_calendar(self) -> MarketCalendar: - """Return the selected or source-implied market calendar.""" - if self.source is DataSourceName.YAHOO: - return self.market_calendar or MarketCalendar.XNYS - if self.source is DataSourceName.BINANCE: - return MarketCalendar.TWENTY_FOUR_SEVEN - assert self.market_calendar is not None # enforced by validator below - return self.market_calendar - - @property - def is_247_market(self) -> bool: - """Resolve the effective 24/7-market flag.""" - return self.effective_market_calendar is MarketCalendar.TWENTY_FOUR_SEVEN + def symbols(self) -> list[str]: + """Normalised list of tickers, one per instrument.""" + return [instrument.symbol for instrument in self.instruments] - @field_validator("symbols") - @classmethod - def _dedupe_and_upper(cls, value: list[str]) -> list[str]: - """Normalise tickers: strip, uppercase, drop duplicates (keep order). + @model_validator(mode="after") + def _check_unique_symbols(self) -> DataConfig: + """Reject the same symbol appearing in more than one instrument. - Raises: - ValueError: If a symbol contains anything outside - `_SAFE_PATH_COMPONENT` — the ``csv`` source builds - ``raw_dir / f"{symbol}.csv"`` directly from this value with - no further sanitisation. + Price series are indexed by symbol alone downstream (the canonical + schema's SYMBOL column, price_matrix columns) — two instruments for + the same ticker would be an unresolvable collision, not a case to + silently support. """ seen: set[str] = set() - out: list[str] = [] - for raw in value: - sym = raw.strip().upper() - if not sym: - continue - _validate_path_component(sym, field_name="symbol") - if sym not in seen: - seen.add(sym) - out.append(sym) - if not out: - raise ValueError("`symbols` must contain at least one ticker.") - return out + duplicates: set[str] = set() + for instrument in self.instruments: + if instrument.symbol in seen: + duplicates.add(instrument.symbol) + seen.add(instrument.symbol) + if duplicates: + raise ValueError( + f"Duplicate symbol(s) {sorted(duplicates)} across `instruments` " + "— each symbol may appear as only one instrument (one source, " + "one calendar) per experiment." + ) + return self @model_validator(mode="after") def _check_dates(self) -> DataConfig: @@ -434,12 +488,83 @@ def _check_dates(self) -> DataConfig: return self @model_validator(mode="after") - def _check_frequency_supported(self) -> DataConfig: - allowed = _SOURCE_SUPPORTED_FREQUENCIES.get(self.source) - if allowed is not None and self.frequency not in allowed: + def _check_frequency_supported_by_every_instrument(self) -> DataConfig: + sources = {instrument.source for instrument in self.instruments} + allowed = compatible_frequencies_for_sources(sources) + if self.frequency not in allowed: + remote = sorted( + (source for source in sources if source is not DataSourceName.CSV), + key=str, + ) + details = ", ".join( + f"{source}: {sorted(_SOURCE_SUPPORTED_FREQUENCIES[source])}" + for source in remote + ) raise ValueError( - f"frequency '{self.frequency}' is not supported by source " - f"'{self.source}'. Supported: {sorted(allowed)}." + f"frequency '{self.frequency}' is not supported by every " + "instrument's source. Supported frequencies per remote " + f"source: {details or '(none)'}." + ) + return self + + @model_validator(mode="after") + def _check_intraday_frequency_requires_uniform_calendar(self) -> DataConfig: + """Reject a sub-daily mixed-calendar universe. + + Verified-closure handling (:mod:`quantlab.data.closures`) only + operates at daily frequency -- an intraday, mixed-calendar universe + (e.g. Yahoo/XNYS '1h' alongside Binance/24-7 '1h') has no equivalent + mechanism, so a held equity inevitably hits an hour the other + calendar trades but it has no return for, failing deep inside + accounting with a confusing error instead of at config load. Until a + genuine per-session intraday timeline exists, refuse this + combination explicitly. + """ + if self.frequency is DataFrequency.H1: + calendars = {instrument.calendar for instrument in self.instruments} + if len(calendars) > 1: + raise ValueError( + "Intraday frequency '1h' does not support a " + f"mixed-calendar universe ({sorted(calendars)}) -- " + "verified-closure handling only operates at daily " + "frequency, so a held equity would inevitably hit an " + "hour another calendar trades but it has no return for. " + "Use a single shared calendar for '1h', or daily " + "frequency for a mixed-calendar universe." + ) + return self + + @model_validator(mode="after") + def _warn_if_mixed_calendars_dilute_windowed_features(self) -> DataConfig: + """Warn (never reject) that rolling-window features may be diluted. + + A verified closure's synthetic bar (:mod:`quantlab.data.closures`) + is exactly flat -- zero return, zero volume -- so any trailing + window counted in raw *periods* (a momentum lookback, a volatility + window, an ADV window, a technical indicator's own window, ...) + spans MORE real trading sessions than its configured length for a + session-bound instrument sharing a combined timeline with an + always-open one (e.g. equities alongside crypto): those flat bars + silently dilute volatility/ADV estimates, and a "252-period" + lookback stretches across more than 252 real equity sessions. + Computing every instrument's own features on its native calendar + before aligning signals would remove this entirely, but that is a + substantially larger redesign than a single validator can express + -- this only makes the existing, structural limitation visible at + config load instead of a silent distortion (see + docs/limitations.md). + """ + calendars = {instrument.calendar for instrument in self.instruments} + if len(calendars) > 1: + logger.warning( + "Instruments span more than one calendar (%s): any " + "rolling-window feature (momentum lookback, volatility " + "window, ADV window, technical indicators, ...) counts raw " + "periods, not real trading sessions per instrument -- a " + "session-bound instrument's estimates are diluted by the " + "flat, zero-return/zero-volume closure bars inserted to " + "keep the combined timeline dense. See docs/limitations.md.", + sorted(calendars), ) return self @@ -456,39 +581,15 @@ def _check_forward_fill_limit_is_relevant(self) -> DataConfig: return self @model_validator(mode="after") - def _check_market_calendar_matches_source(self) -> DataConfig: - """Apply QuantLab's current one-calendar-per-experiment policy. - - Yahoo supports XNYS or 24/7, Binance is always 24/7, and CSV has no - implied calendar. Other exchange calendars remain unsupported. - """ - if self.source is DataSourceName.BINANCE: - if self.market_calendar not in (None, MarketCalendar.TWENTY_FOUR_SEVEN): - raise ValueError( - f"market_calendar: {self.market_calendar!r} is not " - "permitted with source: 'binance' — every Binance " - "symbol genuinely trades 24/7, so there is no real " - "instrument this combination could correctly describe. " - "Leave market_calendar unset (implied '24/7')." - ) - elif self.source is DataSourceName.CSV and self.market_calendar is None: - raise ValueError( - "market_calendar must be set explicitly ('XNYS' or '24/7') " - "for source: 'csv' — a CSV feed could contain either kind " - "of data, and nothing else here can tell which." - ) - return self - - @model_validator(mode="after") - def _check_bundled_demo_data_scoped_to_csv(self) -> DataConfig: - """Restrict the bundled synthetic-data fallback to CSV configs.""" - if self.use_bundled_demo_data and self.source is not DataSourceName.CSV: + def _check_bundled_demo_data_requires_a_csv_instrument(self) -> DataConfig: + """Restrict the bundled synthetic-data fallback to csv instruments.""" + if self.use_bundled_demo_data and not any( + instrument.source is DataSourceName.CSV for instrument in self.instruments + ): raise ValueError( - f"use_bundled_demo_data: true is not permitted with source: " - f"{self.source!r} — the bundled-demo-CSV fallback is only " - "ever consulted by the csv loader, so setting this alongside " - "any other source has no effect and only misleadingly " - "suggests an offline fallback is configured." + "use_bundled_demo_data: true has no effect without at least " + "one csv-sourced instrument — the bundled-demo-CSV fallback " + "is only ever consulted by the csv loader." ) return self @@ -543,6 +644,22 @@ def _check_weight_bounds(self) -> PortfolioConfig: ) return self + @model_validator(mode="after") + def _check_volatility_targeting_requires_target_volatility(self) -> PortfolioConfig: + """Reject an implicit target rather than silently defaulting to 12%. + + ``volatility_targeting`` sizes leverage directly off this number -- + a value a user reading the YAML would never see must never drive + real leverage decisions, so it must always be explicit. + """ + if self.allocator == "volatility_targeting" and self.target_volatility is None: + raise ValueError( + "allocator 'volatility_targeting' requires an explicit " + "target_volatility (e.g. 0.12 for 12% annualised) — there is " + "no implicit default." + ) + return self + @model_validator(mode="after") def _warn_if_positions_and_weight_cap_infeasible(self) -> PortfolioConfig: """Warn when the position/weight caps can't reach the gross ceiling. @@ -587,31 +704,26 @@ class BacktestConfig(_StrictModel): initial_capital: float = Field(default=100_000.0, gt=0.0) benchmark_kind: BenchmarkKind = BenchmarkKind.SYMBOL - benchmark_symbol: str | None = None + benchmark: InstrumentConfig | None = Field( + default=None, + description=( + "Benchmark instrument (symbol/source/calendar), only valid when " + "benchmark_kind='symbol'. If its symbol is already a tradable " + "instrument under data.instruments, its source and calendar must " + "match exactly — the already-loaded series is reused rather than " + "downloaded twice." + ), + ) risk_free_rate: float = DEFAULT_RISK_FREE_RATE periods_per_year: int | None = Field(default=None, gt=0) - @field_validator("benchmark_symbol") - @classmethod - def _normalize_and_validate_benchmark_symbol(cls, value: str | None) -> str | None: - """Normalise the benchmark and make it safe as a CSV/cache filename.""" - if value is None: - return None - sym = value.strip().upper() - if not sym: - return None - _validate_path_component(sym, field_name="benchmark_symbol") - return sym - @model_validator(mode="after") def _check_benchmark_configuration(self) -> BacktestConfig: if ( self.benchmark_kind is not BenchmarkKind.SYMBOL - and self.benchmark_symbol is not None + and self.benchmark is not None ): - raise ValueError( - "benchmark_symbol is only valid when benchmark_kind='symbol'." - ) + raise ValueError("benchmark is only valid when benchmark_kind='symbol'.") return self @@ -674,6 +786,83 @@ class ReproducibilityConfig(_StrictModel): random_seed: int = Field(default=42, ge=0) +class StressTestSettings(_StrictModel): + """Toggle for the ``robustness stress-test`` / orchestrator run.""" + + enabled: bool = False + + +class BootstrapSettings(_StrictModel): + """Settings for a block-bootstrap resample of realised returns.""" + + enabled: bool = False + n_iterations: int = Field(default=1000, gt=0) + block_size: int = Field(default=1, gt=0) + + +class PermutationTestSettings(_StrictModel): + """Settings for the random-sign Monte Carlo permutation test.""" + + enabled: bool = False + n_iterations: int = Field(default=1000, gt=0) + + +class SensitivitySettings(_StrictModel): + """Two-parameter sweep for the parameter-sensitivity heatmap. + + ``parameters`` must name exactly two strategy parameters (the sweep's x + and y axes) with their candidate values; unlike ``validation. + parameter_grid``, there is no default here — sensitivity has no + meaningful "no parameters selected" fallback. + """ + + enabled: bool = False + parameters: dict[str, list[Any]] | None = None + + @model_validator(mode="after") + def _check_parameters_shape(self) -> SensitivitySettings: + if self.parameters is None: + if self.enabled: + raise ValueError( + "robustness.sensitivity.enabled is true but parameters is " + "not set -- sensitivity has no meaningful default (unlike " + "validation.parameter_grid), so the x/y axes and their " + "candidate values must be given explicitly." + ) + return self + if len(self.parameters) != 2: + raise ValueError( + "robustness.sensitivity.parameters must name exactly 2 " + f"parameters (the x and y axes), got {len(self.parameters)}." + ) + for name, candidates in self.parameters.items(): + if not name.strip(): + raise ValueError( + "robustness.sensitivity.parameters names must be non-empty strings." + ) + if not candidates: + raise ValueError( + f"robustness.sensitivity.parameters.{name} must " + "contain at least one candidate value." + ) + return self + + +class RobustnessConfig(_StrictModel): + """Optional CLI/dashboard robustness-suite settings (``robustness:``). + + Absent from YAML means every technique stays disabled — running a + backtest or walk-forward is unaffected either way. + """ + + stress_test: StressTestSettings = Field(default_factory=StressTestSettings) + bootstrap: BootstrapSettings = Field(default_factory=BootstrapSettings) + permutation_test: PermutationTestSettings = Field( + default_factory=PermutationTestSettings + ) + sensitivity: SensitivitySettings = Field(default_factory=SensitivitySettings) + + class ExperimentConfig(_StrictModel): """Top-level, reproducible description of a single experiment. @@ -691,6 +880,7 @@ class ExperimentConfig(_StrictModel): reproducibility: ReproducibilityConfig = Field( default_factory=ReproducibilityConfig ) + robustness: RobustnessConfig = Field(default_factory=RobustnessConfig) @field_validator("experiment_name") @classmethod @@ -710,6 +900,7 @@ def _check_component_names(self) -> ExperimentConfig: from quantlab.strategies import ( available_strategies, strategy_parameter_names, + strategy_sweepable_parameter_names, validate_strategy_parameters, ) @@ -746,6 +937,37 @@ def _check_component_names(self) -> ExperimentConfig: **dict(zip(names, values, strict=True)), }, ) + sensitivity_parameters = self.robustness.sensitivity.parameters + if sensitivity_parameters is not None: + # Boolean/structural parameters (e.g. long_only) are excluded: + # sweeping one changes which other parameters are even + # meaningful, so sensitivity treats them as fixed, matching the + # default walk-forward grid's own rule. + accepted = strategy_sweepable_parameter_names(self.strategy.name) + unknown = sorted(set(sensitivity_parameters) - accepted) + if unknown: + raise ValueError( + f"Unknown or unsweepable robustness.sensitivity.parameters " + f"key(s) {unknown} for strategy '{self.strategy.name}'. " + f"Accepted parameters: {sorted(accepted)}." + ) + # Same value-combination check as validation.parameter_grid above: + # a name being sweepable doesn't mean every candidate value (or + # combination across the two axes) is actually valid for this + # strategy (e.g. lookback_period: [0], or a combination this + # strategy's own validator rejects) -- catch it here, at config + # load, rather than only once the sensitivity sweep actually runs. + sensitivity_names = list(sensitivity_parameters) + for values in itertools.product( + *(sensitivity_parameters[name] for name in sensitivity_names) + ): + validate_strategy_parameters( + self.strategy.name, + { + **self.strategy.parameters, + **dict(zip(sensitivity_names, values, strict=True)), + }, + ) # A pairs strategy can trade only symbols present in the loaded universe. if self.strategy.name == "pairs_trading": symbol_a = str(self.strategy.parameters["symbol_a"]).strip().upper() @@ -822,6 +1044,84 @@ def _check_component_names(self) -> ExperimentConfig: ) return self + @model_validator(mode="after") + def _check_mixed_calendars_require_explicit_periods_per_year( + self, + ) -> ExperimentConfig: + """Forbid inferring one annualisation factor from multiple calendars. + + `DataConfig` alone can't see `backtest.periods_per_year`, so this + cross-field check lives here rather than on a sub-config. + """ + calendars = {instrument.calendar for instrument in self.data.instruments} + if len(calendars) > 1 and self.backtest.periods_per_year is None: + raise ValueError( + "Mixed market calendars require an explicit " + "backtest.periods_per_year — QuantLab cannot infer one " + "annualisation factor when instruments trade on different " + f"calendars ({sorted(calendars)})." + ) + return self + + @model_validator(mode="after") + def _check_benchmark_matches_overlapping_instrument(self) -> ExperimentConfig: + """A benchmark that duplicates a tradable symbol must match it exactly. + + Downstream data is keyed by symbol alone, so an inconsistent + source/calendar override for an overlapping benchmark would be + ambiguous — reject it here rather than silently picking one. + """ + benchmark = self.backtest.benchmark + if benchmark is None: + return self + for instrument in self.data.instruments: + if instrument.symbol != benchmark.symbol: + continue + if ( + instrument.source != benchmark.source + or instrument.calendar != benchmark.calendar + ): + raise ValueError( + f"backtest.benchmark symbol {benchmark.symbol!r} is " + f"already a tradable instrument with source=" + f"{instrument.source!r}, calendar={instrument.calendar!r}; " + "the benchmark override must match exactly or be omitted " + "(the tradable instrument's data is then reused automatically)." + ) + break + return self + + @model_validator(mode="after") + def _check_benchmark_frequency_supported_by_its_own_source( + self, + ) -> ExperimentConfig: + """An external benchmark's source must support the configured frequency too. + + `DataConfig._check_frequency_supported_by_every_instrument` only sees + `data.instruments` — a benchmark that reuses a tradable instrument's + data is already covered there (and cross-checked for source/calendar + consistency by `_check_benchmark_matches_overlapping_instrument` + above), but a benchmark outside the tradable universe has its own, + otherwise-unchecked source. Without this, e.g. frequency: '1mo' with + an external Binance benchmark would be silently accepted here only + to fail later, confusingly, at download time. + """ + benchmark = self.backtest.benchmark + if benchmark is None or benchmark.symbol in self.data.symbols: + return self + allowed = compatible_frequencies_for_sources([benchmark.source]) + if self.data.frequency not in allowed: + supported = _SOURCE_SUPPORTED_FREQUENCIES.get( + benchmark.source, set(DataFrequency) + ) + raise ValueError( + f"frequency '{self.data.frequency}' is not supported by " + f"backtest.benchmark's source {benchmark.source!r} (symbol " + f"{benchmark.symbol!r}). Supported frequencies: " + f"{sorted(supported)}." + ) + return self + # ----------------------------------------------------------------- # # Construction helpers # ----------------------------------------------------------------- # @@ -899,14 +1199,23 @@ def periods_per_year(self) -> int: """Resolve annualisation factor. Priority: explicit ``backtest.periods_per_year`` > frequency lookup > - daily default. The frequency lookup distinguishes XNYS sessions from - 24/7 markets. + daily default. The frequency lookup distinguishes 24/7 markets from + session-bound ones, off the calendar every instrument shares — a + validator guarantees a single shared calendar whenever + ``backtest.periods_per_year`` isn't set explicitly. """ if self.backtest.periods_per_year is not None: return self.backtest.periods_per_year + # Local import: avoids a top-level quantlab.data <-> quantlab.config cycle. + from quantlab.data.calendar import is_247, uniform_calendar + + calendar = uniform_calendar( + instrument.calendar for instrument in self.data.instruments + ) + assert calendar is not None # enforced by _check_mixed_calendars_... table = ( CRYPTO_FREQUENCY_TO_PERIODS_PER_YEAR - if self.data.is_247_market + if is_247(calendar) else FREQUENCY_TO_PERIODS_PER_YEAR ) return table.get(self.data.frequency, TRADING_DAYS_PER_YEAR) @@ -916,8 +1225,13 @@ def periods_per_year(self) -> int: # ----------------------------------------------------------------- # @property def data_source(self) -> str: - """Data source identifier (e.g. ``"yahoo"``, ``"binance"``, ``"csv"``).""" - return self.data.source + """Data source label: a single name, or ``"mixed (a, b)"``.""" + sources = sorted( + {str(instrument.source) for instrument in self.data.instruments} + ) + if len(sources) == 1: + return sources[0] + return f"mixed ({', '.join(sources)})" @property def symbols(self) -> list[str]: @@ -962,7 +1276,17 @@ def risk_free_rate(self) -> float: @property def benchmark_symbol(self) -> str | None: """Symbol to compare performance against, if any.""" - return self.backtest.benchmark_symbol + return self.backtest.benchmark.symbol if self.backtest.benchmark else None + + @property + def benchmark_source(self) -> DataSourceName | None: + """Data source of the benchmark instrument, if any.""" + return self.backtest.benchmark.source if self.backtest.benchmark else None + + @property + def benchmark_calendar(self) -> str | None: + """Calendar of the benchmark instrument, if any.""" + return self.backtest.benchmark.calendar if self.backtest.benchmark else None @property def benchmark_kind(self) -> BenchmarkKind: @@ -974,7 +1298,7 @@ def benchmark_label(self) -> str | None: """Human-readable benchmark name, or ``None`` when disabled.""" kind = self.backtest.benchmark_kind if kind is BenchmarkKind.SYMBOL: - return self.backtest.benchmark_symbol + return self.benchmark_symbol if kind is BenchmarkKind.EQUAL_WEIGHT: return "Equal weight" if kind is BenchmarkKind.FIRST_ASSET: diff --git a/src/quantlab/dashboard/app.py b/src/quantlab/dashboard/app.py index fd0d537..0ebfe39 100644 --- a/src/quantlab/dashboard/app.py +++ b/src/quantlab/dashboard/app.py @@ -4,39 +4,72 @@ streamlit run src/quantlab/dashboard/app.py -Lets a user configure an experiment in the sidebar, run the look-ahead-safe -backtest, inspect metrics/charts/trades, run robustness checks and download an -HTML research report. +Lets a user configure an experiment in the sidebar, run the backtest (its +delayed-execution barrier prevents common look-ahead leakage, though a custom +strategy remains responsible for its own causal construction), inspect +metrics/charts/trades, run robustness checks and download an HTML research +report. """ from __future__ import annotations +from collections.abc import Callable from datetime import date -from typing import TYPE_CHECKING, cast +from typing import TYPE_CHECKING, Any, cast import pandas as pd import streamlit as st +from quantlab.config import DataSourceName, compatible_frequencies_for_sources from quantlab.dashboard.components import ( render_charts, + render_exposure_and_cost_charts, + render_gross_net_comparison, render_metric_cards, + render_sensitivity_heatmap, render_trade_table, ) from quantlab.dashboard.state import ( binance_trading_symbols, build_config_from_inputs, default_end_date, + detect_calendar, + detect_source, + estimate_walk_forward_backtest_count, run_dashboard_backtest, + run_dashboard_bootstrap, + run_dashboard_permutation_test, + run_dashboard_sensitivity, run_dashboard_stress_tests, + run_dashboard_walk_forward, + run_dashboard_walk_forward_sensitivity, + run_dashboard_walk_forward_stress_tests, yahoo_common_symbols, ) -from quantlab.logging_config import get_logger -from quantlab.strategies.base import available_strategies +from quantlab.logging_config import configure_logging, get_logger +from quantlab.progress import ProgressReporter +from quantlab.strategies.base import ( + available_strategies, + strategy_parameter_names, + strategy_sweepable_parameter_names, +) +from quantlab.validation.parameter_grid import parse_parameter_grid_values +from quantlab.validation.parameter_sensitivity import ( + infer_sensitivity_parameter_columns, +) if TYPE_CHECKING: from quantlab.backtesting.result import BacktestResult from quantlab.data.base import SymbolSuggestion + from quantlab.validation.walk_forward import WalkForwardResult +# Streamlit runs this file in its own process (`quantlab dashboard` launches +# it via `subprocess.run`; a user can also run `streamlit run` on it +# directly), separate from any process that already called +# configure_logging() -- without this call here too, the dashboard's own +# logger has no handlers attached, so its exceptions/warnings are never +# written to logs/quantlab.log. +configure_logging() logger = get_logger(__name__) st.set_page_config(page_title="QuantLab", page_icon="📈", layout="wide") @@ -87,12 +120,6 @@ def _yahoo_universe_labels() -> dict[str, str]: "Not every symbol is suggested — if yours is missing, type its exact " "ticker and it'll still be accepted." ) -#: Shown whenever mixing symbols across markets is possible (csv and yahoo; -#: Binance is exempt since every pair already shares the same 24/7 calendar). -_MARKET_CALENDAR_NOTE = ( - "One market calendar applies to the entire universe, so every symbol " - "must follow the same trading schedule." -) def _symbols_picker( @@ -101,7 +128,6 @@ def _symbols_picker( default_symbols: tuple[str, ...], *, accept_new_options: bool = False, - warn_market_calendar: bool = False, ) -> list[str]: """A single instant, client-side-filtered dropdown over a preloaded universe. @@ -121,8 +147,6 @@ def _symbols_picker( ) if accept_new_options: help_text += " " + _INCOMPLETE_LIST_NOTE - if warn_market_calendar: - help_text += " " + _MARKET_CALENDAR_NOTE if key not in st.session_state: st.session_state[key] = [ @@ -151,49 +175,122 @@ def _symbols_picker( def _binance_symbols_picker() -> list[str]: - return _symbols_picker( - _binance_universe_labels(), "binance_symbols", ("BTCUSDT", "ETHUSDT") - ) + # Empty by default: all three pickers are visible simultaneously now, and + # a non-empty default here would immediately conflict with CSV's bundled + # demo default below (see `_combine_instrument_picks`). + return _symbols_picker(_binance_universe_labels(), "binance_symbols", ()) def _yahoo_symbols_picker() -> list[str]: return _symbols_picker( _yahoo_universe_labels(), "yahoo_symbols", - ("SPY", "QQQ", "TLT", "GLD"), + (), accept_new_options=True, - warn_market_calendar=True, ) -def _symbol_selectbox( - label_by_symbol: dict[str, str], - key: str, - default_symbol: str, - help_text: str, - *, - accept_new_options: bool = False, -) -> str: - """A single-symbol dropdown over an already-known ``{symbol: label}`` map.""" - if accept_new_options: - help_text += " " + _INCOMPLETE_LIST_NOTE - options = list(label_by_symbol.values()) - default_label = label_by_symbol.get( - default_symbol, options[0] if options else default_symbol +def _csv_symbols_picker() -> list[str]: + raw = st.text_input( + "CSV symbols (comma-separated)", + "SPY, QQQ, TLT, GLD", + help=( + "Local files under data/raw, one CSV per symbol. When 'Allow " + "bundled synthetic demo data' below is enabled, QuantLab falls " + "back to its bundled SPY/QQQ/TLT/GLD demo files if every " + "requested local file is absent." + ), ) - if key not in st.session_state: - st.session_state[key] = default_label - picked_label = st.selectbox( - "Benchmark symbol", - options=options, - key=key, - help=help_text, - accept_new_options=accept_new_options, + return _parse_symbols(raw) + + +def _combine_instrument_picks( + yahoo_symbols: list[str], + binance_symbols: list[str], + csv_symbols: list[str], +) -> tuple[list[str], dict[str, str], list[str]]: + """Merge the three pickers into one ordered, deduplicated symbol list. + + Provenance is the picker a symbol actually came from — never a + heuristic — so the instrument table's Source default is always exact. + A symbol picked from two different pickers is a conflict: never + silently deduplicated (which source/calendar would even apply is + ambiguous), excluded from the returned symbol list and reported + separately so the caller can block submission. + """ + picks: list[tuple[list[str], str]] = [ + (yahoo_symbols, "yahoo"), + (binance_symbols, "binance"), + (csv_symbols, "csv"), + ] + seen_in: dict[str, list[str]] = {} + order: list[str] = [] + for symbols, source_name in picks: + for symbol in symbols: + if symbol not in seen_in: + order.append(symbol) + seen_in.setdefault(symbol, []).append(source_name) + conflicts = [symbol for symbol in order if len(seen_in[symbol]) > 1] + conflict_set = set(conflicts) + provenance = { + symbol: seen_in[symbol][0] for symbol in order if symbol not in conflict_set + } + combined = [symbol for symbol in order if symbol not in conflict_set] + return combined, provenance, conflicts + + +def _instrument_table( + symbols: list[str], provenance: dict[str, str] +) -> list[dict[str, str]]: + """Editable Source/Calendar table, one row per selected symbol. + + Source defaults to the picker the symbol came from (``provenance``) — + never the ``detect_source`` heuristic. Calendar defaults to + ``detect_calendar``'s best guess. Both are editable and rebuilt from + ``symbols`` on every render, so removing a symbol from a picker above + drops its row (and any prior edit) on the next run instead of leaving a + stale entry behind. + """ + overrides: dict[str, dict[str, str]] = st.session_state.get( + "instrument_overrides", {} ) - symbol_by_label = {label: symbol for symbol, label in label_by_symbol.items()} - if picked_label is None: - return "" - return symbol_by_label.get(picked_label, picked_label.strip().upper()) + rows = [] + for symbol in symbols: + saved = overrides.get(symbol, {}) + default_source = saved.get("source") or provenance.get(symbol, "csv") + default_calendar = saved.get("calendar") or ( + detect_calendar(symbol, DataSourceName(default_source)) or "XNYS" + ) + rows.append( + { + "Instrument": symbol, + "Source": default_source, + "Calendar": default_calendar, + } + ) + edited = st.data_editor( + pd.DataFrame(rows, columns=["Instrument", "Source", "Calendar"]), + column_config={ + "Instrument": st.column_config.TextColumn(disabled=True), + "Source": st.column_config.SelectboxColumn( + options=["yahoo", "binance", "csv"], required=True + ), + "Calendar": st.column_config.TextColumn( + required=True, + help="'24/7' for a continuous market, or a pandas_market_calendars " + "name such as XNYS, XHKG, XLON.", + ), + }, + hide_index=True, + width="stretch", + key="instrument_table_editor", + ) + records = cast(list[dict[str, str]], edited.to_dict("records")) + st.session_state["instrument_overrides"] = { + row["Instrument"]: {"source": row["Source"], "calendar": row["Calendar"]} + for row in records + } + return records def _strategy_param_inputs(strategy_name: str, symbols: list[str]) -> dict: @@ -562,9 +659,10 @@ def _strategy_param_inputs(strategy_name: str, symbols: list[str]) -> dict: """ QuantLab turns a financial hypothesis into a reproducible, bias-aware experiment: **data → cleaning & validation → feature functions → signals → - allocation → execution costs → look-ahead-safe accounting → risk metrics + allocation → execution costs → delayed-execution accounting → risk metrics → validation → reporting**. Signals are strictly shifted before returns - to prevent look-ahead bias. + to prevent common look-ahead leakage; a custom strategy remains + responsible for its own causal construction. Source: [github.com/sefaav/QuantLab](https://github.com/sefaav/QuantLab) · [Report an issue](https://github.com/sefaav/QuantLab/issues) @@ -572,23 +670,54 @@ def _strategy_param_inputs(strategy_name: str, symbols: list[str]) -> dict: """ ) +mode = st.segmented_control( + "Mode", + ["Backtest", "Walk-forward"], + default="Backtest", + key="dashboard_mode", + help=( + "Backtest: a single run over the full sample, optionally with a " + "chronological holdout. Walk-forward: repeatedly select parameters " + "on a validation block and evaluate them out-of-sample on the " + "following test block, stitched across the whole history — this is " + "QuantLab's grid-search mechanism." + ), +) +if mode is None: + mode = "Backtest" + # --------------------------------------------------------------------------- # # Sidebar configuration # --------------------------------------------------------------------------- # with st.sidebar: st.header("Experiment configuration") - source = st.selectbox( - "Data source", - ["csv", "yahoo", "binance"], - index=0, - help=( - "csv reads local files from data/raw. A separate opt-in below " - "allows QuantLab's bundled synthetic demo files when every " - "requested local file is absent. yahoo and binance download and " - "locally cache real market data, and need network access." - ), + st.subheader("Instruments") + st.caption( + "Pick symbols from any of the three sources below — they all " + "combine into one multi-market universe." + ) + with st.expander("Yahoo Finance", expanded=False): + yahoo_symbols = _yahoo_symbols_picker() + with st.expander("Binance", expanded=False): + binance_symbols = _binance_symbols_picker() + with st.expander("CSV (local files)", expanded=True): + csv_symbols = _csv_symbols_picker() + + symbols, provenance, conflicts = _combine_instrument_picks( + yahoo_symbols, binance_symbols, csv_symbols ) - if source == "csv": + if conflicts: + st.error( + "Picked from more than one source, so source/calendar would be " + "ambiguous — remove the duplicate from one picker: " + + ", ".join(sorted(conflicts)) + ) + if not symbols: + st.warning("Pick at least one symbol above to configure an instrument.") + + instrument_rows = _instrument_table(symbols, provenance) + use_bundled_demo_data = False + if any(row["Source"] == "csv" for row in instrument_rows): use_bundled_demo_data = st.toggle( "Allow bundled synthetic demo data", value=False, @@ -599,22 +728,34 @@ def _strategy_param_inputs(strategy_name: str, symbols: list[str]) -> dict: "symbols still fail explicitly." ), ) - else: - use_bundled_demo_data = False - if source == "binance": - symbols = _binance_symbols_picker() - elif source == "yahoo": - symbols = _yahoo_symbols_picker() - else: - symbols_raw = st.text_input( - "Symbols (comma-separated)", - "SPY, QQQ, TLT, GLD", - help=( - "Tradable universe. pairs_trading needs at least two symbols " - f"here; its two legs are then picked below. {_MARKET_CALENDAR_NOTE}" - ), + + instrument_calendars = {row["Calendar"] for row in instrument_rows} + periods_per_year: int | None = None + if len(instrument_calendars) > 1: + st.warning( + "Instruments span more than one calendar " + f"({', '.join(sorted(instrument_calendars))}), so QuantLab " + "cannot infer a single annualisation factor automatically — " + "set one explicitly." + ) + # Default to the 24/7 convention as soon as any instrument actually + # trades continuously -- a mixed portfolio that includes one is + # closer to a "always-open" annualisation than a pure business-day + # one, and 252 silently understates volatility/Sharpe for it. + default_periods_per_year = 365 if "24/7" in instrument_calendars else 252 + periods_per_year = int( + st.number_input( + "Periods per year (annualisation factor)", + min_value=1, + value=default_periods_per_year, + step=1, + help=( + "Used to annualise Sharpe, volatility and vol-targeting " + "across the whole portfolio. 252 for a business-day " + "equity convention, 365 for a continuous 24/7 one." + ), + ) ) - symbols = _parse_symbols(symbols_raw) # Sidebar date fields need the full width to keep labels and values readable. start_date = st.date_input( @@ -631,57 +772,96 @@ def _strategy_param_inputs(strategy_name: str, symbols: list[str]) -> dict: help="Requested end of the sample, same caveat as Start date above.", ) - # Offer only frequencies supported by the selected backend. - frequency_options = ( - ["1d", "1h", "1w"] if source == "binance" else ["1d", "1h", "1w", "1mo"] + # Offer only frequencies compatible with every selected instrument's + # source — the same intersection ExperimentConfig itself validates, so + # the picker can never offer something the config would then reject. + instrument_sources = {DataSourceName(row["Source"]) for row in instrument_rows} + frequency_options = sorted(compatible_frequencies_for_sources(instrument_sources)) + # '1h' has no verified-closure handling for a mixed-calendar universe + # (that machinery only operates at daily frequency) -- offering it would + # let the config validator reject the run only after "Run backtest" is + # clicked, so it's excluded here too, matching what ExperimentConfig + # itself would refuse. + intraday_blocked_by_mixed_calendar = ( + len(instrument_calendars) > 1 and "1h" in frequency_options ) + if intraday_blocked_by_mixed_calendar: + frequency_options = [f for f in frequency_options if f != "1h"] frequency = st.selectbox( "Frequency", frequency_options, - index=0, + index=0 if frequency_options else None, help=( "Bar size requested from the data source; also sets the " "annualisation factor used by every risk metric." ), ) - if source == "csv": + if not frequency_options: + st.error( + "No frequency is compatible with every selected source — remove " + "one of the conflicting sources above." + ) + elif intraday_blocked_by_mixed_calendar: + st.caption( + "'1h' is unavailable for a mixed-calendar universe — verified " + "closures only work at daily frequency." + ) + if any(row["Source"] == "csv" for row in instrument_rows): st.caption( "For CSV data, frequency controls annualisation and data-quality " "checks but does not resample the file. A mismatch with the " "observed timestamps is reported after the run." ) - # Yahoo and CSV experiments select a supported calendar explicitly. - market_calendar: str | None - if source in {"csv", "yahoo"}: - market_calendar = st.selectbox( - "Market calendar", - ["XNYS", "24/7"], + with st.expander("Advanced data settings"): + missing_value_policy = st.selectbox( + "Missing value policy", + ["drop", "forward_fill", "raise", "none"], index=0, help=( - "Use 'XNYS' for US equities and ETFs, or '24/7' for continuous " - "markets such as crypto. This controls annualisation, settlement " - "and gap checks." + "How the cleaner treats missing canonical market data bars: " + "drop removes affected rows; forward_fill fills up to the " + "limit below; raise fails the run on any gap; none leaves " + "gaps as-is." ), ) - else: - market_calendar = None - st.caption("Market calendar: implied by Binance (24/7).") - if source in {"csv", "yahoo"}: - st.warning( - "One calendar applies to every symbol. Do not mix markets with " - "different trading schedules (for example AAPL and 1211.HK); " - "run them as separate experiments." - ) + if missing_value_policy == "forward_fill": + forward_fill_limit = st.number_input( + "Forward-fill limit (consecutive bars)", + min_value=1, + value=1, + step=1, + help=( + "Maximum consecutive missing bars filled per symbol " + "before the gap is left as-is." + ), + ) + else: + forward_fill_limit = 1 + + strategy_options = available_strategies() + if mode == "Walk-forward": + # buy_and_hold has no parameters (BuyAndHoldStrategy._freeze_parameters()), + # so there is nothing for fold-by-fold validation-block selection to + # select — walk-forward would just repeat the same signal on every + # fold for no benefit over a single backtest. + strategy_options = [name for name in strategy_options if name != "buy_and_hold"] strategy_name = st.selectbox( "Strategy", - available_strategies(), + strategy_options, index=0, help=( - "Signal-generation method: buy_and_hold (no signal, baseline " - "exposure); time_series_momentum / cross_sectional_momentum " - "(trend continuation); trend_following (moving-average trend); " - "mean_reversion / pairs_trading (reversion to a trailing mean or " - "spread). Its own parameters appear below." + "Signal-generation method: time_series_momentum / " + "cross_sectional_momentum (trend continuation); trend_following " + "(moving-average trend); mean_reversion / pairs_trading " + "(reversion to a trailing mean or spread)." + + ( + "" + if mode == "Walk-forward" + else " buy_and_hold (no signal, baseline exposure) is also " + "available here, but has no parameters to select, so it is " + "hidden in Walk-forward mode." + ) + + " Its own parameters appear below." ), ) @@ -853,45 +1033,238 @@ def _strategy_param_inputs(strategy_name: str, symbols: list[str]) -> dict: target_volatility = None maximum_leverage = 1.0 + if strategy_name == "pairs_trading": + target_minimum_weight = None + maximum_gross_exposure = None + maximum_net_exposure = None + target_maximum_positions = None + maximum_turnover = None + st.caption( + "Advanced portfolio constraints are disabled for pairs_trading: " + "a minimum position size, position count cap, or exposure cap " + "could drop one leg and break the pair hedge." + ) + else: + # Set by the non-pairs_trading branch above whenever this branch runs. + assert maximum_weight is not None + with st.expander("Advanced portfolio constraints"): + if st.checkbox( + "Enable minimum position size", + value=False, + help=( + "Reject any target weight smaller than this instead of " + "holding a near-zero position." + ), + ): + target_minimum_weight = st.slider( + "Minimum position size", + 0.0, + maximum_weight, + min(0.02, maximum_weight), + 0.01, + help="Smallest allowed non-zero target weight per asset.", + ) + else: + target_minimum_weight = None + if st.checkbox( + "Cap gross exposure", + value=False, + help=( + "Limit total absolute exposure (sum of |weight|) across all assets." + ), + ): + maximum_gross_exposure = st.slider( + "Max gross exposure", + 0.1, + 3.0, + 1.0, + 0.1, + help="Ceiling on gross exposure, enforced on top of Max leverage.", + ) + else: + maximum_gross_exposure = None + if st.checkbox( + "Cap net exposure", + value=False, + help="Limit net directional exposure (sum of signed weights).", + ): + maximum_net_exposure = st.slider( + "Max net exposure", + 0.0, + 3.0, + 1.0, + 0.1, + help="Ceiling on |long weight - short weight| across all assets.", + ) + else: + maximum_net_exposure = None + if st.checkbox( + "Cap number of positions", + value=False, + help=( + "Limit how many assets can be held with a non-zero " + "target weight at once." + ), + ): + target_maximum_positions = st.number_input( + "Max number of positions", + min_value=1, + value=min(10, max(1, len(symbols))), + step=1, + help="Largest number of simultaneously non-zero target weights.", + ) + else: + target_maximum_positions = None + if st.checkbox( + "Cap turnover per rebalance", + value=False, + help=( + "Limit how much total weight can change at each " + "rebalance, spreading large shifts over several periods." + ), + ): + maximum_turnover = st.slider( + "Max turnover per rebalance", + 0.05, + 2.0, + 0.5, + 0.05, + help="Maximum L1 weight change allowed at each rebalance.", + ) + else: + maximum_turnover = None + st.subheader("Validation") - enable_holdout = st.checkbox( - "Chronological holdout (train / validation / test)", - value=False, - help=( - "Split one continuous backtest chronologically and report each " - "block separately. No fitting or parameter tuning happens here. " - "Treat the trailing test block as out-of-sample only if you fixed " - "the strategy and parameters before inspecting it; the headline " - "metric cards still describe the full sample." - ), - ) validation_ratio: float | None = None test_ratio: float | None = None - if enable_holdout: - validation_ratio = st.slider( - "Validation fraction", - 0.05, - 0.4, - 0.2, - 0.05, + train_window = 500 + validation_window = 126 + test_window = 126 + expanding = True + optimization_metric = "sharpe" + parameter_grid: dict[str, list] = {} + if mode == "Walk-forward": + st.caption( + "Select parameters on each fold's validation block and evaluate " + "them out-of-sample on the following test block, repeated and " + "stitched across the whole history. This mode's own Results " + "tab shows that stitched out-of-sample evidence, not a " + "full-sample fit." + ) + train_window = st.number_input( + "Train window (periods)", + min_value=10, + value=500, + step=10, + help="Training periods per fold, used to fit the strategy state.", + ) + validation_window = st.number_input( + "Validation window (periods)", + min_value=5, + value=126, + step=5, + help="Validation periods per fold, used to select parameters.", + ) + test_window = st.number_input( + "Test window (periods)", + min_value=5, + value=126, + step=5, + help="Out-of-sample test periods per fold, stitched into the OOS series.", + ) + expanding = st.toggle( + "Expanding training window", + value=True, help=( - "Middle chronological slice reported separately for manual " - "assessment. This dashboard backtest does not tune or select " - "parameters automatically." + "On: each fold's training block grows to include everything " + "before it. Off: training slides forward, always Train " + "window periods long." ), ) - test_ratio = st.slider( - "Test fraction", - 0.05, - 0.4, - 0.2, - 0.05, + optimization_metric = st.selectbox( + "Optimization metric", + ["sharpe", "sortino", "calmar", "total_return"], + index=0, + help="Metric used to pick the best parameter combination on each fold.", + ) + st.caption( + "Parameters to search below — leave empty to use a compact, " + "strategy-specific default grid at run time." + ) + grid_param_names = sorted(strategy_parameter_names(strategy_name)) + selected_grid_params = st.multiselect( + "Grid parameters", + grid_param_names, + help="Strategy parameters to vary across candidate values.", + ) + for parameter_name in selected_grid_params: + raw_values = st.text_input( + f"Candidate values for {parameter_name} (comma-separated)", + key=f"wf_grid_{parameter_name}", + ) + parameter_grid[parameter_name] = parse_parameter_grid_values(raw_values) + # A rough estimate only (used to warn about a slow configuration + # before data is loaded) -- treat the universe as 24/7 only when + # every instrument genuinely is, otherwise fall back to the + # business-day convention. + is_247_market = bool(instrument_rows) and all( + row["Calendar"] == "24/7" for row in instrument_rows + ) + estimated_backtests = estimate_walk_forward_backtest_count( + start_date=start_date, + end_date=end_date or default_end_date(), + is_247_market=is_247_market, + train_window=train_window, + validation_window=validation_window, + test_window=test_window, + expanding=expanding, + parameter_grid=parameter_grid, + ) + if estimated_backtests <= 0: + st.warning( + "No walk-forward fold fits the requested date range and " + "windows — widen the date range or shorten the windows.", + icon="⚠️", + ) + else: + enable_holdout = st.checkbox( + "Chronological holdout (train / validation / test)", + value=False, help=( - "Final chronological slice held out as the out-of-sample " - "test block — its metrics are what the report calls " - "out-of-sample evidence." + "Split one continuous backtest chronologically and report " + "each block separately. No fitting or parameter tuning " + "happens here. Treat the trailing test block as " + "out-of-sample only if you fixed the strategy and " + "parameters before inspecting it; the headline metric " + "cards still describe the full sample." ), ) + if enable_holdout: + validation_ratio = st.slider( + "Validation fraction", + 0.05, + 0.4, + 0.2, + 0.05, + help=( + "Middle chronological slice reported separately for " + "manual assessment. This dashboard backtest does not " + "tune or select parameters automatically." + ), + ) + test_ratio = st.slider( + "Test fraction", + 0.05, + 0.4, + 0.2, + 0.05, + help=( + "Final chronological slice, reported separately as the " + "'Test' block. Genuinely out-of-sample only if the " + "strategy and parameters were fixed before it was ever " + "inspected — this dashboard has no way to verify that." + ), + ) st.subheader("Costs & capital") initial_capital = st.number_input( @@ -933,36 +1306,60 @@ def _strategy_param_inputs(strategy_name: str, symbols: list[str]) -> dict: "configured risk-free rate." ), ) + # The benchmark symbol is itself an instrument (source + calendar), with + # the same provenance rule as the table above: if it duplicates a + # tradable instrument, its source/calendar are reused verbatim rather + # than letting the user configure an inconsistency the config would + # reject anyway (source/calendar must match exactly when they overlap). if benchmark_kind == "symbol": - if source == "binance": - benchmark_symbol = _symbol_selectbox( - _binance_universe_labels(), - "binance_benchmark_symbol", - "BTCUSDT", - "External symbol to compare against — pick from Binance's " - "active spot pairs.", - ) - elif source == "yahoo": - benchmark_symbol = _symbol_selectbox( - _yahoo_universe_labels(), - "yahoo_benchmark_symbol", - "SPY", - "External symbol to compare against — pick from the same " - "bundled list as Symbols above, or type an exact symbol " - f"not in the list. {_MARKET_CALENDAR_NOTE}", - accept_new_options=True, - ) - else: - benchmark_symbol = st.text_input( + benchmark_symbol = ( + st.text_input( "Benchmark symbol", "SPY", - help=( - "External symbol to download and compare against, e.g. " - f"SPY. {_MARKET_CALENDAR_NOTE}" + help="External symbol to compare the strategy against.", + ) + .strip() + .upper() + ) + matching_instrument = next( + (row for row in instrument_rows if row["Instrument"] == benchmark_symbol), + None, + ) + if matching_instrument is not None: + benchmark_source = matching_instrument["Source"] + benchmark_calendar = matching_instrument["Calendar"] + st.caption( + f"{benchmark_symbol} is already a tradable instrument — its " + f"source ({benchmark_source}) and calendar " + f"({benchmark_calendar}) are reused as-is." + ) + elif benchmark_symbol: + detected_source = detect_source(benchmark_symbol) + source_options = ["yahoo", "binance", "csv"] + benchmark_source = st.selectbox( + "Benchmark source", + source_options, + index=source_options.index( + detected_source.value if detected_source else "csv" ), + key="benchmark_source_select", + help="Data source for the external benchmark symbol.", ) + benchmark_calendar = st.text_input( + "Benchmark calendar", + detect_calendar(benchmark_symbol, DataSourceName(benchmark_source)) + or "XNYS", + key="benchmark_calendar_input", + help="'24/7' for a continuous market, or a " + "pandas_market_calendars name such as XNYS, XHKG, XLON.", + ) + else: + benchmark_source = "csv" + benchmark_calendar = "XNYS" else: benchmark_symbol = "" + benchmark_source = "csv" + benchmark_calendar = "XNYS" if benchmark_kind == "first_asset": first_symbol = symbols[0] if symbols else "the first universe symbol" st.caption(f"Benchmark asset: {first_symbol}") @@ -993,21 +1390,157 @@ def _strategy_param_inputs(strategy_name: str, symbols: list[str]) -> dict: 0.5, help=( "Additional execution cost beyond commission and spread, " - "modelling market impact. Constant here; a volume-based model " - "scaling with trade size is available via the Python API." + "modelling market impact under the constant slippage model " + "below." ), ) + with st.expander("Advanced execution settings"): + slippage_model = st.selectbox( + "Slippage model", + ["constant", "volume"], + index=0, + help=( + "constant applies the slippage bps above uniformly to every " + "trade. volume instead scales slippage with each trade's " + "size relative to average daily volume, using the impact " + "coefficient below." + ), + ) + if slippage_model == "volume": + impact_coefficient = st.number_input( + "Volume impact coefficient", + min_value=0.0, + value=0.1, + step=0.01, + help=( + "Multiplies sqrt(order size / average daily volume) — " + "added on top of the slippage bps above. For liquid " + "instruments (e.g. SPY, QQQ) and a modest position size " + "relative to their average daily volume, that square " + "root is tiny, so even a large coefficient can leave " + "results looking identical to the constant model — this " + "term is built to matter for large orders in thin " + "markets, not small ones in deep markets." + ), + ) + else: + impact_coefficient = 0.1 + + submission_blocked = bool(conflicts) or not symbols or not frequency_options + if mode == "Walk-forward": + run = st.button( + "Run walk-forward", + type="primary", + width="stretch", + disabled=submission_blocked, + ) + else: + run = st.button( + "Run backtest", + type="primary", + width="stretch", + disabled=submission_blocked, + ) + + +def _run_and_store( + session_key: str, + label: str, + compute: Callable[[Callable[[int, int], None]], Any], +) -> None: + """Run one robustness technique, storing its result or showing the error. + + Shared by every individual "Run X" button and the "Run all" button below + it, so there is exactly one place each technique's on-demand execution + happens — no separate logic path for the bulk button. ``compute`` + receives a progress callback; functions that don't report progress + (bootstrap, permutation — genuinely fast, resampling only — and the + Backtest-mode plain sensitivity variant) simply ignore it, so the bar + sits at an indeterminate 0% for their duration instead of stepping + through counts. + """ + st.session_state.pop(session_key, None) + st.session_state.pop("report_html", None) + st.session_state.pop("wf_report_html", None) + title = f"{label[0].upper()}{label[1:]}" + progress_bar = st.progress(0.0, text=f"{title}: starting…") + try: + st.session_state[session_key] = compute( + _make_progress_callback(progress_bar, title) + ) + except Exception as exc: + logger.exception("Dashboard %s failed", label) + st.error(f"{title} failed: {exc}") + finally: + progress_bar.empty() + + +def _make_progress_callback( + progress_bar: Any, title: str +) -> Callable[[int, int], None]: + """Build an ``on_progress(done, total)`` callback driving a live progress bar. + + Text/ETA come from a shared `ProgressReporter` (also used by the CLI's + terminal progress line, for the same estimate on both interfaces) — this + function only renders it into the Streamlit widget. + """ + reporter = ProgressReporter(title) + + def _on_progress(done: int, total: int) -> None: + progress_bar.progress( + reporter.fraction(done, total), text=reporter.text(done, total) + ) + + return _on_progress + + +def _render_bootstrap_interpretation() -> None: + """Explain how to read the bootstrap summary table's columns.""" + st.caption( + "How to read this: p05/p95 form a 90% interval across resamples of " + "these same, already-realised returns. If a statistic's p05 sits on " + "the wrong side of zero (e.g. a negative CAGR or Sharpe), ordinary " + "resampling variation in this exact history could plausibly have " + "produced a loss — the result isn't robust to resampling yet, " + "regardless of how good the point estimate looks." + ) + + +def _render_permutation_interpretation(n_iterations: int) -> None: + """Explain how to read the permutation test's p-value.""" + floor = 1.0 / (n_iterations + 1) + st.caption( + "How to read this: the p-value is the fraction of random-sign " + "permutations whose Sharpe matched or beat the real one. Below " + "~0.05 is the conventional threshold for treating the result as " + f"unlikely under the no-edge null. With {n_iterations} iterations, " + f"the p-value can't go below {floor:.4f} — landing there just means " + "none of the permutations beat the real Sharpe, not that the edge " + "is certain; more iterations would refine the number further." + ) + - run = st.button("Run backtest", type="primary", width="stretch") +def _expected_data_hash(result: BacktestResult) -> str: + """Return the displayed result's data hash, or fail loudly if missing.""" + data_hash = result.metadata.get("data_hash") + if not isinstance(data_hash, str): + raise RuntimeError( + "The displayed result has no valid data hash. Run it again " + "before running this check." + ) + return data_hash def _render_robustness_tab(result: BacktestResult) -> None: - """Render chronological holdout evidence and on-demand stress tests.""" + """Render chronological holdout evidence and on-demand robustness checks.""" holdout_report = result.metadata.get("holdout_report") st.markdown("#### Chronological holdout (train / validation / test)") if holdout_report: - # Two-way train/test holdouts omit the validation row. - blocks = [("Train", "train"), ("Test (out-of-sample)", "test")] + # Two-way train/test holdouts omit the validation row. Labeled + # plainly "Test", not "out-of-sample": whether it's genuinely OOS + # depends on parameters having been fixed before looking at it, a + # property of the user's own workflow this table can't verify. + blocks = [("Train", "train"), ("Test", "test")] if "validation_metrics" in holdout_report: blocks.insert(1, ("Validation", "validation")) rows = [ @@ -1059,22 +1592,13 @@ def _render_robustness_tab(result: BacktestResult) -> None: "report." ) if st.button("Run stress tests"): - st.session_state.pop("stress_tests", None) - st.session_state.pop("report_html", None) - with st.spinner("Running stress-test scenarios…"): - try: - expected_data_hash = result.metadata.get("data_hash") - if not isinstance(expected_data_hash, str): - raise RuntimeError( - "The displayed result has no valid data hash. " - "Run the backtest again before running stress tests." - ) - st.session_state["stress_tests"] = run_dashboard_stress_tests( - result.config, expected_data_hash - ) - except Exception as exc: - logger.exception("Dashboard stress tests failed") - st.error(f"Stress tests failed: {exc}") + _run_and_store( + "stress_tests", + "stress tests", + lambda progress: run_dashboard_stress_tests( + result.config, _expected_data_hash(result), on_progress=progress + ), + ) stress = st.session_state.get("stress_tests") if stress is not None: st.dataframe( @@ -1094,52 +1618,630 @@ def _render_robustness_tab(result: BacktestResult) -> None: }, ) + st.markdown("#### Bootstrap") + st.caption( + "Resamples the realised returns (block bootstrap) into a " + "distribution of plausible CAGR/Sharpe/drawdown/final-value " + "outcomes. Resamples already-realised returns only — no strategy " + "re-run, no parameter optimization." + ) + bootstrap_n_iterations = st.number_input( + "Bootstrap iterations", + min_value=100, + value=1000, + step=100, + key="bt_bootstrap_n", + ) + bootstrap_block_size = st.number_input( + "Block size", + min_value=1, + value=1, + step=1, + key="bt_bootstrap_block", + help="Consecutive-period block length; 1 resamples individual periods.", + ) + if st.button("Run bootstrap"): + _run_and_store( + "bootstrap_summary", + "bootstrap", + lambda _progress: run_dashboard_bootstrap( + result.config, + result.returns, + n_iterations=bootstrap_n_iterations, + block_size=bootstrap_block_size, + ), + ) + bootstrap_summary = st.session_state.get("bootstrap_summary") + if bootstrap_summary is not None: + st.dataframe(bootstrap_summary, width="stretch", hide_index=True) + _render_bootstrap_interpretation() + + st.markdown("#### Permutation Monte Carlo") + st.caption( + "Randomly flips the sign of excess returns to test the realised " + "Sharpe against a no-edge random-sign null. A low p-value is " + "evidence against that specific null, not a probability of future " + "profitability." + ) + permutation_n_iterations = st.number_input( + "Permutation iterations", + min_value=100, + value=1000, + step=100, + key="bt_permutation_n", + ) + if st.button("Run permutation test"): + _run_and_store( + "permutation_test", + "permutation test", + lambda _progress: run_dashboard_permutation_test( + result.config, result.returns, n_iterations=permutation_n_iterations + ), + ) + permutation = st.session_state.get("permutation_test") + if permutation is not None: + perm_cols = st.columns(2) + perm_cols[0].metric("Real Sharpe", f"{permutation['real_sharpe']:.2f}") + perm_cols[1].metric("p-value", f"{permutation['p_value']:.4f}") + _render_permutation_interpretation(int(permutation["n_iterations"])) + + st.markdown("#### Parameter sensitivity") + st.caption( + "Re-runs the backtest across a 2-parameter grid to show how " + "sensitive the result is to the exact parameter choice. Boolean/" + "structural parameters (e.g. long_only) aren't offered — they " + "change which other parameters are even meaningful, so sweeping " + "them isn't well-defined for a 2D heatmap." + ) + sensitivity_param_names = sorted( + strategy_sweepable_parameter_names(result.config.strategy_name) + ) + sens_col1, sens_col2 = st.columns(2) + with sens_col1: + sensitivity_x = st.selectbox( + "Parameter (x-axis)", sensitivity_param_names, key="bt_sens_x" + ) + sensitivity_x_values = st.text_input( + "Candidate values (x, comma-separated)", key="bt_sens_x_values" + ) + with sens_col2: + remaining_params = [p for p in sensitivity_param_names if p != sensitivity_x] + sensitivity_y = st.selectbox( + "Parameter (y-axis)", remaining_params, key="bt_sens_y" + ) + sensitivity_y_values = st.text_input( + "Candidate values (y, comma-separated)", key="bt_sens_y_values" + ) + sensitivity_ready = bool( + sensitivity_x + and sensitivity_y + and sensitivity_x_values + and sensitivity_y_values + ) + + def _run_sensitivity() -> None: + _run_and_store( + "sensitivity", + "parameter sensitivity", + lambda _progress: run_dashboard_sensitivity( + result.config, + _expected_data_hash(result), + sensitivity_x, + parse_parameter_grid_values(sensitivity_x_values), + sensitivity_y, + parse_parameter_grid_values(sensitivity_y_values), + ), + ) + + if st.button("Run parameter sensitivity", disabled=not sensitivity_ready): + _run_sensitivity() + sensitivity = st.session_state.get("sensitivity") + if sensitivity is not None: + # Read the axes back off the result itself, not the (possibly since + # changed) sidebar selection above -- otherwise changing the axis + # pickers after a run without re-running would render a stale + # result under mismatched labels, or crash pivoting on a column the + # stored result never had. + used_x, used_y = infer_sensitivity_parameter_columns(sensitivity) + if (used_x, used_y) != (sensitivity_x, sensitivity_y): + st.caption( + f"Showing the last run's axes ({used_x} / {used_y}) — " + "the pickers above have changed since. Run again to update." + ) + render_sensitivity_heatmap(st, sensitivity, used_x, used_y) + + st.divider() + if st.button("Run all robustness tests", type="secondary"): + _run_and_store( + "stress_tests", + "stress tests", + lambda progress: run_dashboard_stress_tests( + result.config, _expected_data_hash(result), on_progress=progress + ), + ) + _run_and_store( + "bootstrap_summary", + "bootstrap", + lambda _progress: run_dashboard_bootstrap( + result.config, + result.returns, + n_iterations=bootstrap_n_iterations, + block_size=bootstrap_block_size, + ), + ) + _run_and_store( + "permutation_test", + "permutation test", + lambda _progress: run_dashboard_permutation_test( + result.config, result.returns, n_iterations=permutation_n_iterations + ), + ) + if sensitivity_ready: + _run_sensitivity() + else: + st.caption( + "Skipped parameter sensitivity: pick both parameters and " + "candidate values above first." + ) + st.rerun() + + +def _render_walk_forward_robustness_tab(wf: WalkForwardResult) -> None: + """Render per-fold selection evidence and on-demand robustness checks. + + Stress tests and parameter sensitivity here always re-run the whole + walk-forward selection process per scenario/cell + (``run_dashboard_walk_forward_stress_tests`` / + ``run_dashboard_walk_forward_sensitivity``) rather than reuse Backtest + mode's plain-backtest variants — this tab must never silently show + numbers from a different validation method than the one in effect. + """ + oos_result = wf.oos_result + assert oos_result is not None # guarded by _execute_walk_forward + + st.markdown("#### Fold summary") + st.caption( + "Selected parameters and realised metrics for each walk-forward " + "fold's out-of-sample test block." + ) + st.dataframe( + wf.summary_table(), + width="stretch", + hide_index=True, + column_config={ + "test_return": st.column_config.NumberColumn(format="percent"), + "test_sharpe": st.column_config.NumberColumn(format="%.2f"), + "validation_score": st.column_config.NumberColumn(format="%.3f"), + }, + ) + + st.markdown("#### Parameter stability across folds") + stability = wf.parameter_stability() + if stability: + st.caption( + "Coefficient of variation of each selected numeric parameter " + "across folds — lower means walk-forward selection was more " + "consistent, though this alone does not establish robustness." + ) + st.dataframe( + pd.DataFrame( + { + "parameter": list(stability), + "coefficient_of_variation": list(stability.values()), + } + ), + width="stretch", + hide_index=True, + column_config={ + "coefficient_of_variation": st.column_config.NumberColumn( + format="%.3f" + ), + }, + ) + else: + st.info( + "Not enough numeric parameter selections across folds to " + "compute stability (e.g. a single fold, or no grid parameters)." + ) + + st.markdown("#### Stress tests") + st.caption( + "**Commission x2/x5 and slippage x2** re-select parameters under " + "the new costs from a per-candidate weight cache built once for " + "all three — cheap to re-score since signals and portfolio " + "allocation never depend on execution costs, but this still " + "genuinely re-selects, it does not just rescale the baseline's " + "fixed weights. **Execution delay +1** and — with more than 2 " + "symbols — **reduced universe** instead re-run the whole " + "walk-forward process (every fold's validation-block selection, " + "then OOS reconstruction) from scratch, since delay changes the " + "weights themselves and a reduced universe changes signal " + "generation; substantially slower than the three cost-only " + "scenarios. **Best 10 days removed** does not re-run anything — " + "it directly zeroes the 10 best days already in the baseline OOS " + "returns above, since removing realised returns changes no " + "configuration to re-select against." + ) + if st.button("Run stress tests", key="wf_run_stress"): + _run_and_store( + "wf_stress_tests", + "stress tests", + lambda progress: run_dashboard_walk_forward_stress_tests( + oos_result.config, + wf, + _expected_data_hash(oos_result), + on_progress=progress, + ), + ) + wf_stress = st.session_state.get("wf_stress_tests") + if wf_stress is not None: + st.dataframe( + wf_stress, + width="stretch", + hide_index=True, + column_config={ + "scenario": st.column_config.TextColumn("Scenario"), + "total_return": st.column_config.NumberColumn( + "Total return", format="percent" + ), + "cagr": st.column_config.NumberColumn("CAGR", format="percent"), + "sharpe": st.column_config.NumberColumn("Sharpe", format="%.2f"), + "max_drawdown": st.column_config.NumberColumn( + "Max drawdown", format="percent" + ), + }, + ) + + st.markdown("#### Bootstrap") + st.caption( + "Resamples the stitched out-of-sample returns (block bootstrap) — " + "resamples already-realised returns only, so this is exactly as " + "fast as in Backtest mode regardless of the walk-forward cost above." + ) + wf_bootstrap_n_iterations = st.number_input( + "Bootstrap iterations", + min_value=100, + value=1000, + step=100, + key="wf_bootstrap_n", + ) + wf_bootstrap_block_size = st.number_input( + "Block size", min_value=1, value=1, step=1, key="wf_bootstrap_block" + ) + if st.button("Run bootstrap", key="wf_run_bootstrap"): + _run_and_store( + "wf_bootstrap_summary", + "bootstrap", + lambda _progress: run_dashboard_bootstrap( + oos_result.config, + oos_result.returns, + n_iterations=wf_bootstrap_n_iterations, + block_size=wf_bootstrap_block_size, + ), + ) + wf_bootstrap_summary = st.session_state.get("wf_bootstrap_summary") + if wf_bootstrap_summary is not None: + st.dataframe(wf_bootstrap_summary, width="stretch", hide_index=True) + _render_bootstrap_interpretation() + + st.markdown("#### Permutation Monte Carlo") + st.caption( + "Randomly flips the sign of the stitched OOS excess returns to " + "test the realised Sharpe against a no-edge random-sign null." + ) + wf_permutation_n_iterations = st.number_input( + "Permutation iterations", + min_value=100, + value=1000, + step=100, + key="wf_permutation_n", + ) + if st.button("Run permutation test", key="wf_run_permutation"): + _run_and_store( + "wf_permutation_test", + "permutation test", + lambda _progress: run_dashboard_permutation_test( + oos_result.config, + oos_result.returns, + n_iterations=wf_permutation_n_iterations, + ), + ) + wf_permutation = st.session_state.get("wf_permutation_test") + if wf_permutation is not None: + wf_perm_cols = st.columns(2) + wf_perm_cols[0].metric("Real Sharpe", f"{wf_permutation['real_sharpe']:.2f}") + wf_perm_cols[1].metric("p-value", f"{wf_permutation['p_value']:.4f}") + _render_permutation_interpretation(int(wf_permutation["n_iterations"])) + + st.markdown("#### Parameter sensitivity") + st.caption( + "Re-runs the **whole walk-forward process** for each grid cell " + "(the two swept parameters pinned, no further inner optimization) " + "— can be slow: every cell costs roughly a full walk-forward run. " + "Boolean/structural parameters (e.g. long_only) aren't offered — " + "they change which other parameters are even meaningful, so " + "sweeping them isn't well-defined for a 2D heatmap." + ) + wf_sensitivity_param_names = sorted( + strategy_sweepable_parameter_names(oos_result.config.strategy_name) + ) + wf_sens_col1, wf_sens_col2 = st.columns(2) + with wf_sens_col1: + wf_sensitivity_x = st.selectbox( + "Parameter (x-axis)", wf_sensitivity_param_names, key="wf_sens_x" + ) + wf_sensitivity_x_values = st.text_input( + "Candidate values (x, comma-separated)", key="wf_sens_x_values" + ) + with wf_sens_col2: + wf_remaining_params = [ + p for p in wf_sensitivity_param_names if p != wf_sensitivity_x + ] + wf_sensitivity_y = st.selectbox( + "Parameter (y-axis)", wf_remaining_params, key="wf_sens_y" + ) + wf_sensitivity_y_values = st.text_input( + "Candidate values (y, comma-separated)", key="wf_sens_y_values" + ) + wf_sensitivity_ready = bool( + wf_sensitivity_x + and wf_sensitivity_y + and wf_sensitivity_x_values + and wf_sensitivity_y_values + ) + + def _run_wf_sensitivity() -> None: + _run_and_store( + "wf_sensitivity", + "parameter sensitivity", + lambda progress: run_dashboard_walk_forward_sensitivity( + oos_result.config, + _expected_data_hash(oos_result), + wf_sensitivity_x, + parse_parameter_grid_values(wf_sensitivity_x_values), + wf_sensitivity_y, + parse_parameter_grid_values(wf_sensitivity_y_values), + on_progress=progress, + ), + ) + + if st.button( + "Run parameter sensitivity", + key="wf_run_sensitivity", + disabled=not wf_sensitivity_ready, + ): + _run_wf_sensitivity() + wf_sensitivity = st.session_state.get("wf_sensitivity") + if wf_sensitivity is not None: + # See the Backtest-mode sensitivity section above for why the axes + # are read back off the result itself, not the sidebar's current + # (possibly since changed) selection. + used_x, used_y = infer_sensitivity_parameter_columns(wf_sensitivity) + if (used_x, used_y) != (wf_sensitivity_x, wf_sensitivity_y): + st.caption( + f"Showing the last run's axes ({used_x} / {used_y}) — " + "the pickers above have changed since. Run again to update." + ) + render_sensitivity_heatmap(st, wf_sensitivity, used_x, used_y) + + st.divider() + if st.button("Run all robustness tests", key="wf_run_all", type="secondary"): + _run_and_store( + "wf_stress_tests", + "stress tests", + lambda progress: run_dashboard_walk_forward_stress_tests( + oos_result.config, + wf, + _expected_data_hash(oos_result), + on_progress=progress, + ), + ) + _run_and_store( + "wf_bootstrap_summary", + "bootstrap", + lambda _progress: run_dashboard_bootstrap( + oos_result.config, + oos_result.returns, + n_iterations=wf_bootstrap_n_iterations, + block_size=wf_bootstrap_block_size, + ), + ) + _run_and_store( + "wf_permutation_test", + "permutation test", + lambda _progress: run_dashboard_permutation_test( + oos_result.config, + oos_result.returns, + n_iterations=wf_permutation_n_iterations, + ), + ) + if wf_sensitivity_ready: + _run_wf_sensitivity() + else: + st.caption( + "Skipped parameter sensitivity: pick both parameters and " + "candidate values above first." + ) + st.rerun() + + +def _collect_backtest_robustness_evidence() -> tuple[ + dict[str, object], tuple[object, ...] +]: + """Gather every on-demand Backtest-mode robustness result for the report.""" + evidence: dict[str, object] = {} + cache_parts: list[object] = [] + for session_key, label in ( + ("stress_tests", "stress_tests"), + ("bootstrap_summary", "bootstrap"), + ("permutation_test", "permutation_test"), + ("sensitivity", "sensitivity"), + ): + value = st.session_state.get(session_key) + cache_parts.append(id(value) if value is not None else None) + if value is not None: + evidence[label] = value + return evidence, tuple(cache_parts) + + +def _collect_walk_forward_robustness_evidence( + wf: WalkForwardResult, +) -> tuple[dict[str, object], tuple[object, ...]]: + """Gather fold evidence plus every on-demand Walk-forward robustness result.""" + evidence: dict[str, object] = {"walk_forward": wf.summary_table()} + cache_parts: list[object] = [id(wf)] + for session_key, label in ( + ("wf_stress_tests", "stress_tests"), + ("wf_bootstrap_summary", "bootstrap"), + ("wf_permutation_test", "permutation_test"), + ("wf_sensitivity", "sensitivity"), + ): + value = st.session_state.get(session_key) + cache_parts.append(id(value) if value is not None else None) + if value is not None: + evidence[label] = value + return evidence, tuple(cache_parts) + + +def _render_report_tab( + result: BacktestResult, + robustness: dict[str, object] | None, + *, + cache_key_extra: object, + session_key: str, +) -> None: + """Render the HTML report tab, shared by Backtest and Walk-forward modes.""" + st.markdown("### Research report") + cache_key = (id(result), cache_key_extra) + cached_report = cast( + tuple[tuple[int, object], tuple[str, list[str]]] | None, + st.session_state.get(session_key), + ) + if cached_report is not None and cached_report[0] == cache_key: + html, chart_warnings = cached_report[1] + else: + chart_warnings = [] + html = result.to_html(robustness=robustness, warnings=chart_warnings) + st.session_state[session_key] = (cache_key, (html, chart_warnings)) + if chart_warnings: + # Surface individual chart failures without discarding the report. + st.warning( + "Some charts could not be rendered into this report:\n" + + "\n".join(f"- {w}" for w in chart_warnings) + ) + st.download_button( + "Download HTML report", + html.encode("utf-8"), + file_name=f"{result.config.experiment_name}_report.html", + mime="text/html", + ) + st.iframe(html, height=800) + # --------------------------------------------------------------------------- # # Run and results # --------------------------------------------------------------------------- # def _collect_inputs() -> dict: """Return the current sidebar values used to build the experiment config.""" - return { + instruments = [ + { + "symbol": row["Instrument"], + "source": row["Source"], + "calendar": row["Calendar"], + } + for row in instrument_rows + ] + benchmark = ( + { + "symbol": benchmark_symbol, + "source": benchmark_source, + "calendar": benchmark_calendar, + } + if benchmark_kind == "symbol" and benchmark_symbol + else None + ) + inputs: dict = { "experiment_name": f"dashboard_{strategy_name}", - "source": source, + "instruments": instruments, "use_bundled_demo_data": use_bundled_demo_data, - "symbols": symbols, "start_date": start_date, "end_date": end_date or default_end_date(), "frequency": frequency, - "market_calendar": market_calendar, + "missing_value_policy": missing_value_policy, + "forward_fill_limit": forward_fill_limit, "strategy_name": strategy_name, "strategy_parameters": strategy_parameters, "allocator": allocator, "maximum_weight": maximum_weight, "long_only": long_only, + "target_minimum_weight": target_minimum_weight, + "maximum_gross_exposure": maximum_gross_exposure, + "maximum_net_exposure": maximum_net_exposure, + "target_maximum_positions": target_maximum_positions, + "maximum_turnover": maximum_turnover, "target_volatility": target_volatility, "volatility_window": volatility_window, "maximum_leverage": maximum_leverage, "rebalance_frequency": rebalance_frequency, - "validation_ratio": validation_ratio, - "test_ratio": test_ratio, "initial_capital": initial_capital, "benchmark_kind": benchmark_kind, - "benchmark_symbol": benchmark_symbol, + "benchmark": benchmark, + "periods_per_year": periods_per_year, "risk_free_rate": risk_free_rate_percent / 100.0, "commission_bps": commission_bps, "spread_bps": spread_bps, "slippage_bps": slippage_bps, + "slippage_model": slippage_model, + "impact_coefficient": impact_coefficient, } + if mode == "Walk-forward": + inputs["validation_method"] = "walk_forward" + inputs["train_window"] = train_window + inputs["validation_window"] = validation_window + inputs["test_window"] = test_window + inputs["expanding"] = expanding + inputs["optimization_metric"] = optimization_metric + inputs["parameter_grid"] = parameter_grid + else: + inputs["validation_ratio"] = validation_ratio + inputs["test_ratio"] = test_ratio + return inputs -def _clear_result_state() -> None: +def _clear_backtest_result_state() -> None: """Remove artefacts that no longer describe a successful backtest.""" - for key in ("result", "result_inputs", "warnings", "stress_tests", "report_html"): + for key in ( + "result", + "result_inputs", + "warnings", + "stress_tests", + "bootstrap_summary", + "permutation_test", + "sensitivity", + "report_html", + ): st.session_state.pop(key, None) -def _execute() -> None: +def _clear_walk_forward_result_state() -> None: + """Remove artefacts that no longer describe a successful walk-forward run.""" + for key in ( + "wf_result", + "wf_result_inputs", + "wf_warnings", + "wf_stress_tests", + "wf_bootstrap_summary", + "wf_permutation_test", + "wf_sensitivity", + "wf_report_html", + ): + st.session_state.pop(key, None) + + +def _execute_backtest() -> None: inputs = _collect_inputs() - _clear_result_state() - with st.spinner("Running look-ahead-safe backtest…"): + _clear_backtest_result_state() + with st.spinner("Running backtest…"): try: config = build_config_from_inputs(inputs) result, warnings = run_dashboard_backtest(config) @@ -1153,79 +2255,151 @@ def _execute() -> None: st.session_state["warnings"] = warnings +def _execute_walk_forward() -> None: + inputs = _collect_inputs() + _clear_walk_forward_result_state() + progress_bar = st.progress(0.0, text="Walk-forward: starting…") + try: + config = build_config_from_inputs(inputs) + wf, warnings = run_dashboard_walk_forward( + config, + on_progress=_make_progress_callback(progress_bar, "Walk-forward"), + ) + except Exception as exc: + logger.exception("Dashboard walk-forward failed") + st.error(f"Walk-forward failed: {exc}") + return + finally: + progress_bar.empty() + if wf.oos_result is None: + st.error( + "No walk-forward fold fit the requested date range and " + "windows — widen the date range or shorten the windows." + ) + return + + st.session_state["wf_result"] = wf + st.session_state["wf_result_inputs"] = inputs + st.session_state["wf_warnings"] = warnings + + if run: - _execute() + if mode == "Walk-forward": + _execute_walk_forward() + else: + _execute_backtest() -result = st.session_state.get("result") -if result is None: - st.info("Configure an experiment in the sidebar and click **Run backtest**.") -else: - # Warn when the current controls no longer describe the saved result. - if _collect_inputs() != st.session_state.get("result_inputs"): - st.warning( - "Sidebar configuration has changed since this result was " - "computed — click **Run backtest** to refresh it.", - icon="⚠️", +if mode == "Walk-forward": + wf = st.session_state.get("wf_result") + if wf is None: + st.info( + "Configure an experiment in the sidebar and click **Run walk-forward**." ) - data_warnings = st.session_state.get("warnings", []) - frequency_warnings = [ - w for w in data_warnings if "does not match the declared frequency" in w - ] - other_warnings = [w for w in data_warnings if w not in frequency_warnings] - if frequency_warnings: - # Frequency mismatches invalidate all annualised metrics. - st.error( - "**Frequency mismatch detected** — the metrics below use the " - "wrong annualisation factor and should not be trusted:\n" - + "\n".join(f"- {w}" for w in frequency_warnings), - icon="🚫", - ) - for warning in other_warnings: - st.caption(f"⚠️ {warning}") - - # Dynamic tabs render only the selected tab; the stable key also supports tests. - tab_results, tab_trades, tab_robustness, tab_report = st.tabs( - ["Results", "Trades", "Robustness", "Report"], - on_change="rerun", - key="dashboard_active_tab", - ) - if tab_results.open: - with tab_results: - render_metric_cards(st, result) - render_charts(st, result) - if tab_trades.open: - with tab_trades: - render_trade_table(st, result) - if tab_robustness.open: - with tab_robustness: - _render_robustness_tab(result) - if tab_report.open: - with tab_report: - st.markdown("### Research report") - # Include current stress evidence and avoid rebuilding unchanged HTML. - stress = st.session_state.get("stress_tests") - robustness = {"stress_tests": stress} if stress is not None else None - cache_key = (id(result), id(stress) if stress is not None else None) - cached_report = cast( - tuple[tuple[int, int | None], tuple[str, list[str]]] | None, - st.session_state.get("report_html"), + else: + oos_result = wf.oos_result + assert oos_result is not None # guarded by _execute_walk_forward + if _collect_inputs() != st.session_state.get("wf_result_inputs"): + st.warning( + "Sidebar configuration has changed since this result was " + "computed — click **Run walk-forward** to refresh it.", + icon="⚠️", ) - if cached_report is not None and cached_report[0] == cache_key: - html, chart_warnings = cached_report[1] - else: - chart_warnings = [] - html = result.to_html(robustness=robustness, warnings=chart_warnings) - st.session_state["report_html"] = (cache_key, (html, chart_warnings)) - if chart_warnings: - # Surface individual chart failures without discarding the report. - st.warning( - "Some charts could not be rendered into this report:\n" - + "\n".join(f"- {w}" for w in chart_warnings) + data_warnings = st.session_state.get("wf_warnings", []) + frequency_warnings = [ + w for w in data_warnings if "does not match the declared frequency" in w + ] + other_warnings = [w for w in data_warnings if w not in frequency_warnings] + if frequency_warnings: + st.error( + "**Frequency mismatch detected** — the metrics below use " + "the wrong annualisation factor and should not be " + "trusted:\n" + "\n".join(f"- {w}" for w in frequency_warnings), + icon="🚫", + ) + for warning in other_warnings: + st.caption(f"⚠️ {warning}") + + tab_results, tab_trades, tab_robustness, tab_report = st.tabs( + ["Results", "Trades", "Robustness", "Report"], + on_change="rerun", + key="dashboard_active_tab", + ) + if tab_results.open: + with tab_results: + render_metric_cards(st, oos_result) + render_charts(st, oos_result) + render_gross_net_comparison(st, oos_result) + render_exposure_and_cost_charts(st, oos_result) + if tab_trades.open: + with tab_trades: + render_trade_table(st, oos_result) + if tab_robustness.open: + with tab_robustness: + _render_walk_forward_robustness_tab(wf) + if tab_report.open: + with tab_report: + wf_robustness, wf_cache_parts = ( + _collect_walk_forward_robustness_evidence(wf) + ) + _render_report_tab( + oos_result, + wf_robustness, + cache_key_extra=wf_cache_parts, + session_key="wf_report_html", ) - st.download_button( - "Download HTML report", - html.encode("utf-8"), - file_name=f"{result.config.experiment_name}_report.html", - mime="text/html", +else: + result = st.session_state.get("result") + if result is None: + st.info("Configure an experiment in the sidebar and click **Run backtest**.") + else: + # Warn when the current controls no longer describe the saved result. + if _collect_inputs() != st.session_state.get("result_inputs"): + st.warning( + "Sidebar configuration has changed since this result was " + "computed — click **Run backtest** to refresh it.", + icon="⚠️", ) - st.iframe(html, height=800) + data_warnings = st.session_state.get("warnings", []) + frequency_warnings = [ + w for w in data_warnings if "does not match the declared frequency" in w + ] + other_warnings = [w for w in data_warnings if w not in frequency_warnings] + if frequency_warnings: + # Frequency mismatches invalidate all annualised metrics. + st.error( + "**Frequency mismatch detected** — the metrics below use " + "the wrong annualisation factor and should not be " + "trusted:\n" + "\n".join(f"- {w}" for w in frequency_warnings), + icon="🚫", + ) + for warning in other_warnings: + st.caption(f"⚠️ {warning}") + + # Dynamic tabs render only the selected tab; the stable key also + # supports tests. + tab_results, tab_trades, tab_robustness, tab_report = st.tabs( + ["Results", "Trades", "Robustness", "Report"], + on_change="rerun", + key="dashboard_active_tab", + ) + if tab_results.open: + with tab_results: + render_metric_cards(st, result) + render_charts(st, result) + render_gross_net_comparison(st, result) + render_exposure_and_cost_charts(st, result) + if tab_trades.open: + with tab_trades: + render_trade_table(st, result) + if tab_robustness.open: + with tab_robustness: + _render_robustness_tab(result) + if tab_report.open: + with tab_report: + bt_robustness, bt_cache_parts = _collect_backtest_robustness_evidence() + _render_report_tab( + result, + bt_robustness or None, + cache_key_extra=bt_cache_parts, + session_key="report_html", + ) diff --git a/src/quantlab/dashboard/components.py b/src/quantlab/dashboard/components.py index 0c07707..ad7fa34 100644 --- a/src/quantlab/dashboard/components.py +++ b/src/quantlab/dashboard/components.py @@ -59,6 +59,79 @@ def formatted_metric(key: str, spec: str) -> str: cols[i % 4].metric(label, value, help=help_text) +def render_gross_net_comparison(st: Any, result: BacktestResult) -> None: + """Render gross-vs-net performance and cost drag.""" + comparison = result.gross_net_comparison() + + def fmt_pct(key: str) -> str: + value = comparison.get(key) + return f"{value:.2%}" if value is not None and np.isfinite(value) else "n/a" + + def fmt_num(key: str) -> str: + value = comparison.get(key) + return f"{value:.2f}" if value is not None and np.isfinite(value) else "n/a" + + st.markdown("#### Gross vs Net") + cards = [ + ("Net total return", fmt_pct("net_total_return"), None), + ("Gross total return", fmt_pct("gross_total_return"), None), + ( + "Cost drag", + fmt_pct("cost_drag"), + "Gross minus net total return — the cumulative performance " + "given up to trading costs.", + ), + ("Net Sharpe", fmt_num("net_sharpe"), None), + ("Gross Sharpe", fmt_num("gross_sharpe"), None), + ] + cols = st.columns(5) + for i, (label, value, help_text) in enumerate(cards): + cols[i].metric(label, value, help=help_text) + + +def render_sensitivity_heatmap( + st: Any, + sensitivity: pd.DataFrame, + parameter_x: str, + parameter_y: str, + metric: str = "sharpe", +) -> None: + """Render a parameter-sensitivity sweep as a Plotly heatmap. + + Shared by Backtest and Walk-forward mode: both feed this the same shape + of ``sensitivity`` DataFrame (from ``run_parameter_sensitivity`` or its + walk-forward-aware variant), so only the data source differs upstream. + """ + import plotly.graph_objects as go + + from quantlab.validation.parameter_sensitivity import sensitivity_heatmap_data + + failed = int((sensitivity["status"] == "failed").sum()) if len(sensitivity) else 0 + if failed: + st.caption( + f"{failed} of {len(sensitivity)} combination(s) failed and are " + "excluded from the heatmap below." + ) + heatmap = sensitivity_heatmap_data(sensitivity, parameter_x, parameter_y, metric) + fig = go.Figure( + go.Heatmap( + z=heatmap.to_numpy(), + x=[str(v) for v in heatmap.columns], + y=[str(v) for v in heatmap.index], + colorscale="RdYlGn", + colorbar={"title": metric}, + ) + ) + fig.update_layout( + title=f"Sensitivity: {metric} by {parameter_x} / {parameter_y}", + xaxis_title=parameter_x, + yaxis_title=parameter_y, + height=380, + ) + st.plotly_chart(fig, width="stretch") + st.dataframe(sensitivity, width="stretch", hide_index=True) + + def _line(x: Any, y: Any, name: str, color: str, dash: str | None = None) -> Any: import plotly.graph_objects as go @@ -139,15 +212,6 @@ def render_charts(st: Any, result: BacktestResult) -> None: col3, col4 = st.columns(2) - # Exposure. - gross = gross_exposure_series(result.positions) - net = net_exposure_series(result.positions) - fig_exp = go.Figure() - fig_exp.add_trace(_line(gross.index, gross.to_numpy(), "Gross", STRATEGY)) - fig_exp.add_trace(_line(net.index, net.to_numpy(), "Net", ACCENT)) - fig_exp.update_layout(title="Gross / net exposure", height=300) - col3.plotly_chart(fig_exp, width="stretch") - # Turnover. if result.turnover is not None: fig_to = go.Figure( @@ -158,18 +222,7 @@ def render_charts(st: Any, result: BacktestResult) -> None: ) ) fig_to.update_layout(title="Turnover", height=300) - col4.plotly_chart(fig_to, width="stretch") - - col5, col6 = st.columns(2) - - # Cumulative costs. - if "total" in result.costs.columns: - cum = result.costs["total"].cumsum() - fig_cost = go.Figure( - go.Scatter(x=cum.index, y=cum.to_numpy(), line={"color": NEGATIVE}) - ) - fig_cost.update_layout(title="Cumulative cost (fraction)", height=300) - col5.plotly_chart(fig_cost, width="stretch") + col3.plotly_chart(fig_to, width="stretch") # Same adaptive window and formula as the HTML report's rolling charts. window = adaptive_rolling_window(len(rets)) @@ -182,9 +235,9 @@ def render_charts(st: Any, result: BacktestResult) -> None: ) ) fig_rs.update_layout(title=f"Rolling Sharpe ({window}p)", height=300) - col6.plotly_chart(fig_rs, width="stretch") + col4.plotly_chart(fig_rs, width="stretch") - col7, col8 = st.columns(2) + col5, col6 = st.columns(2) # Rolling volatility. roll_vol = rets.rolling(window).std(ddof=1) * np.sqrt(ppy) @@ -192,14 +245,14 @@ def render_charts(st: Any, result: BacktestResult) -> None: go.Scatter(x=roll_vol.index, y=roll_vol.to_numpy(), line={"color": BENCHMARK}) ) fig_rv.update_layout(title=f"Rolling volatility ({window}p)", height=300) - col7.plotly_chart(fig_rv, width="stretch") + col5.plotly_chart(fig_rv, width="stretch") # Return distribution. fig_hist = go.Figure( go.Histogram(x=rets.dropna().to_numpy(), nbinsx=50, marker_color=STRATEGY) ) fig_hist.update_layout(title="Return distribution", height=300) - col8.plotly_chart(fig_hist, width="stretch") + col6.plotly_chart(fig_hist, width="stretch") # Positions over time. fig_pos = go.Figure() @@ -217,6 +270,29 @@ def render_charts(st: Any, result: BacktestResult) -> None: st.plotly_chart(fig_pos, width="stretch") +def render_exposure_and_cost_charts(st: Any, result: BacktestResult) -> None: + """Render gross/net exposure and cumulative cost, shown after Gross vs Net.""" + import plotly.graph_objects as go + + col1, col2 = st.columns(2) + + gross = gross_exposure_series(result.positions) + net = net_exposure_series(result.positions) + fig_exp = go.Figure() + fig_exp.add_trace(_line(gross.index, gross.to_numpy(), "Gross", STRATEGY)) + fig_exp.add_trace(_line(net.index, net.to_numpy(), "Net", ACCENT)) + fig_exp.update_layout(title="Gross / net exposure", height=300) + col1.plotly_chart(fig_exp, width="stretch") + + if "total" in result.costs.columns: + cum = result.costs["total"].cumsum() + fig_cost = go.Figure( + go.Scatter(x=cum.index, y=cum.to_numpy(), line={"color": NEGATIVE}) + ) + fig_cost.update_layout(title="Cumulative cost (fraction)", height=300) + col2.plotly_chart(fig_cost, width="stretch") + + def render_trade_table(st: Any, result: BacktestResult) -> None: """Render the trade table with a CSV download.""" trades = result.trades diff --git a/src/quantlab/dashboard/state.py b/src/quantlab/dashboard/state.py index e8bb6ff..dade34a 100644 --- a/src/quantlab/dashboard/state.py +++ b/src/quantlab/dashboard/state.py @@ -3,22 +3,46 @@ from __future__ import annotations import csv +from collections.abc import Callable from datetime import date from functools import lru_cache from pathlib import Path -from typing import Any +from typing import TYPE_CHECKING, Any import pandas as pd from quantlab.backtesting.result import BacktestResult from quantlab.backtesting.runner import run_backtest_from_config from quantlab.config import ExperimentConfig +from quantlab.constants import GENERATED_REPORTS_DIR from quantlab.data.base import SymbolSuggestion from quantlab.data.binance import BinanceDataSource from quantlab.data.loader import DataLoader +from quantlab.data.resolution import detect_calendar, detect_source from quantlab.data.storage import ParquetStorage from quantlab.exceptions import BacktestError +__all__ = [ + "binance_trading_symbols", + "build_config_from_inputs", + "default_end_date", + "detect_calendar", + "detect_source", + "estimate_walk_forward_backtest_count", + "run_dashboard_backtest", + "run_dashboard_bootstrap", + "run_dashboard_permutation_test", + "run_dashboard_sensitivity", + "run_dashboard_stress_tests", + "run_dashboard_walk_forward", + "run_dashboard_walk_forward_sensitivity", + "run_dashboard_walk_forward_stress_tests", + "yahoo_common_symbols", +] + +if TYPE_CHECKING: + from quantlab.validation.walk_forward import WalkForwardResult + #: A curated, bundled reference list (S&P 500 constituents plus major ETFs) #: shipped with the package. Yahoo has no downloadable "every symbol" #: endpoint the way Binance does, so this stands in as an offline, instant @@ -28,18 +52,24 @@ def build_config_from_inputs(inputs: dict[str, Any]) -> ExperimentConfig: - """Assemble a validated :class:`ExperimentConfig` from dashboard inputs.""" + """Assemble a validated :class:`ExperimentConfig` from dashboard inputs. + + ``instruments`` and ``benchmark`` are taken as-is: the dashboard's + instrument table (built directly from picker provenance, not a + heuristic) and benchmark section are already fully resolved by the time + they reach this function -- each row IS a piece of the config, not a + delta against a global default that no longer exists. + """ return ExperimentConfig.from_dict( { "experiment_name": inputs.get("experiment_name", "dashboard_run"), "data": { - "source": inputs["source"], - "symbols": inputs["symbols"], + "instruments": inputs["instruments"], "start_date": inputs["start_date"], "end_date": inputs["end_date"], "frequency": inputs.get("frequency", "1d"), "missing_value_policy": inputs.get("missing_value_policy", "drop"), - "market_calendar": inputs.get("market_calendar"), + "forward_fill_limit": inputs.get("forward_fill_limit", 1), "use_bundled_demo_data": inputs.get("use_bundled_demo_data", False), }, "strategy": { @@ -49,6 +79,11 @@ def build_config_from_inputs(inputs: dict[str, Any]) -> ExperimentConfig: "portfolio": { "allocator": inputs["allocator"], "maximum_weight": inputs.get("maximum_weight"), + "target_minimum_weight": inputs.get("target_minimum_weight"), + "maximum_gross_exposure": inputs.get("maximum_gross_exposure"), + "maximum_net_exposure": inputs.get("maximum_net_exposure"), + "target_maximum_positions": inputs.get("target_maximum_positions"), + "maximum_turnover": inputs.get("maximum_turnover"), "long_only": inputs.get("long_only", False), "target_volatility": inputs.get("target_volatility"), "volatility_window": inputs.get("volatility_window", 63), @@ -59,23 +94,41 @@ def build_config_from_inputs(inputs: dict[str, Any]) -> ExperimentConfig: "commission_bps": inputs.get("commission_bps", 2.0), "spread_bps": inputs.get("spread_bps", 3.0), "slippage_bps": inputs.get("slippage_bps", 2.0), + "slippage_model": inputs.get("slippage_model", "constant"), + "impact_coefficient": inputs.get("impact_coefficient", 0.1), }, "backtest": { "initial_capital": inputs.get("initial_capital", 100_000.0), "benchmark_kind": inputs.get("benchmark_kind", "symbol"), - "benchmark_symbol": inputs.get("benchmark_symbol") or None, + "benchmark": inputs.get("benchmark"), + "periods_per_year": inputs.get("periods_per_year"), "risk_free_rate": inputs.get("risk_free_rate", 0.02), }, - "validation": { - "method": "holdout", - "validation_ratio": inputs.get("validation_ratio"), - "test_ratio": inputs.get("test_ratio"), - }, + "validation": _validation_block_from_inputs(inputs), "reproducibility": {"random_seed": inputs.get("random_seed", 42)}, } ) +def _validation_block_from_inputs(inputs: dict[str, Any]) -> dict[str, Any]: + """Build the ``validation:`` config block for the active dashboard mode.""" + if inputs.get("validation_method") == "walk_forward": + return { + "method": "walk_forward", + "train_window": inputs.get("train_window"), + "validation_window": inputs.get("validation_window"), + "test_window": inputs.get("test_window"), + "expanding": inputs.get("expanding", True), + "optimization_metric": inputs.get("optimization_metric", "sharpe"), + "parameter_grid": inputs.get("parameter_grid") or None, + } + return { + "method": "holdout", + "validation_ratio": inputs.get("validation_ratio"), + "test_ratio": inputs.get("test_ratio"), + } + + def run_dashboard_backtest( config: ExperimentConfig, ) -> tuple[BacktestResult, list[str]]: @@ -85,8 +138,107 @@ def run_dashboard_backtest( return result, report.warnings +def _checkpoint_path(config: ExperimentConfig, technique: str) -> Path: + """Return the on-disk checkpoint path for one technique of ``config``. + + Same convention the CLI uses (``GENERATED_REPORTS_DIR / + experiment_name / ".checkpoint_.pkl"``), so an interrupted + dashboard run (e.g. the Streamlit server process itself restarting) and + a same-named CLI run can resume each other's progress. Two different + dashboard configs that happen to share a default ``experiment_name`` + don't collide unsafely: ``compute_provenance``'s config/data/code match + still gates whether a checkpoint is actually reused. + """ + experiment_dir = GENERATED_REPORTS_DIR / config.experiment_name + return experiment_dir / f".checkpoint_{technique}.pkl" + + +def run_dashboard_walk_forward( + config: ExperimentConfig, + *, + on_progress: Callable[[int, int], None] | None = None, +) -> tuple[WalkForwardResult, list[str]]: + """Load data and run walk-forward validation, returning the result and warnings. + + Windows, expanding mode, optimization metric and the parameter grid are + all read from ``config.validation`` (as assembled by + :func:`build_config_from_inputs`), matching how ``quantlab walk-forward`` + resolves the same settings from a YAML config. + + Args: + config: Validated experiment config, with ``validation.method`` set + to ``"walk_forward"``. + on_progress: Optional callback invoked as ``on_progress(done, total)`` + once before the first fold and once after each fold completes, + for the caller to drive a live progress bar. + """ + from quantlab.validation.parameter_grid import parameter_grid_for_config + from quantlab.validation.walk_forward import ( + WalkForwardValidator, + resolve_walk_forward_windows, + ) + + data, report = DataLoader().load(config) + validator = WalkForwardValidator(config) + train_window, validation_window, test_window = resolve_walk_forward_windows(config) + result = validator.run( + data, + parameter_grid=parameter_grid_for_config(config), + train_window=train_window, + validation_window=validation_window, + test_window=test_window, + expanding=config.validation.expanding, + on_progress=on_progress, + checkpoint_path=_checkpoint_path(config, "walk_forward"), + ) + return result, report.warnings + + +def estimate_walk_forward_backtest_count( + *, + start_date: date, + end_date: date, + is_247_market: bool, + train_window: int, + validation_window: int, + test_window: int, + expanding: bool, + parameter_grid: dict[str, list[Any]], +) -> int: + """Estimate how many single backtests a walk-forward run will execute. + + Approximates the number of bars from the requested date range (business + days for an XNYS-like calendar, calendar days for a 24/7 market) since + the actual data is not loaded yet at this point in the sidebar — this is + an estimate to warn about a slow configuration, not an exact count. + """ + from quantlab.validation.splits import walk_forward_windows + + if is_247_market: + approximate_bars = max(0, (end_date - start_date).days) + 1 + index = pd.date_range(start_date, periods=approximate_bars, freq="D") + else: + index = pd.bdate_range(start_date, end_date) + if len(index) == 0: + return 0 + windows = walk_forward_windows( + pd.DatetimeIndex(index), + train_window, + validation_window, + test_window, + expanding=expanding, + ) + n_combinations = 1 + for values in parameter_grid.values(): + n_combinations *= max(1, len(values)) + return len(windows) * (n_combinations + 1) + + def run_dashboard_stress_tests( - config: ExperimentConfig, expected_data_hash: str + config: ExperimentConfig, + expected_data_hash: str, + *, + on_progress: Callable[[int, int], None] | None = None, ) -> pd.DataFrame: """Run stress scenarios only if reloaded data matches the displayed run.""" from quantlab.validation.robustness import run_stress_tests @@ -98,7 +250,157 @@ def run_dashboard_stress_tests( "Market data changed since the displayed backtest. Run the " "backtest again before running stress tests." ) - return run_stress_tests(data, config) + return run_stress_tests( + data, + config, + on_progress=on_progress, + checkpoint_path=_checkpoint_path(config, "stress_test"), + ) + + +def run_dashboard_walk_forward_stress_tests( + config: ExperimentConfig, + wf_baseline: WalkForwardResult, + expected_data_hash: str, + *, + on_progress: Callable[[int, int], None] | None = None, +) -> pd.DataFrame: + """Walk-forward-aware stress scenarios, staleness-checked like the above. + + Re-runs the whole walk-forward process per scenario + (:func:`~quantlab.validation.robustness.run_walk_forward_stress_tests`) + instead of :func:`run_dashboard_stress_tests`'s plain-backtest variant — + Walk-forward mode's Robustness tab must never silently show numbers from + a different validation method than the one currently in effect. + """ + from quantlab.validation.robustness import run_walk_forward_stress_tests + + data, _ = DataLoader().load(config) + actual_data_hash = ParquetStorage.hash_frame(data) + if actual_data_hash != expected_data_hash: + raise BacktestError( + "Market data changed since the displayed walk-forward run. Run " + "walk-forward again before running stress tests." + ) + return run_walk_forward_stress_tests( + data, + config, + wf_baseline, + on_progress=on_progress, + checkpoint_path=_checkpoint_path(config, "stress_test"), + ) + + +def run_dashboard_bootstrap( + config: ExperimentConfig, + returns: pd.Series, + *, + n_iterations: int, + block_size: int, +) -> pd.DataFrame: + """Block-bootstrap the given returns. + + Mode-agnostic: bootstrap resamples already-realised returns and + optimizes nothing, so the same function applies whether ``returns`` is + ``result.returns`` (Backtest mode) or ``wf.oos_result.returns`` + (Walk-forward mode) — no data reload or staleness check is needed since + it never touches market data, only the already-displayed series. + """ + from quantlab.validation.bootstrap import bootstrap_returns + + return bootstrap_returns( + returns, + n_iterations=n_iterations, + block_size=block_size, + seed=config.random_seed, + periods_per_year=config.periods_per_year, + initial_capital=config.initial_capital, + risk_free_rate=config.risk_free_rate, + ).summary() + + +def run_dashboard_permutation_test( + config: ExperimentConfig, + returns: pd.Series, + *, + n_iterations: int, +) -> dict[str, float]: + """Random-sign Monte Carlo permutation test (mode-agnostic, see bootstrap).""" + from quantlab.validation.robustness import monte_carlo_permutation + + return monte_carlo_permutation( + returns, + n_iterations=n_iterations, + seed=config.random_seed, + periods_per_year=config.periods_per_year, + risk_free_rate=config.risk_free_rate, + ) + + +def run_dashboard_sensitivity( + config: ExperimentConfig, + expected_data_hash: str, + parameter_x: str, + values_x: list[Any], + parameter_y: str, + values_y: list[Any], +) -> pd.DataFrame: + """Run a plain-backtest parameter-sensitivity sweep. + + Staleness-checked like :func:`run_dashboard_stress_tests`. + """ + from quantlab.validation.parameter_sensitivity import run_parameter_sensitivity + + data, _ = DataLoader().load(config) + actual_data_hash = ParquetStorage.hash_frame(data) + if actual_data_hash != expected_data_hash: + raise BacktestError( + "Market data changed since the displayed backtest. Run the " + "backtest again before running parameter sensitivity." + ) + return run_parameter_sensitivity( + data, config, parameter_x, values_x, parameter_y, values_y + ) + + +def run_dashboard_walk_forward_sensitivity( + config: ExperimentConfig, + expected_data_hash: str, + parameter_x: str, + values_x: list[Any], + parameter_y: str, + values_y: list[Any], + *, + on_progress: Callable[[int, int], None] | None = None, +) -> pd.DataFrame: + """Walk-forward-aware parameter-sensitivity sweep, staleness-checked. + + Each grid cell re-runs the whole walk-forward process + (:func:`~quantlab.validation.parameter_sensitivity. + run_walk_forward_parameter_sensitivity`) instead of the plain + single-backtest variant, for the same reason as stress tests above. + """ + from quantlab.validation.parameter_sensitivity import ( + run_walk_forward_parameter_sensitivity, + ) + + data, _ = DataLoader().load(config) + actual_data_hash = ParquetStorage.hash_frame(data) + if actual_data_hash != expected_data_hash: + raise BacktestError( + "Market data changed since the displayed walk-forward run. Run " + "walk-forward again before running parameter sensitivity." + ) + return run_walk_forward_parameter_sensitivity( + data, + config, + parameter_x, + values_x, + parameter_y, + values_y, + on_progress=on_progress, + checkpoint_path=_checkpoint_path(config, "sensitivity"), + ) def default_end_date() -> date: diff --git a/src/quantlab/data/base.py b/src/quantlab/data/base.py index 2670be7..96b4313 100644 --- a/src/quantlab/data/base.py +++ b/src/quantlab/data/base.py @@ -48,7 +48,8 @@ class MarketDataSource(ABC): be in the canonical long OHLCV schema. """ - #: Human-readable source identifier, matched against ``config.data.source``. + #: Human-readable source identifier, matched against an + #: :class:`~quantlab.config.InstrumentConfig`'s ``source``. name: str = "base" @abstractmethod @@ -59,17 +60,20 @@ def download( end: date, frequency: str, *, - is_247_market: bool = False, + calendar: str = "XNYS", ) -> pd.DataFrame: """Download raw data and return it in canonical long OHLCV format. Args: - symbols: Tickers to download. + symbols: Tickers to download. The loader always calls this with + exactly one symbol; every symbol in a single call shares + ``calendar``. start: Inclusive start date. end: Inclusive end date. frequency: Bar frequency, e.g. ``"1d"``. - is_247_market: Whether bar settlement follows a continuous - calendar instead of exchange sessions. + calendar: Calendar bar settlement is measured against — + ``"24/7"`` for a continuous market, or a named exchange + calendar. Returns: A DataFrame with the columns of diff --git a/src/quantlab/data/binance.py b/src/quantlab/data/binance.py index db21889..fd2262b 100644 --- a/src/quantlab/data/binance.py +++ b/src/quantlab/data/binance.py @@ -74,13 +74,30 @@ def download( end: date, frequency: str = "1d", *, - is_247_market: bool = False, + calendar: str = "24/7", ) -> pd.DataFrame: """Download candles for ``symbols`` and normalise to canonical schema. - ``is_247_market`` is unused because Binance provides each kline's - explicit ``close_time`` and QuantLab only supports Binance as 24/7. + ``calendar`` is unused because Binance provides each kline's explicit + ``close_time`` and every Binance instrument's calendar is always + ``"24/7"`` (enforced by :class:`~quantlab.config.InstrumentConfig`). """ + if not isinstance(symbols, list) or not symbols: + raise DataDownloadError("Binance download requires at least one symbol.") + normalised_symbols: list[str] = [] + for position, symbol in enumerate(symbols): + if not isinstance(symbol, str) or not symbol.strip(): + raise DataDownloadError( + f"Binance symbol at position {position} must be a non-empty string." + ) + normalised_symbols.append(symbol.strip().upper()) + if not isinstance(start, date) or not isinstance(end, date): + raise DataDownloadError("Binance start and end must be date values.") + if start > end: + raise DataDownloadError("Binance start must be on or before end.") + if not isinstance(frequency, str): + raise DataDownloadError("Binance frequency must be a string.") + interval = _INTERVAL.get(frequency) if interval is None: raise DataDownloadError( @@ -89,7 +106,10 @@ def download( ) # Use one cutoff instant for every symbol in this download. now_ms = int(time.time() * 1000) - frames = [self._download_one(s, start, end, interval, now_ms) for s in symbols] + frames = [ + self._download_one(s, start, end, interval, now_ms) + for s in normalised_symbols + ] frames = [f for f in frames if not f.empty] if not frames: raise DataDownloadError( diff --git a/src/quantlab/data/calendar.py b/src/quantlab/data/calendar.py index c5213fa..b768bb1 100644 --- a/src/quantlab/data/calendar.py +++ b/src/quantlab/data/calendar.py @@ -1,13 +1,17 @@ """Trading-calendar and bar-settlement helpers. -Canonical market-data timestamps are timezone-naive UTC. Equity settlement -uses the maintained XNYS schedule; continuous markets use calendar periods. +Canonical market-data timestamps are timezone-naive UTC. Every named calendar +(any name accepted by ``pandas_market_calendars``, e.g. ``"XNYS"``, ``"XHKG"``, +``"CME_Equity"``) settles bars against its own maintained schedule; the +special sentinel ``"24/7"`` is a continuous calendar handled without +consulting ``pandas_market_calendars`` at all. """ from __future__ import annotations import functools -from typing import Any +from collections.abc import Iterable +from typing import Any, cast import numpy as np import pandas as pd @@ -16,10 +20,53 @@ from quantlab.exceptions import DataValidationError -_XNYS = mcal.get_calendar("XNYS") +_TWENTY_FOUR_SEVEN = "24/7" -# XNYS sessions, including exchange holidays and exceptional closures. -XNYS_BUSINESS_DAY: CustomBusinessDay = _XNYS.holidays() + +def is_247(calendar: str) -> bool: + """Return whether ``calendar`` is the continuous (non-exchange) sentinel.""" + return calendar == _TWENTY_FOUR_SEVEN + + +@functools.cache +def _mcal_calendar(name: str) -> mcal.MarketCalendar: + """Return the cached ``pandas_market_calendars`` calendar for ``name``. + + Never call with ``"24/7"`` — check :func:`is_247` first. + """ + try: + return mcal.get_calendar(name) + except RuntimeError as exc: + raise DataValidationError(f"Unknown market calendar {name!r}: {exc}") from exc + + +def validate_calendar_name(calendar: str) -> None: + """Raise ``DataValidationError`` if ``calendar`` is not a usable name.""" + if is_247(calendar): + return + _mcal_calendar(calendar) + + +def uniform_calendar(calendars: Iterable[str]) -> str | None: + """Return the shared calendar name if every value is identical, else ``None``.""" + values = set(calendars) + if len(values) == 1: + return next(iter(values)) + return None + + +@functools.cache +def business_day_offset(calendar: str) -> CustomBusinessDay: + """Return the cached session offset (holidays included) for ``calendar``. + + Only meaningful for a non-24/7 calendar — callers check :func:`is_247` first. + """ + return cast("CustomBusinessDay", _mcal_calendar(calendar).holidays()) + + +# Kept as a plain module constant for ergonomics: XNYS remains the default and +# by far the most common calendar in the codebase and its tests. +XNYS_BUSINESS_DAY: CustomBusinessDay = business_day_offset("XNYS") def _normalise_utc_day(ts: pd.Timestamp) -> pd.Timestamp: @@ -32,62 +79,166 @@ def _normalise_utc_day(ts: pd.Timestamp) -> pd.Timestamp: return value.normalize() -def xnys_holidays(start: pd.Timestamp, end: pd.Timestamp) -> pd.DatetimeIndex: - """Return XNYS holiday dates within the inclusive range.""" +def holidays_between( + calendar: str, start: pd.Timestamp, end: pd.Timestamp +) -> pd.DatetimeIndex: + """Return ``calendar``'s holiday dates within the inclusive range.""" start_day = _normalise_utc_day(start) end_day = _normalise_utc_day(end) if start_day > end_day: raise ValueError("start must be on or before end.") + offset = business_day_offset(calendar) # The runtime attribute exists, but the pandas stub does not expose it. - raw_holidays = pd.DatetimeIndex( - np.asarray(getattr(XNYS_BUSINESS_DAY, "holidays")) # noqa: B009 - ) + raw_holidays = pd.DatetimeIndex(np.asarray(getattr(offset, "holidays"))) # noqa: B009 return raw_holidays[(raw_holidays >= start_day) & (raw_holidays <= end_day)] +def session_weekmask(calendar: str) -> str: + """Return ``calendar``'s own weekday pattern, for ``numpy.busday_count``. + + Never assume Monday-Friday: a calendar such as XSAU trades Sunday- + Thursday, so any business-day arithmetic must use its real weekmask + (e.g. ``numpy.busday_count``'s default weekmask is Monday-Friday and + would silently miscount for such a calendar). + """ + offset = business_day_offset(calendar) + # The runtime attribute exists, but the pandas stub does not expose it. + return cast(str, getattr(offset, "weekmask")) # noqa: B009 + + _SCHEDULE_START = pd.Timestamp("1950-01-01") _SCHEDULE_END = pd.Timestamp("2075-12-31") -@functools.lru_cache(maxsize=1) -def _xnys_schedule() -> pd.DataFrame: - """Return a process-cached XNYS open/close schedule.""" - schedule: pd.DataFrame = _XNYS.schedule( +@functools.cache +def _schedule_for(calendar: str) -> pd.DataFrame: + """Return a process-cached open/close schedule for ``calendar``.""" + schedule: pd.DataFrame = _mcal_calendar(calendar).schedule( start_date=_SCHEDULE_START, end_date=_SCHEDULE_END ) return schedule -def xnys_sessions(start: pd.Timestamp, end: pd.Timestamp) -> pd.DataFrame: - """Return XNYS sessions with timezone-naive UTC open and close times.""" +def sessions(calendar: str, start: pd.Timestamp, end: pd.Timestamp) -> pd.DataFrame: + """Return ``calendar``'s sessions with timezone-naive UTC session times. + + Always has ``market_open``/``market_close``. A calendar with an official + intraday break (e.g. XHKG's lunch recess) also has ``break_start``/ + ``break_end``, normalized the same way -- never left tz-aware while the + other two columns are tz-naive, which would silently corrupt any + comparison between them. A calendar without a break simply has no break + columns, exactly as ``pandas_market_calendars`` reports it. + """ start_day = _normalise_utc_day(start) end_day = _normalise_utc_day(end) if start_day > end_day: raise ValueError("start must be on or before end.") if start_day >= _SCHEDULE_START and end_day <= _SCHEDULE_END: - schedule = _xnys_schedule().loc[start_day:end_day].copy() + schedule = _schedule_for(calendar).loc[start_day:end_day].copy() else: - schedule = _XNYS.schedule(start_date=start_day, end_date=end_day).copy() - - for column in ("market_open", "market_close"): - schedule[column] = pd.to_datetime(schedule[column], utc=True).dt.tz_localize( - None + schedule = ( + _mcal_calendar(calendar) + .schedule(start_date=start_day, end_date=end_day) + .copy() ) + + for column in ("market_open", "market_close", "break_start", "break_end"): + if column in schedule.columns: + schedule[column] = pd.to_datetime( + schedule[column], utc=True + ).dt.tz_localize(None) schedule.index = pd.DatetimeIndex(schedule.index).tz_localize(None).normalize() return schedule -def _market_close_for_session(day: pd.Timestamp) -> pd.Timestamp | None: - """Return a session's timezone-naive UTC close, or ``None``.""" - schedule = _xnys_schedule() +def has_session_break(calendar: str) -> bool: + """Return whether ``calendar`` has an official intraday break (recess). + + ``24/7`` and most equity/futures calendars never do; a handful (e.g. + XHKG's lunch recess) do, and a session's tradable time is then two + disjoint intervals, not one continuous ``[market_open, market_close)`` + block -- see :func:`sessions`. + """ + if is_247(calendar): + return False + return "break_start" in _schedule_for(calendar).columns + + +def session_labels(calendar: str, ts: pd.Series) -> pd.Series: + """Return each timestamp's real trading-session date, index-aligned to ``ts``. + + Never a naive UTC calendar-day boundary (``ts.dt.date`` / + ``ts.dt.normalize()``): a large positive UTC offset (e.g. Sydney, + +10/+11) can push a session's local-morning open into the *previous* UTC + calendar day, silently splitting one real session's bars across two + different "days" and corrupting anything that groups or compares by day + for such a calendar. ``ts`` must be sorted ascending. + + Matches each timestamp to the first session whose close has not yet + happened at that instant (smallest ``market_close >= ts``) -- the + session actually "in progress or next up" at that moment, covering the + whole gap since the previous session's close. This is deliberately not + a match against the nearest ``market_open``: for a calendar whose + sessions open many hours after UTC midnight (e.g. XNYS, opening at + 13:30 UTC), a daily bar conventionally timestamped at UTC midnight of + its own trading date is *closer in raw time* to the previous session's + open than to its own -- "nearest open" would silently misattribute + every such bar to the day before, merging or dropping bars under any + grouping built on this label. Matching on the close instead correctly + keeps a midnight-of-D bar on D (D's own close is still hours away, the + previous session's is a full day-plus behind) while still handling a + genuine intraday bar the same way "nearest" did (mid-session, at-open, + or well-before-open all still resolve to their own session, since its + close is the next one due) and still correctly handling a session that + opens before UTC midnight of its own label date. + """ + # A forward search needs the *next* session's close on or after every + # row, including the last one -- e.g. a genuinely post-market timestamp + # on `ts.max()`'s own calendar date can fall after that date's own + # close, needing the following session. Padding the fetch window well + # past any realistic holiday closure (a market closed 10+ consecutive + # calendar days is not a real case any calendar here models) guarantees + # one is always available; sessions() only returns real session rows, + # so the extra padding costs a few unused trailing rows, never a wrong + # match. + schedule = sessions(calendar, ts.min(), ts.max() + pd.Timedelta(days=10)) + if schedule.empty: + return cast("pd.Series", ts.dt.normalize()) + # `ts` and `schedule["market_close"]` come from independent sources (a + # caller's own data vs. pandas_market_calendars' schedule) that need not + # share the same datetime64 resolution (e.g. Parquet-cached data can + # come back as `[ms]` while the schedule is `[us]`) -- merge_asof + # requires an exact dtype match on its join keys, not just "both + # datetime64", so both sides are normalised to `[ns]` (this project's + # own canonical resolution) right before the merge. + lookup = pd.merge_asof( + pd.DataFrame({"ts": ts.to_numpy(dtype="datetime64[ns]")}), + pd.DataFrame( + { + "session": schedule.index.to_numpy(), + "close": schedule["market_close"].to_numpy(dtype="datetime64[ns]"), + } + ).sort_values("close"), + left_on="ts", + right_on="close", + direction="forward", + ) + return pd.Series(lookup["session"].to_numpy(), index=ts.index) + + +def _market_close_for_session(calendar: str, day: pd.Timestamp) -> pd.Timestamp | None: + """Return a session's timezone-naive UTC close on ``calendar``, or ``None``.""" + schedule = _schedule_for(calendar) if _SCHEDULE_START <= day <= _SCHEDULE_END: if day not in schedule.index: return None raw_close: Any = schedule.at[day, "market_close"] else: - one_day: pd.DataFrame = _XNYS.schedule(start_date=day, end_date=day) + one_day: pd.DataFrame = _mcal_calendar(calendar).schedule( + start_date=day, end_date=day + ) if one_day.empty: return None raw_close = one_day.iloc[0]["market_close"] @@ -95,7 +246,7 @@ def _market_close_for_session(day: pd.Timestamp) -> pd.Timestamp | None: close = pd.Timestamp(raw_close) if close.tzinfo is None: raise DataValidationError( - f"XNYS returned a timezone-naive close for {day.date()}." + f"{calendar} returned a timezone-naive close for {day.date()}." ) return close.tz_convert("UTC").tz_localize(None) @@ -119,65 +270,172 @@ def _market_close_for_session(day: pd.Timestamp) -> pd.Timestamp | None: def last_trading_day_on_or_before( - ts: pd.Timestamp, *, is_247_market: bool + ts: pd.Timestamp, *, calendar: str = "XNYS" ) -> pd.Timestamp: """Return the latest trading day on or before ``ts``, normalized.""" day = _normalise_utc_day(ts) - if is_247_market: + if is_247(calendar): return day - return pd.Timestamp(XNYS_BUSINESS_DAY.rollback(day)).normalize() + return pd.Timestamp(business_day_offset(calendar).rollback(day)).normalize() def first_trading_day_on_or_after( - ts: pd.Timestamp, *, is_247_market: bool + ts: pd.Timestamp, *, calendar: str = "XNYS" ) -> pd.Timestamp: """Return the earliest trading day on or after ``ts``, normalized.""" day = _normalise_utc_day(ts) - if is_247_market: + if is_247(calendar): return day - return pd.Timestamp(XNYS_BUSINESS_DAY.rollforward(day)).normalize() + return pd.Timestamp(business_day_offset(calendar).rollforward(day)).normalize() + +def is_session_day(calendar: str, days: pd.DatetimeIndex) -> np.ndarray: + """Return a boolean array: whether each (UTC, normalized) day is a session. -def daily_equity_bucket_settlement(ts: pd.Timestamp) -> pd.Timestamp: + ``"24/7"`` treats every day as a session. For a named exchange calendar, a + day is a session iff it is in that calendar's own schedule from + ``pandas_market_calendars`` -- never a hardcoded Monday-Friday + assumption, which would be wrong for a calendar whose weekend falls on + different days (e.g. XSAU's Friday-Saturday weekend, Sunday-Thursday + trading week: a hardcoded weekday check would mark a real XSAU Sunday + session closed and a real XSAU Friday closure open). + """ + normalized = pd.DatetimeIndex([_normalise_utc_day(day) for day in days]) + if is_247(calendar): + return np.ones(len(normalized), dtype=bool) + if len(normalized) == 0: + return np.zeros(0, dtype=bool) + start_day, end_day = normalized.min(), normalized.max() + if start_day >= _SCHEDULE_START and end_day <= _SCHEDULE_END: + session_index = _schedule_for(calendar).index + else: + session_index = ( + _mcal_calendar(calendar) + .schedule(start_date=start_day, end_date=end_day) + .index + ) + return np.asarray(normalized.isin(session_index), dtype=bool) + + +def daily_equity_bucket_settlement( + ts: pd.Timestamp, *, calendar: str = "XNYS" +) -> pd.Timestamp: """Return the close boundary for an equity daily bar dated ``ts``. - Genuine XNYS sessions use their scheduled close. A non-session date has - no exchange close, so it uses the following UTC midnight as a conservative - boundary instead of inventing a 16:00 close. + A genuine session on ``calendar`` uses its scheduled close. A non-session + date has no exchange close, so it uses the following UTC midnight as a + conservative boundary instead of inventing a close time. """ day = _normalise_utc_day(ts) - close = _market_close_for_session(day) + close = _market_close_for_session(calendar, day) return close if close is not None else day + pd.Timedelta(days=1) -def weekly_bucket_settlement(ts: pd.Timestamp, *, is_247_market: bool) -> pd.Timestamp: - """Return the close of the calendar week containing ``ts``.""" +_WEEKDAY_ABBREVIATIONS = { + "Mon": 0, + "Tue": 1, + "Wed": 2, + "Thu": 3, + "Fri": 4, + "Sat": 5, + "Sun": 6, +} + + +@functools.cache +def _structural_trading_weekdays(calendar: str) -> frozenset[int]: + """Return the weekday numbers (Mon=0..Sun=6) this calendar trades on. + + Derived from the offset's ``weekmask`` alone -- the calendar's fixed + weekly pattern, independent of any specific date's holidays. A one-off + holiday (e.g. Thanksgiving, a Thursday) must never be mistaken for the + week's structural boundary the way a genuine weekend is. + """ + weekmask: str = cast("Any", business_day_offset(calendar)).weekmask + return frozenset(_WEEKDAY_ABBREVIATIONS[name] for name in weekmask.split()) + + +def weekly_bucket_start(ts: pd.Timestamp, *, calendar: str = "XNYS") -> pd.Timestamp: + """Return the label date of the trading week containing ``ts``. + + The mirror of :func:`weekly_bucket_settlement`: the first day of the + same structural trading-weekday run (e.g. Sunday for XSAU, Monday for + XNYS), not an intraday instant -- for labelling a resampled weekly bar + the same way every other resampling target is labelled, a plain + calendar-day date. Always names the *same* week as + ``weekly_bucket_settlement`` for the same ``ts`` (a rest day anchors to + the week that just ended in both, never a different week from one + function to the other), so grouping by either gives the same partition. + """ + day = _normalise_utc_day(ts) + if is_247(calendar): + return day - pd.Timedelta(days=day.dayofweek) + + trading_weekdays = _structural_trading_weekdays(calendar) + cursor = day + if cursor.dayofweek not in trading_weekdays: + # Same rest-day anchoring as weekly_bucket_settlement: a rest day + # belongs to the week that just ended, not the one about to start. + while cursor.dayofweek not in trading_weekdays: + cursor = cursor - pd.Timedelta(days=1) + while (cursor - pd.Timedelta(days=1)).dayofweek in trading_weekdays: + cursor = cursor - pd.Timedelta(days=1) + return cursor + + +def weekly_bucket_settlement( + ts: pd.Timestamp, *, calendar: str = "XNYS" +) -> pd.Timestamp: + """Return the close of the trading week containing ``ts``.""" day = _normalise_utc_day(ts) - week_start = day - pd.Timedelta(days=day.dayofweek) - if is_247_market: + if is_247(calendar): + week_start = day - pd.Timedelta(days=day.dayofweek) return week_start + pd.Timedelta(weeks=1) - last_session = last_trading_day_on_or_before( - week_start + pd.Timedelta(days=6), is_247_market=False - ) - return daily_equity_bucket_settlement(last_session) + # The trading week containing `ts` is bounded by *this calendar's own* + # structural rest days, never a fixed Monday-Sunday window -- wrong for + # a non-Western trading week (e.g. XSAU trades Sunday-Thursday, so + # Monday is mid-week, not the start). Membership uses the weekmask only + # (not `is_session_day`, which also excludes one-off holidays) so a + # mid-week holiday like Thanksgiving never gets mistaken for the + # boundary of the week. A rest day anchors backward onto the week that + # just ended (a Saturday belongs to the week whose last trading weekday + # was Friday, exactly as it does for XNYS today); a trading weekday + # walks forward to the last trading weekday of its own run. Only once + # that structural end date is found does `last_trading_day_on_or_before` + # resolve an actual holiday landing exactly on it (e.g. a market-holiday + # Friday rolls back to Thursday's real close). + trading_weekdays = _structural_trading_weekdays(calendar) + cursor = day + if cursor.dayofweek in trading_weekdays: + while (cursor + pd.Timedelta(days=1)).dayofweek in trading_weekdays: + cursor = cursor + pd.Timedelta(days=1) + else: + while cursor.dayofweek not in trading_weekdays: + cursor = cursor - pd.Timedelta(days=1) + cursor = last_trading_day_on_or_before(cursor, calendar=calendar) + return daily_equity_bucket_settlement(cursor, calendar=calendar) -def monthly_bucket_settlement(ts: pd.Timestamp, *, is_247_market: bool) -> pd.Timestamp: +def monthly_bucket_settlement( + ts: pd.Timestamp, *, calendar: str = "XNYS" +) -> pd.Timestamp: """Return the close of the calendar month containing ``ts``.""" day = _normalise_utc_day(ts) month_start = pd.Timestamp(year=day.year, month=day.month, day=1) next_month_start = month_start + pd.DateOffset(months=1) - if is_247_market: + if is_247(calendar): return next_month_start last_session = last_trading_day_on_or_before( - next_month_start - pd.Timedelta(days=1), is_247_market=False + next_month_start - pd.Timedelta(days=1), calendar=calendar ) - return daily_equity_bucket_settlement(last_session) + return daily_equity_bucket_settlement(last_session, calendar=calendar) -def bar_bucket_end(ts: pd.Series, frequency: str, *, is_247_market: bool) -> pd.Series: +def bar_bucket_end( + ts: pd.Series, frequency: str, *, calendar: str = "XNYS" +) -> pd.Series: """Return each bar's settlement instant as timezone-naive UTC.""" if frequency not in FREQUENCY_TIMEDELTA: raise DataValidationError( @@ -192,23 +450,21 @@ def bar_bucket_end(ts: pd.Series, frequency: str, *, is_247_market: bool) -> pd. if frequency in MONTHLY_FREQUENCIES: def settle_monthly(value: Any) -> pd.Timestamp: - return monthly_bucket_settlement( - pd.Timestamp(value), is_247_market=is_247_market - ) + return monthly_bucket_settlement(pd.Timestamp(value), calendar=calendar) return timestamps.map(settle_monthly) if frequency in PERIODIC_FREQUENCIES: def settle_weekly(value: Any) -> pd.Timestamp: - return weekly_bucket_settlement( - pd.Timestamp(value), is_247_market=is_247_market - ) + return weekly_bucket_settlement(pd.Timestamp(value), calendar=calendar) return timestamps.map(settle_weekly) - if frequency in DAILY_FREQUENCIES and not is_247_market: + if frequency in DAILY_FREQUENCIES and not is_247(calendar): def settle_daily(value: Any) -> pd.Timestamp: - return daily_equity_bucket_settlement(pd.Timestamp(value)) + return daily_equity_bucket_settlement( + pd.Timestamp(value), calendar=calendar + ) return timestamps.map(settle_daily) return timestamps + FREQUENCY_TIMEDELTA[frequency] diff --git a/src/quantlab/data/closures.py b/src/quantlab/data/closures.py new file mode 100644 index 0000000..203912c --- /dev/null +++ b/src/quantlab/data/closures.py @@ -0,0 +1,217 @@ +"""Verified-closure detection for a multi-instrument tradable universe. + +Distinguishes a *verified closure* (a date that is not a trading session on a +symbol's own calendar) from a *genuinely missing* bar (a date the calendar +says should be a session, but no provider row exists for it) — only the +former is handled here. A genuinely missing bar remains a data-quality +problem governed by ``missing_value_policy``, unchanged. + +Callers must restrict ``data``/``symbols`` to the *tradable* universe only +(never an external benchmark) — see :mod:`quantlab.data.loader` — so that a +benchmark on a different calendar can never inflate the portfolio's own +timeline with synthetic closure bars that no tradable instrument needs. + +Closure semantics are only well-defined at daily granularity: sub-daily +session boundaries need open/close *times*, not just date membership, which +the validator's existing intraday gap tolerance already absorbs separately. +""" + +from __future__ import annotations + +from collections.abc import Mapping, Sequence + +import numpy as np +import pandas as pd + +from quantlab.constants import ( + ADJUSTED_CLOSE, + CLOSE, + HIGH, + LOW, + OPEN, + SYMBOL, + TIMESTAMP, + VOLUME, +) +from quantlab.data.base import pivot_field +from quantlab.data.calendar import is_session_day +from quantlab.exceptions import DataValidationError + +#: insert_verified_closure_bars/tradable_mask_for are no-ops outside this. +DAILY_FREQUENCY = "1d" + + +def verified_closure_mask( + dates: pd.DatetimeIndex, + symbols: Sequence[str], + calendar_for_symbol: Mapping[str, str], +) -> pd.DataFrame: + """Return a ``dates x symbols`` bool frame: True where verifiably closed. + + A cell is True when ``date`` is not a trading session on that symbol's + own calendar (weekend/holiday), independent of whether a row happens to + exist there. + """ + columns = { + symbol: ~is_session_day(calendar_for_symbol[symbol], dates) + for symbol in symbols + } + return pd.DataFrame(columns, index=dates, columns=list(symbols)) + + +def tradable_mask_for( + dates: pd.DatetimeIndex, + symbols: Sequence[str], + calendar_for_symbol: Mapping[str, str], +) -> pd.DataFrame: + """Return a ``dates x symbols`` bool frame: True where tradable (open).""" + return ~verified_closure_mask(dates, symbols, calendar_for_symbol) + + +def _drop_real_bars_on_closures( + data: pd.DataFrame, + *, + dates: pd.DatetimeIndex, + symbols: Sequence[str], + closure: pd.DataFrame, + strict: bool, + warnings: list[str] | None, +) -> pd.DataFrame: + """Discard a real row whose own symbol's calendar was closed that day. + + A verified closure means the market did not open, so no legitimate trade + could have produced this row -- keeping it would let a data anomaly (bad + provider row, timezone slip, a stray weekend print) inject a fictitious + price move into the return series, silently breaking the "a verified + closure is never traded" guarantee. Dropping it here, before the fill + logic below runs, makes the date fall back to an ordinary verified + closure (flat, last known price) -- exactly as if no row had ever been + supplied for it. + """ + date_positions = dates.get_indexer(pd.Index(data[TIMESTAMP])) + symbol_positions = pd.Index(symbols).get_indexer(pd.Index(data[SYMBOL])) + covered = symbol_positions >= 0 + is_closure_row = np.zeros(len(data), dtype=bool) + is_closure_row[covered] = closure.to_numpy()[ + date_positions[covered], symbol_positions[covered] + ] + if not is_closure_row.any(): + return data + + anomalous = data.loc[is_closure_row] + examples = ", ".join( + f"{row[SYMBOL]}@{row[TIMESTAMP].date()}" + for _, row in anomalous.head(5).iterrows() + ) + message = ( + f"{int(is_closure_row.sum())} row(s) fall on a verified market " + f"closure for their own symbol's calendar (e.g. {examples}) and " + "were discarded -- a closed market cannot produce a real trade." + ) + if strict: + raise DataValidationError(message) + if warnings is not None: + warnings.append(message) + return data.loc[~is_closure_row].reset_index(drop=True) + + +def insert_verified_closure_bars( + data: pd.DataFrame, + *, + symbol_calendars: Mapping[str, str], + frequency: str, + strict: bool = False, + warnings: list[str] | None = None, + counts: dict[str, int] | None = None, +) -> pd.DataFrame: + """Insert a synthetic bar for each verified closure that needs one. + + A synthetic bar is inserted for ``(date, symbol)`` only when: (a) some + *other* symbol in ``data`` already has a real row on ``date`` (dates are + drawn from the union of what's actually present, so this holds by + construction — never invents a date nothing in ``data`` trades on), (b) + ``date`` is a verified closure for ``symbol``'s own calendar, and (c) + ``symbol`` already has at least one earlier real bar to carry forward + (never extrapolates before a symbol's first observed bar). + + ``open``/``high``/``low``/``close`` all repeat the last known ``close`` + (a flat, zero-range bar); ``adjusted_close`` separately repeats the last + known ``adjusted_close`` — never derived from ``close``, since the two + can differ (splits/dividends) and each must stay flat independently so + ``pct_change`` is exactly 0 on both series. ``volume`` is 0 explicitly + (never forward-filled), so no strategy or volume-based slippage model can + mistake a verified closure for real trading activity. + + A *real* row that already sits on a verified closure (a data anomaly, not + a gap) is discarded rather than trusted -- see + :func:`_drop_real_bars_on_closures`. In ``strict`` mode this raises + :class:`~quantlab.exceptions.DataValidationError`; otherwise a + description is appended to ``warnings`` (when given) and the row is + dropped before the fill logic below runs. + + A no-op when ``frequency`` isn't daily, or when nothing needs filling. + + ``counts``, when given, is updated in place with ``"discarded"`` (real + rows removed by :func:`_drop_real_bars_on_closures`) and ``"inserted"`` + (synthetic rows added below) as two separate non-negative numbers -- + never netted against each other, unlike a single delta-of-lengths count, + which can go negative and misrepresent what actually happened to the + data (see :class:`~quantlab.data.validator.DataQualityReport`). + """ + if frequency != DAILY_FREQUENCY or data.empty: + return data + + symbols = sorted(symbol_calendars) + dates = pd.DatetimeIndex(sorted(data[TIMESTAMP].unique())) + closure = verified_closure_mask(dates, symbols, symbol_calendars) + + before_drop = len(data) + data = _drop_real_bars_on_closures( + data, + dates=dates, + symbols=symbols, + closure=closure, + strict=strict, + warnings=warnings, + ) + if counts is not None: + counts["discarded"] = before_drop - len(data) + if data.empty: + return data + dates = pd.DatetimeIndex(sorted(data[TIMESTAMP].unique())) + closure = verified_closure_mask(dates, symbols, symbol_calendars) + + close_wide = pivot_field(data, CLOSE).reindex(index=dates, columns=symbols) + adjusted_wide = pivot_field(data, ADJUSTED_CLOSE).reindex( + index=dates, columns=symbols + ) + filled_close = close_wide.ffill() + filled_adjusted = adjusted_wide.ffill() + + # Verified closure, no real row that day, and a prior real bar to carry + # forward (ffill leaves leading NaN before a symbol's first observation). + needs_fill = close_wide.isna() & closure & filled_close.notna() + if not needs_fill.to_numpy().any(): + return data + + rows, columns = np.where(needs_fill.to_numpy()) + fill_dates = dates[rows] + fill_symbols = [symbols[column] for column in columns] + close_values = filled_close.to_numpy()[rows, columns] + adjusted_values = filled_adjusted.to_numpy()[rows, columns] + synthetic = pd.DataFrame( + { + TIMESTAMP: fill_dates, + SYMBOL: fill_symbols, + OPEN: close_values, + HIGH: close_values, + LOW: close_values, + CLOSE: close_values, + ADJUSTED_CLOSE: adjusted_values, + VOLUME: 0.0, + } + ) + if counts is not None: + counts["inserted"] = len(synthetic) + combined = pd.concat([data, synthetic], ignore_index=True) + return combined.sort_values([TIMESTAMP, SYMBOL]).reset_index(drop=True) diff --git a/src/quantlab/data/loader.py b/src/quantlab/data/loader.py index 820ddb9..51ea4cf 100644 --- a/src/quantlab/data/loader.py +++ b/src/quantlab/data/loader.py @@ -2,16 +2,41 @@ from __future__ import annotations +from collections import defaultdict +from collections.abc import Mapping from datetime import date from pathlib import Path +import numpy as np import pandas as pd -from quantlab.config import BenchmarkKind, ExperimentConfig, MissingValuePolicy -from quantlab.constants import DEMO_DATA_DIR, RAW_DATA_DIR, SYMBOL, TIMESTAMP -from quantlab.data.base import MarketDataSource, ensure_canonical_schema -from quantlab.data.calendar import FREQUENCY_TIMEDELTA, bar_bucket_end +from quantlab.config import ( + BenchmarkKind, + DataSourceName, + ExperimentConfig, + InstrumentConfig, + MissingValuePolicy, +) +from quantlab.constants import ( + ADJUSTED_CLOSE, + CLOSE, + DEMO_DATA_DIR, + HIGH, + LOW, + OPEN, + RAW_DATA_DIR, + SYMBOL, + TIMESTAMP, + VOLUME, +) +from quantlab.data.base import MarketDataSource, ensure_canonical_schema, pivot_field +from quantlab.data.calendar import FREQUENCY_TIMEDELTA, bar_bucket_end, is_247, sessions from quantlab.data.cleaner import DataCleaner +from quantlab.data.closures import ( + DAILY_FREQUENCY, + insert_verified_closure_bars, + tradable_mask_for, +) from quantlab.data.storage import ParquetStorage, _drop_still_open_bars from quantlab.data.validator import DataQualityReport, DataValidator from quantlab.exceptions import DataDownloadError, DataValidationError @@ -37,6 +62,132 @@ def build_source(name: str) -> MarketDataSource: ) +def _apply_missing_value_policy_to_genuine_gaps( + data: pd.DataFrame, + *, + symbol_calendars: Mapping[str, str], + frequency: str, + policy: MissingValuePolicy, + forward_fill_limit: int, + warnings: list[str], +) -> pd.DataFrame: + """Govern a (date, symbol) combination with no row at all, by policy. + + ``missing_value_policy`` (applied by :class:`~quantlab.data.cleaner. + DataCleaner`) only ever sees rows that already exist -- it can drop or + fill a NaN *value* inside a row, but it has no way to notice that a row + is entirely absent for a symbol on a date it should have traded. Left + unhandled, that silently produces an incomplete panel (only caught much + later, confusingly, by the engine's "asset return missing while held" + guard). This runs after :func:`~quantlab.data.closures. + insert_verified_closure_bars`, so a verified closure (a real non-session + day) is never mistaken for a gap -- only a real trading session with no + data counts here. + + A no-op when ``frequency`` isn't daily (closure/gap semantics are only + well-defined at daily granularity, see ``quantlab.data.closures``), or + under policy ``none`` (gaps stay exactly as they already are, governed + by the existing "abnormal gap" warning). + """ + if frequency != DAILY_FREQUENCY or data.empty or policy is MissingValuePolicy.NONE: + return data + symbols = sorted(symbol_calendars) + dates = pd.DatetimeIndex(sorted(data[TIMESTAMP].unique())) + # A date nothing in `data` trades on is never invented -- `dates` is + # drawn only from what's actually present, same convention as + # insert_verified_closure_bars. + tradable = tradable_mask_for(dates, symbols, symbol_calendars) + close_wide = pivot_field(data, CLOSE).reindex(index=dates, columns=symbols) + # A symbol's coverage simply not having started yet, or having already + # ended, is a *coverage-window* difference between symbols -- handled + # separately by DataLoader.load()'s common-start/common-end trimming, + # with its own clear warning. Only a hole strictly between a symbol's + # own first and last observed dates is a genuine gap this function + # should govern; leading/trailing absence relative to the symbol's own + # history must never be double-handled here first. + observed = close_wide.notna() + within_own_range = observed.cummax() & observed[::-1].cummax()[::-1] + missing = close_wide.isna() & tradable & within_own_range + if not missing.to_numpy().any(): + return data + + if policy is MissingValuePolicy.RAISE: + rows, cols = np.where(missing.to_numpy()) + examples = ", ".join( + f"{symbols[int(c)]}@{dates[int(r)].date()}" + for r, c in list(zip(rows, cols, strict=True))[:5] + ) + raise DataValidationError( + f"{len(rows)} (date, symbol) combination(s) are genuinely " + f"missing under missing_value_policy 'raise' (e.g. {examples}) " + "-- no row exists for a real trading session on that symbol's " + "own calendar (not a verified closure)." + ) + + if policy is MissingValuePolicy.DROP: + affected_dates = dates[missing.to_numpy().any(axis=1)] + warnings.append( + f"{len(affected_dates)} date(s) dropped from the tradable " + "universe: at least one symbol was genuinely missing that day " + "under missing_value_policy 'drop' (e.g. " + f"{[d.date().isoformat() for d in affected_dates[:5]]})." + ) + return data.loc[~data[TIMESTAMP].isin(affected_dates)].reset_index(drop=True) + + # forward_fill: fill from each symbol's own last known price, bounded by + # forward_fill_limit; a date where even one symbol exceeds the limit is + # dropped entirely (same as `drop` above) rather than left partially + # filled, which would risk the same downstream "missing while held" + # failure this function exists to prevent. + filled_close = close_wide.ffill(limit=forward_fill_limit) + adjusted_wide = pivot_field(data, ADJUSTED_CLOSE).reindex( + index=dates, columns=symbols + ) + filled_adjusted = adjusted_wide.ffill(limit=forward_fill_limit) + unresolved = missing & filled_close.isna() + if unresolved.to_numpy().any(): + affected_dates = dates[unresolved.to_numpy().any(axis=1)] + warnings.append( + f"{len(affected_dates)} date(s) dropped from the tradable " + "universe: a genuinely missing (date, symbol) combination " + f"exceeded the {forward_fill_limit}-bar forward-fill limit " + f"(e.g. {[d.date().isoformat() for d in affected_dates[:5]]})." + ) + data = data.loc[~data[TIMESTAMP].isin(affected_dates)].reset_index(drop=True) + keep = ~dates.isin(affected_dates) + dates = dates[keep] + missing = missing.loc[dates] + filled_close = filled_close.loc[dates] + filled_adjusted = filled_adjusted.loc[dates] + + fillable = missing & filled_close.notna() + if not fillable.to_numpy().any(): + return data + rows, cols = np.where(fillable.to_numpy()) + fill_dates = dates[rows] + fill_symbols = [symbols[c] for c in cols] + close_values = filled_close.to_numpy()[rows, cols] + adjusted_values = filled_adjusted.to_numpy()[rows, cols] + synthetic = pd.DataFrame( + { + TIMESTAMP: fill_dates, + SYMBOL: fill_symbols, + OPEN: close_values, + HIGH: close_values, + LOW: close_values, + CLOSE: close_values, + ADJUSTED_CLOSE: adjusted_values, + VOLUME: 0.0, + } + ) + warnings.append( + f"{len(rows)} row(s) forward-filled for genuinely missing (date, " + "symbol) combinations (not a verified closure)." + ) + combined = pd.concat([data, synthetic], ignore_index=True) + return combined.sort_values([TIMESTAMP, SYMBOL]).reset_index(drop=True) + + class DataLoader: """Load clean, validated canonical market data for an experiment.""" @@ -48,59 +199,120 @@ def __init__( self.storage = storage if storage is not None else ParquetStorage() # Resolve the default when constructing the loader so tests can patch it. self.raw_dir = Path(raw_dir) if raw_dir is not None else RAW_DATA_DIR + self._bundled_demo_data_used = False def download( self, config: ExperimentConfig, *, force: bool = False ) -> pd.DataFrame: - """Return raw canonical data for tradable and external benchmark symbols.""" - symbols = self._symbols_to_fetch(config) - source_name = config.data.source - if source_name == "csv": - return self._load_csv( - symbols, use_bundled_demo_data=config.data.use_bundled_demo_data + """Return raw canonical data for tradable and external benchmark instruments.""" + # Reset in case this instance is reused across multiple load() calls + # -- a stale True from an earlier call must never leak into this one. + self._bundled_demo_data_used = False + instruments = list(config.data.instruments) + external_benchmark = self._external_benchmark_instrument(config) + if external_benchmark is not None: + instruments.append(external_benchmark) + return self._download_group(instruments, config, force=force) + + @staticmethod + def _external_benchmark_instrument( + config: ExperimentConfig, + ) -> InstrumentConfig | None: + """Return the benchmark instrument only when outside the tradable universe. + + A benchmark symbol already present in ``data.instruments`` reuses that + instrument's data — a validator guarantees source/calendar agree in + that case, so no separate fetch is needed. + """ + benchmark = config.backtest.benchmark + if benchmark is None or config.benchmark_kind is not BenchmarkKind.SYMBOL: + return None + if benchmark.symbol in config.symbols: + return None + return benchmark + + def _download_group( + self, + instruments: list[InstrumentConfig], + config: ExperimentConfig, + *, + force: bool, + ) -> pd.DataFrame: + """Fetch every instrument, then apply calendar-dependent preparation. + + Calendar-dependent filtering (still-open bars, date-range slicing) + runs only *after* every instrument's frame is assembled from cache or + the provider — never baked into what gets cached — so the same + provider history is never duplicated in the cache just because one + experiment picked a different calendar than another for the same + symbol/source/frequency. + """ + by_source: dict[DataSourceName, list[InstrumentConfig]] = defaultdict(list) + for instrument in instruments: + by_source[instrument.source].append(instrument) + + raw_frames: list[pd.DataFrame] = [] + csv_instruments = by_source.pop(DataSourceName.CSV, []) + if csv_instruments: + raw_frames.append( + self._load_csv( + [instrument.symbol for instrument in csv_instruments], + use_bundled_demo_data=config.data.use_bundled_demo_data, + ) + ) + for source_name, group in by_source.items(): + source = build_source(source_name) + raw_frames.extend( + self._download_symbol(source, instrument, config, force=force) + for instrument in group ) + raw = pd.concat(raw_frames, ignore_index=True) - source = build_source(source_name) - frames = [ - self._download_symbol(source, symbol, config, force=force) - for symbol in symbols + prepared_frames = [ + self._prepare_instrument_frame( + raw.loc[raw[SYMBOL] == instrument.symbol], instrument, config + ) + for instrument in instruments ] - return ensure_canonical_schema(pd.concat(frames, ignore_index=True)) + return ensure_canonical_schema(pd.concat(prepared_frames, ignore_index=True)) @staticmethod - def _symbols_to_fetch(config: ExperimentConfig) -> list[str]: - """Return tradable symbols plus a separate symbol benchmark.""" - symbols = list(config.symbols) - benchmark = ( - config.benchmark_symbol - if config.benchmark_kind is BenchmarkKind.SYMBOL - else None - ) - if benchmark and benchmark not in symbols: - symbols.append(benchmark) - return symbols + def _prepare_instrument_frame( + frame: pd.DataFrame, instrument: InstrumentConfig, config: ExperimentConfig + ) -> pd.DataFrame: + """Calendar-dependent filtering for one instrument. - def load( - self, config: ExperimentConfig, *, force: bool = False - ) -> tuple[pd.DataFrame, DataQualityReport]: - """Return clean, validated data restricted to the configured dates.""" - raw = self.download(config, force=force) - # Keep CSV and remote sources under the same settlement rule. - raw = _drop_still_open_bars( - raw, config.data.frequency, is_247_market=config.data.is_247_market + Applied after any cache read/write, never persisted — the cache stays + calendar-agnostic (see :meth:`_download_group`). + """ + frame = _drop_still_open_bars( + frame, config.data.frequency, calendar=instrument.calendar ) - # Slice before forward-filling so a wider cache cannot affect a narrow run. - sliced_raw = self._slice_range( - raw, + return DataLoader._slice_range( + frame, config.start_date, config.end_date, config.frequency, - is_247_market=config.data.is_247_market, + calendar=instrument.calendar, ) + def load( + self, config: ExperimentConfig, *, force: bool = False + ) -> tuple[pd.DataFrame, DataQualityReport]: + """Return clean, validated data restricted to the configured dates.""" + sliced_raw = self.download(config, force=force) + + symbol_calendars = { + instrument.symbol: instrument.calendar + for instrument in config.data.instruments + } + external_benchmark = self._external_benchmark_instrument(config) + if external_benchmark is not None: + symbol_calendars[external_benchmark.symbol] = external_benchmark.calendar + validator = DataValidator( expected_frequency=config.data.frequency, - is_247_market=config.data.is_247_market, + symbol_calendars=symbol_calendars, ) strict = config.data.missing_value_policy is MissingValuePolicy.RAISE # Record defects before deterministic cleaning removes them. @@ -119,8 +331,127 @@ def load( strict=strict, expected_symbols=expected_symbols, ) + + # Verified-closure bars are inserted only for the TRADABLE universe: an + # external benchmark on a different calendar must never inflate the + # portfolio's own timeline (see quantlab.data.closures). + tradable_symbols = set(config.symbols) + is_tradable = sliced[SYMBOL].isin(tradable_symbols) + tradable_part = sliced.loc[is_tradable] + benchmark_part = sliced.loc[~is_tradable] + tradable_calendars = { + instrument.symbol: instrument.calendar + for instrument in config.data.instruments + } + closure_warnings: list[str] = [] + closure_counts = {"discarded": 0, "inserted": 0} + filled_tradable = insert_verified_closure_bars( + tradable_part, + symbol_calendars=tradable_calendars, + frequency=config.data.frequency, + strict=strict, + warnings=closure_warnings, + counts=closure_counts, + ) + report.warnings.extend(closure_warnings) + report.closure_discarded_count = closure_counts["discarded"] + report.closure_inserted_count = closure_counts["inserted"] + + # A real trading session with no row at all for a symbol -- a + # genuine gap, never a verified closure (already handled above) -- + # must be explicitly governed by missing_value_policy, the same + # guarantee documented for a missing *value* inside an existing + # row. Scoped to the tradable universe only, same reasoning as + # closure-fill: an external benchmark's own gaps are its own + # concern, never forced onto the portfolio's tradable timeline. + gap_warnings: list[str] = [] + filled_tradable = _apply_missing_value_policy_to_genuine_gaps( + filled_tradable, + symbol_calendars=tradable_calendars, + frequency=config.data.frequency, + policy=config.data.missing_value_policy, + forward_fill_limit=config.data.forward_fill_limit, + warnings=gap_warnings, + ) + report.warnings.extend(gap_warnings) + + sliced = ( + pd.concat([filled_tradable, benchmark_part], ignore_index=True) + .sort_values([TIMESTAMP, SYMBOL]) + .reset_index(drop=True) + ) + + # A mixed-calendar tradable universe's combined timeline (union of + # every instrument's own sessions) can start earlier than a + # session-bound instrument's actual first observation -- e.g. a 24/7 + # instrument already has a bar on a date a Yahoo/CSV equity simply + # has no data for yet, which closure-fill correctly leaves alone + # (never extrapolates before a symbol's first observed bar, see + # quantlab.data.closures). Left unhandled, that produces an + # unrecoverable NaN on the equity's own genuinely-first trading day + # once price_matrix pivots to the union grid and pct_change cascades + # -- caught only downstream, confusingly, by the benchmark-alignment + # or missing-return-while-held guards. Trim the whole panel (both + # tradable and any external-benchmark rows, which are unused before + # this point anyway) to the date every tradable symbol has real + # coverage from, so every downstream consumer starts from a panel + # where each tradable symbol genuinely has a price on its first row. + tradable_now = sliced.loc[sliced[SYMBOL].isin(tradable_symbols)] + first_by_symbol = tradable_now.groupby(SYMBOL)[TIMESTAMP].min() + if len(first_by_symbol) and first_by_symbol.max() > first_by_symbol.min(): + common_start = first_by_symbol.max() + # The symbol(s) that push the common start this late (their own + # first observation *is* common_start) -- not the ones losing + # rows, which is every symbol whose coverage began earlier. + limiting_symbols = sorted( + first_by_symbol.index[first_by_symbol == common_start] + ) + before = len(sliced) + sliced = sliced.loc[sliced[TIMESTAMP] >= common_start].reset_index( + drop=True + ) + report.warnings.append( + f"Tradable universe coverage effectively starts " + f"{common_start.date()}, later than the requested start -- " + f"{limiting_symbols} have no data before then (dropped " + f"{before - len(sliced)} earlier row(s) from other symbols)." + ) + + # Symmetric case at the other end: one tradable symbol's data simply + # stops earlier than another's (e.g. a stale feed), while the + # combined union timeline (built from every instrument's own + # sessions) keeps going. Those trailing dates aren't verified + # closures for the stopped symbol -- they're real sessions on its own + # calendar with no data at all -- so closure-fill correctly leaves + # them alone, and an unheld/unrebalanced position would otherwise hit + # an unrecoverable "asset return missing while held" failure deep in + # the engine instead of a clear, load-time explanation. Trim the + # whole panel the same way the start side already does. + tradable_now = sliced.loc[sliced[SYMBOL].isin(tradable_symbols)] + last_by_symbol = tradable_now.groupby(SYMBOL)[TIMESTAMP].max() + if len(last_by_symbol) and last_by_symbol.min() < last_by_symbol.max(): + common_end = last_by_symbol.min() + limiting_symbols = sorted( + last_by_symbol.index[last_by_symbol == common_end] + ) + before = len(sliced) + sliced = sliced.loc[sliced[TIMESTAMP] <= common_end].reset_index(drop=True) + report.warnings.append( + f"Tradable universe coverage effectively ends " + f"{common_end.date()}, earlier than the requested end -- " + f"{limiting_symbols} have no data after then (dropped " + f"{before - len(sliced)} later row(s) from other symbols)." + ) + report.raw_row_count = len(sliced_raw) report.clean_row_count = len(sliced) + report.bundled_demo_data_used = self._bundled_demo_data_used + # row_count was set inside validate(), before closure-fill (which can + # now both insert and discard rows, see quantlab.data.closures) and + # the start/end coverage trims above ever ran -- refresh it so it + # reflects the data this call actually returns, the same as + # clean_row_count just above. + report.row_count = len(sliced) present_symbols = set(sliced[SYMBOL].unique()) missing_symbols = sorted(set(expected_symbols) - present_symbols) if missing_symbols: @@ -150,14 +481,39 @@ def load( ) return sliced, report + @staticmethod + def _symbols_to_fetch(config: ExperimentConfig) -> list[str]: + """Return tradable symbols plus a separate symbol benchmark.""" + symbols = list(config.symbols) + benchmark = ( + config.benchmark_symbol + if config.benchmark_kind is BenchmarkKind.SYMBOL + else None + ) + if benchmark and benchmark not in symbols: + symbols.append(benchmark) + return symbols + def _download_symbol( self, source: MarketDataSource, - symbol: str, + instrument: InstrumentConfig, config: ExperimentConfig, *, force: bool, ) -> pd.DataFrame: + """Cache-aware fetch for one instrument. + + ``read_covered_symbol``/``read_symbol`` already mask any still-open + bar from the returned view (calendar-dependent, but never rewrites + the cache file -- see :meth:`~quantlab.data.storage.ParquetStorage. + read_symbol`'s own docstring). What this method does *not* apply is + the date-range restriction (``_slice_range``): that full + "prepare" pass runs afterward, in :meth:`_prepare_instrument_frame`, + which is what the "applied only after any cache read/write" claim + there actually refers to. + """ + symbol = instrument.symbol frequency = config.frequency start, end = config.start_date, config.end_date cached = None @@ -168,7 +524,7 @@ def _download_symbol( frequency, start, end, - is_247_market=config.data.is_247_market, + calendar=instrument.calendar, ) if cached is not None: logger.info("Cache hit for %s (%s).", symbol, source.name) @@ -180,14 +536,14 @@ def _download_symbol( start, end, frequency, - is_247_market=config.data.is_247_market, + calendar=instrument.calendar, ) self.storage.write_symbol( downloaded, source.name, symbol, frequency, - is_247_market=config.data.is_247_market, + calendar=instrument.calendar, replace_start=start, replace_end=end, ) @@ -195,7 +551,7 @@ def _download_symbol( source.name, symbol, frequency, - is_247_market=config.data.is_247_market, + calendar=instrument.calendar, ) if persisted is None: raise DataDownloadError( @@ -228,6 +584,7 @@ def _load_csv( raise DataDownloadError( f"Bundled demo data is incomplete; missing files: {missing}." ) + self._bundled_demo_data_used = True else: raise DataDownloadError( "CSV source files were not found. Expected: " @@ -251,18 +608,33 @@ def _slice_range( end: date, frequency: str, *, - is_247_market: bool, + calendar: str, ) -> pd.DataFrame: """Restrict raw timestamps and exclude bars settling after ``end``.""" timestamps = pd.to_datetime(data[TIMESTAMP]) end_boundary = pd.Timestamp(end) + pd.Timedelta(days=1) - mask = (timestamps >= pd.Timestamp(start)) & (timestamps < end_boundary) + # A naive UTC midnight boundary would drop a session's genuine + # early bars for a calendar whose local session opens before UTC + # midnight of its own label date (e.g. XASX, UTC+10/+11 -- its + # session dated `start` can open the previous UTC calendar day). + # Only relevant when `start` is itself a real session for this + # calendar; otherwise the naive boundary is already correct (the + # next real session, whenever it falls, has no reason to start + # before it). + start_boundary = pd.Timestamp(start) + if not is_247(calendar): + start_schedule = sessions(calendar, start_boundary, start_boundary) + if not start_schedule.empty: + start_boundary = min( + start_boundary, pd.Timestamp(start_schedule.iloc[0]["market_open"]) + ) + mask = (timestamps >= start_boundary) & (timestamps < end_boundary) sliced = data.loc[mask] if frequency in FREQUENCY_TIMEDELTA and not sliced.empty: bucket_ends = bar_bucket_end( pd.to_datetime(sliced[TIMESTAMP]), frequency, - is_247_market=is_247_market, + calendar=calendar, ) sliced = sliced.loc[bucket_ends <= end_boundary] return sliced.reset_index(drop=True) diff --git a/src/quantlab/data/resampler.py b/src/quantlab/data/resampler.py index 4cbac97..08eda82 100644 --- a/src/quantlab/data/resampler.py +++ b/src/quantlab/data/resampler.py @@ -3,6 +3,7 @@ from __future__ import annotations from collections.abc import Callable +from typing import Any import pandas as pd @@ -18,7 +19,12 @@ VOLUME, ) from quantlab.data.base import ensure_canonical_schema -from quantlab.data.calendar import FREQUENCY_TIMEDELTA +from quantlab.data.calendar import ( + FREQUENCY_TIMEDELTA, + is_247, + session_labels, + weekly_bucket_start, +) from quantlab.exceptions import DataValidationError @@ -49,9 +55,98 @@ def _sum_known_volume(values: pd.Series) -> float: "1M": "MS", } +# _FREQ_ALIAS's values are for `.resample(rule, label="left", closed="left")`, +# not for `.to_period()` -- the two disagree about what a "W-MON"-anchored +# week even is. `.resample("W-MON", label="left", closed="left")` genuinely +# bins Monday..Sunday (the explicit label/closed override the ambiguity). +# `Period(freq="W-MON")` does not: it means "week *ending* on Monday", i.e. +# Tuesday..Monday -- so grouping by `.to_period("W-MON")` would silently +# split a real Monday..Sunday week into a lone Monday plus a Tuesday..Friday +# remainder the following calendar week. pandas.Period has no anchored +# "month start" frequency distinct from a calendar month either -- 'MS' (a +# resample/date_range-only alias) must become 'M' for to_period(). The +# calendar-aware weekly path below never reaches `_PERIOD_ALIAS` at all +# (see `_resample_by_session`); this mapping is only used for the +# UTC-period path (`calendar` omitted or "24/7") and for monthly targets. +_PERIOD_ALIAS = {**_FREQ_ALIAS, "1mo": "M", "1M": "M"} + +#: `resample_ohlcv`'s own aliases for a weekly target. +_WEEKLY_KEYS = frozenset({"1w", "1W"}) + + +def _resample_by_session( + indexed: pd.DataFrame, target: str, calendar: str +) -> pd.DataFrame: + """Group by each bar's real trading session instead of a raw UTC period. + + Mirrors :func:`~quantlab.portfolio.rebalancing.rebalance_dates`'s + calendar-aware grouping technique: each row is first mapped to its own + session's real label date, then that label is grouped into the target + period -- so a session that straddles UTC midnight (e.g. XASX under + daylight saving) is never split across two output bars just because its + bars happen to fall on two different raw UTC calendar days. + + A weekly target additionally never groups by a fixed Monday-Sunday + period (``Period(freq="W-SUN")``): a calendar whose trading week isn't + Western (e.g. XSAU, Sunday-Thursday) has its Sunday session glued to + the *previous* ISO week instead of the Monday-Thursday sessions it + actually trades alongside, splitting one real trading week across two + output bars. :func:`~quantlab.data.calendar.weekly_bucket_start` + already resolves "which trading week does this date belong to, and + what's its own label date" using the calendar's own structural + weekdays (the same weekly-boundary logic `bar_bucket_end` uses for + cache/gap checks via its sibling `weekly_bucket_settlement`), so + grouping by it directly -- rather than by a pandas ``Period`` -- is + correct for every calendar, Western or not. + """ + session_dates = session_labels(calendar, pd.Series(indexed.index)) + if target in _WEEKLY_KEYS: + + def label_week_start(value: Any) -> pd.Timestamp: + return weekly_bucket_start(pd.Timestamp(value), calendar=calendar) + + week_starts = session_dates.map(label_week_start) + aggregated = indexed.groupby(week_starts.to_numpy()).agg(_AGG) + else: + periods = pd.DatetimeIndex(session_dates.to_numpy()).to_period( + _PERIOD_ALIAS[target] + ) + aggregated = indexed.groupby(periods.to_numpy()).agg(_AGG) + aggregated.index = pd.DatetimeIndex( + [period.start_time for period in aggregated.index] + ) + aggregated.index.name = TIMESTAMP + return aggregated.sort_index() + + +def _snap_to_nominal_frequency(observed: pd.Timedelta) -> pd.Timedelta: + """Classify a raw observed gap as the finest nominal cadence it fits. + + A raw gap between two adjacent bars is not directly comparable to + :data:`~quantlab.data.calendar.FREQUENCY_TIMEDELTA`'s fixed nominal + values: a real trading day's next bar can land 1-4 raw calendar days + later (a weekend, or a weekend plus a holiday), and a real calendar + month is 28-31 raw days, not a fixed 30. Comparing a literal gap + directly against a nominal target would misclassify already-daily data + with a weekend gap (e.g. Friday to Monday, 3 raw days) as coarser than + daily, or already-monthly data whose two bars are a genuine 31-day month + apart as coarser than monthly -- rejecting a resample that should be a + same-frequency no-op. Each band's upper bound comfortably covers its + cadence's known calendar variability while staying well short of the + next cadence's own nominal step, so this only ever *widens* what the + literal minimum would have accepted, never narrows it. + """ + if observed <= FREQUENCY_TIMEDELTA["1h"]: + return FREQUENCY_TIMEDELTA["1h"] + if observed <= pd.Timedelta(days=5): + return FREQUENCY_TIMEDELTA["1d"] + if observed <= pd.Timedelta(days=10): + return FREQUENCY_TIMEDELTA["1w"] + return FREQUENCY_TIMEDELTA["1mo"] + def _observed_source_step(data: pd.DataFrame) -> pd.Timedelta: - """Infer the finest positive spacing observed within any symbol.""" + """Infer the nominal source frequency from the finest observed spacing.""" candidates: list[pd.Timedelta] = [] for _, group in data.groupby(SYMBOL, sort=False): timestamps = pd.DatetimeIndex(group[TIMESTAMP]).sort_values().unique() @@ -66,7 +161,7 @@ def _observed_source_step(data: pd.DataFrame) -> pd.Timedelta: "Cannot infer the source frequency from fewer than two distinct " "timestamps for any symbol; pass source_frequency explicitly." ) - return min(candidates) + return _snap_to_nominal_frequency(min(candidates)) def resample_ohlcv( @@ -74,6 +169,7 @@ def resample_ohlcv( frequency: str, *, source_frequency: str | None = None, + calendar: str | None = None, ) -> pd.DataFrame: """Aggregate a canonical long OHLCV frame to the same or a coarser frequency. @@ -82,6 +178,13 @@ def resample_ohlcv( frequency: Supported target frequency. source_frequency: Optional declared input frequency. When omitted, the finest positive timestamp spacing is inferred per symbol. + calendar: Optional instrument calendar. Omitted (the default) or + ``"24/7"`` groups by raw UTC period boundaries, exactly as + before. Any other calendar groups by each bar's real trading + session instead (see :func:`~quantlab.data.calendar. + session_labels`) -- a raw UTC boundary would otherwise split one + real session's bars across two output bars for a calendar whose + local session crosses UTC midnight (e.g. XASX, UTC+10/+11). Raises: DataValidationError: If the schema, frequency, uniqueness, or @@ -123,15 +226,21 @@ def resample_ohlcv( f"frequency {frequency!r}." ) + session_calendar = ( + calendar if calendar is not None and not is_247(calendar) else None + ) out_frames: list[pd.DataFrame] = [] price_columns = [column for column in PRICE_COLUMNS if column in canonical] for symbol, group in canonical.groupby(SYMBOL, sort=True): indexed = group.set_index(TIMESTAMP).sort_index() - # This mapping is valid pandas usage; pandas-stubs does not model the - # mixed string/callable aggregation overload precisely. - resampled = indexed.resample( - _FREQ_ALIAS[target], label="left", closed="left" - ).agg(_AGG) # type: ignore[arg-type] + if session_calendar is not None: + resampled = _resample_by_session(indexed, target, session_calendar) + else: + # This mapping is valid pandas usage; pandas-stubs does not model + # the mixed string/callable aggregation overload precisely. + resampled = indexed.resample( + _FREQ_ALIAS[target], label="left", closed="left" + ).agg(_AGG) # type: ignore[arg-type] resampled = resampled.dropna(subset=price_columns, how="all") resampled[SYMBOL] = symbol out_frames.append(resampled.reset_index()) diff --git a/src/quantlab/data/resolution.py b/src/quantlab/data/resolution.py new file mode 100644 index 0000000..0257211 --- /dev/null +++ b/src/quantlab/data/resolution.py @@ -0,0 +1,85 @@ +"""Symbol -> source/calendar suggestions, for the dashboard only. + +Pure, deterministic, offline heuristics used to pre-fill a form — never +consulted by config validation, the data loader, or the validator. Once a +config is built (YAML or dashboard), it is explicit and fully resolved; +:class:`~quantlab.config.InstrumentConfig` always carries a concrete +source/calendar, never a value inferred here at run time. +""" + +from __future__ import annotations + +import re + +from quantlab.config import DataSourceName + +#: Quote assets covering the overwhelming majority of active Binance pairs. +_BINANCE_QUOTE_ASSETS = frozenset( + { + "USDT", + "BUSD", + "USDC", + "FDUSD", + "TUSD", + "DAI", + "BTC", + "ETH", + "BNB", + "EUR", + "GBP", + "TRY", + "BRL", + } +) +_BINANCE_SHAPE = re.compile(r"^[A-Z0-9]{2,20}$") + +#: A bare US ticker, or one with a short exchange suffix (e.g. "1211.HK"). +_YAHOO_SHAPE = re.compile(r"^[A-Z][A-Z0-9]{0,5}(\.[A-Z]{1,3})?$") + +#: Hand-maintained, conservative: an unmapped suffix returns None rather than +#: a wrong guess (e.g. Yahoo suffixes not listed here). +_YAHOO_SUFFIX_CALENDAR: dict[str | None, str] = { + None: "XNYS", + "L": "LSE", + "HK": "XHKG", + "T": "XTKS", + "PA": "XPAR", + "DE": "XFRA", + "MI": "XMIL", + "AS": "XAMS", + "SW": "XSWX", + "TO": "XTSE", + "SI": "XSES", + "AX": "XASX", + "KS": "XKRX", +} + + +def detect_source(symbol: str) -> DataSourceName | None: + """Best-effort guess at a symbol's data source, or ``None`` if unsure. + + Never returns ``csv``: nothing about a bare ticker string implies a + local file, so a csv-sourced instrument always needs an explicit choice. + """ + candidate = symbol.strip().upper() + if not candidate: + return None + if _BINANCE_SHAPE.match(candidate) and any( + candidate.endswith(quote) and len(candidate) > len(quote) + 1 + for quote in _BINANCE_QUOTE_ASSETS + ): + return DataSourceName.BINANCE + if _YAHOO_SHAPE.match(candidate): + return DataSourceName.YAHOO + return None + + +def detect_calendar(symbol: str, source: DataSourceName) -> str | None: + """Best-effort guess at a symbol's calendar given its (resolved) source.""" + if source is DataSourceName.BINANCE: + return "24/7" + if source is DataSourceName.YAHOO: + candidate = symbol.strip().upper() + suffix = candidate.split(".", 1)[1] if "." in candidate else None + return _YAHOO_SUFFIX_CALENDAR.get(suffix) + return None diff --git a/src/quantlab/data/storage.py b/src/quantlab/data/storage.py index 5a4a99c..d2292f2 100644 --- a/src/quantlab/data/storage.py +++ b/src/quantlab/data/storage.py @@ -23,13 +23,16 @@ FREQUENCY_TIMEDELTA, MONTHLY_FREQUENCIES, PERIODIC_FREQUENCIES, - XNYS_BUSINESS_DAY, bar_bucket_end, + business_day_offset, first_trading_day_on_or_after, + is_247, last_trading_day_on_or_before, monthly_bucket_settlement, + session_labels, + sessions, weekly_bucket_settlement, - xnys_sessions, + weekly_bucket_start, ) from quantlab.exceptions import DataValidationError from quantlab.logging_config import get_logger @@ -38,12 +41,25 @@ # Increment when cached data or its normalization contract changes. A new # namespace prevents older files from silently surviving a code-level fix. -_CACHE_FORMAT_VERSION = "v2" +# v3: adds the per-row `_fetched_at` provenance column (see +# `_FETCHED_AT_COLUMN`) -- a v2 file has no such column and no way to +# retrofit one honestly, so it must never be silently reused as if its +# bars' fetch-vs-settlement timing were known. +_CACHE_FORMAT_VERSION = "v3" _DAILY_POSTING_LAG = pd.Timedelta(hours=12) _INTRADAY_POSTING_LAG = pd.Timedelta(minutes=30) _PERIODIC_POSTING_LAG = pd.Timedelta(hours=12) _LOCK_TIMEOUT_SECONDS = 30.0 +# Internal-only column (never part of the canonical OHLCV schema, always +# stripped before data leaves this module): the wall-clock instant each row +# was last written by `write_symbol`. Tracked per row, not per file -- +# `write_symbol` merges incoming rows into a file that may already hold +# older rows fetched at a different time, and a later write touching only +# an unrelated date range must not be mistaken for having refreshed every +# row in the file (see `_frame_covers`). +_FETCHED_AT_COLUMN = "_fetched_at" + def _utc_now() -> pd.Timestamp: """Return the current instant as timezone-naive UTC.""" @@ -78,16 +94,34 @@ def _has_internal_month_gap( def _has_internal_week_gap( - timestamps: pd.Series, range_start: pd.Timestamp, range_end: pd.Timestamp + timestamps: pd.Series, + range_start: pd.Timestamp, + range_end: pd.Timestamp, + *, + calendar: str, ) -> bool: - """Return whether a touched calendar week contains no bar.""" + """Return whether a touched trading week (``calendar``'s own week) has no bar. + + Buckets by :func:`~quantlab.data.calendar.weekly_bucket_start`, not a + fixed Monday-Sunday ``Period("W")`` -- a calendar whose trading week + isn't Western (e.g. XSAU, Sunday-Thursday) has its Sunday session + grouped with the *previous* ISO week by ``.to_period("W")``, splitting + one real trading week's coverage across two periods and reporting a + perfectly complete cache as having an internal gap. + """ if range_start > range_end: return False - expected = pd.period_range( - range_start.to_period("W"), range_end.to_period("W"), freq="W" - ) - present = set(pd.to_datetime(timestamps).dt.to_period("W")) - return any(period not in present for period in expected) + expected_starts: set[pd.Timestamp] = set() + cursor = weekly_bucket_start(range_start, calendar=calendar) + last_bucket = weekly_bucket_start(range_end, calendar=calendar) + while cursor <= last_bucket: + expected_starts.add(cursor) + cursor = cursor + pd.Timedelta(days=7) + present = { + weekly_bucket_start(pd.Timestamp(value), calendar=calendar) + for value in pd.to_datetime(timestamps) + } + return any(bucket not in present for bucket in expected_starts) _HASH_SUFFIX_SHAPE = re.compile(r"-[0-9a-f]{10}$") @@ -129,29 +163,43 @@ def _sanitize_non_finite_floats(value: object) -> object: def _drop_still_open_bars( - data: pd.DataFrame, frequency: str, *, is_247_market: bool = False + data: pd.DataFrame, frequency: str, *, calendar: str ) -> pd.DataFrame: - """Exclude bars whose settlement instant is still in the future.""" + """Exclude bars not yet safely final. + + A bar isn't just excluded while its own trading bucket is still open + (``bucket_end > now``) -- it's excluded until ``_posting_lag_for``'s own + tolerance has *also* elapsed (``bucket_end + posting_lag <= now``), the + same threshold every coverage check elsewhere in this module already + uses to decide whether a bar is safe to trust. A provider can still + revise a bar shortly after its bucket closes (this is exactly what the + posting-lag tolerance exists to accommodate for cache *coverage* + checks); serving it to a caller the moment the bucket closes, before + that tolerance has passed, would let a not-yet-finalised value straight + into a backtest even though the rest of the system doesn't yet + consider it settled. + """ if data.empty: return data bucket_end = bar_bucket_end( pd.to_datetime(data[TIMESTAMP]), frequency, - is_247_market=is_247_market, + calendar=calendar, ) - return data.loc[bucket_end <= _utc_now()].reset_index(drop=True) + safe_at = bucket_end + _posting_lag_for(frequency) + return data.loc[safe_at <= _utc_now()].reset_index(drop=True) -def _latest_safe_daily_bar_date( - now: pd.Timestamp, *, is_247_market: bool -) -> pd.Timestamp: +def _latest_safe_daily_bar_date(now: pd.Timestamp, *, calendar: str) -> pd.Timestamp: """Return the date of the latest daily bar expected to be final.""" safe_cutoff = now - _DAILY_POSTING_LAG - if is_247_market: + if is_247(calendar): return safe_cutoff.normalize() - pd.Timedelta(days=1) - schedule = xnys_sessions( - safe_cutoff.normalize() - pd.Timedelta(days=60), safe_cutoff.normalize() + schedule = sessions( + calendar, + safe_cutoff.normalize() - pd.Timedelta(days=60), + safe_cutoff.normalize(), ) eligible = schedule[schedule["market_close"] <= safe_cutoff] if eligible.empty: @@ -164,24 +212,20 @@ def _daily_cache_covers( start: pd.Timestamp, end: pd.Timestamp, *, - is_247_market: bool, + calendar: str, now: pd.Timestamp, ) -> bool: - effective_end = min( - end, _latest_safe_daily_bar_date(now, is_247_market=is_247_market) - ) + effective_end = min(end, _latest_safe_daily_bar_date(now, calendar=calendar)) if effective_end < start: return True - expected_first = first_trading_day_on_or_after(start, is_247_market=is_247_market) - expected_last = last_trading_day_on_or_before( - effective_end, is_247_market=is_247_market - ) + expected_first = first_trading_day_on_or_after(start, calendar=calendar) + expected_last = last_trading_day_on_or_before(effective_end, calendar=calendar) if timestamps.min() > expected_first + _DAILY_POSTING_LAG: return False if timestamps.max() < expected_last - _DAILY_POSTING_LAG: return False - step = pd.Timedelta(days=1) if is_247_market else XNYS_BUSINESS_DAY + step = pd.Timedelta(days=1) if is_247(calendar) else business_day_offset(calendar) return not _has_internal_gap(timestamps, step, expected_first, expected_last) @@ -211,31 +255,70 @@ def _equity_intraday_cache_covers( end: pd.Timestamp, *, step: pd.Timedelta, + calendar: str, now: pd.Timestamp, ) -> bool: - """Check every requested XNYS session, including both range edges.""" + """Check every requested session on ``calendar``, including both range edges.""" safe_cutoff = min(end + pd.Timedelta(days=1), now - _INTRADAY_POSTING_LAG) schedule_end = min(end, safe_cutoff.normalize()) if schedule_end < start: return True - schedule = xnys_sessions(start, schedule_end) + schedule = sessions(calendar, start, schedule_end) if schedule.empty: return True requested = pd.to_datetime(timestamps) - requested = requested[ - (requested >= start) & (requested < end + pd.Timedelta(days=1)) + # Widen by a day on each side before filtering: a calendar whose local + # session crosses UTC midnight (e.g. XASX, UTC+10/+11) opens its + # session labeled `start` on the UTC calendar day *before* `start` + # itself -- a raw `requested >= start` bound would strip that session's + # genuine early bars before they're ever counted, permanently + # undercounting every session on such a calendar. + window = requested[ + (requested >= start - pd.Timedelta(days=1)) + & (requested < end + pd.Timedelta(days=2)) ] - by_day = { - pd.Timestamp(day): pd.DatetimeIndex(values).sort_values() - for day, values in requested.groupby(requested.dt.normalize()) - } + # Group by each bar's real trading-session date (see + # quantlab.data.calendar.session_labels), not a naive UTC calendar-day + # boundary: a calendar whose local session crosses UTC midnight would + # otherwise have one real session's bars split across two different + # "days", undercounting that session and triggering a spurious + # re-download -- or, the other direction, letting a late bar bleed into + # the following session's count and mask a real gap there. Extra + # entries this window pulls in for days outside `[start, schedule_end]` + # are harmless: the loop below only ever looks up a `session_day` + # already constrained to that range. + if window.empty: + by_day: dict[pd.Timestamp, pd.DatetimeIndex] = {} + else: + labels = session_labels(calendar, window) + by_day = { + pd.Timestamp(day): pd.DatetimeIndex(values).sort_values() + for day, values in window.groupby(labels) + } for session_day_raw, row in schedule.iterrows(): session_day = pd.Timestamp(str(session_day_raw)) market_open = pd.Timestamp(row["market_open"]) market_close = pd.Timestamp(row["market_close"]) starts = pd.date_range(market_open, market_close, freq=step, inclusive="left") + # A calendar with an official intraday break (e.g. XHKG's lunch + # recess) trades in two disjoint intervals, not one continuous + # [market_open, market_close) block -- a real provider has no bars + # during the break, so counting it as "expected" would make a + # genuinely complete cache look incomplete and trigger a spurious + # re-download every time. + break_start = row.get("break_start") + break_start_ts = ( + pd.Timestamp(break_start) + if break_start is not None and pd.notna(break_start) + else None + ) + break_end_ts = ( + pd.Timestamp(row["break_end"]) if break_start_ts is not None else None + ) + if break_start_ts is not None and break_end_ts is not None: + starts = starts[(starts < break_start_ts) | (starts >= break_end_ts)] settlements = pd.DatetimeIndex( [min(bar_start + step, market_close) for bar_start in starts] ) @@ -247,41 +330,67 @@ def _equity_intraday_cache_covers( if day_values is None or len(day_values) < expected_count: return False if len(day_values) > 1: - deltas = pd.Series(day_values).diff().dropna() - if (deltas > step * 1.5).any(): + series = pd.Series(day_values) + deltas = series.diff() + excessive = deltas > step * 1.5 + if ( + excessive.any() + and break_start_ts is not None + and break_end_ts is not None + ): + # A gap that straddles the official break isn't a real + # internal gap once the break's own duration is accounted + # for -- same reasoning as excluding it from expected_count + # above. + break_duration = break_end_ts - break_start_ts + previous = series.shift(1) + explained = ( + excessive + & (previous <= break_start_ts) + & (series >= break_end_ts) + & (deltas - break_duration <= step * 1.5) + ) + excessive = excessive & ~explained + if excessive.fillna(False).any(): return False return True def _period_settlement( - timestamp: pd.Timestamp, frequency: str, *, is_247_market: bool + timestamp: pd.Timestamp, frequency: str, *, calendar: str ) -> pd.Timestamp: if frequency in MONTHLY_FREQUENCIES: - return monthly_bucket_settlement(timestamp, is_247_market=is_247_market) - return weekly_bucket_settlement(timestamp, is_247_market=is_247_market) + return monthly_bucket_settlement(timestamp, calendar=calendar) + return weekly_bucket_settlement(timestamp, calendar=calendar) def _previous_period_end(timestamp: pd.Timestamp, frequency: str) -> pd.Timestamp: + """Return any representative date within the period before ``timestamp``'s. + + Which exact date doesn't matter -- :func:`_period_settlement` resolves + every date within a period to the same settlement -- only that it lands + unambiguously one period back. A full 7-day step always does that for a + weekly cadence regardless of which weekday a calendar's own week starts + on (e.g. XSAU trades Sunday-Thursday); the previous ``dayofweek``-based + computation assumed a fixed Monday-Sunday ISO week, which is wrong for + such a calendar. + """ if frequency in MONTHLY_FREQUENCIES: month_start = pd.Timestamp(timestamp.year, timestamp.month, 1) return month_start - pd.Timedelta(days=1) - week_start = timestamp.normalize() - pd.Timedelta(days=timestamp.dayofweek) - return week_start - pd.Timedelta(days=1) + return timestamp.normalize() - pd.Timedelta(days=7) def _latest_safe_period_date( end: pd.Timestamp, frequency: str, *, - is_247_market: bool, + calendar: str, now: pd.Timestamp, ) -> pd.Timestamp: candidate = min(end, now.normalize()) safe_cutoff = now - _PERIODIC_POSTING_LAG - if ( - _period_settlement(candidate, frequency, is_247_market=is_247_market) - > safe_cutoff - ): + if _period_settlement(candidate, frequency, calendar=calendar) > safe_cutoff: candidate = _previous_period_end(candidate, frequency) return candidate @@ -292,29 +401,29 @@ def _periodic_cache_covers( end: pd.Timestamp, frequency: str, *, - is_247_market: bool, + calendar: str, now: pd.Timestamp, ) -> bool: effective_end = _latest_safe_period_date( end, frequency, - is_247_market=is_247_market, + calendar=calendar, now=now, ) if effective_end < start: return True - effective_start = first_trading_day_on_or_after(start, is_247_market=is_247_market) + effective_start = first_trading_day_on_or_after(start, calendar=calendar) if timestamps.min() > effective_start + _PERIODIC_POSTING_LAG: return False required_settlement = _period_settlement( - effective_end, frequency, is_247_market=is_247_market + effective_end, frequency, calendar=calendar ) latest_bucket_end = _period_settlement( pd.Timestamp(timestamps.max()), frequency, - is_247_market=is_247_market, + calendar=calendar, ) if latest_bucket_end < required_settlement: return False @@ -327,7 +436,7 @@ def _periodic_cache_covers( raise DataValidationError("Cached bar timestamps must not be missing.") relevant_settlements = pd.DatetimeIndex( [ - _period_settlement(timestamp, frequency, is_247_market=is_247_market) + _period_settlement(timestamp, frequency, calendar=calendar) for timestamp in relevant_index ] ) @@ -337,7 +446,27 @@ def _periodic_cache_covers( if frequency in MONTHLY_FREQUENCIES: return not _has_internal_month_gap(timestamps, start, effective_end) - return not _has_internal_week_gap(timestamps, start, effective_end) + return not _has_internal_week_gap( + timestamps, start, effective_end, calendar=calendar + ) + + +def _posting_lag_for(frequency: str) -> pd.Timedelta: + """Return the posting-delay tolerance a frequency's coverage check uses. + + The same three lag constants ``_daily_cache_covers``/ + ``_periodic_cache_covers``/``_hourly_247_cache_covers``/ + ``_equity_intraday_cache_covers`` already apply for "how long after + settlement a provider might still be finalising a bar" -- the per-row + staleness check in ``_frame_covers`` uses the same tolerance, so a bar + is force-refreshed only once it has had a fair chance to actually be + posted, not the instant its bucket closes. + """ + if frequency in DAILY_FREQUENCIES: + return _DAILY_POSTING_LAG + if frequency in PERIODIC_FREQUENCIES: + return _PERIODIC_POSTING_LAG + return _INTRADAY_POSTING_LAG class ParquetStorage: @@ -393,15 +522,29 @@ def _cache_path(self, source: str, symbol: str, frequency: str) -> Path: ) def _read_cache_file(self, path: Path, symbol: str) -> pd.DataFrame | None: + """Read the raw cache file, including the internal `_fetched_at` column. + + A file with no `_fetched_at` column (written directly via + :meth:`save`, bypassing :meth:`write_symbol` -- production never + does this) gets it filled with ``NaT``: unknown provenance, treated + by :meth:`_frame_covers` as stale rather than trusted once a row's + bucket has safely closed (it offers no proof of a fresh fetch). + """ if not path.is_file(): return None try: - data = ensure_canonical_schema(self.load(path)) + raw = self.load(path) + canonical = ensure_canonical_schema(raw) + canonical[_FETCHED_AT_COLUMN] = ( + pd.to_datetime(raw[_FETCHED_AT_COLUMN].to_numpy()) + if _FETCHED_AT_COLUMN in raw.columns + else pd.NaT + ) except Exception as exc: # pragma: no cover - corrupt cache is rare logger.warning("Failed to read cache %s: %s", path, exc) return None - present_symbols = set(data[SYMBOL].unique()) + present_symbols = set(canonical[SYMBOL].unique()) if present_symbols and present_symbols != {symbol}: logger.warning( "Ignoring cache %s: expected symbol %s, found %s.", @@ -411,40 +554,56 @@ def _read_cache_file(self, path: Path, symbol: str) -> pd.DataFrame | None: ) return None return ( - data.drop_duplicates(subset=[TIMESTAMP], keep="last") + canonical.drop_duplicates(subset=[TIMESTAMP], keep="last") .sort_values(TIMESTAMP) .reset_index(drop=True) ) + def _read_filtered_with_provenance( + self, source: str, symbol: str, frequency: str, *, calendar: str + ) -> pd.DataFrame | None: + """Settlement-filtered view, still carrying the internal `_fetched_at`. + + Shared by :meth:`read_symbol` (which drops the column before + returning) and :meth:`read_covered_symbol` (which additionally needs + it for :meth:`_frame_covers`'s per-row staleness check). + """ + normalized_symbol = symbol.strip().upper() + path = self._cache_path(source, normalized_symbol, frequency) + data = self._read_cache_file(path, normalized_symbol) + if data is None: + return None + return _drop_still_open_bars(data, frequency, calendar=calendar) + def read_symbol( self, source: str, symbol: str, frequency: str, *, - is_247_market: bool = False, + calendar: str, ) -> pd.DataFrame | None: - """Return one cached symbol after purging provisional bars.""" - normalized_symbol = symbol.strip().upper() - path = self._cache_path(source, normalized_symbol, frequency) - data = self._read_cache_file(path, normalized_symbol) - if data is None: + """Return one cached symbol with provisional bars filtered out. + + Filters the returned view only -- never rewrites the file. Two + experiments can legitimately share one cache key (same source, + symbol, frequency) while requesting different calendars (e.g. XNYS + vs 24/7), which settle a bar's bucket at different instants; if a + read purged the file using whichever caller happened to ask first, + one calendar's "still open" opinion could permanently delete a bar + another calendar had already correctly settled and stored. Leaving + the file untouched keeps the cache genuinely calendar-independent: + :meth:`write_symbol` never drops still-open bars either (see its own + docstring), so the persisted file's content never depends on which + calendar happened to write last -- only each caller's own read + applies its own settlement opinion. + """ + filtered = self._read_filtered_with_provenance( + source, symbol, frequency, calendar=calendar + ) + if filtered is None: return None - filtered = _drop_still_open_bars(data, frequency, is_247_market=is_247_market) - if filtered.equals(data): - return filtered - - # Re-read under the lock so a concurrent writer cannot be overwritten - # by a purge based on an older snapshot. - with self._lock(path): - current = self._read_cache_file(path, normalized_symbol) - if current is None: - return None - filtered = _drop_still_open_bars( - current, frequency, is_247_market=is_247_market - ) - self._atomic_save_unlocked(filtered, path) - return filtered + return filtered.drop(columns=[_FETCHED_AT_COLUMN]) def write_symbol( self, @@ -453,7 +612,7 @@ def write_symbol( symbol: str, frequency: str, *, - is_247_market: bool = False, + calendar: str, replace_start: date | None = None, replace_end: date | None = None, ) -> Path: @@ -461,9 +620,30 @@ def write_symbol( ``replace_start`` and ``replace_end`` may delimit a freshly downloaded interval whose previous cached rows must be removed before merging. + + Deliberately does *not* drop still-open bars before persisting -- + the cache key is source/symbol/frequency only, with no calendar + component, so filtering the stored file by whichever calendar + happened to call last would make the same file's on-disk content + depend on write order between experiments using different + calendars, silently reintroducing the same calendar dependence + :meth:`read_symbol` is designed to avoid. A still-open bar is + instead naturally superseded once its real, closed value is next + downloaded -- and this is now actually enforced, not merely + aspirational: every incoming row is stamped with the current instant + under the internal ``_fetched_at`` column, preserved per row across + merges (a row untouched by this write keeps its *previous* + ``_fetched_at``, never inherits this write's), which + :meth:`_frame_covers` uses to force a redownload of any row whose + bucket was still open when it was actually fetched and has since + settled. ``calendar`` is still used, but only to make the + ``replace_start``/``replace_end`` purge itself calendar-aware (see + below) -- never to decide which rows are settled/still-open, which + stays exclusively a read-time decision. """ normalized_symbol = symbol.strip().upper() incoming = ensure_canonical_schema(data) + incoming[_FETCHED_AT_COLUMN] = _utc_now() present_symbols = set(incoming[SYMBOL].unique()) if present_symbols and present_symbols != {normalized_symbol}: raise DataValidationError( @@ -490,6 +670,19 @@ def write_symbol( ): timestamps = pd.to_datetime(existing[TIMESTAMP]) lower = pd.Timestamp(replace_start) + # A naive UTC-midnight `lower` would let a genuine + # `replace_start` session bar survive a forced replacement + # for a calendar whose local session opens before UTC + # midnight of its own label date (e.g. XASX under daylight + # saving, UTC+11 -- its session dated `replace_start` can + # open on the previous UTC calendar day), the same crossing + # `DataLoader._slice_range` already accounts for on read. + if not is_247(calendar): + start_schedule = sessions(calendar, lower, lower) + if not start_schedule.empty: + lower = min( + lower, pd.Timestamp(start_schedule.iloc[0]["market_open"]) + ) upper = pd.Timestamp(replace_end) + pd.Timedelta(days=1) existing = existing.loc[(timestamps < lower) | (timestamps >= upper)] @@ -500,9 +693,6 @@ def write_symbol( .sort_values(TIMESTAMP) .reset_index(drop=True) ) - merged = _drop_still_open_bars( - merged, frequency, is_247_market=is_247_market - ) self._atomic_save_unlocked(merged, path) logger.info("Wrote %d cached rows to %s", len(merged), path) return path @@ -514,9 +704,29 @@ def _frame_covers( start: date, end: date, *, - is_247_market: bool, + calendar: str, ) -> bool: - """Apply frequency-specific coverage rules to a cached frame.""" + """Apply frequency-specific coverage rules to a cached frame. + + Also guards against a stale row anywhere within the requested + ``[start, end]`` range, not only the newest one in the file: a + symbol whose frontier keeps advancing (new bars appended over time) + can leave an older, still-provisional-when-fetched bar buried + mid-file, never revisited again -- checking only the newest row + would stop catching it the moment a newer bar arrives. A row counts + as covering its bucket only when it carries proof (the per-row + ``_fetched_at`` column ``write_symbol`` always sets, see its own + docstring) of having been fetched at or after that bucket's safe + instant (``bucket_end`` plus this frequency's posting-lag tolerance, + see ``_posting_lag_for``) -- once that instant has passed, a row + without such proof (a too-early fetch, or unknown provenance from a + file written directly via :meth:`save`, bypassing + :meth:`write_symbol`; production never does this) is treated as + stale rather than trusted. Rows whose own bucket doesn't overlap the + requested range are ignored: a narrow re-download can't refresh + them, so counting them here would make the cache look permanently + incomplete for requests that never touch them. + """ if cached.empty: return False if frequency not in FREQUENCY_TIMEDELTA: @@ -532,15 +742,47 @@ def _frame_covers( end_ts = pd.Timestamp(end) now = _utc_now() + if _FETCHED_AT_COLUMN in cached.columns: + fetched_at = pd.to_datetime( + cached.loc[timestamps.index, _FETCHED_AT_COLUMN] + ) + bucket_end = bar_bucket_end(timestamps, frequency, calendar=calendar) + safe_at = bucket_end + _posting_lag_for(frequency) + # A row's own bucket may sit entirely outside [start, end] (an + # older bar the frontier has since moved past) -- such a row can + # never be refreshed by a write that only replaces the requested + # range, so counting it here would make the cache permanently + # "not covering" every future request that doesn't happen to + # touch it too. Scope staleness to buckets overlapping the + # requested window, using the same day-inclusive widening as the + # frequency-specific coverage checks below (``end`` is a + # calendar day, so its bucket can extend past midnight). + in_requested_range = (timestamps < end_ts + pd.Timedelta(days=1)) & ( + bucket_end > start_ts + ) + # Once a row's own safe-at instant has passed, only a *confirmed* + # fetch at or after that instant proves the bar is the settled + # value, not a provisional one -- a row whose provenance is + # unknown (``_fetched_at`` missing/``NaT``, e.g. a file written + # directly via :meth:`save`, bypassing :meth:`write_symbol`; + # production never does this) offers no such proof and must be + # treated the same as a row confirmed too-early, not silently + # trusted. + verified_by_now = safe_at <= now + confirmed_fresh = fetched_at.notna() & (fetched_at >= safe_at) + stale = in_requested_range & verified_by_now & ~confirmed_fresh + if stale.any(): + return False + if frequency in DAILY_FREQUENCIES: return _daily_cache_covers( timestamps, start_ts, end_ts, - is_247_market=is_247_market, + calendar=calendar, now=now, ) - if is_247_market and frequency in {"1h", "1H"}: + if is_247(calendar) and frequency in {"1h", "1H"}: return _hourly_247_cache_covers(timestamps, start_ts, end_ts, now=now) if frequency in PERIODIC_FREQUENCIES: return _periodic_cache_covers( @@ -548,7 +790,7 @@ def _frame_covers( start_ts, end_ts, frequency, - is_247_market=is_247_market, + calendar=calendar, now=now, ) return _equity_intraday_cache_covers( @@ -556,6 +798,7 @@ def _frame_covers( start_ts, end_ts, step=FREQUENCY_TIMEDELTA[frequency], + calendar=calendar, now=now, ) @@ -567,23 +810,17 @@ def read_covered_symbol( start: date, end: date, *, - is_247_market: bool = False, + calendar: str, ) -> pd.DataFrame | None: """Read a symbol once and return it only when it covers the request.""" - cached = self.read_symbol( - source, symbol, frequency, is_247_market=is_247_market + filtered = self._read_filtered_with_provenance( + source, symbol, frequency, calendar=calendar ) - if cached is None: + if filtered is None: return None - if not self._frame_covers( - cached, - frequency, - start, - end, - is_247_market=is_247_market, - ): + if not self._frame_covers(filtered, frequency, start, end, calendar=calendar): return None - return cached + return filtered.drop(columns=[_FETCHED_AT_COLUMN]) def cache_covers( self, @@ -593,7 +830,7 @@ def cache_covers( start: date, end: date, *, - is_247_market: bool = False, + calendar: str, ) -> bool: """Return whether the cache contains every safely final requested bar.""" return ( @@ -603,7 +840,7 @@ def cache_covers( frequency, start, end, - is_247_market=is_247_market, + calendar=calendar, ) is not None ) diff --git a/src/quantlab/data/validator.py b/src/quantlab/data/validator.py index b295e7a..781bee4 100644 --- a/src/quantlab/data/validator.py +++ b/src/quantlab/data/validator.py @@ -2,7 +2,7 @@ from __future__ import annotations -from collections.abc import Sequence +from collections.abc import Mapping, Sequence from dataclasses import dataclass, field from datetime import date, datetime from typing import Any, cast @@ -24,14 +24,19 @@ ) from quantlab.data.calendar import DAILY_FREQUENCIES as _DAILY_FREQUENCIES from quantlab.data.calendar import FREQUENCY_TIMEDELTA as _FREQUENCY_TIMEDELTA -from quantlab.data.calendar import XNYS_BUSINESS_DAY as _XNYS_BUSINESS_DAY +from quantlab.data.calendar import business_day_offset as _business_day_offset from quantlab.data.calendar import ( first_trading_day_on_or_after as _first_trading_day_on_or_after, ) +from quantlab.data.calendar import has_session_break as _has_session_break +from quantlab.data.calendar import holidays_between as _holidays_between +from quantlab.data.calendar import is_247 as _is_247 from quantlab.data.calendar import ( last_trading_day_on_or_before as _last_trading_day_on_or_before, ) -from quantlab.data.calendar import xnys_holidays as _xnys_holidays +from quantlab.data.calendar import session_labels as _session_labels +from quantlab.data.calendar import session_weekmask as _session_weekmask +from quantlab.data.calendar import sessions as _sessions from quantlab.exceptions import DataValidationError from quantlab.logging_config import get_logger @@ -76,10 +81,30 @@ class DataQualityReport: invalid_price_count: int = 0 missing_periods: list[MissingPeriod] = field(default_factory=list) warnings: list[str] = field(default_factory=list) + #: Real rows discarded because they fell on a verified closure for their + #: own symbol's calendar (a data anomaly, not a gap). + closure_discarded_count: int = 0 + #: Synthetic flat bars inserted for a verified closure with no real row. + closure_inserted_count: int = 0 + #: Whether the bundled synthetic CSV fallback (``use_bundled_demo_data``) + #: was actually triggered for at least one instrument -- distinct from + #: the config merely *enabling* it, which by itself says nothing about + #: whether local files were actually missing this run. + bundled_demo_data_used: bool = False @property def removed_row_count(self) -> int | None: - """Return rows removed by cleaning when both stages are known.""" + """Return the net raw-to-clean row-count delta when both stages are known. + + A net figure, not a count of any single effect: cleaning can both + remove rows (duplicates, invalid prices, dropped gaps) and add rows + (verified-closure bars, forward-filled gaps), so this can be zero or + even negative (more rows added than removed) without that meaning + "nothing happened." For what specifically happened, use the + dedicated counts instead: ``duplicate_count``, ``invalid_price_ + count``, ``missing_value_count``, ``closure_inserted_count``, + ``closure_discarded_count``. + """ if self.raw_row_count is None or self.clean_row_count is None: return None return self.raw_row_count - self.clean_row_count @@ -123,6 +148,9 @@ def to_dict(self) -> dict[str, Any]: "missing_periods": [period.to_dict() for period in self.missing_periods], "warnings": list(self.warnings), "is_clean": self.is_clean, + "closure_discarded_count": self.closure_discarded_count, + "closure_inserted_count": self.closure_inserted_count, + "bundled_demo_data_used": self.bundled_demo_data_used, } @@ -136,9 +164,12 @@ class DataValidator: periods is flagged as an abnormal gap. min_coverage_rows: Minimum rows per symbol before a short-coverage warning is raised. - is_247_market: True for venues that trade around the clock (e.g. - crypto). Sub-daily bars on a market that is *not* 24/7 legitimately - jump overnight and across weekends; gap detection tolerates that + symbol_calendars: Each symbol's own calendar name (``"24/7"`` or any + ``pandas_market_calendars`` name). Required for every symbol this + validator will see — gap detection resolves each symbol's own + calendar rather than assuming one market for the whole dataset. + Sub-daily bars on a market that is *not* 24/7 legitimately jump + overnight and across weekends; gap detection tolerates that explicitly instead of flagging every session boundary. """ @@ -148,7 +179,7 @@ def __init__( *, max_gap_periods: int = 5, min_coverage_rows: int = 30, - is_247_market: bool = False, + symbol_calendars: Mapping[str, str], ) -> None: if ( expected_frequency is not None @@ -164,12 +195,12 @@ def __init__( ): if isinstance(value, bool) or not isinstance(value, int) or value <= 0: raise ValueError(f"{name} must be a positive integer.") - if not isinstance(is_247_market, bool): - raise TypeError("is_247_market must be a boolean.") + if not isinstance(symbol_calendars, Mapping): + raise TypeError("symbol_calendars must be a mapping of symbol -> calendar.") self.expected_frequency = expected_frequency self.max_gap_periods = max_gap_periods self.min_coverage_rows = min_coverage_rows - self.is_247_market = is_247_market + self.symbol_calendars = symbol_calendars @staticmethod def _prepare_input(data: pd.DataFrame) -> pd.DataFrame: @@ -437,6 +468,26 @@ def _check_expected_symbols( if strict: raise DataValidationError(message) + @staticmethod + def _session_break( + calendar: str, ts: pd.Timestamp + ) -> tuple[pd.Timestamp, pd.Timestamp] | None: + """Return the (break_start, break_end) of ``ts``'s own session. + + ``None`` when that session has no official intraday break. Only + meaningful for a calendar :func:`~quantlab.data.calendar. + has_session_break` already confirmed has one. + """ + day = ts.normalize() + schedule = _sessions(calendar, day, day) + if schedule.empty: + return None + row = schedule.iloc[0] + break_start = row.get("break_start") + if break_start is None or pd.isna(break_start): + return None + return pd.Timestamp(break_start), pd.Timestamp(row["break_end"]) + def _check_symbol_coverage( self, symbol: str, @@ -445,6 +496,10 @@ def _check_symbol_coverage( start: date | None = None, end: date | None = None, ) -> None: + calendar = self.symbol_calendars.get(symbol) + if calendar is None: + raise DataValidationError(f"No calendar configured for symbol {symbol!r}.") + is_247_market = _is_247(calendar) ts = pd.to_datetime(group[TIMESTAMP]).sort_values() deltas = ts.diff().dropna() observed_step = deltas.median() if not deltas.empty else pd.Timedelta(0) @@ -456,14 +511,14 @@ def _check_symbol_coverage( step = expected_step or observed_step # Two rows are enough to detect a declared-frequency mismatch. if observed_step > pd.Timedelta(0): - self._check_declared_frequency(symbol, ts, deltas, report) + self._check_declared_frequency(symbol, calendar, ts, deltas, report) # Continuous markets have no legitimate exchange closures. - gap_periods = 1 if self.is_247_market else self.max_gap_periods + gap_periods = 1 if is_247_market else self.max_gap_periods base_tolerance = ( step * gap_periods if step > pd.Timedelta(0) else pd.Timedelta(0) ) - if self.is_247_market: + if is_247_market: # Make an edge lag of exactly one expected period fail. tolerance = max( base_tolerance - pd.Timedelta(microseconds=1), pd.Timedelta(0) @@ -473,15 +528,13 @@ def _check_symbol_coverage( range_start = pd.Timestamp(start) if start is not None else None range_end = pd.Timestamp(end) if end is not None else None - if not self.is_247_market: + if not is_247_market: if range_start is not None: range_start = _first_trading_day_on_or_after( - range_start, is_247_market=False + range_start, calendar=calendar ) if range_end is not None: - range_end = _last_trading_day_on_or_before( - range_end, is_247_market=False - ) + range_end = _last_trading_day_on_or_before(range_end, calendar=calendar) if start is not None and len(ts): assert range_start is not None lag = ts.iloc[0] - range_start @@ -511,32 +564,38 @@ def _check_symbol_coverage( if step <= pd.Timedelta(0): return intraday_threshold = step * gap_periods - if not self.is_247_market and self.expected_frequency in _DAILY_FREQUENCIES: + if not is_247_market and self.expected_frequency in _DAILY_FREQUENCIES: start_days = ( ts.shift(1).loc[deltas.index].to_numpy().astype("datetime64[D]") ) end_days = ts.loc[deltas.index].to_numpy().astype("datetime64[D]") holidays = ( - _xnys_holidays(ts.min(), ts.max()).to_numpy().astype("datetime64[D]") + _holidays_between(calendar, ts.min(), ts.max()) + .to_numpy() + .astype("datetime64[D]") ) session_steps = pd.Series( - np.busday_count(start_days, end_days, holidays=holidays), + np.busday_count( + start_days, + end_days, + weekmask=_session_weekmask(calendar), + holidays=holidays, + ), index=deltas.index, ) gap_candidates = session_steps > gap_periods else: gap_candidates = deltas > intraday_threshold - if ( - not self.is_247_market - and step < pd.Timedelta(days=1) - and gap_candidates.any() - ): - # Evaluate cross-day gaps against XNYS sessions, not wall-clock time. + if not is_247_market and step < pd.Timedelta(days=1) and gap_candidates.any(): + # Evaluate cross-day gaps against this symbol's own calendar + # sessions, not wall-clock time. starts = ts.shift(1).loc[deltas.index] ends = ts.loc[deltas.index] - # Infer typical edge times to detect truncated bordering sessions. - by_day = ts.groupby(ts.dt.normalize()) + # Infer typical edge times to detect truncated bordering + # sessions. Group by each timestamp's real trading session (see + # session_labels), not a naive UTC calendar-day boundary. + by_day = ts.groupby(_session_labels(calendar, ts)) last_by_day = by_day.max().dt.time first_by_day = by_day.min().dt.time # Ties prefer the widest observed session. @@ -549,7 +608,22 @@ def _check_symbol_coverage( start_ts, end_ts = starts.loc[pos], ends.loc[pos] start_date, end_date = start_ts.date(), end_ts.date() if start_date == end_date: - continue # same session: genuinely abnormal, keep flagged + # Same session: genuinely abnormal, UNLESS it's fully + # explained by the calendar's own official intraday + # break (e.g. XHKG's lunch recess) -- a real provider + # legitimately has no bars during it. + if _has_session_break(calendar): + session_break = self._session_break(calendar, start_ts) + if session_break is not None: + break_start, break_end = session_break + residual = (end_ts - start_ts) - (break_end - break_start) + if ( + start_ts <= break_start + and end_ts >= break_end + and residual <= intraday_threshold + ): + gap_candidates.loc[pos] = False + continue if typical_last_time is not None and typical_first_time is not None: expected_tail_end = pd.Timestamp.combine( start_date, typical_last_time @@ -565,7 +639,7 @@ def _check_symbol_coverage( skipped = pd.bdate_range( start=start_date + pd.Timedelta(days=1), end=end_date - pd.Timedelta(days=1), - freq=_XNYS_BUSINESS_DAY, + freq=_business_day_offset(calendar), ) if len(skipped) == 0: gap_candidates.loc[pos] = False @@ -587,28 +661,42 @@ def _check_symbol_coverage( ) def _check_declared_frequency( - self, symbol: str, ts: pd.Series, deltas: pd.Series, report: DataQualityReport + self, + symbol: str, + calendar: str, + ts: pd.Series, + deltas: pd.Series, + report: DataQualityReport, ) -> None: """Compare median, matching fraction and 24/7 mean spacing. - Daily equity deltas are measured in XNYS sessions. Intraday equity - matching excludes cross-session deltas, which are legitimate closures. + Daily equity deltas are measured in the symbol's own calendar + sessions. Intraday equity matching excludes cross-session deltas, + which are legitimate closures. """ if self.expected_frequency is None or deltas.empty: return expected = _FREQUENCY_TIMEDELTA.get(self.expected_frequency) if expected is None or expected <= pd.Timedelta(0): return - daily_equity = not self.is_247_market and expected == pd.Timedelta(days=1) + is_247_market = _is_247(calendar) + daily_equity = not is_247_market and expected == pd.Timedelta(days=1) if daily_equity: - # Count sessions so weekends and XNYS holidays have zero duration. + # Count sessions so weekends and holidays have zero duration. starts = ts.shift(1).loc[deltas.index].to_numpy().astype("datetime64[D]") ends = ts.loc[deltas.index].to_numpy().astype("datetime64[D]") holidays = ( - _xnys_holidays(ts.min(), ts.max()).to_numpy().astype("datetime64[D]") + _holidays_between(calendar, ts.min(), ts.max()) + .to_numpy() + .astype("datetime64[D]") ) ratios = pd.Series( - np.busday_count(starts, ends, holidays=holidays).astype(float), + np.busday_count( + starts, + ends, + weekmask=_session_weekmask(calendar), + holidays=holidays, + ).astype(float), index=deltas.index, ) else: @@ -626,14 +714,42 @@ def _check_declared_frequency( ) return - is_equity_subdaily = not self.is_247_market and expected < pd.Timedelta(days=1) + is_equity_subdaily = not is_247_market and expected < pd.Timedelta(days=1) if is_equity_subdaily: - same_day = (ts.dt.date == ts.shift(1).dt.date).reindex( + # Real trading-session labels, not naive UTC calendar dates (see + # session_labels): otherwise a session that straddles UTC + # midnight in local terms (e.g. Sydney, +10/+11) would have its + # own intraday deltas wrongly excluded as "cross-session". + labels = _session_labels(calendar, ts) + same_day = (labels == labels.shift(1)).reindex( deltas.index, fill_value=False ) intraday_deltas = deltas[same_day] if intraday_deltas.empty: return + if _has_session_break(calendar): + # A delta that fully spans the calendar's own official + # intraday break (e.g. XHKG's lunch recess) is not "missing + # a bar" -- no real provider has one during the break -- so + # it must not count against the declared-frequency matching + # fraction either, the same reasoning already applied to + # abnormal-gap detection above. + schedule = _sessions(calendar, ts.min(), ts.max()) + break_start_map = schedule.get("break_start", pd.Series(dtype=object)) + break_end_map = schedule.get("break_end", pd.Series(dtype=object)) + row_break_start = labels.map(break_start_map) + row_break_end = labels.map(break_end_map) + previous_ts = ts.shift(1) + explained = ( + row_break_start.notna() + & (previous_ts <= row_break_start) + & (ts >= row_break_end) + ) + intraday_deltas = intraday_deltas[ + ~explained.reindex(intraday_deltas.index, fill_value=False) + ] + if intraday_deltas.empty: + return intraday_ratios = ( intraday_deltas.dt.total_seconds() / expected.total_seconds() ) @@ -654,10 +770,10 @@ def _check_declared_frequency( matching_fraction = ((ratios >= 1.0 / tolerance) & (ratios <= tolerance)).mean() minimum_fraction = ( _FREQUENCY_MATCH_MINIMUM_FRACTION_247 - if self.is_247_market + if is_247_market else _FREQUENCY_MATCH_MINIMUM_FRACTION ) - if self.is_247_market: + if is_247_market: # The mean catches sparse large gaps that a fraction floor can miss. mean_step = cast("pd.Timedelta", deltas.mean()) mean_ratio = mean_step / expected diff --git a/src/quantlab/data/yahoo.py b/src/quantlab/data/yahoo.py index b61f9e9..7f799e3 100644 --- a/src/quantlab/data/yahoo.py +++ b/src/quantlab/data/yahoo.py @@ -30,11 +30,6 @@ SymbolSuggestion, ensure_canonical_schema, ) -from quantlab.data.calendar import ( - daily_equity_bucket_settlement, - monthly_bucket_settlement, - weekly_bucket_settlement, -) from quantlab.exceptions import DataDownloadError from quantlab.logging_config import get_logger @@ -43,13 +38,6 @@ #: Map QuantLab frequency strings to yfinance ``interval`` values. _INTERVAL = {"1d": "1d", "1h": "1h", "1w": "1wk", "1mo": "1mo"} -#: Fixed bucket lengths; monthly settlement uses calendar arithmetic. -_INTERVAL_TIMEDELTA: dict[str, pd.Timedelta] = { - "1d": pd.Timedelta(days=1), - "1h": pd.Timedelta(hours=1), - "1wk": pd.Timedelta(weeks=1), -} - #: Yahoo's unofficial, public, unauthenticated symbol-search endpoint. Used #: only for dashboard autocomplete, not for downloading price data. _SEARCH_URL = "https://query1.finance.yahoo.com/v1/finance/search" @@ -160,7 +148,7 @@ def download( end: date, frequency: str = "1d", *, - is_247_market: bool = False, + calendar: str = "XNYS", ) -> pd.DataFrame: """Download and normalise data for ``symbols``. @@ -169,7 +157,19 @@ def download( start: Inclusive start date. end: Inclusive end date. frequency: One of ``1d``, ``1h``, ``1w``, ``1mo``. - is_247_market: Use continuous UTC settlement instead of XNYS. + calendar: Accepted for interface parity with other sources but + unused: the returned frame is never filtered by settlement + here. Two experiments can request the same Yahoo symbol under + different calendars, and the download cache (keyed only by + source/symbol/frequency, with no calendar component) must + stay identical either way — settlement-dependent filtering + (which bars are still forming, and which fall within the + requested end date) is applied only after any cache read/ + write, by :class:`~quantlab.data.loader.DataLoader` (see + :meth:`~quantlab.data.storage.ParquetStorage.write_symbol`'s + own docstring). Compare + :class:`~quantlab.data.binance.BinanceDataSource`, which + likewise accepts but ignores ``calendar``. Returns: Canonical long OHLCV frame for all successfully downloaded symbols. @@ -190,8 +190,8 @@ def download( raise DataDownloadError("Yahoo start and end must be date values.") if start > end: raise DataDownloadError("Yahoo start must be on or before end.") - if not isinstance(is_247_market, bool): - raise DataDownloadError("is_247_market must be a boolean.") + if not isinstance(calendar, str) or not calendar.strip(): + raise DataDownloadError("calendar must be a non-empty string.") if not isinstance(frequency, str): raise DataDownloadError("Yahoo frequency must be a string.") @@ -202,15 +202,11 @@ def download( f"Supported: {sorted(_INTERVAL)}." ) - # Use one cutoff instant for every symbol in this request. - now = pd.Timestamp.now(tz="UTC").tz_localize(None) frames: list[pd.DataFrame] = [] failures: dict[str, str] = {} for symbol in normalised_symbols: try: - frames.append( - self._download_one(symbol, start, end, interval, now, is_247_market) - ) + frames.append(self._download_one(symbol, start, end, interval)) except DataDownloadError as exc: logger.error("Giving up on %s: %s", symbol, exc) failures[symbol] = str(exc) @@ -233,8 +229,6 @@ def _download_one( start: date, end: date, interval: str, - now: pd.Timestamp, - is_247_market: bool = False, ) -> pd.DataFrame: """Download a single symbol with retries and normalise it.""" try: @@ -272,19 +266,11 @@ def _download_one( last_error = DataDownloadError(f"Empty response for {symbol}.") else: try: - normalised = self._normalise( - raw, symbol, interval, now, end, is_247_market - ) + return self._normalise(raw, symbol, interval) except Exception as exc: raise DataDownloadError( f"Yahoo returned an invalid schema for {symbol}: {exc}" ) from exc - if normalised.empty: - raise DataDownloadError( - f"Yahoo returned data for {symbol}, but every bar was " - "still forming or settled after the requested end." - ) - return normalised if attempt < self.max_retries: time.sleep(self.retry_backoff_seconds * attempt) raise DataDownloadError( @@ -297,14 +283,20 @@ def _normalise( raw: pd.DataFrame, symbol: str, interval: str, - now: pd.Timestamp, - end: date, - is_247_market: bool = False, ) -> pd.DataFrame: """Convert one Yahoo frame to canonical OHLCV. - Bars are retained only after their XNYS or 24/7 settlement boundary - and only when that boundary is inside the requested inclusive range. + Returns every row Yahoo provided, including a bar for a still-forming + session -- settlement-dependent filtering (which bars are still + forming, and which fall within the requested end date) is applied + only after any cache read/write, by + :class:`~quantlab.data.loader.DataLoader`. Baking a settlement + opinion in here, before the frame is ever cached, would make the + cache's on-disk content depend on which calendar the first caller to + fill it happened to request, even though the cache key (source/ + symbol/frequency) carries no calendar component -- see + :meth:`~quantlab.data.storage.ParquetStorage.write_symbol`'s own + docstring for the invariant this preserves. """ df = raw.copy() # Flatten a possible MultiIndex column (field, ticker) → field. @@ -325,10 +317,26 @@ def _normalise( "Returns may omit distributions or split adjustments.", symbol, ) + if interval in {"1d", "1wk", "1mo"}: + # A calendar-date granularity (daily/weekly/monthly) has no + # meaningful time-of-day -- the timestamp represents a *local* + # trading date, not a specific UTC instant. Converting through + # UTC first (as the intraday branch below correctly does) would + # shift that date for any exchange ahead of UTC (e.g. XASX + # +10/+11, XHKG +8): a tz-aware Yahoo response of, say, Monday + # 00:00 AEDT becomes Sunday 13:00 UTC, silently turning a + # Monday session into "Sunday". Stripping the timezone directly + # keeps the local wall-clock date unchanged; a no-op when Yahoo + # already returns naive daily timestamps. + bar_timestamps = pd.to_datetime(df[ts_col]).dt.tz_localize(None) + else: + # Intraday: the timestamp is a genuine instant, so the UTC + # conversion below is correct and required (see + # test_yahoo_intraday_timezone_converted_to_utc_not_stripped_naively). + bar_timestamps = pd.to_datetime(df[ts_col], utc=True).dt.tz_localize(None) out = pd.DataFrame( { - # Convert aware timestamps to UTC before removing the timezone. - TIMESTAMP: pd.to_datetime(df[ts_col], utc=True).dt.tz_localize(None), + TIMESTAMP: bar_timestamps, SYMBOL: symbol.upper(), OPEN: pd.to_numeric(df["Open"], errors="coerce"), HIGH: pd.to_numeric(df["High"], errors="coerce"), @@ -343,35 +351,4 @@ def _normalise( timestamps = pd.DatetimeIndex(out[TIMESTAMP]) if timestamps.hasnans: raise ValueError("Yahoo returned a missing or invalid timestamp.") - if interval == "1mo": - bar_end = pd.DatetimeIndex( - [ - monthly_bucket_settlement( - timestamp, is_247_market=is_247_market - ) - for timestamp in timestamps - ] - ) - elif interval == "1wk": - bar_end = pd.DatetimeIndex( - [ - weekly_bucket_settlement(timestamp, is_247_market=is_247_market) - for timestamp in timestamps - ] - ) - elif interval == "1d" and not is_247_market: - bar_end = pd.DatetimeIndex( - [ - daily_equity_bucket_settlement(timestamp) - for timestamp in timestamps - ] - ) - else: - bar_end = timestamps + _INTERVAL_TIMEDELTA.get( - interval, pd.Timedelta(0) - ) - end_boundary = pd.Timestamp(end) + pd.Timedelta(days=1) - out = out[(bar_end <= now) & (bar_end <= end_boundary)].reset_index( - drop=True - ) return out diff --git a/src/quantlab/execution/orders.py b/src/quantlab/execution/orders.py index d553d1b..e5e8995 100644 --- a/src/quantlab/execution/orders.py +++ b/src/quantlab/execution/orders.py @@ -2,8 +2,11 @@ from __future__ import annotations +from numbers import Integral + import numpy as np import pandas as pd +from pandas.api.types import is_bool_dtype from quantlab.exceptions import BacktestError @@ -63,10 +66,91 @@ def equity_before_period( return previous -def executed_weights(held_weights: pd.DataFrame) -> pd.DataFrame: - """Shift decisions by one period so period-t returns use t-1 weights.""" +def shift_respecting_tradability( + frame: pd.DataFrame, periods: int, tradable: pd.DataFrame +) -> pd.DataFrame: + """Shift each column by ``periods`` steps among its own tradable rows. + + A raw ``frame.shift(periods)`` treats every row as a valid execution + opportunity for every symbol -- wrong whenever a symbol is untradable on + some rows (a closed market on a mixed-calendar timeline): a decision + made on the last date a symbol was tradable must "execute" on that + symbol's *next real tradable opportunity*, not on the next raw row, + which may be a date the symbol can't actually trade on at all (e.g. a + weekend row that only exists because another, always-open instrument + shares the same combined index). For each column, a closed row repeats + the last value already produced for a tradable row (frozen, no + reallocation happens while closed); a tradable row takes the value from + ``periods`` tradable rows back for that column, never a raw row-count + lookback. + """ + if isinstance(periods, (bool, np.bool_)) or not isinstance(periods, Integral): + raise BacktestError("periods must be a non-negative integer.") + if int(periods) < 0: + raise BacktestError("periods must be a non-negative integer.") + if not isinstance(tradable, pd.DataFrame): + raise BacktestError("tradable must be a pandas DataFrame.") + if not frame.index.equals(tradable.index) or not frame.columns.equals( + tradable.columns + ): + raise BacktestError( + "tradable must have exactly the same index and columns as frame, " + "in the same order." + ) + non_bool_columns = [ + column for column, dtype in tradable.dtypes.items() if not is_bool_dtype(dtype) + ] + if non_bool_columns: + raise BacktestError( + f"tradable must contain only boolean values; column(s) " + f"{non_bool_columns} are not boolean dtype (e.g. a string " + "'False' would otherwise silently coerce to True)." + ) + result = pd.DataFrame(index=frame.index, columns=frame.columns, dtype=float) + for column in frame.columns: + values = frame[column].to_numpy(dtype=float) + mask = tradable[column].to_numpy(dtype=bool) + tradable_positions = np.flatnonzero(mask) + # A column's first `periods` tradable positions have no tradable + # row "behind" them to reference -- there is no prior decision, + # so (matching the same "start flat" convention as + # executed_weights' own row-0 override) this is 0.0, not NaN. Left + # as NaN, the ffill below would propagate NaN through every row + # before the column's first real shifted value -- e.g. a symbol + # closed on the very first rows of a mixed-calendar history that + # opens on, say, a Friday -- and executed_weights' row-0-only + # override can't reach those later rows to fix them. + shifted_at_tradable = np.zeros(len(tradable_positions)) + if len(tradable_positions) > periods: + source = tradable_positions[: len(tradable_positions) - periods] + shifted_at_tradable[periods:] = values[source] + full = np.full(len(frame.index), np.nan) + full[tradable_positions] = shifted_at_tradable + column_result = pd.Series(full, index=frame.index) + # Same "no prior decision -> flat" convention for any row before a + # column's first tradable one (a symbol closed on the very first + # row(s) of the whole history): ffill alone cannot reach *leading* + # NaN, since there is nothing earlier to carry forward. + result[column] = column_result.ffill().fillna(0.0) + return result + + +def executed_weights( + held_weights: pd.DataFrame, *, tradable: pd.DataFrame | None = None +) -> pd.DataFrame: + """Shift decisions by one period so period-t returns use t-1 weights. + + When ``tradable`` is given, the shift is per-symbol tradability-aware + (see :func:`shift_respecting_tradability`): a symbol's decision only + appears in the returned frame on its own next tradable row, not the raw + next row -- a decision made right before a closure (e.g. Friday, before + a weekend) is never misattributed as trading during the closure itself. + """ held = validate_execution_frame(held_weights, name="held_weights") - executed = held.shift(1) + if tradable is not None: + executed = shift_respecting_tradability(held, 1, tradable) + else: + executed = held.shift(1) if len(executed): executed.iloc[0, :] = 0.0 return executed diff --git a/src/quantlab/logging_config.py b/src/quantlab/logging_config.py index 8293423..6474469 100644 --- a/src/quantlab/logging_config.py +++ b/src/quantlab/logging_config.py @@ -12,6 +12,7 @@ from __future__ import annotations import logging +import sys import warnings from logging.handlers import RotatingFileHandler from pathlib import Path @@ -25,6 +26,34 @@ _CONFIGURED = False +class _CurrentStderrHandler(logging.StreamHandler): + """A console handler that always writes to the *current* ``sys.stderr``. + + A plain ``StreamHandler()`` snapshots ``sys.stderr`` once at + construction time. ``configure_logging`` only ever builds this handler + once per process (see ``_CONFIGURED``), so anything that later replaces + ``sys.stderr`` and closes the old one -- pytest captures a fresh proxy + per test and tears down the previous one -- would leave this + long-lived handler holding a dead reference, raising "I/O operation on + closed file" the next time anything logs. Resolving the stream fresh on + every emit avoids that regardless of how many times the process's + ``sys.stderr`` gets swapped out underneath it. + """ + + def __init__(self) -> None: + super().__init__() + + @property + def stream(self) -> object: + return sys.stderr + + @stream.setter + def stream(self, value: object) -> None: + # logging.Handler.__init__ assigns self.stream = stream once; + # silently ignored so the getter above always wins. + pass + + def configure_logging( level: int | str = logging.INFO, *, @@ -33,10 +62,20 @@ def configure_logging( ) -> logging.Logger: """Configure and return the package-level ``quantlab`` logger. + Only the *first* call in a process actually builds handlers -- every + later call is a no-op except for adjusting ``level``, which always takes + effect. A ``log_file``/``console`` value passed to a second or later call + is silently ignored; whichever values the first call in the process used + remain in effect for its whole lifetime. Call this once, as early as + possible, with the settings you actually want. + Args: level: Logging level for the package logger (name or numeric value). - log_file: Preferred log file. Defaults to ``logs/quantlab.log``. - console: Whether to also emit records to stderr. + Applied on every call, even after the first. + log_file: Preferred log file. Defaults to ``logs/quantlab.log``. Only + honoured on the first call in the process. + console: Whether to also emit records to stderr. Only honoured on + the first call in the process. Returns: The configured package logger. Child loggers are obtained with @@ -54,7 +93,7 @@ def configure_logging( formatter = logging.Formatter(_DEFAULT_FORMAT, datefmt=_DATE_FORMAT) if console: - console_handler = logging.StreamHandler() + console_handler = _CurrentStderrHandler() console_handler.setFormatter(formatter) logger.addHandler(console_handler) diff --git a/src/quantlab/portfolio/rebalancing.py b/src/quantlab/portfolio/rebalancing.py index 7f44c94..b12e0fb 100644 --- a/src/quantlab/portfolio/rebalancing.py +++ b/src/quantlab/portfolio/rebalancing.py @@ -3,16 +3,31 @@ Targets are sampled on rebalance dates and represented as constant portfolio weights between them. This vectorised approximation does not model weight drift caused by relative asset-price moves between rebalances. + +Timing convention: every function in this module produces *decided* weights, +not executed ones -- including a row where a closed symbol's pending target +first resolves after reopening (see :func:`rebalance_and_cap_turnover`'s +``tradable`` parameter). ``held_weights[t]`` is "what the strategy decided +using information available through t," never "what the portfolio actually +holds at t." :mod:`quantlab.backtesting.accounting` always applies one further +(tradability-respecting) shift before any weight can affect returns, turnover +or costs -- uniformly, with no special case for a reopening row. A target +that first appears in ``held_weights`` on a symbol's reopening day therefore +does not affect the portfolio until that symbol's *next* tradable session, +exactly as an ordinary scheduled rebalance decided on day T only takes effect +on day T+1 -- never on day T itself. """ from __future__ import annotations import numpy as np import pandas as pd +from pandas.api.types import is_bool_dtype from quantlab.config import PortfolioConfig, RebalanceFrequency from quantlab.constants import EPSILON -from quantlab.exceptions import InvalidConfigurationError +from quantlab.data.calendar import is_247, session_labels, weekly_bucket_start +from quantlab.exceptions import BacktestError, InvalidConfigurationError from quantlab.portfolio._validation import ( boolean, finite_real, @@ -28,9 +43,23 @@ def rebalance_dates( - index: pd.DatetimeIndex, frequency: RebalanceFrequency | str + index: pd.DatetimeIndex, + frequency: RebalanceFrequency | str, + *, + calendar: str | None = None, ) -> pd.DatetimeIndex: - """Return the first available observation in each rebalance period.""" + """Return the first available observation in each rebalance period. + + ``calendar``, when given (and not ``"24/7"``), groups by each + timestamp's real trading-session date instead of its raw UTC value -- + otherwise a calendar whose local session crosses UTC midnight (e.g. + XASX, UTC+10/+11) could have one session's own bars split across two + different weekly/monthly periods right at a period boundary, and + every bar frequency shares the same calendar-aware grouping. Omit it + (the default) for a portfolio with no single shared calendar -- a raw + UTC boundary is the same documented approximation already used + elsewhere for a mixed-calendar universe. + """ validated_index = validate_datetime_index(index, name="index") rebalance_frequency = _parse_frequency(frequency) if len(validated_index) == 0 or rebalance_frequency is RebalanceFrequency.DAILY: @@ -46,20 +75,48 @@ def rebalance_dates( if validated_index.tz is not None else validated_index ) - periods = grouping_index.to_period(_PERIOD_ALIAS[rebalance_frequency]) - is_first = ~pd.Series(periods, index=validated_index).duplicated().to_numpy() + session_calendar = ( + calendar if calendar is not None and not is_247(calendar) else None + ) + if session_calendar is not None: + grouping_index = pd.DatetimeIndex( + session_labels(session_calendar, pd.Series(grouping_index)).to_numpy() + ) + is_weekly = rebalance_frequency is RebalanceFrequency.WEEKLY + if session_calendar is not None and is_weekly: + # A calendar's trading week isn't always Monday-Sunday (e.g. XSAU + # trades Sunday-Thursday) -- `.to_period("W")` always bins by the + # fixed ISO week, which would split such a week's own sessions + # across two different periods right at its own boundary (its + # Sunday session falls in the *previous* ISO week from its + # Monday-Thursday sessions). `weekly_bucket_start` groups by the + # calendar's own trading week instead, mirroring the resampler's + # identical fix (see quantlab.data.resampler._resample_by_session). + group_keys: pd.Index = pd.DatetimeIndex( + [ + weekly_bucket_start(timestamp, calendar=session_calendar) + for timestamp in grouping_index + ] + ) + else: + group_keys = grouping_index.to_period(_PERIOD_ALIAS[rebalance_frequency]) + is_first = ~pd.Series(group_keys, index=validated_index).duplicated().to_numpy() return pd.DatetimeIndex(validated_index[is_first]) def apply_rebalancing( target_weights: pd.DataFrame, frequency: RebalanceFrequency | str, + *, + calendar: str | None = None, ) -> pd.DataFrame: """Sample finite targets on rebalance dates and hold them between dates.""" validated = validate_frame( target_weights, name="target_weights", require_datetime_index=True ) - dates = rebalance_dates(pd.DatetimeIndex(validated.index), frequency) + dates = rebalance_dates( + pd.DatetimeIndex(validated.index), frequency, calendar=calendar + ) on_dates = validated.loc[validated.index.isin(dates)] return on_dates.reindex(validated.index).ffill().astype(float) @@ -72,15 +129,47 @@ def compute_turnover(held_weights: pd.DataFrame) -> pd.Series: def rebalance_and_cap_turnover( - target_weights: pd.DataFrame, portfolio_config: PortfolioConfig + target_weights: pd.DataFrame, + portfolio_config: PortfolioConfig, + *, + tradable: pd.DataFrame | None = None, + calendar: str | None = None, ) -> pd.DataFrame: """Apply the stateful schedule and turnover cap over one continuous index. Minimum-weight and position-count constraints apply to targets upstream. A turnover-limited interpolation may temporarily cross those non-convex target-only boundaries while remaining within all exposure constraints. + + Args: + target_weights: Raw target weights, one row per date. + portfolio_config: Rebalance frequency, turnover cap and exposure caps. + tradable: Optional ``dates x symbols`` bool frame (True = that symbol + is tradable that date). When given, a closed symbol never trades + that date — its rebalance is deferred as a pending target and + caught up (even off-schedule, possibly over several sessions if + ``maximum_turnover`` limits the rate) as soon as it reopens. Note + that a pending target resolving in the returned frame on a + symbol's reopening day is still only a *decision* dated that + day — see the module docstring's timing convention — it does not + reach the accounting layer's executed weights, turnover or costs + until that symbol's next tradable session. When ``None`` (the + default), behaviour is exactly the pre-existing schedule/ + turnover-cap path below, unchanged. + calendar: Optional shared calendar name, forwarded to + :func:`rebalance_dates` so a weekly/monthly schedule groups by + real trading sessions instead of raw UTC dates. Only meaningful + when every instrument shares one calendar; omit for a mixed + universe (see :func:`rebalance_dates`). """ - held = apply_rebalancing(target_weights, portfolio_config.rebalance_frequency) + if tradable is not None: + return _rebalance_tradability_aware( + target_weights, portfolio_config, tradable, calendar=calendar + ) + + held = apply_rebalancing( + target_weights, portfolio_config.rebalance_frequency, calendar=calendar + ) if portfolio_config.maximum_turnover is None: return held @@ -89,7 +178,9 @@ def rebalance_and_cap_turnover( gross_caps.append(portfolio_config.maximum_gross_exposure) effective_gross_cap = min(gross_caps) dates = rebalance_dates( - pd.DatetimeIndex(held.index), portfolio_config.rebalance_frequency + pd.DatetimeIndex(held.index), + portfolio_config.rebalance_frequency, + calendar=calendar, ) return cap_turnover( held, @@ -157,27 +248,48 @@ def cap_turnover( return pd.DataFrame(output, index=validated.index, columns=validated.columns) -def _validate_target_row_compliant( - target: np.ndarray, +def _compliance_violations( + weights: np.ndarray, *, maximum_weight: float | None, maximum_gross_exposure: float | None, maximum_net_exposure: float | None, long_only: bool, - row_label: object, -) -> None: - """Require each target endpoint to satisfy the convex constraints.""" +) -> list[str]: + """Return the names of every convex constraint ``weights`` violates.""" violations: list[str] = [] - if long_only and np.any(target < -EPSILON): + if long_only and np.any(weights < -EPSILON): violations.append("long_only") - if maximum_weight is not None and np.any(np.abs(target) > maximum_weight + EPSILON): + if maximum_weight is not None and np.any( + np.abs(weights) > maximum_weight + EPSILON + ): violations.append("maximum_weight") - gross = float(np.abs(target).sum()) + gross = float(np.abs(weights).sum()) if maximum_gross_exposure is not None and gross > maximum_gross_exposure + EPSILON: violations.append("maximum_gross_exposure") - net = float(abs(target.sum())) + net = float(abs(weights.sum())) if maximum_net_exposure is not None and net > maximum_net_exposure + EPSILON: violations.append("maximum_net_exposure") + return violations + + +def _validate_target_row_compliant( + target: np.ndarray, + *, + maximum_weight: float | None, + maximum_gross_exposure: float | None, + maximum_net_exposure: float | None, + long_only: bool, + row_label: object, +) -> None: + """Require each target endpoint to satisfy the convex constraints.""" + violations = _compliance_violations( + target, + maximum_weight=maximum_weight, + maximum_gross_exposure=maximum_gross_exposure, + maximum_net_exposure=maximum_net_exposure, + long_only=long_only, + ) if violations: raise InvalidConfigurationError( f"Target row at {row_label!r} violates constraints enforced " @@ -185,6 +297,224 @@ def _validate_target_row_compliant( ) +def _max_feasible_fraction( + previous: np.ndarray, + change: np.ndarray, + *, + maximum_weight: float | None, + maximum_gross_exposure: float | None, + maximum_net_exposure: float | None, + long_only: bool, + upper_bound: float, +) -> float: + """Return the largest feasible fraction of ``change`` to apply. + + Finds ``f`` in ``[0, upper_bound]`` keeping ``previous + f * change`` + compliant. ``f=0`` (no movement) is always feasible because ``previous`` is itself + compliant by construction (every row this module produces is). Each + constraint is convex and affine in ``f`` along this segment, so its + feasible set is a prefix ``[0, f_max]`` — bisection is well-founded and + converges to the exact boundary. + + This is needed because freezing some columns (a closed symbol) while + others move toward their own target changes the direction of travel from + the straight ``previous -> target`` line that :func:`cap_turnover` relies + on for its convexity argument — the new endpoint is not guaranteed + feasible even though both ``previous`` and the full ``target`` are. + """ + + def compliant(fraction: float) -> bool: + candidate = previous + fraction * change + return not _compliance_violations( + candidate, + maximum_weight=maximum_weight, + maximum_gross_exposure=maximum_gross_exposure, + maximum_net_exposure=maximum_net_exposure, + long_only=long_only, + ) + + if compliant(upper_bound): + return upper_bound + lo, hi = 0.0, upper_bound + for _ in range(60): # ~1e-18 relative precision, far below EPSILON + mid = (lo + hi) / 2 + if compliant(mid): + lo = mid + else: + hi = mid + return lo + + +def _assert_holdings_compliant( + current: np.ndarray, + *, + maximum_weight: float | None, + maximum_gross_exposure: float | None, + maximum_net_exposure: float | None, + long_only: bool, + row_label: object, +) -> None: + """Defensive check: every row this module actually outputs must comply. + + :func:`_max_feasible_fraction` already guarantees this by construction — + a violation here would mean a bug in that search, not a bad input — but + a silent violation would be an expensive, hard-to-diagnose out-of-mandate + position, so this fails loudly rather than trusting the invariant blindly. + """ + violations = _compliance_violations( + current, + maximum_weight=maximum_weight, + maximum_gross_exposure=maximum_gross_exposure, + maximum_net_exposure=maximum_net_exposure, + long_only=long_only, + ) + if violations: + raise BacktestError( + f"Tradability-aware rebalancing produced holdings at {row_label!r} " + f"that violate: {', '.join(violations)}. This indicates a bug in " + "the rebalancing algorithm, not a configuration problem." + ) + + +def _rebalance_tradability_aware( + target_weights: pd.DataFrame, + portfolio_config: PortfolioConfig, + tradable: pd.DataFrame, + *, + calendar: str | None = None, +) -> pd.DataFrame: + """Rebalance while respecting per-symbol tradability. + + A symbol that is closed on a rebalance date never trades that date; its + new target becomes a pending debt that is retried on every subsequent + date it is tradable (not just the next scheduled rebalance) until fully + executed — even if that takes several sessions under a turnover cap. A + symbol that is always tradable is completely unaffected: its cadence + (rebalance-date-only catch-up) is byte-identical to :func:`cap_turnover`. + """ + validated = validate_frame( + target_weights, name="target_weights", require_datetime_index=True + ) + dates = rebalance_dates( + pd.DatetimeIndex(validated.index), + portfolio_config.rebalance_frequency, + calendar=calendar, + ) + is_rebalance_date = np.asarray(validated.index.isin(dates), dtype=bool) + turnover_cap = ( + finite_real( + portfolio_config.maximum_turnover, name="maximum_turnover", minimum=0.0 + ) + if portfolio_config.maximum_turnover is not None + else float("inf") + ) + gross_caps = [portfolio_config.maximum_leverage] + if portfolio_config.maximum_gross_exposure is not None: + gross_caps.append(portfolio_config.maximum_gross_exposure) + gross_cap = min(gross_caps) + weight_cap = _optional_non_negative( + portfolio_config.maximum_weight, name="maximum_weight" + ) + net_cap = _optional_non_negative( + portfolio_config.maximum_net_exposure, name="maximum_net_exposure" + ) + long_only = boolean(portfolio_config.long_only, name="long_only") + + # Exact same *set* of dates and symbols, no missing values -- a mismatched + # set always means an upstream wiring bug (`tradable` is only ever built + # internally from the same data as `target_weights`, never user input), + # so it must raise loudly rather than silently default an unrecognized + # cell to "tradable" and risk trading a symbol that should have stayed + # closed. Column *order* alone is not a mismatch, though: a caller may + # build `tradable` from a declared symbol list while `target_weights` + # comes from an alphabetically-pivoted price matrix -- reindexing onto + # `validated`'s order is always safe once the sets are confirmed equal. + if set(tradable.index) != set(validated.index) or set(tradable.columns) != set( + validated.columns + ): + raise InvalidConfigurationError( + "tradable must have the same dates and symbols as target_weights." + ) + tradable = tradable.reindex(index=validated.index, columns=validated.columns) + if tradable.isna().to_numpy().any(): + raise InvalidConfigurationError("tradable must not contain missing values.") + non_bool_columns = [ + column for column, dtype in tradable.dtypes.items() if not is_bool_dtype(dtype) + ] + if non_bool_columns: + raise InvalidConfigurationError( + f"tradable must contain only boolean values; column(s) " + f"{non_bool_columns} are not boolean dtype (e.g. a string " + "'False' would otherwise silently coerce to True)." + ) + tradable_np = tradable.to_numpy(dtype=bool) + targets = validated.to_numpy(dtype=float) + row_count, column_count = targets.shape + output = np.zeros((row_count, column_count), dtype=float) + previous = np.zeros(column_count, dtype=float) + pending_target = np.zeros(column_count, dtype=float) + pending_due_to_closure = np.zeros(column_count, dtype=bool) + + for row_number in range(row_count): + row_tradable = tradable_np[row_number] + if is_rebalance_date[row_number]: + target_row = targets[row_number] + _validate_target_row_compliant( + target_row, + maximum_weight=weight_cap, + maximum_gross_exposure=gross_cap, + maximum_net_exposure=net_cap, + long_only=long_only, + row_label=validated.index[row_number], + ) + newly_blocked = (~row_tradable) & (np.abs(target_row - previous) > EPSILON) + pending_target = target_row + pending_due_to_closure = pending_due_to_closure | newly_blocked + + eligible = row_tradable & ( + is_rebalance_date[row_number] | pending_due_to_closure + ) + change = np.where(eligible, pending_target - previous, 0.0) + requested_turnover = float(np.abs(change).sum()) + fraction_from_turnover = ( + 1.0 + if requested_turnover <= turnover_cap + EPSILON + else turnover_cap / requested_turnover + ) + fraction = _max_feasible_fraction( + previous, + change, + maximum_weight=weight_cap, + maximum_gross_exposure=gross_cap, + maximum_net_exposure=net_cap, + long_only=long_only, + upper_bound=fraction_from_turnover, + ) + current = previous + fraction * change + _assert_holdings_compliant( + current, + maximum_weight=weight_cap, + maximum_gross_exposure=gross_cap, + maximum_net_exposure=net_cap, + long_only=long_only, + row_label=validated.index[row_number], + ) + + unresolved = np.abs(current - pending_target) > EPSILON + # Only possible when some column is currently untradable (see + # _max_feasible_fraction docstring): with every symbol tradable, this + # row's change/target endpoints are both convex-compliant, so the + # bisection above never binds below the turnover-derived fraction. + compliance_limited = fraction < fraction_from_turnover - EPSILON + pending_due_to_closure = ( + pending_due_to_closure | (eligible & unresolved & compliance_limited) + ) & unresolved + + output[row_number] = current + previous = current + return pd.DataFrame(output, index=validated.index, columns=validated.columns) + + def _rebalance_mask( index: pd.Index, rebalance_index: pd.DatetimeIndex | None ) -> np.ndarray: diff --git a/src/quantlab/progress.py b/src/quantlab/progress.py new file mode 100644 index 0000000..7cb2511 --- /dev/null +++ b/src/quantlab/progress.py @@ -0,0 +1,109 @@ +"""Live-progress pacing shared by the CLI and the dashboard.""" + +from __future__ import annotations + +import time +from dataclasses import dataclass, field + + +@dataclass +class ProgressPacer: + """Tracks a seconds-per-unit pace across progress ticks, asymmetrically. + + An exponential moving average (nudged, not replaced, by each + observation — the approach `tqdm` uses), smoothed asymmetrically: + ``rising_smoothing`` (0.4) partially adopts a tick implying a slower + pace than currently tracked, ``falling_smoothing`` (0.2) partially + adopts one implying a faster pace. Weighting a slowdown more than a + speedup catches up to a genuine sustained slowdown (e.g. an expanding + walk-forward's later, bigger-training-window folds) faster than a + symmetric average would; keeping both partial rather than full (no + single tick fully overrides the tracked rate) avoids one noisy tick + (parameter-grid candidates genuinely cost different amounts) swinging + the estimate on its own. + """ + + rising_smoothing: float = 0.4 + falling_smoothing: float = 0.2 + _rate_seconds_per_unit: float | None = field(default=None, init=False) + _last_done: int = field(default=0, init=False) + _last_elapsed: float = field(default=0.0, init=False) + + def update(self, done: int, elapsed: float) -> None: + """Record a new ``(done, elapsed)`` observation.""" + delta_done = done - self._last_done + delta_elapsed = elapsed - self._last_elapsed + if delta_done > 0 and delta_elapsed > 0: + instantaneous = delta_elapsed / delta_done + if self._rate_seconds_per_unit is None: + self._rate_seconds_per_unit = instantaneous + else: + smoothing = ( + self.rising_smoothing + if instantaneous >= self._rate_seconds_per_unit + else self.falling_smoothing + ) + self._rate_seconds_per_unit = ( + smoothing * instantaneous + + (1 - smoothing) * self._rate_seconds_per_unit + ) + self._last_done = done + self._last_elapsed = elapsed + + def remaining(self, done: int, total: int) -> float | None: + """Return estimated seconds left, or ``None`` before any pace is known.""" + if self._rate_seconds_per_unit is None: + return None + return self._rate_seconds_per_unit * max(0, total - done) + + +class ProgressReporter: + """Turns ``on_progress(done, total)`` ticks into a status line. + + Shared by the dashboard's Streamlit progress bar and the CLI's terminal + progress line — same :class:`ProgressPacer`-based ETA either way, so a + user gets the same, already-tuned estimate whichever interface they run + a walk-forward/stress-test/sensitivity from. Each caller renders + :meth:`text` (and, where relevant, :meth:`fraction`) through its own + mechanism; this class only turns ticks into words. + """ + + def __init__(self, title: str) -> None: + self.title = title + self._started = time.monotonic() + self._pacer = ProgressPacer() + self._first_call = True + + def fraction(self, done: int, total: int) -> float: + """Return the completed fraction, in ``[0, 1]``.""" + return min(1.0, done / total) if total > 0 else 0.0 + + def text(self, done: int, total: int) -> str: + """Return the status text for one ``on_progress(done, total)`` tick. + + A first tick with ``done > 0`` can only mean a checkpoint was + resumed (a fresh run always starts its first tick at 0) — flagged + in the text that once, since nothing else surfaces a resume to the + user otherwise. + """ + now = time.monotonic() - self._started + if self._first_call and done > 0 and total > 0: + text = ( + f"{self.title}: resumed from a previous checkpoint at {done}/{total}…" + ) + elif total > 0 and done >= total: + text = f"{self.title}: finishing…" + else: + self._pacer.update(done, now) + remaining = self._pacer.remaining(done, total) if total > 0 else None + if remaining is not None and remaining >= 1.0: + text = f"{self.title}: {done}/{total} — ~{remaining:.0f}s remaining" + elif total > 0: + # No pace yet, or the estimate ran out while work remains — + # "~0s remaining" would misleadingly read as "any moment + # now" instead of "still going, longer than expected". + text = f"{self.title}: {done}/{total}" + else: + text = f"{self.title}: running…" + self._first_call = False + return text diff --git a/src/quantlab/reporting/charts.py b/src/quantlab/reporting/charts.py index 3d2469b..e0f928e 100644 --- a/src/quantlab/reporting/charts.py +++ b/src/quantlab/reporting/charts.py @@ -174,6 +174,80 @@ def monthly_returns_heatmap(result: BacktestResult) -> Figure: return fig +def sensitivity_heatmap_chart( + sensitivity: pd.DataFrame, metric: str = "sharpe" +) -> Figure: + """Plot a 2-parameter sensitivity sweep as a metric heatmap. + + Infers which two columns are the swept parameters directly from + `sensitivity` itself (see `infer_sensitivity_parameter_columns`), + mirroring the dashboard's interactive Plotly heatmap + (`components.render_sensitivity_heatmap`) in a static form for the HTML + report. + """ + from quantlab.validation.parameter_sensitivity import ( + infer_sensitivity_parameter_columns, + sensitivity_heatmap_data, + ) + + parameter_x, parameter_y = infer_sensitivity_parameter_columns(sensitivity) + pivot = sensitivity_heatmap_data(sensitivity, parameter_x, parameter_y, metric) + + fig, ax = _new_figure((7, max(2.5, 0.5 * len(pivot.index) + 1))) + values = pivot.to_numpy(dtype=float) + finite = values[np.isfinite(values)] + title = f"Sensitivity: {metric} by {parameter_x} / {parameter_y}" + if finite.size == 0: + ax.text( + 0.5, + 0.5, + "No successful combinations to plot.", + ha="center", + va="center", + transform=ax.transAxes, + color=BENCHMARK, + ) + ax.set_title(title, fontsize=11, fontweight="bold") + return fig + + vmin, vmax = float(finite.min()), float(finite.max()) + span = vmax - vmin if vmax > vmin else 1.0 + cmap = colormaps["RdYlGn"].with_extremes(bad="#e5e7eb") + image = ax.imshow( + np.ma.masked_invalid(values), cmap=cmap, vmin=vmin, vmax=vmax, aspect="auto" + ) + ax.set_xticks(range(len(pivot.columns))) + ax.set_xticklabels([str(value) for value in pivot.columns]) + ax.set_yticks(range(len(pivot.index))) + ax.set_yticklabels([str(value) for value in pivot.index]) + ax.set_xlabel(parameter_x, fontsize=9) + ax.set_ylabel(parameter_y, fontsize=9) + ax.set_title(title, fontsize=11, fontweight="bold") + fig.colorbar(image, ax=ax, fraction=0.025, pad=0.02) + for row in range(values.shape[0]): + for column in range(values.shape[1]): + value = values[row, column] + label = f"{value:.2f}" if np.isfinite(value) else "n/a" + # RdYlGn is light (yellow) near the middle of the range and + # darker toward both ends (red/green), so contrast text there. + normalized = (value - vmin) / span + colour = ( + "white" + if np.isfinite(value) and abs(normalized - 0.5) > 0.3 + else "#111827" + ) + ax.text( + column, + row, + label, + ha="center", + va="center", + fontsize=7, + color=colour, + ) + return fig + + def adaptive_rolling_window(n_observations: int) -> int: """Shrink the rolling Sharpe/volatility window for short samples. diff --git a/src/quantlab/reporting/html_report.py b/src/quantlab/reporting/html_report.py index 0070994..cadf2b3 100644 --- a/src/quantlab/reporting/html_report.py +++ b/src/quantlab/reporting/html_report.py @@ -14,6 +14,7 @@ import numpy as np import pandas as pd +from quantlab.logging_config import get_logger from quantlab.reporting import research_summary as rs from quantlab.reporting.charts import report_figures from quantlab.reporting.tables import gross_net_table, metrics_table, subperiod_table @@ -21,6 +22,8 @@ if TYPE_CHECKING: from quantlab.backtesting.result import BacktestResult +logger = get_logger(__name__) + _CSS = """ :root { color-scheme: light; } body { font-family: -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif; @@ -184,8 +187,39 @@ def image(name: str, alt: str) -> str: limitations_html = "".join( f"
  • {html.escape(item)}
  • " for item in rs.limitations(result) ) - robustness_html = _render_robustness(robustness) + robustness_html = _render_robustness(robustness, warnings) data_quality_html = _render_data_quality(result.metadata.get("data_quality")) + # A walk-forward OOS result's `metrics` *are* the stitched out-of-sample + # series (see WalkForwardValidator._build_oos_result) — labelling the + # Results headings "Full-sample" would claim the opposite of what they + # actually are. Holdout/plain results keep the accurate "Full-sample" + # label: their `metrics` remain a genuine full-sample fit even when + # holdout OOS evidence is also attached separately. + results_scope = ( + "Out-of-sample (walk-forward)" + if rs.out_of_sample_scope(result) is not None + else "Full-sample" + ) + # Only claim reproducibility when the engine could positively verify the + # actual strategy/allocator/execution objects against config.yaml's own + # values -- a direct-API run (docs/api.md) can pass a custom object that + # silently diverges from config.yaml on any of the three (see + # BacktestEngine._build_metadata), which must never be asserted away by + # an unconditional footer. All three must verify, not just any one. + config_verified = ( + bool(result.metadata.get("config_yaml_reflects_strategy")) + and bool(result.metadata.get("config_yaml_reflects_allocator")) + and bool(result.metadata.get("config_yaml_reflects_execution")) + ) + reproducibility_note = ( + "reproducible from config.yaml given the same code, data and " + "dependency versions recorded in metadata.json" + if config_verified + else "config.yaml in this bundle may not exactly reflect the " + "strategy/allocator/execution actually used for this run -- see " + "metadata.json's config_yaml_reflects_strategy/" + "config_yaml_reflects_allocator/config_yaml_reflects_execution" + ) document = f""" @@ -219,11 +253,11 @@ def image(name: str, alt: str) -> str:

    Results

    {image("equity_curve", "Equity curve")} {image("drawdown", "Drawdown")} -

    Full-sample headline metrics

    +

    {results_scope} headline metrics

    {_table_html(metrics_table(result))} -

    Full-sample gross vs net

    +

    {results_scope} gross vs net

    {_table_html(gross_net_table(result))} -

    Full-sample performance by year

    +

    {results_scope} performance by year

    {_table_html(_format_report_table(subperiod_table(result)))} {image("monthly_returns", "Monthly returns heatmap")} {image("rolling_sharpe", "Rolling Sharpe")} @@ -240,8 +274,7 @@ def image(name: str, alt: str) -> str:

    Conclusion

    {html.escape(rs.conclusion(result))}
    -
    Generated by QuantLab · reproducible from config.yaml given the - same code, data and dependency versions recorded in metadata.json
    +
    Generated by QuantLab · {reproducibility_note}
    """ @@ -275,7 +308,29 @@ def _render_robustness_value(value: object) -> str: return f"

    {html.escape(str(value))}

    " -def _render_robustness(robustness: dict[str, Any] | None) -> str: +def _render_sensitivity_heatmap( + sensitivity: pd.DataFrame, warnings: list[str] | None +) -> str: + """Render a 2-parameter sensitivity sweep as an embedded heatmap image.""" + from quantlab.reporting.charts import fig_to_base64, sensitivity_heatmap_chart + + try: + data_uri = fig_to_base64(sensitivity_heatmap_chart(sensitivity)) + except Exception as exc: + message = f"Could not render sensitivity heatmap for report: {exc}" + logger.warning(message, exc_info=True) + if warnings is not None: + warnings.append(message) + return ( + '

    Chart unavailable: ' + f"sensitivity heatmap. {html.escape(str(exc))}

    " + ) + return f'Parameter sensitivity heatmap' + + +def _render_robustness( + robustness: dict[str, Any] | None, warnings: list[str] | None = None +) -> str: """Render supplied validation artefacts or explain how to generate them.""" if not robustness: return ( @@ -298,6 +353,15 @@ def _render_robustness(robustness: dict[str, Any] | None) -> str: for key, value in robustness.items(): heading = str(key).replace("_", " ").title() parts.append(f"

    {html.escape(heading)}

    ") + if key == "permutation_test": + parts.append( + "

    Randomly flips the sign of excess returns to test " + "the realised Sharpe against a no-edge random-sign null. A " + "low p-value is evidence against that specific null, not a " + "probability of future profitability.

    " + ) + elif key == "sensitivity" and isinstance(value, pd.DataFrame) and len(value): + parts.append(_render_sensitivity_heatmap(value, warnings)) parts.append(_render_robustness_value(value)) return "".join(parts) diff --git a/src/quantlab/reporting/research_summary.py b/src/quantlab/reporting/research_summary.py index cf8f5ae..516e193 100644 --- a/src/quantlab/reporting/research_summary.py +++ b/src/quantlab/reporting/research_summary.py @@ -51,6 +51,27 @@ def _format_metric(value: object, kind: str) -> str: return f"{number:.2f}" +def _actually_used(result: BacktestResult, key: str, fallback: Any) -> Any: + """Prefer the object actually executed over ``result.config``'s own value. + + ``BacktestEngine`` can be used directly with a custom strategy, + allocator or execution-model instance that need not match + ``config``'s own YAML-derived settings (see docs/api.md's "Extension + points") -- ``result.metadata``'s ``strategy``/``allocator``/ + ``commission_bps``/``spread_bps`` fields record what was actually run, + so report text must read from there, not from ``result.config``, or it + could describe a different reality than the one accounting and the + trade log actually charged. Falls back to ``result.config`` only for an + older saved result or a duck-typed stand-in missing the field. + """ + metadata = getattr(result, "metadata", None) + if isinstance(metadata, Mapping): + value = metadata.get(key) + if value is not None: + return value + return fallback + + def _actual_period(result: BacktestResult) -> tuple[str, str] | None: """Return the dates actually represented by the result.""" index = result.equity_curve.index @@ -69,6 +90,12 @@ def executive_summary(result: BacktestResult) -> str: if actual_period is not None else "over an unavailable observed period" ) + oos_scope = out_of_sample_scope(result) + scope_text = ( + f" These are {oos_scope} results, not a full-sample fit." + if oos_scope is not None + else "" + ) benchmark_text = "" if result.benchmark_returns is not None: @@ -79,9 +106,10 @@ def executive_summary(result: BacktestResult) -> str: f"annualised alpha was {_format_metric(metrics.get('alpha'), 'pct')}." ) + strategy_name = _actually_used(result, "strategy", cfg.strategy_name) return ( - f"The {cfg.strategy_name.replace('_', ' ')} strategy was tested on " - f"{len(cfg.symbols)} instrument(s) {period_text}. Net of modelled " + f"The {strategy_name.replace('_', ' ')} strategy was tested on " + f"{len(cfg.symbols)} instrument(s) {period_text}.{scope_text} Net of modelled " f"transaction costs, total return was " f"{_format_metric(metrics.get('total_return'), 'pct')} " f"(CAGR {_format_metric(metrics.get('cagr'), 'pct')}), annualised volatility " @@ -97,7 +125,7 @@ def executive_summary(result: BacktestResult) -> str: def research_question(result: BacktestResult) -> str: """Return a question that names only configured and attached evidence.""" cfg = result.config - strategy = cfg.strategy_name + strategy = _actually_used(result, "strategy", cfg.strategy_name) portfolio = cfg.portfolio volatility_targeted = ( portfolio.allocator == "volatility_targeting" @@ -164,28 +192,58 @@ def hypothesis(result: BacktestResult) -> str: def _oos_metrics(result: BacktestResult) -> tuple[dict[str, Any], str] | None: - """Return attached OOS metrics, preferring walk-forward evidence.""" + """Return attached OOS metrics, preferring walk-forward evidence. + + Some callers (table builders in particular) are exercised with minimal + duck-typed stand-ins that don't implement the full ``BacktestResult`` + interface, so a missing ``metadata`` attribute is treated the same as + an empty one rather than raising. + """ + metadata = getattr(result, "metadata", None) + if not isinstance(metadata, Mapping): + return None candidates = ( ( "walk_forward_oos_metrics", "out-of-sample (walk-forward test folds only)", ), ( - "holdout_oos_metrics", - "out-of-sample (chronological holdout test block)", + "holdout_chronological_metrics", + "chronological holdout test block (out-of-sample only if " + "strategy/parameter choices were frozen before it was inspected)", ), ) for key, label in candidates: - metrics = result.metadata.get(key) + metrics = metadata.get(key) if isinstance(metrics, Mapping) and metrics: return dict(metrics), label return None +def out_of_sample_scope(result: BacktestResult) -> str | None: + """Return the OOS scope label only when ``result.metrics`` *is* that series. + + Not just whenever some OOS evidence is attached: a holdout result also + carries chronological-test-block evidence, but its own ``metrics`` stay + a genuine full-sample fit (the holdout block's metrics are held + separately, in ``metadata["holdout_chronological_metrics"]``) — + "full-sample" is still correct there. Only a walk-forward result's + ``metrics`` already are the out-of-sample series, so only that case + needs "full-sample" labels corrected elsewhere (e.g. Results headings, + ``tables.subperiod_table``'s aggregate row). + """ + oos = _oos_metrics(result) + if oos is None: + return None + oos_metrics, scope = oos + return scope if oos_metrics == result.metrics else None + + def _portfolio_methodology(result: BacktestResult) -> str: portfolio = result.config.portfolio + allocator_name = _actually_used(result, "allocator", portfolio.allocator) details = [ - f"allocator {portfolio.allocator}", + f"allocator {allocator_name}", f"rebalance cadence {portfolio.rebalance_frequency}", f"maximum leverage {portfolio.maximum_leverage:.2f}x", ] @@ -213,20 +271,30 @@ def _portfolio_methodology(result: BacktestResult) -> str: def _execution_methodology(result: BacktestResult) -> str: execution = result.config.execution - model = str(execution.slippage_model).lower() + commission_bps = float( + _actually_used(result, "commission_bps", execution.commission_bps) + ) + spread_bps = float(_actually_used(result, "spread_bps", execution.spread_bps)) + model = str( + _actually_used(result, "slippage_model", execution.slippage_model) + ).lower() + slippage_bps = float(_actually_used(result, "slippage_bps", execution.slippage_bps)) base = ( - f"commission {execution.commission_bps:.1f} bps of traded notional and " - f"a {execution.spread_bps:.1f} bps full quoted spread (half charged when " + f"commission {commission_bps:.1f} bps of traded notional and " + f"a {spread_bps:.1f} bps full quoted spread (half charged when " "crossing)" ) if model in {"volume", "volume_based"}: + impact_coefficient = float( + _actually_used(result, "impact_coefficient", execution.impact_coefficient) + ) slippage = ( - f"volume-based slippage with {execution.slippage_bps:.1f} bps base " + f"volume-based slippage with {slippage_bps:.1f} bps base " f"slippage plus square-root market impact using trailing dollar ADV " - f"and impact coefficient {execution.impact_coefficient:.4f}" + f"and impact coefficient {impact_coefficient:.4f}" ) else: - slippage = f"constant slippage {execution.slippage_bps:.1f} bps" + slippage = f"constant slippage {slippage_bps:.1f} bps" return f"{base}, and {slippage}" @@ -245,14 +313,36 @@ def methodology(result: BacktestResult) -> str: "chronological holdout with a non-zero test ratio, before drawing " "out-of-sample conclusions." ) + strategy_name = _actually_used(result, "strategy", cfg.strategy_name) return ( - f"The {cfg.strategy_name} strategy generates signals. Portfolio construction " + f"The {strategy_name} strategy generates signals. Portfolio construction " f"uses {_portfolio_methodology(result)}. Execution costs use " f"{_execution_methodology(result)}. Weights are shifted by one observation " f"before earning returns. {validation_text}" ) +def _bundled_demo_data_used(result: BacktestResult) -> bool | None: + """Whether the bundled synthetic CSV fallback actually triggered. + + ``None`` when unknown (no attached data-quality report to consult, e.g. + an older saved result, or a duck-typed stand-in without a full + ``metadata`` attribute -- see ``_oos_metrics``) -- distinct from + ``False`` (known not to have been used), so callers can fall back to a + hedged statement only in the genuinely-unknown case. + """ + metadata = getattr(result, "metadata", None) + if not isinstance(metadata, Mapping): + return None + data_quality = metadata.get("data_quality") + if ( + not isinstance(data_quality, dict) + or "bundled_demo_data_used" not in data_quality + ): + return None + return bool(data_quality["bundled_demo_data_used"]) + + def data_description(result: BacktestResult) -> str: """Describe requested data and the sample actually tested.""" cfg = result.config @@ -264,10 +354,19 @@ def data_description(result: BacktestResult) -> str: ) demo_text = "" if cfg.data.use_bundled_demo_data: - demo_text = ( - " Bundled synthetic CSV fallback was enabled; the saved data artefacts " - "must be consulted to determine whether the fallback was used." - ) + demo_used = _bundled_demo_data_used(result) + if demo_used is True: + demo_text = " Bundled synthetic CSV fallback was used for this run." + elif demo_used is False: + demo_text = ( + " Bundled synthetic CSV fallback was enabled but not needed for " + "this run (local CSV files were found)." + ) + else: + demo_text = ( + " Bundled synthetic CSV fallback was enabled; the saved data " + "artefacts must be consulted to determine whether it was used." + ) return ( f"Source: {cfg.data_source}. Instruments ({len(cfg.symbols)}): " f"{', '.join(cfg.symbols)}. Frequency: {cfg.frequency}. Requested period: " @@ -289,12 +388,46 @@ def limitations(result: BacktestResult) -> list[str]: items.append( "Constant slippage does not vary with order size, liquidity or volatility." ) - if result.config.data_source == "binance": + from quantlab.config import DataSourceName + + if any( + instrument.source is DataSourceName.BINANCE + for instrument in result.config.data.instruments + ): items.append("Crypto data uses one venue rather than a consolidated tape.") if result.config.data.use_bundled_demo_data: + demo_used = _bundled_demo_data_used(result) + if demo_used is True: + items.append( + "Synthetic bundled CSV data was used for this run; it is suitable " + "for demonstrations, not empirical market claims." + ) + elif demo_used is None: + items.append( + "Synthetic bundled CSV data may have been used when local CSV " + "files were absent; it is suitable for demonstrations, not " + "empirical market claims." + ) + metadata = getattr(result, "metadata", None) + if isinstance(metadata, Mapping) and "holdout_chronological_metrics" in metadata: items.append( - "Synthetic bundled CSV data may have been used when local CSV files were " - "absent; it is suitable for demonstrations, not empirical market claims." + "The holdout evidence attached to this report is a chronological " + "test block: data held back from the fitted metrics by a " + "mechanical time split. That alone does not confirm it is " + "genuinely out-of-sample -- it does not by itself confirm that " + "strategy or parameter choices were frozen before this block was " + "ever inspected. Its out-of-sample status depends on that " + "discipline having been followed upstream of this report." + ) + calendars = {instrument.calendar for instrument in result.config.data.instruments} + if len(calendars) > 1: + items.append( + "Instruments span more than one calendar: rolling-window features " + "(momentum lookback, volatility window, ADV window, technical " + "indicators) count raw periods, not real trading sessions per " + "instrument, so a session-bound instrument's estimates are diluted " + "by the flat, zero-return/zero-volume bars inserted on its verified " + "closures to keep the combined timeline dense." ) return items @@ -312,28 +445,38 @@ def conclusion(result: BacktestResult) -> str: """State full-sample and attached OOS evidence without conflating them.""" full_sharpe = result.metrics.get("sharpe_ratio") full_drawdown = result.metrics.get("max_drawdown") + epilogue = ( + " Future performance remains uncertain and depends materially on " + "execution costs, market regime and parameter stability. These " + "results are not a guarantee of future profitability and are not " + "investment advice." + ) oos = _oos_metrics(result) if oos is not None: oos_metrics, scope = oos oos_sharpe = oos_metrics.get("sharpe_ratio") oos_drawdown = oos_metrics.get("max_drawdown") + if oos_metrics == result.metrics: + # A walk-forward OOS result's `metrics` *is* the stitched + # out-of-sample series (see WalkForwardValidator._build_oos_result) + # — there is no separate full-sample fit to report alongside it. + return ( + f"Under the tested assumptions, the strategy displayed " + f"{_disposition(oos_sharpe)} using {scope} data (Sharpe " + f"{_format_metric(oos_sharpe, 'num')}, maximum drawdown " + f"{_format_metric(oos_drawdown, 'pct')})." + epilogue + ) return ( f"Under the tested assumptions, the strategy displayed " f"{_disposition(oos_sharpe)} using {scope} data (out-of-sample Sharpe " f"{_format_metric(oos_sharpe, 'num')}, out-of-sample maximum drawdown " f"{_format_metric(oos_drawdown, 'pct')}). The separate full-sample " f"results are Sharpe {_format_metric(full_sharpe, 'num')} and maximum " - f"drawdown {_format_metric(full_drawdown, 'pct')}. Future performance " - "remains uncertain and depends materially on execution costs, market " - "regime and parameter stability. These results are not a guarantee of " - "future profitability and are not investment advice." + f"drawdown {_format_metric(full_drawdown, 'pct')}." + epilogue ) return ( f"Under the tested assumptions, the strategy displayed " f"{_disposition(full_sharpe)} using full-sample data; no out-of-sample " f"validation is attached (Sharpe {_format_metric(full_sharpe, 'num')}, " - f"maximum drawdown {_format_metric(full_drawdown, 'pct')}). Future " - "performance remains uncertain and depends materially on execution costs, " - "market regime and parameter stability. These results are not a guarantee " - "of future profitability and are not investment advice." + f"maximum drawdown {_format_metric(full_drawdown, 'pct')})." + epilogue ) diff --git a/src/quantlab/reporting/tables.py b/src/quantlab/reporting/tables.py index a7ecdd5..0ea5935 100644 --- a/src/quantlab/reporting/tables.py +++ b/src/quantlab/reporting/tables.py @@ -8,6 +8,7 @@ import numpy as np import pandas as pd +from quantlab.reporting.research_summary import out_of_sample_scope from quantlab.risk.drawdown import max_drawdown from quantlab.risk.metrics import ( annualized_volatility, @@ -115,10 +116,14 @@ def yearly_returns_table(result: BacktestResult) -> pd.DataFrame: def subperiod_table(result: BacktestResult) -> pd.DataFrame: - """Full-sample and yearly performance, turnover and trade counts. - - ``Turnover (x)`` is the cumulative L1 turnover multiple within each row's - period; it is not annualised for the full-sample row. + """Aggregate and yearly performance, turnover and trade counts. + + The aggregate row is labelled "Out-of-sample" instead of "Full sample" + when ``result.metrics`` are themselves a walk-forward OOS series (see + ``research_summary.out_of_sample_scope``) — otherwise it would claim + the opposite of what that series actually is. ``Turnover (x)`` is the + cumulative L1 turnover multiple within each row's period; it is not + annualised for the aggregate row. """ ppy = result.config.periods_per_year rf = result.config.backtest.risk_free_rate @@ -127,7 +132,10 @@ def subperiod_table(result: BacktestResult) -> pd.DataFrame: result.turnover if result.turnover is not None else pd.Series(dtype=float) ) - rows = [_subperiod_row("Full sample", rets, ppy, rf)] + aggregate_label = ( + "Out-of-sample" if out_of_sample_scope(result) is not None else "Full sample" + ) + rows = [_subperiod_row(aggregate_label, rets, ppy, rf)] for year, grp in rets.groupby(pd.DatetimeIndex(rets.index).year): rows.append(_subperiod_row(str(year), grp, ppy, rf)) @@ -136,7 +144,7 @@ def subperiod_table(result: BacktestResult) -> pd.DataFrame: trade_counts = [] trades = result.trades for label in table["Period"]: - if label == "Full sample": + if label == aggregate_label: mask = pd.Series(True, index=rets.index) else: year_match = pd.DatetimeIndex(rets.index).year == int(label) @@ -144,7 +152,7 @@ def subperiod_table(result: BacktestResult) -> pd.DataFrame: turnovers.append(float(turnover[mask].sum()) if len(turnover) else np.nan) if len(trades) and "timestamp" in trades.columns: ts = pd.to_datetime(trades["timestamp"]) - if label == "Full sample": + if label == aggregate_label: trade_counts.append(len(trades)) else: trade_counts.append(int((ts.dt.year == int(label)).sum())) diff --git a/src/quantlab/strategies/__init__.py b/src/quantlab/strategies/__init__.py index 05a5ef5..47b79d9 100644 --- a/src/quantlab/strategies/__init__.py +++ b/src/quantlab/strategies/__init__.py @@ -12,6 +12,7 @@ build_strategy, register_strategy, strategy_parameter_names, + strategy_sweepable_parameter_names, validate_strategy_parameters, ) @@ -43,5 +44,6 @@ "register_strategy", "rolling_hedge_parameters", "strategy_parameter_names", + "strategy_sweepable_parameter_names", "validate_strategy_parameters", ] diff --git a/src/quantlab/strategies/base.py b/src/quantlab/strategies/base.py index 00c5de5..69a97b9 100644 --- a/src/quantlab/strategies/base.py +++ b/src/quantlab/strategies/base.py @@ -97,6 +97,32 @@ def strategy_parameter_names(name: str) -> set[str]: } +def strategy_sweepable_parameter_names(name: str) -> set[str]: + """Return constructor keywords suitable for a 2-parameter sensitivity sweep. + + Excludes boolean-defaulted parameters (structural switches such as + long_only/long_short/dynamic_hedge_ratio): sweeping one changes which + *other* parameters are even meaningful (e.g. bottom_fraction only + matters when long_short=True), and candidate values typed as text + (comma-separated) are easy to misparse as an int/str instead of a bool. + ``default_parameter_grid`` already treats these as fixed, not swept, for + walk-forward's own default grid — sensitivity applies the same rule. + """ + registry_name = _registry_name(name) + if registry_name not in _REGISTRY: + raise StrategyError( + f"Unknown strategy '{registry_name}'. Registered: {sorted(_REGISTRY)}." + ) + signature = inspect.signature(_REGISTRY[registry_name].__init__) + return { + parameter.name + for parameter in signature.parameters.values() + if parameter.name != "self" + and parameter.kind not in (parameter.VAR_POSITIONAL, parameter.VAR_KEYWORD) + and not isinstance(parameter.default, bool) + } + + def _unwrap_simple_type(annotation: Any) -> type | None: """Resolve plain and optional annotations used for early type checks.""" if annotation is Any: diff --git a/src/quantlab/validation/__init__.py b/src/quantlab/validation/__init__.py index bbcc664..f946534 100644 --- a/src/quantlab/validation/__init__.py +++ b/src/quantlab/validation/__init__.py @@ -15,11 +15,14 @@ ) from quantlab.validation.parameter_sensitivity import ( run_parameter_sensitivity, + run_walk_forward_parameter_sensitivity, sensitivity_heatmap_data, ) from quantlab.validation.robustness import ( monte_carlo_permutation, run_stress_tests, + run_walk_forward_stress_tests, + stress_test_checkpoint_paths, ) from quantlab.validation.splits import ( ChronologicalSplit, @@ -51,6 +54,9 @@ "run_holdout_validation", "run_parameter_sensitivity", "run_stress_tests", + "run_walk_forward_parameter_sensitivity", + "run_walk_forward_stress_tests", "sensitivity_heatmap_data", + "stress_test_checkpoint_paths", "walk_forward_windows", ] diff --git a/src/quantlab/validation/checkpoint.py b/src/quantlab/validation/checkpoint.py new file mode 100644 index 0000000..f14153b --- /dev/null +++ b/src/quantlab/validation/checkpoint.py @@ -0,0 +1,334 @@ +"""Resumable-process checkpointing for long-running validation loops. + +Lets an interrupted walk-forward, stress-test or sensitivity run continue from +where it left off instead of restarting, gated on the same kind of provenance +guarantee already used by :func:`quantlab.backtesting.result. +load_previous_robustness_artifacts` (config + data_hash + generator_hash + +dependency_versions, deliberately not git_dirty/git_commit — generator_hash +already hashes current file contents, uncommitted changes included). + +Checkpoint files are pickle, trusted-local-file-only: this module's +:class:`_RestrictedUnpickler` blocks the well-known process/OS/import-machinery +gadgets (``os.system``, ``subprocess``, ``eval``, ...), but that is a coarse +mitigation, not a sandbox — it cannot certify a file as safe, only make the +common attack surface smaller. Provenance checking cannot help here either: +the provenance dict is itself *inside* the pickled payload, so it is only +checked after unpickling has already run whatever an embedded ``__reduce__`` +specifies. Never point a checkpoint path at a file from an untrusted source +(a shared filesystem, a downloaded or cloned experiment folder, ...). +""" + +from __future__ import annotations + +import pickle +from collections.abc import Callable, Iterator +from contextlib import contextmanager +from pathlib import Path +from typing import Any + +import pandas as pd +from filelock import FileLock +from filelock import Timeout as FileLockTimeout + +from quantlab.backtesting import engine as _engine +from quantlab.backtesting.result import _write_path_atomic +from quantlab.config import ExperimentConfig +from quantlab.data.storage import ParquetStorage +from quantlab.exceptions import BacktestError +from quantlab.logging_config import get_logger + +logger = get_logger(__name__) + +_LOCK_TIMEOUT_SECONDS = 30.0 + +# Modules that can reach the OS, the interpreter or the import machinery -- +# never legitimately part of checkpointed validation state (DataFrames, +# dataclasses, plain containers, numbers). Blocking these closes off the +# common pickle remote-code-execution gadgets (os.system, subprocess.Popen, +# ...) without needing a full allowlist of every pandas/numpy internal class +# a DataFrame's pickle stream happens to touch, which is fragile and +# version-dependent. +_DANGEROUS_MODULE_PREFIXES = frozenset( + { + "os", + "posix", + "nt", + "subprocess", + "sys", + "shutil", + "socket", + "importlib", + "runpy", + "ctypes", + "multiprocessing", + "pty", + "code", + "pickle", + } +) +_DANGEROUS_BUILTINS = frozenset( + { + "eval", + "exec", + "compile", + "__import__", + "open", + "input", + "breakpoint", + "getattr", + "setattr", + "delattr", + "globals", + "locals", + "vars", + } +) + + +class _RestrictedUnpickler(pickle.Unpickler): # nosemgrep: avoid-pickle + """Blocks well-known code-execution gadgets in an untrusted pickle. + + A checkpoint file lives in a local experiment output directory and is + read back by quantlab itself later -- but nothing stops it from having + been replaced in the meantime (a shared filesystem, a downloaded or + cloned experiment folder, ...). Provenance can't gate this the way it + gates everything else in this module: the provenance dict is itself + *inside* the pickled payload, so it can only be checked after + unpickling has already run whatever code an embedded ``__reduce__`` + specifies. See :func:`_read_payload`. + """ + + def find_class(self, module: str, name: str) -> Any: + top_level = module.partition(".")[0] + if top_level in _DANGEROUS_MODULE_PREFIXES: + raise pickle.UnpicklingError( + f"Refusing to unpickle {module}.{name}: disallowed module." + ) + if module == "builtins" and name in _DANGEROUS_BUILTINS: + raise pickle.UnpicklingError( + f"Refusing to unpickle builtins.{name}: disallowed callable." + ) + return super().find_class(module, name) + + +def compute_provenance( + config: ExperimentConfig, data: pd.DataFrame, **run_params: Any +) -> dict[str, Any]: + """Fingerprint everything a checkpoint's validity depends on. + + ``run_params`` covers whatever a caller can override independently of + ``config`` itself (train/validation/test windows, parameter grid, + execution delay, ...) — those aren't captured by ``config`` alone but + still change what a resumed run would compute. + + Uses ``_generator_hash()``, not ``_source_hash()``: a checkpoint is + resumed from inside a CLI command's own loop, so a change to the CLI's + own orchestration (e.g. how it passes overrides into this run) can + change what a resumed run computes even when the narrower + computational-only hash is unchanged — the same reasoning + ``load_previous_walk_forward_robustness``/``load_previous_robustness_ + artifacts`` (``quantlab.backtesting.result``) apply to saved-bundle + reuse. See ``_generator_hash()``'s own docstring. + + Calls ``_engine.()`` through the module rather than importing + ``_generator_hash``/``_dependency_versions`` by name, so a test that + monkeypatches ``quantlab.backtesting.engine._generator_hash`` (the + established pattern elsewhere in this codebase for pinning a hash + across two CLI invocations in one test) actually takes effect here too. + """ + return { + "config": config.model_dump(mode="json"), + "data_hash": ParquetStorage.hash_frame(data), + "generator_hash": _engine._generator_hash(), + "dependency_versions": _engine._dependency_versions(), + "run_params": run_params, + } + + +def _lock_path(path: Path) -> Path: + """Return the persistent sibling lock used to serialize checkpoint access.""" + resolved = path.resolve() + return resolved.parent / f".{resolved.name}.lock" + + +@contextmanager +def _locked_checkpoint(path: Path) -> Iterator[None]: + """Serialize reads and writes against one checkpoint file. + + A separate lock from `backtesting.result._locked_bundle`'s (the final + bundle save) on purpose — checkpoint writes happen throughout a run, + the bundle save happens once at the end; they're independent critical + sections and don't need to contend with each other. + """ + lock = FileLock(str(_lock_path(path)), timeout=_LOCK_TIMEOUT_SECONDS) + try: + lock.acquire() + except FileLockTimeout as exc: + raise BacktestError( + f"Timed out waiting to access the checkpoint at {path} after " + f"{_LOCK_TIMEOUT_SECONDS:g} seconds; another process may still be " + "using it." + ) from exc + try: + yield + finally: + lock.release() + + +def _read_payload(path: Path) -> dict[str, Any] | None: + """Return the raw ``{"provenance", "progress", "state"}`` payload, or None. + + A checkpoint is only ever written by :func:`save_checkpoint` with this + exact shape -- exactly these three keys, no more, no fewer -- so any + deviation, including an extra key, means the file is corrupted, foreign, + or stale (never simply "an older valid shape" this module needs to keep + reading); treated as unreadable, same as any other malformed payload. + ``state`` itself is opaque here (its shape is defined by whichever + command wrote it) -- callers must validate it themselves before relying + on it, see :func:`load_checkpoint`. + """ + if not path.is_file(): + return None + try: + with path.open("rb") as handle: + # nosemgrep: avoid-pickle -- trusted-local-file-only by design, + # gated by _RestrictedUnpickler above (blocks the well-known + # code-execution gadgets); see this module's own docstring for + # why a full sandbox isn't achievable here and a JSON-only + # format isn't a drop-in replacement for the arbitrary + # DataFrame/dataclass state this checkpoints. + payload = _RestrictedUnpickler(handle).load() + except Exception as exc: + logger.warning("Checkpoint at %s could not be read (%s).", path, exc) + return None + if ( + not isinstance(payload, dict) + or payload.keys() != {"provenance", "progress", "state"} + or not isinstance(payload["provenance"], dict) + or isinstance(payload["progress"], bool) + or not isinstance(payload["progress"], int) + or payload["progress"] < 0 + ): + logger.warning("Checkpoint at %s has an unexpected shape; ignoring it.", path) + return None + return payload + + +def load_checkpoint( + path: Path, + provenance: dict[str, Any], + *, + validate: Callable[[Any, int], bool] | None = None, +) -> tuple[Any, int] | None: + """Return the checkpointed ``(state, progress)`` if it exists and matches. + + Any problem — missing file, unreadable pickle, mismatched provenance, + or a ``validate`` failure — is treated as "nothing to resume" rather + than raised, so a checkpoint can never block a run, only skip work it + has already done. + + ``progress`` is exactly what the caller last passed to + :func:`save_checkpoint` — return it as-is rather than making the caller + re-derive "how much is done" from ``state`` itself (e.g. via + ``len(state)``), which silently under- or over-counts whenever one + checkpointed unit doesn't correspond to exactly one element of ``state`` + (e.g. a single scenario block that appends several result rows at once). + + Args: + path: Checkpoint file. + provenance: Must equal what the checkpoint was saved with. + validate: Optional callable receiving ``(state, progress)``, + returning whether they form a valid pair *for this specific + command* — e.g. ``state`` has the expected container shape, or + ``progress`` does not exceed this run's own total unit count. + This module has no way to know either on its own: ``state``'s + shape and what "total" means are defined entirely by the + caller. Without a check here, a caller blindly destructuring an + unexpected ``state`` (a corrupted file, or one left over from a + differently-shaped older version of the same command) fails + with a confusing raw unpacking error instead of a clear refusal + to resume. + """ + with _locked_checkpoint(path): + payload = _read_payload(path) + if payload is None: + return None + if payload["provenance"] != provenance: + logger.info( + "Not resuming from %s: config, data, code or run parameters have " + "changed since it was written.", + path, + ) + return None + state, progress = payload["state"], payload["progress"] + if validate is not None: + try: + is_valid = validate(state, progress) + except Exception as exc: + # `state` is untrusted, arbitrary checkpointed data by + # definition -- a caller's validator inspecting its content + # (e.g. comparing a corrupted value that turns out to be + # `pd.NA`) can itself raise partway through, not just return + # False. This module's own contract ("any problem ... is + # treated as 'nothing to resume' rather than raised") has to + # hold even then: a validator crashing must never propagate out + # of a checkpoint read and abort the run it was meant to help. + logger.warning( + "Not resuming from %s: checkpointed state/progress raised " + "%s while validating it; ignoring it.", + path, + exc, + ) + return None + if not is_valid: + logger.warning( + "Not resuming from %s: checkpointed state/progress failed " + "this command's own validation; ignoring it.", + path, + ) + return None + return state, progress + + +def save_checkpoint( + path: Path, provenance: dict[str, Any], state: Any, progress: int +) -> None: + """Atomically replace the checkpoint at ``path``, without ever regressing it. + + ``progress`` is an opaque, caller-supplied count (folds/scenarios/cells/ + candidates already done — not interpreted, only compared). Two processes + racing on the same experiment (same provenance, same path) could + otherwise have the less-advanced one overwrite the more-advanced one's + checkpoint: the lock makes the read-compare-write atomic, and only + writing when ``progress`` is at least as large as what's already on disk + (for matching provenance) means the more-advanced state always wins, + never silently regresses. + """ + with _locked_checkpoint(path): + existing = _read_payload(path) + if ( + existing is not None + and existing["provenance"] == provenance + and existing.get("progress", -1) > progress + ): + logger.debug( + "Not overwriting checkpoint at %s: on-disk progress (%s) is " + "already ahead of this write (%s).", + path, + existing.get("progress"), + progress, + ) + return + payload = {"provenance": provenance, "progress": progress, "state": state} + # nosemgrep: avoid-pickle -- serializing our own trusted in-memory + # state, not deserializing untrusted input; see _read_payload's own + # nosemgrep comment and this module's docstring for the full + # rationale (arbitrary DataFrame/dataclass state, trusted-local-file + # only). + _write_path_atomic(path, lambda tmp: tmp.write_bytes(pickle.dumps(payload))) + + +def clear_checkpoint(path: Path) -> None: + """Remove a checkpoint, e.g. after its run completes or via ``--fresh``.""" + with _locked_checkpoint(path): + path.unlink(missing_ok=True) diff --git a/src/quantlab/validation/holdout.py b/src/quantlab/validation/holdout.py index 91eca1a..94fb808 100644 --- a/src/quantlab/validation/holdout.py +++ b/src/quantlab/validation/holdout.py @@ -92,9 +92,11 @@ def summary_table(self) -> pd.DataFrame: self.validation_end, ) ) - blocks.append( - ("Test (out-of-sample)", self.test_metrics, self.test_start, self.test_end) - ) + # Labeled plainly "Test", not "out-of-sample": whether this block is + # genuinely OOS depends on parameters having been fixed *before* + # looking at it, which is a property of the user's own workflow, + # not something this table can verify (see the module docstring). + blocks.append(("Test", self.test_metrics, self.test_start, self.test_end)) return pd.DataFrame( [ { diff --git a/src/quantlab/validation/parameter_grid.py b/src/quantlab/validation/parameter_grid.py index c00e685..c8a3edc 100644 --- a/src/quantlab/validation/parameter_grid.py +++ b/src/quantlab/validation/parameter_grid.py @@ -7,6 +7,38 @@ from quantlab.config import ExperimentConfig +def parse_parameter_grid_values(raw: str) -> list[Any]: + """Parse comma-separated grid candidates into int/float/bool/str values. + + Shared by the CLI's ``--values-x``/``--values-y`` sensitivity options and + the dashboard's grid-parameter text inputs. Server-side validation + (``WalkForwardValidator.run()``, ``run_parameter_sensitivity()``) is + authoritative; this only turns raw text into the Python types a strategy + constructor actually expects (e.g. an int ``lookback_period``, not the + string ``"120"``). + """ + values: list[Any] = [] + for token in raw.split(","): + text = token.strip() + if not text: + continue + if text.lower() in {"true", "false"}: + values.append(text.lower() == "true") + continue + try: + values.append(int(text)) + continue + except ValueError: + pass + try: + values.append(float(text)) + continue + except ValueError: + pass + values.append(text) + return values + + def parameter_grid_for_config(config: ExperimentConfig) -> dict[str, list[Any]]: """Return the configured walk-forward grid or the strategy default. diff --git a/src/quantlab/validation/parameter_sensitivity.py b/src/quantlab/validation/parameter_sensitivity.py index ec7ed4b..e88cbe9 100644 --- a/src/quantlab/validation/parameter_sensitivity.py +++ b/src/quantlab/validation/parameter_sensitivity.py @@ -2,7 +2,9 @@ from __future__ import annotations -from collections.abc import Sequence +import math +from collections.abc import Callable, Sequence +from pathlib import Path from typing import Any import numpy as np @@ -11,9 +13,15 @@ from quantlab.backtesting.runner import run_backtest_from_config from quantlab.config import ExperimentConfig -from quantlab.exceptions import QuantLabError +from quantlab.exceptions import InvalidConfigurationError, QuantLabError from quantlab.logging_config import get_logger -from quantlab.strategies import strategy_parameter_names +from quantlab.strategies import strategy_sweepable_parameter_names +from quantlab.validation.checkpoint import ( + clear_checkpoint, + compute_provenance, + load_checkpoint, + save_checkpoint, +) logger = get_logger(__name__) @@ -92,6 +100,255 @@ def run_parameter_sensitivity( return pd.DataFrame(rows) +_SENSITIVITY_CELL_METRIC_COLUMNS = ( + "sharpe", + "cagr", + "max_drawdown", + "turnover", + "num_trades", +) + + +def _values_equal(a: Any, b: Any) -> bool: + """Compare two candidate values without requiring them to be scalar. + + ``a`` comes from an untrusted checkpoint, so ``a == b`` itself is not + safe to trust blindly: a scalar sentinel like ``pd.NA`` compares equal + to nothing (``bool(pd.NA)`` raises ``TypeError: boolean value of NA is + ambiguous`` rather than returning ``False``), and an arbitrary corrupted + value could make ``==`` raise outright (e.g. comparing against a type + that doesn't support it). Either way, that only means "not a match" -- + it must never propagate out and abort a checkpoint validation that + otherwise exists precisely to catch corrupted input like this. + """ + try: + equal = a == b + if isinstance(equal, (np.ndarray, pd.Series)): + return bool(np.asarray(equal).all()) + return bool(equal) + except Exception: + return False + + +def _sensitivity_cell_row_is_consistent(row: dict[str, Any]) -> bool: + """Return whether a checkpointed cell's status, metrics and error agree. + + Mirrors the two shapes the loop below actually produces: ``status == + "ok"`` means every metric is a finite number and ``error`` is ``None``; + ``status == "failed"`` means every metric is NaN and ``error`` is a real + (non-empty) message. A cell claiming success while carrying NaN metrics, + or failure while carrying finite ones and no error, is corrupted + regardless of whether its schema and parameter values already checked + out. + """ + status = row.get("status") + error = row.get("error") + metric_values = [row.get(name) for name in _SENSITIVITY_CELL_METRIC_COLUMNS] + if status == "ok": + if error is not None: + return False + return all( + isinstance(value, (int, float)) + and not isinstance(value, bool) + and math.isfinite(value) + for value in metric_values + ) + if status == "failed": + if not (isinstance(error, str) and error): + return False + return all( + isinstance(value, float) and math.isnan(value) for value in metric_values + ) + return False + + +def run_walk_forward_parameter_sensitivity( + data: pd.DataFrame, + base_config: ExperimentConfig, + parameter_x: str, + values_x: list[Any], + parameter_y: str, + values_y: list[Any], + *, + on_progress: Callable[[int, int], None] | None = None, + checkpoint_path: Path | None = None, +) -> pd.DataFrame: + """Two-parameter sweep where each cell re-runs the full walk-forward process. + + Unlike :func:`run_parameter_sensitivity`, each ``(x, y)`` combination is + not evaluated as a single plain backtest: it is pinned as the *only* + candidate in a fresh :class:`~quantlab.validation.walk_forward. + WalkForwardValidator` run (all folds, OOS reconstruction), scored on that + run's out-of-sample metrics. This keeps Walk-forward mode's sensitivity + heatmap genuinely walk-forward-derived rather than silently reusing plain + single-backtest numbers. Train/validation/test windows and expanding + mode come from ``base_config.validation`` + (:func:`~quantlab.validation.walk_forward.resolve_walk_forward_windows`). + + Args: + data: Canonical long OHLCV frame. + base_config: Validated experiment config; its own strategy + parameters supply every field not swept by parameter_x/y. + parameter_x: First swept strategy-parameter name (x-axis). + values_x: Candidate values for parameter_x. + parameter_y: Second swept strategy-parameter name (y-axis). + values_y: Candidate values for parameter_y. + on_progress: Optional callback invoked as ``on_progress(done, total)`` + once before the first cell (or the resumed count, see + ``checkpoint_path``) and once after each cell completes — each + cell here is itself a full walk-forward run, so this reports + coarser, cell-level progress, not individual fold progress. + checkpoint_path: Optional path to persist per-cell progress to, so + an interrupted sweep resumes from its last completed cell + instead of starting over. See ``quantlab.validation.checkpoint``. + """ + from quantlab.validation.walk_forward import ( + WalkForwardValidator, + resolve_walk_forward_windows, + ) + + if not isinstance(data, pd.DataFrame): + raise TypeError("data must be a pandas DataFrame.") + if not isinstance(base_config, ExperimentConfig): + raise TypeError("base_config must be an ExperimentConfig.") + _validate_parameter_axes(base_config, parameter_x, values_x, parameter_y, values_y) + train_window, validation_window, test_window = resolve_walk_forward_windows( + base_config + ) + expanding = base_config.validation.expanding + + # A flat list, not the nested loop below directly, so a resume can slice + # off however many cells a checkpoint already has rows for. + combinations = [(x, y) for x in values_x for y in values_y] + total_cells = len(combinations) + + rows: list[dict[str, Any]] = [] + provenance: dict[str, Any] | None = None + completed_cells = 0 + + expected_cell_keys = { + parameter_x, + parameter_y, + *_SENSITIVITY_CELL_METRIC_COLUMNS, + "status", + "error", + } + + def _validate_cell_state(state: Any, progress: int) -> bool: + # One row per cell, in lockstep with `progress` (unlike the + # scenario-block checkpoints elsewhere, where one unit can append + # several rows at once) -- so an exact length match is meaningful + # here, not just an upper bound. A structurally-plausible but + # incoherent checkpoint (right length, wrong content -- e.g. a + # single-cell state of `["garbage"]`, or a row carrying some other + # cell's parameter values) must never be resumed from: it would + # silently corrupt the sweep with a mismatched or malformed row. + if not (0 <= progress <= total_cells and isinstance(state, list)): + return False + if len(state) != progress: + return False + if not all( + isinstance(row, dict) and row.keys() == expected_cell_keys for row in state + ): + return False + # Each row's own (x, y) must match the combination actually assigned + # to its position -- the same order the loop below resumes from + # (`combinations[completed_cells:]`), so a resumed row can never be + # silently attributed to the wrong cell. + for row, (x, y) in zip(state, combinations[:progress], strict=True): + x_matches = _values_equal(row[parameter_x], x) + y_matches = _values_equal(row[parameter_y], y) + if not (x_matches and y_matches): + return False + return all(_sensitivity_cell_row_is_consistent(row) for row in state) + + if checkpoint_path is not None: + provenance = compute_provenance( + base_config, + data, + parameter_x=parameter_x, + values_x=list(values_x), + parameter_y=parameter_y, + values_y=list(values_y), + ) + checkpoint_result = load_checkpoint( + checkpoint_path, provenance, validate=_validate_cell_state + ) + if checkpoint_result is not None: + rows, completed_cells = checkpoint_result + logger.info( + "Resuming walk-forward sensitivity from checkpoint: %d/%d " + "cells already done.", + completed_cells, + total_cells, + ) + if on_progress is not None: + on_progress(completed_cells, total_cells) + + for x, y in combinations[completed_cells:]: + row: dict[str, Any] = {parameter_x: x, parameter_y: y} + try: + config = _with_two_params(base_config, parameter_x, x, parameter_y, y) + wf = WalkForwardValidator(config).run( + data, + # No inner grid: x/y are pinned, so this cell measures + # exactly that combination's walk-forward OOS behaviour, + # not a further optimization on top of it. + parameter_grid={}, + train_window=train_window, + validation_window=validation_window, + test_window=test_window, + expanding=expanding, + ) + if wf.oos_result is None: + raise InvalidConfigurationError( + "No walk-forward fold fit this parameter combination." + ) + except (QuantLabError, ValidationError) as exc: + logger.warning( + "Walk-forward sensitivity combination %s=%s, %s=%s failed: %s", + parameter_x, + x, + parameter_y, + y, + exc, + ) + row.update( + { + "sharpe": float("nan"), + "cagr": float("nan"), + "max_drawdown": float("nan"), + "turnover": float("nan"), + "num_trades": float("nan"), + "status": "failed", + "error": str(exc), + } + ) + else: + metrics = wf.oos_result.metrics + row.update( + { + "sharpe": metrics.get("sharpe_ratio", float("nan")), + "cagr": metrics.get("cagr", float("nan")), + "max_drawdown": metrics.get("max_drawdown", float("nan")), + "turnover": metrics.get("annual_turnover", float("nan")), + "num_trades": metrics.get("number_of_trades", 0.0), + "status": "ok", + "error": None, + } + ) + rows.append(row) + completed_cells += 1 + if checkpoint_path is not None and provenance is not None: + save_checkpoint(checkpoint_path, provenance, rows, completed_cells) + if on_progress is not None: + on_progress(completed_cells, total_cells) + + if checkpoint_path is not None: + clear_checkpoint(checkpoint_path) + return pd.DataFrame(rows) + + def sensitivity_heatmap_data( sensitivity: pd.DataFrame, parameter_x: str, @@ -119,6 +376,39 @@ def sensitivity_heatmap_data( return selected.pivot(index=parameter_y, columns=parameter_x, values=metric) +#: Columns a sensitivity result always carries besides its two swept +#: parameters -- whatever's left after excluding these is the axis pair. +_SENSITIVITY_METRIC_COLUMNS = frozenset( + {"sharpe", "cagr", "max_drawdown", "turnover", "num_trades", "status", "error"} +) + + +def infer_sensitivity_parameter_columns(sensitivity: pd.DataFrame) -> tuple[str, str]: + """Return the two swept-parameter columns a sensitivity result carries. + + A sensitivity DataFrame self-describes which two parameters it was + computed for (whatever columns aren't one of the fixed metric columns); + reading them back off the DataFrame itself, rather than trusting a + caller's separately-tracked "current" axis selection, is what keeps a + live UI (e.g. the dashboard) from rendering a stale result under axis + labels that no longer match what was actually computed -- the picker + widgets can drift after the run without the displayed result becoming + wrong or crashing on a missing column. + """ + parameter_columns = [ + column + for column in sensitivity.columns + if column not in _SENSITIVITY_METRIC_COLUMNS + ] + if len(parameter_columns) != 2: + raise ValueError( + "sensitivity must have exactly two swept-parameter columns; found " + f"{parameter_columns}." + ) + parameter_x, parameter_y = parameter_columns + return parameter_x, parameter_y + + def _validate_parameter_axes( config: ExperimentConfig, parameter_x: object, @@ -135,12 +425,16 @@ def _validate_parameter_axes( names = (parameter_x, parameter_y) if parameter_x == parameter_y: raise ValueError("parameter_x and parameter_y must be different.") - accepted = strategy_parameter_names(config.strategy_name) + accepted = strategy_sweepable_parameter_names(config.strategy_name) unknown = set(names).difference(accepted) if unknown: raise ValueError( - f"Unknown parameters for strategy {config.strategy_name!r}: " - f"{sorted(unknown)}." + f"Unknown or unsweepable parameter(s) for strategy " + f"{config.strategy_name!r}: {sorted(unknown)}. Boolean/structural " + "parameters (e.g. long_only, long_short) cannot be swept — they " + "change which other parameters are even meaningful, so " + "sensitivity treats them as fixed, matching the default " + f"walk-forward grid. Accepted parameters: {sorted(accepted)}." ) for name, values in ((parameter_x, values_x), (parameter_y, values_y)): if isinstance(values, (str, bytes)) or not isinstance(values, Sequence): @@ -149,6 +443,11 @@ def _validate_parameter_axes( raise ValueError(f"Values for {name!r} must not be empty.") if _contains_duplicates(values): raise ValueError(f"Values for {name!r} must not contain duplicates.") + if any(isinstance(value, bool) for value in values): + raise ValueError( + f"Values for {name!r} must not be boolean — sensitivity " + "sweeps numeric or categorical candidates only." + ) def _contains_duplicates(values: Sequence[Any]) -> bool: diff --git a/src/quantlab/validation/robustness.py b/src/quantlab/validation/robustness.py index 922aa18..1595794 100644 --- a/src/quantlab/validation/robustness.py +++ b/src/quantlab/validation/robustness.py @@ -2,12 +2,17 @@ from __future__ import annotations +import math +from collections.abc import Callable +from pathlib import Path +from typing import TYPE_CHECKING, Any + import numpy as np import pandas as pd from quantlab.backtesting.runner import run_backtest_from_config from quantlab.config import ExperimentConfig -from quantlab.constants import SYMBOL +from quantlab.constants import SYMBOL, TIMESTAMP from quantlab.exceptions import QuantLabError from quantlab.logging_config import get_logger from quantlab.risk import metrics as M @@ -19,6 +24,15 @@ ) from quantlab.risk.drawdown import max_drawdown from quantlab.risk.stress import remove_best_days, scale_costs +from quantlab.validation.checkpoint import ( + clear_checkpoint, + compute_provenance, + load_checkpoint, + save_checkpoint, +) + +if TYPE_CHECKING: + from quantlab.validation.walk_forward import WalkForwardResult logger = get_logger(__name__) @@ -62,8 +76,116 @@ def _failed_row(name: str, error: QuantLabError) -> dict[str, object]: } -def run_stress_tests(data: pd.DataFrame, config: ExperimentConfig) -> pd.DataFrame: - """Re-run the experiment under cost, delay and universe perturbations.""" +_STRESS_METRIC_COLUMNS = ("total_return", "cagr", "sharpe", "max_drawdown") + + +def _stress_row_is_consistent(row: dict[str, object]) -> bool: + """Return whether a checkpointed row's status, metrics and error agree. + + Mirrors the two shapes ``_metrics_row``/``_failed_row`` actually + produce: ``status == "ok"`` means every metric is a finite number and + ``error`` is ``None``; ``status == "failed"`` means every metric is NaN + and ``error`` is a real (non-empty) message. A checkpoint claiming + success while carrying NaN metrics, or failure while carrying finite + ones and no error, is corrupted regardless of whether its schema and + scenario name already checked out. + """ + status = row.get("status") + error = row.get("error") + metric_values = [row.get(name) for name in _STRESS_METRIC_COLUMNS] + if status == "ok": + if error is not None: + return False + return all( + isinstance(value, (int, float)) + and not isinstance(value, bool) + and math.isfinite(value) + for value in metric_values + ) + if status == "failed": + if not (isinstance(error, str) and error): + return False + return all( + isinstance(value, float) and math.isnan(value) for value in metric_values + ) + return False + + +def _baseline_returns_is_valid( + baseline: object, + data: pd.DataFrame, + baseline_row: dict[str, object] | None, + periods_per_year: int, + risk_free_rate: float, +) -> bool: + """Return whether a checkpointed ``baseline_returns`` is trustworthy. + + A bare ``isinstance(baseline, pd.Series)`` check would accept an empty + series, one full of NaN/inf, one indexed in 1900, or one that + contradicts the "baseline" row already saved alongside it -- and + "best 10 days removed" (see ``remove_best_days`` below) operates on + this Series directly, not on the metrics row, so a corrupted series + reaches a real computation even when the row itself looks fine. Checked + here: non-empty, genuinely numeric, entirely finite; a strictly + increasing, duplicate-free datetime index; that index falling within + ``data``'s own date coverage (a stray 1900 date can't belong to this + run); and, once a "baseline" row exists to compare against, that + recomputing its metrics from this exact series reproduces it exactly -- + the row and the series must describe the same backtest, not two + independently-forged values that happen to both look plausible alone. + Wrapped in a blanket try/except since every input here is untrusted + checkpoint content, by definition capable of raising in ways no + isinstance check anticipates (e.g. an index type that can't convert to + datetimes at all). + """ + try: + if not isinstance(baseline, pd.Series) or baseline.empty: + return False + if not pd.api.types.is_numeric_dtype(baseline.dtype): + return False + values = baseline.to_numpy(dtype=float) + if not np.isfinite(values).all(): + return False + index = pd.DatetimeIndex(baseline.index) + if not index.is_monotonic_increasing or index.has_duplicates: + return False + data_timestamps = pd.to_datetime(data[TIMESTAMP]) + if index.min() < data_timestamps.min() or index.max() > data_timestamps.max(): + return False + if baseline_row is not None: + recomputed = _metrics_row( + "baseline", baseline, periods_per_year, risk_free_rate + ) + if any( + recomputed[key] != baseline_row[key] for key in _STRESS_METRIC_COLUMNS + ): + return False + return True + except Exception: + return False + + +def run_stress_tests( + data: pd.DataFrame, + config: ExperimentConfig, + *, + on_progress: Callable[[int, int], None] | None = None, + checkpoint_path: Path | None = None, +) -> pd.DataFrame: + """Re-run the experiment under cost, delay and universe perturbations. + + Args: + data: Canonical long OHLCV frame. + config: Experiment configuration. + on_progress: Optional callback invoked as ``on_progress(done, total)`` + once before the first scenario and once after each of the + (baseline plus) up to 6 scenarios below completes — each is a + single backtest, so this is coarser than a fold-level signal but + still enough to show a stalled run is actually progressing. + checkpoint_path: Optional path to persist per-scenario progress to, + so an interrupted run resumes from its last completed scenario + instead of starting over. See ``quantlab.validation.checkpoint``. + """ if not isinstance(data, pd.DataFrame): raise TypeError("data must be a pandas DataFrame.") if not isinstance(config, ExperimentConfig): @@ -73,43 +195,157 @@ def run_stress_tests(data: pd.DataFrame, config: ExperimentConfig) -> pd.DataFra periods_per_year = positive_int(config.periods_per_year, name="periods_per_year") risk_free_rate = finite_real(config.risk_free_rate, name="risk_free_rate") - baseline = run_backtest_from_config(data, config) - rows = [ - _metrics_row("baseline", baseline.returns, periods_per_year, risk_free_rate) + reduced_universe = len(config.symbols) > 2 + total_scenarios = 1 + 3 + 2 + (1 if reduced_universe else 0) + + rows: list[dict[str, object]] = [] + # "best 10 days removed" needs the actual baseline returns Series later, + # not just its already-computed metrics row, so it has to be part of the + # checkpointed state too, or resuming past "baseline" would lose it. + baseline_returns: pd.Series | None = None + provenance: dict[str, Any] | None = None + completed_scenarios = 0 + + # The exact scenario name each row must have, in order -- fixed by this + # function's own scenario sequence below, independent of `progress` + # (which only ever names a prefix of it: a config with two symbols or + # fewer never reaches "reduced universe", and neither does an in-progress + # resume). + _scenario_names_in_order = [ + "baseline", + "commission x2", + "commission x5", + "slippage x2", + "execution delay +1", + "best 10 days removed", + "reduced universe", ] + def _validate_stress_state(state: Any, progress: int) -> bool: + # One row per scenario, in lockstep with `progress` -- so an exact + # length match (not just an upper bound) is meaningful here, and so + # is each row's schema, scenario name/order, and internal + # status/metrics/error consistency: a structurally-plausible but + # incoherent checkpoint (wrong row count, malformed rows, rows all + # named "baseline", or a row claiming success while carrying NaN + # metrics) must never be resumed from -- it would silently skip or + # duplicate real scenarios, corrupt the table, or crash "best 10 + # days removed", which needs baseline_returns specifically, not just + # its metrics row. + if not (0 <= progress <= total_scenarios and isinstance(state, tuple)): + return False + if len(state) != 2: + return False + rows, baseline = state + if not isinstance(rows, list) or len(rows) != progress: + return False + if not all( + isinstance(row, dict) and row.keys() == set(_STRESS_COLUMNS) for row in rows + ): + return False + expected_names = _scenario_names_in_order[:progress] + if [row["scenario"] for row in rows] != expected_names: + return False + if not all(_stress_row_is_consistent(row) for row in rows): + return False + if progress >= 1: + return _baseline_returns_is_valid( + baseline, data, rows[0], periods_per_year, risk_free_rate + ) + return baseline is None + + if checkpoint_path is not None: + provenance = compute_provenance(config, data) + checkpoint_result = load_checkpoint( + checkpoint_path, provenance, validate=_validate_stress_state + ) + if checkpoint_result is not None: + (rows, baseline_returns), completed_scenarios = checkpoint_result + logger.info( + "Resuming stress tests from checkpoint: %d/%d scenarios already done.", + completed_scenarios, + total_scenarios, + ) + + def _checkpoint() -> None: + if checkpoint_path is not None and provenance is not None: + save_checkpoint( + checkpoint_path, + provenance, + (rows, baseline_returns), + completed_scenarios, + ) + + if on_progress is not None: + on_progress(completed_scenarios, total_scenarios) + + if completed_scenarios < 1: + baseline = run_backtest_from_config(data, config) + baseline_returns = baseline.returns + rows.append( + _metrics_row("baseline", baseline_returns, periods_per_year, risk_free_rate) + ) + completed_scenarios += 1 + _checkpoint() + if on_progress is not None: + on_progress(completed_scenarios, total_scenarios) + scenarios = { "commission x2": scale_costs(config, commission_mult=2.0), "commission x5": scale_costs(config, commission_mult=5.0), "slippage x2": scale_costs(config, slippage_mult=2.0), } - for name, scenario_config in scenarios.items(): - result = run_backtest_from_config(data, scenario_config) + for position, (name, scenario_config) in enumerate(scenarios.items(), start=2): + if completed_scenarios < position: + result = run_backtest_from_config(data, scenario_config) + rows.append( + _metrics_row(name, result.returns, periods_per_year, risk_free_rate) + ) + completed_scenarios += 1 + _checkpoint() + if on_progress is not None: + on_progress(completed_scenarios, total_scenarios) + + if completed_scenarios < 5: + delayed = run_backtest_from_config(data, config, execution_delay=1) rows.append( - _metrics_row(name, result.returns, periods_per_year, risk_free_rate) + _metrics_row( + "execution delay +1", + delayed.returns, + periods_per_year, + risk_free_rate, + ) ) + completed_scenarios += 1 + _checkpoint() + if on_progress is not None: + on_progress(completed_scenarios, total_scenarios) - delayed = run_backtest_from_config(data, config, execution_delay=1) - rows.append( - _metrics_row( - "execution delay +1", - delayed.returns, - periods_per_year, - risk_free_rate, - ) - ) - rows.append( - _metrics_row( - "best 10 days removed", - remove_best_days(baseline.returns, 10), - periods_per_year, - risk_free_rate, + if completed_scenarios < 6: + assert baseline_returns is not None + rows.append( + _metrics_row( + "best 10 days removed", + remove_best_days(baseline_returns, 10), + periods_per_year, + risk_free_rate, + ) ) - ) + completed_scenarios += 1 + _checkpoint() + if on_progress is not None: + on_progress(completed_scenarios, total_scenarios) - if len(config.symbols) > 2: + if reduced_universe and completed_scenarios < 7: reduced_symbols = config.symbols[:-1] - data_config = config.data.revalidated_copy(update={"symbols": reduced_symbols}) + reduced_instruments = [ + instrument + for instrument in config.data.instruments + if instrument.symbol in reduced_symbols + ] + data_config = config.data.revalidated_copy( + update={"instruments": reduced_instruments} + ) reduced_config = config.revalidated_copy(update={"data": data_config}) required_symbols = set(reduced_symbols) if config.benchmark_symbol is not None: @@ -129,7 +365,466 @@ def run_stress_tests(data: pd.DataFrame, config: ExperimentConfig) -> pd.DataFra risk_free_rate, ) ) + completed_scenarios += 1 + _checkpoint() + if on_progress is not None: + on_progress(completed_scenarios, total_scenarios) + + if checkpoint_path is not None: + clear_checkpoint(checkpoint_path) + return pd.DataFrame(rows, columns=_STRESS_COLUMNS) + + +def stress_test_checkpoint_paths(checkpoint_path: Path) -> tuple[Path, ...]: + """Return every on-disk checkpoint file a stress-test run can create. + + ``run_walk_forward_stress_tests`` writes a second, nested file for its + weight-cache build (see its own docstring) alongside the main + scenario-block checkpoint at ``checkpoint_path`` -- a caller discarding + "all saved progress" (the CLI's ``--fresh``) must clear every one of + these, not just the main file, or the nested cache can silently survive + and be reused on the next run. The single source of truth for this + derivation, reused by :func:`run_walk_forward_stress_tests` itself so + the two can never drift apart. + """ + return ( + checkpoint_path, + checkpoint_path.with_name(checkpoint_path.stem + "_cache.pkl"), + ) + + +def run_walk_forward_stress_tests( + data: pd.DataFrame, + config: ExperimentConfig, + wf_baseline: WalkForwardResult, + *, + on_progress: Callable[[int, int], None] | None = None, + checkpoint_path: Path | None = None, +) -> pd.DataFrame: + """Re-run the whole walk-forward process under cost/delay/universe stress. + + Unlike :func:`run_stress_tests`, every scenario except "best 10 days + removed" re-evaluates parameter selection under the scenario's + perturbation instead of a single plain backtest — so a Walk-forward + mode's Robustness numbers never silently come from a different + validation method than the one currently in effect. + + The three cost-only scenarios ("commission x2", "commission x5", + "slippage x2") never change signals or portfolio allocation — only the + accounting step depends on execution costs — so they share a single + :class:`~quantlab.validation.walk_forward.WalkForwardWeightCache` built + once from the baseline config, cheaply re-scoring each fold's cached + candidates under the new costs via + :meth:`~quantlab.validation.walk_forward.WalkForwardValidator. + rescore_with_costs` instead of re-running signal generation and + allocation three more times. "Execution delay +1" and "reduced + universe" genuinely change the weights themselves (the delay shift and + the tradable universe respectively), so they still re-execute + :class:`~quantlab.validation.walk_forward.WalkForwardValidator` end to + end. "Best 10 days removed" stays a post-hoc transform of the + already-realised baseline OOS returns: it changes no configuration, so + re-running walk-forward would only waste time reproducing the exact + same selection. + + Args: + data: Canonical long OHLCV frame. + config: The baseline experiment config (``validation.method`` must + be ``"walk_forward"``). + wf_baseline: The already-computed baseline ``WalkForwardResult``, + reused for "baseline" and "best 10 days removed". + on_progress: Optional callback invoked as ``on_progress(done, total)`` + once before any work starts and once after each unit of work + completes: one tick per candidate (folds x grid size) while the + weight cache used by the three cost-only scenarios is + (re)built — the bulk of the total cost — then one tick per + remaining scenario ("execution delay +1" and "reduced universe" + are each a full walk-forward run; the three cost-only rescores + and "best 10 days removed" are + cheap). + checkpoint_path: Optional path to persist progress to, so an + interrupted run resumes instead of starting over — at the + scenario-block level (baseline / [cache-build + the 3 cost-only + rescores] / execution-delay+1 / best-10-days / reduced-universe) + for this function's own progress, plus a separate, nested + checkpoint for the cache-build block specifically (passed + through to :meth:`~quantlab.validation.walk_forward. + WalkForwardValidator.run_with_weight_cache`), since that block is + the expensive one and the whole point of the weight-cache + optimisation is not to have to redo it. See + ``quantlab.validation.checkpoint``. + """ + from quantlab.validation.parameter_grid import parameter_grid_for_config + from quantlab.validation.walk_forward import ( + WalkForwardValidator, + resolve_walk_forward_windows, + ) + + if not isinstance(data, pd.DataFrame): + raise TypeError("data must be a pandas DataFrame.") + if not isinstance(config, ExperimentConfig): + raise TypeError("config must be an ExperimentConfig.") + if SYMBOL not in data.columns: + raise ValueError(f"data must contain a {SYMBOL!r} column.") + if wf_baseline.oos_result is None: + raise ValueError( + "wf_baseline has no OOS result — no fold fit its windows, so " + "there is nothing to stress-test against." + ) + # wf_baseline must actually describe `data`/`config` -- otherwise every + # scenario below (built from `config`, some sharing wf_baseline's own + # cached weights via rescore_with_costs) would silently perturb a + # baseline that doesn't correspond to this run at all. + baseline_config = wf_baseline.oos_result.config + if baseline_config.model_dump(mode="json") != config.model_dump(mode="json"): + raise ValueError( + "wf_baseline was not built from `config`: its own attached " + "config differs from the config passed to this call." + ) + # Required, not merely checked-when-present: a baseline with no recorded + # data_hash at all is not "unverifiable, proceed anyway" -- it is + # exactly the case this check exists to catch, so it must refuse the + # same as a genuine mismatch would. + baseline_data_hash = wf_baseline.oos_result.metadata.get("data_hash") + if baseline_data_hash is None: + raise ValueError( + "wf_baseline was not built from `data`: its own metadata has no " + "recorded data_hash, so it cannot be verified against this " + "call's data." + ) + from quantlab.data.storage import ParquetStorage + + if baseline_data_hash != ParquetStorage.hash_frame(data): + raise ValueError( + "wf_baseline was not built from `data`: its own recorded " + "data_hash differs from this data's hash." + ) + periods_per_year = positive_int(config.periods_per_year, name="periods_per_year") + risk_free_rate = finite_real(config.risk_free_rate, name="risk_free_rate") + train_window, validation_window, test_window = resolve_walk_forward_windows(config) + expanding = config.validation.expanding + grid = parameter_grid_for_config(config) + + # `config`'s own equality with `baseline_config` (checked above) does + # NOT by itself guarantee these were the grid/windows/expanding + # actually used to build `wf_baseline`: a caller can build it with an + # explicit grid/windows that diverge from what `config` alone would + # derive (WalkForwardValidator.run() accepts them as independent + # arguments, not solely inferred from config). Every scenario below + # reuses this recomputed grid/windows, including via wf_baseline's own + # cached candidate weights (rescore_with_costs) -- comparing a baseline + # built under one methodology against scenarios re-derived under a + # silently different one would be methodologically incoherent, so this + # must be verified explicitly rather than assumed from config alone. + baseline_windows = wf_baseline.oos_result.metadata.get("walk_forward_windows") + expected_windows = { + "train_window": train_window, + "validation_window": validation_window, + "test_window": test_window, + "expanding": expanding, + } + if baseline_windows != expected_windows: + raise ValueError( + "wf_baseline was not built with this call's own train/" + "validation/test windows or expanding setting: its own recorded " + f"walk_forward_windows {baseline_windows!r} does not match " + f"{expected_windows!r} derived from `config`." + ) + baseline_grid = wf_baseline.oos_result.metadata.get("walk_forward_parameter_grid") + if baseline_grid != grid: + raise ValueError( + "wf_baseline was not built with this call's own parameter grid: " + f"its own recorded walk_forward_parameter_grid {baseline_grid!r} " + f"does not match {grid!r} derived from `config`." + ) + # The "execution delay +1" scenario below is only meaningful relative to + # a zero-delay baseline; a baseline already run with a non-zero delay + # would need "+1" to mean "one more than the baseline's own", not a + # hardcoded absolute 1. + baseline_delay = wf_baseline.oos_result.metadata.get("walk_forward_execution_delay") + if baseline_delay != 0: + raise ValueError( + "wf_baseline was not built with execution_delay=0: its own " + f"recorded walk_forward_execution_delay is {baseline_delay!r}, " + "so this call's 'execution delay +1' scenario cannot be " + "compared against it." + ) + + def _run_walk_forward( + scenario_config: ExperimentConfig, + scenario_data: pd.DataFrame, + scenario_grid: dict[str, list[object]], + *, + execution_delay: int = 0, + ) -> WalkForwardResult: + return WalkForwardValidator(scenario_config).run( + scenario_data, + parameter_grid=scenario_grid, + train_window=train_window, + validation_window=validation_window, + test_window=test_window, + expanding=expanding, + execution_delay=execution_delay, + ) + + cost_scenarios = { + "commission x2": scale_costs(config, commission_mult=2.0), + "commission x5": scale_costs(config, commission_mult=5.0), + "slippage x2": scale_costs(config, slippage_mult=2.0), + } + reduced_universe = len(config.symbols) > 2 + n_baseline_folds = len(wf_baseline.folds) + n_combinations = math.prod(len(values) for values in grid.values()) if grid else 1 + n_cache_units = n_baseline_folds * n_combinations + total_units = ( + n_cache_units + len(cost_scenarios) + 2 + (1 if reduced_universe else 0) + ) + + def _cache_progress(done: int, _total: int) -> None: + if on_progress is not None: + on_progress(done, total_units) + + # Scenario-block-level checkpoint (own file): baseline / [cache-build + + # the 3 cost-only rescores, as one block] / execution-delay+1 / + # best-10-days / reduced-universe. `rows` is the only state that needs + # to survive between blocks — every block computes from `config`/`data`/ + # `wf_baseline`, already covered by `provenance`, not from a prior + # block's output. + rows: list[dict[str, object]] = [] + provenance: dict[str, Any] | None = None + cache_checkpoint_path: Path | None = None + completed_blocks = 0 + total_blocks = 4 + (1 if reduced_universe else 0) + + def _expected_block_row_count(progress: int) -> int: + """Return exactly how many rows each block count has appended. + + Block 1 ("baseline") appends 1 row; block 2 appends one row per + cost-only scenario (``len(cost_scenarios)`` = 3: commission x2, + commission x5, slippage x2); blocks 3-5 ("execution delay +1", + "best 10 days removed", "reduced universe") each append exactly 1. + Not a simple linear formula in ``progress`` alone, but still fully + determined by it -- there is no ambiguity to fall back to a mere + upper bound for. + """ + if progress <= 0: + return 0 + if progress == 1: + return 1 + if progress == 2: + return 1 + len(cost_scenarios) + return 1 + len(cost_scenarios) + (progress - 2) + + # The exact scenario name each row must have, in order -- not just how + # many rows there should be. Fixed by the block structure above: + # baseline, then the 3 cost-only rescores (in `cost_scenarios`' own + # order), then execution delay, best-10-days, and (if applicable) + # reduced universe. + _scenario_names_in_order = [ + "baseline", + *cost_scenarios.keys(), + "execution delay +1", + "best 10 days removed", + "reduced universe", + ] + + def _validate_block_state(state: Any, progress: int) -> bool: + # A structurally-plausible-but-incoherent checkpoint (e.g. + # progress=5 with zero rows, four rows all named "baseline", or a + # row claiming success while carrying NaN metrics) must never be + # resumed from -- it would silently skip every remaining block, + # corrupt the table with duplicated/misnamed scenarios, or return a + # result as if the whole run had succeeded when a scenario actually + # failed. Row count is exactly determined by progress (see + # _expected_block_row_count), so an exact match -- not just an + # upper bound -- is meaningful here, and so is each row's own + # scenario name and order, schema, and status/metrics/error + # consistency (a malformed row would otherwise only surface later, + # as a confusing KeyError deep in table assembly). + if not (0 <= progress <= total_blocks and isinstance(state, list)): + return False + expected_row_count = _expected_block_row_count(progress) + if len(state) != expected_row_count: + return False + if not all( + isinstance(row, dict) and row.keys() == set(_STRESS_COLUMNS) + for row in state + ): + return False + expected_names = _scenario_names_in_order[:expected_row_count] + if [row["scenario"] for row in state] != expected_names: + return False + return all(_stress_row_is_consistent(row) for row in state) + + if checkpoint_path is not None: + provenance = compute_provenance(config, data) + cache_checkpoint_path = stress_test_checkpoint_paths(checkpoint_path)[1] + checkpoint_result = load_checkpoint( + checkpoint_path, provenance, validate=_validate_block_state + ) + if checkpoint_result is not None: + # `progress` (block count) is loaded as-saved, never re-derived + # from `len(rows)`: block 2 alone appends one row per cost + # scenario, so row count and block count diverge -- deriving + # "how many blocks are done" from len(rows) would misjudge that + # and silently skip the blocks after it on resume. + rows, completed_blocks = checkpoint_result + logger.info( + "Resuming walk-forward stress tests from checkpoint: %d/%d " + "scenario blocks already done.", + completed_blocks, + total_blocks, + ) + # Units already behind us for on_progress purposes, seeded from however + # many blocks a resume already found done — block 1 (baseline) isn't + # itself counted in total_units (see its definition above), only 2-5 are. + completed_units = 0 + if completed_blocks >= 2: + completed_units += n_cache_units + len(cost_scenarios) + completed_units += max(0, completed_blocks - 2) + if on_progress is not None and completed_blocks >= 2: + # Otherwise block 2 is about to run (fresh or resumed) and + # run_with_weight_cache() below already emits its own accurate + # first tick via _cache_progress — a seed call here would either + # duplicate its (0, total_units) or, when resuming mid-cache-build, + # jump straight from a stale 0 to whatever candidate it actually + # resumes at. + on_progress(completed_units, total_units) + + def _checkpoint_block() -> None: + if checkpoint_path is not None and provenance is not None: + save_checkpoint(checkpoint_path, provenance, rows, completed_blocks) + + if completed_blocks < 1: + rows.append( + _metrics_row( + "baseline", + wf_baseline.oos_result.returns, + periods_per_year, + risk_free_rate, + ) + ) + completed_blocks += 1 + _checkpoint_block() + + if completed_blocks < 2: + # Signals and portfolio allocation never depend on execution costs, + # so build the per-candidate weight cache once (this is where the + # candidate-level progress reported above comes from — finer-grained + # than one tick per fold, since this build does roughly twice the + # work of a plain walk-forward fold) and reuse it for every + # cost-only scenario below instead of paying for a full re-run each. + # This block gets its own nested checkpoint (see the docstring): + # it's the expensive one, and the whole point of the weight-cache + # optimisation is not having to redo it. + validator = WalkForwardValidator(config) + _, weight_cache = validator.run_with_weight_cache( + data, + parameter_grid=grid, + train_window=train_window, + validation_window=validation_window, + test_window=test_window, + expanding=expanding, + execution_delay=0, + on_progress=_cache_progress, + checkpoint_path=cache_checkpoint_path, + ) + # No separate on_progress call needed here: run_with_weight_cache's + # own ticks (via _cache_progress) already reached completed_units == + # n_cache_units by the time it returns. + completed_units = n_cache_units + + for name, scenario_config in cost_scenarios.items(): + wf = validator.rescore_with_costs(weight_cache, scenario_config) + assert wf.oos_result is not None # same data/windows as the baseline + rows.append( + _metrics_row( + name, wf.oos_result.returns, periods_per_year, risk_free_rate + ) + ) + completed_units += 1 + if on_progress is not None: + on_progress(completed_units, total_units) + completed_blocks += 1 + if cache_checkpoint_path is not None: + clear_checkpoint(cache_checkpoint_path) + _checkpoint_block() + # else: already done on a previous attempt — completed_units was already + # seeded correctly above, nothing left to recompute for this block. + + if completed_blocks < 3: + delayed = _run_walk_forward(config, data, grid, execution_delay=1) + assert delayed.oos_result is not None + rows.append( + _metrics_row( + "execution delay +1", + delayed.oos_result.returns, + periods_per_year, + risk_free_rate, + ) + ) + completed_units += 1 + completed_blocks += 1 + _checkpoint_block() + if on_progress is not None: + on_progress(completed_units, total_units) + + if completed_blocks < 4: + rows.append( + _metrics_row( + "best 10 days removed", + remove_best_days(wf_baseline.oos_result.returns, 10), + periods_per_year, + risk_free_rate, + ) + ) + completed_units += 1 + completed_blocks += 1 + _checkpoint_block() + if on_progress is not None: + on_progress(completed_units, total_units) + + if reduced_universe and completed_blocks < 5: + reduced_symbols = config.symbols[:-1] + reduced_instruments = [ + instrument + for instrument in config.data.instruments + if instrument.symbol in reduced_symbols + ] + data_config = config.data.revalidated_copy( + update={"instruments": reduced_instruments} + ) + reduced_config = config.revalidated_copy(update={"data": data_config}) + required_symbols = set(reduced_symbols) + if config.benchmark_symbol is not None: + required_symbols.add(config.benchmark_symbol) + subset = data[data[SYMBOL].isin(required_symbols)].reset_index(drop=True) + try: + reduced_grid = parameter_grid_for_config(reduced_config) + wf_reduced = _run_walk_forward(reduced_config, subset, reduced_grid) + if wf_reduced.oos_result is None: + raise QuantLabError( + "No walk-forward fold fit the reduced universe's history." + ) + except QuantLabError as exc: + logger.warning("Reduced-universe walk-forward scenario failed: %s", exc) + rows.append(_failed_row("reduced universe", exc)) + else: + rows.append( + _metrics_row( + "reduced universe", + wf_reduced.oos_result.returns, + periods_per_year, + risk_free_rate, + ) + ) + completed_units += 1 + completed_blocks += 1 + _checkpoint_block() + if on_progress is not None: + on_progress(completed_units, total_units) + if checkpoint_path is not None: + clear_checkpoint(checkpoint_path) return pd.DataFrame(rows, columns=_STRESS_COLUMNS) diff --git a/src/quantlab/validation/walk_forward.py b/src/quantlab/validation/walk_forward.py index 5a87f29..153f2a1 100644 --- a/src/quantlab/validation/walk_forward.py +++ b/src/quantlab/validation/walk_forward.py @@ -3,25 +3,48 @@ from __future__ import annotations import itertools +import time from collections.abc import Callable, Mapping, Sequence from dataclasses import dataclass, field -from numbers import Real +from datetime import UTC, datetime +from numbers import Integral, Real +from pathlib import Path from typing import Any import numpy as np import pandas as pd from pydantic import ValidationError -from quantlab.backtesting.accounting import compute_asset_returns, run_accounting +from quantlab.backtesting.accounting import ( + AccountingResult, + compute_asset_returns, + portfolio_metrics_from_accounting, + run_accounting, +) +from quantlab.backtesting.benchmark import build_benchmark +from quantlab.backtesting.engine import ( + _dependency_versions, + _generator_hash, + _git_commit_hash, + _git_is_dirty, + _source_hash, +) +from quantlab.backtesting.result import BacktestResult from quantlab.backtesting.runner import ( build_execution_from_config, build_strategy_from_config, run_backtest_from_config, ) -from quantlab.config import ExperimentConfig +from quantlab.backtesting.trade_log import build_trade_log +from quantlab.config import BenchmarkKind, ExperimentConfig from quantlab.constants import SYMBOL from quantlab.data.base import price_matrix +from quantlab.data.calendar import uniform_calendar +from quantlab.data.closures import DAILY_FREQUENCY, tradable_mask_for +from quantlab.data.storage import ParquetStorage from quantlab.exceptions import InvalidConfigurationError +from quantlab.execution.execution_model import ExecutionModel +from quantlab.execution.orders import shift_respecting_tradability from quantlab.logging_config import get_logger from quantlab.portfolio.rebalancing import ( rebalance_and_cap_turnover, @@ -32,6 +55,12 @@ from quantlab.risk import metrics as M from quantlab.risk._validation import boolean, finite_real, positive_int from quantlab.strategies import strategy_parameter_names +from quantlab.validation.checkpoint import ( + clear_checkpoint, + compute_provenance, + load_checkpoint, + save_checkpoint, +) from quantlab.validation.splits import WalkForwardWindow, walk_forward_windows logger = get_logger(__name__) @@ -65,6 +94,11 @@ class WalkForwardResult: folds: list[FoldResult] = field(default_factory=list) oos_returns: pd.Series = field(default_factory=lambda: pd.Series(dtype=float)) oos_equity: pd.Series = field(default_factory=lambda: pd.Series(dtype=float)) + # A genuine BacktestResult built from the stitched out-of-sample series, + # reusing the same trade-log/benchmark/metrics pipeline as a single + # backtest so existing result-rendering code (dashboard, HTML report) + # works unchanged. `None` only when no fold produced any OOS weights. + oos_result: BacktestResult | None = None def summary_table(self) -> pd.DataFrame: """Return selected parameters and OOS metrics for each fold.""" @@ -118,6 +152,135 @@ def oos_metrics( ) +@dataclass +class _FoldCandidateWeights: + """One candidate's cost-independent weights, cached for one fold. + + ``None`` fields mean this candidate was skipped for insufficient + train/validation warm-up on this fold (mirrors ``_select_on_validation``'s + own skip condition). + """ + + validation_weights: pd.DataFrame | None + test_targets: pd.DataFrame | None + + +def _windows_match(a: WalkForwardWindow, b: WalkForwardWindow) -> bool: + """Compare two windows field-by-field, never via ``==`` directly. + + ``WalkForwardWindow`` is a plain ``@dataclass(frozen=True)`` with + ``pd.DatetimeIndex`` fields -- its auto-generated ``__eq__`` compares + field tuples, and ``DatetimeIndex.__eq__`` returns an element-wise + boolean array rather than a scalar, which raises ``ValueError`` the + moment Python's tuple comparison needs a single bool out of it for any + index longer than one element. ``Index.equals`` is the correct, + scalar-returning comparison for this exact reason. + """ + return ( + a.fold == b.fold + and a.train.equals(b.train) + and a.validation.equals(b.validation) + and a.test.equals(b.test) + ) + + +def _target_frame_is_valid( + target: object, expected_columns: set[str], expected_index: pd.DatetimeIndex +) -> bool: + """Return whether a checkpointed target-weights frame is trustworthy. + + Checks the actual content, not just ``isinstance(target, pd.DataFrame)`` + -- the wrong symbol set, an index that doesn't match this fold's own + window exactly (a corrupted or unrelated checkpoint could carry a + subset, a reordering, or a stray date from a completely different run, + e.g. the year 1900), or a non-finite value would otherwise silently + corrupt the stitched OOS curve. Dtypes are checked as numeric *before* + attempting a float cast, so a frame holding genuinely non-numeric data + (e.g. object/string columns) fails cleanly here rather than raising out + of this check. + """ + if not isinstance(target, pd.DataFrame): + return False + if set(target.columns) != expected_columns: + return False + if not pd.Index(target.index).equals(pd.DatetimeIndex(expected_index)): + return False + if not all(pd.api.types.is_numeric_dtype(dtype) for dtype in target.dtypes): + return False + return bool(np.isfinite(target.to_numpy(dtype=float)).all()) + + +def _candidate_weights_is_valid( + candidate: object, + expected_columns: set[str], + validation_index: pd.DatetimeIndex, + test_index: pd.DatetimeIndex, +) -> bool: + """Return whether a cached candidate's weights are internally consistent. + + ``_FoldCandidateWeights``'s own docstring says ``None`` fields mean this + candidate was skipped (insufficient warm-up) -- both fields must agree + on that: one ``None`` and the other a real DataFrame is not a state + this code ever produces itself, only a corrupted or hand-edited + checkpoint could, and trusting it risks silently mixing a skipped + candidate's missing weights into a scenario that expects them. When both + fields are present, each is checked with the same full-content rigor as + ``_target_frame_is_valid`` (exact symbol set, exact index against this + fold's own validation/test window, finite values) -- a right-shaped but + wrong-content frame (foreign dates, garbage columns, NaNs) is just as + unsafe to resume from as a missing one. + """ + if not isinstance(candidate, _FoldCandidateWeights): + return False + if candidate.validation_weights is None and candidate.test_targets is None: + return True + return _target_frame_is_valid( + candidate.validation_weights, expected_columns, validation_index + ) and _target_frame_is_valid(candidate.test_targets, expected_columns, test_index) + + +@dataclass +class WalkForwardWeightCache: + """Per-fold, per-candidate weights captured while selecting a baseline. + + Signal generation and portfolio allocation never depend on execution + costs (commission/spread/slippage) — only the accounting step does (see + :meth:`WalkForwardValidator.rescore_with_costs`). Built by + :meth:`WalkForwardValidator.run_with_weight_cache`. + """ + + data: pd.DataFrame + combinations: list[dict[str, Any]] + fold_windows: list[WalkForwardWindow] + candidates: list[list[_FoldCandidateWeights]] + grid: Mapping[str, Sequence[Any]] + train_window: int + validation_window: int + test_window: int + expanding: bool + execution_delay: int + #: The config this cache's weights/candidates were actually computed + #: from -- rescore_with_costs() checks a scenario config against this, + #: not just documents the requirement, so a scenario that silently + #: also changes signals/universe/selection (not just execution costs) + #: is rejected instead of producing quietly wrong results from stale + #: cached weights. + base_config: ExperimentConfig + + +def resolve_walk_forward_windows(config: ExperimentConfig) -> tuple[int, int, int]: + """Resolve train/validation/test windows, applying the documented default. + + Shared by the CLI, dashboard and walk-forward-aware robustness/sensitivity + functions so the 500/126/126 fallback lives in exactly one place. + """ + return ( + config.validation.train_window or 500, + config.validation.validation_window or 126, + config.validation.test_window or 126, + ) + + def _with_params(config: ExperimentConfig, params: dict[str, Any]) -> ExperimentConfig: """Return a revalidated config with strategy parameters overridden.""" merged = {**config.strategy.parameters, **params} @@ -130,6 +293,20 @@ def _with_params(config: ExperimentConfig, params: dict[str, Any]) -> Experiment ) from exc +@dataclass +class _PreparedWalkForward: + """Validated inputs shared by run() and run_with_weight_cache().""" + + tradable: pd.DataFrame + windows: list[WalkForwardWindow] + combinations: list[dict[str, Any]] + periods_per_year: int + risk_free_rate: float + scorer: Callable[[pd.Series, pd.Series, int, float], float] + grid: dict[str, Sequence[Any]] + delay: int + + class WalkForwardValidator: """Select parameters on validation blocks and evaluate them OOS.""" @@ -147,8 +324,585 @@ def run( test_window: int, *, expanding: bool = True, + execution_delay: int = 0, + on_progress: Callable[[int, int], None] | None = None, + checkpoint_path: Path | None = None, + ) -> WalkForwardResult: + """Execute chronological parameter selection and OOS accounting. + + Args: + data: Canonical long OHLCV frame. + parameter_grid: Candidate values per strategy parameter to select + on each fold's validation block. + train_window: Training periods per fold. + validation_window: Validation periods per fold, used for + parameter selection. + test_window: Out-of-sample test periods per fold. + expanding: Grow the training window across folds instead of + sliding it. + on_progress: Optional callback invoked as ``on_progress(done, + total)`` once before the first candidate (``done=0``, or the + resumed count if ``checkpoint_path`` supplied a partial run) + and once after each candidate is considered plus once more + after each fold's out-of-sample weights are computed — + ``total`` being folds x (grid size + 1), matching + ``estimate_walk_forward_backtest_count`` — for a caller (e.g. + the dashboard) to drive a live progress bar instead of + estimating a duration upfront. One tick per whole fold was + too coarse in practice: a fold's own grid search can take + long enough that a caller's pace estimate had too few, too + lumpy data points to track a real, sustained slowdown across + an expanding walk-forward's later, bigger folds. + execution_delay: Extra periods of execution delay applied to both + validation-block parameter selection and the final + out-of-sample weights (the "acting on stale signals" stress + scenario, re-run through the whole selection process rather + than only rescaling the final numbers). + checkpoint_path: Optional path to persist per-fold progress to, + so an interrupted run resumes from its last completed fold + instead of starting over. Silently ignored (fresh start) if + nothing valid is there yet; automatically cleared once this + call completes. See ``quantlab.validation.checkpoint``. + """ + started = time.perf_counter() + expanding = boolean(expanding, name="expanding") + prepared = self._prepare( + data, + parameter_grid, + train_window, + validation_window, + test_window, + expanding=expanding, + execution_delay=execution_delay, + ) + + fold_windows: list[WalkForwardWindow] = [] + fold_parameters: list[dict[str, Any]] = [] + fold_scores: list[float] = [] + target_pieces: list[pd.DataFrame] = [] + + provenance: dict[str, Any] | None = None + + def _validate_fold_state(state: Any, progress: int) -> bool: + # A structurally-plausible-but-incoherent checkpoint (right + # list count, wrong content) must never be resumed from: e.g. a + # `progress` that disagrees with the lists' own length, windows + # left over from a *different* run whose windows happen to + # share this one's length, or a target frame surviving from a + # completely different fold. Content, not just count, is + # checked -- windows must exactly match this run's own + # `prepared.windows` prefix, in order. The whole body is + # wrapped defensively: a checkpoint's *content* is untrusted + # data by definition (it can be replaced or hand-edited on + # disk), so any unexpected shape while inspecting it -- not + # only a failed check -- must resolve to "untrusted", the same + # philosophy `_read_payload` already applies to a malformed + # pickle, never propagate an exception into the caller. + try: + if not (isinstance(state, tuple) and len(state) == 4): + return False + windows, parameters, scores, targets = state + if not all(isinstance(piece, list) for piece in state): + return False + lengths = {len(piece) for piece in state} + if len(lengths) != 1: + return False + count = lengths.pop() + if not (progress == count <= len(prepared.windows)): + return False + if not all( + isinstance(window, WalkForwardWindow) + and _windows_match(window, prepared.windows[position]) + for position, window in enumerate(windows) + ): + return False + # `params in prepared.combinations` (not just + # isinstance(dict)): a parameter dict that isn't actually + # one of this run's own grid candidates could only have + # come from a stale or unrelated checkpoint. + if not all(params in prepared.combinations for params in parameters): + return False + if not all( + isinstance(score, (int, float)) + and not isinstance(score, bool) + and np.isfinite(score) + for score in scores + ): + return False + # A target frame's own columns/index/values matter here, not + # just its Python type -- the wrong symbol set, dates + # outside this fold's own test window (e.g. a stray 1900 + # timestamp), or a non-finite value would otherwise silently + # corrupt the stitched OOS curve. + symbols = set(self.base_config.symbols) + return all( + _target_frame_is_valid(target, symbols, window.test) + for target, window in zip(targets, windows, strict=True) + ) + except Exception: + return False + + if checkpoint_path is not None: + provenance = compute_provenance( + self.base_config, + data, + train_window=train_window, + validation_window=validation_window, + test_window=test_window, + expanding=expanding, + execution_delay=execution_delay, + parameter_grid={k: list(v) for k, v in parameter_grid.items()}, + ) + checkpoint_result = load_checkpoint( + checkpoint_path, provenance, validate=_validate_fold_state + ) + if checkpoint_result is not None: + (fold_windows, fold_parameters, fold_scores, target_pieces), _ = ( + checkpoint_result + ) + logger.info( + "Resuming walk-forward from checkpoint: %d/%d folds already done.", + len(fold_windows), + len(prepared.windows), + ) + resumed_folds = len(fold_windows) + + # One tick per candidate considered plus one for the fold's final + # out-of-sample weights, not one tick per whole fold: see the + # on_progress docstring above for why the coarser version made a + # caller's live pace estimate too imprecise. + total_units = len(prepared.windows) * (len(prepared.combinations) + 1) + units_done = resumed_folds * (len(prepared.combinations) + 1) + if on_progress is not None: + on_progress(units_done, total_units) + + def _tick() -> None: + nonlocal units_done + units_done += 1 + if on_progress is not None: + on_progress(units_done, total_units) + + for window in prepared.windows[resumed_folds:]: + best = self._select_on_validation( + data, + window, + prepared.combinations, + prepared.scorer, + prepared.periods_per_year, + prepared.risk_free_rate, + execution_delay=prepared.delay, + on_candidate=_tick, + ) + targets = self._weights_on_test(data, window, best["params"]) + fold_windows.append(window) + fold_parameters.append(best["params"]) + fold_scores.append(best["score"]) + _tick() + target_pieces.append(targets) + if checkpoint_path is not None and provenance is not None: + save_checkpoint( + checkpoint_path, + provenance, + (fold_windows, fold_parameters, fold_scores, target_pieces), + len(fold_windows), + ) + + result = self._finalize( + fold_windows, + fold_parameters, + fold_scores, + target_pieces, + prepared.tradable, + data, + self.base_config, + prepared.periods_per_year, + prepared.risk_free_rate, + prepared.delay, + prepared.grid, + train_window, + validation_window, + test_window, + expanding, + started, + ) + if checkpoint_path is not None: + clear_checkpoint(checkpoint_path) + return result + + def run_with_weight_cache( + self, + data: pd.DataFrame, + parameter_grid: Mapping[str, Sequence[Any]], + train_window: int, + validation_window: int, + test_window: int, + *, + expanding: bool = True, + execution_delay: int = 0, + on_progress: Callable[[int, int], None] | None = None, + checkpoint_path: Path | None = None, + ) -> tuple[WalkForwardResult, WalkForwardWeightCache]: + """Like :meth:`run`, but also return a cache of per-candidate weights. + + Signal generation and portfolio allocation never depend on execution + costs, so a scenario that only rescales commission/spread/slippage + can reuse the returned cache via :meth:`rescore_with_costs` instead + of paying for a full walk-forward re-run. Building the cache + computes out-of-sample target weights for every candidate on every + fold (not only each fold's winner, since a different candidate can + win once costs change), so this method itself costs somewhat more + than :meth:`run` — the saving comes from amortising that extra cost + across every cost-only scenario that reuses the cache instead of + paying for a full re-run each. + + Args: as :meth:`run`, except ``on_progress`` is reported per + candidate evaluated (``total`` = folds x candidates) rather than + per fold, since this method does roughly twice the work of + :meth:`run` per fold. ``checkpoint_path``, if given, checkpoints + per fold (a fold's cached candidates are only ever used or + dropped as a whole) — an interruption while this cache is being + built resumes at the right fold instead of recomputing it from + scratch, which matters here specifically because building it is + the expensive part the cost-only stress scenarios are meant to + amortise. + """ + started = time.perf_counter() + expanding = boolean(expanding, name="expanding") + prepared = self._prepare( + data, + parameter_grid, + train_window, + validation_window, + test_window, + expanding=expanding, + execution_delay=execution_delay, + ) + + fold_windows: list[WalkForwardWindow] = [] + fold_parameters: list[dict[str, Any]] = [] + fold_scores: list[float] = [] + target_pieces: list[pd.DataFrame] = [] + cached_candidates: list[list[_FoldCandidateWeights]] = [] + + provenance: dict[str, Any] | None = None + + def _validate_cache_fold_state(state: Any, progress: int) -> bool: + # Same reasoning as the plain run()'s _validate_fold_state + # (including the defensive try/except -- checkpoint content is + # untrusted data by definition), for this method's own 5-list + # state shape (it additionally caches every candidate's + # test-block weights, not just the winner's). + try: + if not (isinstance(state, tuple) and len(state) == 5): + return False + windows, parameters, scores, targets, cached = state + if not all(isinstance(piece, list) for piece in state): + return False + lengths = {len(piece) for piece in state} + if len(lengths) != 1: + return False + count = lengths.pop() + if not (progress == count <= len(prepared.windows)): + return False + if not all( + isinstance(window, WalkForwardWindow) + and _windows_match(window, prepared.windows[position]) + for position, window in enumerate(windows) + ): + return False + if not all(params in prepared.combinations for params in parameters): + return False + if not all( + isinstance(score, (int, float)) + and not isinstance(score, bool) + and np.isfinite(score) + for score in scores + ): + return False + symbols = set(self.base_config.symbols) + if not all( + _target_frame_is_valid(target, symbols, window.test) + for target, window in zip(targets, windows, strict=True) + ): + return False + # Every fold's cache must hold exactly one entry per + # candidate in this run's own grid -- a mismatched count + # means it was built against a different (or + # since-changed) parameter_grid. + return all( + isinstance(fold_cache, list) + and len(fold_cache) == len(prepared.combinations) + and all( + _candidate_weights_is_valid( + candidate, symbols, window.validation, window.test + ) + for candidate in fold_cache + ) + for window, fold_cache in zip(windows, cached, strict=True) + ) + except Exception: + return False + + if checkpoint_path is not None: + provenance = compute_provenance( + self.base_config, + data, + train_window=train_window, + validation_window=validation_window, + test_window=test_window, + expanding=expanding, + execution_delay=execution_delay, + parameter_grid={k: list(v) for k, v in parameter_grid.items()}, + ) + checkpoint_result = load_checkpoint( + checkpoint_path, provenance, validate=_validate_cache_fold_state + ) + if checkpoint_result is not None: + ( + ( + fold_windows, + fold_parameters, + fold_scores, + target_pieces, + cached_candidates, + ), + _, + ) = checkpoint_result + logger.info( + "Resuming weight-cache build from checkpoint: %d/%d folds " + "already done.", + len(fold_windows), + len(prepared.windows), + ) + resumed_folds = len(fold_windows) + + # Reported per candidate evaluated, not per fold: this method does + # roughly twice the work of run() per fold (it also captures every + # candidate's test-block targets, not only the winner's), so + # fold-level ticks alone could go a long time between updates — + # especially with few folds — and look stalled to a caller like the + # dashboard's progress bar. + total_candidates = len(prepared.windows) * len(prepared.combinations) + candidates_done = resumed_folds * len(prepared.combinations) + if on_progress is not None: + on_progress(candidates_done, total_candidates) + for window in prepared.windows[resumed_folds:]: + + def _tick() -> None: + nonlocal candidates_done + candidates_done += 1 + if on_progress is not None: + on_progress(candidates_done, total_candidates) + + best_index, score, captured = self._select_and_capture( + data, + window, + prepared.combinations, + prepared.scorer, + prepared.periods_per_year, + prepared.risk_free_rate, + execution_delay=prepared.delay, + on_candidate=_tick, + ) + fold_windows.append(window) + fold_parameters.append(prepared.combinations[best_index]) + fold_scores.append(score) + cached_candidates.append(captured) + test_targets = captured[best_index].test_targets + assert test_targets is not None + target_pieces.append(test_targets) + if checkpoint_path is not None and provenance is not None: + save_checkpoint( + checkpoint_path, + provenance, + ( + fold_windows, + fold_parameters, + fold_scores, + target_pieces, + cached_candidates, + ), + len(fold_windows), + ) + + result = self._finalize( + fold_windows, + fold_parameters, + fold_scores, + target_pieces, + prepared.tradable, + data, + self.base_config, + prepared.periods_per_year, + prepared.risk_free_rate, + prepared.delay, + prepared.grid, + train_window, + validation_window, + test_window, + expanding, + started, + ) + cache = WalkForwardWeightCache( + data=data, + combinations=prepared.combinations, + fold_windows=fold_windows, + candidates=cached_candidates, + grid=prepared.grid, + train_window=train_window, + validation_window=validation_window, + test_window=test_window, + expanding=expanding, + execution_delay=prepared.delay, + base_config=self.base_config, + ) + if checkpoint_path is not None: + clear_checkpoint(checkpoint_path) + return result, cache + + def rescore_with_costs( + self, + cache: WalkForwardWeightCache, + scenario_config: ExperimentConfig, ) -> WalkForwardResult: - """Execute chronological parameter selection and OOS accounting.""" + """Cheaply re-score a cost-only scenario against a cached baseline. + + For every cached candidate on every fold, this re-runs only the + accounting step under ``scenario_config``'s execution model — never + the signal/allocation computation that produced the cached weights + — to re-select each fold's winner, which can differ from the + original selection since a stressed cost can change which candidate + scores best. It then stitches the out-of-sample series exactly as + :meth:`run` would from a fresh full re-run. + + Only valid when ``scenario_config`` differs from the config that + built ``cache`` in execution-cost fields (commission/spread/ + slippage). Anything that would change signals, weights, the + tradable universe or execution delay needs a fresh :meth:`run` or + :meth:`run_with_weight_cache` instead -- enforced below, not just + documented: a mismatch on any other field raises rather than + silently rescoring against stale cached weights that don't actually + reflect what the scenario claims to be. + + Raises: + InvalidConfigurationError: If ``scenario_config`` differs from + ``cache.base_config`` outside the ``execution`` section. + """ + base_dump = cache.base_config.model_dump(mode="json") + scenario_dump = scenario_config.model_dump(mode="json") + base_dump.pop("execution", None) + scenario_dump.pop("execution", None) + if base_dump != scenario_dump: + raise InvalidConfigurationError( + "rescore_with_costs() requires scenario_config to match the " + "config that built cache in every respect except execution " + "costs (commission/spread/slippage/slippage_model/" + "impact_coefficient) -- this scenario also changes something " + "that could change signals, weights, the tradable universe " + "or selection. Use run() or run_with_weight_cache() instead." + ) + + started = time.perf_counter() + periods_per_year = positive_int( + scenario_config.periods_per_year, name="periods_per_year" + ) + risk_free_rate = finite_real( + scenario_config.backtest.risk_free_rate, name="risk_free_rate" + ) + metric = scenario_config.validation.optimization_metric + try: + scorer = _SCORERS[metric] + except KeyError as exc: + raise InvalidConfigurationError( + f"Unsupported walk-forward optimization metric: {metric!r}." + ) from exc + + tradable = cache.data[cache.data[SYMBOL].isin(set(scenario_config.symbols))] + fold_parameters: list[dict[str, Any]] = [] + fold_scores: list[float] = [] + target_pieces: list[pd.DataFrame] = [] + for window, row in zip(cache.fold_windows, cache.candidates, strict=True): + sliced = _slice_between(cache.data, window.train[0], window.validation[-1]) + fold_tradable = sliced[sliced[SYMBOL].isin(set(scenario_config.symbols))] + prices = price_matrix(fold_tradable, adjusted=True) + asset_returns = compute_asset_returns(prices).loc[ + window.validation[0] : window.validation[-1] + ] + execution_model = build_execution_from_config(scenario_config, sliced) + tradable_mask = _tradable_mask_if_mixed_calendar( + scenario_config, pd.DatetimeIndex(asset_returns.index) + ) + + best_score = -np.inf + best_index: int | None = None + for index, candidate in enumerate(row): + if candidate.validation_weights is None: + continue + aligned_tradable = ( + tradable_mask.reindex( + index=candidate.validation_weights.index, + columns=candidate.validation_weights.columns, + ).fillna(True) + if tradable_mask is not None + else None + ) + accounting = run_accounting( + candidate.validation_weights, + asset_returns, + execution_model, + scenario_config.initial_capital, + tradable=aligned_tradable, + ) + equity = M.equity_from_returns(accounting.net_returns) + score = scorer( + accounting.net_returns, equity, periods_per_year, risk_free_rate + ) + if np.isfinite(score) and score > best_score: + best_score = score + best_index = index + if best_index is None: + raise InvalidConfigurationError( + f"Fold {window.fold}: every cached parameter combination " + "produced a non-finite validation score under this " + "scenario's execution costs." + ) + fold_parameters.append(cache.combinations[best_index]) + fold_scores.append(best_score) + test_targets = row[best_index].test_targets + assert test_targets is not None + target_pieces.append(test_targets) + + return self._finalize( + cache.fold_windows, + fold_parameters, + fold_scores, + target_pieces, + tradable, + cache.data, + scenario_config, + periods_per_year, + risk_free_rate, + cache.execution_delay, + cache.grid, + cache.train_window, + cache.validation_window, + cache.test_window, + cache.expanding, + started, + ) + + def _prepare( + self, + data: pd.DataFrame, + parameter_grid: Mapping[str, Sequence[Any]], + train_window: int, + validation_window: int, + test_window: int, + *, + expanding: bool, + execution_delay: int, + ) -> _PreparedWalkForward: + """Validate inputs and compute what run() and run_with_weight_cache() share.""" if not isinstance(data, pd.DataFrame): raise TypeError("data must be a pandas DataFrame.") required_columns = {"timestamp", SYMBOL} @@ -157,7 +911,17 @@ def run( raise InvalidConfigurationError( f"data is missing required columns: {sorted(missing_columns)}." ) - expanding = boolean(expanding, name="expanding") + if isinstance(execution_delay, bool) or not isinstance( + execution_delay, Integral + ): + raise InvalidConfigurationError( + "execution_delay must be a non-negative integer." + ) + if execution_delay < 0: + raise InvalidConfigurationError( + "execution_delay must be a non-negative integer." + ) + delay = int(execution_delay) grid = _validate_parameter_grid(parameter_grid, self.base_config.strategy_name) # A benchmark can have a different calendar, so folds follow only the @@ -202,26 +966,45 @@ def run( raise InvalidConfigurationError( f"Unsupported walk-forward optimization metric: {metric!r}." ) from exc + return _PreparedWalkForward( + tradable=tradable, + windows=windows, + combinations=combinations, + periods_per_year=periods_per_year, + risk_free_rate=risk_free_rate, + scorer=scorer, + grid=grid, + delay=delay, + ) - fold_windows: list[WalkForwardWindow] = [] - fold_parameters: list[dict[str, Any]] = [] - fold_scores: list[float] = [] - target_pieces: list[pd.DataFrame] = [] - for window in windows: - best = self._select_on_validation( - data, - window, - combinations, - scorer, - periods_per_year, - risk_free_rate, - ) - targets = self._weights_on_test(data, window, best["params"]) - fold_windows.append(window) - fold_parameters.append(best["params"]) - fold_scores.append(best["score"]) - target_pieces.append(targets) + def _finalize( + self, + fold_windows: list[WalkForwardWindow], + fold_parameters: list[dict[str, Any]], + fold_scores: list[float], + target_pieces: list[pd.DataFrame], + tradable: pd.DataFrame, + data: pd.DataFrame, + active_config: ExperimentConfig, + periods_per_year: int, + risk_free_rate: float, + delay: int, + grid: Mapping[str, Sequence[Any]], + train_window: int, + validation_window: int, + test_window: int, + expanding: bool, + started: float, + ) -> WalkForwardResult: + """Stitch fold selections into OOS accounting and a WalkForwardResult. + Shared by every selection path (:meth:`run`, + :meth:`run_with_weight_cache`, :meth:`rescore_with_costs`) so + rebalancing/turnover-capping, delay-shifting and final accounting + run identically regardless of which one produced the winners, using + whichever config (``active_config``) is actually in effect for the + scenario being finalised. + """ # Applying rebalancing, turnover and accounting once preserves state # and transaction costs across fold boundaries. if target_pieces: @@ -232,15 +1015,25 @@ def run( "Walk-forward test blocks overlap; duplicate target dates: " f"{list(duplicates[:5])}." ) + tradable_mask = _tradable_mask_if_mixed_calendar( + active_config, pd.DatetimeIndex(all_targets.index) + ) + shared_calendar = uniform_calendar( + instrument.calendar for instrument in active_config.data.instruments + ) all_weights = rebalance_and_cap_turnover( - all_targets, self.base_config.portfolio + all_targets, + active_config.portfolio, + tradable=tradable_mask, + calendar=shared_calendar, ) # A target chosen on a rebalance bar becomes the executed position # on the following bar. schedule = compute_rebalance_dates( pd.DatetimeIndex(all_weights.index), - self.base_config.portfolio.rebalance_frequency, + active_config.portfolio.rebalance_frequency, + calendar=shared_calendar, ) aligned_starts: list[pd.Timestamp] = [] for window in fold_windows: @@ -270,18 +1063,58 @@ def run( prices = price_matrix(tradable, adjusted=True) asset_returns = compute_asset_returns(prices).reindex(all_weights.index) - execution_model = build_execution_from_config(self.base_config, data) + execution_model = build_execution_from_config(active_config, data) + aligned_tradable_mask = ( + tradable_mask.reindex( + index=all_weights.index, columns=all_weights.columns + ).fillna(True) + if tradable_mask is not None + else None + ) + executed_weights = all_weights + if delay > 0: + if aligned_tradable_mask is not None: + # A raw row-count shift would delay execution onto a + # date a symbol can't actually trade on -- same bug the + # mandatory look-ahead-barrier shift inside + # run_accounting avoids, so the extra configured delay + # must avoid it too. + executed_weights = shift_respecting_tradability( + executed_weights, delay, aligned_tradable_mask + ).fillna(0.0) + else: + executed_weights = executed_weights.shift(delay).fillna(0.0) accounting = run_accounting( - all_weights, + executed_weights, asset_returns, execution_model, - self.base_config.initial_capital, + active_config.initial_capital, + tradable=aligned_tradable_mask, ) oos_returns = accounting.net_returns oos_equity = accounting.equity + oos_result = self._build_oos_result( + data, + tradable, + active_config, + accounting, + execution_model, + all_weights, + all_targets, + periods_per_year, + risk_free_rate, + delay, + started, + grid, + train_window, + validation_window, + test_window, + expanding, + ) else: oos_returns = pd.Series(dtype=float) oos_equity = pd.Series(dtype=float) + oos_result = None aligned_starts = [] fold_results: list[FoldResult] = [] @@ -319,7 +1152,159 @@ def run( fold_sharpe, ) - return WalkForwardResult(fold_results, oos_returns, oos_equity) + return WalkForwardResult(fold_results, oos_returns, oos_equity, oos_result) + + def _build_oos_result( + self, + data: pd.DataFrame, + tradable: pd.DataFrame, + active_config: ExperimentConfig, + accounting: AccountingResult, + execution_model: ExecutionModel, + all_weights: pd.DataFrame, + all_targets: pd.DataFrame, + periods_per_year: int, + risk_free_rate: float, + delay: int, + started: float, + grid: Mapping[str, Sequence[Any]], + train_window: int, + validation_window: int, + test_window: int, + expanding: bool, + ) -> BacktestResult: + """Build a genuine BacktestResult from the stitched OOS series. + + Reuses the exact trade-log/benchmark/metrics pipeline + :class:`~quantlab.backtesting.engine.BacktestEngine` uses for a + single backtest, so existing result-rendering code (dashboard, HTML + report) works unchanged on a walk-forward's out-of-sample result. + ``active_config`` is the config actually in effect for this result + (``self.base_config`` from :meth:`run`/:meth:`run_with_weight_cache`, + or a cost-scenario config from :meth:`rescore_with_costs`), so its + cost fields and metadata describe what was actually run. + """ + trades = build_trade_log( + accounting.executed_weights, + accounting.weight_changes, + accounting.equity, + price_matrix(tradable, adjusted=False), + commission_bps=active_config.commission_bps, + spread_bps=active_config.spread_bps, + slippage_model=execution_model.slippage, + slippage_equity=accounting.equity_for_costs, + ) + benchmark_data = ( + data if active_config.benchmark_kind is BenchmarkKind.SYMBOL else tradable + ) + benchmark_returns = build_benchmark( + benchmark_data, + pd.DatetimeIndex(accounting.net_returns.index), + benchmark_symbol=active_config.benchmark_symbol, + benchmark_calendar=active_config.benchmark_calendar, + first_asset_symbol=active_config.symbols[0], + risk_free_rate=risk_free_rate, + periods_per_year=periods_per_year, + kind=str(active_config.benchmark_kind), + ) + metrics = M.compute_metrics( + accounting.net_returns, + accounting.equity, + benchmark_returns=benchmark_returns, + risk_free_rate=risk_free_rate, + periods_per_year=periods_per_year, + ) + metrics.update(portfolio_metrics_from_accounting(accounting, periods_per_year)) + metrics["number_of_trades"] = float(len(trades)) + metrics["average_trade_size"] = ( + float(trades["traded_notional"].mean()) if len(trades) else 0.0 + ) + metrics["total_cost_fraction"] = float(accounting.costs.total.sum()) + + metadata: dict[str, Any] = { + "run_timestamp": datetime.now(UTC).isoformat(), + "experiment_name": active_config.experiment_name, + "strategy": active_config.strategy_name, + "allocator": active_config.portfolio.allocator, + "commission_bps": active_config.commission_bps, + "spread_bps": active_config.spread_bps, + "symbols": active_config.symbols, + "start_date": str(active_config.start_date), + "end_date": str(active_config.end_date), + "random_seed": active_config.random_seed, + "n_rows": len(accounting.net_returns), + "elapsed_seconds": round(time.perf_counter() - started, 4), + "periods_per_year": periods_per_year, + "data_hash": ParquetStorage.hash_frame(data), + "git_commit": _git_commit_hash(), + "git_dirty": _git_is_dirty(), + "dependency_versions": _dependency_versions(), + "code_hash": _source_hash(), + "generator_hash": _generator_hash(), + "walk_forward_execution_delay": delay, + # Unlike BacktestEngine.run() (docs/api.md documents passing it + # a custom strategy/allocator/execution-model instance directly, + # see its own config_yaml_reflects_*), WalkForwardValidator never + # accepts one: every component is always built via + # build_strategy_from_config/build_allocator_from_config/ + # build_execution_from_config(active_config, ...), so there is + # no possible mismatch to verify here -- these are unconditional + # facts about this code path, not a best-effort check. Without + # them, the HTML report's footer (which requires all three + # config_yaml_reflects_* keys) would treat every walk-forward + # result as unverified and never claim reproducibility, even + # though it always is. + "config_yaml_reflects_strategy": True, + "config_yaml_reflects_allocator": True, + "config_yaml_reflects_execution": True, + # `metrics` (below) *are* the out-of-sample metrics — this result + # is the stitched OOS series, not a full-sample fit. Mirrored + # into metadata under this exact key because + # `research_summary._oos_metrics()` and the HTML report's + # methodology/hypothesis/conclusion text look for it there to + # decide whether to describe evidence as out-of-sample; without + # it, a genuinely-OOS walk-forward result was mislabelled + # "full-sample only, no out-of-sample evidence attached". + "walk_forward_oos_metrics": metrics, + "walk_forward_parameter_grid": dict(grid), + "walk_forward_windows": { + "train_window": train_window, + "validation_window": validation_window, + "test_window": test_window, + "expanding": expanding, + }, + } + # Mirrored under these exact keys because + # `load_previous_walk_forward_robustness` (quantlab.backtesting. + # result) compares them to decide whether a later `quantlab report` + # can reuse this bundle's CSVs. Setting them here, not in any one + # CLI command, means every caller of this method gets them for free + # -- `bootstrap`/`stress-test`/`permutation-test`/`sensitivity` in + # walk-forward mode all save this exact `metadata` dict via `result + # IS wf.oos_result`, without routing through the dedicated + # `walk-forward` command's own code, so a per-command setter would + # leave `report` unable to recognise a still-valid bundle any of + # those other commands had just saved, and delete it. + metadata["walk_forward_config_snapshot"] = active_config.model_dump(mode="json") + metadata["walk_forward_run_timestamp"] = metadata["run_timestamp"] + + return BacktestResult( + config=active_config, + equity_curve=accounting.equity, + returns=accounting.net_returns, + benchmark_returns=benchmark_returns, + positions=accounting.executed_weights, + weights=all_weights, + target_weights=all_targets, + signals=pd.DataFrame(), + trades=trades, + costs=accounting.costs.to_frame(), + metrics=metrics, + metadata=metadata, + gross_returns=accounting.gross_returns, + gross_equity=accounting.gross_equity, + turnover=accounting.turnover, + ) def _select_on_validation( self, @@ -329,8 +1314,17 @@ def _select_on_validation( scorer: Callable[[pd.Series, pd.Series, int, float], float], periods_per_year: int, risk_free_rate: float, + *, + execution_delay: int = 0, + on_candidate: Callable[[], None] | None = None, ) -> dict[str, Any]: - """Select the finite, highest-scoring parameter combination.""" + """Select the finite, highest-scoring parameter combination. + + ``on_candidate``, if given, is called once after each candidate is + considered (including ones skipped for insufficient warm-up), for + finer-grained progress reporting than one tick per fold — see + :meth:`_select_and_capture`, which does the same. + """ best_score = -np.inf best_parameters: dict[str, Any] | None = None insufficient_warmup = 0 @@ -349,6 +1343,8 @@ def _select_on_validation( available, required, ) + if on_candidate is not None: + on_candidate() continue returns = _evaluate_fresh_from_window_start( data, @@ -356,9 +1352,12 @@ def _select_on_validation( window.train[0], window.validation[0], window.validation[-1], + execution_delay=execution_delay, ) equity = M.equity_from_returns(returns) score = scorer(returns, equity, periods_per_year, risk_free_rate) + if on_candidate is not None: + on_candidate() if np.isfinite(score) and score > best_score: best_score = score best_parameters = combination @@ -376,6 +1375,86 @@ def _select_on_validation( ) return {"params": best_parameters, "score": float(best_score)} + def _select_and_capture( + self, + data: pd.DataFrame, + window: WalkForwardWindow, + combinations: list[dict[str, Any]], + scorer: Callable[[pd.Series, pd.Series, int, float], float], + periods_per_year: int, + risk_free_rate: float, + *, + execution_delay: int = 0, + on_candidate: Callable[[], None] | None = None, + ) -> tuple[int, float, list[_FoldCandidateWeights]]: + """Capture every candidate's weights alongside selection. + + Like :meth:`_select_on_validation`, but also captures every + candidate's weights into a :class:`WalkForwardWeightCache` row. + Test-block target weights are computed for every candidate, not + only the fold's winner, since a different candidate can win once a + cost-only scenario re-scores this fold with + :meth:`rescore_with_costs`. ``on_candidate``, if given, is called + once after each candidate is considered (including ones skipped for + insufficient warm-up), for finer-grained progress reporting than + one tick per fold. + """ + best_score = -np.inf + best_index: int | None = None + insufficient_warmup = 0 + captured: list[_FoldCandidateWeights] = [] + for index, combination in enumerate(combinations): + config = _with_params(self.base_config, combination) + required = _minimum_observations_for_executable_weight(config) + available = len(window.train) + len(window.validation) + if len(window.validation) < 2 or available < required: + insufficient_warmup += 1 + logger.debug( + "Fold %d: skipping %s because validation ends after %d " + "observations but this configuration needs at least %d " + "before an executable weight can be scored.", + window.fold, + combination, + available, + required, + ) + captured.append(_FoldCandidateWeights(None, None)) + if on_candidate is not None: + on_candidate() + continue + validation_weights, returns = _weights_and_returns_for_validation( + data, + config, + window.train[0], + window.validation[0], + window.validation[-1], + execution_delay=execution_delay, + ) + equity = M.equity_from_returns(returns) + score = scorer(returns, equity, periods_per_year, risk_free_rate) + test_targets = _target_weights_for_window( + data, config, window.train[0], window.test[0], window.test[-1] + ) + captured.append(_FoldCandidateWeights(validation_weights, test_targets)) + if on_candidate is not None: + on_candidate() + if np.isfinite(score) and score > best_score: + best_score = score + best_index = index + if best_index is None: + if combinations and insufficient_warmup == len(combinations): + raise InvalidConfigurationError( + f"Fold {window.fold}: no parameter combination has enough " + "train/validation history to produce an executable weight " + "inside the validation block. Increase the windows or use " + "shorter strategy warm-up parameters." + ) + raise InvalidConfigurationError( + f"Fold {window.fold}: every parameter combination produced a " + "non-finite validation score." + ) + return best_index, float(best_score), captured + def _weights_on_test( self, data: pd.DataFrame, window: WalkForwardWindow, params: dict[str, Any] ) -> pd.DataFrame: @@ -446,6 +1525,29 @@ def _grid_combinations( ] +def _tradable_mask_if_mixed_calendar( + config: ExperimentConfig, index: pd.DatetimeIndex +) -> pd.DataFrame | None: + """Per-symbol tradability mask, only when a raw shift could be wrong. + + ``None`` when every instrument shares one calendar (a raw shift is + already exactly correct, no closure can occur) or the frequency isn't + daily (closure semantics are only well-defined at daily granularity, see + :mod:`quantlab.data.closures`). Shared by every accounting call site + (fold-level candidate scoring, cost-only rescoring, final OOS stitching) + so parameter *selection* is never scored under a different execution + timing than the *finalised* result it selects for. + """ + if config.data.frequency != DAILY_FREQUENCY: + return None + symbol_calendars = { + instrument.symbol: instrument.calendar for instrument in config.data.instruments + } + if uniform_calendar(symbol_calendars.values()) is not None: + return None + return tradable_mask_for(index, config.symbols, symbol_calendars) + + def _slice_between( data: pd.DataFrame, start: pd.Timestamp, end: pd.Timestamp ) -> pd.DataFrame: @@ -461,10 +1563,12 @@ def _weights_for_window( lookback_start: pd.Timestamp, window_start: pd.Timestamp, window_end: pd.Timestamp, + *, + execution_delay: int = 0, ) -> pd.DataFrame: """Return held weights after supplying the required lookback history.""" sliced = _slice_between(data, lookback_start, window_end) - result = run_backtest_from_config(sliced, config) + result = run_backtest_from_config(sliced, config, execution_delay=execution_delay) return result.weights.loc[window_start:window_end] @@ -483,26 +1587,73 @@ def _target_weights_for_window( return result.target_weights.loc[window_start:window_end] -def _evaluate_fresh_from_window_start( +def _weights_and_returns_for_validation( data: pd.DataFrame, config: ExperimentConfig, lookback_start: pd.Timestamp, window_start: pd.Timestamp, window_end: pd.Timestamp, -) -> pd.Series: - """Return independently accounted net returns for candidate scoring.""" + *, + execution_delay: int = 0, +) -> tuple[pd.DataFrame, pd.Series]: + """Return one candidate's (held weights, net returns) on a block. + + Split out of the former ``_evaluate_fresh_from_window_start`` so + ``WalkForwardValidator._select_and_capture`` can retain the weights + instead of discarding them, without duplicating this accounting logic. + """ sliced = _slice_between(data, lookback_start, window_end) window_weights = _weights_for_window( - data, config, lookback_start, window_start, window_end + data, + config, + lookback_start, + window_start, + window_end, + execution_delay=execution_delay, ) tradable = sliced[sliced[SYMBOL].isin(set(config.symbols))] prices = price_matrix(tradable, adjusted=True) asset_returns = compute_asset_returns(prices).loc[window_start:window_end] execution_model = build_execution_from_config(config, sliced) + tradable_mask = _tradable_mask_if_mixed_calendar( + config, pd.DatetimeIndex(window_weights.index) + ) + aligned_tradable = ( + tradable_mask.reindex( + index=window_weights.index, columns=window_weights.columns + ).fillna(True) + if tradable_mask is not None + else None + ) accounting = run_accounting( - window_weights, asset_returns, execution_model, config.initial_capital + window_weights, + asset_returns, + execution_model, + config.initial_capital, + tradable=aligned_tradable, + ) + return window_weights, accounting.net_returns + + +def _evaluate_fresh_from_window_start( + data: pd.DataFrame, + config: ExperimentConfig, + lookback_start: pd.Timestamp, + window_start: pd.Timestamp, + window_end: pd.Timestamp, + *, + execution_delay: int = 0, +) -> pd.Series: + """Return independently accounted net returns for candidate scoring.""" + _, net_returns = _weights_and_returns_for_validation( + data, + config, + lookback_start, + window_start, + window_end, + execution_delay=execution_delay, ) - return accounting.net_returns + return net_returns def _minimum_observations_for_executable_weight(config: ExperimentConfig) -> int: diff --git a/tests/conftest.py b/tests/conftest.py index 2f65b86..3e3b0f6 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -111,13 +111,15 @@ def sample_config() -> ExperimentConfig: { "experiment_name": "unit_test_experiment", "data": { - "source": "csv", - "symbols": ["AAA", "BBB", "CCC"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + {"symbol": "BBB", "source": "csv", "calendar": "XNYS"}, + {"symbol": "CCC", "source": "csv", "calendar": "XNYS"}, + ], "start_date": date(2020, 1, 1), "end_date": date(2021, 8, 1), "frequency": "1d", "missing_value_policy": "drop", - "market_calendar": "XNYS", }, "strategy": {"name": "buy_and_hold", "parameters": {}}, "portfolio": { @@ -132,7 +134,7 @@ def sample_config() -> ExperimentConfig: }, "backtest": { "initial_capital": 100_000.0, - "benchmark_symbol": "AAA", + "benchmark": {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, "risk_free_rate": 0.0, "periods_per_year": 252, }, diff --git a/tests/integration/test_backtest_pipeline.py b/tests/integration/test_backtest_pipeline.py index d797a58..2c61425 100644 --- a/tests/integration/test_backtest_pipeline.py +++ b/tests/integration/test_backtest_pipeline.py @@ -34,11 +34,12 @@ def _config(strategy: dict, allocator: str = "equal_weight") -> ExperimentConfig { "experiment_name": "integration", "data": { - "source": "csv", - "symbols": ["AAA", "BBB", "CCC"], + "instruments": [ + {"symbol": s, "source": "csv", "calendar": "XNYS"} + for s in ["AAA", "BBB", "CCC"] + ], "start_date": "2019-01-01", "end_date": "2021-06-01", - "market_calendar": "XNYS", }, "strategy": strategy, "portfolio": { @@ -54,7 +55,7 @@ def _config(strategy: dict, allocator: str = "equal_weight") -> ExperimentConfig }, "backtest": { "initial_capital": 100_000, - "benchmark_symbol": "AAA", + "benchmark": {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, "risk_free_rate": 0.02, "periods_per_year": 252, }, @@ -127,6 +128,303 @@ def test_reproducible_same_inputs() -> None: assert r1.metrics["sharpe_ratio"] == r2.metrics["sharpe_ratio"] +def test_direct_api_custom_execution_model_is_the_single_source_of_truth() -> None: + """docs/api.md recommends using BacktestEngine directly to supply a + custom execution-model instance. A config declaring 2 bps commission, + run instead with a custom ExecutionModel at 100 bps, must have its + equity curve, trade log and metadata/report all describe the *actual* + 100 bps model, never a mix where accounting charges 100 bps but the + trade log or the report still claim the YAML's 2 bps.""" + from quantlab.execution.costs import CommissionModel, SpreadModel + from quantlab.execution.slippage import ConstantSlippageModel + from quantlab.reporting.research_summary import methodology + + data = _panel() + cfg = _config({"name": "buy_and_hold"}) + assert cfg.commission_bps == 2.0 # confirms the YAML/actual values differ + + custom_model = ExecutionModel( + commission=CommissionModel(100.0), + spread=SpreadModel(50.0), + slippage=ConstantSlippageModel(5.0), + ) + result = BacktestEngine().run( + data, + BuyAndHoldStrategy(), + EqualWeightAllocator(), + custom_model, + cfg, + ) + + # Metadata must record the actual model, not the YAML's. + assert result.metadata["commission_bps"] == 100.0 + assert result.metadata["spread_bps"] == 50.0 + assert result.metadata["slippage_bps"] == 5.0 + + # The trade log's own per-fill commission must match: on any date with + # a real fill, commission = traded_notional * 100bps/10_000, not + # 2bps/10_000. + filled = result.trades.loc[result.trades["traded_notional"] > 0] + assert len(filled) > 0 + implied_bps = (filled["commission"] / filled["traded_notional"]) * 10_000 + assert implied_bps.round(6).unique().tolist() == [100.0] + + # The report's methodology text must describe the actual model too. + text = methodology(result) + assert "commission 100.0 bps" in text + assert "50.0 bps full quoted spread" in text + assert "constant slippage 5.0 bps" in text + assert "2.0 bps" not in text + + +def test_direct_api_records_the_actual_strategy_parameters_used() -> None: + """config.yaml in a saved bundle is still whatever config the caller + happened to pass alongside a custom strategy object -- it can declare + lookback_period=252 while the strategy actually used was built with + lookback_period=10. metadata must record the real, effective value and + flag that config.yaml doesn't reflect it, rather than leaving the only + persisted record of "what ran" silently wrong.""" + from quantlab.strategies.mean_reversion import MeanReversionStrategy + + data = _panel() + cfg = _config({"name": "mean_reversion", "parameters": {"lookback_period": 252}}) + assert cfg.strategy.parameters["lookback_period"] == 252 + + mismatched = BacktestEngine().run( + data, + MeanReversionStrategy(lookback_period=10), + EqualWeightAllocator(), + ExecutionModel.from_config(cfg.execution), + cfg, + ) + assert mismatched.metadata["strategy_parameters"]["lookback_period"] == 10 + assert mismatched.metadata["config_yaml_reflects_strategy"] is False + + matching = BacktestEngine().run( + data, + MeanReversionStrategy(lookback_period=252), + EqualWeightAllocator(), + ExecutionModel.from_config(cfg.execution), + cfg, + ) + assert matching.metadata["strategy_parameters"]["lookback_period"] == 252 + assert matching.metadata["config_yaml_reflects_strategy"] is True + + +def test_direct_api_catches_a_mismatch_on_an_undeclared_default_parameter() -> None: + """config.yaml can omit a parameter entirely, leaving it at the + strategy's own constructor default (20 for mean_reversion's + lookback_period) -- comparing only *declared* config keys would never + even examine lookback_period here, silently missing a mismatch on the + exact parameter the config never mentions.""" + from quantlab.strategies.mean_reversion import MeanReversionStrategy + + data = _panel() + cfg = _config({"name": "mean_reversion", "parameters": {}}) + assert "lookback_period" not in cfg.strategy.parameters + + mismatched = BacktestEngine().run( + data, + MeanReversionStrategy(lookback_period=10), + EqualWeightAllocator(), + ExecutionModel.from_config(cfg.execution), + cfg, + ) + assert mismatched.metadata["config_yaml_reflects_strategy"] is False + + matching = BacktestEngine().run( + data, + MeanReversionStrategy(lookback_period=20), # the constructor's own default + EqualWeightAllocator(), + ExecutionModel.from_config(cfg.execution), + cfg, + ) + assert matching.metadata["config_yaml_reflects_strategy"] is True + + +def test_direct_api_records_whether_config_yaml_reflects_the_allocator() -> None: + """Same guarantee as config_yaml_reflects_strategy, for the allocator: a + custom allocator instance can silently diverge from config.yaml's own + portfolio.allocator settings.""" + from quantlab.portfolio.allocator import InverseVolatilityAllocator + from quantlab.strategies.buy_and_hold import BuyAndHoldStrategy + + data = _panel() + # _config's own defaults: maximum_weight=0.6, volatility_window=40, + # backtest.periods_per_year=252. + cfg = _config({"name": "buy_and_hold"}, allocator="inverse_volatility") + + mismatched = BacktestEngine().run( + data, + BuyAndHoldStrategy(), + InverseVolatilityAllocator( + volatility_window=10, maximum_weight=0.6, periods_per_year=252 + ), + ExecutionModel.from_config(cfg.execution), + cfg, + ) + assert mismatched.metadata["config_yaml_reflects_allocator"] is False + + matching = BacktestEngine().run( + data, + BuyAndHoldStrategy(), + InverseVolatilityAllocator( + volatility_window=40, maximum_weight=0.6, periods_per_year=252 + ), + ExecutionModel.from_config(cfg.execution), + cfg, + ) + assert matching.metadata["config_yaml_reflects_allocator"] is True + + +def test_direct_api_records_whether_config_yaml_reflects_execution() -> None: + """Same guarantee as config_yaml_reflects_strategy/_allocator, for the + execution model: a config declaring 2 bps commission, run instead with a + custom ExecutionModel at 100 bps, must have config_yaml_reflects_execution + report False -- and the HTML report's footer (see + test_reporting_hardening.py) must not claim reproducibility from + config.yaml when only this one of the three flags is false.""" + from quantlab.execution.costs import CommissionModel, SpreadModel + from quantlab.execution.slippage import ConstantSlippageModel + from quantlab.strategies.buy_and_hold import BuyAndHoldStrategy + + data = _panel() + cfg = _config({"name": "buy_and_hold"}) + assert cfg.commission_bps == 2.0 + + mismatched = BacktestEngine().run( + data, + BuyAndHoldStrategy(), + EqualWeightAllocator(), + ExecutionModel( + commission=CommissionModel(100.0), + spread=SpreadModel(50.0), + slippage=ConstantSlippageModel(5.0), + ), + cfg, + ) + assert mismatched.metadata["commission_bps"] == 100.0 + assert mismatched.metadata["config_yaml_reflects_execution"] is False + # The other two components are untouched and still built correctly. + assert mismatched.metadata["config_yaml_reflects_strategy"] is True + assert mismatched.metadata["config_yaml_reflects_allocator"] is True + + matching = BacktestEngine().run( + data, + BuyAndHoldStrategy(), + EqualWeightAllocator(), + ExecutionModel.from_config(cfg.execution), + cfg, + ) + assert matching.metadata["config_yaml_reflects_execution"] is True + + +def test_config_yaml_reflects_strategy_catches_a_behavior_overriding_subclass() -> None: + """A strategy subclass that overrides behaviour (here: always stays in + cash) without changing any constructor parameter is indistinguishable + from its base class by parameter comparison alone, or by an + `isinstance` check, or by `.name` (a class attribute the subclass + inherits unchanged) -- only exact class identity catches it.""" + from quantlab.strategies.buy_and_hold import BuyAndHoldStrategy + + class NeverBuys(BuyAndHoldStrategy): + def generate_signals( + self, data: pd.DataFrame, features: pd.DataFrame | None = None + ) -> pd.DataFrame: + return super().generate_signals(data, features) * 0.0 + + data = _panel() + cfg = _config({"name": "buy_and_hold"}) + + result = BacktestEngine().run( + data, + NeverBuys(), + EqualWeightAllocator(), + ExecutionModel.from_config(cfg.execution), + cfg, + ) + assert result.metadata["config_yaml_reflects_strategy"] is False + + +def test_config_yaml_reflects_allocator_catches_a_behavior_overriding_subclass() -> ( + None +): + """Same guarantee as the strategy case, for the allocator.""" + from quantlab.strategies.buy_and_hold import BuyAndHoldStrategy + + class AlwaysZeroAllocator(EqualWeightAllocator): + def allocate(self, signals, data): # type: ignore[no-untyped-def] + return super().allocate(signals, data) * 0.0 + + data = _panel() + cfg = _config({"name": "buy_and_hold"}) + + result = BacktestEngine().run( + data, + BuyAndHoldStrategy(), + AlwaysZeroAllocator(), + ExecutionModel.from_config(cfg.execution), + cfg, + ) + assert result.metadata["config_yaml_reflects_allocator"] is False + + +def test_config_yaml_reflects_execution_catches_a_commission_subclass() -> None: + """A commission subclass that overrides the actual cost calculation + while still reporting the same `commission_bps` value is + indistinguishable by the numeric comparison alone -- only exact class + identity (`commission_class`) catches it.""" + from quantlab.execution.costs import CommissionModel, SpreadModel + from quantlab.execution.slippage import ConstantSlippageModel + from quantlab.strategies.buy_and_hold import BuyAndHoldStrategy + + class FreeCommission(CommissionModel): + def calculate(self, traded_notional: pd.DataFrame) -> pd.Series: + return super().calculate(traded_notional) * 0.0 + + data = _panel() + cfg = _config({"name": "buy_and_hold"}) + + result = BacktestEngine().run( + data, + BuyAndHoldStrategy(), + EqualWeightAllocator(), + ExecutionModel( + commission=FreeCommission(cfg.commission_bps), + spread=SpreadModel(cfg.execution.spread_bps), + slippage=ConstantSlippageModel(cfg.execution.slippage_bps), + ), + cfg, + ) + assert result.metadata["config_yaml_reflects_execution"] is False + + +def test_config_yaml_reflects_execution_catches_a_manipulated_volume_adv() -> None: + """Two volume-based slippage models with the same scalar parameters but + a different average_daily_volume must not compare as a match -- the + ADV itself is part of what actually drives the cost, via a deterministic + hash rather than embedding the whole matrix into metadata.json.""" + from quantlab.strategies.buy_and_hold import BuyAndHoldStrategy + + data = _panel() + base = _config({"name": "buy_and_hold"}) + cfg = base.revalidated_copy( + update={ + "execution": base.execution.revalidated_copy( + update={"slippage_model": "volume", "impact_coefficient": 0.1} + ) + } + ) + + manipulated = ExecutionModel.from_config( + cfg.execution, average_daily_volume=999_999.0 + ) + result = BacktestEngine().run( + data, BuyAndHoldStrategy(), EqualWeightAllocator(), manipulated, cfg + ) + assert result.metadata["config_yaml_reflects_execution"] is False + + @pytest.mark.parametrize( "benchmark_kind", ["symbol", "equal_weight", "first_asset", "cash"] ) @@ -135,7 +433,11 @@ def test_all_configured_benchmark_kinds_run_end_to_end(benchmark_kind: str) -> N cfg = _config({"name": "buy_and_hold"}) benchmark_update = { "benchmark_kind": benchmark_kind, - "benchmark_symbol": "AAA" if benchmark_kind == "symbol" else None, + "benchmark": ( + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"} + if benchmark_kind == "symbol" + else None + ), } cfg = cfg.revalidated_copy( update={"backtest": cfg.backtest.revalidated_copy(update=benchmark_update)} @@ -159,7 +461,7 @@ def test_equal_weight_benchmark_ignores_data_outside_configured_universe() -> No cfg = cfg.revalidated_copy( update={ "backtest": cfg.backtest.revalidated_copy( - update={"benchmark_kind": "equal_weight", "benchmark_symbol": None} + update={"benchmark_kind": "equal_weight", "benchmark": None} ) } ) diff --git a/tests/integration/test_cli.py b/tests/integration/test_cli.py index b8e7fb2..9096ac1 100644 --- a/tests/integration/test_cli.py +++ b/tests/integration/test_cli.py @@ -2,8 +2,10 @@ from __future__ import annotations +import json from pathlib import Path +import pandas as pd import pytest import yaml from tests.conftest import geometric_series, make_ohlcv @@ -14,7 +16,22 @@ runner = CliRunner() -def _write_offline_experiment(tmp_path: Path) -> tuple[Path, Path]: +@pytest.fixture(autouse=True) +def isolated_reports_dir(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> Path: + """Isolate every CLI integration test's report output under its own + tmp_path, never the real GENERATED_REPORTS_DIR -- several tests below + share the experiment name "cli_test" and would otherwise leak + checkpoints/results between each other whenever the full suite runs in + one process (each still passes fine in isolation), a known source of + full-suite-only flakiness.""" + path = tmp_path / "reports" + _patch_reports_dir(monkeypatch, path) + return path + + +def _write_offline_experiment( + tmp_path: Path, *, extra: dict | None = None +) -> tuple[Path, Path]: """Create CSV data + a config using the csv source under tmp_path.""" raw = tmp_path / "raw" raw.mkdir() @@ -26,11 +43,13 @@ def _write_offline_experiment(tmp_path: Path) -> tuple[Path, Path]: config = { "experiment_name": "cli_test", "data": { - "source": "csv", - "symbols": ["AAA", "BBB", "CCC"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + {"symbol": "BBB", "source": "csv", "calendar": "XNYS"}, + {"symbol": "CCC", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2019-01-01", "end_date": "2020-12-31", - "market_calendar": "XNYS", }, "strategy": { "name": "cross_sectional_momentum", @@ -42,17 +61,48 @@ def _write_offline_experiment(tmp_path: Path) -> tuple[Path, Path]: }, "portfolio": {"allocator": "inverse_volatility", "maximum_weight": 0.6}, "execution": {"commission_bps": 2.0, "spread_bps": 3.0, "slippage_bps": 2.0}, - "backtest": {"initial_capital": 100000, "benchmark_symbol": "AAA"}, + "backtest": { + "initial_capital": 100000, + "benchmark": {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + }, } + if extra: + config.update(extra) config_path = tmp_path / "cli_test.yaml" config_path.write_text(yaml.safe_dump(config), encoding="utf-8") return config_path, raw +def _write_offline_walk_forward_experiment(tmp_path: Path) -> tuple[Path, Path]: + """A walk-forward-mode config with windows small enough for a fast fold.""" + return _write_offline_experiment( + tmp_path, + extra={ + "validation": { + "method": "walk_forward", + "train_window": 150, + "validation_window": 60, + "test_window": 60, + } + }, + ) + + def test_cli_help() -> None: result = runner.invoke(app, ["--help"]) assert result.exit_code == 0 - for command in ["download", "backtest", "walk-forward", "report", "dashboard"]: + for command in [ + "download", + "backtest", + "walk-forward", + "stress-test", + "bootstrap", + "permutation-test", + "sensitivity", + "robustness", + "report", + "dashboard", + ]: assert command in result.stdout @@ -82,3 +132,724 @@ def test_cli_backtest_bad_config_exits_nonzero(tmp_path: Path) -> None: def test_cli_missing_config_exits_nonzero() -> None: result = runner.invoke(app, ["backtest", "--config", "does_not_exist.yaml"]) assert result.exit_code != 0 + + +def _patch_raw_dir(monkeypatch: pytest.MonkeyPatch, raw: Path) -> None: + import quantlab.data.loader as loader_mod + + monkeypatch.setattr(loader_mod, "RAW_DATA_DIR", raw) + + +def _patch_reports_dir(monkeypatch: pytest.MonkeyPatch, reports_dir: Path) -> None: + import quantlab.cli as cli_module + + monkeypatch.setattr(cli_module, "GENERATED_REPORTS_DIR", reports_dir) + + +def test_cli_stress_test_holdout_mode_saves_scenarios( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch, isolated_reports_dir: Path +) -> None: + config_path, raw = _write_offline_experiment(tmp_path) + _patch_raw_dir(monkeypatch, raw) + + result = runner.invoke(app, ["stress-test", "--config", str(config_path)]) + + assert result.exit_code == 0, result.stdout + exp_dir = isolated_reports_dir / "cli_test" + assert (exp_dir / "stress_tests.csv").is_file() + assert "commission x2" in result.stdout + + +@pytest.mark.slow +def test_cli_stress_test_walk_forward_mode_reruns_selection( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch, isolated_reports_dir: Path +) -> None: + """Walk-forward mode must save walk-forward fold artefacts alongside the + stress table, proving the whole process re-ran (not a plain backtest).""" + config_path, raw = _write_offline_walk_forward_experiment(tmp_path) + _patch_raw_dir(monkeypatch, raw) + + result = runner.invoke(app, ["stress-test", "--config", str(config_path)]) + + assert result.exit_code == 0, result.stdout + exp_dir = isolated_reports_dir / "cli_test" + assert (exp_dir / "stress_tests.csv").is_file() + assert (exp_dir / "walk_forward_results.csv").is_file() + assert (exp_dir / "walk_forward_oos_returns.csv").is_file() + metadata = json.loads((exp_dir / "metadata.json").read_text(encoding="utf-8")) + assert "walk_forward_oos_metrics" in metadata + + +@pytest.mark.slow +def test_cli_walk_forward_resumes_from_a_checkpoint_after_an_interruption( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch, isolated_reports_dir: Path +) -> None: + """An interrupted `walk-forward` invocation must leave a checkpoint that + a later, ordinary re-invocation of the same command picks up — fewer + folds get (re-)selected on than a fresh run would need, proving it + actually resumed instead of starting over.""" + config_path, raw = _write_offline_walk_forward_experiment(tmp_path) + _patch_raw_dir(monkeypatch, raw) + from quantlab.validation.walk_forward import WalkForwardValidator + + exp_dir = isolated_reports_dir / "cli_test" + checkpoint_path = exp_dir / ".checkpoint_walk_forward.pkl" + + real_select = WalkForwardValidator._select_on_validation + starts = {"n": 0} + + def _flaky_select(self, *args, **kwargs): # type: ignore[no-untyped-def] + starts["n"] += 1 + if starts["n"] == 2: + raise RuntimeError("simulated interruption") + return real_select(self, *args, **kwargs) + + monkeypatch.setattr(WalkForwardValidator, "_select_on_validation", _flaky_select) + result = runner.invoke(app, ["walk-forward", "--config", str(config_path)]) + assert result.exit_code != 0 + assert checkpoint_path.is_file() + monkeypatch.undo() + # undo() also reverted these two patches (same monkeypatch instance). + _patch_raw_dir(monkeypatch, raw) + _patch_reports_dir(monkeypatch, isolated_reports_dir) + + # `walk-forward` also runs walk-forward-OOS-aware stress tests after + # fold selection, which re-invoke _select_on_validation of their own for + # scenarios that change signals/weights -- counted per call to + # WalkForwardValidator.run() (the fold-selection step) rather than + # globally, so those later, unrelated re-selections don't dilute what + # this test is actually checking: that the *first* run() call (the one + # resuming from the fold checkpoint) needed fewer than a fresh run's 4. + real_run = WalkForwardValidator.run + calls_per_run: list[int] = [] + + def _counting_select(self, *args, **kwargs): # type: ignore[no-untyped-def] + calls_per_run[-1] += 1 + return real_select2(self, *args, **kwargs) + + def _tracking_run(self, *args, **kwargs): # type: ignore[no-untyped-def] + calls_per_run.append(0) + return real_run(self, *args, **kwargs) + + real_select2 = WalkForwardValidator._select_on_validation + monkeypatch.setattr(WalkForwardValidator, "_select_on_validation", _counting_select) + monkeypatch.setattr(WalkForwardValidator, "run", _tracking_run) + result = runner.invoke(app, ["walk-forward", "--config", str(config_path)]) + assert result.exit_code == 0, result.stdout + assert not checkpoint_path.is_file() + assert calls_per_run[0] < 4 # 4 folds total; at least the 1st was already cached + assert (exp_dir / "walk_forward_results.csv").is_file() + + +@pytest.mark.slow +def test_cli_walk_forward_fresh_flag_discards_an_existing_checkpoint( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch, isolated_reports_dir: Path +) -> None: + config_path, raw = _write_offline_walk_forward_experiment(tmp_path) + _patch_raw_dir(monkeypatch, raw) + from quantlab.validation.walk_forward import WalkForwardValidator + + exp_dir = isolated_reports_dir / "cli_test" + checkpoint_path = exp_dir / ".checkpoint_walk_forward.pkl" + + real_select = WalkForwardValidator._select_on_validation + starts = {"n": 0} + + def _flaky_select(self, *args, **kwargs): # type: ignore[no-untyped-def] + starts["n"] += 1 + if starts["n"] == 2: + raise RuntimeError("simulated interruption") + return real_select(self, *args, **kwargs) + + monkeypatch.setattr(WalkForwardValidator, "_select_on_validation", _flaky_select) + result = runner.invoke(app, ["walk-forward", "--config", str(config_path)]) + assert result.exit_code != 0 + assert checkpoint_path.is_file() + monkeypatch.undo() + # undo() also reverted these two patches (same monkeypatch instance). + _patch_raw_dir(monkeypatch, raw) + _patch_reports_dir(monkeypatch, isolated_reports_dir) + + # See test_cli_walk_forward_resumes_from_a_checkpoint_after_an_interruption + # for why this counts per WalkForwardValidator.run() call rather than + # globally: the walk-forward command's own stress-test step also + # re-invokes _select_on_validation for scenarios that change + # signals/weights, unrelated to whether --fresh discarded the fold + # checkpoint. + real_run = WalkForwardValidator.run + calls_per_run: list[int] = [] + + def _counting_select(self, *args, **kwargs): # type: ignore[no-untyped-def] + calls_per_run[-1] += 1 + return real_select2(self, *args, **kwargs) + + def _tracking_run(self, *args, **kwargs): # type: ignore[no-untyped-def] + calls_per_run.append(0) + return real_run(self, *args, **kwargs) + + real_select2 = WalkForwardValidator._select_on_validation + monkeypatch.setattr(WalkForwardValidator, "_select_on_validation", _counting_select) + monkeypatch.setattr(WalkForwardValidator, "run", _tracking_run) + result = runner.invoke( + app, ["walk-forward", "--config", str(config_path), "--fresh"] + ) + assert result.exit_code == 0, result.stdout + # Every fold recomputed, the stale checkpoint was discarded. + assert calls_per_run[0] == 4 + + +@pytest.mark.slow +def test_cli_walk_forward_fresh_flag_discards_the_nested_stress_cache_checkpoint( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch, isolated_reports_dir: Path +) -> None: + """run_walk_forward_stress_tests() writes a second, nested checkpoint + file for its weight-cache build (.checkpoint_stress_test_cache.pkl) + alongside the main .checkpoint_stress_test.pkl -- --fresh must discard + both, or a stale nested cache from an earlier interrupted run could + silently be reused despite --fresh, contradicting its own documented + "discard any existing checkpoint" guarantee.""" + from quantlab.validation.checkpoint import save_checkpoint + from quantlab.validation.robustness import stress_test_checkpoint_paths + + config_path, raw = _write_offline_walk_forward_experiment(tmp_path) + _patch_raw_dir(monkeypatch, raw) + + exp_dir = isolated_reports_dir / "cli_test" + exp_dir.mkdir(parents=True, exist_ok=True) + stress_checkpoint, nested_cache_checkpoint = stress_test_checkpoint_paths( + exp_dir / ".checkpoint_stress_test.pkl" + ) + # A leftover nested cache from some earlier interrupted stress-test run + # -- content doesn't matter, only that --fresh must remove the file + # unconditionally rather than leave it to be silently picked back up. + save_checkpoint(nested_cache_checkpoint, {"dummy": "provenance"}, [], 0) + assert nested_cache_checkpoint.is_file() + + result = runner.invoke( + app, ["walk-forward", "--config", str(config_path), "--fresh"] + ) + assert result.exit_code == 0, result.stdout + assert not stress_checkpoint.is_file() + assert not nested_cache_checkpoint.is_file() + + +def test_cli_bootstrap_cli_flag_overrides_yaml_n_iterations( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch, isolated_reports_dir: Path +) -> None: + """CLI override > YAML > default: --n-iterations must win over + robustness.bootstrap.n_iterations from the config.""" + config_path, raw = _write_offline_experiment( + tmp_path, extra={"robustness": {"bootstrap": {"n_iterations": 250}}} + ) + _patch_raw_dir(monkeypatch, raw) + + result = runner.invoke( + app, + ["bootstrap", "--config", str(config_path), "--n-iterations", "37"], + ) + + assert result.exit_code == 0, result.stdout + exp_dir = isolated_reports_dir / "cli_test" + summary = (exp_dir / "bootstrap_summary.csv").read_text(encoding="utf-8") + assert summary # a real file was written + + # The saved metadata must record the CLI-overridden value (37), not the + # YAML default (250) -- otherwise a custom run is indistinguishable from + # a standard one when the saved bundle is inspected later. + metadata = json.loads((exp_dir / "metadata.json").read_text(encoding="utf-8")) + assert metadata["bootstrap_run_params"]["n_iterations"] == 37 + + +@pytest.mark.parametrize( + "option", + ["--n-iterations", "--block-size"], +) +@pytest.mark.parametrize("value", ["0", "-1"]) +def test_cli_bootstrap_rejects_non_positive_option_values_before_running( + tmp_path: Path, + monkeypatch: pytest.MonkeyPatch, + isolated_reports_dir: Path, + option: str, + value: str, +) -> None: + """--n-iterations/--block-size must be rejected by Typer's own min=1 + bound at CLI-parsing time -- a bare ValueError from the underlying + positive_int() check is not a QuantLabError, so bootstrap()'s own + `except QuantLabError` would leave it as an unhandled traceback, and + only after data was already loaded and a backtest already run.""" + config_path, raw = _write_offline_experiment(tmp_path) + _patch_raw_dir(monkeypatch, raw) + + result = runner.invoke( + app, ["bootstrap", "--config", str(config_path), option, value] + ) + + assert result.exit_code != 0 + assert "Traceback" not in result.stdout + exp_dir = isolated_reports_dir / "cli_test" + assert not (exp_dir / "bootstrap_summary.csv").is_file() + + +@pytest.mark.parametrize("value", ["0", "-1"]) +def test_cli_permutation_test_rejects_non_positive_n_iterations( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch, value: str +) -> None: + config_path, raw = _write_offline_experiment(tmp_path) + _patch_raw_dir(monkeypatch, raw) + + result = runner.invoke( + app, + ["permutation-test", "--config", str(config_path), "--n-iterations", value], + ) + + assert result.exit_code != 0 + assert "Traceback" not in result.stdout + + +def test_cli_sensitivity_records_the_axes_actually_used( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch, isolated_reports_dir: Path +) -> None: + """CLI-supplied sensitivity axes must be recorded in the saved metadata, + not just used to run the sweep -- otherwise a custom-axis run can't be + distinguished from a robustness.sensitivity.parameters-driven one when + the saved bundle is inspected later.""" + config_path, raw = _write_offline_experiment(tmp_path) + _patch_raw_dir(monkeypatch, raw) + + result = runner.invoke( + app, + [ + "sensitivity", + "--config", + str(config_path), + "--param-x", + "lookback_period", + "--values-x", + "60,100", + "--param-y", + "skip_period", + "--values-y", + "5,10", + ], + ) + + assert result.exit_code == 0, result.stdout + exp_dir = isolated_reports_dir / "cli_test" + metadata = json.loads((exp_dir / "metadata.json").read_text(encoding="utf-8")) + run_params = metadata["sensitivity_run_params"] + assert run_params["parameter_x"] == "lookback_period" + assert run_params["values_x"] == [60, 100] + assert run_params["parameter_y"] == "skip_period" + assert run_params["values_y"] == [5, 10] + + +def test_cli_bootstrap_without_cli_flag_uses_yaml_default( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """Without --n-iterations, robustness.bootstrap.n_iterations from the + YAML must be the one actually used (not the Pydantic 1000 default).""" + config_path, raw = _write_offline_experiment( + tmp_path, extra={"robustness": {"bootstrap": {"n_iterations": 17}}} + ) + _patch_raw_dir(monkeypatch, raw) + + captured: dict[str, object] = {} + import quantlab.cli as cli_module + + original = cli_module._compute_bootstrap + + def spy(cfg: object, result: object, **kwargs: object): # type: ignore[no-untyped-def] + captured["n_iterations"] = kwargs.get("n_iterations") + return original(cfg, result, **kwargs) # type: ignore[arg-type] + + monkeypatch.setattr(cli_module, "_compute_bootstrap", spy) + + result = runner.invoke(app, ["bootstrap", "--config", str(config_path)]) + + assert result.exit_code == 0, result.stdout + assert captured["n_iterations"] is None # CLI flag omitted + + +def test_cli_permutation_test_runs( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch, isolated_reports_dir: Path +) -> None: + config_path, raw = _write_offline_experiment(tmp_path) + _patch_raw_dir(monkeypatch, raw) + + result = runner.invoke(app, ["permutation-test", "--config", str(config_path)]) + + assert result.exit_code == 0, result.stdout + assert "p-value" in result.stdout + exp_dir = isolated_reports_dir / "cli_test" + assert (exp_dir / "permutation_test.csv").is_file() + + +def _pin_provenance_for_reuse(monkeypatch: pytest.MonkeyPatch) -> None: + """Freeze generator_hash and git state so a reuse check depends only on + what the test itself varies (e.g. the config). + + `load_previous_robustness_artifacts` checks generator_hash (not git + state — see its docstring), computed from actual current file contents, + including `cli.py` (unlike the narrower `code_hash`, which deliberately + excludes it). A concurrent edit to any `src/quantlab` file while this + test runs would otherwise change `_generator_hash()` between the two + CLI invocations under test and fail it for a reason unrelated to the + reuse logic being tested. `load_previous_walk_forward_robustness` + (`quantlab.backtesting.result`) additionally refuses reuse whenever + either side reports `git_dirty` -- this checkout's own working tree is + routinely dirty during development, which would otherwise fail any + walk-forward-reuse test for a reason that has nothing to do with the + reuse logic under test either. + + Patches both `quantlab.backtesting.engine`'s own module-level functions + (resolved as bare names by `engine.py`'s own `_build_metadata`, so + patching the module's attributes is enough there) and + `quantlab.validation.walk_forward`'s separately *imported* references + to the same functions (`from ...engine import ...` binds its own names + in that module's namespace -- patching only the origin module would + leave a walk-forward OOS result's own metadata, built by + `_build_oos_result`, using the real, unpinned values). + """ + import quantlab.backtesting.engine as engine_module + import quantlab.validation.walk_forward as walk_forward_module + + for module in (engine_module, walk_forward_module): + monkeypatch.setattr(module, "_generator_hash", lambda: "test-generator-hash") + monkeypatch.setattr(module, "_git_is_dirty", lambda: False) + monkeypatch.setattr(module, "_git_commit_hash", lambda: "test-commit") + + +@pytest.mark.slow +def test_cli_stress_test_then_bootstrap_preserves_both_in_report( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch, isolated_reports_dir: Path +) -> None: + """Running stress-test then bootstrap — two separate CLI invocations — + against the same experiment directory must not delete the first + command's evidence. `result.save()`'s pre-save cleanup removes any + `_OPTIONAL_ARTIFACTS` file the specific call in progress doesn't + re-supply, so without `save_with_robustness_reuse` the second command + would silently wipe out the first's CSV and its report section.""" + config_path, raw = _write_offline_experiment( + tmp_path, extra={"experiment_name": "cli_test_robustness_reuse"} + ) + _patch_raw_dir(monkeypatch, raw) + _pin_provenance_for_reuse(monkeypatch) + + exp_dir = isolated_reports_dir / "cli_test_robustness_reuse" + + stress_result = runner.invoke(app, ["stress-test", "--config", str(config_path)]) + assert stress_result.exit_code == 0, stress_result.stdout + assert (exp_dir / "stress_tests.csv").is_file() + + bootstrap_result = runner.invoke(app, ["bootstrap", "--config", str(config_path)]) + assert bootstrap_result.exit_code == 0, bootstrap_result.stdout + + assert (exp_dir / "bootstrap_summary.csv").is_file() + assert (exp_dir / "stress_tests.csv").is_file() + report_html = (exp_dir / "report.html").read_text(encoding="utf-8") + assert "Stress Tests" in report_html + assert "Bootstrap" in report_html + + +@pytest.mark.slow +def test_cli_report_after_walk_forward_bootstrap_preserves_all_evidence( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch, isolated_reports_dir: Path +) -> None: + """`bootstrap` in walk-forward mode, then `report`: the walk-forward CSVs + and bootstrap's own CSV/run-params must all survive `report`'s save. + + `report` always saves via `save_with_walk_forward_reuse` (never + `save_with_robustness_reuse`, which only the on-demand robustness + commands use), so this exercises a genuinely different code path than + test_cli_stress_test_then_bootstrap_preserves_both_in_report above. + Two invariants must both hold for this to work: `save_with_walk_forward_ + reuse` has to know about bootstrap/permutation/sensitivity CSVs (not + only the walk-forward ones), and the walk-forward OOS result bootstrap + saves has to record walk_forward_config_snapshot/walk_forward_run_ + timestamp -- without which `report` couldn't recognise its own + walk-forward CSVs as reusable and would delete them alongside + everything else it doesn't recognise.""" + config_path, raw = _write_offline_walk_forward_experiment(tmp_path) + _patch_raw_dir(monkeypatch, raw) + _pin_provenance_for_reuse(monkeypatch) + + exp_dir = isolated_reports_dir / "cli_test" + + bootstrap_result = runner.invoke( + app, ["bootstrap", "--config", str(config_path), "--n-iterations", "10"] + ) + assert bootstrap_result.exit_code == 0, bootstrap_result.stdout + assert (exp_dir / "bootstrap_summary.csv").is_file() + assert (exp_dir / "walk_forward_results.csv").is_file() + metadata_after_bootstrap = json.loads( + (exp_dir / "metadata.json").read_text(encoding="utf-8") + ) + assert metadata_after_bootstrap.get("bootstrap_run_params") == { + "n_iterations": 10, + "block_size": metadata_after_bootstrap["bootstrap_run_params"]["block_size"], + } + assert "walk_forward_config_snapshot" in metadata_after_bootstrap + assert "walk_forward_run_timestamp" in metadata_after_bootstrap + + report_result = runner.invoke(app, ["report", "--experiment", "cli_test"]) + assert report_result.exit_code == 0, report_result.stdout + + # Nothing bootstrap saved must have been deleted by report's own save. + assert (exp_dir / "bootstrap_summary.csv").is_file() + assert (exp_dir / "walk_forward_results.csv").is_file() + assert (exp_dir / "walk_forward_oos_returns.csv").is_file() + assert (exp_dir / "walk_forward_oos_equity.csv").is_file() + metadata_after_report = json.loads( + (exp_dir / "metadata.json").read_text(encoding="utf-8") + ) + assert ( + metadata_after_report.get("bootstrap_run_params") + == (metadata_after_bootstrap["bootstrap_run_params"]) + ) + assert "walk_forward_oos_metrics" in metadata_after_report + report_html = (exp_dir / "report.html").read_text(encoding="utf-8") + assert "Bootstrap" in report_html + + +@pytest.mark.slow +def test_cli_bootstrap_does_not_reuse_stress_test_from_a_different_config( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch, isolated_reports_dir: Path +) -> None: + """The reuse in the test above must be provenance-checked, not + unconditional: a stress_tests.csv left by a run under a *different* + config must not silently survive into a bootstrap run under a changed + one. Isolated from this checkout's own git state and source tree (see + `_pin_provenance_for_reuse`) so this specifically exercises the config + check, not an incidental dirty-tree or concurrent-edit refusal.""" + config_path, raw = _write_offline_experiment( + tmp_path, + extra={ + "experiment_name": "cli_test_robustness_reuse_mismatch", + "execution": { + "commission_bps": 2.0, + "spread_bps": 3.0, + "slippage_bps": 2.0, + }, + }, + ) + _patch_raw_dir(monkeypatch, raw) + _pin_provenance_for_reuse(monkeypatch) + + exp_dir = isolated_reports_dir / "cli_test_robustness_reuse_mismatch" + + stress_result = runner.invoke(app, ["stress-test", "--config", str(config_path)]) + assert stress_result.exit_code == 0, stress_result.stdout + assert (exp_dir / "stress_tests.csv").is_file() + + # Change the config in place (same experiment_name/data) rather than + # calling _write_offline_experiment a second time, which would try to + # recreate the same tmp_path/raw directory. + config_data = yaml.safe_load(config_path.read_text(encoding="utf-8")) + config_data["execution"]["commission_bps"] = 25.0 + config_path.write_text(yaml.safe_dump(config_data), encoding="utf-8") + + bootstrap_result = runner.invoke(app, ["bootstrap", "--config", str(config_path)]) + assert bootstrap_result.exit_code == 0, bootstrap_result.stdout + + assert (exp_dir / "bootstrap_summary.csv").is_file() + assert not (exp_dir / "stress_tests.csv").is_file() + + +@pytest.mark.slow +def test_cli_bootstrap_does_not_reuse_a_tampered_stress_test_csv( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch, isolated_reports_dir: Path +) -> None: + """A stress_tests.csv edited (or corrupted) on disk after it was saved + must never be silently reused just because it's still valid CSV -- + load_previous_robustness_artifacts must verify its checksum, not only + that provenance (config/data/code) still matches.""" + config_path, raw = _write_offline_experiment( + tmp_path, extra={"experiment_name": "cli_test_tampered_reuse"} + ) + _patch_raw_dir(monkeypatch, raw) + _pin_provenance_for_reuse(monkeypatch) + + exp_dir = isolated_reports_dir / "cli_test_tampered_reuse" + + stress_result = runner.invoke(app, ["stress-test", "--config", str(config_path)]) + assert stress_result.exit_code == 0, stress_result.stdout + assert (exp_dir / "stress_tests.csv").is_file() + + # Tamper with the file directly, bypassing the checksum that was + # recorded when it was originally saved. + tampered = pd.read_csv(exp_dir / "stress_tests.csv") + tampered.loc[0, "sharpe"] = 999.0 + tampered.to_csv(exp_dir / "stress_tests.csv", index=False) + + bootstrap_result = runner.invoke(app, ["bootstrap", "--config", str(config_path)]) + assert bootstrap_result.exit_code == 0, bootstrap_result.stdout + + assert (exp_dir / "bootstrap_summary.csv").is_file() + # The tampered CSV must not have been reused into this save (it's an + # optional artefact the pre-save cleanup removes when the current call + # doesn't re-supply or successfully recover it). + assert not (exp_dir / "stress_tests.csv").is_file() + report_html = (exp_dir / "report.html").read_text(encoding="utf-8") + assert "Stress Tests" not in report_html + + +def test_cli_sensitivity_requires_axes_from_somewhere(tmp_path: Path) -> None: + config_path, _raw = _write_offline_experiment(tmp_path) + + result = runner.invoke(app, ["sensitivity", "--config", str(config_path)]) + + assert result.exit_code != 0 + # The [ERROR] message goes to stderr; result.output merges both streams. + assert "No sensitivity axes given" in result.output + + +def test_cli_sensitivity_rejects_partial_cli_axes(tmp_path: Path) -> None: + config_path, _raw = _write_offline_experiment(tmp_path) + + result = runner.invoke( + app, + [ + "sensitivity", + "--config", + str(config_path), + "--param-x", + "lookback_period", + ], + ) + + assert result.exit_code != 0 + assert "must all be" in result.output + + +def test_cli_sensitivity_runs_with_cli_axes( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch, isolated_reports_dir: Path +) -> None: + config_path, raw = _write_offline_experiment(tmp_path) + _patch_raw_dir(monkeypatch, raw) + + result = runner.invoke( + app, + [ + "sensitivity", + "--config", + str(config_path), + "--param-x", + "lookback_period", + "--values-x", + "60,100", + "--param-y", + "skip_period", + "--values-y", + "5,10", + ], + ) + + assert result.exit_code == 0, result.stdout + exp_dir = isolated_reports_dir / "cli_test" + assert (exp_dir / "sensitivity.csv").is_file() + + +def test_cli_robustness_orchestrator_runs_only_enabled_techniques( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch, isolated_reports_dir: Path +) -> None: + config_path, raw = _write_offline_experiment( + tmp_path, + extra={ + "robustness": { + "bootstrap": {"enabled": True, "n_iterations": 30}, + "permutation_test": {"enabled": True, "n_iterations": 30}, + } + }, + ) + _patch_raw_dir(monkeypatch, raw) + + result = runner.invoke(app, ["robustness", "--config", str(config_path)]) + + assert result.exit_code == 0, result.stdout + exp_dir = isolated_reports_dir / "cli_test" + assert (exp_dir / "bootstrap_summary.csv").is_file() + assert (exp_dir / "permutation_test.csv").is_file() + # Neither stress tests nor sensitivity were enabled in this config. + assert not (exp_dir / "stress_tests.csv").is_file() + assert not (exp_dir / "sensitivity.csv").is_file() + + +def test_cli_robustness_orchestrator_warns_when_nothing_enabled( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + config_path, raw = _write_offline_experiment(tmp_path) + _patch_raw_dir(monkeypatch, raw) + + result = runner.invoke(app, ["robustness", "--config", str(config_path)]) + + assert result.exit_code == 0, result.stdout + assert "no robustness.* technique is enabled" in result.stdout + + +def test_make_cli_progress_callback_returns_none_when_not_a_tty( + monkeypatch: pytest.MonkeyPatch, +) -> None: + """Piped/redirected output (e.g. CI logs) must not get a + carriage-return-redrawn line — it only makes sense on a real terminal, + and every caller already treats on_progress=None as "don't report".""" + import sys + + import quantlab.cli as cli_module + + monkeypatch.setattr(sys.stdout, "isatty", lambda: False) + assert cli_module._make_cli_progress_callback("Walk-forward") is None + + +def test_make_cli_progress_callback_writes_a_redrawn_line_on_a_tty( + monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str] +) -> None: + import sys + + import quantlab.cli as cli_module + + monkeypatch.setattr(sys.stdout, "isatty", lambda: True) + on_progress = cli_module._make_cli_progress_callback("Walk-forward") + assert on_progress is not None + + on_progress(0, 10) + on_progress(5, 10) + out = capsys.readouterr().out + assert out.count("\r") == 2 + assert "Walk-forward: 5/10" in out + assert not out.endswith("\n") # still in progress, no trailing newline yet + + +def test_make_cli_progress_callback_ends_with_a_newline_on_completion( + monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str] +) -> None: + import sys + + import quantlab.cli as cli_module + + monkeypatch.setattr(sys.stdout, "isatty", lambda: True) + on_progress = cli_module._make_cli_progress_callback("Walk-forward") + assert on_progress is not None + + on_progress(0, 4) + on_progress(4, 4) + out = capsys.readouterr().out + assert out.endswith("\n") + assert "finishing" in out + + +def test_make_cli_progress_callback_flags_a_resumed_run( + monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str] +) -> None: + """A first tick with done > 0 can only mean a checkpoint was resumed — + surfaced in the terminal since nothing else would tell the user.""" + import sys + + import quantlab.cli as cli_module + + monkeypatch.setattr(sys.stdout, "isatty", lambda: True) + on_progress = cli_module._make_cli_progress_callback("Walk-forward") + assert on_progress is not None + + on_progress(3, 10) + out = capsys.readouterr().out + assert "resumed from a previous checkpoint" in out diff --git a/tests/integration/test_data_pipeline.py b/tests/integration/test_data_pipeline.py index b8fddb2..d2ab1e9 100644 --- a/tests/integration/test_data_pipeline.py +++ b/tests/integration/test_data_pipeline.py @@ -29,12 +29,13 @@ def test_csv_to_clean_validated_panel(tmp_path: Path) -> None: { "experiment_name": "data_pipe", "data": { - "source": "csv", - "symbols": ["AAA", "BBB"], + "instruments": [ + {"symbol": s, "source": "csv", "calendar": "XNYS"} + for s in ["AAA", "BBB"] + ], "start_date": "2020-01-01", "end_date": "2020-08-01", "missing_value_policy": "drop", - "market_calendar": "XNYS", }, "strategy": {"name": "buy_and_hold"}, } diff --git a/tests/integration/test_report_generation.py b/tests/integration/test_report_generation.py index a612b09..153230c 100644 --- a/tests/integration/test_report_generation.py +++ b/tests/integration/test_report_generation.py @@ -23,11 +23,12 @@ def _result(tmp_seed: int = 1) -> BacktestResult: { "experiment_name": "report_test", "data": { - "source": "csv", - "symbols": ["SPY", "QQQ", "TLT"], + "instruments": [ + {"symbol": s, "source": "csv", "calendar": "XNYS"} + for s in ["SPY", "QQQ", "TLT"] + ], "start_date": "2019-01-01", "end_date": "2020-12-01", - "market_calendar": "XNYS", }, "strategy": { "name": "cross_sectional_momentum", @@ -43,7 +44,10 @@ def _result(tmp_seed: int = 1) -> BacktestResult: "spread_bps": 3.0, "slippage_bps": 2.0, }, - "backtest": {"initial_capital": 100_000, "benchmark_symbol": "SPY"}, + "backtest": { + "initial_capital": 100_000, + "benchmark": {"symbol": "SPY", "source": "csv", "calendar": "XNYS"}, + }, } ) return run_backtest_from_config(data, cfg) diff --git a/tests/regression_helpers.py b/tests/regression_helpers.py index 6ea59a5..ea3b38f 100644 --- a/tests/regression_helpers.py +++ b/tests/regression_helpers.py @@ -3,6 +3,7 @@ from __future__ import annotations import json +from collections.abc import Iterator, Mapping from pathlib import Path from typing import Any @@ -13,6 +14,24 @@ from tests.conftest import geometric_series, make_ohlcv +class _UniformCalendar(Mapping[str, str]): + """A ``symbol_calendars`` mapping returning the same calendar for every + symbol -- for tests that only care about one calendar and don't want to + enumerate every symbol a frame happens to contain.""" + + def __init__(self, calendar: str) -> None: + self._calendar = calendar + + def __getitem__(self, key: str) -> str: + return self._calendar + + def __iter__(self) -> Iterator[str]: + return iter(()) + + def __len__(self) -> int: + return 0 + + def _holdout_config() -> tuple[pd.DataFrame, ExperimentConfig]: frames = [ make_ohlcv(sym, geometric_series(500, mu=mu, sigma=0.012, s0=100.0, seed=seed)) @@ -27,9 +46,11 @@ def _holdout_config() -> tuple[pd.DataFrame, ExperimentConfig]: { "experiment_name": "holdout_report", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA", "BBB", "CCC"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + {"symbol": "BBB", "source": "csv", "calendar": "XNYS"}, + {"symbol": "CCC", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2021-06-01", }, @@ -63,7 +84,10 @@ def _wf_experiment_config() -> ExperimentConfig: { "experiment_name": "wf_experiment", "data": { - "symbols": ["A", "B"], + "instruments": [ + {"symbol": "A", "source": "yahoo", "calendar": "XNYS"}, + {"symbol": "B", "source": "yahoo", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2021-01-01", }, @@ -78,6 +102,9 @@ def _wf_experiment_config() -> ExperimentConfig: _FAKE_CODE_HASH = "c0defeed" +_FAKE_GENERATOR_HASH = "9ea3a708" + + _FAKE_GIT_COMMIT = "abc1234" @@ -119,6 +146,7 @@ def _write_wf_artifacts(exp_dir: Path, config: ExperimentConfig) -> None: "walk_forward_csv_checksums": checksums, "data_hash": _FAKE_DATA_HASH, "code_hash": _FAKE_CODE_HASH, + "generator_hash": _FAKE_GENERATOR_HASH, "git_commit": _FAKE_GIT_COMMIT, "git_dirty": False, "dependency_versions": _FAKE_DEPENDENCY_VERSIONS, @@ -133,6 +161,7 @@ def __init__(self, config: ExperimentConfig) -> None: self.metadata: dict = { "data_hash": _FAKE_DATA_HASH, "code_hash": _FAKE_CODE_HASH, + "generator_hash": _FAKE_GENERATOR_HASH, "git_commit": _FAKE_GIT_COMMIT, "git_dirty": False, "dependency_versions": _FAKE_DEPENDENCY_VERSIONS, @@ -149,7 +178,10 @@ def _try_strategy( { "experiment_name": "x", "data": { - "symbols": ["A", "B"], + "instruments": [ + {"symbol": "A", "source": "csv", "calendar": "XNYS"}, + {"symbol": "B", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2021-01-01", }, @@ -195,9 +227,10 @@ def _rf_test_setup( { "experiment_name": "rf_consistency", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA", "BBB"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + {"symbol": "BBB", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2021-06-01", }, @@ -240,12 +273,16 @@ def _hourly_symbol_frame(freq: str, periods: int, symbol: str) -> pd.DataFrame: ) -def _market_calendar_config(**data_overrides: Any) -> ExperimentConfig: +def _market_calendar_config( + *, source: str = "csv", calendar: str | None = None, **data_overrides: Any +) -> ExperimentConfig: + instrument: dict[str, Any] = {"symbol": "BTC", "source": source} + if calendar is not None: + instrument["calendar"] = calendar payload: dict[str, Any] = { "experiment_name": "test", "data": { - "source": "csv", - "symbols": ["BTC"], + "instruments": [instrument], "start_date": "2020-01-01", "end_date": "2020-06-01", "frequency": "1h", @@ -293,11 +330,11 @@ def _base_config_dict() -> dict[str, Any]: return { "experiment_name": "test", "data": { - "source": "csv", - "symbols": ["AAA"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2020-06-01", - "market_calendar": "XNYS", }, "strategy": {"name": "buy_and_hold", "parameters": {}}, "portfolio": {"allocator": "equal_weight"}, @@ -343,7 +380,8 @@ def _write_daily_cache( "volume": 100.0, } ) - storage.write_symbol(data, source, symbol, "1d") + calendar = "24/7" if source == "binance" else "XNYS" + storage.write_symbol(data, source, symbol, "1d", calendar=calendar) def _ohlcv_at(dates: pd.DatetimeIndex | list, symbol: str = "SPY") -> pd.DataFrame: diff --git a/tests/unit/test_accounting.py b/tests/unit/test_accounting.py index e114864..70d5967 100644 --- a/tests/unit/test_accounting.py +++ b/tests/unit/test_accounting.py @@ -152,3 +152,38 @@ def test_asset_returns_must_cover_held_weight_axes() -> None: with pytest.raises(BacktestError, match="must cover every"): run_accounting(held, asset_returns, _zero_cost_model(), 100_000.0) + + +def test_tradable_tolerates_a_differently_ordered_frame() -> None: + """`tradable`'s column order need not match `held_weights`' own order -- + only the *set* of dates and symbols must agree.""" + idx = pd.date_range("2024-01-05", periods=3, freq="D") + held = pd.DataFrame({"AAA": [0.5, 0.5, 0.5], "BBB": [0.5, 0.5, 0.5]}, index=idx) + asset_returns = pd.DataFrame( + {"AAA": [0.0, 0.01, -0.01], "BBB": [0.0, 0.02, 0.01]}, index=idx + ) + # Same labels as `held`, deliberately reversed column order. + tradable = pd.DataFrame( + {"BBB": [True, True, True], "AAA": [True, True, True]}, index=idx + ) + + result = run_accounting(held, asset_returns, _zero_cost_model(), 100_000.0) + result_with_mask = run_accounting( + held, asset_returns, _zero_cost_model(), 100_000.0, tradable=tradable + ) + pd.testing.assert_series_equal(result.net_returns, result_with_mask.net_returns) + + +def test_tradable_must_cover_the_same_set_of_symbols_as_held_weights() -> None: + """A genuine set mismatch (not just reordering) must still raise -- + silently defaulting an unrecognized symbol to "tradable" could let it + trade on a date it should have stayed closed.""" + idx = pd.date_range("2024-01-05", periods=2, freq="D") + held = pd.DataFrame({"AAA": [0.5, 0.5], "BBB": [0.5, 0.5]}, index=idx) + asset_returns = pd.DataFrame({"AAA": [0.0, 0.01], "BBB": [0.0, 0.02]}, index=idx) + tradable = pd.DataFrame({"AAA": [True, True]}, index=idx) # missing BBB + + with pytest.raises(BacktestError, match="dates and symbols"): + run_accounting( + held, asset_returns, _zero_cost_model(), 100_000.0, tradable=tradable + ) diff --git a/tests/unit/test_benchmark.py b/tests/unit/test_benchmark.py index 5570c0c..479966a 100644 --- a/tests/unit/test_benchmark.py +++ b/tests/unit/test_benchmark.py @@ -150,16 +150,23 @@ def test_loader_fetches_extra_data_only_for_symbol_benchmark() -> None: base = { "experiment_name": "benchmark_fetch", "data": { - "source": "csv", - "symbols": ["AAA", "BBB"], + "instruments": [ + {"symbol": s, "source": "csv", "calendar": "XNYS"} + for s in ["AAA", "BBB"] + ], "start_date": "2024-01-01", "end_date": "2024-02-01", - "market_calendar": "XNYS", }, "strategy": {"name": "buy_and_hold"}, } symbol_cfg = ExperimentConfig.from_dict( - {**base, "backtest": {"benchmark_kind": "symbol", "benchmark_symbol": "SPY"}} + { + **base, + "backtest": { + "benchmark_kind": "symbol", + "benchmark": {"symbol": "SPY", "source": "csv", "calendar": "XNYS"}, + }, + } ) equal_weight_cfg = ExperimentConfig.from_dict( {**base, "backtest": {"benchmark_kind": "equal_weight"}} diff --git a/tests/unit/test_checkpoint.py b/tests/unit/test_checkpoint.py new file mode 100644 index 0000000..22f8ca7 --- /dev/null +++ b/tests/unit/test_checkpoint.py @@ -0,0 +1,290 @@ +"""Tests for the resumable-process checkpointing module.""" + +from __future__ import annotations + +from pathlib import Path + +import pandas as pd + +from quantlab.config import ExperimentConfig +from quantlab.validation.checkpoint import ( + clear_checkpoint, + compute_provenance, + load_checkpoint, + save_checkpoint, +) + + +def test_save_and_load_round_trips_state( + tmp_path: Path, sample_config: ExperimentConfig, synthetic_panel: pd.DataFrame +) -> None: + path = tmp_path / "checkpoint.pkl" + provenance = compute_provenance(sample_config, synthetic_panel) + save_checkpoint(path, provenance, {"folds": [1, 2, 3]}, progress=3) + assert load_checkpoint(path, provenance) == ({"folds": [1, 2, 3]}, 3) + + +def test_load_returns_none_when_file_is_absent( + tmp_path: Path, sample_config: ExperimentConfig, synthetic_panel: pd.DataFrame +) -> None: + provenance = compute_provenance(sample_config, synthetic_panel) + assert load_checkpoint(tmp_path / "missing.pkl", provenance) is None + + +def test_load_returns_none_when_provenance_no_longer_matches( + tmp_path: Path, sample_config: ExperimentConfig, synthetic_panel: pd.DataFrame +) -> None: + path = tmp_path / "checkpoint.pkl" + provenance = compute_provenance(sample_config, synthetic_panel) + save_checkpoint(path, provenance, {"folds": [1]}, progress=1) + + changed_config = sample_config.revalidated_copy( + update={ + "execution": sample_config.execution.revalidated_copy( + update={"commission_bps": 99.0} + ) + } + ) + new_provenance = compute_provenance(changed_config, synthetic_panel) + assert load_checkpoint(path, new_provenance) is None + + +def test_load_returns_none_when_run_params_change( + tmp_path: Path, sample_config: ExperimentConfig, synthetic_panel: pd.DataFrame +) -> None: + """run_params (e.g. a walk-forward grid) aren't part of ``config`` itself, + but still invalidate a checkpoint when they change between attempts.""" + path = tmp_path / "checkpoint.pkl" + provenance = compute_provenance( + sample_config, synthetic_panel, train_window=300, parameter_grid={"a": [1, 2]} + ) + save_checkpoint(path, provenance, {"folds": [1]}, progress=1) + + different_provenance = compute_provenance( + sample_config, + synthetic_panel, + train_window=300, + parameter_grid={"a": [1, 2, 3]}, + ) + assert load_checkpoint(path, different_provenance) is None + + +def test_load_returns_none_when_file_is_corrupted( + tmp_path: Path, sample_config: ExperimentConfig, synthetic_panel: pd.DataFrame +) -> None: + path = tmp_path / "checkpoint.pkl" + path.write_bytes(b"not a pickle") + provenance = compute_provenance(sample_config, synthetic_panel) + assert load_checkpoint(path, provenance) is None + + +def test_load_returns_none_when_payload_has_an_unexpected_shape( + tmp_path: Path, sample_config: ExperimentConfig, synthetic_panel: pd.DataFrame +) -> None: + import pickle + + path = tmp_path / "checkpoint.pkl" + path.write_bytes(pickle.dumps(["not", "a", "dict"])) + provenance = compute_provenance(sample_config, synthetic_panel) + assert load_checkpoint(path, provenance) is None + + +def test_load_returns_none_when_payload_is_missing_the_state_key( + tmp_path: Path, sample_config: ExperimentConfig, synthetic_panel: pd.DataFrame +) -> None: + """A payload that passes the old, incomplete shape check (only checking + for "provenance") but is missing "state" or "progress" must still be + treated as an unreadable checkpoint -- never a raw KeyError, which would + break this module's own documented contract that a bad checkpoint can + only skip work, never crash the caller.""" + import pickle + + path = tmp_path / "checkpoint.pkl" + provenance = compute_provenance(sample_config, synthetic_panel) + path.write_bytes(pickle.dumps({"provenance": provenance})) + assert load_checkpoint(path, provenance) is None + + +def test_load_returns_none_when_progress_is_negative( + tmp_path: Path, sample_config: ExperimentConfig, synthetic_panel: pd.DataFrame +) -> None: + import pickle + + path = tmp_path / "checkpoint.pkl" + provenance = compute_provenance(sample_config, synthetic_panel) + path.write_bytes( + pickle.dumps({"provenance": provenance, "progress": -1, "state": {}}) + ) + assert load_checkpoint(path, provenance) is None + + +def test_load_returns_none_when_payload_has_an_extra_key( + tmp_path: Path, sample_config: ExperimentConfig, synthetic_panel: pd.DataFrame +) -> None: + """The payload shape is exactly {"provenance", "progress", "state"} -- + an extra key means the file is corrupted, foreign, or from an + incompatible version, not "an older valid shape plus something new" to + tolerate.""" + import pickle + + path = tmp_path / "checkpoint.pkl" + provenance = compute_provenance(sample_config, synthetic_panel) + path.write_bytes( + pickle.dumps( + { + "provenance": provenance, + "progress": 1, + "state": {}, + "extra_key": "unexpected", + } + ) + ) + assert load_checkpoint(path, provenance) is None + + +def test_load_checkpoint_rejects_state_failing_a_caller_supplied_validator( + tmp_path: Path, sample_config: ExperimentConfig, synthetic_panel: pd.DataFrame +) -> None: + """A command-specific `validate` callback lets a caller refuse to resume + from a checkpoint whose state/progress doesn't match its own expected + shape (e.g. a wrong container type, or progress exceeding this run's + own total unit count) -- this module has no way to know either on its + own, since `state`'s shape and what "total" means are caller-defined.""" + path = tmp_path / "checkpoint.pkl" + provenance = compute_provenance(sample_config, synthetic_panel) + save_checkpoint(path, provenance, {"folds": [1, 2, 3]}, progress=3) + + # Correctly shaped and within a generous bound -- must still load. + assert load_checkpoint( + path, provenance, validate=lambda state, progress: progress <= 10 + ) == ({"folds": [1, 2, 3]}, 3) + + # A validator that rejects this specific state/progress pair must be + # honoured, exactly like a provenance mismatch. + assert ( + load_checkpoint(path, provenance, validate=lambda state, progress: False) + is None + ) + assert ( + load_checkpoint( + path, provenance, validate=lambda state, progress: progress <= 1 + ) + is None + ) + + +def test_clear_checkpoint_is_idempotent_on_an_absent_file(tmp_path: Path) -> None: + path = tmp_path / "missing.pkl" + clear_checkpoint(path) # must not raise + clear_checkpoint(path) + + +def test_clear_checkpoint_removes_an_existing_file( + tmp_path: Path, sample_config: ExperimentConfig, synthetic_panel: pd.DataFrame +) -> None: + path = tmp_path / "checkpoint.pkl" + provenance = compute_provenance(sample_config, synthetic_panel) + save_checkpoint(path, provenance, {"folds": [1]}, progress=1) + assert path.is_file() + clear_checkpoint(path) + assert not path.is_file() + + +def test_save_does_not_regress_a_more_advanced_checkpoint( + tmp_path: Path, sample_config: ExperimentConfig, synthetic_panel: pd.DataFrame +) -> None: + """Simulates two processes racing on the same experiment: the + less-advanced one's write must not clobber the more-advanced one's.""" + path = tmp_path / "checkpoint.pkl" + provenance = compute_provenance(sample_config, synthetic_panel) + save_checkpoint(path, provenance, {"folds": [1, 2, 3, 4, 5]}, progress=5) + save_checkpoint(path, provenance, {"folds": [1, 2]}, progress=2) + assert load_checkpoint(path, provenance) == ({"folds": [1, 2, 3, 4, 5]}, 5) + + +def test_save_overwrites_when_progress_advances( + tmp_path: Path, sample_config: ExperimentConfig, synthetic_panel: pd.DataFrame +) -> None: + path = tmp_path / "checkpoint.pkl" + provenance = compute_provenance(sample_config, synthetic_panel) + save_checkpoint(path, provenance, {"folds": [1]}, progress=1) + save_checkpoint(path, provenance, {"folds": [1, 2]}, progress=2) + assert load_checkpoint(path, provenance) == ({"folds": [1, 2]}, 2) + + +def test_save_overwrites_stale_provenance_regardless_of_progress( + tmp_path: Path, sample_config: ExperimentConfig, synthetic_panel: pd.DataFrame +) -> None: + """The monotonic guard only applies to a *matching* provenance — a new + run (different provenance) must always be able to start fresh, even if + the old, no-longer-relevant checkpoint had a higher progress count.""" + path = tmp_path / "checkpoint.pkl" + old_provenance = compute_provenance(sample_config, synthetic_panel) + save_checkpoint(path, old_provenance, {"folds": list(range(10))}, progress=10) + + changed_config = sample_config.revalidated_copy( + update={ + "execution": sample_config.execution.revalidated_copy( + update={"commission_bps": 99.0} + ) + } + ) + new_provenance = compute_provenance(changed_config, synthetic_panel) + save_checkpoint(path, new_provenance, {"folds": [1]}, progress=1) + assert load_checkpoint(path, new_provenance) == ({"folds": [1]}, 1) + + +def test_load_refuses_a_malicious_os_system_payload( + tmp_path: Path, sample_config: ExperimentConfig, synthetic_panel: pd.DataFrame +) -> None: + """A checkpoint file's provenance can only be checked *after* + unpickling -- it's itself inside the pickled payload -- so a hostile + file (a shared filesystem, a downloaded experiment folder, ...) must + never get to run arbitrary code just by being read. Provenance + mismatch alone can't be the guard here; the unpickler itself must + refuse the dangerous class before it's ever instantiated.""" + import os + import pickle + + class Evil: + def __reduce__(self) -> tuple[object, ...]: + return (os.system, ("echo pwned > pwned.txt",)) + + path = tmp_path / "checkpoint.pkl" + path.write_bytes(pickle.dumps({"provenance": {}, "progress": 1, "state": Evil()})) + + assert load_checkpoint(path, {}) is None + assert not (tmp_path / "pwned.txt").exists() + + +def test_load_refuses_a_malicious_eval_payload( + tmp_path: Path, sample_config: ExperimentConfig, synthetic_panel: pd.DataFrame +) -> None: + import pickle + + class Evil: + def __reduce__(self) -> tuple[object, ...]: + return (eval, ("1 + 1",)) + + path = tmp_path / "checkpoint.pkl" + path.write_bytes(pickle.dumps({"provenance": {}, "progress": 1, "state": Evil()})) + + assert load_checkpoint(path, {}) is None + + +def test_load_still_round_trips_a_dataframe_containing_state( + tmp_path: Path, sample_config: ExperimentConfig, synthetic_panel: pd.DataFrame +) -> None: + """The restricted unpickler must not collaterally break legitimate + checkpointed state -- a DataFrame's pickle stream touches many + pandas/numpy internal classes, none of which are on the blocklist.""" + path = tmp_path / "checkpoint.pkl" + provenance = compute_provenance(sample_config, synthetic_panel) + frame = pd.DataFrame( + {"a": [1.0, 2.0]}, index=pd.date_range("2024-01-01", periods=2) + ) + save_checkpoint(path, provenance, {"weights": frame}, progress=1) + + state, progress = load_checkpoint(path, provenance) # type: ignore[misc] + pd.testing.assert_frame_equal(state["weights"], frame) + assert progress == 1 diff --git a/tests/unit/test_config.py b/tests/unit/test_config.py index 63fca5b..11da2bc 100644 --- a/tests/unit/test_config.py +++ b/tests/unit/test_config.py @@ -43,11 +43,9 @@ def test_walk_forward_parameter_grid_is_validated_at_config_load() -> None: base: dict[str, Any] = { "experiment_name": "yaml_grid", "data": { - "source": "csv", - "symbols": ["AAA"], + "instruments": [{"symbol": "AAA", "source": "csv", "calendar": "XNYS"}], "start_date": "2020-01-01", "end_date": "2022-01-01", - "market_calendar": "XNYS", }, "strategy": { "name": "mean_reversion", @@ -80,6 +78,205 @@ def test_parameter_grid_is_rejected_for_non_walk_forward_validation() -> None: ) +def _robustness_base_dict(**robustness_overrides: Any) -> dict[str, Any]: + return { + "experiment_name": "robustness_cfg", + "data": { + "instruments": [{"symbol": "AAA", "source": "csv", "calendar": "XNYS"}], + "start_date": "2020-01-01", + "end_date": "2022-01-01", + }, + "strategy": { + "name": "mean_reversion", + "parameters": {"lookback_period": 20}, + }, + "robustness": robustness_overrides, + } + + +def test_robustness_config_defaults_to_everything_disabled() -> None: + config = ExperimentConfig.from_dict( + { + "experiment_name": "no_robustness_block", + "data": { + "instruments": [{"symbol": "AAA", "source": "csv", "calendar": "XNYS"}], + "start_date": "2020-01-01", + "end_date": "2022-01-01", + }, + "strategy": { + "name": "mean_reversion", + "parameters": {"lookback_period": 20}, + }, + } + ) + assert config.robustness.stress_test.enabled is False + assert config.robustness.bootstrap.enabled is False + assert config.robustness.bootstrap.n_iterations == 1000 + assert config.robustness.bootstrap.block_size == 1 + assert config.robustness.permutation_test.enabled is False + assert config.robustness.permutation_test.n_iterations == 1000 + assert config.robustness.sensitivity.enabled is False + assert config.robustness.sensitivity.parameters is None + + +def test_robustness_bootstrap_settings_accept_overrides() -> None: + config = ExperimentConfig.from_dict( + _robustness_base_dict( + bootstrap={"enabled": True, "n_iterations": 500, "block_size": 5} + ) + ) + assert config.robustness.bootstrap.enabled is True + assert config.robustness.bootstrap.n_iterations == 500 + assert config.robustness.bootstrap.block_size == 5 + + +@pytest.mark.parametrize("bad_n_iterations", [0, -1]) +def test_robustness_bootstrap_n_iterations_must_be_positive( + bad_n_iterations: int, +) -> None: + with pytest.raises(InvalidConfigurationError): + ExperimentConfig.from_dict( + _robustness_base_dict(bootstrap={"n_iterations": bad_n_iterations}) + ) + + +@pytest.mark.parametrize( + "parameters", + [ + {"lookback_period": [10, 20]}, + {"lookback_period": [10, 20], "entry_zscore": [1.0, 2.0], "exit_zscore": [0.5]}, + ], +) +def test_robustness_sensitivity_parameters_must_have_exactly_two_keys( + parameters: dict[str, list[Any]], +) -> None: + with pytest.raises(InvalidConfigurationError, match="exactly 2"): + ExperimentConfig.from_dict( + _robustness_base_dict(sensitivity={"parameters": parameters}) + ) + + +def test_robustness_sensitivity_parameters_rejects_empty_candidate_list() -> None: + with pytest.raises(InvalidConfigurationError, match="at least one candidate"): + ExperimentConfig.from_dict( + _robustness_base_dict( + sensitivity={ + "parameters": {"lookback_period": [10, 20], "entry_zscore": []} + } + ) + ) + + +def test_robustness_sensitivity_parameters_names_validated_against_strategy() -> None: + with pytest.raises(InvalidConfigurationError, match="Unknown"): + ExperimentConfig.from_dict( + _robustness_base_dict( + sensitivity={ + "parameters": { + "lookback_period": [10, 20], + "not_a_real_parameter": [1, 2], + } + } + ) + ) + + +def test_robustness_sensitivity_parameters_rejects_boolean_parameter() -> None: + """long_only is a structural switch (default value True/False) — sweeping + it changes which other parameters are even meaningful, so sensitivity + must reject it the same way it rejects an unknown parameter name.""" + with pytest.raises(InvalidConfigurationError, match="Unknown or unsweepable"): + ExperimentConfig.from_dict( + _robustness_base_dict( + sensitivity={ + "parameters": { + "lookback_period": [10, 20], + "long_only": [True, False], + } + } + ) + ) + + +def test_robustness_sensitivity_parameters_accepts_two_valid_keys() -> None: + config = ExperimentConfig.from_dict( + _robustness_base_dict( + sensitivity={ + "enabled": True, + "parameters": { + "lookback_period": [10, 20], + "entry_zscore": [1.0, 2.0], + }, + } + ) + ) + assert config.robustness.sensitivity.enabled is True + assert config.robustness.sensitivity.parameters == { + "lookback_period": [10, 20], + "entry_zscore": [1.0, 2.0], + } + + +def test_robustness_sensitivity_enabled_requires_parameters() -> None: + """Unlike validation.parameter_grid, sensitivity has no meaningful + default -- enabling it without naming the x/y axes must fail at config + load, not silently run nothing (or fail later, confusingly, only once + the sweep itself is attempted).""" + with pytest.raises(InvalidConfigurationError, match="parameters is not set"): + ExperimentConfig.from_dict(_robustness_base_dict(sensitivity={"enabled": True})) + + +def test_robustness_sensitivity_disabled_still_allows_missing_parameters() -> None: + """The requirement above is specifically about `enabled` -- a disabled + (default) sensitivity block must still accept `parameters: None`.""" + config = ExperimentConfig.from_dict( + _robustness_base_dict(sensitivity={"enabled": False}) + ) + assert config.robustness.sensitivity.parameters is None + + +def test_robustness_sensitivity_parameters_rejects_an_invalid_candidate_value() -> None: + """A known, sweepable parameter name doesn't mean every candidate value + is valid for this strategy -- mean_reversion's lookback_period must be + >= 1, so `[0]` must be rejected at config load the same way + validation.parameter_grid already rejects an invalid grid value, + rather than only failing once the sensitivity sweep actually runs.""" + with pytest.raises(InvalidConfigurationError, match="lookback_period"): + ExperimentConfig.from_dict( + _robustness_base_dict( + sensitivity={ + "enabled": True, + "parameters": { + "lookback_period": [0], + "entry_zscore": [1.0, 2.0], + }, + } + ) + ) + + +def test_robustness_sensitivity_parameters_rejects_an_invalid_value_combination() -> ( + None +): + """Each individual value can be independently valid while the + *combination* across the two axes still isn't -- this must be checked + against the strategy's own combined-parameter validator, not just each + axis's values in isolation.""" + with pytest.raises(InvalidConfigurationError, match="exit_zscore"): + ExperimentConfig.from_dict( + _robustness_base_dict( + sensitivity={ + "enabled": True, + "parameters": { + # mean_reversion requires exit_zscore < entry_zscore. + "entry_zscore": [1.0], + "exit_zscore": [2.0], + }, + } + ) + ) + + def test_flat_accessors(sample_config: ExperimentConfig) -> None: """The flat view must mirror the nested config.""" assert sample_config.data_source == "csv" @@ -106,11 +303,12 @@ def test_alternative_benchmark_kinds(kind: str, expected_label: str) -> None: { "experiment_name": "benchmark_kind", "data": { - "source": "csv", - "symbols": ["AAA", "BBB"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + {"symbol": "BBB", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2024-01-01", "end_date": "2024-02-01", - "market_calendar": "XNYS", }, "strategy": {"name": "buy_and_hold"}, "backtest": {"benchmark_kind": kind}, @@ -122,21 +320,25 @@ def test_alternative_benchmark_kinds(kind: str, expected_label: str) -> None: def test_non_symbol_benchmark_rejects_benchmark_symbol() -> None: - with pytest.raises(InvalidConfigurationError, match="benchmark_symbol"): + with pytest.raises(InvalidConfigurationError, match="benchmark is only valid"): ExperimentConfig.from_dict( { "experiment_name": "benchmark_kind", "data": { - "source": "csv", - "symbols": ["AAA"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"} + ], "start_date": "2024-01-01", "end_date": "2024-02-01", - "market_calendar": "XNYS", }, "strategy": {"name": "buy_and_hold"}, "backtest": { "benchmark_kind": "cash", - "benchmark_symbol": "SPY", + "benchmark": { + "symbol": "SPY", + "source": "csv", + "calendar": "XNYS", + }, }, } ) @@ -147,23 +349,46 @@ def test_symbols_are_normalised() -> None: { "experiment_name": "x", "data": { - "symbols": [" spy ", "spy", "QQQ", "qqq"], + "instruments": [ + {"symbol": " spy ", "source": "yahoo", "calendar": "XNYS"}, + {"symbol": "QQQ", "source": "yahoo", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2021-01-01", }, "strategy": {"name": "buy_and_hold"}, } ) - # Deduped, uppercased, order preserved. + # Stripped and uppercased. assert cfg.symbols == ["SPY", "QQQ"] +def test_duplicate_symbol_across_instruments_is_rejected() -> None: + with pytest.raises(InvalidConfigurationError, match="Duplicate symbol"): + ExperimentConfig.from_dict( + { + "experiment_name": "x", + "data": { + "instruments": [ + {"symbol": "SPY", "source": "yahoo", "calendar": "XNYS"}, + {"symbol": "spy", "source": "yahoo", "calendar": "XNYS"}, + ], + "start_date": "2020-01-01", + "end_date": "2021-01-01", + }, + "strategy": {"name": "buy_and_hold"}, + } + ) + + def test_missing_value_policy_enum() -> None: cfg = ExperimentConfig.from_dict( { "experiment_name": "x", "data": { - "symbols": ["SPY"], + "instruments": [ + {"symbol": "SPY", "source": "yahoo", "calendar": "XNYS"} + ], "start_date": "2020-01-01", "end_date": "2021-01-01", "missing_value_policy": "forward_fill", @@ -183,7 +408,9 @@ def test_invalid_forward_fill_limit_is_rejected(value: object) -> None: { "experiment_name": "x", "data": { - "symbols": ["SPY"], + "instruments": [ + {"symbol": "SPY", "source": "yahoo", "calendar": "XNYS"} + ], "start_date": "2020-01-01", "end_date": "2021-01-01", "missing_value_policy": "forward_fill", @@ -200,7 +427,9 @@ def test_non_default_forward_fill_limit_requires_forward_fill_policy() -> None: { "experiment_name": "x", "data": { - "symbols": ["SPY"], + "instruments": [ + {"symbol": "SPY", "source": "yahoo", "calendar": "XNYS"} + ], "start_date": "2020-01-01", "end_date": "2021-01-01", "missing_value_policy": "drop", @@ -217,7 +446,9 @@ def test_end_before_start_is_rejected() -> None: { "experiment_name": "x", "data": { - "symbols": ["SPY"], + "instruments": [ + {"symbol": "SPY", "source": "yahoo", "calendar": "XNYS"} + ], "start_date": "2021-01-01", "end_date": "2020-01-01", }, @@ -232,12 +463,10 @@ def test_same_day_intraday_experiment_is_allowed() -> None: { "experiment_name": "same_day", "data": { - "source": "csv", - "symbols": ["SPY"], + "instruments": [{"symbol": "SPY", "source": "csv", "calendar": "XNYS"}], "start_date": "2024-01-02", "end_date": "2024-01-02", "frequency": "1h", - "market_calendar": "XNYS", }, "strategy": {"name": "buy_and_hold"}, } @@ -251,7 +480,9 @@ def test_same_day_non_intraday_experiment_is_rejected() -> None: { "experiment_name": "same_day_daily", "data": { - "symbols": ["SPY"], + "instruments": [ + {"symbol": "SPY", "source": "yahoo", "calendar": "XNYS"} + ], "start_date": "2024-01-02", "end_date": "2024-01-02", "frequency": "1d", @@ -268,7 +499,9 @@ def test_unknown_key_is_rejected() -> None: { "experiment_name": "x", "data": { - "symbols": ["SPY"], + "instruments": [ + {"symbol": "SPY", "source": "yahoo", "calendar": "XNYS"} + ], "start_date": "2020-01-01", "end_date": "2021-01-01", "typo_field": 123, @@ -352,7 +585,9 @@ def test_periods_per_year_from_frequency() -> None: { "experiment_name": "x", "data": { - "symbols": ["BTCUSDT"], + "instruments": [ + {"symbol": "BTCUSDT", "source": "binance", "calendar": "24/7"} + ], "start_date": "2020-01-01", "end_date": "2021-01-01", "frequency": "1d", @@ -364,6 +599,42 @@ def test_periods_per_year_from_frequency() -> None: assert cfg.periods_per_year == 365 +def test_periods_per_year_derived_from_uniform_calendar_without_override() -> None: + cfg = ExperimentConfig.from_dict( + { + "experiment_name": "x", + "data": { + "instruments": [ + {"symbol": "BTCUSDT", "source": "binance", "calendar": "24/7"} + ], + "start_date": "2020-01-01", + "end_date": "2021-01-01", + "frequency": "1d", + }, + "strategy": {"name": "buy_and_hold"}, + } + ) + assert cfg.periods_per_year == 365 + + +def test_mixed_calendars_require_explicit_periods_per_year() -> None: + with pytest.raises(InvalidConfigurationError, match="Mixed market calendars"): + ExperimentConfig.from_dict( + { + "experiment_name": "x", + "data": { + "instruments": [ + {"symbol": "AAPL", "source": "yahoo", "calendar": "XNYS"}, + {"symbol": "BTCUSDT", "source": "binance", "calendar": "24/7"}, + ], + "start_date": "2020-01-01", + "end_date": "2021-01-01", + }, + "strategy": {"name": "buy_and_hold"}, + } + ) + + def test_yaml_roundtrip(sample_config: ExperimentConfig, tmp_path: Path) -> None: out = sample_config.to_yaml(tmp_path / "cfg.yaml") reloaded = ExperimentConfig.from_yaml(out) diff --git a/tests/unit/test_dashboard.py b/tests/unit/test_dashboard.py index 0992a83..5442b6c 100644 --- a/tests/unit/test_dashboard.py +++ b/tests/unit/test_dashboard.py @@ -18,7 +18,11 @@ import pandas as pd import pytest -from quantlab.dashboard.components import _monthly_return_pivot, render_metric_cards +from quantlab.dashboard.components import ( + _monthly_return_pivot, + render_gross_net_comparison, + render_metric_cards, +) pytest.importorskip("streamlit") @@ -56,105 +60,88 @@ def _sidebar_text_input(at: AppTest, label: str) -> Any: return next(field for field in at.sidebar.text_input if field.label == label) +def _sidebar_multiselect(at: AppTest, label: str) -> Any: + return next(ms for ms in at.sidebar.multiselect if ms.label == label) + + +def _sidebar_multiselect_by_key(at: AppTest, key: str) -> Any: + """Yahoo's and Binance's symbol pickers share the label "Symbols" (both + built from the shared ``_symbols_picker`` helper in app.py), so they + must be told apart by widget key ("yahoo_symbols" / "binance_symbols") + instead of by label.""" + return next(ms for ms in at.sidebar.multiselect if ms.key == key) + + def _configure_offline_pairs_trade(at: AppTest) -> AppTest: """Point the dashboard at locally cached CSV data for SPY/QQQ.""" - _sidebar_selectbox(at, "Data source").set_value("csv").run() - _sidebar_text_input(at, "Symbols (comma-separated)").set_value("SPY, QQQ").run() + _sidebar_text_input(at, "CSV symbols (comma-separated)").set_value("SPY, QQQ").run() _sidebar_date_input(at, "End date").set_value(datetime.date(2019, 6, 1)).run() _sidebar_selectbox(at, "Strategy").set_value("pairs_trading").run() return at -def test_default_dates_are_visible_and_ordered() -> None: - at = AppTest.from_file(APP_PATH, default_timeout=60) - at.run() - - start = _sidebar_date_input(at, "Start date") - end = _sidebar_date_input(at, "End date") - assert start.value == datetime.date(2019, 1, 1) - assert start.value < end.value - - -def test_sidebar_warns_that_one_calendar_applies_to_the_entire_universe() -> None: - at = AppTest.from_file(APP_PATH, default_timeout=60) - at.run() - - assert any( - "One calendar applies to every symbol" in warning.value - and "AAPL and 1211.HK" in warning.value - for warning in at.sidebar.warning - ) - - -def _sidebar_multiselect(at: AppTest, label: str) -> Any: - return next(ms for ms in at.sidebar.multiselect if ms.label == label) - - -_MARKET_CALENDAR_NOTE = ( - "One market calendar applies to the entire universe, so every symbol " - "must follow the same trading schedule." -) - +def _switch_to_walk_forward_mode(at: AppTest) -> AppTest: + at.segmented_control[0].set_value("Walk-forward").run() + return at -def test_csv_symbols_and_benchmark_help_mention_market_calendar() -> None: - at = AppTest.from_file(APP_PATH, default_timeout=60) - at.run() - symbols_field = _sidebar_text_input(at, "Symbols (comma-separated)") - assert _MARKET_CALENDAR_NOTE in symbols_field.proto.help +def _configure_offline_walk_forward(at: AppTest) -> AppTest: + """Point the dashboard at locally cached CSV data with small fold windows. - _sidebar_selectbox(at, "Benchmark").set_value("symbol").run() - benchmark_field = _sidebar_text_input(at, "Benchmark symbol") - assert _MARKET_CALENDAR_NOTE in benchmark_field.proto.help + ``mean_reversion`` (default ``lookback_period=20``) needs far less + warm-up than momentum strategies, but the dashboard's default allocator + is ``inverse_volatility`` (``volatility_window=63``), so train+validation + must still clear that — hence 70/20 rather than something tinier. + """ + _switch_to_walk_forward_mode(at) + _sidebar_text_input(at, "CSV symbols (comma-separated)").set_value("SPY, QQQ").run() + _sidebar_date_input(at, "End date").set_value(datetime.date(2019, 7, 1)).run() + _sidebar_selectbox(at, "Strategy").set_value("mean_reversion").run() + # Weekly (not the default monthly) guarantees a rebalance date inside + # every small test window below, regardless of where a fold happens to + # fall in the calendar. + _sidebar_selectbox(at, "Rebalance frequency").set_value("weekly").run() + _sidebar_number_input(at, "Train window (periods)").set_value(70).run() + _sidebar_number_input(at, "Validation window (periods)").set_value(20).run() + _sidebar_number_input(at, "Test window (periods)").set_value(20).run() + return at -def test_yahoo_symbols_and_benchmark_help_mention_market_calendar() -> None: +def test_default_dates_are_visible_and_ordered() -> None: at = AppTest.from_file(APP_PATH, default_timeout=60) at.run() - _sidebar_selectbox(at, "Data source").set_value("yahoo").run() - - picker = _sidebar_multiselect(at, "Symbols") - assert _MARKET_CALENDAR_NOTE in picker.proto.help - benchmark = _sidebar_selectbox(at, "Benchmark symbol") - assert _MARKET_CALENDAR_NOTE in benchmark.proto.help + start = _sidebar_date_input(at, "Start date") + end = _sidebar_date_input(at, "End date") + assert start.value == datetime.date(2019, 1, 1) + assert start.value < end.value def test_symbols_picker_help_icon_is_not_hidden_by_a_collapsed_label() -> None: """Regression test: Streamlit hides a widget's help tooltip icon along - with a `label_visibility="collapsed"` label, which silently swallowed - the market-calendar/incomplete-list notes above. The label must stay - visible so the help icon (and thus those notes) stays reachable.""" + with a `label_visibility="collapsed"` label, which would silently + swallow the incomplete-list note in `_symbols_picker`'s help text. The + label must stay visible so the help icon (and thus that note) stays + reachable.""" at = AppTest.from_file(APP_PATH, default_timeout=60) at.run() - _sidebar_selectbox(at, "Data source").set_value("yahoo").run() - picker = _sidebar_multiselect(at, "Symbols") + picker = _sidebar_multiselect_by_key(at, "yahoo_symbols") assert picker.proto.label_visibility.value == 0 # VISIBLE -def test_binance_symbols_and_benchmark_help_omit_market_calendar_note() -> None: - """Every Binance pair already shares the same 24/7 calendar, so the - cross-market mixing warning (relevant for csv/yahoo) doesn't apply.""" - at = AppTest.from_file(APP_PATH, default_timeout=60) - at.run() - _sidebar_selectbox(at, "Data source").set_value("binance").run() - - picker = _sidebar_multiselect(at, "Symbols") - assert _MARKET_CALENDAR_NOTE not in picker.proto.help - - benchmark = _sidebar_selectbox(at, "Benchmark symbol") - assert _MARKET_CALENDAR_NOTE not in benchmark.proto.help - - -def test_csv_source_keeps_the_free_text_symbols_field() -> None: +def test_csv_symbols_field_is_free_text_not_a_dropdown() -> None: + """CSV symbols are entered as free text (a local filename), unlike the + always-visible Yahoo/Binance pickers, which are dropdowns over a + preloaded universe.""" at = AppTest.from_file(APP_PATH, default_timeout=60) at.run() assert any( - field.label == "Symbols (comma-separated)" for field in at.sidebar.text_input + field.label == "CSV symbols (comma-separated)" + for field in at.sidebar.text_input ) - assert not any(ms.label == "Symbols" for ms in at.sidebar.multiselect) + assert not any(ms.key == "csv_symbols" for ms in at.sidebar.multiselect) def test_binance_symbols_picker_is_an_instant_dropdown_over_the_full_universe( @@ -178,13 +165,14 @@ def fake_universe(self: BinanceDataSource) -> list[SymbolSuggestion]: at = AppTest.from_file(APP_PATH, default_timeout=60) at.run() - _sidebar_selectbox(at, "Data source").set_value("binance").run() assert not at.exception assert not any(field.label == "Search" for field in at.sidebar.text_input) - picker = _sidebar_multiselect(at, "Symbols") + picker = _sidebar_multiselect_by_key(at, "binance_symbols") assert picker.options == ["BTCUSDT — BTC/USDT", "ETHUSDT — ETH/USDT"] - assert picker.value == ["BTCUSDT — BTC/USDT", "ETHUSDT — ETH/USDT"] + # Empty by default: a non-empty default would immediately conflict with + # CSV's own bundled-demo default (see `_combine_instrument_picks`). + assert picker.value == [] # Selecting from the already-loaded list makes no further fetch. picker.set_value(["ETHUSDT — ETH/USDT"]).run() @@ -201,24 +189,20 @@ def test_yahoo_symbols_picker_is_an_instant_dropdown_over_the_bundled_universe() instead of a live call.""" at = AppTest.from_file(APP_PATH, default_timeout=60) at.run() - _sidebar_selectbox(at, "Data source").set_value("yahoo").run() assert not at.exception assert not any(field.label == "Search" for field in at.sidebar.text_input) - picker = _sidebar_multiselect(at, "Symbols") + picker = _sidebar_multiselect_by_key(at, "yahoo_symbols") # The bundled S&P 500 + ETF + global-company list, not just a handful. assert len(picker.options) > 650 assert "AAPL — Apple Inc." in picker.options assert "MSFT — Microsoft" in picker.options - assert set(picker.value) == { - "SPY — SPDR S&P 500 ETF Trust", - "QQQ — Invesco QQQ Trust (Nasdaq-100)", - "TLT — iShares 20+ Year Treasury Bond ETF", - "GLD — SPDR Gold Shares", - } + # Empty by default: a non-empty default would immediately conflict with + # CSV's own bundled-demo default (see `_combine_instrument_picks`). + assert picker.value == [] # Picking from the already-loaded list is a plain client-side selection. - picker.set_value([*picker.value, "AAPL — Apple Inc."]).run() + picker.set_value(["AAPL — Apple Inc."]).run() assert not at.exception assert "AAPL — Apple Inc." in picker.value @@ -228,9 +212,8 @@ def test_yahoo_symbols_picker_includes_major_non_us_companies() -> None: findable — the bundled list isn't limited to US large caps.""" at = AppTest.from_file(APP_PATH, default_timeout=60) at.run() - _sidebar_selectbox(at, "Data source").set_value("yahoo").run() - picker = _sidebar_multiselect(at, "Symbols") + picker = _sidebar_multiselect_by_key(at, "yahoo_symbols") assert any(option.startswith("BMW.DE") for option in picker.options) @@ -240,9 +223,8 @@ def test_yahoo_symbols_picker_accepts_a_symbol_outside_the_bundled_list() -> Non symbol not in it can still be typed and added directly.""" at = AppTest.from_file(APP_PATH, default_timeout=60) at.run() - _sidebar_selectbox(at, "Data source").set_value("yahoo").run() - picker = _sidebar_multiselect(at, "Symbols") + picker = _sidebar_multiselect_by_key(at, "yahoo_symbols") assert picker.proto.accept_new_options is True assert not any(o.startswith("NOVN.SW") for o in picker.options) @@ -261,15 +243,12 @@ def test_yahoo_shows_a_note_that_suggestions_are_not_exhaustive() -> None: dedicating always-visible space to.""" at = AppTest.from_file(APP_PATH, default_timeout=60) at.run() - _sidebar_selectbox(at, "Data source").set_value("yahoo").run() assert not any( "Not every symbol is suggested" in c.value for c in at.sidebar.caption ) - picker = _sidebar_multiselect(at, "Symbols") + picker = _sidebar_multiselect_by_key(at, "yahoo_symbols") assert "Not every symbol is suggested" in picker.proto.help - benchmark = _sidebar_selectbox(at, "Benchmark symbol") - assert "Not every symbol is suggested" in benchmark.proto.help def test_binance_shows_no_incomplete_suggestions_note( @@ -290,28 +269,12 @@ def test_binance_shows_no_incomplete_suggestions_note( at = AppTest.from_file(APP_PATH, default_timeout=60) at.run() - _sidebar_selectbox(at, "Data source").set_value("binance").run() assert not any( "Not every symbol is suggested" in c.value for c in at.sidebar.caption ) - picker = _sidebar_multiselect(at, "Symbols") + picker = _sidebar_multiselect_by_key(at, "binance_symbols") assert "Not every symbol is suggested" not in picker.proto.help - benchmark = _sidebar_selectbox(at, "Benchmark symbol") - assert "Not every symbol is suggested" not in benchmark.proto.help - - -def test_yahoo_benchmark_symbol_accepts_new_options() -> None: - """AppTest can't simulate typing a brand-new selectbox value (it looks - the value up by index into the fixed options list, which a freshly - typed value isn't part of), so this only checks the widget is - configured to accept one — verified end-to-end manually instead.""" - at = AppTest.from_file(APP_PATH, default_timeout=60) - at.run() - _sidebar_selectbox(at, "Data source").set_value("yahoo").run() - - benchmark = _sidebar_selectbox(at, "Benchmark symbol") - assert benchmark.proto.accept_new_options is True def test_binance_symbols_picker_rejects_symbols_outside_the_universe() -> None: @@ -319,60 +282,11 @@ def test_binance_symbols_picker_rejects_symbols_outside_the_universe() -> None: there is no free-typing escape hatch for it.""" at = AppTest.from_file(APP_PATH, default_timeout=60) at.run() - _sidebar_selectbox(at, "Data source").set_value("binance").run() - picker = _sidebar_multiselect(at, "Symbols") + picker = _sidebar_multiselect_by_key(at, "binance_symbols") assert picker.proto.accept_new_options is False -def test_csv_benchmark_symbol_stays_free_text() -> None: - at = AppTest.from_file(APP_PATH, default_timeout=60) - at.run() - - assert any(field.label == "Benchmark symbol" for field in at.sidebar.text_input) - assert not any(sb.label == "Benchmark symbol" for sb in at.sidebar.selectbox) - - -def test_binance_benchmark_symbol_is_a_dropdown_over_the_same_universe( - monkeypatch: pytest.MonkeyPatch, -) -> None: - from quantlab.data.base import SymbolSuggestion - from quantlab.data.binance import BinanceDataSource - - monkeypatch.setattr( - BinanceDataSource, - "list_trading_symbols", - lambda self: [ - SymbolSuggestion(symbol="BTCUSDT", description="BTC/USDT"), - SymbolSuggestion(symbol="ETHUSDT", description="ETH/USDT"), - ], - ) - st.cache_data.clear() # avoid a real universe cached by an earlier test/run - - at = AppTest.from_file(APP_PATH, default_timeout=60) - at.run() - _sidebar_selectbox(at, "Data source").set_value("binance").run() - - assert not at.exception - benchmark = _sidebar_selectbox(at, "Benchmark symbol") - assert benchmark.options == ["BTCUSDT — BTC/USDT", "ETHUSDT — ETH/USDT"] - assert benchmark.value == "BTCUSDT — BTC/USDT" - - -def test_yahoo_benchmark_symbol_offers_the_full_bundled_universe() -> None: - """The benchmark dropdown isn't limited to the 4 starter symbols — it - shares the same bundled S&P 500 + ETF list as the Symbols picker.""" - at = AppTest.from_file(APP_PATH, default_timeout=60) - at.run() - _sidebar_selectbox(at, "Data source").set_value("yahoo").run() - - assert not at.exception - benchmark = _sidebar_selectbox(at, "Benchmark symbol") - assert len(benchmark.options) > 500 - assert "AAPL — Apple Inc." in benchmark.options - assert benchmark.value == "SPY — SPDR S&P 500 ETF Trust" - - def test_monthly_return_pivot_preserves_a_month_without_observations() -> None: returns = pd.Series( [0.10, -0.05], @@ -412,8 +326,10 @@ def columns(self, n: int) -> list[FakeColumn]: render_metric_cards(fake, result) - # Eight cards over 4 columns wrap into two visual rows of four, matching - # the platform's default two-row metric layout. + # 4 columns: eight cards divide evenly into two full, aligned rows -- + # any count that doesn't evenly divide 8 leaves a ragged last row (e.g. + # 3 columns strands "Total costs"/"Number of trades" alone on a + # half-empty row, visually detached from the grid above). assert fake.columns_requested == 4 assert len(fake.metrics) == 8 costs = next(metric for metric in fake.metrics if metric[0] == "Total costs") @@ -467,7 +383,7 @@ def test_pairs_trading_symbol_inputs_render_without_crash() -> None: at.run() assert not at.exception - _sidebar_text_input(at, "Symbols (comma-separated)").set_value("AAA, BBB").run() + _sidebar_text_input(at, "CSV symbols (comma-separated)").set_value("AAA, BBB").run() _sidebar_selectbox(at, "Strategy").set_value("pairs_trading").run() assert not at.exception @@ -506,12 +422,25 @@ def test_bundled_demo_csvs_require_an_explicit_dashboard_opt_in() -> None: assert at.session_state["result"].config.data.use_bundled_demo_data is True -def test_bundled_demo_toggle_is_hidden_for_non_csv_sources() -> None: +def test_bundled_demo_toggle_visible_only_while_a_csv_instrument_exists() -> None: + """Shown whenever any instrument-table row's Source is "csv" — not + gated by a "Data source" selectbox, since all three pickers are always + visible now.""" at = AppTest.from_file(APP_PATH, default_timeout=60) at.run() - _sidebar_selectbox(at, "Data source").set_value("yahoo").run() + # CSV's own default population (SPY, QQQ, TLT, GLD) means the toggle is + # visible out of the box. + assert any( + toggle.label == "Allow bundled synthetic demo data" + for toggle in at.sidebar.toggle + ) + + _sidebar_text_input(at, "CSV symbols (comma-separated)").set_value("").run() + yahoo_ms = _sidebar_multiselect_by_key(at, "yahoo_symbols") + yahoo_ms.set_value([yahoo_ms.options[0]]).run() + assert not at.exception assert not any( toggle.label == "Allow bundled synthetic demo data" for toggle in at.sidebar.toggle @@ -545,7 +474,9 @@ def test_reversion_exit_slider_stays_strictly_below_entry( at = AppTest.from_file(APP_PATH, default_timeout=60) at.run() if strategy_name == "pairs_trading": - _sidebar_text_input(at, "Symbols (comma-separated)").set_value("AAA, BBB").run() + _sidebar_text_input(at, "CSV symbols (comma-separated)").set_value( + "AAA, BBB" + ).run() _sidebar_selectbox(at, "Strategy").set_value(strategy_name).run() entry = next( @@ -578,7 +509,7 @@ def test_holdout_controls_do_not_claim_automatic_tuning() -> None: def test_pairs_trading_with_fewer_than_two_symbols_shows_error_not_crash() -> None: at = AppTest.from_file(APP_PATH, default_timeout=60) at.run() - _sidebar_text_input(at, "Symbols (comma-separated)").set_value("AAA").run() + _sidebar_text_input(at, "CSV symbols (comma-separated)").set_value("AAA").run() _sidebar_selectbox(at, "Strategy").set_value("pairs_trading").run() assert not at.exception assert any("at least two symbols" in e.value for e in at.sidebar.error) @@ -587,7 +518,7 @@ def test_pairs_trading_with_fewer_than_two_symbols_shows_error_not_crash() -> No def test_pairs_trading_requires_two_distinct_symbols() -> None: at = AppTest.from_file(APP_PATH, default_timeout=60) at.run() - _sidebar_text_input(at, "Symbols (comma-separated)").set_value("AAA, AAA").run() + _sidebar_text_input(at, "CSV symbols (comma-separated)").set_value("AAA, AAA").run() _sidebar_selectbox(at, "Strategy").set_value("pairs_trading").run() assert not at.exception @@ -610,13 +541,19 @@ def test_dashboard_can_disable_volatility_targeting_and_set_risk_free_rate() -> def test_failed_backtest_invalidates_previous_result() -> None: + """Dropping to one CSV symbol while pairs_trading is still selected + leaves `strategy_parameters` without symbol_a/symbol_b, which + ExperimentConfig rejects — a config-validation failure, not an empty + universe (which the Run button now disables outright, so it can no + longer be used to reach this path).""" at = AppTest.from_file(APP_PATH, default_timeout=60) at.run() _configure_offline_pairs_trade(at) at.sidebar.button[0].click().run() assert "result" in at.session_state - _sidebar_text_input(at, "Symbols (comma-separated)").set_value("").run() + _sidebar_text_input(at, "CSV symbols (comma-separated)").set_value("SPY").run() + assert at.sidebar.button[0].proto.disabled is False at.sidebar.button[0].click().run() assert not at.exception @@ -664,7 +601,7 @@ def test_robustness_tab_shows_holdout_table_when_enabled() -> None: assert robustness_tab.label == "Robustness" assert len(robustness_tab.dataframe) == 1 table = robustness_tab.dataframe[0].value - assert list(table["Block"]) == ["Train", "Validation", "Test (out-of-sample)"] + assert list(table["Block"]) == ["Train", "Validation", "Test"] column_config = json.loads(robustness_tab.dataframe[0].proto.columns) assert column_config["CAGR"]["type_config"]["format"] == "percent" assert column_config["Max Drawdown"]["type_config"]["format"] == "percent" @@ -730,8 +667,7 @@ def test_stale_result_warning_shown_after_sidebar_change() -> None: def test_frequency_mismatch_shown_as_prominent_error_not_small_caption() -> None: at = AppTest.from_file(APP_PATH, default_timeout=60) at.run() - _sidebar_selectbox(at, "Data source").set_value("csv").run() - _sidebar_text_input(at, "Symbols (comma-separated)").set_value("SPY, QQQ").run() + _sidebar_text_input(at, "CSV symbols (comma-separated)").set_value("SPY, QQQ").run() _sidebar_date_input(at, "End date").set_value(datetime.date(2019, 6, 1)).run() _sidebar_selectbox(at, "Frequency").set_value("1h").run() at.sidebar.button[0].click().run() @@ -833,3 +769,921 @@ def test_report_tab_includes_stress_tests_run_in_robustness_tab() -> None: assert report_tab.label == "Report" _, (html, _warnings) = at.session_state["report_html"] assert "Stress Tests" in html + + +def test_advanced_data_settings_reveal_forward_fill_limit_only_when_relevant() -> None: + at = AppTest.from_file(APP_PATH, default_timeout=60) + at.run() + + policy = _sidebar_selectbox(at, "Missing value policy") + assert policy.options == ["drop", "forward_fill", "raise", "none"] + assert not any( + field.label == "Forward-fill limit (consecutive bars)" + for field in at.sidebar.number_input + ) + + policy.set_value("forward_fill").run() + assert not at.exception + assert any( + field.label == "Forward-fill limit (consecutive bars)" + for field in at.sidebar.number_input + ) + + +def test_advanced_data_settings_are_accepted_by_the_config() -> None: + at = AppTest.from_file(APP_PATH, default_timeout=60) + at.run() + _configure_offline_pairs_trade(at) + _sidebar_selectbox(at, "Missing value policy").set_value("forward_fill").run() + _sidebar_number_input(at, "Forward-fill limit (consecutive bars)").set_value( + 3 + ).run() + at.sidebar.button[0].click().run() + + assert not at.exception + assert not at.error + result = at.session_state["result"] + assert result.config.data.missing_value_policy == "forward_fill" + assert result.config.data.forward_fill_limit == 3 + + +def test_advanced_execution_settings_reveal_impact_coefficient_only_for_volume() -> ( + None +): + at = AppTest.from_file(APP_PATH, default_timeout=60) + at.run() + + model = _sidebar_selectbox(at, "Slippage model") + assert model.options == ["constant", "volume"] + assert not any( + field.label == "Volume impact coefficient" for field in at.sidebar.number_input + ) + + model.set_value("volume").run() + assert not at.exception + assert any( + field.label == "Volume impact coefficient" for field in at.sidebar.number_input + ) + + +def test_advanced_execution_settings_are_accepted_by_the_config() -> None: + at = AppTest.from_file(APP_PATH, default_timeout=60) + at.run() + _configure_offline_pairs_trade(at) + _sidebar_selectbox(at, "Slippage model").set_value("volume").run() + _sidebar_number_input(at, "Volume impact coefficient").set_value(0.25).run() + at.sidebar.button[0].click().run() + + assert not at.exception + assert not at.error + result = at.session_state["result"] + assert result.config.execution.slippage_model == "volume" + assert result.config.execution.impact_coefficient == pytest.approx(0.25) + + +def test_advanced_portfolio_constraints_hidden_for_pairs_trading() -> None: + """A minimum weight, position cap, or exposure cap could drop one leg + and break the pair hedge, so these constraints must not even be offered.""" + at = AppTest.from_file(APP_PATH, default_timeout=60) + at.run() + _configure_offline_pairs_trade(at) + + assert not any( + c.label == "Enable minimum position size" for c in at.sidebar.checkbox + ) + assert any( + "Advanced portfolio constraints are disabled for pairs_trading" in c.value + for c in at.sidebar.caption + ) + + +def test_advanced_portfolio_constraints_are_accepted_by_the_config() -> None: + at = AppTest.from_file(APP_PATH, default_timeout=60) + at.run() + _sidebar_text_input(at, "CSV symbols (comma-separated)").set_value( + "SPY, QQQ, TLT, GLD" + ).run() + _sidebar_date_input(at, "End date").set_value(datetime.date(2019, 6, 1)).run() + + _sidebar_checkbox(at, "Enable minimum position size").set_value(True).run() + _sidebar_checkbox(at, "Cap gross exposure").set_value(True).run() + _sidebar_checkbox(at, "Cap net exposure").set_value(True).run() + _sidebar_checkbox(at, "Cap number of positions").set_value(True).run() + _sidebar_checkbox(at, "Cap turnover per rebalance").set_value(True).run() + assert not at.exception + + at.sidebar.button[0].click().run() + assert not at.exception + assert not at.error + portfolio = at.session_state["result"].config.portfolio + assert portfolio.target_minimum_weight is not None + assert portfolio.maximum_gross_exposure is not None + assert portfolio.maximum_net_exposure is not None + assert portfolio.target_maximum_positions is not None + assert portfolio.maximum_turnover is not None + + +def test_gross_vs_net_section_renders_with_real_values() -> None: + at = AppTest.from_file(APP_PATH, default_timeout=60) + at.run() + _sidebar_date_input(at, "End date").set_value(datetime.date(2019, 6, 1)).run() + at.sidebar.button[0].click().run() + + assert not at.exception + assert not at.error + metrics = {m.label: m.value for m in at.tabs[0].metric} + for label in ( + "Net total return", + "Gross total return", + "Cost drag", + "Net Sharpe", + "Gross Sharpe", + ): + assert label in metrics + assert metrics[label] != "n/a" + + +def test_gross_vs_net_comparison_uses_a_five_column_grid() -> None: + class FakeColumn: + def __init__(self, sink: list[tuple[str, str, dict[str, object]]]) -> None: + self._sink = sink + + def metric(self, label: str, value: str, **kwargs: object) -> None: + self._sink.append((label, value, kwargs)) + + class FakeStreamlit: + def __init__(self) -> None: + self.columns_requested: int | None = None + self.metrics: list[tuple[str, str, dict[str, object]]] = [] + + def columns(self, n: int) -> list[FakeColumn]: + self.columns_requested = n + return [FakeColumn(self.metrics) for _ in range(n)] + + def markdown(self, text: str) -> None: + pass + + result: Any = SimpleNamespace( + gross_net_comparison=lambda: { + "net_total_return": 0.05, + "net_sharpe": 1.2, + "total_cost": 123.0, + "gross_sharpe": 1.4, + "gross_total_return": 0.07, + "cost_drag": 0.02, + } + ) + fake = FakeStreamlit() + + render_gross_net_comparison(fake, result) + + # 5 columns: exactly one card per column, one full row -- no ragged + # remainder the way a count that doesn't evenly divide 5 would leave. + assert fake.columns_requested == 5 + values = {label: value for label, value, _ in fake.metrics} + assert values["Net total return"] == "5.00%" + assert values["Gross total return"] == "7.00%" + assert values["Cost drag"] == "2.00%" + assert values["Net Sharpe"] == "1.20" + assert values["Gross Sharpe"] == "1.40" + + +def test_gross_vs_net_comparison_shows_na_for_missing_gross_fields() -> None: + class FakeColumn: + def __init__(self, sink: list[tuple[str, str, dict[str, object]]]) -> None: + self._sink = sink + + def metric(self, label: str, value: str, **kwargs: object) -> None: + self._sink.append((label, value, kwargs)) + + class FakeStreamlit: + def __init__(self) -> None: + self.metrics: list[tuple[str, str, dict[str, object]]] = [] + + def columns(self, n: int) -> list[FakeColumn]: + return [FakeColumn(self.metrics) for _ in range(n)] + + def markdown(self, text: str) -> None: + pass + + result: Any = SimpleNamespace( + gross_net_comparison=lambda: { + "net_total_return": 0.05, + "net_sharpe": 1.2, + "total_cost": 0.0, + } + ) + fake = FakeStreamlit() + + render_gross_net_comparison(fake, result) + + values = {label: value for label, value, _ in fake.metrics} + assert values["Gross total return"] == "n/a" + assert values["Gross Sharpe"] == "n/a" + + +def test_walk_forward_mode_reveals_dedicated_sidebar_controls() -> None: + at = AppTest.from_file(APP_PATH, default_timeout=60) + at.run() + assert any(b.label == "Run backtest" for b in at.sidebar.button) + assert any( + c.label == "Chronological holdout (train / validation / test)" + for c in at.sidebar.checkbox + ) + + _switch_to_walk_forward_mode(at) + + assert not at.exception + assert any(b.label == "Run walk-forward" for b in at.sidebar.button) + assert not any(b.label == "Run backtest" for b in at.sidebar.button) + assert not any( + c.label == "Chronological holdout (train / validation / test)" + for c in at.sidebar.checkbox + ) + assert _sidebar_number_input(at, "Train window (periods)").value == 500 + assert _sidebar_number_input(at, "Validation window (periods)").value == 126 + assert _sidebar_number_input(at, "Test window (periods)").value == 126 + assert any(ms.label == "Grid parameters" for ms in at.sidebar.multiselect) + + +def test_walk_forward_mode_hides_buy_and_hold_strategy() -> None: + """buy_and_hold has no parameters, so it has nothing for walk-forward's + fold-by-fold validation-block selection to select — offering it there + would look like optimization is happening when it is not.""" + at = AppTest.from_file(APP_PATH, default_timeout=60) + at.run() + strategy = _sidebar_selectbox(at, "Strategy") + assert "buy_and_hold" in strategy.options + + _switch_to_walk_forward_mode(at) + + strategy = _sidebar_selectbox(at, "Strategy") + assert "buy_and_hold" not in strategy.options + # cross_sectional_momentum (index 0 of the filtered, sorted list) still + # has parameters to select, so it is a meaningful default here. + assert strategy.value == "cross_sectional_momentum" + + +def test_switching_to_walk_forward_with_buy_and_hold_selected_does_not_crash() -> None: + """The Strategy widget's persisted value (buy_and_hold, from Backtest + mode) is no longer in Walk-forward mode's filtered options list — + Streamlit must fall back cleanly, not raise.""" + at = AppTest.from_file(APP_PATH, default_timeout=60) + at.run() + _sidebar_selectbox(at, "Strategy").set_value("buy_and_hold").run() + assert not at.exception + + _switch_to_walk_forward_mode(at) + + assert not at.exception + strategy = _sidebar_selectbox(at, "Strategy") + assert strategy.value in strategy.options + + +def test_walk_forward_mode_has_no_static_backtest_count_estimate() -> None: + """The static "Estimated ~N backtests" caption was replaced by a live + progress bar shown while a run is actually in flight (see + test_walk_forward_run_reports_fold_progress in test_validation.py for + the underlying on_progress contract) — the sidebar no longer guesses a + duration upfront.""" + at = AppTest.from_file(APP_PATH, default_timeout=60) + at.run() + _configure_offline_walk_forward(at) + + assert not at.exception + assert not any("Estimated ~" in c.value for c in at.sidebar.caption) + + +def test_walk_forward_mode_still_warns_when_no_fold_fits() -> None: + """The zero-fold pre-flight warning is a validity check, not a duration + estimate, and must survive removing the "Estimated ~" caption above.""" + at = AppTest.from_file(APP_PATH, default_timeout=60) + at.run() + _switch_to_walk_forward_mode(at) + _sidebar_text_input(at, "CSV symbols (comma-separated)").set_value("SPY, QQQ").run() + _sidebar_date_input(at, "End date").set_value(datetime.date(2019, 6, 1)).run() + _sidebar_number_input(at, "Train window (periods)").set_value(10_000).run() + + assert not at.exception + assert any("No walk-forward fold fits" in w.value for w in at.sidebar.warning) + + +def test_walk_forward_grid_parameter_selection_adds_a_values_field() -> None: + at = AppTest.from_file(APP_PATH, default_timeout=60) + at.run() + _configure_offline_walk_forward(at) + + grid_picker = _sidebar_multiselect(at, "Grid parameters") + assert "lookback_period" in grid_picker.options + grid_picker.set_value(["lookback_period"]).run() + + assert not at.exception + assert any( + field.label == "Candidate values for lookback_period (comma-separated)" + for field in at.sidebar.text_input + ) + + +def test_walk_forward_run_populates_oos_result_and_tabs() -> None: + at = AppTest.from_file(APP_PATH, default_timeout=120) + at.run() + _configure_offline_walk_forward(at) + at.sidebar.button[0].click().run() + + assert not at.exception + assert not at.error + assert "wf_result" in at.session_state + wf = at.session_state["wf_result"] + assert len(wf.folds) >= 1 + assert wf.oos_result is not None + + tab_labels = [t.label for t in at.tabs] + assert tab_labels == ["Results", "Trades", "Robustness", "Report"] + metrics = {m.label: m.value for m in at.tabs[0].metric} + for label in ("Total return", "Sharpe", "Net total return", "Gross total return"): + assert label in metrics + assert metrics[label] != "n/a" + + +def test_walk_forward_robustness_tab_shows_fold_table_and_stability() -> None: + at = AppTest.from_file(APP_PATH, default_timeout=120) + at.run() + _configure_offline_walk_forward(at) + _sidebar_multiselect(at, "Grid parameters").set_value(["lookback_period"]).run() + _sidebar_text_input( + at, "Candidate values for lookback_period (comma-separated)" + ).set_value("10, 20").run() + at.session_state["dashboard_active_tab"] = "Robustness" + at.sidebar.button[0].click().run() + + assert not at.exception + robustness_tab = at.tabs[2] + assert robustness_tab.label == "Robustness" + fold_table = robustness_tab.dataframe[0].value + assert "param_lookback_period" in fold_table.columns + assert "test_sharpe" in fold_table.columns + # Stress tests do appear here, but must be the walk-forward-aware + # variant under the hood — verified at the backend level by + # test_run_walk_forward_stress_tests_reselects_parameters_under_higher_costs + # in test_validation.py, not by this dashboard-rendering test. + assert any(b.label == "Run stress tests" for b in robustness_tab.button) + + +def test_walk_forward_report_tab_includes_fold_evidence() -> None: + at = AppTest.from_file(APP_PATH, default_timeout=120) + at.run() + _configure_offline_walk_forward(at) + at.session_state["dashboard_active_tab"] = "Report" + at.sidebar.button[0].click().run() + + assert not at.exception + report_tab = at.tabs[3] + assert report_tab.label == "Report" + _, (html, _warnings) = at.session_state["wf_report_html"] + assert "walk" in html.lower() + + +def test_walk_forward_no_fitting_fold_shows_error_not_crash() -> None: + at = AppTest.from_file(APP_PATH, default_timeout=60) + at.run() + _switch_to_walk_forward_mode(at) + _sidebar_text_input(at, "CSV symbols (comma-separated)").set_value("SPY, QQQ").run() + _sidebar_date_input(at, "End date").set_value(datetime.date(2019, 6, 1)).run() + _sidebar_number_input(at, "Train window (periods)").set_value(10_000).run() + at.sidebar.button[0].click().run() + + assert not at.exception + assert any("No walk-forward fold fit" in e.value for e in at.error) + assert "wf_result" not in at.session_state + + +def test_switching_to_backtest_mode_does_not_affect_a_stored_walk_forward_result() -> ( + None +): + at = AppTest.from_file(APP_PATH, default_timeout=120) + at.run() + _configure_offline_walk_forward(at) + at.sidebar.button[0].click().run() + assert not at.exception + assert "wf_result" in at.session_state + + at.segmented_control[0].set_value("Backtest").run() + + assert not at.exception + assert "wf_result" in at.session_state + assert any(b.label == "Run backtest" for b in at.sidebar.button) + assert any(i.value.startswith("Configure an experiment") for i in at.info) + + +def _configure_offline_mean_reversion(at: AppTest) -> AppTest: + """A strategy with real grid-eligible parameters, for sensitivity tests.""" + _sidebar_text_input(at, "CSV symbols (comma-separated)").set_value("SPY, QQQ").run() + _sidebar_date_input(at, "End date").set_value(datetime.date(2019, 6, 1)).run() + _sidebar_selectbox(at, "Strategy").set_value("mean_reversion").run() + return at + + +def test_backtest_robustness_tab_bootstrap_runs_and_displays() -> None: + at = AppTest.from_file(APP_PATH, default_timeout=60) + at.run() + _configure_offline_pairs_trade(at) + at.session_state["dashboard_active_tab"] = "Robustness" + at.sidebar.button[0].click().run() + assert not at.exception + + n_iterations = next( + n for n in at.tabs[2].number_input if n.label == "Bootstrap iterations" + ) + n_iterations.set_value(100).run() + bootstrap_button = next(b for b in at.tabs[2].button if b.label == "Run bootstrap") + bootstrap_button.click().run() + + assert not at.exception + assert "bootstrap_summary" in at.session_state + summary = at.session_state["bootstrap_summary"] + assert set(summary["statistic"]) == { + "cagr", + "sharpe", + "max_drawdown", + "final_value", + } + assert len(at.tabs[2].dataframe) >= 1 + + +def test_backtest_robustness_tab_permutation_test_runs_and_displays() -> None: + at = AppTest.from_file(APP_PATH, default_timeout=60) + at.run() + _configure_offline_pairs_trade(at) + at.session_state["dashboard_active_tab"] = "Robustness" + at.sidebar.button[0].click().run() + assert not at.exception + + n_iterations = next( + n for n in at.tabs[2].number_input if n.label == "Permutation iterations" + ) + n_iterations.set_value(100).run() + permutation_button = next( + b for b in at.tabs[2].button if b.label == "Run permutation test" + ) + permutation_button.click().run() + + assert not at.exception + assert "permutation_test" in at.session_state + outcome = at.session_state["permutation_test"] + assert {"real_sharpe", "p_value", "n_iterations"} <= set(outcome) + metric_labels = {m.label for m in at.tabs[2].metric} + assert {"Real Sharpe", "p-value"} <= metric_labels + + +def test_backtest_robustness_tab_sensitivity_runs_and_displays_heatmap() -> None: + at = AppTest.from_file(APP_PATH, default_timeout=60) + at.run() + _configure_offline_mean_reversion(at) + at.session_state["dashboard_active_tab"] = "Robustness" + at.sidebar.button[0].click().run() + assert not at.exception + + robustness_tab = at.tabs[2] + x_select = next( + sb for sb in robustness_tab.selectbox if sb.label == "Parameter (x-axis)" + ) + x_select.set_value("lookback_period").run() + robustness_tab = at.tabs[2] + x_values = next( + f + for f in robustness_tab.text_input + if f.label == "Candidate values (x, comma-separated)" + ) + x_values.set_value("10, 20").run() + robustness_tab = at.tabs[2] + y_select = next( + sb for sb in robustness_tab.selectbox if sb.label == "Parameter (y-axis)" + ) + y_select.set_value("entry_zscore").run() + robustness_tab = at.tabs[2] + y_values = next( + f + for f in robustness_tab.text_input + if f.label == "Candidate values (y, comma-separated)" + ) + y_values.set_value("1.5, 2.5").run() + + robustness_tab = at.tabs[2] + run_button = next( + b for b in robustness_tab.button if b.label == "Run parameter sensitivity" + ) + assert not run_button.proto.disabled + run_button.click().run() + + assert not at.exception + assert "sensitivity" in at.session_state + sensitivity = at.session_state["sensitivity"] + assert len(sensitivity) == 4 + # AppTest has no plotly_chart accessor; render_sensitivity_heatmap also + # renders the raw sensitivity table right after the chart, so its + # presence confirms the heatmap section actually rendered. + assert any(len(df.value) == 4 for df in at.tabs[2].dataframe) + + +def test_walk_forward_robustness_tab_bootstrap_runs_and_displays() -> None: + at = AppTest.from_file(APP_PATH, default_timeout=120) + at.run() + _configure_offline_walk_forward(at) + at.session_state["dashboard_active_tab"] = "Robustness" + at.sidebar.button[0].click().run() + assert not at.exception + + n_iterations = next( + n for n in at.tabs[2].number_input if n.label == "Bootstrap iterations" + ) + n_iterations.set_value(100).run() + bootstrap_button = next(b for b in at.tabs[2].button if b.label == "Run bootstrap") + bootstrap_button.click().run() + + assert not at.exception + assert "wf_bootstrap_summary" in at.session_state + summary = at.session_state["wf_bootstrap_summary"] + assert set(summary["statistic"]) == { + "cagr", + "sharpe", + "max_drawdown", + "final_value", + } + + +def test_walk_forward_robustness_tab_permutation_test_runs_and_displays() -> None: + at = AppTest.from_file(APP_PATH, default_timeout=120) + at.run() + _configure_offline_walk_forward(at) + at.session_state["dashboard_active_tab"] = "Robustness" + at.sidebar.button[0].click().run() + assert not at.exception + + n_iterations = next( + n for n in at.tabs[2].number_input if n.label == "Permutation iterations" + ) + n_iterations.set_value(100).run() + permutation_button = next( + b for b in at.tabs[2].button if b.label == "Run permutation test" + ) + permutation_button.click().run() + + assert not at.exception + assert "wf_permutation_test" in at.session_state + + +def test_walk_forward_robustness_tab_stress_tests_reruns_selection() -> None: + """Confirms the button in Walk-forward mode actually calls the + walk-forward-aware state function (distinct session key, real scenarios) + rather than Backtest mode's plain-backtest variant.""" + at = AppTest.from_file(APP_PATH, default_timeout=180) + at.run() + _configure_offline_walk_forward(at) + at.session_state["dashboard_active_tab"] = "Robustness" + at.sidebar.button[0].click().run() + assert not at.exception + + stress_button = next(b for b in at.tabs[2].button if b.label == "Run stress tests") + stress_button.click().run() + + assert not at.exception + assert "wf_stress_tests" in at.session_state + assert "stress_tests" not in at.session_state # Backtest mode's own key + stress = at.session_state["wf_stress_tests"] + assert "commission x5" in set(stress["scenario"]) + + +def test_backtest_run_all_robustness_tests_populates_every_technique() -> None: + at = AppTest.from_file(APP_PATH, default_timeout=60) + at.run() + _configure_offline_mean_reversion(at) + at.session_state["dashboard_active_tab"] = "Robustness" + at.sidebar.button[0].click().run() + assert not at.exception + + robustness_tab = at.tabs[2] + next( + n for n in robustness_tab.number_input if n.label == "Bootstrap iterations" + ).set_value(100).run() + robustness_tab = at.tabs[2] + next( + n for n in robustness_tab.number_input if n.label == "Permutation iterations" + ).set_value(100).run() + robustness_tab = at.tabs[2] + next( + sb for sb in robustness_tab.selectbox if sb.label == "Parameter (x-axis)" + ).set_value("lookback_period").run() + robustness_tab = at.tabs[2] + next( + f + for f in robustness_tab.text_input + if f.label == "Candidate values (x, comma-separated)" + ).set_value("10, 20").run() + robustness_tab = at.tabs[2] + next( + sb for sb in robustness_tab.selectbox if sb.label == "Parameter (y-axis)" + ).set_value("entry_zscore").run() + robustness_tab = at.tabs[2] + next( + f + for f in robustness_tab.text_input + if f.label == "Candidate values (y, comma-separated)" + ).set_value("1.5, 2.5").run() + + robustness_tab = at.tabs[2] + run_all_button = next( + b for b in robustness_tab.button if b.label == "Run all robustness tests" + ) + run_all_button.click().run() + + assert not at.exception + for key in ("stress_tests", "bootstrap_summary", "permutation_test", "sensitivity"): + assert key in at.session_state, f"{key} was not populated by Run all" + + +# --------------------------------------------------------------------------- # +# Multi-instrument sidebar (Phase C): conflict detection, provenance-based +# source, mixed-calendar handling, frequency-compatibility filtering, and the +# rewritten benchmark lock-on-overlap behaviour. +# --------------------------------------------------------------------------- # + + +def test_conflicting_symbol_across_pickers_blocks_submission_with_error() -> None: + """Picking the same symbol from two pickers makes its source/calendar + ambiguous — never silently deduplicated (see `_combine_instrument_picks` + in app.py).""" + at = AppTest.from_file(APP_PATH, default_timeout=60) + at.run() + assert at.sidebar.button[0].proto.disabled is False + + yahoo_ms = _sidebar_multiselect_by_key(at, "yahoo_symbols") + # SPY is already in CSV's default population (SPY, QQQ, TLT, GLD). + yahoo_ms.set_value(["SPY — SPDR S&P 500 ETF Trust"]).run() + + assert not at.exception + assert any("ambiguous" in e.value and "SPY" in e.value for e in at.sidebar.error) + assert at.sidebar.button[0].proto.disabled is True + + +def test_instrument_source_comes_from_picker_provenance_not_a_heuristic( + monkeypatch: pytest.MonkeyPatch, +) -> None: + """The instrument table's Source column defaults to the picker a symbol + was actually picked from (see `_combine_instrument_picks`'s docstring in + app.py), never a symbol-shape heuristic. Checked against the *built + config* returned by `build_config_from_inputs`, not just the sidebar's + own table, so this exercises the real + sidebar -> `_collect_inputs` -> `build_config_from_inputs` pipeline. + + `run_dashboard_backtest` is monkeypatched to capture the config and + raise immediately (before any data loading happens), so this stays + fully offline — real Binance OHLCV data is never fetched, only its + (also monkeypatched) symbol-suggestion list.""" + import quantlab.dashboard.state as state_module + from quantlab.config import DataSourceName + from quantlab.data.base import SymbolSuggestion + from quantlab.data.binance import BinanceDataSource + + monkeypatch.setattr( + BinanceDataSource, + "list_trading_symbols", + lambda self: [SymbolSuggestion(symbol="BTCUSDT", description="BTC/USDT")], + ) + st.cache_data.clear() # avoid a real universe cached by an earlier test/run + + captured: dict[str, Any] = {} + + def fake_run_dashboard_backtest(config: Any) -> Any: + captured["config"] = config + raise RuntimeError("stop before real data loading") + + monkeypatch.setattr( + state_module, "run_dashboard_backtest", fake_run_dashboard_backtest + ) + + at = AppTest.from_file(APP_PATH, default_timeout=60) + at.run() + _sidebar_text_input(at, "CSV symbols (comma-separated)").set_value("").run() + binance_ms = _sidebar_multiselect_by_key(at, "binance_symbols") + binance_ms.set_value([binance_ms.options[0]]).run() + assert at.sidebar.button[0].proto.disabled is False + at.sidebar.button[0].click().run() + + assert "config" in captured + instruments = captured["config"].data.instruments + assert len(instruments) == 1 + assert instruments[0].symbol == "BTCUSDT" + assert instruments[0].source is DataSourceName.BINANCE + assert instruments[0].calendar == "24/7" + + +def test_frequency_options_reflect_selected_sources( + monkeypatch: pytest.MonkeyPatch, +) -> None: + """The Frequency dropdown offers exactly + `compatible_frequencies_for_sources()`'s answer for the currently + selected instruments' sources — computed here directly rather than + hardcoded, so this test can't silently drift from the real + frequency-compatibility intersection logic in config.py.""" + from quantlab.config import DataSourceName, compatible_frequencies_for_sources + from quantlab.data.base import SymbolSuggestion + from quantlab.data.binance import BinanceDataSource + + monkeypatch.setattr( + BinanceDataSource, + "list_trading_symbols", + lambda self: [SymbolSuggestion(symbol="BTCUSDT", description="BTC/USDT")], + ) + st.cache_data.clear() # avoid a real universe cached by an earlier test/run + + at = AppTest.from_file(APP_PATH, default_timeout=60) + at.run() + freq = next(sb for sb in at.sidebar.selectbox if sb.label == "Frequency") + expected_csv_only = sorted( + f.value for f in compatible_frequencies_for_sources({DataSourceName.CSV}) + ) + assert freq.options == expected_csv_only + + binance_ms = _sidebar_multiselect_by_key(at, "binance_symbols") + binance_ms.set_value([binance_ms.options[0]]).run() + + freq = next(sb for sb in at.sidebar.selectbox if sb.label == "Frequency") + # '1h' is additionally excluded here: adding BTCUSDT mixes calendars + # (CSV's default population is XNYS, BTCUSDT is 24/7), and verified + # closures only work at daily frequency -- see + # test_mixed_calendar_universe_excludes_intraday_frequency below for a + # dedicated check of that exclusion. + expected_mixed = sorted( + f.value + for f in compatible_frequencies_for_sources( + {DataSourceName.CSV, DataSourceName.BINANCE} + ) + if f.value != "1h" + ) + assert freq.options == expected_mixed + assert freq.options != expected_csv_only + + +def test_mixed_calendar_warning_and_periods_per_year_field_appear_together( + monkeypatch: pytest.MonkeyPatch, +) -> None: + """No real Binance/Yahoo network access is available in CI (every other + test in this file that runs an actual backtest stays on CSV data for + exactly that reason), so this only exercises the sidebar's reaction to a + mixed-calendar universe — warning plus field appearing together, and the + Run button staying enabled — not a full multi-source backtest run.""" + from quantlab.data.base import SymbolSuggestion + from quantlab.data.binance import BinanceDataSource + + monkeypatch.setattr( + BinanceDataSource, + "list_trading_symbols", + lambda self: [SymbolSuggestion(symbol="BTCUSDT", description="BTC/USDT")], + ) + st.cache_data.clear() # avoid a real universe cached by an earlier test/run + + at = AppTest.from_file(APP_PATH, default_timeout=60) + at.run() + # CSV's default population is all XNYS, so no mixed-calendar warning yet. + assert not any( + "Instruments span more than one calendar" in w.value for w in at.sidebar.warning + ) + assert not any( + f.label == "Periods per year (annualisation factor)" + for f in at.sidebar.number_input + ) + + binance_ms = _sidebar_multiselect_by_key(at, "binance_symbols") + binance_ms.set_value([binance_ms.options[0]]).run() + + assert not at.exception + assert any( + "Instruments span more than one calendar" in w.value for w in at.sidebar.warning + ) + periods_field = next( + f + for f in at.sidebar.number_input + if f.label == "Periods per year (annualisation factor)" + ) + # Defaults to 365, not 252: the mix includes a 24/7 instrument (BTCUSDT), + # so the business-day equity convention would understate its real + # trading frequency. + assert periods_field.value == 365 + assert at.sidebar.button[0].proto.disabled is False + + +def test_mixed_calendar_universe_excludes_intraday_frequency( + monkeypatch: pytest.MonkeyPatch, +) -> None: + """'1h' must not be offered for a mixed-calendar universe: verified + closures only work at daily frequency, so ExperimentConfig itself would + reject it -- the picker must never offer something the config would + then refuse (same principle as source-compatibility filtering).""" + from quantlab.data.base import SymbolSuggestion + from quantlab.data.binance import BinanceDataSource + + monkeypatch.setattr( + BinanceDataSource, + "list_trading_symbols", + lambda self: [SymbolSuggestion(symbol="BTCUSDT", description="BTC/USDT")], + ) + st.cache_data.clear() # avoid a real universe cached by an earlier test/run + + at = AppTest.from_file(APP_PATH, default_timeout=60) + at.run() + freq = next(sb for sb in at.sidebar.selectbox if sb.label == "Frequency") + assert "1h" in freq.options # CSV's default population is all XNYS + + binance_ms = _sidebar_multiselect_by_key(at, "binance_symbols") + binance_ms.set_value([binance_ms.options[0]]).run() + + freq = next(sb for sb in at.sidebar.selectbox if sb.label == "Frequency") + assert "1h" not in freq.options + assert any( + "'1h' is unavailable for a mixed-calendar universe" in c.value + for c in at.sidebar.caption + ) + + +def test_periods_per_year_value_flows_into_the_built_config( + monkeypatch: pytest.MonkeyPatch, +) -> None: + """Complements the sidebar-only check above: an explicit + "Periods per year" value, entered while the universe spans more than + one calendar, actually reaches `BacktestConfig.periods_per_year` via + `_collect_inputs` / `build_config_from_inputs`. `run_dashboard_backtest` + is monkeypatched to capture the config before any data loading, keeping + this offline.""" + import quantlab.dashboard.state as state_module + from quantlab.data.base import SymbolSuggestion + from quantlab.data.binance import BinanceDataSource + + monkeypatch.setattr( + BinanceDataSource, + "list_trading_symbols", + lambda self: [SymbolSuggestion(symbol="BTCUSDT", description="BTC/USDT")], + ) + st.cache_data.clear() # avoid a real universe cached by an earlier test/run + + captured: dict[str, Any] = {} + + def fake_run_dashboard_backtest(config: Any) -> Any: + captured["config"] = config + raise RuntimeError("stop before real data loading") + + monkeypatch.setattr( + state_module, "run_dashboard_backtest", fake_run_dashboard_backtest + ) + + at = AppTest.from_file(APP_PATH, default_timeout=60) + at.run() + binance_ms = _sidebar_multiselect_by_key(at, "binance_symbols") + binance_ms.set_value([binance_ms.options[0]]).run() + periods_field = next( + f + for f in at.sidebar.number_input + if f.label == "Periods per year (annualisation factor)" + ) + periods_field.set_value(365).run() + at.sidebar.button[0].click().run() + + assert "config" in captured + assert captured["config"].backtest.periods_per_year == 365 + + +def test_benchmark_symbol_matching_an_instrument_locks_its_source_and_calendar() -> ( + None +): + at = AppTest.from_file(APP_PATH, default_timeout=60) + at.run() + + # SPY is already a tradable instrument via CSV's default population. + benchmark = _sidebar_text_input(at, "Benchmark symbol") + assert benchmark.value == "SPY" + assert any( + "SPY is already a tradable instrument" in c.value + and "source (csv)" in c.value + and "calendar (XNYS)" in c.value + for c in at.sidebar.caption + ) + assert not any(sb.label == "Benchmark source" for sb in at.sidebar.selectbox) + assert not any(f.label == "Benchmark calendar" for f in at.sidebar.text_input) + + +def test_benchmark_symbol_not_matching_any_instrument_shows_source_and_calendar() -> ( + None +): + at = AppTest.from_file(APP_PATH, default_timeout=60) + at.run() + _sidebar_text_input(at, "Benchmark symbol").set_value("NOTINLIST").run() + + assert not any( + "is already a tradable instrument" in c.value for c in at.sidebar.caption + ) + source = next(sb for sb in at.sidebar.selectbox if sb.label == "Benchmark source") + assert source.key == "benchmark_source_select" + assert source.options == ["yahoo", "binance", "csv"] + assert source.value == "csv" # detect_source() can't guess a shape-less string + calendar = next(f for f in at.sidebar.text_input if f.label == "Benchmark calendar") + assert calendar.key == "benchmark_calendar_input" + assert calendar.value == "XNYS" diff --git a/tests/unit/test_dashboard_state.py b/tests/unit/test_dashboard_state.py new file mode 100644 index 0000000..8afa8e5 --- /dev/null +++ b/tests/unit/test_dashboard_state.py @@ -0,0 +1,187 @@ +"""Tests for the Streamlit-independent dashboard configuration helpers.""" + +from __future__ import annotations + +import datetime + +import pandas as pd +import pytest + +from quantlab.dashboard.state import ( + build_config_from_inputs, + estimate_walk_forward_backtest_count, +) +from quantlab.validation.parameter_grid import parse_parameter_grid_values + + +def _base_inputs(**overrides: object) -> dict[str, object]: + inputs: dict[str, object] = { + "instruments": [ + {"symbol": "SPY", "source": "csv", "calendar": "XNYS"}, + {"symbol": "QQQ", "source": "csv", "calendar": "XNYS"}, + ], + "start_date": datetime.date(2019, 1, 1), + "end_date": datetime.date(2020, 1, 1), + "strategy_name": "buy_and_hold", + "strategy_parameters": {}, + "allocator": "equal_weight", + "rebalance_frequency": "monthly", + } + inputs.update(overrides) + return inputs + + +def test_build_config_from_inputs_defaults_to_holdout_validation() -> None: + config = build_config_from_inputs(_base_inputs()) + assert config.validation.method == "holdout" + + +def test_build_config_from_inputs_builds_walk_forward_validation_block() -> None: + config = build_config_from_inputs( + _base_inputs( + strategy_name="time_series_momentum", + strategy_parameters={"lookback_period": 120, "skip_period": 5}, + validation_method="walk_forward", + train_window=300, + validation_window=60, + test_window=60, + expanding=False, + optimization_metric="sortino", + parameter_grid={"lookback_period": [60, 120]}, + ) + ) + assert config.validation.method == "walk_forward" + assert config.validation.train_window == 300 + assert config.validation.validation_window == 60 + assert config.validation.test_window == 60 + assert config.validation.expanding is False + assert config.validation.optimization_metric == "sortino" + assert config.validation.parameter_grid == {"lookback_period": [60, 120]} + + +def test_build_config_from_inputs_walk_forward_without_grid_is_none() -> None: + """An empty/missing grid must become `None` (fall back to the strategy's + default grid), not an empty dict rejected as "no candidate values".""" + config = build_config_from_inputs( + _base_inputs( + validation_method="walk_forward", + train_window=300, + validation_window=60, + test_window=60, + parameter_grid={}, + ) + ) + assert config.validation.parameter_grid is None + + +@pytest.mark.parametrize( + ("raw", "expected"), + [ + ("60, 120, 252", [60, 120, 252]), + ("0.1, 0.25, 0.5", [0.1, 0.25, 0.5]), + ("true, false", [True, False]), + ("binary, continuous", ["binary", "continuous"]), + (" 60 ,, 120 ", [60, 120]), + ("", []), + ], +) +def test_parse_parameter_grid_values(raw: str, expected: list[object]) -> None: + assert parse_parameter_grid_values(raw) == expected + + +def test_estimate_walk_forward_backtest_count_matches_fold_times_combinations() -> None: + from quantlab.validation.splits import walk_forward_windows + + start = datetime.date(2018, 1, 1) + end = datetime.date(2021, 12, 31) + index = pd.DatetimeIndex(pd.bdate_range(start, end)) + windows = walk_forward_windows(index, 300, 120, 120, expanding=True) + + estimate = estimate_walk_forward_backtest_count( + start_date=start, + end_date=end, + is_247_market=False, + train_window=300, + validation_window=120, + test_window=120, + expanding=True, + parameter_grid={"lookback_period": [60, 120], "skip_period": [0, 21]}, + ) + + assert estimate == len(windows) * (2 * 2 + 1) + + +def test_estimate_walk_forward_backtest_count_empty_grid_counts_one_combination() -> ( + None +): + estimate = estimate_walk_forward_backtest_count( + start_date=datetime.date(2018, 1, 1), + end_date=datetime.date(2021, 12, 31), + is_247_market=False, + train_window=300, + validation_window=120, + test_window=120, + expanding=True, + parameter_grid={}, + ) + assert estimate > 0 + + +def test_estimate_walk_forward_backtest_count_is_zero_for_too_short_a_range() -> None: + estimate = estimate_walk_forward_backtest_count( + start_date=datetime.date(2020, 1, 1), + end_date=datetime.date(2020, 1, 10), + is_247_market=False, + train_window=300, + validation_window=120, + test_window=120, + expanding=True, + parameter_grid={}, + ) + assert estimate == 0 + + +def test_checkpoint_path_matches_the_cli_convention() -> None: + """Same GENERATED_REPORTS_DIR / experiment_name / '.checkpoint_.pkl' + convention the CLI uses (src/quantlab/cli.py), so a dashboard run and a + same-named CLI run can resume each other's progress.""" + from quantlab.constants import GENERATED_REPORTS_DIR + from quantlab.dashboard.state import _checkpoint_path + + config = build_config_from_inputs(_base_inputs(experiment_name="my_experiment")) + path = _checkpoint_path(config, "walk_forward") + assert path == ( + GENERATED_REPORTS_DIR / "my_experiment" / ".checkpoint_walk_forward.pkl" + ) + + +def test_run_dashboard_walk_forward_passes_its_checkpoint_path_through( + monkeypatch: pytest.MonkeyPatch, +) -> None: + """Wiring check: run_dashboard_walk_forward must forward the same path + _checkpoint_path() computes to WalkForwardValidator.run(), not silently + drop it — the actual resume mechanism is exercised end-to-end elsewhere + (tests/unit/test_validation.py, tests/integration/test_cli.py).""" + from types import SimpleNamespace + + import quantlab.dashboard.state as state_module + from quantlab.dashboard.state import _checkpoint_path, run_dashboard_walk_forward + from quantlab.validation.walk_forward import WalkForwardResult, WalkForwardValidator + + config = build_config_from_inputs(_base_inputs(experiment_name="wiring_check")) + monkeypatch.setattr( + state_module.DataLoader, + "load", + lambda self, cfg: (pd.DataFrame(), SimpleNamespace(warnings=[])), + ) + captured: dict[str, object] = {} + + def _fake_run(self, data, **kwargs): # type: ignore[no-untyped-def] + captured.update(kwargs) + return WalkForwardResult() + + monkeypatch.setattr(WalkForwardValidator, "run", _fake_run) + + run_dashboard_walk_forward(config) + + assert captured["checkpoint_path"] == _checkpoint_path(config, "walk_forward") diff --git a/tests/unit/test_data_api_hardening.py b/tests/unit/test_data_api_hardening.py index 88bd13d..bf29475 100644 --- a/tests/unit/test_data_api_hardening.py +++ b/tests/unit/test_data_api_hardening.py @@ -12,6 +12,7 @@ import numpy as np import pandas as pd import pytest +from tests.regression_helpers import _UniformCalendar from quantlab.config import ExperimentConfig from quantlab.constants import ( @@ -80,11 +81,26 @@ def test_universe_csv_rejects_empty_file(tmp_path: Any) -> None: @pytest.mark.parametrize( ("kwargs", "message"), [ - ({"max_gap_periods": 0}, "max_gap_periods"), - ({"max_gap_periods": True}, "max_gap_periods"), - ({"min_coverage_rows": -1}, "min_coverage_rows"), - ({"expected_frequency": "typo"}, "expected_frequency"), - ({"is_247_market": 1}, "is_247_market"), + ( + {"max_gap_periods": 0, "symbol_calendars": _UniformCalendar("XNYS")}, + "max_gap_periods", + ), + ( + {"max_gap_periods": True, "symbol_calendars": _UniformCalendar("XNYS")}, + "max_gap_periods", + ), + ( + {"min_coverage_rows": -1, "symbol_calendars": _UniformCalendar("XNYS")}, + "min_coverage_rows", + ), + ( + { + "expected_frequency": "typo", + "symbol_calendars": _UniformCalendar("XNYS"), + }, + "expected_frequency", + ), + ({"symbol_calendars": "not_a_mapping"}, "symbol_calendars"), ], ) def test_validator_rejects_invalid_constructor_arguments( @@ -103,7 +119,9 @@ def test_validator_uses_xnys_session_for_weekend_end() -> None: ) ) report = DataValidator( - expected_frequency="1h", min_coverage_rows=1, is_247_market=False + expected_frequency="1h", + min_coverage_rows=1, + symbol_calendars=_UniformCalendar("XNYS"), ).validate( _ohlcv(pd.DatetimeIndex(timestamps), symbol="SPY"), start=date(2024, 1, 1), @@ -115,7 +133,9 @@ def test_validator_uses_xnys_session_for_weekend_end() -> None: def test_validator_counts_each_ohlc_inconsistent_row_once() -> None: frame = _ohlcv(pd.DatetimeIndex(["2024-01-02"])) frame.loc[0, [OPEN, HIGH, LOW, CLOSE]] = [10.0, 5.0, 15.0, 10.0] - report = DataValidator(min_coverage_rows=1).validate(frame) + report = DataValidator( + min_coverage_rows=1, symbol_calendars=_UniformCalendar("XNYS") + ).validate(frame) assert report.invalid_price_count == 1 assert "1 OHLC-inconsistent rows" in report.warnings[0] @@ -125,12 +145,16 @@ def test_validator_rejects_non_numeric_canonical_value_cleanly() -> None: frame[OPEN] = frame[OPEN].astype(object) frame.loc[0, OPEN] = "not-a-price" with pytest.raises(DataValidationError, match="non-numeric"): - DataValidator(min_coverage_rows=1).validate(frame) + DataValidator( + min_coverage_rows=1, symbol_calendars=_UniformCalendar("XNYS") + ).validate(frame) def test_validator_rejects_missing_canonical_columns() -> None: with pytest.raises(DataValidationError, match="canonical columns"): - DataValidator().validate(pd.DataFrame({TIMESTAMP: ["2024-01-01"]})) + DataValidator(symbol_calendars=_UniformCalendar("XNYS")).validate( + pd.DataFrame({TIMESTAMP: ["2024-01-01"]}) + ) def test_missing_period_keeps_symbol_and_serialises_dates() -> None: @@ -138,7 +162,9 @@ def test_missing_period_keeps_symbol_and_serialises_dates() -> None: ["2024-01-01 00:00", "2024-01-01 01:00", "2024-01-01 03:00"] ) report = DataValidator( - expected_frequency="1h", min_coverage_rows=1, is_247_market=True + expected_frequency="1h", + min_coverage_rows=1, + symbol_calendars=_UniformCalendar("24/7"), ).validate(_ohlcv(timestamps, symbol="BTCUSDT")) assert len(report.missing_periods) == 1 period = report.missing_periods[0] @@ -149,19 +175,27 @@ def test_missing_period_keeps_symbol_and_serialises_dates() -> None: def test_declared_frequency_drives_gap_detection() -> None: timestamps = pd.date_range("2024-01-01", periods=4, freq="2h") report = DataValidator( - expected_frequency="1h", min_coverage_rows=1, is_247_market=True + expected_frequency="1h", + min_coverage_rows=1, + symbol_calendars=_UniformCalendar("24/7"), ).validate(_ohlcv(timestamps, symbol="BTCUSDT")) assert len(report.missing_periods) == 3 def test_daily_equity_gap_counts_xnys_sessions() -> None: tolerated = DataValidator( - expected_frequency="1d", max_gap_periods=5, min_coverage_rows=1 + expected_frequency="1d", + max_gap_periods=5, + min_coverage_rows=1, + symbol_calendars=_UniformCalendar("XNYS"), ).validate(_ohlcv(pd.DatetimeIndex(["2024-01-05", "2024-01-12"]))) assert tolerated.missing_periods == [] flagged = DataValidator( - expected_frequency="1d", max_gap_periods=5, min_coverage_rows=1 + expected_frequency="1d", + max_gap_periods=5, + min_coverage_rows=1, + symbol_calendars=_UniformCalendar("XNYS"), ).validate(_ohlcv(pd.DatetimeIndex(["2024-01-05", "2024-01-16"]))) assert len(flagged.missing_periods) == 1 @@ -184,19 +218,19 @@ def test_yahoo_rejects_invalid_retry_parameters( @pytest.mark.parametrize( - ("symbols", "start", "end", "frequency", "is_247_market", "message"), + ("symbols", "start", "end", "frequency", "calendar", "message"), [ - ([], date(2024, 1, 1), date(2024, 1, 2), "1d", False, "at least one symbol"), - ([""], date(2024, 1, 1), date(2024, 1, 2), "1d", False, "non-empty string"), + ([], date(2024, 1, 1), date(2024, 1, 2), "1d", "XNYS", "at least one symbol"), + ([""], date(2024, 1, 1), date(2024, 1, 2), "1d", "XNYS", "non-empty string"), ( ["SPY"], date(2024, 1, 2), date(2024, 1, 1), "1d", - False, + "XNYS", "on or before end", ), - (["SPY"], date(2024, 1, 1), date(2024, 1, 2), "1d", 1, "boolean"), + (["SPY"], date(2024, 1, 1), date(2024, 1, 2), "1d", 1, "non-empty string"), ], ) def test_yahoo_validates_direct_download_arguments( @@ -204,7 +238,7 @@ def test_yahoo_validates_direct_download_arguments( start: date, end: date, frequency: str, - is_247_market: object, + calendar: object, message: str, ) -> None: with pytest.raises(DataDownloadError, match=message): @@ -213,7 +247,7 @@ def test_yahoo_validates_direct_download_arguments( start, end, frequency, - is_247_market=is_247_market, # type: ignore[arg-type] + calendar=calendar, # type: ignore[arg-type] ) @@ -259,29 +293,25 @@ def test_yahoo_logs_adjusted_close_fallback(caplog: pytest.LogCaptureFixture) -> } ).set_index("Date") with caplog.at_level(logging.WARNING): - out = YahooFinanceDataSource._normalise( - raw, - "SPY", - "1d", - pd.Timestamp("2024-01-03 22:00"), - date(2024, 1, 2), - ) + out = YahooFinanceDataSource._normalise(raw, "SPY", "1d") assert out[ADJUSTED_CLOSE].iloc[0] == out[CLOSE].iloc[0] assert "has no adjusted close" in caplog.text def test_yahoo_config_can_select_continuous_calendar() -> None: + from quantlab.data.calendar import is_247 + config = ExperimentConfig.from_dict( { "experiment_name": "yahoo_crypto", "data": { - "source": "yahoo", - "symbols": ["BTC-USD"], + "instruments": [ + {"symbol": "BTC-USD", "source": "yahoo", "calendar": "24/7"} + ], "start_date": "2024-01-01", "end_date": "2024-02-01", - "market_calendar": "24/7", }, "strategy": {"name": "buy_and_hold"}, } ) - assert config.data.is_247_market is True + assert is_247(config.data.instruments[0].calendar) is True diff --git a/tests/unit/test_data_cache_hardening.py b/tests/unit/test_data_cache_hardening.py index 9fdeb58..c81577e 100644 --- a/tests/unit/test_data_cache_hardening.py +++ b/tests/unit/test_data_cache_hardening.py @@ -53,7 +53,7 @@ def test_hourly_247_cache_requires_safely_closed_hours_today( "binance", "BTCUSDT", "1h", - is_247_market=True, + calendar="24/7", ) assert not storage.cache_covers( "binance", @@ -61,7 +61,7 @@ def test_hourly_247_cache_requires_safely_closed_hours_today( "1h", date(2026, 8, 7), date(2026, 8, 8), - is_247_market=True, + calendar="24/7", ) safely_closed_today = pd.date_range("2026-08-08", periods=15, freq="h") @@ -70,7 +70,7 @@ def test_hourly_247_cache_requires_safely_closed_hours_today( "binance", "BTCUSDT", "1h", - is_247_market=True, + calendar="24/7", ) assert storage.cache_covers( "binance", @@ -78,10 +78,59 @@ def test_hourly_247_cache_requires_safely_closed_hours_today( "1h", date(2026, 8, 7), date(2026, 8, 8), - is_247_market=True, + calendar="24/7", ) +@pytest.mark.parametrize( + ("frequency", "calendar", "bar_timestamp"), + [ + ("1h", "24/7", pd.Timestamp("2024-01-03 10:00:00")), + ("1d", "XNYS", pd.Timestamp("2024-01-03")), # Wednesday + ("1w", "XNYS", pd.Timestamp("2024-01-03")), # week ending Friday + ("1mo", "XNYS", pd.Timestamp("2024-01-15")), # month ending Jan 31 + ], +) +def test_drop_still_open_bars_requires_posting_lag_past_bucket_close( + frequency: str, + calendar: str, + bar_timestamp: pd.Timestamp, + monkeypatch: pytest.MonkeyPatch, +) -> None: + """A bar must stay hidden from the served view not just while its own + bucket is open, but until this frequency's posting-lag tolerance has + *also* elapsed past that bucket's close -- the same threshold every + cache-coverage check already uses to decide a bar is safe to trust (see + ``_posting_lag_for``). Checked at the exact boundary instants (not just + a second to either side of them) -- ``_drop_still_open_bars`` compares + with ``<=``, so a bar becomes safe the instant ``now`` reaches + ``bucket_end + posting_lag``, not only strictly after it -- across + hourly, daily, weekly and monthly frequencies.""" + from quantlab.data.calendar import bar_bucket_end + from quantlab.data.storage import _drop_still_open_bars, _posting_lag_for + + frame = _ohlcv([bar_timestamp]) + bucket_end = bar_bucket_end( + pd.Series([bar_timestamp]), frequency, calendar=calendar + ).iloc[0] + posting_lag = _posting_lag_for(frequency) + epsilon = pd.Timedelta(seconds=1) + safe_at = bucket_end + posting_lag + + boundaries = [ + (bucket_end - epsilon, 0, "just before bucket close"), + (bucket_end, 0, "exactly at bucket close"), + (bucket_end + epsilon, 0, "just after close, before posting lag"), + (safe_at - epsilon, 0, "just before posting lag elapses"), + (safe_at, 1, "exactly at the posting-lag boundary"), + (safe_at + epsilon, 1, "just after posting lag elapses"), + ] + for now, expected_len, label in boundaries: + monkeypatch.setattr(storage_module, "_utc_now", lambda now=now: now) + served = _drop_still_open_bars(frame, frequency, calendar=calendar) + assert len(served) == expected_len, label + + def test_equity_hourly_cache_requires_the_final_requested_session( tmp_path: Path, monkeypatch: pytest.MonkeyPatch ) -> None: @@ -91,16 +140,16 @@ def test_equity_hourly_cache_requires_the_final_requested_session( storage = ParquetStorage(tmp_path / "cache", tmp_path / "metadata") days = pd.date_range("2024-01-02", "2024-01-05", freq="B") hours = [day + pd.Timedelta(hours=hour) for day in days for hour in range(9, 16)] - storage.write_symbol(_ohlcv(hours), "yahoo", "AAA", "1h") + storage.write_symbol(_ohlcv(hours), "yahoo", "AAA", "1h", calendar="XNYS") assert not storage.cache_covers( - "yahoo", "AAA", "1h", date(2024, 1, 2), date(2024, 1, 8) + "yahoo", "AAA", "1h", date(2024, 1, 2), date(2024, 1, 8), calendar="XNYS" ) monday = [pd.Timestamp("2024-01-08") + pd.Timedelta(hours=h) for h in range(9, 16)] - storage.write_symbol(_ohlcv(monday), "yahoo", "AAA", "1h") + storage.write_symbol(_ohlcv(monday), "yahoo", "AAA", "1h", calendar="XNYS") assert storage.cache_covers( - "yahoo", "AAA", "1h", date(2024, 1, 2), date(2024, 1, 8) + "yahoo", "AAA", "1h", date(2024, 1, 2), date(2024, 1, 8), calendar="XNYS" ) @@ -135,6 +184,246 @@ def test_resampler_rejects_duplicates_and_unknown_frequencies() -> None: resample_ohlcv(frame.iloc[[0]], "2h", source_frequency="1h") +def test_resampler_without_a_calendar_splits_a_utc_midnight_crossing_session() -> None: + """Baseline (documents current default behaviour, not the desired one): + with no ``calendar`` passed, two hourly bars from the SAME XASX session + (which opens before UTC midnight of its own label date under daylight + saving) land in two different daily output bars, purely because they + fall on two different raw UTC calendar days.""" + from quantlab.data.calendar import sessions + + schedule = sessions("XASX", pd.Timestamp("2024-01-01"), pd.Timestamp("2024-01-05")) + market_open = schedule.iloc[0]["market_open"] + assert market_open.date() < schedule.index[0].date() # confirms the crossing + + bars = pd.DatetimeIndex([market_open, market_open + pd.Timedelta(hours=1)]) + data = _ohlcv(bars, symbol="BHP") + daily = resample_ohlcv(data, "1d", source_frequency="1h") + assert len(daily) == 2 + + +def test_resampler_with_calendar_merges_a_utc_midnight_crossing_session() -> None: + """The fix: passing the instrument's own calendar groups by its real + trading session instead of a raw UTC period, so the same two bars from + test_resampler_without_a_calendar_splits_a_utc_midnight_crossing_session + merge into the one daily bar they actually belong to.""" + from quantlab.data.calendar import sessions + + schedule = sessions("XASX", pd.Timestamp("2024-01-01"), pd.Timestamp("2024-01-05")) + session_date = schedule.index[0] + market_open = schedule.iloc[0]["market_open"] + + bars = pd.DatetimeIndex([market_open, market_open + pd.Timedelta(hours=1)]) + data = pd.DataFrame( + { + "timestamp": bars, + "symbol": "BHP", + "open": [10.0, 10.5], + "high": [10.5, 11.0], + "low": [9.5, 10.0], + "close": [10.2, 10.8], + "adjusted_close": [10.2, 10.8], + "volume": [100.0, 200.0], + } + ) + daily = resample_ohlcv(data, "1d", source_frequency="1h", calendar="XASX") + assert len(daily) == 1 + assert daily["timestamp"].iloc[0] == pd.Timestamp(session_date) + assert daily["open"].iloc[0] == 10.0 # first chronologically, not first per UTC day + assert daily["close"].iloc[0] == 10.8 # last chronologically + assert daily["volume"].iloc[0] == 300.0 + + +def test_resampler_weekly_xnys_produces_one_bar_per_monday_sunday_week() -> None: + """A full XNYS week (Tue-Fri, since Monday Jan 1 is a holiday) plus the + following Mon-Fri week must resample into exactly one weekly bar each, + Monday-labelled -- ``Period(freq="W-MON")`` means "week *ending* on + Monday" (Tuesday..Monday), not "week starting on Monday", so grouping by + it would wrongly split a Mon-Fri week into a lone Monday bar plus a + Tue-Fri remainder attributed to the next week.""" + dates = pd.bdate_range("2024-01-02", "2024-01-12") # Tue-Fri, then Mon-Fri + data = pd.DataFrame( + { + "timestamp": dates, + "symbol": "AAPL", + "open": range(len(dates)), + "high": range(len(dates)), + "low": range(len(dates)), + "close": range(len(dates)), + "adjusted_close": range(len(dates)), + "volume": 100.0, + } + ).astype( + { + "open": float, + "high": float, + "low": float, + "close": float, + "adjusted_close": float, + } + ) + + for cal in (None, "XNYS"): + weekly = resample_ohlcv( + data, "1w", source_frequency="1d", **({"calendar": cal} if cal else {}) + ) + assert len(weekly) == 2 + assert weekly["timestamp"].tolist() == [ + pd.Timestamp("2024-01-01"), + pd.Timestamp("2024-01-08"), + ] + # Week 1 (Jan 2-5, 4 rows: opens 0-3) must stay a single bar, not + # split into a lone Monday (there is none -- Jan 1 is a holiday) and + # a remainder. + assert weekly["open"].iloc[0] == 0.0 + assert weekly["close"].iloc[0] == 3.0 + assert weekly["open"].iloc[1] == 4.0 + assert weekly["close"].iloc[1] == 8.0 + + +def test_resampler_weekly_with_utc_midnight_crossing_calendar_aligns_to_monday() -> ( + None +): + """Same Monday..Sunday week-boundary bug, but for a calendar whose own + daily bars are timestamped via session_labels (real trading-session + dates that can themselves cross UTC midnight) rather than raw calendar + dates -- weekly resampling on top of that must still group Monday + through Sunday, not Tuesday through Monday.""" + from quantlab.data.calendar import sessions + + schedule = sessions("XASX", pd.Timestamp("2024-01-01"), pd.Timestamp("2024-01-14")) + session_dates = list(schedule.index) + opens = [schedule.loc[d, "market_open"] for d in session_dates] + data = pd.DataFrame( + { + "timestamp": opens, + "symbol": "BHP", + "open": range(len(opens)), + "high": range(len(opens)), + "low": range(len(opens)), + "close": range(len(opens)), + "adjusted_close": range(len(opens)), + "volume": 100.0, + } + ).astype( + { + "open": float, + "high": float, + "low": float, + "close": float, + "adjusted_close": float, + } + ) + + weekly = resample_ohlcv(data, "1w", source_frequency="1d", calendar="XASX") + # Every output timestamp must be a Monday, and every session must land + # in the week containing its own real session date. + assert (pd.DatetimeIndex(weekly["timestamp"]).dayofweek == 0).all() + expected_weeks = sorted( + {d.normalize() - pd.Timedelta(days=d.dayofweek) for d in session_dates} + ) + assert weekly["timestamp"].tolist() == expected_weeks + + +def test_resampler_weekly_with_a_non_western_trading_week_does_not_split_it() -> None: + """A calendar whose trading week isn't Monday-Sunday (XSAU trades + Sunday-Thursday) must never have its own real trading week split + across two output bars just because a fixed ISO week boundary glues + Sunday to the previous week instead of the Monday-Thursday sessions it + actually trades alongside.""" + from quantlab.data.calendar import sessions + + schedule = sessions("XSAU", pd.Timestamp("2024-01-07"), pd.Timestamp("2024-01-11")) + dates = list(schedule.index) + assert [d.strftime("%a") for d in dates] == ["Sun", "Mon", "Tue", "Wed", "Thu"] + data = pd.DataFrame( + { + "timestamp": dates, + "symbol": "X", + "open": range(len(dates)), + "high": range(len(dates)), + "low": range(len(dates)), + "close": range(len(dates)), + "adjusted_close": range(len(dates)), + "volume": 100.0, + } + ).astype( + { + "open": float, + "high": float, + "low": float, + "close": float, + "adjusted_close": float, + } + ) + + weekly = resample_ohlcv(data, "1w", source_frequency="1d", calendar="XSAU") + # All five sessions (Sun-Thu) are one real trading week -- must produce + # exactly one bar, not split Sunday off into its own. + assert len(weekly) == 1 + assert weekly["timestamp"].iloc[0] == pd.Timestamp("2024-01-07") + assert weekly["open"].iloc[0] == 0.0 + assert weekly["close"].iloc[0] == 4.0 + + +def _ohlcv_frame(dates: list[str], *, symbol: str = "AAA") -> pd.DataFrame: + return pd.DataFrame( + { + "timestamp": pd.to_datetime(dates), + "symbol": symbol, + "open": 1.0, + "high": 1.0, + "low": 1.0, + "close": 1.0, + "adjusted_close": 1.0, + "volume": 100.0, + } + ) + + +def test_resample_infers_daily_source_frequency_across_a_weekend_gap() -> None: + """Two adjacent daily bars, Friday then Monday, are 3 raw calendar days + apart -- a literal-gap inference would misread that as a 3-day source + frequency and then refuse to resample it even to '1d' itself, since a + 3-day source is (wrongly) 'coarser' than a 1-day target.""" + data = _ohlcv_frame(["2024-01-05", "2024-01-08"]) # Friday, Monday + out = resample_ohlcv(data, "1d") + assert len(out) == 2 + + +def test_resample_infers_monthly_source_frequency_from_a_31_day_gap() -> None: + """Two adjacent monthly bars (Jan 1st, Feb 1st) are a genuine 31 raw + calendar days apart, while FREQUENCY_TIMEDELTA['1mo'] is a fixed nominal + 30 days -- a literal-gap comparison would treat the observed 31-day + source as coarser than the 30-day '1mo' target and refuse even a + monthly-to-monthly no-op resample.""" + data = _ohlcv_frame(["2024-01-01", "2024-02-01"]) + out = resample_ohlcv(data, "1mo") + assert len(out) == 2 + + +def test_weekly_cache_covers_a_non_western_trading_week_without_a_false_gap( + tmp_path: Path, +) -> None: + """A single weekly bar labeled at the start of an XSAU (Sunday-Thursday) + trading week must be recognised as complete for a request spanning only + that same week -- grouping the gap check by a fixed Monday-Sunday ISO + week would split that one real week across two ISO periods and report a + perfectly complete cache as having an internal gap, forcing a spurious + re-download.""" + storage = ParquetStorage(tmp_path / "cache", tmp_path / "metadata") + storage.write_symbol( + _ohlcv_frame(["2024-01-07"], symbol="AAA"), # a Sunday, week start + "yahoo", + "AAA", + "1w", + calendar="XSAU", + ) + assert storage.cache_covers( + "yahoo", "AAA", "1w", date(2024, 1, 7), date(2024, 1, 11), calendar="XSAU" + ) + + class _PartialSource(MarketDataSource): name = "partial" @@ -145,31 +434,33 @@ def download( end: date, frequency: str, *, - is_247_market: bool = False, + calendar: str = "XNYS", ) -> pd.DataFrame: - del symbols, start, end, frequency, is_247_market + del symbols, start, end, frequency, calendar return _ohlcv(["2024-01-03"]) def test_forced_download_returns_the_persisted_merged_frame(tmp_path: Path) -> None: storage = ParquetStorage(tmp_path / "cache", tmp_path / "metadata") - storage.write_symbol(_ohlcv(["2023-12-31", "2024-01-01"]), "partial", "AAA", "1d") + storage.write_symbol( + _ohlcv(["2023-12-31", "2024-01-01"]), "partial", "AAA", "1d", calendar="24/7" + ) config = ExperimentConfig.from_dict( { "experiment_name": "forced_consistency", "data": { - "source": "csv", - "symbols": ["AAA"], + "instruments": [{"symbol": "AAA", "source": "csv", "calendar": "24/7"}], "start_date": "2024-01-01", "end_date": "2024-01-03", - "market_calendar": "24/7", }, "strategy": {"name": "buy_and_hold"}, } ) loader = DataLoader(storage=storage) - returned = loader._download_symbol(_PartialSource(), "AAA", config, force=True) - persisted = storage.read_symbol("partial", "AAA", "1d", is_247_market=True) + returned = loader._download_symbol( + _PartialSource(), config.data.instruments[0], config, force=True + ) + persisted = storage.read_symbol("partial", "AAA", "1d", calendar="24/7") assert persisted is not None pd.testing.assert_frame_equal(returned, persisted) assert returned["timestamp"].dt.strftime("%Y-%m-%d").tolist() == [ @@ -178,24 +469,363 @@ def test_forced_download_returns_the_persisted_merged_frame(tmp_path: Path) -> N ] +def test_write_symbol_never_drops_still_open_bars_from_the_persisted_file( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """The cache key has no calendar component, so the same file must never + depend on which calendar happened to write last. A Wednesday bar is + already settled under XNYS (its close, plus the daily posting-lag + tolerance, is well before UTC midnight the next day) but still 'open' + under a 24/7 calendar (whose daily bucket, plus that same tolerance, + settles even later) -- writing it under either calendar must never let + that calendar's own settlement opinion decide whether the bar survives + in the FILE itself, which would silently delete another experiment's + already-settled data.""" + write_time = pd.Timestamp("2024-01-03 22:00:00") # after XNYS close + monkeypatch.setattr(storage_module, "_utc_now", lambda: write_time) + storage = ParquetStorage(tmp_path / "cache", tmp_path / "metadata") + + bar = _ohlcv(["2024-01-03"], symbol="AAA") + storage.write_symbol(bar, "yahoo", "AAA", "1d", calendar="XNYS") + # A second experiment on the same (source, symbol, frequency) key, using + # a 24/7 calendar, writes next -- it must not purge XNYS's already- + # settled bar from the shared file just because 24/7 still considers it + # provisional. + storage.write_symbol(bar.iloc[:0], "yahoo", "AAA", "1d", calendar="24/7") + + raw = pd.read_parquet(storage._cache_path("yahoo", "AAA", "1d")) + assert len(raw) == 1 + + # Each caller's own read still applies its own settlement opinion -- + # only the persisted file is calendar-independent. XNYS's close (~21:00 + # UTC) plus the 12h daily posting lag has passed by 10:00 the next day; + # 24/7's bucket (open until UTC midnight) plus that same lag hasn't. + read_time = pd.Timestamp("2024-01-04 10:00:00") + monkeypatch.setattr(storage_module, "_utc_now", lambda: read_time) + xnys_view = storage.read_symbol("yahoo", "AAA", "1d", calendar="XNYS") + always_open_view = storage.read_symbol("yahoo", "AAA", "1d", calendar="24/7") + assert xnys_view is not None + assert len(xnys_view) == 1 + assert always_open_view is not None + assert always_open_view.empty + + +def test_cache_covers_forces_a_refresh_of_a_bar_settled_after_it_was_written( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """write_symbol's own docstring says a still-open bar is 'naturally + superseded once its real, closed value is next downloaded' -- but + nothing forces that next download to actually happen: coverage-checking + only checks presence, not whether the bar was still forming when it was + fetched. Without the per-row `_fetched_at` provenance write_symbol + always sets, once enough wall time passes for the bar to look 'settled' + from read_symbol's point of view, cache_covers would report the range + as fully covered forever, silently serving the stale provisional OHLCV + value fetched while the market was still open.""" + storage = ParquetStorage(tmp_path / "cache", tmp_path / "metadata") + bar_date = pd.Timestamp("2024-01-16") + + # Fetched at 19:00 UTC -- XNYS (closes ~21:00 UTC in winter) is still + # open, so this bar is genuinely provisional at write time. + still_open_now = pd.Timestamp("2024-01-16 19:00:00") + monkeypatch.setattr(storage_module, "_utc_now", lambda: still_open_now) + storage.write_symbol( + _ohlcv([bar_date], symbol="AAPL"), "yahoo", "AAPL", "1d", calendar="XNYS" + ) + + served_before_close = storage.read_symbol("yahoo", "AAPL", "1d", calendar="XNYS") + assert served_before_close is not None + assert served_before_close.empty # correctly masked while still open + + # Two days later: the bar has genuinely settled by now, but nothing has + # re-downloaded it -- the cached value is still the stale provisional one. + monkeypatch.setattr( + storage_module, "_utc_now", lambda: pd.Timestamp("2024-01-18 12:00:00") + ) + covers = storage.cache_covers( + "yahoo", "AAPL", "1d", bar_date.date(), bar_date.date(), calendar="XNYS" + ) + assert covers is False # must force a redownload, never silently accept + + +def test_cache_staleness_check_is_per_row_not_per_file( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """A per-file `last_write_time` would be wrongly refreshed by any write + to the file, even one touching an unrelated, older date range -- making + a genuinely still-provisional bar look freshly confirmed. Provenance + must be tracked per row: a write to one date must never mark a + *different* date's bar as freshly written.""" + storage = ParquetStorage(tmp_path / "cache", tmp_path / "metadata") + provisional_date = pd.Timestamp("2024-01-16") + + still_open_now = pd.Timestamp("2024-01-16 19:00:00") + monkeypatch.setattr(storage_module, "_utc_now", lambda: still_open_now) + storage.write_symbol( + _ohlcv([provisional_date], symbol="AAPL"), + "yahoo", + "AAPL", + "1d", + calendar="XNYS", + ) + + # A later write to a completely different, older date -- must not reset + # the provisional bar's own fetch time. + unrelated_write_time = pd.Timestamp("2024-01-17 08:00:00") + monkeypatch.setattr(storage_module, "_utc_now", lambda: unrelated_write_time) + older_date = pd.Timestamp("2024-01-02") + storage.write_symbol( + _ohlcv([older_date], symbol="AAPL"), + "yahoo", + "AAPL", + "1d", + calendar="XNYS", + replace_start=older_date.date(), + replace_end=older_date.date(), + ) + + monkeypatch.setattr( + storage_module, "_utc_now", lambda: pd.Timestamp("2024-01-18 12:00:00") + ) + covers = storage.cache_covers( + "yahoo", + "AAPL", + "1d", + provisional_date.date(), + provisional_date.date(), + calendar="XNYS", + ) + assert covers is False + + +def test_cache_staleness_check_still_finds_a_stale_bar_buried_mid_file( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """Checking only the newest (frontier) row would stop catching a stale + bar the moment a newer bar is appended -- the stale bar becomes an + 'internal' row and is silently never revisited again.""" + storage = ParquetStorage(tmp_path / "cache", tmp_path / "metadata") + provisional_date = pd.Timestamp("2024-01-16") + + still_open_now = pd.Timestamp("2024-01-16 19:00:00") + monkeypatch.setattr(storage_module, "_utc_now", lambda: still_open_now) + storage.write_symbol( + _ohlcv([provisional_date], symbol="BTC"), "yahoo", "BTC", "1d", calendar="XNYS" + ) + + # A genuinely new bar is appended the next day -- the old provisional + # bar is now buried mid-file, no longer the frontier. + next_day_close = pd.Timestamp("2024-01-17 22:00:00") + monkeypatch.setattr(storage_module, "_utc_now", lambda: next_day_close) + storage.write_symbol( + _ohlcv([pd.Timestamp("2024-01-17")], symbol="BTC"), + "yahoo", + "BTC", + "1d", + calendar="XNYS", + ) + + monkeypatch.setattr( + storage_module, "_utc_now", lambda: pd.Timestamp("2024-01-20 12:00:00") + ) + covers = storage.cache_covers( + "yahoo", + "BTC", + "1d", + provisional_date.date(), + provisional_date.date(), + calendar="XNYS", + ) + assert covers is False + + +def test_cache_staleness_respects_the_posting_lag_not_just_bucket_close( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """A bar fetched moments after its bucket closed, but before the + posting-lag tolerance (12h for daily bars) has elapsed, is still fair + game to be a provider's not-yet-finalised value -- it must still be + treated as needing a refresh once the full lag has since passed without + one, not accepted as final the instant the bucket itself closed.""" + from quantlab.data.calendar import daily_equity_bucket_settlement + + storage = ParquetStorage(tmp_path / "cache", tmp_path / "metadata") + bar_date = pd.Timestamp("2024-02-01") + bucket_end = daily_equity_bucket_settlement(bar_date, calendar="XNYS") + + just_after_close = bucket_end + pd.Timedelta(minutes=1) + monkeypatch.setattr(storage_module, "_utc_now", lambda: just_after_close) + storage.write_symbol( + _ohlcv([bar_date], symbol="EARLY"), "yahoo", "EARLY", "1d", calendar="XNYS" + ) + + # Well past the 12h posting lag, still no refresh. + after_posting_lag = bucket_end + pd.Timedelta(hours=13) + monkeypatch.setattr(storage_module, "_utc_now", lambda: after_posting_lag) + covers = storage.cache_covers( + "yahoo", "EARLY", "1d", bar_date.date(), bar_date.date(), calendar="XNYS" + ) + assert covers is False + + +def test_cache_staleness_check_ignores_a_stale_row_outside_the_requested_range( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """A row's own bucket can sit entirely outside the requested range (an + older bar the frontier has since moved past) -- a narrow re-download of + the requested range can never refresh that unrelated row, so it must + never keep the cache permanently 'not covering' requests that don't + touch it. Only a stale row that overlaps the requested range should + force a refresh (see the sibling test below).""" + storage = ParquetStorage(tmp_path / "cache", tmp_path / "metadata") + + # Jan 16: fetched while still provisional -- stays stale forever, but + # it's outside every later request for Jan 17 alone. + still_open_now = pd.Timestamp("2024-01-16 19:00:00") + monkeypatch.setattr(storage_module, "_utc_now", lambda: still_open_now) + storage.write_symbol( + _ohlcv([pd.Timestamp("2024-01-16")], symbol="AAA"), + "yahoo", + "AAA", + "1d", + calendar="XNYS", + ) + + # Jan 17: fetched properly, well after its own close + posting lag. + proper_time = pd.Timestamp("2024-01-18 10:00:00") + monkeypatch.setattr(storage_module, "_utc_now", lambda: proper_time) + storage.write_symbol( + _ohlcv([pd.Timestamp("2024-01-17")], symbol="AAA"), + "yahoo", + "AAA", + "1d", + calendar="XNYS", + ) + + monkeypatch.setattr( + storage_module, "_utc_now", lambda: pd.Timestamp("2024-01-20 12:00:00") + ) + # A request for Jan 17 only is unaffected by Jan 16's stale row. + assert storage.cache_covers( + "yahoo", "AAA", "1d", date(2024, 1, 17), date(2024, 1, 17), calendar="XNYS" + ) + # A request that actually includes Jan 16 still catches its staleness. + assert not storage.cache_covers( + "yahoo", "AAA", "1d", date(2024, 1, 16), date(2024, 1, 17), calendar="XNYS" + ) + + +def test_cache_covers_rejects_a_v3_row_with_unknown_provenance( + tmp_path: Path, +) -> None: + """A v3-format cache file's per-row provenance guarantee is only real if + a row lacking it (e.g. one written directly via :meth:`ParquetStorage. + save`, bypassing :meth:`write_symbol`; production never does this) is + treated as unverified rather than silently trusted -- otherwise the + guarantee is bypassable by any code path that skips ``write_symbol``.""" + storage = ParquetStorage(tmp_path / "cache", tmp_path / "metadata") + bar_date = pd.Timestamp("2024-01-16") + path = storage._cache_path("yahoo", "AAA", "1d") + storage.save(_ohlcv([bar_date], symbol="AAA"), path) + + assert not storage.cache_covers( + "yahoo", "AAA", "1d", bar_date.date(), bar_date.date(), calendar="XNYS" + ) + + +def test_cache_staleness_check_survives_an_empty_write( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """An empty incoming write (e.g. a provider returning zero new rows for + an already-covered range) must not crash the staleness check, and must + not disturb the existing rows' own provenance.""" + storage = ParquetStorage(tmp_path / "cache", tmp_path / "metadata") + bar_date = pd.Timestamp("2024-01-16") + + still_open_now = pd.Timestamp("2024-01-16 19:00:00") + monkeypatch.setattr(storage_module, "_utc_now", lambda: still_open_now) + storage.write_symbol( + _ohlcv([bar_date], symbol="AAPL"), "yahoo", "AAPL", "1d", calendar="XNYS" + ) + + empty = _ohlcv([], symbol="AAPL").astype( + {"timestamp": "datetime64[ns]", "symbol": "object"} + ) + monkeypatch.setattr( + storage_module, "_utc_now", lambda: pd.Timestamp("2024-01-17 08:00:00") + ) + storage.write_symbol(empty, "yahoo", "AAPL", "1d", calendar="XNYS") + + monkeypatch.setattr( + storage_module, "_utc_now", lambda: pd.Timestamp("2024-01-18 12:00:00") + ) + covers = storage.cache_covers( + "yahoo", "AAPL", "1d", bar_date.date(), bar_date.date(), calendar="XNYS" + ) + assert covers is False + + +def test_forced_replacement_purges_a_session_bar_crossing_utc_midnight( + tmp_path: Path, +) -> None: + """A naive [UTC midnight, next UTC midnight) replace window would miss a + genuine session bar for a calendar whose local session opens before UTC + midnight of its own label date (e.g. XASX under daylight saving, + UTC+11) -- the stale bar would silently survive a forced replacement + meant to purge it.""" + from quantlab.data.calendar import sessions + + schedule = sessions("XASX", pd.Timestamp("2024-01-01"), pd.Timestamp("2024-01-31")) + session_date = schedule.index[0] + market_open = schedule.iloc[0]["market_open"] + assert market_open.date() < session_date.date() # confirms the crossing scenario + + storage = ParquetStorage(tmp_path / "cache", tmp_path / "metadata") + stale = _ohlcv([market_open], symbol="BHP") + storage.write_symbol(stale, "asx", "BHP", "1d", calendar="XASX") + + fresh = _ohlcv([market_open], symbol="BHP", volume=200.0) + storage.write_symbol( + fresh, + "asx", + "BHP", + "1d", + calendar="XASX", + replace_start=session_date.date(), + replace_end=session_date.date(), + ) + raw = pd.read_parquet(storage._cache_path("asx", "BHP", "1d")) + assert len(raw) == 1 + assert raw["volume"].iloc[0] == 200.0 + + def test_storage_deduplicates_the_first_write_and_validates_its_symbol( tmp_path: Path, ) -> None: storage = ParquetStorage(tmp_path / "cache", tmp_path / "metadata") duplicate = _ohlcv(["2024-01-01", "2024-01-01"]) - storage.write_symbol(duplicate, "yahoo", "AAA", "1d") - cached = storage.read_symbol("yahoo", "AAA", "1d") + storage.write_symbol(duplicate, "yahoo", "AAA", "1d", calendar="XNYS") + cached = storage.read_symbol("yahoo", "AAA", "1d", calendar="XNYS") assert cached is not None assert len(cached) == 1 with pytest.raises(DataValidationError, match="rows for"): - storage.write_symbol(_ohlcv(["2024-01-02"], symbol="BBB"), "yahoo", "AAA", "1d") + storage.write_symbol( + _ohlcv(["2024-01-02"], symbol="BBB"), "yahoo", "AAA", "1d", calendar="XNYS" + ) def test_storage_uses_a_versioned_cache_namespace(tmp_path: Path) -> None: + from quantlab.data.storage import _CACHE_FORMAT_VERSION + storage = ParquetStorage(tmp_path / "cache", tmp_path / "metadata") - path = storage.write_symbol(_ohlcv(["2024-01-01"]), "yahoo", "AAA", "1d") - assert path.relative_to(tmp_path / "cache").parts[0] == "v2" + path = storage.write_symbol( + _ohlcv(["2024-01-01"]), "yahoo", "AAA", "1d", calendar="XNYS" + ) + # Asserted against the live constant, not a hardcoded literal, so this + # test documents "the cache is namespaced by version" without needing an + # update on every future version bump. + assert path.relative_to(tmp_path / "cache").parts[0] == _CACHE_FORMAT_VERSION def test_atomic_save_keeps_the_previous_file_when_serialization_fails( @@ -225,11 +855,9 @@ def test_loader_refuses_a_symbol_with_zero_usable_rows(tmp_path: Path) -> None: { "experiment_name": "mislabeled_csv", "data": { - "source": "csv", - "symbols": ["AAA"], + "instruments": [{"symbol": "AAA", "source": "csv", "calendar": "24/7"}], "start_date": "2024-01-01", "end_date": "2024-01-02", - "market_calendar": "24/7", }, "strategy": {"name": "buy_and_hold"}, } diff --git a/tests/unit/test_data_cleaner.py b/tests/unit/test_data_cleaner.py index b4bd71d..4526bc4 100644 --- a/tests/unit/test_data_cleaner.py +++ b/tests/unit/test_data_cleaner.py @@ -6,6 +6,7 @@ import pandas as pd import pytest from tests.conftest import make_ohlcv +from tests.regression_helpers import _UniformCalendar from quantlab.config import MissingValuePolicy from quantlab.constants import CLOSE, HIGH, LOW, SYMBOL, TIMESTAMP, VOLUME @@ -122,14 +123,18 @@ def test_validator_detects_duplicates_strict() -> None: data = _simple("SPY") dup = pd.concat([data, data.iloc[[0]]], ignore_index=True) with pytest.raises(DataValidationError, match="duplicate"): - DataValidator().validate(dup, strict=True) + DataValidator(symbol_calendars=_UniformCalendar("XNYS")).validate( + dup, strict=True + ) def test_validator_detects_negative_price_strict() -> None: data = _simple() data.loc[1, CLOSE] = -1.0 with pytest.raises(DataValidationError, match="non-positive"): - DataValidator().validate(data, strict=True) + DataValidator(symbol_calendars=_UniformCalendar("XNYS")).validate( + data, strict=True + ) def test_validator_detects_high_below_low() -> None: @@ -137,7 +142,9 @@ def test_validator_detects_high_below_low() -> None: # Force an impossible bar: high < low. data.loc[2, HIGH] = 50.0 data.loc[2, LOW] = 200.0 - report = DataValidator().validate(data, strict=False) + report = DataValidator(symbol_calendars=_UniformCalendar("XNYS")).validate( + data, strict=False + ) assert report.invalid_price_count > 0 assert any("OHLC" in w for w in report.warnings) @@ -145,14 +152,18 @@ def test_validator_detects_high_below_low() -> None: def test_validator_report_counts_missing_values() -> None: data = _simple() data.loc[1, CLOSE] = np.nan - report = DataValidator().validate(data, strict=False) + report = DataValidator(symbol_calendars=_UniformCalendar("XNYS")).validate( + data, strict=False + ) assert report.missing_value_count.get(CLOSE) == 1 assert report.row_count == len(data) def test_validator_flags_symbol_absent_via_empty() -> None: empty = _simple().iloc[0:0] - report = DataValidator().validate(empty, strict=False) + report = DataValidator(symbol_calendars=_UniformCalendar("XNYS")).validate( + empty, strict=False + ) assert any("empty" in w.lower() for w in report.warnings) diff --git a/tests/unit/test_data_sources_offline.py b/tests/unit/test_data_sources_offline.py index a8e77cc..8e19245 100644 --- a/tests/unit/test_data_sources_offline.py +++ b/tests/unit/test_data_sources_offline.py @@ -6,8 +6,6 @@ from __future__ import annotations -from datetime import date - import numpy as np import pandas as pd import pytest @@ -30,9 +28,7 @@ def test_yahoo_normalise_flat_columns() -> None: }, index=pd.date_range("2020-01-01", periods=2, name="Date"), ) - out = YahooFinanceDataSource._normalise( - raw, "spy", "1d", pd.Timestamp("2025-01-01"), date(2025, 1, 1) - ) + out = YahooFinanceDataSource._normalise(raw, "spy", "1d") assert list(out["symbol"].unique()) == ["SPY"] assert out["close"].tolist() == [100.5, 101.5] assert out["timestamp"].is_monotonic_increasing @@ -48,9 +44,7 @@ def test_yahoo_normalise_multiindex_columns() -> None: index=idx, columns=cols, ) - out = YahooFinanceDataSource._normalise( - raw, "SPY", "1d", pd.Timestamp("2025-01-01"), date(2025, 1, 1) - ) + out = YahooFinanceDataSource._normalise(raw, "SPY", "1d") assert len(out) == 2 assert (out["close"] > 0).all() diff --git a/tests/unit/test_data_storage.py b/tests/unit/test_data_storage.py index d12338d..3b49c7b 100644 --- a/tests/unit/test_data_storage.py +++ b/tests/unit/test_data_storage.py @@ -29,14 +29,14 @@ def test_parquet_roundtrip(tmp_path: Path) -> None: def test_symbol_cache_merge_and_cover(tmp_path: Path) -> None: storage = ParquetStorage(cache_dir=tmp_path / "cache", metadata_dir=tmp_path / "md") early = make_ohlcv("AAA", np.linspace(100, 105, 6), start="2020-01-01") - storage.write_symbol(early, "yahoo", "AAA", "1d") + storage.write_symbol(early, "yahoo", "AAA", "1d", calendar="XNYS") assert storage.cache_covers( - "yahoo", "AAA", "1d", date(2020, 1, 1), date(2020, 1, 3) + "yahoo", "AAA", "1d", date(2020, 1, 1), date(2020, 1, 3), calendar="XNYS" ) # A later slice is merged in without duplicating timestamps. later = make_ohlcv("AAA", np.linspace(106, 112, 7), start="2020-01-09") - storage.write_symbol(later, "yahoo", "AAA", "1d") - merged = storage.read_symbol("yahoo", "AAA", "1d") + storage.write_symbol(later, "yahoo", "AAA", "1d", calendar="XNYS") + merged = storage.read_symbol("yahoo", "AAA", "1d", calendar="XNYS") assert merged is not None assert not merged.duplicated(subset=[TIMESTAMP]).any() @@ -71,12 +71,13 @@ def test_csv_source_loader(tmp_path: Path) -> None: { "experiment_name": "csv_test", "data": { - "source": "csv", - "symbols": ["AAA", "BBB"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + {"symbol": "BBB", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2020-02-15", "missing_value_policy": "drop", - "market_calendar": "XNYS", }, "strategy": {"name": "buy_and_hold"}, } diff --git a/tests/unit/test_logging_config.py b/tests/unit/test_logging_config.py index 5199247..f44985f 100644 --- a/tests/unit/test_logging_config.py +++ b/tests/unit/test_logging_config.py @@ -2,7 +2,9 @@ from __future__ import annotations +import io import logging +import sys from pathlib import Path from typing import NoReturn @@ -33,11 +35,48 @@ def refuse_file_handler(*args: object, **kwargs: object) -> NoReturn: ) assert configured is logger + # isinstance, not an exact type check: the console handler is + # _CurrentStderrHandler, a StreamHandler subclass that always + # resolves sys.stderr fresh on every emit instead of a snapshot + # taken at construction time (see its docstring for why). assert any( - type(handler) is logging.StreamHandler for handler in logger.handlers + isinstance(handler, logging.StreamHandler) for handler in logger.handlers ) assert "File logging disabled" in capsys.readouterr().err finally: logger.handlers.clear() logger.handlers.extend(original_handlers) logger.propagate = original_propagate + + +def test_console_handler_survives_sys_stderr_being_swapped_and_closed() -> None: + """A plain logging.StreamHandler() snapshots sys.stderr once at + construction; if the process later replaces sys.stderr (e.g. pytest + swaps in a fresh per-test capture object and closes the previous one -- + the console handler is only ever built once per process, gated on + configure_logging's own _CONFIGURED latch), it would try to write to + the now-closed old stream and log a swallowed "I/O operation on closed + file" error instead of the real message. The console handler must + resolve sys.stderr fresh on every emit instead.""" + handler = logging_config._CurrentStderrHandler() + logger = logging.getLogger("quantlab-test-console-handler-survives") + logger.addHandler(handler) + logger.setLevel(logging.WARNING) + logger.propagate = False + old_stderr = sys.stderr + try: + first = io.StringIO() + sys.stderr = first + logger.warning("first message") + first.close() + + second = io.StringIO() + sys.stderr = second + logger.warning("second message") + finally: + sys.stderr = old_stderr + logger.removeHandler(handler) + + output = second.getvalue() + assert "second message" in output + assert "Logging error" not in output diff --git a/tests/unit/test_orders.py b/tests/unit/test_orders.py index 16c16b6..71f9106 100644 --- a/tests/unit/test_orders.py +++ b/tests/unit/test_orders.py @@ -9,6 +9,7 @@ from quantlab.exceptions import BacktestError from quantlab.execution.orders import ( executed_weights, + shift_respecting_tradability, traded_notional, weight_changes, ) @@ -46,3 +47,60 @@ def test_traded_notional_rejects_missing_equity_dates() -> None: with pytest.raises(BacktestError, match="exactly the execution-date index"): traded_notional(changes, equity) + + +def test_shift_respecting_tradability_no_leading_nan_through_closure() -> None: + """A symbol whose very first tradable row is immediately followed by a + multi-row closure (e.g. a mixed-calendar history starting on a Friday, + where the weekend rows only exist because another, always-open + instrument shares the combined index) must never leave NaN on those + closed rows: there is no prior decision, so -- same "start flat" + convention as everywhere else -- they hold 0.0, not NaN propagated by a + leading gap that ffill can't reach.""" + index = pd.date_range("2024-01-05", periods=4, freq="D") # Fri, Sat, Sun, Mon + held = pd.DataFrame( + {"AAPL": [0.5, 0.5, 0.5, 0.6], "BTC": [0.5, 0.5, 0.5, 0.4]}, index=index + ) + tradable = pd.DataFrame( + {"AAPL": [True, False, False, True], "BTC": [True, True, True, True]}, + index=index, + ) + shifted = shift_respecting_tradability(held, 1, tradable) + assert shifted["AAPL"].tolist() == [0.0, 0.0, 0.0, 0.5] + assert np.isfinite(shifted.to_numpy()).all() + + executed = executed_weights(held, tradable=tradable) + assert np.isfinite(executed.to_numpy()).all() + assert executed["AAPL"].tolist() == [0.0, 0.0, 0.0, 0.5] + + +def test_shift_respecting_tradability_rejects_a_negative_periods() -> None: + index = pd.date_range("2024-01-01", periods=3, freq="D") + held = pd.DataFrame({"AAA": [0.5, 0.5, 0.5]}, index=index) + tradable = pd.DataFrame({"AAA": [True, True, True]}, index=index) + + with pytest.raises(BacktestError, match="non-negative integer"): + shift_respecting_tradability(held, -1, tradable) + + +def test_shift_respecting_tradability_rejects_misaligned_tradable_axes() -> None: + index = pd.date_range("2024-01-01", periods=3, freq="D") + held = pd.DataFrame({"AAA": [0.5, 0.5, 0.5]}, index=index) + # Same values, different (reversed) row order -- a silent misalignment + # this must catch rather than trading the wrong row against the wrong + # tradability flag. + tradable = pd.DataFrame({"AAA": [True, True, True]}, index=index[::-1]) + + with pytest.raises(BacktestError, match="same index and columns"): + shift_respecting_tradability(held, 1, tradable) + + +def test_shift_respecting_tradability_rejects_non_boolean_tradable_values() -> None: + """A string 'False' would otherwise silently coerce to True under a bare + ``.to_numpy(dtype=bool)`` -- this must be rejected outright instead.""" + index = pd.date_range("2024-01-01", periods=3, freq="D") + held = pd.DataFrame({"AAA": [0.5, 0.5, 0.5]}, index=index) + tradable = pd.DataFrame({"AAA": ["True", "False", "True"]}, index=index) + + with pytest.raises(BacktestError, match="boolean dtype"): + shift_respecting_tradability(held, 1, tradable) diff --git a/tests/unit/test_portfolio.py b/tests/unit/test_portfolio.py index b353401..5f50806 100644 --- a/tests/unit/test_portfolio.py +++ b/tests/unit/test_portfolio.py @@ -119,6 +119,31 @@ def test_rebalance_dates_monthly() -> None: assert dates[0] == idx[0] +def test_rebalance_dates_weekly_does_not_split_a_non_western_trading_week() -> None: + """XSAU trades Sunday-Thursday. Grouping by a fixed Monday-Sunday ISO + week (`.to_period("W")`) would put XSAU's Sunday session in the + *previous* ISO week from its own Monday-Thursday sessions, splitting one + real trading week into two rebalances instead of one -- calendar-aware + grouping must use the calendar's own trading week instead (mirrors the + equivalent resampler fix, see quantlab.data.resampler._resample_by_session).""" + idx = pd.DatetimeIndex( + [ + "2024-01-07", + "2024-01-08", + "2024-01-09", + "2024-01-10", + "2024-01-11", # week 1: Sun-Thu + "2024-01-14", + "2024-01-15", + "2024-01-16", + "2024-01-17", + "2024-01-18", # week 2: Sun-Thu + ] + ) + dates = rebalance_dates(idx, RebalanceFrequency.WEEKLY, calendar="XSAU") + assert list(dates) == [idx[0], idx[5]] + + def test_apply_rebalancing_holds_between_dates() -> None: idx = pd.date_range("2020-01-01", periods=60, freq="D") target = pd.DataFrame(np.linspace(0.1, 0.9, 60), index=idx, columns=["A"]) diff --git a/tests/unit/test_portfolio_hardening.py b/tests/unit/test_portfolio_hardening.py index 10ccf70..e494cc7 100644 --- a/tests/unit/test_portfolio_hardening.py +++ b/tests/unit/test_portfolio_hardening.py @@ -13,6 +13,7 @@ import pytest import quantlab.portfolio as portfolio +from quantlab.config import PortfolioConfig from quantlab.exceptions import InvalidConfigurationError from quantlab.portfolio.allocator import ( InverseVolatilityAllocator, @@ -31,6 +32,7 @@ apply_rebalancing, cap_turnover, compute_turnover, + rebalance_and_cap_turnover, rebalance_dates, ) from quantlab.portfolio.volatility_targeting import ( @@ -145,6 +147,25 @@ def test_rebalance_dates_rejects_invalid_frequency_and_duplicate_index() -> None rebalance_dates(pd.date_range("2024-01-01", periods=2), "yearly") +def test_rebalance_and_cap_turnover_rejects_a_non_boolean_tradable_mask() -> None: + """A `tradable` column carrying object-dtype values (e.g. the literal + string 'False') must be rejected explicitly -- a raw + `.to_numpy(dtype=bool)` conversion would otherwise silently coerce any + non-empty string, including 'False' itself, to True. Mirrors + quantlab.execution.orders.validate_execution_frame's identical guard.""" + idx = pd.date_range("2024-01-01", periods=3, freq="D") + targets = pd.DataFrame({"A": [1.0, 1.0, 1.0], "B": [0.0, 0.0, 0.0]}, index=idx) + tradable = pd.DataFrame( + {"A": [True, True, True], "B": ["False", "False", "False"]}, + index=idx, + dtype=object, + ) + with pytest.raises(InvalidConfigurationError, match="boolean"): + rebalance_and_cap_turnover( + targets, PortfolioConfig(allocator="equal_weight"), tradable=tradable + ) + + def test_turnover_functions_reject_non_finite_weights() -> None: bad = pd.DataFrame({"A": [0.5, np.nan, 0.0]}) with pytest.raises(InvalidConfigurationError, match="missing"): diff --git a/tests/unit/test_progress.py b/tests/unit/test_progress.py new file mode 100644 index 0000000..490a23e --- /dev/null +++ b/tests/unit/test_progress.py @@ -0,0 +1,83 @@ +"""Tests for the CLI/dashboard-shared progress pacer.""" + +from __future__ import annotations + +import pytest + +from quantlab.progress import ProgressPacer + + +def test_progress_pacer_has_no_estimate_before_any_pace_is_known() -> None: + pacer = ProgressPacer() + assert pacer.remaining(0, 10) is None + pacer.update(0, 0.0) # the initial done=0 tick establishes no rate yet + assert pacer.remaining(0, 10) is None + + +def test_progress_pacer_matches_a_constant_pace() -> None: + """1 unit per second, 10 units total, 4 done at t=4s -> 6s left.""" + pacer = ProgressPacer() + for done in range(1, 5): + pacer.update(done, float(done)) + assert pacer.remaining(4, 10) == pytest.approx(6.0) + + +def test_progress_pacer_reacts_partially_to_a_single_slow_tick() -> None: + """A single tick implying a slower pace is nudged towards, not fully + adopted (``rising_smoothing=0.4``) — a fully-adopting earlier version + let one noisy tick (parameter-grid candidates genuinely cost different + amounts, so per-tick rate oscillates with no real trend) ratchet the + whole estimate up to that single outlier, observed as the displayed + estimate jumping upward mid-run instead of trending down.""" + pacer = ProgressPacer() + for done in range(1, 6): + pacer.update(done, float(done)) # a steady 1s/unit so far + assert pacer.remaining(5, 10) == pytest.approx(5.0) + + pacer.update(6, 15.0) # this one unit took 10s, not 1s + # rate = 0.4 * 10.0 + 0.6 * 1.0 = 4.6 -> 4 units left * 4.6 = 18.4, + # nowhere near the 40.0 a full jump to the outlier's rate would give. + assert pacer.remaining(6, 10) == pytest.approx(18.4) + + +def test_progress_pacer_still_catches_up_to_a_sustained_slowdown() -> None: + """Several *consecutive* slower ticks (a genuine trend, not one noisy + outlier) must still converge close to the new pace within a handful of + ticks — the property that motivated asymmetric smoothing in the first + place, preserved even after damping the single-tick reaction above.""" + pacer = ProgressPacer() + for done in range(1, 6): + pacer.update(done, float(done)) # a steady 1s/unit so far + for done in range(6, 11): + pacer.update(done, 5.0 + (done - 5) * 10.0) # now a sustained 10s/unit + # rate after 5 consecutive 10s/unit ticks, starting from 1.0: + # 4.6 -> 6.76 -> 8.056 -> 8.8336 -> 9.30016 (within 7% of the true 10.0 + # pace, from a standing start, in only 5 ticks). + assert pacer.remaining(10, 12) == pytest.approx(18.60032, rel=1e-3) + + +def test_progress_pacer_reacts_gradually_to_a_speedup() -> None: + """A tick implying a faster pace than currently tracked is only + partially trusted (the default ``falling_smoothing=0.2``) — one + unusually quick tick shouldn't swing the estimate down only to be + contradicted by the next.""" + pacer = ProgressPacer() + for done in range(1, 6): + pacer.update(done, float(done) * 10.0) # a steady 10s/unit so far + assert pacer.remaining(5, 10) == pytest.approx(50.0) + + pacer.update(6, 51.0) # this one unit took just 1s, not 10s + # rate = 0.2 * 1.0 + 0.8 * 10.0 = 8.2 -> 4 units left * 8.2 = 32.8. + assert pacer.remaining(6, 10) == pytest.approx(32.8) + + +def test_progress_pacer_ignores_non_increasing_updates() -> None: + """A caller reporting the same or an earlier `done` (e.g. a duplicate + tick) must not corrupt the tracked pace or divide by zero.""" + pacer = ProgressPacer() + pacer.update(3, 3.0) + pacer.update(3, 4.0) # same done again, time still passed + pacer.update(2, 5.0) # done went backwards + # No exception, and the pace from the one genuine forward step (3 units + # in 3 seconds) is still what's tracked. + assert pacer.remaining(3, 10) == pytest.approx(7.0) diff --git a/tests/unit/test_regression_data.py b/tests/unit/test_regression_data.py index 1c69474..c018cd7 100644 --- a/tests/unit/test_regression_data.py +++ b/tests/unit/test_regression_data.py @@ -25,6 +25,7 @@ _ohlcv_at, _ohlcv_frame, _try_strategy, + _UniformCalendar, _wf_experiment_config, _write_daily_cache, _write_ohlcv_csv, @@ -45,9 +46,9 @@ def test_adv_only_uses_volume_known_through_prior_day() -> None: { "experiment_name": "adv_causality", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2020-01-20", }, @@ -129,12 +130,10 @@ def test_adv_window_uses_calendar_days_not_bars() -> None: { "experiment_name": "adv_bars_vs_days", "data": { - "source": "csv", - "symbols": ["BTC"], + "instruments": [{"symbol": "BTC", "source": "csv", "calendar": "24/7"}], "start_date": "2020-01-01", "end_date": "2020-03-01", "frequency": "1h", - "market_calendar": "24/7", }, "strategy": {"name": "buy_and_hold"}, "execution": { @@ -144,7 +143,9 @@ def test_adv_window_uses_calendar_days_not_bars() -> None: }, } ) - assert cfg.data.is_247_market + from quantlab.data.calendar import is_247 + + assert is_247(cfg.data.instruments[0].calendar) model = build_execution_from_config(cfg, frame) assert isinstance(model.slippage, VolumeBasedSlippageModel) adv = model.slippage.average_daily_volume @@ -167,9 +168,9 @@ def test_adv_window_unchanged_for_daily_bar_configs() -> None: { "experiment_name": "adv_daily_unchanged", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2020-03-01", }, @@ -181,7 +182,9 @@ def test_adv_window_unchanged_for_daily_bar_configs() -> None: }, } ) - assert not cfg.data.is_247_market + from quantlab.data.calendar import is_247 + + assert not is_247(cfg.data.instruments[0].calendar) model = build_execution_from_config(cfg, frame) assert isinstance(model.slippage, VolumeBasedSlippageModel) adv = model.slippage.average_daily_volume @@ -221,9 +224,9 @@ def test_adv_uses_unadjusted_price_for_historical_dollar_volume() -> None: { "experiment_name": "adv_raw_price", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2020-01-03", }, @@ -250,9 +253,9 @@ def test_adv_bar_scaling_ignores_metrics_annualisation_override() -> None: { "experiment_name": "adv_physical_frequency", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2020-01-03", "frequency": "1d", @@ -292,9 +295,9 @@ def test_adv_window_scales_down_for_weekly_bars() -> None: { "experiment_name": "adv_weekly", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2021-06-01", "frequency": "1w", @@ -329,8 +332,13 @@ def test_unknown_data_source_rejected_at_config_load() -> None: { "experiment_name": "x", "data": { - "source": "not_a_real_source", - "symbols": ["A"], + "instruments": [ + { + "symbol": "A", + "source": "not_a_real_source", + "calendar": "XNYS", + } + ], "start_date": "2020-01-01", "end_date": "2021-01-01", }, @@ -366,9 +374,10 @@ def test_frequency_mismatch_is_flagged_as_a_data_warning() -> None: ) inputs = { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["SPY", "QQQ"], + "instruments": [ + {"symbol": "SPY", "source": "csv", "calendar": "XNYS"}, + {"symbol": "QQQ", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2019-01-01", "end_date": "2019-06-01", "frequency": "1h", @@ -377,7 +386,7 @@ def test_frequency_mismatch_is_flagged_as_a_data_warning() -> None: "allocator": "equal_weight", "rebalance_frequency": "monthly", "initial_capital": 100_000.0, - "benchmark_symbol": None, + "benchmark": None, "commission_bps": 2.0, "spread_bps": 3.0, "slippage_bps": 2.0, @@ -392,8 +401,9 @@ def test_binance_hourly_annualises_with_24_7_market_factor() -> None: { "experiment_name": "x", "data": { - "source": "binance", - "symbols": ["BTCUSDT"], + "instruments": [ + {"symbol": "BTCUSDT", "source": "binance", "calendar": "24/7"}, + ], "start_date": "2020-01-01", "end_date": "2021-01-01", "frequency": "1h", @@ -409,8 +419,9 @@ def test_yahoo_hourly_annualisation_unchanged() -> None: { "experiment_name": "x", "data": { - "source": "yahoo", - "symbols": ["SPY"], + "instruments": [ + {"symbol": "SPY", "source": "yahoo", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2021-01-01", "frequency": "1h", @@ -427,8 +438,9 @@ def test_binance_monthly_frequency_rejected() -> None: { "experiment_name": "x", "data": { - "source": "binance", - "symbols": ["BTCUSDT"], + "instruments": [ + {"symbol": "BTCUSDT", "source": "binance", "calendar": "24/7"}, + ], "start_date": "2020-01-01", "end_date": "2021-01-01", "frequency": "1mo", @@ -438,13 +450,60 @@ def test_binance_monthly_frequency_rejected() -> None: ) +def test_binance_download_rejects_a_none_symbol() -> None: + """Binance's own download() must validate its arguments as rigorously as + Yahoo's does -- a None/blank symbol must be a clear error, not an + internal AttributeError or a wasted request to the provider.""" + from quantlab.data.binance import BinanceDataSource + from quantlab.exceptions import DataDownloadError + + with pytest.raises(DataDownloadError, match="non-empty string"): + BinanceDataSource().download( + [None], # type: ignore[list-item] + date(2020, 1, 1), + date(2020, 1, 31), + ) + + +def test_binance_download_rejects_no_symbols() -> None: + from quantlab.data.binance import BinanceDataSource + from quantlab.exceptions import DataDownloadError + + with pytest.raises(DataDownloadError, match="at least one symbol"): + BinanceDataSource().download([], date(2020, 1, 1), date(2020, 1, 31)) + + +def test_binance_download_rejects_start_after_end() -> None: + from quantlab.data.binance import BinanceDataSource + from quantlab.exceptions import DataDownloadError + + with pytest.raises(DataDownloadError, match="on or before end"): + BinanceDataSource().download(["BTCUSDT"], date(2020, 2, 1), date(2020, 1, 1)) + + +def test_binance_download_rejects_string_dates() -> None: + """A caller passing ISO date strings instead of `date` objects must get + a clear error, not silently query the provider with the wrong type.""" + from quantlab.data.binance import BinanceDataSource + from quantlab.exceptions import DataDownloadError + + with pytest.raises(DataDownloadError, match="must be date values"): + BinanceDataSource().download( + ["BTCUSDT"], + "2020-01-01", # type: ignore[arg-type] + "2020-01-31", # type: ignore[arg-type] + ) + + def test_pairs_trading_same_symbol_rejected() -> None: with pytest.raises(InvalidConfigurationError): ExperimentConfig.from_dict( { "experiment_name": "x", "data": { - "symbols": ["AAA"], + "instruments": [ + {"symbol": "AAA", "source": "yahoo", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2021-01-01", }, @@ -462,9 +521,9 @@ def test_csv_source_with_unknown_frequency_rejected() -> None: { "experiment_name": "x", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["A"], + "instruments": [ + {"symbol": "A", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2021-01-01", "frequency": "typo", @@ -483,9 +542,11 @@ def test_frequency_mismatch_flagged_even_on_short_history() -> None: frame = make_ohlcv( "AAA", [100.0 + i for i in range(10)], start="2020-01-01", freq="D" ) - report = DataValidator(expected_frequency="1h", min_coverage_rows=30).validate( - frame - ) + report = DataValidator( + expected_frequency="1h", + min_coverage_rows=30, + symbol_calendars=_UniformCalendar("XNYS"), + ).validate(frame) assert any("does not match the declared frequency" in w for w in report.warnings) @@ -511,7 +572,9 @@ def test_intraday_equity_session_boundaries_not_flagged_as_gaps() -> None: } ) report = DataValidator( - expected_frequency="1h", min_coverage_rows=5, is_247_market=False + expected_frequency="1h", + min_coverage_rows=5, + symbol_calendars=_UniformCalendar("XNYS"), ).validate(frame) assert not any("abnormal gap" in w for w in report.warnings) @@ -540,7 +603,9 @@ def test_intraday_equity_mid_session_gap_still_flagged() -> None: } ) report = DataValidator( - expected_frequency="1h", min_coverage_rows=5, is_247_market=False + expected_frequency="1h", + min_coverage_rows=5, + symbol_calendars=_UniformCalendar("XNYS"), ).validate(frame) assert any("abnormal gap" in w for w in report.warnings) assert len(report.missing_periods) == 1 @@ -571,7 +636,9 @@ def test_intraday_crypto_genuine_gap_still_flagged() -> None: } ) report = DataValidator( - expected_frequency="1h", min_coverage_rows=5, is_247_market=True + expected_frequency="1h", + min_coverage_rows=5, + symbol_calendars=_UniformCalendar("24/7"), ).validate(frame) assert any("abnormal gap" in w for w in report.warnings) @@ -602,7 +669,9 @@ def test_gap_detection_flags_missing_whole_business_day() -> None: } ) report = DataValidator( - expected_frequency="1h", min_coverage_rows=5, is_247_market=False + expected_frequency="1h", + min_coverage_rows=5, + symbol_calendars=_UniformCalendar("XNYS"), ).validate(frame) assert any("abnormal gap" in w for w in report.warnings) @@ -631,7 +700,9 @@ def test_gap_detection_tolerates_us_holiday_long_weekend() -> None: } ) report = DataValidator( - expected_frequency="1h", min_coverage_rows=5, is_247_market=False + expected_frequency="1h", + min_coverage_rows=5, + symbol_calendars=_UniformCalendar("XNYS"), ).validate(frame) assert not any("abnormal gap" in w for w in report.warnings) @@ -645,7 +716,9 @@ def test_gap_detection_flags_missing_columbus_day_session() -> None: if d != pd.Timestamp("2020-10-12") ] report = DataValidator( - expected_frequency="1h", min_coverage_rows=5, is_247_market=False + expected_frequency="1h", + min_coverage_rows=5, + symbol_calendars=_UniformCalendar("XNYS"), ).validate(_hourly_frame(sessions)) assert any("abnormal gap" in w for w in report.warnings) @@ -658,7 +731,9 @@ def test_gap_detection_tolerates_good_friday_closure() -> None: sessions = [pd.Timestamp("2020-04-09"), pd.Timestamp("2020-04-13")] report = DataValidator( - expected_frequency="1h", min_coverage_rows=5, is_247_market=False + expected_frequency="1h", + min_coverage_rows=5, + symbol_calendars=_UniformCalendar("XNYS"), ).validate(_hourly_frame(sessions)) assert not any("abnormal gap" in w for w in report.warnings) @@ -668,7 +743,9 @@ def test_gap_detection_flags_bars_trimmed_from_session_end() -> None: sessions = list(pd.bdate_range("2020-01-06", periods=6)) report = DataValidator( - expected_frequency="1h", min_coverage_rows=5, is_247_market=False + expected_frequency="1h", + min_coverage_rows=5, + symbol_calendars=_UniformCalendar("XNYS"), ).validate(_hourly_frame(sessions, remove={2: {1, 2, 3, 4, 5, 6}})) assert any("abnormal gap" in w for w in report.warnings) @@ -701,7 +778,9 @@ def test_gap_detection_tail_truncation_detected_with_only_two_sessions() -> None } ) report = DataValidator( - expected_frequency="1h", min_coverage_rows=5, is_247_market=False + expected_frequency="1h", + min_coverage_rows=5, + symbol_calendars=_UniformCalendar("XNYS"), ).validate(frame) assert any("abnormal gap" in w for w in report.warnings) @@ -732,7 +811,9 @@ def test_gap_detection_head_truncation_detected_with_only_two_sessions() -> None } ) report = DataValidator( - expected_frequency="1h", min_coverage_rows=5, is_247_market=False + expected_frequency="1h", + min_coverage_rows=5, + symbol_calendars=_UniformCalendar("XNYS"), ).validate(frame) assert any("abnormal gap" in w for w in report.warnings) @@ -754,7 +835,10 @@ def test_pairs_trading_symbol_not_in_universe_rejected_at_config_load() -> None: { "experiment_name": "x", "data": { - "symbols": ["AAA", "BBB"], + "instruments": [ + {"symbol": "AAA", "source": "yahoo", "calendar": "XNYS"}, + {"symbol": "BBB", "source": "yahoo", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2021-01-01", }, @@ -774,7 +858,10 @@ def test_pairs_trading_symbol_in_universe_after_normalization_accepted() -> None { "experiment_name": "x", "data": { - "symbols": ["AAA", "BBB"], + "instruments": [ + {"symbol": "AAA", "source": "yahoo", "calendar": "XNYS"}, + {"symbol": "BBB", "source": "yahoo", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2021-01-01", }, @@ -823,7 +910,9 @@ def test_exact_match_still_clean() -> None: frame = _hourly_symbol_frame("1D", 40, "AAA") report = DataValidator( - expected_frequency="1d", min_coverage_rows=5, is_247_market=False + expected_frequency="1d", + min_coverage_rows=5, + symbol_calendars=_UniformCalendar("XNYS"), ).validate(frame) assert not any( "does not match the declared frequency" in w for w in report.warnings @@ -848,9 +937,9 @@ def test_partial_coverage_of_requested_range_flagged() -> None: "volume": 1000.0, } ) - report = DataValidator(min_coverage_rows=5).validate( - frame, start=date(2020, 1, 1), end=date(2020, 4, 30) - ) + report = DataValidator( + min_coverage_rows=5, symbol_calendars=_UniformCalendar("XNYS") + ).validate(frame, start=date(2020, 1, 1), end=date(2020, 4, 30)) assert any( "data starts" in w and "after the requested start" in w for w in report.warnings ) @@ -877,33 +966,39 @@ def test_gap_detected_even_below_min_coverage_rows() -> None: "volume": 1000.0, } ) - report = DataValidator(min_coverage_rows=30, is_247_market=True).validate(frame) + report = DataValidator( + min_coverage_rows=30, symbol_calendars=_UniformCalendar("24/7") + ).validate(frame) assert any("Short coverage" in w for w in report.warnings) assert any("abnormal gap" in w for w in report.warnings) assert len(report.missing_periods) == 1 -def test_csv_source_requires_explicit_market_calendar() -> None: - from quantlab.exceptions import InvalidConfigurationError - - with pytest.raises(InvalidConfigurationError, match="market_calendar"): +def test_instrument_requires_explicit_calendar() -> None: + """Every instrument requires an explicit calendar, whatever its source — + there is no per-source default to fall back to.""" + with pytest.raises(InvalidConfigurationError, match="calendar"): _market_calendar_config() def test_csv_bitcoin_can_declare_crypto_via_explicit_field() -> None: - """Declaring `market_calendar: 24/7` on a csv source yields 24/7 + """Declaring `calendar: 24/7` on a csv instrument yields 24/7 (8760/year for 1h bars) annualization.""" - cfg = _market_calendar_config(market_calendar="24/7") - assert cfg.data.is_247_market is True + from quantlab.data.calendar import is_247 + + cfg = _market_calendar_config(calendar="24/7") + assert is_247(cfg.data.instruments[0].calendar) is True assert cfg.periods_per_year == 24 * 365 def test_csv_source_can_declare_xnys_explicitly() -> None: - """Declaring `market_calendar: XNYS` on a csv source yields equity + """Declaring `calendar: XNYS` on a csv instrument yields equity (252 * 7 = 1764/year for `_market_calendar_config`'s 1h bars) annualization, not 24/7.""" - cfg = _market_calendar_config(market_calendar="XNYS") - assert cfg.data.is_247_market is False + from quantlab.data.calendar import is_247 + + cfg = _market_calendar_config(calendar="XNYS") + assert is_247(cfg.data.instruments[0].calendar) is False assert cfg.periods_per_year == 252 * 7 @@ -911,19 +1006,23 @@ def test_binance_cannot_be_overridden_back_to_equity() -> None: from quantlab.exceptions import InvalidConfigurationError with pytest.raises(InvalidConfigurationError, match="not permitted"): - _market_calendar_config(source="binance", market_calendar="XNYS") + _market_calendar_config(source="binance", calendar="XNYS") def test_yahoo_can_select_24_7_calendar() -> None: """Yahoo serves continuous instruments as well as XNYS securities.""" - cfg = _market_calendar_config(source="yahoo", market_calendar="24/7") - assert cfg.data.is_247_market is True + from quantlab.data.calendar import is_247 + + cfg = _market_calendar_config(source="yahoo", calendar="24/7") + assert is_247(cfg.data.instruments[0].calendar) is True assert cfg.periods_per_year == 365 * 24 def test_shipped_configs_have_the_expected_calendar() -> None: import pathlib + from quantlab.data.calendar import is_247, uniform_calendar + configs_dir = pathlib.Path(__file__).resolve().parents[2] / "configs" expected = { "btc_trend.yaml": (True, 365), @@ -933,9 +1032,11 @@ def test_shipped_configs_have_the_expected_calendar() -> None: "momentum_sp500.yaml": (False, 252), "pairs_trading.yaml": (False, 252), } - for name, (is_247, ppy) in expected.items(): + for name, (is_247_expected, ppy) in expected.items(): cfg = ExperimentConfig.from_yaml(configs_dir / name) - assert cfg.data.is_247_market is is_247, name + calendar = uniform_calendar(i.calendar for i in cfg.data.instruments) + assert calendar is not None, name + assert is_247(calendar) is is_247_expected, name assert cfg.periods_per_year == ppy, name @@ -1114,6 +1215,51 @@ def make_csv(path: Path, close: float) -> None: assert sorted(bundled["close"].tolist()) == [100.0, 999.0] +def test_loader_report_records_whether_bundled_demo_data_was_actually_used( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """`use_bundled_demo_data=True` only *enables* the fallback -- it says + nothing about whether local files were actually missing this run. The + report must record whether the fallback genuinely triggered, not just + whether it was allowed to.""" + import quantlab.data.loader as loader_mod + from quantlab.data.loader import DataLoader + + demo_dir = tmp_path / "demo_data" + demo_dir.mkdir() + make_ohlcv("SPY", [100.0] * 200, start="2020-01-01").to_csv( + demo_dir / "SPY.csv", index=False + ) + monkeypatch.setattr(loader_mod, "DEMO_DATA_DIR", demo_dir) + + cfg = ExperimentConfig.from_dict( + { + "experiment_name": "bundled_demo_used_repro", + "data": { + "instruments": [{"symbol": "SPY", "source": "csv", "calendar": "XNYS"}], + "start_date": "2020-01-01", + "end_date": "2020-06-01", + "use_bundled_demo_data": True, + }, + "strategy": {"name": "buy_and_hold"}, + } + ) + + empty_raw_dir = tmp_path / "empty_raw" + empty_raw_dir.mkdir() + _, report_used = DataLoader(raw_dir=empty_raw_dir).load(cfg) + assert report_used.bundled_demo_data_used is True + assert report_used.to_dict()["bundled_demo_data_used"] is True + + real_raw_dir = tmp_path / "real_raw" + real_raw_dir.mkdir() + make_ohlcv("SPY", [100.0] * 200, start="2020-01-01").to_csv( + real_raw_dir / "SPY.csv", index=False + ) + _, report_unused = DataLoader(raw_dir=real_raw_dir).load(cfg) + assert report_unused.bundled_demo_data_used is False + + def test_csv_loader_does_not_silently_substitute_demo_data_by_default( tmp_path: Path, monkeypatch: pytest.MonkeyPatch ) -> None: @@ -1137,11 +1283,14 @@ def test_csv_loader_does_not_silently_substitute_demo_data_by_default( def test_use_bundled_demo_data_rejected_with_a_non_csv_source() -> None: for source in ("yahoo", "binance"): + symbol = "BTCUSDT" if source == "binance" else "SPY" + calendar = "24/7" if source == "binance" else "XNYS" payload = { "experiment_name": "test", "data": { - "source": source, - "symbols": ["BTCUSDT"] if source == "binance" else ["SPY"], + "instruments": [ + {"symbol": symbol, "source": source, "calendar": calendar} + ], "start_date": "2020-01-01", "end_date": "2020-06-01", "use_bundled_demo_data": True, @@ -1167,7 +1316,7 @@ def test_source_hash_is_platform_independent_and_reuses_cache( ) first = engine._source_hash() - fingerprint_after_first_call = engine._source_hash_fingerprint + fingerprint_after_first_call = engine._source_hash_cache["source"][0] assert fingerprint_after_first_call is not None assert all("\\" not in rel for rel, _mtime in fingerprint_after_first_call) @@ -1175,16 +1324,19 @@ def test_source_hash_is_platform_independent_and_reuses_cache( # value rather than re-reading and re-hashing every file's bytes again. second = engine._source_hash() assert second == first - assert engine._source_hash_fingerprint == fingerprint_after_first_call + assert engine._source_hash_cache["source"][0] == fingerprint_after_first_call def test_source_hash_ignores_dashboard_and_cli_edits( tmp_path: Path, monkeypatch: pytest.MonkeyPatch ) -> None: """No notebook cell and no computational backtest path imports the - dashboard or the CLI entry point, so editing either must not change the - hash -- otherwise unrelated dashboard/CLI edits force spurious notebook - rebuilds and spuriously invalidate walk-forward artifact reuse.""" + dashboard or the CLI entry point, so editing either must not change + `_source_hash()` (`code_hash`) -- otherwise unrelated dashboard/CLI + edits would force spurious notebook rebuilds. Saved-bundle reuse uses + the separate, wider `_generator_hash()` instead (see + test_generator_hash_is_sensitive_to_cli_edits_but_not_dashboard_edits), + precisely because CLI orchestration changes DO need to invalidate that.""" import shutil from quantlab.backtesting import engine @@ -1207,7 +1359,7 @@ def test_source_hash_ignores_dashboard_and_cli_edits( (fake_root / "cli.py").read_text(encoding="utf-8") + "\n# edited\n", encoding="utf-8", ) - monkeypatch.setattr(engine, "_source_hash_computed_at", None) + monkeypatch.delitem(engine._source_hash_cache, "source", raising=False) assert engine._source_hash() == original # A module actually on the computational path must still be caught. @@ -1215,10 +1367,48 @@ def test_source_hash_ignores_dashboard_and_cli_edits( (fake_root / "constants.py").read_text(encoding="utf-8") + "\n# edited\n", encoding="utf-8", ) - monkeypatch.setattr(engine, "_source_hash_computed_at", None) + monkeypatch.delitem(engine._source_hash_cache, "source", raising=False) assert engine._source_hash() != original +def test_generator_hash_is_sensitive_to_cli_edits_but_not_dashboard_edits( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """`_generator_hash()` gates reuse of a *saved bundle* (walk-forward and + robustness CSVs, checkpoints) -- unlike `_source_hash()`/`code_hash`, it + must catch a change to `cli.py`'s own orchestration of how that bundle + gets assembled or reused, since an unchanged computational hash alone + does not guarantee an unchanged bundle. The dashboard is still excluded + from both: no saved bundle depends on it either.""" + import shutil + + from quantlab.backtesting import engine + + real_root = Path(engine.__file__).resolve().parents[1] + fake_root = tmp_path / "quantlab" + shutil.copytree(real_root, fake_root) + monkeypatch.setattr( + engine, "__file__", str(fake_root / "backtesting" / "engine.py") + ) + + original = engine._generator_hash() + + (fake_root / "dashboard" / "app.py").write_text( + (fake_root / "dashboard" / "app.py").read_text(encoding="utf-8") + + "\n# edited\n", + encoding="utf-8", + ) + monkeypatch.delitem(engine._source_hash_cache, "generator", raising=False) + assert engine._generator_hash() == original + + (fake_root / "cli.py").write_text( + (fake_root / "cli.py").read_text(encoding="utf-8") + "\n# edited\n", + encoding="utf-8", + ) + monkeypatch.delitem(engine._source_hash_cache, "generator", raising=False) + assert engine._generator_hash() != original + + def test_robustness_placeholder_does_not_overclaim_cli_coverage() -> None: from quantlab.reporting.html_report import _render_robustness @@ -1247,16 +1437,16 @@ def test_cache_covers_tolerates_a_weekend_end_date(tmp_path: Path) -> None: "volume": 100.0, } ) - storage.write_symbol(data, "yahoo", "AAA", "1d") + storage.write_symbol(data, "yahoo", "AAA", "1d", calendar="XNYS") # End date is a Sunday two days after the last cached (Friday) bar. assert storage.cache_covers( - "yahoo", "AAA", "1d", date(2023, 1, 2), date(2024, 1, 7) + "yahoo", "AAA", "1d", date(2023, 1, 2), date(2024, 1, 7), calendar="XNYS" ) # A genuinely stale cache (far beyond any reasonable non-trading gap) # must still be reported as not covering. assert not storage.cache_covers( - "yahoo", "AAA", "1d", date(2023, 1, 2), date(2024, 2, 1) + "yahoo", "AAA", "1d", date(2023, 1, 2), date(2024, 2, 1), calendar="XNYS" ) @@ -1279,12 +1469,12 @@ def test_cache_covers_tolerates_a_weekend_start_date(tmp_path: Path) -> None: "volume": 100.0, } ) - storage.write_symbol(data, "yahoo", "AAA", "1d") + storage.write_symbol(data, "yahoo", "AAA", "1d", calendar="XNYS") # Requested start (Sunday 2023-01-01) is one day before the first cached # (Monday) bar. assert storage.cache_covers( - "yahoo", "AAA", "1d", date(2023, 1, 1), date(2024, 1, 5) + "yahoo", "AAA", "1d", date(2023, 1, 1), date(2024, 1, 5), calendar="XNYS" ) @@ -1330,7 +1520,7 @@ def test_save_persists_warnings_into_metadata_json(tmp_path: Path) -> None: def test_symbol_path_traversal_rejected() -> None: payload = _base_config_dict() payload["data"] = dict(payload["data"]) - payload["data"]["symbols"] = ["../../etc/passwd"] + payload["data"]["instruments"][0]["symbol"] = "../../etc/passwd" with pytest.raises(InvalidConfigurationError, match="Invalid symbol"): ExperimentConfig.from_dict(payload) @@ -1339,7 +1529,7 @@ def test_symbol_validation_accepts_real_yahoo_ticker_conventions() -> None: for symbol in ["^GSPC", "^DJI", "^VIX", "EURUSD=X", "GC=F", "ES=F"]: payload = _base_config_dict() payload["data"] = dict(payload["data"]) - payload["data"]["symbols"] = [symbol] + payload["data"]["instruments"][0]["symbol"] = symbol cfg = ExperimentConfig.from_dict(payload) assert cfg.symbols == [symbol] @@ -1347,7 +1537,7 @@ def test_symbol_validation_accepts_real_yahoo_ticker_conventions() -> None: # newly-allowed characters. payload = _base_config_dict() payload["data"] = dict(payload["data"]) - payload["data"]["symbols"] = ["^../../etc/passwd"] + payload["data"]["instruments"][0]["symbol"] = "^../../etc/passwd" with pytest.raises(InvalidConfigurationError, match="Invalid symbol"): ExperimentConfig.from_dict(payload) @@ -1366,14 +1556,14 @@ def test_symbol_rejects_windows_reserved_device_names() -> None: ]: payload = _base_config_dict() payload["data"] = dict(payload["data"]) - payload["data"]["symbols"] = [bad] + payload["data"]["instruments"][0]["symbol"] = bad with pytest.raises(InvalidConfigurationError, match="reserved device name"): ExperimentConfig.from_dict(payload) for ok in ["COM0", "LPT0", "CONSOLE", "NULL", "SPY", "AAPL"]: payload = _base_config_dict() payload["data"] = dict(payload["data"]) - payload["data"]["symbols"] = [ok] + payload["data"]["instruments"][0]["symbol"] = ok cfg = ExperimentConfig.from_dict(payload) assert cfg.symbols == [ok] @@ -1382,30 +1572,34 @@ def test_symbol_rejects_a_trailing_dot_or_space() -> None: for bad in ["FOO.", "FOO..", "SPY.", "AAPL.CSV."]: payload = _base_config_dict() payload["data"] = dict(payload["data"]) - payload["data"]["symbols"] = [bad] + payload["data"]["instruments"][0]["symbol"] = bad with pytest.raises(InvalidConfigurationError, match="must not end with"): ExperimentConfig.from_dict(payload) # Sanity: an ordinary name containing internal dots remains accepted. payload = _base_config_dict() payload["data"] = dict(payload["data"]) - payload["data"]["symbols"] = ["BRK.B"] + payload["data"]["instruments"][0]["symbol"] = "BRK.B" cfg = ExperimentConfig.from_dict(payload) assert cfg.symbols == ["BRK.B"] def test_benchmark_symbol_path_traversal_rejected() -> None: payload = _base_config_dict() - payload["backtest"] = {"benchmark_symbol": "../outside"} - with pytest.raises(InvalidConfigurationError, match="benchmark_symbol"): + payload["backtest"] = { + "benchmark": {"symbol": "../outside", "source": "csv", "calendar": "XNYS"} + } + with pytest.raises(InvalidConfigurationError, match="Invalid symbol"): ExperimentConfig.from_dict(payload) def test_benchmark_symbol_normalized_like_data_symbols() -> None: payload = _base_config_dict() - payload["backtest"] = {"benchmark_symbol": " spy "} + payload["backtest"] = { + "benchmark": {"symbol": " spy ", "source": "csv", "calendar": "XNYS"} + } cfg = ExperimentConfig.from_dict(payload) - assert cfg.backtest.benchmark_symbol == "SPY" + assert cfg.benchmark_symbol == "SPY" def test_data_hash_covers_benchmark_symbol_too() -> None: @@ -1420,16 +1614,18 @@ def test_data_hash_covers_benchmark_symbol_too() -> None: { "experiment_name": "test", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["A"], + "instruments": [ + {"symbol": "A", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2020-06-01", }, "strategy": {"name": "buy_and_hold", "parameters": {}}, "portfolio": {"allocator": "equal_weight"}, "execution": {}, - "backtest": {"benchmark_symbol": "BENCH"}, + "backtest": { + "benchmark": {"symbol": "BENCH", "source": "csv", "calendar": "XNYS"} + }, "validation": {"method": "holdout"}, "reproducibility": {"random_seed": 42}, } @@ -1468,11 +1664,11 @@ def test_cache_covers_hourly_survives_a_weekend_with_calendar_tolerance( "volume": 100.0, } ) - storage.write_symbol(data, "yahoo", "AAA", "1h") + storage.write_symbol(data, "yahoo", "AAA", "1h", calendar="XNYS") # ~57 hours between the last (Friday) bar and Sunday. assert storage.cache_covers( - "yahoo", "AAA", "1h", date(2024, 1, 1), date(2024, 1, 7) + "yahoo", "AAA", "1h", date(2024, 1, 1), date(2024, 1, 7), calendar="XNYS" ) @@ -1497,16 +1693,16 @@ def test_cache_covers_equity_hourly_rejects_a_sparse_cache_gap( "volume": 100.0, } ) - storage.write_symbol(data, "yahoo", "AAA", "1h", is_247_market=False) + storage.write_symbol(data, "yahoo", "AAA", "1h", calendar="XNYS") assert not storage.cache_covers( - "yahoo", "AAA", "1h", date(2024, 1, 4), date(2024, 1, 5), is_247_market=False + "yahoo", "AAA", "1h", date(2024, 1, 4), date(2024, 1, 5), calendar="XNYS" ) # Sanity: a request entirely inside a real weekend (no trading day at # all in range) must not be rejected just for lacking a bar that could # never exist. assert storage.cache_covers( - "yahoo", "AAA", "1h", date(2024, 1, 6), date(2024, 1, 7), is_247_market=False + "yahoo", "AAA", "1h", date(2024, 1, 6), date(2024, 1, 7), calendar="XNYS" ) @@ -1524,11 +1720,11 @@ def test_cache_covers_equity_hourly_detects_an_internal_missing_hour( day_hours = day_hours[day_hours.hour != 12] # drop noon internally hours.extend(day_hours) storage.write_symbol( - _make_hourly_frame(hours), "yahoo", "AAA", "1h", is_247_market=False + _make_hourly_frame(hours), "yahoo", "AAA", "1h", calendar="XNYS" ) assert not storage.cache_covers( - "yahoo", "AAA", "1h", date(2024, 1, 2), date(2024, 1, 12), is_247_market=False + "yahoo", "AAA", "1h", date(2024, 1, 2), date(2024, 1, 12), calendar="XNYS" ) @@ -1545,11 +1741,11 @@ def test_cache_covers_equity_hourly_detects_an_entire_missing_session( continue # entire session missing hours.extend(pd.date_range(d.replace(hour=9), d.replace(hour=15), freq="h")) storage.write_symbol( - _make_hourly_frame(hours), "yahoo", "AAA", "1h", is_247_market=False + _make_hourly_frame(hours), "yahoo", "AAA", "1h", calendar="XNYS" ) assert not storage.cache_covers( - "yahoo", "AAA", "1h", date(2024, 1, 2), date(2024, 1, 12), is_247_market=False + "yahoo", "AAA", "1h", date(2024, 1, 2), date(2024, 1, 12), calendar="XNYS" ) @@ -1564,18 +1760,142 @@ def test_cache_covers_equity_hourly_complete_cache_still_passes( for d in bdays: hours.extend(pd.date_range(d.replace(hour=9), d.replace(hour=15), freq="h")) storage.write_symbol( - _make_hourly_frame(hours), "yahoo", "AAA", "1h", is_247_market=False + _make_hourly_frame(hours), "yahoo", "AAA", "1h", calendar="XNYS" ) assert storage.cache_covers( - "yahoo", "AAA", "1h", date(2024, 1, 2), date(2024, 1, 12), is_247_market=False + "yahoo", "AAA", "1h", date(2024, 1, 2), date(2024, 1, 12), calendar="XNYS" ) # A single-day request landing exactly on the cache's own extent must # also still pass (and must still be able to detect a gap, see the two # tests above, which both use single- and multi-day ranges). assert storage.cache_covers( - "yahoo", "AAA", "1h", date(2024, 1, 2), date(2024, 1, 2), is_247_market=False + "yahoo", "AAA", "1h", date(2024, 1, 2), date(2024, 1, 2), calendar="XNYS" + ) + + +def test_cache_covers_equity_hourly_handles_a_session_crossing_utc_midnight( + tmp_path: Path, +) -> None: + """XASX (UTC+10/+11) sessions open ~23:00 UTC the day *before* their own + labeled session date and close ~05:00 UTC on it. Grouping cache + coverage by naive UTC calendar day would split one real session's bars + across two different "days", undercounting each and wrongly declaring a + complete cache incomplete.""" + from quantlab.data.calendar import sessions + from quantlab.data.storage import ParquetStorage + + storage = ParquetStorage(cache_dir=tmp_path / "cache", metadata_dir=tmp_path / "md") + schedule = sessions("XASX", pd.Timestamp("2024-01-08"), pd.Timestamp("2024-01-10")) + hours: list[pd.Timestamp] = [] + for _, row in schedule.iterrows(): + hours.extend( + pd.date_range(row["market_open"], row["market_close"], freq="h")[:-1] + ) + storage.write_symbol( + _make_hourly_frame(hours), "yahoo", "AAA", "1h", calendar="XASX" + ) + + assert storage.cache_covers( + "yahoo", "AAA", "1h", date(2024, 1, 8), date(2024, 1, 10), calendar="XASX" + ) + + +def test_cache_covers_equity_hourly_tolerates_xhkg_lunch_break( + tmp_path: Path, +) -> None: + """XHKG has an official intraday break (lunch recess): a real provider + legitimately has no bars during it. Treating a session as one + continuous [open, close) block would count the break as "expected" + and wrongly declare a genuinely complete cache incomplete -- but a + real internal gap (unrelated to the break) must still be caught.""" + from quantlab.data.calendar import sessions + from quantlab.data.storage import ParquetStorage + + schedule = sessions("XHKG", pd.Timestamp("2024-01-08"), pd.Timestamp("2024-01-08")) + row = schedule.iloc[0] + hours = list( + pd.date_range( + row["market_open"], row["break_start"], freq="h", inclusive="left" + ) + ) + list( + pd.date_range(row["break_end"], row["market_close"], freq="h", inclusive="left") + ) + + complete = ParquetStorage(cache_dir=tmp_path / "c1", metadata_dir=tmp_path / "m1") + complete.write_symbol( + _make_hourly_frame(hours), "yahoo", "AAA", "1h", calendar="XHKG" + ) + assert complete.cache_covers( + "yahoo", "AAA", "1h", date(2024, 1, 8), date(2024, 1, 8), calendar="XHKG" + ) + + gapped_hours = hours[:-1] # drop the last real bar -- a genuine gap + gapped = ParquetStorage(cache_dir=tmp_path / "c2", metadata_dir=tmp_path / "m2") + gapped.write_symbol( + _make_hourly_frame(gapped_hours), "yahoo", "AAA", "1h", calendar="XHKG" + ) + assert not gapped.cache_covers( + "yahoo", "AAA", "1h", date(2024, 1, 8), date(2024, 1, 8), calendar="XHKG" + ) + + +def test_validator_does_not_flag_xhkg_lunch_break_as_an_abnormal_gap() -> None: + """The same break-awareness must apply to DataValidator's own gap and + frequency-matching checks, not just the storage cache-coverage check.""" + from quantlab.data.calendar import sessions + from quantlab.data.validator import DataValidator + + schedule = sessions("XHKG", pd.Timestamp("2024-01-08"), pd.Timestamp("2024-02-20")) + rows: list[pd.Timestamp] = [] + for _, row in schedule.iterrows(): + starts = pd.date_range( + row["market_open"], row["market_close"], freq="1h", inclusive="left" + ) + starts = starts[(starts < row["break_start"]) | (starts >= row["break_end"])] + rows.extend(starts) + + df = pd.DataFrame( + { + "timestamp": rows, + "symbol": "AAA", + "open": 1.0, + "high": 1.0, + "low": 1.0, + "close": 1.0, + "adjusted_close": 1.0, + "volume": 100.0, + } + ) + report = DataValidator( + expected_frequency="1h", symbol_calendars={"AAA": "XHKG"} + ).validate(df, strict=False) + assert not any("abnormal gap" in w for w in report.warnings) + assert not any("matching fraction" in w or "matching" in w for w in report.warnings) + + # A genuine, break-unrelated gap (a whole missing session) must still + # be caught. + rows_missing_session = [ + ts + for ts in rows + if ts.normalize() != pd.Timestamp(str(schedule.index[15])).normalize() + ] + df_missing = pd.DataFrame( + { + "timestamp": rows_missing_session, + "symbol": "AAA", + "open": 1.0, + "high": 1.0, + "low": 1.0, + "close": 1.0, + "adjusted_close": 1.0, + "volume": 100.0, + } ) + report_missing = DataValidator( + expected_frequency="1h", symbol_calendars={"AAA": "XHKG"} + ).validate(df_missing, strict=False) + assert any("abnormal gap" in w for w in report_missing.warnings) def test_cache_covers_weekly_does_not_over_tolerate_real_staleness( @@ -1597,10 +1917,10 @@ def test_cache_covers_weekly_does_not_over_tolerate_real_staleness( "volume": 100.0, } ) - storage.write_symbol(data, "yahoo", "AAA", "1w") + storage.write_symbol(data, "yahoo", "AAA", "1w", calendar="XNYS") assert not storage.cache_covers( - "yahoo", "AAA", "1w", date(2024, 1, 1), date(2024, 1, 29) + "yahoo", "AAA", "1w", date(2024, 1, 1), date(2024, 1, 29), calendar="XNYS" ) @@ -1623,7 +1943,7 @@ def test_cache_covers_247_market_does_not_mask_missing_crypto_days( "volume": 100.0, } ) - storage.write_symbol(data, "binance", "BTCUSDT", "1h") + storage.write_symbol(data, "binance", "BTCUSDT", "1h", calendar="24/7") # A genuine 72-hour gap must be caught for a 24/7 market... assert not storage.cache_covers( @@ -1632,7 +1952,7 @@ def test_cache_covers_247_market_does_not_mask_missing_crypto_days( "1h", date(2023, 12, 29), date(2024, 1, 4), - is_247_market=True, + calendar="24/7", ) # The same cache also misses genuine XNYS sessions through January 4; # exact session coverage must reject it instead of spending weekend slack. @@ -1642,7 +1962,7 @@ def test_cache_covers_247_market_does_not_mask_missing_crypto_days( "1h", date(2023, 12, 29), date(2024, 1, 4), - is_247_market=False, + calendar="XNYS", ) # A tiny, realistic posting lag (a few hours before the *end* of the # requested day, not its start — `end` is inclusive of its whole @@ -1653,22 +1973,24 @@ def test_cache_covers_247_market_does_not_mask_missing_crypto_days( "1h", date(2023, 12, 29), date(2023, 12, 31), - is_247_market=True, + calendar="24/7", ) -def test_dataloader_threads_is_247_market_into_cache_covers() -> None: - """`DataLoader._download_symbol` must pass the config's resolved - `is_247_market` flag through to `cache_covers`, not rely on its - (equity-biased) default.""" +def test_dataloader_threads_calendar_into_cache_covers() -> None: + """`DataLoader._download_symbol` must pass the instrument's own resolved + `calendar` through to `cache_covers`, not rely on its (equity-biased) + default.""" from quantlab.config import ExperimentConfig + from quantlab.data.calendar import is_247 cfg = ExperimentConfig.from_dict( { "experiment_name": "test", "data": { - "source": "binance", - "symbols": ["BTCUSDT"], + "instruments": [ + {"symbol": "BTCUSDT", "source": "binance", "calendar": "24/7"}, + ], "start_date": "2020-01-01", "end_date": "2020-06-01", "frequency": "1d", @@ -1681,7 +2003,7 @@ def test_dataloader_threads_is_247_market_into_cache_covers() -> None: "reproducibility": {"random_seed": 42}, } ) - assert cfg.data.is_247_market is True + assert is_247(cfg.data.instruments[0].calendar) is True def test_cache_covers_end_boundary_matches_loaders_inclusive_day( @@ -1703,7 +2025,7 @@ def test_cache_covers_end_boundary_matches_loaders_inclusive_day( "volume": 100.0, } ) - storage.write_symbol(data, "binance", "BTCUSDT", "1h") + storage.write_symbol(data, "binance", "BTCUSDT", "1h", calendar="24/7") # Cache stops Jan 2 23:00; the entire 24 bars of Jan 3 are missing. assert not storage.cache_covers( @@ -1712,7 +2034,7 @@ def test_cache_covers_end_boundary_matches_loaders_inclusive_day( "1h", date(2024, 1, 1), date(2024, 1, 3), - is_247_market=True, + calendar="24/7", ) # But it does genuinely cover through Jan 2 itself. assert storage.cache_covers( @@ -1721,7 +2043,7 @@ def test_cache_covers_end_boundary_matches_loaders_inclusive_day( "1h", date(2024, 1, 1), date(2024, 1, 2), - is_247_market=True, + calendar="24/7", ) @@ -1745,7 +2067,7 @@ def test_cache_covers_equity_does_not_skip_a_real_weekday_gap( "volume": 100.0, } ) - storage.write_symbol(data, "yahoo", "SPY", "1d") + storage.write_symbol(data, "yahoo", "SPY", "1d", calendar="XNYS") # Request through the following Tuesday: Monday + Tuesday sessions are # genuinely missing from the cache. @@ -1755,7 +2077,7 @@ def test_cache_covers_equity_does_not_skip_a_real_weekday_gap( "1d", date(2023, 1, 2), date(2024, 1, 9), - is_247_market=False, + calendar="XNYS", ) # Request through the weekend itself (Sunday): nothing more could # possibly exist, so this must still be tolerated. @@ -1765,7 +2087,7 @@ def test_cache_covers_equity_does_not_skip_a_real_weekday_gap( "1d", date(2023, 1, 2), date(2024, 1, 7), - is_247_market=False, + calendar="XNYS", ) @@ -1783,7 +2105,7 @@ def test_cache_covers_complete_daily_cache_is_not_declared_incomplete( "1d", date(2024, 1, 1), date(2024, 1, 10), - is_247_market=True, + calendar="24/7", ) @@ -1798,11 +2120,11 @@ def test_cache_covers_rejects_a_missing_single_weekday_session( dates = pd.bdate_range("2024-12-01", "2025-01-03") _write_daily_cache(storage, "yahoo", "SPY", dates) assert not storage.cache_covers( - "yahoo", "SPY", "1d", date(2024, 12, 1), date(2025, 1, 6), is_247_market=False + "yahoo", "SPY", "1d", date(2024, 12, 1), date(2025, 1, 6), calendar="XNYS" ) # Through Sunday (the weekend itself): nothing more could exist. assert storage.cache_covers( - "yahoo", "SPY", "1d", date(2024, 12, 1), date(2025, 1, 5), is_247_market=False + "yahoo", "SPY", "1d", date(2024, 12, 1), date(2025, 1, 5), calendar="XNYS" ) @@ -1820,7 +2142,7 @@ def test_cache_covers_rejects_several_missing_leading_sessions( dates = pd.bdate_range("2025-01-24", "2025-02-01") _write_daily_cache(storage, "yahoo", "SPY", dates) assert not storage.cache_covers( - "yahoo", "SPY", "1d", date(2025, 1, 20), date(2025, 2, 1), is_247_market=False + "yahoo", "SPY", "1d", date(2025, 1, 20), date(2025, 2, 1), calendar="XNYS" ) @@ -1844,14 +2166,14 @@ def test_cache_covers_hourly_247_flags_missing_edge_hours( "volume": 100.0, } ) - storage.write_symbol(data, "binance", "BTCUSDT", "1h") + storage.write_symbol(data, "binance", "BTCUSDT", "1h", calendar="24/7") assert not storage.cache_covers( "binance", "BTCUSDT", "1h", date(2024, 1, 1), date(2024, 1, 2), - is_247_market=True, + calendar="24/7", ) @@ -1877,9 +2199,9 @@ def test_cache_covers_weekly_complete_cache_is_not_declared_incomplete( "volume": 100.0, } ) - storage.write_symbol(data, "yahoo", "SPY", "1w") + storage.write_symbol(data, "yahoo", "SPY", "1w", calendar="XNYS") assert storage.cache_covers( - "yahoo", "SPY", "1w", date(2024, 1, 1), date(2024, 12, 30), is_247_market=False + "yahoo", "SPY", "1w", date(2024, 1, 1), date(2024, 12, 30), calendar="XNYS" ) @@ -1901,9 +2223,9 @@ def test_cache_covers_monthly_january_bar_covers_whole_january( "volume": 100.0, } ) - storage.write_symbol(data, "yahoo", "SPY", "1mo") + storage.write_symbol(data, "yahoo", "SPY", "1mo", calendar="XNYS") assert storage.cache_covers( - "yahoo", "SPY", "1mo", date(2021, 1, 1), date(2021, 1, 31), is_247_market=False + "yahoo", "SPY", "1mo", date(2021, 1, 1), date(2021, 1, 31), calendar="XNYS" ) @@ -1925,13 +2247,13 @@ def test_cache_covers_monthly_february_bar_does_not_mask_missing_march( "volume": 100.0, } ) - storage.write_symbol(data, "yahoo", "SPY", "1mo") + storage.write_symbol(data, "yahoo", "SPY", "1mo", calendar="XNYS") assert not storage.cache_covers( - "yahoo", "SPY", "1mo", date(2021, 2, 1), date(2021, 3, 1), is_247_market=False + "yahoo", "SPY", "1mo", date(2021, 2, 1), date(2021, 3, 1), calendar="XNYS" ) # But the same cache genuinely does cover a request confined to February. assert storage.cache_covers( - "yahoo", "SPY", "1mo", date(2021, 2, 1), date(2021, 2, 28), is_247_market=False + "yahoo", "SPY", "1mo", date(2021, 2, 1), date(2021, 2, 28), calendar="XNYS" ) @@ -1942,9 +2264,9 @@ def test_cache_covers_monthly_detects_a_missing_internal_month( storage = ParquetStorage(cache_dir=tmp_path / "cache", metadata_dir=tmp_path / "md") dates = pd.to_datetime(["2021-01-01", "2021-03-01"]) - storage.write_symbol(_ohlcv_at(dates), "yahoo", "SPY", "1mo") + storage.write_symbol(_ohlcv_at(dates), "yahoo", "SPY", "1mo", calendar="XNYS") assert not storage.cache_covers( - "yahoo", "SPY", "1mo", date(2021, 1, 1), date(2021, 3, 31), is_247_market=False + "yahoo", "SPY", "1mo", date(2021, 1, 1), date(2021, 3, 31), calendar="XNYS" ) @@ -1957,9 +2279,9 @@ def test_cache_covers_weekly_detects_a_missing_internal_week( storage = ParquetStorage(cache_dir=tmp_path / "cache", metadata_dir=tmp_path / "md") dates = pd.to_datetime(["2021-01-01", "2021-01-15"]) - storage.write_symbol(_ohlcv_at(dates), "yahoo", "SPY", "1w") + storage.write_symbol(_ohlcv_at(dates), "yahoo", "SPY", "1w", calendar="XNYS") assert not storage.cache_covers( - "yahoo", "SPY", "1w", date(2021, 1, 1), date(2021, 1, 15), is_247_market=False + "yahoo", "SPY", "1w", date(2021, 1, 1), date(2021, 1, 15), calendar="XNYS" ) @@ -1972,15 +2294,17 @@ def test_cache_covers_monthly_and_weekly_complete_caches_still_pass( storage = ParquetStorage(cache_dir=tmp_path / "cache", metadata_dir=tmp_path / "md") monthly = pd.to_datetime(["2021-01-01", "2021-02-01", "2021-03-01"]) - storage.write_symbol(_ohlcv_at(monthly), "yahoo", "SPY", "1mo") + storage.write_symbol(_ohlcv_at(monthly), "yahoo", "SPY", "1mo", calendar="XNYS") assert storage.cache_covers( - "yahoo", "SPY", "1mo", date(2021, 1, 1), date(2021, 3, 31), is_247_market=False + "yahoo", "SPY", "1mo", date(2021, 1, 1), date(2021, 3, 31), calendar="XNYS" ) weekly = pd.to_datetime(["2021-01-01", "2021-01-08", "2021-01-15"]) - storage.write_symbol(_ohlcv_at(weekly, symbol="QQQ"), "yahoo", "QQQ", "1w") + storage.write_symbol( + _ohlcv_at(weekly, symbol="QQQ"), "yahoo", "QQQ", "1w", calendar="XNYS" + ) assert storage.cache_covers( - "yahoo", "QQQ", "1w", date(2021, 1, 1), date(2021, 1, 15), is_247_market=False + "yahoo", "QQQ", "1w", date(2021, 1, 1), date(2021, 1, 15), calendar="XNYS" ) @@ -1991,14 +2315,18 @@ def test_cache_covers_monthly_bar_does_not_overclaim_past_its_own_month( storage = ParquetStorage(cache_dir=tmp_path / "cache", metadata_dir=tmp_path / "md") storage.write_symbol( - _ohlcv_at(pd.to_datetime(["2021-01-02"])), "yahoo", "SPY", "1mo" + _ohlcv_at(pd.to_datetime(["2021-01-02"])), + "yahoo", + "SPY", + "1mo", + calendar="XNYS", ) assert not storage.cache_covers( - "yahoo", "SPY", "1mo", date(2021, 1, 2), date(2021, 2, 1), is_247_market=False + "yahoo", "SPY", "1mo", date(2021, 1, 2), date(2021, 2, 1), calendar="XNYS" ) # But it does genuinely cover a request confined to its own month. assert storage.cache_covers( - "yahoo", "SPY", "1mo", date(2021, 1, 2), date(2021, 1, 31), is_247_market=False + "yahoo", "SPY", "1mo", date(2021, 1, 2), date(2021, 1, 31), calendar="XNYS" ) @@ -2009,9 +2337,9 @@ def test_cache_covers_monthly_gap_in_requested_start_month_detected( storage = ParquetStorage(cache_dir=tmp_path / "cache", metadata_dir=tmp_path / "md") dates = pd.to_datetime(["2019-12-01", "2020-02-01"]) - storage.write_symbol(_ohlcv_at(dates), "yahoo", "SPY", "1mo") + storage.write_symbol(_ohlcv_at(dates), "yahoo", "SPY", "1mo", calendar="XNYS") assert not storage.cache_covers( - "yahoo", "SPY", "1mo", date(2020, 1, 15), date(2020, 2, 29), is_247_market=False + "yahoo", "SPY", "1mo", date(2020, 1, 15), date(2020, 2, 29), calendar="XNYS" ) @@ -2022,9 +2350,9 @@ def test_cache_covers_weekly_gap_in_requested_start_week_detected( storage = ParquetStorage(cache_dir=tmp_path / "cache", metadata_dir=tmp_path / "md") dates = pd.to_datetime(["2020-01-01", "2020-01-15"]) - storage.write_symbol(_ohlcv_at(dates), "yahoo", "SPY", "1w") + storage.write_symbol(_ohlcv_at(dates), "yahoo", "SPY", "1w", calendar="XNYS") assert not storage.cache_covers( - "yahoo", "SPY", "1w", date(2020, 1, 10), date(2020, 1, 15), is_247_market=False + "yahoo", "SPY", "1w", date(2020, 1, 10), date(2020, 1, 15), calendar="XNYS" ) @@ -2035,9 +2363,9 @@ def test_cache_covers_monthly_tolerates_shifting_first_trading_day( storage = ParquetStorage(cache_dir=tmp_path / "cache", metadata_dir=tmp_path / "md") dates = pd.to_datetime(["2020-01-03", "2020-02-03", "2020-03-03", "2020-04-03"]) - storage.write_symbol(_ohlcv_at(dates), "yahoo", "SPY", "1mo") + storage.write_symbol(_ohlcv_at(dates), "yahoo", "SPY", "1mo", calendar="XNYS") assert storage.cache_covers( - "yahoo", "SPY", "1mo", date(2020, 1, 3), date(2020, 4, 3), is_247_market=False + "yahoo", "SPY", "1mo", date(2020, 1, 3), date(2020, 4, 3), calendar="XNYS" ) @@ -2051,9 +2379,9 @@ def test_cache_covers_weekly_tolerates_a_holiday_shifted_first_week( pd.Timestamp("2024-01-02"), *pd.date_range("2024-01-08", "2024-12-30", freq="W-MON"), ] - storage.write_symbol(_ohlcv_at(dates), "yahoo", "SPY", "1w") + storage.write_symbol(_ohlcv_at(dates), "yahoo", "SPY", "1w", calendar="XNYS") assert storage.cache_covers( - "yahoo", "SPY", "1w", date(2024, 1, 2), date(2024, 12, 30), is_247_market=False + "yahoo", "SPY", "1w", date(2024, 1, 2), date(2024, 12, 30), calendar="XNYS" ) @@ -2064,16 +2392,16 @@ def test_cache_covers_rejects_sparse_cache_narrower_than_a_bucket( storage = ParquetStorage(cache_dir=tmp_path / "cache", metadata_dir=tmp_path / "md") dates = pd.to_datetime(["2024-01-01", "2024-01-10"]) - storage.write_symbol(_ohlcv_at(dates), "yahoo", "SPY", "1w") + storage.write_symbol(_ohlcv_at(dates), "yahoo", "SPY", "1w", calendar="XNYS") assert not storage.cache_covers( - "yahoo", "SPY", "1w", date(2024, 1, 5), date(2024, 1, 6), is_247_market=False + "yahoo", "SPY", "1w", date(2024, 1, 5), date(2024, 1, 6), calendar="XNYS" ) # Same root cause, different shape: the one raw-timestamp match that # exists (January 1st) is real, but its own bucket doesn't settle until # the following week, so a request for exactly that one day alone still # can't actually be served either. assert not storage.cache_covers( - "yahoo", "SPY", "1w", date(2024, 1, 1), date(2024, 1, 1), is_247_market=False + "yahoo", "SPY", "1w", date(2024, 1, 1), date(2024, 1, 1), calendar="XNYS" ) @@ -2087,26 +2415,36 @@ def test_cache_covers_weekly_request_starting_on_a_holiday( pd.Timestamp("2024-01-02"), *pd.date_range("2024-01-08", "2024-03-25", freq="W-MON"), ] - storage.write_symbol(_ohlcv_at(dates), "yahoo", "SPY", "1w") + storage.write_symbol(_ohlcv_at(dates), "yahoo", "SPY", "1w", calendar="XNYS") assert storage.cache_covers( - "yahoo", "SPY", "1w", date(2024, 1, 1), date(2024, 3, 1), is_247_market=False + "yahoo", "SPY", "1w", date(2024, 1, 1), date(2024, 3, 1), calendar="XNYS" ) # Sanity: a genuine gap must still be caught, holiday-start or not. gappy = [d for d in dates if d != pd.Timestamp("2024-01-08")] - storage.write_symbol(_ohlcv_at(gappy, symbol="QQQ"), "yahoo", "QQQ", "1w") + storage.write_symbol( + _ohlcv_at(gappy, symbol="QQQ"), "yahoo", "QQQ", "1w", calendar="XNYS" + ) assert not storage.cache_covers( - "yahoo", "QQQ", "1w", date(2024, 1, 1), date(2024, 3, 1), is_247_market=False + "yahoo", "QQQ", "1w", date(2024, 1, 1), date(2024, 3, 1), calendar="XNYS" ) -def test_write_symbol_drops_a_still_open_bar(tmp_path: Path) -> None: +def test_write_then_read_symbol_hides_a_still_open_bar_from_the_served_view( + tmp_path: Path, +) -> None: + """The round trip serves a still-open bar as absent -- write_symbol + itself never drops it from the persisted file (see + test_write_symbol_never_drops_still_open_bars_from_the_persisted_file); + only read_symbol's own view is filtered.""" from quantlab.data.storage import ParquetStorage storage = ParquetStorage(cache_dir=tmp_path / "cache", metadata_dir=tmp_path / "md") now = pd.Timestamp.now(tz="UTC").tz_localize(None) still_open_month = now.normalize() + pd.offsets.MonthBegin(1) - storage.write_symbol(_ohlcv_at([still_open_month]), "yahoo", "SPY", "1mo") - cached = storage.read_symbol("yahoo", "SPY", "1mo") + storage.write_symbol( + _ohlcv_at([still_open_month]), "yahoo", "SPY", "1mo", calendar="XNYS" + ) + cached = storage.read_symbol("yahoo", "SPY", "1mo", calendar="XNYS") assert cached is None or cached.empty @@ -2124,12 +2462,24 @@ def test_write_symbol_forced_rewrite_clears_a_stale_legacy_bar( assert len(before) == 1 # stale bar present, read directly off disk empty = _ohlcv_at([]).astype({"timestamp": "datetime64[ns]", "symbol": "object"}) - storage.write_symbol(empty, "yahoo", "SPY", "1mo") - after = storage.read_symbol("yahoo", "SPY", "1mo") + storage.write_symbol(empty, "yahoo", "SPY", "1mo", calendar="XNYS") + after = storage.read_symbol("yahoo", "SPY", "1mo", calendar="XNYS") assert after is None or after.empty -def test_read_symbol_purges_a_still_open_bar_from_disk(tmp_path: Path) -> None: +def test_read_symbol_filters_a_still_open_bar_without_touching_disk( + tmp_path: Path, +) -> None: + """read_symbol must never rewrite the cache file -- only write_symbol + does. Two experiments can legitimately share one cache key (same + source/symbol/frequency) while using different calendars, which settle + a bar's bucket at different instants (e.g. XNYS's real close time vs + 24/7's UTC-midnight convention); if a read purged the file using + whichever caller happened to ask first, one calendar's "still open" + opinion could permanently delete a bar another calendar had already + correctly settled and stored. Filtering the served view without ever + rewriting the file rules that out categorically, regardless of which + calendar reads it or in what order.""" from quantlab.data.storage import ParquetStorage storage = ParquetStorage(cache_dir=tmp_path / "cache", metadata_dir=tmp_path / "md") @@ -2138,14 +2488,14 @@ def test_read_symbol_purges_a_still_open_bar_from_disk(tmp_path: Path) -> None: path = storage._cache_path("yahoo", "SPY", "1mo") storage.save(_ohlcv_at([still_open_month]), path) - served = storage.read_symbol("yahoo", "SPY", "1mo") + served = storage.read_symbol("yahoo", "SPY", "1mo", calendar="XNYS") assert served is not None assert served.empty - # Purged from disk too, not merely filtered in-memory -- a second, - # independent read of the raw file must not see it either. + # Left untouched on disk -- a still-open bar is filtered for THIS + # caller only, never purged from the shared file. on_disk = storage.load(path) - assert on_disk.empty + assert len(on_disk) == 1 def test_csv_source_does_not_serve_a_still_open_bar(tmp_path: Path) -> None: @@ -2180,12 +2530,10 @@ def test_csv_source_does_not_serve_a_still_open_bar(tmp_path: Path) -> None: { "experiment_name": "test", "data": { - "source": "csv", - "symbols": ["BTC"], + "instruments": [{"symbol": "BTC", "source": "csv", "calendar": "24/7"}], "start_date": str(dates[0].date()), "end_date": str(still_open_day.date()), "frequency": "1d", - "market_calendar": "24/7", }, "strategy": {"name": "buy_and_hold"}, } @@ -2212,9 +2560,9 @@ def test_cache_covers_detects_missing_internal_daily_bar(tmp_path: Path) -> None "volume": 100.0, } ) - storage.write_symbol(data, "yahoo", "SPY", "1d") + storage.write_symbol(data, "yahoo", "SPY", "1d", calendar="XNYS") assert not storage.cache_covers( - "yahoo", "SPY", "1d", date(2021, 1, 4), date(2021, 3, 1), is_247_market=False + "yahoo", "SPY", "1d", date(2021, 1, 4), date(2021, 3, 1), calendar="XNYS" ) @@ -2238,9 +2586,9 @@ def test_cache_covers_detects_missing_internal_hourly_247_bar( "volume": 100.0, } ) - storage.write_symbol(data, "binance", "BTC", "1h") + storage.write_symbol(data, "binance", "BTC", "1h", calendar="24/7") assert not storage.cache_covers( - "binance", "BTC", "1h", date(2021, 1, 1), date(2021, 1, 2), is_247_market=True + "binance", "BTC", "1h", date(2021, 1, 1), date(2021, 1, 2), calendar="24/7" ) @@ -2264,9 +2612,9 @@ def test_cache_covers_tolerates_a_small_number_of_calendar_blind_spots( "volume": 100.0, } ) - storage.write_symbol(data, "yahoo", "SPY", "1d") + storage.write_symbol(data, "yahoo", "SPY", "1d", calendar="XNYS") assert storage.cache_covers( - "yahoo", "SPY", "1d", date(2012, 10, 1), date(2012, 11, 30), is_247_market=False + "yahoo", "SPY", "1d", date(2012, 10, 1), date(2012, 11, 30), calendar="XNYS" ) @@ -2290,9 +2638,9 @@ def test_cache_covers_rejects_an_arbitrary_missing_session( "volume": 100.0, } ) - storage.write_symbol(data, "yahoo", "SPY", "1d") + storage.write_symbol(data, "yahoo", "SPY", "1d", calendar="XNYS") assert not storage.cache_covers( - "yahoo", "SPY", "1d", date(2019, 1, 1), date(2019, 12, 31), is_247_market=False + "yahoo", "SPY", "1d", date(2019, 1, 1), date(2019, 12, 31), calendar="XNYS" ) @@ -2316,14 +2664,14 @@ def test_cache_covers_247_daily_has_zero_calendar_tolerance( "volume": 100.0, } ) - storage.write_symbol(data, "binance", "BTCUSDT", "1d") + storage.write_symbol(data, "binance", "BTCUSDT", "1d", calendar="24/7") assert not storage.cache_covers( "binance", "BTCUSDT", "1d", date(2021, 1, 1), date(2021, 3, 1), - is_247_market=True, + calendar="24/7", ) @@ -2349,14 +2697,14 @@ def test_cache_covers_247_hourly_has_zero_calendar_tolerance( "volume": 100.0, } ) - storage.write_symbol(data, "binance", "BTCUSDT", "1h") + storage.write_symbol(data, "binance", "BTCUSDT", "1h", calendar="24/7") assert not storage.cache_covers( "binance", "BTCUSDT", "1h", date(2021, 1, 1), date(2021, 1, 20), - is_247_market=True, + calendar="24/7", ) @@ -2378,9 +2726,9 @@ def test_cache_covers_equity_daily_tolerance_unaffected(tmp_path: Path) -> None: "volume": 100.0, } ) - storage.write_symbol(data, "yahoo", "SPY", "1d") + storage.write_symbol(data, "yahoo", "SPY", "1d", calendar="XNYS") assert storage.cache_covers( - "yahoo", "SPY", "1d", date(2012, 10, 1), date(2012, 11, 30), is_247_market=False + "yahoo", "SPY", "1d", date(2012, 10, 1), date(2012, 11, 30), calendar="XNYS" ) @@ -2406,9 +2754,9 @@ def test_cache_covers_complete_daily_and_hourly_caches_still_pass( "volume": 100.0, } ) - storage.write_symbol(data, "yahoo", "SPY", "1d") + storage.write_symbol(data, "yahoo", "SPY", "1d", calendar="XNYS") assert storage.cache_covers( - "yahoo", "SPY", "1d", date(2021, 1, 4), date(2021, 1, 8), is_247_market=False + "yahoo", "SPY", "1d", date(2021, 1, 4), date(2021, 1, 8), calendar="XNYS" ) hours = pd.date_range("2021-01-01", periods=48, freq="h").tolist() @@ -2424,9 +2772,9 @@ def test_cache_covers_complete_daily_and_hourly_caches_still_pass( "volume": 100.0, } ) - storage.write_symbol(data2, "binance", "BTC", "1h") + storage.write_symbol(data2, "binance", "BTC", "1h", calendar="24/7") assert storage.cache_covers( - "binance", "BTC", "1h", date(2021, 1, 1), date(2021, 1, 2), is_247_market=True + "binance", "BTC", "1h", date(2021, 1, 1), date(2021, 1, 2), calendar="24/7" ) @@ -2450,9 +2798,9 @@ def test_cache_covers_ignores_a_gap_outside_the_requested_range( "volume": 100.0, } ) - storage.write_symbol(data, "yahoo", "SPY", "1d") + storage.write_symbol(data, "yahoo", "SPY", "1d", calendar="XNYS") assert storage.cache_covers( - "yahoo", "SPY", "1d", date(2020, 1, 1), date(2020, 12, 31), is_247_market=False + "yahoo", "SPY", "1d", date(2020, 1, 1), date(2020, 12, 31), calendar="XNYS" ) # A request that actually spans the (small, tolerated) 2012 Sandy gap # must still pass too — see @@ -2477,9 +2825,10 @@ def test_cache_covers_ignores_a_gap_outside_the_requested_range( "yahoo", "QQQ", "1d", + calendar="XNYS", ) assert not storage.cache_covers( - "yahoo", "QQQ", "1d", date(2016, 1, 1), date(2016, 12, 31), is_247_market=False + "yahoo", "QQQ", "1d", date(2016, 1, 1), date(2016, 12, 31), calendar="XNYS" ) @@ -2505,9 +2854,9 @@ def test_cache_covers_hourly_247_ignores_a_gap_outside_the_requested_range( "volume": 100.0, } ) - storage.write_symbol(data, "binance", "BTC", "1h") + storage.write_symbol(data, "binance", "BTC", "1h", calendar="24/7") assert storage.cache_covers( - "binance", "BTC", "1h", date(2021, 1, 7), date(2021, 1, 8), is_247_market=True + "binance", "BTC", "1h", date(2021, 1, 7), date(2021, 1, 8), calendar="24/7" ) @@ -2549,14 +2898,14 @@ def test_cache_covers_daily_spy_stopped_dec30_2021_is_incomplete_for_dec31( "volume": 100.0, } ) - storage.write_symbol(data, "yahoo", "SPY", "1d") + storage.write_symbol(data, "yahoo", "SPY", "1d", calendar="XNYS") assert not storage.cache_covers( "yahoo", "SPY", "1d", date(2021, 12, 20), date(2021, 12, 31), - is_247_market=False, + calendar="XNYS", ) @@ -2577,10 +2926,10 @@ def test_cache_covers_a_future_end_date_does_not_perpetually_fail( # cache stopping at a fixed "yesterday" would itself be stale (missing # today's already-closed session) whenever this test happens to run # after today's market close. - latest_closed_day = last_trading_day_on_or_before(today, is_247_market=False) + latest_closed_day = last_trading_day_on_or_before(today, calendar="XNYS") if latest_closed_day == today and daily_equity_bucket_settlement(today) > now: latest_closed_day = last_trading_day_on_or_before( - today - pd.Timedelta(days=1), is_247_market=False + today - pd.Timedelta(days=1), calendar="XNYS" ) dates = pd.bdate_range(end=latest_closed_day, periods=250) data = pd.DataFrame( @@ -2595,10 +2944,10 @@ def test_cache_covers_a_future_end_date_does_not_perpetually_fail( "volume": 100.0, } ) - storage.write_symbol(data, "yahoo", "SPY", "1d") + storage.write_symbol(data, "yahoo", "SPY", "1d", calendar="XNYS") future_end = (today + pd.Timedelta(days=365)).date() assert storage.cache_covers( - "yahoo", "SPY", "1d", dates[0].date(), future_end, is_247_market=False + "yahoo", "SPY", "1d", dates[0].date(), future_end, calendar="XNYS" ) @@ -2626,10 +2975,10 @@ def test_cache_covers_a_future_end_date_still_rejects_a_genuinely_stale_cache( "volume": 100.0, } ) - storage.write_symbol(stale, "yahoo", "SPY", "1d") + storage.write_symbol(stale, "yahoo", "SPY", "1d", calendar="XNYS") future_end = (today + pd.Timedelta(days=365)).date() assert not storage.cache_covers( - "yahoo", "SPY", "1d", dates[0].date(), future_end, is_247_market=False + "yahoo", "SPY", "1d", dates[0].date(), future_end, calendar="XNYS" ) @@ -2676,11 +3025,11 @@ def test_safe_prevents_cache_read_write_collision_end_to_end() -> None: "volume": 0.0, } ) - storage.write_symbol(eur, "yahoo", "EURUSD=X", "1d") - storage.write_symbol(other, "yahoo", "EURUSD_X", "1d") + storage.write_symbol(eur, "yahoo", "EURUSD=X", "1d", calendar="XNYS") + storage.write_symbol(other, "yahoo", "EURUSD_X", "1d", calendar="XNYS") - read_eur = storage.read_symbol("yahoo", "EURUSD=X", "1d") - read_other = storage.read_symbol("yahoo", "EURUSD_X", "1d") + read_eur = storage.read_symbol("yahoo", "EURUSD=X", "1d", calendar="XNYS") + read_other = storage.read_symbol("yahoo", "EURUSD_X", "1d", calendar="XNYS") assert read_eur is not None assert read_other is not None assert (read_eur["close"] == 1.1).all() @@ -2713,10 +3062,10 @@ def test_load_slices_before_cleaning_not_after() -> None: # The *correct*, order-independent pipeline: slice first, then clean. sliced_then_cleaned_wide = cleaner.clean( - DataLoader._slice_range(raw_wide, start, end, "1d", is_247_market=False) + DataLoader._slice_range(raw_wide, start, end, "1d", calendar="XNYS") ) sliced_then_cleaned_narrow = cleaner.clean( - DataLoader._slice_range(narrow, start, end, "1d", is_247_market=False) + DataLoader._slice_range(narrow, start, end, "1d", calendar="XNYS") ) assert len(sliced_then_cleaned_wide) == len(sliced_then_cleaned_narrow) == 2 pd.testing.assert_frame_equal( @@ -2729,10 +3078,10 @@ def test_load_slices_before_cleaning_not_after() -> None: # regression back to that order is caught by this test actually # detecting a difference. clean_then_slice_wide = DataLoader._slice_range( - cleaner.clean(raw_wide), start, end, "1d", is_247_market=False + cleaner.clean(raw_wide), start, end, "1d", calendar="XNYS" ) clean_then_slice_narrow = DataLoader._slice_range( - cleaner.clean(narrow), start, end, "1d", is_247_market=False + cleaner.clean(narrow), start, end, "1d", calendar="XNYS" ) assert len(clean_then_slice_wide) != len(clean_then_slice_narrow) @@ -2753,7 +3102,9 @@ def test_validator_flags_a_requested_symbol_with_zero_rows() -> None: } ) # A file for "AAA" that actually contains "BBB"'s data. - report = DataValidator().validate(frame, expected_symbols=["AAA"]) + report = DataValidator(symbol_calendars=_UniformCalendar("XNYS")).validate( + frame, expected_symbols=["AAA"] + ) assert not report.is_clean assert any("AAA" in w for w in report.warnings) @@ -2779,13 +3130,17 @@ def test_validator_flags_a_symbol_fully_removed_by_cleaning() -> None: cleaned = DataCleaner(MissingValuePolicy.DROP).clean(frame) assert "BBB" not in set(cleaned["symbol"].unique()) - report = DataValidator().validate(cleaned, expected_symbols=["AAA", "BBB"]) + report = DataValidator(symbol_calendars=_UniformCalendar("XNYS")).validate( + cleaned, expected_symbols=["AAA", "BBB"] + ) assert not report.is_clean assert any("BBB" in w for w in report.warnings) # Without `expected_symbols`, validation must still complete normally # (not raise/error) — it simply can't detect the missing-symbol gap. - report_without = DataValidator().validate(cleaned) + report_without = DataValidator(symbol_calendars=_UniformCalendar("XNYS")).validate( + cleaned + ) assert not any("BBB" in w for w in report_without.warnings) @@ -2806,7 +3161,9 @@ def test_validator_raises_on_missing_symbol_in_strict_mode() -> None: } ) with pytest.raises(DataValidationError, match="BBB"): - DataValidator().validate(frame, expected_symbols=["AAA", "BBB"], strict=True) + DataValidator(symbol_calendars=_UniformCalendar("XNYS")).validate( + frame, expected_symbols=["AAA", "BBB"], strict=True + ) def test_loader_passes_expected_symbols_including_benchmark() -> None: @@ -2834,7 +3191,11 @@ def test_frequency_mismatch_flagged_at_exact_tolerance_boundary() -> None: "volume": 1000.0, } ) - report = DataValidator(expected_frequency="1h", min_coverage_rows=1).validate(frame) + report = DataValidator( + expected_frequency="1h", + min_coverage_rows=1, + symbol_calendars=_UniformCalendar("XNYS"), + ).validate(frame) assert any("does not match the declared frequency" in w for w in report.warnings) @@ -2856,7 +3217,11 @@ def test_frequency_exact_match_still_clean_after_boundary_fix() -> None: "volume": 1000.0, } ) - report = DataValidator(expected_frequency="1h", min_coverage_rows=1).validate(frame) + report = DataValidator( + expected_frequency="1h", + min_coverage_rows=1, + symbol_calendars=_UniformCalendar("XNYS"), + ).validate(frame) assert not any( "does not match the declared frequency" in w for w in report.warnings ) @@ -2869,9 +3234,11 @@ def test_frequency_uniform_89min_bars_declared_1h_now_flagged() -> None: from quantlab.data.validator import DataValidator idx = pd.date_range("2020-01-01", periods=50, freq="89min") - report = DataValidator(expected_frequency="1h", min_coverage_rows=1).validate( - _ohlcv_frame(idx) - ) + report = DataValidator( + expected_frequency="1h", + min_coverage_rows=1, + symbol_calendars=_UniformCalendar("XNYS"), + ).validate(_ohlcv_frame(idx)) assert report.warnings @@ -2882,9 +3249,11 @@ def test_frequency_uniform_41min_bars_declared_1h_now_flagged() -> None: from quantlab.data.validator import DataValidator idx = pd.date_range("2020-01-01", periods=50, freq="41min") - report = DataValidator(expected_frequency="1h", min_coverage_rows=1).validate( - _ohlcv_frame(idx) - ) + report = DataValidator( + expected_frequency="1h", + min_coverage_rows=1, + symbol_calendars=_UniformCalendar("XNYS"), + ).validate(_ohlcv_frame(idx)) assert report.warnings @@ -2898,7 +3267,9 @@ def test_frequency_mixed_60_40_spacing_median_cannot_hide_it() -> None: timestamps.append(timestamps[-1] + pd.Timedelta(hours=int(h))) idx = pd.DatetimeIndex(timestamps) report = DataValidator( - expected_frequency="1h", min_coverage_rows=1, is_247_market=True + expected_frequency="1h", + min_coverage_rows=1, + symbol_calendars=_UniformCalendar("24/7"), ).validate(_ohlcv_frame(idx)) assert report.warnings @@ -2908,7 +3279,9 @@ def test_frequency_normal_equity_daily_weekends_not_flagged() -> None: idx = pd.bdate_range("2015-01-01", periods=500) report = DataValidator( - expected_frequency="1d", min_coverage_rows=1, is_247_market=False + expected_frequency="1d", + min_coverage_rows=1, + symbol_calendars=_UniformCalendar("XNYS"), ).validate(_ohlcv_frame(idx)) assert not report.warnings @@ -2918,7 +3291,9 @@ def test_frequency_equity_daily_friday_to_monday_not_flagged() -> None: idx = pd.DatetimeIndex([pd.Timestamp("2024-01-05"), pd.Timestamp("2024-01-08")]) report = DataValidator( - expected_frequency="1d", min_coverage_rows=1, is_247_market=False + expected_frequency="1d", + min_coverage_rows=1, + symbol_calendars=_UniformCalendar("XNYS"), ).validate(_ohlcv_frame(idx)) assert not report.warnings @@ -2931,7 +3306,9 @@ def test_frequency_equity_daily_genuine_every_other_day_still_flagged() -> None: idx = pd.bdate_range("2020-01-01", periods=200)[::2] report = DataValidator( - expected_frequency="1d", min_coverage_rows=1, is_247_market=False + expected_frequency="1d", + min_coverage_rows=1, + symbol_calendars=_UniformCalendar("XNYS"), ).validate(_ohlcv_frame(idx)) assert report.warnings @@ -2941,7 +3318,9 @@ def test_frequency_equity_daily_friday_to_tuesday_after_mlk_not_flagged() -> Non idx = pd.DatetimeIndex([pd.Timestamp("2024-01-12"), pd.Timestamp("2024-01-16")]) report = DataValidator( - expected_frequency="1d", min_coverage_rows=1, is_247_market=False + expected_frequency="1d", + min_coverage_rows=1, + symbol_calendars=_UniformCalendar("XNYS"), ).validate(_ohlcv_frame(idx)) assert not report.warnings @@ -2957,7 +3336,9 @@ def test_frequency_equity_subdaily_overnight_gaps_not_flagged() -> None: ) idx = pd.DatetimeIndex(dates) report = DataValidator( - expected_frequency="1h", min_coverage_rows=1, is_247_market=False + expected_frequency="1h", + min_coverage_rows=1, + symbol_calendars=_UniformCalendar("XNYS"), ).validate(_ohlcv_frame(idx)) assert not report.warnings @@ -2972,7 +3353,9 @@ def test_frequency_247_market_80_20_mix_now_flagged() -> None: timestamps.append(timestamps[-1] + pd.Timedelta(hours=5)) idx = pd.DatetimeIndex(timestamps) report = DataValidator( - expected_frequency="1h", min_coverage_rows=1, is_247_market=True + expected_frequency="1h", + min_coverage_rows=1, + symbol_calendars=_UniformCalendar("24/7"), ).validate(_ohlcv_frame(idx)) assert report.warnings @@ -2987,7 +3370,9 @@ def test_frequency_247_market_exactly_90_10_mix_now_flagged() -> None: timestamps.append(timestamps[-1] + pd.Timedelta(hours=5)) idx = pd.DatetimeIndex(timestamps) report = DataValidator( - expected_frequency="1h", min_coverage_rows=1, is_247_market=True + expected_frequency="1h", + min_coverage_rows=1, + symbol_calendars=_UniformCalendar("24/7"), ).validate(_ohlcv_frame(idx)) assert report.warnings @@ -3002,7 +3387,9 @@ def test_frequency_247_market_91_9_mix_now_flagged() -> None: timestamps.append(timestamps[-1] + pd.Timedelta(hours=5)) idx = pd.DatetimeIndex(timestamps) report = DataValidator( - expected_frequency="1h", min_coverage_rows=1, is_247_market=True + expected_frequency="1h", + min_coverage_rows=1, + symbol_calendars=_UniformCalendar("24/7"), ).validate(_ohlcv_frame(idx)) assert report.warnings @@ -3016,7 +3403,9 @@ def test_frequency_247_market_large_clean_series_not_flagged() -> None: timestamps.append(timestamps[-1] + step) idx = pd.DatetimeIndex(timestamps) report = DataValidator( - expected_frequency="1h", min_coverage_rows=1, is_247_market=True + expected_frequency="1h", + min_coverage_rows=1, + symbol_calendars=_UniformCalendar("24/7"), ).validate(_ohlcv_frame(idx)) assert not any( "does not match the declared frequency" in w for w in report.warnings @@ -3032,7 +3421,9 @@ def test_frequency_247_market_single_missing_bar_now_flagged() -> None: timestamps.append(timestamps[-1] + step) idx = pd.DatetimeIndex(timestamps) report = DataValidator( - expected_frequency="1h", min_coverage_rows=1, is_247_market=True + expected_frequency="1h", + min_coverage_rows=1, + symbol_calendars=_UniformCalendar("24/7"), ).validate(_ohlcv_frame(idx)) assert any("abnormal gap" in w for w in report.warnings) assert len(report.missing_periods) == 1 @@ -3067,7 +3458,9 @@ def frame(dates: pd.DatetimeIndex) -> pd.DataFrame: ) validator = DataValidator( - expected_frequency="1d", is_247_market=True, min_coverage_rows=1 + expected_frequency="1d", + symbol_calendars=_UniformCalendar("24/7"), + min_coverage_rows=1, ) missing_first = pd.date_range("2024-01-02", "2024-01-30", freq="D") @@ -3099,7 +3492,9 @@ def test_frequency_247_hourly_missing_the_last_23_hours_now_flagged() -> None: dates = pd.date_range("2020-01-01", "2020-01-05 00:00:00", freq="1h") incomplete = _ohlcv_frame(dates) report = DataValidator( - expected_frequency="1h", is_247_market=True, min_coverage_rows=1 + expected_frequency="1h", + symbol_calendars=_UniformCalendar("24/7"), + min_coverage_rows=1, ).validate(incomplete, start=date(2020, 1, 1), end=date(2020, 1, 5)) assert report.warnings assert not report.is_clean @@ -3107,7 +3502,9 @@ def test_frequency_247_hourly_missing_the_last_23_hours_now_flagged() -> None: # Sanity: a history reaching the day's actual last expected hour is clean. complete_dates = pd.date_range("2020-01-01", "2020-01-05 23:00:00", freq="1h") complete_report = DataValidator( - expected_frequency="1h", is_247_market=True, min_coverage_rows=1 + expected_frequency="1h", + symbol_calendars=_UniformCalendar("24/7"), + min_coverage_rows=1, ).validate( _ohlcv_frame(complete_dates), start=date(2020, 1, 1), end=date(2020, 1, 5) ) @@ -3124,7 +3521,9 @@ def test_frequency_equity_subdaily_bar_missing_every_session_now_flagged() -> No dates.extend(session_start + pd.Timedelta(hours=h) for h in range(7) if h != 3) idx = pd.DatetimeIndex(dates) report = DataValidator( - expected_frequency="1h", min_coverage_rows=1, is_247_market=False + expected_frequency="1h", + min_coverage_rows=1, + symbol_calendars=_UniformCalendar("XNYS"), ).validate(_ohlcv_frame(idx)) assert report.warnings @@ -3145,9 +3544,7 @@ def test_yahoo_intraday_timezone_converted_to_utc_not_stripped_naively() -> None index=idx, ) raw.index.name = "Datetime" - out = YahooFinanceDataSource._normalise( - raw, "AAPL", "1h", pd.Timestamp("2025-01-01"), date(2025, 1, 1) - ) + out = YahooFinanceDataSource._normalise(raw, "AAPL", "1h") assert out["timestamp"].dt.tz is None assert out["timestamp"].tolist() == [ pd.Timestamp("2021-01-04 14:30:00"), @@ -3175,9 +3572,7 @@ def test_yahoo_daily_naive_timestamps_unaffected_by_tz_fix() -> None: index=idx, ) raw.index.name = "Date" - out = YahooFinanceDataSource._normalise( - raw, "AAPL", "1d", pd.Timestamp("2025-01-01"), date(2025, 1, 1) - ) + out = YahooFinanceDataSource._normalise(raw, "AAPL", "1d") assert out["timestamp"].dt.tz is None assert out["timestamp"].tolist() == [ pd.Timestamp("2021-01-04"), @@ -3186,72 +3581,35 @@ def test_yahoo_daily_naive_timestamps_unaffected_by_tz_fix() -> None: ] -def test_yahoo_drops_a_still_open_daily_bar() -> None: - from quantlab.data.yahoo import YahooFinanceDataSource - - now = pd.Timestamp("2021-01-10 15:00:00") - idx = pd.date_range("2021-01-04", "2021-01-10", freq="D") - raw = pd.DataFrame( - { - "Open": 1.0, - "High": 1.0, - "Low": 1.0, - "Close": 1.0, - "Adj Close": 1.0, - "Volume": 100, - }, - index=idx, - ) - raw.index.name = "Date" - out = YahooFinanceDataSource._normalise(raw, "AAA", "1d", now, date(2021, 1, 10)) - assert out["timestamp"].tolist() == list(idx[:-1]) - - -def test_yahoo_keeps_fully_historical_bars() -> None: - """A genuinely historical - download, where every bar's period has long since ended, must be - completely unaffected by this filter.""" - from quantlab.data.yahoo import YahooFinanceDataSource - - now = pd.Timestamp("2025-01-01") - idx = pd.date_range("2021-01-04", "2021-01-10", freq="D") - raw = pd.DataFrame( - { - "Open": 1.0, - "High": 1.0, - "Low": 1.0, - "Close": 1.0, - "Adj Close": 1.0, - "Volume": 100, - }, - index=idx, - ) - raw.index.name = "Date" - out = YahooFinanceDataSource._normalise(raw, "AAA", "1d", now, date(2021, 1, 10)) - assert out["timestamp"].tolist() == list(idx) - - -def test_yahoo_drops_a_still_open_monthly_bar() -> None: - """Same rule, for a monthly bar — the current month's bar (dated the 1st) - must be dropped while `now` is still within that same month.""" +def test_yahoo_daily_tz_aware_timestamps_keep_the_local_date() -> None: + """A calendar-date granularity (daily/weekly/monthly) represents a + *local* trading date, not a specific UTC instant. Converting a + tz-aware Yahoo response through UTC first (correct for intraday, see + test_yahoo_intraday_timezone_converted_to_utc_not_stripped_naively) + would shift the date backward for any exchange ahead of UTC (e.g. + XASX, UTC+11) -- turning a Monday session into "Sunday".""" from quantlab.data.yahoo import YahooFinanceDataSource - now = pd.Timestamp("2021-01-15") - idx = pd.to_datetime(["2020-11-01", "2020-12-01", "2021-01-01"]) + idx = pd.date_range("2024-01-08", periods=3, freq="D", tz="Australia/Sydney") raw = pd.DataFrame( { - "Open": 1.0, - "High": 1.0, - "Low": 1.0, - "Close": 1.0, - "Adj Close": 1.0, - "Volume": 100, + "Open": [1.0, 2.0, 3.0], + "High": [1.0, 2.0, 3.0], + "Low": [1.0, 2.0, 3.0], + "Close": [1.0, 2.0, 3.0], + "Adj Close": [1.0, 2.0, 3.0], + "Volume": [100, 200, 300], }, index=idx, ) raw.index.name = "Date" - out = YahooFinanceDataSource._normalise(raw, "AAA", "1mo", now, date(2021, 1, 15)) - assert out["timestamp"].tolist() == list(idx[:-1]) + out = YahooFinanceDataSource._normalise(raw, "BHP.AX", "1d") + assert out["timestamp"].dt.tz is None + assert out["timestamp"].tolist() == [ + pd.Timestamp("2024-01-08"), + pd.Timestamp("2024-01-09"), + pd.Timestamp("2024-01-10"), + ] def test_canonical_schema_normalises_timezone_aware_timestamps() -> None: @@ -3263,7 +3621,7 @@ def test_canonical_schema_normalises_timezone_aware_timestamps() -> None: assert out["timestamp"].dt.tz is None # Must not raise, and must not silently drop the in-range rows. sliced = DataLoader._slice_range( - out, date(2020, 1, 1), date(2020, 1, 2), "1d", is_247_market=False + out, date(2020, 1, 1), date(2020, 1, 2), "1d", calendar="XNYS" ) assert len(sliced) == 2 @@ -3300,9 +3658,9 @@ def test_cli_backtest_prints_data_warning_text_not_just_a_count( config = { "experiment_name": "cli_data_warning_test", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2020-03-01", "frequency": "1h", @@ -3342,9 +3700,9 @@ def test_run_backtest_script_prints_data_warning_text_not_just_a_count( config = { "experiment_name": "run_backtest_script_warning_test", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2020-03-01", "frequency": "1h", @@ -3389,9 +3747,9 @@ def test_generate_report_script_prints_data_warning_text_not_just_a_count( config = { "experiment_name": "generate_report_script_warning_test", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2020-03-01", "frequency": "1h", @@ -3523,31 +3881,6 @@ def test_binance_drops_candle_closing_after_requested_end() -> None: assert len(out2) == 1 -def test_yahoo_drops_bar_closing_after_requested_end() -> None: - from quantlab.data.yahoo import YahooFinanceDataSource - - idx = pd.to_datetime(["2024-03-01"]) - raw = pd.DataFrame( - { - "Open": [1.0], - "High": [1.0], - "Low": [1.0], - "Close": [1.0], - "Adj Close": [1.0], - "Volume": [100], - }, - index=idx, - ) - raw.index.name = "Date" - now = pd.Timestamp("2024-06-01") # well after the bar's own bucket closed - - out = YahooFinanceDataSource._normalise(raw, "AAA", "1mo", now, date(2024, 3, 15)) - assert out.empty - - out2 = YahooFinanceDataSource._normalise(raw, "AAA", "1mo", now, date(2024, 4, 1)) - assert len(out2) == 1 - - def test_slice_range_drops_a_look_ahead_bar_reused_from_a_wider_cache() -> None: from quantlab.data.loader import DataLoader @@ -3567,14 +3900,14 @@ def test_slice_range_drops_a_look_ahead_bar_reused_from_a_wider_cache() -> None: # Narrower request: Jan 3rd falls inside the Jan 1st-7th bar's own # bucket, which hasn't genuinely closed by Jan 3rd -- must drop it. narrow = DataLoader._slice_range( - cached, date(2024, 1, 1), date(2024, 1, 3), "1w", is_247_market=False + cached, date(2024, 1, 1), date(2024, 1, 3), "1w", calendar="XNYS" ) assert narrow.empty # A request reaching far enough for the bar's own week to have # genuinely closed must still keep it. wide = DataLoader._slice_range( - cached, date(2024, 1, 1), date(2024, 1, 10), "1w", is_247_market=False + cached, date(2024, 1, 1), date(2024, 1, 10), "1w", calendar="XNYS" ) assert len(wide) == 1 @@ -3599,125 +3932,37 @@ def test_slice_range_drops_a_look_ahead_monthly_bar_from_wider_cache() -> None: ) narrow = DataLoader._slice_range( - cached, date(2024, 3, 1), date(2024, 3, 15), "1mo", is_247_market=False + cached, date(2024, 3, 1), date(2024, 3, 15), "1mo", calendar="XNYS" ) assert narrow.empty wide = DataLoader._slice_range( - cached, date(2024, 3, 1), date(2024, 4, 1), "1mo", is_247_market=False + cached, date(2024, 3, 1), date(2024, 4, 1), "1mo", calendar="XNYS" ) assert len(wide) == 1 -def test_yahoo_keeps_a_week_that_genuinely_finished_on_friday() -> None: - from quantlab.data.yahoo import YahooFinanceDataSource +def test_daily_equity_bucket_settlement_reflects_a_real_early_close() -> None: + from quantlab.data.calendar import daily_equity_bucket_settlement - idx = pd.to_datetime(["2024-01-01"]) # a Monday - raw = pd.DataFrame( - { - "Open": [1.0], - "High": [1.0], - "Low": [1.0], - "Close": [1.0], - "Adj Close": [1.0], - "Volume": [100], - }, - index=idx, - ) - raw.index.name = "Date" - now = pd.Timestamp("2026-01-01") + # 2024-11-29 (day after Thanksgiving) is a documented NYSE early-close + # session: 1pm ET, not the ordinary 4pm. + early_close = daily_equity_bucket_settlement(pd.Timestamp("2024-11-29")) + ordinary_close = daily_equity_bucket_settlement(pd.Timestamp("2024-11-27")) + assert early_close == pd.Timestamp("2024-11-29 18:00:00") # 1pm EST -> UTC + assert ordinary_close == pd.Timestamp("2024-11-27 21:00:00") # 4pm EST -> UTC + assert early_close.hour < ordinary_close.hour - # Requested through that week's own Friday -- the week has genuinely - # finished (equity markets never trade the intervening weekend). - out = YahooFinanceDataSource._normalise(raw, "SPY", "1wk", now, date(2024, 1, 5)) - assert len(out) == 1 - # Requested only through the Wednesday of that same week -- the week - # has not finished yet, still correctly dropped. - out2 = YahooFinanceDataSource._normalise(raw, "SPY", "1wk", now, date(2024, 1, 3)) - assert out2.empty +def test_daily_equity_bucket_settlement_is_dst_aware_across_the_spring_transition() -> ( + None +): + from quantlab.data.calendar import daily_equity_bucket_settlement - -def test_yahoo_keeps_a_month_whose_last_trading_day_already_passed() -> None: - from quantlab.data.yahoo import YahooFinanceDataSource - - idx = pd.to_datetime(["2024-11-01"]) - raw = pd.DataFrame( - { - "Open": [1.0], - "High": [1.0], - "Low": [1.0], - "Close": [1.0], - "Adj Close": [1.0], - "Volume": [100], - }, - index=idx, - ) - raw.index.name = "Date" - now = pd.Timestamp("2026-01-01") - - out = YahooFinanceDataSource._normalise(raw, "SPY", "1mo", now, date(2024, 11, 29)) - assert len(out) == 1 - - # Still correctly dropped for a request ending before the month's own - # last trading day. - out2 = YahooFinanceDataSource._normalise(raw, "SPY", "1mo", now, date(2024, 11, 15)) - assert out2.empty - - -def test_yahoo_keeps_a_daily_bar_finalised_after_market_close() -> None: - from quantlab.data.yahoo import YahooFinanceDataSource - - idx = pd.to_datetime(["2024-01-16"]) - raw = pd.DataFrame( - { - "Open": [1.0], - "High": [1.0], - "Low": [1.0], - "Close": [1.0], - "Adj Close": [1.0], - "Volume": [100], - }, - index=idx, - ) - raw.index.name = "Date" - - # 21:30 UTC = 4:30pm EST -- just after the real market close. - now_after_close = pd.Timestamp("2024-01-16 21:30:00") - out = YahooFinanceDataSource._normalise( - raw, "SPY", "1d", now_after_close, date(2024, 1, 16) - ) - assert len(out) == 1 - - # 19:00 UTC = 2pm EST -- market still open, must still be dropped. - now_before_close = pd.Timestamp("2024-01-16 19:00:00") - out2 = YahooFinanceDataSource._normalise( - raw, "SPY", "1d", now_before_close, date(2024, 1, 16) - ) - assert out2.empty - - -def test_daily_equity_bucket_settlement_reflects_a_real_early_close() -> None: - from quantlab.data.calendar import daily_equity_bucket_settlement - - # 2024-11-29 (day after Thanksgiving) is a documented NYSE early-close - # session: 1pm ET, not the ordinary 4pm. - early_close = daily_equity_bucket_settlement(pd.Timestamp("2024-11-29")) - ordinary_close = daily_equity_bucket_settlement(pd.Timestamp("2024-11-27")) - assert early_close == pd.Timestamp("2024-11-29 18:00:00") # 1pm EST -> UTC - assert ordinary_close == pd.Timestamp("2024-11-27 21:00:00") # 4pm EST -> UTC - assert early_close.hour < ordinary_close.hour - - -def test_daily_equity_bucket_settlement_is_dst_aware_across_the_spring_transition() -> ( - None -): - from quantlab.data.calendar import daily_equity_bucket_settlement - - before_dst = daily_equity_bucket_settlement(pd.Timestamp("2024-03-08")) # EST - after_dst = daily_equity_bucket_settlement(pd.Timestamp("2024-03-11")) # EDT - assert before_dst == pd.Timestamp("2024-03-08 21:00:00") # 4pm EST = 21:00 UTC - assert after_dst == pd.Timestamp("2024-03-11 20:00:00") # 4pm EDT = 20:00 UTC + before_dst = daily_equity_bucket_settlement(pd.Timestamp("2024-03-08")) # EST + after_dst = daily_equity_bucket_settlement(pd.Timestamp("2024-03-11")) # EDT + assert before_dst == pd.Timestamp("2024-03-08 21:00:00") # 4pm EST = 21:00 UTC + assert after_dst == pd.Timestamp("2024-03-11 20:00:00") # 4pm EDT = 20:00 UTC def test_daily_equity_bucket_settlement_is_conservative_for_a_non_session() -> None: @@ -3753,78 +3998,131 @@ def test_periodic_equity_settlement_uses_the_last_session_close() -> None: expected = daily_equity_bucket_settlement(pd.Timestamp("2024-11-29")) assert ( - weekly_bucket_settlement(pd.Timestamp("2024-11-25"), is_247_market=False) + weekly_bucket_settlement(pd.Timestamp("2024-11-25"), calendar="XNYS") == expected ) assert ( - monthly_bucket_settlement(pd.Timestamp("2024-11-01"), is_247_market=False) + monthly_bucket_settlement(pd.Timestamp("2024-11-01"), calendar="XNYS") == expected ) -def test_yahoo_247_daily_not_closed_at_equity_market_close() -> None: - from quantlab.data.yahoo import YahooFinanceDataSource +def test_weekly_bucket_settlement_uses_the_calendars_own_trading_week() -> None: + """XSAU trades Sunday-Thursday (weekend Friday-Saturday) -- a fixed + Monday-Sunday ISO week would misfile every date into the wrong week + (Monday isn't the start of XSAU's week, Sunday isn't its end). Every day + from Sunday through Saturday of one native XSAU week must settle at that + same week's Thursday close, mirroring how every day from Monday through + Sunday of an XNYS week already settles at that week's Friday close.""" + from quantlab.data.calendar import ( + daily_equity_bucket_settlement, + weekly_bucket_settlement, + ) - idx = pd.to_datetime(["2024-01-16"]) - raw = pd.DataFrame( - { - "Open": [1.0], - "High": [1.0], - "Low": [1.0], - "Close": [1.0], - "Adj Close": [1.0], - "Volume": [100], - }, - index=idx, + expected = daily_equity_bucket_settlement( + pd.Timestamp("2024-01-11"), calendar="XSAU" ) - raw.index.name = "Date" + for day in [ + "2024-01-07", # Sunday -- start of the native week + "2024-01-08", + "2024-01-09", + "2024-01-10", + "2024-01-11", # Thursday -- end of the native week + "2024-01-12", # Friday -- rest day, belongs to the week just ended + "2024-01-13", # Saturday -- rest day, same + ]: + assert ( + weekly_bucket_settlement(pd.Timestamp(day), calendar="XSAU") == expected + ), day + + +def test_weekly_bucket_settlement_not_derailed_by_a_midweek_holiday() -> None: + """A one-off holiday (Thanksgiving, a Thursday) must never be mistaken + for the structural end of the trading week -- the week still runs + through its real last trading weekday (Friday), just skipping the + holiday itself.""" + from quantlab.data.calendar import ( + daily_equity_bucket_settlement, + weekly_bucket_settlement, + ) + + expected = daily_equity_bucket_settlement(pd.Timestamp("2024-11-29")) # Friday + for day in ["2024-11-25", "2024-11-26", "2024-11-27", "2024-11-28", "2024-11-29"]: + assert ( + weekly_bucket_settlement(pd.Timestamp(day), calendar="XNYS") == expected + ), day + + +def test_weekly_bucket_settlement_resolves_a_holiday_on_the_boundary_weekday() -> None: + """A one-off holiday landing exactly *on* the structural last trading + weekday (Good Friday 2024-03-29, a Friday, for XNYS) is different from + a mid-week holiday: the structural walk lands the cursor itself on the + holiday, which has no real close of its own. Falling back to + daily_equity_bucket_settlement's own "no session -> next UTC midnight" + default there (Saturday 2024-03-30 00:00) would be wrong -- the week + must instead resolve to the last real trading day before it (Thursday + 2024-03-28) and settle at *that* day's actual close.""" + from quantlab.data.calendar import ( + daily_equity_bucket_settlement, + weekly_bucket_settlement, + ) + + expected = daily_equity_bucket_settlement( + pd.Timestamp("2024-03-28"), calendar="XNYS" + ) + assert expected == pd.Timestamp("2024-03-28 20:00:00") + for day in [ + "2024-03-25", # Monday + "2024-03-26", + "2024-03-27", + "2024-03-28", # Thursday -- last real trading day + "2024-03-29", # Good Friday -- holiday, structurally the boundary + "2024-03-30", # Saturday -- rest day, belongs to the week just ended + "2024-03-31", # Sunday -- rest day, same + ]: + assert ( + weekly_bucket_settlement(pd.Timestamp(day), calendar="XNYS") == expected + ), day + + +def test_bar_bucket_end_distinguishes_xnys_close_from_24_7_midnight() -> None: + """The same daily bar settles at different instants under different + calendars -- XNYS at its real market close, 24/7 at UTC midnight. This is + the single settlement primitive :class:`~quantlab.data.storage. + ParquetStorage`'s ``_drop_still_open_bars``/``_slice_range`` rely on for + every provider (Yahoo included, see quantlab.data.yahoo._normalise's own + docstring) -- filtering must key off the calendar actually configured for + the symbol, not a fixed cutoff.""" + from quantlab.data.calendar import bar_bucket_end + + idx = pd.Series(pd.to_datetime(["2024-01-16"])) + xnys_close = bar_bucket_end(idx, "1d", calendar="XNYS") + day_247_close = bar_bucket_end(idx, "1d", calendar="24/7") # 21:30 UTC: already closed for an equity asset, but the crypto day # genuinely runs until midnight UTC. now = pd.Timestamp("2024-01-16 21:30:00") - out_equity = YahooFinanceDataSource._normalise( - raw, "SPY", "1d", now, date(2024, 1, 16), False - ) - assert len(out_equity) == 1 - out_crypto = YahooFinanceDataSource._normalise( - raw, "BTC-USD", "1d", now, date(2024, 1, 16), True - ) - assert out_crypto.empty + assert (xnys_close <= now).all() + assert not (day_247_close <= now).all() # Just after midnight UTC: the crypto day has genuinely finished too. now_after_midnight = pd.Timestamp("2024-01-17 00:30:00") - out_crypto_done = YahooFinanceDataSource._normalise( - raw, "BTC-USD", "1d", now_after_midnight, date(2024, 1, 16), True - ) - assert len(out_crypto_done) == 1 + assert (day_247_close <= now_after_midnight).all() -def test_yahoo_247_weekly_not_closed_at_friday_equity_close() -> None: - from quantlab.data.yahoo import YahooFinanceDataSource +def test_bar_bucket_end_distinguishes_xnys_friday_close_from_24_7_monday() -> None: + """Same distinction as :func:`test_bar_bucket_end_distinguishes_xnys_ + close_from_24_7_midnight`, for a weekly bar: an equity week closes + Friday, but a 24/7 week doesn't close until the following Monday.""" + from quantlab.data.calendar import bar_bucket_end - idx = pd.to_datetime(["2024-01-01"]) # a Monday - raw = pd.DataFrame( - { - "Open": [1.0], - "High": [1.0], - "Low": [1.0], - "Close": [1.0], - "Adj Close": [1.0], - "Volume": [100], - }, - index=idx, - ) - raw.index.name = "Date" + idx = pd.Series(pd.to_datetime(["2024-01-01"])) # a Monday + xnys_close = bar_bucket_end(idx, "1w", calendar="XNYS") + day_247_close = bar_bucket_end(idx, "1w", calendar="24/7") sunday_noon = pd.Timestamp("2024-01-07 12:00:00") - out_equity = YahooFinanceDataSource._normalise( - raw, "SPY", "1wk", sunday_noon, date(2024, 1, 7), False - ) - assert len(out_equity) == 1 # equity week already closed Friday - out_crypto = YahooFinanceDataSource._normalise( - raw, "BTC-USD", "1wk", sunday_noon, date(2024, 1, 7), True - ) - assert out_crypto.empty # crypto week doesn't close until Monday + assert (xnys_close <= sunday_noon).all() # equity week already closed Friday + assert not (day_247_close <= sunday_noon).all() # 24/7 week runs to Monday def test_drop_still_open_bars_uses_the_right_calendar( @@ -3839,11 +4137,11 @@ def test_drop_still_open_bars_uses_the_right_calendar( now = pd.Timestamp.now(tz="UTC").tz_localize(None) today = pd.Timestamp(year=now.year, month=now.month, day=now.day) closed_session = last_trading_day_on_or_before( - today - pd.Timedelta(days=1), is_247_market=False + today - pd.Timedelta(days=1), calendar="XNYS" ) data = pd.DataFrame({"timestamp": [closed_session], "symbol": ["AAPL"]}) - assert len(_drop_still_open_bars(data, "1d", is_247_market=False)) == 1 - assert len(_drop_still_open_bars(data, "1d", is_247_market=True)) == 1 + assert len(_drop_still_open_bars(data, "1d", calendar="XNYS")) == 1 + assert len(_drop_still_open_bars(data, "1d", calendar="24/7")) == 1 equity_close = daily_equity_bucket_settlement(closed_session) flat_close = closed_session + pd.Timedelta(days=1) @@ -3862,8 +4160,8 @@ def test_drop_still_open_bars_uses_the_right_calendar( "volume": 100.0, } ) - storage.write_symbol(equity_data, "yahoo", "AAPL", "1d", is_247_market=False) - read_back = storage.read_symbol("yahoo", "AAPL", "1d", is_247_market=False) + storage.write_symbol(equity_data, "yahoo", "AAPL", "1d", calendar="XNYS") + read_back = storage.read_symbol("yahoo", "AAPL", "1d", calendar="XNYS") assert read_back is not None assert len(read_back) == 1 @@ -3888,9 +4186,7 @@ def test_yahoo_missing_close_reaches_missing_value_policy() -> None: index=idx, ) raw.index.name = "Date" - out = YahooFinanceDataSource._normalise( - raw, "AAA", "1d", pd.Timestamp("2025-01-01"), date(2020, 1, 3) - ) + out = YahooFinanceDataSource._normalise(raw, "AAA", "1d") assert len(out) == 3 # the row is no longer dropped inside `_normalise` assert out["close"].isna().sum() == 1 @@ -3919,50 +4215,10 @@ def test_yahoo_missing_volume_not_silently_zeroed() -> None: index=idx, ) raw.index.name = "Date" - out = YahooFinanceDataSource._normalise( - raw, "AAA", "1d", pd.Timestamp("2025-01-01"), date(2020, 1, 3) - ) + out = YahooFinanceDataSource._normalise(raw, "AAA", "1d") assert out["volume"].isna().tolist() == [False, True, False] -def test_yahoo_download_one_raises_when_every_bar_is_filtered_out() -> None: - from unittest.mock import patch - - from quantlab.data.yahoo import YahooFinanceDataSource - from quantlab.exceptions import DataDownloadError - - source = YahooFinanceDataSource(max_retries=1) - now = pd.Timestamp.now(tz="UTC").tz_localize(None) - # Dated *tomorrow*, not today: with market-close-aware daily - # settlement, "today" is only still-forming before 4pm US/Eastern — - # ambiguous depending on what time of day this test happens to run. - # Tomorrow's own close is unconditionally still in the future relative - # to `now`, regardless of time of day, so it stays unambiguously - # still-forming. - still_forming = now.normalize() + pd.Timedelta(days=1) - idx = pd.DatetimeIndex([still_forming]) - raw = pd.DataFrame( - { - "Open": [1.0], - "High": [1.0], - "Low": [1.0], - "Close": [1.0], - "Adj Close": [1.0], - "Volume": [100], - }, - index=idx, - ) - raw.index.name = "Date" - - with ( - patch("yfinance.download", return_value=raw), - pytest.raises(DataDownloadError), - ): - source._download_one( - "AAA", still_forming.date(), still_forming.date(), "1d", now - ) - - def test_binance_download_one_threads_a_single_now_across_batches( monkeypatch: pytest.MonkeyPatch, ) -> None: @@ -4032,9 +4288,9 @@ def test_loader_strict_mode_raises_on_duplicate_rows_before_cleaning( { "experiment_name": "dup_raise_test", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2020-01-03", "missing_value_policy": "raise", @@ -4086,9 +4342,9 @@ def test_loader_strict_mode_raises_on_non_positive_price_before_cleaning( { "experiment_name": "neg_price_raise_test", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2020-01-03", "missing_value_policy": "raise", @@ -4126,10 +4382,10 @@ def test_loader_report_reflects_pre_clean_defects_under_drop_policy( "volume": 100.0, } for ts, price in [ - ("2020-01-01", 10.0), - ("2020-01-01", 10.0), # duplicate - ("2020-01-02", -5.0), # non-positive - ("2020-01-03", 12.0), + ("2020-01-03", 10.0), + ("2020-01-03", 10.0), # duplicate + ("2020-01-06", -5.0), # non-positive + ("2020-01-07", 12.0), ] ], ) @@ -4137,11 +4393,11 @@ def test_loader_report_reflects_pre_clean_defects_under_drop_policy( { "experiment_name": "drop_policy_report_test", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA"], - "start_date": "2020-01-01", - "end_date": "2020-01-03", + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + ], + "start_date": "2020-01-03", + "end_date": "2020-01-07", "missing_value_policy": "drop", }, "strategy": {"name": "buy_and_hold"}, @@ -4192,9 +4448,9 @@ def test_data_quality_report_persists_into_result_metadata_and_html( { "experiment_name": "dq_persist_test", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2020-01-05", "frequency": "1h", @@ -4253,7 +4509,9 @@ def test_quality_report_warnings_reflect_duplicate_and_price_counts() -> None: "volume": 100.0, } ) - report = DataValidator().validate(df, strict=False) + report = DataValidator(symbol_calendars=_UniformCalendar("XNYS")).validate( + df, strict=False + ) assert report.duplicate_count == 2 assert report.invalid_price_count == 5 assert not report.is_clean @@ -4283,9 +4541,9 @@ def test_loader_report_reflects_missing_values_dropped_before_validation( "volume": 100.0, } for ts, close in [ - ("2020-01-01", 10.0), - ("2020-01-02", ""), # missing -> dropped by the `drop` policy - ("2020-01-03", 12.0), + ("2020-01-03", 10.0), + ("2020-01-06", ""), # missing -> dropped by the `drop` policy + ("2020-01-07", 12.0), ] ], ) @@ -4293,11 +4551,11 @@ def test_loader_report_reflects_missing_values_dropped_before_validation( { "experiment_name": "missing_value_drop_report_test", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA"], - "start_date": "2020-01-01", - "end_date": "2020-01-03", + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + ], + "start_date": "2020-01-03", + "end_date": "2020-01-07", "missing_value_policy": "drop", }, "strategy": {"name": "buy_and_hold"}, @@ -4346,9 +4604,9 @@ def test_loader_missing_values_not_double_counted_under_none_policy( { "experiment_name": "missing_value_none_report_test", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2020-01-03", "missing_value_policy": "none", @@ -4386,3 +4644,1150 @@ def test_write_metadata_produces_strict_json_for_nan_and_infinity( assert "Infinity" not in text parsed = json.loads(text) assert parsed == {"skewness": None, "kurtosis": None, "ok": 1.5} + + +# --------------------------------------------------------------------------- # +# Multi-instrument calendars: verified closures, multi-source loading, +# benchmark isolation (Phase A of the calendar-per-instrument initiative). +# --------------------------------------------------------------------------- # + + +def _write_instrument_csv(raw_dir: Path, symbol: str, frame: pd.DataFrame) -> None: + frame.to_csv(raw_dir / f"{symbol}.csv", index=False) + + +def test_mixed_xnys_and_247_symbol_gets_forward_filled_on_weekend( + tmp_path: Path, +) -> None: + """A weekday-only (XNYS) instrument loaded alongside a 24/7 instrument + must get synthetic weekend bars carrying its last close forward.""" + raw = tmp_path / "raw" + raw.mkdir() + aapl_dates = pd.bdate_range("2024-01-01", "2024-01-10") # weekdays only + btc_dates = pd.date_range("2024-01-01", "2024-01-10", freq="D") # every day + _write_instrument_csv( + raw, + "AAPL", + make_ohlcv( + "AAPL", np.linspace(100, 109, len(aapl_dates)), start="2024-01-01", freq="B" + ), + ) + _write_instrument_csv( + raw, + "BTC", + make_ohlcv( + "BTC", + np.linspace(40000, 40009, len(btc_dates)), + start="2024-01-01", + freq="D", + ), + ) + + cfg = ExperimentConfig.from_dict( + { + "experiment_name": "mixed_calendar", + "data": { + "instruments": [ + {"symbol": "AAPL", "source": "csv", "calendar": "XNYS"}, + {"symbol": "BTC", "source": "csv", "calendar": "24/7"}, + ], + "start_date": "2024-01-01", + "end_date": "2024-01-10", + }, + "strategy": {"name": "buy_and_hold"}, + "backtest": {"periods_per_year": 252}, + } + ) + from quantlab.data.loader import DataLoader + + data, report = DataLoader(raw_dir=raw).load(cfg) + aapl = data[data["symbol"] == "AAPL"].set_index("timestamp").sort_index() + # Saturday 2024-01-06 and Sunday 2024-01-07 must now exist for AAPL. + saturday = pd.Timestamp("2024-01-06") + assert saturday in aapl.index + friday_close = aapl.loc[pd.Timestamp("2024-01-05"), "close"] + assert aapl.loc[saturday, "close"] == pytest.approx(friday_close) + assert aapl.loc[saturday, "volume"] == 0.0 + assert report.closure_inserted_count > 0 + + +def test_verified_closure_return_is_exactly_zero_and_does_not_cascade( + tmp_path: Path, +) -> None: + """A verified closure produces exactly a 0 return that day, and the + following real session's return is a real number, never NaN (the + cascading-NaN bug forward-filling before pct_change eliminates).""" + raw = tmp_path / "raw" + raw.mkdir() + aapl_dates = pd.bdate_range("2024-01-01", "2024-01-10") + btc_dates = pd.date_range("2024-01-01", "2024-01-10", freq="D") + _write_instrument_csv( + raw, + "AAPL", + make_ohlcv( + "AAPL", np.linspace(100, 109, len(aapl_dates)), start="2024-01-01", freq="B" + ), + ) + _write_instrument_csv( + raw, + "BTC", + make_ohlcv( + "BTC", + np.linspace(40000, 40009, len(btc_dates)), + start="2024-01-01", + freq="D", + ), + ) + cfg = ExperimentConfig.from_dict( + { + "experiment_name": "mixed_calendar_returns", + "data": { + "instruments": [ + {"symbol": "AAPL", "source": "csv", "calendar": "XNYS"}, + {"symbol": "BTC", "source": "csv", "calendar": "24/7"}, + ], + "start_date": "2024-01-01", + "end_date": "2024-01-10", + }, + "strategy": {"name": "buy_and_hold"}, + "backtest": {"periods_per_year": 252}, + } + ) + from quantlab.backtesting.accounting import compute_asset_returns + from quantlab.data.base import price_matrix + from quantlab.data.loader import DataLoader + + data, _ = DataLoader(raw_dir=raw).load(cfg) + prices = price_matrix(data, adjusted=True) + returns = compute_asset_returns(prices) + saturday = pd.Timestamp("2024-01-06") + monday = pd.Timestamp("2024-01-08") + assert returns.loc[saturday, "AAPL"] == 0.0 + assert not pd.isna(returns.loc[monday, "AAPL"]) + + +def test_genuine_data_gap_is_not_treated_as_a_verified_closure(tmp_path: Path) -> None: + """A real, non-calendar gap on a single-instrument (single-calendar) + experiment must still be governed by `missing_value_policy`, completely + unaffected by the closure machinery (which is a no-op here since there's + no second instrument to union a wider date grid with).""" + raw = tmp_path / "raw" + raw.mkdir() + # Start on Jan 2 (not Jan 1, an XNYS holiday) so every bar in `frame` sits + # on a real trading day -- otherwise the Jan 1 bar would itself be a real + # row on a verified closure and get discarded before this test's own gap + # scenario is even reached. + dates = pd.bdate_range("2024-01-02", "2024-02-01") + frame = make_ohlcv( + "AAA", np.linspace(100, 118, len(dates)), start="2024-01-02", freq="B" + ) + # Remove a week-plus run of genuine trading days (2024-01-08..2024-01-16, + # 7 business days) -- long enough to exceed DataValidator's default + # max_gap_periods=5 tolerance and register as an abnormal gap, unlike a + # single verified calendar closure. + removed = pd.bdate_range("2024-01-08", "2024-01-16") + frame = frame[~frame["timestamp"].isin(removed)].reset_index(drop=True) + _write_instrument_csv(raw, "AAA", frame) + cfg = ExperimentConfig.from_dict( + { + "experiment_name": "genuine_gap", + "data": { + "instruments": [{"symbol": "AAA", "source": "csv", "calendar": "XNYS"}], + "start_date": "2024-01-02", + "end_date": "2024-02-01", + }, + "strategy": {"name": "buy_and_hold"}, + "backtest": {"periods_per_year": 252}, + } + ) + from quantlab.data.loader import DataLoader + + data, report = DataLoader(raw_dir=raw).load(cfg) + assert report.closure_inserted_count == 0 + assert report.closure_discarded_count == 0 + assert not (set(removed) & set(data["timestamp"])) + assert any("abnormal gap" in w for w in report.warnings) + + +def test_real_bar_on_verified_closure_is_discarded_not_treated_as_a_trade( + tmp_path: Path, +) -> None: + """A real (anomalous) provider row dated on a verified closure -- e.g. a + stray Saturday print for an XNYS symbol -- must never be trusted as a + genuine trade: it is discarded, not forward-flowed into the return + series, however implausible its price looks.""" + raw = tmp_path / "raw" + raw.mkdir() + # Friday, Saturday (closed for XNYS!), Monday -- Saturday's price jumps + # 100 -> 200, which would be a fabricated 100% return if trusted. + dates = pd.to_datetime(["2024-01-05", "2024-01-06", "2024-01-08"]) + frame = make_ohlcv("AAA", [100.0, 200.0, 205.0], start="2024-01-05", freq="D") + frame["timestamp"] = dates + _write_instrument_csv(raw, "AAA", frame) + cfg = ExperimentConfig.from_dict( + { + "experiment_name": "closure_real_bar", + "data": { + "instruments": [{"symbol": "AAA", "source": "csv", "calendar": "XNYS"}], + "start_date": "2024-01-05", + "end_date": "2024-01-08", + }, + "strategy": {"name": "buy_and_hold"}, + } + ) + from quantlab.backtesting.runner import run_backtest_from_config + from quantlab.data.loader import DataLoader + + data, report = DataLoader(raw_dir=raw).load(cfg) + assert pd.Timestamp("2024-01-06") not in set(data["timestamp"]) + assert any("verified market closure" in w for w in report.warnings) + + result = run_backtest_from_config(data, cfg) + assert pd.Timestamp("2024-01-06") not in result.returns.index + # The real Friday->Monday move (100 -> 205), never a separate fabricated + # 100% Saturday leg (100 -> 200) chained with a second 2.5% leg. + assert result.returns.loc[pd.Timestamp("2024-01-08")] == pytest.approx(1.05) + + +def test_real_bar_on_verified_closure_raises_in_strict_mode(tmp_path: Path) -> None: + raw = tmp_path / "raw" + raw.mkdir() + dates = pd.to_datetime(["2024-01-05", "2024-01-06", "2024-01-08"]) + frame = make_ohlcv("AAA", [100.0, 200.0, 205.0], start="2024-01-05", freq="D") + frame["timestamp"] = dates + _write_instrument_csv(raw, "AAA", frame) + cfg = ExperimentConfig.from_dict( + { + "experiment_name": "closure_real_bar_strict", + "data": { + "instruments": [{"symbol": "AAA", "source": "csv", "calendar": "XNYS"}], + "start_date": "2024-01-05", + "end_date": "2024-01-08", + "missing_value_policy": "raise", + }, + "strategy": {"name": "buy_and_hold"}, + } + ) + from quantlab.data.loader import DataLoader + from quantlab.exceptions import DataValidationError + + with pytest.raises(DataValidationError, match="verified market closure"): + DataLoader(raw_dir=raw).load(cfg) + + +def test_loader_report_row_count_reflects_closure_fill_drops(tmp_path: Path) -> None: + """``row_count`` is set inside DataValidator.validate(), before closure- + fill (which can now discard anomalous rows, not just insert synthetic + ones -- see quantlab.data.closures) ever runs. It must be refreshed + afterward the same way ``clean_row_count`` already is, or it silently + goes stale whenever a symbol has a real bar on its own verified + closure.""" + raw = tmp_path / "raw" + raw.mkdir() + dates = pd.to_datetime(["2024-01-05", "2024-01-06", "2024-01-08"]) + frame = make_ohlcv("AAA", [100.0, 200.0, 205.0], start="2024-01-05", freq="D") + frame["timestamp"] = dates + _write_instrument_csv(raw, "AAA", frame) + cfg = ExperimentConfig.from_dict( + { + "experiment_name": "closure_real_bar_row_count", + "data": { + "instruments": [{"symbol": "AAA", "source": "csv", "calendar": "XNYS"}], + "start_date": "2024-01-05", + "end_date": "2024-01-08", + }, + "strategy": {"name": "buy_and_hold"}, + } + ) + from quantlab.data.loader import DataLoader + + data, report = DataLoader(raw_dir=raw).load(cfg) + assert report.row_count == len(data) + assert report.row_count == report.clean_row_count == 2 + + +def test_loader_report_decomposes_closure_inserted_from_discarded( + tmp_path: Path, +) -> None: + """A single net counter would go negative here and hide what actually + happened (one row discarded, none inserted) -- ``DataQualityReport`` + has no such net counter; ``closure_discarded_count``/ + ``closure_inserted_count`` report the two effects separately, never + netted against each other.""" + raw = tmp_path / "raw" + raw.mkdir() + dates = pd.to_datetime(["2024-01-05", "2024-01-06", "2024-01-08"]) + frame = make_ohlcv("AAA", [100.0, 200.0, 205.0], start="2024-01-05", freq="D") + frame["timestamp"] = dates + _write_instrument_csv(raw, "AAA", frame) + cfg = ExperimentConfig.from_dict( + { + "experiment_name": "closure_counts_decomposed", + "data": { + "instruments": [{"symbol": "AAA", "source": "csv", "calendar": "XNYS"}], + "start_date": "2024-01-05", + "end_date": "2024-01-08", + }, + "strategy": {"name": "buy_and_hold"}, + } + ) + from quantlab.data.loader import DataLoader + + _, report = DataLoader(raw_dir=raw).load(cfg) + assert report.closure_discarded_count == 1 + assert report.closure_inserted_count == 0 + assert not hasattr(report, "closure_fill_count") + + +def test_closure_fill_is_noop_for_non_daily_frequency() -> None: + from quantlab.constants import ( + ADJUSTED_CLOSE, + CLOSE, + HIGH, + LOW, + OPEN, + SYMBOL, + TIMESTAMP, + VOLUME, + ) + from quantlab.data.closures import insert_verified_closure_bars + + dates = pd.date_range("2024-01-05", periods=3, freq="h") + frame = pd.DataFrame( + { + TIMESTAMP: dates, + SYMBOL: "AAA", + OPEN: 1.0, + HIGH: 1.0, + LOW: 1.0, + CLOSE: 1.0, + ADJUSTED_CLOSE: 1.0, + VOLUME: 1.0, + } + ) + result = insert_verified_closure_bars( + frame, symbol_calendars={"AAA": "XNYS"}, frequency="1h" + ) + pd.testing.assert_frame_equal(result, frame) + + +def test_xhkg_gap_detection_uses_hong_kong_holidays_not_xnys() -> None: + """A symbol on the XHKG calendar must have its gaps evaluated against + Hong Kong's own holiday schedule, not the hard-coded XNYS one.""" + from quantlab.data.validator import DataValidator + + # 2024-02-12 is a Hong Kong (Lunar New Year) holiday but an ordinary + # XNYS trading day -- a symbol skipping straight from 2024-02-09 to + # 2024-02-14 (skipping only HK holidays + a weekend) must not be flagged + # as an abnormal gap under XHKG, even though it would be under XNYS. + dates = pd.DatetimeIndex(["2024-02-09", "2024-02-14"]) + frame = _ohlcv_frame(dates, symbol="0001.HK") + report_xhkg = DataValidator( + expected_frequency="1d", + min_coverage_rows=1, + symbol_calendars=_UniformCalendar("XHKG"), + ).validate(frame) + assert not any("abnormal gap" in w for w in report_xhkg.warnings) + + +def test_session_labels_handles_a_calendar_whose_session_crosses_utc_midnight() -> None: + """A calendar whose local trading day starts before UTC midnight (e.g. + XASX/ASX, UTC+10/+11) must have its session recognized as one real + trading day, not split by a naive UTC calendar-day boundary + (ts.dt.normalize()/ts.dt.date) -- otherwise gap/frequency-mismatch + detection would wrongly treat bars within the same real session as + belonging to two different "days".""" + from quantlab.data.calendar import session_labels + + # 2024-01-09's real ASX session opens 2024-01-08 23:00 UTC and closes + # 2024-01-09 05:00 UTC -- straddling UTC midnight in local terms. + ts = pd.Series( + pd.to_datetime( + ["2024-01-08 23:30:00", "2024-01-09 01:00:00", "2024-01-09 03:00:00"] + ) + ) + labels = session_labels("XASX", ts) + assert labels.nunique() == 1 + assert labels.iloc[0] == pd.Timestamp("2024-01-09") + + +def test_session_labels_keeps_yahoo_style_midnight_daily_bars_on_their_own_day() -> ( + None +): + """Yahoo's daily bars are timestamped at UTC midnight of their own + trading date. For a calendar whose session opens many hours after UTC + midnight (e.g. XNYS, 13:30 UTC), midnight of day D is *closer in raw + time* to the previous session's open than to its own -- matching by + nearest market_open would misattribute every consecutive daily bar to + the day before, silently merging Monday's and Tuesday's volume under + one label and turning 5 daily bars into 4 after a daily->daily + resample. Matching by forward-on-close instead (see session_labels' + own docstring) avoids this.""" + from quantlab.data.calendar import session_labels + + ts = pd.Series( + pd.to_datetime( + [ + "2024-08-01", + "2024-08-02", + "2024-08-05", + "2024-08-06", + "2024-08-07", + ] + ) + ) + labels = session_labels("XNYS", ts) + assert labels.tolist() == ts.tolist() # each bar keeps its own day + assert labels.nunique() == 5 # never merged + + +def test_session_labels_post_market_on_the_last_date_still_resolves() -> None: + """A genuinely post-market timestamp on `ts`'s own last calendar date + (after that date's close) needs the *next* session's close to resolve + -- the schedule fetched for `ts` must reach far enough past `ts.max()` + to find it, or this silently returns NaT instead of a real label.""" + from quantlab.data.calendar import session_labels + + ts = pd.Series(pd.to_datetime(["2024-08-05 10:00:00", "2024-08-05 23:00:00"])) + labels = session_labels("XNYS", ts) + assert labels.notna().all() + assert labels.iloc[0] == pd.Timestamp("2024-08-05") + assert labels.iloc[1] == pd.Timestamp("2024-08-06") + + +def test_session_labels_tolerates_a_coarser_datetime_resolution_than_the_schedule() -> ( + None +): + """Parquet-cached data can come back as ``datetime64[ms]`` while + pandas_market_calendars' own schedule is ``[us]`` -- pandas' merge_asof + (used internally to match each timestamp to its session) requires an + exact dtype match on its join keys, not just "both datetime64", so a + caller passing a coarser resolution than the schedule's must not raise + ``MergeError: incompatible merge keys``.""" + from quantlab.data.calendar import session_labels + + ts = pd.Series( + pd.to_datetime(["2024-08-01", "2024-08-02"]).values.astype("datetime64[ms]") + ) + assert ts.dtype == "datetime64[ms]" + labels = session_labels("XNYS", ts) + assert labels.tolist() == [pd.Timestamp("2024-08-01"), pd.Timestamp("2024-08-02")] + + +def test_closure_bar_is_flat_zero_volume_with_independent_adjusted_close() -> None: + """A synthetic closure bar: OHLC flat at the last close, adjusted_close + flat at the last adjusted_close *independently* (not derived from + close), volume exactly 0 -- even when close and adjusted_close diverge + (e.g. after a split).""" + from quantlab.constants import ( + ADJUSTED_CLOSE, + CLOSE, + HIGH, + LOW, + OPEN, + SYMBOL, + TIMESTAMP, + VOLUME, + ) + from quantlab.data.closures import insert_verified_closure_bars + + aapl_dates = pd.to_datetime(["2024-01-05"]) # Friday only + btc_dates = pd.to_datetime(["2024-01-05", "2024-01-06"]) # Fri + Sat + data = pd.concat( + [ + pd.DataFrame( + { + TIMESTAMP: aapl_dates, + SYMBOL: "AAPL", + OPEN: 100.0, + HIGH: 100.0, + LOW: 100.0, + CLOSE: 100.0, + ADJUSTED_CLOSE: 90.0, # diverges from close, e.g. a split + VOLUME: 1_000.0, + } + ), + pd.DataFrame( + { + TIMESTAMP: btc_dates, + SYMBOL: "BTC", + OPEN: 40_000.0, + HIGH: 40_000.0, + LOW: 40_000.0, + CLOSE: 40_000.0, + ADJUSTED_CLOSE: 40_000.0, + VOLUME: 1_000.0, + } + ), + ], + ignore_index=True, + ) + filled = insert_verified_closure_bars( + data, symbol_calendars={"AAPL": "XNYS", "BTC": "24/7"}, frequency="1d" + ) + synthetic = filled[ + (filled[SYMBOL] == "AAPL") & (filled[TIMESTAMP] == pd.Timestamp("2024-01-06")) + ].iloc[0] + assert synthetic[OPEN] == 100.0 + assert synthetic[HIGH] == 100.0 + assert synthetic[LOW] == 100.0 + assert synthetic[CLOSE] == 100.0 + assert synthetic[ADJUSTED_CLOSE] == 90.0 # independent of close, not derived + assert synthetic[VOLUME] == 0.0 + + +def test_multi_source_experiment_downloads_from_each_instruments_own_source( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """A yahoo-sourced and a binance-sourced instrument in the same + experiment must each be routed to their own provider.""" + from quantlab.data import loader as loader_module + from quantlab.data.base import MarketDataSource + from quantlab.data.loader import DataLoader + from quantlab.data.storage import ParquetStorage as _ParquetStorage + + calls: list[tuple[str, list[str]]] = [] + + class _FakeSource(MarketDataSource): + def __init__(self, name: str) -> None: + self.name = name + + def download( + self, + symbols: list[str], + start: date, + end: date, + frequency: str, + *, + calendar: str = "XNYS", + ) -> pd.DataFrame: + calls.append((self.name, list(symbols))) + return make_ohlcv( + symbols[0], np.linspace(100, 110, 5), start="2024-01-01", freq="B" + ) + + def fake_build_source(name: str) -> _FakeSource: + return _FakeSource(name) + + monkeypatch.setattr(loader_module, "build_source", fake_build_source) + cfg = ExperimentConfig.from_dict( + { + "experiment_name": "multi_source", + "data": { + "instruments": [ + {"symbol": "SPY", "source": "yahoo", "calendar": "XNYS"}, + {"symbol": "BTCUSDT", "source": "binance", "calendar": "24/7"}, + ], + "start_date": "2024-01-01", + "end_date": "2024-01-05", + }, + "backtest": {"periods_per_year": 252}, + "strategy": {"name": "buy_and_hold"}, + } + ) + loader = DataLoader( + storage=_ParquetStorage( + cache_dir=tmp_path / "cache", metadata_dir=tmp_path / "metadata" + ) + ) + loader.download(cfg) + routed = dict(calls) + assert routed.get("yahoo") == ["SPY"] + assert routed.get("binance") == ["BTCUSDT"] + + +def test_benchmark_overlapping_tradable_instrument_is_not_downloaded_twice( + tmp_path: Path, +) -> None: + raw = tmp_path / "raw" + raw.mkdir() + _write_instrument_csv( + raw, "SPY", make_ohlcv("SPY", np.linspace(100, 110, 10), start="2024-01-01") + ) + cfg = ExperimentConfig.from_dict( + { + "experiment_name": "benchmark_overlap", + "data": { + "instruments": [{"symbol": "SPY", "source": "csv", "calendar": "XNYS"}], + "start_date": "2024-01-01", + "end_date": "2024-01-15", + }, + "strategy": {"name": "buy_and_hold"}, + "backtest": { + "benchmark": {"symbol": "SPY", "source": "csv", "calendar": "XNYS"} + }, + } + ) + from quantlab.data.loader import DataLoader + + data = DataLoader(raw_dir=raw).download(cfg) + # SPY must appear exactly once per timestamp, not duplicated by a second + # (redundant) download of the same symbol as an "external" benchmark. + assert not data.duplicated(subset=["timestamp", "symbol"]).any() + + +def test_external_benchmark_frequency_must_be_supported_by_its_own_source() -> None: + """A benchmark outside the tradable universe has its own source, whose + frequency support `DataConfig._check_frequency_supported_by_every_ + instrument` never sees (it only checks `data.instruments`). Without a + dedicated check, e.g. frequency '1mo' with an external Binance + benchmark would be silently accepted at config-load time only to fail + later, confusingly, at download time.""" + base: dict[str, Any] = { + "experiment_name": "external_benchmark_frequency", + "data": { + "instruments": [{"symbol": "AAPL", "source": "yahoo", "calendar": "XNYS"}], + "start_date": "2020-01-01", + "end_date": "2021-01-01", + "frequency": "1mo", + }, + "strategy": {"name": "buy_and_hold"}, + "backtest": { + "benchmark": { + "symbol": "BTCUSDT", + "source": "binance", + "calendar": "24/7", + } + }, + } + with pytest.raises(InvalidConfigurationError, match="benchmark's source"): + ExperimentConfig.from_dict(base) + + # The tradable side alone supports '1mo' (Yahoo does) -- confirms the + # rejection above is specifically about the benchmark's own source, not + # a false positive from the existing tradable-side check. + ExperimentConfig.from_dict({**base, "data": {**base["data"], "frequency": "1d"}}) + + +def test_benchmark_outside_tradable_universe_loaded_via_its_own_instrument( + tmp_path: Path, +) -> None: + raw = tmp_path / "raw" + raw.mkdir() + _write_instrument_csv( + raw, "AAA", make_ohlcv("AAA", np.linspace(100, 110, 10), start="2024-01-01") + ) + _write_instrument_csv( + raw, "BENCH", make_ohlcv("BENCH", np.linspace(50, 60, 10), start="2024-01-01") + ) + cfg = ExperimentConfig.from_dict( + { + "experiment_name": "external_benchmark", + "data": { + "instruments": [{"symbol": "AAA", "source": "csv", "calendar": "XNYS"}], + "start_date": "2024-01-01", + "end_date": "2024-01-15", + }, + "strategy": {"name": "buy_and_hold"}, + "backtest": { + "benchmark": {"symbol": "BENCH", "source": "csv", "calendar": "XNYS"} + }, + } + ) + from quantlab.data.loader import DataLoader + + data, _report = DataLoader(raw_dir=raw).load(cfg) + assert "BENCH" in set(data["symbol"].unique()) + + +def test_external_benchmark_never_expands_the_tradable_timeline(tmp_path: Path) -> None: + """A 24/7 external benchmark must never cause synthetic weekend bars to + appear for an all-XNYS tradable universe.""" + raw = tmp_path / "raw" + raw.mkdir() + # AAPL starts on Jan 2 (not Jan 1, an XNYS holiday) so every bar sits on a + # real trading day -- otherwise the Jan 1 bar would itself be a real row + # on a verified closure and get discarded before it ever reaches the + # weekend-expansion assertion below. + aapl_dates = pd.bdate_range("2024-01-02", "2024-01-10") + btc_dates = pd.date_range("2024-01-01", "2024-01-10", freq="D") + _write_instrument_csv( + raw, + "AAPL", + make_ohlcv( + "AAPL", np.linspace(100, 109, len(aapl_dates)), start="2024-01-02", freq="B" + ), + ) + _write_instrument_csv( + raw, + "BENCHBTC", + make_ohlcv( + "BENCHBTC", + np.linspace(40000, 40009, len(btc_dates)), + start="2024-01-01", + freq="D", + ), + ) + cfg = ExperimentConfig.from_dict( + { + "experiment_name": "benchmark_never_expands", + "data": { + "instruments": [ + {"symbol": "AAPL", "source": "csv", "calendar": "XNYS"} + ], + "start_date": "2024-01-01", + "end_date": "2024-01-10", + }, + "strategy": {"name": "buy_and_hold"}, + "backtest": { + "benchmark": { + "symbol": "BENCHBTC", + "source": "csv", + "calendar": "24/7", + } + }, + } + ) + from quantlab.data.loader import DataLoader + + data, report = DataLoader(raw_dir=raw).load(cfg) + aapl = data[data["symbol"] == "AAPL"] + assert pd.Timestamp("2024-01-06") not in set(aapl["timestamp"]) # no Saturday + assert pd.Timestamp("2024-01-07") not in set(aapl["timestamp"]) # no Sunday + assert report.closure_inserted_count == 0 + assert report.closure_discarded_count == 0 + + +def test_external_benchmark_is_validated_with_its_own_calendar(tmp_path: Path) -> None: + """The validator must receive the external benchmark's own calendar (not + KeyError on a symbol it doesn't recognise), while that calendar never + feeds the tradable-universe closure machinery.""" + raw = tmp_path / "raw" + raw.mkdir() + _write_instrument_csv( + raw, "AAA", make_ohlcv("AAA", np.linspace(100, 110, 10), start="2024-01-01") + ) + _write_instrument_csv( + raw, + "BENCHBTC", + make_ohlcv( + "BENCHBTC", np.linspace(40000, 40010, 10), start="2024-01-01", freq="D" + ), + ) + cfg = ExperimentConfig.from_dict( + { + "experiment_name": "benchmark_own_calendar", + "data": { + "instruments": [{"symbol": "AAA", "source": "csv", "calendar": "XNYS"}], + "start_date": "2024-01-01", + "end_date": "2024-01-15", + }, + "strategy": {"name": "buy_and_hold"}, + "backtest": { + "benchmark": { + "symbol": "BENCHBTC", + "source": "csv", + "calendar": "24/7", + } + }, + } + ) + from quantlab.data.loader import DataLoader + + # Must not raise (no KeyError from the validator's strict symbol_calendars). + data, _report = DataLoader(raw_dir=raw).load(cfg) + assert "BENCHBTC" in set(data["symbol"].unique()) + + +def test_csv_instrument_never_narrows_the_frequency_intersection() -> None: + from quantlab.config import ( + DataFrequency, + DataSourceName, + compatible_frequencies_for_sources, + ) + + only_csv = compatible_frequencies_for_sources([DataSourceName.CSV]) + assert only_csv == set(DataFrequency) + + mixed = compatible_frequencies_for_sources( + [DataSourceName.CSV, DataSourceName.YAHOO] + ) + yahoo_only = compatible_frequencies_for_sources([DataSourceName.YAHOO]) + assert mixed == yahoo_only # csv is neutral, never narrows the result + + +def test_market_data_cache_is_independent_of_experiment_calendar( + tmp_path: Path, +) -> None: + """The same (source, symbol, frequency) cache entry must be reused + regardless of which calendar the requesting experiment declares for + that instrument -- calendar-dependent filtering happens only after + reading the cache, never baked into what gets written to it.""" + from quantlab.data.base import MarketDataSource + from quantlab.data.loader import DataLoader + from quantlab.data.storage import ParquetStorage + + storage = ParquetStorage(cache_dir=tmp_path / "cache", metadata_dir=tmp_path / "md") + + class _FakeSource(MarketDataSource): + name = "yahoo" + call_count = 0 + + def download( + self, + symbols: list[str], + start: date, + end: date, + frequency: str, + *, + calendar: str = "XNYS", + ) -> pd.DataFrame: + _FakeSource.call_count += 1 + return make_ohlcv( + symbols[0], np.linspace(100, 110, 10), start="2024-01-01", freq="D" + ) + + loader = DataLoader(storage=storage) + instrument_xnys = ExperimentConfig.from_dict( + { + "experiment_name": "cache_a", + "data": { + "instruments": [ + {"symbol": "AAA", "source": "yahoo", "calendar": "XNYS"} + ], + "start_date": "2024-01-01", + "end_date": "2024-01-10", + }, + "strategy": {"name": "buy_and_hold"}, + } + ).data.instruments[0] + instrument_247 = ExperimentConfig.from_dict( + { + "experiment_name": "cache_b", + "data": { + "instruments": [ + {"symbol": "AAA", "source": "yahoo", "calendar": "24/7"} + ], + "start_date": "2024-01-01", + "end_date": "2024-01-10", + }, + "strategy": {"name": "buy_and_hold"}, + } + ).data.instruments[0] + dummy_config = ExperimentConfig.from_dict( + { + "experiment_name": "cache_dummy", + "data": { + "instruments": [ + {"symbol": "AAA", "source": "yahoo", "calendar": "XNYS"} + ], + "start_date": "2024-01-01", + "end_date": "2024-01-10", + }, + "strategy": {"name": "buy_and_hold"}, + } + ) + source = _FakeSource() + loader._download_symbol(source, instrument_xnys, dummy_config, force=False) + loader._download_symbol(source, instrument_247, dummy_config, force=False) + # Both instruments share the same (source, symbol, frequency) cache key, + # so the second call must be served from the cache the first call wrote + # -- the provider is hit only once. + assert _FakeSource.call_count == 1 + + +def test_loader_trims_to_common_coverage_when_a_247_symbol_starts_earlier( + tmp_path: Path, +) -> None: + """A 24/7 instrument's earlier real coverage must not widen the combined + tradable timeline into a date an XNYS instrument has no data for yet -- + left unfixed, price_matrix's pct_change would produce an unrecoverable + NaN on the XNYS instrument's own genuinely-first trading day (caught, + confusingly, only by a downstream benchmark-alignment or + missing-return-while-held guard). The loader must instead trim the whole + panel to the date every tradable symbol actually has data from.""" + from quantlab.constants import TIMESTAMP + + raw = tmp_path / "raw" + raw.mkdir() + # SPY/TSLA: XNYS, first real bar 2019-01-02 (2019-01-01 is a holiday). + bdates = pd.bdate_range("2019-01-02", periods=10) + for sym, seed in [("SPY", 1), ("TSLA", 2)]: + sym_prices = geometric_series( + len(bdates), mu=0.0005, sigma=0.01, s0=100.0, seed=seed + ) + frame = make_ohlcv(sym, sym_prices, start="2019-01-02", freq="B") + _write_instrument_csv(raw, sym, frame) + # ETH: 24/7, already has a real bar on 2019-01-01. + cdates = pd.date_range("2019-01-01", periods=14) + eth_prices = geometric_series(len(cdates), mu=0.0003, sigma=0.02, s0=100.0, seed=3) + _write_instrument_csv( + raw, "ETH", make_ohlcv("ETH", eth_prices, start="2019-01-01", freq="D") + ) + + cfg = ExperimentConfig.from_dict( + { + "experiment_name": "common_coverage", + "data": { + "instruments": [ + {"symbol": "SPY", "source": "csv", "calendar": "XNYS"}, + {"symbol": "TSLA", "source": "csv", "calendar": "XNYS"}, + {"symbol": "ETH", "source": "csv", "calendar": "24/7"}, + ], + "start_date": "2019-01-01", + "end_date": "2019-01-14", + }, + "backtest": {"periods_per_year": 252}, + "strategy": {"name": "buy_and_hold"}, + } + ) + from quantlab.data.loader import DataLoader + + data, report = DataLoader(raw_dir=raw).load(cfg) + assert data[TIMESTAMP].min() == pd.Timestamp("2019-01-02") + assert any( + "coverage effectively starts 2019-01-02" in w and "SPY" in w and "TSLA" in w + for w in report.warnings + ) + + from quantlab.backtesting.accounting import compute_asset_returns + from quantlab.data.base import price_matrix + + prices = price_matrix(data, adjusted=True) + returns = compute_asset_returns(prices) + # No NaN survives beyond the mandatory first row (undefined by + # construction -- there is no prior price for anything on day 1). + assert not returns.iloc[1:].isna().to_numpy().any() + + from quantlab.backtesting.runner import run_backtest_from_config + + result = run_backtest_from_config(data, cfg) + assert not result.returns.isna().any() + + +def test_loader_trims_to_common_coverage_when_a_symbol_ends_earlier( + tmp_path: Path, +) -> None: + """Symmetric case at the other end of history: one tradable symbol's data + simply stops earlier than another's (a stale feed), while the other + keeps going -- left unfixed, the engine hits an unrecoverable "asset + return missing while held" failure on the first date the stopped + symbol has no data for. The loader must trim the whole panel to the + date every tradable symbol actually still has data through, the same + way it already trims to a common start.""" + from quantlab.constants import TIMESTAMP + + raw = tmp_path / "raw" + raw.mkdir() + # AAPL stops 5 business days before MSFT does; both same calendar (XNYS) + # so no closure-fill interaction confounds the scenario. + aapl_dates = pd.bdate_range("2024-01-02", "2024-01-10") + msft_dates = pd.bdate_range("2024-01-02", "2024-01-17") + for sym, dates in [("AAPL", aapl_dates), ("MSFT", msft_dates)]: + prices = geometric_series(len(dates), mu=0.0005, sigma=0.01, s0=100.0, seed=1) + frame = make_ohlcv(sym, prices, start="2024-01-02", freq="B") + frame["timestamp"] = dates + _write_instrument_csv(raw, sym, frame) + + cfg = ExperimentConfig.from_dict( + { + "experiment_name": "common_end_coverage", + "data": { + "instruments": [ + {"symbol": "AAPL", "source": "csv", "calendar": "XNYS"}, + {"symbol": "MSFT", "source": "csv", "calendar": "XNYS"}, + ], + "start_date": "2024-01-02", + "end_date": "2024-01-17", + }, + "strategy": {"name": "buy_and_hold"}, + } + ) + from quantlab.data.loader import DataLoader + + data, report = DataLoader(raw_dir=raw).load(cfg) + assert data[TIMESTAMP].max() == pd.Timestamp("2024-01-10") + assert any( + "coverage effectively ends 2024-01-10" in w and "AAPL" in w + for w in report.warnings + ) + + from quantlab.backtesting.runner import run_backtest_from_config + + result = run_backtest_from_config(data, cfg) + assert not result.returns.isna().any() + + +def _write_gap_pair(raw: Path, missing_date: str) -> None: + """Two 24/7 instruments spanning 2024-01-01..06; ETH has no row at all + for ``missing_date`` (a genuine gap), while BTC trades every day.""" + btc_dates = pd.date_range("2024-01-01", "2024-01-06", freq="D") + eth_dates = pd.DatetimeIndex( + [d for d in btc_dates if d != pd.Timestamp(missing_date)] + ) + btc_prices = geometric_series( + len(btc_dates), mu=0.0005, sigma=0.01, s0=100.0, seed=1 + ) + btc = make_ohlcv("BTC", btc_prices, start="2024-01-01", freq="D") + btc["timestamp"] = btc_dates + _write_instrument_csv(raw, "BTC", btc) + eth_prices = geometric_series( + len(eth_dates), mu=0.0005, sigma=0.01, s0=50.0, seed=2 + ) + eth = make_ohlcv("ETH", eth_prices, start="2024-01-01", freq="D") + eth["timestamp"] = eth_dates + _write_instrument_csv(raw, "ETH", eth) + + +def _gap_config(policy: str) -> ExperimentConfig: + return ExperimentConfig.from_dict( + { + "experiment_name": f"genuine_gap_{policy}", + "data": { + "instruments": [ + {"symbol": "BTC", "source": "csv", "calendar": "24/7"}, + {"symbol": "ETH", "source": "csv", "calendar": "24/7"}, + ], + "start_date": "2024-01-01", + "end_date": "2024-01-06", + "missing_value_policy": policy, + }, + "strategy": {"name": "buy_and_hold"}, + } + ) + + +def test_genuine_gap_under_raise_policy_gives_a_clear_early_error( + tmp_path: Path, +) -> None: + """A (date, symbol) combination with no row at all for a real trading + session -- never a verified closure -- must be governed by + ``missing_value_policy`` the same way a missing *value* already is. + Under ``raise`` it must fail loudly at load time, not surface later as + an opaque "asset return missing while held" backtest failure.""" + from quantlab.exceptions import DataValidationError + + raw = tmp_path / "raw" + raw.mkdir() + _write_gap_pair(raw, "2024-01-03") + cfg = _gap_config("raise") + + from quantlab.data.loader import DataLoader + + with pytest.raises(DataValidationError, match="ETH@2024-01-03"): + DataLoader(raw_dir=raw).load(cfg) + + +def test_genuine_gap_under_drop_policy_removes_the_date_and_backtest_succeeds( + tmp_path: Path, +) -> None: + """``drop`` must remove the affected date from the *whole* tradable + universe (not just the missing symbol's own row) so the resulting panel + stays dense enough for the engine to run end to end.""" + from quantlab.constants import SYMBOL, TIMESTAMP + from quantlab.data.loader import DataLoader + + raw = tmp_path / "raw" + raw.mkdir() + _write_gap_pair(raw, "2024-01-03") + cfg = _gap_config("drop") + + data, report = DataLoader(raw_dir=raw).load(cfg) + assert pd.Timestamp("2024-01-03") not in set(data[TIMESTAMP]) + assert any("dropped from the tradable universe" in w for w in report.warnings) + # BTC also loses its (perfectly fine) row that day -- the whole date is + # dropped, not just ETH's missing one. + btc_dates = set(data.loc[data[SYMBOL] == "BTC", TIMESTAMP]) + assert pd.Timestamp("2024-01-03") not in btc_dates + + from quantlab.backtesting.runner import run_backtest_from_config + + result = run_backtest_from_config(data, cfg) + assert not result.returns.isna().any() + + +def test_genuine_gap_under_forward_fill_policy_materializes_a_flat_bar( + tmp_path: Path, +) -> None: + """``forward_fill`` must synthesize a flat bar (close carried forward, + zero volume) for the missing (date, symbol) rather than dropping the + date outright, and the backtest must run cleanly on the result.""" + from quantlab.constants import CLOSE, SYMBOL, TIMESTAMP, VOLUME + from quantlab.data.loader import DataLoader + + raw = tmp_path / "raw" + raw.mkdir() + _write_gap_pair(raw, "2024-01-03") + cfg = _gap_config("forward_fill") + + data, report = DataLoader(raw_dir=raw).load(cfg) + assert pd.Timestamp("2024-01-03") in set(data.loc[data[SYMBOL] == "ETH", TIMESTAMP]) + assert any("forward-filled" in w for w in report.warnings) + eth_sorted = data.loc[data[SYMBOL] == "ETH"].sort_values(TIMESTAMP) + filled_row = eth_sorted.loc[eth_sorted[TIMESTAMP] == pd.Timestamp("2024-01-03")] + prior_row = eth_sorted.loc[eth_sorted[TIMESTAMP] == pd.Timestamp("2024-01-02")] + assert filled_row[CLOSE].iloc[0] == prior_row[CLOSE].iloc[0] + assert filled_row[VOLUME].iloc[0] == 0.0 + + from quantlab.backtesting.runner import run_backtest_from_config + + result = run_backtest_from_config(data, cfg) + assert not result.returns.isna().any() + + +def test_genuine_gap_under_none_policy_is_left_unfilled(tmp_path: Path) -> None: + """``none`` must remain an explicit pass-through: the gap stays exactly + as-is (no drop, no synthetic row), consistent with existing "abnormal + gap" warning behaviour -- this fix must never activate under ``none``.""" + from quantlab.constants import SYMBOL, TIMESTAMP + from quantlab.data.loader import DataLoader + + raw = tmp_path / "raw" + raw.mkdir() + _write_gap_pair(raw, "2024-01-03") + cfg = _gap_config("none") + + data, _report = DataLoader(raw_dir=raw).load(cfg) + eth_dates = set(data.loc[data[SYMBOL] == "ETH", TIMESTAMP]) + assert pd.Timestamp("2024-01-03") not in eth_dates + assert len(data.loc[data[SYMBOL] == "ETH"]) == 5 + + +def test_genuine_gap_detection_does_not_reclassify_a_trailing_coverage_difference( + tmp_path: Path, +) -> None: + """A symbol whose feed simply stops earlier than another's (all dates + trailing its own last observation) is a coverage-window difference, + handled by the loader's own common-end trim with its own warning -- it + must never be caught first by genuine-gap drop/forward-fill, which + would needlessly discard the *other* symbol's perfectly good rows on + those trailing dates too.""" + from quantlab.constants import SYMBOL, TIMESTAMP + from quantlab.data.loader import DataLoader + + raw = tmp_path / "raw" + raw.mkdir() + aapl_dates = pd.bdate_range("2024-01-02", "2024-01-10") + msft_dates = pd.bdate_range("2024-01-02", "2024-01-17") + for sym, dates in [("AAPL", aapl_dates), ("MSFT", msft_dates)]: + prices = geometric_series(len(dates), mu=0.0005, sigma=0.01, s0=100.0, seed=1) + frame = make_ohlcv(sym, prices, start="2024-01-02", freq="B") + frame["timestamp"] = dates + _write_instrument_csv(raw, sym, frame) + + cfg = ExperimentConfig.from_dict( + { + "experiment_name": "trailing_not_a_gap", + "data": { + "instruments": [ + {"symbol": "AAPL", "source": "csv", "calendar": "XNYS"}, + {"symbol": "MSFT", "source": "csv", "calendar": "XNYS"}, + ], + "start_date": "2024-01-02", + "end_date": "2024-01-17", + "missing_value_policy": "drop", + }, + "strategy": {"name": "buy_and_hold"}, + } + ) + data, report = DataLoader(raw_dir=raw).load(cfg) + assert data[TIMESTAMP].max() == pd.Timestamp("2024-01-10") + assert any( + "coverage effectively ends 2024-01-10" in w and "AAPL" in w + for w in report.warnings + ) + assert not any("dropped from the tradable universe" in w for w in report.warnings) + # MSFT keeps every one of its own rows through 01-10; none were + # discarded by the genuine-gap logic misfiring on trailing dates. + msft_kept = data.loc[data[SYMBOL] == "MSFT", TIMESTAMP] + assert len(msft_kept) == len(pd.bdate_range("2024-01-02", "2024-01-10")) diff --git a/tests/unit/test_regression_execution.py b/tests/unit/test_regression_execution.py index a7f3360..806d3b4 100644 --- a/tests/unit/test_regression_execution.py +++ b/tests/unit/test_regression_execution.py @@ -33,9 +33,10 @@ def test_target_volatility_applies_with_any_allocator() -> None: base: dict[str, Any] = { "experiment_name": "x", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA", "BBB", "CCC"], + "instruments": [ + {"symbol": s, "source": "csv", "calendar": "XNYS"} + for s in ["AAA", "BBB", "CCC"] + ], "start_date": "2020-01-01", "end_date": "2021-06-01", }, @@ -131,9 +132,10 @@ def test_volume_slippage_is_not_degenerate() -> None: { "experiment_name": "vol_slip", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA", "BBB", "CCC"], + "instruments": [ + {"symbol": s, "source": "csv", "calendar": "XNYS"} + for s in ["AAA", "BBB", "CCC"] + ], "start_date": "2020-01-01", "end_date": "2020-10-01", }, @@ -168,7 +170,9 @@ def test_negative_maximum_net_exposure_rejected() -> None: { "experiment_name": "x", "data": { - "symbols": ["A"], + "instruments": [ + {"symbol": "A", "source": "csv", "calendar": "XNYS"} + ], "start_date": "2020-01-01", "end_date": "2021-01-01", }, @@ -184,7 +188,9 @@ def test_minimum_weight_above_maximum_weight_rejected() -> None: { "experiment_name": "x", "data": { - "symbols": ["A"], + "instruments": [ + {"symbol": "A", "source": "csv", "calendar": "XNYS"} + ], "start_date": "2020-01-01", "end_date": "2021-01-01", }, @@ -200,7 +206,9 @@ def test_unknown_allocator_rejected_at_config_load() -> None: { "experiment_name": "x", "data": { - "symbols": ["A"], + "instruments": [ + {"symbol": "A", "source": "csv", "calendar": "XNYS"} + ], "start_date": "2020-01-01", "end_date": "2021-01-01", }, @@ -216,7 +224,9 @@ def test_unknown_slippage_model_rejected_at_config_load() -> None: { "experiment_name": "x", "data": { - "symbols": ["A"], + "instruments": [ + {"symbol": "A", "source": "csv", "calendar": "XNYS"} + ], "start_date": "2020-01-01", "end_date": "2021-01-01", }, @@ -727,9 +737,10 @@ def test_execution_delay_is_a_true_resimulation_not_a_returns_shift() -> None: { "experiment_name": "test", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA", "BBB"], + "instruments": [ + {"symbol": s, "source": "csv", "calendar": "XNYS"} + for s in ["AAA", "BBB"] + ], "start_date": "2020-01-01", "end_date": "2021-01-01", "frequency": "1d", @@ -789,9 +800,7 @@ def test_scale_costs_slippage_mult_also_scales_impact_coefficient() -> None: { "experiment_name": "test", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA"], + "instruments": [{"symbol": "AAA", "source": "csv", "calendar": "XNYS"}], "start_date": "2020-01-01", "end_date": "2021-01-01", "frequency": "1d", @@ -950,9 +959,10 @@ def test_engine_turnover_cap_never_exceeds_the_configured_budget() -> None: { "experiment_name": "test", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA", "BBB", "CCC", "DDD"], + "instruments": [ + {"symbol": s, "source": "csv", "calendar": "XNYS"} + for s in ["AAA", "BBB", "CCC", "DDD"] + ], "start_date": "2020-01-01", "end_date": "2020-06-01", "frequency": "1d", @@ -1294,7 +1304,16 @@ def test_engine_only_trades_cap_turnover_on_rebalance_dates() -> None: result = run_backtest_from_config(data, cfg) from quantlab.portfolio.rebalancing import rebalance_dates - dates = rebalance_dates(pd.DatetimeIndex(result.positions.index), "monthly") + # The engine now groups rebalance periods calendar-aware (see + # rebalance_dates' calendar parameter) whenever every instrument shares + # one calendar -- both symbols here are XNYS, so this check must use the + # same calendar to determine "the" rebalance dates, or a bar dated on an + # XNYS holiday in this test's raw bdate-range fixture (not run through + # DataLoader's own holiday/closure handling) would land in a different + # calendar month than a naive .to_period("M") assumes. + dates = rebalance_dates( + pd.DatetimeIndex(result.positions.index), "monthly", calendar="XNYS" + ) # `result.positions` is `executed_weights = held.shift(1)` (the # look-ahead barrier), so a rebalance decided on date `d` only shows up # as a change one period *later* in `result.positions` — shift the @@ -1312,3 +1331,485 @@ def test_engine_only_trades_cap_turnover_on_rebalance_dates() -> None: .sum(axis=1)[non_rebalance_mask] ) assert (turnover_on_non_rebalance_days == 0.0).all() + + +# --------------------------------------------------------------------------- # +# Tradability-aware rebalancing (`rebalance_and_cap_turnover(..., tradable=)`) +# --------------------------------------------------------------------------- # + + +def assert_all_rows_compliant( + result: pd.DataFrame, + *, + maximum_weight: float | None = None, + maximum_gross_exposure: float | None = None, + maximum_net_exposure: float | None = None, + long_only: bool = False, +) -> None: + """Every row a tradability-aware rebalance produces must respect the + portfolio's convex constraints -- especially with one or more instruments + closed, the case that historically could break this invariant.""" + values = result.to_numpy(dtype=float) + if long_only: + assert (values >= -1e-9).all() + if maximum_weight is not None: + assert (np.abs(values) <= maximum_weight + 1e-9).all() + if maximum_gross_exposure is not None: + assert (np.abs(values).sum(axis=1) <= maximum_gross_exposure + 1e-9).all() + if maximum_net_exposure is not None: + assert (np.abs(values.sum(axis=1)) <= maximum_net_exposure + 1e-9).all() + + +def test_tradable_none_preserves_exact_current_behavior() -> None: + """The default (no `tradable`) path must be byte-identical to today's + `apply_rebalancing` + `cap_turnover`, since every existing caller/test + relies on this contract.""" + from quantlab.config import PortfolioConfig, RebalanceFrequency + from quantlab.portfolio.rebalancing import ( + apply_rebalancing, + cap_turnover, + rebalance_and_cap_turnover, + ) + + idx = pd.date_range("2024-01-01", periods=10, freq="D") + targets = pd.DataFrame({"A": [0.5] * 10, "B": [0.5] * 10}, index=idx) + cfg = PortfolioConfig( + rebalance_frequency=RebalanceFrequency.DAILY, maximum_turnover=0.1 + ) + expected = cap_turnover( + apply_rebalancing(targets, "daily"), 0.1, rebalance_index=idx + ) + actual = rebalance_and_cap_turnover(targets, cfg) + pd.testing.assert_frame_equal(expected, actual) + + +def test_tradability_aware_defers_target_while_symbol_closed() -> None: + """A closed symbol must never trade -- its held weight stays exactly at + its last traded value on every date it is closed.""" + from quantlab.config import PortfolioConfig, RebalanceFrequency + from quantlab.portfolio.rebalancing import rebalance_and_cap_turnover + + idx = pd.date_range("2024-01-05", periods=6, freq="D") # Fri..Wed + targets = pd.DataFrame( + {"AAPL": [0.5, 0.5, 0.5, 0.6, 0.6, 0.6], "BTC": [0.5, 0.5, 0.5, 0.4, 0.4, 0.4]}, + index=idx, + ) + tradable = pd.DataFrame( + {"AAPL": [True, False, False, True, True, True], "BTC": [True] * 6}, index=idx + ) + cfg = PortfolioConfig(rebalance_frequency=RebalanceFrequency.DAILY, long_only=True) + held = rebalance_and_cap_turnover(targets, cfg, tradable=tradable) + assert held.loc[idx[1], "AAPL"] == held.loc[idx[0], "AAPL"] + assert held.loc[idx[2], "AAPL"] == held.loc[idx[0], "AAPL"] + assert_all_rows_compliant(held, long_only=True) + + +def test_tradability_aware_tolerates_a_differently_ordered_tradable_frame() -> None: + """`tradable`'s column order need not match `target_weights`' own order + (e.g. an alphabetically-pivoted price matrix vs. a declared symbol + list) -- only the *set* of dates and symbols must agree. A stricter, + order-sensitive check previously rejected this as a mismatch even + though every label was present on both sides.""" + from quantlab.config import PortfolioConfig, RebalanceFrequency + from quantlab.portfolio.rebalancing import rebalance_and_cap_turnover + + idx = pd.date_range("2024-01-05", periods=6, freq="D") + targets = pd.DataFrame( + {"AAPL": [0.5, 0.5, 0.5, 0.6, 0.6, 0.6], "BTC": [0.5, 0.5, 0.5, 0.4, 0.4, 0.4]}, + index=idx, + ) + # Same labels as `targets`, deliberately reversed column order. + tradable = pd.DataFrame( + {"BTC": [True] * 6, "AAPL": [True, False, False, True, True, True]}, index=idx + ) + cfg = PortfolioConfig(rebalance_frequency=RebalanceFrequency.DAILY, long_only=True) + held = rebalance_and_cap_turnover(targets, cfg, tradable=tradable) + assert held.loc[idx[1], "AAPL"] == held.loc[idx[0], "AAPL"] + assert held.loc[idx[2], "AAPL"] == held.loc[idx[0], "AAPL"] + assert_all_rows_compliant(held, long_only=True) + + +def test_tradability_aware_rejects_a_tradable_frame_missing_a_symbol() -> None: + """A genuine set mismatch (not just reordering) must still raise -- + silently defaulting an unrecognized symbol to "tradable" could let it + trade on a date it should have stayed closed.""" + from quantlab.config import PortfolioConfig, RebalanceFrequency + from quantlab.exceptions import InvalidConfigurationError + from quantlab.portfolio.rebalancing import rebalance_and_cap_turnover + + idx = pd.date_range("2024-01-05", periods=3, freq="D") + targets = pd.DataFrame({"AAPL": [0.5, 0.5, 0.5], "BTC": [0.5, 0.5, 0.5]}, index=idx) + tradable = pd.DataFrame({"AAPL": [True, True, True]}, index=idx) # missing BTC + cfg = PortfolioConfig(rebalance_frequency=RebalanceFrequency.DAILY, long_only=True) + with pytest.raises(InvalidConfigurationError, match="dates and symbols"): + rebalance_and_cap_turnover(targets, cfg, tradable=tradable) + + +def test_tradability_aware_catches_up_on_first_reopening_date_even_off_schedule() -> ( + None +): + """A monthly rebalance falls on a date AAPL is closed (a Sunday). + AAPL's pending target must resolve in `held_weights` on its first + tradable date afterward (Monday) -- which is *not* itself a scheduled + rebalance date -- rather than waiting for next month's. This is still + only a *decision*, dated Monday: see the module docstring's timing + convention -- it does not reach the accounting layer's executed + weights until AAPL's next tradable session (Tuesday), the same + one-period lag every other decision in this module is subject to. That + full-pipeline timing is covered separately by + test_reopening_catch_up_decision_only_executes_the_following_tradable_session + in test_regression_execution.py.""" + from quantlab.config import PortfolioConfig, RebalanceFrequency + from quantlab.portfolio.rebalancing import rebalance_and_cap_turnover + + # All four dates fall in January, so "monthly" rebalancing has exactly + # one rebalance date for this whole window: idx[0] (Sunday, Jan 7). + idx = pd.date_range("2024-01-07", periods=4, freq="D") # Sun, Mon, Tue, Wed + targets = pd.DataFrame({"AAPL": [0.6] * 4, "BTC": [0.4] * 4}, index=idx) + tradable = pd.DataFrame( + {"AAPL": [False, True, True, True], "BTC": [True] * 4}, index=idx + ) + cfg = PortfolioConfig( + rebalance_frequency=RebalanceFrequency.MONTHLY, long_only=True + ) + held = rebalance_and_cap_turnover(targets, cfg, tradable=tradable) + assert held.loc[idx[0], "AAPL"] == 0.0 # blocked on the rebalance date itself + assert held.loc[idx[1], "AAPL"] == pytest.approx(0.6) # decided Monday + assert held.loc[idx[1], "BTC"] == pytest.approx(0.4) # BTC traded on schedule + + +def test_reopening_catch_up_decision_only_executes_the_following_tradable_session() -> ( + None +): + """Genuine end-to-end pipeline check (rebalancing.py -> accounting.py) + for the exact scenario above: `rebalance_and_cap_turnover` resolves + AAPL's pending target in `held_weights` on Monday (its reopening day), + but that is only a decision, per this module's documented timing + convention -- it must not affect the accounting layer's executed + weights, turnover or cost until AAPL's next tradable session, Tuesday. + Positions, returns, turnover and costs are all checked together so a + future change that lets the two layers drift out of sync (e.g. one + side collapsing the closure-catch-up delay with the standard + no-look-ahead shift, the other not) is caught here, not discovered as + a confusing mismatch between a rebalancing-only test and a full + backtest.""" + from quantlab.backtesting.accounting import run_accounting + from quantlab.config import PortfolioConfig, RebalanceFrequency + from quantlab.portfolio.rebalancing import rebalance_and_cap_turnover + + idx = pd.date_range("2024-01-07", periods=4, freq="D") # Sun, Mon, Tue, Wed + targets = pd.DataFrame({"AAPL": [0.6] * 4, "BTC": [0.4] * 4}, index=idx) + tradable = pd.DataFrame( + {"AAPL": [False, True, True, True], "BTC": [True] * 4}, index=idx + ) + cfg = PortfolioConfig( + rebalance_frequency=RebalanceFrequency.MONTHLY, long_only=True + ) + held = rebalance_and_cap_turnover(targets, cfg, tradable=tradable) + assert held.loc[idx[1], "AAPL"] == pytest.approx(0.6) # decided Monday + + # AAPL is closed on Sunday, so it has no meaningful return that day; + # a non-zero executed weight there would raise, but AAPL's executed + # weight is (and must remain) exactly zero on Sunday. + asset_returns = pd.DataFrame( + { + "AAPL": [np.nan, 0.01, -0.02, 0.015], + "BTC": [0.005, -0.01, 0.02, 0.0], + }, + index=idx, + ) + result = run_accounting( + held, asset_returns, _flat_execution_model(), 100.0, tradable=tradable + ) + assert result.executed_weights.loc[idx[0], "AAPL"] == 0.0 + assert result.executed_weights.loc[idx[1], "AAPL"] == 0.0 # not yet Monday + assert result.executed_weights.loc[idx[2], "AAPL"] == pytest.approx(0.6) # Tuesday + + # AAPL's own per-symbol weight change lands on Tuesday, not Monday -- + # the weight_changes frame agrees with executed_weights. + assert result.weight_changes.loc[idx[1], "AAPL"] == pytest.approx(0.0) + assert result.weight_changes.loc[idx[2], "AAPL"] == pytest.approx(0.6) + # Total turnover on Monday is BTC's own first-decision execution (0.4, + # decided Sunday, executed Monday under the same one-period rule) -- + # AAPL contributes nothing to it. Tuesday's turnover is AAPL's + # catch-up alone, since BTC is already flat that day. + assert result.turnover.loc[idx[1]] == pytest.approx(0.4) + assert result.turnover.loc[idx[2]] == pytest.approx(0.6) + + +def test_pending_target_remains_pending_after_partial_turnover_fill() -> None: + """When a turnover cap only partially closes the gap on reopening, the + debt must stay open (not silently considered done).""" + from quantlab.config import PortfolioConfig, RebalanceFrequency + from quantlab.portfolio.rebalancing import rebalance_and_cap_turnover + + idx = pd.date_range("2024-01-05", periods=3, freq="D") # Fri, Sat, Sun + targets = pd.DataFrame({"A": [0.2, 0.8, 0.8], "B": [0.2, 0.2, 0.2]}, index=idx) + tradable = pd.DataFrame({"A": [True, False, True], "B": [True] * 3}, index=idx) + cfg = PortfolioConfig( + rebalance_frequency=RebalanceFrequency.DAILY, + maximum_turnover=0.2, + long_only=True, + ) + held = rebalance_and_cap_turnover(targets, cfg, tradable=tradable) + # A is closed on idx[1] (Saturday); its new target (0.8) is set that day + # but can't execute. On idx[2] (Sunday) it reopens and the 0.2 turnover + # cap only lets it move part-way -- it must not have fully reached 0.8. + assert held.loc[idx[1], "A"] == held.loc[idx[0], "A"] + assert cast(float, held.loc[idx[2], "A"]) > cast(float, held.loc[idx[0], "A"]) + assert cast(float, held.loc[idx[2], "A"]) < 0.8 + + +def test_pending_target_continues_catching_up_on_following_open_sessions() -> None: + """The scenario from review: a rebalance blocked by a closure, a partial + turnover-capped catch-up the next day, and a *further* catch-up the day + after that -- without waiting for another scheduled rebalance.""" + from quantlab.config import PortfolioConfig, RebalanceFrequency + from quantlab.portfolio.rebalancing import rebalance_and_cap_turnover + + idx = pd.date_range("2024-01-07", periods=3, freq="D") # Sun, Mon, Tue + # Sunday is the (blocked) monthly rebalance date; A stays closed only on + # Sunday, then is open Monday and Tuesday. + targets = pd.DataFrame({"A": [0.9, 0.9, 0.9], "B": [0.1, 0.1, 0.1]}, index=idx) + tradable = pd.DataFrame({"A": [False, True, True], "B": [True] * 3}, index=idx) + cfg = PortfolioConfig( + rebalance_frequency=RebalanceFrequency.MONTHLY, + maximum_turnover=0.3, + long_only=True, + ) + held = rebalance_and_cap_turnover(targets, cfg, tradable=tradable) + assert held.loc[idx[0], "A"] == 0.0 # never traded, blocked from the start + monday = cast(float, held.loc[idx[1], "A"]) + assert 0.0 < monday < 0.9 # partial catch-up + tuesday = cast(float, held.loc[idx[2], "A"]) + assert tuesday > monday # continues catching up, no new rebalance needed + assert tuesday <= 0.9 + 1e-9 + + +def test_pending_flag_clears_when_target_is_fully_reached() -> None: + """Once a deferred target is fully executed, the symbol must return to + the ordinary rebalance-date-only cadence (no further drift).""" + from quantlab.config import PortfolioConfig, RebalanceFrequency + from quantlab.portfolio.rebalancing import rebalance_and_cap_turnover + + idx = pd.date_range("2024-01-05", periods=4, freq="D") # Fri, Sat, Sun, Mon + targets = pd.DataFrame( + {"A": [0.2, 0.6, 0.6, 0.6], "B": [0.2, 0.2, 0.2, 0.2]}, index=idx + ) + tradable = pd.DataFrame( + {"A": [True, False, True, True], "B": [True] * 4}, index=idx + ) + cfg = PortfolioConfig(rebalance_frequency=RebalanceFrequency.DAILY, long_only=True) + held = rebalance_and_cap_turnover(targets, cfg, tradable=tradable) + # A reaches 0.6 on Sunday (its first reopening, no turnover cap), then + # Monday is a rebalance date with the SAME target (0.6) -- it must simply + # stay there, not move further. + assert held.loc[idx[2], "A"] == pytest.approx(0.6) + assert held.loc[idx[3], "A"] == pytest.approx(0.6) + + +def test_normal_always_open_symbol_does_not_converge_between_rebalance_dates() -> None: + """A symbol that is never closed must keep today's exact cadence: its + weight is exactly flat on every date that is *not* a scheduled + rebalance date, jumping only on rebalance dates -- even in a mixed + portfolio where some other symbol does have closures. The tradability + machinery must never turn a normal turnover-capped catch-up into + continuous day-by-day drift.""" + from quantlab.config import PortfolioConfig, RebalanceFrequency + from quantlab.portfolio.rebalancing import ( + rebalance_and_cap_turnover, + rebalance_dates, + ) + + idx = pd.date_range("2024-01-01", periods=40, freq="D") + targets = pd.DataFrame( + {"ALWAYS_OPEN": [0.9] * 40, "SOMETIMES_CLOSED": [0.1] * 40}, index=idx + ) + tradable = pd.DataFrame( + { + "ALWAYS_OPEN": [True] * 40, + # Closed for a stretch, so pending-due-to-closure logic is + # genuinely exercised for the OTHER column during this run. + "SOMETIMES_CLOSED": [d.day not in range(5, 10) for d in idx], + }, + index=idx, + ) + cfg = PortfolioConfig( + rebalance_frequency=RebalanceFrequency.MONTHLY, maximum_turnover=0.1 + ) + held = rebalance_and_cap_turnover(targets, cfg, tradable=tradable) + + schedule = rebalance_dates(idx, "monthly") + is_rebalance_date = idx.isin(schedule) + always_open = held["ALWAYS_OPEN"] + # On every non-rebalance date, ALWAYS_OPEN's weight must be identical to + # the previous date's -- no drift, regardless of what the other column's + # closures are doing that day. + unchanged = always_open.diff().fillna(0.0) == 0.0 + assert unchanged[~is_rebalance_date].all() + # It must actually still be capped by the turnover budget (not just + # trivially flat because it started at its target). + assert always_open.iloc[0] < 0.9 + + +def test_turnover_budget_excludes_closed_symbols() -> None: + """The turnover cap for a date must apply only to symbols actually + tradable that day -- a closed symbol never consumes any of the budget, + directly or via being scaled down alongside open symbols.""" + from quantlab.config import PortfolioConfig, RebalanceFrequency + from quantlab.portfolio.rebalancing import rebalance_and_cap_turnover + + idx = pd.date_range("2024-01-01", periods=2, freq="D") + targets = pd.DataFrame({"A": [0.5, 1.0], "B": [0.5, 0.0]}, index=idx) + tradable = pd.DataFrame({"A": [True, True], "B": [True, False]}, index=idx) + cfg = PortfolioConfig( + rebalance_frequency=RebalanceFrequency.DAILY, + maximum_turnover=0.2, + long_only=True, + ) + held = rebalance_and_cap_turnover(targets, cfg, tradable=tradable) + # B (closed) contributes nothing to day-1's turnover; A gets the full budget. + day_1 = cast(float, held.loc[idx[1], "A"]) + day_0 = cast(float, held.loc[idx[0], "A"]) + assert (day_1 - day_0) == pytest.approx(0.2) + + +def test_no_trade_cost_or_turnover_for_closed_symbol() -> None: + """A closed symbol's frozen weight must translate into exactly zero + executed weight *change* -- no cost, no turnover -- confirming + `execution_model.py`/`accounting.py` need no changes of their own.""" + from quantlab.portfolio.rebalancing import compute_turnover + + idx = pd.date_range("2024-01-01", periods=3, freq="D") + held = pd.DataFrame({"A": [0.5, 0.5, 0.5], "B": [0.2, 0.5, 0.7]}, index=idx) + turnover = compute_turnover(held) + # A never changes across these rows -- turnover on day 2/3 must come + # entirely from B. + assert turnover.iloc[1] == pytest.approx(abs(0.5 - 0.2)) + assert turnover.iloc[2] == pytest.approx(abs(0.7 - 0.5)) + + +def test_frozen_symbol_forces_partial_execution_to_stay_within_gross_exposure() -> None: + """The exact scenario identified in review: previous A=0.5/B=0.5 + (gross=1.0), a new target A=1.0/B=0.0 (also gross=1.0, individually + valid), but B is closed. Naively freezing B at 0.5 while moving A to 1.0 + would give gross=1.5 -- this must never happen.""" + from quantlab.config import PortfolioConfig, RebalanceFrequency + from quantlab.portfolio.rebalancing import rebalance_and_cap_turnover + + idx = pd.date_range("2024-01-01", periods=2, freq="D") + targets = pd.DataFrame({"A": [0.5, 1.0], "B": [0.5, 0.0]}, index=idx) + tradable = pd.DataFrame({"A": [True, True], "B": [True, False]}, index=idx) + cfg = PortfolioConfig( + rebalance_frequency=RebalanceFrequency.DAILY, + maximum_gross_exposure=1.0, + long_only=True, + ) + held = rebalance_and_cap_turnover(targets, cfg, tradable=tradable) + assert_all_rows_compliant(held, maximum_gross_exposure=1.0, long_only=True) + # B stays frozen; A must NOT reach 1.0, since B pinned at 0.5 forbids it. + assert held.loc[idx[1], "B"] == pytest.approx(0.5) + assert cast(float, held.loc[idx[1], "A"]) < 1.0 - 1e-6 + + +def test_max_feasible_fraction_finds_the_exact_convex_boundary() -> None: + """Direct unit test of the bisection helper against a hand-computed + boundary: previous=[0.5, 0.5], change=[0.5, 0.0] (only column 0 moves), + gross_cap=1.0 -- the exact boundary is f=0 (any positive f breaches gross).""" + from quantlab.portfolio.rebalancing import _max_feasible_fraction + + previous = np.array([0.5, 0.5]) + change = np.array([0.5, 0.0]) + fraction = _max_feasible_fraction( + previous, + change, + maximum_weight=None, + maximum_gross_exposure=1.0, + maximum_net_exposure=None, + long_only=True, + upper_bound=1.0, + ) + assert fraction == pytest.approx(0.0, abs=1e-6) + + # A looser cap (1.2) allows exactly f=0.4 (0.5 + 0.4*0.5 = 0.7, + 0.5 = 1.2). + fraction_loose = _max_feasible_fraction( + previous, + change, + maximum_weight=None, + maximum_gross_exposure=1.2, + maximum_net_exposure=None, + long_only=True, + upper_bound=1.0, + ) + assert fraction_loose == pytest.approx(0.4, abs=1e-6) + + +def test_compliance_limited_shortfall_becomes_pending_and_retried_next_session() -> ( + None +): + """When gross-exposure interaction (not turnover) limits how far a + column can move because another column is frozen, the shortfall must + still be retried on the next tradable date -- not silently dropped.""" + from quantlab.config import PortfolioConfig, RebalanceFrequency + from quantlab.portfolio.rebalancing import rebalance_and_cap_turnover + + idx = pd.date_range("2024-01-01", periods=3, freq="D") + # Day 0: A=0.5,B=0.5. Day 1: target A=1.0,B=0.0 but B closed -> A limited + # by gross cap, not reaching 1.0. Day 2: B still closed -> A must keep + # trying (and since B stays frozen at 0.5, A stays capped at <=0.5 too, + # but the mechanism must still attempt it rather than giving up). + targets = pd.DataFrame({"A": [0.5, 1.0, 1.0], "B": [0.5, 0.0, 0.0]}, index=idx) + tradable = pd.DataFrame({"A": [True] * 3, "B": [True, False, False]}, index=idx) + cfg = PortfolioConfig( + rebalance_frequency=RebalanceFrequency.DAILY, + maximum_gross_exposure=1.0, + long_only=True, + ) + held = rebalance_and_cap_turnover(targets, cfg, tradable=tradable) + assert_all_rows_compliant(held, maximum_gross_exposure=1.0, long_only=True) + # A never exceeds what's feasible while B stays frozen at 0.5. + assert (held["A"] <= 0.5 + 1e-9).all() + + +def test_compliance_limited_flag_never_triggers_when_every_symbol_is_tradable() -> None: + """Non-regression for the review's central concern: with no closures + anywhere, compliance can never bind below the turnover-derived fraction, + so the pending mechanism must never activate -- cadence stays exactly + the plain `cap_turnover` behaviour.""" + from quantlab.config import PortfolioConfig, RebalanceFrequency + from quantlab.portfolio.rebalancing import ( + apply_rebalancing, + cap_turnover, + rebalance_and_cap_turnover, + ) + + idx = pd.date_range("2024-01-01", periods=8, freq="D") + targets = pd.DataFrame({"A": [0.9] * 8, "B": [0.05] * 8}, index=idx) + tradable = pd.DataFrame({"A": [True] * 8, "B": [True] * 8}, index=idx) + cfg = PortfolioConfig( + rebalance_frequency=RebalanceFrequency.DAILY, + maximum_turnover=0.05, + maximum_gross_exposure=1.0, + ) + held = rebalance_and_cap_turnover(targets, cfg, tradable=tradable) + expected = cap_turnover( + apply_rebalancing(targets, "daily"), + 0.05, + rebalance_index=idx, + maximum_gross_exposure=1.0, + ) + pd.testing.assert_frame_equal(held, expected) + + +def test_no_execution_cost_or_turnover_for_a_closed_symbol_on_closed_dates() -> None: + """End-to-end confirmation that a closed symbol never appears in the + accounting layer's turnover/cost path on a date it's closed.""" + from quantlab.backtesting.accounting import compute_executed_weights + + idx = pd.date_range("2024-01-01", periods=3, freq="D") + held = pd.DataFrame({"A": [0.5, 0.5, 0.5], "B": [0.2, 0.5, 0.7]}, index=idx) + executed = compute_executed_weights(held) + # A's executed (lagged) series is constant after the mechanical + # first-row-zero artifact (compute_executed_weights always forces row 0 + # to 0.0 regardless of activity) -- no trade is ever implied thereafter. + assert executed["A"].iloc[1:].nunique(dropna=True) <= 1 diff --git a/tests/unit/test_regression_reporting.py b/tests/unit/test_regression_reporting.py index f7ea8a6..7cbabc0 100644 --- a/tests/unit/test_regression_reporting.py +++ b/tests/unit/test_regression_reporting.py @@ -108,7 +108,10 @@ def test_report_command_skips_reinjection_when_config_differs(tmp_path: Path) -> { "experiment_name": "wf_experiment", "data": { - "symbols": ["C", "D"], # different universe + "instruments": [ + {"symbol": "C", "source": "csv", "calendar": "XNYS"}, + {"symbol": "D", "source": "csv", "calendar": "XNYS"}, + ], # different universe "start_date": "2020-01-01", "end_date": "2021-01-01", }, @@ -124,10 +127,14 @@ def test_report_command_skips_reinjection_when_config_differs(tmp_path: Path) -> assert "walk_forward_oos_metrics" not in fake_result.metadata -def test_report_command_missing_checksums_does_not_block_reuse( +def test_report_command_missing_checksums_blocks_reuse( tmp_path: Path, ) -> None: - """Missing checksums alone are not evidence of an artefact mismatch.""" + """Missing checksums can't verify artefact integrity, so they must not + be treated as a free pass to reuse anyway -- checksums are recorded + unconditionally at every save (see BacktestResult.save()), so their + absence here is itself a red flag (an incomplete or tampered + metadata.json), not proof of "nothing to check".""" import json as _json from quantlab.backtesting.result import load_previous_walk_forward_robustness @@ -147,11 +154,56 @@ def test_report_command_missing_checksums_does_not_block_reuse( exp_dir, fake_result, # type: ignore[arg-type] ) - assert robustness is not None - assert fake_result.metadata["walk_forward_oos_metrics"] == { - "sharpe_ratio": 0.42, - "cagr": 0.05, - } + assert robustness is None + assert "walk_forward_oos_metrics" not in fake_result.metadata + + +def test_report_command_refuses_reuse_for_malformed_metadata_json( + tmp_path: Path, +) -> None: + """A hand-edited or partially-written metadata.json must be refused + gracefully, the same as a missing file or a mismatched hash -- not + crash reuse detection with a raw json.JSONDecodeError.""" + from quantlab.backtesting.result import load_previous_walk_forward_robustness + + exp_dir = tmp_path / "wf_experiment" + exp_dir.mkdir() + config = _wf_experiment_config() + _write_wf_artifacts(exp_dir, config) + + (exp_dir / "metadata.json").write_text("{not valid json", encoding="utf-8") + + fake_result = _FakeResult(config) + robustness = load_previous_walk_forward_robustness( + exp_dir, + fake_result, # type: ignore[arg-type] + ) + assert robustness is None + assert "walk_forward_oos_metrics" not in fake_result.metadata + + +def test_load_previous_robustness_artifacts_refuses_reuse_for_malformed_metadata_json( + tmp_path: Path, +) -> None: + """Same guarantee as load_previous_walk_forward_robustness, for the + holdout/plain-backtest robustness-artefact reuse path: a malformed + metadata.json must be refused gracefully, not crash with a raw + json.JSONDecodeError.""" + from quantlab.backtesting.result import load_previous_robustness_artifacts + + exp_dir = tmp_path / "wf_experiment" + exp_dir.mkdir() + config = _wf_experiment_config() + _write_wf_artifacts(exp_dir, config) + + (exp_dir / "metadata.json").write_text("{not valid json", encoding="utf-8") + + fake_result = _FakeResult(config) + artifacts = load_previous_robustness_artifacts( + exp_dir, + fake_result, # type: ignore[arg-type] + ) + assert artifacts == {} def test_config_dir_prefers_a_package_bundled_copy_when_present( @@ -222,11 +274,12 @@ def test_cli_shipped_config_resolves_a_bundled_config_by_name( (bundled_dir / "demo_offline.yaml").write_text( "experiment_name: bundled_copy\n" "data:\n" - " source: csv\n" - " symbols: [AAA]\n" + " instruments:\n" + " - symbol: AAA\n" + " source: csv\n" + " calendar: XNYS\n" " start_date: '2020-01-01'\n" " end_date: '2021-01-01'\n" - " market_calendar: XNYS\n" "strategy:\n" " name: buy_and_hold\n", encoding="utf-8", @@ -389,6 +442,13 @@ def test_cli_walk_forward_delegates_all_validation_csvs_to_result_save( folds=[object()], oos_returns=returns, oos_equity=equity, + # None here (not a full BacktestResult): exercises cli.py's + # documented fallback to oos_metrics() when oos_result is absent, + # same as this test's own intent -- it isn't testing OOS-metrics + # completeness (see test_saved_metadata_records_an_explicit_ + # result_scope / the walk-forward metrics-reuse tests for that), + # only that the CLI delegates validation CSVs to result.save(). + oos_result=None, summary_table=lambda: summary, oos_metrics=lambda periods_per_year, risk_free_rate: { "sharpe_ratio": 0.42, @@ -426,7 +486,9 @@ def run(self, loaded_data: pd.DataFrame, **kwargs: object) -> object: ) monkeypatch.setattr(walk_forward_module, "WalkForwardValidator", FakeValidator) monkeypatch.setattr( - robustness_module, "run_stress_tests", lambda _data, _cfg: stress + robustness_module, + "run_stress_tests", + lambda _data, _cfg, **_kwargs: stress, ) monkeypatch.setattr( runner_module, @@ -467,16 +529,10 @@ def test_download_data_wrapper_reports_source_aware_persistence( ) -> None: import sys - from quantlab.config import DataSourceName - wrapper: Any = _import_script("download_data") config_path = tmp_path / "experiment.yaml" config_path.write_text("unused: true\n", encoding="utf-8") - config = type( - "Config", - (), - {"data": type("Data", (), {"source": DataSourceName(source)})()}, - )() + config = type("Config", (), {"data_source": source})() frame = pd.DataFrame({"symbol": ["AAA", "AAA"], "close": [1.0, 2.0]}) monkeypatch.setattr( @@ -580,6 +636,28 @@ def test_code_hash_changes_when_quantlab_source_changes( assert original != mutated +def test_generator_hash_changes_when_generate_report_script_changes( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """scripts/generate_report.py lives outside src/quantlab/ entirely, so + _hash_source_tree's own rglob scan can never reach it -- but it makes + the exact same walk-forward save/reuse decision as the CLI + (save_with_walk_forward_reuse), so its own content must still be + covered by _generator_hash(), the hash everything gating artifact + reuse is keyed on.""" + from quantlab.backtesting import engine + + fake_script = tmp_path / "generate_report.py" + fake_script.write_text("# v1\n", encoding="utf-8") + monkeypatch.setattr(engine, "_GENERATOR_SCRIPT", fake_script) + + original = engine._generator_hash() + fake_script.write_text("# v2 -- edited\n", encoding="utf-8") + mutated = engine._generator_hash() + + assert original != mutated + + def test_dependency_versions_tracks_statsmodels() -> None: from quantlab.backtesting.runner import run_backtest_from_config @@ -590,6 +668,19 @@ def test_dependency_versions_tracks_statsmodels() -> None: assert "statsmodels" in versions +def test_dependency_versions_tracks_pandas_market_calendars() -> None: + """pandas-market-calendars directly drives calendar/session/settlement + results (holidays, sessions, closures) -- a version bump can change + backtest output the same way a pandas/numpy bump can, so it must be + part of provenance too, not silently missing from it.""" + from quantlab.backtesting.runner import run_backtest_from_config + + data, cfg = _holdout_config() + result = run_backtest_from_config(data, cfg) + versions = result.metadata["dependency_versions"] + assert "pandas-market-calendars" in versions + + def test_git_dirty_state_is_recorded_alongside_commit_hash( tmp_path: Path, monkeypatch: pytest.MonkeyPatch ) -> None: @@ -1045,9 +1136,9 @@ def test_run_backtest_script_flags_save_warnings_instead_of_plain_success( config = { "experiment_name": "run_backtest_script_save_warning_test", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2020-03-01", }, @@ -1099,9 +1190,9 @@ def test_generate_report_script_flags_save_warnings_instead_of_plain_success( config = { "experiment_name": "generate_report_script_save_warning_test", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2020-03-01", }, @@ -1151,9 +1242,9 @@ def test_saved_metrics_json_has_no_nan_or_infinity_tokens( { "experiment_name": "nan_json_test", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2020-01-30", }, @@ -1191,9 +1282,9 @@ def test_cumulative_costs_chart_actually_appears_in_html_report() -> None: { "experiment_name": "cumulative_costs_html_test", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2020-04-30", }, @@ -1218,9 +1309,9 @@ def test_save_warnings_surface_a_failed_report_chart( { "experiment_name": "chart_failure_test", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2020-04-30", }, @@ -1241,3 +1332,43 @@ def boom(_result: Any) -> Any: ) html_text = (out / "report.html").read_text(encoding="utf-8") assert "drawdown" in html_text.lower() # the other charts still rendered + + +def test_saved_metadata_records_an_explicit_result_scope(tmp_path: Path) -> None: + """Different CLI commands in walk-forward mode save fundamentally + different result objects to the same experiment directory (a + full-sample result with OOS evidence only attached as metadata, vs the + OOS-stitched result itself) -- metadata.json must say explicitly which + one `self.metrics` is, so a bundle read later isn't ambiguous about + which methodology produced it.""" + from quantlab.backtesting.runner import run_backtest_from_config + + data = make_ohlcv( + "AAA", geometric_series(120, mu=0.0005, sigma=0.01, s0=100.0, seed=1) + ) + cfg = ExperimentConfig.from_dict( + { + "experiment_name": "result_scope_test", + "data": { + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + ], + "start_date": "2020-01-01", + "end_date": "2020-04-30", + }, + "strategy": {"name": "buy_and_hold"}, + } + ) + + full_sample = run_backtest_from_config(data, cfg) + out = full_sample.save(tmp_path / "full_sample") + metadata = json.loads((out / "metadata.json").read_text(encoding="utf-8")) + assert metadata["result_scope"] == "full_sample" + + # Simulate a genuine wf.oos_result (see _attach_walk_forward_evidence / + # walk_forward.py's own construction): its metrics ARE the OOS series. + oos_scoped = run_backtest_from_config(data, cfg) + oos_scoped.metadata["walk_forward_oos_metrics"] = dict(oos_scoped.metrics) + out = oos_scoped.save(tmp_path / "oos_scoped") + metadata = json.loads((out / "metadata.json").read_text(encoding="utf-8")) + assert metadata["result_scope"] == "out-of-sample (walk-forward test folds only)" diff --git a/tests/unit/test_regression_risk.py b/tests/unit/test_regression_risk.py index a6db547..ba6ee44 100644 --- a/tests/unit/test_regression_risk.py +++ b/tests/unit/test_regression_risk.py @@ -73,7 +73,7 @@ def test_static_hedge_ratio_no_lookahead() -> None: # Changing future data must not change the beta value seen at earlier dates. b_changed_future = b.copy() - b_changed_future.iloc[15:] += 1000.0 + b_changed_future.iloc[15:] = b_changed_future.iloc[15:].add(1000.0) beta_changed = _rolling_hedge_ratio(a, b_changed_future, window=5, dynamic=False) pd.testing.assert_series_equal(beta.iloc[:15], beta_changed.iloc[:15]) @@ -111,7 +111,7 @@ def test_slice_range_excludes_day_after_end() -> None: data = make_ohlcv("AAA", np.linspace(100, 110, 5), start="2020-01-01", freq="D") sliced = DataLoader._slice_range( - data, date(2020, 1, 1), date(2020, 1, 2), "1d", is_247_market=False + data, date(2020, 1, 1), date(2020, 1, 2), "1d", calendar="XNYS" ) dates = sliced["timestamp"].dt.strftime("%Y-%m-%d").tolist() assert dates == ["2020-01-01", "2020-01-02"] @@ -134,9 +134,10 @@ def test_benchmark_outside_universe_is_loaded_but_not_tradable( { "experiment_name": "bench_test", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["EWA", "EWC"], + "instruments": [ + {"symbol": "EWA", "source": "csv", "calendar": "XNYS"}, + {"symbol": "EWC", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2019-01-01", "end_date": "2019-08-01", }, @@ -155,7 +156,10 @@ def test_benchmark_outside_universe_is_loaded_but_not_tradable( "spread_bps": 3.0, "slippage_bps": 2.0, }, - "backtest": {"initial_capital": 100_000, "benchmark_symbol": "SPY"}, + "backtest": { + "initial_capital": 100_000, + "benchmark": {"symbol": "SPY", "source": "csv", "calendar": "XNYS"}, + }, } ) loader = DataLoader( @@ -177,7 +181,9 @@ def test_unknown_validation_method_rejected() -> None: { "experiment_name": "x", "data": { - "symbols": ["A"], + "instruments": [ + {"symbol": "A", "source": "csv", "calendar": "XNYS"} + ], "start_date": "2020-01-01", "end_date": "2021-01-01", }, @@ -193,7 +199,9 @@ def test_unknown_optimization_metric_rejected_at_config_load() -> None: { "experiment_name": "x", "data": { - "symbols": ["A"], + "instruments": [ + {"symbol": "A", "source": "csv", "calendar": "XNYS"} + ], "start_date": "2020-01-01", "end_date": "2021-01-01", }, @@ -204,21 +212,23 @@ def test_unknown_optimization_metric_rejected_at_config_load() -> None: def test_crypto_monthly_annualises_at_12_not_252() -> None: + from quantlab.data.calendar import is_247 + cfg = ExperimentConfig.from_dict( { "experiment_name": "x", "data": { - "source": "csv", - "symbols": ["BTC"], + "instruments": [ + {"symbol": "BTC", "source": "csv", "calendar": "24/7"}, + ], "start_date": "2020-01-01", "end_date": "2021-01-01", "frequency": "1mo", - "market_calendar": "24/7", }, "strategy": {"name": "buy_and_hold"}, } ) - assert cfg.data.is_247_market + assert is_247(cfg.data.instruments[0].calendar) assert cfg.periods_per_year == 12 @@ -262,7 +272,9 @@ def test_2x_hourly_mismatch_now_flagged() -> None: frame = _hourly_symbol_frame("2h", 40, "BTCUSDT") report = DataValidator( - expected_frequency="1h", min_coverage_rows=5, is_247_market=True + expected_frequency="1h", + min_coverage_rows=5, + symbol_calendars={"BTCUSDT": "24/7"}, ).validate(frame) assert any("does not match the declared frequency" in w for w in report.warnings) @@ -272,7 +284,9 @@ def test_2x_daily_mismatch_now_flagged() -> None: frame = _hourly_symbol_frame("2D", 40, "AAA") report = DataValidator( - expected_frequency="1d", min_coverage_rows=5, is_247_market=False + expected_frequency="1d", + min_coverage_rows=5, + symbol_calendars={"AAA": "XNYS"}, ).validate(frame) assert any("does not match the declared frequency" in w for w in report.warnings) @@ -298,7 +312,9 @@ def test_end_boundary_is_strictly_exclusive() -> None: "volume": 1000.0, } ) - report = DataValidator(min_coverage_rows=1).validate(frame, end=date(2020, 1, 31)) + report = DataValidator( + min_coverage_rows=1, symbol_calendars={"AAA": "XNYS"} + ).validate(frame, end=date(2020, 1, 31)) assert any("rows after requested end" in w for w in report.warnings) @@ -454,7 +470,12 @@ def test_source_hash_ttl_catches_a_mtime_preserving_edit( # Once the TTL has elapsed, the edit must be caught even though the # fingerprint never changed. - monkeypatch.setattr(engine, "_source_hash_computed_at", time.monotonic() - 61.0) + fingerprint, value, _computed_at = engine._source_hash_cache["source"] + monkeypatch.setitem( + engine._source_hash_cache, + "source", + (fingerprint, value, time.monotonic() - 61.0), + ) mutated = engine._source_hash() assert mutated != original @@ -481,7 +502,9 @@ def test_dotted_ticker_and_underscored_name_are_accepted() -> None: names commonly use underscores.""" payload = _base_config_dict() payload["data"] = dict(payload["data"]) - payload["data"]["symbols"] = ["BRK.B"] + payload["data"]["instruments"] = [ + {"symbol": "BRK.B", "source": "csv", "calendar": "XNYS"} + ] payload["experiment_name"] = "my_experiment-2024.v1" cfg = ExperimentConfig.from_dict(payload) assert cfg.symbols == ["BRK.B"] @@ -566,11 +589,11 @@ def test_safe_prevents_hash_shape_collision_end_to_end(tmp_path: Path) -> None: "volume": 0.0, } ) - storage.write_symbol(first, "yahoo", "A=80", "1d") - storage.write_symbol(second, "yahoo", "A_80-5673847950", "1d") + storage.write_symbol(first, "yahoo", "A=80", "1d", calendar="XNYS") + storage.write_symbol(second, "yahoo", "A_80-5673847950", "1d", calendar="XNYS") - read_first = storage.read_symbol("yahoo", "A=80", "1d") - read_second = storage.read_symbol("yahoo", "A_80-5673847950", "1d") + read_first = storage.read_symbol("yahoo", "A=80", "1d", calendar="XNYS") + read_second = storage.read_symbol("yahoo", "A_80-5673847950", "1d", calendar="XNYS") assert read_first is not None assert read_second is not None assert (read_first["close"] == 1.1).all() @@ -725,14 +748,14 @@ def test_slice_range_drops_a_look_ahead_hourly_bar() -> None: ) narrow = DataLoader._slice_range( - data, date(2024, 1, 5), date(2024, 1, 5), "1h", is_247_market=True + data, date(2024, 1, 5), date(2024, 1, 5), "1h", calendar="24/7" ) # The 22:30 bar's bucket (23:30) closes before the request's own end # boundary; the 23:30 bar's bucket (00:30 the next day) does not. assert list(narrow["timestamp"]) == [pd.Timestamp("2024-01-05 22:30")] wider = DataLoader._slice_range( - data, date(2024, 1, 5), date(2024, 1, 6), "1h", is_247_market=True + data, date(2024, 1, 5), date(2024, 1, 6), "1h", calendar="24/7" ) assert len(wider) == 2 @@ -747,10 +770,10 @@ def test_trading_day_helpers_normalize_the_time_component() -> None: ) assert last_trading_day_on_or_before( - pd.Timestamp("2024-01-06 15:30"), is_247_market=False + pd.Timestamp("2024-01-06 15:30"), calendar="XNYS" ) == pd.Timestamp("2024-01-05") assert first_trading_day_on_or_after( - pd.Timestamp("2024-01-07 15:30"), is_247_market=False + pd.Timestamp("2024-01-07 15:30"), calendar="XNYS" ) == pd.Timestamp("2024-01-08") diff --git a/tests/unit/test_regression_strategies.py b/tests/unit/test_regression_strategies.py index dcd6590..b1617b8 100644 --- a/tests/unit/test_regression_strategies.py +++ b/tests/unit/test_regression_strategies.py @@ -23,7 +23,9 @@ def test_unknown_strategy_name_rejected_at_config_load() -> None: { "experiment_name": "x", "data": { - "symbols": ["A"], + "instruments": [ + {"symbol": "A", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2021-01-01", }, @@ -38,7 +40,9 @@ def test_unknown_strategy_parameter_rejected_at_config_load() -> None: { "experiment_name": "x", "data": { - "symbols": ["A"], + "instruments": [ + {"symbol": "A", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2021-01-01", }, @@ -55,7 +59,9 @@ def test_known_strategy_parameters_still_accepted() -> None: { "experiment_name": "x", "data": { - "symbols": ["A"], + "instruments": [ + {"symbol": "A", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2021-01-01", }, @@ -74,7 +80,9 @@ def test_var_keyword_catch_all_does_not_admit_bogus_parameters() -> None: { "experiment_name": "x", "data": { - "symbols": ["A"], + "instruments": [ + {"symbol": "A", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2021-01-01", }, @@ -89,7 +97,9 @@ def test_wrong_type_strategy_parameter_rejected() -> None: { "experiment_name": "x", "data": { - "symbols": ["A"], + "instruments": [ + {"symbol": "A", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2021-01-01", }, @@ -107,7 +117,10 @@ def test_pairs_trading_missing_required_parameter_rejected() -> None: { "experiment_name": "x", "data": { - "symbols": ["AAA", "BBB"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + {"symbol": "BBB", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2021-01-01", }, @@ -125,7 +138,9 @@ def test_mean_reversion_zero_lookback_rejected() -> None: { "experiment_name": "x", "data": { - "symbols": ["A"], + "instruments": [ + {"symbol": "A", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2021-01-01", }, @@ -143,7 +158,10 @@ def test_cross_sectional_momentum_out_of_range_top_fraction_rejected() -> None: { "experiment_name": "x", "data": { - "symbols": ["A", "B"], + "instruments": [ + {"symbol": "A", "source": "csv", "calendar": "XNYS"}, + {"symbol": "B", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2021-01-01", }, @@ -161,7 +179,9 @@ def test_time_series_momentum_unknown_signal_scaling_rejected() -> None: { "experiment_name": "x", "data": { - "symbols": ["A"], + "instruments": [ + {"symbol": "A", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2021-01-01", }, @@ -180,7 +200,9 @@ def test_int_accepted_for_float_strategy_parameter() -> None: { "experiment_name": "x", "data": { - "symbols": ["A"], + "instruments": [ + {"symbol": "A", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2021-01-01", }, @@ -498,8 +520,9 @@ def test_strategy_periods_per_year_injected_from_config() -> None: { "experiment_name": "test", "data": { - "source": "binance", - "symbols": ["BTCUSDT"], + "instruments": [ + {"symbol": "BTCUSDT", "source": "binance", "calendar": "24/7"}, + ], "start_date": "2020-01-01", "end_date": "2020-06-01", "frequency": "1d", @@ -528,8 +551,9 @@ def test_explicit_strategy_periods_per_year_still_wins() -> None: { "experiment_name": "test", "data": { - "source": "binance", - "symbols": ["BTCUSDT"], + "instruments": [ + {"symbol": "BTCUSDT", "source": "binance", "calendar": "24/7"}, + ], "start_date": "2020-01-01", "end_date": "2020-06-01", "frequency": "1d", diff --git a/tests/unit/test_regression_validation.py b/tests/unit/test_regression_validation.py index 5563427..0027a3b 100644 --- a/tests/unit/test_regression_validation.py +++ b/tests/unit/test_regression_validation.py @@ -41,9 +41,11 @@ def test_holdout_config_produces_attached_oos_metrics() -> None: { "experiment_name": "holdout", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA", "BBB", "CCC"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + {"symbol": "BBB", "source": "csv", "calendar": "XNYS"}, + {"symbol": "CCC", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2021-06-01", }, @@ -70,8 +72,8 @@ def test_holdout_config_produces_attached_oos_metrics() -> None: } ) result = run_backtest_from_config(data, cfg) - assert "holdout_oos_metrics" in result.metadata - assert "sharpe_ratio" in result.metadata["holdout_oos_metrics"] + assert "holdout_chronological_metrics" in result.metadata + assert "sharpe_ratio" in result.metadata["holdout_chronological_metrics"] def test_conclusion_never_claims_oos_without_artifact() -> None: @@ -87,9 +89,10 @@ def test_conclusion_never_claims_oos_without_artifact() -> None: { "experiment_name": "plain", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA", "BBB"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + {"symbol": "BBB", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2020-11-01", }, @@ -98,7 +101,7 @@ def test_conclusion_never_claims_oos_without_artifact() -> None: } ) result = run_backtest_from_config(data, cfg) - assert "holdout_oos_metrics" not in result.metadata + assert "holdout_chronological_metrics" not in result.metadata assert "walk_forward_oos_metrics" not in result.metadata text = conclusion(result) + methodology(result) assert "out-of-sample" not in text.lower() or "full-sample" in text.lower() @@ -162,7 +165,8 @@ def test_holdout_split_table_appears_in_html_report_without_manual_wiring() -> N data, cfg = _holdout_config() result = run_backtest_from_config(data, cfg) html = result.to_html() - assert "Test (out-of-sample)" in html + assert "Holdout Split" in html + assert "Test" in html def test_conclusion_cross_references_full_sample_and_oos_sharpe_by_name() -> None: @@ -176,11 +180,147 @@ def test_conclusion_cross_references_full_sample_and_oos_sharpe_by_name() -> Non assert "out-of-sample" in text.lower() # The two Sharpe values must both be printed, not just one. full_sharpe = result.metrics["sharpe_ratio"] - oos_sharpe = result.metadata["holdout_oos_metrics"]["sharpe_ratio"] + oos_sharpe = result.metadata["holdout_chronological_metrics"]["sharpe_ratio"] assert f"{full_sharpe:.2f}" in text assert f"{oos_sharpe:.2f}" in text +def test_conclusion_does_not_claim_separate_full_sample_for_walk_forward() -> None: + """A walk-forward OOS result's `metrics` *is* the stitched OOS series — + the conclusion must not present it a second time as a separate + "full-sample" figure alongside an identical "out-of-sample" one.""" + from quantlab.reporting.research_summary import conclusion + from quantlab.validation.walk_forward import WalkForwardValidator + + data, cfg = _rf_test_setup() + wf = WalkForwardValidator(cfg).run( + data, parameter_grid={}, train_window=200, validation_window=50, test_window=50 + ) + assert wf.oos_result is not None + text = conclusion(wf.oos_result) + assert "separate full-sample" not in text + oos_sharpe = wf.oos_result.metadata["walk_forward_oos_metrics"]["sharpe_ratio"] + formatted = f"{oos_sharpe:.2f}" + assert formatted in text + # Printed once, not once as "out-of-sample" and again as a duplicate + # "full-sample" figure that happens to be numerically identical. + assert text.count(formatted) == 1 + + +def test_out_of_sample_scope_distinguishes_walk_forward_from_holdout() -> None: + """Only a walk-forward OOS result's `metrics` themselves *are* the + out-of-sample series — a holdout result's `metrics` remain a genuine + full-sample fit even though OOS evidence is also attached separately, + so it must not be flagged the same way.""" + from quantlab.backtesting.runner import run_backtest_from_config + from quantlab.reporting.research_summary import out_of_sample_scope + from quantlab.validation.walk_forward import WalkForwardValidator + + data, cfg = _rf_test_setup() + wf = WalkForwardValidator(cfg).run( + data, parameter_grid={}, train_window=200, validation_window=50, test_window=50 + ) + assert wf.oos_result is not None + assert ( + out_of_sample_scope(wf.oos_result) + == "out-of-sample (walk-forward test folds only)" + ) + + holdout_data, holdout_cfg = _holdout_config() + holdout_result = run_backtest_from_config(holdout_data, holdout_cfg) + assert "holdout_chronological_metrics" in holdout_result.metadata + assert out_of_sample_scope(holdout_result) is None + + plain_result = run_backtest_from_config(data, cfg) + assert out_of_sample_scope(plain_result) is None + + +def test_limitations_caveats_the_holdout_blocks_out_of_sample_label() -> None: + """A holdout split is only "out-of-sample" if strategy/parameter choices + were genuinely frozen before it was inspected -- QuantLab has no way to + verify that discipline was followed, so the report must say so rather + than silently presenting the label as an established fact. Walk-forward + doesn't need this caveat: its rolling-window discipline is baked into + the validation loop itself, not a promise from the user.""" + from quantlab.backtesting.runner import run_backtest_from_config + from quantlab.reporting.research_summary import limitations + from quantlab.validation.walk_forward import WalkForwardValidator + + holdout_data, holdout_cfg = _holdout_config() + holdout_result = run_backtest_from_config(holdout_data, holdout_cfg) + holdout_items = limitations(holdout_result) + assert any("out-of-sample" in item and "frozen" in item for item in holdout_items) + + data, cfg = _rf_test_setup() + wf = WalkForwardValidator(cfg).run( + data, parameter_grid={}, train_window=200, validation_window=50, test_window=50 + ) + assert wf.oos_result is not None + wf_items = limitations(wf.oos_result) + assert not any("frozen" in item for item in wf_items) + + plain_result = run_backtest_from_config(data, cfg) + plain_items = limitations(plain_result) + assert not any("frozen" in item for item in plain_items) + + +def test_subperiod_table_labels_walk_forward_aggregate_as_out_of_sample() -> None: + """`subperiod_table`'s aggregate row must not call a walk-forward OOS + series "Full sample" — the opposite of what it is.""" + from quantlab.reporting.tables import subperiod_table + from quantlab.validation.walk_forward import WalkForwardValidator + + data, cfg = _rf_test_setup() + wf = WalkForwardValidator(cfg).run( + data, parameter_grid={}, train_window=200, validation_window=50, test_window=50 + ) + assert wf.oos_result is not None + table = subperiod_table(wf.oos_result) + periods = set(table["Period"]) + assert "Out-of-sample" in periods + assert "Full sample" not in periods + + +def test_html_report_labels_walk_forward_results_as_out_of_sample() -> None: + """The Results section headings and executive summary must say + out-of-sample (walk-forward), never the "Full-sample" wording that's + only accurate for a genuine full-sample fit.""" + from quantlab.validation.walk_forward import WalkForwardValidator + + data, cfg = _rf_test_setup() + wf = WalkForwardValidator(cfg).run( + data, parameter_grid={}, train_window=200, validation_window=50, test_window=50 + ) + assert wf.oos_result is not None + html = wf.oos_result.to_html() + assert "Out-of-sample (walk-forward) headline metrics" in html + assert "Full-sample" not in html + assert "These are out-of-sample (walk-forward test folds only) results" in html + + +def test_walk_forward_oos_result_reports_config_yaml_reflects_everything() -> None: + """WalkForwardValidator never accepts a custom strategy/allocator/ + execution-model instance the way BacktestEngine.run() does (docs/api.md) + -- every component is always built from active_config alone, so all + three config_yaml_reflects_* flags are unconditional facts here, not a + best-effort verification. Without them present and True, the HTML + report's footer (which requires all three) would treat every + walk-forward result as unverified and never claim reproducibility, even + though a walk-forward result always is.""" + from quantlab.validation.walk_forward import WalkForwardValidator + + data, cfg = _rf_test_setup() + wf = WalkForwardValidator(cfg).run( + data, parameter_grid={}, train_window=200, validation_window=50, test_window=50 + ) + assert wf.oos_result is not None + assert wf.oos_result.metadata["config_yaml_reflects_strategy"] is True + assert wf.oos_result.metadata["config_yaml_reflects_allocator"] is True + assert wf.oos_result.metadata["config_yaml_reflects_execution"] is True + html = wf.oos_result.to_html() + assert "reproducible from config.yaml given the same code" in html + + def test_holdout_test_ratio_without_validation_ratio_does_not_crash() -> None: from quantlab.backtesting.runner import run_backtest_from_config @@ -193,9 +333,10 @@ def test_holdout_test_ratio_without_validation_ratio_does_not_crash() -> None: { "experiment_name": "holdout_no_validation_block", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA", "BBB"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + {"symbol": "BBB", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2021-06-01", }, @@ -216,7 +357,7 @@ def test_holdout_test_ratio_without_validation_ratio_does_not_crash() -> None: # "Validation" row for a zero-width synthesised validation period as if # it were a real row with metrics. html = result.to_html() - assert "Test (out-of-sample)" in html + assert "Test" in html assert "Validation" not in html @@ -228,9 +369,9 @@ def test_holdout_empty_train_block_does_not_crash() -> None: { "experiment_name": "holdout_empty_train", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2020-01-02", }, @@ -288,7 +429,10 @@ def test_report_command_detects_config_yaml_edited_after_walk_forward_run( { "experiment_name": "wf_experiment", "data": { - "symbols": ["NEW1", "NEW2"], + "instruments": [ + {"symbol": "NEW1", "source": "yahoo", "calendar": "XNYS"}, + {"symbol": "NEW2", "source": "yahoo", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2021-01-01", }, @@ -329,18 +473,21 @@ def test_report_command_rejects_stale_walk_forward_when_data_hash_differs( assert "walk_forward_oos_metrics" not in fake_result.metadata -def test_report_command_rejects_stale_walk_forward_when_code_hash_differs( +def test_report_command_rejects_stale_walk_forward_when_generator_hash_differs( tmp_path: Path, ) -> None: + """generator_hash, not the narrower code_hash, gates reuse of a saved + bundle: it also covers cli.py's own orchestration of how the bundle + gets assembled, which code_hash deliberately excludes.""" from quantlab.backtesting.result import load_previous_walk_forward_robustness exp_dir = tmp_path / "wf_experiment" exp_dir.mkdir() config = _wf_experiment_config() - _write_wf_artifacts(exp_dir, config) # old metadata.json has _FAKE_CODE_HASH + _write_wf_artifacts(exp_dir, config) # old metadata.json has _FAKE_GENERATOR_HASH fake_result = _FakeResult(config) - fake_result.metadata["code_hash"] = "a-completely-different-code-hash" + fake_result.metadata["generator_hash"] = "a-completely-different-generator-hash" robustness = load_previous_walk_forward_robustness( exp_dir, fake_result, # type: ignore[arg-type] @@ -349,7 +496,7 @@ def test_report_command_rejects_stale_walk_forward_when_code_hash_differs( assert "walk_forward_oos_metrics" not in fake_result.metadata -def test_report_command_rejects_stale_walk_forward_when_code_hash_missing( +def test_report_command_rejects_stale_walk_forward_when_generator_hash_missing( tmp_path: Path, ) -> None: from quantlab.backtesting.result import load_previous_walk_forward_robustness @@ -360,7 +507,7 @@ def test_report_command_rejects_stale_walk_forward_when_code_hash_missing( _write_wf_artifacts(exp_dir, config) fake_result = _FakeResult(config) - fake_result.metadata["code_hash"] = None + fake_result.metadata["generator_hash"] = None robustness = load_previous_walk_forward_robustness( exp_dir, fake_result, # type: ignore[arg-type] @@ -369,9 +516,14 @@ def test_report_command_rejects_stale_walk_forward_when_code_hash_missing( assert "walk_forward_oos_metrics" not in fake_result.metadata -def test_report_command_rejects_stale_walk_forward_when_git_commit_differs( +def test_report_command_reuses_walk_forward_when_git_commit_differs( tmp_path: Path, ) -> None: + """generator_hash already hashes current file contents (uncommitted + changes included), so it alone gives the guarantee needed here -- + a different git_commit (e.g. a rebase, or two checkouts of the exact + same tree state under different commit objects) must never refuse + reuse on its own once generator_hash matches.""" from quantlab.backtesting.result import load_previous_walk_forward_robustness exp_dir = tmp_path / "wf_experiment" @@ -385,26 +537,6 @@ def test_report_command_rejects_stale_walk_forward_when_git_commit_differs( exp_dir, fake_result, # type: ignore[arg-type] ) - assert robustness is None - assert "walk_forward_oos_metrics" not in fake_result.metadata - - -def test_report_command_reuses_walk_forward_when_git_commit_unavailable( - tmp_path: Path, -) -> None: - from quantlab.backtesting.result import load_previous_walk_forward_robustness - - exp_dir = tmp_path / "wf_experiment" - exp_dir.mkdir() - config = _wf_experiment_config() - _write_wf_artifacts(exp_dir, config) - - fake_result = _FakeResult(config) - fake_result.metadata["git_commit"] = None - robustness = load_previous_walk_forward_robustness( - exp_dir, - fake_result, # type: ignore[arg-type] - ) assert robustness is not None assert fake_result.metadata["walk_forward_oos_metrics"] == { "sharpe_ratio": 0.42, @@ -412,9 +544,16 @@ def test_report_command_reuses_walk_forward_when_git_commit_unavailable( } -def test_report_command_rejects_stale_walk_forward_when_tree_is_dirty( +def test_report_command_reuses_walk_forward_when_tree_is_dirty( tmp_path: Path, ) -> None: + """The exact bug this test guards against: `git status`/git_dirty cover + the *whole* repository, not just the files generator_hash is scoped + to, so an ordinarily-uncommitted development session (or an unrelated + change elsewhere in the repo) must never refuse a `report` + regeneration when config/data/generator_hash/dependencies are all + still identical -- generator_hash alone already gives that guarantee, + uncommitted changes included.""" from quantlab.backtesting.result import load_previous_walk_forward_robustness exp_dir = tmp_path / "wf_experiment" @@ -428,8 +567,11 @@ def test_report_command_rejects_stale_walk_forward_when_tree_is_dirty( exp_dir, fake_result, # type: ignore[arg-type] ) - assert robustness is None - assert "walk_forward_oos_metrics" not in fake_result.metadata + assert robustness is not None + assert fake_result.metadata["walk_forward_oos_metrics"] == { + "sharpe_ratio": 0.42, + "cagr": 0.05, + } def test_report_command_rejects_stale_walk_forward_when_dependencies_differ( @@ -547,6 +689,12 @@ def test_report_command_preserves_walk_forward_run_timestamp( def test_generate_report_preserves_walk_forward_artifacts( tmp_path: Path, ) -> None: + """`load_previous_walk_forward_robustness` reuse depends only on + config/data/generator_hash/dependency provenance, not on the ambient + repo's git-dirty state (see test_report_command_reuses_walk_forward_ + when_tree_is_dirty) -- this test needs no git-state pinning to be + deterministic regardless of whatever the checkout's own working tree + looks like during a test run.""" from quantlab.backtesting.result import save_with_walk_forward_reuse from quantlab.backtesting.runner import run_backtest_from_config @@ -557,9 +705,9 @@ def test_generate_report_preserves_walk_forward_artifacts( { "experiment_name": "wf_generate_report_experiment", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2020-10-27", }, @@ -660,6 +808,7 @@ def run_with_commission(commission_bps: float) -> list[pd.Series]: ) +@pytest.mark.slow def test_walk_forward_chains_accounting_state_across_fold_boundaries( monkeypatch: pytest.MonkeyPatch, ) -> None: @@ -673,9 +822,9 @@ def test_walk_forward_chains_accounting_state_across_fold_boundaries( { "experiment_name": "chain_test", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2021-06-01", }, @@ -752,6 +901,7 @@ def fake_weights_on_test( assert fold0_end < fold1_end # sanity: folds are in chronological order +@pytest.mark.slow def test_walk_forward_turnover_cap_chains_across_fold_boundaries( monkeypatch: pytest.MonkeyPatch, ) -> None: @@ -762,9 +912,9 @@ def test_walk_forward_turnover_cap_chains_across_fold_boundaries( { "experiment_name": "turnover_chain_test", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2021-06-01", }, @@ -826,6 +976,7 @@ def spy_run_accounting(all_weights: pd.DataFrame, *args: Any, **kwargs: Any) -> ) +@pytest.mark.slow def test_walk_forward_oos_curve_starts_flat_at_the_very_first_bar( monkeypatch: pytest.MonkeyPatch, ) -> None: @@ -836,9 +987,9 @@ def test_walk_forward_oos_curve_starts_flat_at_the_very_first_bar( { "experiment_name": "first_bar_flat_test", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2021-06-01", }, @@ -890,6 +1041,7 @@ def fake_weights_on_test( assert result.oos_returns.iloc[1] < 0.0, "the entry cost must show up on day 2" +@pytest.mark.slow def test_walk_forward_rejects_test_window_shorter_than_a_rebalance_cycle() -> None: from quantlab.validation.walk_forward import WalkForwardValidator @@ -900,9 +1052,9 @@ def test_walk_forward_rejects_test_window_shorter_than_a_rebalance_cycle() -> No { "experiment_name": "too_short_fold_test", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2021-06-01", }, @@ -936,9 +1088,9 @@ def test_walk_forward_fold_metrics_reflect_only_the_deployed_period() -> None: { "experiment_name": "aligned_fold_test", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2021-06-01", }, @@ -1039,9 +1191,9 @@ def test_holdout_split_ignores_benchmark_calendar() -> None: { "experiment_name": "test", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-11", "end_date": "2020-01-20", "frequency": "1d", @@ -1049,7 +1201,9 @@ def test_holdout_split_ignores_benchmark_calendar() -> None: "strategy": {"name": "buy_and_hold", "parameters": {}}, "portfolio": {"allocator": "equal_weight"}, "execution": {}, - "backtest": {"benchmark_symbol": "BENCH"}, + "backtest": { + "benchmark": {"symbol": "BENCH", "source": "csv", "calendar": "XNYS"} + }, "validation": {"method": "holdout", "test_ratio": 0.4}, "reproducibility": {"random_seed": 42}, } @@ -1087,9 +1241,9 @@ def test_walk_forward_windows_ignore_benchmark_calendar() -> None: { "experiment_name": "test", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-11", "end_date": "2020-02-09", "frequency": "1d", @@ -1101,7 +1255,9 @@ def test_walk_forward_windows_ignore_benchmark_calendar() -> None: # so a 5-bar test_window trivially contains one. "portfolio": {"allocator": "equal_weight", "rebalance_frequency": "daily"}, "execution": {}, - "backtest": {"benchmark_symbol": "BENCH"}, + "backtest": { + "benchmark": {"symbol": "BENCH", "source": "csv", "calendar": "XNYS"} + }, "validation": {"method": "walk_forward"}, "reproducibility": {"random_seed": 42}, } @@ -1128,7 +1284,13 @@ def test_stale_benchmark_and_holdout_artifacts_cleaned_up_on_resave( cfg_with = cfg_with.revalidated_copy( update={ "backtest": cfg_with.backtest.revalidated_copy( - update={"benchmark_symbol": "AAA"} + update={ + "benchmark": { + "symbol": "AAA", + "source": "csv", + "calendar": "XNYS", + } + } ) } ) @@ -1140,9 +1302,7 @@ def test_stale_benchmark_and_holdout_artifacts_cleaned_up_on_resave( cfg_without = cfg_with.revalidated_copy( update={ - "backtest": cfg_with.backtest.revalidated_copy( - update={"benchmark_symbol": None} - ), + "backtest": cfg_with.backtest.revalidated_copy(update={"benchmark": None}), "validation": cfg_with.validation.revalidated_copy( update={ "method": ValidationMethod.WALK_FORWARD, diff --git a/tests/unit/test_reporting_hardening.py b/tests/unit/test_reporting_hardening.py index 983d54c..03f6be0 100644 --- a/tests/unit/test_reporting_hardening.py +++ b/tests/unit/test_reporting_hardening.py @@ -34,9 +34,9 @@ def _config( { "experiment_name": "reporting_hardening", "data": { - "source": "csv", - "market_calendar": "XNYS", - "symbols": ["AAA"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2019-01-01", "end_date": "2021-12-31", "use_bundled_demo_data": demo_fallback, @@ -146,6 +146,61 @@ def test_robustness_tables_format_percentage_columns() -> None: assert "0.42" in rendered +def _sensitivity_frame() -> pd.DataFrame: + return pd.DataFrame( + { + "lookback_period": [60, 60, 120, 120], + "top_fraction": [0.3, 0.5, 0.3, 0.5], + "sharpe": [0.5, 0.8, 0.2, 0.6], + "cagr": [0.1, 0.15, 0.05, 0.12], + "max_drawdown": [-0.1, -0.12, -0.2, -0.15], + "turnover": [1.0, 1.0, 1.0, 1.0], + "num_trades": [10, 10, 10, 10], + "status": ["ok"] * 4, + "error": [None] * 4, + } + ) + + +def test_sensitivity_heatmap_chart_infers_swept_parameters() -> None: + """The two swept-parameter columns are whatever is left after excluding + the fixed metric/status columns every sensitivity table carries.""" + figure = charts.sensitivity_heatmap_chart(_sensitivity_frame()) + try: + assert figure.axes[0].get_xlabel() == "lookback_period" + assert figure.axes[0].get_ylabel() == "top_fraction" + finally: + figure.clear() + + +def test_sensitivity_heatmap_chart_rejects_ambiguous_columns() -> None: + sensitivity = pd.DataFrame( + {"a": [1], "b": [2], "c": [3], "sharpe": [0.5], "status": ["ok"]} + ) + with pytest.raises(ValueError, match="exactly two"): + charts.sensitivity_heatmap_chart(sensitivity) + + +def test_render_robustness_embeds_sensitivity_heatmap() -> None: + rendered = _render_robustness({"sensitivity": _sensitivity_frame()}) + assert ' None: + """A malformed sensitivity table (here, only one swept-parameter column) + must not take down the whole report — same resilience as the other + charts (see report_figures).""" + malformed = pd.DataFrame( + {"lookback_period": [60], "sharpe": [0.5], "status": ["ok"]} + ) + warnings: list[str] = [] + rendered = _render_robustness({"sensitivity": malformed}, warnings) + assert "Chart unavailable" in rendered + assert warnings + assert "60" in rendered # the raw table must still render + + def test_methodology_describes_volume_slippage_and_constraints() -> None: result: Any = SimpleNamespace( config=_config(volume_slippage=True), @@ -222,6 +277,61 @@ def test_html_report_shows_chart_placeholders() -> None: assert "Full-sample headline metrics" in rendered +def test_html_report_footer_claims_reproducibility_when_config_matches() -> None: + """A run built entirely through the config-driven factory (the ordinary + CLI/dashboard path) always has config_yaml_reflects_strategy/allocator + True, so its footer may state the bundle is reproducible from + config.yaml.""" + rendered = _result().to_html(figures={}) + assert "reproducible from config.yaml" in rendered + + +def test_html_report_footer_is_conditional_when_config_does_not_reflect_the_run() -> ( + None +): + """A direct-API run (docs/api.md) whose actual strategy object diverges + from config.yaml must not have its report footer unconditionally claim + the bundle is reproducible from config.yaml (see + BacktestEngine._build_metadata's config_yaml_reflects_strategy).""" + from quantlab.backtesting.engine import BacktestEngine + from quantlab.execution.execution_model import ExecutionModel + from quantlab.portfolio.allocator import EqualWeightAllocator + from quantlab.strategies.mean_reversion import MeanReversionStrategy + + data = make_ohlcv( + "AAA", + geometric_series(180, mu=0.0004, sigma=0.01, s0=100.0, seed=7), + start="2020-01-01", + ) + cfg = ExperimentConfig.from_dict( + { + "experiment_name": "footer_mismatch", + "data": { + "instruments": [{"symbol": "AAA", "source": "csv", "calendar": "XNYS"}], + "start_date": "2020-01-01", + "end_date": "2020-06-30", + }, + "strategy": { + "name": "mean_reversion", + "parameters": {"lookback_period": 252}, + }, + "portfolio": {"allocator": "equal_weight"}, + "backtest": {"initial_capital": 100_000}, + } + ) + result = BacktestEngine().run( + data, + MeanReversionStrategy(lookback_period=10), + EqualWeightAllocator(), + ExecutionModel.from_config(cfg.execution), + cfg, + ) + assert result.metadata["config_yaml_reflects_strategy"] is False + rendered = result.to_html(figures={}) + assert "reproducible from config.yaml given the same code" not in rendered + assert "config.yaml in this bundle may not exactly reflect" in rendered + + def test_data_quality_section_includes_counts_without_warnings() -> None: rendered = _render_data_quality( { diff --git a/tests/unit/test_strategies_hardening.py b/tests/unit/test_strategies_hardening.py index 29d8b25..d303fe2 100644 --- a/tests/unit/test_strategies_hardening.py +++ b/tests/unit/test_strategies_hardening.py @@ -47,11 +47,12 @@ def _config( { "experiment_name": "strategy_hardening", "data": { - "source": "csv", - "symbols": symbols or ["AAA", "BBB"], + "instruments": [ + {"symbol": symbol, "source": "csv", "calendar": "XNYS"} + for symbol in (symbols or ["AAA", "BBB"]) + ], "start_date": "2020-01-01", "end_date": "2021-01-01", - "market_calendar": "XNYS", }, "strategy": {"name": strategy, "parameters": dict(parameters)}, "portfolio": dict(portfolio or {}), diff --git a/tests/unit/test_validation.py b/tests/unit/test_validation.py index b60ad29..5c6fac1 100644 --- a/tests/unit/test_validation.py +++ b/tests/unit/test_validation.py @@ -2,21 +2,68 @@ from __future__ import annotations +import math +from pathlib import Path +from typing import Any, TypedDict + import numpy as np import pandas as pd +import pytest from tests.conftest import geometric_series, make_ohlcv from quantlab.config import ExperimentConfig +from quantlab.exceptions import InvalidConfigurationError +from quantlab.risk import metrics as M +from quantlab.risk.stress import scale_costs from quantlab.validation.bootstrap import bootstrap_returns from quantlab.validation.parameter_sensitivity import ( run_parameter_sensitivity, + run_walk_forward_parameter_sensitivity, sensitivity_heatmap_data, ) from quantlab.validation.robustness import ( monte_carlo_permutation, run_stress_tests, + run_walk_forward_stress_tests, +) +from quantlab.validation.walk_forward import ( + WalkForwardValidator, + resolve_walk_forward_windows, ) -from quantlab.validation.walk_forward import WalkForwardValidator + + +class _WalkForwardWindows(TypedDict): + """Precise keyword types for ``**windows`` call-site unpacking below. + + A plain ``dict[str, object]`` erases each key's own type, so a type + checker cannot verify ``**windows`` against ``run()``'s per-parameter + types (``train_window: int``, ``expanding: bool``, ...) — a TypedDict + keeps each field's real type across the unpack. + """ + + train_window: int + validation_window: int + test_window: int + expanding: bool + + +class _WalkForwardRunKwargs(TypedDict): + """Like :class:`_WalkForwardWindows`, plus ``parameter_grid``.""" + + parameter_grid: dict[str, list[int]] + train_window: int + validation_window: int + test_window: int + expanding: bool + + +class _SensitivitySweepKwargs(TypedDict): + """Precise keyword types for ``**sweep_kwargs`` call-site unpacking.""" + + parameter_x: str + values_x: list[Any] + parameter_y: str + values_y: list[Any] def _panel(n: int = 900) -> pd.DataFrame: @@ -27,16 +74,85 @@ def _panel(n: int = 900) -> pd.DataFrame: return pd.concat(frames, ignore_index=True) +def _mean_reverting_prices( + n: int, seed: int, phi: float = 0.85, scale: float = 0.03 +) -> np.ndarray: + """AR(1) log-price deviations around a stationary mean. + + ``phi < 1`` mean-reverts (same construction as + ``test_features.py::test_half_life_detects_mean_reversion``), giving + ``mean_reversion`` a genuine, tradeable edge — unlike the plain GBM from + ``geometric_series`` used elsewhere in this file. + """ + rng = np.random.default_rng(seed) + x = np.zeros(n) + for t in range(1, n): + x[t] = phi * x[t - 1] + rng.normal(0, scale) + return 100.0 * np.exp(x) + + +def _cost_sensitive_panel(n: int = 500) -> pd.DataFrame: + frames = [ + make_ohlcv("AAA", _mean_reverting_prices(n, seed=11), start="2018-01-01"), + make_ohlcv("BBB", _mean_reverting_prices(n, seed=12), start="2018-01-01"), + ] + return pd.concat(frames, ignore_index=True) + + +def _cost_sensitive_config(commission_bps: float = 50.0) -> ExperimentConfig: + return ExperimentConfig.from_dict( + { + "experiment_name": "cost_sensitivity", + "data": { + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + {"symbol": "BBB", "source": "csv", "calendar": "XNYS"}, + ], + "start_date": "2018-01-01", + "end_date": "2021-12-31", + }, + "strategy": { + "name": "mean_reversion", + "parameters": { + "lookback_period": 10, + "entry_zscore": 1.0, + "exit_zscore": 0.1, + }, + }, + "portfolio": {"allocator": "equal_weight", "rebalance_frequency": "daily"}, + "execution": { + "commission_bps": commission_bps, + "spread_bps": 0.0, + "slippage_bps": 0.0, + }, + "backtest": {"initial_capital": 100_000}, + "validation": { + "method": "walk_forward", + "optimization_metric": "sharpe", + "train_window": 150, + "validation_window": 60, + "test_window": 60, + # Pinned explicitly: run_walk_forward_stress_tests() resolves + # its grid from this config (parameter_grid_for_config), not + # from an argument, so it must match the grid used below. + "parameter_grid": {"entry_zscore": [0.5, 3.0]}, + }, + } + ) + + def _config() -> ExperimentConfig: return ExperimentConfig.from_dict( { "experiment_name": "val", "data": { - "source": "csv", - "symbols": ["AAA", "BBB", "CCC"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + {"symbol": "BBB", "source": "csv", "calendar": "XNYS"}, + {"symbol": "CCC", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2018-01-01", "end_date": "2021-12-31", - "market_calendar": "XNYS", }, "strategy": { "name": "cross_sectional_momentum", @@ -52,12 +168,35 @@ def _config() -> ExperimentConfig: "spread_bps": 3.0, "slippage_bps": 2.0, }, - "backtest": {"initial_capital": 100_000, "benchmark_symbol": "AAA"}, + "backtest": { + "initial_capital": 100_000, + "benchmark": {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + }, "validation": {"optimization_metric": "sharpe"}, } ) +def _config_with_grid(grid: dict[str, list[Any]]) -> ExperimentConfig: + """`_config()` with an explicit `validation.parameter_grid`. + + `run_walk_forward_stress_tests()` verifies a passed-in `wf_baseline` + was actually built with `parameter_grid_for_config(config)`'s own + grid -- a baseline built with some other explicit grid (as several + tests below do, for a cheaper/faster walk-forward run) must have its + config configure that same grid, not rely on the strategy's default. + """ + config = _config() + return config.revalidated_copy( + update={ + "validation": config.validation.revalidated_copy( + update={"method": "walk_forward", "parameter_grid": grid} + ) + } + ) + + +@pytest.mark.slow def test_walk_forward_produces_oos_curve() -> None: data = _panel() validator = WalkForwardValidator(_config()) @@ -78,6 +217,595 @@ def test_walk_forward_produces_oos_curve() -> None: assert "test_sharpe" in table.columns +@pytest.mark.slow +def test_walk_forward_run_reports_fold_progress() -> None: + """on_progress must fire once before the first unit of work (done=0) and + once per completed unit thereafter — one per candidate considered on a + fold's validation block plus one more for that fold's out-of-sample + weights, ending at (total_units, total_units). Not one tick per whole + fold: a fold's own grid search can take long enough that fold-level + ticks alone left the dashboard's live pace estimate with too few, too + lumpy data points to track a real, sustained slowdown across an + expanding walk-forward's later, bigger folds.""" + data = _panel() + validator = WalkForwardValidator(_config()) + progress_calls: list[tuple[int, int]] = [] + grid = {"lookback_period": [60, 120]} + result = validator.run( + data, + parameter_grid=grid, + train_window=300, + validation_window=120, + test_window=120, + expanding=True, + on_progress=lambda done, total: progress_calls.append((done, total)), + ) + n_folds = len(result.folds) + assert n_folds >= 1 + total_units = n_folds * (len(grid["lookback_period"]) + 1) + assert progress_calls[0] == (0, total_units) + assert progress_calls[-1] == (total_units, total_units) + assert [done for done, _ in progress_calls] == list(range(total_units + 1)) + assert all(total == total_units for _, total in progress_calls) + + +@pytest.mark.slow +def test_walk_forward_run_resumes_from_a_checkpoint_and_matches_a_fresh_run( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """An interrupted run's checkpoint, resumed, must produce exactly the + same WalkForwardResult as an uninterrupted run — resuming is not an + approximation, it picks up the identical remaining computation.""" + data = _panel() + grid = {"lookback_period": [60, 120]} + checkpoint_path = tmp_path / "checkpoint.pkl" + + fresh = WalkForwardValidator(_config()).run( + data, + parameter_grid=grid, + train_window=300, + validation_window=120, + test_window=120, + expanding=True, + ) + assert len(fresh.folds) >= 2, "need at least 2 folds to interrupt after the 1st" + + real_select = WalkForwardValidator._select_on_validation + starts = {"n": 0} + + def _flaky_select(self: WalkForwardValidator, *args: object, **kwargs: object): # type: ignore[no-untyped-def] + starts["n"] += 1 + if starts["n"] == 2: + raise RuntimeError("simulated interruption") + return real_select(self, *args, **kwargs) # type: ignore[arg-type] + + monkeypatch.setattr(WalkForwardValidator, "_select_on_validation", _flaky_select) + with pytest.raises(RuntimeError, match="simulated interruption"): + WalkForwardValidator(_config()).run( + data, + parameter_grid=grid, + train_window=300, + validation_window=120, + test_window=120, + expanding=True, + checkpoint_path=checkpoint_path, + ) + assert checkpoint_path.is_file() + monkeypatch.undo() + + resumed = WalkForwardValidator(_config()).run( + data, + parameter_grid=grid, + train_window=300, + validation_window=120, + test_window=120, + expanding=True, + checkpoint_path=checkpoint_path, + ) + assert not checkpoint_path.is_file() # cleared after completing successfully + assert resumed.oos_result is not None + assert fresh.oos_result is not None + pd.testing.assert_series_equal(resumed.oos_result.returns, fresh.oos_result.returns) + assert [f.best_params for f in resumed.folds] == [ + f.best_params for f in fresh.folds + ] + + +@pytest.mark.slow +def test_walk_forward_run_refuses_a_checkpoint_whose_window_does_not_match( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """A checkpoint whose fold_windows entry has drifted from what this + run's own prepared.windows actually are (right list length, wrong + content) must never be resumed from -- a length-only check would accept + it and silently stitch the wrong fold's parameters/targets into the OOS + curve. Content, not just count, must match.""" + from quantlab.validation.checkpoint import ( + compute_provenance, + load_checkpoint, + save_checkpoint, + ) + from quantlab.validation.splits import WalkForwardWindow + + data = _panel() + grid = {"lookback_period": [60, 120]} + checkpoint_path = tmp_path / "checkpoint.pkl" + windows_kwargs: _WalkForwardWindows = { + "train_window": 300, + "validation_window": 120, + "test_window": 120, + "expanding": True, + } + + fresh = WalkForwardValidator(_config()).run( + data, parameter_grid=grid, **windows_kwargs + ) + assert len(fresh.folds) >= 2, "need at least 2 folds to interrupt after the 1st" + + real_select = WalkForwardValidator._select_on_validation + starts = {"n": 0} + + def _flaky_select(self: WalkForwardValidator, *args: object, **kwargs: object): # type: ignore[no-untyped-def] + starts["n"] += 1 + if starts["n"] == 2: + raise RuntimeError("simulated interruption") + return real_select(self, *args, **kwargs) # type: ignore[arg-type] + + monkeypatch.setattr(WalkForwardValidator, "_select_on_validation", _flaky_select) + with pytest.raises(RuntimeError, match="simulated interruption"): + WalkForwardValidator(_config()).run( + data, + parameter_grid=grid, + checkpoint_path=checkpoint_path, + **windows_kwargs, + ) + monkeypatch.undo() + assert checkpoint_path.is_file() + + provenance = compute_provenance( + _config(), + data, + train_window=300, + validation_window=120, + test_window=120, + expanding=True, + execution_delay=0, + parameter_grid={"lookback_period": [60, 120]}, + ) + loaded = load_checkpoint(checkpoint_path, provenance) + assert loaded is not None + (fold_windows, fold_parameters, fold_scores, target_pieces), progress = loaded + real_window = fold_windows[0] + corrupted_window = WalkForwardWindow( + fold=real_window.fold, + train=real_window.train, + validation=real_window.validation, + test=real_window.test[:-1], # a genuinely different test block + ) + save_checkpoint( + checkpoint_path, + provenance, + ([corrupted_window], fold_parameters, fold_scores, target_pieces), + progress, + ) + + resumed = WalkForwardValidator(_config()).run( + data, + parameter_grid=grid, + checkpoint_path=checkpoint_path, + **windows_kwargs, + ) + assert resumed.oos_result is not None + assert fresh.oos_result is not None + pd.testing.assert_series_equal(resumed.oos_result.returns, fresh.oos_result.returns) + + +@pytest.mark.slow +def test_walk_forward_run_refuses_a_checkpoint_with_a_garbage_target_frame( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """A checkpointed target-weights frame with the wrong columns and a + date from a completely different era (e.g. 1900) passes a bare + isinstance(pd.DataFrame) check but is obviously not this fold's real + target weights -- content, not just Python type, must be verified.""" + from quantlab.validation.checkpoint import ( + compute_provenance, + load_checkpoint, + save_checkpoint, + ) + + data = _panel() + grid = {"lookback_period": [60, 120]} + checkpoint_path = tmp_path / "checkpoint.pkl" + windows_kwargs: _WalkForwardWindows = { + "train_window": 300, + "validation_window": 120, + "test_window": 120, + "expanding": True, + } + + fresh = WalkForwardValidator(_config()).run( + data, parameter_grid=grid, **windows_kwargs + ) + assert len(fresh.folds) >= 2, "need at least 2 folds to interrupt after the 1st" + + real_select = WalkForwardValidator._select_on_validation + starts = {"n": 0} + + def _flaky_select(self: WalkForwardValidator, *args: object, **kwargs: object): # type: ignore[no-untyped-def] + starts["n"] += 1 + if starts["n"] == 2: + raise RuntimeError("simulated interruption") + return real_select(self, *args, **kwargs) # type: ignore[arg-type] + + monkeypatch.setattr(WalkForwardValidator, "_select_on_validation", _flaky_select) + with pytest.raises(RuntimeError, match="simulated interruption"): + WalkForwardValidator(_config()).run( + data, + parameter_grid=grid, + checkpoint_path=checkpoint_path, + **windows_kwargs, + ) + monkeypatch.undo() + assert checkpoint_path.is_file() + + provenance = compute_provenance( + _config(), + data, + train_window=300, + validation_window=120, + test_window=120, + expanding=True, + execution_delay=0, + parameter_grid={"lookback_period": [60, 120]}, + ) + loaded = load_checkpoint(checkpoint_path, provenance) + assert loaded is not None + (fold_windows, fold_parameters, fold_scores, target_pieces), progress = loaded + garbage = pd.DataFrame({"WRONG": [1.0]}, index=pd.to_datetime(["1900-01-01"])) + corrupted_targets = [garbage, *target_pieces[1:]] + save_checkpoint( + checkpoint_path, + provenance, + (fold_windows, fold_parameters, fold_scores, corrupted_targets), + progress, + ) + + resumed = WalkForwardValidator(_config()).run( + data, + parameter_grid=grid, + checkpoint_path=checkpoint_path, + **windows_kwargs, + ) + assert resumed.oos_result is not None + assert fresh.oos_result is not None + pd.testing.assert_series_equal(resumed.oos_result.returns, fresh.oos_result.returns) + + +@pytest.mark.slow +def test_walk_forward_run_refuses_a_checkpoint_with_an_incomplete_target_frame( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """A checkpointed target-weights frame missing one date from its own + fold's test window is a genuine *subset* -- right columns, only + in-window dates -- so a subset-only index check (``index <= + expected``) would wrongly accept it. The stitched OOS curve needs every + date in the window, so a strictly incomplete frame must be rejected + too, not only one carrying foreign or extra dates.""" + from quantlab.validation.checkpoint import ( + compute_provenance, + load_checkpoint, + save_checkpoint, + ) + + data = _panel() + grid = {"lookback_period": [60, 120]} + checkpoint_path = tmp_path / "checkpoint.pkl" + windows_kwargs: _WalkForwardWindows = { + "train_window": 300, + "validation_window": 120, + "test_window": 120, + "expanding": True, + } + + fresh = WalkForwardValidator(_config()).run( + data, parameter_grid=grid, **windows_kwargs + ) + assert len(fresh.folds) >= 2, "need at least 2 folds to interrupt after the 1st" + + real_select = WalkForwardValidator._select_on_validation + starts = {"n": 0} + + def _flaky_select(self: WalkForwardValidator, *args: object, **kwargs: object): # type: ignore[no-untyped-def] + starts["n"] += 1 + if starts["n"] == 2: + raise RuntimeError("simulated interruption") + return real_select(self, *args, **kwargs) # type: ignore[arg-type] + + monkeypatch.setattr(WalkForwardValidator, "_select_on_validation", _flaky_select) + with pytest.raises(RuntimeError, match="simulated interruption"): + WalkForwardValidator(_config()).run( + data, + parameter_grid=grid, + checkpoint_path=checkpoint_path, + **windows_kwargs, + ) + monkeypatch.undo() + assert checkpoint_path.is_file() + + provenance = compute_provenance( + _config(), + data, + train_window=300, + validation_window=120, + test_window=120, + expanding=True, + execution_delay=0, + parameter_grid={"lookback_period": [60, 120]}, + ) + loaded = load_checkpoint(checkpoint_path, provenance) + assert loaded is not None + (fold_windows, fold_parameters, fold_scores, target_pieces), progress = loaded + incomplete = target_pieces[0].iloc[1:] + corrupted_targets = [incomplete, *target_pieces[1:]] + save_checkpoint( + checkpoint_path, + provenance, + (fold_windows, fold_parameters, fold_scores, corrupted_targets), + progress, + ) + + resumed = WalkForwardValidator(_config()).run( + data, + parameter_grid=grid, + checkpoint_path=checkpoint_path, + **windows_kwargs, + ) + assert resumed.oos_result is not None + assert fresh.oos_result is not None + pd.testing.assert_series_equal(resumed.oos_result.returns, fresh.oos_result.returns) + + +@pytest.mark.slow +def test_walk_forward_run_refuses_a_checkpoint_with_a_non_grid_parameter( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """A checkpointed parameter dict that isn't actually one of this run's + own grid candidates (e.g. left over from a since-changed grid) passes a + bare isinstance(dict) check but could only have come from a stale or + unrelated checkpoint.""" + from quantlab.validation.checkpoint import ( + compute_provenance, + load_checkpoint, + save_checkpoint, + ) + + data = _panel() + grid = {"lookback_period": [60, 120]} + checkpoint_path = tmp_path / "checkpoint.pkl" + windows_kwargs: _WalkForwardWindows = { + "train_window": 300, + "validation_window": 120, + "test_window": 120, + "expanding": True, + } + + fresh = WalkForwardValidator(_config()).run( + data, parameter_grid=grid, **windows_kwargs + ) + assert len(fresh.folds) >= 2, "need at least 2 folds to interrupt after the 1st" + + real_select = WalkForwardValidator._select_on_validation + starts = {"n": 0} + + def _flaky_select(self: WalkForwardValidator, *args: object, **kwargs: object): # type: ignore[no-untyped-def] + starts["n"] += 1 + if starts["n"] == 2: + raise RuntimeError("simulated interruption") + return real_select(self, *args, **kwargs) # type: ignore[arg-type] + + monkeypatch.setattr(WalkForwardValidator, "_select_on_validation", _flaky_select) + with pytest.raises(RuntimeError, match="simulated interruption"): + WalkForwardValidator(_config()).run( + data, + parameter_grid=grid, + checkpoint_path=checkpoint_path, + **windows_kwargs, + ) + monkeypatch.undo() + assert checkpoint_path.is_file() + + provenance = compute_provenance( + _config(), + data, + train_window=300, + validation_window=120, + test_window=120, + expanding=True, + execution_delay=0, + parameter_grid={"lookback_period": [60, 120]}, + ) + loaded = load_checkpoint(checkpoint_path, provenance) + assert loaded is not None + (fold_windows, fold_parameters, fold_scores, target_pieces), progress = loaded + # 999 was never in the grid [60, 120]. + corrupted_parameters = [{"lookback_period": 999}, *fold_parameters[1:]] + save_checkpoint( + checkpoint_path, + provenance, + (fold_windows, corrupted_parameters, fold_scores, target_pieces), + progress, + ) + + resumed = WalkForwardValidator(_config()).run( + data, + parameter_grid=grid, + checkpoint_path=checkpoint_path, + **windows_kwargs, + ) + assert resumed.oos_result is not None + assert fresh.oos_result is not None + pd.testing.assert_series_equal(resumed.oos_result.returns, fresh.oos_result.returns) + + +@pytest.mark.slow +def test_walk_forward_run_does_not_reuse_a_checkpoint_from_a_different_config( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """A checkpoint written by one config must not be silently reused by a + later run against a different one sharing the same checkpoint path — + every candidate must actually be (re-)computed, not skipped.""" + data = _panel() + checkpoint_path = tmp_path / "checkpoint.pkl" + + # Interrupt after the 1st fold completes, so there is something on disk + # to (not) reuse below. + real_select = WalkForwardValidator._select_on_validation + starts = {"n": 0} + + def _flaky_select(self: WalkForwardValidator, *args: object, **kwargs: object): # type: ignore[no-untyped-def] + starts["n"] += 1 + if starts["n"] == 2: + raise RuntimeError("simulated interruption") + return real_select(self, *args, **kwargs) # type: ignore[arg-type] + + monkeypatch.setattr(WalkForwardValidator, "_select_on_validation", _flaky_select) + with pytest.raises(RuntimeError, match="simulated interruption"): + WalkForwardValidator(_config()).run( + data, + parameter_grid={"lookback_period": [60, 120]}, + train_window=300, + validation_window=120, + test_window=120, + expanding=True, + checkpoint_path=checkpoint_path, + ) + assert checkpoint_path.is_file() + monkeypatch.undo() + + calls = {"n": 0} + real_select2 = WalkForwardValidator._select_on_validation + + def _counting_select(self: WalkForwardValidator, *args: object, **kwargs: object): # type: ignore[no-untyped-def] + calls["n"] += 1 + return real_select2(self, *args, **kwargs) # type: ignore[arg-type] + + monkeypatch.setattr(WalkForwardValidator, "_select_on_validation", _counting_select) + # A different grid: same checkpoint path, different provenance. + different_config = _config() + result = WalkForwardValidator(different_config).run( + data, + parameter_grid={"lookback_period": [60, 90, 120]}, + train_window=300, + validation_window=120, + test_window=120, + expanding=True, + checkpoint_path=checkpoint_path, + ) + # Every fold was actually selected on, not skipped as "already done". + assert calls["n"] == len(result.folds) + + +@pytest.mark.slow +def test_walk_forward_oos_result_is_a_coherent_backtest_result() -> None: + """`oos_result` must be a genuine BacktestResult built from the stitched + OOS series, reusing the same trade-log/benchmark/metrics pipeline as a + single backtest, so dashboard/report rendering works on it unchanged.""" + data = _panel() + validator = WalkForwardValidator(_config()) + result = validator.run( + data, + parameter_grid={"lookback_period": [60, 120]}, + train_window=300, + validation_window=120, + test_window=120, + expanding=True, + ) + + oos = result.oos_result + assert oos is not None + assert oos.config is validator.base_config + # The BacktestResult's own series must be exactly the stitched OOS series. + assert oos.returns.equals(result.oos_returns) + assert oos.equity_curve.equals(result.oos_equity) + assert list(oos.returns.index) == list(oos.equity_curve.index) + + for key in ("sharpe_ratio", "total_return", "cagr", "max_drawdown"): + assert np.isfinite(oos.metrics[key]) + + # cross_sectional_momentum with monthly rebalancing over multiple folds + # must produce real trades, not an empty placeholder trade log. + assert len(oos.trades) > 0 + assert set(oos.weights.columns) == set(validator.base_config.symbols) + assert oos.target_weights is not None + assert set(oos.target_weights.columns) == set(validator.base_config.symbols) + assert oos.gross_returns is not None + assert oos.gross_equity is not None + + assert oos.metadata["code_hash"] + assert oos.metadata["data_hash"] + assert oos.metadata["walk_forward_execution_delay"] == 0 + + +def test_walk_forward_oos_result_is_none_without_any_fold() -> None: + """No fold fits the requested windows in the available history, so + there is no OOS series to build a BacktestResult from.""" + data = _panel() + validator = WalkForwardValidator(_config()) + result = validator.run( + data, + parameter_grid={}, + train_window=10_000, + validation_window=120, + test_window=120, + expanding=True, + ) + + assert result.folds == [] + assert result.oos_result is None + + +@pytest.mark.slow +def test_walk_forward_execution_delay_changes_the_oos_series() -> None: + """execution_delay must be re-run through the whole selection process + (not just rescale the final numbers): it feeds every per-fold candidate + evaluation via `_weights_for_window`, so a delayed run's OOS series + should differ from an undelayed one for a strategy that actually trades.""" + data = _panel() + base_kwargs: _WalkForwardRunKwargs = { + "parameter_grid": {"lookback_period": [60, 120]}, + "train_window": 300, + "validation_window": 120, + "test_window": 120, + "expanding": True, + } + undelayed = WalkForwardValidator(_config()).run(data, **base_kwargs) + delayed = WalkForwardValidator(_config()).run( + data, **base_kwargs, execution_delay=1 + ) + + assert undelayed.oos_result is not None + assert delayed.oos_result is not None + assert delayed.oos_result.metadata["walk_forward_execution_delay"] == 1 + assert not delayed.oos_result.returns.equals(undelayed.oos_result.returns) + + +@pytest.mark.parametrize("bad_delay", [-1, True, 1.5]) +def test_walk_forward_run_rejects_invalid_execution_delay(bad_delay: object) -> None: + data = _panel() + validator = WalkForwardValidator(_config()) + with pytest.raises(InvalidConfigurationError, match="execution_delay"): + validator.run( + data, + parameter_grid={}, + train_window=300, + validation_window=120, + test_window=120, + execution_delay=bad_delay, # type: ignore[arg-type] + ) + + +@pytest.mark.slow def test_parameter_sensitivity_grid() -> None: data = _panel() sens = run_parameter_sensitivity( @@ -94,6 +822,969 @@ def test_parameter_sensitivity_grid() -> None: assert heat.shape == (2, 2) +def test_parameter_sensitivity_rejects_a_boolean_parameter_name() -> None: + """long_short is a structural switch (default False) — sweeping it + changes whether bottom_fraction even matters, so it must be rejected + the same way an unknown parameter name is, for both the plain and + walk-forward-aware sensitivity sweeps.""" + data = _panel() + for sweep in (run_parameter_sensitivity, run_walk_forward_parameter_sensitivity): + with pytest.raises(ValueError, match="Unknown or unsweepable"): + sweep( + data, + _config(), + parameter_x="lookback_period", + values_x=[60, 120], + parameter_y="long_short", + values_y=[True, False], + ) + + +def test_parameter_sensitivity_rejects_boolean_candidate_values() -> None: + """Even a numeric-looking parameter must reject boolean candidate + values — Python's bool is an int subclass, so True/False could + otherwise slip through undetected as 1/0.""" + data = _panel() + for sweep in (run_parameter_sensitivity, run_walk_forward_parameter_sensitivity): + with pytest.raises(ValueError, match="boolean"): + sweep( + data, + _config(), + parameter_x="lookback_period", + values_x=[True, False], + parameter_y="top_fraction", + values_y=[0.3, 0.5], + ) + + +@pytest.mark.slow +def test_run_walk_forward_stress_tests_reselects_parameters_under_higher_costs() -> ( + None +): + """The methodological point of the whole process-level/returns-level + split: a Walk-forward mode stress scenario must genuinely re-run + selection, not rescale a fixed baseline's weights. entry_zscore=0.5 + trades far more often than 3.0 on this mean-reverting panel, so it must + lose ground once commission is stressed 5x — and the stress-test + function's own numbers must come from that re-selected run.""" + data = _cost_sensitive_panel() + config = _cost_sensitive_config(commission_bps=50.0) + grid = {"entry_zscore": [0.5, 3.0]} + windows: _WalkForwardWindows = { + "train_window": 150, + "validation_window": 60, + "test_window": 60, + "expanding": True, + } + + wf_baseline = WalkForwardValidator(config).run(data, parameter_grid=grid, **windows) + assert wf_baseline.oos_result is not None + baseline_choices = [fold.best_params["entry_zscore"] for fold in wf_baseline.folds] + # The high-turnover parameter must win at least one fold at baseline cost + # — otherwise there is nothing for higher costs to knock it away from. + assert 0.5 in baseline_choices + + x5_config = scale_costs(config, commission_mult=5.0) + wf_x5 = WalkForwardValidator(x5_config).run(data, parameter_grid=grid, **windows) + assert wf_x5.oos_result is not None + x5_choices = [fold.best_params["entry_zscore"] for fold in wf_x5.folds] + + # The core assertion: re-running walk-forward selection under 5x + # commission actually changes which parameter wins on at least one fold. + assert x5_choices != baseline_choices + assert x5_choices.count(0.5) < baseline_choices.count(0.5) + + # run_walk_forward_stress_tests's own "commission x5" row must be derived + # from exactly this re-selected run, not from the baseline's fixed weights. + stress = run_walk_forward_stress_tests(data, config, wf_baseline) + row = stress.loc[stress["scenario"] == "commission x5"].iloc[0] + expected_sharpe = M.sharpe_ratio( + wf_x5.oos_result.returns, config.risk_free_rate, config.periods_per_year + ) + assert row["sharpe"] == pytest.approx(expected_sharpe) + assert row["status"] == "ok" + + +@pytest.mark.slow +def test_run_with_weight_cache_matches_plain_run() -> None: + """run_with_weight_cache() must select the same winners and produce the + same OOS series as run() for identical inputs — the cache is a + by-product of the same computation, not a different one.""" + data = _cost_sensitive_panel() + config = _cost_sensitive_config(commission_bps=50.0) + grid = {"entry_zscore": [0.5, 3.0]} + windows: _WalkForwardWindows = { + "train_window": 150, + "validation_window": 60, + "test_window": 60, + "expanding": True, + } + + plain = WalkForwardValidator(config).run(data, parameter_grid=grid, **windows) + cached, _weight_cache = WalkForwardValidator(config).run_with_weight_cache( + data, parameter_grid=grid, **windows + ) + + assert plain.oos_result is not None + assert cached.oos_result is not None + assert [f.best_params for f in cached.folds] == [f.best_params for f in plain.folds] + pd.testing.assert_series_equal(cached.oos_result.returns, plain.oos_result.returns) + + +@pytest.mark.slow +def test_run_with_weight_cache_resumes_from_a_checkpoint_and_matches_a_fresh_run( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """Same guarantee as :func:`test_walk_forward_run_resumes_from_a_checkpoint_ + and_matches_a_fresh_run`, for run_with_weight_cache() specifically — this is + the method run_walk_forward_stress_tests() relies on to avoid rebuilding + its weight cache from scratch on resume, so it must be independently + resumable and bit-for-bit reproducible on its own.""" + data = _cost_sensitive_panel() + config = _cost_sensitive_config(commission_bps=50.0) + grid = {"entry_zscore": [0.5, 3.0]} + windows: _WalkForwardWindows = { + "train_window": 150, + "validation_window": 60, + "test_window": 60, + "expanding": True, + } + checkpoint_path = tmp_path / "checkpoint.pkl" + + fresh, _fresh_cache = WalkForwardValidator(config).run_with_weight_cache( + data, parameter_grid=grid, **windows + ) + assert len(fresh.folds) >= 2, "need at least 2 folds to interrupt after the 1st" + + real_capture = WalkForwardValidator._select_and_capture + starts = {"n": 0} + + def _flaky_capture(self: WalkForwardValidator, *args: object, **kwargs: object): # type: ignore[no-untyped-def] + starts["n"] += 1 + if starts["n"] == 2: + raise RuntimeError("simulated interruption") + return real_capture(self, *args, **kwargs) # type: ignore[arg-type] + + monkeypatch.setattr(WalkForwardValidator, "_select_and_capture", _flaky_capture) + with pytest.raises(RuntimeError, match="simulated interruption"): + WalkForwardValidator(config).run_with_weight_cache( + data, parameter_grid=grid, checkpoint_path=checkpoint_path, **windows + ) + assert checkpoint_path.is_file() + monkeypatch.undo() + + resumed, _resumed_cache = WalkForwardValidator(config).run_with_weight_cache( + data, parameter_grid=grid, checkpoint_path=checkpoint_path, **windows + ) + assert not checkpoint_path.is_file() + assert resumed.oos_result is not None + assert fresh.oos_result is not None + pd.testing.assert_series_equal(resumed.oos_result.returns, fresh.oos_result.returns) + assert [f.best_params for f in resumed.folds] == [ + f.best_params for f in fresh.folds + ] + + +@pytest.mark.slow +def test_run_with_weight_cache_refuses_a_checkpoint_with_a_mismatched_candidate_cache( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """Same guarantee as :func:`test_walk_forward_run_refuses_a_checkpoint_ + whose_window_does_not_match`, for run_with_weight_cache()'s own 5-list + state: a fold's cached-candidates entry with the wrong number of + candidates (stale from a different parameter_grid) must never be + resumed from -- only a length-only list-of-lists check would miss this, + since the outer list count alone stays correct.""" + from quantlab.validation.checkpoint import ( + compute_provenance, + load_checkpoint, + save_checkpoint, + ) + + data = _cost_sensitive_panel() + config = _cost_sensitive_config(commission_bps=50.0) + grid = {"entry_zscore": [0.5, 3.0]} + windows: _WalkForwardWindows = { + "train_window": 150, + "validation_window": 60, + "test_window": 60, + "expanding": True, + } + checkpoint_path = tmp_path / "checkpoint.pkl" + + fresh, _fresh_cache = WalkForwardValidator(config).run_with_weight_cache( + data, parameter_grid=grid, **windows + ) + assert len(fresh.folds) >= 2, "need at least 2 folds to interrupt after the 1st" + + real_capture = WalkForwardValidator._select_and_capture + starts = {"n": 0} + + def _flaky_capture(self: WalkForwardValidator, *args: object, **kwargs: object): # type: ignore[no-untyped-def] + starts["n"] += 1 + if starts["n"] == 2: + raise RuntimeError("simulated interruption") + return real_capture(self, *args, **kwargs) # type: ignore[arg-type] + + monkeypatch.setattr(WalkForwardValidator, "_select_and_capture", _flaky_capture) + with pytest.raises(RuntimeError, match="simulated interruption"): + WalkForwardValidator(config).run_with_weight_cache( + data, parameter_grid=grid, checkpoint_path=checkpoint_path, **windows + ) + monkeypatch.undo() + assert checkpoint_path.is_file() + + provenance = compute_provenance( + config, + data, + train_window=150, + validation_window=60, + test_window=60, + expanding=True, + execution_delay=0, + parameter_grid={"entry_zscore": [0.5, 3.0]}, + ) + loaded = load_checkpoint(checkpoint_path, provenance) + assert loaded is not None + (windows_l, parameters, scores, targets, cached_candidates), progress = loaded + # Drop one cached candidate from the first fold -- stale as if this + # cache had been built against a smaller grid. + corrupted_cache = [cached_candidates[0][:-1], *cached_candidates[1:]] + save_checkpoint( + checkpoint_path, + provenance, + (windows_l, parameters, scores, targets, corrupted_cache), + progress, + ) + + resumed, _resumed_cache = WalkForwardValidator(config).run_with_weight_cache( + data, parameter_grid=grid, checkpoint_path=checkpoint_path, **windows + ) + assert resumed.oos_result is not None + assert fresh.oos_result is not None + pd.testing.assert_series_equal(resumed.oos_result.returns, fresh.oos_result.returns) + + +@pytest.mark.slow +def test_run_with_weight_cache_refuses_a_checkpoint_with_a_corrupted_candidate_frame( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """Same guarantee as :func:`test_run_with_weight_cache_refuses_a_ + checkpoint_with_a_mismatched_candidate_cache`, but for a candidate's own + weights content instead of the cache's length: a candidate whose + ``validation_weights`` carries a NaN is structurally a DataFrame of the + right shape (columns/index untouched) -- only a content check, not a + bare isinstance/None check, catches it.""" + from quantlab.validation.checkpoint import ( + compute_provenance, + load_checkpoint, + save_checkpoint, + ) + from quantlab.validation.walk_forward import _FoldCandidateWeights + + data = _cost_sensitive_panel() + config = _cost_sensitive_config(commission_bps=50.0) + grid = {"entry_zscore": [0.5, 3.0]} + windows: _WalkForwardWindows = { + "train_window": 150, + "validation_window": 60, + "test_window": 60, + "expanding": True, + } + checkpoint_path = tmp_path / "checkpoint.pkl" + + fresh, _fresh_cache = WalkForwardValidator(config).run_with_weight_cache( + data, parameter_grid=grid, **windows + ) + assert len(fresh.folds) >= 2, "need at least 2 folds to interrupt after the 1st" + + real_capture = WalkForwardValidator._select_and_capture + starts = {"n": 0} + + def _flaky_capture(self: WalkForwardValidator, *args: object, **kwargs: object): # type: ignore[no-untyped-def] + starts["n"] += 1 + if starts["n"] == 2: + raise RuntimeError("simulated interruption") + return real_capture(self, *args, **kwargs) # type: ignore[arg-type] + + monkeypatch.setattr(WalkForwardValidator, "_select_and_capture", _flaky_capture) + with pytest.raises(RuntimeError, match="simulated interruption"): + WalkForwardValidator(config).run_with_weight_cache( + data, parameter_grid=grid, checkpoint_path=checkpoint_path, **windows + ) + monkeypatch.undo() + assert checkpoint_path.is_file() + + provenance = compute_provenance( + config, + data, + train_window=150, + validation_window=60, + test_window=60, + expanding=True, + execution_delay=0, + parameter_grid={"entry_zscore": [0.5, 3.0]}, + ) + loaded = load_checkpoint(checkpoint_path, provenance) + assert loaded is not None + (windows_l, parameters, scores, targets, cached_candidates), progress = loaded + + first_fold = cached_candidates[0] + first_candidate = next( + c for c in first_fold if isinstance(c.validation_weights, pd.DataFrame) + ) + corrupted_weights = first_candidate.validation_weights.copy() + corrupted_weights.iloc[0, 0] = np.nan + corrupted_candidate = _FoldCandidateWeights( + corrupted_weights, first_candidate.test_targets + ) + corrupted_first_fold = [ + corrupted_candidate if c is first_candidate else c for c in first_fold + ] + corrupted_cache = [corrupted_first_fold, *cached_candidates[1:]] + save_checkpoint( + checkpoint_path, + provenance, + (windows_l, parameters, scores, targets, corrupted_cache), + progress, + ) + + resumed, _resumed_cache = WalkForwardValidator(config).run_with_weight_cache( + data, parameter_grid=grid, checkpoint_path=checkpoint_path, **windows + ) + assert resumed.oos_result is not None + assert fresh.oos_result is not None + pd.testing.assert_series_equal(resumed.oos_result.returns, fresh.oos_result.returns) + + +@pytest.mark.slow +def test_rescore_with_costs_matches_a_fresh_scenario_run() -> None: + """rescore_with_costs() must reproduce a fresh full re-run's fold + selection and OOS returns under a scaled-cost scenario — it must be a + faster way to compute the same answer, not an approximation.""" + data = _cost_sensitive_panel() + config = _cost_sensitive_config(commission_bps=50.0) + grid = {"entry_zscore": [0.5, 3.0]} + windows: _WalkForwardWindows = { + "train_window": 150, + "validation_window": 60, + "test_window": 60, + "expanding": True, + } + + validator = WalkForwardValidator(config) + _, weight_cache = validator.run_with_weight_cache( + data, parameter_grid=grid, **windows + ) + + x5_config = scale_costs(config, commission_mult=5.0) + rescored = validator.rescore_with_costs(weight_cache, x5_config) + fresh = WalkForwardValidator(x5_config).run(data, parameter_grid=grid, **windows) + + assert rescored.oos_result is not None + assert fresh.oos_result is not None + assert [f.best_params for f in rescored.folds] == [ + f.best_params for f in fresh.folds + ] + pd.testing.assert_series_equal( + rescored.oos_result.returns, fresh.oos_result.returns + ) + assert rescored.oos_result.metrics["total_cost_fraction"] == pytest.approx( + fresh.oos_result.metrics["total_cost_fraction"] + ) + + +@pytest.mark.slow +def test_run_walk_forward_stress_tests_best_days_removed_reuses_baseline() -> None: + """The one scenario that changes no configuration must not re-run the + walk-forward process — it is a direct post-hoc transform of the + baseline's already-realised OOS returns.""" + data = _panel() + grid = {"lookback_period": [60, 120]} + # run_walk_forward_stress_tests() now verifies wf_baseline was actually + # built with this call's own grid (parameter_grid_for_config(config)) + # and windows (resolve_walk_forward_windows(config)), so both must match + # what the baseline below is built with. + config = _config_with_grid(grid) + train_window, validation_window, test_window = resolve_walk_forward_windows(config) + wf_baseline = WalkForwardValidator(config).run( + data, + parameter_grid=grid, + train_window=train_window, + validation_window=validation_window, + test_window=test_window, + expanding=config.validation.expanding, + ) + assert wf_baseline.oos_result is not None + + stress = run_walk_forward_stress_tests(data, config, wf_baseline) + assert set(stress["scenario"]) >= { + "baseline", + "commission x2", + "commission x5", + "slippage x2", + "execution delay +1", + "best 10 days removed", + } + from quantlab.risk.stress import remove_best_days + + expected_returns = remove_best_days(wf_baseline.oos_result.returns, 10) + expected_sharpe = M.sharpe_ratio( + expected_returns, config.risk_free_rate, config.periods_per_year + ) + row = stress.loc[stress["scenario"] == "best 10 days removed"].iloc[0] + assert row["sharpe"] == pytest.approx(expected_sharpe) + + +def test_run_walk_forward_stress_tests_rejects_a_baseline_without_oos_result() -> None: + from quantlab.validation.walk_forward import WalkForwardResult + + data = _panel() + config = _config() + with pytest.raises(ValueError, match="no OOS result"): + run_walk_forward_stress_tests(data, config, WalkForwardResult()) + + +def _baseline_windows() -> _WalkForwardWindows: + return { + "train_window": 300, + "validation_window": 120, + "test_window": 120, + "expanding": True, + } + + +@pytest.mark.slow +def test_wf_stress_tests_rejects_a_baseline_built_from_a_different_config() -> None: + """Every stress scenario below is derived from `config` (windows, grid) + and assumed to correspond to `wf_baseline`'s own methodology -- a + baseline actually built from a *different* config would silently mix + two methodologies (e.g. different train/test windows) without this + check, corrupting every scenario that reuses its cached weights.""" + data = _panel() + grid = {"lookback_period": [60, 120]} + baseline_config = _config() + wf_baseline = WalkForwardValidator(baseline_config).run( + data, parameter_grid=grid, **_baseline_windows() + ) + assert wf_baseline.oos_result is not None + + different_config = baseline_config.revalidated_copy( + update={ + "portfolio": baseline_config.portfolio.revalidated_copy( + update={"maximum_weight": 0.9} + ) + } + ) + with pytest.raises(ValueError, match="wf_baseline was not built from `config`"): + run_walk_forward_stress_tests(data, different_config, wf_baseline) + + +@pytest.mark.slow +def test_wf_stress_tests_rejects_a_baseline_built_from_different_data() -> None: + """A baseline computed against one data panel, passed alongside a + *different* panel, must be rejected rather than silently stress-testing + against data that never actually produced it.""" + data = _panel() + grid = {"lookback_period": [60, 120]} + config = _config() + wf_baseline = WalkForwardValidator(config).run( + data, parameter_grid=grid, **_baseline_windows() + ) + assert wf_baseline.oos_result is not None + + different_data = _panel(n=901) # different length -> different data_hash + with pytest.raises(ValueError, match="wf_baseline was not built from `data`"): + run_walk_forward_stress_tests(different_data, config, wf_baseline) + + +@pytest.mark.slow +def test_run_walk_forward_stress_tests_reports_scenario_progress() -> None: + """on_progress must fire once before any work starts (done=0) and once + per completed unit of work — first one tick per fold while the weight + cache shared by the cost-only scenarios is (re)built, then one tick per + remaining scenario — ending at (total, total).""" + data = _panel() + grid = {"lookback_period": [60, 120]} + config = _config_with_grid(grid) + # run_walk_forward_stress_tests() resolves its own windows from `config` + # (resolve_walk_forward_windows), so wf_baseline must be built the same + # way real callers (dashboard/CLI) do — otherwise its fold count + # wouldn't match the weight cache's, which this progress accounting + # relies on. + train_window, validation_window, test_window = resolve_walk_forward_windows(config) + wf_baseline = WalkForwardValidator(config).run( + data, + parameter_grid=grid, + train_window=train_window, + validation_window=validation_window, + test_window=test_window, + expanding=config.validation.expanding, + ) + assert wf_baseline.oos_result is not None + + progress_calls: list[tuple[int, int]] = [] + stress = run_walk_forward_stress_tests( + data, + config, + wf_baseline, + on_progress=lambda done, total: progress_calls.append((done, total)), + ) + # 3 symbols configured -> the reduced-universe scenario is also included. + n_scenarios = len(stress) - 1 # every row except "baseline" is a scenario + # run_walk_forward_stress_tests() resolves its own grid from `config` + # too (parameter_grid_for_config), independently of the grid used above + # to build wf_baseline — cache-building progress is reported per + # candidate (folds x this grid's size), not per fold. + from quantlab.validation.parameter_grid import parameter_grid_for_config + + grid = parameter_grid_for_config(config) + n_combinations = math.prod(len(values) for values in grid.values()) + total_units = len(wf_baseline.folds) * n_combinations + n_scenarios + assert progress_calls[0] == (0, total_units) + assert progress_calls[-1] == (total_units, total_units) + assert [done for done, _ in progress_calls] == list(range(total_units + 1)) + + +@pytest.mark.slow +def test_run_walk_forward_stress_tests_resumes_the_weight_cache_build( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """The weight-cache build inside run_walk_forward_stress_tests() — the + expensive part the cache exists to amortise across the 3 cost-only + scenarios — must itself be resumable via its own nested checkpoint: an + interruption partway through it must not force rebuilding the cache + from scratch, or the whole point of caching is defeated on any restart. + """ + data = _panel() + grid = {"lookback_period": [60, 120]} + config = _config_with_grid(grid) + train_window, validation_window, test_window = resolve_walk_forward_windows(config) + wf_baseline = WalkForwardValidator(config).run( + data, + parameter_grid=grid, + train_window=train_window, + validation_window=validation_window, + test_window=test_window, + expanding=config.validation.expanding, + ) + assert wf_baseline.oos_result is not None + n_folds = len(wf_baseline.folds) + assert n_folds >= 2, "need >= 2 folds to interrupt mid-cache-build" + + checkpoint_path = tmp_path / "checkpoint.pkl" + cache_checkpoint_path = tmp_path / "checkpoint_cache.pkl" + + real_capture = WalkForwardValidator._select_and_capture + starts = {"n": 0} + + def _flaky_capture(self: WalkForwardValidator, *args: object, **kwargs: object): # type: ignore[no-untyped-def] + starts["n"] += 1 + if starts["n"] == 2: + raise RuntimeError("simulated interruption") + return real_capture(self, *args, **kwargs) # type: ignore[arg-type] + + monkeypatch.setattr(WalkForwardValidator, "_select_and_capture", _flaky_capture) + with pytest.raises(RuntimeError, match="simulated interruption"): + run_walk_forward_stress_tests( + data, config, wf_baseline, checkpoint_path=checkpoint_path + ) + # "baseline" (block 1) completed and checkpointed before the cache-build + # (block 2) even started, so the outer, scenario-level checkpoint exists + # too — it just still only has 1 block recorded. + assert checkpoint_path.is_file() + assert cache_checkpoint_path.is_file() + monkeypatch.undo() + + calls = {"n": 0} + real_capture2 = WalkForwardValidator._select_and_capture + + def _counting_capture(self: WalkForwardValidator, *args: object, **kwargs: object): # type: ignore[no-untyped-def] + calls["n"] += 1 + return real_capture2(self, *args, **kwargs) # type: ignore[arg-type] + + monkeypatch.setattr(WalkForwardValidator, "_select_and_capture", _counting_capture) + resumed = run_walk_forward_stress_tests( + data, config, wf_baseline, checkpoint_path=checkpoint_path + ) + # Only the folds *not* already cached at interruption time were + # recomputed — proof the cache build actually resumed, not restarted. + assert calls["n"] == n_folds - 1 + assert not checkpoint_path.is_file() + assert not cache_checkpoint_path.is_file() + monkeypatch.undo() + + fresh = run_walk_forward_stress_tests(data, config, wf_baseline) + pd.testing.assert_frame_equal( + resumed.reset_index(drop=True), fresh.reset_index(drop=True) + ) + + +@pytest.mark.slow +def test_run_walk_forward_stress_tests_resume_after_cost_block_runs_every_later_block( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """Regression test: the scenario-block checkpoint's progress must be + tracked explicitly, never re-derived from len(rows). Block 2 (cache + build + 3 cost-only rescores: commission x2, commission x5, slippage x2) + alone appends 1 (baseline) + 3 = 4 rows after only 2 blocks are done -- + re-deriving "how many blocks are done" from len(rows) would think 4 + blocks are done and skip block 3 (execution delay) and block 4 (best 10 + days removed) entirely on resume.""" + from quantlab.validation.checkpoint import compute_provenance, load_checkpoint + + data = _panel() + config = _config_with_grid({}) + train_window, validation_window, test_window = resolve_walk_forward_windows(config) + wf_baseline = WalkForwardValidator(config).run( + data, + parameter_grid={}, + train_window=train_window, + validation_window=validation_window, + test_window=test_window, + expanding=config.validation.expanding, + ) + assert wf_baseline.oos_result is not None + + checkpoint_path = tmp_path / "checkpoint.pkl" + + # Block 2 (cache-build + cost rescores) uses run_with_weight_cache(), not + # .run() -- patching .run() to always fail only intercepts block 3's + # (execution delay) _run_walk_forward() call, which is a plain .run(). + def _boom(*args: object, **kwargs: object) -> None: + raise RuntimeError("simulated interruption right after block 2") + + monkeypatch.setattr(WalkForwardValidator, "run", _boom) + with pytest.raises(RuntimeError, match="simulated interruption"): + run_walk_forward_stress_tests( + data, config, wf_baseline, checkpoint_path=checkpoint_path + ) + monkeypatch.undo() + + provenance = compute_provenance(config, data) + checkpoint_result = load_checkpoint(checkpoint_path, provenance) + assert checkpoint_result is not None + state, progress = checkpoint_result + assert len(state) == 4 # baseline + 3 cost scenarios + assert progress == 2 # but only 2 *blocks* are actually done + + resumed = run_walk_forward_stress_tests( + data, config, wf_baseline, checkpoint_path=checkpoint_path + ) + # The blocks the len(rows)-based bug would have skipped on resume. + assert {"execution delay +1", "best 10 days removed"} <= set(resumed["scenario"]) + assert not checkpoint_path.is_file() + + +@pytest.mark.slow +def test_run_walk_forward_stress_tests_refuses_a_checkpoint_with_wrong_scenario_names( + tmp_path: Path, +) -> None: + """A checkpoint whose row count and schema look right for progress=2 (4 + rows: baseline + 3 cost scenarios) but whose scenario names are wrong + (e.g. all four rows literally named "baseline") is structurally + plausible but incoherent -- it must never be resumed from, or the + result table would silently carry duplicated/misnamed scenario rows.""" + import quantlab.validation.robustness as robustness_module + from quantlab.validation.checkpoint import compute_provenance, save_checkpoint + + data = _panel() + config = _config_with_grid({}) + train_window, validation_window, test_window = resolve_walk_forward_windows(config) + wf_baseline = WalkForwardValidator(config).run( + data, + parameter_grid={}, + train_window=train_window, + validation_window=validation_window, + test_window=test_window, + expanding=config.validation.expanding, + ) + assert wf_baseline.oos_result is not None + + checkpoint_path = tmp_path / "checkpoint.pkl" + provenance = compute_provenance(config, data) + + def make_row(name: str) -> dict[str, object]: + # dict.fromkeys(...) would read more naturally here, but its return + # type is inferred independently of `row`'s own declared type -- + # unlike a comprehension, which a type checker matches bidirectionally + # against it -- so fromkeys(...) alone doesn't satisfy dict[str, + # object] (dict is invariant in its value type). + row: dict[str, object] = { # noqa: C420 + column: None for column in robustness_module._STRESS_COLUMNS + } + row.update({"scenario": name, "status": "ok"}) + return row + + # Four rows, correct schema, correct count for progress=2 -- but every + # row is wrongly named "baseline" instead of the real scenario names. + corrupted_rows = [make_row("baseline") for _ in range(4)] + save_checkpoint(checkpoint_path, provenance, corrupted_rows, 2) + + resumed = run_walk_forward_stress_tests( + data, config, wf_baseline, checkpoint_path=checkpoint_path + ) + fresh = run_walk_forward_stress_tests(data, config, wf_baseline) + pd.testing.assert_frame_equal( + resumed.reset_index(drop=True), fresh.reset_index(drop=True) + ) + + +@pytest.mark.slow +def test_run_walk_forward_stress_tests_refuses_a_checkpoint_with_an_inconsistent_row( + tmp_path: Path, +) -> None: + """Same guarantee as :func:`test_run_walk_forward_stress_tests_refuses_ + a_checkpoint_with_wrong_scenario_names`, but for status/metrics/error + consistency instead of scenario naming: a row claiming ``status= + "failed"`` while still carrying finite metrics and no error message is + just as incoherent as a misnamed one.""" + from quantlab.validation.checkpoint import compute_provenance, save_checkpoint + + data = _panel() + config = _config_with_grid({}) + train_window, validation_window, test_window = resolve_walk_forward_windows(config) + wf_baseline = WalkForwardValidator(config).run( + data, + parameter_grid={}, + train_window=train_window, + validation_window=validation_window, + test_window=test_window, + expanding=config.validation.expanding, + ) + assert wf_baseline.oos_result is not None + + checkpoint_path = tmp_path / "checkpoint.pkl" + provenance = compute_provenance(config, data) + + scenario_names = ["baseline", "commission x2", "commission x5", "slippage x2"] + + def contradictory_row(name: str) -> dict[str, object]: + return { + "scenario": name, + "total_return": 0.1, + "cagr": 0.05, + "sharpe": 1.0, + "max_drawdown": -0.1, + "status": "failed", # claims failure while metrics are finite + "error": None, # and no error message to go with it + } + + corrupted_rows = [contradictory_row(name) for name in scenario_names] + save_checkpoint(checkpoint_path, provenance, corrupted_rows, 2) + + resumed = run_walk_forward_stress_tests( + data, config, wf_baseline, checkpoint_path=checkpoint_path + ) + fresh = run_walk_forward_stress_tests(data, config, wf_baseline) + pd.testing.assert_frame_equal( + resumed.reset_index(drop=True), fresh.reset_index(drop=True) + ) + + +@pytest.mark.slow +def test_walk_forward_parameter_sensitivity_grid() -> None: + data = _panel() + sens = run_walk_forward_parameter_sensitivity( + data, + _config(), + parameter_x="lookback_period", + values_x=[60, 120], + parameter_y="top_fraction", + values_y=[0.3, 0.5], + ) + assert len(sens) == 4 + assert {"sharpe", "cagr", "max_drawdown", "status"} <= set(sens.columns) + assert (sens["status"] == "ok").all() + + +@pytest.mark.slow +def test_walk_forward_parameter_sensitivity_reports_cell_progress() -> None: + """on_progress must fire once before the first cell (done=0) and once + per completed cell, ending at (n_cells, n_cells) — a coarser, + cell-level signal since each cell is itself a full walk-forward run.""" + data = _panel() + progress_calls: list[tuple[int, int]] = [] + sens = run_walk_forward_parameter_sensitivity( + data, + _config(), + parameter_x="lookback_period", + values_x=[60, 120], + parameter_y="top_fraction", + values_y=[0.3, 0.5], + on_progress=lambda done, total: progress_calls.append((done, total)), + ) + n_cells = len(sens) + assert n_cells == 4 + assert progress_calls[0] == (0, n_cells) + assert progress_calls[-1] == (n_cells, n_cells) + assert [done for done, _ in progress_calls] == list(range(n_cells + 1)) + + +@pytest.mark.slow +def test_walk_forward_parameter_sensitivity_resumes_from_a_checkpoint( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """An interrupted sweep, resumed, must produce exactly the same rows + (same order, same values) as an uninterrupted one — cells are + independent, so resuming is a matter of not recomputing already-done + ones, not approximating anything.""" + data = _panel() + checkpoint_path = tmp_path / "checkpoint.pkl" + sweep_kwargs: _SensitivitySweepKwargs = { + "parameter_x": "lookback_period", + "values_x": [60, 120], + "parameter_y": "top_fraction", + "values_y": [0.3, 0.5], + } + + real_run = WalkForwardValidator.run + starts = {"n": 0} + + def _flaky_run(self: WalkForwardValidator, *args: object, **kwargs: object): # type: ignore[no-untyped-def] + starts["n"] += 1 + if starts["n"] == 3: + raise RuntimeError("simulated interruption") + return real_run(self, *args, **kwargs) # type: ignore[arg-type] + + monkeypatch.setattr(WalkForwardValidator, "run", _flaky_run) + with pytest.raises(RuntimeError, match="simulated interruption"): + run_walk_forward_parameter_sensitivity( + data, _config(), checkpoint_path=checkpoint_path, **sweep_kwargs + ) + assert checkpoint_path.is_file() + monkeypatch.undo() + + resumed = run_walk_forward_parameter_sensitivity( + data, _config(), checkpoint_path=checkpoint_path, **sweep_kwargs + ) + assert not checkpoint_path.is_file() + + fresh = run_walk_forward_parameter_sensitivity(data, _config(), **sweep_kwargs) + pd.testing.assert_frame_equal( + resumed.reset_index(drop=True), fresh.reset_index(drop=True) + ) + + +@pytest.mark.slow +def test_walk_forward_parameter_sensitivity_refuses_a_checkpoint_with_a_garbage_cell( + tmp_path: Path, +) -> None: + """A checkpoint state of ``["garbage"]`` for a one-cell sweep has the + right Python type (list) and the right length (matches progress=1), but + its single element is not a row dict at all -- a length-only check + would wrongly accept it and let "garbage" flow straight into the result + table.""" + from quantlab.validation.checkpoint import compute_provenance, save_checkpoint + + data = _panel() + checkpoint_path = tmp_path / "checkpoint.pkl" + sweep_kwargs: _SensitivitySweepKwargs = { + "parameter_x": "lookback_period", + "values_x": [60], + "parameter_y": "top_fraction", + "values_y": [0.3], + } + provenance = compute_provenance( + _config(), + data, + parameter_x="lookback_period", + values_x=[60], + parameter_y="top_fraction", + values_y=[0.3], + ) + save_checkpoint(checkpoint_path, provenance, ["garbage"], 1) + + resumed = run_walk_forward_parameter_sensitivity( + data, _config(), checkpoint_path=checkpoint_path, **sweep_kwargs + ) + fresh = run_walk_forward_parameter_sensitivity(data, _config(), **sweep_kwargs) + pd.testing.assert_frame_equal( + resumed.reset_index(drop=True), fresh.reset_index(drop=True) + ) + assert "garbage" not in resumed.to_numpy() + + +@pytest.mark.slow +def test_walk_forward_parameter_sensitivity_recovers_from_a_pd_na_checkpoint( + tmp_path: Path, +) -> None: + """A checkpointed cell whose swept-parameter value is ``pd.NA`` used to + crash the resume path with ``TypeError: boolean value of NA is + ambiguous`` deep inside the comparison that checks a cell's value + against its expected combination -- an exception that then propagated + out of ``load_checkpoint`` despite its own contract that a corrupted + checkpoint is only ever skipped, never raised. Must now be treated as + "not a match" and trigger a fresh recompute instead of crashing the + whole sweep.""" + from quantlab.validation.checkpoint import compute_provenance, save_checkpoint + + data = _panel() + checkpoint_path = tmp_path / "checkpoint.pkl" + sweep_kwargs: _SensitivitySweepKwargs = { + "parameter_x": "lookback_period", + "values_x": [60], + "parameter_y": "top_fraction", + "values_y": [0.3], + } + provenance = compute_provenance( + _config(), + data, + parameter_x="lookback_period", + values_x=[60], + parameter_y="top_fraction", + values_y=[0.3], + ) + corrupted_row = { + "lookback_period": pd.NA, + "top_fraction": 0.3, + "sharpe": 1.0, + "cagr": 0.1, + "max_drawdown": -0.1, + "turnover": 0.2, + "num_trades": 5.0, + "status": "ok", + "error": None, + } + save_checkpoint(checkpoint_path, provenance, [corrupted_row], 1) + + resumed = run_walk_forward_parameter_sensitivity( + data, _config(), checkpoint_path=checkpoint_path, **sweep_kwargs + ) + fresh = run_walk_forward_parameter_sensitivity(data, _config(), **sweep_kwargs) + pd.testing.assert_frame_equal( + resumed.reset_index(drop=True), fresh.reset_index(drop=True) + ) + + +@pytest.mark.slow +def test_walk_forward_sensitivity_differs_from_plain_backtest_sensitivity() -> None: + """A walk-forward sensitivity cell re-runs the whole selection process on + each fold, so it must not simply reproduce the plain single-backtest + sensitivity's numbers for the same parameter combination.""" + data = _panel() + config = _config() + + plain = run_parameter_sensitivity( + data, + config, + parameter_x="lookback_period", + values_x=[60], + parameter_y="top_fraction", + values_y=[0.3], + ) + wf = run_walk_forward_parameter_sensitivity( + data, + config, + parameter_x="lookback_period", + values_x=[60], + parameter_y="top_fraction", + values_y=[0.3], + ) + assert wf["status"].iloc[0] == "ok" + assert plain["sharpe"].iloc[0] != pytest.approx(wf["sharpe"].iloc[0]) + + def test_bootstrap_summary_percentiles() -> None: rng = np.random.default_rng(0) returns = pd.Series(rng.normal(0.0005, 0.01, 500)) @@ -115,6 +1806,7 @@ def test_bootstrap_is_reproducible() -> None: pd.testing.assert_frame_equal(a, b) +@pytest.mark.slow def test_stress_tests_include_expected_scenarios() -> None: data = _panel() table = run_stress_tests(data, _config()) @@ -128,6 +1820,269 @@ def test_stress_tests_include_expected_scenarios() -> None: assert c5 <= base + 1e-9 +@pytest.mark.slow +def test_stress_tests_reports_scenario_progress() -> None: + """on_progress must fire once before the first scenario (done=0) and + once per completed scenario (baseline included), ending at + (n_scenarios, n_scenarios).""" + data = _panel() + progress_calls: list[tuple[int, int]] = [] + table = run_stress_tests( + data, + _config(), + on_progress=lambda done, total: progress_calls.append((done, total)), + ) + n_scenarios = len(table) # every row, including "baseline", is a scenario + assert progress_calls[0] == (0, n_scenarios) + assert progress_calls[-1] == (n_scenarios, n_scenarios) + assert [done for done, _ in progress_calls] == list(range(n_scenarios + 1)) + + +@pytest.mark.slow +def test_stress_tests_resumes_from_a_checkpoint_including_baseline_returns( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """Interrupting right after "baseline" and resuming must still get + "best 10 days removed" right — it needs the actual baseline returns + Series, not just its already-computed metrics row, so the checkpoint + has to carry that Series across the interruption, not only `rows`.""" + import quantlab.validation.robustness as robustness_module + + data = _panel() + config = _config() + checkpoint_path = tmp_path / "checkpoint.pkl" + + real_backtest = robustness_module.run_backtest_from_config + calls = {"n": 0} + + def _flaky_backtest(*args: object, **kwargs: object): # type: ignore[no-untyped-def] + calls["n"] += 1 + if calls["n"] == 2: # 1st call is "baseline"; interrupt right after it + raise RuntimeError("simulated interruption") + return real_backtest(*args, **kwargs) # type: ignore[arg-type] + + monkeypatch.setattr(robustness_module, "run_backtest_from_config", _flaky_backtest) + with pytest.raises(RuntimeError, match="simulated interruption"): + run_stress_tests(data, config, checkpoint_path=checkpoint_path) + assert checkpoint_path.is_file() + monkeypatch.undo() + + resumed = run_stress_tests(data, config, checkpoint_path=checkpoint_path) + assert not checkpoint_path.is_file() + fresh = run_stress_tests(data, config) + pd.testing.assert_frame_equal( + resumed.reset_index(drop=True), fresh.reset_index(drop=True) + ) + + +@pytest.mark.slow +def test_stress_tests_refuses_a_structurally_plausible_but_incoherent_checkpoint( + tmp_path: Path, +) -> None: + """A checkpoint whose `progress` claims 1 scenario is done, but whose + `rows` list is empty (or whose baseline_returns Series is missing), is + structurally valid (a 2-tuple of a list and an optional Series) but + incoherent -- it must never be resumed from, since it would otherwise + silently under-report scenarios or crash "best 10 days removed" (which + needs the actual baseline_returns Series, not just its metrics row).""" + from quantlab.validation.checkpoint import compute_provenance, save_checkpoint + + data = _panel() + config = _config() + checkpoint_path = tmp_path / "checkpoint.pkl" + provenance = compute_provenance(config, data) + + # progress=1 (baseline claimed done) but no rows and no baseline_returns. + save_checkpoint(checkpoint_path, provenance, ([], None), 1) + + resumed = run_stress_tests(data, config, checkpoint_path=checkpoint_path) + fresh = run_stress_tests(data, config) + # A trusted-but-corrupted checkpoint would have skipped recomputing + # "baseline" entirely, producing a table missing rows (or crashing) -- + # matching a truly fresh run proves it started over instead. + pd.testing.assert_frame_equal( + resumed.reset_index(drop=True), fresh.reset_index(drop=True) + ) + + +@pytest.mark.slow +def test_stress_tests_refuses_a_checkpoint_with_wrong_scenario_names( + tmp_path: Path, +) -> None: + """A checkpoint whose row count and schema look right for progress=7 + (every scenario `_config()`'s 3-symbol universe produces, including + "reduced universe") but whose scenario names are all "baseline" (with + every metric missing to boot) is structurally plausible but incoherent + -- it must never be resumed from, or the result table would silently + carry seven duplicated "baseline" rows instead of the real scenarios.""" + from quantlab.validation.checkpoint import compute_provenance, save_checkpoint + + data = _panel() + config = _config() + checkpoint_path = tmp_path / "checkpoint.pkl" + provenance = compute_provenance(config, data) + + def make_row(name: str) -> dict[str, object]: + return { + "scenario": name, + "total_return": float("nan"), + "cagr": float("nan"), + "sharpe": float("nan"), + "max_drawdown": float("nan"), + "status": "ok", + "error": None, + } + + corrupted_rows = [make_row("baseline") for _ in range(7)] + save_checkpoint(checkpoint_path, provenance, (corrupted_rows, pd.Series([0.0])), 7) + + resumed = run_stress_tests(data, config, checkpoint_path=checkpoint_path) + fresh = run_stress_tests(data, config) + pd.testing.assert_frame_equal( + resumed.reset_index(drop=True), fresh.reset_index(drop=True) + ) + assert list(resumed["scenario"]) != ["baseline"] * 7 + + +@pytest.mark.slow +def test_stress_tests_refuses_a_checkpoint_with_an_inconsistent_row( + tmp_path: Path, +) -> None: + """A checkpoint row with the right scenario name and schema, but whose + status/metrics/error disagree (here: ``status="ok"`` while every metric + is NaN) is structurally plausible but incoherent -- it must never be + resumed from.""" + from quantlab.validation.checkpoint import compute_provenance, save_checkpoint + + data = _panel() + config = _config() + checkpoint_path = tmp_path / "checkpoint.pkl" + provenance = compute_provenance(config, data) + + contradictory_row = { + "scenario": "baseline", + "total_return": float("nan"), + "cagr": float("nan"), + "sharpe": float("nan"), + "max_drawdown": float("nan"), + "status": "ok", # claims success while every metric is NaN + "error": None, + } + save_checkpoint( + checkpoint_path, provenance, ([contradictory_row], pd.Series([0.0])), 1 + ) + + resumed = run_stress_tests(data, config, checkpoint_path=checkpoint_path) + fresh = run_stress_tests(data, config) + pd.testing.assert_frame_equal( + resumed.reset_index(drop=True), fresh.reset_index(drop=True) + ) + + +@pytest.mark.slow +@pytest.mark.parametrize( + "kind", ["empty", "non_datetime_index", "object_dtype", "nan", "infinite"] +) +def test_stress_tests_refuses_a_checkpoint_with_a_corrupted_baseline_series( + kind: str, tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """A bare ``isinstance(baseline, pd.Series)`` check would accept an + empty series, one indexed by something other than real dates, one + holding non-numeric data, or one containing NaN/infinite values -- and + "best 10 days removed" operates on this Series directly, not on the + already-validated "baseline" metrics row, so a corrupted series reaches + a real computation even when the row next to it looks fine. Interrupts + a real run right after "baseline" (so the paired row is genuine), then + swaps in each kind of corrupted series before resuming -- every case + must be rejected and trigger a fresh recompute, never a crash or a + silently-accepted bad series.""" + import quantlab.validation.robustness as robustness_module + from quantlab.validation.checkpoint import ( + compute_provenance, + load_checkpoint, + save_checkpoint, + ) + + data = _panel() + config = _config() + checkpoint_path = tmp_path / "checkpoint.pkl" + + real_backtest = robustness_module.run_backtest_from_config + calls = {"n": 0} + + def _flaky_backtest(*args: object, **kwargs: object): # type: ignore[no-untyped-def] + calls["n"] += 1 + if calls["n"] == 2: # 1st call is "baseline"; interrupt right after it + raise RuntimeError("simulated interruption") + return real_backtest(*args, **kwargs) # type: ignore[arg-type] + + monkeypatch.setattr(robustness_module, "run_backtest_from_config", _flaky_backtest) + with pytest.raises(RuntimeError, match="simulated interruption"): + run_stress_tests(data, config, checkpoint_path=checkpoint_path) + monkeypatch.undo() + assert checkpoint_path.is_file() + + provenance = compute_provenance(config, data) + loaded = load_checkpoint(checkpoint_path, provenance) + assert loaded is not None + (rows, _baseline), progress = loaded + + stray_index = pd.date_range("1900-01-01", periods=3) + corrupted: object + if kind == "empty": + corrupted = pd.Series(dtype=float) + elif kind == "non_datetime_index": + corrupted = pd.Series([0.01, 0.02, 0.03]) # plain RangeIndex, not dates + elif kind == "object_dtype": + corrupted = pd.Series(["a", "b", "c"], index=stray_index) + elif kind == "nan": + corrupted = pd.Series([0.01, float("nan"), 0.02], index=stray_index) + else: + corrupted = pd.Series([0.01, float("inf"), 0.02], index=stray_index) + + save_checkpoint(checkpoint_path, provenance, (rows, corrupted), progress) + + resumed = run_stress_tests(data, config, checkpoint_path=checkpoint_path) + fresh = run_stress_tests(data, config) + pd.testing.assert_frame_equal( + resumed.reset_index(drop=True), fresh.reset_index(drop=True) + ) + + +@pytest.mark.slow +def test_run_stress_tests_does_not_reuse_a_checkpoint_from_a_different_config( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + import quantlab.validation.robustness as robustness_module + + data = _panel() + checkpoint_path = tmp_path / "checkpoint.pkl" + + real_backtest = robustness_module.run_backtest_from_config + calls = {"n": 0} + + def _flaky_backtest(*args: object, **kwargs: object): # type: ignore[no-untyped-def] + calls["n"] += 1 + if calls["n"] == 2: + raise RuntimeError("simulated interruption") + return real_backtest(*args, **kwargs) # type: ignore[arg-type] + + monkeypatch.setattr(robustness_module, "run_backtest_from_config", _flaky_backtest) + with pytest.raises(RuntimeError, match="simulated interruption"): + run_stress_tests(data, _config(), checkpoint_path=checkpoint_path) + assert checkpoint_path.is_file() + monkeypatch.undo() + + # A config with a different commission -> different provenance -> the + # checkpoint above must be ignored, not partially reused. + different_config = scale_costs(_config(), commission_mult=3.0) + result = run_stress_tests(data, different_config, checkpoint_path=checkpoint_path) + expected = run_stress_tests(data, different_config) + pd.testing.assert_frame_equal( + result.reset_index(drop=True), expected.reset_index(drop=True) + ) + + def test_monte_carlo_permutation_reports_pvalue() -> None: rng = np.random.default_rng(2) returns = pd.Series(rng.normal(0.001, 0.01, 500)) diff --git a/tests/unit/test_validation_hardening.py b/tests/unit/test_validation_hardening.py index 41a5adb..ebc0b2e 100644 --- a/tests/unit/test_validation_hardening.py +++ b/tests/unit/test_validation_hardening.py @@ -55,11 +55,13 @@ def _config(*, benchmark: str | None = None) -> ExperimentConfig: { "experiment_name": "validation_hardening", "data": { - "source": "csv", - "symbols": ["AAA", "BBB", "CCC"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + {"symbol": "BBB", "source": "csv", "calendar": "XNYS"}, + {"symbol": "CCC", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2020-12-31", - "market_calendar": "XNYS", }, "strategy": { "name": "cross_sectional_momentum", @@ -69,7 +71,13 @@ def _config(*, benchmark: str | None = None) -> ExperimentConfig: "top_fraction": 0.3, }, }, - "backtest": {"benchmark_symbol": benchmark}, + "backtest": { + "benchmark": ( + {"symbol": benchmark, "source": "csv", "calendar": "XNYS"} + if benchmark is not None + else None + ) + }, } ) @@ -135,11 +143,15 @@ def test_default_walk_forward_grid_covers_each_builtin_strategy_with_valid_combi { "experiment_name": f"grid_{strategy_name}", "data": { - "source": "csv", - "symbols": ["AAA", "BBB", "CCC", "DDD", "EEE"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + {"symbol": "BBB", "source": "csv", "calendar": "XNYS"}, + {"symbol": "CCC", "source": "csv", "calendar": "XNYS"}, + {"symbol": "DDD", "source": "csv", "calendar": "XNYS"}, + {"symbol": "EEE", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2010-01-01", "end_date": "2020-12-31", - "market_calendar": "XNYS", }, "strategy": {"name": strategy_name, "parameters": parameters}, "portfolio": portfolio, @@ -163,11 +175,15 @@ def test_default_cross_sectional_long_short_grid_remains_disjoint() -> None: { "experiment_name": "grid_cross_sectional_long_short", "data": { - "source": "csv", - "symbols": ["AAA", "BBB", "CCC", "DDD", "EEE"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + {"symbol": "BBB", "source": "csv", "calendar": "XNYS"}, + {"symbol": "CCC", "source": "csv", "calendar": "XNYS"}, + {"symbol": "DDD", "source": "csv", "calendar": "XNYS"}, + {"symbol": "EEE", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2010-01-01", "end_date": "2020-12-31", - "market_calendar": "XNYS", }, "strategy": { "name": "cross_sectional_momentum", @@ -223,11 +239,12 @@ def _pairs_walk_forward_config() -> ExperimentConfig: { "experiment_name": "pairs_warmup", "data": { - "source": "csv", - "symbols": ["AAA", "BBB"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + {"symbol": "BBB", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2025-12-31", - "market_calendar": "XNYS", }, "strategy": { "name": "pairs_trading", @@ -268,6 +285,7 @@ def fake_evaluate( _data: pd.DataFrame, candidate: ExperimentConfig, *_bounds: pd.Timestamp, + execution_delay: int = 0, ) -> pd.Series: evaluated.append( { @@ -356,7 +374,7 @@ def test_random_sign_test_centres_on_risk_free_return() -> None: ppy = 252 risk_free_rate = 0.05 excess = pd.Series([0.01, -0.004, 0.006, -0.002] * 25) - shifted = excess + risk_free_rate / ppy + shifted = excess.add(risk_free_rate / ppy) zero_rate = monte_carlo_permutation( excess, n_iterations=200, seed=7, periods_per_year=ppy ) @@ -559,7 +577,7 @@ def test_parameter_axes_reject_bad_names_and_value_collections() -> None: run_parameter_sensitivity( pd.DataFrame(), config, "", [1], "top_fraction", [0.3] ) - with pytest.raises(ValueError, match="Unknown parameters"): + with pytest.raises(ValueError, match="Unknown or unsweepable"): run_parameter_sensitivity( pd.DataFrame(), config, "not_a_param", [1], "top_fraction", [0.3] ) @@ -623,11 +641,12 @@ def _holdout_config(**validation_overrides: object) -> ExperimentConfig: { "experiment_name": "holdout_hardening", "data": { - "source": "csv", - "symbols": ["AAA", "BBB"], + "instruments": [ + {"symbol": "AAA", "source": "csv", "calendar": "XNYS"}, + {"symbol": "BBB", "source": "csv", "calendar": "XNYS"}, + ], "start_date": "2020-01-01", "end_date": "2020-12-31", - "market_calendar": "XNYS", }, "strategy": {"name": "buy_and_hold", "parameters": {}}, "portfolio": {"allocator": "equal_weight"}, @@ -643,7 +662,7 @@ def test_holdout_report_summary_table_lists_train_validation_and_test() -> None: report = run_holdout_report(data, config, result) assert report is not None table = report.summary_table() - assert list(table["Block"]) == ["Train", "Validation", "Test (out-of-sample)"] + assert list(table["Block"]) == ["Train", "Validation", "Test"] assert {"Start", "End", "CAGR", "Sharpe", "Max Drawdown"} <= set(table.columns) @@ -655,7 +674,7 @@ def test_holdout_report_summary_table_omits_an_absent_validation_block() -> None assert report is not None assert not report.has_validation_block table = report.summary_table() - assert list(table["Block"]) == ["Train", "Test (out-of-sample)"] + assert list(table["Block"]) == ["Train", "Test"] assert "validation_metrics" not in report.to_metadata() @@ -798,6 +817,26 @@ def test_validation_package_exports_fold_result() -> None: assert validation.FoldResult is FoldResult +def test_validation_package_exports_walk_forward_robustness_functions() -> None: + """run_walk_forward_stress_tests/run_walk_forward_parameter_sensitivity + are public functionality used by the CLI/dashboard, so they must be + reachable from the package root like every other public entry point + here, not only via their own submodule.""" + import quantlab.validation as validation + from quantlab.validation.parameter_sensitivity import ( + run_walk_forward_parameter_sensitivity, + ) + from quantlab.validation.robustness import run_walk_forward_stress_tests + + assert "run_walk_forward_stress_tests" in validation.__all__ + assert validation.run_walk_forward_stress_tests is run_walk_forward_stress_tests + assert "run_walk_forward_parameter_sensitivity" in validation.__all__ + assert ( + validation.run_walk_forward_parameter_sensitivity + is run_walk_forward_parameter_sensitivity + ) + + def test_walk_forward_rejects_an_unsupported_optimization_metric( monkeypatch: pytest.MonkeyPatch, ) -> None: diff --git a/uv.lock b/uv.lock index 0417648..52f8e09 100644 --- a/uv.lock +++ b/uv.lock @@ -2320,7 +2320,6 @@ version = "0.1.0" source = { editable = "." } dependencies = [ { name = "filelock" }, - { name = "joblib" }, { name = "matplotlib" }, { name = "numpy" }, { name = "pandas" }, @@ -2373,7 +2372,6 @@ requires-dist = [ { name = "empyrical-reloaded", marker = "extra == 'dev'", specifier = ">=0.5.12" }, { name = "filelock", specifier = ">=3.13" }, { name = "ipykernel", marker = "extra == 'notebooks'", specifier = ">=6.29" }, - { name = "joblib", specifier = ">=1.3" }, { name = "jupyter", marker = "extra == 'notebooks'", specifier = ">=1.0" }, { name = "matplotlib", specifier = ">=3.8" }, { name = "mkdocs", marker = "extra == 'docs'", specifier = ">=1.5,<2" },