0% found this document useful (0 votes)
10 views

Code Python 10 CP

Uploaded by

Phượng Phạm
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views

Code Python 10 CP

Uploaded by

Phượng Phạm
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 10

import numpy as np

import pandas as pd
from pylab import plt, mpl
from scipy.optimize import minimize
plt.style.use('seaborn-v0_8')
mpl.rcParams['savefig.dpi']=300
mpl.rcParams['font.family'] = 'serif'
np.set_printoptions(precision=5, suppress=True,
formatter={'float': lambda x: f'{x:6.3f}'})

url='ma 10 cp _1 .csv'

raw = pd.read_csv(url, index_col=0, parse_dates=True).dropna()

raw.info()

<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 259 entries, 2018-01-05 to 2022-12-30
Data columns (total 10 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 ACB 259 non-null int64
1 BID 259 non-null int64
2 FPT 259 non-null int64
3 HDB 259 non-null int64
4 HPG 259 non-null int64
5 MBB 259 non-null int64
6 PLX 259 non-null int64
7 SAB 259 non-null int64
8 SSI 259 non-null int64
9 VIC 259 non-null int64
dtypes: int64(10)
memory usage: 22.3 KB

symbols = ['ACB','BID', 'FPT','HDB','HPG','MBB','PLX','SAB','SSI','VIC']

rets = np.log(raw[symbols] / raw[symbols].shift(1)).dropna()

(raw[symbols] / raw[symbols].iloc[0]).plot(figsize=(10, 6));


weights = len(rets.columns) * [1 / len(rets.columns)]

def port_return(rets, weights):


return np.dot(rets.mean(), weights) * 52

port_return(rets, weights)

-0.09182403043677012

def port_volatility(rets, weights):


return np.dot(weights, np.dot(rets.cov() * 52 , weights)) ** 0.5

port_volatility(rets, weights)

0.26253260925188804

def port_sharpe(rets, weights):


return port_return(rets, weights) / port_volatility(rets, weights)

port_sharpe(rets, weights)

-0.34976238075121996

w = np.random.random((1000, len(symbols)))
w = (w.T / w.sum(axis=1)).T

w[:5]

array([[ 0.088, 0.105, 0.089, 0.143, 0.145, 0.196, 0.036, 0.021,


0.106, 0.070],
[ 0.172, 0.020, 0.178, 0.156, 0.061, 0.166, 0.103, 0.015,
0.120, 0.010],
[ 0.168, 0.131, 0.121, 0.200, 0.012, 0.076, 0.163, 0.006,
0.004, 0.120],
[ 0.081, 0.021, 0.115, 0.124, 0.153, 0.003, 0.144, 0.106,
0.090, 0.163],
[ 0.035, 0.095, 0.037, 0.100, 0.170, 0.126, 0.112, 0.090,
0.080, 0.155]])

pvr = [(port_volatility(rets[symbols], weights),


port_return(rets[symbols], weights))
for weights in w]
pvr = np.array(pvr)

psr = pvr[:, 1] / pvr[:, 0]

plt.figure(figsize=(10, 6))
fig = plt.scatter(pvr[:, 0], pvr[:, 1],
c=psr, cmap='coolwarm')
cb = plt.colorbar(fig)
cb.set_label('Sharpe ratio')
plt.xlabel('expected volatility')
plt.ylabel('expected return')
plt.title(' | '.join(symbols));

bnds = len(symbols) * [(0, 1),]


bnds

[(0, 1),(0, 1),(0, 1),(0, 1),(0, 1),(0, 1),(0, 1),(0, 1),(0, 1),(0, 1)]

cons = {'type': 'eq', 'fun': lambda weights: weights.sum() - 1}


opt_weights = {}
for year in range(2018, 2022):
rets_ = rets[symbols].loc[f'{year}-01-01':f'{year}-12-31']
ow = minimize(lambda weights: -port_sharpe(rets_, weights),
len(symbols) * [1 / len(symbols)],
bounds=bnds,
constraints=cons)['x']
opt_weights[year] = ow

opt_weights

{2018: array([ 0.000, 0.499, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000,
0.000, 0.501]),
2019: array([ 0.000, 0.171, 0.515, 0.000, 0.000, 0.000, 0.000, 0.000,
0.000, 0.314]),
2020: array([ 0.000, 0.000, 0.000, 0.000, 0.454, 0.000, 0.000, 0.000,
0.546, 0.000]),
2021: array([ 0.027, 0.000, 0.838, 0.000, 0.000, 0.000, 0.000, 0.000,
0.135, 0.000])}

res = pd.DataFrame()
for year in range(2018,2022):
rets_ = rets[symbols].loc[f'{year}-01-01':f'{year}-12-31']
epv = port_volatility(rets_, opt_weights[year])
epr = port_return(rets_, opt_weights[year])
esr = epr / epv
rets_ = rets[symbols].loc[f'{year + 1}-01-01':f'{year + 1}-12-31']
rpv = port_volatility(rets_, opt_weights[year])
rpr = port_return(rets_, opt_weights[year])
rsr = rpr / rpv
res = pd.concat([res, pd.DataFrame({'epv': epv, 'epr': epr, 'esr':
esr,
'rpv': rpv, 'rpr': rpr, 'rsr': rsr},
index=[year + 1])])

res

epv epr esr rpv rpr rsr


2019 0.362510 0.205161 0.565945 0.169198 0.246944 1.459496
2020 0.148001 0.275497 1.861449 0.251253 -0.000268 -0.001068
2021 0.412817 0.575185 1.393315 0.347598 0.295699 0.850690
2022 0.286489 0.445871 1.556325 0.355344 -0.322437 -0.907394

res.mean()

epv 0.302455
epr 0.375428
esr 1.344259
rpv 0.280848
rpr 0.054984
rsr 0.350431
dtype: float64

res[['epv', 'rpv']].corr()

epv rpv
epv 1.000000 0.132481
rpv 0.132481 1.000000

res[['epv', 'rpv']].plot(kind='bar', figsize=(10, 6),


title='Expected vs. Realized Portfolio Volatility');

res[['epr', 'rpr']].corr()

epr rpr
epr 1.000000 -0.039914
rpr -0.039914 1.000000

res[['epr', 'rpr']].plot(kind='bar', figsize=(10, 6),


title='Expected vs. Realized Portfolio Return');
res[['esr', 'rsr']].corr()

esr rsr
esr 1.000000 -0.751587
rsr -0.751587 1.000000

res[['esr', 'rsr']].plot(kind='bar', figsize=(10, 6),


title='Expected vs. Realized Sharpe Ratio');
r = 0.005

market = 'HPG'

rets = np.log(raw / raw.shift(1)).dropna()

res = pd.DataFrame()

for sym in rets.columns[:5]:


print('\n' + sym)
print(54 * '=')
for year in range(2018, 2022):
rets_ = rets.loc[f'{year}-01-01':f'{year}-12-31']
muM = rets_[market].mean() * 52
cov = rets_.cov().loc[sym, market]
var = rets_[market].var()
beta = cov / var
rets_ = rets.loc[f'{year + 1}-01-01':f'{year + 1}-12-31']
muM = rets_[market].mean() * 52
mu_capm = r + beta * (muM - r)
mu_real = rets_[sym].mean() * 52
res = pd.concat([res, pd.DataFrame({'symbol': sym,
'mu_capm': mu_capm,
'mu_real': mu_real},
index=[year + 1])], sort=True)
print('{} | beta: {:.3f} | mu_capm: {:6.3f} | mu_real: {:6.3f}'
.format(year + 1, beta, mu_capm, mu_real))
ACB
======================================================
2019 | beta: 0.308 | mu_capm: -0.082 | mu_real: -0.271
2020 | beta: -0.088 | mu_capm: -0.043 | mu_real: 0.209
2021 | beta: 0.390 | mu_capm: 0.047 | mu_real: 0.205
2022 | beta: 0.084 | mu_capm: -0.076 | mu_real: -0.463

BID
======================================================
2019 | beta: 0.415 | mu_capm: -0.113 | mu_real: 0.301
2020 | beta: 0.052 | mu_capm: 0.034 | mu_real: 0.035
2021 | beta: 0.529 | mu_capm: 0.062 | mu_real: -0.255
2022 | beta: 0.253 | mu_capm: -0.241 | mu_real: 0.040

FPT
======================================================
2019 | beta: 0.203 | mu_capm: -0.053 | mu_real: 0.317
2020 | beta: 0.065 | mu_capm: 0.041 | mu_real: 0.025
2021 | beta: 0.413 | mu_capm: 0.050 | mu_real: 0.453
2022 | beta: 0.536 | mu_capm: -0.515 | mu_real: -0.194

HDB
======================================================
2019 | beta: 0.446 | mu_capm: -0.122 | mu_real: -0.118
2020 | beta: 0.050 | mu_capm: 0.032 | mu_real: -0.126
2021 | beta: 0.521 | mu_capm: 0.061 | mu_real: 0.262
2022 | beta: 0.232 | mu_capm: -0.220 | mu_real: -0.673

HPG
======================================================
2019 | beta: 1.000 | mu_capm: -0.279 | mu_real: -0.279
2020 | beta: 1.000 | mu_capm: 0.555 | mu_real: 0.555
2021 | beta: 1.000 | mu_capm: 0.113 | mu_real: 0.113
2022 | beta: 1.000 | mu_capm: -0.965 | mu_real: -0.965

sym = 'HDB'

res[res['symbol'] == sym].corr()

C:\Users\php31\AppData\Local\Temp\ipykernel_20292\1491550360.py:1:
FutureWarning: The default value of numeric_only in DataFrame.corr is
deprecated. In a future version, it will default to False. Select only valid
columns or specify the value of numeric_only to silence this warning.
res[res['symbol'] == sym].corr()

mu_capm mu_real
mu_capm 1.000000 0.874742
mu_real 0.874742 1.000000
res[res['symbol'] == sym].plot(kind='bar',
figsize=(10, 6), title=sym);

grouped = res.groupby('symbol').mean()
grouped

mu_capm mu_real
symbol
ACB -0.038771 -0.079857
BID -0.064552 0.030268
FPT -0.119263 0.150493
HDB -0.061972 -0.163616
HPG -0.144148 -0.144148

grouped.plot(kind='bar', figsize=(10, 6), title='Average Values');

You might also like