Beispiel #1
0
 def test_7_next_expiry(self):
     res1 = stxcal.next_expiry(self.dt1)
     res2 = stxcal.next_expiry(self.dt1, 10)
     res3 = stxcal.next_expiry(self.dt1, 50)
     res4 = stxcal.next_expiry(self.dt1, 100)
     self.assertTrue((res1 == '2016-12-16') and (res2 == '2017-01-20') and
                     (res3 == '2017-03-17') and (res4 == '2017-05-19'))
Beispiel #2
0
 def eod_analysis(self, ana_date):
     # special case when the date is an option expiry date:
     #   1. wait until eoddata is downloaded.
     #   2. calculate liquidity leaders
     #   3. download options for all liquidity leaders
     #   4. calculate option spread leaders
     #   5. populate leaders table
     #   6. MON vs. FRI
     next_exp = stxcal.next_expiry(ana_date, 0)
     if next_exp == ana_date:
         res = stxdb.db_read_cmd('select max(date) from eods where '
                                 'open_interest>=0')
         last_eod_date = str(res[0][0])
         while last_eod_date < ana_date:
             print('Could not find eod data for {0:s}, sleeping one hour'.
                   format(ana_date))
             time.sleep(3600)
             res = stxdb.db_read_cmd('select max(date) from eods where '
                                     'open_interest>=0')
             last_eod_date = str(res[0][0])
         self.get_liq_leaders(ana_date)
         self.get_data(ana_date, get_eod=False, get_for_all=True)
         self.get_opt_spread_leaders(ana_date)
     else:
         self.get_data(ana_date, get_for_all=False, get_eod=True)
     setup_df = self.calc_setups(ana_date)
     self.mail_analysis(setup_df)
Beispiel #3
0
 def get_opt_spreads(self, crt_date, eod):
     exp_date = stxcal.next_expiry(crt_date, min_days=(1 if eod else 0))
     q = sql.Composed([
         sql.SQL('select stk, opt_spread from leaders '
                 'where expiry='),
         sql.Literal(exp_date)
     ])
     cnx = stxdb.db_get_cnx()
     with cnx.cursor() as crs:
         crs.execute(q.as_string(cnx))
         spread_dict = {x[0]: x[1] for x in crs}
     return spread_dict
Beispiel #4
0
 def eow_job(self):
     print('247 end of week job')
     print('247 end of week job')
     ana_date = '2002-04-19'
     crt_date = '2002-07-19'
     max_dt_q = stxdb.db_read_cmd('select max(dt) from leaders')
     if max_dt_q[0][0] is not None:
         ana_date = str(max_dt_q[0][0])
     crt_date = str(datetime.datetime.now().date())
     self.end_date = stxcal.move_busdays(
         str(datetime.datetime.now().date()), 1)
     while ana_date <= crt_date:
         self.get_liq_leaders(ana_date)
         self.get_opt_spread_leaders(ana_date)
         ana_date = stxcal.move_busdays(stxcal.next_expiry(ana_date), 0)
Beispiel #5
0
 def get_liq_leaders(self, ana_date, min_act=80000, min_rcr=0.015):
     stk_list = stxdb.db_read_cmd(
         "select distinct stk from eods where "
         "date='{0:s}' order by stk".format(ana_date))
     all_stocks = [
         s[0] for s in stk_list if re.match(r'^[A-Za-z]', str(s[0]))
     ]
     print('Found {0:d} stocks for {1:s}'.format(len(all_stocks), ana_date))
     next_exp = stxcal.next_expiry(ana_date)
     next_exp_busday = stxcal.move_busdays(next_exp, 0)
     num_stx = 0
     num = 0
     liq_leaders = []
     for s in all_stocks:
         num += 1
         ts = self.ts_dct.get(s)
         if ts is None:
             ts = StxTS(s, self.start_date, self.end_date)
             ts.set_day(str(ts.df.index[-1].date()))
             ts.df['activity'] = ts.df['volume'] * ts.df['c']
             ts.df['avg_act'] = ts.df['activity'].rolling(50).mean()
             ts.df['rg'] = ts.df['hi'] - ts.df['lo']
             ts.df['avg_rg'] = ts.df['rg'].rolling(50).mean()
             ts.df['rg_c_ratio'] = ts.df['avg_rg'] / ts.df['c']
             self.ts_dct[s] = ts
             num_stx += 1
         stk_act = [s]
         if self.is_liq_leader(ts, ana_date, min_act, min_rcr, stk_act):
             liq_leaders.append(stk_act)
         if num % 1000 == 0 or num == len(all_stocks):
             print('Processed {0:d} stocks, found {1:d} liquidity leaders'.
                   format(num, len(liq_leaders)))
     print('Found {0:d} liquidity leaders for {1:s}'.format(
         len(liq_leaders), ana_date))
     print('Loaded {0:d} stocks for {1:s}'.format(num_stx, ana_date))
     cnx = stxdb.db_get_cnx()
     with cnx.cursor() as crs:
         for ldr in liq_leaders:
             crs.execute(
                 'insert into leaders(exp,stk,activity,opt_spread) values '
                 + crs.mogrify('(%s,%s,%s,%s)',
                               [next_exp, ldr[0],
                                int(ldr[1]), -1000]) +
                 'on conflict do nothing')
Beispiel #6
0
 def get_leaders(self, ldr_date, get_for_all=True):
     ldr_expiry = stxcal.next_expiry(ldr_date)
     cnx = stxdb.db_get_cnx()
     if get_for_all:
         q = sql.Composed([
             sql.SQL('select stk from leaders where exp='),
             sql.Literal(ldr_expiry)
         ])
     else:
         q = sql.Composed([
             sql.SQL('select stk from leaders where exp='),
             sql.Literal(ldr_expiry),
             sql.SQL(' and opt_spread >= 0 and atm_price is not null '
                     'and atm_price<='),
             sql.Literal(self.max_atm_price),
             sql.SQL('and stk not in (select * from exclusions) '
                     'order by opt_spread asc limit '),
             sql.Literal(self.num_stx)
         ])
     with cnx.cursor() as crs:
         crs.execute(q.as_string(cnx))
         ldrs = [x[0] for x in crs]
     return ldrs
Beispiel #7
0
    def load_opts_daily(self, opt_fname):
        # print('{0:s} -load_opts_daily'.format(stxcal.print_current_time()))
        invalid_days = [
            '2002-02-01', '2002-02-04', '2002-02-05', '2002-02-06',
            '2002-02-07', '2002-05-30', '2002-05-31', '2002-06-14',
            '2002-06-17', '2002-12-02', '2002-12-03', '2002-12-04',
            '2002-12-05', '2002-12-06', '2002-12-09', '2002-12-10'
        ]
        dt = '{0:s}-{1:s}-{2:s}'.format(opt_fname[-12:-8], opt_fname[-8:-6],
                                        opt_fname[-6:-4])
        if dt in invalid_days:
            return 0, 0
        # print('dt = {0:s}'.format(dt))
        exp_0 = stxcal.next_expiry(dt, min_days=0)
        # print('exp_0 = {0:s}'.format(exp_0))
        exp_1 = stxcal.next_expiry(exp_0)
        # print('exp_1 = {0:s}'.format(exp_1))
        exps = [str(exp_0), str(exp_1)]
        spot_dct, opt_dct, spots, opts = {}, {}, [], []
        stx = {}
        sep = ' '
        # print('opt_fname = {0:s}'.format(opt_fname))
        with open(opt_fname) as csvfile:
            frdr = csv.reader(csvfile)
            for row in frdr:
                stk = row[0]
                # print('dt = {0:s}, stk = {1:s}, exps = {2:s}'.
                #       format(dt, stk, str(exps)))
                # print('row = {0:s}'.format(str(row)))
                try:
                    spot = int(100 * float(row[1]))
                    cp = row[5][:1]
                    exp = str(datetime.strptime(row[6], '%m/%d/%Y').date())
                    strike = int(100 * float(row[8]))
                    bid = int(100 * float(row[10]))
                    ask = int(100 * float(row[11]))
                    volume = int(row[12])
                    # print('exp = {0:s}'.format(exp))
                except:
                    # print(traceback.print_exc())
                    continue
                # print('1')
                if exp not in exps or ask == 0 or spot >= 2147483647 or \
                   strike >= 2147483647 or bid >= 2147483647 or \
                   ask >= 2147483647 or volume >= 2147483647:
                    continue
                # print('2')
                if stk not in spot_dct:
                    spot_dct[stk] = spot
                    spots.append([stk, dt, spot])
                opt_key = ':'.join([exp, stk, cp, str(strike)])
                if opt_key not in opt_dct:
                    opt_dct[opt_key] = [bid, ask, volume]
                    opts.append([exp, stk, cp, strike, dt, bid, ask, volume])
                # print('len(spots) {0:d}, len(opts) = {1:d}'.format(
                #     len(spots), len(opts)))

        spots_upload_file = '{0:s}/spots.txt'.format(self.upload_dir)
        opts_upload_file = '{0:s}/opts.txt'.format(self.upload_dir)
        with open(spots_upload_file, 'w') as spots_file:
            for s in spots:
                spots_file.write('{0:s}\t{1:s}\t{2:d}\n'.format(
                    s[0], s[1], s[2]))
        with open(opts_upload_file, 'w') as opts_file:
            for o in opts:
                opts_file.write('{0:s}\t{1:s}\t{2:s}\t{3:d}\t{4:s}\t{5:d}\t'
                                '{6:d}\t{7:d}\t0\n'.format(
                                    o[0], o[1], o[2], o[3], o[4], o[5], o[6],
                                    o[7]))
        if self.upload_spots:
            stxdb.db_upload_file(spots_upload_file, self.spot_tbl, '\t')
        if self.upload_options:
            stxdb.db_upload_file(opts_upload_file, self.opt_tbl, '\t')
        d_spots, d_opts = len(spots), len(opts)
        print('{0:s}\t{1:s}\t{2:5d}\t{3:6d}'.format(
            stxcal.print_current_time(), dt, d_spots, d_opts))
        return d_spots, d_opts
Beispiel #8
0
 def get_opt_spread_leaders(self, ldr_date):
     next_exp = stxcal.next_expiry(ldr_date)
     calc_exp = stxcal.next_expiry(ldr_date, 9)
     crt_date = stxcal.current_busdate()
     cnx = stxdb.db_get_cnx()
     stx = self.get_leaders(ldr_date)
     print('Calculating option spread for {0:d} stocks'.format(len(stx)))
     num = 0
     if ldr_date <= self.last_opt_date:
         opt_tbl_name = 'options'
         spot_tbl_name = 'opt_spots'
         spot_column = 'spot'
         opt_date_column = 'date'
     else:
         opt_tbl_name = 'opt_cache'
         spot_tbl_name = 'eods'
         spot_column = 'c'
         opt_date_column = 'dt'
     for stk in stx:
         print('stk = {0:s}'.format(stk))
         spot_q = sql.Composed([
             sql.SQL('select {} from {} where stk=').format(
                 sql.Identifier(spot_column),
                 sql.Identifier(spot_tbl_name)),
             sql.Literal(stk),
             sql.SQL(' and date='),
             sql.Literal(crt_date)
         ])
         with cnx.cursor() as crs:
             crs.execute(spot_q.as_string(cnx))
             spot_res = crs.fetchone()
             if spot_res is None:
                 continue
             spot = float(spot_res[0])
         tokens = stk.split('.')
         und = '.'.join(tokens[:-1]) if tokens[-1].isdigit() else stk
         opt_q = sql.Composed([
             sql.SQL('select * from {} where expiry=').format(
                 sql.Identifier(opt_tbl_name)),
             sql.Literal(calc_exp),
             sql.SQL(' and und='),
             sql.Literal(und),
             sql.SQL(' and {}=').format(sql.Identifier(opt_date_column)),
             sql.Literal(crt_date)
         ])
         opt_df = pd.read_sql(opt_q.as_string(cnx), cnx)
         if len(opt_df) < 6:
             continue
         opt_df['strike_spot'] = abs(opt_df['strike'] - spot)
         opt_df['spread'] = 100 * (1 - opt_df['bid'] / opt_df['ask'])
         opt_df.sort_values(by=['strike_spot'], inplace=True)
         opt_df['avg_spread'] = opt_df['spread'].rolling(6).mean()
         try:
             avg_spread = int(opt_df.iloc[5].avg_spread * 100)
             avg_atm_price = round(
                 (opt_df.iloc[0].ask + opt_df.iloc[1].ask) / 2, 2)
             with cnx.cursor() as crs:
                 crs.execute(
                     'update leaders set opt_spread=%s, '
                     'atm_price=%s where stk=%s and exp=%s',
                     (avg_spread, avg_atm_price, stk, next_exp))
         except:
             print('Failed to calc avg_spread for {0:s}'.format(stk))
         num += 1
         if num % 100 == 0 or num == len(stx):
             print('Calculated option spread for {0:d} stocks'.format(num))