Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: ml4t/backtest
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.1.7
Choose a base ref
...
head repository: ml4t/backtest
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v0.1.8
Choose a head ref
  • 6 commits
  • 22 files changed
  • 3 contributors

Commits on Sep 12, 2026

  1. release: wait for the simple index before exercising the published wh…

    …eel (#95)
    
    The post-release job verified the publication against two different PyPI
    endpoints and treated them as one. 'Verify PyPI identity and digests' reads
    https://pypi.org/pypi/<name>/<version>/json; 'Install and exercise the
    published wheel' reads https://pypi.org/simple/ through uv. They propagate
    independently, so the first can pass on a version the second has not listed.
    
    Measured on 0.1.7: publish completed 11:59:22Z, the install failed 24s later
    with 'no version of ml4t-backtest==0.1.7', and a re-run of the same job at
    12:03:22Z passed unchanged. Nothing was wrong with the release; the check was
    faster than the index.
    
    Retry the install for up to 12 attempts over 120s, the same budget the
    deployed-documentation recheck already uses below it, and fail with an
    explicit message naming the simple index if it never appears. A genuinely
    absent artifact still fails, two minutes later.
    
    
    Claude-Session: https://claude.ai/code/session_01UPDj1nioTuD4xATMVyhZxB
    
    Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
    stefan-jansen and claude authored Sep 12, 2026
    Configuration menu
    Copy the full SHA
    2f717e3 View commit details
    Browse the repository at this point in the history

Commits on Sep 15, 2026

  1. Reconcile time zones before the as-of join, so trade enrichment stops…

    … failing silently (#97)
    
    * Reconcile time zones before the as-of join, so trade enrichment stops failing silently
    
    enrich_trades_with_signals joins trade times against signal timestamps, and the two sides
    reach it from different places: trade times come out of the engine carrying the bar clock
    without its zone, while a prediction panel is read from parquet with its zone intact.
    join_asof refuses a naive left key against an aware right key, and BacktestProfile wraps
    this call in a try that degrades to an empty frame with a UserWarning - so the reader does
    not get a traceback, they get a tear sheet quietly missing its ML trade-alignment charts.
    
    Found in case_studies/nasdaq100_microstructure/20_strategy_analysis.ipynb, whose committed
    output carries 'Prediction enrichment failed: datatypes of join keys don't match -
    entry_time: datetime[us] on left does not match timestamp: datetime[us, UTC] on right'.
    
    A naive column here is the same wall clock with the zone dropped, so it is localized and
    never shifted. Measured on that case study: reading the naive trade times as UTC matches 703
    of 905 trades to an exact (symbol, instant) row in the prediction panel, and reading them as
    America/New_York matches 199; the residual 202 are trades entered between two prediction
    instants, which is what a backward as-of join is for. Shifting instead of localizing would
    still return rows, so getting this backwards would be silent rather than loud. Where both
    sides are aware and disagree the signals are converted, because two aware columns already
    name instants.
    
    The negative control neutralizes the helper with a monkeypatch and asserts the join still
    raises, so the other six tests are evidence that this path is load-bearing rather than
    assertions polars would satisfy on its own.
    
    * Re-derive the retained correctness evidence under the current engine source
    
    The timezone-alignment change moves the engine tree digest, and provenance.py stamps
    that digest into every retained record, so all 68 read stale against the working tree.
    Correctness is the kind of evidence that is genuinely re-derived rather than certified:
    it is cheap and tolerant of a contended machine.
    
    66 pass, 2 unsupported, unchanged from the previous matrix. Compared leaf by leaf against
    the committed copy: 231,740 values, 201 differ, and every one of the 201 is a digest, a
    commit or a timestamp. No correctness value moved.
    
    Every record is stamped dirty:false, so this was produced from a clean tree.
    
    * Rebuild the real-strategy evidence under the current engine, and certify the timings against it
    
    The timezone-alignment change moves the engine tree digest, and the three retained evidence
    files answer to it in three different ways. Correctness was re-derived in 281370c. This is
    the other two.
    
    REAL_STRATEGY_RESULTS.json has a hard equality on the digest and no certification path, so
    it is rebuilt from runs: all 17 required pairs regenerated and compared, 17/17 pass, and the
    promoted file carries commit 281370c with dirty false. The first rebuild today was refused
    by its own gate - it ran while CORRECTNESS_RESULTS.json was still uncommitted, and
    provenance.py stamps dirty from git status taken at build time - so the driver that produced
    this one refuses on a dirty tree rather than discovering it eighteen minutes later.
    
    REAL_STRATEGY_PERFORMANCE.json is certified rather than re-timed. The timed region is the
    single line result = engine.run() at validation/real_strategy_runner.py:386, the declared
    timing_policy excludes result extraction and reporting, and enrich_trades_with_signals - the
    only caller of the new _align_join_time_zones - has no caller anywhere in src/ and runs after
    that call returns. So the added code cannot execute inside the measured interval. That
    mechanism is the stored reason; correctness parity alone would not be sufficient and
    certify_source's own docstring says so.
    
    generate_parity_claims.py --check passes against the regenerated claims.
    stefan-jansen authored Sep 15, 2026
    Configuration menu
    Copy the full SHA
    17887d6 View commit details
    Browse the repository at this point in the history

Commits on Sep 19, 2026

  1. ci: bump astral-sh/setup-uv in the github-actions group (#96)

    Bumps the github-actions group with 1 update: [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv).
    
    
    Updates `astral-sh/setup-uv` from 10.0.1 to 10.1.0
    - [Release notes](https://github.com/astral-sh/setup-uv/releases)
    - [Commits](astral-sh/setup-uv@20cfd1b...bec219d)
    
    ---
    updated-dependencies:
    - dependency-name: astral-sh/setup-uv
      dependency-version: 10.1.0
      dependency-type: direct:production
      update-type: version-update:semver-minor
      dependency-group: github-actions
    ...
    
    Signed-off-by: dependabot[bot] <[email protected]>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    Co-authored-by: Stefan Jansen <[email protected]>
    dependabot[bot] and stefan-jansen authored Sep 19, 2026
    Configuration menu
    Copy the full SHA
    2bc7baf View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    5d3c7c1 View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    c02cca7 View commit details
    Browse the repository at this point in the history

Commits on Sep 21, 2026

  1. Configuration menu
    Copy the full SHA
    a32a206 View commit details
    Browse the repository at this point in the history
Loading