Simple simulator for investors
Project description
cvxsimulator
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.
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
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 cvxsimulator-1.1.0.tar.gz
.
File metadata
- Download URL: cvxsimulator-1.1.0.tar.gz
- Upload date:
- Size: 17.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/5.1.1 CPython/3.10.12
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | c96b082fc5fbbf9c6ea45593d5ba652e7338388016b24e23cee43178637d46b2 |
|
MD5 | 9436774149c3f74734bbbcfc6b385d33 |
|
BLAKE2b-256 | 4f55a85d3f2894fb028508fa51e2381fa01e40cc1d2fdd3d015097091751f4a1 |
File details
Details for the file cvxsimulator-1.1.0-py3-none-any.whl
.
File metadata
- Download URL: cvxsimulator-1.1.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
Algorithm | Hash digest | |
---|---|---|
SHA256 | 96d6b6bdfdc2e1e49c6a0a7b5a2c108e55253b726ed74a6da122cac7599a1cae |
|
MD5 | 1f93386624d5d1683135f5b6f4806a7e |
|
BLAKE2b-256 | 7ff9a2f2480ba68922919e682f2e4cb1d6176f0d5dac69f4571fcbe56b903b2c |