hyperquant 0.87__py3-none-any.whl → 0.89__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.
Potentially problematic release.
This version of hyperquant might be problematic. Click here for more details.
hyperquant/broker/coinw.py
CHANGED
|
@@ -60,11 +60,10 @@ class Coinw:
|
|
|
60
60
|
"all",
|
|
61
61
|
] = "all",
|
|
62
62
|
*,
|
|
63
|
-
instrument: str | None = None,
|
|
64
63
|
position_type: Literal["execute", "plan", "planTrigger"] = "execute",
|
|
65
64
|
page: int | None = None,
|
|
66
65
|
page_size: int | None = None,
|
|
67
|
-
|
|
66
|
+
instrument: str | None = None,
|
|
68
67
|
) -> None:
|
|
69
68
|
"""刷新本地缓存,使用 CoinW REST API。
|
|
70
69
|
|
|
@@ -108,16 +107,8 @@ class Coinw:
|
|
|
108
107
|
)
|
|
109
108
|
|
|
110
109
|
if include_position:
|
|
111
|
-
if not instrument:
|
|
112
|
-
raise ValueError("instrument is required when updating positions")
|
|
113
|
-
params = {"instrument": instrument}
|
|
114
|
-
if open_ids:
|
|
115
|
-
params["openIds"] = open_ids
|
|
116
110
|
requests.append(
|
|
117
|
-
self.client.get(
|
|
118
|
-
f"{self.rest_api}/v1/perpum/positions",
|
|
119
|
-
params=params,
|
|
120
|
-
)
|
|
111
|
+
self.client.get(f"{self.rest_api}/v1/perpum/positions/all")
|
|
121
112
|
)
|
|
122
113
|
|
|
123
114
|
if include_balance:
|
|
@@ -186,6 +177,51 @@ class Coinw:
|
|
|
186
177
|
data = await res.json()
|
|
187
178
|
return self._ensure_ok("place_order", data)
|
|
188
179
|
|
|
180
|
+
async def close_position(
|
|
181
|
+
self,
|
|
182
|
+
open_id: str | int,
|
|
183
|
+
*,
|
|
184
|
+
position_type: Literal["plan", "planTrigger", "execute"] = "plan",
|
|
185
|
+
close_num: str | float | int | None = None,
|
|
186
|
+
close_rate: str | float | int | None = None,
|
|
187
|
+
order_price: str | float | None = None,
|
|
188
|
+
instrument: str | None = None,
|
|
189
|
+
) -> dict[str, Any]:
|
|
190
|
+
"""关闭单个仓位(``DELETE /v1/perpum/positions``)。
|
|
191
|
+
|
|
192
|
+
Params
|
|
193
|
+
------
|
|
194
|
+
open_id: ``openId`` / 持仓唯一 ID。
|
|
195
|
+
position_type: 订单类型 ``plan`` / ``planTrigger`` / ``execute``。
|
|
196
|
+
close_num: 按合约数量平仓(与 ``close_rate`` 至少指定其一)。
|
|
197
|
+
close_rate: 按比例平仓(0-1)。
|
|
198
|
+
order_price: 限价平仓时指定价格。
|
|
199
|
+
instrument: 交易品种(部分情况下需要传入,例如限价单)。
|
|
200
|
+
"""
|
|
201
|
+
|
|
202
|
+
if close_num is None and close_rate is None:
|
|
203
|
+
raise ValueError("close_num or close_rate must be provided")
|
|
204
|
+
|
|
205
|
+
payload: dict[str, Any] = {
|
|
206
|
+
"id": str(open_id),
|
|
207
|
+
"positionType": position_type,
|
|
208
|
+
}
|
|
209
|
+
if close_num is not None:
|
|
210
|
+
payload["closeNum"] = str(close_num)
|
|
211
|
+
if close_rate is not None:
|
|
212
|
+
payload["closeRate"] = str(close_rate)
|
|
213
|
+
if order_price is not None:
|
|
214
|
+
payload["orderPrice"] = str(order_price)
|
|
215
|
+
if instrument is not None:
|
|
216
|
+
payload["instrument"] = instrument
|
|
217
|
+
|
|
218
|
+
res = await self.client.delete(
|
|
219
|
+
f"{self.rest_api}/v1/perpum/positions",
|
|
220
|
+
data=payload,
|
|
221
|
+
)
|
|
222
|
+
data = await res.json()
|
|
223
|
+
return self._ensure_ok("close_position", data)
|
|
224
|
+
|
|
189
225
|
async def place_order_web(
|
|
190
226
|
self,
|
|
191
227
|
instrument: str,
|
|
@@ -292,7 +328,7 @@ class Coinw:
|
|
|
292
328
|
ws_app = await self._ensure_private_ws()
|
|
293
329
|
payloads = [
|
|
294
330
|
{"event": "sub", "params": {"biz": "futures", "type": "order"}},
|
|
295
|
-
{"event": "sub", "params": {"biz": "futures", "type": "position"}},
|
|
331
|
+
# {"event": "sub", "params": {"biz": "futures", "type": "position"}},
|
|
296
332
|
{"event": "sub", "params": {"biz": "futures", "type": "position_change"}},
|
|
297
333
|
{"event": "sub", "params": {"biz": "futures", "type": "assets"}},
|
|
298
334
|
]
|
|
@@ -280,16 +280,8 @@ class Orders(DataStore):
|
|
|
280
280
|
class Position(DataStore):
|
|
281
281
|
"""CoinW 当前持仓数据存储。"""
|
|
282
282
|
|
|
283
|
-
_KEYS = ["
|
|
283
|
+
_KEYS = ["openId"]
|
|
284
284
|
|
|
285
|
-
@staticmethod
|
|
286
|
-
def _normalize(entry: dict[str, Any]) -> dict[str, Any] | None:
|
|
287
|
-
position_id = entry.get("id")
|
|
288
|
-
if position_id is None:
|
|
289
|
-
return None
|
|
290
|
-
normalized = dict(entry)
|
|
291
|
-
normalized["id"] = str(position_id)
|
|
292
|
-
return normalized
|
|
293
285
|
|
|
294
286
|
def _onresponse(self, data: Any) -> None:
|
|
295
287
|
payload = []
|
|
@@ -302,9 +294,8 @@ class Position(DataStore):
|
|
|
302
294
|
for entry in payload or []:
|
|
303
295
|
if not isinstance(entry, dict):
|
|
304
296
|
continue
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
items.append(normalized)
|
|
297
|
+
entry['openId'] = str(entry.get("id"))
|
|
298
|
+
items.append(entry)
|
|
308
299
|
|
|
309
300
|
self._clear()
|
|
310
301
|
if items:
|
|
@@ -312,6 +303,7 @@ class Position(DataStore):
|
|
|
312
303
|
|
|
313
304
|
def _on_message(self, msg: dict[str, Any]) -> None:
|
|
314
305
|
data = msg.get("data")
|
|
306
|
+
|
|
315
307
|
if isinstance(data, dict) and data.get("result") is not None:
|
|
316
308
|
return
|
|
317
309
|
|
|
@@ -325,26 +317,28 @@ class Position(DataStore):
|
|
|
325
317
|
return
|
|
326
318
|
|
|
327
319
|
to_insert: list[dict[str, Any]] = []
|
|
320
|
+
to_update: list[dict[str, Any]] = []
|
|
328
321
|
to_delete: list[dict[str, Any]] = []
|
|
329
322
|
|
|
330
323
|
for entry in entries:
|
|
331
324
|
if not isinstance(entry, dict):
|
|
332
325
|
continue
|
|
333
|
-
normalized =
|
|
334
|
-
if not normalized:
|
|
335
|
-
continue
|
|
326
|
+
normalized = entry
|
|
336
327
|
|
|
337
|
-
status = normalized.get("status")
|
|
338
|
-
normalized_status = str(status).lower() if status is not None else ""
|
|
339
|
-
remove = normalized_status in {"close", "closed", "1", "2"}
|
|
340
328
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
329
|
+
if normalized.get("status") == 'close':
|
|
330
|
+
to_delete.append(normalized)
|
|
331
|
+
continue
|
|
332
|
+
|
|
333
|
+
if self.find(normalized):
|
|
334
|
+
to_update.append(normalized)
|
|
335
|
+
else:
|
|
344
336
|
to_insert.append(normalized)
|
|
345
337
|
|
|
346
338
|
if to_delete:
|
|
347
339
|
self._delete(to_delete)
|
|
340
|
+
if to_update:
|
|
341
|
+
self._update(to_update)
|
|
348
342
|
if to_insert:
|
|
349
343
|
self._insert(to_insert)
|
|
350
344
|
|
|
@@ -449,11 +443,12 @@ class CoinwFuturesDataStore(DataStoreCollection):
|
|
|
449
443
|
|
|
450
444
|
def onmessage(self, msg: Item, ws: ClientWebSocketResponse | None = None) -> None:
|
|
451
445
|
msg_type = msg.get("type")
|
|
446
|
+
# print(msg)
|
|
452
447
|
if msg_type == "depth":
|
|
453
448
|
self.book._on_message(msg)
|
|
454
449
|
elif msg_type == "order":
|
|
455
450
|
self.orders._on_message(msg)
|
|
456
|
-
elif msg_type == "position":
|
|
451
|
+
elif msg_type == "position" or msg_type == "position_change":
|
|
457
452
|
self.position._on_message(msg)
|
|
458
453
|
elif msg_type == "assets":
|
|
459
454
|
self.balance._on_message(msg)
|
|
@@ -470,7 +465,7 @@ class CoinwFuturesDataStore(DataStoreCollection):
|
|
|
470
465
|
self.ticker._onresponse(data)
|
|
471
466
|
elif res.url.path == "/v1/perpum/orders/open":
|
|
472
467
|
self.orders._onresponse(data)
|
|
473
|
-
elif res.url.path == "/v1/perpum/positions":
|
|
468
|
+
elif res.url.path == "/v1/perpum/positions/all":
|
|
474
469
|
self.position._onresponse(data)
|
|
475
470
|
elif res.url.path == "/v1/perpum/account/getUserAssets":
|
|
476
471
|
self.balance._onresponse(data)
|
|
@@ -655,17 +650,48 @@ class CoinwFuturesDataStore(DataStoreCollection):
|
|
|
655
650
|
- REST: ``GET /v1/perpum/positions``
|
|
656
651
|
- WebSocket: ``type == "position"``
|
|
657
652
|
|
|
658
|
-
|
|
653
|
+
.. code:: json
|
|
659
654
|
|
|
660
655
|
{
|
|
661
|
-
"
|
|
662
|
-
"
|
|
663
|
-
"
|
|
664
|
-
"
|
|
665
|
-
"
|
|
666
|
-
"
|
|
667
|
-
"
|
|
668
|
-
|
|
656
|
+
"currentPiece": "0",
|
|
657
|
+
"isProfession": 0,
|
|
658
|
+
"leverage": "10",
|
|
659
|
+
"originalType": "execute",
|
|
660
|
+
"orderId": "33309059291614824",
|
|
661
|
+
"contractType": 1,
|
|
662
|
+
"openId": "2435521222638707873",
|
|
663
|
+
"fee": "0.00020724",
|
|
664
|
+
"openPrice": "0.3456",
|
|
665
|
+
"orderStatus": "finish",
|
|
666
|
+
"instrument": "JUP",
|
|
667
|
+
"quantityUnit": 1,
|
|
668
|
+
"source": "api",
|
|
669
|
+
"updatedDate": 1761192795412,
|
|
670
|
+
"positionModel": 1,
|
|
671
|
+
"feeRate": "0.0006",
|
|
672
|
+
"netProfit": "-0.00040724",
|
|
673
|
+
"baseSize": "1",
|
|
674
|
+
"quote": "usdt",
|
|
675
|
+
"liquidateBy": "manual",
|
|
676
|
+
"totalPiece": "1",
|
|
677
|
+
"orderPrice": "0",
|
|
678
|
+
"id": "23469279597150213",
|
|
679
|
+
"fundingSettle": "0",
|
|
680
|
+
"direction": "long",
|
|
681
|
+
"margin": "0.03435264",
|
|
682
|
+
"takerMaker": 1,
|
|
683
|
+
"indexPrice": "0.3455",
|
|
684
|
+
"quantity": "0.03456",
|
|
685
|
+
"userId": "1757458",
|
|
686
|
+
"closedPiece": "1",
|
|
687
|
+
"createdDate": 1761192793000,
|
|
688
|
+
"hedgeId": "23469279597150214",
|
|
689
|
+
"closePrice": "0.3454",
|
|
690
|
+
"positionMargin": "0.03435264",
|
|
691
|
+
"base": "jup",
|
|
692
|
+
"realPrice": "0.3454",
|
|
693
|
+
"status": "close"
|
|
694
|
+
}
|
|
669
695
|
"""
|
|
670
696
|
|
|
671
697
|
return self._get("position", Position)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hyperquant
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.89
|
|
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
|
|
@@ -6,7 +6,7 @@ hyperquant/logkit.py,sha256=nUo7nx5eONvK39GOhWwS41zNRL756P2J7-5xGzwXnTY,8462
|
|
|
6
6
|
hyperquant/notikit.py,sha256=x5yAZ_tAvLQRXcRbcg-VabCaN45LUhvlTZnUqkIqfAA,3596
|
|
7
7
|
hyperquant/broker/auth.py,sha256=xNZEQP0LRRV9BkT2uXBJ-vFfeahUnRVq1bjIT6YbQu8,10089
|
|
8
8
|
hyperquant/broker/bitget.py,sha256=X_S0LKZ7FZAEb6oEMr1vdGP1fondzK74BhmNTpRDSEA,9488
|
|
9
|
-
hyperquant/broker/coinw.py,sha256=
|
|
9
|
+
hyperquant/broker/coinw.py,sha256=SnJU0vASh77rfcpMGWaIfTblQSjQk3vjlW_4juYdbcs,17214
|
|
10
10
|
hyperquant/broker/edgex.py,sha256=TqUO2KRPLN_UaxvtLL6HnA9dAQXC1sGxOfqTHd6W5k8,18378
|
|
11
11
|
hyperquant/broker/hyperliquid.py,sha256=7MxbI9OyIBcImDelPJu-8Nd53WXjxPB5TwE6gsjHbto,23252
|
|
12
12
|
hyperquant/broker/lbank.py,sha256=98M5wmSoeHwbBYMA3rh25zqLb6fQKVaEmwqALF5nOvY,22181
|
|
@@ -17,7 +17,7 @@ hyperquant/broker/lib/hpstore.py,sha256=LnLK2zmnwVvhEbLzYI-jz_SfYpO1Dv2u2cJaRAb8
|
|
|
17
17
|
hyperquant/broker/lib/hyper_types.py,sha256=HqjjzjUekldjEeVn6hxiWA8nevAViC2xHADOzDz9qyw,991
|
|
18
18
|
hyperquant/broker/lib/util.py,sha256=iMU1qF0CHj5zzlIMEQGwjz-qtEVosEe7slXOCuB7Rcw,566
|
|
19
19
|
hyperquant/broker/models/bitget.py,sha256=0RwDY75KrJb-c-oYoMxbqxWfsILe-n_Npojz4UFUq7c,11389
|
|
20
|
-
hyperquant/broker/models/coinw.py,sha256=
|
|
20
|
+
hyperquant/broker/models/coinw.py,sha256=LvLMVP7i-qkkTK1ubw8eBkMK2RQmFoKPxdKqmC4IToY,22157
|
|
21
21
|
hyperquant/broker/models/edgex.py,sha256=vPAkceal44cjTYKQ_0BoNAskOpmkno_Yo1KxgMLPc6Y,33954
|
|
22
22
|
hyperquant/broker/models/hyperliquid.py,sha256=c4r5739ibZfnk69RxPjQl902AVuUOwT8RNvKsMtwXBY,9459
|
|
23
23
|
hyperquant/broker/models/lbank.py,sha256=vHkNKxIMzpoC_EwcZnEOPOupizF92yGWi9GKxvYYFUQ,19181
|
|
@@ -26,6 +26,6 @@ hyperquant/datavison/_util.py,sha256=92qk4vO856RqycO0YqEIHJlEg-W9XKapDVqAMxe6rbw
|
|
|
26
26
|
hyperquant/datavison/binance.py,sha256=3yNKTqvt_vUQcxzeX4ocMsI5k6Q6gLZrvgXxAEad6Kc,5001
|
|
27
27
|
hyperquant/datavison/coinglass.py,sha256=PEjdjISP9QUKD_xzXNzhJ9WFDTlkBrRQlVL-5pxD5mo,10482
|
|
28
28
|
hyperquant/datavison/okx.py,sha256=yg8WrdQ7wgWHNAInIgsWPM47N3Wkfr253169IPAycAY,6898
|
|
29
|
-
hyperquant-0.
|
|
30
|
-
hyperquant-0.
|
|
31
|
-
hyperquant-0.
|
|
29
|
+
hyperquant-0.89.dist-info/METADATA,sha256=NBPtmJcSeB4mhyzR_K0yISNPcMaiyzLqfjGkA_q6dME,4317
|
|
30
|
+
hyperquant-0.89.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
31
|
+
hyperquant-0.89.dist-info/RECORD,,
|
|
File without changes
|