---
title: "Fama French"
description: "Fama French dataset from QuantConnect."
canonical: https://www.quantconnect.com/docs/v2/writing-algorithms/datasets/quantconnect/fama-french
markdown: https://www.quantconnect.com/docs/v2/writing-algorithms/datasets/quantconnect/fama-french.md
language: python
source: https://github.com/QuantConnect/Documentation/tree/master/03%20Writing%20Algorithms/14%20Datasets/02%20QuantConnect/14%20Fama%20French
modified: 2026-11-11
index: https://www.quantconnect.com/llms.txt
---

# Fama French

[Documentation](https://www.quantconnect.com/docs/v2.md) > [Writing Algorithms](https://www.quantconnect.com/docs/v2/writing-algorithms.md) > Datasets > [QuantConnect](https://www.quantconnect.com/docs/v2/writing-algorithms/datasets/quantconnect.md) > Fama French

> Code examples are shown in Python. Append `?lang=csharp` to this URL for the C# version of this page.

## Introduction

The Fama-French Factors dataset by QuantConnect provides calculated returns of the Fama-French five-factor model, the momentum factor, and the risk-free rate for US Equities. The data covers the US Equity market, starts in January 1998, and is delivered on a daily frequency. This dataset is created by computing each factor from US Equity fundamentals and prices, built to the published Fama-French definitions.

For more information about the Fama French dataset, including CLI commands and pricing, see the [dataset listing](https://www.quantconnect.com/datasets/quantconnect-fama-french).

## About the Provider

QuantConnect was founded in 2012 to serve quants everywhere with the best possible algorithmic trading technology. Seeking to disrupt a notoriously closed-source industry, QuantConnect takes a radically open-source approach to algorithmic trading. Through the QuantConnect web platform, more than 50,000 quants are served every month.

## Getting Started

The following snippet demonstrates how to request data from the Fama-French Factors dataset:

```python
self.fama_french = self.add_data(FamaFrench, "FF", Resolution.DAILY).symbol
```

## Data Summary

The following table describes the dataset properties:

| Property | Value |
| --- | --- |
| Start Date | January 1998 |
| Asset Coverage | 1 US Equity Market Series |
| Data Density | Regular |
| Resolution | Daily |
| Timezone | New York |

## Requesting Data

To add Fama-French Factors data to your algorithm, call the `add_data` method. Save a reference to the dataset `Symbol` so you can access the data later in your algorithm.

```python
class FamaFrenchDataAlgorithm(QCAlgorithm):
    def initialize(self) -> None:
        self.set_start_date(2020, 1, 1)
        self.set_end_date(2020, 12, 31)
        self.set_cash(100000)

        self.spy = self.add_equity("SPY", Resolution.DAILY).symbol
        self.fama_french = self.add_data(FamaFrench, "FF", Resolution.DAILY).symbol
```

## Accessing Data

To get the current Fama-French Factors data, index the current [`Slice`](https://www.quantconnect.com/docs/v2/writing-algorithms/key-concepts/time-modeling/timeslices.md) with the dataset `Symbol`. `Slice` objects deliver unique events to your algorithm as they happen, but the `Slice` may not contain data for your dataset at every time step. To avoid issues, check if the `Slice` contains the data you want before you index it.

```python
def on_data(self, slice: Slice) -> None:
    if slice.contains_key(self.fama_french):
        factors = slice[self.fama_french]
        self.log(f"Momentum at {slice.time}: {factors.momentum}")
```

To iterate through all of the dataset objects in the current `Slice`, call the `get` method.

```python
def on_data(self, slice: Slice) -> None:
    for dataset_symbol, data_point in slice.get(FamaFrench).items():
        self.log(f"{dataset_symbol} momentum at {slice.time}: {data_point.momentum}")
```

## Historical Data

To get historical Fama-French Factors data, call the `history` method with the dataset `Symbol`. If there is no data in the period you request, the history result is empty.

```python
# DataFrame
history_df = self.history(self.fama_french, 100, Resolution.DAILY)

# Dataset objects
history_bars = self.history[FamaFrench](self.fama_french, 100, Resolution.DAILY)
```

For more information about historical data, see [History Requests](https://www.quantconnect.com/docs/v2/writing-algorithms/historical-data/history-requests.md).

## Remove Subscriptions

To remove your subscription to Fama-French Factors data, call the `remove_security` method.

```python
self.remove_security(self.fama_french)
```

## Example Applications

The Fama-French Factors dataset enables you to measure and time factor exposure in your strategies. Examples include the following strategies:

- Regressing strategy returns on the factors to separate alpha from factor exposure
- Rotating between value and growth tilts based on recent value factor returns
- Holding equity risk only when the momentum factor is trending up

### Classic Algorithm Example

The following example algorithm buys SPY when the Fama-French momentum factor is positive. Otherwise, it holds cash.

```python
from AlgorithmImports import *

class FamaFrenchFactorsAlgorithm(QCAlgorithm):
    def initialize(self):
        self.set_start_date(2020, 1, 1)
        self.set_end_date(2020, 12, 31)
        self.set_cash(100000)

        self.spy = self.add_equity("SPY", Resolution.DAILY).symbol
        self.fama_french = self.add_data(FamaFrench, "FF", Resolution.DAILY).symbol

        history = self.history[FamaFrench](self.fama_french, 60, Resolution.DAILY)
        self.debug(f"We got {len(list(history))} items from our history request")

    def on_data(self, slice):
        if not slice.contains_key(self.fama_french):
            return

        momentum = slice[self.fama_french].momentum
        if momentum is None:
            return

        # Invest the whole portfolio in SPY while the momentum factor is positive
        if momentum > 0:
            self.set_holdings(self.spy, 1)

        # Liquidate SPY while the momentum factor is zero or negative
        else:
            self.liquidate(self.spy)
```

### Framework Algorithm Example

The following example algorithm emits an up insight for SPY when the Fama-French momentum factor is positive. Otherwise, it emits a flat insight.

```python
from AlgorithmImports import *

class FamaFrenchFrameworkAlgorithm(QCAlgorithm):

    def initialize(self) -> None:
        self.set_start_date(2020, 1, 1)
        self.set_end_date(2020, 12, 31)
        self.set_cash(100000)

        self.universe_settings.resolution = Resolution.DAILY

        symbols = [Symbol.create("SPY", SecurityType.EQUITY, Market.USA)]
        self.set_universe_selection(ManualUniverseSelectionModel(symbols))

        self.add_alpha(FamaFrenchAlphaModel(self))

        self.set_portfolio_construction(EqualWeightingPortfolioConstructionModel())
        self.set_execution(ImmediateExecutionModel())

class FamaFrenchAlphaModel(AlphaModel):

    def __init__(self, algorithm: QCAlgorithm) -> None:
        self._tradable_symbols = []

        # Add the Fama-French factors data.
        self._fama_french = algorithm.add_data(FamaFrench, "FF", Resolution.DAILY).symbol

        history = algorithm.history[FamaFrench](self._fama_french, 60, Resolution.DAILY)
        algorithm.debug(f"We got {len(list(history))} items from our history request")

    def update(self, algorithm: QCAlgorithm, data: Slice) -> List[Insight]:
        if self._fama_french not in data:
            return []

        momentum = data[self._fama_french].momentum
        if momentum is None:
            return []

        # Emit an up insight when momentum is positive, otherwise a flat insight.
        direction = InsightDirection.UP if momentum > 0 else InsightDirection.FLAT
        return [Insight.price(symbol, timedelta(days=7), direction) for symbol in self._tradable_symbols]

    def on_securities_changed(self, algorithm: QCAlgorithm, changes: SecurityChanges) -> None:
        for security in changes.added_securities:
            if security.symbol != self._fama_french:
                self._tradable_symbols.append(security.symbol)

        for security in changes.removed_securities:
            if security.symbol in self._tradable_symbols:
                self._tradable_symbols.remove(security.symbol)
```

## Data Point Attributes

The Fama-French Factors dataset provides `FamaFrench` objects, which have the following attributes:

*Members of `QuantConnect.DataSource.FamaFrench` (JSON): https://www.quantconnect.com/services/inspector?type=T:QuantConnect.DataSource.FamaFrench&language=python*
