rangebar 12.1.1__tar.gz → 12.1.2__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.
- {rangebar-12.1.1 → rangebar-12.1.2}/.mise.toml +13 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/CHANGELOG.md +7 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/Cargo.lock +9 -9
- {rangebar-12.1.1 → rangebar-12.1.2}/Cargo.toml +1 -1
- {rangebar-12.1.1 → rangebar-12.1.2}/PKG-INFO +1 -1
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-core/src/interbar.rs +59 -7
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-core/src/processor.rs +22 -2
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/constants.py +11 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/orchestration/helpers.py +29 -4
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/orchestration/range_bars.py +16 -4
- {rangebar-12.1.1 → rangebar-12.1.2}/.cargo/config.toml +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/.gitignore +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/.mcp.json +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/.mise/tasks/bench.toml +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/.mise/tasks/cache.toml +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/.mise/tasks/checksum.toml +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/.mise/tasks/deps.toml +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/.mise/tasks/dev.toml +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/.mise/tasks/diag.toml +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/.mise/tasks/prof.toml +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/.mise/tasks/release.toml +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/.mise/tasks/research.toml +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/.mise/tasks/smoke.toml +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/.mise/tasks/validate.toml +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/.pre-commit-config.yaml +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/.releaserc.yml +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/CLAUDE.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/LICENSE +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/README.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/RESUME.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/STATISTICAL_VALIDITY_AUDIT.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/benches/rangebar_bench.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/build.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/CLAUDE.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-core/CHANGELOG.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-core/Cargo.toml +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-core/README.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-core/src/arrow_export.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-core/src/checkpoint.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-core/src/fixed_point.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-core/src/intrabar/drawdown.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-core/src/intrabar/features.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-core/src/intrabar/ith.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-core/src/intrabar/mod.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-core/src/intrabar/normalize.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-core/src/intrabar/types.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-core/src/lib.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-core/src/test_data_loader.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-core/src/test_utils/generators.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-core/src/test_utils/mod.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-core/src/timestamp.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-core/src/types.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-core/tests/cross_boundary_validation.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-core/tests/cross_date_real_data_validation.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-core/tests/cross_year_boundary_test.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-core/tests/incomplete_bar_continuation_proof.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-providers/CHANGELOG.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-providers/Cargo.toml +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-providers/README.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-providers/src/binance/checksum.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-providers/src/binance/historical.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-providers/src/binance/mod.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-providers/src/binance/symbols.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-providers/src/binance/websocket.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-providers/src/exness/builder.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-providers/src/exness/client.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-providers/src/exness/conversion.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-providers/src/exness/mod.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-providers/src/exness/types.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-providers/src/lib.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-streaming/CHANGELOG.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-streaming/Cargo.toml +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-streaming/README.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-streaming/src/indicators.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-streaming/src/lib.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-streaming/src/processor.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-streaming/src/replay_buffer.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-streaming/src/stats.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-streaming/src/universal.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/deny.toml +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/docs/ARCHITECTURE.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/docs/CONTEXT.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/docs/MEMORY_REMEDIATION_PLAN.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/docs/adr/2026-01-31-realtime-streaming-api.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/docs/analysis/2025-10-10-flash-crash.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/docs/api.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/docs/development/PERFORMANCE.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/docs/development/RELEASE.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/docs/migration-v8.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/docs/plans/issue-59-inter-bar-features.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/docs/rangebar_core_api.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/docs/research/2026-02-02-intrabar-microstructure-claude-opus.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/docs/research/2026-02-02-intrabar-microstructure-gemini-3-pro.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/docs/research/2026-02-03-cfm-optimal-threshold-gemini-3-pro.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/docs/research/2026-02-03-memory-efficient-streaming.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/docs/research/INDEX.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/docs/research/adversarial-audit-methodology.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/docs/research/external/time-to-convergence-stationarity-gap.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/docs/research/labeling-for-ml.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/docs/research/market-regime-patterns.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/docs/research/multi-threshold-patterns.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/docs/research/multifactor-patterns.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/docs/research/pattern-research-summary.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/docs/research/price-action-patterns.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/docs/research/tda-parameter-sensitivity-audit.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/docs/research/tda-regime-patterns.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/docs/research/volatility-regime-patterns.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/docs/verification/issue-62-verification-report.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/examples/README.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/examples/backtesting_integration.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/examples/basic_usage.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/examples/binance_csv_example.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/examples/get_range_bars_example.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/examples/validate_output.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/examples/with_clickhouse_cache.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/package-lock.json +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/package.json +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/pyproject.toml +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/CLAUDE.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/__init__.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/__init__.pyi +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/checkpoint.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/cli.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/clickhouse/CLAUDE.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/clickhouse/__init__.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/clickhouse/bulk_operations.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/clickhouse/cache.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/clickhouse/client.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/clickhouse/config.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/clickhouse/mixin.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/clickhouse/preflight.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/clickhouse/query_operations.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/clickhouse/schema.sql +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/clickhouse/tunnel.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/conversion.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/exceptions.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/exness.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/hooks.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/logging.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/notify/__init__.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/notify/pushover.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/notify/telegram.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/orchestration/__init__.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/orchestration/count_bounded.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/orchestration/models.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/orchestration/precompute.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/orchestration/tick_fetcher.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/ouroboros.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/processors/__init__.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/processors/api.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/processors/core.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/resource_guard.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/storage/__init__.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/storage/checksum_registry.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/storage/parquet.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/streaming.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/threshold.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/validation/__init__.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/validation/cache_staleness.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/validation/continuity.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/validation/gap_classification.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/validation/post_storage.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/validation/tier1.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/python/rangebar/validation/tier2.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/rust-toolchain.toml +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/rustfmt.toml +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/adwin_regime_detection_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/analyze_flash_crash.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/bootstrap_permutation_validation_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/build-release.sh +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/cache_clear.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/cache_status.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/check-release-config.sh +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/coarse_to_fine_cascade.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/combined_pattern_audit_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/combined_regime_analysis_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/combined_rv_alignment_analysis_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/cross_asset_correlation_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/cross_regime_correlation_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/cross_threshold_alignment.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/dependency_monitor.sh +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/direction_patterns_reaudit.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/download_exness_eurusd.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/download_exness_forex.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/duration_autocorrelation.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/duration_autocorrelation_audit.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/duration_volatility_prediction.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/fdr_corrected_patterns.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/fill_all_symbols.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/fill_gaps_2025_2026.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/fill_gaps_littleblack.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/fill_gaps_retry.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/historical_formation_patterns_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/historical_formation_regime_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/hurst_adjusted_kelly_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/hurst_adjusted_psr_analysis_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/hurst_exponent_analysis_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/hurst_multi_estimator_audit.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/microstructure_clickhouse.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/microstructure_patterns.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/microstructure_simple.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/monitor_population.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/multi_threshold_pattern_analysis_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/multibar_continuation.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/multibar_forward_returns_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/multifactor_multigranularity_patterns.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/multifactor_patterns.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/multifactor_patterns_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/multithreshold_combinations_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/multithreshold_regime_combinations_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/oos_validation_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/parameter_sensitivity_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/pattern_correlation_analysis_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/pattern_return_profiles_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/pattern_return_stats.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/populate_1000dbps.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/populate_250dbps.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/populate_250dbps_extended.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/populate_safe.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/position_sizing_analysis_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/process_exness_eurusd_to_cache.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/profiling_tools.sh +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/psr_mintrl_analysis_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/publish-to-pypi.sh +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/publish-wheels.sh +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/purge_crypto_low_threshold.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/regenerate_cache.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/regime_analysis.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/regime_analysis_50dbps_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/regime_analysis_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/regime_transition_analysis_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/run_large_scale_benchmark.sh +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/run_length_momentum_analysis.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/run_length_momentum_multi_symbol.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/run_length_momentum_wfo.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/rv_return_profile_analysis_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/semantic-release.sh +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/tda_break_event_alignment_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/tda_conditioned_patterns.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/tda_cupy_accelerated.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/tda_gpu_analysis.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/tda_hurst_by_regime_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/tda_parameter_sweep_audit.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/tda_regime_hurst_analysis_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/tda_regime_pattern_analysis_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/tda_ripser_plusplus.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/tda_rolling_threshold.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/tda_solusdt_250_audit.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/tda_solusdt_250_littleblack.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/tda_structural_break_analysis_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/tda_volatility_forecast.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/tda_wfo_3way.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/tda_wfo_abstain.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/tda_wfo_audit.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/temporal_safe_patterns_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/three_bar_alignment_analysis_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/three_bar_pattern_analysis_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/three_bar_pattern_audit_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/three_factor_hurst_analysis_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/three_factor_pattern_analysis_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/transaction_cost_analysis_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/trend_filter_analysis.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/upload_eurusd_to_clickhouse.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/validate_clickhouse.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/validate_memory_efficiency.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/validate_microstructure_features.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/validate_n_range_bars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/volatility_regime_analysis_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/volatility_regime_audit_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/volume_conditioned_patterns.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/scripts/volume_conditioned_patterns_polars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/src/lib.rs +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/test_data/BTCUSDT/BTCUSDT_aggTrades_20250901.csv +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/test_data/ETHUSDT/ETHUSDT_aggTrades_20250901.csv +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/test_data/README.md +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/tests/conftest.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/tests/fixtures/.gitignore +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/tests/fixtures/BTCUSDT-aggTrades-2024-01-01.zip +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/tests/test_cache_schema_evolution.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/tests/test_clickhouse.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/tests/test_clickhouse_integration.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/tests/test_crypto_minimum_threshold.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/tests/test_e2e_optimized.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/tests/test_edge_cases.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/tests/test_examples.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/tests/test_get_n_range_bars.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/tests/test_get_range_bars_e2e.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/tests/test_issue_5_reproduction.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/tests/test_issues_7_8.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/tests/test_microstructure_features.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/tests/test_ouroboros.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/tests/test_polars_only_downstream.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/tests/test_preflight.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/tests/test_python_api.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/tests/test_real_data.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/tests/test_rust_bindings.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/tests/test_storage.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/tests/test_streaming.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/tests/test_validation_presets.py +0 -0
- {rangebar-12.1.1 → rangebar-12.1.2}/uv.lock +0 -0
|
@@ -27,6 +27,19 @@ RANGEBAR_FOREX_MIN_THRESHOLD = "50"
|
|
|
27
27
|
RANGEBAR_EQUITIES_MIN_THRESHOLD = "100"
|
|
28
28
|
RANGEBAR_UNKNOWN_MIN_THRESHOLD = "1"
|
|
29
29
|
|
|
30
|
+
# =============================================================================
|
|
31
|
+
# SSoT: Microstructure Feature Defaults (Issue #68)
|
|
32
|
+
# =============================================================================
|
|
33
|
+
# When include_microstructure=True, these defaults are used unless overridden.
|
|
34
|
+
# INTER_BAR_LOOKBACK_COUNT: Trades in lookback window for inter-bar features.
|
|
35
|
+
# - Recommended: 100-500 (200 is good balance of signal vs compute)
|
|
36
|
+
# - Set to 0 to disable inter-bar features while keeping intra-bar
|
|
37
|
+
# INCLUDE_INTRA_BAR_FEATURES: Enable ITH + statistical features within bars.
|
|
38
|
+
# - "true" enables 22 intra_* columns (ITH, complexity, statistical)
|
|
39
|
+
# - "false" disables (use if you only need lookback_* features)
|
|
40
|
+
RANGEBAR_INTER_BAR_LOOKBACK_COUNT = "200"
|
|
41
|
+
RANGEBAR_INCLUDE_INTRA_BAR_FEATURES = "true"
|
|
42
|
+
|
|
30
43
|
# =============================================================================
|
|
31
44
|
# GitHub Account Isolation
|
|
32
45
|
# =============================================================================
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
## [12.1.2](https://github.com/terrylica/rangebar-py/compare/v12.1.1...v12.1.2) (2026-02-04)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **interbar:** preserve lookback trades across bar boundaries ([#68](https://github.com/terrylica/rangebar-py/issues/68)) ([d8e3fc9](https://github.com/terrylica/rangebar-py/commit/d8e3fc94bc160c20314801e5e3be684969972888))
|
|
7
|
+
|
|
1
8
|
## [12.1.1](https://github.com/terrylica/rangebar-py/compare/v12.1.0...v12.1.1) (2026-02-03)
|
|
2
9
|
|
|
3
10
|
|
|
@@ -3337,7 +3337,7 @@ dependencies = [
|
|
|
3337
3337
|
|
|
3338
3338
|
[[package]]
|
|
3339
3339
|
name = "rangebar"
|
|
3340
|
-
version = "12.1.
|
|
3340
|
+
version = "12.1.2"
|
|
3341
3341
|
dependencies = [
|
|
3342
3342
|
"chrono",
|
|
3343
3343
|
"insta",
|
|
@@ -3359,7 +3359,7 @@ dependencies = [
|
|
|
3359
3359
|
|
|
3360
3360
|
[[package]]
|
|
3361
3361
|
name = "rangebar-batch"
|
|
3362
|
-
version = "12.1.
|
|
3362
|
+
version = "12.1.2"
|
|
3363
3363
|
dependencies = [
|
|
3364
3364
|
"polars",
|
|
3365
3365
|
"rangebar-core",
|
|
@@ -3371,7 +3371,7 @@ dependencies = [
|
|
|
3371
3371
|
|
|
3372
3372
|
[[package]]
|
|
3373
3373
|
name = "rangebar-cli"
|
|
3374
|
-
version = "12.1.
|
|
3374
|
+
version = "12.1.2"
|
|
3375
3375
|
dependencies = [
|
|
3376
3376
|
"chrono",
|
|
3377
3377
|
"clap",
|
|
@@ -3396,7 +3396,7 @@ dependencies = [
|
|
|
3396
3396
|
|
|
3397
3397
|
[[package]]
|
|
3398
3398
|
name = "rangebar-config"
|
|
3399
|
-
version = "12.1.
|
|
3399
|
+
version = "12.1.2"
|
|
3400
3400
|
dependencies = [
|
|
3401
3401
|
"chrono",
|
|
3402
3402
|
"config",
|
|
@@ -3408,7 +3408,7 @@ dependencies = [
|
|
|
3408
3408
|
|
|
3409
3409
|
[[package]]
|
|
3410
3410
|
name = "rangebar-core"
|
|
3411
|
-
version = "12.1.
|
|
3411
|
+
version = "12.1.2"
|
|
3412
3412
|
dependencies = [
|
|
3413
3413
|
"ahash",
|
|
3414
3414
|
"arrow",
|
|
@@ -3425,7 +3425,7 @@ dependencies = [
|
|
|
3425
3425
|
|
|
3426
3426
|
[[package]]
|
|
3427
3427
|
name = "rangebar-io"
|
|
3428
|
-
version = "12.1.
|
|
3428
|
+
version = "12.1.2"
|
|
3429
3429
|
dependencies = [
|
|
3430
3430
|
"polars",
|
|
3431
3431
|
"rangebar-core",
|
|
@@ -3435,7 +3435,7 @@ dependencies = [
|
|
|
3435
3435
|
|
|
3436
3436
|
[[package]]
|
|
3437
3437
|
name = "rangebar-providers"
|
|
3438
|
-
version = "12.1.
|
|
3438
|
+
version = "12.1.2"
|
|
3439
3439
|
dependencies = [
|
|
3440
3440
|
"chrono",
|
|
3441
3441
|
"csv",
|
|
@@ -3455,7 +3455,7 @@ dependencies = [
|
|
|
3455
3455
|
|
|
3456
3456
|
[[package]]
|
|
3457
3457
|
name = "rangebar-py"
|
|
3458
|
-
version = "12.1.
|
|
3458
|
+
version = "12.1.2"
|
|
3459
3459
|
dependencies = [
|
|
3460
3460
|
"arrow",
|
|
3461
3461
|
"arrow-array",
|
|
@@ -3474,7 +3474,7 @@ dependencies = [
|
|
|
3474
3474
|
|
|
3475
3475
|
[[package]]
|
|
3476
3476
|
name = "rangebar-streaming"
|
|
3477
|
-
version = "12.1.
|
|
3477
|
+
version = "12.1.2"
|
|
3478
3478
|
dependencies = [
|
|
3479
3479
|
"async-trait",
|
|
3480
3480
|
"chrono",
|
|
@@ -10,7 +10,7 @@ resolver = "2"
|
|
|
10
10
|
[workspace.package]
|
|
11
11
|
# CRITICAL: Prevent crates.io publishing - this is a PyPI-only project
|
|
12
12
|
publish = false
|
|
13
|
-
version = "12.1.
|
|
13
|
+
version = "12.1.2"
|
|
14
14
|
authors = ["Terry Li <terry@eonlabs.com>"]
|
|
15
15
|
categories = ["algorithms", "data-structures", "finance"]
|
|
16
16
|
documentation = "https://docs.rs/rangebar"
|
|
@@ -145,41 +145,93 @@ pub struct TradeHistory {
|
|
|
145
145
|
trades: VecDeque<TradeSnapshot>,
|
|
146
146
|
/// Configuration for lookback
|
|
147
147
|
config: InterBarConfig,
|
|
148
|
+
/// Timestamp threshold: trades with timestamp < this are protected from pruning.
|
|
149
|
+
/// Set to the oldest timestamp we might need for lookback computation.
|
|
150
|
+
/// Updated each time a new bar opens.
|
|
151
|
+
protected_until: Option<i64>,
|
|
148
152
|
}
|
|
149
153
|
|
|
150
154
|
impl TradeHistory {
|
|
151
155
|
/// Create new trade history with given configuration
|
|
152
156
|
pub fn new(config: InterBarConfig) -> Self {
|
|
153
157
|
let capacity = match &config.lookback_mode {
|
|
154
|
-
LookbackMode::FixedCount(n) => *n,
|
|
155
|
-
LookbackMode::FixedWindow(_) =>
|
|
158
|
+
LookbackMode::FixedCount(n) => *n * 2, // 2x capacity to hold pre-bar + in-bar trades
|
|
159
|
+
LookbackMode::FixedWindow(_) => 2000, // Initial capacity for time-based
|
|
156
160
|
};
|
|
157
161
|
Self {
|
|
158
162
|
trades: VecDeque::with_capacity(capacity),
|
|
159
163
|
config,
|
|
164
|
+
protected_until: None,
|
|
160
165
|
}
|
|
161
166
|
}
|
|
162
167
|
|
|
163
168
|
/// Push a new trade to the history buffer
|
|
164
169
|
///
|
|
165
|
-
/// Automatically prunes old entries based on lookback mode
|
|
170
|
+
/// Automatically prunes old entries based on lookback mode, but preserves
|
|
171
|
+
/// trades needed for lookback computation (timestamp < protected_until).
|
|
166
172
|
pub fn push(&mut self, trade: &AggTrade) {
|
|
167
173
|
let snapshot = TradeSnapshot::from(trade);
|
|
168
174
|
self.trades.push_back(snapshot);
|
|
169
|
-
self.prune(
|
|
175
|
+
self.prune();
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/// Notify that a new bar has opened at the given timestamp
|
|
179
|
+
///
|
|
180
|
+
/// This sets the protection threshold to ensure trades from before the bar
|
|
181
|
+
/// opened are preserved for lookback computation. The protection extends
|
|
182
|
+
/// until the next bar opens and calls this method again.
|
|
183
|
+
pub fn on_bar_open(&mut self, bar_open_time: i64) {
|
|
184
|
+
// Protect all trades with timestamp < bar_open_time
|
|
185
|
+
// These are the trades that can be used for lookback computation
|
|
186
|
+
self.protected_until = Some(bar_open_time);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/// Notify that the current bar has closed
|
|
190
|
+
///
|
|
191
|
+
/// This is intentionally a no-op. We keep protection until the next bar opens,
|
|
192
|
+
/// which ensures the lookback window is available for feature computation.
|
|
193
|
+
pub fn on_bar_close(&mut self) {
|
|
194
|
+
// No-op: Keep protection until next bar opens
|
|
195
|
+
// This ensures lookback trades survive between bars
|
|
170
196
|
}
|
|
171
197
|
|
|
172
198
|
/// Prune old trades based on lookback configuration
|
|
173
|
-
|
|
199
|
+
///
|
|
200
|
+
/// Pruning logic:
|
|
201
|
+
/// - For FixedCount(n): Keep up to 2*n trades total, but never prune trades
|
|
202
|
+
/// with timestamp < protected_until (needed for lookback)
|
|
203
|
+
/// - For FixedWindow: Standard time-based pruning, but respect protected_until
|
|
204
|
+
fn prune(&mut self) {
|
|
174
205
|
match &self.config.lookback_mode {
|
|
175
206
|
LookbackMode::FixedCount(n) => {
|
|
176
|
-
|
|
207
|
+
// Keep at most 2*n trades (n for lookback + n for next bar's lookback)
|
|
208
|
+
let max_trades = *n * 2;
|
|
209
|
+
while self.trades.len() > max_trades {
|
|
210
|
+
// Check if front trade is protected
|
|
211
|
+
if let Some(front) = self.trades.front() {
|
|
212
|
+
if let Some(protected) = self.protected_until {
|
|
213
|
+
if front.timestamp < protected {
|
|
214
|
+
// Don't prune protected trades
|
|
215
|
+
break;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
177
219
|
self.trades.pop_front();
|
|
178
220
|
}
|
|
179
221
|
}
|
|
180
222
|
LookbackMode::FixedWindow(window_us) => {
|
|
181
|
-
|
|
223
|
+
// Find the oldest trade we need
|
|
224
|
+
let newest_timestamp = self.trades.back().map(|t| t.timestamp).unwrap_or(0);
|
|
225
|
+
let cutoff = newest_timestamp - window_us;
|
|
226
|
+
|
|
182
227
|
while let Some(front) = self.trades.front() {
|
|
228
|
+
// Respect protection
|
|
229
|
+
if let Some(protected) = self.protected_until {
|
|
230
|
+
if front.timestamp < protected {
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
// Prune if outside time window
|
|
183
235
|
if front.timestamp < cutoff {
|
|
184
236
|
self.trades.pop_front();
|
|
185
237
|
} else {
|
|
@@ -260,6 +260,10 @@ impl RangeBarProcessor {
|
|
|
260
260
|
// This matches the batch path's defer_open semantics - the breaching trade
|
|
261
261
|
// closes the current bar, and the NEXT trade opens the new bar.
|
|
262
262
|
if self.defer_open {
|
|
263
|
+
// Issue #68: Notify history that new bar is opening (preserves pre-bar trades)
|
|
264
|
+
if let Some(ref mut history) = self.trade_history {
|
|
265
|
+
history.on_bar_open(trade.timestamp);
|
|
266
|
+
}
|
|
263
267
|
self.current_bar_state = Some(if self.include_intra_bar_features {
|
|
264
268
|
RangeBarState::new_with_trade_accumulation(&trade, self.threshold_decimal_bps)
|
|
265
269
|
} else {
|
|
@@ -272,6 +276,10 @@ impl RangeBarProcessor {
|
|
|
272
276
|
match &mut self.current_bar_state {
|
|
273
277
|
None => {
|
|
274
278
|
// First trade - initialize new bar
|
|
279
|
+
// Issue #68: Notify history that new bar is opening (preserves pre-bar trades)
|
|
280
|
+
if let Some(ref mut history) = self.trade_history {
|
|
281
|
+
history.on_bar_open(trade.timestamp);
|
|
282
|
+
}
|
|
275
283
|
self.current_bar_state = Some(if self.include_intra_bar_features {
|
|
276
284
|
RangeBarState::new_with_trade_accumulation(&trade, self.threshold_decimal_bps)
|
|
277
285
|
} else {
|
|
@@ -313,9 +321,11 @@ impl RangeBarProcessor {
|
|
|
313
321
|
|
|
314
322
|
// Issue #59: Compute inter-bar features from lookback window
|
|
315
323
|
// Features are computed from trades BEFORE bar.open_time (no lookahead)
|
|
316
|
-
if let Some(ref history) = self.trade_history {
|
|
324
|
+
if let Some(ref mut history) = self.trade_history {
|
|
317
325
|
let inter_bar_features = history.compute_features(bar_state.bar.open_time);
|
|
318
326
|
bar_state.bar.set_inter_bar_features(&inter_bar_features);
|
|
327
|
+
// Issue #68: Notify history that bar is closing (resumes normal pruning)
|
|
328
|
+
history.on_bar_close();
|
|
319
329
|
}
|
|
320
330
|
|
|
321
331
|
// Issue #59: Compute intra-bar features from accumulated trades
|
|
@@ -451,6 +461,10 @@ impl RangeBarProcessor {
|
|
|
451
461
|
|
|
452
462
|
if defer_open {
|
|
453
463
|
// Previous bar closed, this agg_record opens new bar
|
|
464
|
+
// Issue #68: Notify history that new bar is opening (preserves pre-bar trades)
|
|
465
|
+
if let Some(ref mut history) = self.trade_history {
|
|
466
|
+
history.on_bar_open(agg_record.timestamp);
|
|
467
|
+
}
|
|
454
468
|
current_bar = Some(if self.include_intra_bar_features {
|
|
455
469
|
RangeBarState::new_with_trade_accumulation(agg_record, self.threshold_decimal_bps)
|
|
456
470
|
} else {
|
|
@@ -463,6 +477,10 @@ impl RangeBarProcessor {
|
|
|
463
477
|
match current_bar {
|
|
464
478
|
None => {
|
|
465
479
|
// First bar initialization
|
|
480
|
+
// Issue #68: Notify history that new bar is opening (preserves pre-bar trades)
|
|
481
|
+
if let Some(ref mut history) = self.trade_history {
|
|
482
|
+
history.on_bar_open(agg_record.timestamp);
|
|
483
|
+
}
|
|
466
484
|
current_bar = Some(if self.include_intra_bar_features {
|
|
467
485
|
RangeBarState::new_with_trade_accumulation(agg_record, self.threshold_decimal_bps)
|
|
468
486
|
} else {
|
|
@@ -504,10 +522,12 @@ impl RangeBarProcessor {
|
|
|
504
522
|
bar_state.bar.compute_microstructure_features();
|
|
505
523
|
|
|
506
524
|
// Issue #59: Compute inter-bar features from lookback window
|
|
507
|
-
if let Some(ref history) = self.trade_history {
|
|
525
|
+
if let Some(ref mut history) = self.trade_history {
|
|
508
526
|
let inter_bar_features =
|
|
509
527
|
history.compute_features(bar_state.bar.open_time);
|
|
510
528
|
bar_state.bar.set_inter_bar_features(&inter_bar_features);
|
|
529
|
+
// Issue #68: Notify history that bar is closing (resumes normal pruning)
|
|
530
|
+
history.on_bar_close();
|
|
511
531
|
}
|
|
512
532
|
|
|
513
533
|
// Issue #59: Compute intra-bar features from accumulated trades
|
|
@@ -11,6 +11,12 @@ SSoT (Single Source of Truth) for:
|
|
|
11
11
|
- _CRYPTO_BASES: Known crypto base symbols for asset class detection
|
|
12
12
|
- _FOREX_CURRENCIES: Known forex currencies for asset class detection
|
|
13
13
|
- MEM_GUARDS: Memory guard registry (Issue #49)
|
|
14
|
+
|
|
15
|
+
Environment Variable SSoT (from .mise.toml):
|
|
16
|
+
- RANGEBAR_CRYPTO_MIN_THRESHOLD: Minimum threshold for crypto (1000 dbps)
|
|
17
|
+
- RANGEBAR_FOREX_MIN_THRESHOLD: Minimum threshold for forex (50 dbps)
|
|
18
|
+
- RANGEBAR_INTER_BAR_LOOKBACK_COUNT: Lookback for inter-bar features (200)
|
|
19
|
+
- RANGEBAR_INCLUDE_INTRA_BAR_FEATURES: Auto-enable intra-bar features (true)
|
|
14
20
|
"""
|
|
15
21
|
|
|
16
22
|
from __future__ import annotations
|
|
@@ -341,4 +347,9 @@ MEM_GUARDS: dict[str, dict[str, str]] = {
|
|
|
341
347
|
"location": "orchestration/helpers.py:304",
|
|
342
348
|
"stage": "processing",
|
|
343
349
|
},
|
|
350
|
+
"MEM-012": {
|
|
351
|
+
"description": "Streaming bar batches (10K) to prevent OOM",
|
|
352
|
+
"location": "orchestration/helpers.py:236",
|
|
353
|
+
"stage": "processing",
|
|
354
|
+
},
|
|
344
355
|
}
|
|
@@ -95,9 +95,19 @@ def _stream_range_bars_binance(
|
|
|
95
95
|
}[market]
|
|
96
96
|
|
|
97
97
|
# Issue #68: Auto-enable v12 features when include_microstructure=True
|
|
98
|
+
# SSoT: Defaults from mise.toml env vars
|
|
99
|
+
import os
|
|
100
|
+
|
|
98
101
|
effective_lookback = inter_bar_lookback_count
|
|
99
102
|
if include_microstructure and effective_lookback is None:
|
|
100
|
-
effective_lookback =
|
|
103
|
+
effective_lookback = int(
|
|
104
|
+
os.environ.get("RANGEBAR_INTER_BAR_LOOKBACK_COUNT", "200")
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
enable_intra = False
|
|
108
|
+
if include_microstructure:
|
|
109
|
+
intra_env = os.environ.get("RANGEBAR_INCLUDE_INTRA_BAR_FEATURES", "true")
|
|
110
|
+
enable_intra = intra_env.lower() in ("true", "1", "yes")
|
|
101
111
|
|
|
102
112
|
# Create processor with symbol for checkpoint support
|
|
103
113
|
processor = RangeBarProcessor(
|
|
@@ -105,7 +115,7 @@ def _stream_range_bars_binance(
|
|
|
105
115
|
symbol=symbol,
|
|
106
116
|
prevent_same_timestamp_close=prevent_same_timestamp_close,
|
|
107
117
|
inter_bar_lookback_count=effective_lookback,
|
|
108
|
-
include_intra_bar_features=
|
|
118
|
+
include_intra_bar_features=enable_intra,
|
|
109
119
|
)
|
|
110
120
|
bar_buffer: list[dict] = []
|
|
111
121
|
|
|
@@ -357,12 +367,27 @@ def _process_binance_trades(
|
|
|
357
367
|
|
|
358
368
|
# Use provided processor or create new one
|
|
359
369
|
if processor is None:
|
|
370
|
+
# Issue #68: Auto-enable v12 features when include_microstructure=True
|
|
371
|
+
# This ensures all code paths apply defaults, not just range_bars.py
|
|
372
|
+
import os
|
|
373
|
+
|
|
374
|
+
effective_lookback = inter_bar_lookback_count
|
|
375
|
+
if include_microstructure and effective_lookback is None:
|
|
376
|
+
effective_lookback = int(
|
|
377
|
+
os.environ.get("RANGEBAR_INTER_BAR_LOOKBACK_COUNT", "200")
|
|
378
|
+
)
|
|
379
|
+
|
|
380
|
+
enable_intra = include_intra_bar_features
|
|
381
|
+
if include_microstructure and not enable_intra:
|
|
382
|
+
intra_env = os.environ.get("RANGEBAR_INCLUDE_INTRA_BAR_FEATURES", "true")
|
|
383
|
+
enable_intra = intra_env.lower() in ("true", "1", "yes")
|
|
384
|
+
|
|
360
385
|
processor = RangeBarProcessor(
|
|
361
386
|
threshold_decimal_bps,
|
|
362
387
|
symbol=symbol,
|
|
363
388
|
prevent_same_timestamp_close=prevent_same_timestamp_close,
|
|
364
|
-
inter_bar_lookback_count=
|
|
365
|
-
include_intra_bar_features=
|
|
389
|
+
inter_bar_lookback_count=effective_lookback,
|
|
390
|
+
include_intra_bar_features=enable_intra,
|
|
366
391
|
)
|
|
367
392
|
|
|
368
393
|
# MEM-012: Stream bars in batches instead of accumulating all in memory
|
|
@@ -545,11 +545,23 @@ def get_range_bars(
|
|
|
545
545
|
|
|
546
546
|
# Process segment (reuse processor for state continuity within segment)
|
|
547
547
|
# Issue #68: Auto-enable v12 features when include_microstructure=True
|
|
548
|
-
#
|
|
549
|
-
#
|
|
548
|
+
# SSoT: Defaults from mise.toml env vars (RANGEBAR_INTER_BAR_LOOKBACK_COUNT,
|
|
549
|
+
# RANGEBAR_INCLUDE_INTRA_BAR_FEATURES)
|
|
550
|
+
import os
|
|
551
|
+
|
|
550
552
|
effective_lookback = inter_bar_lookback_count
|
|
551
553
|
if include_microstructure and effective_lookback is None:
|
|
552
|
-
|
|
554
|
+
# Read from env (mise SSoT) with fallback
|
|
555
|
+
effective_lookback = int(
|
|
556
|
+
os.environ.get("RANGEBAR_INTER_BAR_LOOKBACK_COUNT", "200")
|
|
557
|
+
)
|
|
558
|
+
|
|
559
|
+
# Intra-bar features: auto-enable if microstructure requested
|
|
560
|
+
# SSoT from mise.toml, defaults to True when include_microstructure=True
|
|
561
|
+
enable_intra = False
|
|
562
|
+
if include_microstructure:
|
|
563
|
+
intra_env = os.environ.get("RANGEBAR_INCLUDE_INTRA_BAR_FEATURES", "true")
|
|
564
|
+
enable_intra = intra_env.lower() in ("true", "1", "yes")
|
|
553
565
|
|
|
554
566
|
segment_bars, processor = _process_binance_trades(
|
|
555
567
|
segment_ticks,
|
|
@@ -560,7 +572,7 @@ def get_range_bars(
|
|
|
560
572
|
symbol=symbol,
|
|
561
573
|
prevent_same_timestamp_close=prevent_same_timestamp_close,
|
|
562
574
|
inter_bar_lookback_count=effective_lookback,
|
|
563
|
-
include_intra_bar_features=
|
|
575
|
+
include_intra_bar_features=enable_intra,
|
|
564
576
|
)
|
|
565
577
|
|
|
566
578
|
if segment_bars is not None and not segment_bars.empty:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-core/tests/cross_date_real_data_validation.rs
RENAMED
|
File without changes
|
|
File without changes
|
{rangebar-12.1.1 → rangebar-12.1.2}/crates/rangebar-core/tests/incomplete_bar_continuation_proof.rs
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rangebar-12.1.1 → rangebar-12.1.2}/docs/research/2026-02-02-intrabar-microstructure-claude-opus.md
RENAMED
|
File without changes
|