Skip to content

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

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
class MCBase(ABC):
    """Base class for a Monte-Carlo process."""

    stats: dict = {}

    def __init__(self, dataset: dict) -> None:
        self.dataset = dataset
        self.reset()

    @abstractmethod
    def reset(self):
        """The derived class must implement this method to reset the state of the model
        to time zero."""
        ...

    def set_stat(self, key: str, val):
        self.stats[key] = val

    def get_value(self, unit):
        """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."""
        return None

    def get_df(self):
        """Return the discount factor at the current time.
        The return value is a float, or an np array of floats."""
        ...

    @abstractmethod
    def advance(self, new_time: float):
        """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.MCBase.reset abstractmethod

The derived class must implement this method to reset the state of the model to time zero.

Source code in finmc\models\base.py
@abstractmethod
def reset(self):
    """The derived class must implement this method to reset the state of the model
    to time zero."""
    ...

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.

Source code in finmc\models\base.py
def get_value(self, unit):
    """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."""
    return None

finmc.models.base.MCBase.get_df

Return the discount factor at the current time. The return value is a float, or an np array of floats.

Source code in finmc\models\base.py
def get_df(self):
    """Return the discount factor at the current time.
    The return value is a float, or an np array of floats."""
    ...

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.

Source code in finmc\models\base.py
@abstractmethod
def advance(self, new_time: float):
    """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
class MCFixedStep(MCBase):
    """A Monte-Carlo process which breaks down the 'advance' step into fixed time steps
    specified by the TIMESTEP parameter."""

    def advance(self, new_time):
        while new_time > self.cur_time + self.timestep:
            self.step(self.cur_time + self.timestep)
        if new_time > self.cur_time + 1e-10:
            self.step(new_time)

    @abstractmethod
    def step(self, new_time: float):
        """The derived class must implement this method, which advances the model by a timestep equal to or
        less than the TIMESTEP parameter."""
        ...

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.

Source code in finmc\models\base.py
@abstractmethod
def step(self, new_time: float):
    """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)

See complete code of BSMC here