orderflow_backtest/tasks/prd-cumulative-volume-delta.md

5.1 KiB
Raw Blame History

Cumulative Volume Delta (CVD) Product Requirements Document

1) Introduction / Overview

  • Compute and visualize Cumulative Volume Delta (CVD) from trade data processed by OHLCProcessor.process_trades, aligned to the existing OHLC bar cadence.
  • CVD is defined as the cumulative sum of volume delta, where volume delta = buy_volume - sell_volume per trade.
  • Trade classification: side == "buy" → positive volume delta, side == "sell" → negative volume delta.
  • Persist CVD time series as scalar values per window to metrics_data.json and render a CVD line chart beneath the current OBI subplot in the Dash UI.

2) Goals

  • Compute volume delta from individual trades using the side field in the Trade dataclass.
  • Accumulate CVD across all processed trades (no session resets initially).
  • Aggregate CVD into window-aligned scalar values per window_seconds.
  • Extend metrics_data.json schema to include CVD values alongside existing OBI data.
  • Add a CVD line chart subplot beneath OBI in the main chart, sharing the time axis.
  • Throttle intra-window upserts of CVD values using the same approach/frequency as current OHLC throttling; always write on window close.

3) User Stories

  • As a researcher, I want CVD computed from actual trade data so I can assess buying/selling pressure over time.
  • As an analyst, I want CVD stored per time window so I can correlate it with price movements and OBI patterns.
  • As a developer, I want cumulative CVD values so I can analyze long-term directional bias in volume flow.

4) Functional Requirements

  1. Inputs and Definitions
    • Compute volume delta on every trade in OHLCProcessor.process_trades:
      • If trade.side == "buy"volume_delta = +trade.size
      • If trade.side == "sell"volume_delta = -trade.size
      • If trade.side is neither "buy" nor "sell" → volume_delta = 0 (log warning)
    • Accumulate into running CVD: self.cvd_cumulative += volume_delta
  2. Windowing & Aggregation
    • Use the same window_seconds boundary as OHLC bars; window anchor is derived from the trade timestamp.
    • Store CVD value at window boundaries (end-of-window CVD snapshot).
    • On window rollover, capture the current self.cvd_cumulative value for that window.
  3. Persistence
    • Extend metrics_data.json schema from [timestamp, obi_open, obi_high, obi_low, obi_close] to [timestamp, obi_open, obi_high, obi_low, obi_close, cvd_value].
    • Update viz_io.py functions to handle the new 6-element schema.
    • Keep only the last 1000 rows.
    • Upsert intra-window CVD values periodically (throttled, matching OHLC's approach) and always write on window close.
  4. Visualization
    • Read extended metrics_data.json in the Dash app with the same tolerant JSON reading/caching approach.
    • Extend the main figure to a fourth row for CVD line chart beneath OBI, sharing the x-axis.
    • Style CVD as a line chart with appropriate color (distinct from OHLC/Volume/OBI) and add a zero baseline.
  5. Performance & Correctness
    • CVD compute happens on every trade; I/O is throttled to maintain UI responsiveness.
    • Use existing logging and error handling patterns; must not crash if metrics JSON is temporarily unreadable.
    • Handle backward compatibility: if existing metrics_data.json has 5-element rows, treat missing CVD as 0.
  6. Testing
    • Unit tests for volume delta calculation with "buy", "sell", and invalid side values.
    • Unit tests for CVD accumulation across multiple trades and window boundaries.
    • Integration test: fixture trades produce correct CVD progression in metrics_data.json.

5) Non-Goals

  • No CVD reset functionality (will be implemented later).
  • No additional derived CVD metrics (e.g., CVD rate of change, normalized CVD).
  • No database persistence for CVD; JSON IPC only.
  • No strategy/signal changes based on CVD.

6) Design Considerations

  • Implement CVD calculation in OHLCProcessor.process_trades alongside existing OHLC aggregation.
  • Extend viz_io.py metrics functions to support 6-element schema while maintaining backward compatibility.
  • Add CVD state tracking: self.cvd_cumulative, self.cvd_window_value per window.
  • Follow the same throttling pattern as OBI metrics for consistency.

7) Technical Considerations

  • Add CVD computation in the trade processing loop within OHLCProcessor.process_trades.
  • Extend upsert_metric_bar and add_metric_bar functions to accept optional cvd_value parameter.
  • Handle schema migration gracefully: read existing 5-element rows, append 0.0 for missing CVD.
  • Use the same window alignment as trades (based on trade timestamp, not orderbook timestamp).

8) Success Metrics

  • metrics_data.json present with valid 6-element rows during processing.
  • CVD subplot updates smoothly and aligns with OHLC window timestamps.
  • CVD increases during buy-heavy periods, decreases during sell-heavy periods.
  • No noticeable performance regression in trade processing or UI responsiveness.

9) Open Questions

  • None; CVD computation approach confirmed using trade.side field. Schema extension approach confirmed for metrics_data.json.