Giter Site home page Giter Site logo

exoticmontecarloengine's Introduction

EMCE - Exotic Monte Carlo Engine

Monte Carlo pricers for exotic derivatives in both Python / C++. The reason to code it up in two languages:

  • Both are languages commonly used in quantitative finance - implementing a solution in both languages provides a holistic way to learn the intracicies of both languages from bottom-up through comparison.
  • The languages themselves boast different benefits - Python allows for a quicker development cycle where C++ provides the raw speed where there is demand for performance.

Contributions are more than welcome!

C++

Actions Status Actions Status

  • The library can be found here.
  • Example tests can be found here
  • Project to-dos are here.

Features

  • Interface fully interporable between CUDA/C++, switching via enum.

Requirements

  • CUDA toolkit (tested on 11.7.0) with nvcc compiler.
  • CMake (version >= 3.18, as we need CUDA with C++17 standard).
  • C++17 compliant compiler.

Install

Build:

cmake -S ./cpp/emce -B build
cmake --build

Run tests:

ctest --test-dir ./build

Python

Actions Status

Exotic Monte Carlo Pricer: An equity/FX exotic Monte Carlo pricer.

  • To do: see this link for a list of issues and project info.
  • Examples: see unit tests here.

Features (goals)

  • advanced smile modelling (LV, SV, LSV)
  • coherent multi-asset simulation (hybrid exotic engine)
  • support wide range of path-dependent exotics
  • advanced variance reduction techniques (control variant, Quasi random numbers)
  • risk engine (FDM, AAD)

Python notebooks (analytics):

  • Vanilla put/call pricing with flat vol
  • Path dependent option pricing with flat vol (tbd)
  • Barrier option risk profiles with flat vol (tbd)
  • Simle dynamics under BS model with local vol (tbd)
  • Smile dynamics under BS model with SV - Heston model (tbd)
  • Convergence speed under different RNGs (tbd)
  • Rainbow option pricing (tbd)

exoticmontecarloengine's People

Contributors

kylchiu avatar ccjeremylo avatar

Stargazers

 avatar  avatar  avatar tony.ng avatar  avatar Richard Hung avatar

Watchers

 avatar

exoticmontecarloengine's Issues

Add an implied vol solver to support calibration

A pricing engine is useless without the ability to calibrate to data.

We start with adding two different numerical inversion solvers (root finders):

  • Bisection
  • Newton Raphson

Then we implement a calibration routine using the solvers to build a (naive) BS vol surface.

[Python] Support risks calculation (Greeks)

Start with building a (re-usable and extendible) risk engine that computes sensitivities using finite difference method.

If feeling fancy: try to ensure the design is compatible with adjoint algorithmic differentiation (AAD), as implementing AAD usually requires considerable re-engineering of the library.

[Python] Add local vol model

See #14 for background.

Proposal for local vol model design:

Assume we have access to liquid put and call option quotes

  • Propose using a panda dataframe as container for the discrete set of put and call price quotes for a range of $T$ and $K$.
  • For the purpose of this "library", we will use some dummy data for testing/analysis, unless someone knows any cheap and easy way to access option quotes
  • In practise, it is not clear to me if market option prices are quoted in terms of IV or option premium. Our infrastructure should be able to handle both. Conversion from option premium to IV is available thanks to #16.

Code up a vol_surface_interpolation abstract base class:

  • has a virtual function interpolate()
  • write a naive linear 2D interpolation child class for now - very bad idea!
  • add spline based methods later

Code up an implied_vol_surface abstract base class

  • has a virtual function implied_vol() to get IV any given T and K: $T,K \mapsto \sigma(T-t_0,K)$
  • write an equity_BS_implied_vol_surface child class that takes in object vol_surface_interpolation as input in ctor

Code up a local_vol_surface abstract base class

  • has a virtual function local_vol()
  • write BS_local_vol child class that takes in object equity_BS_implied_vol_surface as input in ctor
  • see eq 2.19 of Bergomi - equation can be found in ch.2
  • any LSV model we add in the future would be a child class of local_vol_surface

Use local vol given by BS_local_vol object in our GBM analytical stock price long stepping simulator

  • by long stepping GBM, I mean solving GBM SDE analytically, ie $\ln \frac{S(T)}{S(t_0)}= \int_{t_0}^T r(s) - q(s) - \frac{1}{2} \widetilde{\sigma}^2(T-s,K) ds + \int_{t_0}^T \widetilde{\sigma}(T-s,K) dW_s $, where $T$ is option maturity and $\widetilde{\sigma}(\tau,K)$ is the local vol for time to expiry $\tau$ and option strike $K$ - I think here we are implicitly assuming sticky strike rolling of the LV surface...more thinking required
  • In practise, given our current set up (of using the parameter class) we would likely need to write a lambda $s \mapsto \widetilde{\sigma}(s,K)$ for a given $K$, and use that as an input to our BS simulation engine - doesn't seem like a scalable design...suggestions are welcome
  • Need some thinking how to handle discrete steps, e.g. Euler method

Write tests and notebook to check:

  • Smile dynamics - needs some thinking, see ch.2.5 of Bergomi
  • Ability to reprice OTM and ITM vanilla options
  • This LSE deck gives quite a good overview for smile/vol modelling without going into crazy maths

[Python] Support multi-asset exotics (e.g. best-of/worst-of)

The payoff structure of simple rainbow options (e.g. best-of) is fairly simple. The challenge in pricing these multi-asset exotic is the difficulty in incorporating correlation in the multi-asset simulation model.

A rough roadmap:

  1. Refractor MC engine to support multiple un-correlated simulated equity names
  2. Incorporate Cholesky decomposition into the random number generation process to allow for correlated Brownians, #29
  3. Support multi-asset payoff structures
  4. Put everything together (and adding unit tests)

[Python] Use random number seed

There is currently no way to specify random number seed in the python Exotic Monte Carlo Engine. Without the ability to set seeds, we cannot generate a same set of random variables (rv's). This is problematic as:

  • difficult to unit test/replicate results
  • Not able to run risks (Greeks)

Rough plan:

  • set seed in base class RandomBase ctor - see here
  • Implement a new subclass (naming = PseudoRandom?), inheriting from RandomBase. It should be able to set seed when generating pseudo rv's.
  • Delete the TestRandom class as it is just a temporary solution. Amend old code to use the new subclass - see here and here
  • Add new unit tests in here to test model dynamics with non-zero vol
  • Add new unit tests here to test behaviour of set_seed(), get_gaussians(), and get_uniforms() methods

[Python] Support path-dependent payoffs

Rough plan: (will enrich to give more context on design)

  1. build out exotic engine
  2. add simple path-dependent payoffs - e.g. asian
  3. enrich option class to support path-dependent payoffs
  4. add unit tests
  5. add notebooks for analysis

[C++] Update first order greeks logic

Thanks to #38, we now have the ability to compute first order Greeks using FDM.

The current implementation is agnostic to the type of risk that is being computed. This may not be ideal as different types of risk should be subject to different bump styles (for both numerical stability and financial reasons). E.g. rho should be computed via an absolute bump, rather than a relative one.

Further more, theta is a special type of risk that should not be computed via bumping, but rather via "rolling". To explain what I mean by that, theoretically, we compute theta as $\theta = -\frac{\partial V}{\partial t}$, where $t = T-t_0$ denotes time to maturity. This implicitly implies that we are allowed to hold all other model parameters constant. But in practise, traders are concerned with the PnL impact of leaving our option position overnight, which will include effects from the "natural" time decay of other market variables. So conceptually, theta is more like $\theta = \frac{dV}{dt} = -\sum_i \frac{\partial V}{\partial x_i} \frac{dx_i}{d t}$ instead (not sure if this is the right formulation?).

In the context of finite differencing, this means that the "bumped state" should account for the time effects of the other model parameters as well. E.g. rates and equity spot should be rolled along its forward curve, i.e. $S(t_0) \rightarrow E[S(t+\delta t) | t_0] = F(t_0, t+\delta t)$ (only true under forward measure?). The implied vol surface should be rolled forward as well if the term structure of vol is non flat. Note that the rolling methodology of the vol surface is non-trivial, see e.g. here for a high level review, and here for a model in depth discussion.

PS: not sure if what I said above it 100% legit...will update as I understand the problem better.

[Python] Support quasi random numbers in random number generator

It is well known that using quasi-random numbers (QRN) improves convergence speed of a Monte Carlo pricer. This issues aims to support QRN in our random number generator (RNG).

See here for the current implementation of the RNG.

Would be nice to then add a notebook to perform convergence speed analysis - comparing performance of our pricer with either QRN or pseudo random numbers (PRN).

[C++/CMake] Fix relative paths to use correct project root + refactor project CMakeLists.txt

Currently the C++ project is https://en.wikipedia.org/wiki/Header-only. This typically has the benefit of simplicity and better enabling link time optimisation BUT leads to longer compilation times. This becomes more of an issue as most functions in our code require compilation on both host + device side - i.e. even longer times. We can package this properly as a static/shared library instead.

Moreover, some paths are not correct and reference (incorrect) relative paths. These need to be fixed.

[Python] Support Geometric Style Asian Option

This change is building on the work in PR #30:

Rough Plan:

  • Add geometric asian option (plus renaming current asian option to arithemtic)
  • Add unit tests (for payoff and pricing)
  • Add notebook for visualisation and analysis

[Python] Inability to capture volatility skew

Cannot capture vol skew in the python Exotic Monte Carlo Engine. To do:

  • Incorporate local vol model (industry standard approach to capture day-0 smile/skew)
  • Incorporate stochastic vol model (LV produces 'weird' smile dynamics, which is not great when pricing path-dependent options. In such cases, SV models are required)

Ideally will have both implemented. Keep in mind the design should support any volatility model, making it extendible.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.