Skip to main content

ConditionalBuilder

Struct ConditionalBuilder 

pub struct ConditionalBuilder { /* private fields */ }
Expand description

Builder for constructing Conditional orders with a fluent API.

This builder provides a type-safe way to construct conditional orders with proper validation of required fields and configuration constraints. It supports:

  • Price-based triggers (rises above/falls below)
  • Order-linked activation (bracket orders)
  • Flexible quantity specifications
  • Optional expiry configuration

It will also build a trailing-stop trigger or an OCO link, but the sequencer rejects both (125 and 129) — see Trigger and Conditional.

§Required Fields

The following fields must be set before calling build():

  • Trigger condition: rises_above() or falls_below()
  • Trigger: Price level or trailing configuration
  • Reference price: last_trade_price(), index_price(), or mark_price()

§Examples

Basic stop-loss order:

use types::api::submit_order::{ConditionalBuilder, Trigger};

let conditional = ConditionalBuilder::new()
    .falls_below()
    .trigger(Trigger::price("45000.00"))
    .last_trade_price()
    .build()
    .unwrap();

Stop with order-linked activation:

use types::api::submit_order::{ConditionalBuilder, Trigger};

let conditional = ConditionalBuilder::new()
    .falls_below()
    .trigger(Trigger::price("45000.00"))
    .mark_price()
    .order_linked_activation_client_id("entry-order-123", "1.0")
    .absolute_quantity("1.0")
    .build()
    .unwrap();

Take-profit on half the position:

use types::api::submit_order::{ConditionalBuilder, Trigger};

let take_profit = ConditionalBuilder::new()
    .rises_above()
    .trigger(Trigger::price("55000.00"))
    .last_trade_price()
    .percentage_of_position_at_trigger("0.5")
    .build()
    .unwrap();

Implementations§

§

impl ConditionalBuilder

pub fn new() -> ConditionalBuilder

Creates a new ConditionalBuilder with all fields unset.

§Example
use types::api::submit_order::ConditionalBuilder;

let builder = ConditionalBuilder::new();

pub fn trigger_condition( self, condition: TriggerCondition, ) -> ConditionalBuilder

Sets the trigger condition directly.

Tip: Consider using rises_above() or falls_below() for better readability.

§Arguments
  • condition - The trigger condition to use
§Example
use types::api::submit_order::ConditionalBuilder;
use types::common::TriggerCondition;

let builder = ConditionalBuilder::new()
    .trigger_condition(TriggerCondition::RisesAbove);

pub fn rises_above(self) -> ConditionalBuilder

Sets trigger condition to RisesAbove (for breakout/take-profit orders).

The order will trigger when the reference price rises above the trigger level.

Required field - Must be set before calling build().

§Example
use types::api::submit_order::ConditionalBuilder;

let builder = ConditionalBuilder::new()
    .rises_above();  // Trigger when price rises above target

pub fn falls_below(self) -> ConditionalBuilder

Sets trigger condition to FallsBelow (for stop-loss orders).

The order will trigger when the reference price falls below the trigger level.

Required field - Must be set before calling build().

§Example
use types::api::submit_order::ConditionalBuilder;

let builder = ConditionalBuilder::new()
    .falls_below();  // Trigger when price falls below stop level

pub fn trigger(self, trigger: Trigger) -> ConditionalBuilder

Sets the trigger mechanism (price or trailing stop).

Required field - Must be set before calling build().

§Arguments
  • trigger - Either a fixed price level or trailing stop configuration
§Example
use types::api::submit_order::{ConditionalBuilder, Trigger};

// Fixed price trigger
let builder = ConditionalBuilder::new()
    .trigger(Trigger::price("50000.00"));

// Trailing stop trigger
let builder = ConditionalBuilder::new()
    .trigger(Trigger::numeric_trailing_distance("500.00"));

pub fn reference_price( self, reference_price: ReferencePrice, ) -> ConditionalBuilder

Sets the reference price source directly.

Tip: Consider using last_trade_price(), index_price(), or mark_price() for better readability.

Required field - Must be set before calling build().

pub fn last_trade_price(self) -> ConditionalBuilder

Sets reference price to last trade price.

Uses the most recent executed trade price to evaluate the trigger condition.

Required field - Must be set before calling build().

§Example
use types::api::submit_order::ConditionalBuilder;

let builder = ConditionalBuilder::new()
    .last_trade_price();

pub fn index_price(self) -> ConditionalBuilder

Sets reference price to index price.

Uses the external index price to evaluate the trigger condition.

Required field - Must be set before calling build().

§Example
use types::api::submit_order::ConditionalBuilder;

let builder = ConditionalBuilder::new()
    .index_price();

pub fn mark_price(self) -> ConditionalBuilder

Sets reference price to mark price.

Uses the fair value mark price to evaluate the trigger condition.

Required field - Must be set before calling build().

§Example
use types::api::submit_order::ConditionalBuilder;

let builder = ConditionalBuilder::new()
    .mark_price();

pub fn expiry(self, expiry: ConditionalExpiry) -> ConditionalBuilder

Sets an optional expiry configuration.

When the expiry timestamp is reached, the conditional order will either trigger or cancel based on the expiry settings.

§Arguments
  • expiry - Expiry configuration with timestamp and action
§Example
use types::api::submit_order::{ConditionalBuilder, ConditionalExpiry};

let builder = ConditionalBuilder::new()
    .expiry(ConditionalExpiry::trigger_at(1747313713));

pub fn quantity(self, quantity: Quantity) -> ConditionalBuilder

Sets the order quantity directly.

Tip: Consider using specific methods like absolute_quantity() or percentage_of_position_at_trigger().

pub fn absolute_quantity<S>(self, quantity: S) -> ConditionalBuilder
where S: Into<String>,

Sets an absolute quantity for the order.

§Arguments
  • quantity - Absolute quantity as a decimal string (e.g., “1.5”, “0.001”)
§Example
use types::api::submit_order::ConditionalBuilder;

let builder = ConditionalBuilder::new()
    .absolute_quantity("1.5");

pub fn percentage_of_position_at_trigger<S>( self, percentage: S, ) -> ConditionalBuilder
where S: Into<String>,

Sets quantity as a percentage of position at trigger time.

The quantity will be calculated based on the position size when the conditional order triggers (not when it’s submitted).

§Arguments
  • percentage - a fraction of the position in (0,1], as a decimal string ("0.5" is 50%). Anything zero, negative or greater than 1 is rejected with OrderPercentageOfPositionQuantityMustBeGreaterThanZeroAndLesserThanOne (139).
§Example
use types::api::submit_order::ConditionalBuilder;

let builder = ConditionalBuilder::new()
    .percentage_of_position_at_trigger("0.5");  // 50% of position

pub fn percentage_of_position_at_submission<S>( self, percentage: S, ) -> ConditionalBuilder
where S: Into<String>,

Sets quantity as a percentage of position at submission time.

The quantity will be calculated and locked based on the position size when the conditional order is submitted (not when it triggers).

§Arguments
  • percentage - Percentage as a decimal string (e.g., “50” for 50%)
§Example
use types::api::submit_order::ConditionalBuilder;

let builder = ConditionalBuilder::new()
    .percentage_of_position_at_submission("0.5");  // 50% of current position

Sets quantity to match the linked order’s full quantity.

Not supported. The sequencer rejects any conditional carrying this quantity with OrderLinkQuantityNotSupported (133), whether or not order linking is configured. Use absolute_quantity() or a percentage-of-position quantity.

Requires: Order linking must be configured via order_linked_activation_client_id() or order_linked_activation_order_id().

§Example
use types::api::submit_order::ConditionalBuilder;

let builder = ConditionalBuilder::new()
    .order_linked_activation_client_id("entry-order-123", "1.0")
    .order_link_quantity();  // Match the linked order's quantity

Sets quantity to match the linked order’s filled quantity.

Not supported. The sequencer rejects any conditional carrying this quantity with OrderLinkQuantityNotSupported (133).

Requires: Order linking must be configured via order_linked_activation_client_id() or order_linked_activation_order_id().

§Example
use types::api::submit_order::ConditionalBuilder;

let builder = ConditionalBuilder::new()
    .order_linked_activation_client_id("entry-order-123", "1.0")
    .filled_order_link_quantity();  // Match filled portion only

pub fn order_linked_activation_client_id<S>( self, client_order_id: S, fill_quantity: S, ) -> ConditionalBuilder
where S: Into<String>,

Links this conditional order to activate when another order is filled.

This creates a bracket order relationship where this conditional order activates after the specified parent order reaches a fill threshold.

Note: Cannot be used with order_linked_activation_order_id().

§Arguments
  • client_order_id - Client-assigned ID of the parent order
  • fill_quantity - Minimum fill quantity to activate (decimal string)
§Example
use types::api::submit_order::ConditionalBuilder;

let builder = ConditionalBuilder::new()
    .order_linked_activation_client_id("entry-order-123", "1.0");

pub fn order_linked_activation_order_id<S>( self, order_id: u128, fill_quantity: S, ) -> ConditionalBuilder
where S: Into<String>,

Links this conditional order to activate when another order is filled (by order ID).

This creates a bracket order relationship where this conditional order activates after the specified parent order reaches a fill threshold.

Note: Cannot be used with order_linked_activation_client_id().

§Arguments
  • order_id - Exchange-assigned ID of the parent order
  • fill_quantity - Minimum fill quantity to activate (decimal string)
§Example
use types::api::submit_order::ConditionalBuilder;

let builder = ConditionalBuilder::new()
    .order_linked_activation_order_id(123456789, "1.0");

Links this order with another in an OCO (One-Cancels-Other) relationship.

Not supported. A conditional carrying an OCO link is rejected by the sequencer with OcoOrdersNotSupported (129); nothing cancels the other leg. Submit the two legs independently and cancel the loser yourself.

Note: Cannot be used with oco_link_order_id().

§Arguments
  • client_order_id - Client-assigned ID of the linked OCO order
§Example
use types::api::submit_order::ConditionalBuilder;

let builder = ConditionalBuilder::new()
    .oco_link_client_id("stop-loss-order-456");

Links this order with another in an OCO relationship (by order ID).

Not supported. A conditional carrying an OCO link is rejected by the sequencer with OcoOrdersNotSupported (129).

Note: Cannot be used with oco_link_client_id().

§Arguments
  • order_id - Exchange-assigned ID of the linked OCO order
§Example
use types::api::submit_order::ConditionalBuilder;

let builder = ConditionalBuilder::new()
    .oco_link_order_id(987654321);

pub fn build(self) -> Result<Conditional, ConditionalBuilderError>

Builds the Conditional order, consuming the builder.

§Returns
  • Ok(Conditional) - Successfully built conditional order
  • Err(ConditionalBuilderError) - Missing required fields or invalid configuration
§Errors

Returns an error if:

  • Any required field is missing (trigger_condition, trigger, reference_price)
  • Order linking is used without fill quantity
  • Both OCO client ID and order ID are specified
  • Both activation client ID and order ID are specified
§Example
use types::api::submit_order::{ConditionalBuilder, Trigger};

let conditional = ConditionalBuilder::new()
    .falls_below()
    .trigger(Trigger::price("45000.00"))
    .last_trade_price()
    .build()
    .expect("Failed to build conditional");

Trait Implementations§

§

impl Debug for ConditionalBuilder

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for ConditionalBuilder

§

fn default() -> ConditionalBuilder

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<U> As for U

§

fn as_<T>(self) -> T
where T: CastFrom<U>, U: Sized,

Casts self to type T. The semantics of numeric casting with the as operator are followed, so <T as As>::as_::<U> can be used in the same way as T as U for numeric conversions. Read more
§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<T> Clear for T
where T: InitializableFromZeroed + ?Sized,

§

fn clear(&mut self)

Completely overwrites this value.
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> InitializableFromZeroed for T
where T: Default,

§

unsafe fn initialize(place: *mut T)

Called to initialize a place to a valid value, after it is set to all-bits-zero. Read more
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts 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

§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
§

impl<T> IntoRequest<T> for T

§

fn into_request(self) -> Request<T>

Wrap the input message T in a Request
§

impl<L> LayerExt<L> for L

§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in [Layered].
§

impl<T> MaybeSend for T
where T: Send,

§

impl<T> Pipe for T
where T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more