hyperquant 0.91__tar.gz → 0.92__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.
Potentially problematic release.
This version of hyperquant might be problematic. Click here for more details.
- {hyperquant-0.91 → hyperquant-0.92}/PKG-INFO +1 -1
- {hyperquant-0.91 → hyperquant-0.92}/pyproject.toml +1 -1
- {hyperquant-0.91 → hyperquant-0.92}/src/hyperquant/broker/coinup.py +9 -8
- {hyperquant-0.91 → hyperquant-0.92}/src/hyperquant/broker/models/coinup.py +2 -1
- hyperquant-0.92/tests/test_coinup.py +281 -0
- {hyperquant-0.91 → hyperquant-0.92}/uv.lock +1 -1
- hyperquant-0.91/tests/test_coinup.py +0 -41
- {hyperquant-0.91 → hyperquant-0.92}/.gitignore +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/.python-version +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/README.md +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/apis.json +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/data/alpine_smoke.log +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/data/logs/notikit.log +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/data/logs/test_order_sync.log +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/data/records_swap.csv +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/data/records_swapc.csv +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/doc/coinup.md +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/doc/lbank.md +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/pub.sh +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/requirements-dev.lock +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/requirements.lock +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/src/hyperquant/__init__.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/src/hyperquant/broker/auth.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/src/hyperquant/broker/bitget.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/src/hyperquant/broker/coinw.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/src/hyperquant/broker/edgex.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/src/hyperquant/broker/hyperliquid.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/src/hyperquant/broker/lbank.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/src/hyperquant/broker/lib/edgex_sign.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/src/hyperquant/broker/lib/hpstore.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/src/hyperquant/broker/lib/hyper_types.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/src/hyperquant/broker/lib/util.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/src/hyperquant/broker/models/bitget.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/src/hyperquant/broker/models/coinw.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/src/hyperquant/broker/models/edgex.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/src/hyperquant/broker/models/hyperliquid.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/src/hyperquant/broker/models/lbank.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/src/hyperquant/broker/models/ourbit.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/src/hyperquant/broker/ourbit.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/src/hyperquant/broker/ws.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/src/hyperquant/core.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/src/hyperquant/datavison/_util.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/src/hyperquant/datavison/binance.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/src/hyperquant/datavison/coinglass.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/src/hyperquant/datavison/okx.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/src/hyperquant/db.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/src/hyperquant/draw.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/src/hyperquant/logkit.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/src/hyperquant/notikit.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/tests/test_bitget.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/tests/test_coinw.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/tests/test_draw.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/tests/test_edgex.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/tests/test_lbank.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/tests/test_ourbit.py +0 -0
- {hyperquant-0.91 → hyperquant-0.92}/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.92
|
|
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
|
|
@@ -209,27 +209,27 @@ class Coinup:
|
|
|
209
209
|
|
|
210
210
|
async def sub_orderbook(
|
|
211
211
|
self,
|
|
212
|
-
|
|
212
|
+
symbols: Sequence[str] | str,
|
|
213
213
|
*,
|
|
214
214
|
depth_step: str = "step0",
|
|
215
215
|
depth_limit: int | None = None,
|
|
216
216
|
) -> pybotters.ws.WebSocketApp:
|
|
217
217
|
"""订阅订单簿深度频道。
|
|
218
218
|
|
|
219
|
-
参数 ``channels`` 支持 ``subSymbol`` 或完整频道名称:
|
|
220
|
-
|
|
221
219
|
- ``"e_wlfiusdt"`` -> 发送 ``market_e_wlfiusdt_depth_step0``
|
|
222
220
|
- ``"market_e_wlfiusdt_depth_step0"`` -> 原样发送
|
|
223
221
|
"""
|
|
224
222
|
|
|
225
|
-
if isinstance(
|
|
226
|
-
|
|
223
|
+
if isinstance(symbols, str):
|
|
224
|
+
symbols = [symbols]
|
|
227
225
|
|
|
228
226
|
payloads = []
|
|
229
|
-
for
|
|
230
|
-
ch =
|
|
227
|
+
for symbol in symbols:
|
|
228
|
+
ch = symbol.lower()
|
|
229
|
+
# 去除特殊符号
|
|
230
|
+
ch = ch.replace("-", "").replace("_", "")
|
|
231
231
|
if not ch.startswith("market_"):
|
|
232
|
-
ch = f"
|
|
232
|
+
ch = f"market_e_{ch}_depth_{depth_step}"
|
|
233
233
|
payloads.append(
|
|
234
234
|
{
|
|
235
235
|
"event": "sub",
|
|
@@ -239,6 +239,7 @@ class Coinup:
|
|
|
239
239
|
},
|
|
240
240
|
}
|
|
241
241
|
)
|
|
242
|
+
print(payloads)
|
|
242
243
|
|
|
243
244
|
if not payloads:
|
|
244
245
|
raise ValueError("channels must not be empty")
|
|
@@ -32,13 +32,14 @@ class Book(DataStore):
|
|
|
32
32
|
bids = bids[: self.limit]
|
|
33
33
|
chanel = msg["channel"]
|
|
34
34
|
symbol = chanel.split("_")[2].upper()
|
|
35
|
+
symbol = symbol.replace("USDT", "-USDT")
|
|
35
36
|
asks = [
|
|
36
37
|
{"s": symbol, "S": "a", "p": float(price), "q": float(quantity)} for price, quantity in asks
|
|
37
38
|
]
|
|
38
39
|
bids = [
|
|
39
40
|
{"s": symbol, "S": "b", "p": float(price), "q": float(quantity)} for price, quantity in bids
|
|
40
41
|
]
|
|
41
|
-
self.
|
|
42
|
+
self._find_and_delete({"s": symbol})
|
|
42
43
|
self._insert(asks + bids)
|
|
43
44
|
|
|
44
45
|
class Detail(DataStore):
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import pybotters
|
|
2
|
+
from hyperquant.broker.coinup import Coinup, CoinUpDataStore
|
|
3
|
+
import asyncio
|
|
4
|
+
from logging import Logger
|
|
5
|
+
import time
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from typing import Any, Literal
|
|
8
|
+
from hyperquant.logkit import get_logger
|
|
9
|
+
from hyperquant.broker.coinup import Coinup
|
|
10
|
+
|
|
11
|
+
apis = {"coinup": ["948a3841361bd38c30fc37355c3fb01a35135042c1c44698bed6f9cd6262cce0"]}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
async def test_update():
|
|
15
|
+
async with pybotters.Client(apis=apis) as client:
|
|
16
|
+
async with Coinup(client=client) as broker:
|
|
17
|
+
# await broker.update("detail")
|
|
18
|
+
# print(broker.store.detail.get({"symbol": "WLFI-USDT"}))
|
|
19
|
+
# await broker.update("position")
|
|
20
|
+
# print(broker.store.position.find())
|
|
21
|
+
await broker.update("history_orders")
|
|
22
|
+
print(broker.store.history_orders.find())
|
|
23
|
+
|
|
24
|
+
# await broker.update('orders')
|
|
25
|
+
# print(broker.store.orders.find())
|
|
26
|
+
|
|
27
|
+
async def test_cancel_order():
|
|
28
|
+
async with pybotters.Client(apis=apis) as client:
|
|
29
|
+
async with Coinup(client=client) as broker:
|
|
30
|
+
await broker.cancel_order('169', '2951914186269633768')
|
|
31
|
+
|
|
32
|
+
async def test_place_order():
|
|
33
|
+
async with pybotters.Client(apis=apis) as client:
|
|
34
|
+
async with Coinup(client=client) as broker:
|
|
35
|
+
# 市价单
|
|
36
|
+
order = await broker.place_order(
|
|
37
|
+
'WLFI-USDT',
|
|
38
|
+
side='sell',
|
|
39
|
+
volume='1',
|
|
40
|
+
order_type='market',
|
|
41
|
+
offset='CLOSE',
|
|
42
|
+
)
|
|
43
|
+
print(order)
|
|
44
|
+
|
|
45
|
+
async def test_sub_book():
|
|
46
|
+
async with pybotters.Client(apis=apis) as client:
|
|
47
|
+
async with Coinup(client=client) as broker:
|
|
48
|
+
symbols = [d['symbol'] for d in broker.store.detail.find()]
|
|
49
|
+
symbols = symbols[:30]
|
|
50
|
+
|
|
51
|
+
await broker.sub_orderbook(symbols, depth_limit=1)
|
|
52
|
+
print("Subscribed orderbook", symbols)
|
|
53
|
+
while True:
|
|
54
|
+
await asyncio.sleep(1)
|
|
55
|
+
print(broker.store.book.find())
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _to_float(value: Any) -> float:
|
|
59
|
+
try:
|
|
60
|
+
if value is None:
|
|
61
|
+
return 0.0
|
|
62
|
+
return float(value)
|
|
63
|
+
except (TypeError, ValueError):
|
|
64
|
+
return 0.0
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _extract_position_volume(snapshot: dict[str, Any] | None) -> float:
|
|
68
|
+
if not snapshot:
|
|
69
|
+
return 0.0
|
|
70
|
+
return _to_float(
|
|
71
|
+
snapshot.get("canCloseVolume")
|
|
72
|
+
or snapshot.get("positionVolume")
|
|
73
|
+
or snapshot.get("volume")
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def _extract_order_id(payload: Any) -> str | None:
|
|
78
|
+
if payload is None:
|
|
79
|
+
return None
|
|
80
|
+
if 'ids' in payload:
|
|
81
|
+
ids = payload.get('ids')
|
|
82
|
+
if isinstance(ids, list) and ids:
|
|
83
|
+
return str(ids[0])
|
|
84
|
+
else:
|
|
85
|
+
return None
|
|
86
|
+
|
|
87
|
+
def _extract_order_state(snapshot: dict[str, Any] | None) -> str | None:
|
|
88
|
+
if not snapshot:
|
|
89
|
+
return None
|
|
90
|
+
for key in ("status", "state", "orderStatus", "statusName"):
|
|
91
|
+
value = snapshot.get(key)
|
|
92
|
+
if value in (None, ""):
|
|
93
|
+
continue
|
|
94
|
+
return str(value)
|
|
95
|
+
return None
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def _is_order_final(snapshot: dict[str, Any] | None) -> bool:
|
|
99
|
+
state = _extract_order_state(snapshot)
|
|
100
|
+
if state is None:
|
|
101
|
+
return False
|
|
102
|
+
|
|
103
|
+
normalized = state.strip().lower()
|
|
104
|
+
if normalized in {
|
|
105
|
+
"0",
|
|
106
|
+
"1",
|
|
107
|
+
"new",
|
|
108
|
+
"pending",
|
|
109
|
+
"processing",
|
|
110
|
+
"submitting",
|
|
111
|
+
"submitted",
|
|
112
|
+
"wait",
|
|
113
|
+
"waiting",
|
|
114
|
+
"partial",
|
|
115
|
+
"partialfill",
|
|
116
|
+
"partial-filled",
|
|
117
|
+
"partially_filled",
|
|
118
|
+
"partially-filled",
|
|
119
|
+
}:
|
|
120
|
+
return False
|
|
121
|
+
|
|
122
|
+
try:
|
|
123
|
+
numeric = float(normalized)
|
|
124
|
+
except ValueError:
|
|
125
|
+
pass
|
|
126
|
+
else:
|
|
127
|
+
# CoinUp 使用 0/1 表示活跃状态,其余视为终态
|
|
128
|
+
if int(numeric) in (0, 1):
|
|
129
|
+
return False
|
|
130
|
+
return True
|
|
131
|
+
|
|
132
|
+
if any(token in normalized for token in ("cancel", "done", "finish", "filled", "complete", "success", "fail")):
|
|
133
|
+
return True
|
|
134
|
+
|
|
135
|
+
# 其他未知状态保持保守,由调用方通过时间/仓位变化判断
|
|
136
|
+
return False
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
@dataclass
|
|
140
|
+
class OrderSyncResult:
|
|
141
|
+
position: dict[str, Any] | None
|
|
142
|
+
order: dict[str, Any] | None
|
|
143
|
+
before_volume: float
|
|
144
|
+
after_volume: float
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
async def order_sync_polling(
|
|
148
|
+
broker: Coinup,
|
|
149
|
+
*,
|
|
150
|
+
symbol: str,
|
|
151
|
+
side: Literal["BUY", "SELL"],
|
|
152
|
+
volume: float | int | str,
|
|
153
|
+
offset: Literal["OPEN", "CLOSE"],
|
|
154
|
+
order_type: Literal["limit", "market", 1, 2] = "limit",
|
|
155
|
+
price: float | int | str | None = None,
|
|
156
|
+
leverage_level: int | str = 1,
|
|
157
|
+
position_type: int | str = 1,
|
|
158
|
+
order_unit: int | str = 2,
|
|
159
|
+
expect_change: float = 0.0,
|
|
160
|
+
window_sec: float = 6.0,
|
|
161
|
+
poll_interval: float = 0.5,
|
|
162
|
+
cancel_retry: int = 3,
|
|
163
|
+
logger: Logger | None = None,
|
|
164
|
+
) -> OrderSyncResult:
|
|
165
|
+
await broker.update("position")
|
|
166
|
+
baseline = broker.store.position.get({"symbol": symbol})
|
|
167
|
+
before_volume = _extract_position_volume(baseline)
|
|
168
|
+
|
|
169
|
+
contract_id = broker.get_contract_id(symbol)
|
|
170
|
+
history_payload = {"contractId": contract_id} if contract_id else None
|
|
171
|
+
|
|
172
|
+
order_id: str | None = None
|
|
173
|
+
need_cancel = True
|
|
174
|
+
current_volume = before_volume
|
|
175
|
+
position_snapshot: dict[str, Any] | None = None
|
|
176
|
+
order_snapshot: dict[str, Any] | None = None
|
|
177
|
+
try:
|
|
178
|
+
started_at = time.time() * 1000
|
|
179
|
+
response = await broker.place_order(
|
|
180
|
+
symbol=symbol,
|
|
181
|
+
side=side,
|
|
182
|
+
volume=volume,
|
|
183
|
+
order_type=order_type,
|
|
184
|
+
price=price,
|
|
185
|
+
position_type=position_type,
|
|
186
|
+
leverage_level=leverage_level,
|
|
187
|
+
offset=offset,
|
|
188
|
+
order_unit=order_unit,
|
|
189
|
+
)
|
|
190
|
+
latency = int(time.time() * 1000 - started_at)
|
|
191
|
+
if logger:
|
|
192
|
+
logger.info(f"下单延迟 {latency} ms")
|
|
193
|
+
order_id = _extract_order_id(response)
|
|
194
|
+
if order_id is None:
|
|
195
|
+
raise RuntimeError(f"place_order 缺少 order_id: {response}")
|
|
196
|
+
except Exception:
|
|
197
|
+
raise
|
|
198
|
+
|
|
199
|
+
deadline = time.monotonic() + window_sec
|
|
200
|
+
|
|
201
|
+
try:
|
|
202
|
+
while time.monotonic() < deadline:
|
|
203
|
+
try:
|
|
204
|
+
await broker.update(
|
|
205
|
+
"history_orders",
|
|
206
|
+
history_orders_payload=history_payload,
|
|
207
|
+
)
|
|
208
|
+
except Exception as exc: # pragma: no cover - 防御
|
|
209
|
+
if logger:
|
|
210
|
+
logger.debug(f"history_orders 更新失败: {exc}")
|
|
211
|
+
if order_id is not None:
|
|
212
|
+
candidate = broker.store.history_orders.get({"orderId": order_id})
|
|
213
|
+
if candidate:
|
|
214
|
+
order_snapshot = candidate
|
|
215
|
+
if _is_order_final(candidate):
|
|
216
|
+
need_cancel = False
|
|
217
|
+
break
|
|
218
|
+
|
|
219
|
+
await asyncio.sleep(poll_interval)
|
|
220
|
+
else:
|
|
221
|
+
if logger:
|
|
222
|
+
logger.warning(
|
|
223
|
+
f"订单处理超时: symbol={symbol} side={side} offset={offset} order_id={order_id}"
|
|
224
|
+
)
|
|
225
|
+
finally:
|
|
226
|
+
if order_id and need_cancel:
|
|
227
|
+
for attempt in range(cancel_retry):
|
|
228
|
+
try:
|
|
229
|
+
await broker.cancel_order(symbol, order_id)
|
|
230
|
+
break
|
|
231
|
+
except Exception as exc: # pragma: no cover - 防御
|
|
232
|
+
if logger:
|
|
233
|
+
logger.info(
|
|
234
|
+
f"撤单失败({attempt + 1}/{cancel_retry}): order_id={order_id} err={exc}"
|
|
235
|
+
)
|
|
236
|
+
await asyncio.sleep(0.5)
|
|
237
|
+
|
|
238
|
+
try:
|
|
239
|
+
await broker.update(
|
|
240
|
+
"history_orders",
|
|
241
|
+
history_orders_payload=history_payload,
|
|
242
|
+
)
|
|
243
|
+
except Exception as exc: # pragma: no cover - 防御
|
|
244
|
+
if logger:
|
|
245
|
+
logger.debug(f"history_orders 更新失败: {exc}")
|
|
246
|
+
if order_id is not None:
|
|
247
|
+
latest_entry = broker.store.history_orders.get({"orderId": order_id})
|
|
248
|
+
if latest_entry:
|
|
249
|
+
order_snapshot = latest_entry
|
|
250
|
+
|
|
251
|
+
try:
|
|
252
|
+
await broker.update("position")
|
|
253
|
+
except Exception as exc: # pragma: no cover - 防御
|
|
254
|
+
if logger:
|
|
255
|
+
logger.debug(f"position 更新失败: {exc}")
|
|
256
|
+
position_snapshot = broker.store.position.get({"symbol": symbol})
|
|
257
|
+
current_volume = _extract_position_volume(position_snapshot)
|
|
258
|
+
|
|
259
|
+
return OrderSyncResult(position_snapshot, order_snapshot, before_volume, current_volume)
|
|
260
|
+
|
|
261
|
+
async def test_order_sync_polling():
|
|
262
|
+
logger = get_logger("test_order_sync_polling")
|
|
263
|
+
async with pybotters.Client(apis=apis) as client:
|
|
264
|
+
async with Coinup(client=client) as broker:
|
|
265
|
+
result = await order_sync_polling(
|
|
266
|
+
broker,
|
|
267
|
+
symbol="WLFI-USDT",
|
|
268
|
+
side="BUY",
|
|
269
|
+
volume=3,
|
|
270
|
+
offset="OPEN",
|
|
271
|
+
order_type="market",
|
|
272
|
+
logger=logger,
|
|
273
|
+
)
|
|
274
|
+
print(result)
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
if __name__ == "__main__":
|
|
279
|
+
import asyncio
|
|
280
|
+
|
|
281
|
+
asyncio.run(test_sub_book())
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import pybotters
|
|
2
|
-
from hyperquant.broker.coinup import Coinup, CoinUpDataStore
|
|
3
|
-
|
|
4
|
-
apis = {"coinup": ["948a3841361bd38c30fc37355c3fb01a35135042c1c44698bed6f9cd6262cce0"]}
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
async def test_update():
|
|
8
|
-
async with pybotters.Client(apis=apis) as client:
|
|
9
|
-
async with Coinup(client=client) as broker:
|
|
10
|
-
# await broker.update("detail")
|
|
11
|
-
# print(broker.store.detail.get({"symbol": "WLFI-USDT"}))
|
|
12
|
-
# await broker.update("position")
|
|
13
|
-
# print(broker.store.position.find())
|
|
14
|
-
await broker.update("history_orders")
|
|
15
|
-
print(broker.store.history_orders.find())
|
|
16
|
-
|
|
17
|
-
# await broker.update('orders')
|
|
18
|
-
# print(broker.store.orders.find())
|
|
19
|
-
|
|
20
|
-
async def test_cancel_order():
|
|
21
|
-
async with pybotters.Client(apis=apis) as client:
|
|
22
|
-
async with Coinup(client=client) as broker:
|
|
23
|
-
await broker.cancel_order('169', '2951914186269633768')
|
|
24
|
-
|
|
25
|
-
async def test_place_order():
|
|
26
|
-
async with pybotters.Client(apis=apis) as client:
|
|
27
|
-
async with Coinup(client=client) as broker:
|
|
28
|
-
# 市价单
|
|
29
|
-
order = await broker.place_order(
|
|
30
|
-
'WLFI-USDT',
|
|
31
|
-
side='sell',
|
|
32
|
-
volume='1',
|
|
33
|
-
order_type='market',
|
|
34
|
-
offset='CLOSE',
|
|
35
|
-
)
|
|
36
|
-
print(order)
|
|
37
|
-
|
|
38
|
-
if __name__ == "__main__":
|
|
39
|
-
import asyncio
|
|
40
|
-
|
|
41
|
-
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
|