多维度股票量化指标体系详解

目录

[1. 估值维度指标](#1. 估值维度指标)

[1.1 相对估值指标](#1.1 相对估值指标)

[1.2 Python实现相对估值指标计算](#1.2 Python实现相对估值指标计算)

[2. 技术分析维度指标](#2. 技术分析维度指标)

[2.1 趋势指标](#2.1 趋势指标)

[2.1.1 移动平均线(MA)](#2.1.1 移动平均线(MA))

[2.1.2 MACD (移动平均线收敛散度)](#2.1.2 MACD (移动平均线收敛散度))

[2.2 Python实现MACD指标计算](#2.2 Python实现MACD指标计算)

[2.3 震荡指标](#2.3 震荡指标)

[2.3.1 RSI (相对强弱指数)](#2.3.1 RSI (相对强弱指数))

[2.4 Python实现RSI指标计算](#2.4 Python实现RSI指标计算)

[3. 资金流向维度指标](#3. 资金流向维度指标)

[3.1 资金流向指标](#3.1 资金流向指标)

[3.2 Python实现OBV指标计算](#3.2 Python实现OBV指标计算)

[4. 基本面维度指标](#4. 基本面维度指标)

[4.1 盈利能力指标](#4.1 盈利能力指标)

[4.2 Python实现盈利能力指标计算](#4.2 Python实现盈利能力指标计算)

[5. 市场情绪维度指标](#5. 市场情绪维度指标)

[5.1 市场情绪指标](#5.1 市场情绪指标)

[5.2 Python实现波动率计算](#5.2 Python实现波动率计算)

[6. 多维度指标的综合应用](#6. 多维度指标的综合应用)

[6.1 构建综合评分模型](#6.1 构建综合评分模型)

[6.2 多维度背离识别](#6.2 多维度背离识别)

[7. 实战应用与注意事项](#7. 实战应用与注意事项)

[7.1 指标组合使用策略](#7.1 指标组合使用策略)

[7.2 注意事项](#7.2 注意事项)

[8. 完整的量化分析框架示例](#8. 完整的量化分析框架示例)

结论


在股票量化投资领域,单一维度的分析往往难以捕捉市场的全貌。构建科学、全面的多维度指标体系是识别股价与价值背离、预测行情涨跌的基础。本文将系统地介绍五大核心维度的指标体系,并提供Python实现代码,帮助投资者构建自己的量化分析框架。

1. 估值维度指标

估值维度反映了股票价格与公司基本面价值之间的关系,是判断股票是否被高估或低估的重要依据。

1.1 相对估值指标

指标名称 计算公式 含义与应用 适用场景
市盈率(P/E) 股价 / 每股收益 反映投资者愿意为每1元收益支付的价格 稳定盈利的成熟企业
市净率(P/B) 股价 / 每股净资产 反映投资者愿意为每1元净资产支付的价格 重资产行业、金融行业
市销率(P/S) 股价 / 每股销售额 反映投资者愿意为每1元销售额支付的价格 尚未盈利的成长型公司
市盈率相对盈利增长比率(PEG) 市盈率 / 盈利增长率 考虑成长性的市盈率指标 高增长企业

1.2 Python实现相对估值指标计算

python 复制代码
import numpy as np
import pandas as pd

def calculate_valuation_metrics(price, eps, bvps, sales_per_share, growth_rate=None):
    """
    计算相对估值指标
    
    参数:
    price: 股价
    eps: 每股收益
    bvps: 每股净资产
    sales_per_share: 每股销售额
    growth_rate: 年盈利增长率(可选)
    
    返回:
    包含各估值指标的字典
    """
    # 处理可能的零值或NaN值
    if eps == 0 or eps is None:
        pe = None
    else:
        pe = price / eps
    
    if bvps == 0 or bvps is None:
        pb = None
    else:
        pb = price / bvps
    
    if sales_per_share == 0 or sales_per_share is None:
        ps = None
    else:
        ps = price / sales_per_share
    
    # 计算PEG比率
    if pe is not None and growth_rate and growth_rate != 0:
        peg = pe / growth_rate
    else:
        peg = None
    
    return {
        '市盈率(P/E)': pe,
        '市净率(P/B)': pb,
        '市销率(P/S)': ps,
        'PEG比率': peg
    }

# 测试代码
def test_valuation_metrics():
    # 测试正常情况
    result = calculate_valuation_metrics(price=100, eps=5, bvps=20, sales_per_share=25, growth_rate=0.2)
    assert round(result['市盈率(P/E)'], 2) == 20.0
    assert round(result['市净率(P/B)'], 2) == 5.0
    assert round(result['市销率(P/S)'], 2) == 4.0
    assert round(result['PEG比率'], 2) == 100.0  # 注意:这里的增长率通常用百分比的绝对值
    
    # 测试零值处理
    result = calculate_valuation_metrics(price=100, eps=0, bvps=20, sales_per_share=25)
    assert result['市盈率(P/E)'] is None
    
    print("估值指标计算测试通过!")

2. 技术分析维度指标

技术分析维度主要通过研究价格和成交量的历史数据,识别可能的价格走势和反转信号。

2.1 趋势指标

2.1.1 移动平均线(MA)

移动平均线是最基础的技术分析指标,通过平滑价格数据来识别趋势方向。常见的移动平均线包括5日、10日、20日、60日、120日和250日均线。

2.1.2 MACD (移动平均线收敛散度)

MACD是一种趋势跟踪和动量指标,由两线一柱组成:快速移动平均线、慢速移动平均线和柱状图。它能够识别趋势变化的强度和方向。

2.2 Python实现MACD指标计算

python 复制代码
import pandas as pd
import numpy as np

def calculate_macd(prices, fast_period=12, slow_period=26, signal_period=9):
    """
    计算MACD指标
    
    参数:
    prices: 价格序列(Pandas Series或列表)
    fast_period: 快速EMA的周期,默认12
    slow_period: 慢速EMA的周期,默认26
    signal_period: 信号线EMA的周期,默认9
    
    返回:
    包含MACD线、信号线和柱状图的字典
    """
    # 确保输入是Pandas Series
    if not isinstance(prices, pd.Series):
        prices = pd.Series(prices)
    
    # 计算快速和慢速EMA
    fast_ema = prices.ewm(span=fast_period, adjust=False).mean()
    slow_ema = prices.ewm(span=slow_period, adjust=False).mean()
    
    # 计算MACD线
    macd_line = fast_ema - slow_ema
    
    # 计算信号线(MACD的EMA)
    signal_line = macd_line.ewm(span=signal_period, adjust=False).mean()
    
    # 计算柱状图
    histogram = macd_line - signal_line
    
    return {
        'macd_line': macd_line,
        'signal_line': signal_line,
        'histogram': histogram
    }

# 测试代码
def test_macd():
    # 创建测试数据
    np.random.seed(42)
    test_prices = pd.Series(np.random.rand(50) * 100 + 100)
    
    # 计算MACD
    result = calculate_macd(test_prices)
    
    # 验证结果不为空
    assert len(result['macd_line']) == len(test_prices)
    assert len(result['signal_line']) == len(test_prices)
    assert len(result['histogram']) == len(test_prices)
    
    # 验证第一个值(由于EMA的计算方式,第一个值应该等于价格)
    assert result['macd_line'].iloc[0] == 0  # 因为fast_ema和slow_ema的第一个值都等于价格
    
    print("MACD计算测试通过!")

2.3 震荡指标

2.3.1 RSI (相对强弱指数)

RSI是衡量价格变动速度和幅度的指标,用于判断超买超卖情况。RSI的取值范围为0到100,通常认为RSI>70表示超买,RSI<30表示超卖。

2.4 Python实现RSI指标计算

python 复制代码
import pandas as pd
import numpy as np

def calculate_rsi(prices, period=14):
    """
    计算RSI(相对强弱指数)
    
    参数:
    prices: 价格序列(Pandas Series或列表)
    period: 计算周期,默认14
    
    返回:
    RSI值序列
    """
    # 确保输入是Pandas Series
    if not isinstance(prices, pd.Series):
        prices = pd.Series(prices)
    
    # 计算价格变化
    delta = prices.diff()
    
    # 分离涨跌
    gain = (delta.where(delta > 0, 0)).rolling(window=period).mean()
    loss = (-delta.where(delta < 0, 0)).rolling(window=period).mean()
    
    # 计算相对强弱
    rs = gain / loss
    
    # 计算RSI
    rsi = 100 - (100 / (1 + rs))
    
    return rsi

# 测试代码
def test_rsi():
    # 创建测试数据 - 完全上涨的情况
    up_prices = pd.Series(range(1, 20))
    rsi_up = calculate_rsi(up_prices)
    # 完全上涨的序列最后几个RSI值应该接近100
    assert rsi_up.iloc[-1] > 90
    
    # 创建测试数据 - 完全下跌的情况
    down_prices = pd.Series(range(20, 1, -1))
    rsi_down = calculate_rsi(down_prices)
    # 完全下跌的序列最后几个RSI值应该接近0
    assert rsi_down.iloc[-1] < 10
    
    # 创建测试数据 - 震荡行情
    np.random.seed(42)
    volatile_prices = pd.Series(np.random.rand(50) * 20 + 100)
    rsi_volatile = calculate_rsi(volatile_prices)
    # RSI值应该在合理范围内
    assert rsi_volatile.dropna().min() >= 0
    assert rsi_volatile.dropna().max() <= 100
    
    print("RSI计算测试通过!")

3. 资金流向维度指标

资金流向维度主要关注市场资金的流入流出情况,能够帮助我们了解市场主力的行为和意图。

3.1 资金流向指标

指标名称 计算方法 含义与应用
大单净流入 大单买入金额 - 大单卖出金额 反映大资金的流向趋势
资金净流入率 (当日资金净流入 / 当日成交额) * 100% 反映资金流入的相对强度
OBV (能量潮) 基于价格变动方向累计成交量 通过成交量变化预测价格趋势

3.2 Python实现OBV指标计算

python 复制代码
import pandas as pd

def calculate_obv(prices, volumes):
    """
    计算OBV(能量潮)指标
    
    参数:
    prices: 价格序列(收盘价)
    volumes: 成交量序列
    
    返回:
    OBV值序列
    """
    # 确保输入是Pandas Series
    if not isinstance(prices, pd.Series):
        prices = pd.Series(prices)
    if not isinstance(volumes, pd.Series):
        volumes = pd.Series(volumes)
    
    # 创建价格变化的掩码
    price_change = prices.diff()
    
    # 创建OBV序列,初始值为0
    obv = pd.Series(0, index=prices.index)
    
    # 计算OBV
    for i in range(1, len(prices)):
        if price_change.iloc[i] > 0:
            # 价格上涨,加上成交量
            obv.iloc[i] = obv.iloc[i-1] + volumes.iloc[i]
        elif price_change.iloc[i] < 0:
            # 价格下跌,减去成交量
            obv.iloc[i] = obv.iloc[i-1] - volumes.iloc[i]
        else:
            # 价格不变,OBV不变
            obv.iloc[i] = obv.iloc[i-1]
    
    return obv

# 测试代码
def test_obv():
    # 创建测试数据
    dates = pd.date_range('2023-01-01', periods=5)
    prices = pd.Series([100, 101, 100, 102, 103], index=dates)
    volumes = pd.Series([1000, 1200, 1100, 1300, 1400], index=dates)
    
    # 计算OBV
    obv = calculate_obv(prices, volumes)
    
    # 手动计算的预期结果
    expected_obv = pd.Series([0, 1200, 100, 1400, 2800], index=dates)
    
    # 验证结果
    pd.testing.assert_series_equal(obv, expected_obv)
    
    print("OBV计算测试通过!")

4. 基本面维度指标

基本面维度关注企业的内在价值,通过分析财务数据评估企业的盈利能力、成长能力和财务健康度。

4.1 盈利能力指标

指标名称 计算公式 含义与应用
ROE (净资产收益率) 净利润 / 平均净资产 * 100% 衡量企业运用净资产盈利的能力
ROA (总资产收益率) 净利润 / 平均总资产 * 100% 衡量企业运用全部资产盈利的能力
净利率 净利润 / 营业收入 * 100% 反映企业的最终盈利能力

4.2 Python实现盈利能力指标计算

python 复制代码
def calculate_profitability_metrics(net_profit, revenue, total_assets_begin, total_assets_end, equity_begin, equity_end):
    """
    计算盈利能力指标
    
    参数:
    net_profit: 净利润
    revenue: 营业收入
    total_assets_begin: 期初总资产
    total_assets_end: 期末总资产
    equity_begin: 期初净资产
    equity_end: 期末净资产
    
    返回:
    包含各盈利能力指标的字典
    """
    # 计算平均资产和平均净资产
    avg_total_assets = (total_assets_begin + total_assets_end) / 2
    avg_equity = (equity_begin + equity_end) / 2
    
    # 计算ROE、ROA和净利率
    if avg_equity != 0:
        roe = (net_profit / avg_equity) * 100
    else:
        roe = None
    
    if avg_total_assets != 0:
        roa = (net_profit / avg_total_assets) * 100
    else:
        roa = None
    
    if revenue != 0:
        net_margin = (net_profit / revenue) * 100
    else:
        net_margin = None
    
    return {
        'ROE(%)': roe,
        'ROA(%)': roa,
        '净利率(%)': net_margin
    }

# 测试代码
def test_profitability_metrics():
    # 测试正常情况
    result = calculate_profitability_metrics(
        net_profit=100,
        revenue=1000,
        total_assets_begin=500,
        total_assets_end=600,
        equity_begin=300,
        equity_end=350
    )
    
    assert round(result['ROE(%)'], 2) == 31.75  # 100 / 325 * 100
    assert round(result['ROA(%)'], 2) == 18.18  # 100 / 550 * 100
    assert result['净利率(%)'] == 10.0  # 100 / 1000 * 100
    
    # 测试零值处理
    result_zero = calculate_profitability_metrics(
        net_profit=0,
        revenue=1000,
        total_assets_begin=500,
        total_assets_end=600,
        equity_begin=0,
        equity_end=0
    )
    
    assert result_zero['ROE(%)'] is None
    assert round(result_zero['ROA(%)'], 2) == 0.0
    assert result_zero['净利率(%)'] == 0.0
    
    print("盈利能力指标计算测试通过!")

5. 市场情绪维度指标

市场情绪维度反映了投资者的心理状态和市场氛围,对短期价格波动有重要影响。

5.1 市场情绪指标

指标名称 计算方法 含义与应用
换手率 (成交量 / 流通股数) * 100% 反映股票的活跃程度和交易热度
波动率 价格收益率的标准差 反映价格波动的剧烈程度
恐慌贪婪指数 综合多种市场因素计算 衡量整体市场情绪

5.2 Python实现波动率计算

python 复制代码
import pandas as pd
import numpy as np

def calculate_volatility(prices, window=20, annualized=True):
    """
    计算价格波动率
    
    参数:
    prices: 价格序列
    window: 计算窗口,默认20个交易日
    annualized: 是否年化,默认True
    
    返回:
    波动率序列
    """
    # 确保输入是Pandas Series
    if not isinstance(prices, pd.Series):
        prices = pd.Series(prices)
    
    # 计算日收益率
    returns = prices.pct_change()
    
    # 计算滚动波动率(标准差)
    volatility = returns.rolling(window=window).std()
    
    # 如果需要年化,乘以交易日的平方根(假设一年252个交易日)
    if annualized:
        volatility = volatility * np.sqrt(252)
    
    # 转换为百分比
    volatility = volatility * 100
    
    return volatility

# 测试代码
def test_volatility():
    # 创建测试数据
    np.random.seed(42)
    test_prices = pd.Series(100 + np.cumsum(np.random.randn(100) * 2))
    
    # 计算波动率
    volatility = calculate_volatility(test_prices, window=20, annualized=True)
    
    # 验证结果长度
    assert len(volatility) == len(test_prices)
    
    # 验证非年化波动率
    volatility_non_annual = calculate_volatility(test_prices, window=20, annualized=False)
    # 非年化波动率应该小于年化波动率
    assert volatility_non_annual.dropna().mean() < volatility.dropna().mean()
    
    # 验证波动率是否合理
    assert volatility.dropna().min() >= 0  # 波动率不能为负
    
    print("波动率计算测试通过!")

6. 多维度指标的综合应用

单一维度的指标往往难以全面反映股票的真实状况,综合多个维度的指标能够提供更全面、更可靠的分析。

6.1 构建综合评分模型

python 复制代码
import pandas as pd
import numpy as np

def calculate_comprehensive_score(stock_data, industry_data):
    """
    计算股票的多维度综合评分
    
    参数:
    stock_data: 包含各维度指标的股票数据字典
    industry_data: 包含行业平均水平的字典,用于标准化
    
    返回:
    综合评分(0-100分)
    """
    scores = {}
    weights = {
        '估值维度': 0.2,
        '技术分析维度': 0.2,
        '资金流向维度': 0.2,
        '基本面维度': 0.3,
        '市场情绪维度': 0.1
    }
    
    # 估值维度评分(越低越好,需要反转)
    pe_score = 100 - min(100, (stock_data['pe'] / industry_data['avg_pe']) * 50)
    pb_score = 100 - min(100, (stock_data['pb'] / industry_data['avg_pb']) * 50)
    scores['估值维度'] = (pe_score + pb_score) / 2
    
    # 技术分析维度评分(RSI在40-60之间为中性,超过70为超买,低于30为超卖)
    if stock_data['rsi'] < 30:
        rsi_score = 80  # 超卖,可能反弹
    elif stock_data['rsi'] > 70:
        rsi_score = 30  # 超买,可能回调
    else:
        rsi_score = 50 + (stock_data['rsi'] - 50) * 0.5  # 中性区域线性评分
    
    # MACD评分(MACD线在信号线上方为正向信号)
    if stock_data['macd_histogram'] > 0:
        macd_score = 70 + min(30, stock_data['macd_histogram'] * 10)
    else:
        macd_score = 30 + max(-20, stock_data['macd_histogram'] * 10)
    
    scores['技术分析维度'] = (rsi_score + macd_score) / 2
    
    # 资金流向维度评分
    # 假设obv_trend是OBV的趋势方向(1为上升,0为持平,-1为下降)
    # fund_flow_ratio是资金净流入率
    obv_score = 70 if stock_data['obv_trend'] == 1 else (30 if stock_data['obv_trend'] == -1 else 50)
    flow_score = max(0, min(100, 50 + stock_data['fund_flow_ratio'] * 100))
    scores['资金流向维度'] = (obv_score + flow_score) / 2
    
    # 基本面维度评分
    roe_score = min(100, (stock_data['roe'] / industry_data['avg_roe']) * 50 + 50)
    growth_score = min(100, (stock_data['growth_rate'] / industry_data['avg_growth']) * 50 + 50)
    scores['基本面维度'] = (roe_score + growth_score) / 2
    
    # 市场情绪维度评分
    # 假设sentiment_index是市场情绪指数(0-100)
    # 适度的活跃(中等换手率)是好的
    turnover_score = 70 if 1 < stock_data['turnover'] < 5 else (30 if stock_data['turnover'] > 10 else 50)
    sentiment_score = 60 + (stock_data['sentiment_index'] - 50) * 0.8
    scores['市场情绪维度'] = (turnover_score + sentiment_score) / 2
    
    # 计算加权综合得分
    comprehensive_score = 0
    for dimension, weight in weights.items():
        comprehensive_score += scores[dimension] * weight
    
    return {
        '各维度得分': scores,
        '综合得分': round(comprehensive_score, 2)
    }

# 测试代码
def test_comprehensive_score():
    # 创建测试数据
    stock_data = {
        'pe': 15,
        'pb': 1.8,
        'rsi': 55,
        'macd_histogram': 0.5,
        'obv_trend': 1,
        'fund_flow_ratio': 0.02,
        'roe': 18,
        'growth_rate': 0.25,
        'turnover': 3,
        'sentiment_index': 60
    }
    
    industry_data = {
        'avg_pe': 20,
        'avg_pb': 2.2,
        'avg_roe': 12,
        'avg_growth': 0.15
    }
    
    # 计算综合评分
    result = calculate_comprehensive_score(stock_data, industry_data)
    
    # 验证结果
    assert 0 <= result['综合得分'] <= 100
    assert len(result['各维度得分']) == 5
    
    print(f"综合评分测试通过! 测试股票综合得分为: {result['综合得分']}")

6.2 多维度背离识别

多维度背离是指不同维度指标之间出现的不一致现象,这往往是重要的投资信号。例如:

  • 技术面与基本面背离:股价创新高但基本面指标(如ROE)下降
  • 价格与资金面背离:股价上涨但主力资金净流出
  • 估值与成长性背离:高估值但低成长性
python 复制代码
def detect_divergence(price_data, indicator_data, window=20):
    """
    检测价格与指标之间的背离
    
    参数:
    price_data: 价格序列
    indicator_data: 指标序列
    window: 检测窗口,默认20个交易日
    
    返回:
    背离信号(1:看涨背离, -1:看跌背离, 0:无背离)
    """
    # 确保输入是Pandas Series
    if not isinstance(price_data, pd.Series):
        price_data = pd.Series(price_data)
    if not isinstance(indicator_data, pd.Series):
        indicator_data = pd.Series(indicator_data)
    
    # 获取最近窗口的数据
    recent_prices = price_data.iloc[-window:]
    recent_indicators = indicator_data.iloc[-window:]
    
    # 计算价格和指标的最高值、最低值及其位置
    price_high = recent_prices.max()
    price_high_idx = recent_prices.idxmax()
    price_low = recent_prices.min()
    price_low_idx = recent_prices.idxmin()
    
    indicator_high = recent_indicators.max()
    indicator_high_idx = recent_indicators.idxmax()
    indicator_low = recent_indicators.min()
    indicator_low_idx = recent_indicators.idxmin()
    
    # 检测顶背离(价格创新高,指标未创新高)
    if price_high_idx == recent_prices.index[-1] and indicator_high_idx < recent_indicators.index[-1]:
        if recent_indicators.iloc[-1] < indicator_high * 0.95:  # 指标下降了至少5%
            return -1  # 看跌背离
    
    # 检测底背离(价格创新低,指标未创新低)
    if price_low_idx == recent_prices.index[-1] and indicator_low_idx < recent_indicators.index[-1]:
        if recent_indicators.iloc[-1] > indicator_low * 1.05:  # 指标上升了至少5%
            return 1  # 看涨背离
    
    # 无明显背离
    return 0

# 测试代码
def test_divergence():
    # 创建测试数据 - 顶背离
    dates = pd.date_range('2023-01-01', periods=20)
    # 价格创新高
    top_div_prices = pd.Series([i for i in range(10, 30)], index=dates)
    # 指标先升后降
    top_div_indicators = pd.Series([i for i in range(50, 70)] + [68, 66, 64, 62, 60, 58, 56, 54, 52, 50], 
                                 index=dates)
    
    # 创建测试数据 - 底背离
    # 价格创新低
    bottom_div_prices = pd.Series([30 - i for i in range(20)], index=dates)
    # 指标先降后升
    bottom_div_indicators = pd.Series([50 - i for i in range(10)] + [40, 42, 44, 46, 48, 50, 52, 54, 56, 58], 
                                    index=dates)
    
    # 检测背离
    top_div_result = detect_divergence(top_div_prices, top_div_indicators)
    bottom_div_result = detect_divergence(bottom_div_prices, bottom_div_indicators)
    
    # 验证结果
    assert top_div_result == -1  # 应该检测到顶背离
    assert bottom_div_result == 1  # 应该检测到底背离
    
    print("背离检测测试通过!")

7. 实战应用与注意事项

7.1 指标组合使用策略

在实际应用中,我们需要根据投资目标和风险偏好,合理组合使用不同维度的指标:

  • 价值投资策略:重点关注估值维度和基本面维度,辅以市场情绪维度
  • 趋势跟踪策略:重点关注技术分析维度和资金流向维度
  • 量化择时策略:综合使用所有维度,重点关注背离信号

7.2 注意事项

  • 指标滞后性:技术指标和部分基本面指标存在滞后性,需要结合其他信息判断
  • 不同市场环境适用性:同一指标在不同市场环境下效果可能差异很大
  • 行业差异:不同行业的合理估值水平和技术特征差异显著,需要行业内比较
  • 指标失效风险:当市场结构发生变化时,历史有效的指标可能失效

8. 完整的量化分析框架示例

python 复制代码
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from datetime import datetime, timedelta

class MultiDimensionStockAnalyzer:
    """
    多维度股票量化分析器
    """
    
    def __init__(self):
        self.data = None
        self.indicators = {}
        self.signals = {}
    
    def load_data(self, prices, volumes=None, fundamental_data=None):
        """加载股票数据"""
        self.data = pd.DataFrame({'price': prices})
        if volumes is not None:
            self.data['volume'] = volumes
        if fundamental_data is not None:
            for key, value in fundamental_data.items():
                self.data[key] = value
        return self
    
    def calculate_technical_indicators(self):
        """计算技术指标"""
        # 计算移动平均线
        self.data['MA5'] = self.data['price'].rolling(window=5).mean()
        self.data['MA20'] = self.data['price'].rolling(window=20).mean()
        
        # 计算RSI
        self.data['RSI'] = calculate_rsi(self.data['price'])
        
        # 计算MACD
        macd_result = calculate_macd(self.data['price'])
        self.data['MACD'] = macd_result['macd_line']
        self.data['Signal'] = macd_result['signal_line']
        self.data['MACD_Hist'] = macd_result['histogram']
        
        # 计算波动率
        self.data['Volatility'] = calculate_volatility(self.data['price'])
        
        # 如果有成交量数据,计算OBV
        if 'volume' in self.data.columns:
            self.data['OBV'] = calculate_obv(self.data['price'], self.data['volume'])
        
        return self
    
    def calculate_valuation_metrics(self, market_cap, eps, bvps, sales):
        """计算估值指标"""
        self.data['PE'] = market_cap / eps
        self.data['PB'] = market_cap / bvps
        self.data['PS'] = market_cap / sales
        return self
    
    def detect_signals(self):
        """检测交易信号"""
        # 金叉死叉信号
        self.data['MA_5_20_Cross'] = 0
        self.data.loc[(self.data['MA5'] > self.data['MA20']) & 
                     (self.data['MA5'].shift(1) <= self.data['MA20'].shift(1)), 'MA_5_20_Cross'] = 1  # 金叉
        self.data.loc[(self.data['MA5'] < self.data['MA20']) & 
                     (self.data['MA5'].shift(1) >= self.data['MA20'].shift(1)), 'MA_5_20_Cross'] = -1  # 死叉
        
        # RSI超买超卖信号
        self.data['RSI_Signal'] = 0
        self.data.loc[self.data['RSI'] > 70, 'RSI_Signal'] = -1  # 超买
        self.data.loc[self.data['RSI'] < 30, 'RSI_Signal'] = 1  # 超卖
        
        # MACD柱状图信号
        self.data['MACD_Signal'] = 0
        self.data.loc[(self.data['MACD_Hist'] > 0) & (self.data['MACD_Hist'].shift(1) <= 0), 'MACD_Signal'] = 1  # 柱状图由负转正
        self.data.loc[(self.data['MACD_Hist'] < 0) & (self.data['MACD_Hist'].shift(1) >= 0), 'MACD_Signal'] = -1  # 柱状图由正转负
        
        # 检测背离信号
        self.data['Divergence'] = 0
        for i in range(60, len(self.data)):
            window_data = self.data.iloc[i-60:i]
            rsi_divergence = detect_divergence(window_data['price'], window_data['RSI'], window=20)
            self.data.iloc[i, self.data.columns.get_loc('Divergence')] = rsi_divergence
        
        return self
    
    def generate_comprehensive_signal(self):
        """生成综合信号"""
        # 简单加权综合
        self.data['Composite_Signal'] = 0
        
        # MA交叉信号权重
        self.data['Composite_Signal'] += self.data['MA_5_20_Cross'] * 0.3
        
        # RSI信号权重
        self.data['Composite_Signal'] += self.data['RSI_Signal'] * 0.2
        
        # MACD信号权重
        self.data['Composite_Signal'] += self.data['MACD_Signal'] * 0.2
        
        # 背离信号权重(背离信号通常更重要)
        self.data['Composite_Signal'] += self.data['Divergence'] * 0.3
        
        # 生成最终信号
        self.data['Final_Signal'] = 0
        self.data.loc[self.data['Composite_Signal'] > 0.2, 'Final_Signal'] = 1  # 买入信号
        self.data.loc[self.data['Composite_Signal'] < -0.2, 'Final_Signal'] = -1  # 卖出信号
        
        return self
    
    def plot_analysis(self, start_date=None, end_date=None):
        """可视化分析结果"""
        plot_data = self.data.copy()
        if start_date and end_date:
            plot_data = plot_data[(plot_data.index >= start_date) & (plot_data.index <= end_date)]
        
        # 创建图表
        fig, axes = plt.subplots(4, 1, figsize=(15, 12), sharex=True)
        
        # 价格和移动平均线
        axes[0].plot(plot_data.index, plot_data['price'], label='Price')
        axes[0].plot(plot_data.index, plot_data['MA5'], label='MA5')
        axes[0].plot(plot_data.index, plot_data['MA20'], label='MA20')
        
        # 标记买入卖出信号
        buy_signals = plot_data[plot_data['Final_Signal'] == 1]
        sell_signals = plot_data[plot_data['Final_Signal'] == -1]
        axes[0].scatter(buy_signals.index, buy_signals['price'], marker='^', color='g', s=100, label='Buy Signal')
        axes[0].scatter(sell_signals.index, sell_signals['price'], marker='v', color='r', s=100, label='Sell Signal')
        
        axes[0].set_title('Price and Moving Averages')
        axes[0].legend()
        
        # RSI
        axes[1].plot(plot_data.index, plot_data['RSI'])
        axes[1].axhline(y=70, color='r', linestyle='--')
        axes[1].axhline(y=30, color='g', linestyle='--')
        axes[1].set_title('RSI')
        
        # MACD
        axes[2].plot(plot_data.index, plot_data['MACD'], label='MACD')
        axes[2].plot(plot_data.index, plot_data['Signal'], label='Signal')
        axes[2].bar(plot_data.index, plot_data['MACD_Hist'], label='Histogram')
        axes[2].set_title('MACD')
        axes[2].legend()
        
        # 综合信号
        axes[3].plot(plot_data.index, plot_data['Composite_Signal'], label='Composite Signal')
        axes[3].axhline(y=0, color='k', linestyle='-')
        axes[3].set_title('Composite Signal')
        axes[3].legend()
        
        plt.tight_layout()
        plt.show()
        
        return self
    
    def backtest(self, initial_capital=100000, transaction_cost=0.001):
        """简单回测"""
        backtest_data = self.data.copy()
        
        # 初始化回测参数
        backtest_data['Position'] = 0  # 持仓状态
        backtest_data['Capital'] = initial_capital
        backtest_data['Holdings'] = 0  # 持仓市值
        backtest_data['Total'] = initial_capital  # 总资产
        
        # 执行回测
        for i in range(1, len(backtest_data)):
            # 继承前一天的持仓
            backtest_data.iloc[i, backtest_data.columns.get_loc('Position')] = backtest_data.iloc[i-1]['Position']
            
            # 检查信号
            if backtest_data.iloc[i]['Final_Signal'] == 1 and backtest_data.iloc[i-1]['Position'] <= 0:
                # 买入信号
                backtest_data.iloc[i, backtest_data.columns.get_loc('Position')] = 1
                # 计算交易成本
                cost = backtest_data.iloc[i-1]['Capital'] * transaction_cost
                # 更新资金和持仓
                backtest_data.iloc[i, backtest_data.columns.get_loc('Capital')] = backtest_data.iloc[i-1]['Capital'] - cost
                backtest_data.iloc[i, backtest_data.columns.get_loc('Holdings')] = backtest_data.iloc[i-1]['Capital'] - cost
            
            elif backtest_data.iloc[i]['Final_Signal'] == -1 and backtest_data.iloc[i-1]['Position'] >= 0:
                # 卖出信号
                backtest_data.iloc[i, backtest_data.columns.get_loc('Position')] = -1
                # 计算交易成本
                cost = backtest_data.iloc[i-1]['Holdings'] * transaction_cost
                # 更新资金和持仓
                backtest_data.iloc[i, backtest_data.columns.get_loc('Capital')] = backtest_data.iloc[i-1]['Capital'] + backtest_data.iloc[i-1]['Holdings'] - cost
                backtest_data.iloc[i, backtest_data.columns.get_loc('Holdings')] = 0
            
            # 更新市值
            if backtest_data.iloc[i]['Position'] == 1:
                # 持有多头
                price_change_ratio = backtest_data.iloc[i]['price'] / backtest_data.iloc[i-1]['price']
                backtest_data.iloc[i, backtest_data.columns.get_loc('Holdings')] = backtest_data.iloc[i-1]['Holdings'] * price_change_ratio
            
            # 计算总资产
            backtest_data.iloc[i, backtest_data.columns.get_loc('Total')] = backtest_data.iloc[i]['Capital'] + backtest_data.iloc[i]['Holdings']
        
        # 计算回测指标
        total_return = (backtest_data['Total'].iloc[-1] / initial_capital) - 1
        annual_return = ((1 + total_return) ** (252 / len(backtest_data))) - 1
        
        # 计算最大回撤
        backtest_data['Rolling_Max'] = backtest_data['Total'].cummax()
        backtest_data['Drawdown'] = (backtest_data['Total'] - backtest_data['Rolling_Max']) / backtest_data['Rolling_Max']
        max_drawdown = backtest_data['Drawdown'].min()
        
        # 计算夏普比率(假设无风险利率为0)
        daily_returns = backtest_data['Total'].pct_change()
        sharpe_ratio = np.sqrt(252) * daily_returns.mean() / daily_returns.std()
        
        self.backtest_results = {
            'total_return': total_return,
            'annual_return': annual_return,
            'max_drawdown': max_drawdown,
            'sharpe_ratio': sharpe_ratio
        }
        
        return self.backtest_results

# 示例用法
def demo_analyzer():
    # 创建模拟数据
    np.random.seed(42)
    dates = pd.date_range('2022-01-01', periods=250)
    prices = 100 + np.cumsum(np.random.randn(250))
    volumes = np.random.randint(1000, 5000, 250)
    
    # 初始化分析器
    analyzer = MultiDimensionStockAnalyzer()
    
    # 加载数据并计算指标
    analyzer.load_data(prices=prices, volumes=volumes)
    analyzer.calculate_technical_indicators()
    
    # 检测信号并生成综合信号
    analyzer.detect_signals()
    analyzer.generate_comprehensive_signal()
    
    # 回测
    results = analyzer.backtest()
    
    print(f"回测结果:\n"  
          f"总收益率: {results['total_return']*100:.2f}%\n"  
          f"年化收益率: {results['annual_return']*100:.2f}%\n"  
          f"最大回撤: {results['max_drawdown']*100:.2f}%\n"  
          f"夏普比率: {results['sharpe_ratio']:.2f}")
    
    return analyzer

结论

构建科学、全面的多维度股票量化指标体系是提高投资决策质量的关键。通过本文介绍的五大维度(估值、技术分析、资金流向、基本面、市场情绪)的指标分析,投资者可以更客观地评估股票价值,识别股价与价值的背离,从而提高投资决策的准确性。

需要强调的是,任何量化模型都有其局限性,市场是复杂多变的。投资者在使用这些指标时,应该结合宏观经济环境、行业发展趋势等因素进行综合判断。同时,定期回测和优化模型也是保持策略有效性的重要手段。

免责声明:本文内容仅供学习和研究使用,不构成任何投资建议。股市有风险,投资需谨慎。

相关推荐
傻啦嘿哟2 小时前
Python将Excel工作表转换为PDF:从入门到实战
python·pdf·excel
老鱼说AI2 小时前
BPE编码从零开始实现pytorch
开发语言·人工智能·python·机器学习·chatgpt·nlp·gpt-3
陳陈陳2 小时前
AIGC 时代,用自然语言操作数据库:SQLite + LLM 的轻量级实践
前端·数据库·python
林炳然2 小时前
Python-Basic Day-4 函数-基础知识
python
FreeCode2 小时前
LangSmith Studio 调试智能体
python·langchain·agent
Paraverse_徐志斌2 小时前
基于 PyTorch + BERT 意图识别与模型微调
人工智能·pytorch·python·bert·transformer
wtrees_松阳2 小时前
Flask数据加密实战:医疗系统安全指南
开发语言·python
数据知道3 小时前
FastAPI项目:构建打字速度测试网站(MySQL版本)
数据库·python·mysql·fastapi·python项目
vvoennvv3 小时前
【Python TensorFlow】CNN-BiLSTM-Attention时序预测 卷积神经网络-双向长短期记忆神经网络组合模型带注意力机制(附代码)
python·神经网络·cnn·tensorflow·lstm·bilstm·注意力