QF-Lib Documentation

repository·master·Indexed 21 days ago

https://github.com/quarkfin/qf-lib

A Python quantitative finance library for high-quality backtesting of investment strategies using an event-driven architecture. It features flexible data sourcing from Bloomberg, Quandl, Haver Analytics, and Portara, tools to prevent look-ahead bias, and automated summary generation. The library includes comprehensive modules for alpha models, position sizing, commission and slippage modeling, portfolio management, and financial time series analysis.

Tokens
41.7K
Snippets
100
Records
168
Agent score
73%

What's inside qf-lib

  1. What is QF-Lib?

    master

    QF-Lib is a Python library for quantitative finance, primarily focused on backtesting investment strategies using an event-driven architecture. It simulates market events (like daily opening/closing) to allow users to test and evaluate custom strategies.

    Key Features

    • Flexible Data Sourcing: Supports Bloomberg, Quandl, Haver Analytics, and Portara. Note that additional dependencies may be required for specific providers.
    • Look-ahead Bias Prevention: Built-in tools to ensure backtesting integrity.
    • Enhanced Data Containers: Custom containers that extend pandas Series and Dataframes functionality.
    • Summary Generation: Automatically generates informative documents summarizing study results using various available templates.
  2. Overview of QF-Lib

    master

    QF-Lib is a modular Python library designed for quantitative finance. It provides a suite of tools for financial research, including:

    • Event-Driven Backtester: An advanced architecture that simulates market events (such as daily market open and close) to test alpha models, position sizing, commissions, and slippage. It is designed to allow users to move from historical testing to production using the same architecture.
    • Portfolio Construction & Optimization: Tools for building and optimizing investment portfolios.
    • Financial Analysis: Time series analysis, risk monitoring, and rich charting capabilities.
    • Data Handling: Adapted Pandas containers for financial data.
    • Reporting: Exporters for generating publication-ready reports in PDF, Excel, or via email.

    The library was developed at the CERN Pension Fund and is released under the Apache License 2.0.

  3. Explore the QF-Lib API modules

    master

    The QF-Lib public Python API is organized into several specialized modules. Depending on your workflow, you can use the following modules:

    • Backtesting: For event-driven backtesting, including strategies, orders, portfolios, execution, and trading sessions.
    • Data Providers: For market data adapters (supports CSV, Bloomberg, Quandl, YFinance, Alpaca, etc.).
    • Containers: For typed pandas and xarray wrappers for prices, returns, and futures data.
    • Common: For tickers, enums, date utilities, return/risk ratios, and factorisation helpers.
    • Analysis: For tearsheets, timeseries and trade analysis, signals plotting, and overfitting tools.
    • Plotting: For chart classes, decorators, and plotting helpers built on Matplotlib.
    • Document Utils: For exporting reports and results to PDF, HTML, and Excel.
    • Indicators: For market indicators used in strategies or standalone analysis.
    • Portfolio Construction: For portfolio optimisers and weighting models (e.g., Min-Variance, Risk Parity, Black-Litterman).
  4. Use Data Provider classes in qf_lib

    master

    The qf_lib.data_providers module provides a variety of specialized classes for fetching financial data from different sources. You can use these providers to ingest price data, futures data, or other financial datasets into your workflow.

    Available provider types include:

    • Base/Abstract Classes: DataProvider, AbstractPriceDataProvider
    • Specialized Data: FuturesDataProvider
    • Pre-configured/Utility: PresetDataProvider, PrefetchingDataProvider
    • External API/Source Integrations:
      • BinanceDataProvider (Binance)
      • BloombergDataProvider & BloombergDLDataProvider (Bloomberg)
      • CSVDataProvider (Local CSV files)
      • HaverDataProvider (Haver)
      • PortaraDataProvider (Portara)
      • QuandlDataProvider (Quandl)
      • YFinanceDataProvider (Yahoo Finance)
      • AlpacaDataProvider (Alpaca via alpaca-py)
  5. Use the portfolio construction module in qf_lib

    master

    The qf_lib.portfolio_construction module provides a suite of tools for building and optimizing investment portfolios. It includes various portfolio models, optimizers, and advanced estimation techniques like Black-Litterman and Robust Covariance.

    Key components available in this module include:

    Portfolio Models

    These classes represent specific portfolio strategies and objectives:

    • Portfolio: Base portfolio model.
    • EfficientFrontierPortfolio: Portfolios on the efficient frontier.
    • EqualRiskContributionPortfolio: Portfolios where each asset contributes equally to total risk.
    • KellyPortfolio: Portfolios optimized using the Kelly Criterion.
    • MaxDiversificationPortfolio: Portfolios focused on maximizing diversification.
    • MaxExcessReturnPortfolio: Portfolios maximizing return in excess of a benchmark.
    • MaxSharpeRatioPortfolio: Portfolios maximizing the Sharpe ratio.
    • MinVariancePortfolio: Portfolios minimizing total variance.
    • MultiFactorPortfolio: Portfolios constructed using multi-factor models.
    • RiskParityPortfolio: Portfolios designed for risk parity.

    Optimizers

    • QuadraticOptimizer: For solving quadratic programming problems.
    • NonlinearFunctionOptimizer: For solving non-linear optimization problems.

    Advanced Estimation & Models

    • BlackLitterman: Implements the Black-Litterman model for combining market equilibrium with investor views.
    • RobustCovariance: Provides robust methods for estimating covariance matrices.
  6. Configure Backtest Session and Data Request frequencies

    master

    QF-Lib distinguishes between the Backtest Session Frequency (how the simulation steps through time) and the Data Request Frequency (the bar size of the data you fetch).

    Backtest Session Frequency

    Set via BacktestTradingSessionBuilder.set_frequency. This defines the event cycle for computing orders and P&L.

    • Frequency.DAILY: One event cycle per trading day (default).
    • Frequency.MIN_1: One event cycle per minute (intraday).

    Data Request Frequency

    When calling get_price, get_history, or historical_price, you can pass a frequency= argument. This does not have to match the session frequency. For example, you can run a daily backtest but fetch 30-minute bars to calculate an indicator.

    Supported frequencies for data requests:

    • Frequency.MIN_5, Frequency.MIN_15, Frequency.MIN_30, Frequency.MIN_60
    • Frequency.WEEKLY
    • Frequency.MONTHLY
    # Set the backtest to step daily
    session_builder.set_frequency(Frequency.DAILY)
    
    # Inside the strategy, fetch 30-minute bars for an indicator
    series = self.data_provider.historical_price(
        self.ticker, PriceField.Close, nr_of_bars=20, frequency=Frequency.MIN_30
    )
  7. Limit order fills using max_volume_share_limit

    master

    Slippage models in QF-Lib can also limit the volume of an order to prevent it from exceeding a certain percentage of the daily market volume. This prevents unrealistic orders that assume you can trade massive amounts of an asset without moving the market.

    Use the max_volume_share_limit parameter (a float between 0 and 1) when configuring a slippage model. For example, setting max_volume_share_limit=0.15 ensures that the fill volume will not exceed 15% of the daily volume for that asset.

    from qf_lib.backtesting.execution_handler.slippage.price_based_slippage import PriceBasedSlippage
    
    # ... inside main or setup ...
    # Adds 0.1% price slippage and limits fills to 15% of daily volume
    session_builder.set_slippage_model(PriceBasedSlippage, slippage_rate=0.001, max_volume_share_limit=0.15)
  8. Use PositionSizer to manage trade sizing

    master

    A PositionSizer converts Signal objects (which contain suggested_exposure, fraction_at_risk, confidence, and expected_move) into sized Order objects.

    Available built-in options:

    • SimplePositionSizer: Allocates 100% of portfolio per signal (default).
    • FixedPortfolioPercentagePositionSizer: Allocates a fixed percentage of portfolio per signal.
    • InitialRiskPositionSizer: Sizes so that hitting the stop loss risks at most initial_risk of the portfolio.
    • InitialRiskWithVolumePositionSizer: Same as initial-risk sizing, but capped by recent average volume.
  9. How the Backtesting event-driven architecture works

    master

    The Backtester uses an event-driven architecture managed by the EventManager.

    Core Workflow:

    1. The EventManager maintains an events queue.
    2. When dispatch_next_event is called, the manager retrieves the next event from the queue and notifies all registered interested components.
    3. Components can trigger new events by calling the publish(event) method.
    4. The trading_session component acts as the orchestrator, wiring all components together and running the event loop.

    Key Components:

    • alpha_model: Calculates signal objects (containing suggested exposure, confidence, etc.).
    • broker: An abstract interface for simulating market brokers.
    • execution_handler: An abstract class (e.g., SimulatedExecutionHandler) that manages the transition from order objects to actual Transaction objects, handling slippage and commissions.
    • position_sizer: Converts signal objects from the AlphaModel into Order objects.
    • portfolio: Stores the active BacktestPosition objects.
    • data_providers: Market data adapters (CSV, Bloomberg, etc.) that implement the DataProvider interface. Inside a backtest, the session exposes ts.data_provider, which is clock-aware to prevent look-ahead bias (seeing 'data from the future').
  10. Use PeriodicEvent for frequency-based events

    master

    A PeriodicEvent triggers at a predefined frequency (e.g., Frequency.MIN_30) within a specific [start_time, end_time] range.

    Key features:

    • It triggers at the start_time but does not necessarily trigger at the end_time (it stops once the range is exceeded).
    • Use exclude_weekends() to prevent the event from generating on Saturdays and Sundays.
    • PeriodicEvent is implemented for DAILY frequencies and higher (e.g., MIN_60, MIN_15). For monthly or quarterly events, use RegularTimeEvent instead.
    • IntradayBarEvent is a specialized PeriodicEvent with a hardcoded 1-minute frequency used by SimulatedExecutionHandler for intraday trading.
  11. Add visual elements to charts using Decorators

    master

    Decorators are used to add visual or data elements to an existing chart. You apply them by calling chart.add_decorator(decorator_instance).

    Available decorators include:

    • DataElementDecorator: Adds a data series (line or bars).
    • TitleDecorator: Sets the chart title.
    • LegendDecorator: Adds a legend. Use legend.add_entry(data_elem, label) to label specific series.
    • AxesLabelDecorator: Sets x-axis and y-axis labels.
    • AxisTickLabelsDecorator: Customises axis tick labels (e.g., rotation, custom strings).
    • ConeDecorator: Adds a shaded volatility cone to a LineChart.
    • HorizontalLineDecorator: Draws a horizontal reference line.
    • VerticalSpanDecorator: Adds a shaded vertical band (e.g., to highlight a drawdown period).
    • TextDecorator: Places arbitrary text anywhere on the chart.
    • StemDecorator: Adds a stem plot overlay.
    • ScatterDecorator: Adds a scatter plot layer.
    • TopDrawdownDecorator: Highlights the N largest drawdown periods on a line chart.