admin 发表于 昨天 15:19

蒙特卡洛模拟的代码

import numpy as np
import matplotlib.pyplot as plt

def monte_carlo_simulation(
    S0: float,
    mu: float,
    sigma: float,
    T: float,
    n_sim: int,
    n_steps: int
) -> np.ndarray:
    """
    使用几何布朗运动(GBM)对资产价格进行蒙特卡洛模拟。

    参数
    ----------
    S0 : float
      初始资产价格。
    mu : float
      年化预期收益率(无风险利率或历史漂移率)。
    sigma : float
      年化波动率。
    T : float
      模拟期限(年)。
    n_sim : int
      模拟路径数量。
    n_steps : int
      每条路径的时间步数。

    返回
    -------
    paths : np.ndarray, shape (n_sim, n_steps + 1)
      模拟价格矩阵,每一行是一条路径,每一列是一个时间点。
    """

    dt = T / n_steps
    # 布朗运动的漂移项修正(伊藤引理)
    drift = (mu - 0.5 * sigma ** 2) * dt
    # 随机冲击的标准差
    vol = sigma * np.sqrt(dt)

    # 生成标准正态随机数 (n_sim, n_steps)
    Z = np.random.standard_normal((n_sim, n_steps))

    # 对数收益率
    log_returns = drift + vol * Z

    # 累积对数收益率
    log_returns_cum = np.cumsum(log_returns, axis=1)

    # 将初始价格添加到第一列,构建完整路径
    paths = np.zeros((n_sim, n_steps + 1))
    paths[:, 0] = S0
    paths[:, 1:] = S0 * np.exp(log_returns_cum)

    return paths


# --------------
# 示例使用与可视化
# --------------
if __name__ == "__main__":
    # 参数设置
    S0 = 100      # 初始价格
    mu = 0.05   # 预期收益率 5%
    sigma = 0.2   # 波动率 20%
    T = 1.0       # 模拟1年
    n_sim = 1000# 1000条路径
    n_steps = 252 # 252个交易日

    # 运行模拟
    price_paths = monte_carlo_simulation(S0, mu, sigma, T, n_sim, n_steps)

    # 期末价格统计
    final_prices = price_paths[:, -1]
    print(f"期末价格均值: {final_prices.mean():.2f}")
    print(f"期末价格标准差: {final_prices.std():.2f}")
    print(f"5% VaR (历史法): {S0 - np.percentile(final_prices, 5):.2f}")

    # 可视化部分路径
    plt.figure(figsize=(10, 6))
    plt.plot(price_paths.T[:, :100], alpha=0.1, color='blue')
    plt.axhline(y=S0, linestyle='--', color='red', alpha=0.5, label='Initial Price')
    plt.title("Monte Carlo Simulation of Asset Prices (GBM)")
    plt.xlabel("Time Steps")
    plt.ylabel("Price")
    plt.legend()
    plt.show()

    # 期末价格分布直方图
    plt.figure(figsize=(8, 5))
    plt.hist(final_prices, bins=50, alpha=0.7, color='skyblue', edgecolor='black')
    plt.axvline(x=S0, linestyle='--', color='red', label='Initial Price')
    plt.title("Distribution of Final Prices")
    plt.xlabel("Price")
    plt.ylabel("Frequency")
    plt.legend()
    plt.show()

页: [1]
查看完整版本: 蒙特卡洛模拟的代码