hyperquant 0.73__tar.gz → 0.75__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 (48) hide show
  1. {hyperquant-0.73 → hyperquant-0.75}/PKG-INFO +1 -1
  2. {hyperquant-0.73 → hyperquant-0.75}/apis.json +4 -2
  3. {hyperquant-0.73 → hyperquant-0.75}/pyproject.toml +1 -1
  4. {hyperquant-0.73 → hyperquant-0.75}/src/hyperquant/broker/lbank.py +222 -4
  5. {hyperquant-0.73 → hyperquant-0.75}/src/hyperquant/broker/models/lbank.py +3 -0
  6. {hyperquant-0.73 → hyperquant-0.75}/tests/test_lbank.py +91 -82
  7. {hyperquant-0.73 → hyperquant-0.75}/uv.lock +1 -1
  8. {hyperquant-0.73 → hyperquant-0.75}/.gitignore +0 -0
  9. {hyperquant-0.73 → hyperquant-0.75}/.python-version +0 -0
  10. {hyperquant-0.73 → hyperquant-0.75}/README.md +0 -0
  11. {hyperquant-0.73 → hyperquant-0.75}/data/alpine_smoke.log +0 -0
  12. {hyperquant-0.73 → hyperquant-0.75}/data/logs/notikit.log +0 -0
  13. {hyperquant-0.73 → hyperquant-0.75}/data/logs/test_order_sync.log +0 -0
  14. {hyperquant-0.73 → hyperquant-0.75}/data/records_swap.csv +0 -0
  15. {hyperquant-0.73 → hyperquant-0.75}/data/records_swapc.csv +0 -0
  16. {hyperquant-0.73 → hyperquant-0.75}/doc/lbank.md +0 -0
  17. {hyperquant-0.73 → hyperquant-0.75}/pub.sh +0 -0
  18. {hyperquant-0.73 → hyperquant-0.75}/requirements-dev.lock +0 -0
  19. {hyperquant-0.73 → hyperquant-0.75}/requirements.lock +0 -0
  20. {hyperquant-0.73 → hyperquant-0.75}/src/hyperquant/__init__.py +0 -0
  21. {hyperquant-0.73 → hyperquant-0.75}/src/hyperquant/broker/auth.py +0 -0
  22. {hyperquant-0.73 → hyperquant-0.75}/src/hyperquant/broker/bitget.py +0 -0
  23. {hyperquant-0.73 → hyperquant-0.75}/src/hyperquant/broker/edgex.py +0 -0
  24. {hyperquant-0.73 → hyperquant-0.75}/src/hyperquant/broker/hyperliquid.py +0 -0
  25. {hyperquant-0.73 → hyperquant-0.75}/src/hyperquant/broker/lib/edgex_sign.py +0 -0
  26. {hyperquant-0.73 → hyperquant-0.75}/src/hyperquant/broker/lib/hpstore.py +0 -0
  27. {hyperquant-0.73 → hyperquant-0.75}/src/hyperquant/broker/lib/hyper_types.py +0 -0
  28. {hyperquant-0.73 → hyperquant-0.75}/src/hyperquant/broker/lib/util.py +0 -0
  29. {hyperquant-0.73 → hyperquant-0.75}/src/hyperquant/broker/models/bitget.py +0 -0
  30. {hyperquant-0.73 → hyperquant-0.75}/src/hyperquant/broker/models/edgex.py +0 -0
  31. {hyperquant-0.73 → hyperquant-0.75}/src/hyperquant/broker/models/hyperliquid.py +0 -0
  32. {hyperquant-0.73 → hyperquant-0.75}/src/hyperquant/broker/models/ourbit.py +0 -0
  33. {hyperquant-0.73 → hyperquant-0.75}/src/hyperquant/broker/ourbit.py +0 -0
  34. {hyperquant-0.73 → hyperquant-0.75}/src/hyperquant/broker/ws.py +0 -0
  35. {hyperquant-0.73 → hyperquant-0.75}/src/hyperquant/core.py +0 -0
  36. {hyperquant-0.73 → hyperquant-0.75}/src/hyperquant/datavison/_util.py +0 -0
  37. {hyperquant-0.73 → hyperquant-0.75}/src/hyperquant/datavison/binance.py +0 -0
  38. {hyperquant-0.73 → hyperquant-0.75}/src/hyperquant/datavison/coinglass.py +0 -0
  39. {hyperquant-0.73 → hyperquant-0.75}/src/hyperquant/datavison/okx.py +0 -0
  40. {hyperquant-0.73 → hyperquant-0.75}/src/hyperquant/db.py +0 -0
  41. {hyperquant-0.73 → hyperquant-0.75}/src/hyperquant/draw.py +0 -0
  42. {hyperquant-0.73 → hyperquant-0.75}/src/hyperquant/logkit.py +0 -0
  43. {hyperquant-0.73 → hyperquant-0.75}/src/hyperquant/notikit.py +0 -0
  44. {hyperquant-0.73 → hyperquant-0.75}/tests/test_bitget.py +0 -0
  45. {hyperquant-0.73 → hyperquant-0.75}/tests/test_draw.py +0 -0
  46. {hyperquant-0.73 → hyperquant-0.75}/tests/test_edgex.py +0 -0
  47. {hyperquant-0.73 → hyperquant-0.75}/tests/test_ourbit.py +0 -0
  48. {hyperquant-0.73 → hyperquant-0.75}/tests/tmp.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hyperquant
3
- Version: 0.73
3
+ Version: 0.75
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,8 +7,10 @@
7
7
  "78Uke-bPB57YoRzAwY7SkWyPQFeKkPuWVQakC0k9rSI",
8
8
  "3MB7nAnnNPTxAnwdbjDPew-02b746d6a832346a46a97faf054b2909c1a0b58a35e04c3504923a99a5503c1c"
9
9
  ],
10
- "lbank": ["617a2d77b4cd4dfbbaa2094c17017bdb"],
11
- "bitget": [
10
+ "lbank": [
11
+ "925a645e03c84c8e96b96008e98b75f7"
12
+ ],
13
+ "bitget":[
12
14
  "bg_03e0445d9282f248d22842cfe6f30192",
13
15
  "67ec894753d75fec12332881278420863a960ec39c8f5acf1de88aa1da926854",
14
16
  "huainian0408"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "hyperquant"
3
- version = "0.73"
3
+ version = "0.75"
4
4
  description = "A minimal yet hyper-efficient backtesting framework for quantitative trading"
5
5
  authors = [
6
6
  { name = "MissinA", email = "1421329142@qq.com" }
@@ -136,6 +136,162 @@ class Lbank:
136
136
 
137
137
  await self.store.initialize(*requests)
138
138
 
139
+ async def query_trade(
140
+ self,
141
+ order_id: str | None = None,
142
+ *,
143
+ product_group: str = "SwapU",
144
+ page_index: int = 1,
145
+ page_size: int = 20,
146
+ ) -> list[dict[str, Any]]:
147
+ """Fetch trade executions linked to a given OrderSysID.
148
+
149
+ Example response payload::
150
+
151
+ [
152
+ {
153
+ "TradeUnitID": "e1b03fb1-6849-464f-a",
154
+ "ProductGroup": "SwapU",
155
+ "CloseProfit": 0,
156
+ "BusinessNo": 1001770339345505,
157
+ "TradeID": "1000162046503720",
158
+ "PositionID": "1000632926272299",
159
+ "DeriveSource": "0",
160
+ "OrderID": "",
161
+ "Direction": "0",
162
+ "InstrumentID": "SOLUSDT",
163
+ "OffsetFlag": "0",
164
+ "Remark": "def",
165
+ "DdlnTime": "0",
166
+ "UseMargin": 0.054213,
167
+ "Currency": "USDT",
168
+ "Turnover": 5.4213,
169
+ "SettlementGroup": "SwapU",
170
+ "Leverage": 100,
171
+ "OrderSysID": "1000632948114584",
172
+ "ExchangeID": "Exchange",
173
+ "AccountID": "e1b03fb1-6849-464f-a986-94b9a6e625e6",
174
+ "TradeTime": 1760161085,
175
+ "Fee": 0.00325278,
176
+ "OrderPrice": 180.89,
177
+ "InsertTime": 1760161085,
178
+ "MemberID": "e1b03fb1-6849-464f-a986-94b9a6e625e6",
179
+ "MatchRole": "1",
180
+ "ClearCurrency": "USDT",
181
+ "Price": 180.71,
182
+ "Volume": 0.03,
183
+ "OpenPrice": 182.94,
184
+ "MasterAccountID": "",
185
+ "PriceCurrency": "USDT",
186
+ "FeeCurrency": "USDT"
187
+ }
188
+ ]
189
+ """
190
+
191
+ if not order_id:
192
+ raise ValueError("order_id is required to query order executions")
193
+
194
+ params = {
195
+ "ProductGroup": product_group,
196
+ "OrderSysID": order_id,
197
+ "pageIndex": page_index,
198
+ "pageSize": page_size,
199
+ }
200
+
201
+ res = await self.client.get(
202
+ f"{self.front_api}/cfd/query/v1.0/Trade",
203
+ params=params,
204
+ headers=self._rest_headers,
205
+ )
206
+ data = await res.json()
207
+ payload = self._ensure_ok("query_trade", data)
208
+
209
+ if isinstance(payload, dict):
210
+ rows = payload.get("data")
211
+ if isinstance(rows, list):
212
+ return rows
213
+ elif isinstance(payload, list): # pragma: no cover - defensive fallback
214
+ return payload
215
+
216
+ return []
217
+
218
+ async def query_order(
219
+ self,
220
+ order_id: str | None = None,
221
+ *,
222
+ product_group: str = "SwapU",
223
+ page_index: int = 1,
224
+ page_size: int = 20,
225
+ ) -> dict[str, Any]:
226
+ """
227
+ 返回值示例:
228
+
229
+ .. code:: json
230
+
231
+ {
232
+ "order_id": "1000632478428573",
233
+ "instrument_id": "SOLUSDT",
234
+ "position_id": "1000632478428573",
235
+ "direction": "0",
236
+ "offset_flag": "0",
237
+ "trade_time": 1760123456,
238
+ "avg_price": 182.5,
239
+ "volume": 0.03,
240
+ "turnover": 5.475,
241
+ "fee": 0.003285,
242
+ "trade_count": 1
243
+ }
244
+
245
+ 如果没有订单成交返回
246
+ {
247
+ "order_id": "1000632478428573",
248
+ "trade_count": 0
249
+ }
250
+ """
251
+
252
+ if not order_id:
253
+ raise ValueError("order_id is required to query order statistics")
254
+
255
+ trades = await self.query_trade(
256
+ order_id,
257
+ product_group=product_group,
258
+ page_index=page_index,
259
+ page_size=page_size,
260
+ )
261
+
262
+ if not trades:
263
+ return {
264
+ "order_id": order_id,
265
+ "trade_count": 0,
266
+ }
267
+
268
+ def _to_float(value: Any) -> float:
269
+ try:
270
+ return float(value)
271
+ except (TypeError, ValueError):
272
+ return 0.0
273
+
274
+ total_volume = sum(_to_float(trade.get("Volume")) for trade in trades)
275
+ total_turnover = sum(_to_float(trade.get("Turnover")) for trade in trades)
276
+ total_fee = sum(_to_float(trade.get("Fee")) for trade in trades)
277
+
278
+ avg_price = total_turnover / total_volume if total_volume else None
279
+ last_trade = trades[-1]
280
+
281
+ return {
282
+ "order_id": order_id,
283
+ "instrument_id": last_trade.get("InstrumentID"),
284
+ "position_id": last_trade.get("PositionID"),
285
+ "direction": last_trade.get("Direction"),
286
+ "offset_flag": last_trade.get("OffsetFlag"),
287
+ "trade_time": last_trade.get("TradeTime"),
288
+ "avg_price": avg_price,
289
+ "volume": total_volume,
290
+ "turnover": total_turnover,
291
+ "fee": total_fee,
292
+ "trade_count": len(trades),
293
+ }
294
+
139
295
  def _resolve_instrument(self) -> str | None:
140
296
  detail_entries = self.store.detail.find()
141
297
  if detail_entries:
@@ -212,7 +368,71 @@ class Lbank:
212
368
  order_proportion: str = "0.0000",
213
369
  client_order_id: str | None = None,
214
370
  ) -> dict[str, Any]:
215
- """Create an order using documented REST parameters."""
371
+ """Create an order using documented REST parameters.
372
+
373
+ 返回示例:
374
+
375
+ .. code:: json
376
+
377
+ {
378
+ "offsetFlag": "5",
379
+ "orderType": "1",
380
+ "reserveMode": "0",
381
+ "fee": "0.0066042",
382
+ "frozenFee": "0",
383
+ "ddlnTime": "0",
384
+ "userID": "lbank_exchange_user",
385
+ "masterAccountID": "",
386
+ "exchangeID": "Exchange",
387
+ "accountID": "e1b03fb1-6849-464f-a986-94b9a6e625e6",
388
+ "orderSysID": "1000633129818889",
389
+ "volumeRemain": "0",
390
+ "price": "183.36",
391
+ "businessValue": "1760183423813",
392
+ "frozenMargin": "0",
393
+ "instrumentID": "SOLUSDT",
394
+ "posiDirection": "2",
395
+ "volumeMode": "1",
396
+ "volume": "0.06",
397
+ "insertTime": "1760183423",
398
+ "copyMemberID": "",
399
+ "position": "0.06",
400
+ "tradePrice": "183.45",
401
+ "leverage": "100",
402
+ "businessResult": "",
403
+ "availableUse": "0",
404
+ "orderStatus": "1",
405
+ "openPrice": "182.94",
406
+ "frozenMoney": "0",
407
+ "remark": "def",
408
+ "reserveUse": "0",
409
+ "sessionNo": "41",
410
+ "isCrossMargin": "1",
411
+ "closeProfit": "0.0306",
412
+ "businessNo": "1001770756852986", # 订单有成交会并入仓位 businessNo
413
+ "relatedOrderSysID": "",
414
+ "positionID": "1000632926272299",
415
+ "mockResp": false,
416
+ "deriveSource": "0",
417
+ "copyOrderID": "",
418
+ "currency": "USDT",
419
+ "turnover": "11.007",
420
+ "frontNo": "-68",
421
+ "direction": "1",
422
+ "orderPriceType": "4",
423
+ "volumeCancled": "0",
424
+ "updateTime": "1760183423",
425
+ "localID": "1000633129818889",
426
+ "volumeTraded": "0.06",
427
+ "appid": "WEB",
428
+ "tradeUnitID": "e1b03fb1-6849-464f-a",
429
+ "businessType": "P",
430
+ "memberID": "e1b03fb1-6849-464f-a986-94b9a6e625e6",
431
+ "timeCondition": "0",
432
+ "copyProfit": "0"
433
+ }
434
+
435
+ """
216
436
 
217
437
  direction_code = self._normalize_direction(direction)
218
438
  offset_code = self._normalize_offset(offset_flag)
@@ -244,9 +464,7 @@ class Lbank:
244
464
  # logger.warning("Price is ignored for market orders")
245
465
  pass
246
466
 
247
- # if client_order_id:
248
- # payload["LocalID"] = client_order_id
249
- print(payload)
467
+
250
468
  res = await self.client.post(
251
469
  f"{self.front_api}/cfd/cff/v1/SendOrderInsert",
252
470
  json=payload,
@@ -271,6 +271,7 @@ class Position(DataStore):
271
271
  if not entry:
272
272
  return None
273
273
  position_id = entry.get("PositionID")
274
+ bus_id = entry.get("BusinessNo")
274
275
  if not position_id:
275
276
  return None
276
277
 
@@ -279,6 +280,7 @@ class Position(DataStore):
279
280
 
280
281
  return {
281
282
  "position_id": position_id,
283
+ "bus_id": bus_id,
282
284
  "symbol": entry.get("InstrumentID"),
283
285
  "side": side,
284
286
  "quantity": entry.get("Position"),
@@ -473,6 +475,7 @@ class LbankDataStore(DataStoreCollection):
473
475
  [
474
476
  {
475
477
  "position_id": <仓位ID>,
478
+ "bus_id": <订单ID覆盖>,
476
479
  "symbol": <合约ID>,
477
480
  "side": "long" / "short" / "net",
478
481
  "quantity": <持仓数量>,
@@ -2,9 +2,10 @@ import asyncio
2
2
  import json
3
3
  import time
4
4
  import zlib
5
- from typing import Literal
5
+ from typing import Literal, Union
6
6
 
7
7
  from aiohttp import ClientWebSocketResponse
8
+ from aiohttp.client_exceptions import ContentTypeError
8
9
  import pybotters
9
10
 
10
11
 
@@ -103,28 +104,33 @@ async def test_broker_subbook():
103
104
  async def test_update():
104
105
  async with pybotters.Client(apis='./apis.json') as client:
105
106
  async with Lbank(client) as lb:
106
- # await lb.update('position')
107
- # print(lb.store.position.find())
107
+ await lb.update('position')
108
+ print(lb.store.position.find())
108
109
  # await lb.update('balance')
109
110
  # print(lb.store.balance.find())
110
111
  # await lb.update('detail')
111
112
  # print(lb.store.detail.find())
112
- await lb.update('orders')
113
+ # await lb.update('orders')
114
+ # await lb.update('orders_finish')
113
115
 
114
- print(lb.store.order_finish.find())
116
+ # print(lb.store.order_finish.find({
117
+ # 'order_id': '1000632478428573'
118
+ # }))
115
119
 
116
120
  async def test_place():
117
121
  async with pybotters.Client(apis='./apis.json') as client:
118
122
  async with Lbank(client) as lb:
119
123
  order = await lb.place_order(
120
- "0GUSDT",
124
+ "SOLUSDT",
121
125
  direction="buy",
122
126
  order_type='limit_gtc',
123
- price=3.5342,
124
- volume=4.176760504552669,
127
+ price=182,
128
+ volume=0.03,
125
129
  )
126
130
  print(order)
127
131
 
132
+
133
+
128
134
  async def test_cancel():
129
135
  async with pybotters.Client(apis='./apis.json') as client:
130
136
  async with Lbank(client) as lb:
@@ -132,36 +138,6 @@ async def test_cancel():
132
138
  print(res)
133
139
 
134
140
 
135
- async def wait_order_state_poll(
136
- broker: Lbank,
137
- order_id: str,
138
- symbol: str,
139
- seconds: float,
140
- poll_interval: float = 0.5,
141
- ) -> dict:
142
- """轮询 REST 接口,等待订单进入终态。"""
143
-
144
- async with asyncio.timeout(seconds):
145
- last_snapshot: dict | None = None
146
- while True:
147
- await broker.update("orders")
148
- snapshot = broker.store.orders.get({"order_id": order_id})
149
- if snapshot:
150
- last_snapshot = snapshot
151
- status = snapshot.get("status")
152
- if status in {"filled", "canceled"}:
153
- return snapshot
154
- else:
155
- await broker.update_finish_order(instrument_id=symbol)
156
- finished = broker.store.order_finish.get({"order_id": order_id})
157
- if finished:
158
- return finished
159
- await asyncio.sleep(poll_interval)
160
-
161
- # asyncio.timeout will raise TimeoutError; this return is defensive
162
- return last_snapshot or {}
163
-
164
-
165
141
  async def order_sync_polling(
166
142
  broker: Lbank,
167
143
  *,
@@ -172,24 +148,17 @@ async def order_sync_polling(
172
148
  volume: float | None = None,
173
149
  window_sec: float = 5.0,
174
150
  grace_sec: float = 5.0,
175
- poll_interval: float = 0.5,
176
- ) -> dict:
177
- """
178
- 由于 LBank 暂无订单推送,这里通过 ``update`` 轮询同步订单状态。
151
+ poll_interval: float = 0.5
152
+ ) :
179
153
 
180
- - window_sec: 主轮询窗口,订单若持续存在则触发撤单流程。
181
- - grace_sec: 撤单后的额外等待窗口。
154
+ """
155
+ 返回
156
+ {'order_id': '1000633291976722', 'instrument_id': 'SOLUSDT', 'position_id': '1000633291830781', 'direction': '1', 'offset_flag': '0', 'trade_time': 1760203736, 'avg_price': 183.95000000000002, 'volume': 0.03, 'turnover': 5.5185, 'fee': 0.0033111, 'trade_count': 1}
157
+ 或者
158
+ {'order_id': '1000633291976722', 'trade_count': 0}
182
159
  """
183
160
 
184
161
  norm_type = order_type.lower()
185
- if norm_type not in {"market", "limit_gtc", "limit_ioc"}:
186
- raise ValueError(f"unsupported order_type: {order_type}")
187
-
188
- if norm_type != "market" and price is None:
189
- raise ValueError("price is required for limit orders")
190
- if volume is None:
191
- raise ValueError("volume is required for LBank orders")
192
-
193
162
  started = int(time.time() * 1000)
194
163
  resp = await broker.place_order(
195
164
  symbol,
@@ -198,58 +167,98 @@ async def order_sync_polling(
198
167
  price=price,
199
168
  volume=volume,
200
169
  )
170
+
201
171
  latency = int(time.time() * 1000) - started
202
- print(f"下单延迟 {latency} ms")
203
172
 
204
- order_id = (
205
- resp.get("orderSysID")
206
- or resp.get("OrderSysID")
207
- or resp.get("order_id")
208
- or resp.get("orderId")
209
- )
173
+ order_id = resp.get("orderSysID")
174
+ # print(f"下单延迟 {latency} ms, 订单号: {order_id}")
175
+
210
176
  if not order_id:
211
177
  raise RuntimeError(f"place_order 返回缺少 order_id: {resp}")
212
178
 
179
+
180
+ position_id = resp.get("positionID")
181
+ if not position_id:
182
+ raise RuntimeError(f"place_order 返回缺少 position_id: {resp}")
183
+
184
+ if 'volumeRemain' in resp and float(resp['volumeRemain']) == 0:
185
+ return {
186
+ "order_id": order_id,
187
+ "trade_count": 1,
188
+ "volume": volume,
189
+ "avg_price": float(resp.get('openPrice', 0)),
190
+ "turnover": float(resp.get('turnover', 0)),
191
+ "fee": float(resp.get('fee', 0)),
192
+ "position_id": position_id,
193
+ "direction": direction,
194
+ "offset_flag": resp.get('offsetFlag', '0'),
195
+ "trade_time": resp.get('updateTime'),
196
+ }
197
+
198
+ trade_resp = None
199
+
200
+ async def _poll_orders(timeout_sec: float) -> dict | None:
201
+ nonlocal trade_resp
202
+ async with asyncio.timeout(timeout_sec):
203
+ while True:
204
+ trade_resp = await broker.query_order(order_id)
205
+ traded_volume = float(trade_resp.get("volume", 0))
206
+ if traded_volume == volume:
207
+ return
208
+ await asyncio.sleep(poll_interval)
209
+
213
210
  try:
214
- return await wait_order_state_poll(
215
- broker,
216
- order_id,
217
- symbol,
218
- window_sec,
219
- poll_interval=poll_interval,
220
- )
211
+ await _poll_orders(window_sec)
212
+
221
213
  except TimeoutError:
214
+ pass
215
+
216
+ for _attempt in range(3):
217
+ try:
218
+ await broker.cancel_order(order_id)
219
+ break
220
+ except Exception as e:
221
+ if '不存在' in str(e):
222
+ break
223
+ else:
224
+ print(f'撤单失败, 重试 {_attempt+1}/3: {e}')
225
+
222
226
  try:
223
- await broker.cancel_order(order_id)
224
- except Exception as exc:
225
- print(f"cancel failed: {exc}")
226
- try:
227
- return await wait_order_state_poll(
228
- broker,
229
- order_id,
230
- symbol,
231
- grace_sec,
232
- poll_interval=poll_interval,
233
- )
227
+ await _poll_orders(window_sec)
234
228
  except TimeoutError:
235
- return {"order_id": order_id, "symbol": symbol, "state": "timeout"}
229
+ pass
230
+
231
+ return trade_resp
236
232
 
237
233
 
238
234
  async def test_order_sync_polling():
239
235
  async with pybotters.Client(apis="./apis.json") as client:
240
236
  async with Lbank(client) as lb:
237
+ await lb.sub_orderbook(["SOLUSDT"], limit=1)
238
+ await lb.store.book.wait()
239
+ bid0 = float(lb.store.book.find({"s": "SOLUSDT", 'S': 'b'})[0]['p'])
240
+ bid0 = bid0 - 0.01
241
+ # bid0 = bid0 - 1
242
+ print(bid0)
243
+
241
244
  result = await order_sync_polling(
242
245
  lb,
243
246
  symbol="SOLUSDT",
244
247
  direction="buy",
245
- order_type="limit_gtc",
246
- price=200.1,
248
+ order_type="limit_GTC",
249
+ price=bid0,
247
250
  volume=0.03,
248
251
  window_sec=3.0,
249
- grace_sec=3.0,
250
- poll_interval=1.0,
252
+ grace_sec=1,
253
+ poll_interval=1
251
254
  )
252
255
  print(result)
253
256
 
257
+ async def test_query_order():
258
+ async with pybotters.Client(apis='./apis.json') as client:
259
+ async with Lbank(client) as lb:
260
+ res = await lb.query_order("1000633284579483")
261
+ print(res)
262
+
254
263
  if __name__ == "__main__":
255
264
  asyncio.run(test_order_sync_polling())
@@ -530,7 +530,7 @@ wheels = [
530
530
 
531
531
  [[package]]
532
532
  name = "hyperquant"
533
- version = "0.72"
533
+ version = "0.74"
534
534
  source = { editable = "." }
535
535
  dependencies = [
536
536
  { name = "aiohttp" },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes