Source code for yabte.utilities.simulation.weiner

r"""Weiner process.

Weiner process :math:`W_t` such that,

#. :math:`W_0 = 0`
#. :math:`\forall t>0, u \ge  0, s<t \Rightarrow W_{t+u}-W_{t} \text{ independent of } W_s`
#. :math:`W_{t+u}-W_{t}\sim {\mathcal {N}}(0,u)`
#. :math:`W_t` is continuous
"""

import numpy as np


[docs]def weiner_simulate_paths( n_steps: int, n_sims: int = 1, stdev: float | np.ndarray = 1, R: np.ndarray = np.array([[1]]), rng=None, ): """Generate simulated Weiner paths. `stdev` is the increment size, `R` a correlation matrix, `n_steps` is how many time steps, `n_sims` the number of simulations and `rng` a numpy random number generator (optional). If `stdev` is a scalar it will be broadcasted to the size of `n_sims`. """ R = np.atleast_2d(R) stdev = np.resize(stdev, n_sims).reshape(n_sims, 1) if rng is None: rng = np.random.default_rng() k = R.shape[0] # simulate 'n_sims' price paths of `k` sized asset groups with 'n_steps' timesteps dws = rng.multivariate_normal( mean=np.zeros(k), cov=R, size=(n_steps - 1, n_sims), check_valid="raise" ) # use cumsum as speed up ws = np.concatenate([np.zeros((1, n_sims, k)), np.cumsum(dws, axis=0)]) return stdev * ws