quantbt-engine 1.0.9__tar.gz → 1.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/CHANGELOG.md +24 -0
- {quantbt_engine-1.0.9/src/quantbt_engine.egg-info → quantbt_engine-1.1.0}/PKG-INFO +23 -15
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/README.md +21 -14
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/pyproject.toml +11 -4
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/__init__.py +1 -1
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/generated_product_contracts.py +4 -4
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0/src/quantbt_engine.egg-info}/PKG-INFO +23 -15
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt_engine.egg-info/SOURCES.txt +3 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt_engine.egg-info/requires.txt +3 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase46c_import_graph.py +17 -2
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase46f_packaging_release.py +6 -3
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase47a_grid_adapter.py +9 -2
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase47c_grid_parity.py +9 -2
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase47d_grid_optimizer.py +9 -2
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase48a_release_surfaces.py +11 -5
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase48f_release_gate.py +3 -3
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase50_nested_mode1_causal.py +3 -0
- quantbt_engine-1.1.0/tests/test_phase55a_native_distribution.py +183 -0
- quantbt_engine-1.1.0/tests/test_phase55b_public_release.py +170 -0
- quantbt_engine-1.1.0/tests/test_release_channel_policy.py +49 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/LICENSE +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/MANIFEST.in +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/setup.cfg +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/adapters/__init__.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/adapters/nautilus/__init__.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/adapters/nautilus/_dependency.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/adapters/nautilus/backend.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/adapters/nautilus/instruments.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/adapters/nautilus/options.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/adapters/nautilus/reports.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/api/__init__.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/api/event_driven.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/backends/__init__.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/backends/_native_event_rust.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/backends/native_event.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/backends/native_option.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/backends/native_portfolio.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/backends/native_portfolio_package.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/backends/native_strategy_ir.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/backends/native_vectorized.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/backtester.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/benchmarks/__init__.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/benchmarks/compare_phase9_parity.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/benchmarks/gamma_scalping_backtestsample.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/benchmarks/profile_phase7.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/benchmarks/run_arbitrage_phase_e.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/benchmarks/run_optimization_overhead.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/benchmarks/run_options_engine.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/benchmarks/run_pct_equity_nautilus_smoke.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/benchmarks/run_phase12_arbitrage_cert.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/benchmarks/run_phase12_benchmark_nautilus_cert.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/benchmarks/run_phase13_portfolio_report.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/benchmarks/run_phase13_wfo_cache.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/benchmarks/run_phase14_service_loop.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/benchmarks/run_phase15a_nautilus_certification.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/benchmarks/run_phase15b_synthetic_depth.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/benchmarks/run_phase16_performance_debt.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/benchmarks/run_phase30e_reactive_runner.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/benchmarks/run_phase31_intrabar.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/benchmarks/run_phase34a_native_event_memory.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/benchmarks/run_phase34b_native_event_prepared_score.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/benchmarks/run_phase34c_native_event_single_pass.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/benchmarks/run_phase49b_wfo_performance.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/benchmarks/run_phase7.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/benchmarks/run_portfolio_real_parity.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/__init__.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/accounting_contracts.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/arbitrage.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/basket.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/certification.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/constraints.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/engine.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/event.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/event_contracts.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/execution_contract.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/execution_depth.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/execution_trace.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/generated_native_event_contracts.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/instrument_contracts.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/intrabar_kernel.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/intrabar_reference.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/intrabar_session.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/market_tape.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/native_event_capabilities.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/native_event_parity.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/native_event_promotion.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/order_compiler.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/orders.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/package_execution_contracts.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/portfolio.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/portfolio_execution_contracts.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/preprocessor.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/product_contracts.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/reactive.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/results.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/schema.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/scopes.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/structured_orders.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/types.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/vectorized.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/endpoint.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/engine_spi/__init__.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/engine_spi/errors.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/engine_spi/native_event.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/engine_spi/protocol.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/engine_spi/registry.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/engines.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/errors.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/metrics/__init__.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/metrics/options_analytics.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/metrics/performance.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/optimization/__init__.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/optimization/callbacks.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/optimization/candidate_selection.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/optimization/config.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/optimization/constraints.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/optimization/evaluator.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/optimization/evaluators/__init__.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/optimization/evaluators/arbitrage.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/optimization/evaluators/generic.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/optimization/evaluators/grid_dca.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/optimization/evaluators/intrabar.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/optimization/evaluators/native_event.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/optimization/evaluators/options.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/optimization/evaluators/portfolio.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/optimization/evaluators/signal.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/optimization/multiseed.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/optimization/objectives.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/optimization/optimizer.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/optimization/result.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/optimization/samplers.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/optimization/space.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/options/__init__.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/options/cache.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/options/conventions.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/options/data.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/options/execution.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/options/fees.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/options/greeks.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/options/hedging.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/options/iv.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/options/ledger.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/options/lifecycle.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/options/margin.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/options/packages.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/options/pricing.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/options/schema.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/options/selectors.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/options/strategy.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/options/surface.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/options/tape.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/options/templates/__init__.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/options/templates/packages.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/planning/__init__.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/planning/capabilities.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/planning/fingerprints.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/planning/models.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/planning/output.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/planning/resolve.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/portfolio.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/preparation/__init__.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/preparation/cache.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/preparation/models.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/preparation/native_event.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/preparation/native_execution.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/py.typed +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/reporting/__init__.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/reporting/arbitrage_audit.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/reporting/nautilus_bundle.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/reporting/nautilus_certification.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/reporting/nautilus_diagnostics.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/reporting/parity.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/reporting/portfolio_audit.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/reporting/portfolio_nautilus.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/results/__init__.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/results/raw.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/sizing/__init__.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/sizing/fast.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/sizing/modes.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/strategies/__init__.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/strategies/commands.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/strategies/context.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/strategies/driver.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/strategies/native_ir.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/strategies/requirements.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/viz/__init__.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/viz/plots.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/viz/themes.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/walkforward.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt_engine.egg-info/dependency_links.txt +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt_engine.egg-info/top_level.txt +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_endpoint.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_metrics_intraday_scope.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_optimization_core.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_optimization_evaluators.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_optimization_integration.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_optimization_phase33b.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_optimization_samplers.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_pct_equity_nautilus_smoke.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase0_baseline.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase11_native_portfolio_backend.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase11_native_portfolio_full_surface.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase11_portfolio_engine_spec.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase11_portfolio_institutional_scenarios.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase11_portfolio_nautilus_validation.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase11_portfolio_real_parity_script.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase12_arbitrage_certification.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase12_benchmark_nautilus_cert.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase13_arbitrage_certification_cleanup.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase13_portfolio_report_parity.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase14_service_loop_benchmark.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase14c_prepared_report_levels.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase15a_nautilus_certification.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase15b_synthetic_depth.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase16_prepared_service_context.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase1_schema.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase2_native_vectorized.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase30a_native_event_lifecycle_contract.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase30b_native_event_lifecycle_kernel.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase30c_native_event_endpoint_lifecycle.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase30d_native_event_reactive_runner.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase30e_native_event_incremental_runner.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase31_merge_blockers.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase31a_execution_correctness_contract.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase31b_market_tape_intrabar_oracle.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase31c_intrabar_kernel.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase31d_certification.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase31h_intrabar_session_reference.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase34a_native_event_artifacts.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase34b_native_event_prepared_score.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase34c_native_event_single_pass.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase3_native_event.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase42_packaging_layout.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase42c_ci_release.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase45a_source_tree_sync.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase45d_native_event_zero_object.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase46a_correctness_certification.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase46b_score_rss.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase48b_release_hygiene.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase48c_event_driven_facade.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase49a_walkforward_schedules.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase49b_wfo_performance.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase4_basket.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase5_1_nautilus_report_bundle.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase5_3_arbitrage_audit.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase5_3_institutional_simulations.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase5_3_portfolio_audit.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase5_4_debt_domain_validation.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase5_4_endpoint_depth.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase5_4_nautilus_depth.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase5_nautilus_adapter.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase6_public_api.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase7_benchmark_suite.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase8_arbitrage_phase_a.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase8_arbitrage_phase_b.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase8_arbitrage_phase_c.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase8_arbitrage_phase_d.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase8_arbitrage_phase_e.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase8_arbitrage_phase_f.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase8_arbitrage_phase_g.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase8_arbitrage_phase_h.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_phase9_performance_parity.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_pre48e_native_event_fast_paths.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_real.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_real_endpoints.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_shared_quantity_constraints.py +0 -0
- {quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/tests/test_walkforward_phase1.py +0 -0
|
@@ -2,6 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `quantbt-engine` are documented here.
|
|
4
4
|
|
|
5
|
+
## [1.1.0] - Unreleased
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- Renamed the governed public release line to `1.1.0` and synchronized package
|
|
10
|
+
metadata, runtime version, generated core/native contracts, lockfile, and
|
|
11
|
+
release documentation.
|
|
12
|
+
- Prepared the governed public `quantbt-native==0.4.1` companion contract for
|
|
13
|
+
Linux x86_64 / CPython 3.11-3.13. The core declares an exact,
|
|
14
|
+
platform-marked dependency; unsupported platforms keep Python/Numba.
|
|
15
|
+
- Added a native-first, wheel-only manylinux OIDC release workflow and a six-row
|
|
16
|
+
Ubuntu 22.04/24.04 Poetry consumer proof. The core release preflights the
|
|
17
|
+
matching public native artifact before it can publish.
|
|
18
|
+
- Kept public release certification self-contained by excluding private,
|
|
19
|
+
out-of-tree Grid integration fixtures from its test shard profile.
|
|
20
|
+
- Updated release, install, capability, troubleshooting, and handoff docs to
|
|
21
|
+
state that supported users receive a pre-built wheel rather than compiling
|
|
22
|
+
Rust locally.
|
|
23
|
+
|
|
24
|
+
### Compatibility
|
|
25
|
+
|
|
26
|
+
- No endpoint signature, execution policy, promotion threshold, or domain
|
|
27
|
+
accounting behavior changes in this packaging-only phase.
|
|
28
|
+
|
|
5
29
|
## [1.0.9] - 2026-08-21
|
|
6
30
|
|
|
7
31
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: quantbt-engine
|
|
3
|
-
Version: 1.0
|
|
3
|
+
Version: 1.1.0
|
|
4
4
|
Summary: Transparent, high-performance quantitative backtesting engine
|
|
5
5
|
Author-email: Vu Cong Minh <vugioan11022002@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -27,6 +27,7 @@ License-File: LICENSE
|
|
|
27
27
|
Requires-Dist: numpy<2.3,>=2.2.6
|
|
28
28
|
Requires-Dist: pandas<2.4,>=2.3.3
|
|
29
29
|
Requires-Dist: numba<0.66,>=0.65.1
|
|
30
|
+
Requires-Dist: quantbt-native==0.4.1; sys_platform == "linux" and platform_machine == "x86_64" and implementation_name == "cpython" and python_version >= "3.11" and python_version < "3.14"
|
|
30
31
|
Provides-Extra: optimization
|
|
31
32
|
Requires-Dist: optuna<4.9,>=4.8.0; extra == "optimization"
|
|
32
33
|
Requires-Dist: arch<8.1,>=8.0.0; extra == "optimization"
|
|
@@ -298,7 +299,7 @@ Rust is execution-authoritative only where the public request, accounting
|
|
|
298
299
|
contract, installed-wheel parity corpus, and promotion policy have all been
|
|
299
300
|
certified. The generated Stage-B policy has this deliberately narrow scope:
|
|
300
301
|
|
|
301
|
-
| Route | Rust behavior with a matching
|
|
302
|
+
| Route | Rust behavior with a matching companion | Public default elsewhere |
|
|
302
303
|
|---|---|---|
|
|
303
304
|
| Static V2/V3 `OrderCommand` tape | `auto` at 10,000+ bars | Python |
|
|
304
305
|
| Bounded Native Strategy IR, batch, causal-fold scorer | `auto` at 2,000+ bars | Python |
|
|
@@ -351,8 +352,9 @@ and the support boundary is in
|
|
|
351
352
|
Phase 54B.4 adds an installed-wheel release gate, rather than a new speed
|
|
352
353
|
claim. It proves clean core-only fallback, exact core/native-pair handshake,
|
|
353
354
|
promotion decisions, and Python/Rust accounting parity for every governed
|
|
354
|
-
route. The
|
|
355
|
-
|
|
355
|
+
route. The `1.1.0` / `quantbt-native==0.4.1` release pair adds a pre-built
|
|
356
|
+
Linux x86_64 CPython 3.11-3.13 companion; it is published native-first and
|
|
357
|
+
proved through a public Poetry consumer matrix. See the
|
|
356
358
|
[native release handoff](docs/migration/native_release_handoff.md).
|
|
357
359
|
|
|
358
360
|
### Historical Phase 46F package and dual-backend release evidence
|
|
@@ -363,9 +365,9 @@ wheel:
|
|
|
363
365
|
|
|
364
366
|
| Release artifact | Current status | Backend policy |
|
|
365
367
|
|---|---|---|
|
|
366
|
-
| `quantbt-engine` wheel/sdist |
|
|
367
|
-
| `quantbt-native` PyO3 wheel |
|
|
368
|
-
| `quantbt-engine[native]` |
|
|
368
|
+
| `quantbt-engine` wheel/sdist | governed core release | all existing endpoints remain available |
|
|
369
|
+
| `quantbt-native` PyO3 wheel | exact Linux x86_64 CPython 3.11-3.13 companion | Stage-B `auto` only for certified static/IR/batch rows |
|
|
370
|
+
| `quantbt-engine[native]` | compatibility alias | matching companion is a direct platform dependency |
|
|
369
371
|
|
|
370
372
|
The committed Phase 46F rerun compares the same prepared static tape and keeps
|
|
371
373
|
Python/Rust accounting parity at 100%:
|
|
@@ -437,8 +439,9 @@ and a SHA256 release manifest. The TestPyPI workflow is manual and OIDC
|
|
|
437
439
|
protected; it must be run with an unused matching RC version/tag and reviewed
|
|
438
440
|
before production PyPI publication. See
|
|
439
441
|
[`docs/testpypi_release_checklist.md`](docs/testpypi_release_checklist.md).
|
|
440
|
-
`
|
|
441
|
-
|
|
442
|
+
This historical `1.0.8` release evidence intentionally excluded
|
|
443
|
+
`quantbt-native`; `auto` remained Python and explicit Rust remained
|
|
444
|
+
capability-gated.
|
|
442
445
|
|
|
443
446
|
### Phase 48C stable event-driven facade evidence
|
|
444
447
|
|
|
@@ -578,9 +581,11 @@ facade; it is not a universal Rust speed claim.
|
|
|
578
581
|
Phase 48E.1 also locks typed API 0.4 step results, count-only score sinks,
|
|
579
582
|
reusable SoA audit buffers, separate command/lifecycle/fill reports, compact
|
|
580
583
|
validated Rust order state, and reset/lifecycle parity. This paragraph records
|
|
581
|
-
the historical pre-promotion state; the current Stage-B
|
|
582
|
-
|
|
583
|
-
|
|
584
|
+
the historical pre-promotion state; the current Stage-B policy is the bounded
|
|
585
|
+
static/IR/batch policy above. The `native` extra remains a compatibility alias;
|
|
586
|
+
Phase 55A instead prepares a direct, platform-marked dependency for the
|
|
587
|
+
CPython 3.11/3.12/3.13 Linux x86_64 wheel matrix. It becomes public only after
|
|
588
|
+
the Phase 55B clean-install workflow passes.
|
|
584
589
|
|
|
585
590
|
Ecosystem positioning:
|
|
586
591
|
|
|
@@ -781,9 +786,12 @@ feature is under development:
|
|
|
781
786
|
pip install -e /root/bobby/pool_alpha/quantbt
|
|
782
787
|
```
|
|
783
788
|
|
|
784
|
-
For reproducible deployments, pin
|
|
785
|
-
`pip install quantbt-engine==1.0
|
|
786
|
-
`from quantbt import QuantBTEndpoint`.
|
|
789
|
+
For reproducible deployments, pin the governed release, for example
|
|
790
|
+
`pip install quantbt-engine==1.1.0`, and keep the unchanged import
|
|
791
|
+
`from quantbt import QuantBTEndpoint`. On supported Linux, the exact pre-built
|
|
792
|
+
native companion resolves automatically; it does not require a new import or
|
|
793
|
+
endpoint API. The release order and Poetry proof are in the
|
|
794
|
+
[TestPyPI release checklist](docs/testpypi_release_checklist.md).
|
|
787
795
|
|
|
788
796
|
## Quick Start
|
|
789
797
|
|
|
@@ -247,7 +247,7 @@ Rust is execution-authoritative only where the public request, accounting
|
|
|
247
247
|
contract, installed-wheel parity corpus, and promotion policy have all been
|
|
248
248
|
certified. The generated Stage-B policy has this deliberately narrow scope:
|
|
249
249
|
|
|
250
|
-
| Route | Rust behavior with a matching
|
|
250
|
+
| Route | Rust behavior with a matching companion | Public default elsewhere |
|
|
251
251
|
|---|---|---|
|
|
252
252
|
| Static V2/V3 `OrderCommand` tape | `auto` at 10,000+ bars | Python |
|
|
253
253
|
| Bounded Native Strategy IR, batch, causal-fold scorer | `auto` at 2,000+ bars | Python |
|
|
@@ -300,8 +300,9 @@ and the support boundary is in
|
|
|
300
300
|
Phase 54B.4 adds an installed-wheel release gate, rather than a new speed
|
|
301
301
|
claim. It proves clean core-only fallback, exact core/native-pair handshake,
|
|
302
302
|
promotion decisions, and Python/Rust accounting parity for every governed
|
|
303
|
-
route. The
|
|
304
|
-
|
|
303
|
+
route. The `1.1.0` / `quantbt-native==0.4.1` release pair adds a pre-built
|
|
304
|
+
Linux x86_64 CPython 3.11-3.13 companion; it is published native-first and
|
|
305
|
+
proved through a public Poetry consumer matrix. See the
|
|
305
306
|
[native release handoff](docs/migration/native_release_handoff.md).
|
|
306
307
|
|
|
307
308
|
### Historical Phase 46F package and dual-backend release evidence
|
|
@@ -312,9 +313,9 @@ wheel:
|
|
|
312
313
|
|
|
313
314
|
| Release artifact | Current status | Backend policy |
|
|
314
315
|
|---|---|---|
|
|
315
|
-
| `quantbt-engine` wheel/sdist |
|
|
316
|
-
| `quantbt-native` PyO3 wheel |
|
|
317
|
-
| `quantbt-engine[native]` |
|
|
316
|
+
| `quantbt-engine` wheel/sdist | governed core release | all existing endpoints remain available |
|
|
317
|
+
| `quantbt-native` PyO3 wheel | exact Linux x86_64 CPython 3.11-3.13 companion | Stage-B `auto` only for certified static/IR/batch rows |
|
|
318
|
+
| `quantbt-engine[native]` | compatibility alias | matching companion is a direct platform dependency |
|
|
318
319
|
|
|
319
320
|
The committed Phase 46F rerun compares the same prepared static tape and keeps
|
|
320
321
|
Python/Rust accounting parity at 100%:
|
|
@@ -386,8 +387,9 @@ and a SHA256 release manifest. The TestPyPI workflow is manual and OIDC
|
|
|
386
387
|
protected; it must be run with an unused matching RC version/tag and reviewed
|
|
387
388
|
before production PyPI publication. See
|
|
388
389
|
[`docs/testpypi_release_checklist.md`](docs/testpypi_release_checklist.md).
|
|
389
|
-
`
|
|
390
|
-
|
|
390
|
+
This historical `1.0.8` release evidence intentionally excluded
|
|
391
|
+
`quantbt-native`; `auto` remained Python and explicit Rust remained
|
|
392
|
+
capability-gated.
|
|
391
393
|
|
|
392
394
|
### Phase 48C stable event-driven facade evidence
|
|
393
395
|
|
|
@@ -527,9 +529,11 @@ facade; it is not a universal Rust speed claim.
|
|
|
527
529
|
Phase 48E.1 also locks typed API 0.4 step results, count-only score sinks,
|
|
528
530
|
reusable SoA audit buffers, separate command/lifecycle/fill reports, compact
|
|
529
531
|
validated Rust order state, and reset/lifecycle parity. This paragraph records
|
|
530
|
-
the historical pre-promotion state; the current Stage-B
|
|
531
|
-
|
|
532
|
-
|
|
532
|
+
the historical pre-promotion state; the current Stage-B policy is the bounded
|
|
533
|
+
static/IR/batch policy above. The `native` extra remains a compatibility alias;
|
|
534
|
+
Phase 55A instead prepares a direct, platform-marked dependency for the
|
|
535
|
+
CPython 3.11/3.12/3.13 Linux x86_64 wheel matrix. It becomes public only after
|
|
536
|
+
the Phase 55B clean-install workflow passes.
|
|
533
537
|
|
|
534
538
|
Ecosystem positioning:
|
|
535
539
|
|
|
@@ -730,9 +734,12 @@ feature is under development:
|
|
|
730
734
|
pip install -e /root/bobby/pool_alpha/quantbt
|
|
731
735
|
```
|
|
732
736
|
|
|
733
|
-
For reproducible deployments, pin
|
|
734
|
-
`pip install quantbt-engine==1.0
|
|
735
|
-
`from quantbt import QuantBTEndpoint`.
|
|
737
|
+
For reproducible deployments, pin the governed release, for example
|
|
738
|
+
`pip install quantbt-engine==1.1.0`, and keep the unchanged import
|
|
739
|
+
`from quantbt import QuantBTEndpoint`. On supported Linux, the exact pre-built
|
|
740
|
+
native companion resolves automatically; it does not require a new import or
|
|
741
|
+
endpoint API. The release order and Poetry proof are in the
|
|
742
|
+
[TestPyPI release checklist](docs/testpypi_release_checklist.md).
|
|
736
743
|
|
|
737
744
|
## Quick Start
|
|
738
745
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "quantbt-engine"
|
|
7
|
-
version = "1.0
|
|
7
|
+
version = "1.1.0"
|
|
8
8
|
description = "Transparent, high-performance quantitative backtesting engine"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11,<3.14"
|
|
@@ -36,6 +36,9 @@ dependencies = [
|
|
|
36
36
|
"numpy>=2.2.6,<2.3",
|
|
37
37
|
"pandas>=2.3.3,<2.4",
|
|
38
38
|
"numba>=0.65.1,<0.66",
|
|
39
|
+
# Supported Linux consumers receive a pre-built PyO3 companion. Other
|
|
40
|
+
# platforms retain the Python/Numba core without source compilation.
|
|
41
|
+
"quantbt-native==0.4.1; sys_platform == 'linux' and platform_machine == 'x86_64' and implementation_name == 'cpython' and python_version >= '3.11' and python_version < '3.14'",
|
|
39
42
|
]
|
|
40
43
|
|
|
41
44
|
[project.optional-dependencies]
|
|
@@ -54,9 +57,8 @@ viz = [
|
|
|
54
57
|
validation = [
|
|
55
58
|
"nautilus-trader>=1.230.0,<1.231; python_version >= '3.12'",
|
|
56
59
|
]
|
|
57
|
-
#
|
|
58
|
-
#
|
|
59
|
-
# manylinux wheel and clean-install gates.
|
|
60
|
+
# Backward-compatible extra name. The bounded native companion is a direct,
|
|
61
|
+
# platform-marked dependency on supported Linux, so this extra adds nothing.
|
|
60
62
|
native = []
|
|
61
63
|
all = [
|
|
62
64
|
"optuna>=4.8.0,<4.9",
|
|
@@ -100,3 +102,8 @@ python_files = ["test_*.py"]
|
|
|
100
102
|
|
|
101
103
|
[tool.uv]
|
|
102
104
|
package = true
|
|
105
|
+
|
|
106
|
+
[tool.uv.sources]
|
|
107
|
+
# Phase 55A lock/build source. This local override is never emitted into the
|
|
108
|
+
# public wheel metadata; consumers resolve the exact PyPI requirement above.
|
|
109
|
+
quantbt-native = { path = "rust/native_event" }
|
{quantbt_engine-1.0.9 → quantbt_engine-1.1.0}/src/quantbt/core/generated_product_contracts.py
RENAMED
|
@@ -4,11 +4,11 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import json
|
|
6
6
|
|
|
7
|
-
PRODUCT_CONTRACT_REGISTRY_FINGERPRINT = "
|
|
7
|
+
PRODUCT_CONTRACT_REGISTRY_FINGERPRINT = "ee8cfc3b99fcad075cd215e9aadcbc2467eb2eaf44f55720f9a4c810149bbdba"
|
|
8
8
|
PRODUCT_CONTRACT_REGISTRY_ID = "quantbt-native-event-product-v1"
|
|
9
9
|
PRODUCT_CONTRACT_REGISTRY_SCHEMA_VERSION = 1
|
|
10
10
|
NATIVE_EVENT_LIFECYCLE_REGISTRY_FINGERPRINT = "601d639f1c398ac81f3c8231c30d067372c80e71ae4e5f097182f00c5c91f05d"
|
|
11
|
-
NATIVE_EVENT_PRODUCT_REGISTRY = json.loads('{\n "capability_normalization": {\n "amend": [\n "native_event_v2_full_contract",\n "r2_stop_amend_replace_reduce_only_constraints"\n ],\n "cancel": [\n "native_event_v2_full_contract",\n "r1_place_cancel_market_limit_gtc",\n "rust_batched_tape",\n "rust_batched_tape_audit"\n ],\n "fok": [\n "native_event_v2_full_contract"\n ],\n "funding": [\n "native_event_v2_full_contract"\n ],\n "gtc": [\n "native_event_v2_full_contract",\n "r1_place_cancel_market_limit_gtc",\n "rust_batched_tape",\n "rust_batched_tape_audit"\n ],\n "gtd": [\n "native_event_v2_full_contract"\n ],\n "ioc": [\n "native_event_v2_full_contract"\n ],\n "limit": [\n "native_event_v2_full_contract",\n "r1_place_cancel_market_limit_gtc",\n "rust_batched_tape",\n "rust_batched_tape_audit"\n ],\n "liquidation": [\n "native_event_v2_full_contract"\n ],\n "market": [\n "native_event_v2_full_contract",\n "r1_place_cancel_market_limit_gtc",\n "rust_batched_tape",\n "rust_batched_tape_audit"\n ],\n "multi_symbol": [\n "native_event_v2_full_contract"\n ],\n "oco": [\n "native_event_v2_full_contract"\n ],\n "parent_child": [\n "native_event_v2_full_contract"\n ],\n "place": [\n "native_event_v2_full_contract",\n "r1_place_cancel_market_limit_gtc",\n "rust_batched_tape",\n "rust_batched_tape_audit"\n ],\n "quantity_constraints": [\n "native_event_v2_full_contract",\n "r2_stop_amend_replace_reduce_only_constraints"\n ],\n "reduce_only": [\n "native_event_v2_full_contract",\n "r2_stop_amend_replace_reduce_only_constraints"\n ],\n "replace": [\n "native_event_v2_full_contract",\n "r2_stop_amend_replace_reduce_only_constraints"\n ],\n "single_symbol": [\n "native_event_v2_full_contract",\n "reactive_session",\n "r1_single_symbol",\n "rust_batched_tape",\n "rust_batched_tape_audit"\n ],\n "stop_limit": [\n "native_event_v2_full_contract",\n "r2_stop_amend_replace_reduce_only_constraints"\n ],\n "stop_market": [\n "native_event_v2_full_contract",\n "r2_stop_amend_replace_reduce_only_constraints"\n ]\n },\n "compatibility": [\n {\n "command_abis": [\n "full-command-v1"\n ],\n "core_version": "1.0.9",\n "fallback": "explicit_rust_fails_fast; auto_routes_certified_static_ir_or_python_with_reason",\n "native_protocol_max": 1,\n "native_protocol_min": 1,\n "native_version": "0.4.0",\n "result_abis": [\n "native-event-result-v1"\n ],\n "status": "exact_staged_pair"\n }\n ],\n "deprecations": [\n {\n "error_from": null,\n "feature": "event_lifecycle aliases",\n "introduced": "1.0.7",\n "migration_doc": "docs/contracts/contract_registry.md",\n "owner": "correctness",\n "removal_target": null,\n "replacement": "explicit event_lifecycle_v2_next_bar_close or event_lifecycle_v3_next_open",\n "warning_from": "1.0.8"\n },\n {\n "error_from": null,\n "feature": "Native StrategyContext legacy materialization",\n "introduced": "1.0.8",\n "migration_doc": "docs/native_strategy_ir.md",\n "owner": "strategy-ir",\n "removal_target": "2.0",\n "replacement": "StrategyContextView plus CommandWriter",\n "warning_from": null\n }\n ],\n "extension_capabilities": [\n "r0_import_smoke",\n "reactive_session",\n "r1_single_symbol",\n "r1_place_cancel_market_limit_gtc",\n "r2_stop_amend_replace_reduce_only_constraints",\n "prepared_market_core",\n "rust_batched_tape",\n "rust_batched_tape_score",\n "rust_batched_tape_audit",\n "rust_batched_tape_sparse",\n "native_event_v2_full_contract",\n "native_event_v2_multisymbol",\n "native_event_v2_funding",\n "native_event_v2_liquidation",\n "native_event_v2_cancel_all_oco",\n "native_event_v2_tif_expiry",\n "native_event_v2_relationships",\n "native_event_v2_quantity_preflight",\n "event_contract_registry_v1",\n "event_lifecycle_v2_next_bar_close",\n "event_lifecycle_v3_next_open",\n "bar_fill_reason_v1",\n "lifecycle_transition_schema_v1",\n "semantic_descriptor_v1",\n "deterministic_quantization_v1",\n "core_abi_0_5",\n "generation_safe_order_arena",\n "flat_static_tape_output",\n "static_tape_compact",\n "native_strategy_ir_v1",\n "native_strategy_ir_signal_target",\n "native_strategy_ir_grid_level",\n "native_strategy_ir_dca_periodic",\n "native_strategy_ir_fixed_bracket",\n "native_strategy_ir_batch_v1",\n "native_portfolio_target_preflight_v1",\n "native_package_transaction_preflight_v1",\n "native_portfolio_target_market_v1",\n "native_package_atomic_market_v1"\n ],\n "lifecycle_registry": {\n "fingerprint": "601d639f1c398ac81f3c8231c30d067372c80e71ae4e5f097182f00c5c91f05d",\n "path": "contracts/native_event_contract_registry.json",\n "schema_version": 1\n },\n "promotion_policy": {\n "default_backend_policy": "certified_only",\n "default_stage": "static_ir",\n "rules": [\n {\n "enabled": true,\n "id": "static_tape_rust_stage_b",\n "min_bars": 10000,\n "required_capabilities": [\n "native_event_v2_full_contract",\n "native_event_v2_multisymbol",\n "native_event_v2_funding",\n "native_event_v2_liquidation",\n "native_event_v2_cancel_all_oco",\n "native_event_v2_tif_expiry",\n "native_event_v2_relationships",\n "native_event_v2_quantity_preflight"\n ],\n "stage": "static_ir",\n "workload_id": "event_static_tape_v2_v3"\n },\n {\n "enabled": true,\n "id": "native_ir_rust_stage_b",\n "min_bars": 2000,\n "required_capabilities": [\n "native_event_v2_full_contract",\n "native_strategy_ir_v1",\n "native_strategy_ir_signal_target",\n "native_strategy_ir_grid_level",\n "native_strategy_ir_dca_periodic",\n "native_strategy_ir_fixed_bracket",\n "native_strategy_ir_batch_v1"\n ],\n "stage": "static_ir",\n "workload_id": "native_strategy_ir_v1"\n },\n {\n "enabled": false,\n "id": "portfolio_target_rust_stage_c",\n "min_bars": 2000,\n "required_capabilities": [\n "native_event_v2_full_contract",\n "native_portfolio_target_market_v1"\n ],\n "stage": "portfolio",\n "workload_id": "portfolio_target_market_v1"\n },\n {\n "enabled": false,\n "id": "package_transaction_rust_stage_d",\n "min_bars": 1,\n "required_capabilities": [\n "native_event_v2_full_contract",\n "native_package_atomic_market_v1"\n ],\n "stage": "package",\n "workload_id": "package_atomic_market_v1"\n }\n ],\n "schema_version": 1,\n "stages": [\n "explicit_only",\n "static_ir",\n "portfolio",\n "package"\n ],\n "table_version": "native-event-promotion-v2"\n },\n "registry_id": "quantbt-native-event-product-v1",\n "runtime_descriptor": {\n "account": {\n "liquidation_models": [\n "zero_equity_legacy"\n ],\n "margin_models": [\n "gross_cross"\n ],\n "pnl_models": [\n "linear_quote_settled"\n ]\n },\n "contracts": [\n "event_lifecycle_v2_next_bar_close",\n "event_lifecycle_v3_next_open"\n ],\n "descriptor_version": "native-event-semantics-v1",\n "native_api": "0.4",\n "orders": {\n "gap_policy": [\n "legacy_trigger",\n "open_worse_than_trigger"\n ],\n "partial_fill": false,\n "types": [\n "market",\n "limit",\n "stop_market",\n "stop_limit"\n ],\n "volume_model": "infinite_bar_liquidity"\n },\n "portfolio": {\n "package_atomicity": "bar_transaction_atomic_market_v1",\n "target_execution": "target_units_market_v1_all_or_none_v2"\n }\n },\n "schema_version": 1,\n "stable_capability_matrix": {\n "capabilities": {\n "amend": true,\n "cancel": true,\n "fok": true,\n "funding": true,\n "gtc": true,\n "gtd": true,\n "ioc": true,\n "limit": true,\n "liquidation": true,\n "market": true,\n "multi_symbol": true,\n "oco": true,\n "parent_child": true,\n "place": true,\n "quantity_constraints": true,\n "reduce_only": true,\n "replace": true,\n "single_symbol": true,\n "stop_limit": true,\n "stop_market": true\n },\n "version": "full-contract-v2-0.4"\n },\n "versions": {\n "capability_descriptor": {\n "current": "workload-capability-v1"\n },\n "command_abi": {\n "accepted": [\n "full-command-v1"\n ],\n "current": "full-command-v1"\n },\n "core_package": {\n "distribution": "quantbt-engine",\n "python_requires": ">=3.11,<3.14",\n "version": "1.0.9"\n },\n "native_package": {\n "distribution": "quantbt-native",\n "published": false,\n "release_policy": "staged_local_only",\n "version": "0.4.0"\n },\n "native_protocol": {\n "maximum": 1,\n "minimum": 1\n },\n "result_abi": {\n "accepted": [\n "native-event-result-v1"\n ],\n "current": "native-event-result-v1"\n },\n "strategy_ir": {\n "accepted": [\n "native-strategy-ir-v1"\n ],\n "current": "native-strategy-ir-v1"\n },\n "trace_schema": {\n "current": "canonical-execution-trace-v1",\n "readable_release_lines": 2\n }\n },\n "workloads": [\n {\n "account_models": [\n "linear_quote_settled_gross_cross"\n ],\n "auto_promotion": true,\n "contracts": [\n "event_lifecycle_v2_next_bar_close",\n "event_lifecycle_v3_next_open"\n ],\n "id": "event_static_tape_v2_v3",\n "maturity": "promoted",\n "max_symbols": null,\n "package_policies": [],\n "platforms": [\n "cpython-3.11+",\n "linux-x86_64-local"\n ],\n "portfolio_modes": [],\n "profiles": [\n "score",\n "minimal",\n "standard",\n "audit"\n ],\n "strategy_modes": [\n "static_commands"\n ],\n "trace_schemas": [\n "canonical-execution-trace-v1"\n ]\n },\n {\n "account_models": [\n "linear_quote_settled_gross_cross"\n ],\n "auto_promotion": false,\n "contracts": [\n "event_lifecycle_v2_next_bar_close",\n "event_lifecycle_v3_next_open"\n ],\n "id": "event_python_callback_v2_v3",\n "maturity": "experimental",\n "max_symbols": null,\n "package_policies": [],\n "platforms": [\n "cpython-3.11+",\n "linux-x86_64-local"\n ],\n "portfolio_modes": [],\n "profiles": [\n "score",\n "minimal",\n "standard",\n "audit"\n ],\n "strategy_modes": [\n "python_callback_compat"\n ],\n "trace_schemas": [\n "canonical-execution-trace-v1"\n ]\n },\n {\n "account_models": [\n "linear_quote_settled_gross_cross"\n ],\n "auto_promotion": true,\n "contracts": [\n "event_lifecycle_v2_next_bar_close",\n "event_lifecycle_v3_next_open"\n ],\n "id": "native_strategy_ir_v1",\n "maturity": "promoted",\n "max_symbols": 1,\n "package_policies": [],\n "platforms": [\n "cpython-3.11+",\n "linux-x86_64-local"\n ],\n "portfolio_modes": [],\n "profiles": [\n "score",\n "minimal",\n "standard",\n "audit"\n ],\n "strategy_modes": [\n "ir_v1"\n ],\n "trace_schemas": [\n "canonical-execution-trace-v1"\n ]\n },\n {\n "account_models": [\n "linear_quote_settled_gross_cross"\n ],\n "auto_promotion": false,\n "contracts": [\n "event_lifecycle_v3_next_open"\n ],\n "id": "portfolio_target_preflight_v1",\n "maturity": "experimental",\n "max_symbols": null,\n "package_policies": [],\n "platforms": [\n "cpython-3.11+",\n "linux-x86_64-local"\n ],\n "portfolio_modes": [\n "target_units"\n ],\n "profiles": [\n "score",\n "audit"\n ],\n "strategy_modes": [\n "portfolio_target_preflight"\n ],\n "trace_schemas": [\n "canonical-execution-trace-v1"\n ]\n },\n {\n "account_models": [\n "linear_quote_settled_gross_cross"\n ],\n "auto_promotion": false,\n "contracts": [\n "event_lifecycle_v3_next_open"\n ],\n "id": "package_transaction_preflight_v1",\n "maturity": "experimental",\n "max_symbols": null,\n "package_policies": [\n "all_or_none",\n "best_effort",\n "sequential",\n "hedge_after_primary"\n ],\n "platforms": [\n "cpython-3.11+",\n "linux-x86_64-local"\n ],\n "portfolio_modes": [],\n "profiles": [\n "score",\n "audit"\n ],\n "strategy_modes": [\n "package_transaction_preflight"\n ],\n "trace_schemas": [\n "canonical-execution-trace-v1"\n ]\n },\n {\n "account_models": [\n "linear_quote_settled_gross_cross"\n ],\n "auto_promotion": false,\n "contracts": [\n "event_lifecycle_v2_next_bar_close"\n ],\n "id": "portfolio_target_market_v1",\n "maturity": "certified",\n "max_symbols": null,\n "package_policies": [],\n "platforms": [\n "cpython-3.11+",\n "linux-x86_64-local"\n ],\n "portfolio_modes": [\n "target_units"\n ],\n "profiles": [\n "score",\n "minimal",\n "standard",\n "audit"\n ],\n "strategy_modes": [\n "portfolio_target_market"\n ],\n "trace_schemas": [\n "canonical-execution-trace-v1"\n ]\n },\n {\n "account_models": [\n "linear_quote_settled_gross_cross"\n ],\n "auto_promotion": false,\n "contracts": [\n "event_lifecycle_v2_next_bar_close"\n ],\n "id": "package_atomic_market_v1",\n "maturity": "certified",\n "max_symbols": null,\n "package_policies": [\n "all_or_none"\n ],\n "platforms": [\n "cpython-3.11+",\n "linux-x86_64-local"\n ],\n "portfolio_modes": [],\n "profiles": [\n "score",\n "minimal",\n "standard",\n "audit"\n ],\n "strategy_modes": [\n "package_atomic_market"\n ],\n "trace_schemas": [\n "canonical-execution-trace-v1"\n ]\n }\n ]\n}')
|
|
11
|
+
NATIVE_EVENT_PRODUCT_REGISTRY = json.loads('{\n "capability_normalization": {\n "amend": [\n "native_event_v2_full_contract",\n "r2_stop_amend_replace_reduce_only_constraints"\n ],\n "cancel": [\n "native_event_v2_full_contract",\n "r1_place_cancel_market_limit_gtc",\n "rust_batched_tape",\n "rust_batched_tape_audit"\n ],\n "fok": [\n "native_event_v2_full_contract"\n ],\n "funding": [\n "native_event_v2_full_contract"\n ],\n "gtc": [\n "native_event_v2_full_contract",\n "r1_place_cancel_market_limit_gtc",\n "rust_batched_tape",\n "rust_batched_tape_audit"\n ],\n "gtd": [\n "native_event_v2_full_contract"\n ],\n "ioc": [\n "native_event_v2_full_contract"\n ],\n "limit": [\n "native_event_v2_full_contract",\n "r1_place_cancel_market_limit_gtc",\n "rust_batched_tape",\n "rust_batched_tape_audit"\n ],\n "liquidation": [\n "native_event_v2_full_contract"\n ],\n "market": [\n "native_event_v2_full_contract",\n "r1_place_cancel_market_limit_gtc",\n "rust_batched_tape",\n "rust_batched_tape_audit"\n ],\n "multi_symbol": [\n "native_event_v2_full_contract"\n ],\n "oco": [\n "native_event_v2_full_contract"\n ],\n "parent_child": [\n "native_event_v2_full_contract"\n ],\n "place": [\n "native_event_v2_full_contract",\n "r1_place_cancel_market_limit_gtc",\n "rust_batched_tape",\n "rust_batched_tape_audit"\n ],\n "quantity_constraints": [\n "native_event_v2_full_contract",\n "r2_stop_amend_replace_reduce_only_constraints"\n ],\n "reduce_only": [\n "native_event_v2_full_contract",\n "r2_stop_amend_replace_reduce_only_constraints"\n ],\n "replace": [\n "native_event_v2_full_contract",\n "r2_stop_amend_replace_reduce_only_constraints"\n ],\n "single_symbol": [\n "native_event_v2_full_contract",\n "reactive_session",\n "r1_single_symbol",\n "rust_batched_tape",\n "rust_batched_tape_audit"\n ],\n "stop_limit": [\n "native_event_v2_full_contract",\n "r2_stop_amend_replace_reduce_only_constraints"\n ],\n "stop_market": [\n "native_event_v2_full_contract",\n "r2_stop_amend_replace_reduce_only_constraints"\n ]\n },\n "compatibility": [\n {\n "command_abis": [\n "full-command-v1"\n ],\n "core_version": "1.1.0",\n "fallback": "explicit_rust_fails_fast; auto_routes_certified_static_ir_or_python_with_reason",\n "native_protocol_max": 1,\n "native_protocol_min": 1,\n "native_version": "0.4.1",\n "result_abis": [\n "native-event-result-v1"\n ],\n "status": "exact_staged_pair"\n }\n ],\n "deprecations": [\n {\n "error_from": null,\n "feature": "event_lifecycle aliases",\n "introduced": "1.0.7",\n "migration_doc": "docs/contracts/contract_registry.md",\n "owner": "correctness",\n "removal_target": null,\n "replacement": "explicit event_lifecycle_v2_next_bar_close or event_lifecycle_v3_next_open",\n "warning_from": "1.0.8"\n },\n {\n "error_from": null,\n "feature": "Native StrategyContext legacy materialization",\n "introduced": "1.0.8",\n "migration_doc": "docs/native_strategy_ir.md",\n "owner": "strategy-ir",\n "removal_target": "2.0",\n "replacement": "StrategyContextView plus CommandWriter",\n "warning_from": null\n }\n ],\n "extension_capabilities": [\n "r0_import_smoke",\n "reactive_session",\n "r1_single_symbol",\n "r1_place_cancel_market_limit_gtc",\n "r2_stop_amend_replace_reduce_only_constraints",\n "prepared_market_core",\n "rust_batched_tape",\n "rust_batched_tape_score",\n "rust_batched_tape_audit",\n "rust_batched_tape_sparse",\n "native_event_v2_full_contract",\n "native_event_v2_multisymbol",\n "native_event_v2_funding",\n "native_event_v2_liquidation",\n "native_event_v2_cancel_all_oco",\n "native_event_v2_tif_expiry",\n "native_event_v2_relationships",\n "native_event_v2_quantity_preflight",\n "event_contract_registry_v1",\n "event_lifecycle_v2_next_bar_close",\n "event_lifecycle_v3_next_open",\n "bar_fill_reason_v1",\n "lifecycle_transition_schema_v1",\n "semantic_descriptor_v1",\n "deterministic_quantization_v1",\n "core_abi_0_5",\n "generation_safe_order_arena",\n "flat_static_tape_output",\n "static_tape_compact",\n "native_strategy_ir_v1",\n "native_strategy_ir_signal_target",\n "native_strategy_ir_grid_level",\n "native_strategy_ir_dca_periodic",\n "native_strategy_ir_fixed_bracket",\n "native_strategy_ir_batch_v1",\n "native_portfolio_target_preflight_v1",\n "native_package_transaction_preflight_v1",\n "native_portfolio_target_market_v1",\n "native_package_atomic_market_v1"\n ],\n "lifecycle_registry": {\n "fingerprint": "601d639f1c398ac81f3c8231c30d067372c80e71ae4e5f097182f00c5c91f05d",\n "path": "contracts/native_event_contract_registry.json",\n "schema_version": 1\n },\n "promotion_policy": {\n "default_backend_policy": "certified_only",\n "default_stage": "static_ir",\n "rules": [\n {\n "enabled": true,\n "id": "static_tape_rust_stage_b",\n "min_bars": 10000,\n "required_capabilities": [\n "native_event_v2_full_contract",\n "native_event_v2_multisymbol",\n "native_event_v2_funding",\n "native_event_v2_liquidation",\n "native_event_v2_cancel_all_oco",\n "native_event_v2_tif_expiry",\n "native_event_v2_relationships",\n "native_event_v2_quantity_preflight"\n ],\n "stage": "static_ir",\n "workload_id": "event_static_tape_v2_v3"\n },\n {\n "enabled": true,\n "id": "native_ir_rust_stage_b",\n "min_bars": 2000,\n "required_capabilities": [\n "native_event_v2_full_contract",\n "native_strategy_ir_v1",\n "native_strategy_ir_signal_target",\n "native_strategy_ir_grid_level",\n "native_strategy_ir_dca_periodic",\n "native_strategy_ir_fixed_bracket",\n "native_strategy_ir_batch_v1"\n ],\n "stage": "static_ir",\n "workload_id": "native_strategy_ir_v1"\n },\n {\n "enabled": false,\n "id": "portfolio_target_rust_stage_c",\n "min_bars": 2000,\n "required_capabilities": [\n "native_event_v2_full_contract",\n "native_portfolio_target_market_v1"\n ],\n "stage": "portfolio",\n "workload_id": "portfolio_target_market_v1"\n },\n {\n "enabled": false,\n "id": "package_transaction_rust_stage_d",\n "min_bars": 1,\n "required_capabilities": [\n "native_event_v2_full_contract",\n "native_package_atomic_market_v1"\n ],\n "stage": "package",\n "workload_id": "package_atomic_market_v1"\n }\n ],\n "schema_version": 1,\n "stages": [\n "explicit_only",\n "static_ir",\n "portfolio",\n "package"\n ],\n "table_version": "native-event-promotion-v2"\n },\n "registry_id": "quantbt-native-event-product-v1",\n "runtime_descriptor": {\n "account": {\n "liquidation_models": [\n "zero_equity_legacy"\n ],\n "margin_models": [\n "gross_cross"\n ],\n "pnl_models": [\n "linear_quote_settled"\n ]\n },\n "contracts": [\n "event_lifecycle_v2_next_bar_close",\n "event_lifecycle_v3_next_open"\n ],\n "descriptor_version": "native-event-semantics-v1",\n "native_api": "0.4",\n "orders": {\n "gap_policy": [\n "legacy_trigger",\n "open_worse_than_trigger"\n ],\n "partial_fill": false,\n "types": [\n "market",\n "limit",\n "stop_market",\n "stop_limit"\n ],\n "volume_model": "infinite_bar_liquidity"\n },\n "portfolio": {\n "package_atomicity": "bar_transaction_atomic_market_v1",\n "target_execution": "target_units_market_v1_all_or_none_v2"\n }\n },\n "schema_version": 1,\n "stable_capability_matrix": {\n "capabilities": {\n "amend": true,\n "cancel": true,\n "fok": true,\n "funding": true,\n "gtc": true,\n "gtd": true,\n "ioc": true,\n "limit": true,\n "liquidation": true,\n "market": true,\n "multi_symbol": true,\n "oco": true,\n "parent_child": true,\n "place": true,\n "quantity_constraints": true,\n "reduce_only": true,\n "replace": true,\n "single_symbol": true,\n "stop_limit": true,\n "stop_market": true\n },\n "version": "full-contract-v2-0.4"\n },\n "versions": {\n "capability_descriptor": {\n "current": "workload-capability-v1"\n },\n "command_abi": {\n "accepted": [\n "full-command-v1"\n ],\n "current": "full-command-v1"\n },\n "core_package": {\n "distribution": "quantbt-engine",\n "python_requires": ">=3.11,<3.14",\n "version": "1.1.0"\n },\n "native_package": {\n "distribution": "quantbt-native",\n "published": true,\n "release_policy": "public_manylinux_x86_64_cpython_311_313_phase55b",\n "version": "0.4.1"\n },\n "native_protocol": {\n "maximum": 1,\n "minimum": 1\n },\n "result_abi": {\n "accepted": [\n "native-event-result-v1"\n ],\n "current": "native-event-result-v1"\n },\n "strategy_ir": {\n "accepted": [\n "native-strategy-ir-v1"\n ],\n "current": "native-strategy-ir-v1"\n },\n "trace_schema": {\n "current": "canonical-execution-trace-v1",\n "readable_release_lines": 2\n }\n },\n "workloads": [\n {\n "account_models": [\n "linear_quote_settled_gross_cross"\n ],\n "auto_promotion": true,\n "contracts": [\n "event_lifecycle_v2_next_bar_close",\n "event_lifecycle_v3_next_open"\n ],\n "id": "event_static_tape_v2_v3",\n "maturity": "promoted",\n "max_symbols": null,\n "package_policies": [],\n "platforms": [\n "cpython-3.11+",\n "linux-x86_64-local"\n ],\n "portfolio_modes": [],\n "profiles": [\n "score",\n "minimal",\n "standard",\n "audit"\n ],\n "strategy_modes": [\n "static_commands"\n ],\n "trace_schemas": [\n "canonical-execution-trace-v1"\n ]\n },\n {\n "account_models": [\n "linear_quote_settled_gross_cross"\n ],\n "auto_promotion": false,\n "contracts": [\n "event_lifecycle_v2_next_bar_close",\n "event_lifecycle_v3_next_open"\n ],\n "id": "event_python_callback_v2_v3",\n "maturity": "experimental",\n "max_symbols": null,\n "package_policies": [],\n "platforms": [\n "cpython-3.11+",\n "linux-x86_64-local"\n ],\n "portfolio_modes": [],\n "profiles": [\n "score",\n "minimal",\n "standard",\n "audit"\n ],\n "strategy_modes": [\n "python_callback_compat"\n ],\n "trace_schemas": [\n "canonical-execution-trace-v1"\n ]\n },\n {\n "account_models": [\n "linear_quote_settled_gross_cross"\n ],\n "auto_promotion": true,\n "contracts": [\n "event_lifecycle_v2_next_bar_close",\n "event_lifecycle_v3_next_open"\n ],\n "id": "native_strategy_ir_v1",\n "maturity": "promoted",\n "max_symbols": 1,\n "package_policies": [],\n "platforms": [\n "cpython-3.11+",\n "linux-x86_64-local"\n ],\n "portfolio_modes": [],\n "profiles": [\n "score",\n "minimal",\n "standard",\n "audit"\n ],\n "strategy_modes": [\n "ir_v1"\n ],\n "trace_schemas": [\n "canonical-execution-trace-v1"\n ]\n },\n {\n "account_models": [\n "linear_quote_settled_gross_cross"\n ],\n "auto_promotion": false,\n "contracts": [\n "event_lifecycle_v3_next_open"\n ],\n "id": "portfolio_target_preflight_v1",\n "maturity": "experimental",\n "max_symbols": null,\n "package_policies": [],\n "platforms": [\n "cpython-3.11+",\n "linux-x86_64-local"\n ],\n "portfolio_modes": [\n "target_units"\n ],\n "profiles": [\n "score",\n "audit"\n ],\n "strategy_modes": [\n "portfolio_target_preflight"\n ],\n "trace_schemas": [\n "canonical-execution-trace-v1"\n ]\n },\n {\n "account_models": [\n "linear_quote_settled_gross_cross"\n ],\n "auto_promotion": false,\n "contracts": [\n "event_lifecycle_v3_next_open"\n ],\n "id": "package_transaction_preflight_v1",\n "maturity": "experimental",\n "max_symbols": null,\n "package_policies": [\n "all_or_none",\n "best_effort",\n "sequential",\n "hedge_after_primary"\n ],\n "platforms": [\n "cpython-3.11+",\n "linux-x86_64-local"\n ],\n "portfolio_modes": [],\n "profiles": [\n "score",\n "audit"\n ],\n "strategy_modes": [\n "package_transaction_preflight"\n ],\n "trace_schemas": [\n "canonical-execution-trace-v1"\n ]\n },\n {\n "account_models": [\n "linear_quote_settled_gross_cross"\n ],\n "auto_promotion": false,\n "contracts": [\n "event_lifecycle_v2_next_bar_close"\n ],\n "id": "portfolio_target_market_v1",\n "maturity": "certified",\n "max_symbols": null,\n "package_policies": [],\n "platforms": [\n "cpython-3.11+",\n "linux-x86_64-local"\n ],\n "portfolio_modes": [\n "target_units"\n ],\n "profiles": [\n "score",\n "minimal",\n "standard",\n "audit"\n ],\n "strategy_modes": [\n "portfolio_target_market"\n ],\n "trace_schemas": [\n "canonical-execution-trace-v1"\n ]\n },\n {\n "account_models": [\n "linear_quote_settled_gross_cross"\n ],\n "auto_promotion": false,\n "contracts": [\n "event_lifecycle_v2_next_bar_close"\n ],\n "id": "package_atomic_market_v1",\n "maturity": "certified",\n "max_symbols": null,\n "package_policies": [\n "all_or_none"\n ],\n "platforms": [\n "cpython-3.11+",\n "linux-x86_64-local"\n ],\n "portfolio_modes": [],\n "profiles": [\n "score",\n "minimal",\n "standard",\n "audit"\n ],\n "strategy_modes": [\n "package_atomic_market"\n ],\n "trace_schemas": [\n "canonical-execution-trace-v1"\n ]\n }\n ]\n}')
|
|
12
12
|
NATIVE_EVENT_RUNTIME_DESCRIPTOR = json.loads('{\n "account": {\n "liquidation_models": [\n "zero_equity_legacy"\n ],\n "margin_models": [\n "gross_cross"\n ],\n "pnl_models": [\n "linear_quote_settled"\n ]\n },\n "contracts": [\n "event_lifecycle_v2_next_bar_close",\n "event_lifecycle_v3_next_open"\n ],\n "descriptor_version": "native-event-semantics-v1",\n "native_api": "0.4",\n "orders": {\n "gap_policy": [\n "legacy_trigger",\n "open_worse_than_trigger"\n ],\n "partial_fill": false,\n "types": [\n "market",\n "limit",\n "stop_market",\n "stop_limit"\n ],\n "volume_model": "infinite_bar_liquidity"\n },\n "portfolio": {\n "package_atomicity": "bar_transaction_atomic_market_v1",\n "target_execution": "target_units_market_v1_all_or_none_v2"\n }\n}')
|
|
13
13
|
NATIVE_EVENT_CAPABILITY_MATRIX_VERSION = "full-contract-v2-0.4"
|
|
14
14
|
NATIVE_EVENT_STABLE_CAPABILITIES = dict(NATIVE_EVENT_PRODUCT_REGISTRY["stable_capability_matrix"]["capabilities"])
|
|
@@ -19,8 +19,8 @@ NATIVE_EVENT_PROMOTION_TABLE_VERSION = "native-event-promotion-v2"
|
|
|
19
19
|
WORKLOAD_CAPABILITY_DESCRIPTORS = tuple(NATIVE_EVENT_PRODUCT_REGISTRY["workloads"])
|
|
20
20
|
NATIVE_EVENT_COMPATIBILITY_MATRIX = tuple(NATIVE_EVENT_PRODUCT_REGISTRY["compatibility"])
|
|
21
21
|
NATIVE_EVENT_DEPRECATION_MATRIX = tuple(NATIVE_EVENT_PRODUCT_REGISTRY["deprecations"])
|
|
22
|
-
NATIVE_EVENT_CORE_PACKAGE_VERSION = "1.0
|
|
23
|
-
NATIVE_EVENT_NATIVE_PACKAGE_VERSION = "0.4.
|
|
22
|
+
NATIVE_EVENT_CORE_PACKAGE_VERSION = "1.1.0"
|
|
23
|
+
NATIVE_EVENT_NATIVE_PACKAGE_VERSION = "0.4.1"
|
|
24
24
|
NATIVE_EVENT_CORE_PROTOCOL_MIN = 1
|
|
25
25
|
NATIVE_EVENT_CORE_PROTOCOL_MAX = 1
|
|
26
26
|
NATIVE_EVENT_COMMAND_ABI_VERSION = "full-command-v1"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: quantbt-engine
|
|
3
|
-
Version: 1.0
|
|
3
|
+
Version: 1.1.0
|
|
4
4
|
Summary: Transparent, high-performance quantitative backtesting engine
|
|
5
5
|
Author-email: Vu Cong Minh <vugioan11022002@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -27,6 +27,7 @@ License-File: LICENSE
|
|
|
27
27
|
Requires-Dist: numpy<2.3,>=2.2.6
|
|
28
28
|
Requires-Dist: pandas<2.4,>=2.3.3
|
|
29
29
|
Requires-Dist: numba<0.66,>=0.65.1
|
|
30
|
+
Requires-Dist: quantbt-native==0.4.1; sys_platform == "linux" and platform_machine == "x86_64" and implementation_name == "cpython" and python_version >= "3.11" and python_version < "3.14"
|
|
30
31
|
Provides-Extra: optimization
|
|
31
32
|
Requires-Dist: optuna<4.9,>=4.8.0; extra == "optimization"
|
|
32
33
|
Requires-Dist: arch<8.1,>=8.0.0; extra == "optimization"
|
|
@@ -298,7 +299,7 @@ Rust is execution-authoritative only where the public request, accounting
|
|
|
298
299
|
contract, installed-wheel parity corpus, and promotion policy have all been
|
|
299
300
|
certified. The generated Stage-B policy has this deliberately narrow scope:
|
|
300
301
|
|
|
301
|
-
| Route | Rust behavior with a matching
|
|
302
|
+
| Route | Rust behavior with a matching companion | Public default elsewhere |
|
|
302
303
|
|---|---|---|
|
|
303
304
|
| Static V2/V3 `OrderCommand` tape | `auto` at 10,000+ bars | Python |
|
|
304
305
|
| Bounded Native Strategy IR, batch, causal-fold scorer | `auto` at 2,000+ bars | Python |
|
|
@@ -351,8 +352,9 @@ and the support boundary is in
|
|
|
351
352
|
Phase 54B.4 adds an installed-wheel release gate, rather than a new speed
|
|
352
353
|
claim. It proves clean core-only fallback, exact core/native-pair handshake,
|
|
353
354
|
promotion decisions, and Python/Rust accounting parity for every governed
|
|
354
|
-
route. The
|
|
355
|
-
|
|
355
|
+
route. The `1.1.0` / `quantbt-native==0.4.1` release pair adds a pre-built
|
|
356
|
+
Linux x86_64 CPython 3.11-3.13 companion; it is published native-first and
|
|
357
|
+
proved through a public Poetry consumer matrix. See the
|
|
356
358
|
[native release handoff](docs/migration/native_release_handoff.md).
|
|
357
359
|
|
|
358
360
|
### Historical Phase 46F package and dual-backend release evidence
|
|
@@ -363,9 +365,9 @@ wheel:
|
|
|
363
365
|
|
|
364
366
|
| Release artifact | Current status | Backend policy |
|
|
365
367
|
|---|---|---|
|
|
366
|
-
| `quantbt-engine` wheel/sdist |
|
|
367
|
-
| `quantbt-native` PyO3 wheel |
|
|
368
|
-
| `quantbt-engine[native]` |
|
|
368
|
+
| `quantbt-engine` wheel/sdist | governed core release | all existing endpoints remain available |
|
|
369
|
+
| `quantbt-native` PyO3 wheel | exact Linux x86_64 CPython 3.11-3.13 companion | Stage-B `auto` only for certified static/IR/batch rows |
|
|
370
|
+
| `quantbt-engine[native]` | compatibility alias | matching companion is a direct platform dependency |
|
|
369
371
|
|
|
370
372
|
The committed Phase 46F rerun compares the same prepared static tape and keeps
|
|
371
373
|
Python/Rust accounting parity at 100%:
|
|
@@ -437,8 +439,9 @@ and a SHA256 release manifest. The TestPyPI workflow is manual and OIDC
|
|
|
437
439
|
protected; it must be run with an unused matching RC version/tag and reviewed
|
|
438
440
|
before production PyPI publication. See
|
|
439
441
|
[`docs/testpypi_release_checklist.md`](docs/testpypi_release_checklist.md).
|
|
440
|
-
`
|
|
441
|
-
|
|
442
|
+
This historical `1.0.8` release evidence intentionally excluded
|
|
443
|
+
`quantbt-native`; `auto` remained Python and explicit Rust remained
|
|
444
|
+
capability-gated.
|
|
442
445
|
|
|
443
446
|
### Phase 48C stable event-driven facade evidence
|
|
444
447
|
|
|
@@ -578,9 +581,11 @@ facade; it is not a universal Rust speed claim.
|
|
|
578
581
|
Phase 48E.1 also locks typed API 0.4 step results, count-only score sinks,
|
|
579
582
|
reusable SoA audit buffers, separate command/lifecycle/fill reports, compact
|
|
580
583
|
validated Rust order state, and reset/lifecycle parity. This paragraph records
|
|
581
|
-
the historical pre-promotion state; the current Stage-B
|
|
582
|
-
|
|
583
|
-
|
|
584
|
+
the historical pre-promotion state; the current Stage-B policy is the bounded
|
|
585
|
+
static/IR/batch policy above. The `native` extra remains a compatibility alias;
|
|
586
|
+
Phase 55A instead prepares a direct, platform-marked dependency for the
|
|
587
|
+
CPython 3.11/3.12/3.13 Linux x86_64 wheel matrix. It becomes public only after
|
|
588
|
+
the Phase 55B clean-install workflow passes.
|
|
584
589
|
|
|
585
590
|
Ecosystem positioning:
|
|
586
591
|
|
|
@@ -781,9 +786,12 @@ feature is under development:
|
|
|
781
786
|
pip install -e /root/bobby/pool_alpha/quantbt
|
|
782
787
|
```
|
|
783
788
|
|
|
784
|
-
For reproducible deployments, pin
|
|
785
|
-
`pip install quantbt-engine==1.0
|
|
786
|
-
`from quantbt import QuantBTEndpoint`.
|
|
789
|
+
For reproducible deployments, pin the governed release, for example
|
|
790
|
+
`pip install quantbt-engine==1.1.0`, and keep the unchanged import
|
|
791
|
+
`from quantbt import QuantBTEndpoint`. On supported Linux, the exact pre-built
|
|
792
|
+
native companion resolves automatically; it does not require a new import or
|
|
793
|
+
endpoint API. The release order and Poetry proof are in the
|
|
794
|
+
[TestPyPI release checklist](docs/testpypi_release_checklist.md).
|
|
787
795
|
|
|
788
796
|
## Quick Start
|
|
789
797
|
|
|
@@ -236,6 +236,8 @@ tests/test_phase49a_walkforward_schedules.py
|
|
|
236
236
|
tests/test_phase49b_wfo_performance.py
|
|
237
237
|
tests/test_phase4_basket.py
|
|
238
238
|
tests/test_phase50_nested_mode1_causal.py
|
|
239
|
+
tests/test_phase55a_native_distribution.py
|
|
240
|
+
tests/test_phase55b_public_release.py
|
|
239
241
|
tests/test_phase5_1_nautilus_report_bundle.py
|
|
240
242
|
tests/test_phase5_3_arbitrage_audit.py
|
|
241
243
|
tests/test_phase5_3_institutional_simulations.py
|
|
@@ -258,5 +260,6 @@ tests/test_phase9_performance_parity.py
|
|
|
258
260
|
tests/test_pre48e_native_event_fast_paths.py
|
|
259
261
|
tests/test_real.py
|
|
260
262
|
tests/test_real_endpoints.py
|
|
263
|
+
tests/test_release_channel_policy.py
|
|
261
264
|
tests/test_shared_quantity_constraints.py
|
|
262
265
|
tests/test_walkforward_phase1.py
|
|
@@ -2,6 +2,9 @@ numpy<2.3,>=2.2.6
|
|
|
2
2
|
pandas<2.4,>=2.3.3
|
|
3
3
|
numba<0.66,>=0.65.1
|
|
4
4
|
|
|
5
|
+
[:sys_platform == "linux" and platform_machine == "x86_64" and implementation_name == "cpython" and python_version >= "3.11" and python_version < "3.14"]
|
|
6
|
+
quantbt-native==0.4.1
|
|
7
|
+
|
|
5
8
|
[all]
|
|
6
9
|
optuna<4.9,>=4.8.0
|
|
7
10
|
arch<8.1,>=8.0.0
|
|
@@ -111,8 +111,23 @@ def test_phase46c_lazy_export_access_is_thread_safe_after_resolution() -> None:
|
|
|
111
111
|
def test_phase46c_dependency_ownership_is_explicit() -> None:
|
|
112
112
|
metadata = tomllib.loads((PROJECT_ROOT / "pyproject.toml").read_text(encoding="utf-8"))
|
|
113
113
|
project = metadata["project"]
|
|
114
|
-
|
|
115
|
-
|
|
114
|
+
dependencies = list(project["dependencies"])
|
|
115
|
+
dependency_names = {
|
|
116
|
+
item.split(";", 1)[0].split(">", 1)[0].split("=", 1)[0].strip()
|
|
117
|
+
for item in dependencies
|
|
118
|
+
}
|
|
119
|
+
assert dependency_names == {"numpy", "pandas", "numba", "quantbt-native"}
|
|
120
|
+
|
|
121
|
+
native_dependency = next(item for item in dependencies if item.startswith("quantbt-native=="))
|
|
122
|
+
assert native_dependency.startswith("quantbt-native==0.4.1;")
|
|
123
|
+
for marker in (
|
|
124
|
+
"sys_platform == 'linux'",
|
|
125
|
+
"platform_machine == 'x86_64'",
|
|
126
|
+
"implementation_name == 'cpython'",
|
|
127
|
+
"python_version >= '3.11'",
|
|
128
|
+
"python_version < '3.14'",
|
|
129
|
+
):
|
|
130
|
+
assert marker in native_dependency
|
|
116
131
|
|
|
117
132
|
optional = project["optional-dependencies"]
|
|
118
133
|
assert any(item.startswith("matplotlib") for item in optional["viz"])
|
|
@@ -63,9 +63,12 @@ def test_phase46f_production_publish_rejects_prereleases() -> None:
|
|
|
63
63
|
assert "github.event.release.draft" in payload["jobs"]["publish"]["if"]
|
|
64
64
|
|
|
65
65
|
|
|
66
|
-
def
|
|
66
|
+
def test_phase55a_linux_native_companion_is_an_exact_core_dependency() -> None:
|
|
67
67
|
metadata = tomllib.loads((PROJECT_ROOT / "pyproject.toml").read_text(encoding="utf-8"))
|
|
68
68
|
dependencies = metadata["project"]["dependencies"]
|
|
69
|
-
|
|
70
|
-
assert
|
|
69
|
+
native_dependency = next(item for item in dependencies if item.startswith("quantbt-native=="))
|
|
70
|
+
assert native_dependency.startswith("quantbt-native==0.4.1;")
|
|
71
|
+
assert "sys_platform == 'linux'" in native_dependency
|
|
72
|
+
assert "platform_machine == 'x86_64'" in native_dependency
|
|
73
|
+
assert "implementation_name == 'cpython'" in native_dependency
|
|
71
74
|
assert metadata["project"]["optional-dependencies"]["native"] == []
|
|
@@ -20,10 +20,17 @@ GRID_PATH = Path(
|
|
|
20
20
|
)
|
|
21
21
|
|
|
22
22
|
|
|
23
|
+
def _grid_fixture_is_readable() -> bool:
|
|
24
|
+
try:
|
|
25
|
+
return GRID_PATH.is_file()
|
|
26
|
+
except OSError:
|
|
27
|
+
return False
|
|
28
|
+
|
|
29
|
+
|
|
23
30
|
@pytest.fixture(scope="module")
|
|
24
31
|
def grid_module():
|
|
25
|
-
if not
|
|
26
|
-
pytest.skip(f"external Grid module is
|
|
32
|
+
if not _grid_fixture_is_readable():
|
|
33
|
+
pytest.skip(f"external Grid module is unavailable or unreadable: {GRID_PATH}")
|
|
27
34
|
|
|
28
35
|
module_name = "phase47a_dynamic_grid_quantbt_native_event"
|
|
29
36
|
spec = importlib.util.spec_from_file_location(module_name, GRID_PATH)
|
|
@@ -23,10 +23,17 @@ GRID_PATH = Path(
|
|
|
23
23
|
)
|
|
24
24
|
|
|
25
25
|
|
|
26
|
+
def _grid_fixture_is_readable() -> bool:
|
|
27
|
+
try:
|
|
28
|
+
return GRID_PATH.is_file()
|
|
29
|
+
except OSError:
|
|
30
|
+
return False
|
|
31
|
+
|
|
32
|
+
|
|
26
33
|
def _load_grid_module():
|
|
27
|
-
if not
|
|
34
|
+
if not _grid_fixture_is_readable():
|
|
28
35
|
pytest.skip(
|
|
29
|
-
f"external Grid fixture is unavailable: {GRID_PATH}",
|
|
36
|
+
f"external Grid fixture is unavailable or unreadable: {GRID_PATH}",
|
|
30
37
|
allow_module_level=True,
|
|
31
38
|
)
|
|
32
39
|
spec = importlib.util.spec_from_file_location("phase47c_grid_alpha", GRID_PATH)
|
|
@@ -20,10 +20,17 @@ GRID_PATH = Path(
|
|
|
20
20
|
)
|
|
21
21
|
|
|
22
22
|
|
|
23
|
+
def _grid_fixture_is_readable() -> bool:
|
|
24
|
+
try:
|
|
25
|
+
return GRID_PATH.is_file()
|
|
26
|
+
except OSError:
|
|
27
|
+
return False
|
|
28
|
+
|
|
29
|
+
|
|
23
30
|
def _load_grid_module():
|
|
24
|
-
if not
|
|
31
|
+
if not _grid_fixture_is_readable():
|
|
25
32
|
pytest.skip(
|
|
26
|
-
f"external Grid fixture is unavailable: {GRID_PATH}",
|
|
33
|
+
f"external Grid fixture is unavailable or unreadable: {GRID_PATH}",
|
|
27
34
|
allow_module_level=True,
|
|
28
35
|
)
|
|
29
36
|
spec = importlib.util.spec_from_file_location("phase47d_grid_alpha", GRID_PATH)
|