How the Betting Against Beta Factor Strategy Works: A Complete Python Implementation

The betting against beta factor strategy constructs a market-neutral portfolio by going long low-beta securities and short high-beta securities, scaling each leg to achieve a target beta of 1.0 to capture the risk-adjusted premium where low-beta assets outperform.

The betting against beta factor strategy is a systematic approach implemented in the awesome-systematic-trading repository that exploits the empirical inverse relationship between market beta and expected returns. This strategy creates a zero-cost, zero-beta portfolio by leveraging the spread between low-beta and high-beta assets across US equities and global country ETFs.

Core Mechanics of the Betting Against Beta Strategy

The strategy follows a rigorous quantitative pipeline from data collection through execution. According to the source code in the paperswithbacktest/awesome-systematic-trading repository, the implementation relies on rolling window calculations and precise beta estimation to maintain market neutrality.

Data Collection and Beta Calculation

Each implementation maintains a rolling window of daily closing prices spanning approximately 252 trading days (self.period = 12 * 21). In betting-against-beta-factor-in-stocks.py, this data feeds into QuantConnect's coarse and fine selection pipeline, while the country ETF version processes incoming price ticks directly.

Beta estimation follows the standard financial formula implemented using NumPy:

cov = np.cov(asset_returns, market_returns)[0][1]
market_variance = np.var(market_returns)
beta = cov / market_variance

In the stock implementation (lines 100-106), this calculation uses a one-year rolling window of returns against the SPY benchmark. The country ETF version (lines 84-89) applies the same formula after refreshing monthly price windows.

Portfolio Construction and Decile Ranking

Assets are ranked by their estimated beta to form long and short legs. The US equities implementation in betting-against-beta-factor-in-stocks.py uses a decile-based approach (lines 112-116):

  • Long leg: Lowest-beta decile (bottom 10%)
  • Short leg: Highest-beta decile (top 10%)

For the country ETF implementation in betting-against-beta-factor-in-country-equity-indexes.py, the strategy uses a median split, placing assets below the median beta in the long portfolio and those above in the short portfolio (lines 95-97).

Leverage Normalization for Market Neutrality

To achieve true market neutrality, each leg is beta-scaled to target a portfolio beta of 1.0:

long_lvg = 1 / long_mean_beta
short_lvg = 1 / short_mean_beta

This scaling ensures the long and short positions offset market exposure. The implementation caps leverage via self.leverage_cap to prevent excessive margin requirements (lines 28-35 for stocks, lines 46-52 for ETFs).

Implementation Details for US Equities

The betting-against-beta-factor-in-stocks.py file implements the strategy for a CRSP-like universe of US equities. The algorithm uses QuantConnect's RollingWindow[float] objects to maintain price history and calculates betas against the SPY benchmark.

Rebalancing occurs at the start of each month using the Selection scheduler (line 41). Positions are entered via SetHoldings (lines 55-58) with a custom fee model (CustomFeeModel) set to 0.5 basis points to simulate realistic transaction costs. The implementation enforces a leverage limit of self.leverage_cap * 3 to control margin risk.

Implementation Details for Country ETFs

The betting-against-beta-factor-in-country-equity-indexes.py file adapts the strategy for global equity-style ETFs. This version processes price data directly from incoming ticks and triggers rebalancing when the month changes (lines 72-74).

Rather than deciles, this implementation uses a median-beta split to create balanced long and short exposure. The leverage cap is set to 15x for this universe, reflecting the different volatility characteristics of diversified country indexes compared to individual stocks.

Risk Management and Execution

Both implementations employ strict risk controls through the CustomFeeModel class and leverage limits. The stock version applies fees of 0.5 basis points per trade, while position sizing respects the calculated leverage ratios to maintain the zero-beta target.

The SetHoldings method adjusts portfolio weights automatically based on the scaled betas, ensuring the strategy remains market-neutral after each rebalance. This execution framework allows the strategy to capture the betting against beta premium while isolating idiosyncratic risk from systematic market movements.

Summary

  • The betting against beta factor strategy exploits the inverse relationship between beta and risk-adjusted returns by going long low-beta assets and short high-beta assets.
  • Beta calculation uses 252-day rolling windows of daily returns against a market benchmark (SPY), implemented via np.cov and np.var in lines 100-106 of the stock file.
  • Portfolio construction uses decile ranking for US equities and median splits for country ETFs to form long and short legs.
  • Leverage normalization scales each leg to achieve a target beta of 1.0, creating a zero-cost, market-neutral portfolio.
  • Monthly rebalancing and custom fee models ensure realistic backtesting conditions in QuantConnect.

Frequently Asked Questions

What is the betting against beta anomaly?

The betting against beta anomaly refers to the empirical finding that low-beta securities generate higher risk-adjusted returns than predicted by the Capital Asset Pricing Model (CAPM), while high-beta securities underperform. This violates the standard CAPM assumption that higher beta should correlate linearly with higher expected returns, creating an exploitable spread for market-neutral strategies.

How is beta calculated in the betting against beta strategy?

Beta is calculated as the covariance between asset returns and market returns divided by the variance of market returns: beta = cov(asset_returns, market_returns) / var(market_returns). The awesome-systematic-trading implementation uses NumPy's np.cov and np.var functions on 252-day rolling windows to estimate this relationship daily for each security in the universe.

What is the difference between the stock and ETF implementations?

The stock implementation in betting-against-beta-factor-in-stocks.py uses decile-based ranking (bottom 10% long, top 10% short) and leverages QuantConnect's coarse/fine universe selection pipeline. The country ETF implementation in betting-against-beta-factor-in-country-equity-indexes.py uses a simpler median split and processes price data directly from ticks, with a higher leverage cap (15x vs. variable stock cap) reflecting the diversification benefits of country indexes.

Why is leverage scaling important in BAB strategies?

Leverage scaling ensures the portfolio achieves market neutrality by adjusting position sizes inversely to the average beta of each leg. By applying 1 / mean_beta scaling to both long and short positions, the strategy creates a zero-beta portfolio that isolates the alpha from the beta-return relationship while eliminating exposure to broad market movements.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →