From a72a9475c00bc9c83dda910f8a476854f23bba87 Mon Sep 17 00:00:00 2001 From: Davide Casale Date: Wed, 24 Apr 2024 16:42:54 +0200 Subject: [PATCH 1/6] Add support for event base_margin_info and symbol_margin_info. --- MANIFEST | 38 ------------------- .../rest/_interfaces/rest_auth_endpoints.py | 2 +- bfxapi/types/serializers.py | 10 ++++- .../_event_emitter/bfx_event_emitter.py | 4 +- .../_handlers/auth_events_handler.py | 27 ++++++++----- 5 files changed, 31 insertions(+), 50 deletions(-) delete mode 100644 MANIFEST diff --git a/MANIFEST b/MANIFEST deleted file mode 100644 index f5e35c2..0000000 --- a/MANIFEST +++ /dev/null @@ -1,38 +0,0 @@ -# file GENERATED by distutils, do NOT edit -setup.py -bfxapi/__init__.py -bfxapi/_client.py -bfxapi/_version.py -bfxapi/exceptions.py -bfxapi/_utils/__init__.py -bfxapi/_utils/json_decoder.py -bfxapi/_utils/json_encoder.py -bfxapi/_utils/logging.py -bfxapi/rest/__init__.py -bfxapi/rest/_bfx_rest_interface.py -bfxapi/rest/exceptions.py -bfxapi/rest/_interface/__init__.py -bfxapi/rest/_interface/interface.py -bfxapi/rest/_interface/middleware.py -bfxapi/rest/_interfaces/__init__.py -bfxapi/rest/_interfaces/rest_auth_endpoints.py -bfxapi/rest/_interfaces/rest_merchant_endpoints.py -bfxapi/rest/_interfaces/rest_public_endpoints.py -bfxapi/types/__init__.py -bfxapi/types/dataclasses.py -bfxapi/types/labeler.py -bfxapi/types/notification.py -bfxapi/types/serializers.py -bfxapi/websocket/__init__.py -bfxapi/websocket/_connection.py -bfxapi/websocket/exceptions.py -bfxapi/websocket/subscriptions.py -bfxapi/websocket/_client/__init__.py -bfxapi/websocket/_client/bfx_websocket_bucket.py -bfxapi/websocket/_client/bfx_websocket_client.py -bfxapi/websocket/_client/bfx_websocket_inputs.py -bfxapi/websocket/_event_emitter/__init__.py -bfxapi/websocket/_event_emitter/bfx_event_emitter.py -bfxapi/websocket/_handlers/__init__.py -bfxapi/websocket/_handlers/auth_events_handler.py -bfxapi/websocket/_handlers/public_channels_handler.py diff --git a/bfxapi/rest/_interfaces/rest_auth_endpoints.py b/bfxapi/rest/_interfaces/rest_auth_endpoints.py index 6c34b14..50ae249 100644 --- a/bfxapi/rest/_interfaces/rest_auth_endpoints.py +++ b/bfxapi/rest/_interfaces/rest_auth_endpoints.py @@ -248,7 +248,7 @@ def get_ledgers( def get_base_margin_info(self) -> BaseMarginInfo: return serializers.BaseMarginInfo.parse( - *(self._m.post("auth/r/info/margin/base")[1]) + *self._m.post("auth/r/info/margin/base") ) def get_symbol_margin_info(self, symbol: str) -> SymbolMarginInfo: diff --git a/bfxapi/types/serializers.py b/bfxapi/types/serializers.py index ae2b3b1..4ec04d7 100644 --- a/bfxapi/types/serializers.py +++ b/bfxapi/types/serializers.py @@ -745,7 +745,15 @@ BaseMarginInfo = generate_labeler_serializer( name="BaseMarginInfo", klass=dataclasses.BaseMarginInfo, - labels=["user_pl", "user_swaps", "margin_balance", "margin_net", "margin_min"], + labels=[ + "_PLACEHOLDER", + "user_pl", + "user_swaps", + "margin_balance", + "margin_net", + "margin_min", + ], + flat=True, ) PositionClaim = generate_labeler_serializer( diff --git a/bfxapi/websocket/_event_emitter/bfx_event_emitter.py b/bfxapi/websocket/_event_emitter/bfx_event_emitter.py index 3638767..64e59b4 100644 --- a/bfxapi/websocket/_event_emitter/bfx_event_emitter.py +++ b/bfxapi/websocket/_event_emitter/bfx_event_emitter.py @@ -64,6 +64,8 @@ "trade_execution", "trade_execution_update", "wallet_update", + "base_margin_info", + "symbol_margin_info", "notification", "on-req-notification", "ou-req-notification", @@ -105,7 +107,7 @@ def on( ) -> Union[_Handler, Callable[[_Handler], _Handler]]: if event not in BfxEventEmitter._EVENTS: raise UnknownEventError( - f"Can't register to unknown event: <{event}> (to get a full" + f"Can't register to unknown event: <{event}> (to get a full " "list of available events see https://docs.bitfinex.com/)." ) diff --git a/bfxapi/websocket/_handlers/auth_events_handler.py b/bfxapi/websocket/_handlers/auth_events_handler.py index 89d6ce8..c756ab4 100644 --- a/bfxapi/websocket/_handlers/auth_events_handler.py +++ b/bfxapi/websocket/_handlers/auth_events_handler.py @@ -51,17 +51,26 @@ def __init__(self, event_emitter: EventEmitter) -> None: def handle(self, abbrevation: str, stream: Any) -> None: if abbrevation == "n": self.__notification(stream) + elif abbrevation == "miu": + if stream[0] == "base": + self.__event_emitter.emit( + "base_margin_info", serializers.BaseMarginInfo.parse(*stream) + ) + elif stream[0] == "sym": + self.__event_emitter.emit( + "symbol_margin_info", serializers.SymbolMarginInfo.parse(*stream) + ) + else: + for abbrevations, serializer in AuthEventsHandler.__SERIALIZERS.items(): + if abbrevation in abbrevations: + event = AuthEventsHandler.__ABBREVIATIONS[abbrevation] - for abbrevations, serializer in AuthEventsHandler.__SERIALIZERS.items(): - if abbrevation in abbrevations: - event = AuthEventsHandler.__ABBREVIATIONS[abbrevation] + if all(isinstance(sub_stream, list) for sub_stream in stream): + data = [serializer.parse(*sub_stream) for sub_stream in stream] + else: + data = serializer.parse(*stream) - if all(isinstance(sub_stream, list) for sub_stream in stream): - data = [serializer.parse(*sub_stream) for sub_stream in stream] - else: - data = serializer.parse(*stream) - - self.__event_emitter.emit(event, data) + self.__event_emitter.emit(event, data) def __notification(self, stream: Any) -> None: event: str = "notification" From 847d887babade4c6a0f41da590fa1787df1c5590 Mon Sep 17 00:00:00 2001 From: Davide Casale Date: Wed, 24 Apr 2024 17:20:00 +0200 Subject: [PATCH 2/6] Add support for event funding_info_update. --- bfxapi/rest/_interfaces/rest_auth_endpoints.py | 2 +- bfxapi/types/dataclasses.py | 1 + bfxapi/types/serializers.py | 10 +++++++++- bfxapi/websocket/_event_emitter/bfx_event_emitter.py | 1 + bfxapi/websocket/_handlers/auth_events_handler.py | 2 ++ 5 files changed, 14 insertions(+), 2 deletions(-) diff --git a/bfxapi/rest/_interfaces/rest_auth_endpoints.py b/bfxapi/rest/_interfaces/rest_auth_endpoints.py index 50ae249..8b01f45 100644 --- a/bfxapi/rest/_interfaces/rest_auth_endpoints.py +++ b/bfxapi/rest/_interfaces/rest_auth_endpoints.py @@ -551,7 +551,7 @@ def get_funding_trades_history( def get_funding_info(self, key: str) -> FundingInfo: return serializers.FundingInfo.parse( - *(self._m.post(f"auth/r/info/funding/{key}")[2]) + *self._m.post(f"auth/r/info/funding/{key}") ) def transfer_between_wallets( diff --git a/bfxapi/types/dataclasses.py b/bfxapi/types/dataclasses.py index 91337f2..c3e4458 100644 --- a/bfxapi/types/dataclasses.py +++ b/bfxapi/types/dataclasses.py @@ -428,6 +428,7 @@ class FundingAutoRenew(_Type): @dataclass() class FundingInfo(_Type): + symbol: str yield_loan: float yield_lend: float duration_loan: float diff --git a/bfxapi/types/serializers.py b/bfxapi/types/serializers.py index 4ec04d7..b9abaca 100644 --- a/bfxapi/types/serializers.py +++ b/bfxapi/types/serializers.py @@ -632,7 +632,15 @@ FundingInfo = generate_labeler_serializer( name="FundingInfo", klass=dataclasses.FundingInfo, - labels=["yield_loan", "yield_lend", "duration_loan", "duration_lend"], + labels=[ + "_PLACEHOLDER", + "symbol", + "yield_loan", + "yield_lend", + "duration_loan", + "duration_lend", + ], + flat=True, ) Wallet = generate_labeler_serializer( diff --git a/bfxapi/websocket/_event_emitter/bfx_event_emitter.py b/bfxapi/websocket/_event_emitter/bfx_event_emitter.py index 64e59b4..2e48a6b 100644 --- a/bfxapi/websocket/_event_emitter/bfx_event_emitter.py +++ b/bfxapi/websocket/_event_emitter/bfx_event_emitter.py @@ -66,6 +66,7 @@ "wallet_update", "base_margin_info", "symbol_margin_info", + "funding_info_update", "notification", "on-req-notification", "ou-req-notification", diff --git a/bfxapi/websocket/_handlers/auth_events_handler.py b/bfxapi/websocket/_handlers/auth_events_handler.py index c756ab4..0a2230a 100644 --- a/bfxapi/websocket/_handlers/auth_events_handler.py +++ b/bfxapi/websocket/_handlers/auth_events_handler.py @@ -33,6 +33,7 @@ class AuthEventsHandler: "flc": "funding_loan_close", "ws": "wallet_snapshot", "wu": "wallet_update", + "fiu": "funding_info_update", } __SERIALIZERS: Dict[Tuple[str, ...], serializers._Serializer] = { @@ -43,6 +44,7 @@ class AuthEventsHandler: ("fcs", "fcn", "fcu", "fcc"): serializers.FundingCredit, ("fls", "fln", "flu", "flc"): serializers.FundingLoan, ("ws", "wu"): serializers.Wallet, + ("fiu",): serializers.FundingInfo, } def __init__(self, event_emitter: EventEmitter) -> None: From 8f7d6950c29105473eab346e49bb2279633c6fac Mon Sep 17 00:00:00 2001 From: Davide Casale Date: Wed, 24 Apr 2024 17:33:32 +0200 Subject: [PATCH 3/6] Add support for event balance_update. --- bfxapi/types/__init__.py | 1 + bfxapi/types/dataclasses.py | 6 ++++++ bfxapi/types/serializers.py | 6 ++++++ bfxapi/websocket/_event_emitter/bfx_event_emitter.py | 1 + bfxapi/websocket/_handlers/auth_events_handler.py | 2 ++ 5 files changed, 16 insertions(+) diff --git a/bfxapi/types/__init__.py b/bfxapi/types/__init__.py index 0b1df46..cf17b88 100644 --- a/bfxapi/types/__init__.py +++ b/bfxapi/types/__init__.py @@ -1,5 +1,6 @@ from .dataclasses import ( BalanceAvailable, + BalanceInfo, BaseMarginInfo, Candle, CurrencyConversion, diff --git a/bfxapi/types/dataclasses.py b/bfxapi/types/dataclasses.py index c3e4458..c1d40d6 100644 --- a/bfxapi/types/dataclasses.py +++ b/bfxapi/types/dataclasses.py @@ -608,6 +608,12 @@ class DerivativePositionCollateralLimits(_Type): max_collateral: float +@dataclass +class BalanceInfo(_Type): + aum: float + aum_net: float + + # endregion # region Dataclass definitions for types of merchant use diff --git a/bfxapi/types/serializers.py b/bfxapi/types/serializers.py index b9abaca..25054e4 100644 --- a/bfxapi/types/serializers.py +++ b/bfxapi/types/serializers.py @@ -904,4 +904,10 @@ labels=["min_collateral", "max_collateral"], ) +BalanceInfo = generate_labeler_serializer( + name="BalanceInfo", + klass=dataclasses.BalanceInfo, + labels=["aum", "aum_net"], +) + # endregion diff --git a/bfxapi/websocket/_event_emitter/bfx_event_emitter.py b/bfxapi/websocket/_event_emitter/bfx_event_emitter.py index 2e48a6b..21bbfd6 100644 --- a/bfxapi/websocket/_event_emitter/bfx_event_emitter.py +++ b/bfxapi/websocket/_event_emitter/bfx_event_emitter.py @@ -67,6 +67,7 @@ "base_margin_info", "symbol_margin_info", "funding_info_update", + "balance_update", "notification", "on-req-notification", "ou-req-notification", diff --git a/bfxapi/websocket/_handlers/auth_events_handler.py b/bfxapi/websocket/_handlers/auth_events_handler.py index 0a2230a..486e9f7 100644 --- a/bfxapi/websocket/_handlers/auth_events_handler.py +++ b/bfxapi/websocket/_handlers/auth_events_handler.py @@ -34,6 +34,7 @@ class AuthEventsHandler: "ws": "wallet_snapshot", "wu": "wallet_update", "fiu": "funding_info_update", + "bu": "balance_update", } __SERIALIZERS: Dict[Tuple[str, ...], serializers._Serializer] = { @@ -45,6 +46,7 @@ class AuthEventsHandler: ("fls", "fln", "flu", "flc"): serializers.FundingLoan, ("ws", "wu"): serializers.Wallet, ("fiu",): serializers.FundingInfo, + ("bu",): serializers.BalanceInfo, } def __init__(self, event_emitter: EventEmitter) -> None: From 3010961b696545209b2ec08d162d8885ec60cdda Mon Sep 17 00:00:00 2001 From: Davide Casale Date: Wed, 24 Apr 2024 17:42:46 +0200 Subject: [PATCH 4/6] Add /examples/websocket/auth/calc.py demo to show how calc works. --- examples/websocket/auth/calc.py | 40 +++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 examples/websocket/auth/calc.py diff --git a/examples/websocket/auth/calc.py b/examples/websocket/auth/calc.py new file mode 100644 index 0000000..3099f00 --- /dev/null +++ b/examples/websocket/auth/calc.py @@ -0,0 +1,40 @@ +# python -c "import examples.websocket.auth.calc" + +import os + +from bfxapi import Client +from bfxapi.types import BaseMarginInfo, FundingInfo, SymbolMarginInfo + +bfx = Client( + api_key=os.getenv("BFX_API_KEY"), + api_secret=os.getenv("BFX_API_SECRET"), +) + + +@bfx.wss.on("authenticated") +async def on_authenticated(_): + await bfx.wss.inputs.calc("margin_base") + + await bfx.wss.inputs.calc("margin_sym_tBTCUSD") + + await bfx.wss.inputs.calc("funding_sym_fUST") + + +@bfx.wss.on("base_margin_info") +def on_base_margin_info(data: BaseMarginInfo): + print("Base margin info:", data) + + +@bfx.wss.on("symbol_margin_info") +def on_symbol_margin_info(data: SymbolMarginInfo): + if data.symbol == "tBTCUSD": + print("Symbol margin info:", data) + + +@bfx.wss.on("funding_info_update") +def on_funding_info_update(data: FundingInfo): + if data.symbol == "fUST": + print("Funding info update:", data) + + +bfx.wss.run() From a72c574ad2c1eb86b8cb605bc3f2793da403e06e Mon Sep 17 00:00:00 2001 From: Davide Casale Date: Wed, 24 Apr 2024 17:43:59 +0200 Subject: [PATCH 5/6] Bump __version__ in file bfxapi/_version.py to v3.0.2. --- bfxapi/_version.py | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bfxapi/_version.py b/bfxapi/_version.py index 0552768..131942e 100644 --- a/bfxapi/_version.py +++ b/bfxapi/_version.py @@ -1 +1 @@ -__version__ = "3.0.1" +__version__ = "3.0.2" diff --git a/setup.py b/setup.py index 5172b21..f800292 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ setup( name="bitfinex-api-py", - version="3.0.1", + version="3.0.2", description="Official Bitfinex Python API", long_description=( "A Python reference implementation of the Bitfinex API " From 74b6c770bf0d7ec94dd9917a11dfdcb7f20777a8 Mon Sep 17 00:00:00 2001 From: Davide Casale Date: Thu, 25 Apr 2024 16:07:43 +0200 Subject: [PATCH 6/6] Improve /example/websocket/auth/calc.py demo. --- examples/websocket/auth/calc.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/examples/websocket/auth/calc.py b/examples/websocket/auth/calc.py index 3099f00..eac6937 100644 --- a/examples/websocket/auth/calc.py +++ b/examples/websocket/auth/calc.py @@ -13,11 +13,7 @@ @bfx.wss.on("authenticated") async def on_authenticated(_): - await bfx.wss.inputs.calc("margin_base") - - await bfx.wss.inputs.calc("margin_sym_tBTCUSD") - - await bfx.wss.inputs.calc("funding_sym_fUST") + await bfx.wss.inputs.calc("margin_base", "margin_sym_tBTCUSD", "funding_sym_fUST") @bfx.wss.on("base_margin_info")