-
Notifications
You must be signed in to change notification settings - Fork 0
/
util.py
109 lines (77 loc) · 3.95 KB
/
util.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter
import ssl
def web_prices(symbol:list,sourceURL:str='https://www.cryptodatadownload.com/cdd/',
exchange:str='Binance',pair:str='USDT',periodicity:str='d',number_observations:int=360) -> pd.DataFrame:
"""
Check https://www.cryptodatadownload.com/data/ for avaible exchanges ,periodicity, and pairs
"""
ssl._create_default_https_context = ssl._create_unverified_context
data = pd.DataFrame()
for _ in range(len(symbol)):
data_price = pd.read_csv(sourceURL+exchange+'_'+symbol[_]+pair+'_'+periodicity+'.csv',header=1)
data_price = data_price[['date','close']]
data_price.columns = ['date', symbol[_]]
data_price.set_index('date', inplace=True)
data = data.join(data_price, how='outer')
data.dropna(inplace= True)
data.sort_index(ascending=False, inplace=True)
return data.head(number_observations)
def rate_of_return(prices: pd.DataFrame,LogReturn=False) -> pd.DataFrame:
if LogReturn:
return np.log(1 + prices.pct_change(-1)).dropna()
else:
return prices.pct_change(-1).dropna()
def risk_by_asset(Returns:pd.DataFrame)-> pd.DataFrame:
risk_asset = (Returns.std() * np.sqrt(252)).to_frame()
risk_asset.columns = ['Risk']
mean_returns_asset = (Returns.mean()*252).to_frame()
mean_returns_asset.columns = ['Return']
return risk_asset.join(mean_returns_asset, how='outer')
def efficient_frontier(returns,N_simulations,RiskFreeRate,save_simulatios=True):
portfolio_risk_return=[]
portfolio_metrics={'portfolio_returns': 0, 'portfolio_risk': 0, 'portfolio_sharpe_ratio': -99,'portfolio_weights':[],'portfolio_risk_return':[]}
for portfolio in range (N_simulations):
#Random Weight
weights = np.random.random_sample(len(returns.columns))
weights = weights / np.sum(weights)
#Calculate Return
portfolio_mean_return= sum(returns.mean()*weights)*252
#Calculate Risk
cov_matrix = (returns.cov())*252
port_variance = (weights.T).dot(cov_matrix.dot(weights))
port_standard_deviation = np.sqrt(port_variance)
#Calculate Sharpe Ratio
sharpe_ratio = ((portfolio_mean_return- RiskFreeRate)/port_standard_deviation)
if save_simulatios:
portfolio_risk_return.append([portfolio_mean_return,port_standard_deviation,sharpe_ratio])
if sharpe_ratio>portfolio_metrics['portfolio_sharpe_ratio']:
portfolio_metrics.update({'portfolio_returns':portfolio_mean_return})
portfolio_metrics.update({'portfolio_risk':port_standard_deviation})
portfolio_metrics.update({'portfolio_sharpe_ratio':sharpe_ratio})
portfolio_metrics.update({'portfolio_weights':weights})
portfolio_metrics.update({'portfolio_risk_return':portfolio_risk_return})
return portfolio_metrics
class graphs():
def risk_retun(RiskReturn_asset):
fig, ax = plt.subplots()
ax.yaxis.set_major_formatter(FuncFormatter('{0:.0%}'.format))
ax.xaxis.set_major_formatter(FuncFormatter('{0:.0%}'.format))
RiskReturn_asset.plot(x ='Risk', y='Return', kind = 'scatter',ax=ax,title='Return/Risk by asset',alpha=0.5)
for k, v in RiskReturn_asset.iterrows():
ax.annotate(k, v)
plt.grid()
plt.show()
def portfolio_simulation(data):
data_grafico=data['portfolio_risk_return']
returns = [item[0] for item in data_grafico]
risk = [item[1] for item in data_grafico]
sharpe_ratio = [item[2] for item in data_grafico]
plt.scatter(risk, returns, c=sharpe_ratio)
plt.colorbar(label='Sharpe Ratio')
plt.xlabel('Volatility')
plt.ylabel('Returns')
plt.scatter(data['portfolio_risk'], data['portfolio_returns'],c='red', s=50)
plt.show()