用于填充 Numpy 数组的动态输入,无需 for 蒙特卡罗循环

问题描述 投票:0回答:1

我从其他贡献者那里得到了一些使用 numpy 进行蒙特卡罗(随机游走)的优雅代码。然而,目前“vol”(又称标准差)是提供的常数。理想情况下,它应该随着时间的推移而变化。有没有办法修改此代码以使“vol”成为 numpy 索引的函数?我可以使用 for 循环来完成此操作,但出于性能原因,我试图将其保持矢量化。

import numpy as np

def montecarlo_brownian(start_value, T_years, steps, vol, rate = 0, sims = 1000): 
    """ generate random walks from a starting value for Monte Carlo analysis

    Args:
        start_value (float):    starting value for random walks
        T_year (float):         number of years in question
        steps (int):            substeps within each year 
        vol (float):            annualized standard deviation (ie, implied volatility)
        rate (float):           risk free interest rate
        sims (int):             number of simulations to execute
    
    Returns:
        (np.array)  columns of random walks 
    """
    times = np.linspace(0, T_years, steps+1)
    dt = times[1] - times[0]
    
    B = np.random.normal(0, np.sqrt(dt), size=(sims, steps)).T
    S = np.exp((rate - vol ** 2/ 2) * dt + vol * B)
    S = start_value * S.cumprod(axis=0)
    return S

评论者 jared 要求提供 for 循环逻辑的示例。我会定义一个函数

def get_vol(t):
  pass
  #some function that calculates vol based on how much time is left 

然后使用类似的东西:


def monte_carlo_with_changing_vol(S0, r, T, num_sims, num_steps, volatility):
    dt = T / num_steps
    paths = np.zeros((num_sims, num_steps + 1))
    paths[:, 0] = S0

    for i in range(num_sims):
        for j in range(1, num_steps + 1):
            current_vol = vol(j)
            paths[i, j] = paths[i, j - 1] * np.exp((r - 0.5 * current_vol ** 2) * dt + current_vol * np.sqrt(dt) * np.random.normal(0, 1))

    return paths
python arrays numpy indexing random-walk
1个回答
0
投票

@jared 的评论修复了这个问题,用 vol[:,None] 替换 vol 并将 vol 作为适当大小的数组传递

© www.soinside.com 2019 - 2024. All rights reserved.