From 802779636f3b2ed62e79cee7027ba6ee945c0b14 Mon Sep 17 00:00:00 2001 From: Chuck Office Date: Mon, 20 Oct 2025 16:17:59 +0800 Subject: [PATCH 1/7] feat: add metadata cache --- edgex_sdk/client.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/edgex_sdk/client.py b/edgex_sdk/client.py index 55654b9..8e7db06 100644 --- a/edgex_sdk/client.py +++ b/edgex_sdk/client.py @@ -53,6 +53,8 @@ def __init__(self, base_url: str, account_id: int, stark_private_key: str, self.transfer = TransferClient(self.async_client) self.asset = AssetClient(self.async_client) + self._cached_metadata: Dict[str, Any] | None = None + async def __aenter__(self): """Async context manager entry.""" await self.async_client._ensure_session() @@ -73,7 +75,9 @@ def internal_client(self): async def get_metadata(self) -> Dict[str, Any]: """Get the exchange metadata.""" - return await self.metadata.get_metadata() + if self._cached_metadata is None: + self._cached_metadata = await self.metadata.get_metadata() + return self._cached_metadata async def get_server_time(self) -> Dict[str, Any]: """Get the current server time.""" From d0a57e34a194caab405347116dbe91972f9e2f3a Mon Sep 17 00:00:00 2001 From: Chuck Office Date: Tue, 21 Oct 2025 17:02:43 +0800 Subject: [PATCH 2/7] fix: fix trade-event callback --- edgex_sdk/ws/client.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/edgex_sdk/ws/client.py b/edgex_sdk/ws/client.py index 0571bce..27418c7 100644 --- a/edgex_sdk/ws/client.py +++ b/edgex_sdk/ws/client.py @@ -167,6 +167,20 @@ def _handle_messages(self): self.handlers[channel_type](message) continue + if msg.get("type") == "trade-event": + account_handler = self.handlers.get("account") + if account_handler is not None: + account_handler(message) + + order_handler = self.handlers.get("order") + if order_handler is not None: + order_handler(message) + + position_handler = self.handlers.get("position") + if position_handler is not None: + position_handler(message) + + # Call registered handlers for other message types msg_type = msg.get("type", "") if msg_type in self.handlers: From eb6e94783f9be2d6e206db5811b8343add9a2a36 Mon Sep 17 00:00:00 2001 From: Chuck Date: Sun, 26 Oct 2025 23:30:58 +0800 Subject: [PATCH 3/7] feat: add order api --- config.toml | 4 ++ edgex_sdk/order/client.py | 110 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 config.toml diff --git a/config.toml b/config.toml new file mode 100644 index 0000000..8c04203 --- /dev/null +++ b/config.toml @@ -0,0 +1,4 @@ +[mcp_servers.context7] +args = ["-y", "@upstash/context7-mcp", "--api-key", "ctx7sk-94270ca0-e14a-4908-a84e-b0f04057c1d2"] +command = "pnpx" +startup_timeout_ms = 20_000 diff --git a/edgex_sdk/order/client.py b/edgex_sdk/order/client.py index b6ccfc3..7fc4887 100644 --- a/edgex_sdk/order/client.py +++ b/edgex_sdk/order/client.py @@ -8,6 +8,7 @@ CreateOrderParams, CancelOrderParams, GetActiveOrderParams, + GetHistoryOrderParams, OrderFillTransactionParams, TimeInForce, OrderType @@ -261,6 +262,61 @@ async def get_active_orders(self, params: GetActiveOrderParams) -> Dict[str, Any params=query_params ) + async def get_history_orders(self, params: GetHistoryOrderParams) -> Dict[str, Any]: + """ + Get historical orders with pagination and filters. + + Args: + params: History order query parameters + + Returns: + Dict[str, Any]: The historical orders + + Raises: + ValueError: If the request fails + """ + # Build query parameters + query_params = { + "accountId": str(self.async_client.get_account_id()) + } + + # Add pagination parameters + if params.size: + query_params["size"] = params.size + if params.offset_data: + query_params["offsetData"] = params.offset_data + + # Add filter parameters + if params.filter_coin_id_list: + query_params["filterCoinIdList"] = ",".join(params.filter_coin_id_list) + if params.filter_contract_id_list: + query_params["filterContractIdList"] = ",".join(params.filter_contract_id_list) + if params.filter_type_list: + query_params["filterTypeList"] = ",".join(params.filter_type_list) + if params.filter_status_list: + query_params["filterStatusList"] = ",".join(params.filter_status_list) + + # Add boolean filters + if params.filter_is_liquidate is not None: + query_params["filterIsLiquidateList"] = str(params.filter_is_liquidate).lower() + if params.filter_is_deleverage is not None: + query_params["filterIsDeleverageList"] = str(params.filter_is_deleverage).lower() + if params.filter_is_position_tpsl is not None: + query_params["filterIsPositionTpslList"] = str(params.filter_is_position_tpsl).lower() + + # Add time filters + if params.filter_start_created_time_inclusive > 0: + query_params["filterStartCreatedTimeInclusive"] = str(params.filter_start_created_time_inclusive) + if params.filter_end_created_time_exclusive > 0: + query_params["filterEndCreatedTimeExclusive"] = str(params.filter_end_created_time_exclusive) + + # Execute request using async client + return await self.async_client.make_authenticated_request( + method="GET", + path="/api/v1/private/order/getHistoryOrderPage", + params=query_params + ) + async def get_order_fill_transactions(self, params: OrderFillTransactionParams) -> Dict[str, Any]: """ Get order fill transactions with pagination and filters. @@ -314,6 +370,60 @@ async def get_order_fill_transactions(self, params: OrderFillTransactionParams) params=query_params ) + async def get_orders_by_ids(self, order_id_list: List[str]) -> Dict[str, Any]: + """ + Get orders by account ID and order IDs (batch). + + Args: + order_id_list: List of order IDs to fetch + + Returns: + Dict[str, Any]: Orders matching the provided IDs + + Raises: + ValueError: If input is invalid or request fails + """ + if not order_id_list: + raise ValueError("order_id_list must not be empty") + + data = { + "accountId": str(self.async_client.get_account_id()), + "orderIdList": order_id_list, + } + + return await self.async_client.make_authenticated_request( + method="POST", + path="/api/v1/private/order/getOrderByIdBatch", + data=data, + ) + + async def get_orders_by_client_order_ids(self, client_order_id_list: List[str]) -> Dict[str, Any]: + """ + Get orders by client order IDs (batch). + + Args: + client_order_id_list: List of client order IDs to fetch + + Returns: + Dict[str, Any]: Orders matching the provided client order IDs + + Raises: + ValueError: If input is invalid or request fails + """ + if not client_order_id_list: + raise ValueError("client_order_id_list must not be empty") + + data = { + "accountId": str(self.async_client.get_account_id()), + "clientOrderIdList": client_order_id_list, + } + + return await self.async_client.make_authenticated_request( + method="POST", + path="/api/v1/private/order/getOrderByClientOrderIdBatch", + data=data, + ) + async def get_max_order_size(self, contract_id: str, price: float) -> Dict[str, Any]: """ Get the maximum order size for a given contract and price. From 29a8457545b54d824261ede042f7d9a97f16891a Mon Sep 17 00:00:00 2001 From: Chuck Office Date: Mon, 27 Oct 2025 12:34:11 +0800 Subject: [PATCH 4/7] fix: fix query list params --- config.toml | 4 ---- edgex_sdk/order/client.py | 8 ++++---- pyproject.toml | 2 +- 3 files changed, 5 insertions(+), 9 deletions(-) delete mode 100644 config.toml diff --git a/config.toml b/config.toml deleted file mode 100644 index 8c04203..0000000 --- a/config.toml +++ /dev/null @@ -1,4 +0,0 @@ -[mcp_servers.context7] -args = ["-y", "@upstash/context7-mcp", "--api-key", "ctx7sk-94270ca0-e14a-4908-a84e-b0f04057c1d2"] -command = "pnpx" -startup_timeout_ms = 20_000 diff --git a/edgex_sdk/order/client.py b/edgex_sdk/order/client.py index 7fc4887..aca65ad 100644 --- a/edgex_sdk/order/client.py +++ b/edgex_sdk/order/client.py @@ -388,12 +388,12 @@ async def get_orders_by_ids(self, order_id_list: List[str]) -> Dict[str, Any]: data = { "accountId": str(self.async_client.get_account_id()), - "orderIdList": order_id_list, + "orderIdList": ",".join(order_id_list), } return await self.async_client.make_authenticated_request( method="POST", - path="/api/v1/private/order/getOrderByIdBatch", + path="/api/v1/private/order/getOrderById", data=data, ) @@ -415,12 +415,12 @@ async def get_orders_by_client_order_ids(self, client_order_id_list: List[str]) data = { "accountId": str(self.async_client.get_account_id()), - "clientOrderIdList": client_order_id_list, + "clientOrderIdList": ",".join(client_order_id_list), } return await self.async_client.make_authenticated_request( method="POST", - path="/api/v1/private/order/getOrderByClientOrderIdBatch", + path="/api/v1/private/order/getOrderByClientOrderId", data=data, ) diff --git a/pyproject.toml b/pyproject.toml index 10df441..c616bb9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "edgex-python-sdk" -version = "0.3.0" +version = "0.3.1" description = "A Python SDK for interacting with the EdgeX Exchange API" readme = "README.md" license = {text = "MIT"} From 3a6559bd0e04a2e58f5e7bf8c50016a4ce4e67a8 Mon Sep 17 00:00:00 2001 From: Chuck Office Date: Mon, 27 Oct 2025 12:35:53 +0800 Subject: [PATCH 5/7] fix: fix query orders method --- edgex_sdk/order/client.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/edgex_sdk/order/client.py b/edgex_sdk/order/client.py index aca65ad..c40ad09 100644 --- a/edgex_sdk/order/client.py +++ b/edgex_sdk/order/client.py @@ -392,7 +392,7 @@ async def get_orders_by_ids(self, order_id_list: List[str]) -> Dict[str, Any]: } return await self.async_client.make_authenticated_request( - method="POST", + method="GET", path="/api/v1/private/order/getOrderById", data=data, ) @@ -419,7 +419,7 @@ async def get_orders_by_client_order_ids(self, client_order_id_list: List[str]) } return await self.async_client.make_authenticated_request( - method="POST", + method="GET", path="/api/v1/private/order/getOrderByClientOrderId", data=data, ) From 79cc608b31a33a2aa8e7a247e0e0b093da264b4f Mon Sep 17 00:00:00 2001 From: Chuck Office Date: Mon, 27 Oct 2025 12:36:18 +0800 Subject: [PATCH 6/7] fix: fix query orders method --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c616bb9..1aebe84 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "edgex-python-sdk" -version = "0.3.1" +version = "0.3.2" description = "A Python SDK for interacting with the EdgeX Exchange API" readme = "README.md" license = {text = "MIT"} From ab393aca95d39bfcdba7a3459af686dcba008381 Mon Sep 17 00:00:00 2001 From: Chuck Office Date: Mon, 27 Oct 2025 12:38:02 +0800 Subject: [PATCH 7/7] fix: fix query orders params --- edgex_sdk/order/client.py | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/edgex_sdk/order/client.py b/edgex_sdk/order/client.py index c40ad09..f155231 100644 --- a/edgex_sdk/order/client.py +++ b/edgex_sdk/order/client.py @@ -386,7 +386,7 @@ async def get_orders_by_ids(self, order_id_list: List[str]) -> Dict[str, Any]: if not order_id_list: raise ValueError("order_id_list must not be empty") - data = { + query_params = { "accountId": str(self.async_client.get_account_id()), "orderIdList": ",".join(order_id_list), } @@ -394,7 +394,7 @@ async def get_orders_by_ids(self, order_id_list: List[str]) -> Dict[str, Any]: return await self.async_client.make_authenticated_request( method="GET", path="/api/v1/private/order/getOrderById", - data=data, + params=query_params, ) async def get_orders_by_client_order_ids(self, client_order_id_list: List[str]) -> Dict[str, Any]: @@ -413,7 +413,7 @@ async def get_orders_by_client_order_ids(self, client_order_id_list: List[str]) if not client_order_id_list: raise ValueError("client_order_id_list must not be empty") - data = { + query_params = { "accountId": str(self.async_client.get_account_id()), "clientOrderIdList": ",".join(client_order_id_list), } @@ -421,7 +421,7 @@ async def get_orders_by_client_order_ids(self, client_order_id_list: List[str]) return await self.async_client.make_authenticated_request( method="GET", path="/api/v1/private/order/getOrderByClientOrderId", - data=data, + params=query_params, ) async def get_max_order_size(self, contract_id: str, price: float) -> Dict[str, Any]: diff --git a/pyproject.toml b/pyproject.toml index 1aebe84..f52c4bd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "edgex-python-sdk" -version = "0.3.2" +version = "0.3.3" description = "A Python SDK for interacting with the EdgeX Exchange API" readme = "README.md" license = {text = "MIT"}