# 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)