|
@@ -1,7 +1,11 @@
|
|
|
# -*- coding: utf-8 -*-
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
from QuantLib import *
|
|
from QuantLib import *
|
|
|
-
|
|
|
|
|
|
|
+from bs4 import BeautifulSoup
|
|
|
|
|
+from urllib2 import urlopen, Request
|
|
|
|
|
+from time import strftime
|
|
|
|
|
+import time
|
|
|
|
|
+import traceback
|
|
|
|
|
|
|
|
|
|
|
|
|
def cal_implvol(spot, strike, callput, evaldate, exdate, rate, div, vol, premium):
|
|
def cal_implvol(spot, strike, callput, evaldate, exdate, rate, div, vol, premium):
|
|
@@ -71,11 +75,132 @@ def str2qdate(yyyymmdd):
|
|
|
return Date(int(yyyymmdd[6:8]), months[int(yyyymmdd[4:6])-1 ], int(yyyymmdd[0:4]))
|
|
return Date(int(yyyymmdd[6:8]), months[int(yyyymmdd[4:6])-1 ], int(yyyymmdd[0:4]))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+def qdate2str(dd):
|
|
|
|
|
+ return '%s%s%s' % (dd.ISO()[0:4], dd.ISO()[5:7], dd.ISO()[8:10])
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
def str2qopt_type(callput):
|
|
def str2qopt_type(callput):
|
|
|
if callput.upper() == 'C':
|
|
if callput.upper() == 'C':
|
|
|
return Option.Call
|
|
return Option.Call
|
|
|
return Option.Put
|
|
return Option.Put
|
|
|
|
|
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def get_hk_holidays(year):
|
|
|
|
|
+ month_names = {'January' : 1,
|
|
|
|
|
+ 'February': 2,
|
|
|
|
|
+ 'March': 3,
|
|
|
|
|
+ 'April': 4,
|
|
|
|
|
+ 'May': 5,
|
|
|
|
|
+ 'June': 6,
|
|
|
|
|
+ 'July': 7,
|
|
|
|
|
+ 'August': 8,
|
|
|
|
|
+ 'September': 9,
|
|
|
|
|
+ 'October': 10,
|
|
|
|
|
+ 'November': 11,
|
|
|
|
|
+ 'December': 12,
|
|
|
|
|
+ }
|
|
|
|
|
+ try:
|
|
|
|
|
+ url = 'http://www.gov.hk/en/about/abouthk/holiday/{{year}}.htm'
|
|
|
|
|
+ url = url.replace('{{year}}', str(year))
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ headers = { 'User-Agent' : 'Mozilla/5.0' }
|
|
|
|
|
+ req = Request(url, None, headers)
|
|
|
|
|
+ html = urlopen(req).read()
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ soup = BeautifulSoup(html, 'html5lib')
|
|
|
|
|
+
|
|
|
|
|
+ tds = soup.findAll('h3')[0].parent.findAll('td', 'date')
|
|
|
|
|
+
|
|
|
|
|
+ d1 = map(lambda x: (int(x.text.split(' ')[0]), x.text.split(' ')[1]), tds[1:])
|
|
|
|
|
+ holidays = map(lambda x: '%d%02d%02d' % (year, int(month_names[x[1]]), int(x[0]) ), d1)
|
|
|
|
|
+ #return map(lambda x: strftime('%Y%m%d', time.strptime('%s %s %s' % (month_names.index(x[1])+1, x[0], year), "%m %d %Y")), d1)
|
|
|
|
|
+ #print d1
|
|
|
|
|
+ print holidays
|
|
|
|
|
+
|
|
|
|
|
+ return holidays
|
|
|
|
|
+
|
|
|
|
|
+ except:
|
|
|
|
|
+ traceback.print_exc()
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def get_HSI_last_trading_day(holidays, month, year):
|
|
|
|
|
+
|
|
|
|
|
+ cal = HongKong()
|
|
|
|
|
+ map(lambda x: cal.addHoliday(str2qdate(x)), holidays)
|
|
|
|
|
+
|
|
|
|
|
+ def deduce_last_trading_day(ld):
|
|
|
|
|
+
|
|
|
|
|
+ ld = ld - 1
|
|
|
|
|
+ #print '###' + str(ld)
|
|
|
|
|
+ if cal.isHoliday(ld):
|
|
|
|
|
+ return deduce_last_trading_day(ld - 1)
|
|
|
|
|
+ elif not cal.isBusinessDay(ld):
|
|
|
|
|
+ return deduce_last_trading_day(ld - 1)
|
|
|
|
|
+ else:
|
|
|
|
|
+ #print '---' + str(ld)
|
|
|
|
|
+ return ld
|
|
|
|
|
+
|
|
|
|
|
+ return qdate2str(deduce_last_trading_day(Date.endOfMonth(Date(1, month, year))))
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+# QUANTLIB Period class usage:
|
|
|
|
|
+# https://ipythonquant.wordpress.com/2015/04/04/a-brief-introduction-to-the-quantlib-in-python/
|
|
|
|
|
+# check usage below:
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+# def get_HSI_expiry(year):
|
|
|
|
|
+#
|
|
|
|
|
+# month_names = [January,
|
|
|
|
|
+# February,
|
|
|
|
|
+# March,
|
|
|
|
|
+# April,
|
|
|
|
|
+# May,
|
|
|
|
|
+# June,
|
|
|
|
|
+# July,
|
|
|
|
|
+# August,
|
|
|
|
|
+# September,
|
|
|
|
|
+# October,
|
|
|
|
|
+# November,
|
|
|
|
|
+# December,
|
|
|
|
|
+# ]
|
|
|
|
|
+# mm_dd = {}
|
|
|
|
|
+# # load calendar
|
|
|
|
|
+# holidays = ['20160101', '20160208', '20160209', '20160210', '20160325', '20160326', '20160328', '20160404', '20160502', '20160514', '20160609', '20160701', '20160916', '20161001', '20161010', '20161226', '20161227']
|
|
|
|
|
+# chk = HongKong()
|
|
|
|
|
+#
|
|
|
|
|
+#
|
|
|
|
|
+# map(lambda x: chk.addHoliday(Date(int(x[6:8]), month_names[int(x[4:6])-1], int(x[0:4]))), holidays)
|
|
|
|
|
+#
|
|
|
|
|
+#
|
|
|
|
|
+# #print Date.todaysDate() - 1
|
|
|
|
|
+# #chk.addHoliday(Date(24, December, 2015))
|
|
|
|
|
+# def deduce_last_trading_day(ld):
|
|
|
|
|
+# # ld -=1
|
|
|
|
|
+# ld = ld - 1
|
|
|
|
|
+#
|
|
|
|
|
+# if chk.isHoliday(ld):
|
|
|
|
|
+# return deduce_last_trading_day(ld - 1)
|
|
|
|
|
+# elif not chk.isBusinessDay(ld):
|
|
|
|
|
+# return deduce_last_trading_day(ld - 1)
|
|
|
|
|
+#
|
|
|
|
|
+# print ld
|
|
|
|
|
+# return ld
|
|
|
|
|
+#
|
|
|
|
|
+#
|
|
|
|
|
+#
|
|
|
|
|
+# return map(lambda x: deduce_last_trading_day(Date.endOfMonth(Date(1, x, year) + Period("1m"))), range(1, 12))
|
|
|
|
|
+# #mm_dd = deduce_last_trading_day(Date.endOfMonth(Date.todaysDate()))
|
|
|
|
|
+# #return mm_dd
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
if __name__ == '__main__':
|
|
if __name__ == '__main__':
|
|
|
|
|
|
|
|
|
|
|
|
@@ -145,15 +270,38 @@ if __name__ == '__main__':
|
|
|
|
|
|
|
|
#print ''.join ('%s=%0.4f, '%(k,v) for k, v in results.iteritems())
|
|
#print ''.join ('%s=%0.4f, '%(k,v) for k, v in results.iteritems())
|
|
|
|
|
|
|
|
|
|
+#
|
|
|
|
|
+# chk = HongKong()
|
|
|
|
|
+# chk.addHoliday(Date(24, December, 2015))
|
|
|
|
|
+# chk.addHoliday(Date(19, October, 2015))
|
|
|
|
|
+# chk.addHoliday(str2qdate('20151020'))
|
|
|
|
|
+# print chk.isBusinessDay(Date(24, December, 2015))
|
|
|
|
|
+# print chk.isBusinessDay(Date(19, October, 2015))
|
|
|
|
|
+# print chk.isEndOfMonth(Date(29, October, 2015))
|
|
|
|
|
+# print chk.isEndOfMonth(Date(30, October, 2015))
|
|
|
|
|
+# print chk.advance(Date(17, October, 2015), 1, 0)
|
|
|
|
|
+# print chk.advance(Date(17, October, 2015), 1, 1)
|
|
|
|
|
+# print chk.advance(Date(17, October, 2015), 1, 2)
|
|
|
|
|
+ #print get_HSI_expiry(2016)
|
|
|
|
|
+
|
|
|
|
|
+ holidays = get_hk_holidays(2016)
|
|
|
|
|
|
|
|
- chk = HongKong()
|
|
|
|
|
- chk.addHoliday(Date(24, December, 2015))
|
|
|
|
|
- chk.addHoliday(Date(19, October, 2015))
|
|
|
|
|
- chk.addHoliday(str2qdate('20151020'))
|
|
|
|
|
- print chk.isBusinessDay(Date(24, December, 2015))
|
|
|
|
|
- print chk.isBusinessDay(Date(19, October, 2015))
|
|
|
|
|
- print chk.isEndOfMonth(Date(29, October, 2015))
|
|
|
|
|
- print chk.isEndOfMonth(Date(30, October, 2015))
|
|
|
|
|
- print chk.advance(Date(17, October, 2015), 1, 0)
|
|
|
|
|
- print chk.advance(Date(17, October, 2015), 1, 1)
|
|
|
|
|
- print chk.advance(Date(17, October, 2015), 1, 2)
|
|
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ month_names = [January,
|
|
|
|
|
+ February,
|
|
|
|
|
+ March,
|
|
|
|
|
+ April,
|
|
|
|
|
+ May,
|
|
|
|
|
+ June,
|
|
|
|
|
+ July,
|
|
|
|
|
+ August,
|
|
|
|
|
+ September,
|
|
|
|
|
+ October,
|
|
|
|
|
+ November,
|
|
|
|
|
+ December,
|
|
|
|
|
+ ]
|
|
|
|
|
+ for i in month_names:
|
|
|
|
|
+ dd = get_HSI_last_trading_day(holidays, i, 2016)
|
|
|
|
|
+ print dd
|
|
|
|
|
+
|