148 lines
5.0 KiB
Markdown
148 lines
5.0 KiB
Markdown
|
|
# Module: metrics_calculator
|
||
|
|
|
||
|
|
## Purpose
|
||
|
|
The `metrics_calculator` module handles calculation and management of trading metrics including Order Book Imbalance (OBI) and Cumulative Volume Delta (CVD). It provides windowed aggregation with throttled updates for real-time visualization.
|
||
|
|
|
||
|
|
## Public Interface
|
||
|
|
|
||
|
|
### Classes
|
||
|
|
- `MetricsCalculator(window_seconds: int = 60, emit_every_n_updates: int = 25)`: Main metrics calculation engine
|
||
|
|
|
||
|
|
### Methods
|
||
|
|
- `update_cvd_from_trade(side: str, size: float) -> None`: Update CVD from individual trade data
|
||
|
|
- `update_obi_metrics(timestamp: str, total_bids: float, total_asks: float) -> None`: Update OBI metrics from orderbook volumes
|
||
|
|
- `finalize_metrics() -> None`: Emit final metrics bar at processing end
|
||
|
|
|
||
|
|
### Properties
|
||
|
|
- `cvd_cumulative: float`: Current cumulative volume delta value
|
||
|
|
|
||
|
|
### Private Methods
|
||
|
|
- `_emit_metrics_bar() -> None`: Emit current metrics to visualization layer
|
||
|
|
|
||
|
|
## Usage Examples
|
||
|
|
|
||
|
|
```python
|
||
|
|
from metrics_calculator import MetricsCalculator
|
||
|
|
|
||
|
|
# Initialize calculator
|
||
|
|
calc = MetricsCalculator(window_seconds=60, emit_every_n_updates=25)
|
||
|
|
|
||
|
|
# Update CVD from trades
|
||
|
|
calc.update_cvd_from_trade("buy", 1.5) # +1.5 CVD
|
||
|
|
calc.update_cvd_from_trade("sell", 1.0) # -1.0 CVD, net +0.5
|
||
|
|
|
||
|
|
# Update OBI from orderbook
|
||
|
|
total_bids, total_asks = 150.0, 120.0
|
||
|
|
calc.update_obi_metrics("1640995200000", total_bids, total_asks)
|
||
|
|
|
||
|
|
# Access current CVD
|
||
|
|
current_cvd = calc.cvd_cumulative # 0.5
|
||
|
|
|
||
|
|
# Finalize at end of processing
|
||
|
|
calc.finalize_metrics()
|
||
|
|
```
|
||
|
|
|
||
|
|
## Metrics Definitions
|
||
|
|
|
||
|
|
### Cumulative Volume Delta (CVD)
|
||
|
|
- **Formula**: CVD = Σ(buy_volume - sell_volume)
|
||
|
|
- **Interpretation**: Positive = more buying pressure, Negative = more selling pressure
|
||
|
|
- **Accumulation**: Running total across all processed trades
|
||
|
|
- **Update Frequency**: Every trade
|
||
|
|
|
||
|
|
### Order Book Imbalance (OBI)
|
||
|
|
- **Formula**: OBI = total_bid_volume - total_ask_volume
|
||
|
|
- **Interpretation**: Positive = more bid liquidity, Negative = more ask liquidity
|
||
|
|
- **Aggregation**: OHLC-style bars per time window (open, high, low, close)
|
||
|
|
- **Update Frequency**: Throttled per orderbook update
|
||
|
|
|
||
|
|
## Dependencies
|
||
|
|
|
||
|
|
### Internal
|
||
|
|
- `viz_io.upsert_metric_bar`: Output interface for visualization
|
||
|
|
|
||
|
|
### External
|
||
|
|
- `logging`: Warning messages for unknown trade sides
|
||
|
|
- `typing`: Type annotations
|
||
|
|
|
||
|
|
## Windowed Aggregation
|
||
|
|
|
||
|
|
### OBI Windows
|
||
|
|
- **Window Size**: Configurable via `window_seconds` (default: 60)
|
||
|
|
- **Window Alignment**: Aligned to epoch time boundaries
|
||
|
|
- **OHLC Tracking**: Maintains open, high, low, close values per window
|
||
|
|
- **Rollover**: Automatic window transitions with final bar emission
|
||
|
|
|
||
|
|
### Throttling Mechanism
|
||
|
|
- **Purpose**: Reduce I/O overhead during high-frequency updates
|
||
|
|
- **Trigger**: Every N updates (configurable via `emit_every_n_updates`)
|
||
|
|
- **Behavior**: Emits intermediate updates for real-time visualization
|
||
|
|
- **Final Emission**: Guaranteed on window rollover and finalization
|
||
|
|
|
||
|
|
## State Management
|
||
|
|
|
||
|
|
### CVD State
|
||
|
|
- `cvd_cumulative: float`: Running total across all trades
|
||
|
|
- **Persistence**: Maintained throughout processor lifetime
|
||
|
|
- **Updates**: Incremental addition/subtraction per trade
|
||
|
|
|
||
|
|
### OBI State
|
||
|
|
- `metrics_window_start: int`: Current window start timestamp
|
||
|
|
- `metrics_bar: dict`: Current OBI OHLC values
|
||
|
|
- `_metrics_since_last_emit: int`: Throttling counter
|
||
|
|
|
||
|
|
## Output Format
|
||
|
|
|
||
|
|
### Metrics Bar Structure
|
||
|
|
```python
|
||
|
|
{
|
||
|
|
'obi_open': float, # First OBI value in window
|
||
|
|
'obi_high': float, # Maximum OBI in window
|
||
|
|
'obi_low': float, # Minimum OBI in window
|
||
|
|
'obi_close': float, # Latest OBI value
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Visualization Integration
|
||
|
|
- Emitted via `viz_io.upsert_metric_bar(timestamp, obi_open, obi_high, obi_low, obi_close, cvd_value)`
|
||
|
|
- Compatible with existing OHLC visualization infrastructure
|
||
|
|
- Real-time updates during active processing
|
||
|
|
|
||
|
|
## Performance Characteristics
|
||
|
|
|
||
|
|
- **Low Memory**: Maintains only current window state
|
||
|
|
- **Throttled I/O**: Configurable update frequency prevents excessive writes
|
||
|
|
- **Efficient Updates**: O(1) operations for trade and OBI updates
|
||
|
|
- **Window Management**: Automatic transitions without manual intervention
|
||
|
|
|
||
|
|
## Configuration
|
||
|
|
|
||
|
|
### Constructor Parameters
|
||
|
|
- `window_seconds: int`: Time window for OBI aggregation (default: 60)
|
||
|
|
- `emit_every_n_updates: int`: Throttling factor for intermediate updates (default: 25)
|
||
|
|
|
||
|
|
### Tuning Guidelines
|
||
|
|
- **Higher throttling**: Reduces I/O load, delays real-time updates
|
||
|
|
- **Lower throttling**: More responsive visualization, higher I/O overhead
|
||
|
|
- **Window size**: Affects granularity of OBI trends (shorter = more detail)
|
||
|
|
|
||
|
|
## Testing
|
||
|
|
|
||
|
|
```bash
|
||
|
|
uv run pytest test_metrics_calculator.py -v
|
||
|
|
```
|
||
|
|
|
||
|
|
Test coverage includes:
|
||
|
|
- CVD accumulation accuracy across multiple trades
|
||
|
|
- OBI window rollover and OHLC tracking
|
||
|
|
- Throttling behavior verification
|
||
|
|
- Edge cases (unknown trade sides, empty windows)
|
||
|
|
- Integration with visualization output
|
||
|
|
|
||
|
|
## Known Limitations
|
||
|
|
|
||
|
|
- CVD calculation assumes binary buy/sell classification
|
||
|
|
- No support for partial fills or complex order types
|
||
|
|
- OBI calculation treats all liquidity equally (no price weighting)
|
||
|
|
- Window boundaries aligned to absolute timestamps (no sliding windows)
|