hyperquant 0.71__tar.gz → 0.72__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.71 → hyperquant-0.72}/PKG-INFO +1 -1
- {hyperquant-0.71 → hyperquant-0.72}/apis.json +5 -2
- {hyperquant-0.71 → hyperquant-0.72}/pyproject.toml +1 -1
- hyperquant-0.72/src/hyperquant/broker/bitget.py +291 -0
- {hyperquant-0.71 → hyperquant-0.72}/src/hyperquant/broker/models/bitget.py +13 -8
- {hyperquant-0.71 → hyperquant-0.72}/src/hyperquant/broker/models/lbank.py +2 -1
- {hyperquant-0.71 → hyperquant-0.72}/tests/test_bitget.py +33 -4
- {hyperquant-0.71 → hyperquant-0.72}/tests/test_lbank.py +8 -7
- {hyperquant-0.71 → hyperquant-0.72}/uv.lock +1 -1
- hyperquant-0.71/doc/edgex_act.md +0 -1592
- hyperquant-0.71/doc/edgex_debug.md +0 -2
- hyperquant-0.71/doc/edgex_order.md +0 -1767
- hyperquant-0.71/doc/edgex_ws.md +0 -0
- hyperquant-0.71/src/hyperquant/broker/bitget.py +0 -107
- {hyperquant-0.71 → hyperquant-0.72}/.gitignore +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/.python-version +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/README.md +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/data/alpine_smoke.log +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/data/logs/notikit.log +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/data/logs/test_order_sync.log +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/data/records_swap.csv +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/data/records_swapc.csv +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/doc/lbank.md +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/pub.sh +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/requirements-dev.lock +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/requirements.lock +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/src/hyperquant/__init__.py +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/src/hyperquant/broker/auth.py +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/src/hyperquant/broker/edgex.py +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/src/hyperquant/broker/hyperliquid.py +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/src/hyperquant/broker/lbank.py +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/src/hyperquant/broker/lib/edgex_sign.py +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/src/hyperquant/broker/lib/hpstore.py +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/src/hyperquant/broker/lib/hyper_types.py +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/src/hyperquant/broker/lib/util.py +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/src/hyperquant/broker/models/edgex.py +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/src/hyperquant/broker/models/hyperliquid.py +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/src/hyperquant/broker/models/ourbit.py +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/src/hyperquant/broker/ourbit.py +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/src/hyperquant/broker/ws.py +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/src/hyperquant/core.py +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/src/hyperquant/datavison/_util.py +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/src/hyperquant/datavison/binance.py +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/src/hyperquant/datavison/coinglass.py +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/src/hyperquant/datavison/okx.py +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/src/hyperquant/db.py +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/src/hyperquant/draw.py +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/src/hyperquant/logkit.py +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/src/hyperquant/notikit.py +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/tests/test_draw.py +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/tests/test_edgex.py +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/tests/test_ourbit.py +0 -0
- {hyperquant-0.71 → hyperquant-0.72}/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.72
|
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,7 +7,10 @@
|
|
7
7
|
"78Uke-bPB57YoRzAwY7SkWyPQFeKkPuWVQakC0k9rSI",
|
8
8
|
"3MB7nAnnNPTxAnwdbjDPew-02b746d6a832346a46a97faf054b2909c1a0b58a35e04c3504923a99a5503c1c"
|
9
9
|
],
|
10
|
-
"lbank": [
|
11
|
-
|
10
|
+
"lbank": ["617a2d77b4cd4dfbbaa2094c17017bdb"],
|
11
|
+
"bitget": [
|
12
|
+
"bg_03e0445d9282f248d22842cfe6f30192",
|
13
|
+
"67ec894753d75fec12332881278420863a960ec39c8f5acf1de88aa1da926854",
|
14
|
+
"huainian0408"
|
12
15
|
]
|
13
16
|
}
|
@@ -0,0 +1,291 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import logging
|
4
|
+
from typing import Any, Literal
|
5
|
+
|
6
|
+
import pybotters
|
7
|
+
|
8
|
+
from .models.bitget import BitgetDataStore
|
9
|
+
from .lib.util import fmt_value
|
10
|
+
|
11
|
+
logger = logging.getLogger(__name__)
|
12
|
+
|
13
|
+
|
14
|
+
class Bitget:
|
15
|
+
"""Bitget public/privileged client (REST + WS).
|
16
|
+
|
17
|
+
默认只支持单向持仓(One-way mode)。
|
18
|
+
"""
|
19
|
+
|
20
|
+
def __init__(
|
21
|
+
self,
|
22
|
+
client: pybotters.Client,
|
23
|
+
*,
|
24
|
+
rest_api: str | None = None,
|
25
|
+
ws_url: str | None = None,
|
26
|
+
) -> None:
|
27
|
+
self.client = client
|
28
|
+
self.store = BitgetDataStore()
|
29
|
+
|
30
|
+
self.rest_api = rest_api or "https://api.bitget.com"
|
31
|
+
self.ws_url = ws_url or "wss://ws.bitget.com/v2/ws/public"
|
32
|
+
self.ws_url_private = ws_url or "wss://ws.bitget.com/v2/ws/private"
|
33
|
+
|
34
|
+
self._ws_app = None
|
35
|
+
|
36
|
+
async def __aenter__(self) -> "Bitget":
|
37
|
+
await self.update("detail")
|
38
|
+
return self
|
39
|
+
|
40
|
+
async def __aexit__(self, exc_type, exc, tb) -> None: # pragma: no cover - symmetry
|
41
|
+
pass
|
42
|
+
|
43
|
+
async def sub_personal(self) -> None:
|
44
|
+
sub_msg = {
|
45
|
+
"op": "subscribe",
|
46
|
+
"args": [
|
47
|
+
{"instType": "USDT-FUTURES", "channel": "orders", "instId": "default"},
|
48
|
+
{
|
49
|
+
"instType": "USDT-FUTURES",
|
50
|
+
"channel": "positions",
|
51
|
+
"instId": "default",
|
52
|
+
},
|
53
|
+
{"instType": "USDT-FUTURES", "channel": "account", "coin": "default"},
|
54
|
+
],
|
55
|
+
}
|
56
|
+
self.client.ws_connect(
|
57
|
+
self.ws_url_private,
|
58
|
+
send_json=sub_msg,
|
59
|
+
hdlr_json=self.store.onmessage,
|
60
|
+
)
|
61
|
+
|
62
|
+
async def update(
|
63
|
+
self,
|
64
|
+
update_type: Literal["detail", "ticker", "all"] = "all",
|
65
|
+
) -> None:
|
66
|
+
"""Refresh cached REST resources."""
|
67
|
+
|
68
|
+
requests: list[Any] = []
|
69
|
+
|
70
|
+
if update_type in {"detail", "all"}:
|
71
|
+
requests.append(
|
72
|
+
self.client.get(
|
73
|
+
f"{self.rest_api}/api/v2/mix/market/contracts",
|
74
|
+
params={"productType": "usdt-futures"},
|
75
|
+
)
|
76
|
+
)
|
77
|
+
|
78
|
+
if update_type in {"ticker", "all"}:
|
79
|
+
requests.append(
|
80
|
+
self.client.get(
|
81
|
+
f"{self.rest_api}/api/v2/mix/market/tickers",
|
82
|
+
params={"productType": "usdt-futures"},
|
83
|
+
)
|
84
|
+
)
|
85
|
+
|
86
|
+
if not requests:
|
87
|
+
raise ValueError(f"update_type err: {update_type}")
|
88
|
+
|
89
|
+
await self.store.initialize(*requests)
|
90
|
+
|
91
|
+
async def place_order(
|
92
|
+
self,
|
93
|
+
symbol: str,
|
94
|
+
*,
|
95
|
+
direction: Literal["buy", "sell", "long", "short", "0", "1"],
|
96
|
+
volume: float,
|
97
|
+
price: float | None = None,
|
98
|
+
order_type: Literal[
|
99
|
+
"market",
|
100
|
+
"limit_gtc",
|
101
|
+
"limit_ioc",
|
102
|
+
"limit_fok",
|
103
|
+
"limit_post_only",
|
104
|
+
"limit",
|
105
|
+
] = "market",
|
106
|
+
margin_mode: Literal["isolated", "crossed"] = "crossed",
|
107
|
+
product_type: str = "USDT-FUTURES",
|
108
|
+
margin_coin: str = "USDT",
|
109
|
+
reduce_only: bool | None = None,
|
110
|
+
offset_flag: Literal["open", "close", "0", "1"] | None = None,
|
111
|
+
client_order_id: str | None = None,
|
112
|
+
extra_params: dict[str, Any] | None = None,
|
113
|
+
) -> dict[str, Any]:
|
114
|
+
"""Create an order via ``POST /api/v2/mix/order/place-order``.
|
115
|
+
|
116
|
+
Parameters mirror the Bitget V2 contract REST API but are normalized to
|
117
|
+
match the broker interface (``direction``, ``order_type`` etc.).
|
118
|
+
"""
|
119
|
+
|
120
|
+
side = self._normalize_direction(direction)
|
121
|
+
order_type_code, force_code = self._resolve_order_type(order_type)
|
122
|
+
|
123
|
+
if reduce_only is None:
|
124
|
+
reduce_only = self._normalize_offset(offset_flag)
|
125
|
+
|
126
|
+
detail = self._get_detail_entry(symbol)
|
127
|
+
volume_str = self._format_with_step(
|
128
|
+
volume, detail.get("step_size") or detail.get("stepSize")
|
129
|
+
)
|
130
|
+
|
131
|
+
payload: dict[str, Any] = {
|
132
|
+
"symbol": symbol,
|
133
|
+
"productType": product_type,
|
134
|
+
"marginMode": margin_mode,
|
135
|
+
"marginCoin": margin_coin,
|
136
|
+
"side": side,
|
137
|
+
"size": volume_str,
|
138
|
+
"orderType": order_type_code,
|
139
|
+
}
|
140
|
+
|
141
|
+
if force_code:
|
142
|
+
payload["force"] = force_code
|
143
|
+
|
144
|
+
if order_type_code == "limit":
|
145
|
+
if price is None:
|
146
|
+
raise ValueError("price is required for Bitget limit orders")
|
147
|
+
payload["price"] = self._format_with_step(
|
148
|
+
price,
|
149
|
+
detail.get("tick_size") or detail.get("tickSize"),
|
150
|
+
)
|
151
|
+
elif price is not None:
|
152
|
+
logger.debug("Price %.8f ignored for market order", price)
|
153
|
+
|
154
|
+
if reduce_only is True:
|
155
|
+
payload["reduceOnly"] = "YES"
|
156
|
+
elif reduce_only is False:
|
157
|
+
payload["reduceOnly"] = "NO"
|
158
|
+
|
159
|
+
if client_order_id:
|
160
|
+
payload["clientOid"] = client_order_id
|
161
|
+
|
162
|
+
if extra_params:
|
163
|
+
payload.update(extra_params)
|
164
|
+
|
165
|
+
res = await self.client.post(
|
166
|
+
f"{self.rest_api}/api/v2/mix/order/place-order",
|
167
|
+
data=payload,
|
168
|
+
)
|
169
|
+
data = await res.json()
|
170
|
+
return self._ensure_ok("place_order", data)
|
171
|
+
|
172
|
+
async def cancel_order(
|
173
|
+
self,
|
174
|
+
order_sys_id: str,
|
175
|
+
*,
|
176
|
+
symbol: str,
|
177
|
+
margin_mode: Literal["isolated", "crossed"],
|
178
|
+
product_type: str = "USDT-FUTURES",
|
179
|
+
margin_coin: str = "USDT",
|
180
|
+
client_order_id: str | None = None,
|
181
|
+
) -> dict[str, Any]:
|
182
|
+
"""Cancel an order via ``POST /api/v2/mix/order/cancel-order``."""
|
183
|
+
|
184
|
+
payload = {
|
185
|
+
"symbol": symbol,
|
186
|
+
"productType": product_type,
|
187
|
+
"marginMode": margin_mode,
|
188
|
+
"marginCoin": margin_coin,
|
189
|
+
}
|
190
|
+
|
191
|
+
if client_order_id:
|
192
|
+
payload["clientOid"] = client_order_id
|
193
|
+
else:
|
194
|
+
payload["orderId"] = order_sys_id
|
195
|
+
|
196
|
+
res = await self.client.post(
|
197
|
+
f"{self.rest_api}/api/v2/mix/order/cancel-order",
|
198
|
+
json=payload,
|
199
|
+
)
|
200
|
+
data = await res.json()
|
201
|
+
return self._ensure_ok("cancel_order", data)
|
202
|
+
|
203
|
+
async def sub_orderbook(self, symbols: list[str], channel: str = "books1") -> None:
|
204
|
+
"""Subscribe to Bitget order-book snapshots/updates."""
|
205
|
+
|
206
|
+
submsg = {"op": "subscribe", "args": []}
|
207
|
+
for symbol in symbols:
|
208
|
+
submsg["args"].append(
|
209
|
+
{"instType": "SPOT", "channel": channel, "instId": symbol}
|
210
|
+
)
|
211
|
+
|
212
|
+
self.client.ws_connect(
|
213
|
+
self.ws_url,
|
214
|
+
send_json=submsg,
|
215
|
+
hdlr_json=self.store.onmessage,
|
216
|
+
)
|
217
|
+
|
218
|
+
def _get_detail_entry(self, symbol: str) -> dict[str, Any]:
|
219
|
+
detail = self.store.detail.get({"symbol": symbol})
|
220
|
+
if not detail:
|
221
|
+
raise ValueError(
|
222
|
+
f"Unknown Bitget instrument: {symbol}. Call update('detail') first or provide valid symbol."
|
223
|
+
)
|
224
|
+
return detail
|
225
|
+
|
226
|
+
@staticmethod
|
227
|
+
def _format_with_step(value: float, step: Any) -> str:
|
228
|
+
if step in (None, 0, "0"):
|
229
|
+
return str(value)
|
230
|
+
try:
|
231
|
+
step_float = float(step)
|
232
|
+
except (TypeError, ValueError): # pragma: no cover - defensive guard
|
233
|
+
return str(value)
|
234
|
+
if step_float <= 0:
|
235
|
+
return str(value)
|
236
|
+
return fmt_value(value, step_float)
|
237
|
+
|
238
|
+
@staticmethod
|
239
|
+
def _normalize_direction(direction: str) -> str:
|
240
|
+
mapping = {
|
241
|
+
"buy": "buy",
|
242
|
+
"long": "buy",
|
243
|
+
"0": "buy",
|
244
|
+
"sell": "sell",
|
245
|
+
"short": "sell",
|
246
|
+
"1": "sell",
|
247
|
+
}
|
248
|
+
key = str(direction).lower()
|
249
|
+
try:
|
250
|
+
return mapping[key]
|
251
|
+
except KeyError as exc: # pragma: no cover - guard
|
252
|
+
raise ValueError(f"Unsupported direction: {direction}") from exc
|
253
|
+
|
254
|
+
@staticmethod
|
255
|
+
def _normalize_offset(
|
256
|
+
offset: Literal["open", "close", "0", "1"] | None,
|
257
|
+
) -> bool | None:
|
258
|
+
if offset is None:
|
259
|
+
return None
|
260
|
+
mapping = {
|
261
|
+
"open": False,
|
262
|
+
"0": False,
|
263
|
+
"close": True,
|
264
|
+
"1": True,
|
265
|
+
}
|
266
|
+
key = str(offset).lower()
|
267
|
+
if key in mapping:
|
268
|
+
return mapping[key]
|
269
|
+
raise ValueError(f"Unsupported offset_flag: {offset}")
|
270
|
+
|
271
|
+
@staticmethod
|
272
|
+
def _resolve_order_type(order_type: str) -> tuple[str, str | None]:
|
273
|
+
mapping = {
|
274
|
+
"market": ("market", None),
|
275
|
+
"limit": ("limit", "gtc"),
|
276
|
+
"limit_gtc": ("limit", "gtc"),
|
277
|
+
"limit_ioc": ("limit", "ioc"),
|
278
|
+
"limit_fok": ("limit", "fok"),
|
279
|
+
"limit_post_only": ("limit", "post_only"),
|
280
|
+
}
|
281
|
+
key = str(order_type).lower()
|
282
|
+
try:
|
283
|
+
return mapping[key]
|
284
|
+
except KeyError as exc: # pragma: no cover - guard
|
285
|
+
raise ValueError(f"Unsupported order_type: {order_type}") from exc
|
286
|
+
|
287
|
+
@staticmethod
|
288
|
+
def _ensure_ok(operation: str, data: Any) -> dict[str, Any]:
|
289
|
+
if not isinstance(data, dict) or data.get("code") != "00000":
|
290
|
+
raise RuntimeError(f"{operation} failed: {data}")
|
291
|
+
return data.get("data") or {}
|
@@ -16,13 +16,18 @@ class Detail(DataStore):
|
|
16
16
|
_KEYS = ["symbol"]
|
17
17
|
|
18
18
|
def _transform(self, entry: dict[str, Any]) -> dict[str, Any] | None:
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
step_size = place_to_step(
|
23
|
-
tick_size = place_to_step(
|
24
|
-
|
25
|
-
entry[
|
19
|
+
step_place = entry.get("volume_place", 1)
|
20
|
+
tick_place = entry.get("price_place", 1)
|
21
|
+
|
22
|
+
step_size = place_to_step(step_place)
|
23
|
+
tick_size = place_to_step(tick_place)
|
24
|
+
|
25
|
+
entry["stepSize"] = step_size
|
26
|
+
entry["tickSize"] = tick_size
|
27
|
+
# expose snake_case aliases for downstream callers keeping legacy naming
|
28
|
+
entry["step_size"] = step_size
|
29
|
+
entry["tick_size"] = tick_size
|
30
|
+
|
26
31
|
return entry
|
27
32
|
|
28
33
|
def _onresponse(self, data: list[dict[str, Any]] | dict[str, Any] | None) -> None:
|
@@ -280,4 +285,4 @@ class BitgetDataStore(BitgetV2DataStore):
|
|
280
285
|
}
|
281
286
|
]
|
282
287
|
"""
|
283
|
-
return self._get("book")
|
288
|
+
return self._get("book")
|
@@ -184,7 +184,8 @@ class Orders(DataStore):
|
|
184
184
|
"side": direction,
|
185
185
|
"offset": offset_flag,
|
186
186
|
"order_type": order_kind,
|
187
|
-
"price": entry.get("Price"),
|
187
|
+
"price": entry.get('TradePrice') or entry.get("Price"),
|
188
|
+
"order_price": entry.get("OrderPrice") or entry.get('Price'),
|
188
189
|
"quantity": entry.get("Volume"),
|
189
190
|
"filled": entry.get("VolumeTraded"),
|
190
191
|
"remaining": entry.get("VolumeRemain"),
|
@@ -1,6 +1,7 @@
|
|
1
|
+
import time
|
1
2
|
import pybotters
|
2
3
|
from hyperquant.broker.models.bitget import BitgetDataStore
|
3
|
-
|
4
|
+
pybotters.auth
|
4
5
|
|
5
6
|
async def test_update():
|
6
7
|
async with pybotters.Client() as client:
|
@@ -42,8 +43,10 @@ async def test_broker_update():
|
|
42
43
|
async with pybotters.Client() as client:
|
43
44
|
bg = Bitget(client)
|
44
45
|
store = BitgetDataStore()
|
45
|
-
await bg.update('all')
|
46
|
-
print(bg.store.detail.find())
|
46
|
+
# await bg.update('all')
|
47
|
+
# print(bg.store.detail.find())
|
48
|
+
await bg.update('ticker')
|
49
|
+
print(bg.store.ticker.find())
|
47
50
|
|
48
51
|
async def test_broker_sub_orderbook():
|
49
52
|
async with pybotters.Client() as client:
|
@@ -53,7 +56,33 @@ async def test_broker_sub_orderbook():
|
|
53
56
|
await asyncio.sleep(1)
|
54
57
|
print(bg.store.book.find())
|
55
58
|
|
59
|
+
async def test_order():
|
60
|
+
async with pybotters.Client(apis='./apis.json') as client:
|
61
|
+
bg = Bitget(client)
|
62
|
+
await bg.__aenter__()
|
63
|
+
ts = time.time() * 1000
|
64
|
+
res = await bg.place_order(
|
65
|
+
'SOLUSDT',
|
66
|
+
direction='long',
|
67
|
+
order_type='limit_gtc',
|
68
|
+
volume=0.1,
|
69
|
+
price=185
|
70
|
+
)
|
71
|
+
# print(res)
|
72
|
+
print(f'订单延迟: {time.time() * 1000 - ts} ms')
|
73
|
+
|
74
|
+
async def test_sub_personal():
|
75
|
+
async with pybotters.Client(apis='./apis.json') as client:
|
76
|
+
bg = Bitget(client)
|
77
|
+
await bg.__aenter__()
|
78
|
+
await bg.sub_personal()
|
79
|
+
with bg.store.orders.watch() as stream:
|
80
|
+
async for change in stream:
|
81
|
+
print("Orders changed:", change)
|
82
|
+
|
83
|
+
|
84
|
+
|
56
85
|
if __name__ == "__main__":
|
57
86
|
import asyncio
|
58
87
|
|
59
|
-
asyncio.run(
|
88
|
+
asyncio.run(test_order())
|
@@ -107,10 +107,11 @@ async def test_update():
|
|
107
107
|
# print(lb.store.position.find())
|
108
108
|
# await lb.update('balance')
|
109
109
|
# print(lb.store.balance.find())
|
110
|
-
await lb.update('detail')
|
111
|
-
print(lb.store.detail.find())
|
112
|
-
|
113
|
-
|
110
|
+
# await lb.update('detail')
|
111
|
+
# print(lb.store.detail.find())
|
112
|
+
await lb.update('orders')
|
113
|
+
|
114
|
+
print(lb.store.order_finish.find())
|
114
115
|
|
115
116
|
async def test_place():
|
116
117
|
async with pybotters.Client(apis='./apis.json') as client:
|
@@ -241,8 +242,8 @@ async def test_order_sync_polling():
|
|
241
242
|
lb,
|
242
243
|
symbol="SOLUSDT",
|
243
244
|
direction="buy",
|
244
|
-
order_type="
|
245
|
-
price=200,
|
245
|
+
order_type="limit_gtc",
|
246
|
+
price=200.1,
|
246
247
|
volume=0.03,
|
247
248
|
window_sec=3.0,
|
248
249
|
grace_sec=3.0,
|
@@ -251,4 +252,4 @@ async def test_order_sync_polling():
|
|
251
252
|
print(result)
|
252
253
|
|
253
254
|
if __name__ == "__main__":
|
254
|
-
asyncio.run(
|
255
|
+
asyncio.run(test_order_sync_polling())
|