rangebar 11.6.0__tar.gz → 11.6.1__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-11.6.0 → rangebar-11.6.1}/.mise.toml +5 -6
- {rangebar-11.6.0 → rangebar-11.6.1}/CHANGELOG.md +9 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/Cargo.lock +9 -9
- {rangebar-11.6.0 → rangebar-11.6.1}/Cargo.toml +2 -2
- {rangebar-11.6.0 → rangebar-11.6.1}/PKG-INFO +1 -1
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/resource_guard.py +80 -6
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/publish-to-pypi.sh +37 -30
- {rangebar-11.6.0 → rangebar-11.6.1}/.gitignore +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/.mcp.json +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/.pre-commit-config.yaml +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/.releaserc.yml +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/CLAUDE.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/LICENSE +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/README.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/RESUME.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/STATISTICAL_VALIDITY_AUDIT.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/benches/rangebar_bench.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/build.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/CLAUDE.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-core/CHANGELOG.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-core/Cargo.toml +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-core/README.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-core/src/arrow_export.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-core/src/checkpoint.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-core/src/fixed_point.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-core/src/interbar.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-core/src/lib.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-core/src/processor.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-core/src/test_data_loader.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-core/src/test_utils/generators.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-core/src/test_utils/mod.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-core/src/timestamp.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-core/src/types.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-core/tests/cross_boundary_validation.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-core/tests/cross_date_real_data_validation.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-core/tests/cross_year_boundary_test.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-core/tests/incomplete_bar_continuation_proof.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-providers/CHANGELOG.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-providers/Cargo.toml +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-providers/README.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-providers/src/binance/checksum.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-providers/src/binance/historical.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-providers/src/binance/mod.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-providers/src/binance/symbols.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-providers/src/binance/websocket.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-providers/src/exness/builder.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-providers/src/exness/client.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-providers/src/exness/conversion.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-providers/src/exness/mod.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-providers/src/exness/types.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-providers/src/lib.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-streaming/CHANGELOG.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-streaming/Cargo.toml +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-streaming/README.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-streaming/src/indicators.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-streaming/src/lib.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-streaming/src/processor.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-streaming/src/replay_buffer.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-streaming/src/stats.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/crates/rangebar-streaming/src/universal.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/deny.toml +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/docs/ARCHITECTURE.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/docs/CONTEXT.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/docs/MEMORY_REMEDIATION_PLAN.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/docs/adr/2026-01-31-realtime-streaming-api.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/docs/analysis/2025-10-10-flash-crash.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/docs/api.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/docs/development/PERFORMANCE.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/docs/development/RELEASE.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/docs/migration-v8.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/docs/plans/issue-59-inter-bar-features.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/docs/rangebar_core_api.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/docs/research/2026-02-02-intrabar-microstructure-claude-opus.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/docs/research/2026-02-02-intrabar-microstructure-gemini-3-pro.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/docs/research/INDEX.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/docs/research/adversarial-audit-methodology.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/docs/research/external/time-to-convergence-stationarity-gap.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/docs/research/labeling-for-ml.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/docs/research/market-regime-patterns.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/docs/research/multi-threshold-patterns.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/docs/research/multifactor-patterns.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/docs/research/pattern-research-summary.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/docs/research/price-action-patterns.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/docs/research/tda-parameter-sensitivity-audit.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/docs/research/tda-regime-patterns.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/docs/research/volatility-regime-patterns.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/examples/README.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/examples/backtesting_integration.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/examples/basic_usage.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/examples/binance_csv_example.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/examples/get_range_bars_example.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/examples/validate_output.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/examples/with_clickhouse_cache.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/package-lock.json +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/package.json +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/pyproject.toml +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/CLAUDE.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/__init__.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/__init__.pyi +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/checkpoint.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/cli.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/clickhouse/CLAUDE.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/clickhouse/__init__.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/clickhouse/bulk_operations.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/clickhouse/cache.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/clickhouse/client.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/clickhouse/config.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/clickhouse/mixin.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/clickhouse/preflight.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/clickhouse/query_operations.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/clickhouse/schema.sql +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/clickhouse/tunnel.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/constants.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/conversion.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/exceptions.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/exness.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/hooks.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/logging.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/notify/__init__.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/notify/pushover.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/notify/telegram.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/orchestration/__init__.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/orchestration/count_bounded.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/orchestration/helpers.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/orchestration/models.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/orchestration/precompute.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/orchestration/range_bars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/orchestration/tick_fetcher.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/ouroboros.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/processors/__init__.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/processors/api.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/processors/core.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/storage/__init__.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/storage/checksum_registry.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/storage/parquet.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/streaming.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/validation/__init__.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/validation/cache_staleness.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/validation/continuity.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/validation/gap_classification.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/validation/post_storage.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/validation/tier1.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/python/rangebar/validation/tier2.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/rust-toolchain.toml +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/rustfmt.toml +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/adwin_regime_detection_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/analyze_flash_crash.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/bootstrap_permutation_validation_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/build-release.sh +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/cache_clear.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/cache_status.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/check-release-config.sh +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/coarse_to_fine_cascade.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/combined_pattern_audit_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/combined_regime_analysis_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/combined_rv_alignment_analysis_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/cross_asset_correlation_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/cross_regime_correlation_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/cross_threshold_alignment.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/dependency_monitor.sh +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/direction_patterns_reaudit.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/download_exness_eurusd.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/download_exness_forex.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/duration_autocorrelation.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/duration_autocorrelation_audit.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/duration_volatility_prediction.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/fdr_corrected_patterns.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/fill_all_symbols.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/fill_gaps_2025_2026.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/fill_gaps_littleblack.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/fill_gaps_retry.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/historical_formation_patterns_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/historical_formation_regime_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/hurst_adjusted_kelly_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/hurst_adjusted_psr_analysis_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/hurst_exponent_analysis_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/hurst_multi_estimator_audit.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/microstructure_clickhouse.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/microstructure_patterns.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/microstructure_simple.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/monitor_population.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/multi_threshold_pattern_analysis_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/multibar_continuation.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/multibar_forward_returns_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/multifactor_multigranularity_patterns.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/multifactor_patterns.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/multifactor_patterns_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/multithreshold_combinations_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/multithreshold_regime_combinations_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/oos_validation_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/parameter_sensitivity_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/pattern_correlation_analysis_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/pattern_return_profiles_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/pattern_return_stats.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/populate_1000dbps.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/populate_250dbps.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/populate_250dbps_extended.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/populate_safe.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/position_sizing_analysis_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/process_exness_eurusd_to_cache.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/profiling_tools.sh +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/psr_mintrl_analysis_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/publish-wheels.sh +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/regenerate_cache.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/regime_analysis.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/regime_analysis_50dbps_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/regime_analysis_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/regime_transition_analysis_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/run_large_scale_benchmark.sh +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/run_length_momentum_analysis.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/run_length_momentum_multi_symbol.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/run_length_momentum_wfo.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/rv_return_profile_analysis_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/semantic-release.sh +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/tda_break_event_alignment_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/tda_conditioned_patterns.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/tda_cupy_accelerated.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/tda_gpu_analysis.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/tda_hurst_by_regime_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/tda_parameter_sweep_audit.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/tda_regime_hurst_analysis_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/tda_regime_pattern_analysis_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/tda_ripser_plusplus.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/tda_rolling_threshold.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/tda_solusdt_250_audit.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/tda_solusdt_250_littleblack.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/tda_structural_break_analysis_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/tda_volatility_forecast.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/tda_wfo_3way.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/tda_wfo_abstain.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/tda_wfo_audit.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/temporal_safe_patterns_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/three_bar_alignment_analysis_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/three_bar_pattern_analysis_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/three_bar_pattern_audit_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/three_factor_hurst_analysis_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/three_factor_pattern_analysis_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/transaction_cost_analysis_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/trend_filter_analysis.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/upload_eurusd_to_clickhouse.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/validate_clickhouse.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/validate_memory_efficiency.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/validate_microstructure_features.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/validate_n_range_bars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/volatility_regime_analysis_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/volatility_regime_audit_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/volume_conditioned_patterns.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/scripts/volume_conditioned_patterns_polars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/src/lib.rs +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/test_data/BTCUSDT/BTCUSDT_aggTrades_20250901.csv +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/test_data/ETHUSDT/ETHUSDT_aggTrades_20250901.csv +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/test_data/README.md +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/tests/conftest.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/tests/fixtures/.gitignore +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/tests/fixtures/BTCUSDT-aggTrades-2024-01-01.zip +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/tests/test_cache_schema_evolution.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/tests/test_clickhouse.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/tests/test_clickhouse_integration.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/tests/test_e2e_optimized.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/tests/test_edge_cases.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/tests/test_examples.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/tests/test_get_n_range_bars.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/tests/test_get_range_bars_e2e.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/tests/test_issue_5_reproduction.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/tests/test_issues_7_8.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/tests/test_microstructure_features.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/tests/test_ouroboros.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/tests/test_polars_only_downstream.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/tests/test_preflight.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/tests/test_python_api.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/tests/test_real_data.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/tests/test_rust_bindings.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/tests/test_storage.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/tests/test_streaming.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/tests/test_validation_presets.py +0 -0
- {rangebar-11.6.0 → rangebar-11.6.1}/uv.lock +0 -0
|
@@ -17,12 +17,11 @@ GH_TOKEN = "{{ read_file(path=env.HOME ~ '/.claude/.secrets/gh-token-terrylica')
|
|
|
17
17
|
GITHUB_TOKEN = "{{ read_file(path=env.HOME ~ '/.claude/.secrets/gh-token-terrylica') | trim }}"
|
|
18
18
|
|
|
19
19
|
# =============================================================================
|
|
20
|
-
#
|
|
20
|
+
# 1Password Configuration (SSoT for secrets)
|
|
21
21
|
# =============================================================================
|
|
22
|
-
# PyPI:
|
|
23
|
-
# GitHub PAT:
|
|
24
|
-
|
|
25
|
-
DOPPLER_PYPI_CONFIG = "prd"
|
|
22
|
+
# PyPI: op item get djevteztvbcqgcm3yl4njkawjq --fields credential --reveal
|
|
23
|
+
# GitHub PAT: stored in gh-token-terrylica file
|
|
24
|
+
OP_PYPI_ITEM = "djevteztvbcqgcm3yl4njkawjq"
|
|
26
25
|
|
|
27
26
|
# =============================================================================
|
|
28
27
|
# ClickHouse Cache Configuration (SSoT for cache hosts)
|
|
@@ -435,7 +434,7 @@ description = "Preview what semantic-release would do (no changes)"
|
|
|
435
434
|
run = "bun install --silent 2>/dev/null && GH_CONFIG_DIR=$HOME/.config/gh/profiles/terrylica GITHUB_TOKEN=$(gh auth token) bun run semantic-release --dry-run --no-ci"
|
|
436
435
|
|
|
437
436
|
[tasks."release:pypi"]
|
|
438
|
-
description = "Publish to PyPI using
|
|
437
|
+
description = "Publish to PyPI using 1Password credentials (local-only, ADR-0027)"
|
|
439
438
|
depends = ["release:build-all"]
|
|
440
439
|
run = "./scripts/publish-to-pypi.sh"
|
|
441
440
|
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
## [11.6.1](https://github.com/terrylica/rangebar-py/compare/v11.6.0...v11.6.1) (2026-02-02)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **ci:** correct rust-toolchain action name ([fa252ce](https://github.com/terrylica/rangebar-py/commit/fa252ceeb1b2f3d4216fceb3e0eaf3fbdc4bed6a))
|
|
7
|
+
* **ci:** simplify workflow to match working configuration ([5128fd6](https://github.com/terrylica/rangebar-py/commit/5128fd6a5ade367dbde371c186de0512095c0116))
|
|
8
|
+
* **resource:** make auto_memory_guard() multiprocessing-safe (Issue [#61](https://github.com/terrylica/rangebar-py/issues/61)) ([b55057a](https://github.com/terrylica/rangebar-py/commit/b55057afb3a10f530ec8d1ac1520d81169ad5fcc))
|
|
9
|
+
|
|
1
10
|
# [11.6.0](https://github.com/terrylica/rangebar-py/compare/v11.5.0...v11.6.0) (2026-02-02)
|
|
2
11
|
|
|
3
12
|
|
|
@@ -3430,7 +3430,7 @@ dependencies = [
|
|
|
3430
3430
|
|
|
3431
3431
|
[[package]]
|
|
3432
3432
|
name = "rangebar"
|
|
3433
|
-
version = "11.6.
|
|
3433
|
+
version = "11.6.1"
|
|
3434
3434
|
dependencies = [
|
|
3435
3435
|
"chrono",
|
|
3436
3436
|
"insta",
|
|
@@ -3452,7 +3452,7 @@ dependencies = [
|
|
|
3452
3452
|
|
|
3453
3453
|
[[package]]
|
|
3454
3454
|
name = "rangebar-batch"
|
|
3455
|
-
version = "11.6.
|
|
3455
|
+
version = "11.6.1"
|
|
3456
3456
|
dependencies = [
|
|
3457
3457
|
"polars",
|
|
3458
3458
|
"rangebar-core",
|
|
@@ -3464,7 +3464,7 @@ dependencies = [
|
|
|
3464
3464
|
|
|
3465
3465
|
[[package]]
|
|
3466
3466
|
name = "rangebar-cli"
|
|
3467
|
-
version = "11.6.
|
|
3467
|
+
version = "11.6.1"
|
|
3468
3468
|
dependencies = [
|
|
3469
3469
|
"chrono",
|
|
3470
3470
|
"clap",
|
|
@@ -3489,7 +3489,7 @@ dependencies = [
|
|
|
3489
3489
|
|
|
3490
3490
|
[[package]]
|
|
3491
3491
|
name = "rangebar-config"
|
|
3492
|
-
version = "11.6.
|
|
3492
|
+
version = "11.6.1"
|
|
3493
3493
|
dependencies = [
|
|
3494
3494
|
"chrono",
|
|
3495
3495
|
"config",
|
|
@@ -3501,7 +3501,7 @@ dependencies = [
|
|
|
3501
3501
|
|
|
3502
3502
|
[[package]]
|
|
3503
3503
|
name = "rangebar-core"
|
|
3504
|
-
version = "11.6.
|
|
3504
|
+
version = "11.6.1"
|
|
3505
3505
|
dependencies = [
|
|
3506
3506
|
"ahash",
|
|
3507
3507
|
"arrow",
|
|
@@ -3518,7 +3518,7 @@ dependencies = [
|
|
|
3518
3518
|
|
|
3519
3519
|
[[package]]
|
|
3520
3520
|
name = "rangebar-io"
|
|
3521
|
-
version = "11.6.
|
|
3521
|
+
version = "11.6.1"
|
|
3522
3522
|
dependencies = [
|
|
3523
3523
|
"polars",
|
|
3524
3524
|
"rangebar-core",
|
|
@@ -3528,7 +3528,7 @@ dependencies = [
|
|
|
3528
3528
|
|
|
3529
3529
|
[[package]]
|
|
3530
3530
|
name = "rangebar-providers"
|
|
3531
|
-
version = "11.6.
|
|
3531
|
+
version = "11.6.1"
|
|
3532
3532
|
dependencies = [
|
|
3533
3533
|
"chrono",
|
|
3534
3534
|
"csv",
|
|
@@ -3548,7 +3548,7 @@ dependencies = [
|
|
|
3548
3548
|
|
|
3549
3549
|
[[package]]
|
|
3550
3550
|
name = "rangebar-py"
|
|
3551
|
-
version = "11.6.
|
|
3551
|
+
version = "11.6.1"
|
|
3552
3552
|
dependencies = [
|
|
3553
3553
|
"arrow",
|
|
3554
3554
|
"arrow-array",
|
|
@@ -3567,7 +3567,7 @@ dependencies = [
|
|
|
3567
3567
|
|
|
3568
3568
|
[[package]]
|
|
3569
3569
|
name = "rangebar-streaming"
|
|
3570
|
-
version = "11.6.
|
|
3570
|
+
version = "11.6.1"
|
|
3571
3571
|
dependencies = [
|
|
3572
3572
|
"async-trait",
|
|
3573
3573
|
"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 = "11.6.
|
|
13
|
+
version = "11.6.1"
|
|
14
14
|
authors = ["Terry Li <terry@eonlabs.com>"]
|
|
15
15
|
categories = ["algorithms", "data-structures", "finance"]
|
|
16
16
|
documentation = "https://docs.rs/rangebar"
|
|
@@ -97,7 +97,7 @@ criterion = { version = "0.5", features = ["html_reports"] }
|
|
|
97
97
|
|
|
98
98
|
[package]
|
|
99
99
|
name = "rangebar-py"
|
|
100
|
-
version = "11.6.
|
|
100
|
+
version = "11.6.1"
|
|
101
101
|
edition = "2021"
|
|
102
102
|
authors = ["Terry Li"]
|
|
103
103
|
license = "MIT"
|
|
@@ -6,6 +6,7 @@ using only stdlib modules (no psutil dependency).
|
|
|
6
6
|
MEM-009: Process-level RLIMIT_AS cap (MemoryError instead of OOM kill)
|
|
7
7
|
MEM-010: Pre-flight memory estimation before tick loading
|
|
8
8
|
MEM-011: Environment variable default (RANGEBAR_MAX_MEMORY_GB)
|
|
9
|
+
MEM-012: Multiprocessing-safe memory guard (Issue #61)
|
|
9
10
|
|
|
10
11
|
Environment Variables
|
|
11
12
|
---------------------
|
|
@@ -18,7 +19,23 @@ RANGEBAR_MAX_MEMORY_PCT : float
|
|
|
18
19
|
Default memory limit as fraction of total RAM (0.0-1.0).
|
|
19
20
|
Example: RANGEBAR_MAX_MEMORY_PCT=0.7 (for 70% of RAM)
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
RANGEBAR_NO_MEMORY_GUARD : str
|
|
23
|
+
Set to "1" to disable automatic memory guard entirely.
|
|
24
|
+
Useful for multiprocessing workers or when RLIMIT_AS conflicts
|
|
25
|
+
with Polars/Rust memory allocators.
|
|
26
|
+
|
|
27
|
+
If both GB and PCT are set, the smaller limit is used.
|
|
28
|
+
|
|
29
|
+
Multiprocessing Safety (Issue #61)
|
|
30
|
+
----------------------------------
|
|
31
|
+
On Linux, RLIMIT_AS (virtual address space) conflicts with mmap-based
|
|
32
|
+
allocators used by Polars and Rust. This can cause "Cannot allocate memory"
|
|
33
|
+
errors even when physical RAM is available.
|
|
34
|
+
|
|
35
|
+
The auto_memory_guard() function:
|
|
36
|
+
1. Skips if RANGEBAR_NO_MEMORY_GUARD=1
|
|
37
|
+
2. Skips if running in a multiprocessing child (detected via _RANGEBAR_GUARD_PID)
|
|
38
|
+
3. On Linux, uses RLIMIT_DATA instead of RLIMIT_AS to avoid mmap conflicts
|
|
22
39
|
"""
|
|
23
40
|
|
|
24
41
|
from __future__ import annotations
|
|
@@ -120,6 +137,7 @@ def set_memory_limit(
|
|
|
120
137
|
limit_bytes = min(limits)
|
|
121
138
|
|
|
122
139
|
# MEM-009: Set process-level cap
|
|
140
|
+
# MEM-012: Use RLIMIT_DATA on Linux to avoid mmap conflicts (Issue #61)
|
|
123
141
|
try:
|
|
124
142
|
if sys.platform == "darwin":
|
|
125
143
|
# macOS: RLIMIT_RSS is advisory (kernel doesn't enforce)
|
|
@@ -130,11 +148,19 @@ def set_memory_limit(
|
|
|
130
148
|
limit_bytes = hard_limit
|
|
131
149
|
resource.setrlimit(resource.RLIMIT_RSS, (limit_bytes, limit_bytes))
|
|
132
150
|
else:
|
|
133
|
-
# Linux:
|
|
134
|
-
|
|
151
|
+
# Linux: Use RLIMIT_DATA instead of RLIMIT_AS (Issue #61)
|
|
152
|
+
# RLIMIT_AS limits virtual address space including mmap regions,
|
|
153
|
+
# which conflicts with Polars/Rust allocators that use mmap().
|
|
154
|
+
# RLIMIT_DATA limits the data segment (heap) which is more
|
|
155
|
+
# appropriate for controlling actual memory allocation.
|
|
156
|
+
#
|
|
157
|
+
# Note: RLIMIT_DATA is less strict than RLIMIT_AS - it won't
|
|
158
|
+
# prevent mmap allocations, but it will limit malloc/brk usage.
|
|
159
|
+
# For full protection, users should rely on cgroups or systemd.
|
|
160
|
+
_, hard_limit = resource.getrlimit(resource.RLIMIT_DATA)
|
|
135
161
|
if hard_limit != resource.RLIM_INFINITY and limit_bytes > hard_limit:
|
|
136
162
|
limit_bytes = hard_limit
|
|
137
|
-
resource.setrlimit(resource.
|
|
163
|
+
resource.setrlimit(resource.RLIMIT_DATA, (limit_bytes, limit_bytes))
|
|
138
164
|
except (ValueError, OSError):
|
|
139
165
|
# Can't set limit (e.g., unprivileged user, macOS restrictions)
|
|
140
166
|
return -1
|
|
@@ -149,6 +175,10 @@ def set_memory_limit(
|
|
|
149
175
|
# Mutable container to track if memory limit was applied (avoids global stmt)
|
|
150
176
|
_memory_limit_state: dict[str, bool] = {"applied": False}
|
|
151
177
|
|
|
178
|
+
# MEM-012: Environment variable key for multiprocessing-safe state tracking
|
|
179
|
+
# This survives fork() and allows child processes to detect parent's limit
|
|
180
|
+
_GUARD_PID_KEY = "_RANGEBAR_GUARD_PID"
|
|
181
|
+
|
|
152
182
|
|
|
153
183
|
def _parse_env_float(name: str) -> float | None:
|
|
154
184
|
"""Parse environment variable as float, returning None on failure."""
|
|
@@ -245,13 +275,42 @@ def ensure_memory_limit(
|
|
|
245
275
|
return limit
|
|
246
276
|
|
|
247
277
|
|
|
278
|
+
def _is_multiprocessing_child() -> bool:
|
|
279
|
+
"""Check if we're in a multiprocessing child process (MEM-012).
|
|
280
|
+
|
|
281
|
+
Detects if memory guard was already applied by a parent process
|
|
282
|
+
by checking the _RANGEBAR_GUARD_PID environment variable.
|
|
283
|
+
|
|
284
|
+
Returns True if:
|
|
285
|
+
1. _RANGEBAR_GUARD_PID is set (parent applied the guard)
|
|
286
|
+
2. Current PID differs from stored PID (we're a child)
|
|
287
|
+
"""
|
|
288
|
+
guard_pid = os.environ.get(_GUARD_PID_KEY)
|
|
289
|
+
if not guard_pid:
|
|
290
|
+
return False
|
|
291
|
+
|
|
292
|
+
try:
|
|
293
|
+
parent_pid = int(guard_pid)
|
|
294
|
+
# If our PID differs from the stored PID, we're a child
|
|
295
|
+
# The child inherits the RLIMIT from parent, no need to re-apply
|
|
296
|
+
return os.getpid() != parent_pid
|
|
297
|
+
except ValueError:
|
|
298
|
+
return False
|
|
299
|
+
|
|
300
|
+
|
|
248
301
|
def auto_memory_guard() -> int:
|
|
249
|
-
"""Automatically enable memory guard at module import (MEM-011).
|
|
302
|
+
"""Automatically enable memory guard at module import (MEM-011, MEM-012).
|
|
250
303
|
|
|
251
304
|
This function is called when `import rangebar` is executed.
|
|
252
305
|
It ensures a memory limit is always set unless explicitly disabled
|
|
253
306
|
via RANGEBAR_NO_MEMORY_GUARD=1.
|
|
254
307
|
|
|
308
|
+
Multiprocessing Safety (Issue #61)
|
|
309
|
+
----------------------------------
|
|
310
|
+
- Skips if RANGEBAR_NO_MEMORY_GUARD=1
|
|
311
|
+
- Skips if running in a multiprocessing child (limit inherited from parent)
|
|
312
|
+
- On Linux, uses RLIMIT_DATA instead of RLIMIT_AS to avoid mmap conflicts
|
|
313
|
+
|
|
255
314
|
Returns
|
|
256
315
|
-------
|
|
257
316
|
int
|
|
@@ -266,9 +325,24 @@ def auto_memory_guard() -> int:
|
|
|
266
325
|
RANGEBAR_MAX_MEMORY_PCT : float
|
|
267
326
|
Override default limit as fraction of RAM.
|
|
268
327
|
"""
|
|
328
|
+
# Check explicit disable first
|
|
269
329
|
if os.environ.get("RANGEBAR_NO_MEMORY_GUARD") == "1":
|
|
270
330
|
return -1
|
|
271
|
-
|
|
331
|
+
|
|
332
|
+
# MEM-012: Skip in multiprocessing children (Issue #61)
|
|
333
|
+
# Child processes inherit RLIMIT from parent via fork()
|
|
334
|
+
if _is_multiprocessing_child():
|
|
335
|
+
_memory_limit_state["applied"] = True # Mark as handled
|
|
336
|
+
return -1
|
|
337
|
+
|
|
338
|
+
# Apply the limit
|
|
339
|
+
limit = ensure_memory_limit()
|
|
340
|
+
|
|
341
|
+
# MEM-012: Store our PID so child processes can detect inheritance
|
|
342
|
+
if limit > 0:
|
|
343
|
+
os.environ[_GUARD_PID_KEY] = str(os.getpid())
|
|
344
|
+
|
|
345
|
+
return limit
|
|
272
346
|
|
|
273
347
|
|
|
274
348
|
@dataclass(frozen=True)
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
# PyPI Publishing with
|
|
2
|
+
# PyPI Publishing with 1Password Secret Management (Local-Only)
|
|
3
3
|
#
|
|
4
4
|
# WORKSPACE-WIDE POLICY: This script must ONLY run on local machines.
|
|
5
5
|
# CI/CD publishing is forbidden - see ADR-0027 for rationale.
|
|
6
6
|
#
|
|
7
7
|
# Prerequisites:
|
|
8
|
-
# -
|
|
8
|
+
# - 1Password CLI installed (brew install 1password-cli)
|
|
9
9
|
# - uv package manager installed (curl -LsSf https://astral.sh/uv/install.sh | sh)
|
|
10
|
-
# -
|
|
10
|
+
# - PyPI token stored in 1Password (item: djevteztvbcqgcm3yl4njkawjq)
|
|
11
11
|
# - pyproject.toml with name and version fields
|
|
12
12
|
#
|
|
13
13
|
# Usage:
|
|
@@ -20,13 +20,10 @@
|
|
|
20
20
|
set -euo pipefail
|
|
21
21
|
|
|
22
22
|
# ============================================================================
|
|
23
|
-
# CONFIGURATION
|
|
23
|
+
# CONFIGURATION
|
|
24
24
|
# ============================================================================
|
|
25
|
-
#
|
|
26
|
-
|
|
27
|
-
DOPPLER_PROJECT="${DOPPLER_PROJECT:-claude-config}"
|
|
28
|
-
DOPPLER_CONFIG="${DOPPLER_CONFIG:-prd}"
|
|
29
|
-
DOPPLER_PYPI_SECRET="${DOPPLER_PYPI_SECRET:-PYPI_TOKEN}"
|
|
25
|
+
# 1Password item ID for PyPI token (project-scoped for rangebar)
|
|
26
|
+
OP_PYPI_ITEM="${OP_PYPI_ITEM:-djevteztvbcqgcm3yl4njkawjq}"
|
|
30
27
|
PYPI_VERIFY_DELAY="${PYPI_VERIFY_DELAY:-3}"
|
|
31
28
|
|
|
32
29
|
# ============================================================================
|
|
@@ -217,26 +214,26 @@ echo ""
|
|
|
217
214
|
echo "Publishing to PyPI (Local Workflow)"
|
|
218
215
|
echo "======================================================"
|
|
219
216
|
|
|
220
|
-
# Step 0: Verify
|
|
221
|
-
echo -e "\n Step 0: Verifying
|
|
217
|
+
# Step 0: Verify 1Password token is available
|
|
218
|
+
echo -e "\n Step 0: Verifying 1Password credentials..."
|
|
222
219
|
|
|
223
|
-
if ! command -v
|
|
224
|
-
echo " ERROR:
|
|
225
|
-
echo " Install: brew install
|
|
220
|
+
if ! command -v op &> /dev/null; then
|
|
221
|
+
echo " ERROR: 1Password CLI not installed"
|
|
222
|
+
echo " Install: brew install 1password-cli"
|
|
226
223
|
exit 1
|
|
227
224
|
fi
|
|
228
225
|
|
|
229
|
-
# Try to get
|
|
230
|
-
if ! PYPI_TOKEN=$(
|
|
231
|
-
echo " ERROR:
|
|
226
|
+
# Try to get PyPI token from 1Password
|
|
227
|
+
if ! PYPI_TOKEN=$(op item get "$OP_PYPI_ITEM" --fields credential --reveal 2>/dev/null); then
|
|
228
|
+
echo " ERROR: PyPI token not found in 1Password (item: $OP_PYPI_ITEM)"
|
|
232
229
|
echo ""
|
|
233
|
-
echo " To fix,
|
|
234
|
-
echo "
|
|
230
|
+
echo " To fix, create a PyPI token and save to 1Password:"
|
|
231
|
+
echo " 1. Get token from: https://pypi.org/manage/account/token/"
|
|
232
|
+
echo " 2. Save to 1Password with: op item create --category='API Credential' --title='PyPI Token' 'credential=pypi-xxx'"
|
|
235
233
|
echo ""
|
|
236
|
-
echo " Get token from: https://pypi.org/manage/account/token/"
|
|
237
234
|
exit 1
|
|
238
235
|
fi
|
|
239
|
-
echo "
|
|
236
|
+
echo " 1Password token verified"
|
|
240
237
|
|
|
241
238
|
# Step 1: Verify pyproject.toml exists
|
|
242
239
|
echo -e "\n Step 1: Reading package info from pyproject.toml..."
|
|
@@ -309,18 +306,28 @@ else
|
|
|
309
306
|
echo " Built: dist/${PACKAGE_NAME}-${CURRENT_VERSION}*"
|
|
310
307
|
fi
|
|
311
308
|
|
|
312
|
-
# Step
|
|
313
|
-
echo -e "\n Step
|
|
314
|
-
echo " Using
|
|
315
|
-
|
|
316
|
-
# Use
|
|
317
|
-
|
|
318
|
-
|
|
309
|
+
# Step 3: Publish to PyPI using twine (more reliable for maturin projects)
|
|
310
|
+
echo -e "\n Step 3: Publishing to PyPI..."
|
|
311
|
+
echo " Using PyPI token from 1Password"
|
|
312
|
+
|
|
313
|
+
# Use twine for maturin projects (uv publish has issues with pre-built wheels)
|
|
314
|
+
if grep -q '\[tool.maturin\]' pyproject.toml; then
|
|
315
|
+
# Publish all wheels and sdist for current version
|
|
316
|
+
TWINE_USERNAME=__token__ TWINE_PASSWORD="${PYPI_TOKEN}" twine upload \
|
|
317
|
+
"dist/${PACKAGE_NAME}-${CURRENT_VERSION}"-*.whl \
|
|
318
|
+
"target/wheels/${PACKAGE_NAME}-${CURRENT_VERSION}.tar.gz" 2>&1 || \
|
|
319
|
+
TWINE_USERNAME=__token__ TWINE_PASSWORD="${PYPI_TOKEN}" twine upload \
|
|
320
|
+
"dist/${PACKAGE_NAME}-${CURRENT_VERSION}"-*.whl
|
|
321
|
+
else
|
|
322
|
+
# Use UV_PUBLISH_TOKEN environment variable for security (no token in process list)
|
|
323
|
+
UV_PUBLISH_TOKEN="${PYPI_TOKEN}" $UV_CMD publish 2>&1 | grep -E "(Uploading|succeeded|Failed)" || \
|
|
324
|
+
UV_PUBLISH_TOKEN="${PYPI_TOKEN}" $UV_CMD publish
|
|
325
|
+
fi
|
|
319
326
|
|
|
320
327
|
echo " Published to PyPI"
|
|
321
328
|
|
|
322
|
-
# Step
|
|
323
|
-
echo -e "\n Step
|
|
329
|
+
# Step 4: Verify publication on PyPI
|
|
330
|
+
echo -e "\n Step 4: Verifying on PyPI..."
|
|
324
331
|
sleep "$PYPI_VERIFY_DELAY"
|
|
325
332
|
|
|
326
333
|
# Check if package version is live on PyPI
|
|
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-11.6.0 → rangebar-11.6.1}/crates/rangebar-core/tests/cross_date_real_data_validation.rs
RENAMED
|
File without changes
|
|
File without changes
|
{rangebar-11.6.0 → rangebar-11.6.1}/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-11.6.0 → rangebar-11.6.1}/docs/research/2026-02-02-intrabar-microstructure-claude-opus.md
RENAMED
|
File without changes
|
{rangebar-11.6.0 → rangebar-11.6.1}/docs/research/2026-02-02-intrabar-microstructure-gemini-3-pro.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rangebar-11.6.0 → rangebar-11.6.1}/docs/research/external/time-to-convergence-stationarity-gap.md
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
|