Ejemplo n.º 1
0
    def __init__(self, mode='full_history', verbose=False):

        # os.environ['TZ'] = 'America/New_York'
        # tzset()

        self._dt_wallstreet_ = get_wallstreet_time(
        )['datetime'] - datetime.datetime.now()
        self._dir_out_ = os.path.join(DIR_DATA, mode)
        self._date_format_ = '%Y-%m-%d'
        self._date_time_format_ = '%Y-%m-%d-%H-%M-%S'
        self._max_connection_attempts_ = 20

        self.rexp_live_dollar = re.compile(r'starQuote.*?<')
        self.rexp_live_volume = re.compile(r'olume<.+?</td>')
        self.rexp_yahoo_prices_list = re.compile(r'"prices":\[.*?\]')

        self.n_cpu = os.cpu_count()
        self.verbose = verbose
        self.symbs = list()
        self.live_now = False
        self.dfs = None
        self.alpha_vantage_state = 'ok'

        if mode and not os.path.isdir(self._dir_out_):
            os.makedirs(self._dir_out_)
            print('Created: %s' % self._dir_out_)
Ejemplo n.º 2
0
 def run(self):
     wst = get_wallstreet_time()
     if not wst['is_market_open']:
         print("Waiting {:.2f} hours for market to open".format(
             wst['open_in'] / 3600))
         sleep(wst['open_in'])
     print('Market now open')
     if self.trader is not None:
         self.begin_trade()
     else:
         print('No trader')
Ejemplo n.º 3
0
    def sort_buyables(self):
        wst = get_wallstreet_time(offset_close=self.trade_end_offset)
        if not wst['is_market_open']:
            # prevent buy when near end of day
            return None

        rvalues = [
            self.stocks.get_stock(s).price_trend(k=self.__trend_window).rvalue
            for s in self.stocks.symbols
        ]
        idx = np.argsort(rvalues)[::-1]
        symbs = np.array(self.stocks.symbols)[idx]
        buy_symbs = []
        for s in symbs:
            if s not in self.holding \
                    and s not in self.pending_buy \
                    and s not in self.pending_sell \
                    and s not in self.pending_cancel:
                buy_symbs.append(s)
        return buy_symbs
Ejemplo n.º 4
0
    def sell_criteria(self, symbol):
        wst = get_wallstreet_time(offset_close=self.trade_end_offset)
        if wst['is_market_open']:
            # sell everything by end of day
            return True

        if symbol not in self.holding or symbol in self.pending_sell:
            return False

        stat = self.stocks.price_trend(symbol, k=self.__trend_window)
        stock = self.stocks.get_stock(symbol)
        # diff is relative to previous cached price
        diff = stock.price - self.cached_price[symbol]
        lb = self.lb_ratio * stock.open_price
        print(': {} rval={:.5f} pval={:.5f} diff={:.2f} lb={:.2f}'.format(
            symbol, stat.rvalue, stat.pvalue, diff, lb))
        if diff <= lb:
            print('sell criteria ({}): below lower bound'.format(symbol))
            return True
        # elif stat.pvalue <= 0.1 and stat.rvalue < 0:
        #     # Too sensitive at the moment
        #     print('sell criteria ({}): trending down'.format(symbol))
        #     return True
        return False
Ejemplo n.º 5
0
    def trade_sequence(self):
        print('\n___ sequence {} ______'.format(datetime.now()))
        # check pending status
        self.get_all_pending_status()

        # get updates on qualified stocks
        # don't update cached_price yet,
        # need the previous cached_price
        # to determine sell criteria
        self.stocks.update()

        # check if there are stocks that should be
        # sold off
        for s in self.stocks.symbols:
            # sell stocks that should be dumped off
            if self.sell_criteria(s) and self.sell(s):
                self.pending_sell.append(s)

        # check global trend and make sure still in trade period
        # TODO - sell/buy criteria are bad! Need to figure out
        #  a decent strategy
        stat = self.stocks.price_trend(k=self.__trend_window)
        global_statistic = stat.statistic
        global_pvalue = stat.pvalue
        print(': Global stat={} pval={}'.format(global_statistic,
                                                global_pvalue))
        wst = get_wallstreet_time(offset_close=self.trade_end_offset)
        if wst['is_market_open'] and global_statistic > 4 and global_pvalue < 1e-4:
            # see if there are partitions available
            # to buy stocks that are worth it
            if self.partitions_remain > 0:
                # get all the symbols worth investing
                buyable_symbols = self.sort_buyables()

                # this tracks N x parition for each symbol
                # so if there are more partitions left than
                # buyable_symbols, same symbol can be assigned
                # more than 1 partition
                stock_partitions = defaultdict(int)

                if buyable_symbols:
                    for i in range(self.partitions_remain):
                        symb = buyable_symbols[i % len(buyable_symbols)]
                        stock_partitions[symb] += 1
                    for symb, p in stock_partitions.items():
                        if self.buy(symb, p * self.partition_size):
                            self.pending_buy.append(symb)
        elif not wst['is_market_open'] or (global_statistic < -4
                                           and global_pvalue < 1e-4):
            if not wst['is_market_open']:
                print('! End of day soon, selling everything...')
            # sell all and cancel all buy orders
            if self.pending_buy:
                self.cancel_all_pending('buy')
            if self.holding:
                self.batch_order(list(self.holding.keys()), 'sell')
        else:
            print(
                '! Does not meet buy or sell criteria, continue watching market ...'
            )

        # update cached_price
        for s in self.cached_price:
            if self.stocks.get_stock(s).price:
                self.cached_price[s] = self.stocks.get_stock(s).price
Ejemplo n.º 6
0
    def begin_trade(self):
        """
        Call this at market open to find stocks to scalp.
        Watch the first 10 iterations before calculating trend.
        :return:
        """
        print('\nBegin trading ...\n')

        # 1. scan for open-high stocks
        # Take 60 - 75 sec for 342 stocks
        # About 5 sec for 30
        print('Scanning %d stocks for open-high ...' % self.stocks.n_stocks)
        t0 = time()
        self.stocks.update()
        remove_stocks = []
        for symb, stock in self.stocks.stocks.items():
            if stock.open_close_change is None or stock.open_close_change <= 0:
                remove_stocks.append(symb)
        for s in remove_stocks:
            self.stocks.remove(s)
        print('|- scan took {:.2f} sec'.format(time() - t0))

        # 2. Sort open-close ratio from low to high
        # take the first N-split X 3 to watch for
        # It seems like the ones that open too high do not growth much
        # but the ones the open slighly high are more likely to grow
        symbs = np.array(self.stocks.symbols)
        changes = np.array(
            [self.stocks.get_stock(s).open_close_change for s in symbs])
        idx = np.argsort(changes)
        n_track = 3 * self.n_splits
        if len(symbs) > n_track:
            remove_stocks = symbs[idx][n_track:]
            for s in remove_stocks:
                self.stocks.remove(s)
        self.symbols_qualified = self.stocks.symbols
        print('Tracking %d qualifying stocks' % self.stocks.n_stocks)

        # 3. Conitnue to monitor the qualifying stocks for
        # more iterations
        for i_iter in range(self.__watch_iters):
            sleep(self.__watch_interval_sec)
            self.stocks.update()
            print('|- watch iter {} / {}'.format(i_iter + 1,
                                                 self.__watch_iters))

        # 4. run sequence until trade end or if there are pendings
        wst = get_wallstreet_time(offset_close=self.trade_end_offset)
        while wst['is_market_open'] or self.has_pending:
            self.trade_sequence()
            if self.net_worth <= self.max_loss:
                print('! Reach max loss, selling/cancelling everything.')
                if self.pending_buy:
                    self.cancel_all_pending(method='buy')
                if self.holding:
                    self.batch_order(list(self.holding.keys()), 'sell')
                break
            sleep(self.__watch_interval_sec)

        # 5. close trader
        self.trader.quit()
        print('\nHappy trade day!')
        print('${:,.2f} ===> ${:,.2f}'.format(self.allowance, self.net_worth))