
目录
[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
结论
构建科学、全面的多维度股票量化指标体系是提高投资决策质量的关键。通过本文介绍的五大维度(估值、技术分析、资金流向、基本面、市场情绪)的指标分析,投资者可以更客观地评估股票价值,识别股价与价值的背离,从而提高投资决策的准确性。
需要强调的是,任何量化模型都有其局限性,市场是复杂多变的。投资者在使用这些指标时,应该结合宏观经济环境、行业发展趋势等因素进行综合判断。同时,定期回测和优化模型也是保持策略有效性的重要手段。
免责声明:本文内容仅供学习和研究使用,不构成任何投资建议。股市有风险,投资需谨慎。