Use `Client._pairs` cross-venue table for orders

Since the request handler task will work concurrently across venues
(spot, futes, margin) we need to be sure that we look up the correct
venue to update the order dialog and this is naturally determined by the
FQME-style symbol in the `BrokerdOrder` msg; the best way to map that
symbol-key to the correct venue/`Pair` is by using said `._pairs:
ChainMap`.

Further, handle limit order errors by catching and relaying back an
error response to the EMS. Fix the "account name" to be `binance.usdtm`
so that we can eventually and explicitly support all venues by name.
basic_buy_bot
Tyler Goodlet 2023-06-17 13:26:20 -04:00
parent 98f6d85b65
commit a9c016ba10
1 changed files with 34 additions and 17 deletions

View File

@ -48,6 +48,7 @@ from piker.data._web_bs import (
) )
from piker.brokers import ( from piker.brokers import (
open_cached_client, open_cached_client,
BrokerError,
) )
from piker.clearing._messages import ( from piker.clearing._messages import (
BrokerdOrder, BrokerdOrder,
@ -91,7 +92,8 @@ async def handle_order_requests(
) )
await ems_order_stream.send(BrokerdError( await ems_order_stream.send(BrokerdError(
oid=cancel.oid, oid=cancel.oid,
symbol=cancel.symbol, # TODO: do we need the symbol?
symbol='unknown',
reason=( reason=(
'Invalid `binance` order request dialog oid', 'Invalid `binance` order request dialog oid',
) )
@ -100,12 +102,12 @@ async def handle_order_requests(
else: else:
await client.submit_cancel( await client.submit_cancel(
cancel.symbol, existing.symbol,
cancel.oid, cancel.oid,
) )
case { case {
'account': ('binance.futes' | 'binance.spot') as account, 'account': ('binance.usdtm' | 'binance.spot') as account,
'action': action, 'action': action,
} if action in {'buy', 'sell'}: } if action in {'buy', 'sell'}:
@ -131,9 +133,13 @@ async def handle_order_requests(
) )
await ems_order_stream.send(resp) await ems_order_stream.send(resp)
# lookup the binance-native symbol
bs_mktid: str = client._pairs[order.symbol.upper()].symbol
# call our client api to submit the order # call our client api to submit the order
try:
reqid = await client.submit_limit( reqid = await client.submit_limit(
symbol=order.symbol, symbol=bs_mktid,
side=order.action, side=order.action,
quantity=order.size, quantity=order.size,
price=order.price, price=order.price,
@ -144,6 +150,17 @@ async def handle_order_requests(
# track latest request state # track latest request state
dialogs[reqid].maps.append(msg) dialogs[reqid].maps.append(msg)
except BrokerError as be:
await ems_order_stream.send(
BrokerdError(
oid=msg['oid'],
symbol=msg['symbol'],
reason=(
'`binance` request failed:\n'
f'{be}'
))
)
continue
case _: case _:
account = msg.get('account') account = msg.get('account')
@ -157,7 +174,7 @@ async def handle_order_requests(
oid=msg['oid'], oid=msg['oid'],
symbol=msg['symbol'], symbol=msg['symbol'],
reason=( reason=(
'Invalid `binance` broker request msg:\n{msg}' f'Invalid `binance` broker request msg:\n{msg}'
)) ))
) )
@ -230,7 +247,7 @@ async def open_trade_dialog(
# 'feeTier': 0} # 'feeTier': 0}
if 'account' in req: if 'account' in req:
alias: str = resp['accountAlias'] alias: str = resp['accountAlias']
accounts['binance.usdtm_futes'] = alias accounts['binance.usdtm'] = alias
# @balance response: # @balance response:
# {'accountAlias': 'sRFzFzAuuXsR', # {'accountAlias': 'sRFzFzAuuXsR',