binance: implement `Client.search_symbols()` using `rapidfuzz`

Change the deats inside the method and have the `brokerd` search task
just call it as needed since we already do internal mem caching on the
lookup table.

APIs changed so we need to make some tweaks as per:
- https://github.com/maxbachmann/RapidFuzz/blob/main/api_differences.md
- https://github.com/maxbachmann/RapidFuzz/blob/main/api_differences.md#differences-in-processor-functions

The main motivation is to get better wheel pkging support (for nixos),
better impl in C++, and a more simply licensed dep.
ib_py311_fixes
Tyler Goodlet 2023-09-13 11:59:51 -04:00
parent 4a180019f0
commit 2c88ebe697
2 changed files with 30 additions and 15 deletions

View File

@ -31,6 +31,8 @@ from pprint import pformat
from typing import ( from typing import (
Any, Any,
Callable, Callable,
Hashable,
Sequence,
Type, Type,
) )
import hmac import hmac
@ -549,7 +551,7 @@ class Client:
if sym: if sym:
return pair_table[sym] return pair_table[sym]
else: else:
self._pairs return self._pairs
async def get_assets( async def get_assets(
self, self,
@ -596,14 +598,26 @@ class Client:
fq_pairs: dict = await self.exch_info() fq_pairs: dict = await self.exch_info()
matches = fuzzy.extractBests( # TODO: cache this list like we were in
pattern, # `open_symbol_search()`?
fq_pairs, keys: list[str] = list(fq_pairs)
matches: list[tuple[
Sequence[Hashable], # matching input key
Any, # scores
Any,
]] = fuzzy.extract(
query=pattern.upper(), # since all keys are uppercase
choices=keys,
score_cutoff=50, score_cutoff=50,
) )
# repack in dict form # repack in dict form
return {item[0]['symbol']: item[0] matched_pairs: dict[str, Pair] = {}
for item in matches} for item in matches:
pair_key: str = item[0]
matched_pairs[pair_key] = self._pairs[pair_key]
return matched_pairs
async def bars( async def bars(
self, self,

View File

@ -42,7 +42,7 @@ from trio_typing import TaskStatus
from pendulum import ( from pendulum import (
from_timestamp, from_timestamp,
) )
from fuzzywuzzy import process as fuzzy from rapidfuzz import process as fuzzy
import numpy as np import numpy as np
import tractor import tractor
@ -533,14 +533,15 @@ async def open_symbol_search(
pattern: str pattern: str
async for pattern in stream: async for pattern in stream:
matches = fuzzy.extractBests( # NOTE: pattern fuzzy-matching is done within
# the methd impl.
pairs: dict[str, Pair] = await client.search_symbols(
pattern, pattern,
client._pairs,
score_cutoff=50,
) )
# repack in dict form # repack in fqme-keyed table
await stream.send({ byfqme: dict[start, Pair] = {}
item[0].bs_fqme: item[0] for pair in pairs.values():
for item in matches byfqme[pair.bs_fqme] = pair
})
await stream.send(byfqme)