# RangeBar
High-performance non-lookahead bias range bar construction from Binance UM Futures aggTrades data.
## Overview
RangeBar implements precise range bar construction using a threshold-based algorithm where bars close when price moves ±0.8% (configurable) from the bar's **open price**. This ensures non-lookahead bias - thresholds are computed only from the bar's opening price and never recalculated.
### Key Features
- **Non-lookahead Bias**: Thresholds computed from bar open only, never from high/low ranges
- **Breach Inclusion**: Breach tick is included in the closing bar before next tick opens new bar
- **High Performance**: Rust core processes 137M+ trades/second (2025 benchmarks)
- **Fixed-Point Arithmetic**: No floating-point rounding errors (8 decimal precision)
- **UM Futures Only**: Designed specifically for Binance USD-M Futures aggTrades data
## Installation
### Requirements
- Python 3.13+ (2025 standard)
- Rust 1.89+ (for building from source)
### Using UV (Recommended)
```bash
uv add rangebar
```
### Using pip
```bash
pip install rangebar
```
### Upgrading from v0.1.x
If you're upgrading from a previous version, see the [Migration Guide](MIGRATION.md) for detailed upgrade instructions and breaking changes.
## Quick Start
### CLI Usage
```bash
# Fetch UM Futures aggTrades data
rangebar fetch BTCUSDT 2024-01-01 2024-01-01
# Generate range bars
rangebar generate BTCUSDT_2024-01-01_aggtrades.parquet --threshold-bps 8000
# Inspect generated bars
rangebar inspect BTCUSDT_2024-01-01_range_bars_80bps.parquet --head 5
```
### Python API
```python
from rangebar.range_bars import iter_range_bars_from_aggtrades, AggTrade
from decimal import Decimal
import asyncio
# Create sample trades
trades_data = [
{'a': 1, 'p': '50000.0', 'q': '1.0', 'f': 1, 'l': 1, 'T': 1000, 'm': False},
{'a': 2, 'p': '50400.0', 'q': '1.0', 'f': 2, 'l': 2, 'T': 2000, 'm': False}, # +0.8% breach
{'a': 3, 'p': '50500.0', 'q': '1.0', 'f': 3, 'l': 3, 'T': 3000, 'm': False}, # New bar
]
trades = [AggTrade(data) for data in trades_data]
# Generate range bars
bars = list(iter_range_bars_from_aggtrades(trades, pct=Decimal('0.008')))
print(f"Generated {len(bars)} range bars")
for i, bar in enumerate(bars):
print(f"Bar {i}: Open={bar['open']}, High={bar['high']}, Low={bar['low']}, Close={bar['close']}")
```
### Fetching Market Data
```python
from rangebar.data_fetcher import fetch_um_futures_aggtrades
import asyncio
async def main():
# Fetch UM Futures aggTrades
trades = await fetch_um_futures_aggtrades('BTCUSDT', '2024-01-01', '2024-01-01')
print(f"Fetched {len(trades)} aggTrades")
asyncio.run(main())
```
## Algorithm Specification
### Non-Lookahead Bias Range Bars
1. **Threshold Calculation**: When a bar opens, thresholds are computed as:
- Upper threshold = Open price × (1 + 0.008) = Open × 1.008
- Lower threshold = Open price × (1 - 0.008) = Open × 0.992
2. **Breach Detection**: For each incoming trade tick:
- Update bar OHLCV with the trade (always include the trade)
- Check if trade price ≥ upper threshold OR ≤ lower threshold
- If breach: close current bar, next tick opens new bar
3. **Critical Property**: Thresholds are **NEVER** recalculated after bar opening. This prevents lookahead bias.
### Example: 0.8% Threshold
```
Bar opens at $50,000:
- Upper threshold: $50,000 × 1.008 = $50,400 (fixed)
- Lower threshold: $50,000 × 0.992 = $49,600 (fixed)
Trades sequence:
1. $50,200 → update bar, no breach
2. $50,400 → update bar, BREACH detected → close bar
3. $50,500 → opens new bar with new thresholds
```
## Data Sources
RangeBar fetches data from Binance UM Futures using the [binance-historical-data](https://github.com/stas-prokopiev/binance_historical_data) library.
### Supported Symbols
All Binance UM Futures perpetual contracts (USDT-margined):
- BTCUSDT, ETHUSDT, ADAUSDT, etc.
- Use Binance API symbols exactly as listed
### Data Format
Input: Binance UM Futures aggTrades JSON/CSV
```json
{
"a": 123456789, // Aggregate trade ID
"p": "50000.12345", // Price
"q": "1.50000000", // Quantity
"f": 100, // First trade ID
"l": 105, // Last trade ID
"T": 1609459200000, // Timestamp
"m": false // Is buyer maker
}
```
## Performance
- **Rust Core**: 137M+ trades/second processing (PyO3 0.26, Rust 2024 edition)
- **Python Implementation**: 2.5M+ trades/second (41x speedup with Rust)
- **Memory Efficient**: Streaming processing, minimal memory footprint
- **Fixed-Point**: No floating-point precision errors
- **Modern Stack**: Latest Python 3.13, numpy>=2.3.0, pandas>=2.3.0
### Benchmark Results (v0.2.0)
Tested with latest 2025 dependencies on 1M trade dataset:
- **Peak Rust Performance**: 137,000,000+ trades/sec
- **Python Reference**: 2,500,000+ trades/sec
- **Algorithm Integrity**: 100% verified parity between implementations
## Development
### Requirements
- Python 3.13+ (current 2025 standard)
- Rust 1.89+ (2024 edition)
- UV package manager (recommended)
### Building from Source
```bash
# Clone repository
git clone https://github.com/eonlabs/rangebar.git
cd rangebar
# Install dependencies (requires Python 3.13+)
uv sync
# Build Rust extension
uv run maturin develop --release
# Run tests
uv run pytest
cargo test --release
# Run benchmarks
uv run python benchmark_v2.py
```
### Running Validation
```bash
# Comprehensive algorithm validation
uv run python validate_algorithm_parity.py
```
## Documentation
- [Migration Guide](MIGRATION.md) - Upgrading from v0.1.x to v0.2.0
- [Changelog](CHANGELOG.md) - Version history and breaking changes
- [Publishing Guide](PUBLISH.md) - Instructions for maintainers
## License
MIT License. See [LICENSE](LICENSE) for details.
## Contributing
1. Fork the repository
2. Create a feature branch
3. Run tests: `cargo test --release && uv run pytest`
4. Run benchmarks: `uv run python benchmark_v2.py`
5. Submit a pull request
## Support
- Issues: [GitHub Issues](https://github.com/eonlabs/rangebar/issues)
- Documentation: See CLI help `rangebar --help`
Raw data
{
"_id": null,
"home_page": "https://github.com/eonlabs/rangebar",
"name": "rangebar",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.13",
"maintainer_email": null,
"keywords": "binance, range-bars, trading, cryptocurrency, futures, technical-analysis",
"author": null,
"author_email": "Terry Li <terry@eonlabs.com>",
"download_url": "https://files.pythonhosted.org/packages/6c/53/18d25e66d9cff0a9b1ce966645c991db2a0a77115fa73e9b0b5c3af0cdee/rangebar-0.2.1.tar.gz",
"platform": null,
"description": "# RangeBar\n\nHigh-performance non-lookahead bias range bar construction from Binance UM Futures aggTrades data.\n\n## Overview\n\nRangeBar implements precise range bar construction using a threshold-based algorithm where bars close when price moves \u00b10.8% (configurable) from the bar's **open price**. This ensures non-lookahead bias - thresholds are computed only from the bar's opening price and never recalculated.\n\n### Key Features\n\n- **Non-lookahead Bias**: Thresholds computed from bar open only, never from high/low ranges\n- **Breach Inclusion**: Breach tick is included in the closing bar before next tick opens new bar\n- **High Performance**: Rust core processes 137M+ trades/second (2025 benchmarks)\n- **Fixed-Point Arithmetic**: No floating-point rounding errors (8 decimal precision)\n- **UM Futures Only**: Designed specifically for Binance USD-M Futures aggTrades data\n\n## Installation\n\n### Requirements\n- Python 3.13+ (2025 standard)\n- Rust 1.89+ (for building from source)\n\n### Using UV (Recommended)\n\n```bash\nuv add rangebar\n```\n\n### Using pip\n\n```bash\npip install rangebar\n```\n\n### Upgrading from v0.1.x\n\nIf you're upgrading from a previous version, see the [Migration Guide](MIGRATION.md) for detailed upgrade instructions and breaking changes.\n\n## Quick Start\n\n### CLI Usage\n\n```bash\n# Fetch UM Futures aggTrades data\nrangebar fetch BTCUSDT 2024-01-01 2024-01-01\n\n# Generate range bars \nrangebar generate BTCUSDT_2024-01-01_aggtrades.parquet --threshold-bps 8000\n\n# Inspect generated bars\nrangebar inspect BTCUSDT_2024-01-01_range_bars_80bps.parquet --head 5\n```\n\n### Python API\n\n```python\nfrom rangebar.range_bars import iter_range_bars_from_aggtrades, AggTrade\nfrom decimal import Decimal\nimport asyncio\n\n# Create sample trades\ntrades_data = [\n {'a': 1, 'p': '50000.0', 'q': '1.0', 'f': 1, 'l': 1, 'T': 1000, 'm': False},\n {'a': 2, 'p': '50400.0', 'q': '1.0', 'f': 2, 'l': 2, 'T': 2000, 'm': False}, # +0.8% breach\n {'a': 3, 'p': '50500.0', 'q': '1.0', 'f': 3, 'l': 3, 'T': 3000, 'm': False}, # New bar\n]\n\ntrades = [AggTrade(data) for data in trades_data]\n\n# Generate range bars\nbars = list(iter_range_bars_from_aggtrades(trades, pct=Decimal('0.008')))\n\nprint(f\"Generated {len(bars)} range bars\")\nfor i, bar in enumerate(bars):\n print(f\"Bar {i}: Open={bar['open']}, High={bar['high']}, Low={bar['low']}, Close={bar['close']}\")\n```\n\n### Fetching Market Data\n\n```python\nfrom rangebar.data_fetcher import fetch_um_futures_aggtrades\nimport asyncio\n\nasync def main():\n # Fetch UM Futures aggTrades\n trades = await fetch_um_futures_aggtrades('BTCUSDT', '2024-01-01', '2024-01-01')\n print(f\"Fetched {len(trades)} aggTrades\")\n\nasyncio.run(main())\n```\n\n## Algorithm Specification\n\n### Non-Lookahead Bias Range Bars\n\n1. **Threshold Calculation**: When a bar opens, thresholds are computed as:\n - Upper threshold = Open price \u00d7 (1 + 0.008) = Open \u00d7 1.008\n - Lower threshold = Open price \u00d7 (1 - 0.008) = Open \u00d7 0.992\n\n2. **Breach Detection**: For each incoming trade tick:\n - Update bar OHLCV with the trade (always include the trade)\n - Check if trade price \u2265 upper threshold OR \u2264 lower threshold\n - If breach: close current bar, next tick opens new bar\n\n3. **Critical Property**: Thresholds are **NEVER** recalculated after bar opening. This prevents lookahead bias.\n\n### Example: 0.8% Threshold\n\n```\nBar opens at $50,000:\n- Upper threshold: $50,000 \u00d7 1.008 = $50,400 (fixed)\n- Lower threshold: $50,000 \u00d7 0.992 = $49,600 (fixed)\n\nTrades sequence:\n1. $50,200 \u2192 update bar, no breach\n2. $50,400 \u2192 update bar, BREACH detected \u2192 close bar\n3. $50,500 \u2192 opens new bar with new thresholds\n```\n\n## Data Sources\n\nRangeBar fetches data from Binance UM Futures using the [binance-historical-data](https://github.com/stas-prokopiev/binance_historical_data) library.\n\n### Supported Symbols\n\nAll Binance UM Futures perpetual contracts (USDT-margined):\n- BTCUSDT, ETHUSDT, ADAUSDT, etc.\n- Use Binance API symbols exactly as listed\n\n### Data Format\n\nInput: Binance UM Futures aggTrades JSON/CSV\n```json\n{\n \"a\": 123456789, // Aggregate trade ID\n \"p\": \"50000.12345\", // Price\n \"q\": \"1.50000000\", // Quantity\n \"f\": 100, // First trade ID\n \"l\": 105, // Last trade ID \n \"T\": 1609459200000, // Timestamp\n \"m\": false // Is buyer maker\n}\n```\n\n## Performance\n\n- **Rust Core**: 137M+ trades/second processing (PyO3 0.26, Rust 2024 edition) \n- **Python Implementation**: 2.5M+ trades/second (41x speedup with Rust)\n- **Memory Efficient**: Streaming processing, minimal memory footprint\n- **Fixed-Point**: No floating-point precision errors\n- **Modern Stack**: Latest Python 3.13, numpy>=2.3.0, pandas>=2.3.0\n\n### Benchmark Results (v0.2.0)\nTested with latest 2025 dependencies on 1M trade dataset:\n- **Peak Rust Performance**: 137,000,000+ trades/sec\n- **Python Reference**: 2,500,000+ trades/sec \n- **Algorithm Integrity**: 100% verified parity between implementations\n\n## Development\n\n### Requirements\n\n- Python 3.13+ (current 2025 standard)\n- Rust 1.89+ (2024 edition)\n- UV package manager (recommended)\n\n### Building from Source\n\n```bash\n# Clone repository\ngit clone https://github.com/eonlabs/rangebar.git\ncd rangebar\n\n# Install dependencies (requires Python 3.13+)\nuv sync\n\n# Build Rust extension\nuv run maturin develop --release\n\n# Run tests\nuv run pytest\ncargo test --release\n\n# Run benchmarks\nuv run python benchmark_v2.py\n```\n\n### Running Validation\n\n```bash\n# Comprehensive algorithm validation\nuv run python validate_algorithm_parity.py\n```\n\n## Documentation\n\n- [Migration Guide](MIGRATION.md) - Upgrading from v0.1.x to v0.2.0\n- [Changelog](CHANGELOG.md) - Version history and breaking changes\n- [Publishing Guide](PUBLISH.md) - Instructions for maintainers\n\n## License\n\nMIT License. See [LICENSE](LICENSE) for details.\n\n## Contributing\n\n1. Fork the repository\n2. Create a feature branch \n3. Run tests: `cargo test --release && uv run pytest`\n4. Run benchmarks: `uv run python benchmark_v2.py`\n5. Submit a pull request\n\n## Support\n\n- Issues: [GitHub Issues](https://github.com/eonlabs/rangebar/issues)\n- Documentation: See CLI help `rangebar --help`\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Non-lookahead bias range bar construction from Binance aggTrades data",
"version": "0.2.1",
"project_urls": {
"Homepage": "https://github.com/eonlabs/rangebar",
"Issues": "https://github.com/eonlabs/rangebar/issues",
"Repository": "https://github.com/eonlabs/rangebar"
},
"split_keywords": [
"binance",
" range-bars",
" trading",
" cryptocurrency",
" futures",
" technical-analysis"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "59aa51c93eab755740eee5e0c29a089e206044aa7a4283c29d46e04a474d9111",
"md5": "37d5cdfbda242545564338b4a6166f32",
"sha256": "907aa2c57a1b932673809c4700d6205d1b0960c853ad847dbbc987cab7e293b6"
},
"downloads": -1,
"filename": "rangebar-0.2.1-cp313-cp313-macosx_11_0_arm64.whl",
"has_sig": false,
"md5_digest": "37d5cdfbda242545564338b4a6166f32",
"packagetype": "bdist_wheel",
"python_version": "cp313",
"requires_python": ">=3.13",
"size": 243066,
"upload_time": "2025-09-09T22:28:58",
"upload_time_iso_8601": "2025-09-09T22:28:58.090336Z",
"url": "https://files.pythonhosted.org/packages/59/aa/51c93eab755740eee5e0c29a089e206044aa7a4283c29d46e04a474d9111/rangebar-0.2.1-cp313-cp313-macosx_11_0_arm64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "6c5318d25e66d9cff0a9b1ce966645c991db2a0a77115fa73e9b0b5c3af0cdee",
"md5": "1b10ca547937633caca980cfacaf520c",
"sha256": "89c213075eab31db40bf0d3b038a8bc4a133e85438ed186bf5db86b9705876e7"
},
"downloads": -1,
"filename": "rangebar-0.2.1.tar.gz",
"has_sig": false,
"md5_digest": "1b10ca547937633caca980cfacaf520c",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.13",
"size": 10132585,
"upload_time": "2025-09-09T22:29:00",
"upload_time_iso_8601": "2025-09-09T22:29:00.952997Z",
"url": "https://files.pythonhosted.org/packages/6c/53/18d25e66d9cff0a9b1ce966645c991db2a0a77115fa73e9b0b5c3af0cdee/rangebar-0.2.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-09-09 22:29:00",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "eonlabs",
"github_project": "rangebar",
"github_not_found": true,
"lcname": "rangebar"
}