jasonstrimpel / volatility-trading Goto Github PK
View Code? Open in Web Editor NEWA complete set of volatility estimators based on Euan Sinclair's Volatility Trading
License: GNU General Public License v3.0
A complete set of volatility estimators based on Euan Sinclair's Volatility Trading
License: GNU General Public License v3.0
As Euan Sinclair said in the book "Volatility Trading", we could use Parkinson, RogersSatchell alternative volatility estimator instead of close-to-close volatility estimator and campare the implied volatility with these realized volitilties. However, I found that the Parkinson and RogersSatchell estimators are much larger than the implied volatility.(As is shown in the y-axis in the graphs, they are bigger than 100%, while the close-to-close estimator is more reasonable).
I want to know if we could use alternative volatility estimators like Parkinson and compare the implied volatility with them to trade; or we must compare the the implied volatility with close-to-close volatility?
Add pandas, numpy, and other package requirements
setup( name='volatility-trading', version='0.0.1', url='https://github.com/jasonstrimpel/volatility-trading/', license='GPL-3.0-or-later', packages=['volatility','volatility/models'], install_requires=[ 'numpy~=1.21.4', 'pandas~=1.3.3', # ... other packages )
If use different window other than 30 days, the following should be revised:
# result = (open_vol + 0.164333 * close_vol + 0.835667 * window_rs).apply(np.sqrt) * math.sqrt(252)
k = 0.34 / (1 + (window + 1) / (window - 1))
result = (open_vol + k * close_vol + (1 - k) * window_rs).apply(np.sqrt) * math.sqrt(245)
We should use variables instead of constants.
Hi, Jason,
I have run the sample code in a new Main.py file, however, it prompts the value error. Can you help me? Thank you.
"C:\Program Files\Python36\python.exe" D:/PythonWorkSpace/volatility-trading-master/main.py
C:\Program Files\Python36\lib\site-packages\statsmodels\compat\pandas.py:56: FutureWarning: The pandas.core.datetools module is deprecated and will be removed in a future version. Please use the pandas.tseries module instead.
from pandas.core import datetools
C:\Program Files\Python36\lib\site-packages\numpy\core\fromnumeric.py:56: FutureWarning: reshape is deprecated and will raise in a subsequent release. Please use .values.reshape(...) instead
return getattr(obj, method)(*args, **kwds)
Traceback (most recent call last):
File "D:/PythonWorkSpace/volatility-trading-master/main.py", line 48, in
normed
File "D:\PythonWorkSpace\volatility-trading-master\volatility\volest.py", line 715, in term_sheet
benchmark_compare_fig, benchmark_compare_plt = self.benchmark_compare(window=window)
File "D:\PythonWorkSpace\volatility-trading-master\volatility\volest.py", line 588, in benchmark_compare
cones.plot(date, x, label=self.bench_symbol)
File "C:\Program Files\Python36\lib\site-packages\matplotlib_init.py", line 1717, in inner
return func(ax, *args, **kwargs)
File "C:\Program Files\Python36\lib\site-packages\matplotlib\axes_axes.py", line 1372, in plot
for line in self._get_lines(*args, **kwargs):
File "C:\Program Files\Python36\lib\site-packages\matplotlib\axes_base.py", line 404, in _grab_next_args
for seg in self._plot_args(this, kwargs):
File "C:\Program Files\Python36\lib\site-packages\matplotlib\axes_base.py", line 384, in _plot_args
x, y = self._xy_from_xy(x, y)
File "C:\Program Files\Python36\lib\site-packages\matplotlib\axes_base.py", line 243, in _xy_from_xy
"have shapes {} and {}".format(x.shape, y.shape))
ValueError: x and y must have same first dimension, but have shapes (719,) and (725,)
Please, check line 34 on file YangZhang.py
Current code is
k = 0.34 / (1 + (window + 1) / (window - 1))
I believe the code should be
k = 0.34 / (1.34 + (window + 1) / (window - 1))
Altering the interface to allow for numpy arrays of olhc prices would extend the functionality to non-equity tickers.
@jasonstrimpel Hi Jason, I find that the equation of GarmanKlass is different from that of RogersSatchell, as follows:
GarmanKlass: return trading_periods * v.mean()**0.5
RogersSatchell: return (trading_periods * v.mean())**0.5
Are you sure they are different? Thank you.
The models which follow def f(v) methods seem not to calculate the vols correctly.
17
18 def f(v):
---> 19 return math.sqrt(252 * v.mean())
20
21 result = rs.rolling(window=window, center=False).apply(func=f)
ValueError: math domain error
Am I missing something?
(envy1) C:\Users\User>pip install volest
ERROR: Could not find a version that satisfies the requirement volest
ERROR: No matching distribution found for volest
(envy1) C:\Users\User>pip install volatility-trading
ERROR: Could not find a version that satisfies the requirement volatility-trading
ERROR: No matching distribution found for volatility-trading
I see you have no LICENSE file for this project. The default is copyright.
I would suggest releasing the code under the GPL-3.0-or-later or AGPL-3.0-or-later license so that others are encouraged to contribute changes back to your project.
Apparently matplotlib no longer uses the "normed" property. This deprecated property appears in several places in this project, resulting in the error AttributeError: 'Rectangle' Object Has No Property 'Normed' Solution
.
volest.py:193,285,359,434,453,570,645: SyntaxWarning: "is" with a literal. Did you mean "=="?
log_hl = (prices['Adj High'] / prices['Adj Low']).apply(np.log)
log_co = (prices['Adj Close'] / prices['Adj Open']).apply(np.log)
log_oc = (prices['Adj Open'] / prices['Adj Close']).apply(np.log)
just wondering how this log_oc fits?
tried to modify the code as per book, i.e.
log_hl = (prices['Adj High'] / prices['Adj Low']).apply(np.log)
log_co = (prices['Adj Close'] / prices['Adj Close'].shift(1)).apply(np.log)
this returns, may be because of negative number:
return math.sqrt(252 * v.mean())
ValueError: math domain error
Also, Rogers, Satchell, and Yoon works fine with following lines:
log_ho = (prices['Adj High'] / prices['Adj Open']).apply(np.log)
log_hc = (prices['Adj High'] / prices['Adj Close']).apply(np.log)
log_lo = (prices['Adj Low'] / prices['Adj Open']).apply(np.log)
log_lc = (prices['Adj Low'] / prices['Adj Close']).apply(np.log)
rs = log_hc * log_ho + log_lc * log_lo
Hello,
I've stumbled upon this library while looking for volatility models applicable to the stock market, however I'm a bit confused as to what the purpose of the repo is? Using a Parkinson estimator with SPY as benchmark and United States Steel Corp as the underlying symbol I get an R squared of 0.83. However looking through the code it appears that it is only fitting to the data and not doing any predictions.
My question is how do you apply the results that this repo gives in the real world and would it be correct to assume that these models can be used with the .predict() to get applicable results?
In histogram function:
y = mlab.normpdf(bins, mean, std)
should change to
from scipy.stats import norm
y = norm.pdf(bins, mean, std)
this works fine.
great work.
thanks.
According to the original formula on the textbook, the codes should be revised as following:
# log_co = (price_data['Close'] / price_data['Open']).apply(np.log)
log_cc = (price_data['Close'] / price_data['Close'].shift(1)).apply(np.log)
rs = 0.5 * log_hl**2 - (2*math.log(2)-1) * log_cc**2 # Instead of log_co
Using today's close/open will underestimate the volatility caused by jump, however, if jumps always happen within a period, GarmanKlass will give a negative value to be rooted. Using the above formula based on the textbook:
def f(v):
#print(245*v.mean())
# return math.sqrt(252 * v.mean())
return (245 * (v.mean()))
# q = 245 * v.mean()
# return q
# return math.sqrt(v.mean())
# return math.sqrt(245 * v.mean())
# China Market has about 245 trading days
# If we use intraday data, there should be 240 bars or more
we got:
The second pic is JPM's price during June, 2016. We see that too many jumps result in a negative variance. But Jason's formula won't since abs(log(close/open)) is smaller.
BTW, v ** (1/2) will not raise an error for a negative number while math.sqrt() does.
Every estimator can accept a parameter trading_periods
(probably should be named annual_trading_days), however when calling it in on the of the VolatilityEstimator
methods, there is no way to pass that parameter through. This will cause issues for markets such as FX, crypto and basically anything other than U.S. Equities.
Simple solution is to allow it to be passed through as an option parameter.
volest.py changed to: import models. It was: from volatility import models
models init.py changed to: from models.api import *
data is in tests directory thus: data_file_path = '../tests/JPM.csv'
I would add 2 explicit lines after vol. I needed to reference fig, plt not just plt.
fig, plt = vol.cones(windows=windows, quantiles=quantiles)
plt.show()
I could not get vol.term_sheet to work.
Installed locally after cloning repo using python setup.py install. Trying to run the sample code in a notebook. Using python 3.8.
from volatility import volest
from volatility import data
# data
symbol = 'JPM'
bench = '^GSPC'
data_file_path = '../JPM.csv'
bench_file_path = '../BENCH.csv'
estimator = 'GarmanKlass'
# estimator windows
window = 30
windows = [30, 60, 90, 120]
quantiles = [0.25, 0.75]
bins = 100
normed = True
# use the yahoo helper to correctly format data from finance.yahoo.com
jpm_price_data = data.yahoo_helper(symbol, data_file_path)
spx_price_data = data.yahoo_helper(bench, bench_file_path)
# initialize class
vol = volest.VolatilityEstimator(
price_data=jpm_price_data,
estimator=estimator,
bench_data=spx_price_data
)
Error thrown
---------------------------------------------------------------------------
ImportError Traceback (most recent call last)
<ipython-input-15-890e41b22558> in <module>
----> 1 from volatility import volest
2 from volatility import data
3
4 # data
5 symbol = 'JPM'
<frozen zipimport> in load_module(self, fullname)
~/Dev/hermes/lib/python3.8/site-packages/volatility_trading-0.0.1-py3.8.egg/volatility/volest.py in <module>
10 from matplotlib.backends.backend_pdf import PdfPages
11
---> 12 from volatility import models
13
14 ESTIMATORS = [
ImportError: cannot import name 'models' from 'volatility' (/Users/prabhakar/Dev/hermes/lib/python3.8/site-packages/volatility_trading-0.0.1-py3.8.egg/volatility/__init__.py)
I feel that HT should be used in all other models, not only for adjusting close-to-close volatility. Overlapping data are used for all models when using rolling windows.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.