Portfolio


In [1]:
import pandas as pd
import numpy as np
from beakerx import *

import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)

In [2]:
# load prices from a csv file
prices=pd.read_csv("data/price.csv", index_col=0, header=0, parse_dates=True)

In [3]:
# plot them using beakerx
SimpleTimePlot(prices, prices.keys())



In [4]:
# construct a 1/n portfolio, assets that come in later will initially not have any weight
def f(x):
    # how many assets are alive?
    n = x.notnull().sum()
    # create a new series (this seems to be slow, there must be a more elegant solution?)
    y = pd.Series(index=x.index)
    if n > 0:
        y[x.notnull()] = 1.0/n
    return y

In [16]:
p = pd.DataFrame(index =[pd.Timestamp("today").date()], columns=["A","B","C"], data=[[10.0, 20.0, np.nan]]) 
g = p.apply(f, axis=1)
g


Out[16]:
A B C
2020-03-24 0.5 0.5 NaN

In [6]:
from pyutil.portfolio.portfolio import Portfolio
p = Portfolio(prices=prices, weights=prices.ffill().apply(f, axis=1))

Sector analysis

It is possible to assign each asset to a sector via sectormaps.


In [7]:
sectormap = {"A": "S1", "B": "S1", "C": "S2", "D": "S2", "E": "S2", "F": "S2", "G": "S3"}
p.tail(5).sector(symbolmap=sectormap)


Out[7]:
S1 S2 S3
2015-04-16 0.285714 0.571429 0.142857
2015-04-17 0.285714 0.571429 0.142857
2015-04-20 0.285714 0.571429 0.142857
2015-04-21 0.285714 0.571429 0.142857
2015-04-22 0.285714 0.571429 0.142857

Rebalancing

Daily rebalancing is somewhat expensive. It is possible to "iron" the portfolio and rebalance either

  • on a fixed grid in time
  • with respect to threshold that shall not be exceeded

In [8]:
x = p.iron_time("3M")
# the position are never really constant as the portfolio class is based on weights. Changing this would be expensive for now...
x.position


Out[8]:
A B C D E F G
2013-01-01 0.000085 0.000006 0.000002 0.000038 0.000098 0.000053 0.000057
2013-01-02 0.000085 0.000006 0.000002 0.000038 0.000098 0.000053 0.000057
2013-01-03 0.000085 0.000006 0.000002 0.000038 0.000098 0.000053 0.000057
2013-01-04 0.000085 0.000006 0.000002 0.000038 0.000098 0.000053 0.000057
2013-01-07 0.000085 0.000006 0.000002 0.000038 0.000098 0.000053 0.000057
... ... ... ... ... ... ... ...
2015-04-16 0.000111 0.000006 0.000003 0.000055 0.000072 0.000043 0.000045
2015-04-17 0.000111 0.000006 0.000003 0.000055 0.000072 0.000043 0.000045
2015-04-20 0.000111 0.000006 0.000003 0.000055 0.000072 0.000043 0.000045
2015-04-21 0.000111 0.000006 0.000003 0.000055 0.000072 0.000043 0.000045
2015-04-22 0.000125 0.000005 0.000003 0.000057 0.000072 0.000040 0.000049

602 rows × 7 columns


In [9]:
x.cash


Out[9]:
2013-01-01    2.220446e-16
2013-01-02    0.000000e+00
2013-01-03    0.000000e+00
2013-01-04    0.000000e+00
2013-01-07   -2.220446e-16
                  ...     
2015-04-16    4.440892e-16
2015-04-17    4.440892e-16
2015-04-20    5.551115e-16
2015-04-21    4.440892e-16
2015-04-22    2.220446e-16
Length: 602, dtype: float64

In [10]:
# plot them using beakerx
SimpleTimePlot(x.position, x.assets)



In [ ]:


In [ ]:


In [ ]:


In [ ]: