mirror of
https://github.com/wassname/Volt.git
synced 2026-09-09 11:16:09 +08:00
first commit
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -0,0 +1,27 @@
|
||||
# Volt
|
||||
Public Implementation of
|
||||
*Volatility Based Kernels and Moving Average Means for Accurate Forecasting with Gaussian Processes* [link]
|
||||
|
||||
by [Gregory Benton](https://g-benton.github.io/), [Wesley Maddox](https://wjmaddox.github.io), and [Andrew Gordon Wilson](https://cims.nyu.edu/~andrewgw/).
|
||||
|
||||
Please cite our work if you find it useful:
|
||||
|
||||
```
|
||||
@inproceedings{benton2022volatility,
|
||||
title={olatility Based Kernels and Moving Average Means for Accurate Forecasting with Gaussian Processes},
|
||||
author={Benton, Gregory and Maddox, Wesley and Wilson, Andrew Gordon Gordon},
|
||||
booktitle={International Conference on Machine Learning},
|
||||
year={2022},
|
||||
organization={PMLR}
|
||||
}
|
||||
```
|
||||
|
||||

|
||||
|
||||
## Explanatory Notebook
|
||||
|
||||
To see an overview of how to use Volt with synthetically generated code, see the `Example` notebook which walks through how the code is organized step by step.
|
||||
|
||||
## Experiments
|
||||
|
||||
The two core experimental settings from the paper involve modeling historical wind speeds and stock prices. The code to run these experiments with example commands is in the `experiments` folder.
|
||||
@@ -0,0 +1,26 @@
|
||||
from setuptools import setup
|
||||
import os
|
||||
import sys
|
||||
|
||||
setup(
|
||||
name='voltron',
|
||||
version='alpha',
|
||||
description=('Voltron Repo'),
|
||||
author='Greg Benton',
|
||||
author_email='greg.w.benton@gmail.com',
|
||||
url='https://github.com/g-benton/voltron',
|
||||
license='Apache-2.0',
|
||||
packages=['voltron'],
|
||||
install_requires=[
|
||||
'matplotlib>=3.0.3',
|
||||
'setuptools>=41.0.0',
|
||||
'torch>=1.11.0',
|
||||
'numpy>=1.16.2',
|
||||
'gpytorch>=1.0.1',
|
||||
],
|
||||
include_package_data=True,
|
||||
classifiers=[
|
||||
'Development Status :: 0',
|
||||
'Intended Audience :: Science/Research',
|
||||
'Programming Language :: Python :: 3.7'],
|
||||
)
|
||||
+460
File diff suppressed because one or more lines are too long
@@ -1,2 +1,27 @@
|
||||
# Volt
|
||||
Public Implementation of Volatility Based Kernels and Moving Average Means for Accurate Forecasting with Gaussian Processes
|
||||
Public Implementation of
|
||||
*Volatility Based Kernels and Moving Average Means for Accurate Forecasting with Gaussian Processes* [link]
|
||||
|
||||
by [Gregory Benton](https://g-benton.github.io/), [Wesley Maddox](https://wjmaddox.github.io), and [Andrew Gordon Wilson](https://cims.nyu.edu/~andrewgw/).
|
||||
|
||||
Please cite our work if you find it useful:
|
||||
|
||||
```
|
||||
@inproceedings{benton2022volatility,
|
||||
title={olatility Based Kernels and Moving Average Means for Accurate Forecasting with Gaussian Processes},
|
||||
author={Benton, Gregory and Maddox, Wesley and Wilson, Andrew Gordon Gordon},
|
||||
booktitle={International Conference on Machine Learning},
|
||||
year={2022},
|
||||
organization={PMLR}
|
||||
}
|
||||
```
|
||||
|
||||

|
||||
|
||||
## Explanatory Notebook
|
||||
|
||||
To see an overview of how to use Volt with synthetically generated code, see the `Example` notebook which walks through how the code is organized step by step.
|
||||
|
||||
## Experiments
|
||||
|
||||
The two core experimental settings from the paper involve modeling historical wind speeds and stock prices. The code to run these experiments with example commands is in the `experiments` folder.
|
||||
@@ -1,637 +0,0 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "0d67e226",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import numpy as np\n",
|
||||
"import seaborn as sns\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"from matplotlib.lines import Line2D\n",
|
||||
"from matplotlib.patches import Patch\n",
|
||||
"import torch\n",
|
||||
"import pandas as pd\n",
|
||||
"import copy\n",
|
||||
"from voltron.option_utils import GetTradingDays, GetTrainingData, Pricer, FindLastTradingDays\n",
|
||||
"from scipy.optimize import minimize"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "8ad5b4c2",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"/Users/gregorybenton/miniconda3/lib/python3.8/site-packages/IPython/core/interactiveshell.py:3169: DtypeWarning: Columns (19) have mixed types.Specify dtype option on import or set low_memory=False.\n",
|
||||
" has_raised = await self.run_ast_nodes(code_ast.body, cell_name,\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"SPY = pd.read_csv(\"./data/SPY_prices.csv\")\n",
|
||||
"SPY['Date'] = pd.to_datetime(SPY['Date'])\n",
|
||||
"\n",
|
||||
"years = np.arange(2009, 2018)\n",
|
||||
"opts = pd.DataFrame()\n",
|
||||
"for year in years:\n",
|
||||
" dat = pd.read_csv(\"./data/SPY_\" + str(year) + \".csv\")\n",
|
||||
" dat = dat[dat.type == \"call\"]\n",
|
||||
" quotedate = dat.quotedate.unique()[0]\n",
|
||||
" dat = dat[dat.quotedate == quotedate] \n",
|
||||
" opts = pd.concat((opts, dat), ignore_index=True)\n",
|
||||
"\n",
|
||||
"# exps = [] \n",
|
||||
"# for idx, row in opts.iterrows():\n",
|
||||
"# eday = row.expiration\n",
|
||||
"# exps.append(SPY[SPY.Date == FindLastTradingDays(SPY, [pd.Timestamp(eday)])[0]].Close.item())\n",
|
||||
"# opts['exp_price'] = exps"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "f361417a",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Torch Attempt"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "06969ba7",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"ivol = torch.tensor(opts.impliedvol.to_numpy())\n",
|
||||
"Fs = torch.tensor(opts.underlying_last.to_numpy())\n",
|
||||
"Ks = torch.tensor(opts.strike.to_numpy())\n",
|
||||
"qdays = pd.to_datetime(opts.quotedate).dt.date.to_numpy()\n",
|
||||
"edays = pd.to_datetime(opts.expiration).dt.date.to_numpy()\n",
|
||||
"Ts = torch.tensor(([np.busday_count(qd, ed)/252. for qd, ed in zip(qdays, edays)]))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "465286fb",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def BlackVol(pars, K, f, T):\n",
|
||||
" alpha = torch.exp(pars[0][0])\n",
|
||||
" rho = 2 * torch.sigmoid(pars[0][1]) - 1.\n",
|
||||
" v = torch.exp(pars[0][2])\n",
|
||||
" beta = 1.\n",
|
||||
" num = 1 + (alpha**2 * (1-beta)**2/(24 * (f*K)**(1-beta)) + 0.25 * rho*beta*v*alpha/((f*K)**(0.5*(1-beta))) + v**2*(2-3*rho**2)/24)*T\n",
|
||||
" num*= alpha\n",
|
||||
" \n",
|
||||
" denom = (f*K)**(0.5*(1-beta)) * (1 + (1-beta)**2/24 * torch.log(f/K)**2 + (1-beta)**4/1920 * torch.log(f/K)**4)\n",
|
||||
" \n",
|
||||
" z = v/alpha * (f*K)**(0.5*(1-beta)) * np.log(f/K)\n",
|
||||
" xi_z = torch.log((torch.sqrt(1 - 2 * rho * z + z**2) + z - rho)/(1-rho))\n",
|
||||
" \n",
|
||||
" return num/denom * z/xi_z"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "1ebbc187",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def MinVol(pars):\n",
|
||||
" return torch.mean((ivol - BlackVol(pars, Ks, Fs, Ts)).pow(2))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "57bc7a65",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"pars = [torch.tensor([-1., -5., -3.], requires_grad=True)]\n",
|
||||
"opt = torch.optim.SGD(pars, lr=0.1)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"id": "ab9c2a60",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"iters = 1000\n",
|
||||
"stored_pars = torch.zeros(iters, 3)\n",
|
||||
"losses = []\n",
|
||||
"for e in range(iters):\n",
|
||||
" stored_pars[e, :] = pars[0]\n",
|
||||
" loss = MinVol(pars)\n",
|
||||
" opt.zero_grad()\n",
|
||||
" loss.backward()\n",
|
||||
" losses.append(loss.item())\n",
|
||||
" opt.step() "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"id": "6f6aeab5",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"[<matplotlib.lines.Line2D at 0x7fc4a7df89d0>,\n",
|
||||
" <matplotlib.lines.Line2D at 0x7fc4a7df8a00>,\n",
|
||||
" <matplotlib.lines.Line2D at 0x7fc4a7df8b80>]"
|
||||
]
|
||||
},
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"plt.plot(stored_pars.detach())"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"id": "271add47",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"[<matplotlib.lines.Line2D at 0x7fc4a81a7700>]"
|
||||
]
|
||||
},
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"plt.plot(losses)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "93a71a4d",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Running SABR"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"id": "0bb6a328",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import numpy as np\n",
|
||||
"import torch\n",
|
||||
"import pandas as pd\n",
|
||||
"import copy\n",
|
||||
"from voltron.option_utils import GetTradingDays, GetTrainingData, Pricer, FindLastTradingDays\n",
|
||||
"from scipy.optimize import minimize\n",
|
||||
"\n",
|
||||
"def BlackVol(pars, K, f, T):\n",
|
||||
" alpha = torch.exp(pars[0][0]) ## v0\n",
|
||||
" rho = 2 * torch.sigmoid(pars[0][1]) - 1. ##rho\n",
|
||||
" v = torch.exp(pars[0][2]) ## \"sigma\" \n",
|
||||
" beta = 1.\n",
|
||||
" num = 1 + (alpha**2 * (1-beta)**2/(24 * (f*K)**(1-beta)) +\\\n",
|
||||
" 0.25 * rho*beta*v*alpha/((f*K)**(0.5*(1-beta))) +\\\n",
|
||||
" v**2*(2-3*rho**2)/24)*T\n",
|
||||
" num*= alpha\n",
|
||||
" \n",
|
||||
" denom = (f*K)**(0.5*(1-beta)) * (1 + (1-beta)**2/24 * torch.log(f/K)**2 +\\\n",
|
||||
" (1-beta)**4/1920 * torch.log(f/K)**4)\n",
|
||||
" \n",
|
||||
" z = v/alpha * (f*K)**(0.5*(1-beta)) * np.log(f/K)\n",
|
||||
" xi_z = torch.log((torch.sqrt(1 - 2 * rho * z + z**2) + z - rho)/(1-rho))\n",
|
||||
" \n",
|
||||
" return num/denom * z/xi_z\n",
|
||||
"\n",
|
||||
"def MinVol(pars, Ks, Fs, Ts, ivol):\n",
|
||||
" return torch.mean((ivol - BlackVol(pars, Ks, Fs, Ts)).pow(2))\n",
|
||||
"\n",
|
||||
"def Calibrate(Fs, Ks, Ts, ivol, iters=1000):\n",
|
||||
" pars = [torch.tensor([-1., -5., -3.], requires_grad=True)]\n",
|
||||
" opt = torch.optim.SGD(pars, lr=0.1)\n",
|
||||
" stored_pars = torch.zeros(iters, 3)\n",
|
||||
" losses = []\n",
|
||||
" for e in range(iters):\n",
|
||||
" stored_pars[e, :] = pars[0]\n",
|
||||
" loss = MinVol(pars, Ks, Fs, Ts, ivol)\n",
|
||||
" opt.zero_grad()\n",
|
||||
" loss.backward()\n",
|
||||
" losses.append(loss.item())\n",
|
||||
" opt.step() \n",
|
||||
" \n",
|
||||
" return pars[0].detach().numpy()\n",
|
||||
"\n",
|
||||
"def SABRSim(Np, Nt, S0, V0, sigma, rho, dt=1./252.):\n",
|
||||
" dW = np.random.randn(Nt+1, Np) * np.sqrt(dt)\n",
|
||||
" dZ = rho * dW + np.sqrt(1-rho**2) * np.random.randn(Nt+1, Np) * np.sqrt(dt)\n",
|
||||
" \n",
|
||||
" S = np.zeros((Nt+1, Np))\n",
|
||||
" S[0] = S0\n",
|
||||
" V = np.zeros((Nt+1, Np))\n",
|
||||
" V[0] = V0\n",
|
||||
" \n",
|
||||
" for t in range(Nt):\n",
|
||||
" S[t+1] = S[t] + V[t]*S[t]*dW[t]\n",
|
||||
" V[t+1] = V[t] + sigma*V[t]*dZ[t]\n",
|
||||
" \n",
|
||||
" return S[1:]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"id": "67d9cf31",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"logger = []\n",
|
||||
"full_logger = []\n",
|
||||
"SPY = pd.read_csv(\"./data/SPY_prices.csv\")\n",
|
||||
"SPY['Date'] = pd.to_datetime(SPY['Date'])\n",
|
||||
"Np = 10000\n",
|
||||
"ntrain = 252\n",
|
||||
"year = 2012\n",
|
||||
"options = pd.read_csv(\"./data/SPY_\" + str(year) + \".csv\")\n",
|
||||
"options.expiration = pd.to_datetime(options.expiration)\n",
|
||||
"options.quotedate = pd.to_datetime(options.quotedate)\n",
|
||||
"qday = options.quotedate.unique()[0]\n",
|
||||
"quote_price = SPY[SPY['Date']==qday].Close.item()\n",
|
||||
"options = options[(options.quotedate == qday) & (options.type=='call')]\n",
|
||||
"edays = options.expiration.sort_values().unique()\n",
|
||||
"testdays = (edays - qday)/np.timedelta64(1, \"D\")\n",
|
||||
"edays = edays[(testdays > 100) & (testdays < 365)]\n",
|
||||
"lastdays = FindLastTradingDays(SPY, edays)\n",
|
||||
"ntests = np.array([GetTradingDays(SPY, qday, \n",
|
||||
" pd.Timestamp(ld)) for ld in lastdays])\n",
|
||||
"fulltest = ntests[-1]\n",
|
||||
"train_y = torch.FloatTensor(GetTrainingData(SPY, qday, ntrain).to_numpy())\n",
|
||||
"test_y = torch.FloatTensor(GetTrainingData(SPY, \n",
|
||||
" pd.Timestamp(lastdays[-1]),\n",
|
||||
" fulltest).to_numpy())\n",
|
||||
"full_x = torch.arange(ntrain+fulltest).type(torch.FloatTensor)\n",
|
||||
"full_x = full_x/252.\n",
|
||||
"train_x = full_x[:ntrain]\n",
|
||||
"test_x = full_x[ntrain:]\n",
|
||||
"\n",
|
||||
"## extract data for calibration ##\n",
|
||||
"ivol = torch.tensor(options.impliedvol.to_numpy())\n",
|
||||
"Fs = torch.tensor(options.underlying_last.to_numpy())\n",
|
||||
"Ks = torch.tensor(options.strike.to_numpy())\n",
|
||||
"starts = options.quotedate.dt.date.to_numpy()\n",
|
||||
"ends = options.expiration.dt.date.to_numpy()\n",
|
||||
"Ts = torch.tensor(([np.busday_count(qd, ed)/252. for qd, ed in zip(starts, ends)]))\n",
|
||||
"\n",
|
||||
"pars = Calibrate(Fs, Ks, Ts, ivol)\n",
|
||||
"v0 = np.exp(pars[0])\n",
|
||||
"1/(1 + np.exp(-pars[1]))\n",
|
||||
"rho = (2/(1 + np.exp(-pars[1])) - 1.)\n",
|
||||
"sigma = np.exp(pars[2])\n",
|
||||
"px_paths = SABRSim(Np, fulltest, quote_price, v0, sigma, rho)\n",
|
||||
"px_samples = torch.tensor(px_paths[ntests-1])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"id": "abc47786",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"option_output = Pricer(torch.tensor(px_paths), options, edays, test_y[ntests-1],\n",
|
||||
" quote_price)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"id": "9bb8972b",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div>\n",
|
||||
"<style scoped>\n",
|
||||
" .dataframe tbody tr th:only-of-type {\n",
|
||||
" vertical-align: middle;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe tbody tr th {\n",
|
||||
" vertical-align: top;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe thead th {\n",
|
||||
" text-align: right;\n",
|
||||
" }\n",
|
||||
"</style>\n",
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>Expiry</th>\n",
|
||||
" <th>Strike</th>\n",
|
||||
" <th>Bid</th>\n",
|
||||
" <th>Ask</th>\n",
|
||||
" <th>Voltron</th>\n",
|
||||
" <th>Return</th>\n",
|
||||
" <th>ExpClose</th>\n",
|
||||
" <th>QuoteClose</th>\n",
|
||||
" <th>Year</th>\n",
|
||||
" <th>Sample_Percentile</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>2013-03-16</td>\n",
|
||||
" <td>20.0</td>\n",
|
||||
" <td>121.39</td>\n",
|
||||
" <td>121.61</td>\n",
|
||||
" <td>126.884545</td>\n",
|
||||
" <td>136.729996</td>\n",
|
||||
" <td>156.729996</td>\n",
|
||||
" <td>141.449997</td>\n",
|
||||
" <td>2013</td>\n",
|
||||
" <td>0.781553</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1</th>\n",
|
||||
" <td>2013-03-16</td>\n",
|
||||
" <td>25.0</td>\n",
|
||||
" <td>116.39</td>\n",
|
||||
" <td>116.61</td>\n",
|
||||
" <td>121.884545</td>\n",
|
||||
" <td>131.729996</td>\n",
|
||||
" <td>156.729996</td>\n",
|
||||
" <td>141.449997</td>\n",
|
||||
" <td>2013</td>\n",
|
||||
" <td>0.781553</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2</th>\n",
|
||||
" <td>2013-03-16</td>\n",
|
||||
" <td>30.0</td>\n",
|
||||
" <td>111.39</td>\n",
|
||||
" <td>111.61</td>\n",
|
||||
" <td>116.884545</td>\n",
|
||||
" <td>126.729996</td>\n",
|
||||
" <td>156.729996</td>\n",
|
||||
" <td>141.449997</td>\n",
|
||||
" <td>2013</td>\n",
|
||||
" <td>0.781553</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>3</th>\n",
|
||||
" <td>2013-03-16</td>\n",
|
||||
" <td>35.0</td>\n",
|
||||
" <td>106.39</td>\n",
|
||||
" <td>106.61</td>\n",
|
||||
" <td>111.884545</td>\n",
|
||||
" <td>121.729996</td>\n",
|
||||
" <td>156.729996</td>\n",
|
||||
" <td>141.449997</td>\n",
|
||||
" <td>2013</td>\n",
|
||||
" <td>0.781553</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>4</th>\n",
|
||||
" <td>2013-03-16</td>\n",
|
||||
" <td>40.0</td>\n",
|
||||
" <td>101.39</td>\n",
|
||||
" <td>101.61</td>\n",
|
||||
" <td>106.884545</td>\n",
|
||||
" <td>116.729996</td>\n",
|
||||
" <td>156.729996</td>\n",
|
||||
" <td>141.449997</td>\n",
|
||||
" <td>2013</td>\n",
|
||||
" <td>0.781553</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>...</th>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>651</th>\n",
|
||||
" <td>2013-09-30</td>\n",
|
||||
" <td>169.0</td>\n",
|
||||
" <td>0.33</td>\n",
|
||||
" <td>0.42</td>\n",
|
||||
" <td>0.000000</td>\n",
|
||||
" <td>0.690002</td>\n",
|
||||
" <td>169.690002</td>\n",
|
||||
" <td>141.449997</td>\n",
|
||||
" <td>2013</td>\n",
|
||||
" <td>1.000000</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>652</th>\n",
|
||||
" <td>2013-09-30</td>\n",
|
||||
" <td>170.0</td>\n",
|
||||
" <td>0.28</td>\n",
|
||||
" <td>0.37</td>\n",
|
||||
" <td>0.000000</td>\n",
|
||||
" <td>0.000000</td>\n",
|
||||
" <td>169.690002</td>\n",
|
||||
" <td>141.449997</td>\n",
|
||||
" <td>2013</td>\n",
|
||||
" <td>1.000000</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>653</th>\n",
|
||||
" <td>2013-09-30</td>\n",
|
||||
" <td>175.0</td>\n",
|
||||
" <td>0.14</td>\n",
|
||||
" <td>0.21</td>\n",
|
||||
" <td>0.000000</td>\n",
|
||||
" <td>0.000000</td>\n",
|
||||
" <td>169.690002</td>\n",
|
||||
" <td>141.449997</td>\n",
|
||||
" <td>2013</td>\n",
|
||||
" <td>1.000000</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>654</th>\n",
|
||||
" <td>2013-09-30</td>\n",
|
||||
" <td>180.0</td>\n",
|
||||
" <td>0.08</td>\n",
|
||||
" <td>0.12</td>\n",
|
||||
" <td>0.000000</td>\n",
|
||||
" <td>0.000000</td>\n",
|
||||
" <td>169.690002</td>\n",
|
||||
" <td>141.449997</td>\n",
|
||||
" <td>2013</td>\n",
|
||||
" <td>1.000000</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>655</th>\n",
|
||||
" <td>2013-09-30</td>\n",
|
||||
" <td>185.0</td>\n",
|
||||
" <td>0.04</td>\n",
|
||||
" <td>0.08</td>\n",
|
||||
" <td>0.000000</td>\n",
|
||||
" <td>0.000000</td>\n",
|
||||
" <td>169.690002</td>\n",
|
||||
" <td>141.449997</td>\n",
|
||||
" <td>2013</td>\n",
|
||||
" <td>1.000000</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>\n",
|
||||
"<p>656 rows × 10 columns</p>\n",
|
||||
"</div>"
|
||||
],
|
||||
"text/plain": [
|
||||
" Expiry Strike Bid Ask Voltron Return ExpClose \\\n",
|
||||
"0 2013-03-16 20.0 121.39 121.61 126.884545 136.729996 156.729996 \n",
|
||||
"1 2013-03-16 25.0 116.39 116.61 121.884545 131.729996 156.729996 \n",
|
||||
"2 2013-03-16 30.0 111.39 111.61 116.884545 126.729996 156.729996 \n",
|
||||
"3 2013-03-16 35.0 106.39 106.61 111.884545 121.729996 156.729996 \n",
|
||||
"4 2013-03-16 40.0 101.39 101.61 106.884545 116.729996 156.729996 \n",
|
||||
".. ... ... ... ... ... ... ... \n",
|
||||
"651 2013-09-30 169.0 0.33 0.42 0.000000 0.690002 169.690002 \n",
|
||||
"652 2013-09-30 170.0 0.28 0.37 0.000000 0.000000 169.690002 \n",
|
||||
"653 2013-09-30 175.0 0.14 0.21 0.000000 0.000000 169.690002 \n",
|
||||
"654 2013-09-30 180.0 0.08 0.12 0.000000 0.000000 169.690002 \n",
|
||||
"655 2013-09-30 185.0 0.04 0.08 0.000000 0.000000 169.690002 \n",
|
||||
"\n",
|
||||
" QuoteClose Year Sample_Percentile \n",
|
||||
"0 141.449997 2013 0.781553 \n",
|
||||
"1 141.449997 2013 0.781553 \n",
|
||||
"2 141.449997 2013 0.781553 \n",
|
||||
"3 141.449997 2013 0.781553 \n",
|
||||
"4 141.449997 2013 0.781553 \n",
|
||||
".. ... ... ... \n",
|
||||
"651 141.449997 2013 1.000000 \n",
|
||||
"652 141.449997 2013 1.000000 \n",
|
||||
"653 141.449997 2013 1.000000 \n",
|
||||
"654 141.449997 2013 1.000000 \n",
|
||||
"655 141.449997 2013 1.000000 \n",
|
||||
"\n",
|
||||
"[656 rows x 10 columns]"
|
||||
]
|
||||
},
|
||||
"execution_count": 13,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"option_output"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"id": "51771e55",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"plt.plot(train_x, train_y)\n",
|
||||
"plt.plot(test_x, test_y)\n",
|
||||
"plt.plot(test_x, px_paths[:, :20], c='gray', alpha=0.5);"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 15,
|
||||
"id": "a9503b79",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"(206, 20)"
|
||||
]
|
||||
},
|
||||
"execution_count": 15,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"px_paths[:, :20].shape"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 16,
|
||||
"id": "13d5c888",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"(206, 10000)"
|
||||
]
|
||||
},
|
||||
"execution_count": 16,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"px_paths.shape"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "5867b14f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.8.3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -1,97 +0,0 @@
|
||||
import numpy as np
|
||||
import datetime as dt
|
||||
import matplotlib.pyplot as plt
|
||||
import seaborn as sns
|
||||
import torch
|
||||
import gpytorch
|
||||
import os
|
||||
# import robin_stocks.robinhood as r
|
||||
import pickle5 as pickle
|
||||
import pandas as pd
|
||||
import argparse
|
||||
|
||||
import sys
|
||||
sys.path.append("../")
|
||||
from voltron.likelihoods import VolatilityGaussianLikelihood
|
||||
from voltron.models import SingleTaskVariationalGP as SingleTaskCopulaProcessModel
|
||||
from voltron.kernels import BMKernel, VolatilityKernel
|
||||
from voltron.models import BMGP, VoltronGP
|
||||
from gpytorch.kernels import ScaleKernel, RBFKernel, MaternKernel
|
||||
from voltron.option_utils import GetTradingDays, GetTrainingData, Pricer, FindLastTradingDays
|
||||
from voltron.train_utils import TrainBasicModel
|
||||
|
||||
def main(args):
|
||||
years = [yr for yr in range(2006, 2018)]
|
||||
logger = []
|
||||
full_logger = []
|
||||
SPY = pd.read_csv("./data/SPY_prices.csv")
|
||||
SPY['Date'] = pd.to_datetime(SPY['Date'])
|
||||
ntrain = 252
|
||||
|
||||
nvol = 100
|
||||
npx = 100
|
||||
|
||||
for year in years:
|
||||
options = pd.read_csv("./data/SPY_" + str(year) + ".csv")
|
||||
options.expiration = pd.to_datetime(options.expiration)
|
||||
options.quotedate = pd.to_datetime(options.quotedate)
|
||||
qday = options.quotedate.unique()[0]
|
||||
quote_price = SPY[SPY['Date']==qday].Close.item()
|
||||
options = options[(options.quotedate == qday) & (options.type=='call')]
|
||||
edays = options.expiration.sort_values().unique()
|
||||
testdays = (edays - qday)/np.timedelta64(1, "D")
|
||||
edays = edays[(testdays > 100) & (testdays < 365)]
|
||||
lastdays = FindLastTradingDays(SPY, edays)
|
||||
ntests = np.array([GetTradingDays(SPY, qday, pd.Timestamp(ld)) for ld in lastdays])
|
||||
fulltest = ntests[-1]
|
||||
|
||||
train_y = torch.FloatTensor(GetTrainingData(SPY, qday, ntrain).to_numpy())
|
||||
test_y = torch.FloatTensor(GetTrainingData(SPY,
|
||||
pd.Timestamp(lastdays[-1]),
|
||||
fulltest).to_numpy())
|
||||
full_x = torch.arange(ntrain+fulltest).type(torch.FloatTensor)
|
||||
full_x = full_x/252.
|
||||
train_x = full_x[:ntrain]
|
||||
test_x = full_x[ntrain:]
|
||||
|
||||
dmod, dlh = TrainBasicModel(train_x, train_y, train_iters=500, model_type=args.model,
|
||||
mean_func=args.mean_func)
|
||||
|
||||
## figure out how to price options sanely ##
|
||||
|
||||
nvol = 100
|
||||
npx = 100
|
||||
px_samples = torch.zeros(npx*nvol, len(edays))
|
||||
px_paths = torch.zeros(npx*nvol, fulltest)
|
||||
dmod.eval();
|
||||
|
||||
for vidx in range(nvol):
|
||||
px_pred = dlh(dmod(test_x)).sample(torch.Size((npx,))).exp()
|
||||
px_paths[vidx*npx:(vidx*npx + npx), :] = px_pred.detach()
|
||||
px_samples[vidx*npx:(vidx*npx+npx), :] = px_pred[:, ntests-1].detach()
|
||||
|
||||
|
||||
|
||||
option_output = Pricer(px_samples, options, edays, test_y[ntests-1],
|
||||
quote_price)
|
||||
option_output.to_pickle("./output/" + args.model + "_options" + str(year) + ".pkl")
|
||||
print(str(year), "Done")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument(
|
||||
"--mean_func",
|
||||
type=str,
|
||||
default="loglinear",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--model",
|
||||
type=str,
|
||||
default="matern",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
main(args)
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
BIN
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -1,97 +0,0 @@
|
||||
import numpy as np
|
||||
import datetime as dt
|
||||
import matplotlib.pyplot as plt
|
||||
import seaborn as sns
|
||||
import torch
|
||||
import gpytorch
|
||||
import os
|
||||
# import robin_stocks.robinhood as r
|
||||
import pickle5 as pickle
|
||||
import pandas as pd
|
||||
sns.set_style("whitegrid")
|
||||
sns.set_palette("bright")
|
||||
sns.set(font_scale=2.0)
|
||||
|
||||
|
||||
import sys
|
||||
sys.path.append("../")
|
||||
from voltron.likelihoods import VolatilityGaussianLikelihood
|
||||
from voltron.models import SingleTaskVariationalGP as SingleTaskCopulaProcessModel
|
||||
from voltron.kernels import BMKernel, VolatilityKernel
|
||||
from voltron.models import BMGP, VoltronGP
|
||||
from gpytorch.kernels import ScaleKernel, RBFKernel, MaternKernel
|
||||
from voltron.option_utils import GetTradingDays, GetTrainingData, Pricer, FindLastTradingDays
|
||||
from voltron.train_utils import LearnGPCV, TrainVolModel, TrainDataModel
|
||||
|
||||
def main():
|
||||
years = [yr for yr in range(2006, 2018)]
|
||||
logger = []
|
||||
full_logger = []
|
||||
SPY = pd.read_csv("./data/SPY_prices.csv")
|
||||
SPY['Date'] = pd.to_datetime(SPY['Date'])
|
||||
ntrain = 375
|
||||
|
||||
nvol = 100
|
||||
npx = 100
|
||||
|
||||
for year in years:
|
||||
options = pd.read_csv("./data/SPY_" + str(year) + ".csv")
|
||||
options.expiration = pd.to_datetime(options.expiration)
|
||||
options.quotedate = pd.to_datetime(options.quotedate)
|
||||
qday = options.quotedate.unique()[0]
|
||||
quote_price = SPY[SPY['Date']==qday].Close.item()
|
||||
options = options[(options.quotedate == qday) & (options.type=='call')]
|
||||
edays = options.expiration.sort_values().unique()
|
||||
testdays = (edays - qday)/np.timedelta64(1, "D")
|
||||
edays = edays[(testdays > 100) & (testdays < 365)]
|
||||
lastdays = FindLastTradingDays(SPY, edays)
|
||||
ntests = np.array([GetTradingDays(SPY, qday, pd.Timestamp(ld)) for ld in lastdays])
|
||||
fulltest = ntests[-1]
|
||||
|
||||
train_y = torch.FloatTensor(GetTrainingData(SPY, qday, ntrain).to_numpy())
|
||||
test_y = torch.FloatTensor(GetTrainingData(SPY,
|
||||
pd.Timestamp(lastdays[-1]),
|
||||
fulltest).to_numpy())
|
||||
full_x = torch.arange(ntrain+fulltest).type(torch.FloatTensor)
|
||||
full_x = full_x/252.
|
||||
train_x = full_x[:ntrain]
|
||||
dt = train_x[1]-train_x[0]
|
||||
test_x = full_x[ntrain:]
|
||||
|
||||
## learn vol with GPCV ##
|
||||
vol = LearnGPCV(train_x, train_y, train_iters=750)/(dt**0.5)
|
||||
|
||||
## train vol GP ##
|
||||
vmod, vlh = TrainVolModel(train_x, vol, train_iters=750)
|
||||
|
||||
## train data gp ##
|
||||
dmod, dlh = TrainDataModel(train_x, train_y, vmod, vlh, vol,
|
||||
printing=False, train_iters=750)
|
||||
|
||||
## figure out how to price options sanely ##
|
||||
|
||||
px_samples = torch.zeros(npx*nvol, len(edays))
|
||||
px_paths = torch.zeros(npx*nvol, fulltest)
|
||||
vol_paths = torch.zeros(nvol, fulltest)
|
||||
dmod.vol_model.eval();
|
||||
dmod.eval();
|
||||
|
||||
for vidx in range(nvol):
|
||||
# print(vidx)
|
||||
vol_pred = dmod.vol_model(test_x).sample().exp()
|
||||
vol_paths[vidx, :] = vol_pred.detach()
|
||||
|
||||
px_pred = dmod.GeneratePrediction(test_x, vol_pred, npx).exp()
|
||||
px_paths[vidx*npx:(vidx*npx + npx), :] = px_pred.detach().T
|
||||
px_samples[vidx*npx:(vidx*npx+npx), :] = px_pred[ntests-1].detach().T
|
||||
|
||||
|
||||
option_output = Pricer(px_samples, options, edays, test_y[ntests-1],
|
||||
quote_price)
|
||||
option_output.to_pickle("./output/options" + str(year) + ".pkl")
|
||||
print(str(year), "Done")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
import numpy as np
|
||||
import torch
|
||||
import pandas as pd
|
||||
import copy
|
||||
from voltron.option_utils import GetTradingDays, GetTrainingData, Pricer, FindLastTradingDays
|
||||
from scipy.optimize import minimize
|
||||
|
||||
def BlackVol(pars, K, f, T):
|
||||
alpha = torch.exp(pars[0][0]) ## v0
|
||||
rho = 2 * torch.sigmoid(pars[0][1]) - 1. ##rho
|
||||
v = torch.exp(pars[0][2]) ## "sigma"
|
||||
beta = 1.
|
||||
num = 1 + (alpha**2 * (1-beta)**2/(24 * (f*K)**(1-beta)) +\
|
||||
0.25 * rho*beta*v*alpha/((f*K)**(0.5*(1-beta))) +\
|
||||
v**2*(2-3*rho**2)/24)*T
|
||||
num*= alpha
|
||||
|
||||
denom = (f*K)**(0.5*(1-beta)) * (1 + (1-beta)**2/24 * torch.log(f/K)**2 +\
|
||||
(1-beta)**4/1920 * torch.log(f/K)**4)
|
||||
|
||||
z = v/alpha * (f*K)**(0.5*(1-beta)) * np.log(f/K)
|
||||
xi_z = torch.log((torch.sqrt(1 - 2 * rho * z + z**2) + z - rho)/(1-rho))
|
||||
|
||||
return num/denom * z/xi_z
|
||||
|
||||
def MinVol(pars, Ks, Fs, Ts, ivol):
|
||||
return torch.mean((ivol - BlackVol(pars, Ks, Fs, Ts)).pow(2))
|
||||
|
||||
def Calibrate(Fs, Ks, Ts, ivol, iters=1000):
|
||||
pars = [torch.tensor([-1., -5., -3.], requires_grad=True)]
|
||||
opt = torch.optim.SGD(pars, lr=0.1)
|
||||
stored_pars = torch.zeros(iters, 3)
|
||||
losses = []
|
||||
for e in range(iters):
|
||||
stored_pars[e, :] = pars[0]
|
||||
loss = MinVol(pars, Ks, Fs, Ts, ivol)
|
||||
opt.zero_grad()
|
||||
loss.backward()
|
||||
losses.append(loss.item())
|
||||
opt.step()
|
||||
|
||||
return pars[0].detach().numpy()
|
||||
|
||||
def SABRSim(Np, Nt, S0, V0, sigma, rho, dt=1./252.):
|
||||
dW = np.random.randn(Nt+1, Np) * np.sqrt(dt)
|
||||
dZ = rho * dW + np.sqrt(1-rho**2) * np.random.randn(Nt+1, Np) * np.sqrt(dt)
|
||||
|
||||
S = np.zeros((Nt+1, Np))
|
||||
S[0] = S0
|
||||
V = np.zeros((Nt+1, Np))
|
||||
V[0] = V0
|
||||
|
||||
for t in range(Nt):
|
||||
S[t+1] = S[t] + V[t]*S[t]*dW[t]
|
||||
V[t+1] = V[t] + sigma*V[t]*dZ[t]
|
||||
|
||||
return S[1:]
|
||||
|
||||
def main():
|
||||
years = [yr for yr in range(2006, 2018)]
|
||||
logger = []
|
||||
full_logger = []
|
||||
SPY = pd.read_csv("./data/SPY_prices.csv")
|
||||
SPY['Date'] = pd.to_datetime(SPY['Date'])
|
||||
Np = 10000
|
||||
for year in years:
|
||||
options = pd.read_csv("./data/SPY_" + str(year) + ".csv")
|
||||
options.expiration = pd.to_datetime(options.expiration)
|
||||
options.quotedate = pd.to_datetime(options.quotedate)
|
||||
qday = options.quotedate.unique()[0]
|
||||
quote_price = SPY[SPY['Date']==qday].Close.item()
|
||||
options = options[(options.quotedate == qday) & (options.type=='call')]
|
||||
edays = options.expiration.sort_values().unique()
|
||||
testdays = (edays - qday)/np.timedelta64(1, "D")
|
||||
edays = edays[(testdays > 100) & (testdays < 365)]
|
||||
lastdays = FindLastTradingDays(SPY, edays)
|
||||
ntests = np.array([GetTradingDays(SPY, qday,
|
||||
pd.Timestamp(ld)) for ld in lastdays])
|
||||
fulltest = ntests[-1]
|
||||
|
||||
test_y = torch.FloatTensor(GetTrainingData(SPY,
|
||||
pd.Timestamp(lastdays[-1]),
|
||||
fulltest).to_numpy())
|
||||
|
||||
## extract data for calibration ##
|
||||
ivol = torch.tensor(options.impliedvol.to_numpy())
|
||||
Fs = torch.tensor(options.underlying_last.to_numpy())
|
||||
Ks = torch.tensor(options.strike.to_numpy())
|
||||
starts = options.quotedate.dt.date.to_numpy()
|
||||
ends = options.expiration.dt.date.to_numpy()
|
||||
Ts = torch.tensor(([np.busday_count(qd, ed)/252. for qd, ed in zip(starts, ends)]))
|
||||
|
||||
pars = Calibrate(Fs, Ks, Ts, ivol)
|
||||
v0 = np.exp(pars[0])
|
||||
1/(1 + np.exp(-pars[1]))
|
||||
rho = (2/(1 + np.exp(-pars[1])) - 1.)
|
||||
sigma = np.exp(pars[2])
|
||||
px_paths = SABRSim(Np, fulltest, quote_price, v0, sigma, rho)
|
||||
# px_samples = torch.tensor(px_paths[ntests-1])
|
||||
|
||||
option_output = Pricer(torch.tensor(px_paths), options, edays, test_y[ntests-1],
|
||||
quote_price)
|
||||
|
||||
option_output.to_pickle("./output/sabr" + str(year) + ".pkl")
|
||||
print(str(year), "Done")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,588 +0,0 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "8d4521d7-e61a-4820-b704-4908e9210ee7",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import numpy as np\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"from matplotlib.lines import Line2D\n",
|
||||
"import pandas as pd\n",
|
||||
"import torch\n",
|
||||
"import gpytorch\n",
|
||||
"from gpytorch.means import Mean\n",
|
||||
"import seaborn as sns\n",
|
||||
"import time\n",
|
||||
"import copy\n",
|
||||
"import sys\n",
|
||||
"import os\n",
|
||||
"\n",
|
||||
"sns.set_style('white')\n",
|
||||
"# style.use('whitegrid')\n",
|
||||
"palette = [\"#1b4079\", \"#C6DDF0\", \"#048A81\", \"#B9E28C\", \"#8C2155\", \"#AF7595\", \"#E6480F\", \"#FA9500\"]\n",
|
||||
"sns.set(palette = palette, font_scale=2.0, style=\"white\", rc={\"lines.linewidth\": 2.0})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "3744a8e8-cb18-43ed-81c1-54aed694e292",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def LoadDat(dat, sym, start_idx, ntrain, ntest):\n",
|
||||
" px = torch.FloatTensor(dat[dat.symbol == sym].close_price.to_numpy())\n",
|
||||
" train_y = px[start_idx:ntrain+start_idx].squeeze()\n",
|
||||
" test_y = px[start_idx + ntrain:start_idx + ntrain+ntest].squeeze()\n",
|
||||
" return train_y, test_y\n",
|
||||
"\n",
|
||||
"def LoadSims(SPDR, sym, kernel, mean, k=100):\n",
|
||||
" fpath = \"./saved-outputs/\" + SPDR + \"/\"\n",
|
||||
" fname = sym + \"_\" + kernel + \"_\" + mean + str(k) + \".pt\"\n",
|
||||
" \n",
|
||||
" return torch.load(fpath + fname)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "19d2a38f-0bb2-427f-bd7a-f9423b60e448",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"['XOM' 'CVX' 'EOG' 'COP' 'SLB']\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"hypers = torch.load(\"./saved-outputs/metadata.pt\")\n",
|
||||
"ntrain = hypers['ntrain']\n",
|
||||
"ntest = hypers['ntest']\n",
|
||||
"start_idxs = hypers['start_idxs']\n",
|
||||
"\n",
|
||||
"SPDR = \"XLE\"\n",
|
||||
"dat = pd.read_pickle(dpath + SPDR + \".pkl\")\n",
|
||||
"syms = dat.symbol.unique()\n",
|
||||
"print(syms)\n",
|
||||
"\n",
|
||||
"train_x = torch.arange(ntrain) * 1./252\n",
|
||||
"test_x = torch.arange(ntest) * 1./252 + train_x[-1] + train_x[1]\n",
|
||||
"percentiles = np.linspace(0.05, 0.95, 19)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "4257adde-7106-429c-b418-973dc0345424",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Examples"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "6ccf46b5-183d-400f-ace6-200a3d9d7844",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"['AAPL' 'MSFT' 'NVDA' 'V' 'PYPL']\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"hypers = torch.load(\"./saved-outputs/metadata.pt\")\n",
|
||||
"ntrain = hypers['ntrain']\n",
|
||||
"ntest = hypers['ntest']\n",
|
||||
"start_idxs = hypers['start_idxs']\n",
|
||||
"\n",
|
||||
"SPDR = \"XLK\"\n",
|
||||
"dat = pd.read_pickle(dpath + SPDR + \".pkl\")\n",
|
||||
"syms = dat.symbol.unique()\n",
|
||||
"print(syms)\n",
|
||||
"train_x = torch.arange(ntrain) * 1./252\n",
|
||||
"test_x = torch.arange(ntest) * 1./252 + train_x[-1] + train_x[1]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "9704d083-ce47-4c5e-a5e6-029fa1effbd7",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def ECDF(sample_pxs, true_px): \n",
|
||||
" return (torch.sum(sample_pxs < true_px, 0)/sample_pxs.shape[0])\n",
|
||||
" \n",
|
||||
"def Calibration(pcts, percentile=0.95):\n",
|
||||
" in_band = np.where((pcts < percentile))[0].shape[0]\n",
|
||||
" return in_band/pcts.shape[0]\n",
|
||||
"\n",
|
||||
"def GetCalibration(kernel, mean, k=100, horizon=np.arange(75,100), logger=[], exp=True):\n",
|
||||
" pcts = torch.zeros(len(syms), len(start_idxs), horizon.shape[0])\n",
|
||||
" for sym_idx, sym in enumerate(syms):\n",
|
||||
" \n",
|
||||
" fpath = \"./saved-outputs/\" + SPDR + \"/\"\n",
|
||||
" fname = sym + \"_\" + kernel + \"_\" + mean + str(k) + \".pt\"\n",
|
||||
" if os.path.exists(fpath + fname):\n",
|
||||
" for idx, start_idx in enumerate(start_idxs):\n",
|
||||
" train_y, test_y = LoadDat(dat, sym, start_idx, ntrain, ntest)\n",
|
||||
" preds = LoadSims(SPDR, sym, kernel, mean, k=k)[idx, :, horizon]\n",
|
||||
" if exp:\n",
|
||||
" preds = preds.exp()\n",
|
||||
" \n",
|
||||
" \n",
|
||||
" pcts = pcts.flatten()\n",
|
||||
" percentiles = np.linspace(0.05, 0.95, 19)\n",
|
||||
" log_name = kernel\n",
|
||||
" for pct in percentiles:\n",
|
||||
" clb = Calibration(pcts, pct)\n",
|
||||
" logger.append([clb, np.round(pct, 2), log_name, mean, k])\n",
|
||||
" \n",
|
||||
" return logger"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 20,
|
||||
"id": "4ff19402-e7d7-49c0-890c-5b136265f3ff",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"['AMT' 'PLD' 'CCI' 'EQIX' 'PSA']\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"SPDR = \"XLRE\"\n",
|
||||
"dat = pd.read_pickle(dpath + SPDR + \".pkl\")\n",
|
||||
"syms = dat.symbol.unique()\n",
|
||||
"print(syms)\n",
|
||||
"horizon = np.arange(75, 100)\n",
|
||||
"train_x = torch.arange(ntrain) * 1./252\n",
|
||||
"test_x = torch.arange(ntest) * 1./252 + train_x[-1] + train_x[1]\n",
|
||||
"\n",
|
||||
"logger = []\n",
|
||||
"logger = GetCalibration('matern', 'ewma', 100, logger=logger, horizon=horizon)\n",
|
||||
"logger = GetCalibration('matern', 'ewma', 200, logger=logger, horizon=horizon)\n",
|
||||
"logger = GetCalibration('matern', 'ewma', 400, logger=logger, horizon=horizon)\n",
|
||||
"logger = GetCalibration('matern', 'dewma', 100, logger=logger, horizon=horizon)\n",
|
||||
"logger = GetCalibration('matern', 'dewma', 200, logger=logger, horizon=horizon)\n",
|
||||
"logger = GetCalibration('matern', 'dewma', 400, logger=logger, horizon=horizon)\n",
|
||||
"logger = GetCalibration('matern', 'tewma', 100, logger=logger, horizon=horizon)\n",
|
||||
"logger = GetCalibration('matern', 'tewma', 200, logger=logger, horizon=horizon)\n",
|
||||
"logger = GetCalibration('matern', 'tewma', 400, logger=logger, horizon=horizon)\n",
|
||||
"logger = GetCalibration('matern', 'constant', 100, logger=logger, horizon=horizon, exp=False)\n",
|
||||
"xlre_df = pd.DataFrame(logger)\n",
|
||||
"xlre_df.columns = [\"Calibration\", \"Percentile\", \"Type\", 'Mean', \"k\"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 22,
|
||||
"id": "49f482b5-af3b-4b77-b04d-82716d5b7afb",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"pd.to_pickle(xlre_df, \"./new_matern_calib.pkl\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "7b846b87-3132-42e1-9bff-f9d117176543",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Get NLL"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 94,
|
||||
"id": "63958d47-67f8-4298-94ab-3ff353b4f9ff",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def GetNLL(kernel, mean, k=100, horizon=np.arange(75,100), logger=[], exp=True):\n",
|
||||
" N = 0\n",
|
||||
" nll = 0.\n",
|
||||
" for spdr_idx, spdr in enumerate(SPDRS):\n",
|
||||
" dat = pd.read_pickle(dpath + spdr + \".pkl\")\n",
|
||||
" syms = dat.symbol.unique()\n",
|
||||
" for sym_idx, sym in enumerate(syms):\n",
|
||||
" fpath = \"./saved-outputs/\" + spdr + \"/\"\n",
|
||||
" fname = sym + \"_\" + kernel + \"_\" + mean + str(k) + \".pt\"\n",
|
||||
" if os.path.exists(fpath + fname):\n",
|
||||
" for idx, start_idx in enumerate(start_idxs):\n",
|
||||
" train_y, test_y = LoadDat(dat, sym, start_idx, ntrain, ntest)\n",
|
||||
" test_y = test_y[horizon]\n",
|
||||
" preds = LoadSims(spdr, sym, kernel, mean, k=k)[idx, :, horizon]\n",
|
||||
" if exp:\n",
|
||||
" preds = preds.exp() \n",
|
||||
" try:\n",
|
||||
" nll -= torch.distributions.Normal(preds.mean(0), preds.std(0)).log_prob(test_y).sum()\n",
|
||||
" N += test_y.numel()\n",
|
||||
" except:\n",
|
||||
" pass\n",
|
||||
" # print(\"Failed:\", spdr, sym, idx)\n",
|
||||
"\n",
|
||||
" if N >= 0:\n",
|
||||
" logger.append([nll.item(), N, kernel, mean, k])\n",
|
||||
" return logger"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 105,
|
||||
"id": "8bc987c8-982a-4f1c-bd40-5d444e58e7e0",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"SPDRS = [\"XLRE\", \"XLY\", \"XLF\", \"XLE\", \"XLK\"]\n",
|
||||
"horizon = np.arange(75, 100)\n",
|
||||
"train_x = torch.arange(ntrain) * 1./252\n",
|
||||
"test_x = torch.arange(ntest) * 1./252 + train_x[-1] + train_x[1]\n",
|
||||
"\n",
|
||||
"logger = []\n",
|
||||
"logger = GetNLL('matern', 'ewma', 100, logger=logger, horizon=horizon)\n",
|
||||
"logger = GetNLL('matern', 'ewma', 200, logger=logger, horizon=horizon)\n",
|
||||
"logger = GetNLL('matern', 'ewma', 400, logger=logger, horizon=horizon)\n",
|
||||
"logger = GetNLL('matern', 'dewma', 100, logger=logger, horizon=horizon)\n",
|
||||
"logger = GetNLL('matern', 'dewma', 200, logger=logger, horizon=horizon)\n",
|
||||
"logger = GetNLL('matern', 'dewma', 400, logger=logger, horizon=horizon)\n",
|
||||
"logger = GetNLL('matern', 'tewma', 100, logger=logger, horizon=horizon)\n",
|
||||
"logger = GetNLL('matern', 'tewma', 200, logger=logger, horizon=horizon)\n",
|
||||
"logger = GetNLL('matern', 'tewma', 400, logger=logger, horizon=horizon)\n",
|
||||
"logger = GetNLL('matern', 'constant', 100, logger=logger, horizon=horizon, exp=False)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 106,
|
||||
"id": "dee5af9f-d8d1-4576-bc42-eba43d846e8e",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df = pd.DataFrame(logger)\n",
|
||||
"df.columns = [\"NLL\", \"N\", \"Kernel\", \"Mean\", \"K\"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 107,
|
||||
"id": "84d27556-5456-433b-945a-8107613c7d0f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df['Mean_NLL'] = df[\"NLL\"]/df['N']"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 108,
|
||||
"id": "0d562366-4268-4bd2-a4ff-2e62797cbdb7",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div>\n",
|
||||
"<style scoped>\n",
|
||||
" .dataframe tbody tr th:only-of-type {\n",
|
||||
" vertical-align: middle;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe tbody tr th {\n",
|
||||
" vertical-align: top;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe thead th {\n",
|
||||
" text-align: right;\n",
|
||||
" }\n",
|
||||
"</style>\n",
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>NLL</th>\n",
|
||||
" <th>N</th>\n",
|
||||
" <th>Kernel</th>\n",
|
||||
" <th>Mean</th>\n",
|
||||
" <th>K</th>\n",
|
||||
" <th>Mean_NLL</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>6.726755e+04</td>\n",
|
||||
" <td>4350</td>\n",
|
||||
" <td>matern</td>\n",
|
||||
" <td>ewma</td>\n",
|
||||
" <td>100</td>\n",
|
||||
" <td>15.463804</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1</th>\n",
|
||||
" <td>5.704342e+04</td>\n",
|
||||
" <td>4200</td>\n",
|
||||
" <td>matern</td>\n",
|
||||
" <td>ewma</td>\n",
|
||||
" <td>200</td>\n",
|
||||
" <td>13.581766</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2</th>\n",
|
||||
" <td>6.180194e+04</td>\n",
|
||||
" <td>6300</td>\n",
|
||||
" <td>matern</td>\n",
|
||||
" <td>ewma</td>\n",
|
||||
" <td>400</td>\n",
|
||||
" <td>9.809832</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>3</th>\n",
|
||||
" <td>5.138177e+05</td>\n",
|
||||
" <td>4800</td>\n",
|
||||
" <td>matern</td>\n",
|
||||
" <td>dewma</td>\n",
|
||||
" <td>100</td>\n",
|
||||
" <td>107.045358</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>4</th>\n",
|
||||
" <td>1.109547e+05</td>\n",
|
||||
" <td>4200</td>\n",
|
||||
" <td>matern</td>\n",
|
||||
" <td>dewma</td>\n",
|
||||
" <td>200</td>\n",
|
||||
" <td>26.417781</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>5</th>\n",
|
||||
" <td>7.489109e+04</td>\n",
|
||||
" <td>6450</td>\n",
|
||||
" <td>matern</td>\n",
|
||||
" <td>dewma</td>\n",
|
||||
" <td>400</td>\n",
|
||||
" <td>11.611021</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>6</th>\n",
|
||||
" <td>3.585653e+06</td>\n",
|
||||
" <td>5250</td>\n",
|
||||
" <td>matern</td>\n",
|
||||
" <td>tewma</td>\n",
|
||||
" <td>100</td>\n",
|
||||
" <td>682.981476</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>7</th>\n",
|
||||
" <td>1.216625e+05</td>\n",
|
||||
" <td>3900</td>\n",
|
||||
" <td>matern</td>\n",
|
||||
" <td>tewma</td>\n",
|
||||
" <td>200</td>\n",
|
||||
" <td>31.195507</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>8</th>\n",
|
||||
" <td>7.496420e+04</td>\n",
|
||||
" <td>6450</td>\n",
|
||||
" <td>matern</td>\n",
|
||||
" <td>tewma</td>\n",
|
||||
" <td>400</td>\n",
|
||||
" <td>11.622357</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>9</th>\n",
|
||||
" <td>5.738497e+04</td>\n",
|
||||
" <td>7500</td>\n",
|
||||
" <td>matern</td>\n",
|
||||
" <td>constant</td>\n",
|
||||
" <td>100</td>\n",
|
||||
" <td>7.651330</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>\n",
|
||||
"</div>"
|
||||
],
|
||||
"text/plain": [
|
||||
" NLL N Kernel Mean K Mean_NLL\n",
|
||||
"0 6.726755e+04 4350 matern ewma 100 15.463804\n",
|
||||
"1 5.704342e+04 4200 matern ewma 200 13.581766\n",
|
||||
"2 6.180194e+04 6300 matern ewma 400 9.809832\n",
|
||||
"3 5.138177e+05 4800 matern dewma 100 107.045358\n",
|
||||
"4 1.109547e+05 4200 matern dewma 200 26.417781\n",
|
||||
"5 7.489109e+04 6450 matern dewma 400 11.611021\n",
|
||||
"6 3.585653e+06 5250 matern tewma 100 682.981476\n",
|
||||
"7 1.216625e+05 3900 matern tewma 200 31.195507\n",
|
||||
"8 7.496420e+04 6450 matern tewma 400 11.622357\n",
|
||||
"9 5.738497e+04 7500 matern constant 100 7.651330"
|
||||
]
|
||||
},
|
||||
"execution_count": 108,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"df"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 110,
|
||||
"id": "733dcdd7-bc8a-4530-9ac5-eaa2e5f86085",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"pd.to_pickle(df, \"./matern_nll.pkl\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 56,
|
||||
"id": "330cbdba-bf55-4bf6-814a-09d10a53fd04",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"mean = torch.tensor([1., 5.])\n",
|
||||
"std = torch.tensor([1., 1.])\n",
|
||||
"nrml = torch.distributions.Normal(mean, std)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 57,
|
||||
"id": "1582602c-8015-476a-b01a-a05d8aaf4a4a",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"tensor([0.3989, 0.3989])"
|
||||
]
|
||||
},
|
||||
"execution_count": 57,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"nrml.log_prob(torch.tensor([1., 5.])).exp()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 68,
|
||||
"id": "0f47d060-7f64-4537-b18f-7c5772df4bea",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"preds, y = GetNLL('matern', 'tewma', 400, logger=logger, horizon=horizon)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 69,
|
||||
"id": "e2403da1-c3b7-4d9d-8ae2-c00babfcfdcd",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"torch.Size([1000, 25])"
|
||||
]
|
||||
},
|
||||
"execution_count": 69,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"preds.shape"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 73,
|
||||
"id": "ff68035a-39a5-44e1-bf6a-ecd9b0837bc9",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"nll = 0."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 78,
|
||||
"id": "012b1b96-1afb-4f0a-8ab8-f96e92beacaf",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"nll -= torch.distributions.Normal(preds.mean(0), preds.std(0)).log_prob(y).sum()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 79,
|
||||
"id": "5a9241b1-a686-40fe-a378-cc219333f9bb",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"tensor(242.3718)"
|
||||
]
|
||||
},
|
||||
"execution_count": 79,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"nll"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "5cc3b61d-a2eb-4a33-9dfa-1049c9992345",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.8.8"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -1,854 +0,0 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "92e5b691-e01a-438a-b2b9-543c5fa3f8b2",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Warning no robinhood utils.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import pickle as pkl\n",
|
||||
"import pandas as pd\n",
|
||||
"import numpy as np\n",
|
||||
"import torch\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"import seaborn as sns\n",
|
||||
"import os\n",
|
||||
"from voltron.data import make_ticker_list, GetStockHistory\n",
|
||||
"\n",
|
||||
"sns.set_style('white')\n",
|
||||
"palette = [\"#1b4079\", \"#C6DDF0\", \"#048A81\", \"#B9E28C\", \"#8C2155\", \"#AF7595\", \"#E6480F\", \"#FA9500\"]\n",
|
||||
"sns.set(palette = palette, font_scale=2.0, style=\"white\", rc={\"lines.linewidth\": 4.0})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 30,
|
||||
"id": "1f59e48e-eb80-48b2-8ce5-91596ad136f2",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def ECDF(sample_pxs, true_px): \n",
|
||||
" return (torch.sum(sample_pxs < true_px, 0)/sample_pxs.shape[0])\n",
|
||||
" \n",
|
||||
"def Calibration(pcts, percentile=0.95):\n",
|
||||
" in_band = np.where((pcts < percentile))[0].shape[0]\n",
|
||||
" return in_band/pcts.shape[0]\n",
|
||||
"\n",
|
||||
"def GetNLL(model, mean='ewma', k=100, horizon=np.arange(75,100), \n",
|
||||
" logger=[], exp=True, fdir=\"./saved-outputs/\"):\n",
|
||||
" \n",
|
||||
"\n",
|
||||
" ntrain = 400\n",
|
||||
" n_test_times = 20\n",
|
||||
" ntest = 100\n",
|
||||
" nll = 0.\n",
|
||||
" N = 0\n",
|
||||
" nlls = torch.tensor([])\n",
|
||||
" for tckr in ticker_list:\n",
|
||||
" data = None\n",
|
||||
" try:\n",
|
||||
" data = GetStockHistory(tckr, history=1000, end_date=end_date)\n",
|
||||
" except:\n",
|
||||
" print(\"failed\", tckr)\n",
|
||||
" \n",
|
||||
" if data is not None:\n",
|
||||
"\n",
|
||||
" for idx, date in enumerate(data.index):\n",
|
||||
" fpath = fdir + tckr + \"/\"\n",
|
||||
" fname = model + \"_\"\n",
|
||||
" if model in ['volt', 'matern', 'sm']:\n",
|
||||
" fname += mean + str(k) + \"_\"\n",
|
||||
"\n",
|
||||
" fname += str(date.date()) + \".pt\"\n",
|
||||
"# print(fpath + fname)\n",
|
||||
" if os.path.exists(fpath + fname): \n",
|
||||
" preds = torch.load(fpath + fname) \n",
|
||||
" if isinstance(preds, tuple):\n",
|
||||
" preds = preds[0]\n",
|
||||
" if preds.shape[-1] == 100:\n",
|
||||
" preds = preds[:, horizon]\n",
|
||||
"\n",
|
||||
" test_y = torch.tensor(data.iloc[idx:idx+100].Close.to_numpy())\n",
|
||||
" if test_y.shape[0] == 100:\n",
|
||||
" if exp:\n",
|
||||
" preds = preds.exp()\n",
|
||||
"\n",
|
||||
" try:\n",
|
||||
" curr = torch.distributions.Normal(preds.mean(0), preds.std(0)).log_prob(test_y[horizon])\n",
|
||||
" if curr.mean().abs() < 500:\n",
|
||||
" nlls = torch.cat((curr, nlls))\n",
|
||||
" except:\n",
|
||||
" pass\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" if nlls.numel() > 0:\n",
|
||||
" logger.append([-nlls.sum().item(), -nlls.mean().item(), nlls.std().item(), model, mean, k])\n",
|
||||
" \n",
|
||||
" return logger"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 25,
|
||||
"id": "5fe6b4d6-b49e-4e06-8874-9be43b4ee4bd",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"data_path = \"../../voltron/data/\"\n",
|
||||
"ticker_list = make_ticker_list(data_path + \"nasdaq100.txt\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 27,
|
||||
"id": "d9ed9129-be2d-47e8-9866-5a708c27d225",
|
||||
"metadata": {
|
||||
"collapsed": true,
|
||||
"jupyter": {
|
||||
"outputs_hidden": true
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- ALXN: No data found, symbol may be delisted\n",
|
||||
"failed ALXN\n",
|
||||
"failed CA\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- CELG: No data found, symbol may be delisted\n",
|
||||
"failed CELG\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- CTRP: No data found, symbol may be delisted\n",
|
||||
"failed CTRP\n",
|
||||
"failed ESRX\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- LVNTA: No data found for this date range, symbol may be delisted\n",
|
||||
"failed LVNTA\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- QVCA: No data found for this date range, symbol may be delisted\n",
|
||||
"failed QVCA\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- LMCA: No data found for this date range, symbol may be delisted\n",
|
||||
"failed LMCA\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- LMCK: No data found, symbol may be delisted\n",
|
||||
"failed LMCK\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- LLTC: No data found for this date range, symbol may be delisted\n",
|
||||
"failed LLTC\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- MXIM: No data found, symbol may be delisted\n",
|
||||
"failed MXIM\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- MYL: No data found, symbol may be delisted\n",
|
||||
"failed MYL\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- SYMC: No data found, symbol may be delisted\n",
|
||||
"failed SYMC\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- PCLN: No data found for this date range, symbol may be delisted\n",
|
||||
"failed PCLN\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- VIAB: No data found, symbol may be delisted\n",
|
||||
"failed VIAB\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- WFM: No data found for this date range, symbol may be delisted\n",
|
||||
"failed WFM\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- YHOO: No data found for this date range, symbol may be delisted\n",
|
||||
"failed YHOO\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"log = []\n",
|
||||
"end_date = \"2022-01-20\"\n",
|
||||
"for k in [400]:\n",
|
||||
" for mean in ['ewma']:\n",
|
||||
" log = GetNLL('volt', mean=mean, k=k, horizon=np.arange(75,100), \n",
|
||||
" logger=log, exp=True, fdir=\"../trading/saved-outputs/\")\n",
|
||||
" \n",
|
||||
"# log = GetNLL('matern', mean='constant', k=100, horizon=np.arange(75,100), \n",
|
||||
"# logger=log, exp=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 31,
|
||||
"id": "c00697ab-5884-4c70-9843-1bb49a52716f",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- ALXN: No data found, symbol may be delisted\n",
|
||||
"failed ALXN\n",
|
||||
"failed CA\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- CELG: No data found, symbol may be delisted\n",
|
||||
"failed CELG\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- CTRP: No data found, symbol may be delisted\n",
|
||||
"failed CTRP\n",
|
||||
"failed ESRX\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- LVNTA: No data found for this date range, symbol may be delisted\n",
|
||||
"failed LVNTA\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- QVCA: No data found for this date range, symbol may be delisted\n",
|
||||
"failed QVCA\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- LMCA: No data found for this date range, symbol may be delisted\n",
|
||||
"failed LMCA\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- LMCK: No data found, symbol may be delisted\n",
|
||||
"failed LMCK\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- LLTC: No data found for this date range, symbol may be delisted\n",
|
||||
"failed LLTC\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- MXIM: No data found, symbol may be delisted\n",
|
||||
"failed MXIM\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- MYL: No data found, symbol may be delisted\n",
|
||||
"failed MYL\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- SYMC: No data found, symbol may be delisted\n",
|
||||
"failed SYMC\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- PCLN: No data found for this date range, symbol may be delisted\n",
|
||||
"failed PCLN\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- VIAB: No data found, symbol may be delisted\n",
|
||||
"failed VIAB\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- WFM: No data found for this date range, symbol may be delisted\n",
|
||||
"failed WFM\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- YHOO: No data found for this date range, symbol may be delisted\n",
|
||||
"failed YHOO\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- ALXN: No data found, symbol may be delisted\n",
|
||||
"failed ALXN\n",
|
||||
"failed CA\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- CELG: No data found, symbol may be delisted\n",
|
||||
"failed CELG\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- CTRP: No data found, symbol may be delisted\n",
|
||||
"failed CTRP\n",
|
||||
"failed ESRX\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- LVNTA: No data found for this date range, symbol may be delisted\n",
|
||||
"failed LVNTA\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- QVCA: No data found for this date range, symbol may be delisted\n",
|
||||
"failed QVCA\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- LMCA: No data found for this date range, symbol may be delisted\n",
|
||||
"failed LMCA\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- LMCK: No data found, symbol may be delisted\n",
|
||||
"failed LMCK\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- LLTC: No data found for this date range, symbol may be delisted\n",
|
||||
"failed LLTC\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- MXIM: No data found, symbol may be delisted\n",
|
||||
"failed MXIM\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- MYL: No data found, symbol may be delisted\n",
|
||||
"failed MYL\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- SYMC: No data found, symbol may be delisted\n",
|
||||
"failed SYMC\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- PCLN: No data found for this date range, symbol may be delisted\n",
|
||||
"failed PCLN\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- VIAB: No data found, symbol may be delisted\n",
|
||||
"failed VIAB\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- WFM: No data found for this date range, symbol may be delisted\n",
|
||||
"failed WFM\n",
|
||||
"\n",
|
||||
"1 Failed download:\n",
|
||||
"- YHOO: No data found for this date range, symbol may be delisted\n",
|
||||
"failed YHOO\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"log = []\n",
|
||||
"end_date = \"2022-01-20\"\n",
|
||||
"log = GetNLL('sm', mean='constant', k=100, horizon=np.arange(75,100), \n",
|
||||
" logger=[], exp=True)\n",
|
||||
"log = GetNLL('sm', mean='ewma', k=400, horizon=np.arange(75,100), \n",
|
||||
" logger=log, exp=True)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 32,
|
||||
"id": "89054cf9-fb1c-45a1-aa8b-8884713f4c07",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df = pd.DataFrame(log)\n",
|
||||
"df.columns = [\"Mean_NLL\", \"NLL\", \"Std_NLL\", \"Model\", \"Mean\", \"k\"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 33,
|
||||
"id": "95915269-4bbf-4949-a944-37e076db8889",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"pd.to_pickle(df, \"./sm_nll.pkl\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 34,
|
||||
"id": "e2a5b10f-61a9-4876-a53c-385380955e28",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div>\n",
|
||||
"<style scoped>\n",
|
||||
" .dataframe tbody tr th:only-of-type {\n",
|
||||
" vertical-align: middle;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe tbody tr th {\n",
|
||||
" vertical-align: top;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe thead th {\n",
|
||||
" text-align: right;\n",
|
||||
" }\n",
|
||||
"</style>\n",
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>Mean_NLL</th>\n",
|
||||
" <th>NLL</th>\n",
|
||||
" <th>Std_NLL</th>\n",
|
||||
" <th>Model</th>\n",
|
||||
" <th>Mean</th>\n",
|
||||
" <th>k</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>3.201143e+06</td>\n",
|
||||
" <td>80.430728</td>\n",
|
||||
" <td>113.825740</td>\n",
|
||||
" <td>sm</td>\n",
|
||||
" <td>constant</td>\n",
|
||||
" <td>100</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1</th>\n",
|
||||
" <td>1.134694e+06</td>\n",
|
||||
" <td>147.842929</td>\n",
|
||||
" <td>161.222031</td>\n",
|
||||
" <td>sm</td>\n",
|
||||
" <td>ewma</td>\n",
|
||||
" <td>400</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>\n",
|
||||
"</div>"
|
||||
],
|
||||
"text/plain": [
|
||||
" Mean_NLL NLL Std_NLL Model Mean k\n",
|
||||
"0 3.201143e+06 80.430728 113.825740 sm constant 100\n",
|
||||
"1 1.134694e+06 147.842929 161.222031 sm ewma 400"
|
||||
]
|
||||
},
|
||||
"execution_count": 34,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"df"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "eb9db52e-d56a-47a8-86f5-05e43437c635",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## NLL Plotter"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 48,
|
||||
"id": "38b65cc2-ed27-41a6-ae83-5396a40b2e0d",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"nll = pd.read_pickle(\"./volt_matern_const_nll.pkl\")\n",
|
||||
"nll = pd.concat((nll, pd.read_pickle(\"volt_const_nll.pkl\")))\n",
|
||||
"mat_nll = pd.read_pickle(\"matern_nll.pkl\")\n",
|
||||
"mat_nll[mat_nll[\"Mean\"] != 'constant']\n",
|
||||
"mat_nll.columns = nll.columns\n",
|
||||
"nll = pd.concat((mat_nll, nll))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 49,
|
||||
"id": "7952ac2d-0036-4ce4-bcd9-f7b1cfe1ca68",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div>\n",
|
||||
"<style scoped>\n",
|
||||
" .dataframe tbody tr th:only-of-type {\n",
|
||||
" vertical-align: middle;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe tbody tr th {\n",
|
||||
" vertical-align: top;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe thead th {\n",
|
||||
" text-align: right;\n",
|
||||
" }\n",
|
||||
"</style>\n",
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>Mean_NLL</th>\n",
|
||||
" <th>NLL</th>\n",
|
||||
" <th>Std_NLL</th>\n",
|
||||
" <th>Model</th>\n",
|
||||
" <th>Mean</th>\n",
|
||||
" <th>k</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>6.726756e+04</td>\n",
|
||||
" <td>15.463807</td>\n",
|
||||
" <td>82.817116</td>\n",
|
||||
" <td>matern</td>\n",
|
||||
" <td>ewma</td>\n",
|
||||
" <td>100</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1</th>\n",
|
||||
" <td>5.704343e+04</td>\n",
|
||||
" <td>13.581769</td>\n",
|
||||
" <td>62.178253</td>\n",
|
||||
" <td>matern</td>\n",
|
||||
" <td>ewma</td>\n",
|
||||
" <td>200</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2</th>\n",
|
||||
" <td>6.180195e+04</td>\n",
|
||||
" <td>9.809834</td>\n",
|
||||
" <td>21.427580</td>\n",
|
||||
" <td>matern</td>\n",
|
||||
" <td>ewma</td>\n",
|
||||
" <td>400</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>3</th>\n",
|
||||
" <td>5.138178e+05</td>\n",
|
||||
" <td>107.045380</td>\n",
|
||||
" <td>558.429443</td>\n",
|
||||
" <td>matern</td>\n",
|
||||
" <td>dewma</td>\n",
|
||||
" <td>100</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>4</th>\n",
|
||||
" <td>1.109547e+05</td>\n",
|
||||
" <td>26.417788</td>\n",
|
||||
" <td>160.354996</td>\n",
|
||||
" <td>matern</td>\n",
|
||||
" <td>dewma</td>\n",
|
||||
" <td>200</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>5</th>\n",
|
||||
" <td>7.489107e+04</td>\n",
|
||||
" <td>11.611018</td>\n",
|
||||
" <td>42.626156</td>\n",
|
||||
" <td>matern</td>\n",
|
||||
" <td>dewma</td>\n",
|
||||
" <td>400</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>6</th>\n",
|
||||
" <td>3.585652e+06</td>\n",
|
||||
" <td>682.981384</td>\n",
|
||||
" <td>2605.378174</td>\n",
|
||||
" <td>matern</td>\n",
|
||||
" <td>tewma</td>\n",
|
||||
" <td>100</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>7</th>\n",
|
||||
" <td>1.216624e+05</td>\n",
|
||||
" <td>31.195498</td>\n",
|
||||
" <td>169.649368</td>\n",
|
||||
" <td>matern</td>\n",
|
||||
" <td>tewma</td>\n",
|
||||
" <td>200</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>8</th>\n",
|
||||
" <td>7.496416e+04</td>\n",
|
||||
" <td>11.622351</td>\n",
|
||||
" <td>42.427406</td>\n",
|
||||
" <td>matern</td>\n",
|
||||
" <td>tewma</td>\n",
|
||||
" <td>400</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>4.061322e+03</td>\n",
|
||||
" <td>7.735851</td>\n",
|
||||
" <td>4.734124</td>\n",
|
||||
" <td>matern</td>\n",
|
||||
" <td>constant</td>\n",
|
||||
" <td>100</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>1.173272e+03</td>\n",
|
||||
" <td>4.693086</td>\n",
|
||||
" <td>0.389815</td>\n",
|
||||
" <td>volt</td>\n",
|
||||
" <td>constant</td>\n",
|
||||
" <td>100</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>\n",
|
||||
"</div>"
|
||||
],
|
||||
"text/plain": [
|
||||
" Mean_NLL NLL Std_NLL Model Mean k\n",
|
||||
"0 6.726756e+04 15.463807 82.817116 matern ewma 100\n",
|
||||
"1 5.704343e+04 13.581769 62.178253 matern ewma 200\n",
|
||||
"2 6.180195e+04 9.809834 21.427580 matern ewma 400\n",
|
||||
"3 5.138178e+05 107.045380 558.429443 matern dewma 100\n",
|
||||
"4 1.109547e+05 26.417788 160.354996 matern dewma 200\n",
|
||||
"5 7.489107e+04 11.611018 42.626156 matern dewma 400\n",
|
||||
"6 3.585652e+06 682.981384 2605.378174 matern tewma 100\n",
|
||||
"7 1.216624e+05 31.195498 169.649368 matern tewma 200\n",
|
||||
"8 7.496416e+04 11.622351 42.427406 matern tewma 400\n",
|
||||
"0 4.061322e+03 7.735851 4.734124 matern constant 100\n",
|
||||
"0 1.173272e+03 4.693086 0.389815 volt constant 100"
|
||||
]
|
||||
},
|
||||
"execution_count": 49,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"nll"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 52,
|
||||
"id": "76d6abf1-8385-4450-9c0e-4e92f897bff8",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"/home/greg_b/miniconda3/envs/rpp/lib/python3.8/site-packages/pandas/core/indexing.py:1720: SettingWithCopyWarning: \n",
|
||||
"A value is trying to be set on a copy of a slice from a DataFrame.\n",
|
||||
"Try using .loc[row_indexer,col_indexer] = value instead\n",
|
||||
"\n",
|
||||
"See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
|
||||
" self._setitem_single_column(loc, value, pi)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"temp_df = nll[(nll['Mean'].isin(['constant', 'ewma']))]\n",
|
||||
"temp_df.loc[(temp_df['Mean']=='constant') & (temp_df['Model']=='volt'), 'k'] = 400\n",
|
||||
"temp_df.loc[(temp_df['Mean']=='constant') & (temp_df['Model']=='matern'), 'k'] = 400\n",
|
||||
"\n",
|
||||
"temp_df = temp_df[temp_df['k']==400]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 53,
|
||||
"id": "6582a178-a65f-4f24-a20e-8b8b17e56e5a",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div>\n",
|
||||
"<style scoped>\n",
|
||||
" .dataframe tbody tr th:only-of-type {\n",
|
||||
" vertical-align: middle;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe tbody tr th {\n",
|
||||
" vertical-align: top;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe thead th {\n",
|
||||
" text-align: right;\n",
|
||||
" }\n",
|
||||
"</style>\n",
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>Mean_NLL</th>\n",
|
||||
" <th>NLL</th>\n",
|
||||
" <th>Std_NLL</th>\n",
|
||||
" <th>Model</th>\n",
|
||||
" <th>Mean</th>\n",
|
||||
" <th>k</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>2</th>\n",
|
||||
" <td>61801.953125</td>\n",
|
||||
" <td>9.809834</td>\n",
|
||||
" <td>21.427580</td>\n",
|
||||
" <td>matern</td>\n",
|
||||
" <td>ewma</td>\n",
|
||||
" <td>400</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>4061.321999</td>\n",
|
||||
" <td>7.735851</td>\n",
|
||||
" <td>4.734124</td>\n",
|
||||
" <td>matern</td>\n",
|
||||
" <td>constant</td>\n",
|
||||
" <td>400</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>1173.271529</td>\n",
|
||||
" <td>4.693086</td>\n",
|
||||
" <td>0.389815</td>\n",
|
||||
" <td>volt</td>\n",
|
||||
" <td>constant</td>\n",
|
||||
" <td>400</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>\n",
|
||||
"</div>"
|
||||
],
|
||||
"text/plain": [
|
||||
" Mean_NLL NLL Std_NLL Model Mean k\n",
|
||||
"2 61801.953125 9.809834 21.427580 matern ewma 400\n",
|
||||
"0 4061.321999 7.735851 4.734124 matern constant 400\n",
|
||||
"0 1173.271529 4.693086 0.389815 volt constant 400"
|
||||
]
|
||||
},
|
||||
"execution_count": 53,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"temp_df"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 51,
|
||||
"id": "20d9682b-5e98-4793-8a65-42532cc476d9",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div>\n",
|
||||
"<style scoped>\n",
|
||||
" .dataframe tbody tr th:only-of-type {\n",
|
||||
" vertical-align: middle;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe tbody tr th {\n",
|
||||
" vertical-align: top;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe thead th {\n",
|
||||
" text-align: right;\n",
|
||||
" }\n",
|
||||
"</style>\n",
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>Mean_NLL</th>\n",
|
||||
" <th>NLL</th>\n",
|
||||
" <th>Std_NLL</th>\n",
|
||||
" <th>Model</th>\n",
|
||||
" <th>Mean</th>\n",
|
||||
" <th>k</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>2</th>\n",
|
||||
" <td>61801.953125</td>\n",
|
||||
" <td>9.809834</td>\n",
|
||||
" <td>21.427580</td>\n",
|
||||
" <td>matern</td>\n",
|
||||
" <td>ewma</td>\n",
|
||||
" <td>400</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>4061.321999</td>\n",
|
||||
" <td>7.735851</td>\n",
|
||||
" <td>4.734124</td>\n",
|
||||
" <td>matern</td>\n",
|
||||
" <td>constant</td>\n",
|
||||
" <td>400</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>1173.271529</td>\n",
|
||||
" <td>4.693086</td>\n",
|
||||
" <td>0.389815</td>\n",
|
||||
" <td>volt</td>\n",
|
||||
" <td>constant</td>\n",
|
||||
" <td>400</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>\n",
|
||||
"</div>"
|
||||
],
|
||||
"text/plain": [
|
||||
" Mean_NLL NLL Std_NLL Model Mean k\n",
|
||||
"2 61801.953125 9.809834 21.427580 matern ewma 400\n",
|
||||
"0 4061.321999 7.735851 4.734124 matern constant 400\n",
|
||||
"0 1173.271529 4.693086 0.389815 volt constant 400"
|
||||
]
|
||||
},
|
||||
"execution_count": 51,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"temp_df"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "2cb0ed8b-e4d7-4b78-b676-96d7123ad643",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.8.8"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Vendored
BIN
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -1,232 +0,0 @@
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
import seaborn as sns
|
||||
import torch
|
||||
import gpytorch
|
||||
# from voltron.robinhood_utils import GetStockData
|
||||
import os
|
||||
# import robin_stocks.robinhood as r
|
||||
import pickle5 as pickle
|
||||
|
||||
sns.set_style("whitegrid")
|
||||
sns.set_palette("bright")
|
||||
|
||||
sns.set(font_scale=2.0)
|
||||
sns.set_style('whitegrid')
|
||||
|
||||
import sys
|
||||
sys.path.append("../")
|
||||
from voltron.likelihoods import VolatilityGaussianLikelihood
|
||||
from voltron.models import SingleTaskVariationalGP as SingleTaskCopulaProcessModel
|
||||
from voltron.kernels import BMKernel, VolatilityKernel
|
||||
from voltron.models import BMGP, VoltronGP, MaternGP, SMGP
|
||||
from voltron.means import LogLinearMean
|
||||
from gpytorch.kernels import ScaleKernel, RBFKernel, MaternKernel
|
||||
|
||||
def get_and_fit_gpcv(x, log_returns, printing=False):
|
||||
train_x = x[:-1]
|
||||
dt = train_x[1]-train_x[0]
|
||||
# prepare model
|
||||
likelihood = VolatilityGaussianLikelihood(param="exp")
|
||||
# likelihood.raw_a.data -= 6.
|
||||
covar_module = BMKernel()
|
||||
model = SingleTaskCopulaProcessModel(
|
||||
init_points=train_x.view(-1,1),
|
||||
likelihood=likelihood,
|
||||
use_piv_chol_init=False,
|
||||
mean_module = gpytorch.means.ConstantMean(),
|
||||
covar_module=covar_module,
|
||||
learn_inducing_locations=False
|
||||
)
|
||||
model.mean_module.constant.data -= 4.
|
||||
# model.initialize_variational_parameters(likelihood, train_x, y=log_returns)
|
||||
|
||||
import os
|
||||
smoke_test = ('CI' in os.environ)
|
||||
training_iterations = 2 if smoke_test else 500
|
||||
|
||||
|
||||
# Find optimal model hyperparameters
|
||||
model.train()
|
||||
likelihood.train()
|
||||
|
||||
# Use the adam optimizer
|
||||
# likelihood parameters should be taken acct of in the model
|
||||
optimizer = torch.optim.Adam([
|
||||
{"params": model.parameters()},
|
||||
# {"params": likelihood.parameters(), "lr": 0.1}
|
||||
], lr=0.01)
|
||||
|
||||
# "Loss" for GPs - the marginal log likelihood
|
||||
# num_data refers to the number of training datapoints
|
||||
mll = gpytorch.mlls.VariationalELBO(likelihood, model, log_returns.numel())
|
||||
|
||||
old_loss = 10000.
|
||||
print_every = 50
|
||||
for i in range(training_iterations):
|
||||
# Zero backpropped gradients from previous iteration
|
||||
optimizer.zero_grad()
|
||||
# Get predictive output
|
||||
with gpytorch.settings.num_gauss_hermite_locs(75):
|
||||
output = model(train_x)
|
||||
# Calc loss and backprop gradients
|
||||
loss = -mll(output, log_returns)
|
||||
loss.backward()
|
||||
if printing:
|
||||
if i % print_every == 0:
|
||||
print('Iter %d/%d - Loss: %.3f' % (i + 1,
|
||||
training_iterations,
|
||||
loss.item()))
|
||||
optimizer.step()
|
||||
if old_loss <= loss and i > 100:
|
||||
if printing:
|
||||
print(old_loss, loss)
|
||||
break
|
||||
else:
|
||||
old_loss = loss.item()
|
||||
|
||||
model.eval();
|
||||
likelihood.eval();
|
||||
predictive = model(x)
|
||||
pred_scale = likelihood(predictive).scale.mean(0).detach()
|
||||
samples = likelihood(predictive).scale.detach()
|
||||
|
||||
# plt.plot(x, pred_scale, linewidth = 4)
|
||||
# plt.plot(x, samples.t(), color = "gray", alpha = 0.3)
|
||||
# # plt.ylim((0, 0.25))
|
||||
# plt.show()
|
||||
|
||||
# return scaled volatility prediction
|
||||
return pred_scale / dt**0.5
|
||||
|
||||
def get_and_fit_vol_model(train_x, est_vol):
|
||||
vol_lh = gpytorch.likelihoods.GaussianLikelihood()
|
||||
vol_lh.noise.data = torch.tensor([1e-6])
|
||||
vol_model = BMGP(train_x, est_vol.log(), vol_lh)
|
||||
|
||||
optimizer = torch.optim.Adam([
|
||||
{'params': vol_model.parameters()}, # Includes GaussianLikelihood parameters
|
||||
], lr=0.01)
|
||||
|
||||
# "Loss" for GPs - the marginal log likelihood
|
||||
mll = gpytorch.mlls.ExactMarginalLogLikelihood(vol_lh, vol_model)
|
||||
old_loss = 10000
|
||||
for i in range(500):
|
||||
# Zero gradients from previous iteration
|
||||
optimizer.zero_grad()
|
||||
# Output from model
|
||||
output = vol_model(train_x)
|
||||
# Calc loss and backprop gradients
|
||||
loss = -mll(output, est_vol.log())
|
||||
loss.backward()
|
||||
if i % 50 == 0:
|
||||
print(loss.item())
|
||||
optimizer.step()
|
||||
# if old_loss <= loss:
|
||||
# break
|
||||
# else:
|
||||
# old_loss = loss.item()
|
||||
|
||||
return vol_model
|
||||
|
||||
def get_and_fit_data_model(train_x, train_y, pred_vol, vol_model):
|
||||
voltron_lh = gpytorch.likelihoods.GaussianLikelihood()
|
||||
voltron = VoltronGP(train_x, train_y.log(), voltron_lh, pred_vol)
|
||||
# voltron.mean_module = gpytorch.means.LinearMean(1)
|
||||
voltron.mean_module = LogLinearMean(1)
|
||||
voltron.mean_module.initialize_from_data(train_x, train_y.log())
|
||||
voltron.likelihood.raw_noise.data = torch.tensor([1e-6])
|
||||
voltron.vol_lh = vol_model.likelihood
|
||||
voltron.vol_model = vol_model
|
||||
|
||||
grad_flags = [False, True, True, True, False, False, False]
|
||||
|
||||
for idx, p in enumerate(voltron.parameters()):
|
||||
p.requires_grad = grad_flags[idx]
|
||||
|
||||
voltron.train();
|
||||
voltron_lh.train();
|
||||
voltron.vol_lh.train();
|
||||
voltron.vol_model.train();
|
||||
|
||||
# Use the adam optimizer
|
||||
optimizer = torch.optim.Adam([
|
||||
{'params': voltron.parameters()}, # Includes GaussianLikelihood parameters
|
||||
], lr=0.1)
|
||||
|
||||
# "Loss" for GPs - the marginal log likelihood
|
||||
mll = gpytorch.mlls.ExactMarginalLogLikelihood(voltron_lh, voltron)
|
||||
|
||||
for i in range(500):
|
||||
# Zero gradients from previous iteration
|
||||
optimizer.zero_grad()
|
||||
# Output from model
|
||||
output = voltron(train_x)
|
||||
# Calc loss and backprop gradients
|
||||
loss = -mll(output, train_y.log())
|
||||
loss.backward()
|
||||
# print(loss.item())
|
||||
optimizer.step()
|
||||
return voltron
|
||||
|
||||
def predict_prices(test_x, voltron, nvol=10, npx=10):
|
||||
ntest = test_x.shape[0]
|
||||
vol_paths = torch.zeros(nvol, ntest)
|
||||
px_paths = torch.zeros(npx*nvol, ntest)
|
||||
|
||||
voltron.vol_model.eval();
|
||||
voltron.eval();
|
||||
|
||||
for vidx in range(nvol):
|
||||
vol_pred = voltron.vol_model(test_x).sample().exp()
|
||||
vol_paths[vidx, :] = vol_pred.detach()
|
||||
|
||||
px_pred = voltron.GeneratePrediction(test_x, vol_pred, npx).exp()
|
||||
px_paths[vidx*npx:(vidx*npx+npx), :] = px_pred.detach().T
|
||||
return px_paths
|
||||
|
||||
def get_and_fit_basic_model(train_x, train_y, cov="matern", mean="loglinear"):
|
||||
voltron_lh = gpytorch.likelihoods.GaussianLikelihood()
|
||||
# voltron = VoltronGP(train_x, train_y.log(), voltron_lh, pred_vol)
|
||||
if cov == "matern":
|
||||
model = MaternGP(train_x,
|
||||
train_y.log(), likelihood=voltron_lh)
|
||||
else:
|
||||
model = SMGP(train_x,
|
||||
train_y.log(), likelihood=voltron_lh)
|
||||
if mean == "loglinear":
|
||||
model.mean_module = LogLinearMean(1)
|
||||
model.mean_module.initialize_from_data(train_x, train_y.log())
|
||||
else:
|
||||
model.mean_module = gpytorch.means.ConstantMean()
|
||||
|
||||
|
||||
model.likelihood.raw_noise.data = torch.tensor([1e-6])
|
||||
|
||||
# Use the adam optimizer
|
||||
optimizer = torch.optim.Adam([
|
||||
{'params': model.parameters()}, # Includes GaussianLikelihood parameters
|
||||
], lr=0.1)
|
||||
|
||||
# "Loss" for GPs - the marginal log likelihood
|
||||
mll = gpytorch.mlls.ExactMarginalLogLikelihood(voltron_lh, model)
|
||||
|
||||
for i in range(500):
|
||||
# Zero gradients from previous iteration
|
||||
optimizer.zero_grad()
|
||||
# Output from model
|
||||
output = model(train_x)
|
||||
# Calc loss and backprop gradients
|
||||
loss = -mll(output, train_y.log())
|
||||
loss.backward()
|
||||
# print(loss.item())
|
||||
optimizer.step()
|
||||
return model, voltron_lh
|
||||
|
||||
def predict_basic_prices(test_x, voltron, voltron_lh, npath=1000):
|
||||
ntest = test_x.shape[0]
|
||||
voltron.eval();
|
||||
mod = voltron_lh(voltron(test_x))
|
||||
px_paths = mod.sample(torch.Size(((npath),))).exp().squeeze(-1)
|
||||
|
||||
return px_paths
|
||||
@@ -1,71 +0,0 @@
|
||||
import matplotlib.pyplot as plt
|
||||
import seaborn as sns
|
||||
import numpy as np
|
||||
import torch
|
||||
import pandas as pd
|
||||
|
||||
import gpytorch
|
||||
from torch.nn.functional import softplus
|
||||
from voltron.kernels import BMKernel, VolatilityKernel
|
||||
from voltron.models import BMGP, VoltronGP
|
||||
import argparse
|
||||
from torch.distributions import Beta
|
||||
from scipy.special import betainc
|
||||
from Trainers import *
|
||||
|
||||
def main(args):
|
||||
full_data = pd.read_pickle("../../spdr-data/" + args.SPDR + ".pkl")
|
||||
tckrs = full_data.symbol.unique()
|
||||
|
||||
for tckr in tckrs:
|
||||
data = full_data[full_data["symbol"] == tckr]
|
||||
|
||||
ts = torch.linspace(0, data.shape[0]/252., data.shape[0])
|
||||
# train_x = ts[:ntrain]
|
||||
# test_x = ts[ntrain:(ntrain+ntest)]
|
||||
|
||||
y = torch.FloatTensor(data['close_price'].to_numpy())
|
||||
log_returns = torch.log(y[1:]) - torch.log(y[:-1])
|
||||
dt = ts[1] - ts[0]
|
||||
|
||||
eval_times = list(range(100, ts.shape[0], 100)) #+ [ts.shape[0]]
|
||||
prob_of_increases = []
|
||||
|
||||
for i, time in enumerate(eval_times):
|
||||
print("now running time: ", time)
|
||||
with gpytorch.settings.max_cholesky_size(2000):
|
||||
data_model, data_lh = get_and_fit_basic_model(ts[:time], y[:time],
|
||||
cov=args.kernel, mean=args.mean)
|
||||
end_ind = -1 if i + 1 >= len(eval_times) else eval_times[i+1]
|
||||
paths = predict_basic_prices(ts[time:end_ind], data_model,
|
||||
data_lh).detach()
|
||||
# now we predict the probability of increase at time i + 1
|
||||
prob_of_increase = (paths[..., -1] > y[time]).sum() / paths.shape[-2]
|
||||
print("prob of stock increase: ", prob_of_increase.detach())
|
||||
|
||||
prob_of_increases.append(prob_of_increase.detach())
|
||||
|
||||
torch.save(obj=prob_of_increases, f="./outputs/" + args.kernel + "_" + tckr + ".pt")
|
||||
print(tckr, "Done")
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument(
|
||||
"--SPDR",
|
||||
type=str,
|
||||
default="XLE",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--kernel",
|
||||
type=str,
|
||||
default="matern",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--mean",
|
||||
type=str,
|
||||
default="loglinear",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
main(args)
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
@@ -1,270 +0,0 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 15,
|
||||
"id": "ddc44d8f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import glob"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 29,
|
||||
"id": "79dbbbf6",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"start = r\"\"\"\n",
|
||||
"\\begin{figure}\n",
|
||||
" \\centering\n",
|
||||
" \\includegraphics[width=\\linewidth]{figs/\"\"\"\n",
|
||||
"\n",
|
||||
"mid = r\"\"\"}\n",
|
||||
" \\caption{Trading Strategy for \"\"\"\n",
|
||||
"end = \"\"\".}\n",
|
||||
"\\end{figure}\n",
|
||||
"\"\"\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 26,
|
||||
"id": "ef42d2c4",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"files = glob.glob(\"./trading*\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 27,
|
||||
"id": "40d9639b",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'WFC'"
|
||||
]
|
||||
},
|
||||
"execution_count": 27,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"files[0].split(\"_\")[-1][:-4]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 30,
|
||||
"id": "c802c9e3",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"\\begin{figure}\n",
|
||||
" \\centering\n",
|
||||
" \\includegraphics[width=\\linewidth]{figs/./trading_strategy_WFC.pdf}\n",
|
||||
" \\caption{Trading Strategy for WFC.}\n",
|
||||
"\\end{figure}\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(start + files[0] + mid + files[0].split(\"_\")[-1][:-4] + end)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 37,
|
||||
"id": "b8a6a5fa",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"\\begin{figure}\n",
|
||||
" \\centering\n",
|
||||
" \\includegraphics[width=\\linewidth]{figs/trading_strategy_WFC.pdf}\n",
|
||||
" \\caption{Trading Strategy for WFC.}\n",
|
||||
"\\end{figure}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\\begin{figure}\n",
|
||||
" \\centering\n",
|
||||
" \\includegraphics[width=\\linewidth]{figs/trading_strategy_PLD.pdf}\n",
|
||||
" \\caption{Trading Strategy for PLD.}\n",
|
||||
"\\end{figure}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\\begin{figure}\n",
|
||||
" \\centering\n",
|
||||
" \\includegraphics[width=\\linewidth]{figs/trading_strategy_EOG.pdf}\n",
|
||||
" \\caption{Trading Strategy for EOG.}\n",
|
||||
"\\end{figure}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\\begin{figure}\n",
|
||||
" \\centering\n",
|
||||
" \\includegraphics[width=\\linewidth]{figs/trading_strategy_COP.pdf}\n",
|
||||
" \\caption{Trading Strategy for COP.}\n",
|
||||
"\\end{figure}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\\begin{figure}\n",
|
||||
" \\centering\n",
|
||||
" \\includegraphics[width=\\linewidth]{figs/trading_strategy_JPM.pdf}\n",
|
||||
" \\caption{Trading Strategy for JPM.}\n",
|
||||
"\\end{figure}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\\begin{figure}\n",
|
||||
" \\centering\n",
|
||||
" \\includegraphics[width=\\linewidth]{figs/trading_strategy_BRK.B.pdf}\n",
|
||||
" \\caption{Trading Strategy for BRK.B.}\n",
|
||||
"\\end{figure}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\\begin{figure}\n",
|
||||
" \\centering\n",
|
||||
" \\includegraphics[width=\\linewidth]{figs/trading_strategy_BLK.pdf}\n",
|
||||
" \\caption{Trading Strategy for BLK.}\n",
|
||||
"\\end{figure}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\\begin{figure}\n",
|
||||
" \\centering\n",
|
||||
" \\includegraphics[width=\\linewidth]{figs/trading_strategy_C.pdf}\n",
|
||||
" \\caption{Trading Strategy for C.}\n",
|
||||
"\\end{figure}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\\begin{figure}\n",
|
||||
" \\centering\n",
|
||||
" \\includegraphics[width=\\linewidth]{figs/trading_strategy_SLB.pdf}\n",
|
||||
" \\caption{Trading Strategy for SLB.}\n",
|
||||
"\\end{figure}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\\begin{figure}\n",
|
||||
" \\centering\n",
|
||||
" \\includegraphics[width=\\linewidth]{figs/trading_strategy_BAC.pdf}\n",
|
||||
" \\caption{Trading Strategy for BAC.}\n",
|
||||
"\\end{figure}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\\begin{figure}\n",
|
||||
" \\centering\n",
|
||||
" \\includegraphics[width=\\linewidth]{figs/trading_strategy_MS.pdf}\n",
|
||||
" \\caption{Trading Strategy for MS.}\n",
|
||||
"\\end{figure}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\\begin{figure}\n",
|
||||
" \\centering\n",
|
||||
" \\includegraphics[width=\\linewidth]{figs/trading_strategy_SCHW.pdf}\n",
|
||||
" \\caption{Trading Strategy for SCHW.}\n",
|
||||
"\\end{figure}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\\begin{figure}\n",
|
||||
" \\centering\n",
|
||||
" \\includegraphics[width=\\linewidth]{figs/trading_strategy_GS.pdf}\n",
|
||||
" \\caption{Trading Strategy for GS.}\n",
|
||||
"\\end{figure}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\\begin{figure}\n",
|
||||
" \\centering\n",
|
||||
" \\includegraphics[width=\\linewidth]{figs/trading_strategy_CCI.pdf}\n",
|
||||
" \\caption{Trading Strategy for CCI.}\n",
|
||||
"\\end{figure}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\\begin{figure}\n",
|
||||
" \\centering\n",
|
||||
" \\includegraphics[width=\\linewidth]{figs/trading_strategy_AMT.pdf}\n",
|
||||
" \\caption{Trading Strategy for AMT.}\n",
|
||||
"\\end{figure}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\\begin{figure}\n",
|
||||
" \\centering\n",
|
||||
" \\includegraphics[width=\\linewidth]{figs/trading_strategy_XOM.pdf}\n",
|
||||
" \\caption{Trading Strategy for XOM.}\n",
|
||||
"\\end{figure}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\\begin{figure}\n",
|
||||
" \\centering\n",
|
||||
" \\includegraphics[width=\\linewidth]{figs/trading_strategy_CVX.pdf}\n",
|
||||
" \\caption{Trading Strategy for CVX.}\n",
|
||||
"\\end{figure}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\\begin{figure}\n",
|
||||
" \\centering\n",
|
||||
" \\includegraphics[width=\\linewidth]{figs/trading_strategy_EQIX.pdf}\n",
|
||||
" \\caption{Trading Strategy for EQIX.}\n",
|
||||
"\\end{figure}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\\begin{figure}\n",
|
||||
" \\centering\n",
|
||||
" \\includegraphics[width=\\linewidth]{figs/trading_strategy_AXP.pdf}\n",
|
||||
" \\caption{Trading Strategy for AXP.}\n",
|
||||
"\\end{figure}\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"for stck in files:\n",
|
||||
" tckr = stck.split(\"_\")[-1][:-4]\n",
|
||||
" print(start + stck[2:] + mid + tckr + end)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c9e72667",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.8.3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,61 +0,0 @@
|
||||
import matplotlib.pyplot as plt
|
||||
import seaborn as sns
|
||||
import numpy as np
|
||||
import torch
|
||||
import pandas as pd
|
||||
|
||||
import gpytorch
|
||||
from torch.nn.functional import softplus
|
||||
from voltron.kernels import BMKernel, VolatilityKernel
|
||||
from voltron.models import BMGP, VoltronGP
|
||||
import argparse
|
||||
from torch.distributions import Beta
|
||||
from scipy.special import betainc
|
||||
from Trainers import *
|
||||
|
||||
def main(args):
|
||||
full_data = pd.read_pickle("../../spdr-data/" + args.SPDR + ".pkl")
|
||||
tckrs = full_data.symbol.unique()
|
||||
|
||||
for tckr in tckrs:
|
||||
data = full_data[full_data["symbol"] == tckr]
|
||||
|
||||
ts = torch.linspace(0, data.shape[0]/252., data.shape[0])
|
||||
# train_x = ts[:ntrain]
|
||||
# test_x = ts[ntrain:(ntrain+ntest)]
|
||||
|
||||
y = torch.FloatTensor(data['close_price'].to_numpy())
|
||||
log_returns = torch.log(y[1:]) - torch.log(y[:-1])
|
||||
dt = ts[1] - ts[0]
|
||||
|
||||
eval_times = list(range(100, ts.shape[0], 100)) #+ [ts.shape[0]]
|
||||
prob_of_increases = []
|
||||
|
||||
for i, time in enumerate(eval_times):
|
||||
print("now running time: ", time)
|
||||
with gpytorch.settings.max_cholesky_size(2000):
|
||||
pred_vol = get_and_fit_gpcv(ts[:time], log_returns[:(time - 1)])
|
||||
vol_model = get_and_fit_vol_model(ts[:time], pred_vol)
|
||||
data_model = get_and_fit_data_model(ts[:time], y[:time],
|
||||
pred_vol, vol_model)
|
||||
end_ind = -1 if i + 1 >= len(eval_times) else eval_times[i+1]
|
||||
paths = predict_prices(ts[time:end_ind], data_model).detach()
|
||||
# now we predict the probability of increase at time i + 1
|
||||
prob_of_increase = (paths[..., -1] > y[time]).sum() / paths.shape[-2]
|
||||
# print("prob of stock increase: ", prob_of_increase.detach())
|
||||
|
||||
prob_of_increases.append(prob_of_increase.detach())
|
||||
|
||||
torch.save(obj=prob_of_increases, f="./outputs/voltron_" + tckr + ".pt")
|
||||
print(tckr, "Done")
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument(
|
||||
"--SPDR",
|
||||
type=str,
|
||||
default="XLE",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
main(args)
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Vendored
BIN
Binary file not shown.
+37
-39
@@ -7,66 +7,64 @@ import datetime
|
||||
import warnings
|
||||
|
||||
from voltron.data import make_ticker_list, GetStockHistory
|
||||
from GenerateMultiMeanPreds import GenerateStockPredictions, GenerateBasicPredictions, GenerateOneDayPredictions
|
||||
import sys
|
||||
from GenerateMultiMeanPreds import GenerateStockPredictions, GenerateBasicPredictions
|
||||
from gpytorch.utils.warnings import NumericalWarning
|
||||
warnings.simplefilter("ignore", NumericalWarning)
|
||||
warnings.simplefilter("ignore", UserWarning)
|
||||
|
||||
def main(args):
|
||||
tckr = args.ticker
|
||||
## download data ##
|
||||
|
||||
|
||||
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").date()
|
||||
|
||||
dat = GetStockHistory(tckr, history=args.ntrain + args.lookback,
|
||||
end_date=str(end_date))
|
||||
end_date = datetime.datetime.strptime(args.end_date, "%Y-%m-%d")
|
||||
|
||||
## pick a day to generate forecasts ##
|
||||
end_idxs = torch.arange(args.ntrain, dat.shape[0],
|
||||
int((dat.shape[0]-args.ntrain)/args.ntimes))
|
||||
last_day = end_idxs[args.test_idx]
|
||||
date = str(dat.index[last_day.item()].date())
|
||||
|
||||
print(date, tckr)
|
||||
|
||||
train_y = torch.FloatTensor(dat.Close[last_day.item()-args.ntrain:last_day.item()].to_numpy())
|
||||
|
||||
GenerateOneDayPredictions(tckr, train_y, date,
|
||||
forecast_horizon=args.forecast_horizon,
|
||||
train_iters=args.train_iters,
|
||||
nsample=args.nsample,
|
||||
ntrain=400, save=args.save, mean=args.mean)
|
||||
|
||||
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(
|
||||
"--test_idx",
|
||||
type=int,
|
||||
default=0,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--forecast_horizon",
|
||||
type=int,
|
||||
default=100,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--ticker",
|
||||
type=str,
|
||||
default='ADBE',
|
||||
)
|
||||
parser.add_argument(
|
||||
"--ntrain",
|
||||
type=int,
|
||||
default=400,
|
||||
)
|
||||
parser.add_argument(
|
||||
'--kernel',
|
||||
type=str,
|
||||
@@ -1,152 +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
|
||||
sys.path.append("../trading/")
|
||||
from GenerateMultiMeanPreds import GenerateStockPredictions, GenerateBasicPredictions
|
||||
from gpytorch.utils.warnings import NumericalWarning
|
||||
warnings.simplefilter("ignore", NumericalWarning)
|
||||
|
||||
def main(args):
|
||||
|
||||
if args.end_date is None:
|
||||
end_date = datetime.date.today()
|
||||
else:
|
||||
end_date = datetime.datetime.strptime(args.end_date, "%Y-%m-%d")
|
||||
|
||||
data = GetStockHistory(args.ticker, history=args.ntrain + args.lookback)
|
||||
|
||||
ntest = args.forecast_horizon
|
||||
ntrain = args.ntrain
|
||||
n_test_times = args.n_test_times
|
||||
ntime = data.shape[0]
|
||||
|
||||
test_idxs = torch.arange(ntrain, ntime-ntest,
|
||||
int((ntime-ntest-ntrain)/n_test_times))
|
||||
|
||||
train_x = torch.arange(ntrain) * dt
|
||||
test_x = torch.arange(ntest) * dt + train_x[-1] + dt
|
||||
|
||||
if torch.cuda.is_available():
|
||||
train_x = train_x.cuda()
|
||||
test_x = test_x.cuda()
|
||||
|
||||
####################
|
||||
## setup filename ##
|
||||
####################
|
||||
savepath = "./saved-outputs/" + args.ticker + "/"
|
||||
if not os.path.exists(savepath):
|
||||
os.mkdir(savepath)
|
||||
|
||||
if args.model.lower() == 'lstm':
|
||||
modelname = "lstm"
|
||||
else:
|
||||
if args.model.lower() == 'gp':
|
||||
modelname = "gp_" + args.kernel + "_"
|
||||
elif args.model.lower() == 'volt':
|
||||
modelname = "volt_"
|
||||
|
||||
if args.mean.lower() == 'constant':
|
||||
modelname += 'constant' + "_"
|
||||
elif args.mean.lower() in ['ewma', 'dewma', 'tewma']:
|
||||
modelname += args.mean + args.k + "_"
|
||||
|
||||
|
||||
###############
|
||||
## Main Loop ##
|
||||
###############
|
||||
|
||||
for last_day in test_idxs:
|
||||
date = str(data.index[last_day.item()].date())
|
||||
train_y = data.Close[last_day.item()-ntrain:last_day.item()].to_numpy()
|
||||
train_y = torch.FloatTensor(train_y).to(train_x.device)
|
||||
|
||||
if args.model.lower() == 'lstm':
|
||||
model = LSTM(train_x, train_y, 10, 128, 1)
|
||||
model.Train(args.train_iters)
|
||||
elif args.model.lower() == 'gp':
|
||||
model = BasicGP(train_x, train_y, kernel=args.kernel,
|
||||
mean=args.mean, k=args.k)
|
||||
model.Train(args.train_iters)
|
||||
elif args.model.lower() == 'volt':
|
||||
model = Volt(train_x, train_y, mean=args.mean, k=args.k)
|
||||
model.Train(gpcv_iters=args.train_iters,
|
||||
vol_mod_iters=args.train_iters,
|
||||
data_mod_iters=args.train_iters)
|
||||
else:
|
||||
print("ERROR: Model not found")
|
||||
|
||||
|
||||
samples = model.Forecast(test_x).squeeze()
|
||||
torch.save(samples, savepath + modelname + date + ".pt")
|
||||
torch.cuda.empty_cache()
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--ticker",
|
||||
type=str,
|
||||
default='F',
|
||||
)
|
||||
parser.add_argument(
|
||||
"--ntrain",
|
||||
type=int,
|
||||
default=400,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--n_test_times",
|
||||
type=int,
|
||||
default=25,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--forecast_horizon",
|
||||
type=int,
|
||||
default=100,
|
||||
)
|
||||
parser.add_argument(
|
||||
'--kernel',
|
||||
type=str,
|
||||
default="matern",
|
||||
)
|
||||
parser.add_argument(
|
||||
'--model',
|
||||
type=str,
|
||||
default="volt",
|
||||
)
|
||||
parser.add_argument(
|
||||
'--mean',
|
||||
type=str,
|
||||
default="ewma",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--nsample",
|
||||
type=int,
|
||||
default=1000,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--train_iters",
|
||||
type=int,
|
||||
default=500,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--end_date",
|
||||
default=None,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--lookback",
|
||||
type=int,
|
||||
default=500,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--k",
|
||||
type=int,
|
||||
default=100,
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
main(args)
|
||||
@@ -0,0 +1,298 @@
|
||||
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
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"cells": [],
|
||||
"metadata": {},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
AAPL
|
||||
MSFT
|
||||
GOOG
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+18
-19
@@ -8,7 +8,6 @@ import warnings
|
||||
|
||||
from voltron.data import make_ticker_list, GetStockHistory
|
||||
import sys
|
||||
sys.path.append("../trading/")
|
||||
from GenerateMultiMeanPreds import GenerateStockPredictions, GenerateBasicPredictions
|
||||
from gpytorch.utils.warnings import NumericalWarning
|
||||
warnings.simplefilter("ignore", NumericalWarning)
|
||||
@@ -16,33 +15,33 @@ warnings.simplefilter("ignore", NumericalWarning)
|
||||
def main(args):
|
||||
|
||||
|
||||
data_path = "../../voltron/data/"
|
||||
ticker_file = args.ticker_fname + ".txt"
|
||||
tckr_list = make_ticker_list(data_path + ticker_file)
|
||||
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")
|
||||
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_name=args.mean,
|
||||
ntrain=args.ntrain, save=args.save)
|
||||
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)
|
||||
# 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)
|
||||
# except:
|
||||
# print("FAILED ", tckr)
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
@@ -1,152 +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
|
||||
sys.path.append("../trading/")
|
||||
from GenerateMultiMeanPreds import GenerateStockPredictions, GenerateBasicPredictions
|
||||
from gpytorch.utils.warnings import NumericalWarning
|
||||
warnings.simplefilter("ignore", NumericalWarning)
|
||||
|
||||
def main(args):
|
||||
|
||||
if args.end_date is None:
|
||||
end_date = datetime.date.today()
|
||||
else:
|
||||
end_date = datetime.datetime.strptime(args.end_date, "%Y-%m-%d")
|
||||
|
||||
data = GetStockHistory(args.ticker, history=args.ntrain + args.lookback)
|
||||
|
||||
ntest = args.forecast_horizon
|
||||
ntrain = args.ntrain
|
||||
n_test_times = args.n_test_times
|
||||
ntime = data.shape[0]
|
||||
|
||||
test_idxs = torch.arange(ntrain, ntime-ntest,
|
||||
int((ntime-ntest-ntrain)/n_test_times))
|
||||
|
||||
train_x = torch.arange(ntrain) * dt
|
||||
test_x = torch.arange(ntest) * dt + train_x[-1] + dt
|
||||
|
||||
if torch.cuda.is_available():
|
||||
train_x = train_x.cuda()
|
||||
test_x = test_x.cuda()
|
||||
|
||||
####################
|
||||
## setup filename ##
|
||||
####################
|
||||
savepath = "./saved-outputs/" + args.ticker + "/"
|
||||
if not os.path.exists(savepath):
|
||||
os.mkdir(savepath)
|
||||
|
||||
if args.model.lower() == 'lstm':
|
||||
modelname = "lstm"
|
||||
else:
|
||||
if args.model.lower() == 'gp':
|
||||
modelname = "gp_" + args.kernel + "_"
|
||||
elif args.model.lower() == 'volt':
|
||||
modelname = "volt_"
|
||||
|
||||
if args.mean.lower() == 'constant':
|
||||
modelname += 'constant' + "_"
|
||||
elif args.mean.lower() in ['ewma', 'dewma', 'tewma']:
|
||||
modelname += args.mean + args.k + "_"
|
||||
|
||||
|
||||
###############
|
||||
## Main Loop ##
|
||||
###############
|
||||
|
||||
for last_day in test_idxs:
|
||||
date = str(data.index[last_day.item()].date())
|
||||
train_y = data.Close[last_day.item()-ntrain:last_day.item()].to_numpy()
|
||||
train_y = torch.FloatTensor(train_y).to(train_x.device)
|
||||
|
||||
if args.model.lower() == 'lstm':
|
||||
model = LSTM(train_x, train_y, 10, 128, 1)
|
||||
model.Train(args.train_iters)
|
||||
elif args.model.lower() == 'gp':
|
||||
model = BasicGP(train_x, train_y, kernel=args.kernel,
|
||||
mean=args.mean, k=args.k)
|
||||
model.Train(args.train_iters)
|
||||
elif args.model.lower() == 'volt':
|
||||
model = Volt(train_x, train_y, mean=args.mean, k=args.k)
|
||||
model.Train(gpcv_iters=args.train_iters,
|
||||
vol_mod_iters=args.train_iters,
|
||||
data_mod_iters=args.train_iters)
|
||||
else:
|
||||
print("ERROR: Model not found")
|
||||
|
||||
|
||||
samples = model.Forecast(test_x).squeeze()
|
||||
torch.save(samples, savepath + modelname + date + ".pt")
|
||||
torch.cuda.empty_cache()
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--ticker",
|
||||
type=str,
|
||||
default='F',
|
||||
)
|
||||
parser.add_argument(
|
||||
"--ntrain",
|
||||
type=int,
|
||||
default=400,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--n_test_times",
|
||||
type=int,
|
||||
default=25,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--forecast_horizon",
|
||||
type=int,
|
||||
default=100,
|
||||
)
|
||||
parser.add_argument(
|
||||
'--kernel',
|
||||
type=str,
|
||||
default="matern",
|
||||
)
|
||||
parser.add_argument(
|
||||
'--model',
|
||||
type=str,
|
||||
default="volt",
|
||||
)
|
||||
parser.add_argument(
|
||||
'--mean',
|
||||
type=str,
|
||||
default="ewma",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--nsample",
|
||||
type=int,
|
||||
default=1000,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--train_iters",
|
||||
type=int,
|
||||
default=500,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--end_date",
|
||||
default=None,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--lookback",
|
||||
type=int,
|
||||
default=500,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--k",
|
||||
type=int,
|
||||
default=100,
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
main(args)
|
||||
+58
-66
@@ -63,20 +63,28 @@ def GenerateGPCVPredictions(ticker, dat,
|
||||
def GenerateStockPredictions(ticker, dat,
|
||||
forecast_horizon=20,
|
||||
train_iters=400, nsample=1000,
|
||||
ntrain=400, save=False, ntimes=1,
|
||||
vol_kernel='bm', gpcv_preds=False):
|
||||
ntrain=400, mean='ewma', kernel='volt',
|
||||
save=False, k=300, ntimes=-1):
|
||||
|
||||
end_idxs = torch.arange(ntrain, dat.shape[0],
|
||||
int((dat.shape[0]-ntrain)/ntimes))
|
||||
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
|
||||
|
||||
savepath = "./saved-outputs/" + ticker + "/"
|
||||
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())
|
||||
print(date, ticker)
|
||||
# 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]
|
||||
@@ -88,64 +96,46 @@ def GenerateStockPredictions(ticker, dat,
|
||||
train_y = train_y.cuda()
|
||||
|
||||
# print("Producing " + ticker + " Forecasts.....")
|
||||
vol = LearnGPCV(train_x, train_y, train_iters=train_iters,
|
||||
printing=False, kernel=vol_kernel)
|
||||
vmod, vlh = TrainVolModel(train_x, vol,
|
||||
train_iters=train_iters, printing=False)
|
||||
# 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 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)
|
||||
|
||||
# if save:
|
||||
# model_name = "volt_"
|
||||
# if vol_kernel == 'ou':
|
||||
# model_name = 'vhgp_'
|
||||
# model_name += mean + str(k) + "_"
|
||||
# torch.save(save_samples, savepath + model_name + date + ".pt")
|
||||
# del voltron, lh, vmod, vlh, vol
|
||||
# torch.cuda.empty_cache()
|
||||
|
||||
###################
|
||||
## CONSTANT MEAN ##
|
||||
###################
|
||||
# try:
|
||||
voltron, lh = TrainVoltMagpieModel(train_x, train_y[1:],
|
||||
vmod, vlh, vol,
|
||||
printing=False,
|
||||
train_iters=0,
|
||||
k=100, mean_func='constant')
|
||||
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
|
||||
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:
|
||||
model_name = "volt_"
|
||||
if vol_kernel == 'ou':
|
||||
model_name = 'vhgp_'
|
||||
model_name += "constant_"
|
||||
if not os.path.exists(savepath):
|
||||
os.mkdir(savepath)
|
||||
|
||||
torch.save(save_samples, savepath + model_name + date + ".pt")
|
||||
|
||||
del voltron, lh, vmod, vlh, vol
|
||||
torch.cuda.empty_cache()
|
||||
return
|
||||
# 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,
|
||||
@@ -155,8 +145,10 @@ def GenerateOneDayPredictions(ticker, train_y, date,
|
||||
|
||||
ntest = forecast_horizon
|
||||
dt = 1./252
|
||||
|
||||
savepath = "./saved-outputs/" + ticker + "/"
|
||||
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)
|
||||
|
||||
@@ -211,8 +203,6 @@ def GenerateOneDayPredictions(ticker, train_y, date,
|
||||
|
||||
del voltron, lh, vmod, vlh, vol, save_samples
|
||||
torch.cuda.empty_cache()
|
||||
|
||||
|
||||
return
|
||||
|
||||
|
||||
@@ -229,8 +219,10 @@ def GenerateBasicPredictions(ticker, dat, kernel_name, mean_name='ewma', k=400,
|
||||
int((dat.shape[0]-ntrain)/ntimes))
|
||||
ntest = forecast_horizon
|
||||
dt = 1./252
|
||||
|
||||
savepath = "./saved-outputs/" + ticker + "/"
|
||||
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)
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
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)
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,3 @@
|
||||
AAPL
|
||||
MSFT
|
||||
GOOG
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,125 +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
|
||||
from GenerateMultiMeanPreds import GenerateStockPredictions, GenerateBasicPredictions, GenerateGPCVPredictions
|
||||
from gpytorch.utils.warnings import NumericalWarning
|
||||
warnings.simplefilter("ignore", NumericalWarning)
|
||||
|
||||
def main(args):
|
||||
|
||||
|
||||
data_path = "../../voltron/data/"
|
||||
ticker_file = args.ticker_fname + ".txt"
|
||||
tckr_list = make_ticker_list(data_path + 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").date()
|
||||
|
||||
for tckr in tckr_list:
|
||||
try:
|
||||
data = GetStockHistory(tckr, history=args.ntrain + args.lookback,
|
||||
end_date=str(end_date))
|
||||
except:
|
||||
print(tckr, "FAILED")
|
||||
data = None
|
||||
if data is not None:
|
||||
if args.kernel.lower() == 'volt':
|
||||
GenerateStockPredictions(tckr, data, forecast_horizon=args.forecast_horizon,
|
||||
train_iters=args.train_iters,
|
||||
nsample=args.nsample,
|
||||
ntrain=400, save=args.save, ntimes=args.ntimes,
|
||||
vol_kernel=args.vol_kernel.lower())
|
||||
elif args.kernel.lower() == 'gpcv':
|
||||
GenerateGPCVPredictions(tckr, data, forecast_horizon=args.forecast_horizon,
|
||||
train_iters=args.train_iters,
|
||||
nsample=args.nsample,
|
||||
ntrain=400, 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,
|
||||
ntrain=args.ntrain, save=args.save)
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--ntimes",
|
||||
type=int,
|
||||
default=25,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--forecast_horizon",
|
||||
type=int,
|
||||
default=100,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--ticker_fname",
|
||||
type=str,
|
||||
default='nasdaq100',
|
||||
)
|
||||
parser.add_argument(
|
||||
"--ntrain",
|
||||
type=int,
|
||||
default=400,
|
||||
)
|
||||
parser.add_argument(
|
||||
'--kernel',
|
||||
type=str,
|
||||
default="volt",
|
||||
)
|
||||
parser.add_argument(
|
||||
'--vol_kernel',
|
||||
type=str,
|
||||
default="bm",
|
||||
)
|
||||
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='2022-04-08',
|
||||
)
|
||||
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)
|
||||
@@ -1,182 +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
|
||||
|
||||
|
||||
def main(args):
|
||||
|
||||
|
||||
data_path = "../../voltron/data/"
|
||||
ticker_file = "test_tickers.txt"
|
||||
tckr_list = make_ticker_list(data_path + ticker_file)
|
||||
print("Downloading Data.....")
|
||||
|
||||
if args.end_date.lower() == "none":
|
||||
end_date = str(datetime.date.today())
|
||||
else:
|
||||
end_date = args.end_date
|
||||
|
||||
DataGetter(fpath = data_path, ticker_file=ticker_file, end_date=end_date)
|
||||
print("Data Downloaded.")
|
||||
use_cuda = torch.cuda.is_available()
|
||||
|
||||
ntest = 20
|
||||
dt = 1./252
|
||||
|
||||
print("Producing Forecasts.....")
|
||||
for tckr in tckr_list:
|
||||
dat = pd.read_csv(data_path + tckr + ".csv")
|
||||
train_x = torch.arange(dat.shape[0]-1) * dt
|
||||
test_x = torch.arange(ntest) * dt + train_x[-1] + train_x[1]
|
||||
train_y = torch.FloatTensor(dat.Close.to_numpy())
|
||||
|
||||
if use_cuda:
|
||||
train_x = train_x.cuda()
|
||||
test_x = test_x.cuda()
|
||||
train_y = train_y.cuda()
|
||||
|
||||
train_iters=150
|
||||
mean = 'ewma'
|
||||
nsample = 1000
|
||||
if args.kernel == "volt":
|
||||
vol = LearnGPCV(train_x, train_y, train_iters=args.train_iters,
|
||||
printing=False)
|
||||
vmod, vlh = TrainVolModel(train_x, vol,
|
||||
train_iters=args.train_iters, printing=False)
|
||||
voltron, lh = TrainVoltMagpieModel(train_x, train_y[1:],
|
||||
vmod, vlh, vol,
|
||||
printing=False,
|
||||
train_iters=args.train_iters,
|
||||
k=300, mean_func=args.mean)
|
||||
vmod.eval();
|
||||
if args.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[idx, ::] = GeneratePrediction(train_x, train_y, test_x,
|
||||
predvol, voltron).detach()
|
||||
del predvol
|
||||
|
||||
del voltron, lh, vmod, vlh, vol
|
||||
torch.cuda.empty_cache()
|
||||
else:
|
||||
kernel_possibilities = {"sm": SpectralMixtureKernel, "matern": MaternKernel, "rbf": RBFKernel}
|
||||
kernel = kernel_possibilities[args.kernel.lower()]
|
||||
if type(kernel) is not SpectralMixtureKernel:
|
||||
kernel = ScaleKernel(kernel())
|
||||
else:
|
||||
kernel = kernel()
|
||||
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 = args.mean.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=args.k).to(train_x.device)
|
||||
elif mean_name == "dewma":
|
||||
model.mean_module = DEWMAMean(train_x, train_y.log(), k=args.k).to(train_x.device)
|
||||
elif mean_name == "tewma":
|
||||
model.mean_module = TEWMAMean(train_x, train_y.log(), k=args.k).to(train_x.device)
|
||||
|
||||
if use_cuda:
|
||||
model = model.to(train_x.device)
|
||||
|
||||
mll = ExactMarginalLogLikelihood(model.likelihood, model)
|
||||
fit_gpytorch_torch(mll, options={'maxiter':train_iters, 'disp':False})
|
||||
|
||||
if mean_name in ["loglinear", "constant", 'linear']:
|
||||
save_samples[idx] = model.posterior(test_x).sample(torch.Size((nsample, ))).squeeze(-1).cpu().detach()
|
||||
else:
|
||||
save_samples[idx] = Rollouts(
|
||||
train_x, train_y, test_x, model, nsample=nsample, method = "nonvol"
|
||||
).cpu().detach()
|
||||
|
||||
torch.cuda.empty_cache()
|
||||
del model, kernel
|
||||
|
||||
model_name = args.kernel + "_" + args.mean
|
||||
savepath = "./saved-outputs/" + tckr + "/"
|
||||
|
||||
if not os.path.exists(savepath):
|
||||
os.mkdir(savepath)
|
||||
|
||||
torch.save(save_samples, savepath + str(datetime.date.today()) + ".pt")
|
||||
if args.printing:
|
||||
print("\t" + tckr + " done.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument(
|
||||
"--kernel",
|
||||
type=str,
|
||||
default="volt",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--mean",
|
||||
type=str,
|
||||
default="ewma",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--k",
|
||||
type=int,
|
||||
default=100,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--nsample",
|
||||
type=int,
|
||||
default=1000,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--printing",
|
||||
type=bool,
|
||||
default=False
|
||||
)
|
||||
parser.add_argument(
|
||||
"--train_iters",
|
||||
type=int,
|
||||
default=400,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--end_date",
|
||||
default="none",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
main(args)
|
||||
@@ -1,138 +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 GenerateStockPredictions(ticker, dat,
|
||||
forecast_horizon=20,
|
||||
train_iters=400, nsample=1000,
|
||||
ntrain=400, mean='ewma', kernel='volt',
|
||||
save=False, k=300):
|
||||
|
||||
end_idxs = torch.arange(ntrain, dat.shape[0])
|
||||
ntest = forecast_horizon
|
||||
dt = 1./252
|
||||
|
||||
model_name = kernel + "_" + mean + str(k) + "_"
|
||||
savepath = "./saved-outputs/" + ticker + "/"
|
||||
|
||||
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 = trin_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[idx, ::] = GeneratePrediction(train_x, train_y, test_x,
|
||||
predvol, voltron).detach()
|
||||
del predvol
|
||||
|
||||
del voltron, lh, vmod, vlh, vol
|
||||
torch.cuda.empty_cache()
|
||||
else:
|
||||
kernel_possibilities = {"sm": SpectralMixtureKernel, "matern": MaternKernel, "rbf": RBFKernel}
|
||||
kernel = kernel_possibilities[kernel.lower()]
|
||||
if type(kernel) is not SpectralMixtureKernel:
|
||||
kernel = ScaleKernel(kernel())
|
||||
else:
|
||||
kernel = kernel()
|
||||
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.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)
|
||||
|
||||
mll = ExactMarginalLogLikelihood(model.likelihood, model)
|
||||
fit_gpytorch_torch(mll, options={'maxiter':train_iters, 'disp':False})
|
||||
|
||||
if mean_name in ["loglinear", "constant", 'linear']:
|
||||
save_samples[idx] = model.posterior(test_x).sample(torch.Size((nsample, ))).squeeze(-1).cpu().detach()
|
||||
else:
|
||||
save_samples[idx] = Rollouts(
|
||||
train_x, train_y, test_x, model, nsample=nsample, method = "nonvol"
|
||||
).cpu().detach()
|
||||
|
||||
torch.cuda.empty_cache()
|
||||
del model, kernel
|
||||
|
||||
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
|
||||
@@ -1,69 +0,0 @@
|
||||
import numpy as np
|
||||
import torch
|
||||
import pandas as pd
|
||||
import gpytorch
|
||||
import argparse
|
||||
|
||||
def ValueFunction(pred_samples, curr_px):
|
||||
"""
|
||||
pred_samples = (num samples) x (test times) matrix of forecast paths
|
||||
curr_px = last observed price
|
||||
"""
|
||||
snr = (pred_samples.mean(0) - curr_px)/pred_samples.std(0)
|
||||
|
||||
if snr > 0.2:
|
||||
return 1.
|
||||
else:
|
||||
return 0.
|
||||
|
||||
|
||||
|
||||
def main(args):
|
||||
data_path = "../../voltron/data/"
|
||||
ticker_file = "test_tickers.txt"
|
||||
tckr_list = make_ticker_list(data_path + ticker_file)
|
||||
|
||||
if args.end_date
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument(
|
||||
"--kernel",
|
||||
type=str,
|
||||
default="volt",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--mean",
|
||||
type=str,
|
||||
default="ewma",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--k",
|
||||
type=int,
|
||||
default=100,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--nsample",
|
||||
type=int,
|
||||
default=1000,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--printing",
|
||||
type=bool,
|
||||
default=False
|
||||
)
|
||||
parser.add_argument(
|
||||
"--train_iters",
|
||||
type=int,
|
||||
default=400,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--end_date",
|
||||
default="none",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
main(args)
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,189 +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
|
||||
|
||||
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
|
||||
|
||||
import sys
|
||||
sys.path.append("../../magpie/means/")
|
||||
from EWMA import EWMAMean, DEWMAMean, TEWMAMean
|
||||
|
||||
sys.path.append("../../magpie/")
|
||||
from train_utils import LearnGPCV, TrainVolModel, TrainVoltMagpieModel, TrainBasicModel
|
||||
|
||||
sys.path.append("../../magpie/models/")
|
||||
from VoltMagpie import VoltMagpie
|
||||
|
||||
from voltron.means import LogLinearMean
|
||||
sys.path.append("../spdr-forecasting/")
|
||||
from rollout_utils import GeneratePrediction, Rollouts
|
||||
|
||||
def main(args):
|
||||
savepath = "./saved-outputs/" + args.symbol + "/"
|
||||
if not os.path.exists(savepath):
|
||||
os.mkdir(savepath)
|
||||
|
||||
dpath = "../../magpie/data/"
|
||||
full_data = pd.read_csv(dpath + args.symbol + ".csv")
|
||||
|
||||
full_data = pd.read_csv(dpath + args.symbol + ".csv")
|
||||
full_data["Date"] = pd.to_datetime(full_data['Date'])
|
||||
full_data = full_data.set_index(["Date"])
|
||||
|
||||
ntrain = 450
|
||||
ntest = 20
|
||||
nsample = args.nsample
|
||||
train_iters = 500
|
||||
train_x = torch.arange(ntrain) * 1./252
|
||||
test_x = torch.arange(ntest) * 1./252 + train_x[-1] + train_x[1]
|
||||
dt = train_x[1] - train_x[0]
|
||||
|
||||
start_date = pd.to_datetime("2011-11-21") - pd.Timedelta(ntrain, 'd')
|
||||
px = torch.FloatTensor(full_data.loc[start_date:].Close).squeeze()
|
||||
|
||||
start_idxs = torch.arange(1, px.shape[0] - ntrain - ntest)
|
||||
|
||||
## save the typical stuff to use for plotting/validating ##
|
||||
torch.save({"ntrain":ntrain, "ntest":ntest, "start_idxs":start_idxs},
|
||||
"./saved-outputs/metadata.pt")
|
||||
|
||||
if torch.cuda.is_available():
|
||||
use_cuda = True
|
||||
train_x = train_x.cuda()
|
||||
test_x = test_x.cuda()
|
||||
else:
|
||||
use_cuda = False
|
||||
|
||||
|
||||
fname = args.kernel + "_" + args.mean + str(args.k) + ".pt"
|
||||
|
||||
save_samples = torch.zeros(start_idxs.numel(), nsample, ntest)
|
||||
for idx, start_idx in enumerate(start_idxs):
|
||||
train_y = px[start_idx-1:ntrain+start_idx].squeeze()
|
||||
test_y = px[start_idx + ntrain:start_idx + ntrain+ntest].squeeze()
|
||||
|
||||
if use_cuda:
|
||||
train_y = train_y.cuda()
|
||||
test_y = test_y.cuda()
|
||||
test_x = test_x.cuda()
|
||||
|
||||
if args.kernel.lower() == "volt":
|
||||
|
||||
dt = train_x[1] - train_x[0]
|
||||
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=args.k, mean_func=args.mean)
|
||||
|
||||
vmod.eval();
|
||||
|
||||
if args.mean in ['ewma', 'dewma', 'tewma']:
|
||||
save_samples[idx, ::] = 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[idx, ::] = GeneratePrediction(train_x, train_y, test_x,
|
||||
predvol, voltron).detach()
|
||||
del predvol
|
||||
|
||||
del voltron, lh, vmod, vlh, vol
|
||||
|
||||
else:
|
||||
kernel_possibilities = {"sm": SpectralMixtureKernel, "matern": MaternKernel, "rbf": RBFKernel}
|
||||
kernel = kernel_possibilities[args.kernel.lower()]
|
||||
if type(kernel) is not SpectralMixtureKernel:
|
||||
kernel = ScaleKernel(kernel())
|
||||
else:
|
||||
kernel = kernel()
|
||||
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 = args.mean.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=args.k).to(train_x.device)
|
||||
elif mean_name == "dewma":
|
||||
model.mean_module = DEWMAMean(train_x, train_y.log(), k=args.k).to(train_x.device)
|
||||
elif mean_name == "tewma":
|
||||
model.mean_module = TEWMAMean(train_x, train_y.log(), k=args.k).to(train_x.device)
|
||||
|
||||
if use_cuda:
|
||||
model = model.to(train_x.device)
|
||||
|
||||
mll = ExactMarginalLogLikelihood(model.likelihood, model)
|
||||
fit_gpytorch_torch(mll, options={'maxiter':train_iters, 'disp':False})
|
||||
|
||||
if mean_name in ["loglinear", "constant", 'linear']:
|
||||
save_samples[idx] = model.posterior(test_x).sample(torch.Size((nsample, ))).squeeze(-1).cpu().detach()
|
||||
else:
|
||||
save_samples[idx] = Rollouts(
|
||||
train_x, train_y, test_x, model, nsample=nsample, method = "nonvol"
|
||||
).cpu().detach()
|
||||
|
||||
torch.cuda.empty_cache()
|
||||
del model, kernel
|
||||
|
||||
print("Start Time = ", start_idx.item(), " out of ", len(start_idxs))
|
||||
torch.cuda.empty_cache()
|
||||
torch.save(save_samples, savepath + fname)
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument(
|
||||
"--symbol",
|
||||
type=str,
|
||||
default="SPY",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--kernel",
|
||||
type=str,
|
||||
default="volt",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--mean",
|
||||
type=str,
|
||||
default="ewma",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--k",
|
||||
type=int,
|
||||
default=100,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--nsample",
|
||||
type=int,
|
||||
default=1000,
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
main(args)
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,8 +0,0 @@
|
||||
#!/bin/bash
|
||||
cat ../../voltron/data/nasdaq100.txt | while read line
|
||||
do
|
||||
for test_idx in {0..9}
|
||||
do
|
||||
python TickerSingleDayGenerator.py --kernel=volt --ntimes=25 --test_idx=${test_idx} --save=True --end_date="2022-01-12" --ticker=${line} --mean=constant
|
||||
done
|
||||
done
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user