import numpy as np
import pandas as pd
import time
from quantopian.pipeline import Pipeline
import quantopian.pipeline.data as d
import quantopian.research as r
import quantopian.pipeline.factors as fac
import quantopian.pipeline.filters as f
import math
import alphalens as al
import matplotlib.pyplot as plt
import random
def ret(xs):
return (1+xs).prod()**(1/len(xs))-1
def ra(xs):
return (((1+xs).prod()**(1/len(xs)))**252-1)/(math.sqrt(252)*xs.std())
def unzip(xs):
return tuple([list(tup) for tup in zip(*xs)])
def sim(xs, ys):
x_a = random.random()
x_b = 1 - x_a
zs = x_b*ys + x_a*xs
mu_a = ((1+xs).prod()**(1/len(xs)))-1
mu_b = ((1+ys).prod()**(1/len(ys)))-1
sigma_a = xs.std()
sigma_b = ys.std()
nret = (x_a*ret(xs)+x_b*ret(ys))
nvol = math.sqrt(x_a**2*sigma_a**2 +x_b**2*sigma_b**2 + 2*x_a*x_b*xs.corr(ys)*sigma_a*sigma_b)
anret = (1+nret)**252-1
anvol = math.sqrt(252)*nvol
return (anret, anvol, x_a, x_b, anret/anvol)
start = '2010-01-01'
end = '2020-07-01'
aname = 'spy'
bname = 'gld'
spy = 'a'
gld = 'b'
a = r.returns(symbols(aname), start, end)
b = r.returns(symbols(bname), start, end)
ys = [ sim(a, b) for x in range(0, 100)]
y, x, _, _, _ = unzip(ys)
ax = plt.scatter(x, y)
plt.xlabel("Annualized Volatility")
plt.ylabel("Annualized Return")
df = pd.DataFrame()
df['b'] = b
df['a'] = a
df['rho'] = df['a'].rolling(252).corr(df['b'])
df['sigma_a'] = df['a'].rolling(252).std()
df['sigma_b'] = df['b'].rolling(252).std()
df['x_a'] = (df['rho']*df['sigma_a']*df['sigma_b']-df['sigma_b']**2)\
/(2*df['rho']*df['sigma_a']*df['sigma_b']-df['sigma_a']**2-df['sigma_b']**2)
df['x_b'] = 1 - df['x_a']
df['efp'] = df['x_a']*df['a']+df['x_b']*df['b']
(1+df['a'][df['a'].index > df['efp'].dropna().index[0]]).cumprod().plot(label='S&P 500').legend()
(1+df['b'][df['b'].index > df['efp'].dropna().index[0]]).cumprod().plot(label='Gold').legend()
(1+df['efp'].dropna()).cumprod().plot(label='Portfolio').legend()
df['x_a'].plot(label='S&P 500 weight').legend()
df['x_b'].plot(label='Gold weight').legend()
print("Portfolio beta", df[spy].cov(df['efp'])/df[spy].var())
print("Gold beta", df[spy].cov(df[gld])/df[spy].var())
print("S&P 500 ann vol", math.sqrt(252)*df[spy].std())
print("Gold ann vol", math.sqrt(252)*df[gld].std())
print("Portfolio ann vol", math.sqrt(252)*df['efp'].std())
print("S&P 500 ann ret", ret((1+df[spy])**252-1))
print("Gold ann ret", ret((1+df[gld])**252-1))
print("Portfolio ann ret", ret((1+df['efp'])**252-1))
print("S&P 500 Sharpe", ra(df[spy]))
print("Gold Sharpe", ra(df[gld]))
print("Portfolio Sharpe", ra(df['efp']))