生成纳斯达克和标普500的伪行情数据

jupyter
2509
legacy
Published

2025-09-19

# 生成纳斯达克和标普500的伪行情数据
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# 为可重复性设置随机种子
np.random.seed(41)
# 生成过去一年的工作日(不含周末)日期序列
try:
    # 使用上海时区作为本地时间
    today = pd.Timestamp.now(tz='Asia/Shanghai').normalize()
except Exception:
    # 回退到本地无时区的今天
    today = pd.Timestamp.today().normalize()

start = today - pd.offsets.DateOffset(years=1)
dates = pd.bdate_range(start=start, end=today)  # B 表示工作日频率

len(dates), dates.min(), dates.max()
(261,
 Timestamp('2024-10-04 00:00:00+0800', tz='Asia/Shanghai'),
 Timestamp('2025-10-03 00:00:00+0800', tz='Asia/Shanghai'))
# 定义 GBM 模拟函数
def simulate_gbm(S0: float, mu: float, sigma: float, n_steps: int, dt: float = 1.0/252, seed: int | None = None):
    if seed is not None:
        rng = np.random.default_rng(seed)
        z = rng.standard_normal(n_steps)
    else:
        z = np.random.normal(size=n_steps)
    dr = (mu - 0.5 * sigma**2) * dt + sigma * np.sqrt(dt) * z
    path = S0 * np.exp(np.cumsum(dr))
    return path

n = len(dates)

# 纳指参数(示例)
nasdaq_S0 = 16000.0
nasdaq_mu = 0.10
nasdaq_sigma = 0.25

# 标普500参数(示例)
spx_S0 = 5600.0
spx_mu = 0.08
spx_sigma = 0.20

nasdaq_prices = simulate_gbm(nasdaq_S0, nasdaq_mu, nasdaq_sigma, n)
spx_prices    = simulate_gbm(spx_S0,    spx_mu,    spx_sigma,    n)

df = pd.DataFrame({
    'NASDAQ_Close': nasdaq_prices,
    'SPX_Close': spx_prices,
}, index=dates)

# 标准化至100(首日=100)
df_norm = df / df.iloc[0] * 100.0
df.head()
NASDAQ_Close SPX_Close
2024-10-04 00:00:00+08:00 15936.279209 5615.695306
2024-10-07 00:00:00+08:00 15966.970430 5715.919353
2024-10-08 00:00:00+08:00 16034.465514 5755.178875
2024-10-09 00:00:00+08:00 15806.840474 5821.073011
2024-10-10 00:00:00+08:00 15953.006046 5737.760714
# 图1:标准化至100的相对表现
plt.figure(figsize=(12, 5))
df_norm['NASDAQ_Close'].plot(label='纳斯达克(归一化)', lw=1.6, color='tab:blue')
df_norm['SPX_Close'].plot(label='标普500(归一化)', lw=1.6, color='tab:orange')
plt.title('纳指100 vs 标普500 - 伪行情(过去一年,相对表现=100)', fontname='Microsoft YaHei', fontsize=14)
plt.xlabel('日期', fontname='Microsoft YaHei')
plt.ylabel('相对指数(首日=100)', fontname='Microsoft YaHei')
plt.grid(True, ls='--', alpha=0.4)
plt.legend(prop={'family':'Microsoft YaHei'})
plt.tight_layout()
plt.show()

# 图2:原始指数水平对比(双轴可读性更好)
fig, ax1 = plt.subplots(figsize=(12, 5))
color1 = 'tab:blue'
color2 = 'tab:orange'
l1 = ax1.plot(df.index, df['NASDAQ_Close'], color=color1, lw=1.6, label='纳斯达克')
ax1.set_xlabel('日期', fontname='Microsoft YaHei')
ax1.set_ylabel('纳指水平', color=color1, fontname='Microsoft YaHei')
ax1.tick_params(axis='y', labelcolor=color1)
ax1.grid(True, ls='--', alpha=0.4)

ax2 = ax1.twinx()
l2 = ax2.plot(df.index, df['SPX_Close'], color=color2, lw=1.6, label='标普500')
ax2.set_ylabel('标普水平', color=color2, fontname='Microsoft YaHei')
ax2.tick_params(axis='y', labelcolor=color2)

lines = l1 + l2
labels = [l.get_label() for l in lines]
plt.title('纳指 vs 标普500 - 伪行情(过去一年,原始水平)', fontname='Microsoft YaHei', fontsize=14)
ax1.legend(lines, labels, loc='upper left', prop={'family':'Microsoft YaHei'})
fig.tight_layout()
plt.show()

# 尾部数据预览
df.tail()
NASDAQ_Close SPX_Close
2025-09-29 00:00:00+08:00 15461.133559 4581.174623
2025-09-30 00:00:00+08:00 14964.258063 4559.943464
2025-10-01 00:00:00+08:00 14730.202581 4581.145302
2025-10-02 00:00:00+08:00 14653.702942 4638.402856
2025-10-03 00:00:00+08:00 14567.597756 4649.009116