Strasmore Research
Learn am Matt ConnorBy Matt Connor

VXX ETN: wetin e be and why e dey bleed

VXX no be the VIX. Na ETN wey dey roll VIX futures every day, and the panels here show how e dey grind down if you hold am, plus the 2020 spike wey e give back.

VXX no be the VIX. VXX na one ETN, exchange traded note, wey dey hold the two nearest VIX futures months and dey roll dem every single trading day, so wetin e dey follow na VIX futures, no be the spot number wey dem dey shout for TV. If you buy VXX for your Bamboo, Trove, Chaka or Risevest app the day market scatter, wetin enter your account na short dated futures exposure wrapped inside one IOU from a bank. The panels below show, with real daily prices, wetin dey happen to that kind hold over months and years.

Wetin VXX actually hold

Separate two things first.

  • The VIX na index wey CBOE dey calculate from SPX option prices. Nobody fit buy the index itself. Na number, like temperature reading. We break the calculation down for wetin be the VIX index.
  • VIX futures na contract wey settle to that index on one fixed future date. VXX dey hold the front month and the second month, and every day e dey shift small piece of the position from the front to the back, to keep the average maturity near 30 days.

That daily shift na the engine of this whole post. Whenever the second month dey price higher than the front month, the daily roll dey sell the cheaper contract and buy the costlier one. Market people call that shape contango, and the drag wey e leave behind na roll yield. We do the full mechanics for contango and roll yield inside ETF. VXX no promise anybody the VIX level. Wetin the note promise na the return of one futures index after that daily roll, minus fees.

Wetin the long hold look like

No adjective, just the tape. This panel take the month end close for VXX from January 2019, adjusted for the reverse splits wey we go show below.

QueryVXX month end close since January 2019, adjusted for reverse splits
90 rows (showing 20)
monthmonth_labelvxx_close_adjchange_pct
2019-01-01Jan 2019158474.240
2019-05-01May 2019124600.32-21.4
2019-06-01Jun 2019106496-32.8
2019-07-01Jul 201996624.64-39
2019-08-01Aug 2019110592-30.2
2019-09-01Sep 201997239.04-38.6
2019-10-01Oct 201980896-49
2019-11-01Nov 201967747.84-57.2
2019-12-01Dec 201961931.52-60.9
2020-01-01Jan 202066355.2-58.1
2020-02-01Feb 202093429.76-41
2020-03-01Mar 202018944019.5
2020-04-01Apr 2020155115.52-2.1
2020-05-01May 2020135700.48-14.4
2020-06-01Jun 2020139059.2-12.3
2020-07-01Jul 2020116817.92-26.3
2020-08-01Aug 2020109977.6-30.6
2020-09-01Sep 2020101990.4-35.6
2020-10-01Oct 2020108666.88-31.4
2020-11-01Nov 202070369.28-55.6
The exact SQL behind every number
WITH splits AS
(
    SELECT
        groupArray(execution_date) AS split_dates,
        groupArray(price_factor)   AS price_factors
    FROM
    (
        SELECT
            execution_date,
            toFloat64(any(split_from)) / toFloat64(any(split_to)) AS price_factor
        FROM global_markets.stocks_splits
        WHERE ticker = 'VXX'
        GROUP BY execution_date
    )
),
daily AS
(
    SELECT
        a.date AS date,
        toFloat64(a.close) * arrayProduct(arrayMap((d, f) -> if(d > a.date, f, 1.0), s.split_dates, s.price_factors)) AS adj_close
    FROM global_markets.stocks_daily_aggs AS a
    CROSS JOIN splits AS s
    WHERE a.ticker = 'VXX'
      AND a.date >= toDate('2019-01-01')
),
month_end AS
(
    SELECT
        toStartOfMonth(date)    AS month_start,
        argMax(adj_close, date) AS adj_close
    FROM daily
    GROUP BY month_start
)
SELECT
    toString(month_start)                AS month,
    formatDateTime(month_start, '%b %Y') AS month_label,
    round(adj_close, 2)                  AS vxx_close_adj,
    round(100 * (adj_close / first_value(adj_close) OVER (ORDER BY month_start) - 1), 1) AS change_pct
FROM month_end
ORDER BY month_start
Run am yourself

The panel run from Jan 2019 to Sep 2026, 90 month end prices. Over that stretch the split adjusted price move from $158474.24 to $17.51, wey be -100% end to end.

Two things dey inside those numbers. One, the January 2019 figure dey enter six figures as plain arithmetic: a stack of 1-for-4 reverse splits sit after that month, and each one multiply the older quote by four to state am in today's share terms. Na the same slice of the note, just written the way one share dey quote today. Two, the end to end column dey talk about that adjusted stake, no be about the trading quote. Na near total wipeout in adjusted terms, while the reverse splits keep the live quote, the last number inside the panel, inside normal trading range. The note no reach zero; the adjusted value na the thing wey collapse.

Look the shape well, e no be straight line down. The line dey flat, den e dey shoot up for a few weeks when volatility waka, den the grind dey continue from the new level. Anybody wey enter during one of those jumps and hold am dey carry the grind wey follow.

Year by year, how the grind look

Same series, cut by calendar year: first session close of the year against the last one.

QueryVXX change by calendar year, first session close to last session close
yearchange_pctsessions
2019-66.8188
202015.7253
2021-93.7252
2022-21.1251
2023-93.1250
2024-81.6252
2025-43.5250
2026-32.9181
The exact SQL behind every number
WITH splits AS
(
    SELECT
        groupArray(execution_date) AS split_dates,
        groupArray(price_factor)   AS price_factors
    FROM
    (
        SELECT
            execution_date,
            toFloat64(any(split_from)) / toFloat64(any(split_to)) AS price_factor
        FROM global_markets.stocks_splits
        WHERE ticker = 'VXX'
        GROUP BY execution_date
    )
),
daily AS
(
    SELECT
        a.date AS date,
        toFloat64(a.close) * arrayProduct(arrayMap((d, f) -> if(d > a.date, f, 1.0), s.split_dates, s.price_factors)) AS adj_close
    FROM global_markets.stocks_daily_aggs AS a
    CROSS JOIN splits AS s
    WHERE a.ticker = 'VXX'
      AND a.date >= toDate('2019-01-01')
)
SELECT
    toString(toYear(date))                                                  AS year,
    round(100 * (argMax(adj_close, date) / argMin(adj_close, date) - 1), 1) AS change_pct,
    count()                                                                 AS sessions
FROM daily
GROUP BY year
ORDER BY year
Run am yourself

2019 close at -66.8%. Even 2020, the year of the biggest volatility wahala since 2008, land at 15.7% on this measure, after the March run wey we trace below. The last row na 2026 with 181 sessions inside am, so e still dey partial, and e dey stand at -32.9%.

The reverse splits na the receipt

When a price grind down reach one point, the quote go too small to trade well. The fix wey issuers dey use na reverse split: four shares turn one share, and the quoted price multiply by four. VXX don do am more than once.

QueryEvery VXX split on record, and the share math behind am
execution_datesplit_labelold_shares_per_share_now
2010-11-091-for-44
2012-10-051-for-416
2013-11-081-for-464
2016-08-091-for-4256
2017-08-231-for-41024
2021-04-231-for-44096
2023-03-071-for-416384
2024-07-241-for-465536
The exact SQL behind every number
SELECT
    toString(execution_date)                                    AS execution_date,
    concat(toString(split_to), '-for-', toString(split_from))   AS split_label,
    round(exp(sum(log(toFloat64(split_from) / toFloat64(split_to))) OVER (ORDER BY execution_date)), 0) AS old_shares_per_share_now
FROM
(
    SELECT
        execution_date,
        any(split_from) AS split_from,
        any(split_to)   AS split_to
    FROM global_markets.stocks_splits
    WHERE ticker = 'VXX'
    GROUP BY execution_date
)
ORDER BY execution_date
Run am yourself

8 splits dey inside the record, and the latest one na 1-for-4 on 2024-07-24. The last column dey count how many old shares equal one share of today: by the final row e reach 65536. Any price chart wey no adjust for these events go show you a note wey look like e hold value, when wetin actually happen na that the share count keep shrinking.

The 2020 window: e jump, e give am back

Now pin one real window wey no dey change again. Weekly closes from the week volatility begin waka for February 2020, running one full year forward. gain_pct na where the hold dey each week compared with the first week. peak_gain_pct na the best point the hold ever touch up till that week.

QueryFeb 2020 to Feb 2021: VXX weekly gain from the start week, and the running peak
55 rows (showing 20)
weekweek_labelgain_pctpeak_gain_pct
2020-02-10Feb 10, 202000
2020-02-17Feb 17, 202010.210.2
2020-02-24Feb 24, 202068.768.7
2020-03-02Mar 2, 2020120.6120.6
2020-03-09Mar 9, 2020219.5250.3
2020-03-16Mar 16, 2020347.9410.4
2020-03-23Mar 23, 2020274.3410.4
2020-03-30Mar 30, 2020236.2410.4
2020-04-06Apr 6, 2020207.5410.4
2020-04-13Apr 13, 2020188.8410.4
2020-04-20Apr 20, 2020207.1410.4
2020-04-27Apr 27, 2020204.7410.4
2020-05-04May 4, 2020158.5410.4
2020-05-11May 11, 2020170.7410.4
2020-05-18May 18, 2020154.1410.4
2020-05-25May 25, 2020145410.4
2020-06-01Jun 1, 2020115.8410.4
2020-06-08Jun 8, 2020186.3410.4
2020-06-15Jun 15, 2020172.9410.4
2020-06-22Jun 22, 2020177.4410.4
The exact SQL behind every number
WITH splits AS
(
    SELECT
        groupArray(execution_date) AS split_dates,
        groupArray(price_factor)   AS price_factors
    FROM
    (
        SELECT
            execution_date,
            toFloat64(any(split_from)) / toFloat64(any(split_to)) AS price_factor
        FROM global_markets.stocks_splits
        WHERE ticker = 'VXX'
        GROUP BY execution_date
    )
),
daily AS
(
    SELECT
        a.date AS date,
        toFloat64(a.close) * arrayProduct(arrayMap((d, f) -> if(d > a.date, f, 1.0), s.split_dates, s.price_factors)) AS adj_close
    FROM global_markets.stocks_daily_aggs AS a
    CROSS JOIN splits AS s
    WHERE a.ticker = 'VXX'
      AND a.date >= toDate('2020-02-14')
      AND a.date <  toDate('2021-03-01')
),
weekly AS
(
    SELECT
        toMonday(date)          AS week_start,
        argMax(adj_close, date) AS week_close,
        max(adj_close)          AS week_high
    FROM daily
    GROUP BY week_start
)
SELECT
    toString(week_start)                       AS week,
    formatDateTime(week_start, '%b %e, %Y')    AS week_label,
    round(100 * (week_close / first_value(week_close) OVER (ORDER BY week_start) - 1), 1) AS gain_pct,
    round(100 * (max(week_high) OVER (ORDER BY week_start) / first_value(week_close) OVER (ORDER BY week_start) - 1), 1) AS peak_gain_pct
FROM weekly
ORDER BY week_start
Run am yourself

Starting from the week of Feb 10, 2020, the running peak reach 410.4% above where the hold begin. Na plenty money for a few weeks, and na why VXX dey trend for every market wahala. Then follow the same line go the end: by Feb 22, 2021, about one year later, the same hold dey stand at 18.6% from the start point. That na the part wey people dey miss. The jump and the giveback dey live inside the same instrument.

The volatility level dey come back. The note no dey come back.

Volatility itself no dey trend to zero. E dey climb, e dey fall back to a normal zone. To show that with per contract data, this panel take SPY options near the money with 20 to 45 days to expiry and read the median implied volatility for each month. Implied volatility na the volatility number wey the option price dey imply, the same family of number wey the VIX dey summarise for SPX.

QuerySPY near the money implied volatility, monthly median, 20 to 45 days to expiry
61 rows (showing 20)
monthmonth_labelspy_iv_pctwindow_high_pct
2021-09-01Sep 202114.727.9
2021-10-01Oct 202114.327.9
2021-11-01Nov 20211427.9
2021-12-01Dec 202116.127.9
2022-01-01Jan 202218.427.9
2022-02-01Feb 202221.627.9
2022-03-01Mar 202222.127.9
2022-04-01Apr 202219.527.9
2022-05-01May 202226.327.9
2022-06-01Jun 20222527.9
2022-07-01Jul 20222327.9
2022-08-01Aug 202219.827.9
2022-09-01Sep 202225.627.9
2022-10-01Oct 202227.927.9
2022-11-01Nov 20222327.9
2022-12-01Dec 202220.827.9
2023-01-01Jan 202319.327.9
2023-02-01Feb 202318.727.9
2023-03-01Mar 202319.927.9
2023-04-01Apr 202316.427.9
The exact SQL behind every number
SELECT
    month,
    month_label,
    spy_iv_pct,
    round(max(spy_iv_pct) OVER (), 1) AS window_high_pct
FROM
(
    SELECT
        toStartOfMonth(date)                        AS month_start,
        toString(toStartOfMonth(date))              AS month,
        formatDateTime(toStartOfMonth(date), '%b %Y') AS month_label,
        round(100 * quantileDeterministic(0.5)(toFloat64(implied_volatility), cityHash64(ticker)), 1) AS spy_iv_pct
    FROM global_markets.options_greeks
    WHERE underlying_symbol = 'SPY'
      AND iv_converged = 1
      AND volume > 0
      AND days_to_expiry BETWEEN 20 AND 45
      AND toFloat64(underlying_close) > 0
      AND abs(toFloat64(strike_price) / toFloat64(underlying_close) - 1) < 0.05
      AND date >= toDate('2021-09-01')
    GROUP BY month_start, month, month_label
)
ORDER BY month_start
Run am yourself

From Sep 2021 the monthly median sit at 14.7%, the highest month inside the window print 27.9%, and by Sep 2026 e dey 13.3%. Na round trip. Put the two panels side by side and the lesson clear: the volatility level come back to im zone, the VXX price no come back. The gap between the two na the roll plus fees, stacking session after session. Na also why VIX linked products no dey move one to one with the index, something we treat on im own for why VIX options no dey track the VIX.

ETN mean say na the issuer you dey trust

One more part wey investors dey skip when dem compare VXX with a normal ETF. An ETF dey hold assets: shares, futures, cash, inside a fund wey get custodian. An ETN na unsecured debt note. Barclays Bank PLC issue VXX, and wetin you hold na dem promise to pay the index return. Four practical points follow from that structure.

  1. Credit risk: na the issuer promise you carry. No basket of VIX futures dey sit somewhere with your name on am.
  2. Issuance risk: an issuer fit stop creating new units. When creation stop, the market price fit waka far from the note indicative value, and whoever buy for that premium carry the gap.
  3. Call and maturity: ETNs get maturity date, and plenty of dem give the issuer right to call the note early. Those terms dey inside the prospectus, no be inside the app wey you dey use to buy.
  4. Settlement by formula: when a note end, na the terms of the note decide wetin you collect, no be the sale of any pot of assets.

Daily arithmetic wey work the same kind way dey inside leverage products too, and we cover am for how leveraged ETF dey work.

So who dey use VXX, and how?

Wetin the panels dey show na that VXX na short horizon instrument by design. Traders wey use am dey hold am for days or weeks around one event dem dey watch, den dem exit. The daily roll na cost wey dey run every session, so the longer the hold, the more of that cost the position dey carry. Nothing here na recommendation to buy or sell anything. Na the mechanics and the measured history. One last basic point for anybody buying through a Nigerian app: VXX no dey pay dividend or coupon. All the return na price.

FAQ

VXX and VIX na the same thing?

No. The VIX na index wey CBOE calculate from SPX option prices, and nobody fit buy the index directly. VXX na ETN wey hold the first two VIX futures months and roll dem daily, so the two numbers fit waka different on the same day.

Why VXX price dey grind down over time?

The note dey roll from the front VIX futures month into the next month every trading day. When the next month dey cost more, that shape wey dem call contango, the daily roll dey give up small value, and the effect dey compound over months. The panels above measure the outcome for the windows dem cover.

VXX fit go to zero?

The quoted price dey get support from reverse splits: whenever e too low, four shares turn one and the price multiply by four. The split panel above count how many times e happen. Separately, ETNs get maturity date and often an issuer call right, so a note fit end before the holder plan to sell.

Wetin make ETN different from ETF?

An ETF dey hold assets inside a fund with a custodian. An ETN na unsecured note from a bank, so wetin you hold na the issuer credit plus the index return. If issuance stop, the market price fit trade away from the indicative value.


Every panel here carry the exact SQL under am, open any one and see how the number come. If you wan run the same measure for another ticker or another window, ask the question for plain English on the Strasmore terminal.

#vxx#vix#volatility etn#contango#etn credit risk