From e89bf076e8c62b074ea7793bf8c8453c55189f58 Mon Sep 17 00:00:00 2001 From: wjmaddox Date: Thu, 16 Jun 2022 20:48:44 -0400 Subject: [PATCH] cleanup --- .gitignore | 2 + experiments/.DS_Store | Bin 8196 -> 0 bytes .../ForecastGenerator-checkpoint.py | 114 ------- .../GenerateMultiMeanPreds-checkpoint.py | 298 ------------------ .../LSTMGenerator-checkpoint.py | 133 -------- .../example_tickers-checkpoint.txt | 3 - .../GenerateMultiMeanPreds.cpython-38.pyc | Bin 6849 -> 0 bytes experiments/weather/.DS_Store | Bin 6148 -> 0 bytes 8 files changed, 2 insertions(+), 548 deletions(-) create mode 100644 .gitignore delete mode 100644 experiments/.DS_Store delete mode 100644 experiments/stocks/.ipynb_checkpoints/ForecastGenerator-checkpoint.py delete mode 100644 experiments/stocks/.ipynb_checkpoints/GenerateMultiMeanPreds-checkpoint.py delete mode 100644 experiments/stocks/.ipynb_checkpoints/LSTMGenerator-checkpoint.py delete mode 100644 experiments/stocks/.ipynb_checkpoints/example_tickers-checkpoint.txt delete mode 100644 experiments/stocks/__pycache__/GenerateMultiMeanPreds.cpython-38.pyc delete mode 100644 experiments/weather/.DS_Store diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1b87e13 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*/.ipynb_checkpoints/* +*/__pycache__/* diff --git a/experiments/.DS_Store b/experiments/.DS_Store deleted file mode 100644 index bcf6c890da093476a85ef9a6567f67c79eed50ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeHML2DC16n+z%W+6nZ2!?ua5A`G!;$2wVh=P|wPM&O&w23sE4QY#2DMUPZ=)t2s zs6RpQ@_PyWg-et z*`6t)`9tAxuBno(_Ly%n>JHu-{BST3U~#)0$u^H!2h5CzS&%YjPJe~ z^{rRHD=?D^@cSV|WgA&LFjl`h(C8EZb`IUT;2L>=_6eDA#EYB;ILSl@aDyaH(jICnowSLhz~=z){JH)tDu z2}ZiKOFNxbrPfH|o|s}Pzc{H@>z$+yzu@DC!)JRB-(8<}%{XcPwQsMT;#`_+s|N^ft0aaTzGzA;qrTqB@=zZelptOTlj%#sf1IMeSMm;fqT%x zuVu@7)8QPvyfq#zdEY!3@*Xq4RDL=Shkx*z`Oi}fjhCrLYjj64&MkevIyx>n_P-1{ zI&(-?Ss2M9cWIq@oW?%h2ahe>?LJiGU9h9?K2(*wsP*g9B)sIAl(!b`9vHiZ+oVz0mqDWK-6wdx82wz+jGbk4Oy)OA!Yj2jrMUC`)s99E~}u){wL gaUBB6K9RKpW6^{1&kq9p_kWnj`R~8pf-~9t26P>iVE_OC diff --git a/experiments/stocks/.ipynb_checkpoints/ForecastGenerator-checkpoint.py b/experiments/stocks/.ipynb_checkpoints/ForecastGenerator-checkpoint.py deleted file mode 100644 index add7f03..0000000 --- a/experiments/stocks/.ipynb_checkpoints/ForecastGenerator-checkpoint.py +++ /dev/null @@ -1,114 +0,0 @@ -import numpy as np -import torch -import pandas as pd -import gpytorch -import argparse -import datetime -import warnings - -from voltron.data import make_ticker_list, GetStockHistory -import sys -from GenerateMultiMeanPreds import GenerateStockPredictions, GenerateBasicPredictions -from gpytorch.utils.warnings import NumericalWarning -warnings.simplefilter("ignore", NumericalWarning) - -def main(args): - - - ticker_file = args.ticker_fname + ".txt" - tckr_list = make_ticker_list(ticker_file) - - if args.end_date.lower() == "none": - end_date = datetime.date.today() - else: - end_date = datetime.datetime.strptime(args.end_date, "%Y-%m-%d") - - - for tckr in tckr_list: -# try: - data = GetStockHistory(tckr, history=args.ntrain + args.lookback) - if args.kernel.lower() == 'volt': - GenerateStockPredictions(tckr, data, forecast_horizon=args.forecast_horizon, - train_iters=args.train_iters, - nsample=args.nsample, mean=args.mean, - ntrain=args.ntrain, save=args.save, - ntimes=args.ntimes) - else: - GenerateBasicPredictions(tckr, data, forecast_horizon=args.forecast_horizon, - kernel_name=args.kernel, mean_name=args.mean, - k=args.k, train_iters=args.train_iters, - nsample=args.nsample, ntimes=args.ntimes, - ntrain=args.ntrain, save=args.save) - -# except: -# print("FAILED ", tckr) - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument( - "--ticker_fname", - type=str, - default='test_tickers', - ) - parser.add_argument( - "--ntrain", - type=int, - default=400, - ) - parser.add_argument( - "--ntimes", - type=int, - default=25, - ) - parser.add_argument( - "--forecast_horizon", - type=int, - default=100, - ) - parser.add_argument( - '--kernel', - type=str, - default="volt", - ) - parser.add_argument( - '--mean', - type=str, - default="ewma", - ) - parser.add_argument( - "--nsample", - type=int, - default=1000, - ) - parser.add_argument( - "--printing", - type=bool, - default=False - ) - parser.add_argument( - "--train_iters", - type=int, - default=300, - ) - parser.add_argument( - "--end_date", - default="none", - ) - parser.add_argument( - "--lookback", - type=int, - default=500, - ) - parser.add_argument( - "--save", - type=bool, - default=True, - ) - parser.add_argument( - "--k", - type=int, - default=100, - ) - args = parser.parse_args() - - main(args) \ No newline at end of file diff --git a/experiments/stocks/.ipynb_checkpoints/GenerateMultiMeanPreds-checkpoint.py b/experiments/stocks/.ipynb_checkpoints/GenerateMultiMeanPreds-checkpoint.py deleted file mode 100644 index 0c82708..0000000 --- a/experiments/stocks/.ipynb_checkpoints/GenerateMultiMeanPreds-checkpoint.py +++ /dev/null @@ -1,298 +0,0 @@ -import matplotlib.pyplot as plt -import seaborn as sns -import numpy as np -import torch -import pandas as pd -import os -import gpytorch -import argparse -import datetime - -from botorch.models import SingleTaskGP -from botorch.optim.fit import fit_gpytorch_torch -from gpytorch.likelihoods import GaussianLikelihood -from gpytorch.mlls import ExactMarginalLogLikelihood -from gpytorch.means import ConstantMean, LinearMean -from gpytorch.kernels import SpectralMixtureKernel, MaternKernel, RBFKernel, ScaleKernel -from voltron.means import EWMAMean, DEWMAMean, TEWMAMean -from voltron.train_utils import LearnGPCV, TrainVolModel, TrainVoltMagpieModel, TrainBasicModel -from voltron.models import VoltMagpie -from voltron.means import LogLinearMean - -from voltron.rollout_utils import GeneratePrediction, Rollouts -from voltron.data import make_ticker_list, DataGetter, GetStockHistory - - -def GenerateGPCVPredictions(ticker, dat, - forecast_horizon=20, ntimes=25, - train_iters=400, nsample=1000, - ntrain=400): - - end_idxs = torch.arange(ntrain, dat.shape[0], - int((dat.shape[0]-ntrain)/ntimes)) - ntest = forecast_horizon - dt = 1./252 - - savepath = "./saved-outputs/" + ticker + "/" - if not os.path.exists(savepath): - os.mkdir(savepath) - for last_day in end_idxs: - date = str(dat.index[last_day.item()].date()) - print(date, ticker) - train_y = torch.FloatTensor(dat.Close[last_day.item()-ntrain:last_day.item()].to_numpy()) - train_x = torch.arange(train_y.shape[0]-1) * dt - test_x = torch.arange(ntest) * dt + train_x[-1] + train_x[1] -# try: - use_cuda = torch.cuda.is_available() - if use_cuda: - train_x = train_x.cuda() - test_x = test_x.cuda() - train_y = train_y.cuda() - - model, likelihood = LearnGPCV(train_x, train_y, - train_iters=train_iters, printing=False, return_model=True) - preds = likelihood(model(test_x), - return_gaussian=False).sample(torch.Size((nsample,))) - preds = preds.cumsum(-1).squeeze() - preds = preds.view(-1, preds.shape[-1]) - save_samples = preds.view(-1, preds.shape[-1]) * (dt ** 0.5) + train_y[-1].log() - torch.save(save_samples, savepath + "gpcv_" + date + ".pt") - - return - -def GenerateStockPredictions(ticker, dat, - forecast_horizon=20, - train_iters=400, nsample=1000, - ntrain=400, mean='ewma', kernel='volt', - save=False, k=300, ntimes=-1): - - if ntimes == -1: - end_idxs = torch.arange(ntrain, dat.shape[0]) - else: - end_idxs = torch.arange(ntrain, dat.shape[0], - int((dat.shape[0]-ntrain)/ntimes)) - ntest = forecast_horizon - dt = 1./252 - - model_name = kernel + "_" + mean + str(k) + "_" - par_dir = "./saved-outputs/" - if not os.path.exists(par_dir): - os.mkdir(par_dir) - savepath = par_dir + ticker + "/" - if not os.path.exists(savepath): - os.mkdir(savepath) - - for last_day in end_idxs: - date = str(dat.index[last_day.item()].date()) -# try: - train_y = torch.FloatTensor(dat.Close[last_day.item()-ntrain:last_day.item()].to_numpy()) - train_x = torch.arange(train_y.shape[0]-1) * dt - test_x = torch.arange(ntest) * dt + train_x[-1] + train_x[1] -# try: - use_cuda = torch.cuda.is_available() - if use_cuda: - train_x = train_x.cuda() - test_x = test_x.cuda() - train_y = train_y.cuda() - -# print("Producing " + ticker + " Forecasts.....") - if kernel == "volt": - vol = LearnGPCV(train_x, train_y, train_iters=train_iters, - printing=False) - vmod, vlh = TrainVolModel(train_x, vol, - train_iters=train_iters, printing=False) - voltron, lh = TrainVoltMagpieModel(train_x, train_y[1:], - vmod, vlh, vol, - printing=False, - train_iters=train_iters, - k=k, mean_func=mean) - vmod.eval(); - if mean in ['ewma', 'dewma', 'tewma']: - save_samples = Rollouts(train_x, train_y, test_x, voltron, - nsample=nsample) - - else: ## VOLT + STANDARD MEAN - voltron.vol_model.eval() - predvol = voltron.vol_model(test_x).sample(torch.Size((nsample, ))).exp() - save_samples = GeneratePrediction(train_x, train_y, test_x, - predvol, voltron).detach() - del predvol - - del voltron, lh, vmod, vlh, vol - torch.cuda.empty_cache() - - if save: - if not os.path.exists(savepath): - os.mkdir(savepath) - - torch.save(save_samples, savepath + model_name + date + ".pt") -# except: -# nans = torch.ones(nsample, ntest) * torch.nan -# if save: -# if not os.path.exists(savepath): -# os.mkdir(savepath) -# torch.save(nans, savepath + model_name + date + ".pt") - - - return dat, save_samples - - - -def GenerateOneDayPredictions(ticker, train_y, date, - forecast_horizon=20, - train_iters=400, nsample=1000, - ntrain=400, save=False, mean=None): - - ntest = forecast_horizon - dt = 1./252 - par_dir = "./saved-outputs/" - if not os.path.exists(par_dir): - os.mkdir(par_dir) - savepath = par_dir + ticker + "/" - if not os.path.exists(savepath): - os.mkdir(savepath) - - train_x = torch.arange(train_y.shape[0]-1) * dt - test_x = torch.arange(ntest) * dt + train_x[-1] + train_x[1] - use_cuda = torch.cuda.is_available() - if use_cuda: - train_x = train_x.cuda() - test_x = test_x.cuda() - train_y = train_y.cuda() - - vol = LearnGPCV(train_x, train_y, train_iters=train_iters, - printing=False) - vmod, vlh = TrainVolModel(train_x, vol, - train_iters=train_iters, printing=False) - - if mean=='constant': - voltron, lh = TrainVoltMagpieModel(train_x, train_y[1:], - vmod, vlh, vol, - printing=False, - train_iters=200, - mean_func='constant') - vmod.eval(); - voltron.eval(); - save_samples = Rollouts(train_x, train_y, test_x, voltron, - nsample=nsample) - - if save: - model_name = "volt_" + mean + "_" - torch.save(save_samples, savepath + model_name + date + ".pt") - else: - for mean in ['ewma', 'dewma', 'tewma']: - for k in [25, 50, 100, 200, 300, 400]: - try: - voltron, lh = TrainVoltMagpieModel(train_x, train_y[1:], - vmod, vlh, vol, - printing=False, - train_iters=0, - k=k, mean_func=mean) - vmod.eval(); - voltron.eval(); - save_samples = Rollouts(train_x, train_y, test_x, voltron, - nsample=nsample) - except: - print("Failed: ", ticker, mean, k) - if save: - save_samples = torch.ones(nsample, ntest) * torch.nan - - if save: - model_name = "volt_" + mean + str(k) + "_" - torch.save(save_samples, savepath + model_name + date + ".pt") - - del voltron, lh, vmod, vlh, vol, save_samples - torch.cuda.empty_cache() - return - - - -def GenerateBasicPredictions(ticker, dat, kernel_name, mean_name='ewma', k=400, - forecast_horizon=100, - train_iters=600, nsample=1000, - ntrain=400, save=False, ntimes=-1): - - if ntimes == -1: - end_idxs = torch.arange(ntrain, dat.shape[0]) - else: - end_idxs = torch.arange(ntrain, dat.shape[0], - int((dat.shape[0]-ntrain)/ntimes)) - ntest = forecast_horizon - dt = 1./252 - par_dir = "./saved-outputs/" - if not os.path.exists(par_dir): - os.mkdir(par_dir) - savepath = par_dir + ticker + "/" - if not os.path.exists(savepath): - os.mkdir(savepath) - - for last_day in end_idxs: - date = str(dat.index[last_day.item()].date()) - train_y = torch.FloatTensor(dat.Close[last_day.item()-ntrain:last_day.item()].to_numpy()) - train_x = torch.arange(train_y.shape[0]-1) * dt - test_x = torch.arange(ntest) * dt + train_x[-1] + train_x[1] -# try: - use_cuda = torch.cuda.is_available() - if use_cuda: - train_x = train_x.cuda() - test_x = test_x.cuda() - train_y = train_y.cuda() - -# print("Producing " + ticker + " Forecasts.....") - kernel_possibilities = {"sm": SpectralMixtureKernel, - "matern": MaternKernel, - "rbf": RBFKernel} - kernel = kernel_possibilities[kernel_name.lower()] - if kernel_name.lower() != 'sm': - kernel = ScaleKernel(kernel()) - else: - kernel = kernel(num_mixtures=15) - kernel.initialize_from_data_empspect(train_x, train_y.log()) - - train_y = train_y[1:] - - model = SingleTaskGP( - train_x.view(-1,1), - train_y.log().reshape(-1, 1), - covar_module=kernel, - likelihood=GaussianLikelihood() - ) - - mean_name = mean_name.lower() - if mean_name == "loglinear": - model.mean_module = LogLinearMean(1) - model.mean_module.initialize_from_data(train_x, train_y.log()) - elif mean_name == 'linear': - model.mean_module = LinearMean(1) - elif mean_name == "constant": - model.mean_module = ConstantMean() - elif mean_name == "ewma": - model.mean_module = EWMAMean(train_x, train_y.log(), k=k).to(train_x.device) - elif mean_name == "dewma": - model.mean_module = DEWMAMean(train_x, train_y.log(), k=k).to(train_x.device) - elif mean_name == "tewma": - model.mean_module = TEWMAMean(train_x, train_y.log(), k=k).to(train_x.device) - - if use_cuda: - model = model.to(train_x.device) - print("Fitting Model", ticker) - mll = ExactMarginalLogLikelihood(model.likelihood, model) - fit_gpytorch_torch(mll, options={'maxiter':train_iters, 'disp':False}) - - if mean_name in ["loglinear", "constant", 'linear']: - save_samples = model.posterior(test_x).sample(torch.Size((nsample, - ))).squeeze(-1).cpu().detach() - else: - save_samples = Rollouts( - train_x, train_y, test_x, model, nsample=nsample, method = "nonvol" - ).cpu().detach() - - model_name = kernel_name + "_" + mean_name + str(k) + "_" - torch.save(save_samples, savepath + model_name + date + ".pt") - - model.train() - torch.cuda.empty_cache() - del model - - - return dat, save_samples \ No newline at end of file diff --git a/experiments/stocks/.ipynb_checkpoints/LSTMGenerator-checkpoint.py b/experiments/stocks/.ipynb_checkpoints/LSTMGenerator-checkpoint.py deleted file mode 100644 index 7d7c05d..0000000 --- a/experiments/stocks/.ipynb_checkpoints/LSTMGenerator-checkpoint.py +++ /dev/null @@ -1,133 +0,0 @@ -import numpy as np -import torch -import pandas as pd -import gpytorch -import argparse -import datetime -import warnings -import os -from voltron.data import make_ticker_list, GetStockHistory -from LSTMUtils import SequenceDataset, LSTM, TrainLSTM, LSTMRollouts, NLL -from torch.utils.data import DataLoader - -def main(args): - - data_path = "../../voltron/data/" - ticker_file = args.ticker_fname + ".txt" - tckr_list = make_ticker_list(data_path + ticker_file) -# tckr_list = ['TSLA'] - - use_cuda = False - if torch.cuda.is_available(): - use_cuda = True - - ntest = args.forecast_horizon - ntrain = args.ntrain - seq_len = args.seq_length - - if args.end_date.lower() == "none": - end_date = datetime.date.today() - else: - end_date = datetime.datetime.strptime(args.end_date, "%Y-%m-%d") - - - for tckr in tckr_list: - try: - data = GetStockHistory(tckr, history= ntrain + args.lookback) - end_idxs = torch.arange(args.ntrain, data.shape[0], - int((data.shape[0]-args.ntrain)/args.ntimes)) - - savepath = "./saved-outputs/" + tckr + "/" - if not os.path.exists(savepath): - os.mkdir(savepath) - - for last_day in end_idxs: - date = str(data.index[last_day.item()].date()) - raw_y = data.Close[last_day.item()-ntrain:last_day.item()].to_numpy() - raw_y = torch.FloatTensor(raw_y).log() - train_y = (raw_y - raw_y.mean())/raw_y.std() - - ## make trainloader ## - dset = SequenceDataset(train_y, seq_len) - trainloader = DataLoader(dset, batch_size=args.batch_size, shuffle=True) - - model = LSTM(2, seq_len, 128, 1) - if use_cuda: - model = model.cuda() - optimizer = torch.optim.Adam(model.parameters(), lr=0.01) - TrainLSTM(trainloader, model, NLL, optimizer, epochs=args.train_epochs, - printing=True, use_cuda=use_cuda) - - rollouts = LSTMRollouts(model, args.nsample, ntest, - dset, use_cuda).cpu() - rollouts = rollouts * raw_y.std() + raw_y.mean() - torch.save(rollouts, savepath + "lstm_" + date + ".pt") - - del model - except: - print("FAILED ", tckr) - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument( - "--ntimes", - type=int, - default=25, - ) - parser.add_argument( - "--forecast_horizon", - type=int, - default=20, - ) - parser.add_argument( - "--seq_length", - type=int, - default=25, - ) - parser.add_argument( - "--ticker_fname", - type=str, - default='test_tickers', - ) - parser.add_argument( - "--ntrain", - type=int, - default=400, - ) - parser.add_argument( - "--batch_size", - type=int, - default=128, - ) - parser.add_argument( - "--nsample", - type=int, - default=1000, - ) - parser.add_argument( - "--printing", - type=bool, - default=False - ) - parser.add_argument( - "--train_epochs", - type=int, - default=200, - ) - parser.add_argument( - "--end_date", - default="none", - ) - parser.add_argument( - "--lookback", - type=int, - default=500, - ) - parser.add_argument( - "--save", - type=bool, - default=False, - ) - args = parser.parse_args() - - main(args) \ No newline at end of file diff --git a/experiments/stocks/.ipynb_checkpoints/example_tickers-checkpoint.txt b/experiments/stocks/.ipynb_checkpoints/example_tickers-checkpoint.txt deleted file mode 100644 index 23907e6..0000000 --- a/experiments/stocks/.ipynb_checkpoints/example_tickers-checkpoint.txt +++ /dev/null @@ -1,3 +0,0 @@ -AAPL -MSFT -GOOG \ No newline at end of file diff --git a/experiments/stocks/__pycache__/GenerateMultiMeanPreds.cpython-38.pyc b/experiments/stocks/__pycache__/GenerateMultiMeanPreds.cpython-38.pyc deleted file mode 100644 index 19b6b56cf27a6a4e54098ad88fbb47d837cde219..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6849 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 ClY_qi diff --git a/experiments/weather/.DS_Store b/experiments/weather/.DS_Store deleted file mode 100644 index effe4476c5b9de3c8319b8e63f43c2fbcbd295c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK!AiqG5Pe&Fs1&hy@|Yh`=*?qVqTs<(&th#OR&1L7)6;6I25{SAM>li=U@ zW_D>Cs-=jC$PCQ9&FswX&P&+M0&wkV+5{Q^YE;3>Ce0@z{h~`!2_ETmI>s11oS}~a zE|#Lr@fR78cejImTp`CD7T;eV*YsuV8RG_%;bpVa&qlcxaeQ*RZr&(MlHM@uF}_xR zdN@emUs~(urr*xZ2aD^ymt}8Zf^*#R+f1>?%BHLo+k5i~(cdrx=i3j#8_8G;0hP1IECN0oflSs$d+j@Tgk{ja~tW zRk~H!mb--HL;>S~g-7;KoKGeCR2Qxo&ZpBKg}69i;nAnV>C7A_%TH;wGp*T6_L2Y<1B>@ hJ&GACNAWIIh5kqy#5iE#ksgZu2q+C^jDcTe-~+x