hyperquant 0.97__tar.gz → 0.99__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.
- {hyperquant-0.97 → hyperquant-0.99}/PKG-INFO +1 -1
- {hyperquant-0.97 → hyperquant-0.99}/apis.json +3 -3
- {hyperquant-0.97 → hyperquant-0.99}/doc/bitmart.md +3 -0
- {hyperquant-0.97 → hyperquant-0.99}/pyproject.toml +1 -1
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/broker/bitmart.py +45 -25
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/broker/models/bitmart.py +7 -7
- hyperquant-0.99/tests/test_bitmart.py +156 -0
- {hyperquant-0.97 → hyperquant-0.99}/uv.lock +1 -1
- hyperquant-0.97/tests/test_bitmart.py +0 -70
- {hyperquant-0.97 → hyperquant-0.99}/.gitignore +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/.python-version +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/README.md +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/data/alpine_smoke.log +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/data/logs/notikit.log +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/data/logs/test_order_sync.log +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/data/records_swap.csv +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/data/records_swapc.csv +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/doc/coinup.md +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/doc/lbank.md +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/pub.sh +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/requirements-dev.lock +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/requirements.lock +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/__init__.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/broker/auth.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/broker/bitget.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/broker/coinup.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/broker/coinw.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/broker/edgex.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/broker/hyperliquid.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/broker/lbank.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/broker/lib/edgex_sign.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/broker/lib/hpstore.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/broker/lib/hyper_types.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/broker/lib/util.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/broker/lighter.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/broker/models/bitget.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/broker/models/coinup.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/broker/models/coinw.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/broker/models/edgex.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/broker/models/hyperliquid.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/broker/models/lbank.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/broker/models/lighter.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/broker/models/ourbit.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/broker/ourbit.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/broker/ws.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/core.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/datavison/_util.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/datavison/binance.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/datavison/coinglass.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/datavison/okx.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/db.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/draw.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/logkit.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/src/hyperquant/notikit.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/tests/test_bitget.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/tests/test_coinup.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/tests/test_coinw.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/tests/test_draw.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/tests/test_edgex.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/tests/test_lbank.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/tests/test_lighter.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/tests/test_ourbit.py +0 -0
- {hyperquant-0.97 → hyperquant-0.99}/tests/tmp.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hyperquant
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.99
|
|
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
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
"41933ec0f5dace5eee47628ea2e2cb40a491f7fd20f983b385f8bdc5eea3d3ad4a47bd745f70fc2a"
|
|
25
25
|
],
|
|
26
26
|
"bitmart":[
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
27
|
+
"eyJoZWFkZXIiOnsidHlwIjoiQml0TWFydCIsImFsZyI6IkJNQVBJU0lYIn0sInBheWxvYWQiOnsiamlkIjoiMWU0ZjI2OWQxYTJmNGE0YzlhYWFmNjAwZTRiYzkwYzUiLCJ2ZXJzaW9uIjoiMjAyNTEwMzEiLCJleHBpcmVzQXQiOjE3NjE5ODA0MzgwOTAsImJtIjoiVXppdFJkZEdpdUNZek5KWSs5Q25xNkFjMlZWNmhiT0hhRzVwemdTSTE5cGRLS0JJN2FpUThGRXNaQkFyTDFVUlRnclA1b0ZMMDFJNHQvMnVKUENvVlcxQzhCN1ZGUytyTmtXcmpjbGxHY05hZjNSRjVlbGhkT3MvU1N6UXZlcUNhTW1RS0M2LzhxMy9ySG9xK0ttMFFMRzlnSmlLU3lRMCtqUldnUSs1SllOT0pYbm1yVlpHekdmSUpDM0xwNE1aRjBYNlZ3Y2VkcEhmL0FVYjNsM20zVUltbThLWkxHMitiTjRxMUh0NGtJdkxTL2tsMm5COEpLazVISjQ5S2xEN0RXYTg0NkFwUUdBMDlrWkUrbkdTQ3U4L2VUNTNINGFrYmxMbzlJS3FhdERPVG1ORjlGcTZyc3QzRWlIWnFMNFBwdkdwUDlTNDZscnNrQzZjY0xWOTN5a0VEaTh2NlN6REQ5Um5aQnk1L2dDb0F5VFl2em50NC9uR285R2dwS3dGIn0sInNpZ25hdHVyZSI6ImU1bVl6T3lpMTQxTkJTNjhwamc3NHNYaGJuMHF0WDViNkZvb25ZdnU3eGNNeUE5M3BCN2lLMThkWTFLOEZ5ZzVXdlVyakpYK1p5ZlN1aHRDWVMxbHpnPT0ifQ==",
|
|
28
|
+
"genUaMiA34QCgcB2J3lGN44IM88zqL9y9DE5",
|
|
29
|
+
"1c0886dd192a1dd0f23f71f7ab577a45"
|
|
30
30
|
]
|
|
31
31
|
}
|
|
@@ -446,6 +446,9 @@ curl 'https://derivatives.bitmart.com/gw-api/contract-tiger/forward/v1/ifcontrac
|
|
|
446
446
|
# 订单部分
|
|
447
447
|
|
|
448
448
|
category 1 限价单 2 市价单
|
|
449
|
+
|
|
450
|
+
status 4 系统取消
|
|
451
|
+
|
|
449
452
|
## limit gtc
|
|
450
453
|
curl 'https://derivatives.bitmart.com/gw-api/contract-tiger/forward/v1/ifcontract/submitOrder' \
|
|
451
454
|
-H 'accept: application/json, text/plain, */*' \
|
|
@@ -4,7 +4,7 @@ import asyncio
|
|
|
4
4
|
import json
|
|
5
5
|
import random
|
|
6
6
|
import time
|
|
7
|
-
from typing import Any, Literal, Sequence
|
|
7
|
+
from typing import Any, Literal, Optional, Sequence
|
|
8
8
|
|
|
9
9
|
import pybotters
|
|
10
10
|
|
|
@@ -33,10 +33,19 @@ class Bitmart:
|
|
|
33
33
|
|
|
34
34
|
self.account_index = account_index
|
|
35
35
|
self.apis = apis
|
|
36
|
+
self.symbol_to_contract_id: dict[str, str] = {}
|
|
36
37
|
|
|
37
38
|
async def __aenter__(self) -> "Bitmart":
|
|
38
39
|
await self.update("detail")
|
|
39
40
|
asyncio.create_task(self.auto_refresh())
|
|
41
|
+
|
|
42
|
+
for entry in self.store.detail.find():
|
|
43
|
+
contract_id = entry.get("contract_id")
|
|
44
|
+
symbol = entry.get("name") or entry.get("display_name")
|
|
45
|
+
if contract_id is None or symbol is None:
|
|
46
|
+
continue
|
|
47
|
+
self.symbol_to_contract_id[str(symbol)] = str(contract_id)
|
|
48
|
+
|
|
40
49
|
return self
|
|
41
50
|
|
|
42
51
|
async def auto_refresh(self, sec=3600, test=False) -> None:
|
|
@@ -325,8 +334,9 @@ class Bitmart:
|
|
|
325
334
|
*,
|
|
326
335
|
category: Literal[1,2,"limit","market"] = "limit",
|
|
327
336
|
price: float,
|
|
328
|
-
|
|
329
|
-
|
|
337
|
+
qty: float,
|
|
338
|
+
qty_contract: Optional[int] = None,
|
|
339
|
+
side: Literal[1, 2, 3, 4, "open_long", "close_short", "close_long", "open_short", "buy", "sell"] = "open_long",
|
|
330
340
|
mode: Literal[1, 2, 3, 4, "gtc", "ioc", "fok", "maker_only", "maker-only", "post_only"] = "gtc",
|
|
331
341
|
open_type: Literal[1, 2, "cross", "isolated"] = "isolated",
|
|
332
342
|
leverage: int | str = 10,
|
|
@@ -334,8 +344,9 @@ class Bitmart:
|
|
|
334
344
|
trigger_price: float | None = None,
|
|
335
345
|
custom_id: int | str | None = None,
|
|
336
346
|
extra_params: dict[str, Any] | None = None,
|
|
337
|
-
) ->
|
|
347
|
+
) -> int:
|
|
338
348
|
"""Submit an order via ``submitOrder``.
|
|
349
|
+
返回值: order_id (int)
|
|
339
350
|
"""
|
|
340
351
|
|
|
341
352
|
contract_id = self.get_contract_id(symbol)
|
|
@@ -351,25 +362,31 @@ class Bitmart:
|
|
|
351
362
|
raise ValueError(f"Market metadata unavailable for symbol: {symbol}")
|
|
352
363
|
|
|
353
364
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
365
|
+
if qty_contract is not None:
|
|
366
|
+
|
|
367
|
+
contract_size_str = detail.get("contract_size") or detail.get("vol_unit") or "1"
|
|
368
|
+
try:
|
|
369
|
+
contract_size_val = float(contract_size_str)
|
|
370
|
+
except (TypeError, ValueError):
|
|
371
|
+
contract_size_val = 1.0
|
|
372
|
+
if contract_size_val <= 0:
|
|
373
|
+
raise ValueError(f"Invalid contract_size for {symbol}: {contract_size_str}")
|
|
374
|
+
|
|
375
|
+
contracts_float = float(qty) / contract_size_val
|
|
376
|
+
contracts_int = int(round(contracts_float))
|
|
377
|
+
if contracts_int <= 0:
|
|
378
|
+
raise ValueError(
|
|
379
|
+
f"Volume too small for contract size ({contract_size_val}): volume={qty}"
|
|
380
|
+
)
|
|
381
|
+
if abs(contracts_float - contracts_int) > 1e-8:
|
|
382
|
+
raise ValueError(
|
|
383
|
+
f"Volume must be a multiple of contract_size ({contract_size_val}). "
|
|
384
|
+
f"Received volume={qty} -> {contracts_float} contracts."
|
|
385
|
+
)
|
|
386
|
+
else:
|
|
387
|
+
contracts_int = int(qty)
|
|
388
|
+
if contracts_int <= 0:
|
|
389
|
+
raise ValueError(f"Volume must be positive integer contracts: volume={qty}")
|
|
373
390
|
|
|
374
391
|
price_unit = detail.get("price_unit") or 1
|
|
375
392
|
try:
|
|
@@ -396,7 +413,7 @@ class Bitmart:
|
|
|
396
413
|
price_fmt = f"{adjusted_price:.15f}".rstrip("0").rstrip(".") or "0"
|
|
397
414
|
|
|
398
415
|
way_value = self._normalize_enum(
|
|
399
|
-
|
|
416
|
+
side,
|
|
400
417
|
{
|
|
401
418
|
"open_long": 1,
|
|
402
419
|
"close_short": 2,
|
|
@@ -460,7 +477,10 @@ class Bitmart:
|
|
|
460
477
|
|
|
461
478
|
if resp.get("success") is False or resp.get("errno") not in (None, "OK"):
|
|
462
479
|
raise ValueError(f"Bitmart submitOrder error: {resp}")
|
|
463
|
-
|
|
480
|
+
|
|
481
|
+
# {"errno":"OK","message":"Success","data":{"order_id":3000236525013551},"success":true}
|
|
482
|
+
# 直接取order_id返回
|
|
483
|
+
return resp.get("data", {}).get("order_id")
|
|
464
484
|
|
|
465
485
|
async def cancel_order(
|
|
466
486
|
self,
|
|
@@ -381,7 +381,7 @@ class BitmartDataStore(DataStoreCollection):
|
|
|
381
381
|
@property
|
|
382
382
|
def orders(self) -> Orders:
|
|
383
383
|
"""用户订单 (`userAllOrders`)。
|
|
384
|
-
|
|
384
|
+
key: order_id
|
|
385
385
|
.. code:: json
|
|
386
386
|
|
|
387
387
|
[
|
|
@@ -510,19 +510,19 @@ class BitmartDataStore(DataStoreCollection):
|
|
|
510
510
|
{
|
|
511
511
|
"account_id": 14794011,
|
|
512
512
|
"coin_code": "USDT",
|
|
513
|
-
"available_vol": "
|
|
514
|
-
"cash_vol": "
|
|
513
|
+
"available_vol": "10.970977797397999999",
|
|
514
|
+
"cash_vol": "11.000536099457999999",
|
|
515
515
|
"freeze_vol": "0",
|
|
516
|
-
"realised_vol": "0",
|
|
517
|
-
"un_realised_vol": "0",
|
|
518
|
-
"earnings_vol": "0",
|
|
516
|
+
"realised_vol": "0.000536099457999999",
|
|
517
|
+
"un_realised_vol": "-0.00001502",
|
|
518
|
+
"earnings_vol": "0.000536099457999999",
|
|
519
519
|
"total_im": "",
|
|
520
520
|
"margin_balance": "",
|
|
521
521
|
"available_balance": "",
|
|
522
522
|
"trans_out_balance": "",
|
|
523
523
|
"status": 0,
|
|
524
524
|
"total_balance": "",
|
|
525
|
-
"account_rights": "
|
|
525
|
+
"account_rights": "11.000521079457999999",
|
|
526
526
|
"bonus_voucher_vol": "",
|
|
527
527
|
"freeze_bonus_voucher_vol": ""
|
|
528
528
|
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import pybotters
|
|
2
|
+
|
|
3
|
+
from hyperquant.broker.lighter import Lighter
|
|
4
|
+
import asyncio
|
|
5
|
+
from logging import Logger
|
|
6
|
+
import time
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
from typing import Any, Awaitable, Literal
|
|
9
|
+
from hyperquant.logkit import get_logger
|
|
10
|
+
from hyperquant.broker.bitmart import Bitmart
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
async def test_update():
|
|
15
|
+
async with pybotters.Client(apis='./apis.json') as client:
|
|
16
|
+
async with Bitmart(client=client) as broker:
|
|
17
|
+
# print(broker.store.detail.find()[0])
|
|
18
|
+
# await broker.update('balances')
|
|
19
|
+
# print(broker.store.balances.find())
|
|
20
|
+
# await broker.update('ticker')
|
|
21
|
+
# print(broker.store.ticker.find())
|
|
22
|
+
|
|
23
|
+
# await broker.update('history_orders')
|
|
24
|
+
# print(broker.store.orders.find())
|
|
25
|
+
# print(broker.store.orders.get({'order_id':3000237069605967}))
|
|
26
|
+
await broker.update('positions')
|
|
27
|
+
print(broker.store.positions.find())
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
async def test_place():
|
|
31
|
+
async with pybotters.Client(apis='./apis.json') as client:
|
|
32
|
+
async with Bitmart(client=client) as broker:
|
|
33
|
+
|
|
34
|
+
oid = await broker.place_order(
|
|
35
|
+
symbol='ONDOUSDT',
|
|
36
|
+
side='sell',
|
|
37
|
+
category='limit',
|
|
38
|
+
price=0.7,
|
|
39
|
+
qty=0.2,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
print(f"Placed order ID: {oid}")
|
|
43
|
+
|
|
44
|
+
resp = await broker.cancel_order(
|
|
45
|
+
symbol='ONDOUSDT',
|
|
46
|
+
order_ids=[oid],
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
print(f"Cancel response: {resp}")
|
|
50
|
+
|
|
51
|
+
@dataclass
|
|
52
|
+
class OrderSyncResult:
|
|
53
|
+
position: dict[str, Any]
|
|
54
|
+
order: dict[str, Any]
|
|
55
|
+
|
|
56
|
+
async def order_sync_polling(
|
|
57
|
+
broker: Bitmart,
|
|
58
|
+
place_task: Awaitable,
|
|
59
|
+
is_ioc: bool = True,
|
|
60
|
+
cancel_retry: int = 3,
|
|
61
|
+
logger: Logger | None = None,
|
|
62
|
+
) -> OrderSyncResult:
|
|
63
|
+
try:
|
|
64
|
+
oid = await place_task
|
|
65
|
+
except Exception as e:
|
|
66
|
+
if logger:
|
|
67
|
+
logger.warning(f"Order placement failed: {e}")
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
async def sync():
|
|
71
|
+
await broker.update('history_orders')
|
|
72
|
+
await broker.update('positions')
|
|
73
|
+
order = broker.store.orders.get({'order_id': oid})
|
|
74
|
+
if order:
|
|
75
|
+
contract_id = order.get('contract_id')
|
|
76
|
+
positions = broker.store.positions.find({'contract_id': contract_id})
|
|
77
|
+
position = positions[0] if positions else {}
|
|
78
|
+
return OrderSyncResult(position=position, order=order)
|
|
79
|
+
|
|
80
|
+
if is_ioc:
|
|
81
|
+
return await sync()
|
|
82
|
+
else:
|
|
83
|
+
for attempt in range(cancel_retry):
|
|
84
|
+
await asyncio.sleep(1)
|
|
85
|
+
await broker.update('history_orders')
|
|
86
|
+
order = broker.store.orders.get({'order_id': oid})
|
|
87
|
+
# 说明订单已经置入历史委托
|
|
88
|
+
if order:
|
|
89
|
+
return await sync()
|
|
90
|
+
else:
|
|
91
|
+
try:
|
|
92
|
+
await broker.cancel_order(
|
|
93
|
+
symbol=order.get('symbol'),
|
|
94
|
+
order_ids=[oid],
|
|
95
|
+
)
|
|
96
|
+
except Exception as e:
|
|
97
|
+
if logger:
|
|
98
|
+
logger.warning(f"Order cancellation attempt {attempt + 1} failed: {e}")
|
|
99
|
+
|
|
100
|
+
return OrderSyncResult(position={}, order={})
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
async def test_sub_book():
|
|
104
|
+
async with pybotters.Client() as client:
|
|
105
|
+
async with Bitmart(client=client) as broker:
|
|
106
|
+
broker.store.book.limit = 1
|
|
107
|
+
await broker.sub_orderbook(["TRXUSDT", 'XRPUSDT', 'DOTUSDT'])
|
|
108
|
+
while True:
|
|
109
|
+
# await broker.store.book.wait()
|
|
110
|
+
# print(broker.store.book.find())
|
|
111
|
+
asks = broker.store.book.find({"S": "a", 's': 'TRXUSDT'})
|
|
112
|
+
bids = broker.store.book.find({"S": "b", 's': 'TRXUSDT'})
|
|
113
|
+
# 订单薄format化输出
|
|
114
|
+
print("Asks:")
|
|
115
|
+
for ask in asks:
|
|
116
|
+
print(f"Price: {ask['p']}, Quantity: {ask['q']}")
|
|
117
|
+
print("Bids:")
|
|
118
|
+
for bid in bids:
|
|
119
|
+
print(f"Price: {bid['p']}, Quantity: {bid['q']}")
|
|
120
|
+
print("-" * 30)
|
|
121
|
+
await asyncio.sleep(1)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
# with broker.store.book.watch() as stream:
|
|
125
|
+
# async for change in stream:
|
|
126
|
+
# print(change)
|
|
127
|
+
|
|
128
|
+
async def test_auto_refresh():
|
|
129
|
+
async with pybotters.Client(apis='./apis.json') as client:
|
|
130
|
+
async with Bitmart(client=client, apis='./apis.json') as broker:
|
|
131
|
+
await broker.auto_refresh(0, test=True)
|
|
132
|
+
await asyncio.sleep(2)
|
|
133
|
+
|
|
134
|
+
async def test_sync_place():
|
|
135
|
+
logger = get_logger("test_sync_place")
|
|
136
|
+
async with pybotters.Client(apis='./apis.json') as client:
|
|
137
|
+
async with Bitmart(client=client) as broker:
|
|
138
|
+
place_task = broker.place_order(
|
|
139
|
+
symbol='ONDOUSDT',
|
|
140
|
+
side='sell',
|
|
141
|
+
category='market',
|
|
142
|
+
mode='ioc',
|
|
143
|
+
price=0.71,
|
|
144
|
+
qty=0.2,
|
|
145
|
+
)
|
|
146
|
+
result = await order_sync_polling(
|
|
147
|
+
broker,
|
|
148
|
+
place_task,
|
|
149
|
+
is_ioc=False,
|
|
150
|
+
cancel_retry=2,
|
|
151
|
+
logger=logger,
|
|
152
|
+
)
|
|
153
|
+
logger.info(f"Order Sync Result: {result}")
|
|
154
|
+
|
|
155
|
+
if __name__ == "__main__":
|
|
156
|
+
asyncio.run(test_update())
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import pybotters
|
|
2
|
-
|
|
3
|
-
from hyperquant.broker.lighter import Lighter
|
|
4
|
-
import asyncio
|
|
5
|
-
from logging import Logger
|
|
6
|
-
import time
|
|
7
|
-
from dataclasses import dataclass
|
|
8
|
-
from typing import Any, Literal
|
|
9
|
-
from hyperquant.logkit import get_logger
|
|
10
|
-
from hyperquant.broker.bitmart import Bitmart
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
async def test_update():
|
|
15
|
-
async with pybotters.Client(apis='./apis.json') as client:
|
|
16
|
-
async with Bitmart(client=client) as broker:
|
|
17
|
-
# print(broker.store.detail.find()[0])
|
|
18
|
-
# await broker.update('balances')
|
|
19
|
-
# print(broker.store.balances.find())
|
|
20
|
-
await broker.update('ticker')
|
|
21
|
-
print(broker.store.ticker.find())
|
|
22
|
-
|
|
23
|
-
# await broker.update('history_orders')
|
|
24
|
-
# print(broker.store.orders.find())
|
|
25
|
-
|
|
26
|
-
async def test_place():
|
|
27
|
-
async with pybotters.Client(apis='./apis.json') as client:
|
|
28
|
-
async with Bitmart(client=client) as broker:
|
|
29
|
-
order = await broker.place_order(
|
|
30
|
-
symbol='TRXUSDT',
|
|
31
|
-
way='buy',
|
|
32
|
-
category='market',
|
|
33
|
-
price=0.0296,
|
|
34
|
-
qty=1,
|
|
35
|
-
)
|
|
36
|
-
print(order)
|
|
37
|
-
|
|
38
|
-
async def test_sub_book():
|
|
39
|
-
async with pybotters.Client() as client:
|
|
40
|
-
async with Bitmart(client=client) as broker:
|
|
41
|
-
broker.store.book.limit = 1
|
|
42
|
-
await broker.sub_orderbook(["TRXUSDT", 'XRPUSDT', 'DOTUSDT'])
|
|
43
|
-
while True:
|
|
44
|
-
# await broker.store.book.wait()
|
|
45
|
-
# print(broker.store.book.find())
|
|
46
|
-
asks = broker.store.book.find({"S": "a", 's': 'TRXUSDT'})
|
|
47
|
-
bids = broker.store.book.find({"S": "b", 's': 'TRXUSDT'})
|
|
48
|
-
# 订单薄format化输出
|
|
49
|
-
print("Asks:")
|
|
50
|
-
for ask in asks:
|
|
51
|
-
print(f"Price: {ask['p']}, Quantity: {ask['q']}")
|
|
52
|
-
print("Bids:")
|
|
53
|
-
for bid in bids:
|
|
54
|
-
print(f"Price: {bid['p']}, Quantity: {bid['q']}")
|
|
55
|
-
print("-" * 30)
|
|
56
|
-
await asyncio.sleep(1)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
# with broker.store.book.watch() as stream:
|
|
60
|
-
# async for change in stream:
|
|
61
|
-
# print(change)
|
|
62
|
-
|
|
63
|
-
async def test_auto_refresh():
|
|
64
|
-
async with pybotters.Client(apis='./apis.json') as client:
|
|
65
|
-
async with Bitmart(client=client, apis='./apis.json') as broker:
|
|
66
|
-
await broker.auto_refresh(0, test=True)
|
|
67
|
-
await asyncio.sleep(2)
|
|
68
|
-
|
|
69
|
-
if __name__ == "__main__":
|
|
70
|
-
asyncio.run(test_update())
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|