hyperquant 0.46__py3-none-any.whl → 0.48__py3-none-any.whl

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.
@@ -605,17 +605,22 @@ class SpotOrders(DataStore):
605
605
 
606
606
 
607
607
  def _fmt(self, order: dict) -> dict:
608
- state = order.get("state")
609
- if state == 1 or state == 2:
610
- state = "open"
611
- elif state == 3:
612
- state = "filled"
613
- elif state == 4:
614
- state = "canceled"
608
+ # 状态映射:1=open, 2=filled(整单成交), 3=partially_filled, 4=canceled
609
+ state_num = order.get("state") or order.get("status")
610
+ if state_num == 1:
611
+ state_txt = "open"
612
+ elif state_num == 2:
613
+ state_txt = "filled" # ✔ 2 才是整单成交
614
+ elif state_num == 3:
615
+ state_txt = "partially_filled"
616
+ elif state_num == 4:
617
+ state_txt = "canceled"
618
+ else:
619
+ state_txt = "unknown"
615
620
 
616
621
  return {
617
- "order_id": order.get("id"),
618
- "symbol": order.get("symbol"),
622
+ "order_id": order.get("id") or order.get("orderId"),
623
+ "symbol": order.get("symbol") or order.get("s"),
619
624
  "currency": order.get("currency"),
620
625
  "market": order.get("market"),
621
626
  "trade_type": order.get("tradeType"),
@@ -626,8 +631,8 @@ class SpotOrders(DataStore):
626
631
  "deal_quantity": order.get("dealQuantity"),
627
632
  "deal_amount": order.get("dealAmount"),
628
633
  "avg_price": order.get("avgPrice"),
629
- "state": order.get("state"),
630
- "source": order.get("source"),
634
+ "state": state_txt,
635
+ "source": order.get("source") or order.get("internal"),
631
636
  "fee": order.get("fee"),
632
637
  "create_ts": order.get("createTime"),
633
638
  "unique_id": order.get("uniqueId"),
@@ -643,9 +648,9 @@ class SpotOrders(DataStore):
643
648
  self._insert(items)
644
649
 
645
650
  def _on_message(self, msg: dict[str, Any]) -> None:
646
- d:dict = msg.get("d", {})
651
+ d: dict = msg.get("d", {})
647
652
 
648
-
653
+ # 基础字段
649
654
  item = {
650
655
  "order_id": d.get("id"),
651
656
  "symbol": msg.get("s") or d.get("symbol"),
@@ -656,7 +661,6 @@ class SpotOrders(DataStore):
656
661
  "amount": d.get("amount"),
657
662
  "remain_quantity": d.get("remainQ"),
658
663
  "remain_amount": d.get("remainA"),
659
- "state": d.get("status"),
660
664
  "client_order_id": d.get("clientOrderId"),
661
665
  "is_taker": d.get("isTaker"),
662
666
  "create_ts": d.get("createTime"),
@@ -665,28 +669,70 @@ class SpotOrders(DataStore):
665
669
 
666
670
  state = d.get("status")
667
671
 
672
+ # 新建 / 已挂出
668
673
  if state == 1:
669
674
  item["state"] = "open"
670
675
  self._insert([item])
671
-
672
- elif state == 3 or state == 2:
673
- item["state"] = "filled"
674
-
675
- # 如果这三个字段存在追加
676
- if d.get("singleDealId") and d.get("singleDealPrice") and d.get("singleDealQuantity"):
677
- item.update({
678
- "unique_id": d.get("singleDealId"),
679
- "avg_price": d.get("singleDealPrice"),
680
- "deal_quantity": d.get("singleDealQuantity"),
681
- })
676
+ return
682
677
 
683
- self._update([item])
684
- self._find_and_delete({ "order_id": d.get("id") })
685
-
686
- elif state == 4:
678
+ # 成交片段(部分/完全)
679
+ if state in (2, 3):
680
+ # 单片段信息(可能多次推送;需做增量累计 + 去重)
681
+ single_id = d.get("singleDealId")
682
+ single_px = d.get("singleDealPrice")
683
+ single_qty = d.get("singleDealQuantity")
684
+ try:
685
+ px_i = float(single_px) if single_px is not None else 0.0
686
+ qty_i = float(single_qty) if single_qty is not None else 0.0
687
+ except Exception:
688
+ px_i, qty_i = 0.0, 0.0
689
+
690
+ old = self.get({"order_id": d.get("id")})
691
+ old_qty = float(old.get("deal_quantity") or 0.0) if old else 0.0
692
+ old_avg = float(old.get("avg_price") or 0.0) if old else 0.0
693
+ old_last_single = old.get("last_single_id") if old else None
694
+
695
+ # 去重:若与上一片段 ID 相同,认为是重复推送,直接按状态更新不累计
696
+ if old and single_id and old_last_single == single_id:
697
+ new_qty = old_qty
698
+ new_avg = old_avg
699
+ else:
700
+ # VWAP 累计
701
+ new_qty = old_qty + qty_i
702
+ if new_qty > 0:
703
+ new_avg = (old_avg * old_qty + px_i * qty_i) / new_qty
704
+ else:
705
+ new_avg = px_i
706
+
707
+ # 写回
708
+ item.update({
709
+ "avg_price": str(new_avg) if new_qty > 0 else old.get("avg_price") if old else None,
710
+ "deal_quantity": str(new_qty) if new_qty > 0 else old.get("deal_quantity") if old else None,
711
+ "single_id": single_id,
712
+ "last_single_id": single_id,
713
+ })
714
+
715
+ # 状态文本:2=filled(整单), 3=partially_filled
716
+ item["state"] = "filled" if state == 2 else "partially_filled"
717
+
718
+ self._update([item])
719
+
720
+ # 整单成交 → 删除
721
+ if state == 2:
722
+ self._find_and_delete({"order_id": d.get("id")})
723
+ return
724
+
725
+ # 撤单
726
+ if state == 4:
687
727
  item["state"] = "canceled"
688
728
  self._update([item])
689
- self._find_and_delete({ "order_id": d.get("id") })
729
+ self._find_and_delete({"order_id": d.get("id")})
730
+ return
731
+
732
+ # 未知状态:更新后删除,避免脏数据残留
733
+ item["state"] = "unknown"
734
+ self._update([item])
735
+ self._find_and_delete({"order_id": d.get("id")})
690
736
 
691
737
 
692
738
 
@@ -786,7 +832,7 @@ class SpotBook(DataStore):
786
832
  )
787
833
 
788
834
  if not check_con:
789
- logger.warning(f"(丢补丁) version:{now_version} fv:{fv} tv:{tv} ")
835
+ # logger.warning(f"(丢补丁) version:{now_version} fv:{fv} tv:{tv} ")
790
836
  self.loss[symbol] = True # 暂时不这样做
791
837
 
792
838
 
@@ -26,7 +26,8 @@ class OurbitSwap:
26
26
  return self
27
27
 
28
28
  async def update(
29
- self, update_type: Literal["position", "orders", "balance", "ticker", "all"] = "all"
29
+ self,
30
+ update_type: Literal["position", "orders", "balance", "ticker", "all"] = "all",
30
31
  ):
31
32
  """由于交易所很多不支持ws推送,这里使用Rest"""
32
33
  all_urls = [
@@ -34,7 +35,7 @@ class OurbitSwap:
34
35
  f"{self.api_url}/api/v1/private/order/list/open_orders?page_size=200",
35
36
  f"{self.api_url}/api/v1/private/account/assets",
36
37
  f"{self.api_url}/api/v1/contract/ticker",
37
- f"{self.api_url}/api/platform/spot/market/v2/symbols"
38
+ f"{self.api_url}/api/platform/spot/market/v2/symbols",
38
39
  ]
39
40
 
40
41
  url_map = {
@@ -56,13 +57,8 @@ class OurbitSwap:
56
57
  async def sub_tickers(self):
57
58
  self.client.ws_connect(
58
59
  self.ws_url,
59
- send_json={
60
- "method": "sub.tickers",
61
- "param": {
62
- "timezone": "UTC+8"
63
- }
64
- },
65
- hdlr_json=self.store.onmessage
60
+ send_json={"method": "sub.tickers", "param": {"timezone": "UTC+8"}},
61
+ hdlr_json=self.store.onmessage,
66
62
  )
67
63
 
68
64
  async def sub_orderbook(self, symbols: str | list[str]):
@@ -74,26 +70,23 @@ class OurbitSwap:
74
70
 
75
71
  for symbol in symbols:
76
72
  step = self.store.detail.find({"symbol": symbol})[0].get("tick_size")
77
-
78
- send_jsons.append({
79
- "method": "sub.depth.step",
80
- "param": {
81
- "symbol": symbol,
82
- "step": str(step)
73
+
74
+ send_jsons.append(
75
+ {
76
+ "method": "sub.depth.step",
77
+ "param": {"symbol": symbol, "step": str(step)},
83
78
  }
84
- })
79
+ )
85
80
 
86
81
  await self.client.ws_connect(
87
- self.ws_url,
88
- send_json=send_jsons,
89
- hdlr_json=self.store.onmessage
82
+ self.ws_url, send_json=send_jsons, hdlr_json=self.store.onmessage
90
83
  )
91
84
 
92
85
  async def sub_personal(self):
93
86
  self.client.ws_connect(
94
87
  self.ws_url,
95
- send_json={ "method": "sub.personal.user.preference"},
96
- hdlr_json=self.store.onmessage
88
+ send_json={"method": "sub.personal.user.preference"},
89
+ hdlr_json=self.store.onmessage,
97
90
  )
98
91
 
99
92
  def ret_content(self, res: pybotters.FetchResult):
@@ -102,13 +95,15 @@ class OurbitSwap:
102
95
  return res.data["data"]
103
96
  case _:
104
97
  raise Exception(f"Failed api {res.response.url}: {res.data}")
105
-
106
98
 
107
99
  def fmt_price(self, symbol, price: float) -> float:
108
100
  tick = self.store.detail.find({"symbol": symbol})[0].get("tick_size")
109
101
  tick_dec = Decimal(str(tick))
110
102
  price_dec = Decimal(str(price))
111
- return float((price_dec / tick_dec).quantize(Decimal("1"), rounding=ROUND_HALF_UP) * tick_dec)
103
+ return float(
104
+ (price_dec / tick_dec).quantize(Decimal("1"), rounding=ROUND_HALF_UP)
105
+ * tick_dec
106
+ )
112
107
 
113
108
  async def place_order(
114
109
  self,
@@ -135,14 +130,13 @@ class OurbitSwap:
135
130
  raise ValueError("params err")
136
131
 
137
132
  max_lev = self.store.detail.find({"symbol": symbol})[0].get("max_lev")
138
-
133
+
139
134
  if usdt_amount is not None:
140
135
  cs = self.store.detail.find({"symbol": symbol})[0].get("contract_sz")
141
136
  size = max(int(usdt_amount / cs / price), 1)
142
137
 
143
138
  if price is not None:
144
139
  price = self.fmt_price(symbol, price)
145
-
146
140
 
147
141
  leverage = min(max_lev, leverage)
148
142
 
@@ -165,22 +159,23 @@ class OurbitSwap:
165
159
  data["price"] = str(price)
166
160
 
167
161
  if "close" in side:
168
- if side == 'close_buy':
162
+ if side == "close_buy":
169
163
  data["side"] = 2
170
- elif side == 'close_sell':
164
+ elif side == "close_sell":
171
165
  data["side"] = 4
172
-
166
+
173
167
  if position_id is None:
174
168
  raise ValueError("position_id is required for closing position")
175
169
  data["positionId"] = position_id
176
170
  # import time
177
171
  # print(time.time(), '下单')
178
- res = await self.client.fetch(
172
+ res = await self.client.fetch(
179
173
  "POST", f"{self.api_url}/api/v1/private/order/create", data=data
180
174
  )
181
175
  return self.ret_content(res)
182
-
183
- async def place_tpsl(self,
176
+
177
+ async def place_tpsl(
178
+ self,
184
179
  position_id: int,
185
180
  take_profit: Optional[float] = None,
186
181
  stop_loss: Optional[float] = None,
@@ -214,12 +209,9 @@ class OurbitSwap:
214
209
  data["takeProfitPrice"] = take_profit
215
210
  if stop_loss is not None:
216
211
  data["stopLossPrice"] = stop_loss
217
-
218
212
 
219
213
  res = await self.client.fetch(
220
- "POST",
221
- f"{self.api_url}/api/v1/private/stoporder/place",
222
- data=data
214
+ "POST", f"{self.api_url}/api/v1/private/stoporder/place", data=data
223
215
  )
224
216
 
225
217
  return self.ret_content(res)
@@ -312,7 +304,7 @@ class OurbitSwap:
312
304
 
313
305
  class OurbitSpot:
314
306
 
315
- def __init__(self, client: pybotters.Client):
307
+ def __init__(self, client: pybotters.Client, personal_msg_cb: callable=None):
316
308
  """
317
309
  ✅ 完成:
318
310
  下单, 撤单, 查询资金, 查询持有订单, 查询历史订单
@@ -322,6 +314,7 @@ class OurbitSpot:
322
314
  self.store = OurbitSpotDataStore()
323
315
  self.api_url = "https://www.ourbit.com"
324
316
  self.ws_url = "wss://www.ourbit.com/ws"
317
+ self.personal_msg_cb = personal_msg_cb
325
318
 
326
319
  async def __aenter__(self) -> "OurbitSpot":
327
320
  client = self.client
@@ -330,41 +323,39 @@ class OurbitSpot:
330
323
  )
331
324
  return self
332
325
 
333
- async def update(self, update_type: Literal["orders", "balance", "ticker", "book", "all"] = "all"):
326
+ async def update(
327
+ self, update_type: Literal["orders", "balance", "ticker", "book", "all"] = "all"
328
+ ):
334
329
 
335
330
  all_urls = [
336
331
  f"{self.api_url}/api/platform/spot/order/current/orders/v2?orderTypes=1%2C2%2C3%2C4%2C5%2C100&pageNum=1&pageSize=100&states=0%2C1%2C3",
337
332
  f"{self.api_url}/api/assetbussiness/asset/spot/statistic",
338
- f"{self.api_url}/api/platform/spot/market/v2/tickers"
333
+ f"{self.api_url}/api/platform/spot/market/v2/tickers",
339
334
  ]
340
335
 
341
336
  # orderTypes=1%2C2%2C3%2C4%2C5%2C100&pageNum=1&pageSize=100&states=0%2C1%2C3
342
-
337
+
343
338
  url_map = {
344
339
  "orders": [all_urls[0]],
345
340
  "balance": [all_urls[1]],
346
341
  "ticker": [all_urls[2]],
347
- "all": all_urls
342
+ "all": all_urls,
348
343
  }
349
344
 
350
345
  try:
351
346
  urls = url_map[update_type]
352
347
  except KeyError:
353
348
  raise ValueError(f"Unknown update type: {update_type}")
354
-
349
+
355
350
  # 直接传协程进去,initialize 会自己 await
356
351
  await self.store.initialize(*(self.client.get(url) for url in urls))
357
352
 
358
-
359
353
  async def sub_personal(self):
360
354
  """订阅个人频道"""
361
355
  # https://www.ourbit.com/ucenter/api/ws_token
362
- res = await self.client.fetch(
363
- 'GET', f"{self.api_url}/ucenter/api/ws_token"
364
- )
365
-
366
- token = res.data['data'].get("wsToken")
356
+ res = await self.client.fetch("GET", f"{self.api_url}/ucenter/api/ws_token")
367
357
 
358
+ token = res.data["data"].get("wsToken")
368
359
 
369
360
  app = self.client.ws_connect(
370
361
  f"{self.ws_url}?wsToken={token}&platform=web",
@@ -373,23 +364,27 @@ class OurbitSpot:
373
364
  "params": [
374
365
  "spot@private.orders",
375
366
  "spot@private.trigger.orders",
376
- "spot@private.balances"
367
+ "spot@private.balances",
377
368
  ],
378
- "id": 1
369
+ "id": 1,
379
370
  },
380
- hdlr_json=self.store.onmessage
371
+ hdlr_json=(
372
+ self.store.onmessage
373
+ if self.personal_msg_cb is None
374
+ else [self.store.onmessage, self.personal_msg_cb]
375
+ ),
381
376
  )
382
377
 
383
378
  await app._event.wait()
384
-
385
379
 
386
380
  async def sub_orderbook(self, symbols: str | list[str]):
387
381
  """订阅订单簿深度数据
388
-
382
+
389
383
  Args:
390
384
  symbols: 交易对符号,可以是单个字符串或字符串列表
391
385
  """
392
386
  import logging
387
+
393
388
  logger = logging.getLogger("OurbitSpot")
394
389
 
395
390
  if isinstance(symbols, str):
@@ -403,27 +398,29 @@ class OurbitSpot:
403
398
  # 一次sub20个,超过需要分开订阅
404
399
  for i in range(0, len(subscription_params), 20):
405
400
  wsapp = self.client.ws_connect(
406
- 'wss://www.ourbit.com/ws?platform=web',
401
+ "wss://www.ourbit.com/ws?platform=web",
407
402
  send_json={
408
403
  "method": "SUBSCRIPTION",
409
- "params": subscription_params[i:i + 20],
410
- "id": 2
404
+ "params": subscription_params[i : i + 20],
405
+ "id": 2,
411
406
  },
412
- hdlr_json=self.store.onmessage
407
+ hdlr_json=self.store.onmessage,
413
408
  )
414
409
  await wsapp._event.wait()
415
-
410
+
416
411
  # await asyncio.sleep(1) # 等待ws连接稳定
417
412
 
418
413
  # 并发获取每个交易对的初始深度数据
419
414
  tasks = [
420
- self.client.fetch('GET', f"{self.api_url}/api/platform/spot/market/depth?symbol={symbol}")
415
+ self.client.fetch(
416
+ "GET", f"{self.api_url}/api/platform/spot/market/depth?symbol={symbol}"
417
+ )
421
418
  for symbol in symbols
422
419
  ]
423
-
420
+
424
421
  # 等待所有请求完成
425
422
  responses = await asyncio.gather(*tasks)
426
-
423
+
427
424
  # 处理响应数据
428
425
  for idx, response in enumerate(responses):
429
426
  symbol = symbols[idx]
@@ -435,13 +432,15 @@ class OurbitSpot:
435
432
  loss = self.store.book.loss
436
433
  for symbol, is_loss in loss.items():
437
434
  if is_loss:
438
- resp = await self.client.fetch('GET', f"{self.api_url}/api/platform/spot/market/depth?symbol={symbol}")
435
+ resp = await self.client.fetch(
436
+ "GET",
437
+ f"{self.api_url}/api/platform/spot/market/depth?symbol={symbol}",
438
+ )
439
439
  self.store.book._onresponse(resp.data)
440
440
  await asyncio.sleep(1)
441
441
 
442
442
  asyncio.create_task(check_loss())
443
443
 
444
-
445
444
  async def place_order(
446
445
  self,
447
446
  symbol: str,
@@ -449,10 +448,10 @@ class OurbitSpot:
449
448
  price: float = None,
450
449
  quantity: float = None,
451
450
  order_type: Literal["market", "limit"] = "limit",
452
- usdt_amount: float = None
451
+ usdt_amount: float = None,
453
452
  ):
454
453
  """现货下单
455
-
454
+
456
455
  Args:
457
456
  symbol: 交易对,如 "SOL_USDT"
458
457
  side: 买卖方向 "buy" 或 "sell"
@@ -460,7 +459,7 @@ class OurbitSpot:
460
459
  quantity: 数量
461
460
  order_type: 订单类型 "market" 或 "limit"
462
461
  usdt_amount: USDT金额,如果指定则根据价格计算数量
463
-
462
+
464
463
  Returns:
465
464
  订单响应数据
466
465
  """
@@ -469,45 +468,43 @@ class OurbitSpot:
469
468
  raise ValueError("Limit orders require a price")
470
469
  if quantity is None and usdt_amount is None:
471
470
  raise ValueError("Either quantity or usdt_amount must be specified")
472
-
471
+
473
472
  # 解析交易对
474
473
  parts = symbol.split("_")
475
474
  if len(parts) != 2:
476
475
  raise ValueError(f"Invalid symbol format: {symbol}")
477
-
476
+
478
477
  currency, market = parts
479
-
478
+
480
479
  # 获取交易对详情
481
480
  detail = self.store.detail.get({"name": currency})
482
481
  if not detail:
483
482
  raise ValueError(f"Unknown currency: {currency}")
484
-
483
+
485
484
  price_scale = detail.get("price_scale")
486
485
  quantity_scale = detail.get("quantity_scale")
487
-
486
+
488
487
  # 构建请求数据
489
- data = {
490
- "currency": currency,
491
- "market": market,
492
- "tradeType": side.upper()
493
- }
494
-
488
+ data = {"currency": currency, "market": market, "tradeType": side.upper()}
489
+
495
490
  # 处理市价单和限价单的不同参数
496
491
  if order_type == "limit":
497
492
  data["orderType"] = "LIMIT_ORDER"
498
- data["price"] = str(round(price, price_scale) if price_scale is not None else price)
499
-
493
+ data["price"] = str(
494
+ round(price, price_scale) if price_scale is not None else price
495
+ )
496
+
500
497
  # 计算并设置数量
501
498
  if quantity is None and usdt_amount is not None and price:
502
499
  quantity = usdt_amount / price
503
-
500
+
504
501
  if quantity_scale is not None:
505
502
  quantity = round(quantity, quantity_scale)
506
503
  data["quantity"] = str(quantity)
507
-
504
+
508
505
  elif order_type == "market":
509
506
  data["orderType"] = "MARKET_ORDER"
510
-
507
+
511
508
  # 市价单可以使用数量或金额,但不能同时使用
512
509
  if usdt_amount is not None:
513
510
  data["amount"] = str(usdt_amount)
@@ -515,23 +512,29 @@ class OurbitSpot:
515
512
  if quantity_scale is not None:
516
513
  quantity = round(quantity, quantity_scale)
517
514
  data["quantity"] = str(quantity)
518
-
515
+
519
516
  if price:
520
517
  data["price"] = str(price)
521
-
518
+
522
519
  # 确定API端点
523
520
  url = f'{self.api_url}/api/platform/spot/{"v4/order/place" if order_type == "market" else "order/place"}'
524
-
521
+ print(f"Placing {symbol}: {data}")
525
522
  # 发送请求
526
523
  res = await self.client.fetch("POST", url, json=data)
527
-
524
+
528
525
  # 处理响应
529
526
  if res.data.get("msg") == "success":
530
527
  return res.data["data"]
531
528
  raise Exception(f"Failed to place order: {res.data}")
532
-
529
+
533
530
  async def cancel_orders(self, order_ids: list[str]):
534
531
 
535
532
  for order_id in order_ids:
536
- url = f'{self.api_url}/api/platform/spot/order/cancel/v2?orderId={order_id}'
537
- await self.client.fetch("DELETE", url)
533
+ url = f"{self.api_url}/api/platform/spot/order/cancel/v2?orderId={order_id}"
534
+ await self.client.fetch("DELETE", url)
535
+
536
+ async def cancel_order(self, order_id: str):
537
+
538
+ url = f"{self.api_url}/api/platform/spot/order/cancel/v2?orderId={order_id}"
539
+ res = await self.client.fetch("DELETE", url)
540
+ print(res.data)
hyperquant/logkit.py CHANGED
@@ -146,10 +146,25 @@ class MinConsoleHandler(logging.StreamHandler):
146
146
  else:
147
147
  super().emit(record)
148
148
 
149
+ # ====================================================================================================
150
+ # ** NullLogger 类,用于禁用日志 **
151
+ # ====================================================================================================
152
+ class NullLogger:
153
+ def debug(self, *a, **k): pass
154
+ def info(self, *a, **k): pass
155
+ def ok(self, *a, **k): pass
156
+ def warning(self, *a, **k): pass
157
+ def error(self, *a, **k): pass
158
+ def critical(self, *a, **k): pass
159
+ def exception(self, *a, **k): pass
160
+ def divider(self, *a, **k): pass
161
+
149
162
  # ====================================================================================================
150
163
  # ** 功能函数 **
151
164
  # ====================================================================================================
152
- def get_logger(name=None, file_path=None, show_time=False, use_color=True, timezone="Asia/Shanghai") -> Logger:
165
+ def get_logger(name=None, file_path=None, show_time=False, use_color=True, timezone="Asia/Shanghai", level: object = None, enable_console: bool = True, enabled: bool = True):
166
+ if not enabled:
167
+ return NullLogger()
153
168
  if name is None:
154
169
  name = '_'
155
170
  logger_instance = Logger(name, show_time, use_color, timezone) # 传递时区参数
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hyperquant
3
- Version: 0.46
3
+ Version: 0.48
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
@@ -2,20 +2,20 @@ hyperquant/__init__.py,sha256=UpjiX4LS5jmrBc2kE8RiLR02eCfD8JDQrR1q8zkLNcQ,161
2
2
  hyperquant/core.py,sha256=iEI8qTNpyesB_w67SrKXeGoB9JllovBeJKI0EZFYew4,20631
3
3
  hyperquant/db.py,sha256=i2TjkCbmH4Uxo7UTDvOYBfy973gLcGexdzuT_YcSeIE,6678
4
4
  hyperquant/draw.py,sha256=up_lQ3pHeVLoNOyh9vPjgNwjD0M-6_IetSGviQUgjhY,54624
5
- hyperquant/logkit.py,sha256=WALpXpIA3Ywr5DxKKK3k5EKubZ2h-ISGfc5dUReQUBQ,7795
5
+ hyperquant/logkit.py,sha256=nUo7nx5eONvK39GOhWwS41zNRL756P2J7-5xGzwXnTY,8462
6
6
  hyperquant/notikit.py,sha256=x5yAZ_tAvLQRXcRbcg-VabCaN45LUhvlTZnUqkIqfAA,3596
7
7
  hyperquant/broker/auth.py,sha256=oA9Yw1I59-u0Tnoj2e4wUup5q8V5T2qpga5RKbiAiZI,2614
8
8
  hyperquant/broker/hyperliquid.py,sha256=7MxbI9OyIBcImDelPJu-8Nd53WXjxPB5TwE6gsjHbto,23252
9
- hyperquant/broker/ourbit.py,sha256=yQyjkAYuz6-HhVYJ17SNvopiL-CNN7pSTpKW8h4lzHs,17730
9
+ hyperquant/broker/ourbit.py,sha256=50pmapIscWi7vwIjvWY3m3j9wVgrFjK-fZWeFGSxkT4,17924
10
10
  hyperquant/broker/ws.py,sha256=umRzxwCaZaRIgIq4YY-AuA0wCXFT0uOBmQbIXFY8CK0,1555
11
11
  hyperquant/broker/lib/hpstore.py,sha256=LnLK2zmnwVvhEbLzYI-jz_SfYpO1Dv2u2cJaRAb84D8,8296
12
12
  hyperquant/broker/lib/hyper_types.py,sha256=HqjjzjUekldjEeVn6hxiWA8nevAViC2xHADOzDz9qyw,991
13
13
  hyperquant/broker/models/hyperliquid.py,sha256=c4r5739ibZfnk69RxPjQl902AVuUOwT8RNvKsMtwXBY,9459
14
- hyperquant/broker/models/ourbit.py,sha256=aBmc6H1VZ2VZfn6JJGzlsnbc--Tw1dDcUmi2s5YYRJM,39580
14
+ hyperquant/broker/models/ourbit.py,sha256=rFJEFwzTravStHsB0kEwP5YhI2EQsn79Vv7aEiCIWLc,41585
15
15
  hyperquant/datavison/_util.py,sha256=92qk4vO856RqycO0YqEIHJlEg-W9XKapDVqAMxe6rbw,533
16
16
  hyperquant/datavison/binance.py,sha256=3yNKTqvt_vUQcxzeX4ocMsI5k6Q6gLZrvgXxAEad6Kc,5001
17
17
  hyperquant/datavison/coinglass.py,sha256=PEjdjISP9QUKD_xzXNzhJ9WFDTlkBrRQlVL-5pxD5mo,10482
18
18
  hyperquant/datavison/okx.py,sha256=yg8WrdQ7wgWHNAInIgsWPM47N3Wkfr253169IPAycAY,6898
19
- hyperquant-0.46.dist-info/METADATA,sha256=pa_Mm81myuL2GMcSqwm42hdcF7T-srQAsJrng7fHH1A,4317
20
- hyperquant-0.46.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
21
- hyperquant-0.46.dist-info/RECORD,,
19
+ hyperquant-0.48.dist-info/METADATA,sha256=G1KErGZNZ7Cx8-S35chKSAhKvPKDcpE1Z2DvWlqHJuE,4317
20
+ hyperquant-0.48.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
21
+ hyperquant-0.48.dist-info/RECORD,,