vix_utils_tddschn 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,110 @@
1
+ Metadata-Version: 2.3
2
+ Name: vix_utils_tddschn
3
+ Version: 0.2.0
4
+ Summary: Provide VIX Cash and Futures Term Structure as Pandas dataframes
5
+ Keywords: vix,volatility,pandas,vix term structure,cboe
6
+ Author: Doug Ransom, T
7
+ Author-email: Doug Ransom <doug@ransom.vip>, T <45612704+tddschn@users.noreply.github.com>
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Financial and Insurance Industry
11
+ Classifier: Topic :: Office/Business :: Financial :: Investment
12
+ Requires-Dist: pandas
13
+ Requires-Dist: pandas-market-calendars>=4.4.0
14
+ Requires-Dist: aiofiles
15
+ Requires-Dist: aiohttp[speedups]
16
+ Requires-Dist: openpyxl
17
+ Requires-Dist: appdirs
18
+ Requires-Dist: more-itertools
19
+ Requires-Dist: icecream
20
+ Requires-Dist: matplotlib ; extra == 'examples'
21
+ Requires-Dist: scipy ; extra == 'examples'
22
+ Requires-Dist: pytest ; extra == 'test'
23
+ Requires-Python: >=3.11
24
+ Project-URL: home-page, https://github.com/tddschn/vix_utils
25
+ Provides-Extra: examples
26
+ Provides-Extra: test
27
+ Description-Content-Type: text/markdown
28
+
29
+ # VIX Utils
30
+ ## Overview
31
+
32
+ *vix_utils* provides some tools for preparing data for analysing the VIX Futures and Cash Term structures.
33
+
34
+ The futures can also contain a 30 day continuous maturity weighting of front two months of vix futures.
35
+
36
+ VIX Futures Data downloaded from [CBOE Futures Historical Data](https://www.cboe.com/us/futures/market_statistics/historical_data/).
37
+
38
+ Vix Cash Data are downloaded from [CBOE Historical Volatility Indexes](https://www.cboe.com/tradable_products/vix/vix_historical_data/).
39
+
40
+
41
+ There is an API for Python to load the data into Pandas DataFrames. If you do your analysis in Python, use the API.
42
+
43
+ Since there is no documentation yet, look at the examples in the src/vix_utils/examples folder.
44
+ There is a Jupyter Notebook vix_utils.ipynb in that folder.
45
+
46
+ *Important note for Juypter notebooks.*
47
+ You must use async_get_vix_index_histories and async_load_vix_term_structure
48
+ rather than get_vix_index_histories and load_vix_term_structure. There is an example Jupyter notebook "vix_utils use in Jupyter.ipynb" in the src/vix_utils/examples folder.
49
+
50
+ If you do your analysis in other tools such as R or excel, you can use the command line tool vixutil.
51
+
52
+ `vixutil -h` will give the help. The data are availble in record and wide formats. Just run it and look at the excel or csv output to see what they look like.
53
+
54
+
55
+
56
+
57
+ ## Installation
58
+
59
+ You will need a Python 3.11 or later instalation.
60
+
61
+ ### Install from the Python Packaging Index
62
+
63
+ Install using pip from [The Python Package Index ](https://www.pypi.org):
64
+
65
+ `pip install vix_utils`
66
+
67
+ If you want to run the samples, install like this:
68
+ `pip install vix_utils[examples]`
69
+
70
+ The sample to load all the various data frames can be run as:
71
+ 'vix_sample_load_data'
72
+
73
+ The sample to plot the history of futures and cash term structures:
74
+ `vix_sample_plots`
75
+
76
+ To load the sample Jupyter notebook, run vix_sample_load_data to figure out where the examples folder is. Browse there with Jupyter and open a notebook.
77
+
78
+
79
+ ### Development
80
+
81
+ Clone from [github repository](https://github.com/dougransom/vix_utils).
82
+
83
+
84
+ `pip install -e .[test,examples]` will:
85
+ - install vix_utils into your python environment, including any command line scripts.
86
+ - install the necessary prequisites for running any
87
+ tests in the `test` folder, and for running the programs in the `src/vixutils/examples` folder.
88
+
89
+ #### Testing
90
+
91
+ The tests directory contains a few tests. This project wasn't developed with
92
+ [Test Driven Development](https://www.agilealliance.org/glossary/tdd/), unit tests have been added to isolate
93
+ and fix defects.
94
+
95
+ However, new features and bug fixes should be developed with [Test Driven Development](https://www.agilealliance.org/glossary/tdd/) practices when practical.
96
+
97
+
98
+ ## Examples
99
+ Source is in `src/vix_utils/examples`
100
+
101
+ ~~~
102
+ ## Data Notes
103
+ These dates appear to be missing from the CBOE Data.
104
+ At some point they need to be patched in if they exist.
105
+ ```
106
+ [Timestamp('2006-11-10 00:00:00'), Timestamp('2007-01-03 00:00:00'), Timestamp('2021-04-02 00:00:00'), Timestamp('2021-12-24 00:00:00')]
107
+ ```
108
+ There seem to be a few dates where spot indexes are missing, you will have to workaround by using fill feature of Pandas datafame, or skip those days, in any analysis.
109
+ ~~~
110
+
@@ -0,0 +1,82 @@
1
+ # VIX Utils
2
+ ## Overview
3
+
4
+ *vix_utils* provides some tools for preparing data for analysing the VIX Futures and Cash Term structures.
5
+
6
+ The futures can also contain a 30 day continuous maturity weighting of front two months of vix futures.
7
+
8
+ VIX Futures Data downloaded from [CBOE Futures Historical Data](https://www.cboe.com/us/futures/market_statistics/historical_data/).
9
+
10
+ Vix Cash Data are downloaded from [CBOE Historical Volatility Indexes](https://www.cboe.com/tradable_products/vix/vix_historical_data/).
11
+
12
+
13
+ There is an API for Python to load the data into Pandas DataFrames. If you do your analysis in Python, use the API.
14
+
15
+ Since there is no documentation yet, look at the examples in the src/vix_utils/examples folder.
16
+ There is a Jupyter Notebook vix_utils.ipynb in that folder.
17
+
18
+ *Important note for Juypter notebooks.*
19
+ You must use async_get_vix_index_histories and async_load_vix_term_structure
20
+ rather than get_vix_index_histories and load_vix_term_structure. There is an example Jupyter notebook "vix_utils use in Jupyter.ipynb" in the src/vix_utils/examples folder.
21
+
22
+ If you do your analysis in other tools such as R or excel, you can use the command line tool vixutil.
23
+
24
+ `vixutil -h` will give the help. The data are availble in record and wide formats. Just run it and look at the excel or csv output to see what they look like.
25
+
26
+
27
+
28
+
29
+ ## Installation
30
+
31
+ You will need a Python 3.11 or later instalation.
32
+
33
+ ### Install from the Python Packaging Index
34
+
35
+ Install using pip from [The Python Package Index ](https://www.pypi.org):
36
+
37
+ `pip install vix_utils`
38
+
39
+ If you want to run the samples, install like this:
40
+ `pip install vix_utils[examples]`
41
+
42
+ The sample to load all the various data frames can be run as:
43
+ 'vix_sample_load_data'
44
+
45
+ The sample to plot the history of futures and cash term structures:
46
+ `vix_sample_plots`
47
+
48
+ To load the sample Jupyter notebook, run vix_sample_load_data to figure out where the examples folder is. Browse there with Jupyter and open a notebook.
49
+
50
+
51
+ ### Development
52
+
53
+ Clone from [github repository](https://github.com/dougransom/vix_utils).
54
+
55
+
56
+ `pip install -e .[test,examples]` will:
57
+ - install vix_utils into your python environment, including any command line scripts.
58
+ - install the necessary prequisites for running any
59
+ tests in the `test` folder, and for running the programs in the `src/vixutils/examples` folder.
60
+
61
+ #### Testing
62
+
63
+ The tests directory contains a few tests. This project wasn't developed with
64
+ [Test Driven Development](https://www.agilealliance.org/glossary/tdd/), unit tests have been added to isolate
65
+ and fix defects.
66
+
67
+ However, new features and bug fixes should be developed with [Test Driven Development](https://www.agilealliance.org/glossary/tdd/) practices when practical.
68
+
69
+
70
+ ## Examples
71
+ Source is in `src/vix_utils/examples`
72
+
73
+ ~~~
74
+ ## Data Notes
75
+ These dates appear to be missing from the CBOE Data.
76
+ At some point they need to be patched in if they exist.
77
+ ```
78
+ [Timestamp('2006-11-10 00:00:00'), Timestamp('2007-01-03 00:00:00'), Timestamp('2021-04-02 00:00:00'), Timestamp('2021-12-24 00:00:00')]
79
+ ```
80
+ There seem to be a few dates where spot indexes are missing, you will have to workaround by using fill feature of Pandas datafame, or skip those days, in any analysis.
81
+ ~~~
82
+
@@ -0,0 +1,66 @@
1
+ [build-system]
2
+ requires = ["uv_build"]
3
+ build-backend = "uv_build"
4
+
5
+ [project]
6
+ keywords=["vix","volatility","pandas","vix term structure","cboe"]
7
+ name = "vix_utils_tddschn"
8
+ authors = [
9
+ {name="Doug Ransom", email="doug@ransom.vip"},
10
+ {name="T", email="45612704+tddschn@users.noreply.github.com"}
11
+ ]
12
+ description="Provide VIX Cash and Futures Term Structure as Pandas dataframes"
13
+ classifiers = [
14
+ "License :: OSI Approved :: MIT License",
15
+ "Development Status :: 3 - Alpha",
16
+ "Intended Audience :: Financial and Insurance Industry",
17
+ "Topic :: Office/Business :: Financial :: Investment"
18
+ ]
19
+
20
+ readme="README.md"
21
+ requires-python=">=3.11"
22
+ version = "0.2.0"
23
+
24
+ dependencies= [
25
+ "pandas",
26
+ "pandas-market-calendars >= 4.4.0",
27
+ "aiofiles",
28
+ "aiohttp[speedups]",
29
+ "openpyxl",
30
+ "appdirs",
31
+ "more_itertools",
32
+ "icecream"
33
+ ]
34
+
35
+ [project.optional-dependencies]
36
+ test=["pytest"]
37
+ examples=["matplotlib","scipy"]
38
+
39
+ [tool.pytest.ini_options]
40
+ minversion = "7.1.2"
41
+ addopts = "--capture=tee-sys "
42
+ # very important
43
+ #the pythonpath lets pytest load code in your source area
44
+ #in addition to that in site-packages etc.
45
+ #you may want to run your tests without install natlinkcore with flit or pip
46
+ pythonpath = [
47
+ ]
48
+ testpaths= [
49
+ "test",
50
+ ]
51
+ python_files = [
52
+ "test_*.py",
53
+ ]
54
+
55
+ [project.scripts]
56
+ vixutil = "vix_utils.vixutil:main"
57
+
58
+ #samples
59
+ vix_sample_plots="vix_utils.examples.sample_plots:main"
60
+ vix_sample_load_data="vix_utils.examples.sample_load_data:main"
61
+
62
+ [project.urls]
63
+ home-page = "https://github.com/tddschn/vix_utils"
64
+
65
+ [tool.uv.build-backend]
66
+ module-name = "vix_utils"
@@ -0,0 +1,42 @@
1
+ """
2
+ A library for preparing VIX Futures and Cash Term Structures for analysis,
3
+ including a continuous maturity VIX Futures term structure.
4
+ """
5
+
6
+ from importlib.metadata import version, PackageNotFoundError
7
+
8
+ try:
9
+ __version__ = version("vix_utils_tddschn")
10
+ except PackageNotFoundError:
11
+ __version__ = "0.1.7"
12
+
13
+ from .download_vix_futures import (
14
+ pivot_futures_on_monthly_tenor,
15
+ select_monthly_futures,
16
+ async_load_vix_term_structure,
17
+ load_vix_term_structure,
18
+ )
19
+
20
+ from .vix_cash_term_structure import (
21
+ async_get_vix_index_histories,
22
+ get_vix_index_histories,
23
+ pivot_spot_term_structure_on_symbol,
24
+ )
25
+
26
+ from .vix_futures_dates import (
27
+ vix_futures_expiry_date_monthly,
28
+ vix_futures_expiry_date_from_trade_date,
29
+ vix_futures_trade_dates_and_expiry_dates,
30
+ vix_constant_maturity_weights,
31
+ )
32
+
33
+ from .continuous_maturity import (
34
+ continuous_maturity_one_month,
35
+ append_continuous_maturity_one_month,
36
+ )
37
+
38
+ from .cboe_equity_history import (
39
+ async_get_cboe_equity_histories,
40
+ get_cboe_equity_histories,
41
+ pivot_equity_histories_on_symbol,
42
+ )
@@ -0,0 +1,187 @@
1
+ import json
2
+ import logging
3
+ from pathlib import Path
4
+
5
+ import aiofiles
6
+ import aiohttp
7
+ import asyncio
8
+ import pandas as pd
9
+
10
+ from .location import data_dir, make_dir
11
+
12
+ # Browse equities at https://www.cboe.com/us/equities/
13
+ _cboe_equity_history_url = (
14
+ "https://cdn.cboe.com/api/global/delayed_quotes/charts/historical/{symbol}.json"
15
+ )
16
+
17
+
18
+ def _normalize_equity_symbols(symbols):
19
+ if isinstance(symbols, str):
20
+ symbols = [symbols]
21
+ out = []
22
+ for symbol in symbols:
23
+ symbol_str = str(symbol).upper().strip()
24
+ if not symbol_str:
25
+ continue
26
+ if symbol_str in out:
27
+ continue
28
+ out.append(symbol_str)
29
+ return out
30
+
31
+
32
+ def _read_equity_json(fname, symbol):
33
+ try:
34
+ with open(fname) as f:
35
+ data = json.load(f)
36
+ except Exception as e:
37
+ logging.warning(f"Skipping symbol {symbol}: failed to read {fname}: {e}")
38
+ return pd.DataFrame(
39
+ columns=["Trade Date", "Open", "High", "Low", "Close", "Volume", "Symbol"]
40
+ )
41
+
42
+ records = data.get("data", [])
43
+ if not records:
44
+ return pd.DataFrame(
45
+ columns=["Trade Date", "Open", "High", "Low", "Close", "Volume", "Symbol"]
46
+ )
47
+
48
+ df = pd.DataFrame(records)
49
+
50
+ col_map = {
51
+ "date": "Trade Date",
52
+ "open": "Open",
53
+ "high": "High",
54
+ "low": "Low",
55
+ "close": "Close",
56
+ "volume": "Volume",
57
+ }
58
+ df = df.rename(columns={k: v for k, v in col_map.items() if k in df.columns})
59
+ df["Symbol"] = symbol
60
+
61
+ for col in ["Open", "High", "Low", "Close"]:
62
+ if col in df.columns:
63
+ df[col] = pd.to_numeric(df[col], errors="coerce")
64
+ if "Volume" in df.columns:
65
+ df["Volume"] = pd.to_numeric(df["Volume"], errors="coerce")
66
+
67
+ df["Trade Date"] = pd.to_datetime(df["Trade Date"], errors="coerce")
68
+ df = df.dropna(subset=["Trade Date", "Close"])
69
+
70
+ ordered_cols = ["Trade Date"]
71
+ for col in ["Open", "High", "Low", "Close", "Volume", "Symbol"]:
72
+ if col in df.columns:
73
+ ordered_cols.append(col)
74
+ df = df[ordered_cols]
75
+ return df
76
+
77
+
78
+ async def async_get_cboe_equity_histories(symbols):
79
+ """
80
+ Download historical daily OHLCV data for equities/ETFs from CBOE.
81
+
82
+ Uses the endpoint:
83
+ https://cdn.cboe.com/api/global/delayed_quotes/charts/historical/{symbol}.json
84
+
85
+ Parameters
86
+ ----------
87
+ symbols : str or list of str
88
+ Ticker symbol(s) to download (e.g. ``"SPY"`` or ``["SPY", "NVDA"]``).
89
+
90
+ Returns
91
+ -------
92
+ pd.DataFrame
93
+ Records-format DataFrame with columns:
94
+ Trade Date, Open, High, Low, Close, Volume, Symbol.
95
+ """
96
+ symbols = _normalize_equity_symbols(symbols)
97
+
98
+ equity_download_dir = Path(data_dir()) / "equity" / "download"
99
+ make_dir(equity_download_dir)
100
+
101
+ async with aiohttp.ClientSession() as session:
102
+
103
+ async def download_one(symbol):
104
+ url = _cboe_equity_history_url.format(symbol=symbol)
105
+ logging.debug(f"Reading URL {url}")
106
+ cache_path = equity_download_dir / f"{symbol}_History.json"
107
+
108
+ async with session.get(url) as resp:
109
+ if resp.status != 200:
110
+ logging.warning(
111
+ f"Skipping symbol {symbol}: {url} returned HTTP {resp.status}"
112
+ )
113
+ return None
114
+ text = await resp.text()
115
+
116
+ async with aiofiles.open(cache_path, mode="w") as f:
117
+ await f.write(text)
118
+ logging.debug(f"Wrote {cache_path}")
119
+
120
+ return symbol, cache_path
121
+
122
+ downloaded = await asyncio.gather(*(download_one(s) for s in symbols))
123
+
124
+ downloaded = [entry for entry in downloaded if entry is not None]
125
+ if not downloaded:
126
+ return pd.DataFrame(
127
+ columns=["Trade Date", "Open", "High", "Low", "Close", "Volume", "Symbol"]
128
+ )
129
+
130
+ frames = [
131
+ frame
132
+ for frame in (_read_equity_json(path, symbol) for symbol, path in downloaded)
133
+ if not frame.empty
134
+ ]
135
+ if not frames:
136
+ return pd.DataFrame(
137
+ columns=["Trade Date", "Open", "High", "Low", "Close", "Volume", "Symbol"]
138
+ )
139
+
140
+ result = pd.concat(frames)
141
+ result["Trade Date"] = pd.to_datetime(result["Trade Date"])
142
+ result = result.sort_values(["Trade Date", "Symbol"]).reset_index(drop=True)
143
+ logging.debug(f"Equity histories shape: {result.shape}")
144
+ return result
145
+
146
+
147
+ def get_cboe_equity_histories(symbols):
148
+ """
149
+ Download historical daily OHLCV data for equities/ETFs from CBOE.
150
+
151
+ Synchronous wrapper around :func:`async_get_cboe_equity_histories`.
152
+
153
+ Parameters
154
+ ----------
155
+ symbols : str or list of str
156
+ Ticker symbol(s) to download (e.g. ``"SPY"`` or ``["SPY", "NVDA"]``).
157
+
158
+ Returns
159
+ -------
160
+ pd.DataFrame
161
+ Records-format DataFrame with columns:
162
+ Trade Date, Open, High, Low, Close, Volume, Symbol.
163
+ """
164
+ return asyncio.run(async_get_cboe_equity_histories(symbols=symbols))
165
+
166
+
167
+ def pivot_equity_histories_on_symbol(equity_histories):
168
+ """
169
+ Pivot equity histories from record format to wide format.
170
+
171
+ Parameters
172
+ ----------
173
+ equity_histories : pd.DataFrame
174
+ Records-format DataFrame as returned by :func:`get_cboe_equity_histories`.
175
+
176
+ Returns
177
+ -------
178
+ pd.DataFrame
179
+ Wide-format DataFrame with Trade Date as index and a MultiIndex of
180
+ (price column, Symbol) as columns.
181
+ """
182
+ try:
183
+ wide = equity_histories.set_index(["Trade Date", "Symbol"]).unstack()
184
+ except Exception as e:
185
+ logging.error(f"{e} in pivot_equity_histories_on_symbol")
186
+ raise
187
+ return wide
@@ -0,0 +1,146 @@
1
+ from operator import mul
2
+ from functools import partial
3
+ import numpy as np
4
+ from .download_vix_futures import \
5
+ pivot_futures_on_monthly_tenor
6
+ import pandas as pd
7
+ import logging
8
+
9
+ from .vix_futures_dates import vix_futures_expiry_date_monthly, \
10
+ vix_futures_expiry_date_from_trade_date, \
11
+ vix_futures_trade_dates_and_expiry_dates, \
12
+ vix_constant_maturity_weights
13
+
14
+
15
+
16
+ _weighted_column_names=['Open','High','Low','Close','Settle','Change']
17
+
18
+
19
+ def do_weight(trades_df:pd.DataFrame,weight_df:pd.DataFrame,weight_column_name:str,tenor:int):
20
+ """
21
+ Produces a data frame containing a scaled set of select columns.
22
+ parameters:
23
+ ----------
24
+ trades_df: a DataFrame indexed by trade date on axis 0, and by an integer (which represents a tenor which could be monthly or weekly)
25
+ as the first level index on axis 1.
26
+ weight_df: a DataFrame with columns that represent the desired weights.
27
+ weight_column_name: the name of the column with the desired weights.
28
+ tenor: the column index of trades_df for the select columns to be scaled.
29
+
30
+ """
31
+ w=weight_df[weight_column_name]
32
+ weight_fn=partial(mul,w) #a function to multiply by w
33
+ tenor_df=trades_df[tenor]
34
+ v=tenor_df.apply(weight_fn) #apply to the relevant columns.
35
+ return v
36
+
37
+ def do_weighting_months(trades_df : pd.DataFrame,weight_df:pd.DataFrame,weights_and_tenors : list[(str,int)]) ->pd.DataFrame:
38
+ """ Produces a data frame containing the weighted mean of select columns.
39
+ parameters:
40
+ ----------
41
+ trades_df: a DataFrame indexed by trade date on axis 0, and by an integer (which represents a tenor which could be monthly or weekly)
42
+ as the first level index on axis 1.
43
+ weight_df: a dataframe with columns that represent the desired weights.
44
+ weights_and_tenors: a list of tuples of the name of the column weighting and the tenor to be used to find the columns in trades_df.
45
+
46
+ """
47
+ return sum(do_weight(trades_df,weight_df,n,t) for n,t in weights_and_tenors )
48
+
49
+ _weights_and_tenors_vix_front_months=[(f"T{i}W",i) for i in range(1,4)]
50
+
51
+ def do_weighting_front_three_months(trades_df : pd.DataFrame,weight_df : pd.DataFrame) -> pd.DataFrame:
52
+ """
53
+ produces a weighted mean of the nearest monthly futures resulting in an average of maturity one month.
54
+ parameters:
55
+ ----------
56
+ trades_df: a DataFrame indexed by trade date on axis 0, and by Tenor_Monthly (as the first level index) on axis 1.
57
+
58
+ """
59
+ return do_weighting_months(trades_df,weight_df,_weights_and_tenors_vix_front_months)
60
+
61
+ def append_continuous_maturity_one_month(monthly_wide_records : pd.DataFrame)->pd.DataFrame:
62
+ """
63
+ produces a weighted mean of the two nearest monthly futures (using continous_maturity_30day)
64
+ appends it to the monthly_wide_records, with Monthly_Tenor of 1.5 (for ease of sorting)
65
+ There will be fewer columns as the result of continous_maturity_30day has fewer columns for a tenor than
66
+ monthly_wide_records.
67
+ parameters:
68
+ -----------
69
+ monthly_records:
70
+ A DataFrame in a wide format of Monthly records, as returned by pivot_futures_on_monthly_tenor
71
+
72
+ """
73
+
74
+ cm=continuous_maturity_one_month(monthly_wide_records)
75
+ wide_columns=monthly_wide_records[1].columns
76
+ #intersection of columns in the two data frames
77
+
78
+ cols=[col for col in cm.columns if col in wide_columns ]
79
+ new_df1=monthly_wide_records.swaplevel(axis=1)[cols]
80
+ new_cm=cm[cols]
81
+ new_df2=new_df1.swaplevel(axis=1)
82
+ #add a level to new_cm
83
+ d={}
84
+ d[1.5]=new_cm
85
+ e=pd.concat(d,axis=1)
86
+
87
+ #concatenate new_cm (after adding the level of idexing)
88
+ new_df3=pd.concat([new_df2,e],axis=1).sort_index(axis=1)
89
+ return new_df3
90
+
91
+
92
+
93
+
94
+
95
+
96
+
97
+
98
+
99
+ def continuous_maturity_one_month(monthly_wide_records : pd.DataFrame)->pd.DataFrame:
100
+ """
101
+ produces a weighted mean of the two nearest monthly futures resulting in an average of maturity one month.
102
+ parameters:
103
+ -----------
104
+ monthly_records:
105
+ A DataFrame in a wide format of Monthly records, as returned by pivot_futures_on_monthly_tenor
106
+ """
107
+
108
+ df=vix_futures_trade_dates_and_expiry_dates()
109
+
110
+
111
+
112
+ futures_history=pd.DataFrame(monthly_wide_records)
113
+
114
+
115
+
116
+
117
+
118
+ weights_all=vix_constant_maturity_weights(df)
119
+
120
+ #we only need the weigths for dates we have trades
121
+ weights=weights_all[weights_all.index.isin(futures_history.index)]
122
+
123
+ #select the front three months and the columns that have trade values
124
+ #we need three because at times teh front month is ignored and the back two contracts are used.
125
+
126
+ with pd.option_context('display.max_columns',None):
127
+ logging.debug(f"\n{'*'*50}\nColumns to weight:\n{futures_history}")
128
+ front_three_months=futures_history[[1,2,3]]
129
+ futures_history_trade_value_columns=front_three_months.swaplevel(axis=1)[_weighted_column_names].swaplevel(axis=1)
130
+
131
+ weighted_values=do_weighting_front_three_months(futures_history_trade_value_columns,weights)
132
+
133
+ #should have the same number of rows
134
+ assert weighted_values.shape[0]==futures_history_trade_value_columns.shape[0]
135
+
136
+
137
+ df_file=front_three_months.swaplevel(axis=1)["File"]
138
+ weighted_values["File"]=df_file[1]+"+"+df_file[2]
139
+
140
+ weighted_values['Expiry']=weights['Expiry']
141
+
142
+
143
+ weighted_values["Tenor_Days"]=(weighted_values['Expiry']-weighted_values.index).dt.days
144
+
145
+
146
+ return weighted_values