diff --git a/piker/_daemon.py b/piker/_daemon.py index e172fe6b..c206a4d2 100644 --- a/piker/_daemon.py +++ b/piker/_daemon.py @@ -283,7 +283,7 @@ async def maybe_spawn_daemon( lock = Brokerd.locks[service_name] await lock.acquire() - # attach to existing brokerd if possible + # attach to existing daemon by name if possible async with tractor.find_actor(service_name) as portal: if portal is not None: lock.release() diff --git a/piker/brokers/ib.py b/piker/brokers/ib.py index 45b93416..6abe257a 100644 --- a/piker/brokers/ib.py +++ b/piker/brokers/ib.py @@ -1,5 +1,5 @@ # piker: trading gear for hackers -# Copyright (C) Tyler Goodlet (in stewardship for piker0) +# Copyright (C) Tyler Goodlet (in stewardship for pikers) # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by @@ -171,6 +171,7 @@ _adhoc_futes_set = { # equities 'nq.globex', 'mnq.globex', + 'es.globex', 'mes.globex', @@ -178,8 +179,20 @@ _adhoc_futes_set = { 'brr.cmecrypto', 'ethusdrr.cmecrypto', + # agriculture + 'he.globex', # lean hogs + 'le.globex', # live cattle (geezers) + 'gf.globex', # feeder cattle (younguns) + + # raw + 'lb.globex', # random len lumber + # metals - 'xauusd.cmdty', + 'xauusd.cmdty', # gold spot + 'gc.nymex', + 'mgc.nymex', + + 'xagusd.cmdty', # silver spot } # exchanges we don't support at the moment due to not knowing @@ -556,7 +569,7 @@ class Client: else: item = ('status', obj) - log.info(f'eventkit event -> {eventkit_obj}: {item}') + log.info(f'eventkit event ->\n{pformat(item)}') try: to_trio.send_nowait(item) @@ -1362,12 +1375,35 @@ async def trades_dialogue( # ib-gw goes down? Not sure exactly how that's happening looking # at the eventkit code above but we should probably handle it... async for event_name, item in ib_trade_events_stream: + print(f' ib sending {item}') - # XXX: begin normalization of nonsense ib_insync internal - # object-state tracking representations... + # TODO: templating the ib statuses in comparison with other + # brokers is likely the way to go: + # https://interactivebrokers.github.io/tws-api/interfaceIBApi_1_1EWrapper.html#a17f2a02d6449710b6394d0266a353313 + # short list: + # - PendingSubmit + # - PendingCancel + # - PreSubmitted (simulated orders) + # - ApiCancelled (cancelled by client before submission + # to routing) + # - Cancelled + # - Filled + # - Inactive (reject or cancelled but not by trader) + + # XXX: here's some other sucky cases from the api + # - short-sale but securities haven't been located, in this + # case we should probably keep the order in some kind of + # weird state or cancel it outright? + # status='PendingSubmit', message=''), + # status='Cancelled', message='Error 404, + # reqId 1550: Order held while securities are located.'), + # status='PreSubmitted', message='')], if event_name == 'status': + # XXX: begin normalization of nonsense ib_insync internal + # object-state tracking representations... + # unwrap needed data from ib_insync internal types trade: Trade = item status: OrderStatus = trade.orderStatus @@ -1378,10 +1414,13 @@ async def trades_dialogue( reqid=trade.order.orderId, time_ns=time.time_ns(), # cuz why not + + # everyone doin camel case.. status=status.status.lower(), # force lower case filled=status.filled, reason=status.whyHeld, + # this seems to not be necessarily up to date in the # execDetails event.. so we have to send it here I guess? remaining=status.remaining, @@ -1500,6 +1539,12 @@ async def open_symbol_search( if not pattern or pattern.isspace(): log.warning('empty pattern received, skipping..') + # TODO: *BUG* if nothing is returned here the client + # side will cache a null set result and not showing + # anything to the use on re-searches when this query + # timed out. We probably need a special "timeout" msg + # or something... + # XXX: this unblocks the far end search task which may # hold up a multi-search nursery block await stream.send({}) @@ -1507,7 +1552,7 @@ async def open_symbol_search( continue log.debug(f'searching for {pattern}') - # await tractor.breakpoint() + last = time.time() results = await _trio_run_client_method( method='search_stocks',