Skip to content

Instantly share code, notes, and snippets.

@chrism2671
Created May 24, 2016 07:20
Show Gist options
  • Save chrism2671/256ec51515b6849dd695f15fb28caecf to your computer and use it in GitHub Desktop.
Save chrism2671/256ec51515b6849dd695f15fb28caecf to your computer and use it in GitHub Desktop.
import numpy as np
import pandas as pd
from concurrent.futures import ProcessPoolExecutor
from functools import partial
from scipy.optimize import minimize
from accountcurve import *
def optimize_weights(forecasts, prices):
guess = [1/forecasts.shape[1]] * forecasts.shape[1]
bounds = [(0.0,1.0)] * forecasts.shape[1]
cons = ({'type': 'eq', 'fun': lambda x: 1 - sum(x)})
def function(w, forecasts, prices):
wf = (w*forecasts).mean(axis=1)
wf = wf*10/wf.std()
wf = wf.clip(-20,20)
l = accountCurve(wf, prices)
return -l.sharpe()
result = minimize(function, guess, (forecasts, prices), bounds=bounds, method='SLSQP', constraints=cons, tol=0.00001, options={'disp': False ,'eps' : 1e0})
return result.x
def mp_optimize_weights(samples, prices):
with ProcessPoolExecutor() as executor:
return executor.map(partial(optimize_weights, prices=prices), samples)
def bootstrap(prices, forecasts, parallel_process=True):
forecasts.dropna(inplace=True)
prices = prices[forecasts.index]
years = list(set(prices.index.year))
years.sort()
result={}
for year in years:
sample_length = np.int(prices[:str(year)].size/10)
end_of_sample_selection_space = prices[:str(year)].tail(1).index[0] - pd.Timedelta(days=sample_length)
sample_dates = np.random.choice(prices[:end_of_sample_selection_space].index,200)
if(sample_length > 50):
samples = [forecasts.loc[date:date+pd.Timedelta(days=sample_length)] for date in sample_dates]
if parallel_process is True:
weights = pd.DataFrame(list(mp_optimize_weights(samples, prices[:str(year)])))
else:
weights = pd.DataFrame(list(map(partial(optimize_weights, prices=prices[:str(year)]), samples)))
result[year]=weights.mean()
print(year, sample_length)
output = pd.DataFrame.from_dict(result).transpose()
output.columns = forecasts.columns
return output
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment