nado-protocol 0.1.4__py3-none-any.whl → 0.1.5__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.
- nado_protocol/client/apis/market/execute.py +146 -0
- nado_protocol/trigger_client/execute.py +227 -2
- nado_protocol/trigger_client/query.py +19 -0
- nado_protocol/trigger_client/types/models.py +50 -9
- nado_protocol/trigger_client/types/query.py +137 -15
- nado_protocol/utils/twap.py +189 -0
- nado_protocol-0.1.5.dist-info/METADATA +309 -0
- {nado_protocol-0.1.4.dist-info → nado_protocol-0.1.5.dist-info}/RECORD +10 -9
- {nado_protocol-0.1.4.dist-info → nado_protocol-0.1.5.dist-info}/WHEEL +1 -1
- nado_protocol-0.1.4.dist-info/METADATA +0 -159
- {nado_protocol-0.1.4.dist-info → nado_protocol-0.1.5.dist-info}/entry_points.txt +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from typing import Optional, List
|
|
1
2
|
from nado_protocol.engine_client.types.execute import (
|
|
2
3
|
BurnNlpParams,
|
|
3
4
|
CancelAndPlaceParams,
|
|
@@ -16,6 +17,7 @@ from nado_protocol.trigger_client.types.execute import (
|
|
|
16
17
|
)
|
|
17
18
|
from nado_protocol.utils.exceptions import MissingTriggerClient
|
|
18
19
|
from nado_protocol.utils.subaccount import Subaccount
|
|
20
|
+
from nado_protocol.utils.expiration import OrderType
|
|
19
21
|
|
|
20
22
|
|
|
21
23
|
class MarketExecuteAPI(NadoBaseAPI):
|
|
@@ -174,3 +176,147 @@ class MarketExecuteAPI(NadoBaseAPI):
|
|
|
174
176
|
if self.context.trigger_client is None:
|
|
175
177
|
raise MissingTriggerClient()
|
|
176
178
|
return self.context.trigger_client.cancel_product_trigger_orders(params)
|
|
179
|
+
|
|
180
|
+
def place_twap_order(
|
|
181
|
+
self,
|
|
182
|
+
product_id: int,
|
|
183
|
+
price_x18: str,
|
|
184
|
+
total_amount_x18: str,
|
|
185
|
+
times: int,
|
|
186
|
+
slippage_frac: float,
|
|
187
|
+
interval_seconds: int,
|
|
188
|
+
sender: Optional[str] = None,
|
|
189
|
+
subaccount_owner: Optional[str] = None,
|
|
190
|
+
subaccount_name: str = "default",
|
|
191
|
+
expiration: Optional[int] = None,
|
|
192
|
+
nonce: Optional[int] = None,
|
|
193
|
+
custom_amounts_x18: Optional[List[str]] = None,
|
|
194
|
+
reduce_only: bool = False,
|
|
195
|
+
spot_leverage: Optional[bool] = None,
|
|
196
|
+
id: Optional[int] = None,
|
|
197
|
+
) -> ExecuteResponse:
|
|
198
|
+
"""
|
|
199
|
+
Place a TWAP (Time-Weighted Average Price) order.
|
|
200
|
+
|
|
201
|
+
This is a convenience method that creates a TWAP trigger order with the specified parameters.
|
|
202
|
+
|
|
203
|
+
Args:
|
|
204
|
+
product_id (int): The product ID for the order.
|
|
205
|
+
price_x18 (str): The limit price multiplied by 1e18.
|
|
206
|
+
total_amount_x18 (str): The total amount to trade multiplied by 1e18 (signed, negative for sell).
|
|
207
|
+
times (int): Number of TWAP executions (1-500).
|
|
208
|
+
slippage_frac (float): Slippage tolerance as a fraction (e.g., 0.01 for 1%).
|
|
209
|
+
interval_seconds (int): Time interval between executions in seconds.
|
|
210
|
+
sender (Optional[str]): The sender address (32 bytes hex or SubaccountParams). If provided, takes precedence over subaccount_owner/subaccount_name.
|
|
211
|
+
subaccount_owner (Optional[str]): The subaccount owner address. If not provided, uses client's signer address. Ignored if sender is provided.
|
|
212
|
+
subaccount_name (str): The subaccount name. Defaults to "default". Ignored if sender is provided.
|
|
213
|
+
expiration (Optional[int]): Order expiration timestamp. If not provided, calculated as min(((times - 1) * interval_seconds) + 1 hour, 25 hours) from now.
|
|
214
|
+
nonce (Optional[int]): Order nonce. If not provided, will be auto-generated.
|
|
215
|
+
custom_amounts_x18 (Optional[List[str]]): Custom amounts for each execution multiplied by 1e18.
|
|
216
|
+
reduce_only (bool): Whether this is a reduce-only order. Defaults to False.
|
|
217
|
+
spot_leverage (Optional[bool]): Whether to use spot leverage.
|
|
218
|
+
id (Optional[int]): Optional order ID.
|
|
219
|
+
|
|
220
|
+
Returns:
|
|
221
|
+
ExecuteResponse: The response from placing the TWAP order.
|
|
222
|
+
|
|
223
|
+
Raises:
|
|
224
|
+
MissingTriggerClient: If trigger client is not configured.
|
|
225
|
+
"""
|
|
226
|
+
if self.context.trigger_client is None:
|
|
227
|
+
raise MissingTriggerClient()
|
|
228
|
+
return self.context.trigger_client.place_twap_order(
|
|
229
|
+
product_id=product_id,
|
|
230
|
+
price_x18=price_x18,
|
|
231
|
+
total_amount_x18=total_amount_x18,
|
|
232
|
+
times=times,
|
|
233
|
+
slippage_frac=slippage_frac,
|
|
234
|
+
interval_seconds=interval_seconds,
|
|
235
|
+
sender=sender,
|
|
236
|
+
subaccount_owner=subaccount_owner,
|
|
237
|
+
subaccount_name=subaccount_name,
|
|
238
|
+
expiration=expiration,
|
|
239
|
+
nonce=nonce,
|
|
240
|
+
custom_amounts_x18=custom_amounts_x18,
|
|
241
|
+
reduce_only=reduce_only,
|
|
242
|
+
spot_leverage=spot_leverage,
|
|
243
|
+
id=id,
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
def place_price_trigger_order(
|
|
247
|
+
self,
|
|
248
|
+
product_id: int,
|
|
249
|
+
price_x18: str,
|
|
250
|
+
amount_x18: str,
|
|
251
|
+
trigger_price_x18: str,
|
|
252
|
+
trigger_type: str,
|
|
253
|
+
sender: Optional[str] = None,
|
|
254
|
+
subaccount_owner: Optional[str] = None,
|
|
255
|
+
subaccount_name: str = "default",
|
|
256
|
+
expiration: Optional[int] = None,
|
|
257
|
+
nonce: Optional[int] = None,
|
|
258
|
+
reduce_only: bool = False,
|
|
259
|
+
order_type: OrderType = OrderType.DEFAULT,
|
|
260
|
+
spot_leverage: Optional[bool] = None,
|
|
261
|
+
id: Optional[int] = None,
|
|
262
|
+
dependency: Optional[dict] = None,
|
|
263
|
+
) -> ExecuteResponse:
|
|
264
|
+
"""
|
|
265
|
+
Place a price trigger order.
|
|
266
|
+
|
|
267
|
+
This is a convenience method that creates a price trigger order with the specified parameters.
|
|
268
|
+
|
|
269
|
+
Args:
|
|
270
|
+
product_id (int): The product ID for the order.
|
|
271
|
+
price_x18 (str): The limit price multiplied by 1e18.
|
|
272
|
+
amount_x18 (str): The amount to trade multiplied by 1e18 (signed, negative for sell).
|
|
273
|
+
trigger_price_x18 (str): The trigger price multiplied by 1e18.
|
|
274
|
+
trigger_type (str): Type of price trigger - one of:
|
|
275
|
+
"last_price_above", "last_price_below",
|
|
276
|
+
"oracle_price_above", "oracle_price_below",
|
|
277
|
+
"mid_price_above", "mid_price_below".
|
|
278
|
+
sender (Optional[str]): The sender address (32 bytes hex or SubaccountParams). If provided, takes precedence over subaccount_owner/subaccount_name.
|
|
279
|
+
subaccount_owner (Optional[str]): The subaccount owner address. If not provided, uses client's signer address. Ignored if sender is provided.
|
|
280
|
+
subaccount_name (str): The subaccount name. Defaults to "default". Ignored if sender is provided.
|
|
281
|
+
expiration (Optional[int]): Order expiration timestamp. If not provided, defaults to 7 days from now.
|
|
282
|
+
nonce (Optional[int]): Order nonce. If not provided, will be auto-generated.
|
|
283
|
+
reduce_only (bool): Whether this is a reduce-only order. Defaults to False.
|
|
284
|
+
order_type (OrderType): Order execution type (DEFAULT, IOC, FOK, POST_ONLY). Defaults to DEFAULT.
|
|
285
|
+
spot_leverage (Optional[bool]): Whether to use spot leverage.
|
|
286
|
+
id (Optional[int]): Optional order ID.
|
|
287
|
+
dependency (Optional[dict]): Optional dependency trigger dict with 'digest' and 'on_partial_fill' keys.
|
|
288
|
+
|
|
289
|
+
Returns:
|
|
290
|
+
ExecuteResponse: The response from placing the price trigger order.
|
|
291
|
+
|
|
292
|
+
Raises:
|
|
293
|
+
MissingTriggerClient: If trigger client is not configured.
|
|
294
|
+
ValueError: If trigger_type is not supported.
|
|
295
|
+
"""
|
|
296
|
+
if self.context.trigger_client is None:
|
|
297
|
+
raise MissingTriggerClient()
|
|
298
|
+
|
|
299
|
+
# Convert dict to Dependency if provided
|
|
300
|
+
dependency_obj = None
|
|
301
|
+
if dependency is not None:
|
|
302
|
+
from nado_protocol.trigger_client.types.models import Dependency
|
|
303
|
+
|
|
304
|
+
dependency_obj = Dependency.parse_obj(dependency)
|
|
305
|
+
|
|
306
|
+
return self.context.trigger_client.place_price_trigger_order(
|
|
307
|
+
product_id=product_id,
|
|
308
|
+
price_x18=price_x18,
|
|
309
|
+
amount_x18=amount_x18,
|
|
310
|
+
trigger_price_x18=trigger_price_x18,
|
|
311
|
+
trigger_type=trigger_type,
|
|
312
|
+
sender=sender,
|
|
313
|
+
subaccount_owner=subaccount_owner,
|
|
314
|
+
subaccount_name=subaccount_name,
|
|
315
|
+
expiration=expiration,
|
|
316
|
+
nonce=nonce,
|
|
317
|
+
reduce_only=reduce_only,
|
|
318
|
+
order_type=order_type,
|
|
319
|
+
spot_leverage=spot_leverage,
|
|
320
|
+
id=id,
|
|
321
|
+
dependency=dependency_obj,
|
|
322
|
+
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import requests
|
|
2
2
|
from functools import singledispatchmethod
|
|
3
|
-
from typing import Union
|
|
3
|
+
from typing import Union, Optional, List, cast
|
|
4
4
|
from nado_protocol.contracts.types import NadoExecuteType
|
|
5
5
|
from nado_protocol.trigger_client.types.execute import (
|
|
6
6
|
TriggerExecuteParams,
|
|
@@ -16,8 +16,26 @@ from nado_protocol.utils.exceptions import (
|
|
|
16
16
|
BadStatusCodeException,
|
|
17
17
|
ExecuteFailedException,
|
|
18
18
|
)
|
|
19
|
-
from nado_protocol.utils.execute import NadoBaseExecute
|
|
19
|
+
from nado_protocol.utils.execute import NadoBaseExecute, OrderParams
|
|
20
20
|
from nado_protocol.utils.model import NadoBaseModel, is_instance_of_union
|
|
21
|
+
from nado_protocol.utils.twap import create_twap_order
|
|
22
|
+
from nado_protocol.utils.order import build_appendix, OrderAppendixTriggerType
|
|
23
|
+
from nado_protocol.utils.expiration import OrderType, get_expiration_timestamp
|
|
24
|
+
from nado_protocol.utils.nonce import gen_order_nonce
|
|
25
|
+
from nado_protocol.utils.subaccount import SubaccountParams
|
|
26
|
+
from nado_protocol.utils.bytes32 import subaccount_to_hex
|
|
27
|
+
from nado_protocol.trigger_client.types.models import (
|
|
28
|
+
PriceTrigger,
|
|
29
|
+
PriceTriggerData,
|
|
30
|
+
LastPriceAbove,
|
|
31
|
+
LastPriceBelow,
|
|
32
|
+
OraclePriceAbove,
|
|
33
|
+
OraclePriceBelow,
|
|
34
|
+
MidPriceAbove,
|
|
35
|
+
MidPriceBelow,
|
|
36
|
+
PriceRequirement,
|
|
37
|
+
Dependency,
|
|
38
|
+
)
|
|
21
39
|
|
|
22
40
|
|
|
23
41
|
class TriggerExecuteClient(NadoBaseExecute):
|
|
@@ -95,6 +113,213 @@ class TriggerExecuteClient(NadoBaseExecute):
|
|
|
95
113
|
)
|
|
96
114
|
return self.execute(params)
|
|
97
115
|
|
|
116
|
+
def place_twap_order(
|
|
117
|
+
self,
|
|
118
|
+
product_id: int,
|
|
119
|
+
price_x18: str,
|
|
120
|
+
total_amount_x18: str,
|
|
121
|
+
times: int,
|
|
122
|
+
slippage_frac: float,
|
|
123
|
+
interval_seconds: int,
|
|
124
|
+
sender: Optional[Union[str, SubaccountParams]] = None,
|
|
125
|
+
subaccount_owner: Optional[str] = None,
|
|
126
|
+
subaccount_name: str = "default",
|
|
127
|
+
expiration: Optional[int] = None,
|
|
128
|
+
nonce: Optional[int] = None,
|
|
129
|
+
custom_amounts_x18: Optional[List[str]] = None,
|
|
130
|
+
reduce_only: bool = False,
|
|
131
|
+
spot_leverage: Optional[bool] = None,
|
|
132
|
+
id: Optional[int] = None,
|
|
133
|
+
) -> ExecuteResponse:
|
|
134
|
+
"""
|
|
135
|
+
Place a TWAP (Time-Weighted Average Price) order.
|
|
136
|
+
|
|
137
|
+
This is a convenience method that creates a TWAP trigger order with the specified parameters.
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
product_id (int): The product ID for the order.
|
|
141
|
+
price_x18 (str): The limit price multiplied by 1e18.
|
|
142
|
+
total_amount_x18 (str): The total amount to trade multiplied by 1e18 (signed, negative for sell).
|
|
143
|
+
times (int): Number of TWAP executions (1-500).
|
|
144
|
+
slippage_frac (float): Slippage tolerance as a fraction (e.g., 0.01 for 1%).
|
|
145
|
+
interval_seconds (int): Time interval between executions in seconds.
|
|
146
|
+
sender (Optional[str]): The sender address (32 bytes hex or SubaccountParams). If provided, takes precedence over subaccount_owner/subaccount_name.
|
|
147
|
+
subaccount_owner (Optional[str]): The subaccount owner address. If not provided, uses client's signer address. Ignored if sender is provided.
|
|
148
|
+
subaccount_name (str): The subaccount name. Defaults to "default". Ignored if sender is provided.
|
|
149
|
+
expiration (Optional[int]): Order expiration timestamp. If not provided, calculated as min(((times - 1) * interval_seconds) + 1 hour, 25 hours) from now.
|
|
150
|
+
nonce (Optional[int]): Order nonce. If not provided, will be auto-generated.
|
|
151
|
+
custom_amounts_x18 (Optional[List[str]]): Custom amounts for each execution multiplied by 1e18.
|
|
152
|
+
reduce_only (bool): Whether this is a reduce-only order. Defaults to False.
|
|
153
|
+
spot_leverage (Optional[bool]): Whether to use spot leverage.
|
|
154
|
+
id (Optional[int]): Optional order ID.
|
|
155
|
+
|
|
156
|
+
Returns:
|
|
157
|
+
ExecuteResponse: The response from placing the TWAP order.
|
|
158
|
+
"""
|
|
159
|
+
# Calculate default expiration if not provided
|
|
160
|
+
# Backend requires: min_expiration <= expiration <= timestamp + 25 hours
|
|
161
|
+
# Where min_expiration = ((times - 1) * interval) + now
|
|
162
|
+
if expiration is None:
|
|
163
|
+
min_duration = (times - 1) * interval_seconds
|
|
164
|
+
max_duration = 60 * 60 * 25 # 25 hours in seconds
|
|
165
|
+
# Set expiration to minimum duration + 1 hour buffer, capped at 25 hours
|
|
166
|
+
buffer_duration = min(min_duration + 60 * 60, max_duration)
|
|
167
|
+
expiration = get_expiration_timestamp(buffer_duration)
|
|
168
|
+
|
|
169
|
+
# Build sender from subaccount parameters if not directly provided
|
|
170
|
+
sender_value: Union[str, SubaccountParams]
|
|
171
|
+
if sender is None:
|
|
172
|
+
sender_value = SubaccountParams(
|
|
173
|
+
subaccount_owner=subaccount_owner or self.signer.address,
|
|
174
|
+
subaccount_name=subaccount_name,
|
|
175
|
+
)
|
|
176
|
+
else:
|
|
177
|
+
sender_value = sender
|
|
178
|
+
|
|
179
|
+
# Convert sender to hex string if it's SubaccountParams
|
|
180
|
+
sender_hex: str
|
|
181
|
+
if isinstance(sender_value, SubaccountParams):
|
|
182
|
+
sender_hex = subaccount_to_hex(sender_value)
|
|
183
|
+
else:
|
|
184
|
+
sender_hex = sender_value
|
|
185
|
+
|
|
186
|
+
params = create_twap_order(
|
|
187
|
+
product_id=product_id,
|
|
188
|
+
sender=sender_hex,
|
|
189
|
+
price_x18=price_x18,
|
|
190
|
+
total_amount_x18=total_amount_x18,
|
|
191
|
+
expiration=expiration,
|
|
192
|
+
nonce=nonce if nonce is not None else gen_order_nonce(),
|
|
193
|
+
times=times,
|
|
194
|
+
slippage_frac=slippage_frac,
|
|
195
|
+
interval_seconds=interval_seconds,
|
|
196
|
+
custom_amounts_x18=custom_amounts_x18,
|
|
197
|
+
reduce_only=reduce_only,
|
|
198
|
+
spot_leverage=spot_leverage,
|
|
199
|
+
id=id,
|
|
200
|
+
)
|
|
201
|
+
return self.place_trigger_order(params)
|
|
202
|
+
|
|
203
|
+
def place_price_trigger_order(
|
|
204
|
+
self,
|
|
205
|
+
product_id: int,
|
|
206
|
+
price_x18: str,
|
|
207
|
+
amount_x18: str,
|
|
208
|
+
trigger_price_x18: str,
|
|
209
|
+
trigger_type: str,
|
|
210
|
+
sender: Optional[Union[str, SubaccountParams]] = None,
|
|
211
|
+
subaccount_owner: Optional[str] = None,
|
|
212
|
+
subaccount_name: str = "default",
|
|
213
|
+
expiration: Optional[int] = None,
|
|
214
|
+
nonce: Optional[int] = None,
|
|
215
|
+
reduce_only: bool = False,
|
|
216
|
+
order_type: OrderType = OrderType.DEFAULT,
|
|
217
|
+
spot_leverage: Optional[bool] = None,
|
|
218
|
+
id: Optional[int] = None,
|
|
219
|
+
dependency: Optional[Dependency] = None,
|
|
220
|
+
) -> ExecuteResponse:
|
|
221
|
+
"""
|
|
222
|
+
Place a price trigger order.
|
|
223
|
+
|
|
224
|
+
This is a convenience method that creates a price trigger order with the specified parameters.
|
|
225
|
+
|
|
226
|
+
Args:
|
|
227
|
+
product_id (int): The product ID for the order.
|
|
228
|
+
price_x18 (str): The limit price multiplied by 1e18.
|
|
229
|
+
amount_x18 (str): The amount to trade multiplied by 1e18 (signed, negative for sell).
|
|
230
|
+
trigger_price_x18 (str): The trigger price multiplied by 1e18.
|
|
231
|
+
trigger_type (str): Type of price trigger - one of:
|
|
232
|
+
"last_price_above", "last_price_below",
|
|
233
|
+
"oracle_price_above", "oracle_price_below",
|
|
234
|
+
"mid_price_above", "mid_price_below".
|
|
235
|
+
sender (Optional[str]): The sender address (32 bytes hex or SubaccountParams). If provided, takes precedence over subaccount_owner/subaccount_name.
|
|
236
|
+
subaccount_owner (Optional[str]): The subaccount owner address. If not provided, uses client's signer address. Ignored if sender is provided.
|
|
237
|
+
subaccount_name (str): The subaccount name. Defaults to "default". Ignored if sender is provided.
|
|
238
|
+
expiration (Optional[int]): Order expiration timestamp. If not provided, defaults to 7 days from now.
|
|
239
|
+
nonce (Optional[int]): Order nonce. If not provided, will be auto-generated.
|
|
240
|
+
reduce_only (bool): Whether this is a reduce-only order. Defaults to False.
|
|
241
|
+
order_type (OrderType): Order execution type (DEFAULT, IOC, FOK, POST_ONLY). Defaults to DEFAULT.
|
|
242
|
+
spot_leverage (Optional[bool]): Whether to use spot leverage.
|
|
243
|
+
id (Optional[int]): Optional order ID.
|
|
244
|
+
dependency (Optional[Dependency]): Optional dependency trigger. If provided, this order will trigger
|
|
245
|
+
when the specified order (by digest) is filled. The dependency includes:
|
|
246
|
+
- digest (str): The digest of the order to depend on
|
|
247
|
+
- on_partial_fill (bool): Whether to trigger on partial fill (True) or only on full fill (False)
|
|
248
|
+
|
|
249
|
+
Returns:
|
|
250
|
+
ExecuteResponse: The response from placing the price trigger order.
|
|
251
|
+
|
|
252
|
+
Raises:
|
|
253
|
+
ValueError: If trigger_type is not supported.
|
|
254
|
+
"""
|
|
255
|
+
# Create the appropriate price requirement based on trigger type
|
|
256
|
+
price_requirement: PriceRequirement
|
|
257
|
+
if trigger_type == "last_price_above":
|
|
258
|
+
price_requirement = LastPriceAbove(last_price_above=trigger_price_x18)
|
|
259
|
+
elif trigger_type == "last_price_below":
|
|
260
|
+
price_requirement = LastPriceBelow(last_price_below=trigger_price_x18)
|
|
261
|
+
elif trigger_type == "oracle_price_above":
|
|
262
|
+
price_requirement = OraclePriceAbove(oracle_price_above=trigger_price_x18)
|
|
263
|
+
elif trigger_type == "oracle_price_below":
|
|
264
|
+
price_requirement = OraclePriceBelow(oracle_price_below=trigger_price_x18)
|
|
265
|
+
elif trigger_type == "mid_price_above":
|
|
266
|
+
price_requirement = MidPriceAbove(mid_price_above=trigger_price_x18)
|
|
267
|
+
elif trigger_type == "mid_price_below":
|
|
268
|
+
price_requirement = MidPriceBelow(mid_price_below=trigger_price_x18)
|
|
269
|
+
else:
|
|
270
|
+
raise ValueError(
|
|
271
|
+
f"Unsupported trigger_type: {trigger_type}. "
|
|
272
|
+
f"Supported types: ['last_price_above', 'last_price_below', 'oracle_price_above', 'oracle_price_below', 'mid_price_above', 'mid_price_below']"
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
trigger = PriceTrigger(
|
|
276
|
+
price_trigger=PriceTriggerData(
|
|
277
|
+
price_requirement=price_requirement, dependency=dependency
|
|
278
|
+
)
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
# Build appendix with PRICE trigger type
|
|
282
|
+
appendix = build_appendix(
|
|
283
|
+
order_type=order_type,
|
|
284
|
+
reduce_only=reduce_only,
|
|
285
|
+
trigger_type=OrderAppendixTriggerType.PRICE,
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
# Default expiration to 7 days if not provided
|
|
289
|
+
if expiration is None:
|
|
290
|
+
expiration = get_expiration_timestamp(60 * 60 * 24 * 7)
|
|
291
|
+
|
|
292
|
+
# Build sender from subaccount parameters if not directly provided
|
|
293
|
+
sender_value: Union[str, SubaccountParams]
|
|
294
|
+
if sender is None:
|
|
295
|
+
sender_value = SubaccountParams(
|
|
296
|
+
subaccount_owner=subaccount_owner or self.signer.address,
|
|
297
|
+
subaccount_name=subaccount_name,
|
|
298
|
+
)
|
|
299
|
+
else:
|
|
300
|
+
sender_value = sender
|
|
301
|
+
|
|
302
|
+
order_params = OrderParams(
|
|
303
|
+
sender=sender_value,
|
|
304
|
+
priceX18=int(price_x18),
|
|
305
|
+
amount=int(amount_x18),
|
|
306
|
+
expiration=expiration,
|
|
307
|
+
nonce=nonce if nonce is not None else gen_order_nonce(),
|
|
308
|
+
appendix=appendix,
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
params = PlaceTriggerOrderParams(
|
|
312
|
+
product_id=product_id,
|
|
313
|
+
order=order_params,
|
|
314
|
+
trigger=trigger,
|
|
315
|
+
signature=None,
|
|
316
|
+
digest=None,
|
|
317
|
+
spot_leverage=spot_leverage,
|
|
318
|
+
id=id,
|
|
319
|
+
)
|
|
320
|
+
|
|
321
|
+
return self.place_trigger_order(params)
|
|
322
|
+
|
|
98
323
|
def cancel_trigger_orders(
|
|
99
324
|
self, params: CancelTriggerOrdersParams
|
|
100
325
|
) -> ExecuteResponse:
|
|
@@ -4,7 +4,11 @@ from nado_protocol.trigger_client.types import TriggerClientOpts
|
|
|
4
4
|
from nado_protocol.trigger_client.types.query import (
|
|
5
5
|
ListTriggerOrdersParams,
|
|
6
6
|
ListTriggerOrdersRequest,
|
|
7
|
+
ListTwapExecutionsParams,
|
|
8
|
+
ListTwapExecutionsRequest,
|
|
7
9
|
TriggerQueryResponse,
|
|
10
|
+
TriggerQueryParams,
|
|
11
|
+
TriggerQueryRequest,
|
|
8
12
|
)
|
|
9
13
|
from nado_protocol.utils.exceptions import (
|
|
10
14
|
BadStatusCodeException,
|
|
@@ -59,3 +63,18 @@ class TriggerQueryClient(NadoBaseExecute):
|
|
|
59
63
|
NadoTxType.LIST_TRIGGER_ORDERS, params.tx.dict()
|
|
60
64
|
)
|
|
61
65
|
return self.query(ListTriggerOrdersRequest.parse_obj(params).dict())
|
|
66
|
+
|
|
67
|
+
def list_twap_executions(
|
|
68
|
+
self, params: ListTwapExecutionsParams
|
|
69
|
+
) -> TriggerQueryResponse:
|
|
70
|
+
"""
|
|
71
|
+
List TWAP executions for a specific order digest.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
params (ListTwapExecutionsParams): Parameters containing the order digest.
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
TriggerQueryResponse: Response containing TWAP execution details.
|
|
78
|
+
"""
|
|
79
|
+
params = ListTwapExecutionsParams.parse_obj(params)
|
|
80
|
+
return self.query(ListTwapExecutionsRequest.parse_obj(params).dict())
|
|
@@ -1,28 +1,69 @@
|
|
|
1
|
-
from typing import Optional, Union
|
|
1
|
+
from typing import Optional, Union, List
|
|
2
2
|
from nado_protocol.utils.model import NadoBaseModel
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
class
|
|
6
|
-
|
|
5
|
+
class OraclePriceAbove(NadoBaseModel):
|
|
6
|
+
oracle_price_above: str
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
class
|
|
10
|
-
|
|
9
|
+
class OraclePriceBelow(NadoBaseModel):
|
|
10
|
+
oracle_price_below: str
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
class
|
|
13
|
+
class LastPriceAbove(NadoBaseModel):
|
|
14
14
|
last_price_above: str
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
class
|
|
17
|
+
class LastPriceBelow(NadoBaseModel):
|
|
18
18
|
last_price_below: str
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
class MidPriceAbove(NadoBaseModel):
|
|
22
|
+
mid_price_above: str
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class MidPriceBelow(NadoBaseModel):
|
|
26
|
+
mid_price_below: str
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
PriceRequirement = Union[
|
|
30
|
+
OraclePriceAbove,
|
|
31
|
+
OraclePriceBelow,
|
|
32
|
+
LastPriceAbove,
|
|
33
|
+
LastPriceBelow,
|
|
34
|
+
MidPriceAbove,
|
|
35
|
+
MidPriceBelow,
|
|
23
36
|
]
|
|
24
37
|
|
|
25
38
|
|
|
39
|
+
class Dependency(NadoBaseModel):
|
|
40
|
+
digest: str
|
|
41
|
+
on_partial_fill: bool
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class PriceTriggerData(NadoBaseModel):
|
|
45
|
+
price_requirement: PriceRequirement
|
|
46
|
+
dependency: Optional[Dependency] = None
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class TimeTriggerData(NadoBaseModel):
|
|
50
|
+
"""Time-based trigger for TWAP orders."""
|
|
51
|
+
|
|
52
|
+
interval: int # interval in seconds between executions
|
|
53
|
+
amounts: Optional[List[str]] = None # optional custom amounts per execution
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class PriceTrigger(NadoBaseModel):
|
|
57
|
+
price_trigger: PriceTriggerData
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class TimeTrigger(NadoBaseModel):
|
|
61
|
+
time_trigger: TimeTriggerData
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
TriggerCriteria = Union[PriceTrigger, TimeTrigger]
|
|
65
|
+
|
|
66
|
+
|
|
26
67
|
class OrderData(NadoBaseModel):
|
|
27
68
|
sender: str
|
|
28
69
|
priceX18: str
|