OPEN-SOURCE SCRIPT

YURI Calendar Window Engine

11
Three date rules and one measurement. The rules mark the week the monthly listed-option expiry falls in, the turn of the month, and the last session before a US market holiday. The measurement is what this symbol's own daily returns have done on the days each rule marks, set against the days none of the three rules mark, with an error band built from one figure per run of the window rather than one per day. On the funds measured below, none of the three differences reaches that band. That is the result, and it is why nothing here is an entry.

HOW TO USE IT

Put it on a daily chart of a symbol that keeps a US exchange calendar, and load as much history as the chart will give. Each window needs 20 completed runs before its row reads, which is around two years of bars, and the error band goes on narrowing for a long time after that. A symbol that trades seven days a week is refused by name.

Read the status line first. It counts up to the minimum and then reads ok.

Then read the table. Today says which of the three windows the current bar falls in, if any. Each window row gives the mean daily return on the days that window marks, less the mean on ordinary days, in basis points a day, with its error band, its day count and its run count beside it. The comparison that matters is the difference against its own band. A difference smaller than its band is one the history on this chart does not separate from zero, and on the funds measured below that is how all three rows read.

The pane draws one window at a time. Pick it with Window drawn in the pane. The orange line is the running difference, the grey band is its error, and the tint marks the bars the rule selects, so the rule itself can be checked by eye against a calendar.

If the symbol pays dividends, set the chart's dividend adjustment on purpose before comparing any figure with the ones quoted here. THE CHART SETTING THAT MOVES ONE OF THEM says which row it moves and by how much.

WHY THE THREE RULES ARE IN ONE SCRIPT

An ordinary day can only be defined by naming every calendar rule it is not. The baseline each window is measured against is therefore not defined until all three calendars have been computed on the same bar, which is the thing a single-window marker cannot do for itself.

Compare a window against its own complement instead and the comparison is contaminated in a way that is easy to miss. The turn of the month then sits inside the expiry week's baseline, the expiry week sits inside the turn of the month's, and each rule is measured against a mixture containing the others. At the default edges the three rules between them label three days in five of a US equity fund's history, so the contamination would not be small: expiry weeks are 23 percent of days and the turn of the month window is 37 percent, against 38 percent left over.

The three windows are not versions of each other. On SPY's history the expiry week and the turn of the month share no day at all, by construction, since the expiry Friday is dated 15 to 21 and the turn window opens on the 26th. A session before a holiday lands inside an expiry week on 48 days and inside a turn of month on 136. The rank correlations between the three daily flags are small, the largest being minus 0.42, but that pair is the mutually exclusive one and its correlation is driven by the exclusivity rather than by anything in the returns. The count of shared days is the number that carries the point.

WHAT THE THREE WINDOWS ARE

Expiry week is the Monday to Friday week whose Friday is dated 15 to 21 of the month, which is the third Friday and the monthly expiry of US listed options. The rule is written as the nth Friday, so the setting can be moved to the second or fourth Friday's week to see what an ordinary week of the month reads by comparison. The whole week is marked, not the Friday alone.

The setting starts at the second Friday rather than the first, and the reason is worth stating because it is a limit of the arithmetic. A bar is tested by projecting it forward to the Friday of its own week and asking whether that day of month falls in the right range. A week containing a Friday dated 8 or later begins on a Monday dated 4 or later and so begins in the same month, which makes the projection exact; that was checked against a direct computation over every weekday from 1993 to 2026 at the second, third and fourth Friday, with no disagreement. The week of a month's first Friday can begin in the month before, where the projection runs past the end of the range and the early part of the week goes unmarked. At that setting 582 of the 2040 weekdays in those weeks would be missed, so the setting is out of range rather than approximately right.

Turn of the month opens on the first session dated on or after the 26th and closes after the fourth session of the new month. That is around four sessions either side of the boundary. The month's sessions are counted as they arrive rather than backwards from the month's end, which is what lets the far edge be placed without needing to know in advance which days the market will be open.

Session before a holiday is the last session before a day the US market is shut. Holidays are computed rather than listed. Most are a weekday-of-month rule plus the observed-day shift for the fixed dates, with two start years in them: Juneteenth from 2022, and the third Monday of January from 1998. That second one came out of checking the rules against a large index fund's own trading days, which show the exchange open on that Monday in 1994, 1995, 1996 and 1997 and shut on it from 1998 on. Good Friday follows Easter rather than the day of the month, so it is computed too, by the anonymous Gregorian computus in the Meeus, Jones and Butcher form, taking Easter Sunday and stepping back two days.

HOW THE HOLIDAY RULES WERE CHECKED

Against the market's own record rather than against a published list. Every weekday from 1993 to 2026 was compared with whether a large index fund printed a bar on it. Over 8467 sessions, no day the rules call a holiday is a day the market traded, and every one of the 34 Good Fridays in that window is a day it did not. Eleven closed weekdays are not caught: one in April 1994, four in September 2001, two in October 2012, and one each in June 2004, January 2007, December 2018 and January 2025. All eleven are one-off closures the market announced at the time, which is outside what any calendar rule can compute. The session before each of them is not marked, which is a miss on eleven days in 8467.

The Easter computation is why there is no date table in this script and no year it runs out in. An earlier version of this file carried a list of eleven Good Fridays and set aside two months of every year the list did not reach, which on a permanently published script would have meant a permanent degradation from 2027. The computation was checked against that list year for year, and against an independent implementation on every year from 1900 to 2099, with no disagreement in either; in all 200 of those years the result is a Friday, and it falls between March 21 and April 23.

Because of that, the session before Good Friday is marked in every year a chart carries. On the index fund's history that is 34 of 34, where a list covering eleven years could have reached eleven.

A bar that falls on a rules holiday while the chart still prints one, which is what a contract for difference on an index does, is set aside: it ends no run, enters no average of its own, and is counted in its own table row. Its close is still the price the next session's return is measured from, so that session is measured from the set-aside bar rather than from the last real session before it. On a US-listed fund the row reads zero and none of that arises, which is the check that says the calendar and the symbol agree.

WHAT THE NUMBER BESIDE EACH WINDOW IS

The mean daily log return of the days that window marks, in basis points, less the same mean over the days none of the three rules mark. A bar carries the label of its own date, and its return is the close to close move ending on it. No cost is deducted anywhere.

The band is two standard errors of that difference, and it is built from one figure per completed run of the window rather than one per day. A run is a maximal stretch of consecutive marked days: an expiry week is one run of four or five sessions, a turn of month is one run of five to nine, a session before a holiday is a run of one. Counting days would be the wrong denominator if the days inside one run moved together. Measured, they do not: on the twelve comparisons where a run is longer than a day, the run band comes out between 0.940 and 0.969 of the per day band, so the two ways of counting land within six percent of each other. Both figures are in the data window.

Six of the eighteen band comparisons are the pre-holiday bucket, whose runs are one day long by construction, so for those the two bands are arithmetically almost the same whatever the returns do and they are not evidence of anything. The claim above rests on the other twelve, which is why it is quoted as twelve.

Two point estimates are also kept apart and both are printed, and the relationship between them and the band is worth being exact about. Pooling days weights a long run more heavily than a short one; averaging run averages weights them alike. Those are not the same number when run lengths differ: across the eighteen combinations they differ by up to 39 percent of the printed band, and on SPY alone by up to 32. The pane draws the pooled one, while the band is the standard error of the run-weighted one, so the line and the band belong to two different estimators. The direction of that is one-sided and is stated here rather than left to be worked out: the run-weighted estimate is the smaller of the two in every one of the eighteen, with no exception in the other direction, so the pane shows the bigger estimate against the band of the smaller. Both sit inside the band throughout, and since nothing here is claimed to separate from zero, the pairing errs toward showing an effect that then fails to appear. A reader who wants the matched pair should read the run-weighted difference from the data window against the same band.

The run that is open when the chart's history begins is dropped, because its length is whatever the chart happens to start at, and the run still open on the last bar is not counted as a run either. Their days are still in the daily average. That last point is a right censoring and it moves the run count, not the mean.

MEASURED

SPY daily bars, 1993-01-29 to 2026-09-18, chart dividend adjustment on, 8466 classified daily returns. Ordinary days average +1.4 basis points. Expiry week averages +3.8, a difference of +2.4 against a band of 6.5, over 1983 days in 403 runs. Turn of the month averages +6.6, a difference of +5.2 against a band of 5.6, over 3124 days in 403 runs. The session before a holiday averages +9.9, a difference of +8.5 against a band of 11.6, over 298 days in 298 runs.

QQQ from 1999-03-10: minus 0.2 against 10.2, +4.0 against 8.9, +10.9 against 19.7. IWM from 2000-05-26: minus 0.6 against 9.2, +5.0 against 8.2, +14.4 against 16.4. Eighteen window and symbol and adjustment combinations were computed and none reaches two of its own standard errors. The closest is the turn of the month on SPY with the adjustment off, at +5.2 against 5.6, which is 94 percent of its own band.

Two sensitivity checks, because a number that only survives one setting is not a number. Moving the turn of month edges over a grid of three opening days by three closing days moves the SPY difference between +5.2 and +7.2, a span of 2.0 against a band of 5.6. Moving the marked week to a different Friday of the month gives minus 1.9 for the second Friday's week, +2.4 for the third and +1.2 for the fourth, each with a band near 7. Adjacent weeks of the same month come out on opposite sides of zero and all three sit inside their own bands. That is the shape a set of numbers inside their own error takes, and it is the most useful single fact in this description.

THE CHART SETTING THAT MOVES ONE OF THEM

The chart's adjust-for-dividends setting moves the expiry week figure by more than moving the window edges does, and it does so for a structural reason. All 135 of the ex-dividend dates in SPY's loaded history fall inside an expiry week, with a median size of 44 basis points. Turning the adjustment off takes SPY's expiry week reading from +2.4 basis points a day to minus 0.7, a swing of 3.03 on a band of 6.5, and it changes the sign.

The three funds are not alike in this. QQQ has 55 percent of its ex dates inside an expiry week and moves by 0.43. IWM has 17 percent and moves by 0.35. So the size of the effect is a property of the fund's distribution calendar, not of the market.

This script does not read the chart's adjustment setting. Whichever way it is set, both the window average and the ordinary day average are computed on the same series, so the comparison is internally consistent; it is the level of the expiry week figure that changes. The figures quoted above are with it on. Which way a fresh chart arrives set is a platform default rather than a property of the data, so read it off the chart rather than assuming it, and note which way it was when one of these numbers is quoted.

WHAT SEPARATES, AND IT IS NOT A RETURN

The one reading that comes apart cleanly is the spread, which is in the data window as the ratio of the window's daily standard deviation to an ordinary day's. The session before a holiday carries about four fifths of an ordinary session's daily spread: 0.79 on SPY, 0.86 on QQQ, 0.77 on IWM, and under one in 25 of SPY's 34 single years, 25 of QQQ's 28 and 25 of IWM's 27, so it is not one stretch of history doing the work. Part of it is the two shortened sessions, July 3 and December 24, which come in at 0.61, but the 261 full length pre-holiday sessions are still at 0.82. Expiry week and turn of month sit at 0.98 to 1.00 and separate on nothing.

The spread ratio carries no error band in this script and should be read as description rather than as a test. It was kept because it is measurably not the mean difference in other clothes: Spearman is asked second here, because rank correlation is blind to a fold: two readings related by something of the shape y = |2x - 100| can rank near zero against each other and still be one number. So the first question is whether either reading can be computed from the other. Reconstructing the spread ratio from the mean difference over a basis that contains the fold shapes leaves a largest residual of a third of the spread ratio's own range, and the same in reverse leaves a quarter, so neither is a formula of the other. Only then the rank tests: minus 0.73 straight, minus 0.66 against the absolute value of the difference and minus 0.46 against its fold about the median, and minus 0.29 as running series on SPY. All inside the 0.8 bar set beforehand.

A third candidate reading was computed and dropped. The share of up days in a window, less the same share on ordinary days, tracks the mean difference at a Spearman of +0.92 across the same eighteen combinations. That is past the bar, so it says nothing the mean difference has not already said and it is not in the file.

WHERE THE METHODS COME FROM

The turn of the month effect is Lakonishok and Smidt, 1988. The pre-holiday effect is Ariel, 1990. Neither is this script's idea and neither is claimed as one. For expiry week only the calendar definition is used, the third Friday being the monthly expiry of US listed options; no account of why a week around it might differ is offered here, because this script measures and does not explain.

What is added is the shared baseline, the run-based error band, the two point estimates side by side, the set-aside accounting, and the measurement above showing that on these funds the three differences sit inside their own error.

READING IT

A pane on a basis points a day scale. One orange line, the running difference for whichever window is selected, against a grey band at plus and minus two standard errors and a dotted line at zero. Both are running figures, so the band narrows as history accumulates and the line settles. What the pane mostly shows is an estimate wandering inside its own error, which is the honest picture.

The pane tints when the current bar falls inside the drawn window. All three windows are in the table whichever one is drawn.

The table carries which windows today falls in, one row per window with its difference, its band, its day count and its run count, the ordinary day average with its own counts, the days that fall in two windows at once, the days set aside and how many of those were days the market was shut, the total number of daily returns measured, a standing note that the basis is close to close log returns with no costs, and a status line.

The data window carries the two standard errors separately, the difference over its standard error, the spread ratio, the run-weighted difference, the shortest, longest and mean run length of the drawn window, and the classified and set-aside counts.

Wherever a reading is withheld the status line says which of the tests withheld it, instead of a number appearing with a caveat somewhere else. Eight sentences besides ok can appear there, and they are evaluated top to bottom: the bars are synthetic; the bar length is not one day; the symbol keeps a seven day week; weekend bars have shown up in the history; no month has turned over yet; this particular bar was not a session; the ordinary day ledger is short of runs; the drawn window's ledger is short of runs. The last pair are worded alike and kept apart because the two ledgers fill at different rates, so the one that is short is the one named. Synthetic bars are tested before anything else because that is the single case in which all the remaining tests would pass and a wrong reading would look right.

The default minimum is twenty completed runs per bucket. On a chart of 400 daily bars the expiry week ledger holds 18 of them and the pre-holiday ledger 15, so all three rows come in somewhere around two years of loaded history, and the status line counts up to it.

SETTINGS THAT MATTER

The turn of month opening day is the one judgement among the defaults. Twenty six is a round choice and nothing in this script argues it is the right one. The sensitivity above is what it is worth, and the setting is exposed with a range so that moving it is a keystroke.

Which Friday of the month the expiry falls on is three for US listed options. Two and four are there as a control rather than as settings to optimise, and one is out of range for the reason given above.

Completed runs before a window reads applies to the window and to the ordinary day baseline separately. Raising it delays every row and narrows nothing.

The error band in standard errors is two by default. Two standard errors is the usual convention and it is not an exact 95 percent interval here, since it assumes returns that are independent across runs and symmetric, and daily equity returns are neither exactly.

WHAT IT WILL NOT DO

There is no order in it, no alert in it, and nothing it prints is a signal. No filter, no trend condition and no position appear anywhere, deliberately: a readout with a condition bolted to it starts to look like it has answered a question it has not.

It does not say that any of these windows is worth trading. On the three funds measured, every one of the eighteen differences computed sits inside its own two standard error band, which is the opposite of that claim. What it is, is a marker for where in the calendar today falls, carrying how large the effect has been on the symbol in front of you and how large the error on that is.

No cost is deducted anywhere. These are gross close to close moves. A number of a few basis points a day is inside the cost of acting on it for most people, and that comparison is left to the reader because this script does not know what anyone pays.

The averages describe the history loaded on the chart. Scroll back further and they change. A reader on a longer history will see different counts from the ones quoted above, and the table prints the number of daily returns behind every figure for that reason.

The holiday rules are a US exchange calendar. On a symbol that keeps a different holiday calendar the rules will mark the last session before a US holiday, which may be an ordinary session for that symbol. On a symbol that trades at weekends, or whose type is crypto, the script refuses by name rather than reading anything, because the trading day counter behind the turn of month window would be counting days the rules do not recognise.

The bars have to be real prices. Chart types that synthesise a bar out of other bars, Heikin Ashi and Renko and Kagi and Line Break and Point and Figure and Range among them, produce a close that no trade happened at, and an average of those is an average of the chart's own construction. This is the one condition checked before all the others, because it is the one where nothing else would object and the readout would look ordinary.

The bar length has to be one day. Anything shorter, anything weekly or monthly, and the two, three and five day variants are each turned away with the reason on the status line. The multi-day variants deserve their own mention: they answer to most tests the way a daily chart does, so a script that only asked whether the chart was daily would read them and be wrong by a factor of two, three or five. When a chart is turned away, all twenty drawn elements go empty and all nine value cells show a dash, so there is nothing on screen to misread. The ten labels down the table's left column are fixed text and stay where they are.

Every figure looks backwards only. Nothing printed on a bar was computed from a later one, which means the bar still forming will move while it forms and stop moving at its close, and a bar already closed keeps the reading it had. The way that was established: the entire series was recomputed on histories cut short at three different points, one of them three thousand bars back, and each cut's final bar came out bit for bit equal to the same bar of the uncut run.

This is context for a decision, not the decision.

Отказ от ответственности

Информация и публикации не предназначены для предоставления и не являются финансовыми, инвестиционными, торговыми или другими видами советов или рекомендаций, предоставленных или одобренных TradingView. Подробнее читайте в Условиях использования.