Model API
You can write your own models, that are compatible with the utils and calculators in this package.
All models must inherit finmc.models.base.MCBase
.
MC Models in other repos
These are implementations of Monte-Carlo models in other repositories, using the finmc
interface.
Models using MCFixedStep
as base
- Local Vol Model using SVI vols : a local vol model that calibrates on-the-fly from an SVI parameterized volatility surface.
- Qablet Intro to Custom Models: a step by step tutorial to write a Black-Scholes model using finmc interface.
- Heston Almost Exact Simulation: variations of the Heston model.
Models using MCBase
:
- Rough Bergomi Model: implementation of a Rough Bergomi model using a hybrid scheme for the Brownian semistationary processes.
finmc.models.base.MCBase
Base class for a Monte-Carlo process.
Source code in finmc\models\base.py
finmc.models.base.MCBase.reset
abstractmethod
finmc.models.base.MCBase.get_value
Return the value of the asset at the current time, if this asset is handled by the model, otherwise return None. The return value is none, float, or an np array of floats.
finmc.models.base.MCBase.get_df
finmc.models.base.MCBase.advance
abstractmethod
The derived class must implement this method to advance the state of the model to a new time. The model may do so in multiple time steps.
finmc.models.base.MCFixedStep
A Monte-Carlo process which breaks down the 'advance' step into fixed time steps specified by the TIMESTEP parameter.
Source code in finmc\models\base.py
finmc.models.base.MCFixedStep.step
abstractmethod
The derived class must implement this method, which advances the model by a timestep equal to or less than the TIMESTEP parameter.
Example
# Define a single asset Black Scholes process with a flat volatility
class BSMC(MCFixedStep):
def reset(self):
# fetch the model parameters from the dataset
...
# Initialize rng and any arrays
self.rng = Generator(SFC64(self.dataset["MC"].get("SEED")))
self.x_vec = np.zeros(self.n) # process x (log stock)
self.cur_time = 0
def step(self, new_time):
"""Update x_vec in place when we move simulation by time dt."""
dt = new_time - self.cur_time
fwd_rate = self.asset_fwd.rate(new_time, self.cur_time)
dz_vec = self.rng.standard_normal(self.n) * sqrt(dt) * self.vol
self.x_vec += (fwd_rate - self.vol * self.vol / 2.0) * dt + dz_vec
self.cur_time = new_time
def get_value(self, unit):
"""Return the value of the modeled asset at the current time."""
if unit == self.asset:
return self.spot * np.exp(self.x_vec)
def get_df(self):
return self.discounter.discount(self.cur_time)