Rate of return of a portfolio

(rate of return for a security) * (weight in portfolio)

In [1]:
import numpy as np
import pandas as pd
from pandas_datareader import data as wb
import matplotlib.pyplot as plt
In [2]:
tickers = ['PG', 'MSFT', 'F', 'GE']
mydata = pd.DataFrame()
for t in tickers:
    mydata[t] = wb.DataReader(t, data_source='yahoo', start='1995-1-1')['Adj Close']
In [3]:
mydata.info()
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 6375 entries, 1995-01-03 to 2020-04-28
Data columns (total 4 columns):
PG      6375 non-null float64
MSFT    6375 non-null float64
F       6375 non-null float64
GE      6375 non-null float64
dtypes: float64(4)
memory usage: 249.0 KB
In [4]:
mydata.head()
Out[4]:
PG MSFT F GE
Date
1995-01-03 6.320252 2.413537 3.200019 2.729230
1995-01-04 6.269589 2.431082 3.286119 2.729230
1995-01-05 6.180927 2.390982 3.257418 2.735919
1995-01-06 6.193593 2.431082 3.257418 2.722540
1995-01-09 6.168259 2.416045 3.314818 2.695783
In [5]:
mydata.tail()
Out[5]:
PG MSFT F GE
Date
2020-04-22 118.609001 173.520004 4.77 6.43
2020-04-23 119.400002 171.419998 4.89 6.52
2020-04-24 118.779999 174.550003 4.87 6.26
2020-04-27 117.449997 174.050003 5.17 6.43
2020-04-28 116.889999 169.809998 5.38 6.80

Normalization to 100:

$\frac{P_t}{P_0}*100$

In [6]:
mydata.iloc[0]
Out[6]:
PG      6.320252
MSFT    2.413537
F       3.200019
GE      2.729230
Name: 1995-01-03 00:00:00, dtype: float64
In [7]:
(mydata / mydata.iloc[0] * 100).plot(figsize=(15,6))
plt.show()
In [8]:
# not normalized
mydata.plot(figsize=(15,6))
plt.show()
In [9]:
mydata.loc['1995-01-03']
Out[9]:
PG      6.320252
MSFT    2.413537
F       3.200019
GE      2.729230
Name: 1995-01-03 00:00:00, dtype: float64
In [10]:
mydata.iloc[0]
Out[10]:
PG      6.320252
MSFT    2.413537
F       3.200019
GE      2.729230
Name: 1995-01-03 00:00:00, dtype: float64

Calculating the Return of a Portfolio of Securities

In [11]:
returns = mydata
returns.head()
Out[11]:
PG MSFT F GE
Date
1995-01-03 6.320252 2.413537 3.200019 2.729230
1995-01-04 6.269589 2.431082 3.286119 2.729230
1995-01-05 6.180927 2.390982 3.257418 2.735919
1995-01-06 6.193593 2.431082 3.257418 2.722540
1995-01-09 6.168259 2.416045 3.314818 2.695783
In [12]:
returns = (mydata.shift(1))
returns.head()
Out[12]:
PG MSFT F GE
Date
1995-01-03 NaN NaN NaN NaN
1995-01-04 6.320252 2.413537 3.200019 2.729230
1995-01-05 6.269589 2.431082 3.286119 2.729230
1995-01-06 6.180927 2.390982 3.257418 2.735919
1995-01-09 6.193593 2.431082 3.257418 2.722540
In [13]:
returns = (mydata / mydata.shift(1))
returns.head()
Out[13]:
PG MSFT F GE
Date
1995-01-03 NaN NaN NaN NaN
1995-01-04 0.991984 1.007269 1.026906 1.000000
1995-01-05 0.985858 0.983505 0.991266 1.002451
1995-01-06 1.002049 1.016771 1.000000 0.995110
1995-01-09 0.995910 0.993815 1.017621 0.990172
In [14]:
returns = (mydata / mydata.shift(1)) - 1
returns.head()
Out[14]:
PG MSFT F GE
Date
1995-01-03 NaN NaN NaN NaN
1995-01-04 -0.008016 0.007269 0.026906 0.000000
1995-01-05 -0.014142 -0.016495 -0.008734 0.002451
1995-01-06 0.002049 0.016771 0.000000 -0.004890
1995-01-09 -0.004090 -0.006185 0.017621 -0.009828
In [15]:
weights = np.array([0.25, 0.25, 0.25, 0.25])
In [16]:
np.dot(returns, weights)
Out[16]:
array([        nan,  0.00653983, -0.00922993, ..., -0.00772515,
        0.01867412,  0.01725824])
In [17]:
annual_returns = returns.mean() * 250
annual_returns
Out[17]:
PG      0.140423
MSFT    0.216997
F       0.099624
GE      0.085147
dtype: float64
In [18]:
np.dot(annual_returns, weights)
Out[18]:
0.13554795151929935
In [19]:
pfolio_1 = str(round(np.dot(annual_returns, weights), 5) * 100) + ' %'
print(pfolio_1)
13.555 %
In [20]:
weights_2 = np.array([0.4, 0.4, 0.15, 0.15])
pfolio_2 = str(round(np.dot(annual_returns, weights_2), 5) * 100) + ' %'
print(pfolio_2)
17.068 %