def _main(self): """ Main monitor loop """ while True: time.sleep(self.refresh_rate - time.time() % self.refresh_rate) tweets = TWITTER_CLIENT.get_list_statuses(slug='binance-coins', owner_screen_name='tundra_beats') # LOGGER.debug('Retrieved tweets') for tweet in tweets: tweet_dt = twitter_ts(tweet['created_at']) time_since = dt_time_diff(tweet_dt, datetime.utcnow()) if 0 <= time_since < self.refresh_rate: handle = tweet['user']['screen_name'].lower() symbol = [coin for coin, name in self.handle_list.items() if name == handle] if not symbol or len(symbol) > 1: self.logger.error('Twitter handle not in list. Symbol list: {}. Handle: {}'.format( symbol, handle)) else: symbol = symbol[0] self.thread_count += 1 # make a new thread t = threading.Thread( target=self._new_monitor_thread, args=(symbol, handle, tweet, tweet_dt)) t.start() else: break
def test_no_diff(self): ts0 = datetime.now() ts1 = datetime.now() self.assertAlmostEqual(0, dt_time_diff(ts0, ts1), places=3)
def test_neg_diff_over_midnight(self): ts0 = datetime(2018, 3, 11, 0, 0, 11) ts1 = datetime(2018, 3, 10, 23, 59, 50) self.assertEqual(-21, dt_time_diff(ts0, ts1))
def test_neg_diff(self): ts0 = datetime(2018, 3, 10, 23, 59, 50) ts1 = datetime(2018, 3, 10, 23, 59, 47) self.assertEqual(-3, dt_time_diff(ts0, ts1))
def test_small_diff(self): ts0 = datetime(2018, 3, 10, 23, 59, 47) ts1 = datetime(2018, 3, 10, 23, 59, 50) self.assertEqual(3, dt_time_diff(ts0, ts1))
def monitor_market(self, symbol, alert=None, logger=None, init_dt=None): """ Checks the price of a given market at the time intervals given in the MONITOR_INTERVALS variable. :param symbol: market symbol :param alert: optional custom alert object :param logger: optional logger :param init_dt: starting datetime (cannot be bigger than first interval) - defaults to now """ if logger is None: logger = self.logger if alert is None: alert = Alert(symbol, logger=logger) intervals = MONITOR_INTERVALS if not self.reduced_mode else MONITOR_INTERVALS_REDUCED pair = symbol + '/BTC' init_trades = self.client.fetch_trades(pair) if init_dt is not None: last_trade = last_trade_before_dt(init_trades, init_dt) else: last_trade = init_trades[-1] init_dt = datetime.utcnow() prev_interval = dt_time_diff(init_dt, datetime.utcnow()) assert prev_interval < intervals[0], \ 'Cannot monitor {}s interval for an initial time of {}'.format(intervals[0], init_dt) init_price = last_trade['price'] obs = [self.client.fetch_order_book(pair)] gains = [] trades_after = [last_trade] for i, curr_interval in enumerate(intervals): time.sleep(curr_interval - prev_interval) if trades_after is not None and len(trades_after) < 100: trades = self.client.fetch_trades(pair) try: trades_after = splice_trades(trades_after, trades) except OutOfRangeError: logger.warning('trade splicing failed - there may be too many trades to log') trades_after = None obs.append(self.client.fetch_order_book(pair)) price = self.client.fetch_ticker(pair)['last'] gain_since = 100 * (price / init_price - 1) # % gains.append(gain_since) logger.info('{}m monitoring of {} complete at {}. Gain = {:.2f}%'.format( curr_interval / 60, symbol, print_time(), gain_since)) if gain_since > RED_ALERT_GAIN_THRESH[curr_interval]: alert.red('large gain', trigger='{}s gain'.format(curr_interval)) elif gain_since > AMBER_ALERT_GAIN_THRESH[curr_interval]: alert.amber('medium gain', trigger='{}s gain'.format(curr_interval)) prev_interval = curr_interval if self.log_data and alert.curr_tier is not None: # OHLCV should be replaced later ohlcv = np.array( self.client.fetch_ohlcv(pair, timeframe='1m', limit=int(intervals[-1] / 60) + LONG_MA_LEN)) if trades_after is not None and not self.reduced_mode: # 100 trades either side of init dt trades_log = {'before': reduce_trades(init_trades), 'after': reduce_trades(trades_after)} else: trades_log = None data = { 'init price': init_price, 'symbol': symbol, 'ohlcv': ohlcv, 'trades': trades_log, 'gains': gains, 'order books': obs, 'timestamp': init_dt, 'alert history': alert.export() } pickle.dump(data, open(os.path.join(DATA_LOG_PATH, '{}-{}.p'.format(init_dt, symbol)), 'wb'))