use crate::param::{
Asset, Fee, Leverage, Pnl, PositionEffect, PositionSide, Price, Quantity, Side, Trade,
TradeAmount,
};
use crate::pretrade::Lock;
use super::Instrument;
#[macro_export]
macro_rules! has_request_field_trait {
(
$(#[$meta:meta])*
$trait:ident,
$method:ident -> $ret:ty
) => {
$(#[$meta])*
pub trait $trait {
fn $method(&self) -> $ret;
}
impl<T> $trait for T
where
T: std::ops::Deref,
T::Target: $trait,
{
fn $method(&self) -> $ret {
self.deref().$method()
}
}
};
}
has_request_field_trait!(HasInstrument, instrument -> &Instrument);
has_request_field_trait!(HasSide, side -> Side);
has_request_field_trait!(HasTradeAmount, trade_amount -> TradeAmount);
has_request_field_trait!(HasReduceOnly, reduce_only -> bool);
has_request_field_trait!(HasClosePosition, close_position -> bool);
has_request_field_trait!(HasAutoBorrow, auto_borrow -> bool);
has_request_field_trait!(HasPnl, pnl -> Pnl);
has_request_field_trait!(HasFee, fee -> Fee);
has_request_field_trait!(
HasLeavesQuantity,
leaves_quantity -> Quantity
);
has_request_field_trait!(
HasLock,
lock -> Lock
);
has_request_field_trait!(
HasOrderPrice,
price -> Option<Price>
);
has_request_field_trait!(HasOrderPositionSide, position_side -> Option<PositionSide>);
has_request_field_trait!(HasOrderLeverage, leverage -> Option<Leverage>);
has_request_field_trait!(HasOrderCollateralAsset, collateral_asset -> Option<&Asset>);
has_request_field_trait!(HasExecutionReportLastTrade, last_trade -> Option<Trade>);
has_request_field_trait!(HasExecutionReportIsTerminal, is_terminal -> bool);
has_request_field_trait!(HasExecutionReportPositionEffect, position_effect -> Option<PositionEffect>);
has_request_field_trait!(HasExecutionReportPositionSide, position_side -> Option<PositionSide>);
#[cfg(test)]
mod tests {
use super::HasSide;
use crate::core::order::OrderOperation;
use crate::param::{Asset, Quantity, Side, TradeAmount};
use crate::Instrument;
fn operation() -> OrderOperation {
OrderOperation {
instrument: Instrument::new(
Asset::new("BTC").expect("must be valid"),
Asset::new("USD").expect("must be valid"),
),
side: Side::Buy,
trade_amount: TradeAmount::Quantity(Quantity::from_str("1").expect("must be valid")),
price: None,
}
}
#[test]
fn deref_dispatch_calls_method_on_target() {
let boxed: Box<OrderOperation> = Box::new(operation());
assert_eq!(boxed.side(), Side::Buy);
}
}