Documentation

Fama-French factors

QuantCraft can load global Fama-French factor return datasets alongside OHLCV price bars during a backtest or forward run. These are monthly factor returns (FF3 and FF5), fetched once per run — not per ticker. Per-ticker financial statements are a separate feature; see Fundamentals.

This page covers:

  • How Fama-French data differs from fundamentals and from the Trade chart Factor Exposure UI
  • Requirements and how to enable the feature in run modals
  • How to read factor rows in your strategy code

Fama-French vs fundamentals

FundamentalsFama-French factors
DataPer-ticker files (balance sheet, earnings, …)One global monthly factor dataset
Algo accessfundamentals callback argument (fundamentals.current(...))fama_french.qc module singleton
Callback kwargYes — on_bar(..., fundamentals=...)No — read fama_french.qc inside any callback

OHLCV symbols, fundamentals bundles, and Fama-French factors are independent — you can enable any combination in the run modal.


Not the Trade chart Factor Exposure tab

The Trade chart Fundamentals → Factor Exposure tab runs client-side FF3/FF5 regression against chart OHLC. That UI is out of scope for algos. Strategies receive raw monthly factor return rows only (ff3_monthly, ff5_monthly).


Requirements

  • Premium QuantCraft subscription (same gate as fundamentals).
  • Signed in — a valid QuantCraft session token is sent when the checkbox is enabled.
  • UI: Include Fama-French factors (global) is on by default for Premium users in the Run backtest and Chart forward test modals. Uncheck to omit factor data for that run.

Configure from Test (Running code) for backtests, or from Algo Trading Parameters on chart forward runs.


Quick start

After the engine loads factor data, read the singleton inside a callback:

from quantcraft import fama_french def on_bar(bar_index, bar, fundamentals=None, symbol=None): qc = fama_french.qc if qc is None: return # checkbox off or load failed latest = qc.latest_row("ff3_monthly") if latest: mkt_rf = float(latest.get("Mkt-RF", 0)) smb = float(latest.get("SMB", 0)) hml = float(latest.get("HML", 0))

Preferred pattern: from quantcraft import fama_french, then read fama_french.qc inside callbacks (on_init, on_bar, on_tick, …). Do not use from quantcraft.fama_french import qc at module top level — that captures None at import time before the engine loads data.

Alternative: from quantcraft.backtest.runtime import qc_fama_french in callbacks (same live object when set; prefer fama_french.qc in new code).

Legacy from ide.factors_module import … still works for existing strategies.


Reading factor rows

Monthly data lives in datasets keyed by YYYYMM strings (e.g. "192607"), not list indices.

MethodPurpose
qc.latest_row("ff3_monthly")Most recent month as { yyyymm, Mkt-RF, SMB, HML, RF, … }
qc.row("ff3_monthly", "202604")One specific month
qc.rows_chronological("ff5_monthly")Oldest-first list; each item includes yyyymm

Dataset ids:

KeyContents
ff3_monthlyFama-French 3-factor monthly returns
ff5_monthlyFama-French 5-factor monthly returns

Typical FF3 keys: Mkt-RF, SMB, HML, RF. FF5 adds RMW, CMA. Values are decimal strings (percent ÷ 100) — use float(...) for arithmetic.

# Helpers (recommended) latest = fama_french.qc.latest_row("ff3_monthly") history = fama_french.qc.rows_chronological("ff5_monthly") # Raw dict access (keys are YYYYMM strings — not rows[0] / rows[-1]) ff3_rows = fama_french.qc.datasets["ff3_monthly"]["rows"] july_1926 = ff3_rows["192607"]

Enabling in the IDE

Run backtest

In Test → Run backtest, tick Include Fama-French factors (global) (Premium; on by default). Requires sign-in. The engine loads data before your on_init() runs.

There is no factors= callback argument on on_tick / on_bar. Import quantcraft.fama_french and use fama_french.qc.

Chart forward test

In Trade → Algo Trading Parameters, use the same Include Fama-French factors (global) checkbox (default on for Premium).

Bulk forward / Quant Cloud

Bulk forward edit/restart can pass through a saved factors block when present on the draft. See Quant Cloud and Run presets (.qcs).


Run presets (.qcs)

Saved run settings can include:

{ "includeFactors": true }

Loading a preset with includeFactors: true requires Premium; the free tier clears the flag on load. See Run presets (.qcs).


Common mistakes

  • rows[0] / rows[-1] — invalid. dataset["rows"] is a dict keyed by "YYYYMM", not a list. Use latest_row, row, or rows_chronological.
  • from quantcraft.fama_french import qc at file top — captures None before the engine loads data.
  • Expecting a factors= callback — use fama_french.qc inside on_init / on_bar / on_tick instead.

Failure behavior

If the checkbox is on but the fetch fails, the engine logs to stderr (e.g. factors load failed: …) and leaves fama_french.qc = None. Check the Output panel. Always guard before use.