python计算股票年化收益率、波动率、夏普比率、VaR
python代码–使用python的akshare库获取数据
import akshare as ak
import pandas as pd
import numpy as np
import matplotlib.pyplot as pltdef get_stock_data(stock_code, start_date, end_date):"""获取指定股票的历史数据:param stock_code: 股票代码,例如 'sh600519':param start_date: 开始日期,格式 'YYYYMMDD':param end_date: 结束日期,格式 'YYYYMMDD':return: 包含历史数据的 DataFrame"""stock_df = ak.stock_zh_a_hist(symbol=stock_code[2:], period="daily", start_date=start_date, end_date=end_date)stock_df['日期'] = pd.to_datetime(stock_df['日期'])stock_df.set_index('日期', inplace=True)return stock_dfdef calculate_risk_metrics(stock_df):"""计算股票风险指标:param stock_df: 包含历史数据的 DataFrame:return: 包含风险指标的字典和包含日收益率的 DataFrame"""# 计算日收益率stock_df['日收益率'] = stock_df['收盘'].pct_change()# 计算年化收益率annual_return = stock_df['日收益率'].mean() * 252# 计算年化波动率(收益率标准差)annual_volatility = stock_df['日收益率'].std() * np.sqrt(252)# 假设无风险利率为 2%risk_free_rate = 0.02# 计算夏普比率sharpe_ratio = (annual_return - risk_free_rate) / annual_volatility# 计算 VaR(95% 置信水平)var_95 = np.percentile(stock_df['日收益率'].dropna(), 5)return {'年化收益率': annual_return,'年化波动率': annual_volatility,'夏普比率': sharpe_ratio,'日收益率95% VaR': var_95}, stock_dfdef plot_stock_data(stock_df, stock_code):"""绘制股价变化和日收益率变化图:param stock_df: 包含历史数据和日收益率的 DataFrame:param stock_code: 股票代码"""# 设置图片清晰度plt.rcParams['figure.dpi'] = 300# 设置中文字体plt.rcParams['font.sans-serif'] = ['SimHei']plt.rcParams['axes.unicode_minus'] = False# 创建一个包含两个子图的画布fig, axes = plt.subplots(2, 1, figsize=(12, 8))# 绘制股价变化图axes[0].plot(stock_df['收盘'], label='收盘价')axes[0].set_title(f'{stock_code} 股价变化')axes[0].set_ylabel('价格')axes[0].legend()# 绘制日收益率变化图axes[1].plot(stock_df['日收益率'], label='日收益率', color='orange')axes[1].set_title(f'{stock_code} 日收益率变化')axes[1].set_xlabel('日期')axes[1].set_ylabel('收益率')axes[1].legend()# 手动调整子图之间的垂直间距plt.subplots_adjust(hspace=0.5)plt.show()if __name__ == "__main__":stock_code = 'sh601288' # 农业银行start_date = '20240101'end_date = '20250531'# 获取股票数据stock_data = get_stock_data(stock_code, start_date, end_date)# 计算风险指标risk_metrics, stock_data = calculate_risk_metrics(stock_data)print(f"股票代码: {stock_code}")print(f"开始日期: {start_date}")print(f"结束日期: {end_date}")print("风险指标:")for key, value in risk_metrics.items():print(f"{key}: {value:.4f}")# 绘制图表plot_stock_data(stock_data, stock_code)"""我们在 calculate_risk_metrics 函数里添加了 VaR 的计算逻辑,使用 np.percentile 函数计算 95% 置信水平下的日收益率分位数,将其作为 VaR 值。同时,在返回的风险指标字典中添加了 95% VaR 这个指标。最后,在主程序中会打印出新增的 VaR 指标。"""
计算结果:
股票代码: sh601288
开始日期: 20240101
结束日期: 20250531
风险指标:
年化收益率: 0.3293
年化波动率: 0.2067
夏普比率: 1.4961
日收益率95% VaR: -0.0212
指标解释
1. 年化收益率(0.3293,32.93%)
含义:将分析周期内的总收益率换算为年均收益率,反映资产的盈利能力。
解读:
该股票在 1 年 5 个月(约 1.42 年)内的年化收益达 32.93%,显著高于市场平均水平(如沪深 300 指数年均收益约 10%-15%),表明资产增值能力较强。需结合行业特性判断:若属于高成长行业(如新能源、科技),该收益具备合理性;若为传统行业,则可能存在超额收益来源(如业绩爆发、政策利好)。
2. 年化波动率(0.2067,20.67%)
含义:衡量股票价格波动的剧烈程度,通过收益率的标准差年化计算,反映资产的风险水平。
解读:
20.67% 的波动率低于市场多数个股(A 股个股年化波动率通常在 25%-40%),说明该股票价格波动相对平稳。可能原因包括:
公司市值较大(如蓝筹股),抗风险能力强;
行业周期性较弱(如公用事业、消费必需品);
期间市场环境稳定,系统性风险较低。
3. 夏普比率(1.4961)
含义:衡量单位风险获得的超额收益,公式为:
夏普比率 = (年化收益率 - 无风险收益率) / 年化波动率
(无风险收益率通常取同期国债收益率,假设此处以 3% 计算)。
解读:
当无风险收益率为 3% 时,该股票的风险调整后收益为:
(32.93% - 3%) / 20.67% ≈ 1.496,远高于 1 的理想阈值,表明每承担 1 单位风险可获得近 1.5 单位超额收益,风险性价比极佳。
对比:普通股票型基金的夏普比率通常在 0.5-1 之间,该股票的风险收益比优于多数基金产品。
4. 日收益率 95% VaR(-0.0212,-2.12%)
含义:在 95% 的置信水平下,该股票单日可能的最大损失,即 “Value at Risk(风险价值)”。
解读:
日收益率 95% VaR 为 - 2.12%,意味着在 100 个交易日中,约 5 天的损失可能超过 2.12%,其余 95 天的损失小于该值。
结合年化波动率来看,2.12% 的单日最大损失处于合理范围(波动率 20.67% 对应日均波动约 1.3%,95% 分位数略高于均值 + 1.65 倍标准差),说明极端风险可控。