Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
altcoins = ['BTC','ETH','XRP','DASH','XMR','LTC','ZEC','EOS','STR']
altcoin_data = {}
for altcoin in altcoins:
coinpair = 'USDT_{}'.format(altcoin)
crypto_price_df = get_crypto_data(coinpair)
altcoin_data[altcoin] = crypto_price_df
df = merge_dfs_on_column(list(altcoin_data.values()), list(altcoin_data.keys()), 'close')
dateRange = pd.date_range('2018-6-1', periods=365, freq='D')
df = df.loc[dateRange]
fig= plt.figure(figsize=(10,6))
plt.plot(df)
plt.legend(df)
altcoin_Wout_BTC = ['ETH','XRP','DASH','XMR','LTC','ZEC','EOS','STR']
df2 = merge_dfs_on_column(list(altcoin_data.values())[1:len(altcoins)], altcoin_Wout_BTC, 'close')
df2 = df2.loc[dateRange]
fig= plt.figure(figsize=(10,6))
plt.plot(df2)
plt.legend(df2)
m = Model("portfolio")
m.setParam('OutputFlag', 0)
x = [m.addVar(name=symb) for symb in altcoins]
m.setObjective(sum(Corr[i][j]*x[i]*x[j] for i in range(len(altcoins)) for j in range(len(altcoins))), GRB.MINIMIZE)
m.addConstr(sum(x[i] for i in range(len(altcoins))) ==1)
trace = go.Heatmap(z=df.corr().values.tolist(), x=altcoins, y=altcoins)
data=[trace]
py.iplot(data)
import os
import numpy as np
from numpy import linalg as la
import pandas as pd
import pickle
from datetime import datetime
import plotly.offline as py
import plotly.graph_objs as go
py.init_notebook_mode(connected=True)
import matplotlib.pyplot as plt
from gurobipy import GRB,Model
def get_json_data(json_url, cache_path):
'''Download and cache JSON data, return as a dataframe.'''
try:
f = open(cache_path, 'rb')
df = pickle.load(f)
print('Loaded {} from cache'.format(json_url))
except (OSError, IOError) as e:
print('Downloading {}'.format(json_url))
df = pd.read_json(json_url)
df.to_pickle(cache_path)
print('Cached {} at {}'.format(json_url, cache_path))
return df
def get_crypto_data(poloniex_pair):
'''Retrieve cryptocurrency data from poloniex'''
json_url = base_polo_url.format(poloniex_pair, start_date.timestamp(), end_date.timestamp(), period)
data_df = get_json_data(json_url, poloniex_pair)
data_df = data_df.set_index('date')
return data_df
def merge_dfs_on_column(dataframes, labels, col):
'''Merge a single column of each dataframe into a new combined dataframe'''
series_dict = {}
for index in range(len(dataframes)):
series_dict[labels[index]] = dataframes[index][col]
return pd.DataFrame(series_dict)
def nearestPD(A):
"""Find the nearest positive-definite matrix to input
N.J. Higham, "Computing a nearest symmetric positive semidefinite
matrix" (1988): https://doi.org/10.1016/0024-3795(88)90223-6
"""
B = (A + A.T) / 2
_, s, V = la.svd(B)
H = np.dot(V.T, np.dot(np.diag(s), V))
A2 = (B + H) / 2
A3 = (A2 + A2.T) / 2
if isPD(A3):
return A3
spacing = np.spacing(la.norm(A))
I = np.eye(A.shape[0])
k = 1
while not isPD(A3):
mineig = np.min(np.real(la.eigvals(A3)))
A3 += I * (-mineig * k**2 + spacing)
k += 1
return A3
def isPD(B):
"""Returns true when input is positive-definite, via Cholesky"""
try:
_ = la.cholesky(B)
return True
except la.LinAlgError:
return False
if __name__ == '__main__':
import numpy as np
for i in range(10):
for j in range(2, 100):
A = np.random.randn(j, j)
B = nearestPD(A)
assert(isPD(B))
print('unit test passed!')
# Compute trade-off curve.
MinTarget = [i for i in range(500,5000,100)]
risk_data = np.zeros(len(MinTarget))
ret_data = np.zeros(len(MinTarget))
for j in range(len(MinTarget)):
m.addConstr(sum(x[i]*Mu[i] for i in range(len(altcoins))) >= MinTarget[j],'BudgetConstr')
m.optimize()
Invest = m.getAttr('x',x)
Risk = m.objVal
m.remove(m.getConstrByName('BudgetConstr'))
m.update()
risk_data[j] = np.sqrt(Risk)
ret_data[j] = df.mean().T.dot(Invest)
# or --> sum(Mu[i]*Invest[i] for i in range(len(altcoins)))
# Plot long only trade-off curve.
trace = go.Scatter(
x = risk_data,
y = ret_data,
mode = 'lines+markers+text',
text=[i+1 for i in range(len(MinTarget))],
textposition='bottom center'
)
data = [trace]
layout = go.Layout(
title='Risk Analysis of Portfolio',
xaxis=dict(
title='STD(Risk)'
),
yaxis=dict(
title='Return'
)
)
fig = go.Figure(data=data, layout=layout)
py.iplot(fig)
base_polo_url = 'https://poloniex.com/public?command=returnChartData&currencyPair={}&start={}&end={}&period={}'
start_date = datetime.strptime('2018-01-01', '%Y-%m-%d') # get data from the start of 2015
end_date = datetime.now() # up until today
period = 86400 # pull daily data (86,400 seconds per day)
def stacked_bar(data, series_labels, category_labels=None,
show_values=False, value_format="{}", y_label=None,
grid=True, reverse=False):
"""Plots a stacked bar chart with the data and labels provided.
Keyword arguments:
data -- 2-dimensional numpy array or nested list
containing data for each series in rows
series_labels -- list of series labels (these appear in
the legend)
category_labels -- list of category labels (these appear
on the x-axis)
show_values -- If True then numeric value labels will
be shown on each bar
value_format -- Format string for numeric value labels
(default is "{}")
y_label -- Label for y-axis (str)
grid -- If True display grid
reverse -- If True reverse the order that the
series are displayed (left-to-right
or right-to-left)
"""
ny = len(data[0])
ind = list(range(ny))
axes = []
cum_size = np.zeros(ny)
data = np.array(data)
if reverse:
data = np.flip(data, axis=1)
category_labels = reversed(category_labels)
for i, row_data in enumerate(data):
axes.append(plt.bar(ind, row_data, bottom=cum_size,
label=series_labels[i]))
cum_size += row_data
if category_labels:
plt.xticks(ind, category_labels)
if y_label:
plt.ylabel(y_label)
plt.legend()
if grid:
plt.grid()
plt.figure(figsize=(10, 6))
series_labels = altcoins
data = Invest_mat.T
# category_labels = [i+1 for i in range(len(MinTarget))]
stacked_bar(
data,
series_labels,
# category_labels=category_labels,
show_values=True,
value_format="{:.1f}",
y_label="Quantity (units)"
)
# plt.savefig('bar.png')
plt.show()
Mu = df.mean().values.tolist()
Corr = nearestPD(df.cov()).values.tolist()
m.addConstr(x[0]+x[2]<=.9)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.