长期市净率 (PB Ratio) 效应与动量策略结合在股票中的应用

登录后收藏

Onsite backtest IDE

Quant Buffet 原生回测 IDE

Edit and run Quant Buffet Python for 长期市净率 (PB Ratio) 效应与动量策略结合在股票中的应用 in the browser. Results update live with equity, drawdown, and metrics charts. Allowed: backtest.data, backtest.engine, backtest.metrics, numpy, pandas. Define ASSETS and make_on_day(prices). Shortcut: Ctrl+Enter. API docs →

Ready — edit code, then Run backtest.
IDE · 36 lines
Quant Buffet syntax cheat sheet (copy / insert)

Paste these fragments into the editor. The sandbox rejects QuantConnect, os, and network libraries.

Required imports
Only these libraries are allowed in the sandbox.
from __future__ import annotations

import numpy as np
import pandas as pd

from backtest.data import load_daily_prices
from backtest.engine import EngineConfig, PortfolioEngine
from backtest.metrics import compute_metrics
ASSETS list (whitelisted ETFs)
Module-level list. Tickers must be in the Quant Buffet whitelist.
ASSETS = ["SPY", "QQQ", "TLT", "GLD", "BIL"]
make_on_day contract
Must return (on_day, ready). on_day calls engine.set_target_weights.
def make_on_day(prices: pd.DataFrame):
    cols = [c for c in ASSETS if c in prices.columns]
    sma = prices[cols].rolling(200, min_periods=200).mean()
    state = {"last": None}

    def on_day(engine: PortfolioEngine, dt: pd.Timestamp) -> None:
        if sma.loc[dt].isna().all():
            return
        key = (dt.year, dt.month)
        if state["last"] == key:
            return
        state["last"] = key
        long = [
            s for s in cols
            if pd.notna(prices.at[dt, s]) and pd.notna(sma.at[dt, s])
            and prices.at[dt, s] > sma.at[dt, s]
        ]
        weights = {} if not long else {s: 1.0 / len(long) for s in long}
        engine.set_target_weights(dt, weights)

    ready = sma.dropna(how="all").index.min() if sma.notna().any().any() else None
    return on_day, ready
Set target weights
Weights should sum to about 1.0. Empty dict = 100% cash.
engine.set_target_weights(dt, {"SPY": 0.60, "BIL": 0.40})

Live backtest performance

CAGR
6.00%
Sharpe
0.63
Max DD
-18.15%
Vol
10.11%
Sortino
0.93
Beta
0.35
Up days
73%

Run the backtest to populate charts.

Export to your platform

Transform Quant Buffet lab code (ASSETS + make_on_day / PortfolioEngine) into native classes for a third-party IDE — then copy and paste.

Run in: QuantConnect Cloud or LEAN CLI · QCAlgorithm with Equity securities and monthly rebalance.

Detected pattern: Absolute momentumAssets: SPY, TLT, GLD, BIL
# Generated from Quant Buffet → QuantConnect LEAN
# Strategy: 长期市净率 (PB Ratio) 效应与动量策略结合在股票中的应用
# Detected pattern: Absolute momentum
# Source uses Quant Buffet lab APIs (ASSETS + make_on_day / PortfolioEngine).
# Review fees, data, and risk before live trading — educational export only.

from AlgorithmImports import *


class QuantBuffetExport(QCAlgorithm):
    def Initialize(self):
        self.SetStartDate(2010, 1, 1)
        self.SetCash(100000)
        tickers = ["SPY", "TLT", "GLD", "BIL"]
        self.symbols = []
        for t in tickers:
            if "-" in t:  # crypto proxy e.g. BTC-USD
                self.symbols.append(self.AddCrypto(t.replace("-USD", ""), Resolution.Daily).Symbol)
            else:
                self.symbols.append(self.AddEquity(t, Resolution.Daily).Symbol)
        self.Schedule.On(
            self.DateRules.MonthStart(self.symbols[0]),
            self.TimeRules.AfterMarketOpen(self.symbols[0], 30),
            self.Rebalance,
        )
        # Logic: Long assets with positive 252-day return; equal-weight; monthly.

    def Rebalance(self):
        # Pattern: abs_momentum — Long assets with positive 252-day return; equal-weight; monthly.
        # Default: equal-weight. Port your make_on_day weights here via SetHoldings.
        w = 1.0 / len(self.symbols) if self.symbols else 0.0
        for symbol in self.symbols:
            self.SetHoldings(symbol, w)

导出代码使用目标平台的原生类与库。请在第三方 IDE 中安装依赖后运行;实盘前请自行验证。

学术论文

On the Performance of Cyclically Adjusted Valuation Measures

作者关于经周期调整估值指标的表现 [点击查看论文]

机构
  • ?Alpha Architect
  • Villanova University

原文论文截图

Screenshot from the original paper
Screenshot from the original paper

策略概要

该策略的目标是纽约证券交易所/美国证券交易所/纳斯达克市场中市值高于纽约证券交易所第40百分位的公司,排除房地产投资信托基金(REITs)、美国存托凭证(ADRs)、封闭式基金和金融公司,并要求有10年的基本面数据。每月,使用当前价格和经通货膨胀调整的过去10年的账面价值计算周期性调整的账面市值比。股票被分为十分位数,并选择最高的十分位数(最高的账面市值比)。这些股票再按过去12-2个月的动量进行划分,动量较高的那一半股票被纳入等权重的投资组合。投资组合每月进行再平衡,结合价值和动量因素以获得系统性的投资机会。

II. 策略合理性

通过在商业周期内平滑价格和账面价值的波动,增加市净率计算的年限可以增强其预测能力。以低市净率(price-to-book ratios)为特征的价值型公司,持续跑赢市场回报,这主要归因于投资者对成长型股票的过度反应,导致价值型股票被低估。在价值型股票中添加动量过滤器有助于识别那些基本面改善和价格上涨的股票,将其与较弱的股票区分开来。这种价值和动量的结合通过捕捉具有积极增长趋势的低估机会,提高了基本价值策略的绩效,为投资决策提供了更有效的方法。

回测表现

年化收益6.00%
波动率10.11%
贝塔0.35
夏普比率0.63
索提诺比率0.93
最大回撤-18.15%
胜率73%