Skip to main content

Simple simulator for investors

Project description

cvxsimulator

PyPI version Apache 2.0 License Downloads Coverage Status

Open in GitHub Codespaces

Given a universe of $m$ assets we are given prices for each of them at time $t_1, t_2, \ldots t_n$, e.g. we operate using an $n \times m$ matrix where each column corresponds to a particular asset.

In a backtest we iterate in time (e.g. row by row) through the matrix and allocate positions to all or some of the assets. This tool shall help to simplify the accounting. It keeps track of the available cash, the profits achieved, etc.

Analytics

Installation

It is possible to install cvxsimulator with the quantstats extra

pip install cvxsimulator[quantstats]

or without it

pip install cvxsimulator

Creating portfolios

The simulator shall be completely agnostic as to the trading policy/strategy. Our approach follows a rather common pattern:

We demonstrate those steps with somewhat silly policies. They are never good strategies, but are always valid ones.

Create the builder object

The user defines a builder object by loading prices and initialize the amount of cash used in an experiment:

import pandas as pd
from cvx.simulator import Builder

prices = pd.read_csv("prices.csv", index_col=0, parse_dates=True, header=0)
b = Builder(prices=prices, initial_aum=1e6)

Prices have to be valid, there may be NaNs only at the beginning and the end of each column in frame. There can be no NaNs hiding in the middle of any time series.

It is also possible to specify a model for trading costs. The builder helps to fill up the frame of positions. Only once done we construct the actual portfolio.

Loop through time

We have overloaded the __iter__ and __setitem__ methods to create a custom loop. Let's start with a first strategy. Each day we choose two names from the universe at random. Buy one (say 0.1 of your portfolio wealth) and short one the same amount.

for t, state in b:
    # pick two assets at random
    pair = np.random.choice(state.assets, 2, replace=False)
    # compute the pair
    units = pd.Series(index=state.assets, data=0.0)
    units[pair] = [state.nav, -state.nav] / state.prices[pair].values
    # update the position
    b.position = 0.1 * units
    # Do not apply trading costs
    b.aum = state.aum

Here t is the growing list of timestamps, e.g. in the first iteration t is $t1$, in the second iteration it will be $t1, t2$ etc.

A lot of magic is hidden in the state variable. The state gives access to the currently available cash, the current prices and the current valuation of all holdings.

Here's a slightly more realistic loop. Given a set of $4$ assets we want to implemenent the popular $1/n$ strategy.

for t, state in b:
    # each day we invest a quarter of the capital in the assets
    b.position = 0.25 * state.nav / state.prices
    b.aum = state.aum

Note that we update the position at the last element in the t list using a series of actual units rather than weights or cashpositions. The builder class also exposes setters for such alternative conventions.

for t, state in b:
    # each day we invest a quarter of the capital in the assets
    b.weights = np.ones(4)*0.25
    b.aum = state.aum

Build the portfolio

Once finished it is possible to build the portfolio object

portfolio = b.build()

Analytics

The portfolio object supports further analysis and exposes a number of properties, e.g.

portfolio.nav
portfolio.cash
portfolio.equity

It is possible to perform

portfolio.snapshot()

We have also integrated the quantstats package as an optional extra for further analysis. It is usually enough to inject the portfolio.nav into the many functions exposed by this package.

Poetry

We assume you share already the love for Poetry. Once you have installed poetry you can perform

make install

to replicate the virtual environment we have defined in pyproject.toml.

Jupyter

We install JupyterLab on the fly within the aforementioned virtual environment. Executing

make jupyter

will install and start the jupyter lab.

Project details


Release history Release notifications | RSS feed

This version

1.0.0

Download files

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

Source Distribution

cvxsimulator-1.0.0.tar.gz (17.4 kB view details)

Uploaded Source

Built Distribution

cvxsimulator-1.0.0-py3-none-any.whl (21.7 kB view details)

Uploaded Python 3

File details

Details for the file cvxsimulator-1.0.0.tar.gz.

File metadata

  • Download URL: cvxsimulator-1.0.0.tar.gz
  • Upload date:
  • Size: 17.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.1 CPython/3.10.12

File hashes

Hashes for cvxsimulator-1.0.0.tar.gz
Algorithm Hash digest
SHA256 ef8329229538d7b6fb17ee8850372cfb57e4728bba46e6e11caf765a3421f098
MD5 169744c0e649b1946c6e33bea55b7140
BLAKE2b-256 44d53d89c0b48f4211dc0ea3e9ee665a7855e65771a69189f71583e40a25101a

See more details on using hashes here.

File details

Details for the file cvxsimulator-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: cvxsimulator-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 21.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.1 CPython/3.10.12

File hashes

Hashes for cvxsimulator-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 594f1971af796523e02fb4fc07533210d1f990240f1c54583e9d662e98f0cbeb
MD5 38c3b8c40eaa9bfe40519fd845051bef
BLAKE2b-256 d0c49d53aae1c93adc9d3a3f835d768c3509b429f76c7ef367411f1a96db1e42

See more details on using hashes here.

Supported by

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