Monte-Carlo Engine, seed parameter implementation and new numerical schemes for SDEs#270
Monte-Carlo Engine, seed parameter implementation and new numerical schemes for SDEs#270
Conversation
|
I will hopefully review and merge this PR this weekend :) Thanks for this one ! |
|
Sorry it's taken me a while to have a look at this.
|
…d, replacing euler_maruyama()
…end logic to keep same functionality with easier intuition
|
Hey @avhz I have moved I have also included other changes that I have noted at the top of the description. |
|
Looks good :) Just one thing, I would change the method names to a verb, something like |
StochasticProcess now calls generate() run_monte_carlo() -> simulate_stochastic_process() monte_carlo.rs -> simulation.rs
|
Thanks for having a look @avhz ! Agreed with your comment, all references to Monte-Carlo (method names, file names and documentation) have been amended 👍 Tested changes locally. |
|
thanks for your patience ! |
This Pull Request was created to address issue 244.
Latest update
With these latest changes, the emphasis was on implementing the Monte-Carlo only once - so that we would only need to update the code in one place should we need to amend anything regarding the algorithm.
The following changes have been made:
euler_maruyama()method has been replaced withmonte_carlo()StochasticSchemeenum as a parameter forStochasticConfigrun_monte_carlo()inmonte_carlo.rsfractional_process.rsmoduleNote: Jump/Fractional processes require a specific implementation of
run_monte_carlo(). Although this works fine, there might be some issues when user's construct custom jump/fractional processes (like in examples/examples/custom_process.rs) as default implementation will overlook jump/fractional properties. Added to future works section below.Benchmark tests
The following benchmark tests were run using the Euler-Maruyama scheme with the following configuration:
Standard Stochastic Process
GeometricBrownianMotionwithmonte-carlomainThis branch on average is 27% faster than
mainwith Geometric Brownian Motion.Jump Diffusion
MertonJumpDiffusionwithmonte-carlomainThis branch is on average 11% slower than
mainwith Merton Jump Diffusion.We should consider whether generalisation of the Monte-Carlo method is worth this cost.
Of course, we can try to improve performance in a follow up (added to Future work section at the bottom).
Fractional Process
FractionalBrownianMotionwithmonte-carlomainThe performance on a Fraction Brownian motion process is roughly the same.
Centralize Monte-Carlo functionality
Previously, the monte-carlo method needed to be implemented for each numerical method individually. Now there exists a private
monte_carlo()function in theprocess.rsmodule which can be utilised for each numerical method defined in theStochasticProcesstrait, removing the need for re-implementing the Monte-Carlo method every time.Consolidate seeded and "unseeded" numerical methods
The Euler Maruyama method had two implementations, one where a seed can be defined and another where the seed is "randomly" generated,
seedable_euler_maruyamaandeuler_maruyamarespectively.A
seed: Option<u64>parameter is introduced intoStochasticProcessConfigto give the user the ability to fix outcomes, other can be entered asNone, removing the need for two implementations of the same numerical methods.Milstein's scheme & Strang Splitting
The Milstein's scheme and Strang Splitting are numerical methods for SDEs that have been implemented in
process.rsas part of this PR (and utilizemonte_carlo()mentioned before). As such,price_monte_carlo()has been amended slightly to accomodate the new numerical methods.Their methodologies are outlined below.
Define the SDE
where$W_t\sim N\left(0, t\right)$ is the Wiener process. We define $t_n = t_0 + n\Delta t$ where $\Delta t = \frac{t_N-t_0}{M}$ .
Milstein's Scheme
The Milstein scheme at time$t_n\in\left[t_0, t_N\right]$ is defined as
with the initial condition$X_0 = x_0$ .
Strang Splitter
The Strang Splitter method can be split into three steps:
All appropriate unit tests have been added.
Future work
monte_carlo()to handle stochastic volatilityEnable monte_carlo() for custom fractional processesAlthough these points are relevant, they will not be addressed as part of this PR to avoid scope screep.