OPEN-SOURCE SCRIPT
VIX Seasonal Analog Composite

█ OVERVIEW
VIX Seasonal Analog Composite draws three lines in a separate pane: the average seasonal path of all complete years of VIX history, a composite of the historical years whose year-to-date VIX path most closely resembles the current year, and the current year's own VIX path. The script requests CBOE:VIX daily closes directly, so it displays VIX seasonality on any chart symbol: applied to an S&P 500 chart, the pane still shows the VIX. All lines are expressed as a percentage of each year's first daily VIX close, and both seasonal lines are projected forward to the end of the current calendar year. The thesis is that the remainder of a VIX year can be contextualized by the average behavior of prior years, and more specifically by the subset of prior years that have tracked the current year most closely so far.
█ HISTORY / BACKGROUND
Seasonal averaging is a long-standing technique in technical analysis: normalize each historical year to a common starting point, average across years by position in the calendar, and read the result as the instrument's typical annual path. Applied to the VIX Index, it captures the well-documented tendency of implied volatility to trough in summer and firm into autumn. Its main weakness is that every year receives equal weight, so years with no resemblance to current conditions dilute the picture.
The analog-year refinement addresses this. Instead of averaging all history, it ranks past years by their similarity to the current year's realized path and averages only the closest matches. Variants of this approach appear in institutional volatility research. The specific similarity metric, selection count, and construction details vary by practitioner and are generally not disclosed. This script implements one explicit, reproducible version of the method for the VIX with all parameters exposed as inputs.
█ HOW IT WORKS
The script runs a single accumulation pass over the chart's daily history and defers all computation and drawing to the last bar.
1. On every chart bar, the script requests the CBOE:VIX daily close through `request.security`. Calendar-year boundaries are detected with `year(time)`. The first available VIX close of each year becomes that year's anchor. Every subsequent VIX close is stored as close divided by the anchor, indexed by trading-day-of-year (0 to 252), in a persistent matrix with one row per year. Bars where the VIX returns no data, such as chart history predating 1990, are skipped.
2. On the last bar, completed years are screened for eligibility: a year must contain at least the minimum number of observations (default 200 trading days) to enter any calculation. The current year is always excluded from the historical pools.
3. The seasonal average is computed per trading-day index as the arithmetic mean of the normalized values of all eligible years at that index.
4. Analog ranking begins once the current year has at least the minimum elapsed days (default 10). For each eligible year, the script computes the root mean square error between that year's normalized path and the current year's normalized path over the trading days elapsed so far, skipping missing pairs. Years are ranked by ascending RMSE and the closest N (default 10) are selected. The analog composite is the per-day mean of the selected years across the full 253-day span, including days the current year has not yet reached.
5. Both seasonal lines are drawn as polylines anchored to bar time: actual bar times for elapsed days, then projected dates stepped one calendar day at a time with weekends skipped for the remainder of the year.
6. The current-year line is drawn over elapsed days only. By default it is linearly rescaled so that its year-to-date range maps onto the vertical range of the two seasonal curves, emulating a second axis within a single-scale pane. A label at its last point shows the true unrescaled year-to-date percentage.
7. A table in the top right lists the selected analog years and their RMSE scores.
Ranking is recomputed on every update, so the analog set can rotate as the current year develops.
█ HOW TO USE
Apply the indicator to any daily chart of a symbol that trades on the US equity session calendar, such as an S&P 500 index chart or the VIX itself. The pane always displays VIX seasonality regardless of the chart symbol, which allows the seasonal context to sit directly beneath the index you are analyzing. The logic counts trading days within calendar years using the chart's bars, so it is designed for the daily timeframe only; other resolutions will produce meaningless day indexing. VIX daily history extends to 1990, so a chart with sufficient loaded history builds seasonal pools from roughly three and a half decades of complete years.
The gray line is the unconditional seasonal script: what an average year looks like. The colored composite line is the conditional version: what years resembling this one looked like, including how they finished. The red line is the current year. Divergence between the current year and the composite indicates the year is departing from its closest historical precedents; the table shows which years those precedents are and how tight the fits are (lower RMSE means closer). A rotating analog table across weeks means the current year lacks a stable historical match, which is itself information.
The projected segments beyond the current date are historical averages extended in time. They describe how past years behaved from this calendar point onward. They are not forecasts.
█ SETTINGS
• Top analog years: number of closest historical years in the composite. Default 10.
• Min trading days for an eligible year: observation floor for a year to enter any pool. Default 200.
• Min elapsed days before analog ranking: current-year data required before ranking begins. Default 10.
• Show all-year seasonal average: toggles the gray average line. Default on.
• Show top-N analog composite: toggles the composite line. Default on.
• Show current-year YTD line: toggles the current-year path. Default on.
• Rescale YTD onto seasonal range (RHS-style): maps the current-year line onto the seasonal
curves' vertical range for readability. Default on.
• Project remainder of year: extends the seasonal lines to year end. Default on.
• Show analog year table: toggles the analog list with RMSE scores. Default on.
• Average color, Analog composite color, YTD color: line colors.
• Line width: width of all three lines. Default 2.
█ WHAT MAKES IT ORIGINAL
Published seasonality scripts typically plot a single all-year average. This script adds a similarity-ranked analog layer computed entirely on the chart: it maintains a full year-by-trading-day matrix of normalized paths, scores every eligible historical year against the current year by RMSE on each update, and averages only the closest matches, so the composite is conditional on how the current year has actually traded rather than on the calendar alone. The construction is fully disclosed and parameterized, including the similarity metric, the selection count, and the eligibility gates. The forward projection is drawn with time-anchored polylines so both seasonal paths extend beyond the last bar to year end, and the current-year line uses an optional range-mapping transform to keep all three curves readable on a single pane scale, with a label preserving the true value.
█ NOTES / LIMITATIONS
• Daily timeframe only. The trading-day indexing that underlies every calculation assumes one bar
per trading day.
• The analog set is re-ranked on every recalculation using the current year's realized path. The
composite line therefore changes shape as the year develops, including its already-drawn portion.
This is inherent to the method, and it means the line you see today is not the line you would
have seen a month ago. Treat it as a conditional historical average, not a signal history.
• The pane always shows the VIX. The chart symbol supplies only the bar grid and timeline.
• Trading-day indexing follows the chart symbol's bars. Chart symbols whose sessions differ from
the US equity calendar, such as symbols with weekend bars or non-US holiday schedules, will
misalign the day indexing. Use a chart symbol on the US equity session.
• The seasonal pools depend on the chart's loaded bar depth and on VIX data availability from
1990. A chart with shallow history averages over fewer years, and less than two complete years
of overlap draws no seasonal lines at all. Chart bars predating 1990 contribute nothing.
• Partial first years, and any year below the observation floor, are excluded by the eligibility
gate.
• Years are capped at 253 trading days; any bars beyond that index within a year are ignored.
• Forward projection steps calendar days and skips weekends but not exchange holidays, so
projected dates drift a few days long by December. Alignment between curves is by trading-day
index and is unaffected.
• With rescaling on, the pane axis is literal for the seasonal lines only. The current-year line's
axis position is a range mapping; read its true value from the label at its endpoint. Early in
a year, a small realized range makes the rescaled line visually exaggerated.
• All output is drawn over the current calendar year plus its projection. The pane is empty over
prior history, which is expected: prior years are inputs to the curves, not drawn objects.
• The script draws with polylines, a label, and a table only, and declares no plot series, so the
pane scale derives from the drawings.
• Nothing in this script is validated as predictive. Both curves are descriptive averages of
historical paths.
VIX Seasonal Analog Composite draws three lines in a separate pane: the average seasonal path of all complete years of VIX history, a composite of the historical years whose year-to-date VIX path most closely resembles the current year, and the current year's own VIX path. The script requests CBOE:VIX daily closes directly, so it displays VIX seasonality on any chart symbol: applied to an S&P 500 chart, the pane still shows the VIX. All lines are expressed as a percentage of each year's first daily VIX close, and both seasonal lines are projected forward to the end of the current calendar year. The thesis is that the remainder of a VIX year can be contextualized by the average behavior of prior years, and more specifically by the subset of prior years that have tracked the current year most closely so far.
█ HISTORY / BACKGROUND
Seasonal averaging is a long-standing technique in technical analysis: normalize each historical year to a common starting point, average across years by position in the calendar, and read the result as the instrument's typical annual path. Applied to the VIX Index, it captures the well-documented tendency of implied volatility to trough in summer and firm into autumn. Its main weakness is that every year receives equal weight, so years with no resemblance to current conditions dilute the picture.
The analog-year refinement addresses this. Instead of averaging all history, it ranks past years by their similarity to the current year's realized path and averages only the closest matches. Variants of this approach appear in institutional volatility research. The specific similarity metric, selection count, and construction details vary by practitioner and are generally not disclosed. This script implements one explicit, reproducible version of the method for the VIX with all parameters exposed as inputs.
█ HOW IT WORKS
The script runs a single accumulation pass over the chart's daily history and defers all computation and drawing to the last bar.
1. On every chart bar, the script requests the CBOE:VIX daily close through `request.security`. Calendar-year boundaries are detected with `year(time)`. The first available VIX close of each year becomes that year's anchor. Every subsequent VIX close is stored as close divided by the anchor, indexed by trading-day-of-year (0 to 252), in a persistent matrix with one row per year. Bars where the VIX returns no data, such as chart history predating 1990, are skipped.
2. On the last bar, completed years are screened for eligibility: a year must contain at least the minimum number of observations (default 200 trading days) to enter any calculation. The current year is always excluded from the historical pools.
3. The seasonal average is computed per trading-day index as the arithmetic mean of the normalized values of all eligible years at that index.
4. Analog ranking begins once the current year has at least the minimum elapsed days (default 10). For each eligible year, the script computes the root mean square error between that year's normalized path and the current year's normalized path over the trading days elapsed so far, skipping missing pairs. Years are ranked by ascending RMSE and the closest N (default 10) are selected. The analog composite is the per-day mean of the selected years across the full 253-day span, including days the current year has not yet reached.
5. Both seasonal lines are drawn as polylines anchored to bar time: actual bar times for elapsed days, then projected dates stepped one calendar day at a time with weekends skipped for the remainder of the year.
6. The current-year line is drawn over elapsed days only. By default it is linearly rescaled so that its year-to-date range maps onto the vertical range of the two seasonal curves, emulating a second axis within a single-scale pane. A label at its last point shows the true unrescaled year-to-date percentage.
7. A table in the top right lists the selected analog years and their RMSE scores.
Ranking is recomputed on every update, so the analog set can rotate as the current year develops.
█ HOW TO USE
Apply the indicator to any daily chart of a symbol that trades on the US equity session calendar, such as an S&P 500 index chart or the VIX itself. The pane always displays VIX seasonality regardless of the chart symbol, which allows the seasonal context to sit directly beneath the index you are analyzing. The logic counts trading days within calendar years using the chart's bars, so it is designed for the daily timeframe only; other resolutions will produce meaningless day indexing. VIX daily history extends to 1990, so a chart with sufficient loaded history builds seasonal pools from roughly three and a half decades of complete years.
The gray line is the unconditional seasonal script: what an average year looks like. The colored composite line is the conditional version: what years resembling this one looked like, including how they finished. The red line is the current year. Divergence between the current year and the composite indicates the year is departing from its closest historical precedents; the table shows which years those precedents are and how tight the fits are (lower RMSE means closer). A rotating analog table across weeks means the current year lacks a stable historical match, which is itself information.
The projected segments beyond the current date are historical averages extended in time. They describe how past years behaved from this calendar point onward. They are not forecasts.
█ SETTINGS
• Top analog years: number of closest historical years in the composite. Default 10.
• Min trading days for an eligible year: observation floor for a year to enter any pool. Default 200.
• Min elapsed days before analog ranking: current-year data required before ranking begins. Default 10.
• Show all-year seasonal average: toggles the gray average line. Default on.
• Show top-N analog composite: toggles the composite line. Default on.
• Show current-year YTD line: toggles the current-year path. Default on.
• Rescale YTD onto seasonal range (RHS-style): maps the current-year line onto the seasonal
curves' vertical range for readability. Default on.
• Project remainder of year: extends the seasonal lines to year end. Default on.
• Show analog year table: toggles the analog list with RMSE scores. Default on.
• Average color, Analog composite color, YTD color: line colors.
• Line width: width of all three lines. Default 2.
█ WHAT MAKES IT ORIGINAL
Published seasonality scripts typically plot a single all-year average. This script adds a similarity-ranked analog layer computed entirely on the chart: it maintains a full year-by-trading-day matrix of normalized paths, scores every eligible historical year against the current year by RMSE on each update, and averages only the closest matches, so the composite is conditional on how the current year has actually traded rather than on the calendar alone. The construction is fully disclosed and parameterized, including the similarity metric, the selection count, and the eligibility gates. The forward projection is drawn with time-anchored polylines so both seasonal paths extend beyond the last bar to year end, and the current-year line uses an optional range-mapping transform to keep all three curves readable on a single pane scale, with a label preserving the true value.
█ NOTES / LIMITATIONS
• Daily timeframe only. The trading-day indexing that underlies every calculation assumes one bar
per trading day.
• The analog set is re-ranked on every recalculation using the current year's realized path. The
composite line therefore changes shape as the year develops, including its already-drawn portion.
This is inherent to the method, and it means the line you see today is not the line you would
have seen a month ago. Treat it as a conditional historical average, not a signal history.
• The pane always shows the VIX. The chart symbol supplies only the bar grid and timeline.
• Trading-day indexing follows the chart symbol's bars. Chart symbols whose sessions differ from
the US equity calendar, such as symbols with weekend bars or non-US holiday schedules, will
misalign the day indexing. Use a chart symbol on the US equity session.
• The seasonal pools depend on the chart's loaded bar depth and on VIX data availability from
1990. A chart with shallow history averages over fewer years, and less than two complete years
of overlap draws no seasonal lines at all. Chart bars predating 1990 contribute nothing.
• Partial first years, and any year below the observation floor, are excluded by the eligibility
gate.
• Years are capped at 253 trading days; any bars beyond that index within a year are ignored.
• Forward projection steps calendar days and skips weekends but not exchange holidays, so
projected dates drift a few days long by December. Alignment between curves is by trading-day
index and is unaffected.
• With rescaling on, the pane axis is literal for the seasonal lines only. The current-year line's
axis position is a range mapping; read its true value from the label at its endpoint. Early in
a year, a small realized range makes the rescaled line visually exaggerated.
• All output is drawn over the current calendar year plus its projection. The pane is empty over
prior history, which is expected: prior years are inputs to the curves, not drawn objects.
• The script draws with polylines, a label, and a table only, and declares no plot series, so the
pane scale derives from the drawings.
• Nothing in this script is validated as predictive. Both curves are descriptive averages of
historical paths.
סקריפט קוד פתוח
ברוח האמיתית של TradingView, יוצר הסקריפט הזה הפך אותו לקוד פתוח, כך שסוחרים יוכלו לעיין בו ולאמת את פעולתו. כל הכבוד למחבר! אמנם ניתן להשתמש בו בחינם, אך זכור כי פרסום חוזר של הקוד כפוף ל־כללי הבית שלנו.
כתב ויתור
המידע והפרסומים אינם מיועדים להיות, ואינם מהווים, ייעוץ או המלצה פיננסית, השקעתית, מסחרית או מכל סוג אחר המסופקת או מאושרת על ידי TradingView. קרא עוד ב־תנאי השימוש.
סקריפט קוד פתוח
ברוח האמיתית של TradingView, יוצר הסקריפט הזה הפך אותו לקוד פתוח, כך שסוחרים יוכלו לעיין בו ולאמת את פעולתו. כל הכבוד למחבר! אמנם ניתן להשתמש בו בחינם, אך זכור כי פרסום חוזר של הקוד כפוף ל־כללי הבית שלנו.
כתב ויתור
המידע והפרסומים אינם מיועדים להיות, ואינם מהווים, ייעוץ או המלצה פיננסית, השקעתית, מסחרית או מכל סוג אחר המסופקת או מאושרת על ידי TradingView. קרא עוד ב־תנאי השימוש.