Skip to content

class for simulation of stock investing portfolios based on historical data

License

Notifications You must be signed in to change notification settings

uelel/simulatePortfolio

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

simulatePortfolio

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.


Features

  • 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:




Usage

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)

1. Historical data

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)

2. Portfolio

[[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]

3. Currency

currency = 'EUR'

Currency symbol for informative purposes.

4. Start, end date

startDate = datetime.date(2019, 1, 1),
endDate = datetime.date(2020, 1, 1)

datetime.date objects defining simulation timespan.

5. Connection fee

connectionFeePerYear = 2.5

Absolute fee per calendar year.

6. Initial and monhtly contributions

initCont = 2500,
monthCont = 200

Contributed amount for initial and regular investments, respectively.

7. Months per trade

monthsPerTrade = 2

How many months should be between regular investments.

8. Instruments per trade

instrumentsPerTrade = 1

How many instruments should be traded during each regular investment.


Example

from the previous code:


Known issues

  • plots may be distrorted when plotted from terminal.
    Use jupyter notebook or different matplotlib backend.

About

class for simulation of stock investing portfolios based on historical data

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages