- Published on
Financial Data Structures
Financial Data Structures
This document outlines methods for processing and structuring financial data for quantitative analysis, moving from raw data types to structured bars, handling multi-product series, and sampling features for machine learning.
Types of Financial Data
The text identifies four primary types of financial data:
- Fundamental Data: Accounting information that is low-frequency, delayed, and prone to backfilling and forward-looking biases. It is most useful when combined with other data types.
- Market Data: High-frequency trading data (e.g., FIX data) that falls into the "Big Data" category. It can reveal patterns from algorithmic or human trading.
- Analytical Data: Data derived from original sources, often including subjective analysis, which may not be easily replicable.
- Alternative Data: Non-traditional data (e.g., satellite imagery, credit card data) that is difficult to process but can offer a significant predictive edge.
Financial Bars
Bars are used to organize and regularize unstructured, high-frequency market data into a homogeneous format with more favorable statistical properties (e.g., normality, invariance) and reduced noise.


Implementation: Data Structure Controllers
In our RiskLabAI library, we provide a flexible controller system to process raw tick data into various bar types. This system is composed of two main classes:
Controller(fromdata_structure_controller.py): This is the main entry point. It handles reading data efficiently in batches from CSV files or pandas DataFrames and orchestrates the bar construction process.BarsInitializerController(fromcontroller.bars_initializer.py): This class acts as a factory, responsible for creating the specific bar sampling object (e.g., a Dollar Imbalance Bar object) with the correct parameters.
This function takes the method_name (e.g., "expected_dollar_imbalance_bars"), a dictionary of its method_arguments, and the input_data (either a file path or a DataFrame) and processes the data, returning a DataFrame of the constructed bars.
The BarsInitializerController contains static methods for creating each bar type with sensible defaults. Here are some of the key initializers:
- Standard Bars:
- Time Bars:
- Imbalance Bars (Expected vs. Fixed):
- Run Bars (Expected vs. Fixed):
(Note: Implementations for volume_ and tick_ based bars are also available.)
Standard Bars
- Time Bars: Data bucketed at regular time intervals (e.g., 1-minute). This method is discouraged as it produces data with unfavorable statistical properties (e.g., heteroscedasticity).
- Tick Bars: Data sampled after a fixed number of trades (ticks). This synchronizes sampling with market activity but is vulnerable to order fragmentation.
- Volume Bars: Data sampled after a fixed number of shares are traded. This resolves the order fragmentation issue seen in tick bars.
- Dollar Bars: Data sampled every time a specific market value (dollar amount) is traded. This is more stable, especially during high turbulence or corporate actions (splits, buybacks) that distort tick and volume counts.
In our RiskLabAI library, we implement the Standard and Time bars, which all inherit from a common AbstractBars class found in RiskLabAI.data.structures.abstract_bars. This base class manages the core logic for bar construction, including the tick rule implementation (_tick_rule), tracking high/low/open/close prices, and formatting the final bar output (_construct_next_bar).
Our implementations for this section are:
Time Bars: Implemented in
RiskLabAI.data.structures.time_barsas theTimeBarsclass. This class samples bars based on a fixed time duration, which is configured using a human-readable resolution.resolution_type: A string like 'S', 'MIN', 'H' for seconds, minutes, or hours.resolution_units: An integer for the number of units (e.g.,resolution_type='MIN'andresolution_units=5for 5-minute bars).
Standard Bars (Tick, Volume, Dollar): These are implemented in
RiskLabAI.data.structures.standard_barsusing a single, flexibleStandardBarsclass. The behavior is determined by thebar_typestring and athreshold.- To create Tick Bars, we set
bar_type='CUMULATIVE_TICKS'. - To create Volume Bars, we set
bar_type='CUMULATIVE_VOLUME'. - To create Dollar Bars, we set
bar_type='CUMULATIVE_DOLLAR'.
- To create Tick Bars, we set
Implementation
In our RiskLabAI library, we provide a utility function in the utilities_lopez module to aggregate tick-level data into standard OHLCV bars. This function efficiently computes the open, high, low, close, total volume, tick count, and VWAP (volume-weighted average price) for each bar.
Information-Driven Bars
These bars sample more frequently when new information is detected in the market, often by tracking imbalances created by informed traders.
1. Tick Imbalance Bars (TIBs) Samples when the cumulative tick imbalance (buy vs. sell ticks) exceeds an expected threshold.
- Tick Direction:
- Tick Imbalance:
- Expected Imbalance:
- Sampling Condition:
2. Volume and Dollar Imbalance Bars (VIBs/DIBs) Extends TIBs by weighting the imbalance by volume or dollar value.
- Imbalance Indicator:
- Expected Imbalance:
- Sampling Condition:
3. Tick Runs Bars (TRBs) Samples based on consecutive sequences (runs) of buys or sells, which can indicate algorithmic order execution.
- Imbalance Indicator:
- Expected Imbalance:
- Sampling Condition:
4. Volume and Dollar Runs Bars (VRBs/DRBs) Applies the "runs" concept to volume or dollar amounts.
- Imbalance Indicator:
- Expected Imbalance:
- Sampling Condition:
Dealing with Multi-Product Series
This section covers methods for modeling a basket of securities (like a spread or portfolio) as a single time series.
- The ETF Trick: A method to convert a multi-product dataset (e.g., a futures spread) with dynamic weights into a single, continuous total-return series, similar to an ETF. It accounts for holdings, PnL, dividends, and transaction costs.
- Holdings:
- Investment Value:
- Tradeable Basket Units (Volume):
- Holdings:
- PCA Weights: A method to determine portfolio weights () that achieve a user-defined risk distribution () across the principal components (eigenvectors) of the covariance matrix ().
- Covariance Decomposition:
- Portfolio Risk:
- Risk per Component:
- Allocation (Orthogonal Basis):
- Allocation (Original Basis):
- Single Future Roll: A method to create a continuous futures series by calculating and subtracting the cumulative "roll gaps." A more robust method for generating non-negative prices is to compute returns using the rolled price change divided by the raw price, and then take a cumulative product of
(1+r).
In our RiskLabAI.asset_allocation.hedging module, we implement this PCA-based weighting method with the pca_weights function.
This function calculates the eigenvalues and eigenvectors of the covariance matrix. As described in the methodology, a user can pass a specific risk_distribution (the vector) to define the target risk allocation across the principal components, and a risk_target (the value) to scale the overall portfolio. If no risk_distribution is given, the function defaults to allocating 100% of the risk to the component with the smallest eigenvalue, effectively creating a minimum variance portfolio.
Sampling Features
This section discusses methods for selecting relevant observations from structured bars to create feature matrices for ML algorithms.
- Sampling for Reduction:
- Linspace Sampling: Simple sequential sampling (downsampling).
- Uniform Sampling: Randomly drawing samples. Both methods are criticized for not necessarily selecting the most informative observations.
- Event-Based Sampling: The preferred method. Samples are "triggered" when a significant event occurs (e.g., volatility spike, structural break), allowing the ML algorithm to learn from relevant market conditions.
- The CUSUM Filter: A specific event-based sampling technique. It detects a shift in the mean of a series. A sample (event) is triggered when the cumulative sum of deviations () from a target value exceeds a threshold .
- Symmetric CUSUM:
- Sampling: A bar is sampled if , at which point the sum is reset. This prevents multiple triggers from small oscillations around the threshold.
- Symmetric CUSUM:
API reference
RiskLabAI implements these in Python and Julia (signatures auto-generated from the package source):
| Python | Julia |
|---|---|
| |
| |