rangebar


Namerangebar JSON
Version 0.2.1 PyPI version JSON
download
home_pagehttps://github.com/eonlabs/rangebar
SummaryNon-lookahead bias range bar construction from Binance aggTrades data
upload_time2025-09-09 22:29:00
maintainerNone
docs_urlNone
authorNone
requires_python>=3.13
licenseMIT
keywords binance range-bars trading cryptocurrency futures technical-analysis
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # 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"
}
        
Elapsed time: 4.27406s