hyperquant 0.71__tar.gz → 0.73__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. {hyperquant-0.71 → hyperquant-0.73}/PKG-INFO +1 -1
  2. {hyperquant-0.71 → hyperquant-0.73}/apis.json +5 -2
  3. {hyperquant-0.71 → hyperquant-0.73}/pyproject.toml +1 -1
  4. hyperquant-0.73/src/hyperquant/broker/bitget.py +291 -0
  5. {hyperquant-0.71 → hyperquant-0.73}/src/hyperquant/broker/models/bitget.py +84 -8
  6. {hyperquant-0.71 → hyperquant-0.73}/src/hyperquant/broker/models/lbank.py +2 -1
  7. {hyperquant-0.71 → hyperquant-0.73}/tests/test_bitget.py +33 -4
  8. {hyperquant-0.71 → hyperquant-0.73}/tests/test_lbank.py +8 -7
  9. {hyperquant-0.71 → hyperquant-0.73}/uv.lock +1 -1
  10. hyperquant-0.71/doc/edgex_act.md +0 -1592
  11. hyperquant-0.71/doc/edgex_debug.md +0 -2
  12. hyperquant-0.71/doc/edgex_order.md +0 -1767
  13. hyperquant-0.71/doc/edgex_ws.md +0 -0
  14. hyperquant-0.71/src/hyperquant/broker/bitget.py +0 -107
  15. {hyperquant-0.71 → hyperquant-0.73}/.gitignore +0 -0
  16. {hyperquant-0.71 → hyperquant-0.73}/.python-version +0 -0
  17. {hyperquant-0.71 → hyperquant-0.73}/README.md +0 -0
  18. {hyperquant-0.71 → hyperquant-0.73}/data/alpine_smoke.log +0 -0
  19. {hyperquant-0.71 → hyperquant-0.73}/data/logs/notikit.log +0 -0
  20. {hyperquant-0.71 → hyperquant-0.73}/data/logs/test_order_sync.log +0 -0
  21. {hyperquant-0.71 → hyperquant-0.73}/data/records_swap.csv +0 -0
  22. {hyperquant-0.71 → hyperquant-0.73}/data/records_swapc.csv +0 -0
  23. {hyperquant-0.71 → hyperquant-0.73}/doc/lbank.md +0 -0
  24. {hyperquant-0.71 → hyperquant-0.73}/pub.sh +0 -0
  25. {hyperquant-0.71 → hyperquant-0.73}/requirements-dev.lock +0 -0
  26. {hyperquant-0.71 → hyperquant-0.73}/requirements.lock +0 -0
  27. {hyperquant-0.71 → hyperquant-0.73}/src/hyperquant/__init__.py +0 -0
  28. {hyperquant-0.71 → hyperquant-0.73}/src/hyperquant/broker/auth.py +0 -0
  29. {hyperquant-0.71 → hyperquant-0.73}/src/hyperquant/broker/edgex.py +0 -0
  30. {hyperquant-0.71 → hyperquant-0.73}/src/hyperquant/broker/hyperliquid.py +0 -0
  31. {hyperquant-0.71 → hyperquant-0.73}/src/hyperquant/broker/lbank.py +0 -0
  32. {hyperquant-0.71 → hyperquant-0.73}/src/hyperquant/broker/lib/edgex_sign.py +0 -0
  33. {hyperquant-0.71 → hyperquant-0.73}/src/hyperquant/broker/lib/hpstore.py +0 -0
  34. {hyperquant-0.71 → hyperquant-0.73}/src/hyperquant/broker/lib/hyper_types.py +0 -0
  35. {hyperquant-0.71 → hyperquant-0.73}/src/hyperquant/broker/lib/util.py +0 -0
  36. {hyperquant-0.71 → hyperquant-0.73}/src/hyperquant/broker/models/edgex.py +0 -0
  37. {hyperquant-0.71 → hyperquant-0.73}/src/hyperquant/broker/models/hyperliquid.py +0 -0
  38. {hyperquant-0.71 → hyperquant-0.73}/src/hyperquant/broker/models/ourbit.py +0 -0
  39. {hyperquant-0.71 → hyperquant-0.73}/src/hyperquant/broker/ourbit.py +0 -0
  40. {hyperquant-0.71 → hyperquant-0.73}/src/hyperquant/broker/ws.py +0 -0
  41. {hyperquant-0.71 → hyperquant-0.73}/src/hyperquant/core.py +0 -0
  42. {hyperquant-0.71 → hyperquant-0.73}/src/hyperquant/datavison/_util.py +0 -0
  43. {hyperquant-0.71 → hyperquant-0.73}/src/hyperquant/datavison/binance.py +0 -0
  44. {hyperquant-0.71 → hyperquant-0.73}/src/hyperquant/datavison/coinglass.py +0 -0
  45. {hyperquant-0.71 → hyperquant-0.73}/src/hyperquant/datavison/okx.py +0 -0
  46. {hyperquant-0.71 → hyperquant-0.73}/src/hyperquant/db.py +0 -0
  47. {hyperquant-0.71 → hyperquant-0.73}/src/hyperquant/draw.py +0 -0
  48. {hyperquant-0.71 → hyperquant-0.73}/src/hyperquant/logkit.py +0 -0
  49. {hyperquant-0.71 → hyperquant-0.73}/src/hyperquant/notikit.py +0 -0
  50. {hyperquant-0.71 → hyperquant-0.73}/tests/test_draw.py +0 -0
  51. {hyperquant-0.71 → hyperquant-0.73}/tests/test_edgex.py +0 -0
  52. {hyperquant-0.71 → hyperquant-0.73}/tests/test_ourbit.py +0 -0
  53. {hyperquant-0.71 → hyperquant-0.73}/tests/tmp.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hyperquant
3
- Version: 0.71
3
+ Version: 0.73
4
4
  Summary: A minimal yet hyper-efficient backtesting framework for quantitative trading
5
5
  Project-URL: Homepage, https://github.com/yourusername/hyperquant
6
6
  Project-URL: Issues, https://github.com/yourusername/hyperquant/issues
@@ -7,7 +7,10 @@
7
7
  "78Uke-bPB57YoRzAwY7SkWyPQFeKkPuWVQakC0k9rSI",
8
8
  "3MB7nAnnNPTxAnwdbjDPew-02b746d6a832346a46a97faf054b2909c1a0b58a35e04c3504923a99a5503c1c"
9
9
  ],
10
- "lbank": [
11
- "617a2d77b4cd4dfbbaa2094c17017bdb"
10
+ "lbank": ["617a2d77b4cd4dfbbaa2094c17017bdb"],
11
+ "bitget": [
12
+ "bg_03e0445d9282f248d22842cfe6f30192",
13
+ "67ec894753d75fec12332881278420863a960ec39c8f5acf1de88aa1da926854",
14
+ "huainian0408"
12
15
  ]
13
16
  }
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "hyperquant"
3
- version = "0.71"
3
+ version = "0.73"
4
4
  description = "A minimal yet hyper-efficient backtesting framework for quantitative trading"
5
5
  authors = [
6
6
  { name = "MissinA", email = "1421329142@qq.com" }
@@ -0,0 +1,291 @@
1
+ from __future__ import annotations
2
+
3
+ import logging
4
+ from typing import Any, Literal
5
+
6
+ import pybotters
7
+
8
+ from .models.bitget import BitgetDataStore
9
+ from .lib.util import fmt_value
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+
14
+ class Bitget:
15
+ """Bitget public/privileged client (REST + WS).
16
+
17
+ 默认只支持单向持仓(One-way mode)。
18
+ """
19
+
20
+ def __init__(
21
+ self,
22
+ client: pybotters.Client,
23
+ *,
24
+ rest_api: str | None = None,
25
+ ws_url: str | None = None,
26
+ ) -> None:
27
+ self.client = client
28
+ self.store = BitgetDataStore()
29
+
30
+ self.rest_api = rest_api or "https://api.bitget.com"
31
+ self.ws_url = ws_url or "wss://ws.bitget.com/v2/ws/public"
32
+ self.ws_url_private = ws_url or "wss://ws.bitget.com/v2/ws/private"
33
+
34
+ self._ws_app = None
35
+
36
+ async def __aenter__(self) -> "Bitget":
37
+ await self.update("detail")
38
+ return self
39
+
40
+ async def __aexit__(self, exc_type, exc, tb) -> None: # pragma: no cover - symmetry
41
+ pass
42
+
43
+ async def sub_personal(self) -> None:
44
+ sub_msg = {
45
+ "op": "subscribe",
46
+ "args": [
47
+ {"instType": "USDT-FUTURES", "channel": "orders", "instId": "default"},
48
+ {
49
+ "instType": "USDT-FUTURES",
50
+ "channel": "positions",
51
+ "instId": "default",
52
+ },
53
+ {"instType": "USDT-FUTURES", "channel": "account", "coin": "default"},
54
+ ],
55
+ }
56
+ self.client.ws_connect(
57
+ self.ws_url_private,
58
+ send_json=sub_msg,
59
+ hdlr_json=self.store.onmessage,
60
+ )
61
+
62
+ async def update(
63
+ self,
64
+ update_type: Literal["detail", "ticker", "all"] = "all",
65
+ ) -> None:
66
+ """Refresh cached REST resources."""
67
+
68
+ requests: list[Any] = []
69
+
70
+ if update_type in {"detail", "all"}:
71
+ requests.append(
72
+ self.client.get(
73
+ f"{self.rest_api}/api/v2/mix/market/contracts",
74
+ params={"productType": "usdt-futures"},
75
+ )
76
+ )
77
+
78
+ if update_type in {"ticker", "all"}:
79
+ requests.append(
80
+ self.client.get(
81
+ f"{self.rest_api}/api/v2/mix/market/tickers",
82
+ params={"productType": "usdt-futures"},
83
+ )
84
+ )
85
+
86
+ if not requests:
87
+ raise ValueError(f"update_type err: {update_type}")
88
+
89
+ await self.store.initialize(*requests)
90
+
91
+ async def place_order(
92
+ self,
93
+ symbol: str,
94
+ *,
95
+ direction: Literal["buy", "sell", "long", "short", "0", "1"],
96
+ volume: float,
97
+ price: float | None = None,
98
+ order_type: Literal[
99
+ "market",
100
+ "limit_gtc",
101
+ "limit_ioc",
102
+ "limit_fok",
103
+ "limit_post_only",
104
+ "limit",
105
+ ] = "market",
106
+ margin_mode: Literal["isolated", "crossed"] = "crossed",
107
+ product_type: str = "USDT-FUTURES",
108
+ margin_coin: str = "USDT",
109
+ reduce_only: bool | None = None,
110
+ offset_flag: Literal["open", "close", "0", "1"] | None = None,
111
+ client_order_id: str | None = None,
112
+ extra_params: dict[str, Any] | None = None,
113
+ ) -> dict[str, Any]:
114
+ """Create an order via ``POST /api/v2/mix/order/place-order``.
115
+
116
+ Parameters mirror the Bitget V2 contract REST API but are normalized to
117
+ match the broker interface (``direction``, ``order_type`` etc.).
118
+ """
119
+
120
+ side = self._normalize_direction(direction)
121
+ order_type_code, force_code = self._resolve_order_type(order_type)
122
+
123
+ if reduce_only is None:
124
+ reduce_only = self._normalize_offset(offset_flag)
125
+
126
+ detail = self._get_detail_entry(symbol)
127
+ volume_str = self._format_with_step(
128
+ volume, detail.get("step_size") or detail.get("stepSize")
129
+ )
130
+
131
+ payload: dict[str, Any] = {
132
+ "symbol": symbol,
133
+ "productType": product_type,
134
+ "marginMode": margin_mode,
135
+ "marginCoin": margin_coin,
136
+ "side": side,
137
+ "size": volume_str,
138
+ "orderType": order_type_code,
139
+ }
140
+
141
+ if force_code:
142
+ payload["force"] = force_code
143
+
144
+ if order_type_code == "limit":
145
+ if price is None:
146
+ raise ValueError("price is required for Bitget limit orders")
147
+ payload["price"] = self._format_with_step(
148
+ price,
149
+ detail.get("tick_size") or detail.get("tickSize"),
150
+ )
151
+ elif price is not None:
152
+ logger.debug("Price %.8f ignored for market order", price)
153
+
154
+ if reduce_only is True:
155
+ payload["reduceOnly"] = "YES"
156
+ elif reduce_only is False:
157
+ payload["reduceOnly"] = "NO"
158
+
159
+ if client_order_id:
160
+ payload["clientOid"] = client_order_id
161
+
162
+ if extra_params:
163
+ payload.update(extra_params)
164
+
165
+ res = await self.client.post(
166
+ f"{self.rest_api}/api/v2/mix/order/place-order",
167
+ data=payload,
168
+ )
169
+ data = await res.json()
170
+ return self._ensure_ok("place_order", data)
171
+
172
+ async def cancel_order(
173
+ self,
174
+ order_sys_id: str,
175
+ *,
176
+ symbol: str,
177
+ margin_mode: Literal["isolated", "crossed"],
178
+ product_type: str = "USDT-FUTURES",
179
+ margin_coin: str = "USDT",
180
+ client_order_id: str | None = None,
181
+ ) -> dict[str, Any]:
182
+ """Cancel an order via ``POST /api/v2/mix/order/cancel-order``."""
183
+
184
+ payload = {
185
+ "symbol": symbol,
186
+ "productType": product_type,
187
+ "marginMode": margin_mode,
188
+ "marginCoin": margin_coin,
189
+ }
190
+
191
+ if client_order_id:
192
+ payload["clientOid"] = client_order_id
193
+ else:
194
+ payload["orderId"] = order_sys_id
195
+
196
+ res = await self.client.post(
197
+ f"{self.rest_api}/api/v2/mix/order/cancel-order",
198
+ json=payload,
199
+ )
200
+ data = await res.json()
201
+ return self._ensure_ok("cancel_order", data)
202
+
203
+ async def sub_orderbook(self, symbols: list[str], channel: str = "books1") -> None:
204
+ """Subscribe to Bitget order-book snapshots/updates."""
205
+
206
+ submsg = {"op": "subscribe", "args": []}
207
+ for symbol in symbols:
208
+ submsg["args"].append(
209
+ {"instType": "USDT-FUTURES", "channel": channel, "instId": symbol}
210
+ )
211
+
212
+ self.client.ws_connect(
213
+ self.ws_url,
214
+ send_json=submsg,
215
+ hdlr_json=self.store.onmessage,
216
+ )
217
+
218
+ def _get_detail_entry(self, symbol: str) -> dict[str, Any]:
219
+ detail = self.store.detail.get({"symbol": symbol})
220
+ if not detail:
221
+ raise ValueError(
222
+ f"Unknown Bitget instrument: {symbol}. Call update('detail') first or provide valid symbol."
223
+ )
224
+ return detail
225
+
226
+ @staticmethod
227
+ def _format_with_step(value: float, step: Any) -> str:
228
+ if step in (None, 0, "0"):
229
+ return str(value)
230
+ try:
231
+ step_float = float(step)
232
+ except (TypeError, ValueError): # pragma: no cover - defensive guard
233
+ return str(value)
234
+ if step_float <= 0:
235
+ return str(value)
236
+ return fmt_value(value, step_float)
237
+
238
+ @staticmethod
239
+ def _normalize_direction(direction: str) -> str:
240
+ mapping = {
241
+ "buy": "buy",
242
+ "long": "buy",
243
+ "0": "buy",
244
+ "sell": "sell",
245
+ "short": "sell",
246
+ "1": "sell",
247
+ }
248
+ key = str(direction).lower()
249
+ try:
250
+ return mapping[key]
251
+ except KeyError as exc: # pragma: no cover - guard
252
+ raise ValueError(f"Unsupported direction: {direction}") from exc
253
+
254
+ @staticmethod
255
+ def _normalize_offset(
256
+ offset: Literal["open", "close", "0", "1"] | None,
257
+ ) -> bool | None:
258
+ if offset is None:
259
+ return None
260
+ mapping = {
261
+ "open": False,
262
+ "0": False,
263
+ "close": True,
264
+ "1": True,
265
+ }
266
+ key = str(offset).lower()
267
+ if key in mapping:
268
+ return mapping[key]
269
+ raise ValueError(f"Unsupported offset_flag: {offset}")
270
+
271
+ @staticmethod
272
+ def _resolve_order_type(order_type: str) -> tuple[str, str | None]:
273
+ mapping = {
274
+ "market": ("market", None),
275
+ "limit": ("limit", "gtc"),
276
+ "limit_gtc": ("limit", "gtc"),
277
+ "limit_ioc": ("limit", "ioc"),
278
+ "limit_fok": ("limit", "fok"),
279
+ "limit_post_only": ("limit", "post_only"),
280
+ }
281
+ key = str(order_type).lower()
282
+ try:
283
+ return mapping[key]
284
+ except KeyError as exc: # pragma: no cover - guard
285
+ raise ValueError(f"Unsupported order_type: {order_type}") from exc
286
+
287
+ @staticmethod
288
+ def _ensure_ok(operation: str, data: Any) -> dict[str, Any]:
289
+ if not isinstance(data, dict) or data.get("code") != "00000":
290
+ raise RuntimeError(f"{operation} failed: {data}")
291
+ return data.get("data") or {}
@@ -16,13 +16,18 @@ class Detail(DataStore):
16
16
  _KEYS = ["symbol"]
17
17
 
18
18
  def _transform(self, entry: dict[str, Any]) -> dict[str, Any] | None:
19
-
20
- step_size = entry.get('volume_place', 1)
21
- tick_size = entry.get('price_place', 1)
22
- step_size = place_to_step(step_size)
23
- tick_size = place_to_step(tick_size)
24
- entry['tickSize'] = tick_size
25
- entry['stepSize'] = step_size
19
+ step_place = entry.get("volume_place", 1)
20
+ tick_place = entry.get("price_place", 1)
21
+
22
+ step_size = place_to_step(step_place)
23
+ tick_size = place_to_step(tick_place)
24
+
25
+ entry["stepSize"] = step_size
26
+ entry["tickSize"] = tick_size
27
+ # expose snake_case aliases for downstream callers keeping legacy naming
28
+ entry["step_size"] = step_size
29
+ entry["tick_size"] = tick_size
30
+
26
31
  return entry
27
32
 
28
33
  def _onresponse(self, data: list[dict[str, Any]] | dict[str, Any] | None) -> None:
@@ -280,4 +285,75 @@ class BitgetDataStore(BitgetV2DataStore):
280
285
  }
281
286
  ]
282
287
  """
283
- return self._get("book")
288
+ return self._get("book")
289
+
290
+ @property
291
+ def account(self) -> DataStore:
292
+ """
293
+ _KEYS = ["instType", "marginCoin"]
294
+
295
+ Data Structure:
296
+
297
+ .. code:: json
298
+
299
+ [
300
+ {
301
+ "marginCoin": "USDT",
302
+ "frozen": "0.00000000",
303
+ "available": "13.98545761",
304
+ "maxOpenPosAvailable": "13.98545761",
305
+ "maxTransferOut": "13.98545761",
306
+ "equity": "13.98545761",
307
+ "usdtEquity": "13.985457617660",
308
+ "crossedRiskRate": "0",
309
+ "unrealizedPL": "0.000000000000",
310
+ "unionTotalMargin": "100",
311
+ "unionAvailable": "20",
312
+ "unionMm": "15",
313
+ "assetMode": "union"
314
+ }
315
+ ]
316
+ """
317
+ return self._get("account")
318
+
319
+ @property
320
+ def position(self) -> DataStore:
321
+ """
322
+ _KEYS = ["instType", "instId", "posId"]
323
+
324
+ Data Structure:
325
+
326
+ .. code:: json
327
+
328
+ [
329
+ {
330
+ "posId": "1",
331
+ "instId": "ETHUSDT",
332
+ "marginCoin": "USDT",
333
+ "marginSize": "9.5",
334
+ "marginMode": "crossed",
335
+ "holdSide": "short",
336
+ "posMode": "hedge_mode",
337
+ "total": "0.1",
338
+ "available": "0.1",
339
+ "frozen": "0",
340
+ "openPriceAvg": "1900",
341
+ "leverage": 20,
342
+ "achievedProfits": "0",
343
+ "unrealizedPL": "0",
344
+ "unrealizedPLR": "0",
345
+ "liquidationPrice": "5788.108475905242",
346
+ "keepMarginRate": "0.005",
347
+ "marginRate": "0.004416374196",
348
+ "cTime": "1695649246169",
349
+ "breakEvenPrice": "24778.97",
350
+ "totalFee": "1.45",
351
+ "deductedFee": "0.388",
352
+ "markPrice": "2500",
353
+ "assetMode": "union",
354
+ "uTime": "1695711602568",
355
+ "autoMargin": "off"
356
+ }
357
+ ]
358
+ """
359
+ return self._get("position")
@@ -184,7 +184,8 @@ class Orders(DataStore):
184
184
  "side": direction,
185
185
  "offset": offset_flag,
186
186
  "order_type": order_kind,
187
- "price": entry.get("Price"),
187
+ "price": entry.get('TradePrice') or entry.get("Price"),
188
+ "order_price": entry.get("OrderPrice") or entry.get('Price'),
188
189
  "quantity": entry.get("Volume"),
189
190
  "filled": entry.get("VolumeTraded"),
190
191
  "remaining": entry.get("VolumeRemain"),
@@ -1,6 +1,7 @@
1
+ import time
1
2
  import pybotters
2
3
  from hyperquant.broker.models.bitget import BitgetDataStore
3
-
4
+ pybotters.auth
4
5
 
5
6
  async def test_update():
6
7
  async with pybotters.Client() as client:
@@ -42,8 +43,10 @@ async def test_broker_update():
42
43
  async with pybotters.Client() as client:
43
44
  bg = Bitget(client)
44
45
  store = BitgetDataStore()
45
- await bg.update('all')
46
- print(bg.store.detail.find())
46
+ # await bg.update('all')
47
+ # print(bg.store.detail.find())
48
+ await bg.update('ticker')
49
+ print(bg.store.ticker.find())
47
50
 
48
51
  async def test_broker_sub_orderbook():
49
52
  async with pybotters.Client() as client:
@@ -53,7 +56,33 @@ async def test_broker_sub_orderbook():
53
56
  await asyncio.sleep(1)
54
57
  print(bg.store.book.find())
55
58
 
59
+ async def test_order():
60
+ async with pybotters.Client(apis='./apis.json') as client:
61
+ bg = Bitget(client)
62
+ await bg.__aenter__()
63
+ ts = time.time() * 1000
64
+ res = await bg.place_order(
65
+ 'SOLUSDT',
66
+ direction='long',
67
+ order_type='limit_gtc',
68
+ volume=0.1,
69
+ price=185
70
+ )
71
+ # print(res)
72
+ print(f'订单延迟: {time.time() * 1000 - ts} ms')
73
+
74
+ async def test_sub_personal():
75
+ async with pybotters.Client(apis='./apis.json') as client:
76
+ bg = Bitget(client)
77
+ await bg.__aenter__()
78
+ await bg.sub_personal()
79
+ with bg.store.orders.watch() as stream:
80
+ async for change in stream:
81
+ print("Orders changed:", change)
82
+
83
+
84
+
56
85
  if __name__ == "__main__":
57
86
  import asyncio
58
87
 
59
- asyncio.run(test_broker_sub_orderbook())
88
+ asyncio.run(test_order())
@@ -107,10 +107,11 @@ async def test_update():
107
107
  # print(lb.store.position.find())
108
108
  # await lb.update('balance')
109
109
  # print(lb.store.balance.find())
110
- await lb.update('detail')
111
- print(lb.store.detail.find())
112
- # await lb.update('orders_finish')
113
- # print(lb.store.order_finish.find())
110
+ # await lb.update('detail')
111
+ # print(lb.store.detail.find())
112
+ await lb.update('orders')
113
+
114
+ print(lb.store.order_finish.find())
114
115
 
115
116
  async def test_place():
116
117
  async with pybotters.Client(apis='./apis.json') as client:
@@ -241,8 +242,8 @@ async def test_order_sync_polling():
241
242
  lb,
242
243
  symbol="SOLUSDT",
243
244
  direction="buy",
244
- order_type="market",
245
- price=200,
245
+ order_type="limit_gtc",
246
+ price=200.1,
246
247
  volume=0.03,
247
248
  window_sec=3.0,
248
249
  grace_sec=3.0,
@@ -251,4 +252,4 @@ async def test_order_sync_polling():
251
252
  print(result)
252
253
 
253
254
  if __name__ == "__main__":
254
- asyncio.run(test_place())
255
+ asyncio.run(test_order_sync_polling())
@@ -530,7 +530,7 @@ wheels = [
530
530
 
531
531
  [[package]]
532
532
  name = "hyperquant"
533
- version = "0.7"
533
+ version = "0.72"
534
534
  source = { editable = "." }
535
535
  dependencies = [
536
536
  { name = "aiohttp" },