python计算股票年化收益率、波动率、夏普比率、VaR

python代码–使用python的akshare库获取数据

import akshare as ak
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

def 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_df

def 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_df

def 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 倍标准差),说明极端风险可控。

你可能感兴趣的:(python,开发语言)