Featured image of post Investigating A VIX Trading Signal, Part 1: VIX And VVIX

Investigating A VIX Trading Signal, Part 1: VIX And VVIX

A brief look at finding a trading signal based on moving averages of the VIX.

Introduction

From the CBOE VIX website:

“Cboe Global Markets revolutionized investing with the creation of the Cboe Volatility Index® (VIX® Index), the first benchmark index to measure the market’s expectation of future volatility. The VIX Index is based on options of the S&P 500® Index, considered the leading indicator of the broad U.S. stock market. The VIX Index is recognized as the world’s premier gauge of U.S. equity market volatility.”

In this tutorial, we will investigate finding a signal to use as a basis to trade the VIX.

VIX Data

I don’t have access to data for the VIX through Nasdaq Data Link or any other data source, but for our purposes Yahoo Finance is sufficient. Using the yfinance python module, we can pull what we need and quicky dump it to excel to retain it for future use.

Python Functions

Here are the functions needed for this project:

  • calc_vix_trade_pnl: Calculates the profit/loss from VIX options trades.
  • df_info: A simple function to display the information about a DataFrame and the first five rows and last five rows.
  • df_info_markdown: Similar to the df_info function above, except that it coverts the output to markdown.
  • export_track_md_deps: Exports various text outputs to markdown files, which are included in the index.md file created when building the site with Hugo.
  • load_data: Load data from a CSV, Excel, or Pickle file into a pandas DataFrame.
  • pandas_set_decimal_places: Set the number of decimal places displayed for floating-point numbers in pandas.
  • plot_price: Plot the price data from a DataFrame for a specified date range and columns.
  • plot_stats: Generate a scatter plot for the mean OHLC prices.
  • plot_vix_with_trades: Plot the VIX daily high and low prices, along with the VIX spikes, and trades.
  • yf_pull_data: Download daily price data from Yahoo Finance and export it.

Data Overview (VIX)

Acquire CBOE Volatility Index (VIX) Data

First, let’s get the data:

1
2
3
4
5
6
7
8
9
yf_pull_data(
    base_directory=DATA_DIR,
    ticker="^VIX",
    source="Yahoo_Finance", 
    asset_class="Indices", 
    excel_export=True,
    pickle_export=True,
    output_confirmation=True,
)

Load Data - VIX

Now that we have the data, let’s load it up and take a look:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# Set decimal places
pandas_set_decimal_places(2)

# VIX
vix = load_data(
    base_directory=DATA_DIR,
    ticker="^VIX",
    source="Yahoo_Finance", 
    asset_class="Indices",
    timeframe="Daily",
)

# Set 'Date' column as datetime
vix['Date'] = pd.to_datetime(vix['Date'])

# Drop 'Volume'
vix.drop(columns = {'Volume'}, inplace = True)

# Set Date as index
vix.set_index('Date', inplace = True)

# Check to see if there are any NaN values
vix[vix['High'].isna()]

# Forward fill to clean up missing data
vix['High'] = vix['High'].ffill()

DataFrame Info - VIX

Now, running:

1
df_info(vix)

Gives us the following:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
The columns, shape, and data types are:

<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 8925 entries, 1990-01-02 to 2025-06-09
Data columns (total 4 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   Close   8925 non-null   float64
 1   High    8925 non-null   float64
 2   Low     8925 non-null   float64
 3   Open    8925 non-null   float64
dtypes: float64(4)
memory usage: 348.6 KB

The first 5 rows are:

DateCloseHighLowOpen
1990-01-02 00:00:0017.2417.2417.2417.24
1990-01-03 00:00:0018.1918.1918.1918.19
1990-01-04 00:00:0019.2219.2219.2219.22
1990-01-05 00:00:0020.1120.1120.1120.11
1990-01-08 00:00:0020.2620.2620.2620.26

The last 5 rows are:

DateCloseHighLowOpen
2025-06-03 00:00:0017.6919.2117.6418.83
2025-06-04 00:00:0017.6118.0717.4117.68
2025-06-05 00:00:0018.4818.8017.0817.68
2025-06-06 00:00:0016.7718.3516.6518.16
2025-06-09 00:00:0017.1617.7216.8217.69

Statistics - VIX

Some interesting statistics jump out at us when we look at the mean, standard deviation, minimum, and maximum values for the full dataset. The following code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
vix_stats = vix.describe()
num_std = [-1, 0, 1, 2, 3, 4, 5]
for num in num_std:
    vix_stats.loc[f"mean + {num} std"] = {
        'Open': vix_stats.loc['mean']['Open'] + num * vix_stats.loc['std']['Open'],
        'High': vix_stats.loc['mean']['High'] + num * vix_stats.loc['std']['High'],
        'Low': vix_stats.loc['mean']['Low'] + num * vix_stats.loc['std']['Low'],
        'Close': vix_stats.loc['mean']['Close'] + num * vix_stats.loc['std']['Close'],
    }
display(vix_stats)

Gives us:

CloseHighLowOpen
count8925.008925.008925.008925.00
mean19.4920.4118.8219.59
std7.848.397.397.91
min9.149.318.569.01
25%13.8814.5313.4113.93
50%17.6618.3917.0817.70
75%22.8423.8422.1522.98
max82.6989.5372.7682.69
mean + -1 std11.6612.0111.4311.68
mean + 0 std19.4920.4118.8219.59
mean + 1 std27.3328.8026.2127.50
mean + 2 std35.1637.1933.6035.41
mean + 3 std43.0045.5940.9943.32
mean + 4 std50.8453.9848.3851.23
mean + 5 std58.6762.3855.7759.14

We can also run the statistics individually for each year:

1
2
3
4
5
6
7
8
# Group by year and calculate mean and std for OHLC
vix_stats_by_year = vix.groupby(vix.index.year)[["Open", "High", "Low", "Close"]].agg(["mean", "std"])

# Flatten the column MultiIndex
vix_stats_by_year.columns = ['_'.join(col).strip() for col in vix_stats_by_year.columns.values]
vix_stats_by_year.index.name = "Year"

display(vix_stats_by_year)

Gives us:

YearOpen_meanOpen_stdOpen_minOpen_maxHigh_meanHigh_stdHigh_minHigh_maxLow_meanLow_stdLow_minLow_maxClose_meanClose_stdClose_minClose_max
199023.064.7414.7236.4723.064.7414.7236.4723.064.7414.7236.4723.064.7414.7236.47
199118.383.6813.9536.2018.383.6813.9536.2018.383.6813.9536.2018.383.6813.9536.20
199215.232.2610.2920.6716.032.1911.9025.1314.852.1410.2919.6715.452.1211.5121.02
199312.701.379.1816.2013.341.409.5518.3112.251.288.8915.7712.691.339.3117.30
199413.792.069.8623.6114.582.2810.3128.3013.381.999.5923.6113.932.079.9423.87
199512.271.0310.2915.7912.931.0710.9516.9911.960.9810.0614.9712.390.9710.3615.74
199616.311.9211.2423.9016.992.1212.2927.0515.941.8211.1121.4316.441.9412.0021.99
199722.434.3316.6745.6923.114.5618.0248.6421.853.9816.3636.4322.384.1417.0938.20
199825.686.9616.4247.9526.617.3616.5049.5324.896.5816.1045.5825.606.8616.2345.74
199924.392.9018.0532.6225.203.0118.4833.6623.752.7617.0731.1324.372.8817.4232.98
200023.413.4316.8133.7024.103.6617.0634.3122.753.1916.2830.5623.323.4116.5333.49
200126.044.9819.2148.9326.645.1919.3749.3525.224.6118.7442.6625.754.7818.7643.74
200227.537.0317.2348.1728.287.2517.5148.4626.606.6417.0242.0527.296.9117.4045.08
200322.215.3115.5935.2122.615.3516.1935.6621.645.1814.6633.9921.985.2415.5834.69
200415.591.9311.4121.0616.052.0211.6422.6715.051.7911.1420.6115.481.9211.2321.58
200512.841.4410.2318.3313.281.5910.4818.5912.391.329.8816.4112.811.4710.2317.74
200612.902.189.6823.4513.332.4610.0623.8112.381.969.3921.4512.812.259.9023.81
200717.595.369.9932.6818.445.7610.2637.5016.754.959.7030.4417.545.369.8931.09
200832.8316.4116.3080.7434.5717.8317.8489.5330.9614.9615.8272.7632.6916.3816.3080.86
200931.759.2019.5452.6532.789.6119.6757.3630.508.6319.2549.2731.489.0819.4756.65
201022.735.2915.4447.6623.695.8216.0048.2021.694.6115.2340.3022.555.2715.4545.79
201124.278.1714.3146.1825.408.7814.9948.0023.157.5914.2741.5124.208.1414.6248.00
201217.932.6013.6826.3518.592.7214.0827.7317.212.3713.3025.7217.802.5413.4526.66
201314.291.6711.5220.8714.821.8811.7521.9113.801.5111.0519.0414.231.7411.3020.49
201414.232.6510.4029.2614.953.0210.7631.0613.612.2110.2824.6414.172.6210.3225.27
201516.713.9911.7731.9117.795.0312.2253.2915.853.6510.8829.9116.674.3411.9540.74
201616.014.0511.3229.0116.854.4011.4932.0915.163.6610.9326.6715.833.9711.2728.14
201711.141.349.2316.1911.721.549.5217.2810.641.168.5614.9711.091.369.1416.04
201816.635.019.0137.3218.036.129.3150.3015.534.258.9229.6616.645.099.1537.32
201915.572.7411.5527.5416.413.0611.7928.5314.762.3811.0324.0515.392.6111.5425.45
202029.5412.4512.2082.6931.4613.8912.4285.4727.5110.8511.7570.3729.2512.3412.1082.69
202119.833.4715.0235.1621.124.2215.5437.5118.652.9314.1029.2419.663.6215.0137.21
202225.984.3016.5737.5027.254.5917.8138.9424.693.9116.3433.1125.624.2216.6036.45
202317.123.1711.9627.7717.833.5812.4630.8116.362.8911.8124.0016.873.1412.0726.52
202415.693.1411.5333.7116.654.7312.2365.7314.922.5810.6224.0215.613.3611.8638.57
202521.847.2514.8960.1323.538.8515.1660.1320.305.3414.5838.5821.526.8714.7752.33

It is interesting to see how much the mean OHLC values vary by year.

And finally, we can run the statistics individually for each month:

1
2
3
4
5
6
7
8
# Group by month and calculate mean and std for OHLC
vix_stats_by_month = vix.groupby(vix.index.month)[["Open", "High", "Low", "Close"]].agg(["mean", "std"])

# Flatten the column MultiIndex
vix_stats_by_month.columns = ['_'.join(col).strip() for col in vix_stats_by_month.columns.values]
vix_stats_by_month.index.name = "Month"

display(vix_stats_by_month)

Gives us:

MonthOpen_meanOpen_stdOpen_minOpen_maxHigh_meanHigh_stdHigh_minHigh_maxLow_meanLow_stdLow_minLow_maxClose_meanClose_stdClose_minClose_max
119.347.219.0151.5220.137.589.3157.3618.606.878.9249.2719.227.179.1556.65
219.677.2210.1952.5020.517.6510.2653.1618.906.819.7048.9719.587.1310.0252.62
320.479.6310.5982.6921.3910.4911.2485.4719.548.6510.5370.3720.359.5610.7482.69
419.437.4810.3960.1320.247.9310.8960.5918.656.8810.2252.7619.297.2810.3657.06
518.606.049.7547.6619.406.4310.1448.2017.895.639.5640.3018.515.969.7745.79
618.455.809.7944.0919.156.0710.2844.4417.735.449.3734.9718.345.729.7540.79
717.875.759.1848.1718.585.989.5248.4617.245.488.8442.0517.805.679.3644.92
819.176.7410.0445.3420.127.4510.3265.7318.446.389.5241.7719.186.879.9348.00
920.518.329.5948.9321.358.649.8349.3519.747.909.3643.7420.438.209.5146.72
1021.8310.289.2379.1322.8311.109.6289.5320.939.519.1167.8021.7510.249.1980.06
1120.349.659.3180.7421.0410.039.7481.4819.559.028.5672.7620.169.529.1480.86
1219.348.269.3666.6820.098.539.5568.6018.637.888.8962.3119.298.169.3168.51

Deciles - VIX

Here are the levels for each decile, for the full dataset:

1
2
vix_deciles = vix.quantile(np.arange(0, 1.1, 0.1))
display(vix_deciles)

Gives us:

CloseHighLowOpen
0.009.149.318.569.01
0.1012.1212.6311.7212.13
0.2013.2613.8812.8513.31
0.3014.6115.2914.0814.68
0.4016.1016.7615.5616.13
0.5017.6618.3917.0817.70
0.6019.5520.3919.0019.69
0.7021.6422.6520.9921.79
0.8024.3125.3623.5024.38
0.9028.7030.0027.7828.86
1.0082.6989.5372.7682.69

Plots - VIX

Histogram Distribution - VIX

A quick histogram gives us the distribution for the entire dataset, along with the levels for the mean minus 1 standard deviation, mean, mean plus 1 standard deviation, mean plus 2 standard deviations, mean plus 3 standard deviations, and mean plus 4 standard deviations:

Histogram, Mean, And Standard Deviations

Historical Data - VIX

Here’s two plots for the dataset. The first covers 1990 - 2009, and the second 2010 - Present. This is the daily high level:

VIX Daily High, 1990 - 2009

VIX Daily High, 2010 - Present

From these plots, we can see the following:

  • The VIX has really only jumped above 50 several times (GFC, COVID, recently in August of 2024)
  • The highest levels (> 80) occured only during the GFC & COVID
  • Interestingly, the VIX did not ever get above 50 during the .com bubble

Stats By Year - VIX

Here’s the plot for the mean OHLC values for the VIX by year:

VIX OHLC Stats By Year

Stats By Month - VIX

Here’s the plot for the mean OHLC values for the VIX by month:

VIX OHLC Stats By Month

Data Overview (VVIX)

Before moving on to generating a signal, let’s run the above data overview code again, but this time for the CBOE VVIX. From the CBOE VVIX website:

“Volatility is often called a new asset class, and every asset class deserves its own volatility index. The Cboe VVIX IndexSM represents the expected volatility of the VIX®. VVIX derives the expected 30-day volatility of VIX by applying the VIX algorithm to VIX options.”

Looking at the statistics of the VVIX should give us an idea of the volatility of the VIX.

Acquire CBOE VVIX Data

First, let’s get the data:

1
2
3
4
5
6
7
8
9
yf_pull_data(
    base_directory=DATA_DIR,
    ticker="^VVIX",
    source="Yahoo_Finance", 
    asset_class="Indices", 
    excel_export=True,
    pickle_export=True,
    output_confirmation=True,
)

Load Data - VVIX

Now that we have the data, let’s load it up and take a look:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# Set decimal places
pandas_set_decimal_places(2)

# VVIX
vvix = load_data(
    base_directory=DATA_DIR,
    ticker="^VVIX",
    source="Yahoo_Finance", 
    asset_class="Indices",
    timeframe="Daily",
)

# Set 'Date' column as datetime
vvix['Date'] = pd.to_datetime(vvix['Date'])

# Drop 'Volume'
vvix.drop(columns = {'Volume'}, inplace = True)

# Set Date as index
vvix.set_index('Date', inplace = True)

# Check to see if there are any NaN values
vvix[vvix['High'].isna()]

# Forward fill to clean up missing data
vvix['High'] = vvix['High'].ffill()

DataFrame Info - VVIX

Now, running:

1
df_info(vvix)

Gives us the following:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
The columns, shape, and data types are:

<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 8925 entries, 1990-01-02 to 2025-06-09
Data columns (total 4 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   Close   8925 non-null   float64
 1   High    8925 non-null   float64
 2   Low     8925 non-null   float64
 3   Open    8925 non-null   float64
dtypes: float64(4)
memory usage: 348.6 KB

The first 5 rows are:

DateCloseHighLowOpen
1990-01-02 00:00:0017.2417.2417.2417.24
1990-01-03 00:00:0018.1918.1918.1918.19
1990-01-04 00:00:0019.2219.2219.2219.22
1990-01-05 00:00:0020.1120.1120.1120.11
1990-01-08 00:00:0020.2620.2620.2620.26

The last 5 rows are:

DateCloseHighLowOpen
2025-06-03 00:00:0017.6919.2117.6418.83
2025-06-04 00:00:0017.6118.0717.4117.68
2025-06-05 00:00:0018.4818.8017.0817.68
2025-06-06 00:00:0016.7718.3516.6518.16
2025-06-09 00:00:0017.1617.7216.8217.69

Statistics - VVIX

Here are the statistics for the VVIX, generated in the same manner as above for the VIX:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
vvix_stats = vvix.describe()
num_std = [-1, 0, 1, 2, 3, 4, 5]
for num in num_std:
    vvix_stats.loc[f"mean + {num} std"] = {
        'Open': vvix_stats.loc['mean']['Open'] + num * vvix_stats.loc['std']['Open'],
        'High': vvix_stats.loc['mean']['High'] + num * vvix_stats.loc['std']['High'],
        'Low': vvix_stats.loc['mean']['Low'] + num * vvix_stats.loc['std']['Low'],
        'Close': vvix_stats.loc['mean']['Close'] + num * vvix_stats.loc['std']['Close'],
    }
display(vvix_stats)

Gives us:

CloseHighLowOpen
count4629.004629.004629.004629.00
mean93.5095.5591.9493.75
std16.4418.0415.0916.49
min59.7459.7459.3159.31
25%82.3483.4681.4882.55
50%90.5492.2689.3790.86
75%102.20105.0199.93102.55
max207.59212.22187.27212.22
mean + -1 std77.0677.5076.8577.26
mean + 0 std93.5095.5591.9493.75
mean + 1 std109.94113.59107.04110.25
mean + 2 std126.38131.64122.13126.74
mean + 3 std142.82149.68137.22143.23
mean + 4 std159.26167.73152.32159.72
mean + 5 std175.69185.77167.41176.21

We can also run the statistics individually for each year:

1
2
3
4
5
6
7
8
# Group by year and calculate mean and std for OHLC
vvix_stats_by_year = vvix.groupby(vvix.index.year)[["Open", "High", "Low", "Close"]].agg(["mean", "std"])

# Flatten the column MultiIndex
vvix_stats_by_year.columns = ['_'.join(col).strip() for col in vvix_stats_by_year.columns.values]
vvix_stats_by_year.index.name = "Year"

display(vvix_stats_by_year)

Gives us:

YearOpen_meanOpen_stdOpen_minOpen_maxHigh_meanHigh_stdHigh_minHigh_maxLow_meanLow_stdLow_minLow_maxClose_meanClose_stdClose_minClose_max
200787.6813.3163.52142.9987.6813.3163.52142.9987.6813.3163.52142.9987.6813.3163.52142.99
200881.8515.6059.74134.8781.8515.6059.74134.8781.8515.6059.74134.8781.8515.6059.74134.87
200979.788.6364.95104.0279.788.6364.95104.0279.788.6364.95104.0279.788.6364.95104.02
201088.3613.0764.87145.1288.3613.0764.87145.1288.3613.0764.87145.1288.3613.0764.87145.12
201192.9410.2175.94134.6392.9410.2175.94134.6392.9410.2175.94134.6392.9410.2175.94134.63
201294.848.3878.42117.4494.848.3878.42117.4494.848.3878.42117.4494.848.3878.42117.44
201380.528.9762.71111.4380.528.9762.71111.4380.528.9762.71111.4380.528.9762.71111.43
201483.0114.3361.76138.6083.0114.3361.76138.6083.0114.3361.76138.6083.0114.3361.76138.60
201595.4415.5973.07212.2298.4716.3976.41212.2292.1513.3572.20148.6894.8214.7573.18168.75
201693.3610.0277.96131.9595.8210.8678.86132.4290.548.9976.17115.1592.8010.0776.17125.13
201790.508.6575.09134.9892.949.6477.34135.3287.857.7871.75117.2990.018.8075.64135.32
2018102.6013.2283.70176.72106.2716.2685.00203.7399.1711.3182.60165.35102.2614.0483.21180.61
201991.288.4375.58112.7593.618.9875.95117.6388.907.8674.36111.4891.038.3674.98114.40
2020118.6419.3288.39203.03121.9120.8888.54209.76115.0517.3785.31187.27118.3619.3986.87207.59
2021115.519.3796.09151.35119.2911.7098.36168.78111.998.1495.92144.19115.3210.2097.09157.69
2022102.5818.0176.48161.09105.3219.1677.93172.8299.1716.8176.13153.26101.8117.8177.05154.38
202390.958.6474.43127.7393.729.9875.31137.6588.017.3772.27119.6490.348.3873.88124.75
202492.8815.0659.31169.6897.3218.3374.79192.4989.5113.1659.31137.0592.8115.6073.26173.32
2025106.3015.8983.19186.33111.3018.6885.82189.03101.6412.3781.73146.51105.2615.1481.89170.92

And finally, we can run the statistics individually for each month:

1
2
3
4
5
6
7
8
# Group by month and calculate mean and std for OHLC
vvix_stats_by_month = vvix.groupby(vvix.index.month)[["Open", "High", "Low", "Close"]].agg(["mean", "std"])

# Flatten the column MultiIndex
vvix_stats_by_month.columns = ['_'.join(col).strip() for col in vvix_stats_by_month.columns.values]
vvix_stats_by_month.index.name = "Year"

display(vvix_stats_by_month)

Gives us:

YearOpen_meanOpen_stdOpen_minOpen_maxHigh_meanHigh_stdHigh_minHigh_maxLow_meanLow_stdLow_minLow_maxClose_meanClose_stdClose_minClose_max
192.4615.6364.87161.0994.3717.6364.87172.8290.6914.2364.87153.2692.2315.7864.87157.69
293.4918.2465.47176.7295.3920.7065.47203.7391.3916.4365.47165.3593.1318.5865.47180.61
395.3021.6666.97203.0397.3823.5666.97209.7692.9419.5166.97187.2794.8921.5966.97207.59
492.1819.0359.74186.3394.0120.5759.74189.0390.3017.2159.74152.0191.8818.6059.74170.92
592.2516.9361.76145.1893.9517.9961.76151.5090.5416.1461.76145.1291.7916.7961.76146.28
692.9114.9663.52155.4894.4416.2163.52172.2191.3013.9263.52140.1592.7214.9363.52151.60
789.9713.1667.21138.4291.4614.2367.21149.6088.4812.2667.21133.8289.8413.1267.21139.54
896.8316.9468.05212.2298.8918.7268.05212.2294.6814.8668.05148.6896.6116.6368.05173.32
994.7114.0367.94135.1796.5015.5267.94146.3192.8612.5067.94128.4694.4013.7867.94138.93
1097.7414.0164.97149.6099.4315.1164.97154.9996.1413.3564.97144.5597.5214.1564.97152.01
1193.5314.1763.77142.6895.0715.3663.77161.7691.9813.3963.77140.4493.2814.2463.77149.74
1293.3515.0359.31151.3595.3316.6362.71168.3791.7813.7059.31144.1993.4615.0762.71156.10

Deciles - VVIX

Here are the levels for each decile, for the full dataset:

1
2
vvix_deciles = vvix.quantile(np.arange(0, 1.1, 0.1))
display(vvix_deciles)

Gives us:

CloseHighLowOpen
0.0059.7459.7459.3159.31
0.1075.8376.0275.4475.80
0.2080.5881.4379.8280.75
0.3083.9085.2283.0184.17
0.4087.0888.5785.9887.46
0.5090.5492.2689.3790.86
0.6094.2196.1493.0394.51
0.7099.11101.5397.4399.40
0.80106.06109.40103.90106.48
0.90115.27118.80112.48115.53
1.00207.59212.22187.27212.22

Plots - VVIX

Histogram Distribution - VVIX

A quick histogram gives us the distribution for the entire dataset, along with the levels for the mean minus 1 standard deviation, mean, mean plus 1 standard deviation, mean plus 2 standard deviations, mean plus 3 standard deviations, and mean plus 4 standard deviations:

Histogram, Mean, And Standard Deviations

Historical Data - VVIX

Here’s two plots for the dataset. The first covers 2007 - 2016, and the second 2017 - Present. This is the daily high level:

VVIX Daily High, 2007 - 2016

VVIX Daily High, 2017 - Present

Stats By Year - VVIX

Here’s the plot for the mean OHLC values for the VVIX by year:

VVIX OHLC Stats By Year

Stats By Month - VVIX

Here’s the plot for the mean OHLC values for the VVIX by month:

VVIX OHLC Stats By Month

References

  1. https://www.cboe.com/tradable_products/vix/
  2. https://github.com/ranaroussi/yfinance

Code

The jupyter notebook with the functions and all other code is available here.
The html export of the jupyter notebook is available here.
The pdf export of the jupyter notebook is available here.

Built with Hugo
Theme Stack designed by Jimmy