Switch `Client.mkt_mode` to 'usd_futes' if 'perp' in fqme

The beginning of supporting multi-markets through a common API client.
Change to futes market mode in the client if `.perp.` is matched in the
fqme. Currently the exchange info and live feed ws impl will swap out
for their usd-margin futures market equivalent (endpoints).
basic_buy_bot
Tyler Goodlet 2023-06-12 21:58:46 -04:00
parent dc23f1c9bd
commit e68c55e9bd
3 changed files with 45 additions and 30 deletions

View File

@ -30,7 +30,6 @@ from datetime import datetime
from typing import (
Any,
Callable,
Literal,
)
import hmac
import hashlib
@ -53,8 +52,9 @@ from piker.brokers._util import (
get_logger,
)
from .schemas import (
SpotPair,
FutesPair,
PAIRTYPES,
Pair,
MarketType,
)
log = get_logger('piker.brokers.binance')
@ -150,14 +150,6 @@ def binance_timestamp(
return int((when.timestamp() * 1000) + (when.microsecond / 1000))
MarketType: Literal[
'spot',
'margin',
'usd_futes',
'coin_futes',
]
class Client:
'''
Async ReST API client using ``trio`` + ``asks`` B)
@ -319,7 +311,7 @@ class Client:
self,
sym: str | None = None,
mkt_type: MarketType = 'spot',
mkt_type: MarketType | None = None,
) -> dict[str, Pair] | Pair:
'''
@ -334,7 +326,10 @@ class Client:
https://binance-docs.github.io/apidocs/delivery/en/#exchange-information
'''
cached_pair = self._pairs.get(sym)
mkt_type: MarketType = mkt_type or self.mkt_mode
cached_pair = self._pairs.get(
(sym, mkt_type)
)
if cached_pair:
return cached_pair
@ -344,16 +339,15 @@ class Client:
sym = sym.lower()
params = {'symbol': sym}
resp = await self.mkt_req[self.mkt_mode]('exchangeInfo', params=params)
resp = await self.mkt_req[mkt_type]('exchangeInfo', params=params)
entries = resp['symbols']
if not entries:
raise SymbolNotFound(f'{sym} not found:\n{resp}')
# import tractor
# await tractor.breakpoint()
pairs = {}
pairs: dict[str, Pair] = {}
for item in entries:
symbol = item['symbol']
# for spot mkts, pre-process .filters field into
# a table..
@ -364,17 +358,14 @@ class Client:
ftype = entry['filterType']
filters[ftype] = entry
# TODO: lookup pair schema by mkt type
# pair_type = mkt_type
item['filters'] = filters
# pairs[symbol] = SpotPair(
# filters=filters,
# )
pairs[symbol] = FutesPair(**item)
symbol = item['symbol']
pair_type: Pair = PAIRTYPES[mkt_type or self.mkt_mode]
pairs[(symbol, mkt_type)] = pair_type(
**item,
)
# pairs = {
# item['symbol']: Pair(**item) for item in entries
# }
self._pairs.update(pairs)
if sym is not None:
@ -633,8 +624,12 @@ class Client:
@acm
async def get_client() -> Client:
client = Client(mkt_mode='usd_futes')
log.info('Caching exchange infos..')
async def get_client(
mkt_mode: str = 'spot',
) -> Client:
client = Client(mkt_mode=mkt_mode)
log.info(f'{client} in {mkt_mode} mode: caching exchange infos..')
await client.exch_info()
yield client

View File

@ -104,6 +104,7 @@ async def trades_dialogue(
) -> AsyncIterator[dict[str, Any]]:
async with open_cached_client('binance') as client:
await tractor.breakpoint()
if not client.api_key:
await ctx.started('paper')
return

View File

@ -50,6 +50,7 @@ from piker._cacheables import (
from piker.accounting._mktinfo import (
Asset,
MktPair,
unpack_fqme,
digits_to_dec,
)
from piker.data.types import Struct
@ -263,9 +264,27 @@ async def get_mkt_info(
) -> tuple[MktPair, Pair]:
async with open_cached_client('binance') as client:
# uppercase since kraken bs_mktid is always upper
if 'binance' not in fqme:
fqme += '.binance'
pair: Pair = await client.exch_info(fqme.upper())
bs_fqme, _, broker = fqme.rpartition('.')
broker, mkt_ep, venue, suffix = unpack_fqme(fqme)
# bs_fqme, _, broker = fqme.partition('.')
mkt_mode: str = 'spot'
if 'perp' in bs_fqme:
mkt_mode = 'usd_futes'
async with open_cached_client(
'binance',
mkt_mode=mkt_mode,
) as client:
pair_str: str = mkt_ep.upper()
pair: Pair = await client.exch_info(pair_str)
await tractor.breakpoint()
mkt = MktPair(
dst=Asset(
name=pair.baseAsset,