Composable financial contracts with Monte Carlo valuation
Project description
Monte Carlo Contracts
A Python library to compose complex fincancial products from elementary contracts.
This is what it looks like (see Minimal.ipynb for the full example):
ko_option = Until(
Stock("ABC Eqty") > 70,
When(
At(np.datetime64("2024-06-01")),
Or(Stock("ABC Eqty") * One("USD") - 55 * One("USD"), Zero()),
),
)
evaluate(model, ko_option)
# 3.2316051920219797
This library employs ideas from How to Write a Financial Contract by S. L. Peyton Jones and J-M. Eber. However, the implementation is not based on functional programming but rather using an object oriented approach. Also, this implementation is tailored towards Monte Carlo based cashflow generation whereas the paper favours more general methods.
For an introduction to the concepts of composable contracts and usage instructions of this library, see the Introduction notebook.
Features
- Composition of financial contracts using elementary contracts
Zero
,One
,Give
,Scale
,And
,When
,Cond
,Anytime
,Until
,Delay
andExchange
. - Boolean and real valued observables (stochastic processes) to be referenced by contracts.
- Cashflow generation for composed contracts given simulation models on fixed dategrids.
Non-Features
- Financial products description language. This library provides classes to describe financial contracts at a low level; a high level description language could be translated into this low level language, but not the other way round.
- Lifecycle management. Capturing past lifecycle events of financial products such as call rights, knockouts or even fixings is left to a high level description. Doing it here would be very hard due to the nature of the acquisition date free variable and the lack of mandatory start / end dates in particular. Just think about a simple contract such as
When(Stock("ABC") > 100, One("EUR"))
. Which fixings would you require? Up to which point would you perform model simulation? - Pricing methods other than Monte Carlo Simulation. While composable contract representations do not force Monte Carlo methods, this library is designed exclusively for them. Supporting other methods would likely require a separation of contracts and the operations defined on them, e.g. by means of the visitor pattern. In How to Write a Financial Contract, Peyton Jones and Eber favour implementation in functional programming languages where this separation is achieved more naturally.
Examples
Install
With Python 3.8+ on your machine, you can install monte-carlo-contracts
using pip
by running (ideally in a virtual environment)
pip install monte-carlo-contracts
which will automatically install the hard dependencies numpy
and pandas
.
For development or running the examples, you may instead want to run
pip install -e .
and then
pip install -r requirements_dev.txt
from the root directory of this repository.
Available Contracts and Observables
Contract | Description |
---|---|
Contract | Abstract base class for all contracts |
Zero | Neither receive nor pay anything |
One | Receive one unit of currency at acquisition |
Give | Receive all obligations of the underlying contract and pay all rights, i.e. invert the underlying contract |
And | Obtain rights and obligations of all underlying contracts |
Or | Choose at acquisition between the underlying contracts |
Cond | If observable is True at acquisition, obtain contract1, otherwise contract2 |
Scale | Same as the underling contract, but all payments scaled by the value of observable at acquisition |
When | Obtain the underlying contract as soon as observable becomes True after acquisition |
Delay | Obtain the underlying contract and delay all payments to first occurence of observable. |
Anytime | At any point in time after acquisition when observable is True, choose whether to obtain the underlying contract or not; can be exercised only once |
Until | Obtain the underlying contract, but as soon as observable becomes True after acquisition all following payments are nullified |
Exchange | Exchange cashflows resulting from contract to currency at the current spot rate |
Boolean Observable | Description |
---|---|
ObservableBool | Abstract base class for all observables of underlying type bool |
Not | True if observable is False and vice versa |
AndObservable | True if and only if both observables are True |
OrObservable | True if either or both observable are True |
GreaterOrEqualThan | True if and only if observable1 is greater or equal than observable2 |
GreaterThan | True if and only if observable1 is strictly greater than observable2 |
At | True only at date |
Float Observable | Description |
---|---|
ObservableFloat | Abstract base class for all observables of underlying type float, essentially a real-valued stochastic process |
Sum | Equal to the sum of two observables |
Minus | Negative value of observable |
Product | Equal to the product (multiplication) of two observables |
Quotient | Equal to the quotient (division) of two observables |
Power | Equal to observable1 to the power of observable2 |
Maximum | Equal to the maximum of two observables |
Minimum | Equal to the minimum of two observables |
RunningMax | Running maximum of observable over time, seen from first_observation_idx. |
RunningMin | Running minimum of observable over time, seen from first_observation_idx. |
FixedAfter | Equal to observable, but remains constant as soon as fixing_condition becomes true after (including) first_observation_idx. |
Stock | Value of the stock identified by identifier |
FX | Value of the currency spot between base_currency and counter_currency, i.e. 'one unit counter_currency' / 'one unit of base_currency' |
LinearRate | Value of the linear rate (e.g. a LIBOR) with payment frequency in currency |
KonstFloat | Always equal to constant |
History
See HISTORY.md.
Credits
Main developer is luphord luphord@protonmail.com.
cookiecutter-pyscript was used as project template, but the repository structure has evolved considerably.
History
Some future version (not yet)
- ToDo: Observables
Sum
,Product
,Maximum
,Minimum
,AndObservable
andOrObservable
accept more than two contracts to be combined - ToDo: Add JSON (de)serialization for contracts and observables
- ToDo: Add Jupyter based treeview for contracts and observables
- ToDo: Implement cashflow generation for
Or
contract with future payment dates - ToDo: Implement cashflow generation for
Anytime
contract (using Longstaff-Schwartz approach) - ToDo: Implement
get_model_requirements
for all observables and contracts - ToDo: Add a "test model" working for arbitrary underlyings to analyze contracts
- ToDO: fix Ho-Lee-Model
- ToDo: Use instances of a
Currency
class instead of strings to describe currencies - ToDo: Add documentation about the concepts of contracts, observables and acquisition dates
- ToDo: Document financial products lifecycle aspects and their relationship to composable contracts
- ToDo: Add labels to contracts which are forwarded to simulated cashflows
- ToDo: Add documentation about models in Introduction notebook
0.10.0 (2022-04-03)
- Add new
Exchange(currency, contract)
contract - Modify FX options examples to use
Exchange
for cash settlement - Add observables and contracts overview to package doc, as well as to Introduction notebook
0.9.0 (2023-03-26)
- BREAKING CHANGE Convenvience methods
generate_cashflows
,generate_simple_cashflows
,generate_simple_cashflows_in_currency
,generate_simple_cashflows_in_numeraire_currency
andevaluate
that used to be defined onModel
are now standalone functions that accept a model instance as first argument; i.e. instead ofmodel.evaluate(contract)
you now doevaluate(model, contract)
- BREAKING CHANGE Pricing model implementations (at the moment
HoLee
andsimulate_equity_black_scholes_model
) now need to be imported frommcc.pricing_models
; stochastic processes (at the momentBrownianMotion
andGeometricBrownianMotion
) need to be imported frommcc.pricing_models.stochastic_processes
- Split
mcc.py
into multiple modules forming packagemcc
; imports will continue to work as before except for the exceptions listed above - Split tests into multiple smaller modules with more specific focus
- Support Python 3.11
- Upgrade (dev) dependencies
- Development Status :: 3 - Alpha
- BREAKING CHANGE: Remove CLI stub (there was no real CLI functionality anyway)
0.8.0 (2023-03-20)
- BREAKING CHANGE:
Contract
now inherits fromResolvableContract
instead of the other way round - BREAKING CHANGE:
And
andOr
contracts now accept more than two contracts to be combined; these have equivalent semantics to nestedAnd
orOr
contracts and allow for flat structures to improve readability - Add
Delay(observableBool, contract)
contract to delay cashflows to a later point in time (main use case is FX payment offset) - First steps towards model requirements (yet incomplete)
- Fix cashflow generation for nested contracts
0.7.0 (2022-03-13)
- BREAKING CHANGE:
ObservableFloat.simulate
andObservableBool.simulate
now accept aDateIndex
first_observation_idx
as first argument,Contract
classes will passacquisition_idx
; this allows observations to depend on the time of entering a contract, e.g. "maximum spot since acquisition" - BREAKING CHANGE:
FixedAfter
fixes composed observable after (including)first_observation_idx
, not from the beginning - Add operator overloading for
Contract
classes, i.e. you can now doOne("USD") - One("EUR") | 1.2 * One("GBP")
instead ofOr(And(One("USD"), Give(One("EUR"))), Scale(1.2, One("GBP")))
Maximum
andMinimum
observables to observe the larger and smaller value of two observables at the same time on the same pathRunningMax
andRunningMin
observables to observe running extreme values fromfirst_observation_idx
onwards- Support Python 3.10
- Make use of type annotations added to numpy
0.6.0 (2022-03-04)
- BREAKING CHANGE: Make
SimpleCashflows
apandas.DataFrame
- Run notebooks in automated tests using nbval
- Migrate from travis-ci to GitHub Actions
- Explicitly support Python 3.8 and 3.9
- Move history to HISTORY.md
0.5.0 (2020-11-08)
- BREAKING CHANGE: Add
simulated_rates
toModel
(included in constructor); pass an empty dict forsimulated_rates
to adapt your code - BREAKING CHANGE:
BrownianMotion
andGeometricBrownianMotion
generalized to dynamic mean/drift; passmu_t = lambda t: mu * t
to adapt your code LinearRate
observable supported byTermStructureModel
- First steps towards term structure models
FixedAfter
observable to keep an observable fixed after a condition is true- Observables support arithmetic operations (binary
+
,-
,*
,/
,**
and unary-
) with other observables as well as constants (also right operators work) - Working with Observables example notebook
0.4.0 (2020-11-04)
- Discounting (
Model.discount
) - Evaluation (
Model.evaluate
) - String representations for contracts and observables
0.3.0 (2020-10-23)
- Simulation of basic contract
Until
- Currency conversion of
IndexedCashflows
Or
contract supports multiple currenciesObservableFloat
supports<
,<=
,>
and>=
operators withfloat
or otherObservableFloat
instancesObservableBool
supports~
,&
and|
operators for combined conditions- Equity Options and FX Options examples
0.2.0 (2020-10-11)
- Simulation of basic contracts
Zero
,One
,Give
,Scale
,And
,When
andCond
- Partial simulation of
Or
contract - Float observables
Stock
andFX
- Boolean observables
At
SimulatedCashflows
and model-boundIndexedCashflows
to represent cashflows- Basic
Model
allowing the generation of cashflows for the contracts above
0.1.0 (2020-09-22)
- Created using cookiecutter-pyscript
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file monte-carlo-contracts-0.10.0.tar.gz
.
File metadata
- Download URL: monte-carlo-contracts-0.10.0.tar.gz
- Upload date:
- Size: 24.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.8.13
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 9c60ee42bd20f91927db5c0673534c72753799b79f1a25ef66e9f929479215c9 |
|
MD5 | 5dc7cc2ff010cfcf0935ea59902dd655 |
|
BLAKE2b-256 | e133c6ee473ef1400772bd7ab35bef402dad58341505085c0348d76c08937165 |
File details
Details for the file monte_carlo_contracts-0.10.0-py2.py3-none-any.whl
.
File metadata
- Download URL: monte_carlo_contracts-0.10.0-py2.py3-none-any.whl
- Upload date:
- Size: 26.8 kB
- Tags: Python 2, Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.8.13
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 63da74cbebb26c13a287ab2c756108018bc64397916b0cb95f43aca841b69790 |
|
MD5 | 488078eb77b708c9aa4bf26ad2f2884e |
|
BLAKE2b-256 | 77dd5f0a0d0a5a2031b9f6e2f695e17d7895d1a1a4ea87603d47e8e6a5d6c072 |