Skip to main content

Arrow Markets repository for calculation margin requirements for crypto option portfolios.

Project description

Python Version License

Open Margin

Arrow Markets open source repository to compute margin requirements for risky asset portfolios, including crypto options portfolios.

Overview

This repository uses VAR/CVAR methodology to compute the necessary margin required for a portfolio of BTC or ETH options. Negative values refer to the cash margin needed for a given portfolio, while positive margin values count as credits. For further details, please refer to the white paper "Automated Margin Systems in Practice".

Installation

pip install openmargin

Usage

Open Margin calculates the risk of an options portfolio through RiskCalc. A compatible ticker and an options portfolio are the minimum inputs needed to generate the corresponding margin values. Providing the options data as a dataframe to Open Margin substantially reduces margin computation time.

import datetime
import pandas as pd

ticker = "eth"

expiration = datetime.datetime.strptime('2024-09-27 08:00:00', "%Y-%m-%d %H:%M:%S")
strike = 7000.0
kind = "C"
position = -1
portfolio = {'expiration': expiration, 'strike': strike, 'kind': kind, 'position': position}
portfolio = pd.DataFrame([portfolio],columns = ["expiration", "strike", "kind", "position"])

Once the ticker and the portfolio data are ready, margin can be computed with default parameters:

from openmargin.risk import RiskCalc
risk_calculator = RiskCalc(ticker, portfolio)
risk_calculator.get_margin()

RiskCalc has four pillars that can be modified to generate the required margin. All of the examples below assume that minimum inputs and corresponding package imports are complete.

Options Data

Open Margin uses the current options data for BTC and ETH from Deribit. To provide a different dataset, please provide a pandas dataframe containing options data similar to the one shown below:

To download and save the most recent options data:

from openmargin.auxiliary import deribit_option_data

utcnow = datetime.datetime.now(tz=datetime.timezone.utc)
(expiration_datetimes, yearly_times_to_expiration, strikes, log_moneynesses, contract_types, spot_prices, yearly_mark_implied_volatilities, mark_prices, prices) = deribit_option_data(ticker, utcnow)
options_data = pd.DataFrame([spot_prices, expiration_datetimes, yearly_times_to_expiration, strikes, log_moneynesses, contract_types, yearly_mark_implied_volatilities, mark_prices, prices]).T
options_data.columns = ['spot', 'expiration','tte','strike', 'log_money', 'kind','mark_iv','mark_price', 'price']
options_data = options_data.reset_index(drop=True)
options_data.to_csv(f'options_data.csv', index = False)

To load a cahced option dataset and get the corresponding margin values:

options_data = pd.read_csv('options_data.csv', parse_dates=['expiration'])
risk_calculator = RiskCalc(ticker, portfolio, options_data)
risk_calculator.get_margin()

Risk Configuration

Three main risk factors are configured under RiskConfig. Interest rate, sampling frequency and steps are the key parameters currently allowed for user customization. Sampling frequency multiplied by steps determine the trading horizon that will be used to calculate margin values.

from openmargin.risk import RiskConfig, RiskCalc

r = 0.02
sampling_frequency = 4 # hours
steps = 6
risk_params = RiskConfig(r, sampling_frequency, steps)

risk_calculator = RiskCalc(ticker, portfolio, risk_params = risk_params)
risk_calculator.get_margin()

Risk Model

RiskModel class determines the margin method used. Open Margin only allows VAR type margin methods in this public version. To select between VAR and CVAR and to change margin threshold:

from openmargin.risk import VAR, RiskModel, RiskCalc

var_type = 'VAR'
var_threshold = 0.05
margin_method = VAR(var_type, var_threshold)
risk_model = RiskModel(margin_method)

risk_calculator = RiskCalc(ticker, portfolio, risk_model = risk_model)
risk_calculator.get_margin()

Price Paths

Path dependant methods like VAR/CVAR depend on future price paths. 1,000 paths are generated by default by PricePathGenerator. Changes to the default number of paths can be made via:

from openmargin.auxiliary import get_underlier_price
from openmargin.risk import PricePathGenerator, RiskCalc

spot = get_underlier_price(ticker)
number_of_paths = 10_000
price_paths = PricePathGenerator(ticker, risk_params, spot, number_of_paths)

risk_calculator = RiskCalc(ticker, portfolio, price_paths = price_paths)
risk_calculator.get_margin()

The paths can be generated with:

sample_paths = price_paths.generate_paths()

Further customization examples can be found under example.py.

Clone Repo Directly

The repo can also be cloned directly. This is advisable for doing work on the openmargin repo itself. Please see our guidelines for submitting pull requests. Community contributions are welcome!

git clone https://github.com/Arrow-Markets-Research/openmargin
cd openmargin

venv

Initialize a virtual environment (Windows)

python3 -m venv venv
venv/Scripts/activate.bat

Dependencies

From the venv, run

pip install -r requirements.txt

Create a test file in the src/openmargin directory called om-test.py:

import datetime
import pandas as pd
from openmargin.risk import RiskCalc

ticker = "eth"

expiration = datetime.datetime.strptime('2024-09-27 08:00:00', "%Y-%m-%d %H:%M:%S")
strike = 7000.0
kind = "C"
position = -1
portfolio = {'expiration': expiration, 'strike': strike, 'kind': kind, 'position': position}
portfolio = pd.DataFrame([portfolio],columns = ["expiration", "strike", "kind", "position"])

risk_calculator = RiskCalc(ticker, portfolio)
m = risk_calculator.get_margin()

print("portfolio:\n", portfolio, "\nspot:", float(risk_calculator.portfolio.spot), "\ninitial margin:", m[0])

Now, to compute the intitial margin for the chosen portfolio, switch to the src directory and run

python3 -m openmargin.om-test

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

openmargin-0.0.7.tar.gz (74.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

openmargin-0.0.7-py3-none-any.whl (36.3 kB view details)

Uploaded Python 3

File details

Details for the file openmargin-0.0.7.tar.gz.

File metadata

  • Download URL: openmargin-0.0.7.tar.gz
  • Upload date:
  • Size: 74.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.0 CPython/3.8.10

File hashes

Hashes for openmargin-0.0.7.tar.gz
Algorithm Hash digest
SHA256 1d43bcc9f2dfc6786e26690f56f2222890642f9cada5aedac0836a04889a8de4
MD5 cb19e7eb3784c74667ba43f9c4f4776b
BLAKE2b-256 28855d49e8aa76098825757c116797ce53aef93fcae1d7b423d7c410a1e85ff8

See more details on using hashes here.

File details

Details for the file openmargin-0.0.7-py3-none-any.whl.

File metadata

  • Download URL: openmargin-0.0.7-py3-none-any.whl
  • Upload date:
  • Size: 36.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.0 CPython/3.8.10

File hashes

Hashes for openmargin-0.0.7-py3-none-any.whl
Algorithm Hash digest
SHA256 fcf0555d5e3f40446cac8b1448f347589c53359f12cd62ca043c9229be03ab66
MD5 3535bfef6ab3fe530a10576ec51f1ed1
BLAKE2b-256 46707ad268cf70d8886c6bda8f916278b2af50b90d52a05aeef1ef767d157c22

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page