一个简单的价格模拟工具

金凯旋 / 2024-10-21 / 原文

模拟交易价格对于量化分析建模很重要,下面是一个简单的价格模拟工具:

首先, 要找到标的的价格波动属性,而标的的波动每天都不一样,下面这个代码可以直观地绘制出价格波动的变化情况:

def calculate_volatility():

    # 取日线数据
    data = get_data(symbol="rb", duration_seconds=60*60*24, start_dt="2023-01-01", end_dt="2024-10-15")

    # 计算波动率
    data["pct_change"] = data["close"].pct_change()

    volatility = data["pct_change"].std() * np.sqrt(252)  # 假设一年有252个交易日

    print(f"波动率: {volatility:.4f}")

    # 计算对数收益率
    data["log_return"] = np.log(data["close"] / data["close"].shift(1))

    # 计算对数收益波动率
    log_volatility = data["log_return"].std() * np.sqrt(252)  # 假设一年有252个交易日

    print(f"对数收益波动率: {log_volatility:.4f}")

    # 计算滚动的波动率
    data["rolling_volatility"] = data["log_return"].rolling(window=20).std()  #* np.sqrt(252)  # 假设一年有252个交易日

    # 计算 Parkinson 波动率    
    data["parkinson_volatility"] = np.sqrt((1 / (4 * np.log(2))) * (data["high"] / data["low"]).apply(np.log).rolling(window=20).mean() ** 2)    

    # 绘制 Parkinson 波动率曲线 和价格曲线,波动率曲线用左轴,价格曲线用右轴
    fig, ax1 = plt.subplots(figsize=(10, 6))

    ax1.plot(data["parkinson_volatility"], label="Parkinson Volatility", color="blue")
    ax1.plot(data["rolling_volatility"], label="Rolling Volatility", color="green")
    ax1.set_ylabel("Parkinson Volatility", color="blue")
    ax1.tick_params(axis="y", labelcolor="blue")

    ax2 = ax1.twinx()
    ax2.plot(data["close"], label="Price", color="red")
    ax2.set_ylabel("Price", color="red")
    ax2.tick_params(axis="y", labelcolor="red")

    plt.title("Parkinson Volatility and Price")
    plt.xlabel("Date")
    plt.legend()
    plt.show()

  

上文计算了两个不同的波动率,可以看出,在不同的行情下,波动率计算不完全一致,但差别不是很大。

然后模拟:

s0 = 3500          # 假定的初始价格
sigma = 0.008 # 假定波动率为 0.008

def PriceProcess(sigma,dt, s0=100, total_time=1):    
    prices = s0* (1 + np.cumsum(sigma * np.sqrt(dt) * np.random.choice([1, -1],  int(total_time / dt))))
    return np.insert(prices, 0, s0)    

prices = PriceProcess(sigma=sigma,dt=1/240, s0=s0, total_time=1)

# 绘图
import matplotlib.pyplot as plt
plt.plot(prices)
plt.show()