def main(): # Setup REST API connection trade_api = BlockExTradeApi(USERNAME, PASSWORD, API_URL, API_ID) _ = trade_api.login() # That's just a example we don't need access_token # Setup SignalR connecton connection = Connection(f"{API_URL}/signalr", session=None) hub = connection.register_hub('TradingHub') # Set event handlers hub.client.on('MarketOrdersRefreshed', on_message) trader_instruments = trade_api.get_trader_instruments() # Pick an instrument to work with instrument_id = trader_instruments[0]['id'] # Cancel all orders for instrument 0 trade_api.cancel_all_orders(instrument_id=instrument_id) lowest_ask_order(trade_api, instrument_id) highest_bid_order(trade_api, instrument_id) # Run the event loop connection.start()
async def on_debug(**msg): # In case of 'queryExchangeState' print(msg) if 'R' in msg and type(msg['R']) is not bool: # decoded_msg = process_message(msg['R']) # print(decoded_msg); # session.headers.update({'Authorization': 'Bearer {token}'.format(token=token)}) token = msg['R'] print('Token is: ', token) print('-------------------------') # session = Session(); server_url = server_url + "?token=${token}".format(token=token) conn = Connection(server_url, session) # conn.session.headers.update({'Authorization': 'Bearer {token}'.format(token=token)}) appHub = conn.register_hub('omsclienthub') conn.received += on_recieved conn.error += on_error companies = appHub.server.invoke('GetInstrumentList') connection.close() conn.start()
def run(self): # setup SSL context construction if required if self.kwargs["CertFile"]: self._setup_websockets_ssl_certs() # setup SignalR connection (w/ authentication) connection = SignalRConnection(f"{self.kwargs['APIDomain']}/signalr", session=None) connection.qs = {'access_token': self.kwargs['access_token']} hub = connection.register_hub('TradingHub') self._hub = hub self._connection = connection # Set event handlers hub.client.on('MarketTradesRefreshed', lambda x: None) hub.client.on('MarketOrdersRefreshed', self.on_market_tick_received) hub.client.on('tradeCreated', self.on_execution_received) hub.client.on('createTradeOrderResult', self.on_place_order_received) hub.client.on('cancelTradeOrderResult', self.on_cancel_order_received) hub.client.on('cancelAllTradeOrdersResult', self.on_cancel_all_orders_received) connection.received += self.on_raw_msg_received connection.error += self.on_error_received connection.start() pass
def main(): # Create connection # Users can optionally pass a session object to the client, e.g a cfscrape session to bypass cloudflare. connection = Connection('https://beta.bittrex.com/signalr', session=None) # Register hub hub = connection.register_hub('c2') # Assign debug message handler. It streams unfiltered data, uncomment it to test. # connection.received += on_debug # Assign error handler connection.error += on_error # Assign hub message handler # Public callbacks hub.client.on('uE', on_message) hub.client.on('uS', on_message) # Private callbacks hub.client.on('uB', on_private) hub.client.on('uO', on_private) # Send a message # hub.server.invoke('SubscribeToExchangeDeltas', 'BTC-ETH') # Invoke 0 hub.server.invoke('SubscribeToSummaryDeltas') # Invoke 1 # hub.server.invoke('queryExchangeState', 'BTC-NEO') # Invoke 2 # Private methods # API_KEY, API_SECRET = '### API KEY ###', '### API SECRET ###' # hub.server.invoke('GetAuthContext', API_KEY) # Invoke 3 # Start the client connection.start()
async def connect(): global HUB connection = Connection(URL) HUB = connection.register_hub('c3') connection.received += on_message connection.error += on_error connection.start() print('Connected')
def _handle_connect(self): connection = Connection(self.url, Session()) hub = connection.register_hub(BittrexParameters.HUB) connection.received += self._on_debug connection.error += self.on_error hub.client.on(BittrexParameters.MARKET_DELTA, self._on_public) hub.client.on(BittrexParameters.SUMMARY_DELTA, self._on_public) hub.client.on(BittrexParameters.SUMMARY_DELTA_LITE, self._on_public) hub.client.on(BittrexParameters.BALANCE_DELTA, self._on_private) hub.client.on(BittrexParameters.ORDER_DELTA, self._on_private) self.connection = BittrexConnection(connection, hub) thread = Thread(target=self._connection_handler, daemon=True, name='SocketConnectionThread') self.threads.append(thread) thread.start()
async def exchange_client(self, loop, tag): print('Exchange: Bittrex | Connection to {} has opened'.format( sstream[tag])) connection = Connection(ws_url, session=None, loop=loop) hub = connection.register_hub('c2') connection.received += self.on_debug connection.error += self.on_error if sstream[tag][1]: hub.client.on(sstream[tag][1], self.parse_data) if tag != 'SummaryDelta': for i in self.tickers: hub.server.invoke(sstream[tag][0], i) else: hub.server.invoke(sstream[tag][0]) #hub.server.invoke('SubscribeToSummaryDeltas') #hub.server.invoke('queryExchangeState', 'BTC-NEO') connection.start()
# Create hub message handler async def on_message(msg): print("message is {0}".format(msg)) decoded_msg = process_message(msg[0]) print(decoded_msg) if __name__ == "__main__": # Create connection # Users can optionally pass a session object to the client, e.g a cfscrape session to bypass cloudflare. # connection = Connection('https://beta.bittrex.com/signalr', session=None) connection = Connection('http://localhost:5001', session=None) # Register hub # hub = connection.register_hub('c2') hub = connection.register_hub('chatHub') # Assign debug message handler. It streams unfiltered data, uncomment it to test. connection.received += on_debug # Assign error handler connection.error += on_error # Assign hub message handler hub.client.on('ReceiveMessage', on_message) # hub.client.on('uS', on_message) # Send a message hub.server.invoke('SendMessage1', 'BTC-ETH') # hub.server.invoke('SubscribeToSummaryDeltas') # hub.server.invoke('queryExchangeState', 'BTC-NEO')
async def on_recieved(**msg): companies = msg['R'] # Create error handler async def on_error(msg): print(msg) # Create hub message handler async def on_message(msg): decoded_msg = process_message(msg[0]) print(decoded_msg) if __name__ == "__main__": server_url = 'http://firouzex.exphoenixtrade.com/realtime' # Create a connection session = Session() connection = Connection(server_url, session) hub = connection.register_hub('omsclienttokenhub') appHub = connection.register_hub('omsclienthub') connection.received += on_debug connection.error += on_error hub.server.invoke('GetAPIToken', 'fTTTTTT', 'XXXXX') connection.start()
print(msg) # Create hub message handler async def on_message(msg): decoded_msg = await process_message(msg[0]) print(decoded_msg) if __name__ == "__main__": # Create connection # Users can optionally pass a session object to the client, e.g a cfscrape session to bypass cloudflare. connection = Connection('https://beta.bittrex.com/signalr', session=None) # Register hub hub = connection.register_hub('c2') # Assign debug message handler. It streams unfiltered data, uncomment it to test. connection.received += on_debug # Assign error handler connection.error += on_error # Assign hub message handler hub.client.on('uE', on_message) hub.client.on('uS', on_message) # Send a message hub.server.invoke('SubscribeToExchangeDeltas', 'BTC-ETH') hub.server.invoke('SubscribeToSummaryDeltas') hub.server.invoke('queryExchangeState', 'BTC-NEO')
class SignalRClient: """A client for receiving and saving F1 timing data which is streamed live over the SignalR protocol. During an F1 session, timing data and telemetry data are streamed live using the SignalR protocol. This class can be used to connect to the stream and save the received data into a file. The data will be saved in a raw text format without any postprocessing. It is **not** possible to use this data during a session. Instead, the data can be processed after the session using the :mod:`fastf1.api` and :mod:`fastf1.core` Args: filename (str) : filename (opt. with path) for the output file filemode (str, optional) : one of 'w' or 'a'; append to or overwrite file content it the file already exists. Append-mode may be useful if the client is restarted during a session. debug (bool, optional) : When set to true, the complete SignalR message is saved. By default, only the actual data from a message is saved. timeout (int, optional) : Number of seconds after which the client will automatically exit when no message data is received. Set to zero to disable. logger (Logger or None) : By default, errors are logged to the console. If you wish to customize logging, you can pass an instance of :class:`logging.Logger` (see: :mod:`logging`). """ _connection_url = 'https://livetiming.formula1.com/signalr' def __init__(self, filename, filemode='w', debug=False, timeout=60, logger=None): self.headers = { 'User-agent': 'BestHTTP', 'Accept-Encoding': 'gzip, identity', 'Connection': 'keep-alive, Upgrade' } self.topics = [ "Heartbeat", "CarData.z", "Position.z", "ExtrapolatedClock", "TopThree", "RcmSeries", "TimingStats", "TimingAppData", "WeatherData", "TrackStatus", "DriverList", "RaceControlMessages", "SessionInfo", "SessionData", "LapCount", "TimingData" ] self.debug = debug self.filename = filename self.filemode = filemode self.timeout = timeout self._connection = None if not logger: logging.basicConfig( format="%(asctime)s - %(levelname)s: %(message)s") self.logger = logging.getLogger('SignalR') else: self.logger = logger self._output_file = None self._t_last_message = None def _to_file(self, msg): self._output_file.write(msg + '\n') self._output_file.flush() async def _on_do_nothing(self, msg): # just do nothing with the message; intended for debug mode where some # callback method still needs to be provided pass async def _on_message(self, msg): self._t_last_message = time.time() loop = asyncio.get_running_loop() try: with concurrent.futures.ThreadPoolExecutor() as pool: await loop.run_in_executor(pool, self._to_file, str(msg)) except Exception: self.logger.exception("Exception while writing message to file") async def _on_debug(self, **data): if 'M' in data and len(data['M']) > 0: self._t_last_message = time.time() loop = asyncio.get_running_loop() try: with concurrent.futures.ThreadPoolExecutor() as pool: await loop.run_in_executor(pool, self._to_file, str(data)) except Exception: self.logger.exception("Exception while writing message to file") async def _run(self): self._output_file = open(self.filename, self.filemode) # Create connection session = requests.Session() session.headers = self.headers self._connection = Connection(self._connection_url, session=session) # Register hub hub = self._connection.register_hub('Streaming') if self.debug: # Assign error handler self._connection.error += self._on_debug # Assign debug message handler to save raw responses self._connection.received += self._on_debug hub.client.on( 'feed', self._on_do_nothing) # need to connect an async method else: # Assign hub message handler hub.client.on('feed', self._on_message) hub.server.invoke("Subscribe", self.topics) # Start the client loop = asyncio.get_event_loop() with concurrent.futures.ThreadPoolExecutor() as pool: await loop.run_in_executor(pool, self._connection.start) async def _supervise(self): self._t_last_message = time.time() while True: if (self.timeout != 0 and time.time() - self._t_last_message > self.timeout): self.logger.warning(f"Timeout - received no data for more " f"than {self.timeout} seconds!") self._connection.close() return await asyncio.sleep(1) async def _async_start(self): self.logger.info(f"Starting FastF1 live timing client " f"[v{fastf1.__version__}]") await asyncio.gather(asyncio.ensure_future(self._supervise()), asyncio.ensure_future(self._run())) self._output_file.close() self.logger.warning("Exiting...") def start(self): """Connect to the data stream and start writing the data to a file.""" try: asyncio.run(self._async_start()) except KeyboardInterrupt: self.logger.warning("Keyboard interrupt - exiting...") return
class MyBittrex: def __init__(self): self.url = 'https://socket-v3.bittrex.com/signalr' self.trade = 0.0 self.ticker = 0.0 self.tickers = -1 self.book = -1 self.summary = 0.0 self.summaries = -1 self.candle = -1 self.last_state = self.current_time() self.last_date = datetime.today().strftime("%Y-%m-%d %H:%M:%S") self.last_message = "" # Schedule three calls *concurrently*: # Create connection # Users can optionally pass a session object to the client, e.g a cfscrape session to bypass cloudflare. self.con_master = Connection(self.url, session=None) # Register hub self.hub_master = self.con_master.register_hub('c3') # Assign debug message handler. It streams unfiltered data, uncomment it to test. # self.con_master.received += self.on_debug # Assign Time of last packet self.con_master.received += self.on_time # Assign error handler self.con_master.error += self.on_error # Assign hub message handler self.public_methods = [ { 'method': 'candle', 'routine': self.on_candle, 'subscribe': 'candle_ETH-BTC_HOUR_1' }, { 'method': 'heartbeat', 'routine': self.on_heartbeat, 'subscribe': 'heartbeat' }, { 'method': 'marketSummaries', 'routine': self.on_summaries, 'subscribe': 'market_summaries' }, { 'method': 'marketSummary', 'routine': self.on_summary, 'subscribe': 'market_summary_LTC-BTC' }, { 'method': 'orderBook', 'routine': self.on_book, 'subscribe': 'orderbook_ADA-BTC_1' }, { 'method': 'tickers', 'routine': self.on_tickers, 'subscribe': 'tickers' }, { 'method': 'ticker', 'routine': self.on_ticker, 'subscribe': 'ticker_TRX-BTC' }, { 'method': 'trade', 'routine': self.on_trade, 'subscribe': 'trade_BTC-USD' }, ] for method in self.public_methods: self.hub_master.client.on(method['method'], method['routine']) self.hub_master.server.invoke('Subscribe', [[method['subscribe']]]) # Start the client self.con_master.start() @staticmethod async def process_message(message): try: deflated_msg = decompress(b64decode(message), -MAX_WBITS) return json.loads(deflated_msg.decode()) except Exception as ChoCho: print(ChoCho.args) return message # Create time handler. async def on_time(self, **msg): self.last_message = msg self.last_date = datetime.today().strftime("%Y-%m-%d %H:%M:%S") # Create debug message handler. @staticmethod async def on_debug(**msg): print("Debug information: ", end='') print(str(msg)) # Create error handler @staticmethod async def on_error(msg): if 'E' in msg: print('Error: ' + msg['E']) if 'M' in msg: print('Received method: ' + str(msg['M'])) if 'A' in msg: print('Received message: ' + str(msg['A'])) @staticmethod def current_time(): return (Decimal.from_float(datetime.now().timestamp()) * 1000).quantize(Decimal("1"), ROUND_HALF_UP) async def on_message(self, msg): decoded_msg = await self.process_message(msg[0]) print(decoded_msg) async def on_candle(self, msg): decoded_msg = await self.process_message(msg[0]) self.candle = decoded_msg['sequence'] async def on_heartbeat(self, msg): self.last_message = msg # print('.', end='') self.last_state = self.current_time() async def on_summaries(self, msg): decoded_msg = await self.process_message(msg[0]) self.summaries = decoded_msg['sequence'] async def on_summary(self, msg): decoded_msg = await self.process_message(msg[0]) self.summary = decoded_msg['percentChange'] async def on_book(self, msg): decoded_msg = await self.process_message(msg[0]) self.book = decoded_msg['sequence'] async def on_tickers(self, msg): decoded_msg = await self.process_message(msg[0]) self.tickers = decoded_msg['sequence'] async def on_ticker(self, msg): decoded_msg = await self.process_message(msg[0]) self.ticker = decoded_msg['lastTradeRate'] async def on_trade(self, msg): decoded_msg = await self.process_message(msg[0]) self.trade = decoded_msg['deltas'][0]['rate'] def restart(self): for method in self.public_methods: self.hub_master.server.invoke('Subscribe', [[method['subscribe']]]) self.con_master.start() self.last_state = self.current_time()
class BittrexSocket: __hub = None __invoke_event = None __invoke_resp = None __watchdog: Optional[Watchdog] __invoke_lock = Optional[asyncio.Lock] __connection: Optional[Connection] def __init__(self, api_key=None, api_secret=None): self.api_key = api_key self.api_secret = api_secret async def listen(self, channels: list[str], callbacks: dict[str, Callable]): self.__watchdog = Watchdog(HEARTBEAT_TIMEOUT) self.__invoke_lock = asyncio.Lock() await self.__connect() if self.api_key is not None: await self.__auth() assert 'heartbeat' not in channels channels.append('heartbeat') callbacks['heartbeat'] = self.__on_heartbeat await self.__subscribe(channels, callbacks) await self.__watchdog.loop() self.__connection.close() async def __on_heartbeat(self, _): self.__watchdog.reset() async def __connect(self): self.__connection = Connection(URL) self.__hub = self.__connection.register_hub('c3') self.__connection.received += self.__on_message self.__connection.error += self.__on_error self.__connection.start() log.info(f'Connected') async def __on_message(self, **msg): if 'R' in msg: self.__invoke_resp = msg['R'] self.__invoke_event.set() def stop(self): self.__watchdog.stop() async def __on_error(self, msg): log.error(str(msg)) self.stop() async def __auth(self): timestamp = str(int(time.time()) * 1000) random_content = str(uuid.uuid4()) content = timestamp + random_content signed_content = hmac.new(self.api_secret.encode(), content.encode(), hashlib.sha512).hexdigest() response = await self.__invoke('Authenticate', self.api_key, timestamp, random_content, signed_content) if response['Success']: log.info(f'Authenticated') async def reauth(_): asyncio.create_task(self.__auth()) self.__hub.client.on('authenticationExpiring', reauth) else: log.error(f'Authentication failed: {response["ErrorCode"]}') async def __subscribe(self, channels, callbacks): for method, callback in callbacks.items(): self.__hub.client.on( method, corotools.wraptry(corotools.wrapfunc(callback, self.__decode_message), msg='BittrexSocket callback exception')) response = await self.__invoke('Subscribe', channels) for i in range(len(channels)): if response[i]['Success']: log.info(f'Subscription to "{channels[i]}" successful') else: log.error( f'Subscription to "{channels[i]}" failed: {response[i]["ErrorCode"]}' ) self.stop() async def __invoke(self, method, *args): async with self.__invoke_lock: self.__invoke_event = asyncio.Event() self.__hub.server.invoke(method, *args) await self.__invoke_event.wait() return self.__invoke_resp @staticmethod def __decode_message(msg): if not len(msg): return None else: msg = msg[0] try: decompressed_msg = decompress(b64decode(msg, validate=True), -MAX_WBITS) except SyntaxError: decompressed_msg = decompress(b64decode(msg, validate=True)) return json.loads(decompressed_msg.decode())
# Create error handler async def on_error(msg): print(msg) # Create hub message handler async def on_message(msg): print(msg) if __name__ == "__main__": # Create connection connection = Connection('https://socket-stage.bittrex.com/signalr/') # Register hub hub = connection.register_hub('coreHub') # Assign debug message handler. It streams unfiltered data, uncomment it to test. # connection.received += on_debug # Assign error handler connection.error += on_error # Assign hub message handler hub.client.on('updateExchangeState', on_message) # Send a message hub.server.invoke('SubscribeToExchangeDeltas', 'BTC-ETH') # Start the client connection.start()