Here we
present the Chronos
code that generates the list of each
day the New York Stock Exchange was closed the entire day from 1885
through the current year. The list does not show any Sundays, nor any
Saturdays
from 1953 onwards. The NYSE had a two hour trading session (10am to
Noon) on Saturdays from 1873 through 1952. To see the list: NYSE
Full-Day Closures, 1885-Present.
The code
depends upon the fact that the 'SemanticDatePolicy
nyse'
object knows both all the dates when the NYSE was closed for
exceptional reasons (e.g., in observance of the First Lunar Landing by
Apollo 11,) and also knows the current and former NYSE observance rules
for 'regularly-scheduled' market holidays, such as Columbus
day
(until 1954) and New Year's Day (which is not observed when it falls on
a Saturday.) Note that
the 'SemanticDatePolicy
nyse' object
is just an instance of SemanticDatePolicy itself--it is not a
specialized subclass coded to handle the NYSE rules and
exceptions--nor is there any other such NYSE-specific class in the
Chronos codebase.
|
byYears intraYearList stream | byYears
:= SortedCollection sortBlock: [:a :b | a key > b key]. 1885 to:
2006 do: [:year |
intraYearList := SortedCollection sortBlock: [:a :b | a key < b
key].
byYears add: year->intraYearList.
SemanticDatePolicy nyse observedEventOccurenceDatesInYear: year do:
[:semanticKey :date :observanceType |
semanticKey == #weekend
ifFalse:
[intraYearList add:
date->(Array
with:
semanticKey "The
semantic significance of the date."
with: observanceType)]]]. stream
:= 'NYSE_Observed_Holidays-1885-2006.txt' asFilename writeStream. [byYears
do: [:yearAssocToClosureList |
| observanceType |
yearAssocToClosureList value
do: [:assoc |
stream
cr;
nextPutAll:
(assoc key printStringUsing: #rfc2822); "The date"
nextPut: $:;
tab;
nextPutAll:
assoc value first. "The semantic significance of the
date."
observanceType := assoc value last.
observanceType == #nominal
ifFalse:
["The date was observed on some day
other than the
'nominal' day."
stream
space;
nextPut: $(;
nextPutAll: observanceType;
nextPut: $)]]. stream
cr]] ensure:
[stream close].
One can
also use the 'SemanticDatePolicy
nyse' object to
count the number of trading days between two dates, thusly:
[:minDate
:maxDate | | closureCount | minDate >
maxDate ifTrue: [^0]. closureCount := 0. SemanticDatePolicy
nyse
observedEventOccurenceDatesFrom: minDate
through: maxDate do:
[:semanticKey :date :observanceType |
semanticKey == #weekend
ifTrue:
[(date year between: 1873 and: 1952)
ifTrue: [date dayOfWeek = Sunday ifTrue:
[closureCount := closureCount + 1]]
ifFalse: [closureCount := closureCount +
1]]
ifFalse:
[closureCount := closureCount + 1]]. "Must
add 1 because it's a closed interval." (minDate
daysUntil: maxDate) + 1 - closureCount]
value: (YearMonthDay
year: 2003 month: March day: 12)
value: (YearMonthDay
year: 2006 month: January day: 12)
|