Created
September 26, 2010 19:22
-
-
Save aasmith/598234 to your computer and use it in GitHub Desktop.
Option expiry date calculator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Extracted this code out that was not needed. | |
# Keeping here for future reference. | |
# | |
# Finds upcoming expiry dates for monthly equity options. | |
# | |
# Test data is the official CBOE expiration calendars for 2010/11. | |
require 'date' | |
require 'rubygems' | |
require 'active_support' | |
class OptionCalendar | |
class << self | |
FRIDAY = 5 | |
def expiration_for(month) | |
start = month.beginning_of_month | |
expiry_week = start.advance(:days => 14) | |
expiry_week += 1.day while expiry_week.wday != FRIDAY | |
expiry_saturday = expiry_week + 1.day | |
end | |
def next_expiring_months(from = Date.today) | |
this_month = expiration_for(from) | |
next_month = expiration_for(from.next_month) | |
expirations = [ | |
this_month, | |
next_month | |
] | |
# If the first month has already expired, remove it, and add another month out | |
if from >= (this_month - 1.day) | |
expirations.shift | |
expirations << expiration_for(next_month.next_month) | |
end | |
expirations | |
end | |
def nearest_expiration(date, range = 3.days) | |
expiration_date = expiration_for(date + range) | |
if date > expiration_date | |
expiration_date = expiration_for(expiration_date.next_month) | |
end | |
if date >= expiration_date - range | |
expiration_for(expiration_date.next_month) | |
else | |
expiration_date | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'option_calendar' | |
require 'test/unit' | |
class OptionCalendarTest < Test::Unit::TestCase | |
# Saturday expiries | |
EXPIRY_MONTHS = [ | |
[Date.parse("Jan 1 2010"), Date.parse("Jan 16 2010")], | |
[Date.parse("Feb 1 2010"), Date.parse("Feb 20 2010")], | |
[Date.parse("Mar 1 2010"), Date.parse("Mar 20 2010")], | |
[Date.parse("Apr 1 2010"), Date.parse("Apr 17 2010")], | |
[Date.parse("May 1 2010"), Date.parse("May 22 2010")], | |
[Date.parse("Jun 1 2010"), Date.parse("Jun 19 2010")], | |
[Date.parse("Jul 1 2010"), Date.parse("Jul 17 2010")], | |
[Date.parse("Aug 1 2010"), Date.parse("Aug 21 2010")], | |
[Date.parse("Sep 1 2010"), Date.parse("Sep 18 2010")], | |
[Date.parse("Oct 1 2010"), Date.parse("Oct 16 2010")], | |
[Date.parse("Nov 1 2010"), Date.parse("Nov 20 2010")], | |
[Date.parse("Dec 1 2010"), Date.parse("Dec 18 2010")], | |
[Date.parse("Jan 1 2011"), Date.parse("Jan 22 2011")], | |
[Date.parse("Feb 1 2011"), Date.parse("Feb 19 2011")], | |
[Date.parse("Mar 1 2011"), Date.parse("Mar 19 2011")], | |
[Date.parse("Apr 1 2011"), Date.parse("Apr 16 2011")], | |
[Date.parse("May 1 2011"), Date.parse("May 21 2011")], | |
[Date.parse("Jun 1 2011"), Date.parse("Jun 18 2011")], | |
[Date.parse("Jul 1 2011"), Date.parse("Jul 16 2011")], | |
[Date.parse("Aug 1 2011"), Date.parse("Aug 20 2011")], | |
[Date.parse("Sep 1 2011"), Date.parse("Sep 17 2011")], | |
[Date.parse("Oct 1 2011"), Date.parse("Oct 22 2011")], | |
[Date.parse("Nov 1 2011"), Date.parse("Nov 19 2011")], | |
[Date.parse("Dec 1 2011"), Date.parse("Dec 17 2011")] | |
] | |
def test_monthly_expirations | |
EXPIRY_MONTHS.each do |month, exp| | |
message = "Month #{month.strftime("%b")} should have expiry of #{exp}" | |
assert_equal exp, OptionCalendar.expiration_for(month), message | |
assert_equal exp, OptionCalendar.expiration_for(month.end_of_month), message | |
end | |
end | |
NEXT_MONTHS = [ | |
[Date.parse("Sep 15 2010"), Date.parse("Sep 18 2010"), Date.parse("Oct 16 2010")], | |
[Date.parse("Sep 16 2010"), Date.parse("Sep 18 2010"), Date.parse("Oct 16 2010")], | |
[Date.parse("Sep 17 2010"), Date.parse("Oct 16 2010"), Date.parse("Nov 20 2010")], | |
[Date.parse("Sep 18 2010"), Date.parse("Oct 16 2010"), Date.parse("Nov 20 2010")], | |
[Date.parse("Sep 19 2010"), Date.parse("Oct 16 2010"), Date.parse("Nov 20 2010")] | |
] | |
def test_next_expiring_months | |
NEXT_MONTHS.each do |date, *expected| | |
message = "#{date} should have expirations #{expected.inspect}" | |
assert_equal expected, OptionCalendar.next_expiring_months(date), message | |
end | |
end | |
def test_nearest_expiration | |
jan_expiry = OptionCalendar.expiration_for(Date.parse("Jan 2011")) | |
feb_expiry = OptionCalendar.expiration_for(Date.parse("Feb 2011")) | |
assert_equal jan_expiry, OptionCalendar.nearest_expiration(jan_expiry - 4.days, 3.days) | |
assert_equal feb_expiry, OptionCalendar.nearest_expiration(jan_expiry - 3.days, 3.days) | |
assert_equal feb_expiry, OptionCalendar.nearest_expiration(jan_expiry - 2.days, 3.days) | |
assert_equal jan_expiry, OptionCalendar.nearest_expiration(Date.parse("Dec 31 2010"), 3.days) | |
assert_equal feb_expiry, OptionCalendar.nearest_expiration(Date.parse("Dec 31 2010"), 30.days) | |
assert_equal feb_expiry, OptionCalendar.nearest_expiration(Date.parse("Nov 30 2010"), 60.days) | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment