pub struct DydxExecutionClient { /* private fields */ }Expand description
Live execution client for the dYdX v4 exchange adapter.
Supports Market and Limit orders via gRPC. Conditional orders (Stop, Take Profit, Trailing Stop) planned for future releases. dYdX requires u32 client IDs - strings are hashed to fit this constraint.
§Architecture
The client follows a two-layer execution model:
- Synchronous validation - Immediate checks and event generation
- Async submission - Non-blocking gRPC calls via
OrderSubmitter
This matches the pattern used in OKX and other exchange adapters, ensuring consistent behavior across the Nautilus ecosystem.
Implementations§
Source§impl DydxExecutionClient
impl DydxExecutionClient
Sourcepub fn new(
core: ExecutionClientCore,
config: DydxAdapterConfig,
wallet_address: String,
subaccount_number: u32,
) -> Result<Self>
pub fn new( core: ExecutionClientCore, config: DydxAdapterConfig, wallet_address: String, subaccount_number: u32, ) -> Result<Self>
Creates a new DydxExecutionClient.
§Errors
Returns an error if the WebSocket client fails to construct.
Trait Implementations§
Source§impl Debug for DydxExecutionClient
impl Debug for DydxExecutionClient
Source§impl ExecutionClient for DydxExecutionClient
impl ExecutionClient for DydxExecutionClient
Source§fn submit_order(&self, cmd: &SubmitOrder) -> Result<()>
fn submit_order(&self, cmd: &SubmitOrder) -> Result<()>
Submits an order to dYdX via gRPC.
dYdX requires u32 client IDs - Nautilus ClientOrderId strings are hashed to fit. Only Market and Limit orders supported currently. Conditional orders (Stop, Take Profit) will be implemented in future releases.
Validates synchronously, generates OrderSubmitted event, then spawns async task for gRPC submission to avoid blocking. Unsupported order types generate OrderRejected.
Source§fn cancel_order(&self, cmd: &CancelOrder) -> Result<()>
fn cancel_order(&self, cmd: &CancelOrder) -> Result<()>
Cancels an order on dYdX exchange.
Validates the order state and retrieves instrument details before spawning an async task to cancel via gRPC.
§Validation
- Checks order exists in cache
- Validates order is not already closed
- Retrieves instrument from cache for order builder
The cmd contains client/venue order IDs. Returns Ok(()) if cancel request is
spawned successfully or validation fails gracefully. Returns Err if not connected.
§Events
OrderCanceled- Generated when WebSocket confirms cancellationOrderCancelRejected- Generated if exchange rejects cancellation
fn is_connected(&self) -> bool
fn client_id(&self) -> ClientId
fn account_id(&self) -> AccountId
fn venue(&self) -> Venue
fn oms_type(&self) -> OmsType
fn get_account(&self) -> Option<AccountAny>
Source§fn generate_account_state(
&self,
balances: Vec<AccountBalance>,
margins: Vec<MarginBalance>,
reported: bool,
ts_event: UnixNanos,
) -> Result<()>
fn generate_account_state( &self, balances: Vec<AccountBalance>, margins: Vec<MarginBalance>, reported: bool, ts_event: UnixNanos, ) -> Result<()>
Source§fn submit_order_list(&self, _cmd: &SubmitOrderList) -> Result<()>
fn submit_order_list(&self, _cmd: &SubmitOrderList) -> Result<()>
Source§fn modify_order(&self, _cmd: &ModifyOrder) -> Result<()>
fn modify_order(&self, _cmd: &ModifyOrder) -> Result<()>
Source§fn cancel_all_orders(&self, cmd: &CancelAllOrders) -> Result<()>
fn cancel_all_orders(&self, cmd: &CancelAllOrders) -> Result<()>
Source§fn batch_cancel_orders(&self, _cmd: &BatchCancelOrders) -> Result<()>
fn batch_cancel_orders(&self, _cmd: &BatchCancelOrders) -> Result<()>
Source§fn query_account(&self, _cmd: &QueryAccount) -> Result<()>
fn query_account(&self, _cmd: &QueryAccount) -> Result<()>
Source§fn query_order(&self, _cmd: &QueryOrder) -> Result<()>
fn query_order(&self, _cmd: &QueryOrder) -> Result<()>
Source§impl LiveExecutionClient for DydxExecutionClient
impl LiveExecutionClient for DydxExecutionClient
fn get_message_channel(&self) -> UnboundedSender<ExecutionEvent>
fn get_clock(&self) -> Ref<'_, dyn Clock>
Source§fn connect<'life0, 'async_trait>(
&'life0 mut self,
) -> Pin<Box<dyn Future<Output = Result<()>> + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn connect<'life0, 'async_trait>(
&'life0 mut self,
) -> Pin<Box<dyn Future<Output = Result<()>> + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn disconnect<'life0, 'async_trait>(
&'life0 mut self,
) -> Pin<Box<dyn Future<Output = Result<()>> + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn disconnect<'life0, 'async_trait>(
&'life0 mut self,
) -> Pin<Box<dyn Future<Output = Result<()>> + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn generate_order_status_report<'life0, 'life1, 'async_trait>(
&'life0 self,
cmd: &'life1 GenerateOrderStatusReport,
) -> Pin<Box<dyn Future<Output = Result<Option<OrderStatusReport>>> + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn generate_order_status_report<'life0, 'life1, 'async_trait>(
&'life0 self,
cmd: &'life1 GenerateOrderStatusReport,
) -> Pin<Box<dyn Future<Output = Result<Option<OrderStatusReport>>> + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn generate_order_status_reports<'life0, 'life1, 'async_trait>(
&'life0 self,
cmd: &'life1 GenerateOrderStatusReport,
) -> Pin<Box<dyn Future<Output = Result<Vec<OrderStatusReport>>> + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn generate_order_status_reports<'life0, 'life1, 'async_trait>(
&'life0 self,
cmd: &'life1 GenerateOrderStatusReport,
) -> Pin<Box<dyn Future<Output = Result<Vec<OrderStatusReport>>> + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn generate_fill_reports<'life0, 'async_trait>(
&'life0 self,
cmd: GenerateFillReports,
) -> Pin<Box<dyn Future<Output = Result<Vec<FillReport>>> + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn generate_fill_reports<'life0, 'async_trait>(
&'life0 self,
cmd: GenerateFillReports,
) -> Pin<Box<dyn Future<Output = Result<Vec<FillReport>>> + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn generate_position_status_reports<'life0, 'life1, 'async_trait>(
&'life0 self,
cmd: &'life1 GeneratePositionReports,
) -> Pin<Box<dyn Future<Output = Result<Vec<PositionStatusReport>>> + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn generate_position_status_reports<'life0, 'life1, 'async_trait>(
&'life0 self,
cmd: &'life1 GeneratePositionReports,
) -> Pin<Box<dyn Future<Output = Result<Vec<PositionStatusReport>>> + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Auto Trait Implementations§
impl !Freeze for DydxExecutionClient
impl !RefUnwindSafe for DydxExecutionClient
impl !Send for DydxExecutionClient
impl !Sync for DydxExecutionClient
impl Unpin for DydxExecutionClient
impl !UnwindSafe for DydxExecutionClient
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request§impl<L> LayerExt<L> for L
impl<L> LayerExt<L> for L
§fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
Layered].§impl<L> LayerExt<L> for L
impl<L> LayerExt<L> for L
§fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
Layered].