simulatePortfolio is a Python class that upon instantiation simulates performance of portfolio with stock instruments.
The main goal of this project is to provide basic metrics of long(er)-term investments based on the historical data and investment strategy.
-
the simulator was developed for tracking long(er)-term investments with the time horizon of at least several months
-
the simulator implements initial and monthly contributions and two kinds of instrument purchases:
- initial purchase: of all instruments during the start date
- regular purchases: of defined number of instruments at defined monthly intervals.
-
the simulator acknowledges commission scheme typical for brokerage services:
- absolute fee: absolute fee during purchase of one instrument
- relative fee: fraction of purchased volume during purchase of one instrument
- connection fee: absolute fee per calendar year
-
it is necessary to define instrument weights in portfolio.
The instrument weights are aimed to be preserved during simulation by solving of this SOE regularly:
import datetime
from sp import simulatePortfolio
inst1 = {'name':'iShares S&P500', 'data':{datetime.date(2019, 1, 1): 259.05, datetime.date(2019, 2, 1): 276.162, datetime.date(2019, 3, 1): 282.065, datetime.date(2019, 4, 1): 291.348, datetime.date(2019, 5, 1): 287.017, datetime.date(2019, 6, 1): 286.0, datetime.date(2019, 7, 1): 299.4, datetime.date(2019, 8, 1): 294.882, datetime.date(2019, 9, 1): 296.533, datetime.date(2019, 10, 1): 299.253, datetime.date(2019, 11, 1): 311.615, datetime.date(2019, 12, 1): 318.435, datetime.date(2020, 1, 1): 326.11, datetime.date(2020, 2, 1): 325.68}}
inst2 = {'name':'Xetra Gold', 'data': {datetime.date(2019, 1, 1): 36.24, datetime.date(2019, 2, 1): 36.99, datetime.date(2019, 3, 1): 36.92, datetime.date(2019, 4, 1): 36.99, datetime.date(2019, 5, 1): 36.49, datetime.date(2019, 6, 1): 37.8, datetime.date(2019, 7, 1): 39.44, datetime.date(2019, 8, 1): 41.02, datetime.date(2019, 9, 1): 44.66, datetime.date(2019, 10, 1): 43.42, datetime.date(2019, 11, 1): 43.55, datetime.date(2019, 12, 1): 42.53, datetime.date(2020, 1, 1):44.03, datetime.date(2020, 2, 1):45.85}}
simulatePortfolio([[inst1, 0.8, 2.0, 0.00038],
[inst2, 0.2, 2.0, 0.00038]],
currency = 'EUR',
connectionFeePerYear = 2.5,
startDate = datetime.date(2019, 1, 1),
endDate = datetime.date(2020, 1, 1),
initCont = 2500,
monthCont = 200,
monthsPerTrade = 2,
instrumentsPerTrade = 2)
inst1 = {'name':'iShares S&P500', 'data':{datetime.date(2019, 1, 1): 259.05, datetime.date(2019, 2, 1): 276.162, datetime.date(2019, 3, 1): 282.065, datetime.date(2019, 4, 1): 291.348, datetime.date(2019, 5, 1): 287.017, datetime.date(2019, 6, 1): 286.0, datetime.date(2019, 7, 1): 299.4, datetime.date(2019, 8, 1): 294.882, datetime.date(2019, 9, 1): 296.533, datetime.date(2019, 10, 1): 299.253, datetime.date(2019, 11, 1): 311.615, datetime.date(2019, 12, 1): 318.435, datetime.date(2020, 1, 1): 326.11, datetime.date(2020, 2, 1): 325.68}}
inst2 = {'name':'Xetra Gold', 'data': {datetime.date(2019, 1, 1): 36.24, datetime.date(2019, 2, 1): 36.99, datetime.date(2019, 3, 1): 36.92, datetime.date(2019, 4, 1): 36.99, datetime.date(2019, 5, 1): 36.49, datetime.date(2019, 6, 1): 37.8, datetime.date(2019, 7, 1): 39.44, datetime.date(2019, 8, 1): 41.02, datetime.date(2019, 9, 1): 44.66, datetime.date(2019, 10, 1): 43.42, datetime.date(2019, 11, 1): 43.55, datetime.date(2019, 12, 1): 42.53, datetime.date(2020, 1, 1):44.03, datetime.date(2020, 2, 1):45.85}}
Historical data are nested dict
with name
and data
keys.
The actual data points consist of datetime.date
objects coupled with instrument prices per share.
- It is possible to load daily or monthly prices
- Monthly prices should be coupled to the same day in month for all instruments (e.g. all prices are defined on the 1st day of month)
[[inst1, 0.8, 2.0, 0.00038],
[inst2, 0.2, 2.0, 0.00038]]
Portfolio is list
of some instruments.
Each instrument takes the form [historical data, weight, absolute fee, relative fee]
currency = 'EUR'
Currency symbol for informative purposes.
startDate = datetime.date(2019, 1, 1),
endDate = datetime.date(2020, 1, 1)
datetime.date
objects defining simulation timespan.
connectionFeePerYear = 2.5
Absolute fee per calendar year.
initCont = 2500,
monthCont = 200
Contributed amount for initial and regular investments, respectively.
monthsPerTrade = 2
How many months should be between regular investments.
instrumentsPerTrade = 1
How many instruments should be traded during each regular investment.
from the previous code:
- plots may be distrorted when plotted from terminal.
Usejupyter notebook
or differentmatplotlib
backend.