decibel-python-sdk 0.1.0__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.
- decibel/__init__.py +247 -0
- decibel/_base.py +726 -0
- decibel/_constants.py +164 -0
- decibel/_fee_pay.py +301 -0
- decibel/_gas_price_manager.py +262 -0
- decibel/_order_status.py +138 -0
- decibel/_order_types.py +109 -0
- decibel/_pagination.py +82 -0
- decibel/_subaccount_types.py +43 -0
- decibel/_transaction_builder.py +325 -0
- decibel/_utils.py +432 -0
- decibel/_version.py +1 -0
- decibel/abi/__init__.py +23 -0
- decibel/abi/__main__.py +4 -0
- decibel/abi/_registry.py +89 -0
- decibel/abi/_types.py +55 -0
- decibel/abi/generate.py +183 -0
- decibel/abi/json/netna.json +2417 -0
- decibel/abi/json/testnet.json +2919 -0
- decibel/admin.py +868 -0
- decibel/py.typed +0 -0
- decibel/read/__init__.py +279 -0
- decibel/read/_account_overview.py +119 -0
- decibel/read/_base.py +137 -0
- decibel/read/_candlesticks.py +97 -0
- decibel/read/_delegations.py +32 -0
- decibel/read/_leaderboard.py +64 -0
- decibel/read/_market_contexts.py +35 -0
- decibel/read/_market_depth.py +81 -0
- decibel/read/_market_prices.py +100 -0
- decibel/read/_market_trades.py +81 -0
- decibel/read/_markets.py +146 -0
- decibel/read/_portfolio_chart.py +48 -0
- decibel/read/_trading_points.py +36 -0
- decibel/read/_types.py +136 -0
- decibel/read/_user_active_twaps.py +70 -0
- decibel/read/_user_bulk_orders.py +73 -0
- decibel/read/_user_fund_history.py +49 -0
- decibel/read/_user_funding_history.py +45 -0
- decibel/read/_user_notifications.py +87 -0
- decibel/read/_user_open_orders.py +91 -0
- decibel/read/_user_order_history.py +101 -0
- decibel/read/_user_positions.py +84 -0
- decibel/read/_user_subaccounts.py +35 -0
- decibel/read/_user_trade_history.py +77 -0
- decibel/read/_user_twap_history.py +32 -0
- decibel/read/_vaults.py +218 -0
- decibel/read/_ws.py +245 -0
- decibel/write/__init__.py +1949 -0
- decibel/write/_types.py +190 -0
- decibel_python_sdk-0.1.0.dist-info/METADATA +255 -0
- decibel_python_sdk-0.1.0.dist-info/RECORD +53 -0
- decibel_python_sdk-0.1.0.dist-info/WHEEL +4 -0
decibel/py.typed
ADDED
|
File without changes
|
decibel/read/__init__.py
ADDED
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
from aptos_sdk.async_client import RestClient
|
|
6
|
+
|
|
7
|
+
from ._account_overview import (
|
|
8
|
+
AccountOverview,
|
|
9
|
+
AccountOverviewReader,
|
|
10
|
+
AccountOverviewWsMessage,
|
|
11
|
+
VolumeWindow,
|
|
12
|
+
)
|
|
13
|
+
from ._base import ReaderDeps
|
|
14
|
+
from ._candlesticks import (
|
|
15
|
+
Candlestick,
|
|
16
|
+
CandlestickInterval,
|
|
17
|
+
CandlesticksReader,
|
|
18
|
+
CandlestickWsMessage,
|
|
19
|
+
)
|
|
20
|
+
from ._delegations import Delegation, DelegationsReader
|
|
21
|
+
from ._leaderboard import (
|
|
22
|
+
LeaderboardItem,
|
|
23
|
+
LeaderboardReader,
|
|
24
|
+
LeaderboardResponse,
|
|
25
|
+
LeaderboardSortKey,
|
|
26
|
+
)
|
|
27
|
+
from ._market_contexts import MarketContext, MarketContextsReader
|
|
28
|
+
from ._market_depth import (
|
|
29
|
+
MarketDepth,
|
|
30
|
+
MarketDepthAggregationSize,
|
|
31
|
+
MarketDepthReader,
|
|
32
|
+
MarketDepthWsMessage,
|
|
33
|
+
MarketOrder,
|
|
34
|
+
)
|
|
35
|
+
from ._market_prices import (
|
|
36
|
+
AllMarketPricesWsMessage,
|
|
37
|
+
MarketPrice,
|
|
38
|
+
MarketPricesReader,
|
|
39
|
+
MarketPriceWsMessage,
|
|
40
|
+
)
|
|
41
|
+
from ._market_trades import (
|
|
42
|
+
MarketTrade,
|
|
43
|
+
MarketTradesReader,
|
|
44
|
+
MarketTradesResponse,
|
|
45
|
+
MarketTradeWsMessage,
|
|
46
|
+
)
|
|
47
|
+
from ._markets import (
|
|
48
|
+
MarketMode,
|
|
49
|
+
MarketModeConfig,
|
|
50
|
+
MarketsReader,
|
|
51
|
+
PerpMarket,
|
|
52
|
+
PerpMarketConfig,
|
|
53
|
+
SzPrecision,
|
|
54
|
+
)
|
|
55
|
+
from ._portfolio_chart import (
|
|
56
|
+
PortfolioChartItem,
|
|
57
|
+
PortfolioChartReader,
|
|
58
|
+
PortfolioChartTimeRange,
|
|
59
|
+
PortfolioChartType,
|
|
60
|
+
)
|
|
61
|
+
from ._trading_points import (
|
|
62
|
+
OwnerTradingPoints,
|
|
63
|
+
SubaccountPoints,
|
|
64
|
+
TradingPointsReader,
|
|
65
|
+
)
|
|
66
|
+
from ._types import (
|
|
67
|
+
ActivateVaultArgs,
|
|
68
|
+
AssetType,
|
|
69
|
+
BalanceTable,
|
|
70
|
+
CollateralBalanceSheet,
|
|
71
|
+
CreateVaultArgs,
|
|
72
|
+
CrossedPosition,
|
|
73
|
+
DepositToVaultArgs,
|
|
74
|
+
GlobalAccountsState,
|
|
75
|
+
GlobalAccountsStateV1,
|
|
76
|
+
LiquidationConfigV1,
|
|
77
|
+
PerpPosition,
|
|
78
|
+
Precision,
|
|
79
|
+
Store,
|
|
80
|
+
StoreExtendRef,
|
|
81
|
+
WithdrawFromVaultArgs,
|
|
82
|
+
)
|
|
83
|
+
from ._user_active_twaps import (
|
|
84
|
+
TwapStatus,
|
|
85
|
+
UserActiveTwap,
|
|
86
|
+
UserActiveTwapsReader,
|
|
87
|
+
UserActiveTwapsWsMessage,
|
|
88
|
+
)
|
|
89
|
+
from ._user_bulk_orders import (
|
|
90
|
+
UserBulkOrder,
|
|
91
|
+
UserBulkOrdersReader,
|
|
92
|
+
UserBulkOrderWsMessage,
|
|
93
|
+
)
|
|
94
|
+
from ._user_fund_history import (
|
|
95
|
+
FundMovementType,
|
|
96
|
+
UserFund,
|
|
97
|
+
UserFundHistoryReader,
|
|
98
|
+
UserFundHistoryResponse,
|
|
99
|
+
)
|
|
100
|
+
from ._user_funding_history import (
|
|
101
|
+
UserFunding,
|
|
102
|
+
UserFundingHistoryReader,
|
|
103
|
+
UserFundingHistoryResponse,
|
|
104
|
+
)
|
|
105
|
+
from ._user_notifications import (
|
|
106
|
+
NotificationMetadata,
|
|
107
|
+
NotificationType,
|
|
108
|
+
UserNotificationsReader,
|
|
109
|
+
UserNotificationWsMessage,
|
|
110
|
+
)
|
|
111
|
+
from ._user_open_orders import (
|
|
112
|
+
UserOpenOrder,
|
|
113
|
+
UserOpenOrdersReader,
|
|
114
|
+
UserOpenOrdersResponse,
|
|
115
|
+
UserOpenOrdersWsMessage,
|
|
116
|
+
)
|
|
117
|
+
from ._user_order_history import (
|
|
118
|
+
UserOrder,
|
|
119
|
+
UserOrderHistoryReader,
|
|
120
|
+
UserOrders,
|
|
121
|
+
UserOrdersWsMessage,
|
|
122
|
+
)
|
|
123
|
+
from ._user_positions import (
|
|
124
|
+
UserPosition,
|
|
125
|
+
UserPositionsReader,
|
|
126
|
+
UserPositionsWsMessage,
|
|
127
|
+
)
|
|
128
|
+
from ._user_subaccounts import UserSubaccount, UserSubaccountsReader
|
|
129
|
+
from ._user_trade_history import (
|
|
130
|
+
UserTrade,
|
|
131
|
+
UserTradeAction,
|
|
132
|
+
UserTradeHistoryReader,
|
|
133
|
+
UserTradesResponse,
|
|
134
|
+
UserTradesWsMessage,
|
|
135
|
+
)
|
|
136
|
+
from ._user_twap_history import UserTwapHistoryReader, UserTwapHistoryResponse
|
|
137
|
+
from ._vaults import (
|
|
138
|
+
UserOwnedVault,
|
|
139
|
+
UserOwnedVaultsResponse,
|
|
140
|
+
UserPerformanceOnVault,
|
|
141
|
+
Vault,
|
|
142
|
+
VaultDeposit,
|
|
143
|
+
VaultsReader,
|
|
144
|
+
VaultsResponse,
|
|
145
|
+
VaultType,
|
|
146
|
+
VaultWithdrawal,
|
|
147
|
+
)
|
|
148
|
+
from ._ws import DecibelWsSubscription, Unsubscribe
|
|
149
|
+
|
|
150
|
+
if TYPE_CHECKING:
|
|
151
|
+
from collections.abc import Callable
|
|
152
|
+
|
|
153
|
+
from .._constants import DecibelConfig
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
class DecibelReadDex:
|
|
157
|
+
def __init__(
|
|
158
|
+
self,
|
|
159
|
+
config: DecibelConfig,
|
|
160
|
+
*,
|
|
161
|
+
api_key: str | None = None,
|
|
162
|
+
on_ws_error: Callable[[Exception], None] | None = None,
|
|
163
|
+
) -> None:
|
|
164
|
+
aptos = RestClient(config.fullnode_url)
|
|
165
|
+
ws = DecibelWsSubscription(config, api_key, on_ws_error)
|
|
166
|
+
deps = ReaderDeps(config=config, ws=ws, aptos=aptos, api_key=api_key)
|
|
167
|
+
|
|
168
|
+
self.ws = ws
|
|
169
|
+
self.account_overview = AccountOverviewReader(deps)
|
|
170
|
+
self.candlesticks = CandlesticksReader(deps)
|
|
171
|
+
self.delegations = DelegationsReader(deps)
|
|
172
|
+
self.leaderboard = LeaderboardReader(deps)
|
|
173
|
+
self.markets = MarketsReader(deps)
|
|
174
|
+
self.market_prices = MarketPricesReader(deps)
|
|
175
|
+
self.market_depth = MarketDepthReader(deps)
|
|
176
|
+
self.market_trades = MarketTradesReader(deps)
|
|
177
|
+
self.market_contexts = MarketContextsReader(deps)
|
|
178
|
+
self.portfolio_chart = PortfolioChartReader(deps)
|
|
179
|
+
self.user_positions = UserPositionsReader(deps)
|
|
180
|
+
self.user_open_orders = UserOpenOrdersReader(deps)
|
|
181
|
+
self.user_order_history = UserOrderHistoryReader(deps)
|
|
182
|
+
self.user_trade_history = UserTradeHistoryReader(deps)
|
|
183
|
+
self.user_bulk_orders = UserBulkOrdersReader(deps)
|
|
184
|
+
self.user_subaccounts = UserSubaccountsReader(deps)
|
|
185
|
+
self.user_fund_history = UserFundHistoryReader(deps)
|
|
186
|
+
self.user_funding_history = UserFundingHistoryReader(deps)
|
|
187
|
+
self.user_active_twaps = UserActiveTwapsReader(deps)
|
|
188
|
+
self.user_twap_history = UserTwapHistoryReader(deps)
|
|
189
|
+
self.user_notifications = UserNotificationsReader(deps)
|
|
190
|
+
self.vaults = VaultsReader(deps)
|
|
191
|
+
self.trading_points = TradingPointsReader(deps)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
__all__ = [
|
|
195
|
+
"AccountOverview",
|
|
196
|
+
"AccountOverviewWsMessage",
|
|
197
|
+
"ActivateVaultArgs",
|
|
198
|
+
"AllMarketPricesWsMessage",
|
|
199
|
+
"AssetType",
|
|
200
|
+
"BalanceTable",
|
|
201
|
+
"Candlestick",
|
|
202
|
+
"CandlestickInterval",
|
|
203
|
+
"CandlestickWsMessage",
|
|
204
|
+
"CollateralBalanceSheet",
|
|
205
|
+
"CreateVaultArgs",
|
|
206
|
+
"CrossedPosition",
|
|
207
|
+
"DecibelReadDex",
|
|
208
|
+
"Delegation",
|
|
209
|
+
"DepositToVaultArgs",
|
|
210
|
+
"FundMovementType",
|
|
211
|
+
"GlobalAccountsState",
|
|
212
|
+
"GlobalAccountsStateV1",
|
|
213
|
+
"LeaderboardItem",
|
|
214
|
+
"LeaderboardResponse",
|
|
215
|
+
"LeaderboardSortKey",
|
|
216
|
+
"LiquidationConfigV1",
|
|
217
|
+
"MarketContext",
|
|
218
|
+
"MarketDepth",
|
|
219
|
+
"MarketDepthAggregationSize",
|
|
220
|
+
"MarketDepthWsMessage",
|
|
221
|
+
"MarketMode",
|
|
222
|
+
"MarketModeConfig",
|
|
223
|
+
"MarketOrder",
|
|
224
|
+
"MarketPrice",
|
|
225
|
+
"MarketPriceWsMessage",
|
|
226
|
+
"MarketTrade",
|
|
227
|
+
"MarketTradesResponse",
|
|
228
|
+
"MarketTradeWsMessage",
|
|
229
|
+
"NotificationMetadata",
|
|
230
|
+
"NotificationType",
|
|
231
|
+
"OwnerTradingPoints",
|
|
232
|
+
"PerpMarket",
|
|
233
|
+
"PerpMarketConfig",
|
|
234
|
+
"PerpPosition",
|
|
235
|
+
"PortfolioChartItem",
|
|
236
|
+
"PortfolioChartTimeRange",
|
|
237
|
+
"PortfolioChartType",
|
|
238
|
+
"Precision",
|
|
239
|
+
"Store",
|
|
240
|
+
"StoreExtendRef",
|
|
241
|
+
"SubaccountPoints",
|
|
242
|
+
"SzPrecision",
|
|
243
|
+
"TradingPointsReader",
|
|
244
|
+
"TwapStatus",
|
|
245
|
+
"Unsubscribe",
|
|
246
|
+
"UserActiveTwap",
|
|
247
|
+
"UserActiveTwapsWsMessage",
|
|
248
|
+
"UserBulkOrder",
|
|
249
|
+
"UserBulkOrderWsMessage",
|
|
250
|
+
"UserFund",
|
|
251
|
+
"UserFundHistoryResponse",
|
|
252
|
+
"UserFunding",
|
|
253
|
+
"UserFundingHistoryResponse",
|
|
254
|
+
"UserNotificationWsMessage",
|
|
255
|
+
"UserOpenOrder",
|
|
256
|
+
"UserOpenOrdersResponse",
|
|
257
|
+
"UserOpenOrdersWsMessage",
|
|
258
|
+
"UserOrder",
|
|
259
|
+
"UserOrders",
|
|
260
|
+
"UserOrdersWsMessage",
|
|
261
|
+
"UserOwnedVault",
|
|
262
|
+
"UserOwnedVaultsResponse",
|
|
263
|
+
"UserPerformanceOnVault",
|
|
264
|
+
"UserPosition",
|
|
265
|
+
"UserPositionsWsMessage",
|
|
266
|
+
"UserSubaccount",
|
|
267
|
+
"UserTrade",
|
|
268
|
+
"UserTradeAction",
|
|
269
|
+
"UserTradesResponse",
|
|
270
|
+
"UserTradesWsMessage",
|
|
271
|
+
"UserTwapHistoryResponse",
|
|
272
|
+
"Vault",
|
|
273
|
+
"VaultDeposit",
|
|
274
|
+
"VaultsResponse",
|
|
275
|
+
"VaultType",
|
|
276
|
+
"VaultWithdrawal",
|
|
277
|
+
"VolumeWindow",
|
|
278
|
+
"WithdrawFromVaultArgs",
|
|
279
|
+
]
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from enum import StrEnum
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel, ConfigDict
|
|
7
|
+
|
|
8
|
+
from ._base import BaseReader
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from collections.abc import Awaitable, Callable
|
|
12
|
+
|
|
13
|
+
from ._ws import Unsubscribe
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"AccountOverview",
|
|
17
|
+
"AccountOverviewReader",
|
|
18
|
+
"AccountOverviewWsMessage",
|
|
19
|
+
"VolumeWindow",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class VolumeWindow(StrEnum):
|
|
24
|
+
SEVEN_DAYS = "7d"
|
|
25
|
+
FOURTEEN_DAYS = "14d"
|
|
26
|
+
THIRTY_DAYS = "30d"
|
|
27
|
+
NINETY_DAYS = "90d"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class AccountOverview(BaseModel):
|
|
31
|
+
model_config = ConfigDict(populate_by_name=True)
|
|
32
|
+
|
|
33
|
+
perp_equity_balance: float
|
|
34
|
+
unrealized_pnl: float
|
|
35
|
+
unrealized_funding_cost: float
|
|
36
|
+
cross_margin_ratio: float
|
|
37
|
+
maintenance_margin: float
|
|
38
|
+
cross_account_leverage_ratio: float | None
|
|
39
|
+
volume: float | None
|
|
40
|
+
net_deposits: float | None = None
|
|
41
|
+
all_time_return: float | None
|
|
42
|
+
pnl_90d: float | None
|
|
43
|
+
sharpe_ratio: float | None
|
|
44
|
+
max_drawdown: float | None
|
|
45
|
+
weekly_win_rate_12w: float | None
|
|
46
|
+
average_cash_position: float | None
|
|
47
|
+
average_leverage: float | None
|
|
48
|
+
cross_account_position: float
|
|
49
|
+
total_margin: float
|
|
50
|
+
usdc_cross_withdrawable_balance: float
|
|
51
|
+
usdc_isolated_withdrawable_balance: float
|
|
52
|
+
realized_pnl: float | None
|
|
53
|
+
liquidation_fees_paid: float | None
|
|
54
|
+
liquidation_losses: float | None
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class _AccountOverviewWs(BaseModel):
|
|
58
|
+
model_config = ConfigDict(populate_by_name=True)
|
|
59
|
+
|
|
60
|
+
perp_equity_balance: float
|
|
61
|
+
unrealized_pnl: float
|
|
62
|
+
unrealized_funding_cost: float
|
|
63
|
+
cross_margin_ratio: float
|
|
64
|
+
maintenance_margin: float
|
|
65
|
+
cross_account_leverage_ratio: float | None
|
|
66
|
+
net_deposits: float | None = None
|
|
67
|
+
all_time_return: float | None
|
|
68
|
+
pnl_90d: float | None
|
|
69
|
+
sharpe_ratio: float | None
|
|
70
|
+
max_drawdown: float | None
|
|
71
|
+
weekly_win_rate_12w: float | None
|
|
72
|
+
average_cash_position: float | None
|
|
73
|
+
average_leverage: float | None
|
|
74
|
+
cross_account_position: float
|
|
75
|
+
total_margin: float
|
|
76
|
+
usdc_cross_withdrawable_balance: float
|
|
77
|
+
usdc_isolated_withdrawable_balance: float
|
|
78
|
+
realized_pnl: float | None
|
|
79
|
+
liquidation_fees_paid: float | None
|
|
80
|
+
liquidation_losses: float | None
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class AccountOverviewWsMessage(BaseModel):
|
|
84
|
+
model_config = ConfigDict(populate_by_name=True)
|
|
85
|
+
|
|
86
|
+
account_overview: _AccountOverviewWs
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class AccountOverviewReader(BaseReader):
|
|
90
|
+
async def get_by_addr(
|
|
91
|
+
self,
|
|
92
|
+
*,
|
|
93
|
+
sub_addr: str,
|
|
94
|
+
volume_window: VolumeWindow | None = None,
|
|
95
|
+
include_performance: bool = False,
|
|
96
|
+
) -> AccountOverview:
|
|
97
|
+
params: dict[str, str] = {"account": sub_addr}
|
|
98
|
+
if volume_window is not None:
|
|
99
|
+
params["volume_window"] = volume_window.value
|
|
100
|
+
if include_performance:
|
|
101
|
+
params["include_performance"] = "true"
|
|
102
|
+
|
|
103
|
+
response, _, _ = await self.get_request(
|
|
104
|
+
model=AccountOverview,
|
|
105
|
+
url=f"{self.config.trading_http_url}/api/v1/account_overviews",
|
|
106
|
+
params=params,
|
|
107
|
+
)
|
|
108
|
+
return response
|
|
109
|
+
|
|
110
|
+
def subscribe_by_addr(
|
|
111
|
+
self,
|
|
112
|
+
sub_addr: str,
|
|
113
|
+
on_data: (
|
|
114
|
+
Callable[[AccountOverviewWsMessage], None]
|
|
115
|
+
| Callable[[AccountOverviewWsMessage], Awaitable[None]]
|
|
116
|
+
),
|
|
117
|
+
) -> Unsubscribe:
|
|
118
|
+
topic = f"account_overview:{sub_addr}"
|
|
119
|
+
return self.ws.subscribe(topic, AccountOverviewWsMessage, on_data)
|
decibel/read/_base.py
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import TYPE_CHECKING, Any, TypeVar
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel
|
|
7
|
+
|
|
8
|
+
from .._utils import (
|
|
9
|
+
get_request,
|
|
10
|
+
get_request_sync,
|
|
11
|
+
patch_request,
|
|
12
|
+
patch_request_sync,
|
|
13
|
+
post_request,
|
|
14
|
+
post_request_sync,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from aptos_sdk.async_client import RestClient
|
|
19
|
+
|
|
20
|
+
from .._constants import DecibelConfig
|
|
21
|
+
from ._ws import DecibelWsSubscription
|
|
22
|
+
|
|
23
|
+
__all__ = [
|
|
24
|
+
"ReaderDeps",
|
|
25
|
+
"BaseReader",
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
T = TypeVar("T", bound=BaseModel)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@dataclass
|
|
32
|
+
class ReaderDeps:
|
|
33
|
+
config: DecibelConfig
|
|
34
|
+
ws: DecibelWsSubscription
|
|
35
|
+
aptos: RestClient
|
|
36
|
+
api_key: str | None = None
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class BaseReader:
|
|
40
|
+
def __init__(self, deps: ReaderDeps) -> None:
|
|
41
|
+
self._deps = deps
|
|
42
|
+
|
|
43
|
+
@property
|
|
44
|
+
def config(self) -> DecibelConfig:
|
|
45
|
+
return self._deps.config
|
|
46
|
+
|
|
47
|
+
@property
|
|
48
|
+
def ws(self) -> DecibelWsSubscription:
|
|
49
|
+
return self._deps.ws
|
|
50
|
+
|
|
51
|
+
@property
|
|
52
|
+
def aptos(self) -> RestClient:
|
|
53
|
+
return self._deps.aptos
|
|
54
|
+
|
|
55
|
+
async def get_request(
|
|
56
|
+
self,
|
|
57
|
+
model: type[T],
|
|
58
|
+
url: str,
|
|
59
|
+
*,
|
|
60
|
+
params: dict[str, Any] | None = None,
|
|
61
|
+
) -> tuple[T, int, str]:
|
|
62
|
+
return await get_request(
|
|
63
|
+
model=model,
|
|
64
|
+
url=url,
|
|
65
|
+
params=params,
|
|
66
|
+
api_key=self._deps.api_key,
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
async def post_request(
|
|
70
|
+
self,
|
|
71
|
+
model: type[T],
|
|
72
|
+
url: str,
|
|
73
|
+
*,
|
|
74
|
+
body: Any | None = None,
|
|
75
|
+
) -> tuple[T, int, str]:
|
|
76
|
+
return await post_request(
|
|
77
|
+
model=model,
|
|
78
|
+
url=url,
|
|
79
|
+
body=body,
|
|
80
|
+
api_key=self._deps.api_key,
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
async def patch_request(
|
|
84
|
+
self,
|
|
85
|
+
model: type[T],
|
|
86
|
+
url: str,
|
|
87
|
+
*,
|
|
88
|
+
body: Any | None = None,
|
|
89
|
+
) -> tuple[T, int, str]:
|
|
90
|
+
return await patch_request(
|
|
91
|
+
model=model,
|
|
92
|
+
url=url,
|
|
93
|
+
body=body,
|
|
94
|
+
api_key=self._deps.api_key,
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
def get_request_sync(
|
|
98
|
+
self,
|
|
99
|
+
model: type[T],
|
|
100
|
+
url: str,
|
|
101
|
+
*,
|
|
102
|
+
params: dict[str, Any] | None = None,
|
|
103
|
+
) -> tuple[T, int, str]:
|
|
104
|
+
return get_request_sync(
|
|
105
|
+
model=model,
|
|
106
|
+
url=url,
|
|
107
|
+
params=params,
|
|
108
|
+
api_key=self._deps.api_key,
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
def post_request_sync(
|
|
112
|
+
self,
|
|
113
|
+
model: type[T],
|
|
114
|
+
url: str,
|
|
115
|
+
*,
|
|
116
|
+
body: Any | None = None,
|
|
117
|
+
) -> tuple[T, int, str]:
|
|
118
|
+
return post_request_sync(
|
|
119
|
+
model=model,
|
|
120
|
+
url=url,
|
|
121
|
+
body=body,
|
|
122
|
+
api_key=self._deps.api_key,
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
def patch_request_sync(
|
|
126
|
+
self,
|
|
127
|
+
model: type[T],
|
|
128
|
+
url: str,
|
|
129
|
+
*,
|
|
130
|
+
body: Any | None = None,
|
|
131
|
+
) -> tuple[T, int, str]:
|
|
132
|
+
return patch_request_sync(
|
|
133
|
+
model=model,
|
|
134
|
+
url=url,
|
|
135
|
+
body=body,
|
|
136
|
+
api_key=self._deps.api_key,
|
|
137
|
+
)
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from enum import StrEnum
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel, ConfigDict, Field, RootModel
|
|
7
|
+
|
|
8
|
+
from .._utils import get_market_addr
|
|
9
|
+
from ._base import BaseReader
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from collections.abc import Awaitable, Callable
|
|
13
|
+
|
|
14
|
+
from ._ws import Unsubscribe
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"Candlestick",
|
|
18
|
+
"CandlestickInterval",
|
|
19
|
+
"CandlesticksReader",
|
|
20
|
+
"CandlestickWsMessage",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class CandlestickInterval(StrEnum):
|
|
25
|
+
ONE_MINUTE = "1m"
|
|
26
|
+
FIVE_MINUTES = "5m"
|
|
27
|
+
FIFTEEN_MINUTES = "15m"
|
|
28
|
+
THIRTY_MINUTES = "30m"
|
|
29
|
+
ONE_HOUR = "1h"
|
|
30
|
+
TWO_HOURS = "2h"
|
|
31
|
+
FOUR_HOURS = "4h"
|
|
32
|
+
EIGHT_HOURS = "8h"
|
|
33
|
+
TWELVE_HOURS = "12h"
|
|
34
|
+
ONE_DAY = "1d"
|
|
35
|
+
THREE_DAYS = "3d"
|
|
36
|
+
ONE_WEEK = "1w"
|
|
37
|
+
ONE_MONTH = "1mo"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class Candlestick(BaseModel):
|
|
41
|
+
model_config = ConfigDict(populate_by_name=True)
|
|
42
|
+
|
|
43
|
+
time_end: int = Field(alias="T")
|
|
44
|
+
close: float = Field(alias="c")
|
|
45
|
+
high: float = Field(alias="h")
|
|
46
|
+
interval: str = Field(alias="i")
|
|
47
|
+
low: float = Field(alias="l")
|
|
48
|
+
open_price: float = Field(alias="o")
|
|
49
|
+
time_start: int = Field(alias="t")
|
|
50
|
+
volume: float = Field(alias="v")
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class _CandlesticksList(RootModel[list[Candlestick]]):
|
|
54
|
+
pass
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class CandlestickWsMessage(BaseModel):
|
|
58
|
+
model_config = ConfigDict(populate_by_name=True)
|
|
59
|
+
|
|
60
|
+
candle: Candlestick
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class CandlesticksReader(BaseReader):
|
|
64
|
+
async def get_by_name(
|
|
65
|
+
self,
|
|
66
|
+
market_name: str,
|
|
67
|
+
*,
|
|
68
|
+
interval: CandlestickInterval,
|
|
69
|
+
start_time: int,
|
|
70
|
+
end_time: int,
|
|
71
|
+
) -> list[Candlestick]:
|
|
72
|
+
market_addr = get_market_addr(market_name, self.config.deployment.perp_engine_global)
|
|
73
|
+
|
|
74
|
+
response, _, _ = await self.get_request(
|
|
75
|
+
model=_CandlesticksList,
|
|
76
|
+
url=f"{self.config.trading_http_url}/api/v1/candlesticks",
|
|
77
|
+
params={
|
|
78
|
+
"market": market_addr,
|
|
79
|
+
"interval": interval.value,
|
|
80
|
+
"startTime": str(start_time),
|
|
81
|
+
"endTime": str(end_time),
|
|
82
|
+
},
|
|
83
|
+
)
|
|
84
|
+
return response.root
|
|
85
|
+
|
|
86
|
+
def subscribe_by_name(
|
|
87
|
+
self,
|
|
88
|
+
market_name: str,
|
|
89
|
+
interval: CandlestickInterval,
|
|
90
|
+
on_data: (
|
|
91
|
+
Callable[[CandlestickWsMessage], None]
|
|
92
|
+
| Callable[[CandlestickWsMessage], Awaitable[None]]
|
|
93
|
+
),
|
|
94
|
+
) -> Unsubscribe:
|
|
95
|
+
market_addr = get_market_addr(market_name, self.config.deployment.perp_engine_global)
|
|
96
|
+
topic = f"market_candlestick:{market_addr}:{interval.value}"
|
|
97
|
+
return self.ws.subscribe(topic, CandlestickWsMessage, on_data)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, ConfigDict, RootModel
|
|
4
|
+
|
|
5
|
+
from ._base import BaseReader
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"Delegation",
|
|
9
|
+
"DelegationsReader",
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Delegation(BaseModel):
|
|
14
|
+
model_config = ConfigDict(populate_by_name=True)
|
|
15
|
+
|
|
16
|
+
delegated_account: str
|
|
17
|
+
permission_type: str
|
|
18
|
+
expiration_time_s: float | None
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class _DelegationsList(RootModel[list[Delegation]]):
|
|
22
|
+
pass
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class DelegationsReader(BaseReader):
|
|
26
|
+
async def get_all(self, *, sub_addr: str) -> list[Delegation]:
|
|
27
|
+
response, _, _ = await self.get_request(
|
|
28
|
+
model=_DelegationsList,
|
|
29
|
+
url=f"{self.config.trading_http_url}/api/v1/delegations",
|
|
30
|
+
params={"subaccount": sub_addr},
|
|
31
|
+
)
|
|
32
|
+
return response.root
|