def on_action(self, message): self.emit('action', message) return table = message['table'] data = message['data'] alog.debug("on_action") action = message['action'] if action == 'delete': for item in data: self.delete_from_table(table, item) elif action == 'update' and 'id' in data[0]: for item in data: self.update_item_in_table(table, item) elif action == 'partial' and 'id' not in data[0]: self.data[table] = data[0] elif action == 'insert' and 'id' not in data[0]: self.update_keys_in_table(table, data[0]) elif action == 'partial' or action == 'insert': for item in data: self.prepend_to_table(table, item) else: self.update_keys_in_table(table, data[0]) self.emit(table, table, self.get_table(table))
def on_open(self): alog.debug("Websocket Opened.") if self.should_auth: self.emit('auth') self.emit('open')
def GET(self): try: data = web.input() alog.debug(data, 'wx_handle::GET', 'input') if len(data) == 0: return "hello, this is handle view" signature = data.signature timestamp = data.timestamp nonce = data.nonce echostr = data.echostr token = "haojiage" #请按照公众平台官网\基本配置中信息填写 list = [token.encode('utf-8'), timestamp.encode('utf-8'), nonce.encode('utf-8')] list.sort() alog.info(list, 'wx_handle::GET', 'list') sha1 = hashlib.sha1() #map(sha1.update, list) for i in list: sha1.update(i) hashcode = sha1.hexdigest() alog.info("handle/GET func: hashcode:"+hashcode+' signature:'+signature, 'wx_handle::GET', 'check') if hashcode == signature: return echostr else: return "" except Exception as Argument: return Argument
def on_subscribe(self, message): if message['success']: alog.debug("Subscribed to %s." % message['subscribe']) else: self.error("Unable to subscribe to %s. Error: \"%s\" Please\ check and restart." % ( message['request']['args'][0], message['error']))
def start(self): def _go(): self._connect() self._listen() self._disconnect() self.stop = False self.on_open() self.thread = Thread(target=_go) self.thread.start() try: while True: time.sleep(1) now = time.time() heartbeat_delay = now - self.last_heartbeat alog.debug(f'## last heartbeat: {self.last_heartbeat} ' f'diff: {heartbeat_delay} ###') if heartbeat_delay >= self.heartbeat_delay \ and self.last_heartbeat > 0: self.stop = True alog.debug('## heartbeat exceeded delay ###') if self.stop: self.start() break except KeyboardInterrupt: sys.exit(0)
def init(self, reset=False): alog.debug("## init") channels = self.channels symbol = self.symbol shouldAuth = self.shouldAuth websocket = self.websocket if reset: websocket = self.websocket = BitMEXWebsocket() if not websocket: self.websocket = BitMEXWebsocket() self.websocket.connect( shouldAuth=shouldAuth, websocket=websocket ) self.websocket.on('subscribe', self.on_subscribe) self.websocket.on('latency', self.on_latency) self.channels = [] self.subscribe_to_channels(channels) self.subscribe_to_instrument_channels(symbol, channels) self.secureChannels = [] if shouldAuth: self.subscribe_to_secure_instrument_channels(symbol, channels)
def update_item_in_table(self, table, update): alog.debug("# update_item_in_table") alog.debug(json.dumps(update)) item_to_update = next(item for item in self.data[table] if item['id'] == update['id']) item_to_update.update(update)
def delete_from_table(self, table, item): alog.debug('#delete_from_table:%s' % (table)) alog.debug(item) if table not in self.data: self.data[table] = [] delete_item = next(_item for _item in self.data['orderBookL2'] if _item['id'] == item['id']) if delete_item: self.data[table].remove(delete_item)
def prepend_to_table(self, table, item): if table not in self.data: self.data[table] = [] isMaxLength = len(self.data[table]) == self.max_table_length if isMaxLength and 'orderBook' not in table: self.data[table].pop() self.data[table].insert(0, item) alog.debug('#prepend_to_table') alog.debug(self.data[table])
def build_websocket_url(self, base_url=settings.BASE_URL): alog.debug('Build websocket url from: %s' % (base_url)) urlParts = list(urlparse(base_url)) queryString = '' if self.heartbeatEnabled: queryString = '?heartbeat=true' url = "wss://{}/realtime{}".format(urlParts[1], queryString) alog.debug(url) return url
def re_connect(self): alog.debug('## attempt reconnect: %s' % self.reconnect_count) if self.reconnect_count == MAX_RECONNECT: raise Exception("Exceeded reconnection attempts.") sleep(1) self.reconnect_count += 1 self.connect_websocket() for channel in self.channels: self._subscribe_to_channel(channel)
def run_forever(self, **kwargs): """Connect to the websocket in a thread.""" # setup websocket.run_forever arguments ws_run_args = {'sslopt': {"cert_reqs": ssl.CERT_NONE}} if self.heartbeat: ws_run_args['ping_timeout'] = self.ping_timeout ws_run_args['ping_interval'] = self.ping_interval alog.debug(ws_run_args) super().run_forever(**ws_run_args)
async def __call__(self, scope, receive, send): # locals inside the app function (send_wrapper) can't be assigned to, # as the interpreter detects the assignment and thus creates a new # local variable within that function, with that name. instance = {"http_status_code": None} def send_wrapper(response): if response["type"] == "http.response.start": instance["http_status_code"] = response["status"] return send(response) if scope["type"] != "http": alog.debug(f"ASGI scope of type {scope['type']} is not supported yet") await self.app(scope, receive, send) return try: metric_name = self.metric_namer(scope) except AttributeError as e: alog.error( f"Unable to extract metric name from asgi scope: {scope}, skipping statsd timing" ) alog.error(f" -> exception: {e}") await self.app(scope, receive, send) return def emit(stats): statsd_tags = [ f"http_status:{instance['http_status_code']}", f"http_method:{scope['method']}", ] self.client.timing( f"{metric_name}", stats.time, tags=statsd_tags + ["time:wall"] ) self.client.timing( f"{metric_name}", stats.cpu_time, tags=statsd_tags + ["time:cpu"] ) with TimingStats(metric_name) as stats: try: await self.app(scope, receive, send_wrapper) except Exception: stats.stop() instance["http_status_code"] = 500 emit(stats) raise emit(stats)
def on_ping(self, message): timestamp = float(time.time() * 1000) ping_timestamp = float(message[14:]) latency = timestamp - ping_timestamp alog.debug("ping: %s" % (message)) alog.debug("ping timestamp: %s" % (timestamp)) alog.debug("message latency: %s" % (latency)) self.emit('latency', latency) alog.debug(int(timestamp)) self.send_message("primus::pong::%s" % (timestamp))
def header(self): """Return auth headers. Will use API Keys if present in settings.""" auth_header = [] if self.should_auth: alog.info("Authenticating with API Key.") # To auth to the WS using an API key, we generate a signature # of a nonce and the WS API endpoint. alog.debug(settings.BITMEX_API_KEY) nonce = generate_nonce() api_signature = generate_signature(settings.BITMEX_API_SECRET, 'GET', '/realtime', nonce, '') auth_header = [ "api-nonce: " + str(nonce), "api-signature: " + api_signature, "api-key:" + settings.BITMEX_API_KEY ] return auth_header
def POST(self): try: alog.debug('hello', 'wx_handle', 'WXHandle::POST') webData = web.data() alog.info("Handle Post webdata is " + str(webData), 'wx_handle', 'WXHandle::POST') recMsg = wx_receive.parse_xml(webData) if isinstance(recMsg, wx_receive.Msg) and recMsg.MsgType == 'text': toUser = recMsg.FromUserName fromUser = recMsg.ToUserName alog.debug('handle_type:'+recMsg.handle_type, 'WXHandle::POST') if recMsg.handle_type == 'goodprice': calc = GoodPriceCalc() price_data = calc.calc(recMsg.Content) content = calc.to_text(price_data, '\n') elif 'xueqiu_token' == recMsg.handle_type: xueqiu.set_token('xq_a_token='+recMsg.Content) content = u'设置雪球token成功:' + xueqiu.get_token() else: content = u'不支持命令:' + recMsg.Content replyMsg = wx_reply.TextMsg(toUser, fromUser, content) s = replyMsg.send() alog.debug(s, 'wx_handle', 'POST reply') return s else: alog.info('not support', 'WXHandle::POST', u'recMsg.MsgType') return "success" except Exception as Argment: alog.info(Argment, 'WXHandle::POST', u'error') return Argment
def record_history(self, user, retdata, symbal): alog.debug(user + ' ' + symbal, 'good_price::record_history') util.print_json(retdata) if len(user) <= 0: alog.info("user is empty", 'good_price::record_history') return dts = datetime.datetime.now().strftime('%Y-%m-%d') if symbal in retdata.keys(): try: itemdata = retdata[symbal]['basic'] ctx = '\t'.join([ user, dts, symbal, itemdata[CN_name], itemdata[CN_current], itemdata[CN_pe_ttm] ]) util.dump_str("data/user/goodprice_history_%s.txt" % (user), ctx + '\n', mode='a') except: alog.info("histroy data error", 'good_price::record_history') else: alog.info(symbal + "not in retdata", 'good_price::record_history') return
def goodprice_wx(): xmldata = touni(request._get_body_string()) alog.info(xmldata, 'goodprice_wx') #try: if True: recMsg = wx_receive.parse_xml(xmldata) if isinstance(recMsg, wx_receive.Msg) and recMsg.MsgType == 'text': toUser = recMsg.FromUserName fromUser = recMsg.ToUserName recv_content = touni(recMsg.Content) calc = GoodPriceCalc() alog.debug(recv_content, 'goodprice_wx', 'recMsg.Content') price_data = calc.calc(recv_content) content = calc.to_text(price_data, '<br>') replyMsg = wx_reply.TextMsg(toUser, fromUser, recv_content) s = replyMsg.send() alog.debug(s, 'goodprice_wx', 'reply') return s else: alog.info(s, 'goodprice_wx', u'不支持') return "success" """ except Exception as Argment:
def on_message(self, message): super(OrderBookConsole, self).on_message(message) alog.debug(message) # Calculate newest bid-ask spread bid = self.get_bid() bids = self.get_bids(bid) bid_depth = sum([b['size'] for b in bids]) ask = self.get_ask() asks = self.get_asks(ask) ask_depth = sum([a['size'] for a in asks]) if self._bid == bid and self._ask == ask and self._bid_depth == bid_depth and self._ask_depth == ask_depth: # If there are no changes to the bid-ask spread since the last update, no need to print pass else: # If there are differences, update the cache self._bid = bid self._ask = ask self._bid_depth = bid_depth self._ask_depth = ask_depth print('{} {} bid: {:.3f} @ {:.2f}\task: {:.3f} @ {:.2f}'.format( dt.datetime.now(), self.product_id, bid_depth, bid, ask_depth, ask))
def connect_websocket(self): """Connect to the websocket in a thread.""" alog.debug("### Connecting Websocket ###") # setup websocket.run_forever arguments wsRunArgs = { 'sslopt': {"cert_reqs": ssl.CERT_NONE} } if self.heartbeatEnabled: wsRunArgs['ping_timeout'] = 20 wsRunArgs['ping_interval'] = 60 alog.debug("websocket.run_forever: %s" % (wsRunArgs)) # Run the websocket on another thread and enable heartbeat self.wst = threading.Thread( target=lambda: self.websocket_run_forever(wsRunArgs) ) self.wst.daemon = True self.wst.start() alog.info("### Started thread") self.wait_for_connection()
def subscribe_action(self, action, channel, instrument, action_handler): channelKey = "{}:{}".format(channel, instrument) alog.debug("Subscribe to action: %s" % (channelKey)) subscriptionMsg = {"op": "subscribe", "args": [channelKey]} action_event_key = self.gen_action_event_key(action, instrument, channel) alog.debug("Subscribe to %s" % (action_event_key)) self.on(action_event_key, action_handler) if channelKey not in self.channels: self.channels.append(channelKey) alog.debug(subscriptionMsg) self.send_message(subscriptionMsg)
def on_message(self, message): '''Handler for parsing WS messages.''' # Check if ping message ping_message = message[:14] alog.debug(ping_message) if ping_message == PING_MESSAGE_PREFIX: alog.debug(message) return self.emit('ping', message) message = json.loads(message) alog.debug(json.dumps(message, indent=4, sort_keys=True)) action = message['action'] if 'action' in message else None try: if action: table = message['table'] event_name = '' if table in constants.CHANNELS: event_name = "%s:%s" % (action, table) else: if len(message['data']) > 0: instrument = message['data'][0]['symbol'] event_name = self.gen_action_event_key(action, instrument, table) alog.debug(event_name) self.emit(event_name, message) elif 'subscribe' in message: self.emit('subscribe', message) elif 'error' in message: self.error(message['error']) elif 'status' in message: self.emit('status', message) except: alog.error(traceback.format_exc())
def on_latency(self, message): alog.debug("# on_latency") alog.debug(message) latency = [] if 'latency' not in self.data: self.data['latency'] = [] if len(self.data['latency']) > self.max_table_length - 1: self.data['latency'].pop() latency.append(message) self.data['latency'] = latency # calculate average latency avg_latency = sum(latency)/len(latency) self.emit('latency', avg_latency) alog.debug("## avg latency: %s" % (avg_latency))
def get_auth(self): '''Return auth headers. Will use API Keys if present in settings.''' alog.debug('shouldAuth: %s' % self.shouldAuth) if self.shouldAuth: alog.info("Authenticating with API Key.") # To auth to the WS using an API key, we generate a signature # of a nonce and the WS API endpoint. alog.debug(settings.GDAX_API_KEY) nonce = generate_nonce() api_signature = generate_signature( settings.GDAX_API_SECRET, 'GET', '/realtime', nonce, '') auth = [ "api-nonce: " + str(nonce), "api-signature: " + api_signature, "api-key:" + settings.GDAX_API_KEY ] alog.debug(auth) return auth else: return []
import logging import os import alog ################################################################################ # Connection/Auth ################################################################################ # API URL. BASE_URL = os.environ.get('BITMEX_BASE_URL', "https://www.bitmex.com/api/v1/") # The BitMEX API requires permanent API keys. Go to # https://testnet.bitmex.com/api/apiKeys to fill these out. BITMEX_API_KEY = os.environ.get('BITMEX_API_KEY') BITMEX_API_SECRET = os.environ.get('BITMEX_API_SECRET') LOG_LEVEL = os.environ.get('LOG_LEVEL') if LOG_LEVEL is None: LOG_LEVEL = logging.INFO LOG_LEVEL = logging.getLevelName(LOG_LEVEL) alog.debug(LOG_LEVEL) alog.set_level(LOG_LEVEL)
def on_action(self, message): alog.debug(alog.pformat(message))
def on_subscribe(message): if message['success']: alog.debug("Subscribed to %s." % message['subscribe']) else: raise Exception('Unable to subsribe.')
def on_open(self): alog.debug("Websocket Opened.") self.emit('open')
def on_open(self, *kwargs): alog.info("Websocket opened") alog.debug("Websocket Opened. args: " + str(kwargs)) self.emit('open')
def test_debug(self): alog.debug(msg)