hyperquant 1.48__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/__init__.py +8 -0
- hyperquant/broker/auth.py +972 -0
- hyperquant/broker/bitget.py +311 -0
- hyperquant/broker/bitmart.py +720 -0
- hyperquant/broker/coinw.py +487 -0
- hyperquant/broker/deepcoin.py +651 -0
- hyperquant/broker/edgex.py +500 -0
- hyperquant/broker/hyperliquid.py +570 -0
- hyperquant/broker/lbank.py +661 -0
- hyperquant/broker/lib/edgex_sign.py +455 -0
- hyperquant/broker/lib/hpstore.py +252 -0
- hyperquant/broker/lib/hyper_types.py +48 -0
- hyperquant/broker/lib/polymarket/ctfAbi.py +721 -0
- hyperquant/broker/lib/polymarket/safeAbi.py +1138 -0
- hyperquant/broker/lib/util.py +22 -0
- hyperquant/broker/lighter.py +679 -0
- hyperquant/broker/models/apexpro.py +150 -0
- hyperquant/broker/models/bitget.py +359 -0
- hyperquant/broker/models/bitmart.py +635 -0
- hyperquant/broker/models/coinw.py +724 -0
- hyperquant/broker/models/deepcoin.py +809 -0
- hyperquant/broker/models/edgex.py +1053 -0
- hyperquant/broker/models/hyperliquid.py +284 -0
- hyperquant/broker/models/lbank.py +557 -0
- hyperquant/broker/models/lighter.py +868 -0
- hyperquant/broker/models/ourbit.py +1155 -0
- hyperquant/broker/models/polymarket.py +1071 -0
- hyperquant/broker/ourbit.py +550 -0
- hyperquant/broker/polymarket.py +2399 -0
- hyperquant/broker/ws.py +132 -0
- hyperquant/core.py +513 -0
- hyperquant/datavison/_util.py +18 -0
- hyperquant/datavison/binance.py +111 -0
- hyperquant/datavison/coinglass.py +237 -0
- hyperquant/datavison/okx.py +177 -0
- hyperquant/db.py +191 -0
- hyperquant/draw.py +1200 -0
- hyperquant/logkit.py +205 -0
- hyperquant/notikit.py +124 -0
- hyperquant-1.48.dist-info/METADATA +32 -0
- hyperquant-1.48.dist-info/RECORD +42 -0
- hyperquant-1.48.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
from dataclasses import dataclass, field
|
|
5
|
+
from heapq import heappop, heappush
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
import pybotters
|
|
9
|
+
from pybotters.store import DataStore
|
|
10
|
+
from pybotters.ws import ClientWebSocketResponse
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass
|
|
14
|
+
class _SideBook:
|
|
15
|
+
is_ask: bool
|
|
16
|
+
levels: dict[float, tuple[str, str]] = field(default_factory=dict)
|
|
17
|
+
heap: list[tuple[float, float]] = field(default_factory=list)
|
|
18
|
+
|
|
19
|
+
def clear(self) -> None:
|
|
20
|
+
self.levels.clear()
|
|
21
|
+
self.heap.clear()
|
|
22
|
+
|
|
23
|
+
def update_levels(self, updates: list[list[Any]] | None, snapshot: bool) -> None:
|
|
24
|
+
if updates is None:
|
|
25
|
+
return
|
|
26
|
+
|
|
27
|
+
if snapshot:
|
|
28
|
+
self.clear()
|
|
29
|
+
|
|
30
|
+
for entry in updates:
|
|
31
|
+
if not isinstance(entry, (list, tuple)) or len(entry) < 2:
|
|
32
|
+
continue
|
|
33
|
+
price, size = entry[0], entry[1]
|
|
34
|
+
price_val = self._float(price)
|
|
35
|
+
size_val = self._float(size)
|
|
36
|
+
if price_val is None or size_val is None:
|
|
37
|
+
continue
|
|
38
|
+
|
|
39
|
+
if size_val <= 0:
|
|
40
|
+
self.levels.pop(price_val, None)
|
|
41
|
+
continue
|
|
42
|
+
|
|
43
|
+
self.levels[price_val] = (str(price), str(size))
|
|
44
|
+
priority = price_val if self.is_ask else -price_val
|
|
45
|
+
heappush(self.heap, (priority, price_val))
|
|
46
|
+
|
|
47
|
+
def best(self) -> tuple[str, str] | None:
|
|
48
|
+
while self.heap:
|
|
49
|
+
_, price = self.heap[0]
|
|
50
|
+
level = self.levels.get(price)
|
|
51
|
+
if level is not None:
|
|
52
|
+
return level
|
|
53
|
+
heappop(self.heap)
|
|
54
|
+
return None
|
|
55
|
+
|
|
56
|
+
@staticmethod
|
|
57
|
+
def _float(value: Any) -> float | None:
|
|
58
|
+
try:
|
|
59
|
+
return float(value)
|
|
60
|
+
except (TypeError, ValueError):
|
|
61
|
+
return None
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class Book(DataStore):
|
|
65
|
+
"""只维护卖一/买一价的轻量级(book1)深度数据。"""
|
|
66
|
+
|
|
67
|
+
_KEYS = ["s", "S"]
|
|
68
|
+
|
|
69
|
+
def _init(self) -> None:
|
|
70
|
+
self._book: dict[str, dict[str, _SideBook]] = {}
|
|
71
|
+
|
|
72
|
+
def _side(self, symbol: str, side: str) -> _SideBook:
|
|
73
|
+
symbol_book = self._book.setdefault(symbol, {})
|
|
74
|
+
side_book = symbol_book.get(side)
|
|
75
|
+
if side_book is None:
|
|
76
|
+
side_book = _SideBook(is_ask=(side == "a"))
|
|
77
|
+
symbol_book[side] = side_book
|
|
78
|
+
return side_book
|
|
79
|
+
|
|
80
|
+
def _sync_side(self, symbol: str, side: str, best: tuple[str, str] | None) -> None:
|
|
81
|
+
key = {"s": symbol, "S": side}
|
|
82
|
+
current = self.get(key)
|
|
83
|
+
|
|
84
|
+
if best is None:
|
|
85
|
+
if current:
|
|
86
|
+
self._delete([key])
|
|
87
|
+
return
|
|
88
|
+
|
|
89
|
+
price, size = best
|
|
90
|
+
if current and current.get("p") == price and current.get("q") == size:
|
|
91
|
+
return
|
|
92
|
+
|
|
93
|
+
payload = {"s": symbol, "S": side, "p": price, "q": size}
|
|
94
|
+
if current:
|
|
95
|
+
self._update([payload])
|
|
96
|
+
else:
|
|
97
|
+
self._insert([payload])
|
|
98
|
+
|
|
99
|
+
def _on_message(self, msg: dict[str, Any]) -> None:
|
|
100
|
+
b_type = msg.get("type")
|
|
101
|
+
if b_type not in {"snapshot", "delta"}:
|
|
102
|
+
return
|
|
103
|
+
|
|
104
|
+
data = msg.get("data") or {}
|
|
105
|
+
if not data:
|
|
106
|
+
return
|
|
107
|
+
|
|
108
|
+
symbol = data.get("s")
|
|
109
|
+
if not symbol:
|
|
110
|
+
return
|
|
111
|
+
|
|
112
|
+
asks = self._side(symbol, "a")
|
|
113
|
+
bids = self._side(symbol, "b")
|
|
114
|
+
|
|
115
|
+
is_snapshot = b_type == "snapshot"
|
|
116
|
+
asks.update_levels(data.get("a"), snapshot=is_snapshot)
|
|
117
|
+
bids.update_levels(data.get("b"), snapshot=is_snapshot)
|
|
118
|
+
|
|
119
|
+
best_ask = asks.best()
|
|
120
|
+
best_bid = bids.best()
|
|
121
|
+
|
|
122
|
+
self._sync_side(symbol, "a", best_ask)
|
|
123
|
+
self._sync_side(symbol, "b", best_bid)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
store = Book()
|
|
127
|
+
|
|
128
|
+
def callback(msg, ws: ClientWebSocketResponse = None):
|
|
129
|
+
topic = msg.get('topic')
|
|
130
|
+
if not topic:
|
|
131
|
+
return
|
|
132
|
+
if 'orderBook' in topic:
|
|
133
|
+
store._on_message(msg)
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
async def main():
|
|
137
|
+
async with pybotters.Client() as client:
|
|
138
|
+
# webData2
|
|
139
|
+
client.ws_connect(
|
|
140
|
+
"wss://quote.omni.apex.exchange/realtime_public",
|
|
141
|
+
send_json={"op":"subscribe","args":["orderBook25.H.BTCUSDT"]},
|
|
142
|
+
hdlr_json=callback
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
while True:
|
|
146
|
+
await asyncio.sleep(1)
|
|
147
|
+
print(store.find())
|
|
148
|
+
|
|
149
|
+
if __name__ == "__main__":
|
|
150
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
from typing import TYPE_CHECKING, Any, Awaitable
|
|
5
|
+
from aiohttp import ClientResponse
|
|
6
|
+
from pybotters import DataStore
|
|
7
|
+
from pybotters.models.bitget_v2 import BitgetV2DataStore
|
|
8
|
+
from ..lib.util import place_to_step
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from pybotters.typedefs import Item
|
|
12
|
+
|
|
13
|
+
class Detail(DataStore):
|
|
14
|
+
"""Futures instrument metadata store obtained from the futures instrument endpoint."""
|
|
15
|
+
|
|
16
|
+
_KEYS = ["symbol"]
|
|
17
|
+
|
|
18
|
+
def _transform(self, entry: dict[str, Any]) -> dict[str, Any] | None:
|
|
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
|
+
|
|
31
|
+
return entry
|
|
32
|
+
|
|
33
|
+
def _onresponse(self, data: list[dict[str, Any]] | dict[str, Any] | None) -> None:
|
|
34
|
+
if not data:
|
|
35
|
+
self._clear()
|
|
36
|
+
return
|
|
37
|
+
entries = data
|
|
38
|
+
if isinstance(data, dict): # pragma: no cover - defensive guard
|
|
39
|
+
entries = data.get("data") or []
|
|
40
|
+
items: list[dict[str, Any]] = []
|
|
41
|
+
for entry in entries or []:
|
|
42
|
+
transformed = self._transform(entry)
|
|
43
|
+
if transformed:
|
|
44
|
+
items.append(transformed)
|
|
45
|
+
if not items:
|
|
46
|
+
self._clear()
|
|
47
|
+
return
|
|
48
|
+
self._clear()
|
|
49
|
+
self._insert(items)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class Book(DataStore):
|
|
53
|
+
_KEYS = ["t", "s", "S", "p"]
|
|
54
|
+
|
|
55
|
+
def _onmessage(self, msg: Item) -> None:
|
|
56
|
+
action = msg["action"]
|
|
57
|
+
inst_type = msg["arg"]["instType"]
|
|
58
|
+
inst_id = msg["arg"]["instId"]
|
|
59
|
+
|
|
60
|
+
data_to_insert = []
|
|
61
|
+
data_to_update = []
|
|
62
|
+
data_to_delete = []
|
|
63
|
+
for book in msg["data"]:
|
|
64
|
+
for side in ("asks", "bids"):
|
|
65
|
+
for row in book[side]:
|
|
66
|
+
converted_row = {
|
|
67
|
+
"t": inst_type,
|
|
68
|
+
"s": inst_id,
|
|
69
|
+
"S": side[0],
|
|
70
|
+
"p": row[0],
|
|
71
|
+
"q": row[1],
|
|
72
|
+
}
|
|
73
|
+
if action == "snapshot":
|
|
74
|
+
data_to_insert.append(converted_row)
|
|
75
|
+
elif converted_row["q"] != "0":
|
|
76
|
+
data_to_update.append(converted_row)
|
|
77
|
+
else:
|
|
78
|
+
data_to_delete.append(converted_row)
|
|
79
|
+
|
|
80
|
+
# Cleanup on reconnect
|
|
81
|
+
if action == "snapshot":
|
|
82
|
+
self._find_and_delete({"t": inst_type, "s": inst_id})
|
|
83
|
+
|
|
84
|
+
self._insert(data_to_insert)
|
|
85
|
+
self._update(data_to_update)
|
|
86
|
+
self._delete(data_to_delete)
|
|
87
|
+
|
|
88
|
+
def sorted(
|
|
89
|
+
self, query: Item | None = None, limit: int | None = None
|
|
90
|
+
) -> dict[str, list[Item]]:
|
|
91
|
+
return self._sorted(
|
|
92
|
+
item_key="side",
|
|
93
|
+
item_asc_key="a",
|
|
94
|
+
item_desc_key="b",
|
|
95
|
+
sort_key="p",
|
|
96
|
+
query=query,
|
|
97
|
+
limit=limit,
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
class BitgetDataStore(BitgetV2DataStore):
|
|
102
|
+
|
|
103
|
+
def _init(self):
|
|
104
|
+
super()._init()
|
|
105
|
+
self._create('detail', datastore_class=Detail)
|
|
106
|
+
self._create("book", datastore_class=Book)
|
|
107
|
+
|
|
108
|
+
async def initialize(self, *aws: Awaitable[ClientResponse]) -> None:
|
|
109
|
+
for fut in asyncio.as_completed(aws):
|
|
110
|
+
res = await fut
|
|
111
|
+
data = await res.json()
|
|
112
|
+
if res.url.path == '/api/v2/mix/market/contracts':
|
|
113
|
+
self.detail._onresponse(data)
|
|
114
|
+
elif res.url.path == '/api/v2/mix/market/tickers':
|
|
115
|
+
self.ticker._clear()
|
|
116
|
+
tickers = data.get('data', [])
|
|
117
|
+
# 为每个ticker添加额外的字段
|
|
118
|
+
for ticker in tickers:
|
|
119
|
+
symbol = ticker.get('symbol')
|
|
120
|
+
ticker['instId'] = symbol
|
|
121
|
+
ticker['instType'] = 'futures'
|
|
122
|
+
|
|
123
|
+
self.ticker._update(tickers)
|
|
124
|
+
|
|
125
|
+
@property
|
|
126
|
+
def detail(self) -> Detail:
|
|
127
|
+
"""
|
|
128
|
+
_key: symbol
|
|
129
|
+
|
|
130
|
+
Data Structure:
|
|
131
|
+
|
|
132
|
+
.. code:: json
|
|
133
|
+
|
|
134
|
+
[
|
|
135
|
+
{
|
|
136
|
+
"symbol": "BTCUSDT",
|
|
137
|
+
"baseCoin": "BTC",
|
|
138
|
+
"quoteCoin": "USDT",
|
|
139
|
+
"buyLimitPriceRatio": "0.9",
|
|
140
|
+
"sellLimitPriceRatio": "0.9",
|
|
141
|
+
"feeRateUpRatio": "0.1",
|
|
142
|
+
"makerFeeRate": "0.0004",
|
|
143
|
+
"takerFeeRate": "0.0006",
|
|
144
|
+
"openCostUpRatio": "0.1",
|
|
145
|
+
"supportMarginCoins": [
|
|
146
|
+
"USDT"
|
|
147
|
+
],
|
|
148
|
+
"minTradeNum": "0.01",
|
|
149
|
+
"priceEndStep": "1",
|
|
150
|
+
"volumePlace": "2",
|
|
151
|
+
"stepSize": "0.01",
|
|
152
|
+
"tickSize": "0.1",
|
|
153
|
+
"pricePlace": "1",
|
|
154
|
+
"sizeMultiplier": "0.01",
|
|
155
|
+
"symbolType": "perpetual",
|
|
156
|
+
"minTradeUSDT": "5",
|
|
157
|
+
"maxSymbolOrderNum": "999999",
|
|
158
|
+
"maxProductOrderNum": "999999",
|
|
159
|
+
"maxPositionNum": "150",
|
|
160
|
+
"symbolStatus": "normal",
|
|
161
|
+
"offTime": "-1",
|
|
162
|
+
"limitOpenTime": "-1",
|
|
163
|
+
"deliveryTime": "",
|
|
164
|
+
"deliveryStartTime": "",
|
|
165
|
+
"launchTime": "",
|
|
166
|
+
"fundInterval": "8",
|
|
167
|
+
"minLever": "1",
|
|
168
|
+
"maxLever": "125",
|
|
169
|
+
"posLimit": "0.05",
|
|
170
|
+
"maintainTime": "1680165535278",
|
|
171
|
+
"maxMarketOrderQty": "220",
|
|
172
|
+
"maxOrderQty": "1200"
|
|
173
|
+
}]
|
|
174
|
+
|
|
175
|
+
"""
|
|
176
|
+
return self._get('detail')
|
|
177
|
+
|
|
178
|
+
@property
|
|
179
|
+
def ticker(self) -> DataStore:
|
|
180
|
+
"""
|
|
181
|
+
_KEYS = ["instType", "instId"]
|
|
182
|
+
|
|
183
|
+
Data Structure:
|
|
184
|
+
|
|
185
|
+
.. code:: json
|
|
186
|
+
|
|
187
|
+
[
|
|
188
|
+
{
|
|
189
|
+
"symbol": "BTCUSDT",
|
|
190
|
+
"lastPr": "111534.6",
|
|
191
|
+
"askPr": "111534.6",
|
|
192
|
+
"bidPr": "111534.5",
|
|
193
|
+
"bidSz": "23.7924",
|
|
194
|
+
"askSz": "8.1762",
|
|
195
|
+
"high24h": "112300",
|
|
196
|
+
"low24h": "109136.2",
|
|
197
|
+
"ts": "1759115725508",
|
|
198
|
+
"change24h": "0.01906",
|
|
199
|
+
"baseVolume": "35520.11438048",
|
|
200
|
+
"quoteVolume": "3932280581.066103549",
|
|
201
|
+
"usdtVolume": "3932280581.066103549",
|
|
202
|
+
"openUtc": "112100",
|
|
203
|
+
"changeUtc24h": "-0.00504",
|
|
204
|
+
"indexPrice": "111587.6090439271505504",
|
|
205
|
+
"fundingRate": "-0.000002",
|
|
206
|
+
"holdingAmount": "66775.1917",
|
|
207
|
+
"deliveryStartTime": null,
|
|
208
|
+
"deliveryTime": null,
|
|
209
|
+
"deliveryStatus": "",
|
|
210
|
+
"open24h": "109448.3",
|
|
211
|
+
"markPrice": "111537",
|
|
212
|
+
"instId": "BTCUSDT",
|
|
213
|
+
"instType": "futures"
|
|
214
|
+
}
|
|
215
|
+
]
|
|
216
|
+
"""
|
|
217
|
+
return self._get('ticker')
|
|
218
|
+
|
|
219
|
+
@property
|
|
220
|
+
def orders(self) -> DataStore:
|
|
221
|
+
"""
|
|
222
|
+
_KEYS = ["instType", "instId", "orderId"]
|
|
223
|
+
.. code:: json
|
|
224
|
+
|
|
225
|
+
[
|
|
226
|
+
{
|
|
227
|
+
"instType": "futures",
|
|
228
|
+
"instId": "BTCUSDT",
|
|
229
|
+
"orderId": "1",
|
|
230
|
+
"clientOid": "1",
|
|
231
|
+
"size": "8.0000",
|
|
232
|
+
"newSize": "500.0000",
|
|
233
|
+
"notional": "8.000000",
|
|
234
|
+
"orderType": "market",
|
|
235
|
+
"force": "gtc",
|
|
236
|
+
"side": "buy",
|
|
237
|
+
"fillPrice": "26256.0",
|
|
238
|
+
"tradeId": "1",
|
|
239
|
+
"baseVolume": "0.0003",
|
|
240
|
+
"fillTime": "1695797773286",
|
|
241
|
+
"fillFee": "-0.00000018",
|
|
242
|
+
"fillFeeCoin": "BTC",
|
|
243
|
+
"tradeScope": "T",
|
|
244
|
+
"accBaseVolume": "0.0003",
|
|
245
|
+
"priceAvg": "26256.0",
|
|
246
|
+
"status": "partially_filled",
|
|
247
|
+
"cTime": "1695797773257",
|
|
248
|
+
"uTime": "1695797773326",
|
|
249
|
+
"stpMode": "cancel_taker",
|
|
250
|
+
"feeDetail": [
|
|
251
|
+
{
|
|
252
|
+
"feeCoin": "BTC",
|
|
253
|
+
"fee": "-0.00000018"
|
|
254
|
+
}
|
|
255
|
+
],
|
|
256
|
+
"enterPointSource": "WEB"
|
|
257
|
+
}
|
|
258
|
+
]
|
|
259
|
+
"""
|
|
260
|
+
return self._get('orders')
|
|
261
|
+
|
|
262
|
+
@property
|
|
263
|
+
def book(self) -> DataStore:
|
|
264
|
+
"""
|
|
265
|
+
_KEYS = ["t", "s", "S", "p"]
|
|
266
|
+
|
|
267
|
+
Data Structure:
|
|
268
|
+
|
|
269
|
+
.. code:: json
|
|
270
|
+
|
|
271
|
+
[
|
|
272
|
+
{
|
|
273
|
+
"t": "futures",
|
|
274
|
+
"s": "BTCUSDT",
|
|
275
|
+
"S": "a",
|
|
276
|
+
"p": "111534.6",
|
|
277
|
+
"q": "8.1762"
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
"t": "futures",
|
|
281
|
+
"s": "BTCUSDT",
|
|
282
|
+
"S": "b",
|
|
283
|
+
"p": "111534.5",
|
|
284
|
+
"q": "23.7924"
|
|
285
|
+
}
|
|
286
|
+
]
|
|
287
|
+
"""
|
|
288
|
+
return self._get("book")
|
|
289
|
+
|
|
290
|
+
@property
|
|
291
|
+
def account(self) -> DataStore:
|
|
292
|
+
"""
|
|
293
|
+
_KEYS = ["instType", "marginCoin"]
|
|
294
|
+
|
|
295
|
+
Data Structure:
|
|
296
|
+
|
|
297
|
+
.. code:: json
|
|
298
|
+
|
|
299
|
+
[
|
|
300
|
+
{
|
|
301
|
+
"marginCoin": "USDT",
|
|
302
|
+
"frozen": "0.00000000",
|
|
303
|
+
"available": "13.98545761",
|
|
304
|
+
"maxOpenPosAvailable": "13.98545761",
|
|
305
|
+
"maxTransferOut": "13.98545761",
|
|
306
|
+
"equity": "13.98545761",
|
|
307
|
+
"usdtEquity": "13.985457617660",
|
|
308
|
+
"crossedRiskRate": "0",
|
|
309
|
+
"unrealizedPL": "0.000000000000",
|
|
310
|
+
"unionTotalMargin": "100",
|
|
311
|
+
"unionAvailable": "20",
|
|
312
|
+
"unionMm": "15",
|
|
313
|
+
"assetMode": "union"
|
|
314
|
+
}
|
|
315
|
+
]
|
|
316
|
+
"""
|
|
317
|
+
return self._get("account")
|
|
318
|
+
|
|
319
|
+
@property
|
|
320
|
+
def position(self) -> DataStore:
|
|
321
|
+
"""
|
|
322
|
+
_KEYS = ["instType", "instId", "posId"]
|
|
323
|
+
|
|
324
|
+
Data Structure:
|
|
325
|
+
|
|
326
|
+
.. code:: json
|
|
327
|
+
|
|
328
|
+
[
|
|
329
|
+
{
|
|
330
|
+
"posId": "1",
|
|
331
|
+
"instId": "ETHUSDT",
|
|
332
|
+
"marginCoin": "USDT",
|
|
333
|
+
"marginSize": "9.5",
|
|
334
|
+
"marginMode": "crossed",
|
|
335
|
+
"holdSide": "short",
|
|
336
|
+
"posMode": "hedge_mode",
|
|
337
|
+
"total": "0.1",
|
|
338
|
+
"available": "0.1",
|
|
339
|
+
"frozen": "0",
|
|
340
|
+
"openPriceAvg": "1900",
|
|
341
|
+
"leverage": 20,
|
|
342
|
+
"achievedProfits": "0",
|
|
343
|
+
"unrealizedPL": "0",
|
|
344
|
+
"unrealizedPLR": "0",
|
|
345
|
+
"liquidationPrice": "5788.108475905242",
|
|
346
|
+
"keepMarginRate": "0.005",
|
|
347
|
+
"marginRate": "0.004416374196",
|
|
348
|
+
"cTime": "1695649246169",
|
|
349
|
+
"breakEvenPrice": "24778.97",
|
|
350
|
+
"totalFee": "1.45",
|
|
351
|
+
"deductedFee": "0.388",
|
|
352
|
+
"markPrice": "2500",
|
|
353
|
+
"assetMode": "union",
|
|
354
|
+
"uTime": "1695711602568",
|
|
355
|
+
"autoMargin": "off"
|
|
356
|
+
}
|
|
357
|
+
]
|
|
358
|
+
"""
|
|
359
|
+
return self._get("position")
|