hyperquant 0.41__tar.gz → 0.43__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 (32) hide show
  1. {hyperquant-0.41 → hyperquant-0.43}/PKG-INFO +1 -1
  2. {hyperquant-0.41 → hyperquant-0.43}/pyproject.toml +1 -1
  3. {hyperquant-0.41 → hyperquant-0.43}/src/hyperquant/broker/models/ourbit.py +6 -3
  4. {hyperquant-0.41 → hyperquant-0.43}/src/hyperquant/core.py +10 -6
  5. hyperquant-0.43/test.py +55 -0
  6. {hyperquant-0.41 → hyperquant-0.43}/tmp.py +23 -30
  7. {hyperquant-0.41 → hyperquant-0.43}/uv.lock +1 -1
  8. hyperquant-0.41/test.py +0 -120
  9. hyperquant-0.41/tmp2.py +0 -32
  10. {hyperquant-0.41 → hyperquant-0.43}/.gitignore +0 -0
  11. {hyperquant-0.41 → hyperquant-0.43}/.python-version +0 -0
  12. {hyperquant-0.41 → hyperquant-0.43}/README.md +0 -0
  13. {hyperquant-0.41 → hyperquant-0.43}/data/logs/notikit.log +0 -0
  14. {hyperquant-0.41 → hyperquant-0.43}/pub.sh +0 -0
  15. {hyperquant-0.41 → hyperquant-0.43}/requirements-dev.lock +0 -0
  16. {hyperquant-0.41 → hyperquant-0.43}/requirements.lock +0 -0
  17. {hyperquant-0.41 → hyperquant-0.43}/src/hyperquant/__init__.py +0 -0
  18. {hyperquant-0.41 → hyperquant-0.43}/src/hyperquant/broker/auth.py +0 -0
  19. {hyperquant-0.41 → hyperquant-0.43}/src/hyperquant/broker/hyperliquid.py +0 -0
  20. {hyperquant-0.41 → hyperquant-0.43}/src/hyperquant/broker/lib/hpstore.py +0 -0
  21. {hyperquant-0.41 → hyperquant-0.43}/src/hyperquant/broker/lib/hyper_types.py +0 -0
  22. {hyperquant-0.41 → hyperquant-0.43}/src/hyperquant/broker/models/hyperliquid.py +0 -0
  23. {hyperquant-0.41 → hyperquant-0.43}/src/hyperquant/broker/ourbit.py +0 -0
  24. {hyperquant-0.41 → hyperquant-0.43}/src/hyperquant/broker/ws.py +0 -0
  25. {hyperquant-0.41 → hyperquant-0.43}/src/hyperquant/datavison/_util.py +0 -0
  26. {hyperquant-0.41 → hyperquant-0.43}/src/hyperquant/datavison/binance.py +0 -0
  27. {hyperquant-0.41 → hyperquant-0.43}/src/hyperquant/datavison/coinglass.py +0 -0
  28. {hyperquant-0.41 → hyperquant-0.43}/src/hyperquant/datavison/okx.py +0 -0
  29. {hyperquant-0.41 → hyperquant-0.43}/src/hyperquant/db.py +0 -0
  30. {hyperquant-0.41 → hyperquant-0.43}/src/hyperquant/draw.py +0 -0
  31. {hyperquant-0.41 → hyperquant-0.43}/src/hyperquant/logkit.py +0 -0
  32. {hyperquant-0.41 → hyperquant-0.43}/src/hyperquant/notikit.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hyperquant
3
- Version: 0.41
3
+ Version: 0.43
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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "hyperquant"
3
- version = "0.41"
3
+ version = "0.43"
4
4
  description = "A minimal yet hyper-efficient backtesting framework for quantitative trading"
5
5
  authors = [
6
6
  { name = "MissinA", email = "1421329142@qq.com" }
@@ -592,7 +592,11 @@ class SpotBalance(DataStore):
592
592
  def _on_message(self, msg: dict[str, Any]) -> None:
593
593
  data = msg.get("d", {})
594
594
  item = self._fmt_ws(data)
595
- self._update([item])
595
+ av = float(item.get("available", 0))
596
+ if av == 0:
597
+ self._find_and_delete({'currency': item.get("currency")})
598
+ else:
599
+ self._update([item])
596
600
 
597
601
 
598
602
  # SpotOrders: 现货订单数据存储
@@ -929,8 +933,7 @@ class OurbitSpotDataStore(DataStoreCollection):
929
933
  """
930
934
  现货账户余额数据流
931
935
 
932
- Data structure:
933
-
936
+ _KEYS = ["currency"]
934
937
  .. code:: python
935
938
 
936
939
  [
@@ -269,10 +269,10 @@ class ExchangeBase:
269
269
  )
270
270
 
271
271
  class Exchange(ExchangeBase):
272
- def __init__(self, trade_symbols, fee=0.0002, initial_balance=10000, recorded=False):
272
+ def __init__(self, trade_symbols:list=[], fee=0.0002, initial_balance=10000, recorded=False):
273
273
  super().__init__(initial_balance=initial_balance, recorded=recorded)
274
274
  self.fee = fee
275
- self.trade_symbols = trade_symbols
275
+ self.trade_symbols:list = trade_symbols
276
276
  self.id_gen = 0
277
277
  self.account['USDT'].update({
278
278
  'hold': 0,
@@ -280,8 +280,12 @@ class Exchange(ExchangeBase):
280
280
  'short': 0
281
281
  })
282
282
  for symbol in trade_symbols:
283
- self.account[symbol] = {'amount': 0, 'hold_price': 0, 'value': 0, 'price': 0,
284
- 'realised_profit': 0, 'unrealised_profit': 0, 'fee': 0}
283
+ self.account[symbol] = self._act_template
284
+
285
+ @property
286
+ def _act_template(self):
287
+ return {'amount': 0, 'hold_price': 0, 'value': 0, 'price': 0,
288
+ 'realised_profit': 0, 'unrealised_profit': 0, 'fee': 0}.copy()
285
289
 
286
290
  def Trade(self, symbol, direction, price, amount, **kwargs):
287
291
  if self.recorded and 'time' not in kwargs:
@@ -307,8 +311,7 @@ class Exchange(ExchangeBase):
307
311
 
308
312
  if symbol not in self.trade_symbols:
309
313
  self.trade_symbols.append(symbol)
310
- self.account[symbol] = {'amount': 0, 'hold_price': 0, 'value': 0, 'price': 0,
311
- 'realised_profit': 0, 'unrealised_profit': 0, 'fee': 0}
314
+ self.account[symbol] = self._act_template
312
315
 
313
316
  cover_amount = 0 if direction * self.account[symbol]['amount'] >= 0 else min(abs(self.account[symbol]['amount']), amount)
314
317
  open_amount = amount - cover_amount
@@ -343,6 +346,7 @@ class Exchange(ExchangeBase):
343
346
 
344
347
  if kwargs:
345
348
  self.opt.update(kwargs)
349
+ self.account[symbol].update(kwargs)
346
350
 
347
351
  # 记录账户总资产到 history
348
352
  if self.recorded:
@@ -0,0 +1,55 @@
1
+ import asyncio
2
+ import random
3
+ import time
4
+ import pybotters
5
+ import hyperquant
6
+ from hyperquant.broker.models.ourbit import OurbitSpotDataStore
7
+ from hyperquant.broker.ourbit import OurbitSpot
8
+ from hyperquant.core import Exchange
9
+
10
+
11
+ async def main():
12
+ store = OurbitSpotDataStore()
13
+
14
+ async with pybotters.Client(
15
+ apis={
16
+ "ourbit": [
17
+ "WEB3bf088f8b2f2fae07592fe1a6240e2d798100a9cb2a91f8fda1056b6865ab3ee"
18
+ ]
19
+ }
20
+ ) as client:
21
+ res = await client.fetch("POST", "https://www.ourbit.com/ucenter/api/user_info")
22
+
23
+ ob_spot = OurbitSpot(client)
24
+ await ob_spot.__aenter__()
25
+ await ob_spot.update('balance')
26
+
27
+ e = Exchange([], fee=0, initial_balance=0)
28
+
29
+ print(ob_spot.store.balance.find())
30
+
31
+ for info in ob_spot.store.balance.find():
32
+ coin = info['currency']
33
+ if info['currency'] == 'USDT':
34
+ e.account['USDT']['total'] = float(info['available'])
35
+ else:
36
+ if coin not in e.account:
37
+ e.account[coin] = e._act_template
38
+ e.account[coin]['amount'] = float(info['available'])
39
+ e.account[coin]['hold_price'] = float(info['avg_price'])
40
+ e.account[coin]['price'] = float(info['avg_price'])
41
+ e.account[coin]['value'] = float(info['avg_price']) * float(info['available'])
42
+
43
+ # "amount": 1,
44
+ # "hold_price": 1000.0,
45
+ # "value": 1000.0,
46
+ # "price": 1000.0,
47
+ print(e.account)
48
+
49
+
50
+ asyncio.run(main())
51
+ # e = Exchange([], fee=0)
52
+ # e.Buy('btc', 1000, 1)
53
+ # e.Update({'btc':1500})
54
+ # print(e.account)
55
+ # print(e.available_margin)
@@ -21,29 +21,31 @@ async def main():
21
21
 
22
22
  ob_spot = OurbitSpot(client)
23
23
  await ob_spot.__aenter__()
24
- # await ob_spot.sub_personal()
24
+ await ob_spot.sub_personal()
25
25
  # await ob_spot.update('ticker')
26
26
  # print(ob_spot.store.ticker.find())
27
27
 
28
28
  # await ob_spot.sub_orderbook('DOLO_USDT')
29
29
  # print(ob_spot.store.book.find())
30
- await ob_spot.update('ticker')
31
- symbols = [d['symbol'] for d in ob_spot.store.ticker.find()][:5]
30
+ await ob_spot.update('balance')
31
+ # symbols = [d['symbol'] for d in ob_spot.store.ticker.find()][:5]
32
32
 
33
- await ob_spot.sub_orderbook(symbols)
33
+ # await ob_spot.sub_orderbook(symbols)
34
34
 
35
- # print(len(ob_spot.store.book.find()))
36
- import pandas as pd
37
- print(pd.DataFrame(ob_spot.store.book.find({'S': 'a'})))
35
+ # # print(len(ob_spot.store.book.find()))
36
+ # import pandas as pd
37
+ # print(pd.DataFrame(ob_spot.store.book.find({'S': 'a'})))
38
38
 
39
39
 
40
- while True:
41
- await ob_spot.store.book.wait()
42
- print(len(ob_spot.store.book.find()))
43
-
44
40
  # while True:
45
- # await ob_spot.store.balance.wait()
46
- # print(ob_spot.store.balance.find())
41
+ # await ob_spot.store.book.wait()
42
+ # print(len(ob_spot.store.book.find()))
43
+
44
+
45
+ while True:
46
+ await ob_spot.store.balance.wait()
47
+ print(ob_spot.store.balance.find())
48
+
47
49
  return
48
50
 
49
51
  await store.initialize(
@@ -83,21 +85,12 @@ async def main():
83
85
  # print(f'排序耗时: {time.time()*1000 - ts:.2f} ms')
84
86
 
85
87
  async def test_watch_order():
86
- store = OurbitSpotDataStore()
87
88
 
88
- filled_orders = {}
89
-
90
- async def loop_orders():
91
- with ob_spot.store.orders.watch() as stream:
92
- async for change in stream:
93
- if change.operation == 'delete':
94
- if change.data['state'] == 'filled':
95
- filled_orders[change.data['order_id']] = change.data
96
89
 
97
90
  async def watch_orders(ob_spot: OurbitSpot):
98
91
  with ob_spot.store.orders.watch() as stream:
99
92
  async for change in stream:
100
- print(change)
93
+
101
94
  data = change.data
102
95
  if change.operation == 'delete':
103
96
  state = data['state']
@@ -116,13 +109,13 @@ async def test_watch_order():
116
109
  ob_spot = OurbitSpot(client)
117
110
  await ob_spot.__aenter__()
118
111
  await ob_spot.sub_personal()
119
- # await watch_orders(ob_spot)
112
+ await watch_orders(ob_spot)
120
113
 
121
- with ob_spot.store.orders.watch() as stream:
122
- oid = await ob_spot.place_order('SOL_USDT', 'buy', order_type='market', price=205, quantity=0.03 )
123
- print(oid)
124
- async for change in stream:
125
- print(change)
114
+ # with ob_spot.store.orders.watch() as stream:
115
+ # oid = await ob_spot.place_order('SOL_USDT', 'buy', order_type='market', price=205, quantity=0.03 )
116
+ # print(oid)
117
+ # async for change in stream:
118
+ # print(change)
126
119
 
127
120
 
128
121
  # await asyncio.sleep(1)
@@ -145,4 +138,4 @@ async def test_cancel_order():
145
138
  await ob_spot.cancel_orders([oid])
146
139
 
147
140
  if __name__ == "__main__":
148
- asyncio.run(test_cancel_order())
141
+ asyncio.run(main())
@@ -530,7 +530,7 @@ wheels = [
530
530
 
531
531
  [[package]]
532
532
  name = "hyperquant"
533
- version = "0.4"
533
+ version = "0.42"
534
534
  source = { editable = "." }
535
535
  dependencies = [
536
536
  { name = "aiohttp" },
hyperquant-0.41/test.py DELETED
@@ -1,120 +0,0 @@
1
- # import asyncio
2
- # import hyperquant
3
- # from hyperquant.broker.models.ourbit import OurbitSwapDataStore
4
- # import pybotters
5
-
6
- # async def test():
7
- # store = OurbitSwapDataStore()
8
- # async with pybotters.Client(
9
- # apis={
10
- # "ourbit": [
11
- # "WEB3bf088f8b2f2fae07592fe1a6240e2d798100a9cb2a91f8fda1056b6865ab3ee"
12
- # ]
13
- # }
14
- # ) as client:
15
- # await store.initialize( client.get( "https://futures.ourbit.com/api/v1/private/position/open_positions") )
16
- # print(store.position.find())
17
-
18
- # if __name__ == "__main__":
19
- # asyncio.run(test())
20
-
21
- import asyncio
22
- from hyperquant.broker.ourbit import OurbitSwap
23
- import pybotters
24
- import hyperquant
25
-
26
- async def test():
27
- async with pybotters.Client(
28
- apis={
29
- "ourbit": [
30
- "WEB3bf088f8b2f2fae07592fe1a6240e2d798100a9cb2a91f8fda1056b6865ab3ee"
31
- ]
32
- }
33
- ) as client:
34
- ourbit = OurbitSwap(client)
35
- await ourbit.__aenter__()
36
- res = await ourbit.place_order(
37
- symbol="SOL_USDT",
38
- size=1,
39
- side="buy",
40
- order_type="limit_GTC",
41
- price=192
42
- )
43
- print(res)
44
-
45
-
46
- # # await ourbit.update('orders')
47
- # await ourbit.sub_personal()
48
-
49
- # while True:
50
- # await ourbit.store.position.wait()
51
- # print(ourbit.store.position.find())
52
- # # await ourbit.store.position.wait()
53
- # # print(ourbit.store.position.find())
54
- # await ourbit.store.orders.wait()
55
-
56
- # with ourbit.store.orders.watch() as changes:
57
- # async for change in changes:
58
- # print(change.operation, change.data)
59
-
60
-
61
- # print(res.data)
62
-
63
- # print(ourbit.datastore.detail.find({"symbol": "SOL_USDT"}))
64
-
65
- # print(ourbit.datastore.detail.find())
66
-
67
- # await ourbit.update('balance')
68
- # print(ourbit.store.balance.find())
69
-
70
- # res = await client.fetch(
71
- # 'GET',
72
- # 'https://futures.ourbit.com//api/v1/private/order/list/history_orders?category=1&page_num=1&page_size=4&start_time=1755682343814&states=4&symbol=SOL_USDT'
73
- # )
74
-
75
- # print(res.data)
76
-
77
- # print(await ourbit.query_order('219079365441409152'))
78
-
79
- # await ourbit.place_order(
80
- # symbol="SOL_USDT",
81
- # side="sell",
82
- # order_type="market",
83
- # usdt_amount=3,
84
- # price=206.44
85
- # )
86
-
87
- # print(ourbit.datastore.orders.find())
88
-
89
- # await ourbit.cancel_orders(['219206341921656960'])
90
-
91
-
92
- # print(ourbit.datastore.orders.find())
93
-
94
- # ps = ourbit.datastore.position.find({
95
- # "symbol": "SOL_USDT",
96
- # "side": "long"
97
- # })[0]
98
-
99
- # position_id = ps.get("position_id")
100
-
101
- # await ourbit.place_order(
102
- # symbol="SOL_USDT",
103
- # size=1,
104
- # side="close",
105
- # order_type="market",
106
- # position_id=position_id
107
- # )
108
-
109
- # await ourbit.sub_order_book("SOL_USDT")
110
-
111
- # while True:
112
- # await ourbit.store.book.wait()
113
- # asks = ourbit.store.book.find({'side': 'A'})
114
- # bids = ourbit.store.book.find({'side': 'B'})
115
- # print("Ask0:", asks[0]['px'])
116
- # print("Bid0:", bids[0]['px'])
117
- # print('-----\n')
118
-
119
- if __name__ == "__main__":
120
- asyncio.run(test())
hyperquant-0.41/tmp2.py DELETED
@@ -1,32 +0,0 @@
1
- import asyncio
2
- from pybotters.store import DataStore
3
-
4
- store = DataStore(keys=['oid'])
5
-
6
- async def place():
7
- # 模拟服务器返回
8
- store._insert([{'oid': 1}])
9
- # store._delete([{'oid': 1}])
10
- store._find_and_delete({'oid':1})
11
- await asyncio.sleep(0.1)
12
- return
13
-
14
- async def loop_orders():
15
- with store.watch() as stream:
16
- async for change in stream:
17
- print('loop_orders', change)
18
-
19
- async def main():
20
- asyncio.create_task(loop_orders())
21
-
22
-
23
- with store.watch() as stream:
24
- await place()
25
- print('下单完成')
26
- async for change in stream:
27
- print(change)
28
-
29
- if __name__ == "__main__":
30
- asyncio.run(main())
31
-
32
-
File without changes
File without changes
File without changes
File without changes
File without changes