Skip to content

Instantly share code, notes, and snippets.

@aasmith
Created September 26, 2010 19:22
Show Gist options
  • Save aasmith/598234 to your computer and use it in GitHub Desktop.
Save aasmith/598234 to your computer and use it in GitHub Desktop.
Option expiry date calculator
# 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
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