#[cfg(test)]
mod tests {
use crate::errors::PriceLevelError;
use crate::orders::{Hash32, Id, OrderType, Side, TimeInForce};
use crate::price_level::snapshot::SNAPSHOT_FORMAT_VERSION;
use crate::price_level::{PriceLevelSnapshot, PriceLevelSnapshotPackage};
use crate::utils::{Price, Quantity, TimestampMs};
use serde_json::Value;
use std::str::FromStr;
use std::sync::Arc;
fn create_sample_orders() -> Vec<Arc<OrderType<()>>> {
vec![
Arc::new(OrderType::Standard {
id: Id::from_u64(1),
price: Price::new(1000),
quantity: Quantity::new(10),
side: Side::Buy,
user_id: Hash32::zero(),
timestamp: TimestampMs::new(1616823000000),
time_in_force: TimeInForce::Gtc,
extra_fields: (),
}),
Arc::new(OrderType::IcebergOrder {
id: Id::from_u64(2),
price: Price::new(1000),
visible_quantity: Quantity::new(5),
hidden_quantity: Quantity::new(15),
side: Side::Buy,
user_id: Hash32::zero(),
timestamp: TimestampMs::new(1616823000001),
time_in_force: TimeInForce::Gtc,
extra_fields: (),
}),
]
}
#[test]
fn test_snapshot_package_roundtrip() {
let snapshot = PriceLevelSnapshot::with_orders(42, create_sample_orders())
.expect("Failed to create snapshot with orders");
let package =
PriceLevelSnapshotPackage::new(snapshot.clone()).expect("Failed to create package");
assert_eq!(package.version(), SNAPSHOT_FORMAT_VERSION);
package.validate().expect("Package validation failed");
let json = package.to_json().expect("Failed to serialize package");
let restored_package =
PriceLevelSnapshotPackage::from_json(&json).expect("Failed to deserialize package");
restored_package
.validate()
.expect("Checksum validation should succeed");
let restored_snapshot = restored_package
.into_snapshot()
.expect("Snapshot extraction failed");
assert_eq!(restored_snapshot.price(), snapshot.price());
assert_eq!(restored_snapshot.order_count(), snapshot.order_count());
assert_eq!(
restored_snapshot.visible_quantity(),
snapshot.visible_quantity()
);
assert_eq!(
restored_snapshot.hidden_quantity(),
snapshot.hidden_quantity()
);
assert_eq!(restored_snapshot.orders().len(), snapshot.orders().len());
}
#[test]
fn test_snapshot_package_checksum_mismatch() {
let snapshot = PriceLevelSnapshot::with_orders(99, create_sample_orders())
.expect("Failed to create snapshot with orders");
let package = PriceLevelSnapshotPackage::new(snapshot).expect("Failed to create package");
let json = package.to_json().expect("Failed to serialize package");
let mut value: Value = serde_json::from_str(&json).expect("JSON parsing failed");
if let Some(obj) = value.as_object_mut() {
obj.insert(
"checksum".to_string(),
Value::String("deadbeef".to_string()),
);
}
let tampered_json = serde_json::to_string(&value).expect("JSON serialization failed");
let tampered_package = PriceLevelSnapshotPackage::from_json(&tampered_json)
.expect("Deserialization should still succeed");
let err = tampered_package
.validate()
.expect_err("Checksum mismatch expected");
assert!(matches!(err, PriceLevelError::ChecksumMismatch { .. }));
}
#[test]
fn test_new() {
let snapshot = PriceLevelSnapshot::new(1000);
assert_eq!(snapshot.price(), 1000);
assert_eq!(snapshot.visible_quantity(), 0);
assert_eq!(snapshot.hidden_quantity(), 0);
assert_eq!(snapshot.order_count(), 0);
assert!(snapshot.orders().is_empty());
}
#[test]
fn test_default() {
let snapshot = PriceLevelSnapshot::default();
assert_eq!(snapshot.price(), 0);
assert_eq!(snapshot.visible_quantity(), 0);
assert_eq!(snapshot.hidden_quantity(), 0);
assert_eq!(snapshot.order_count(), 0);
assert!(snapshot.orders().is_empty());
}
#[test]
fn test_total_quantity() {
let snapshot = PriceLevelSnapshot::from_raw_parts(1000, 50, 150, 0, Vec::new());
assert!(matches!(snapshot.total_quantity(), Ok(200)));
}
#[test]
fn test_iter_orders() {
let orders = create_sample_orders();
let order_count = orders.len();
let snapshot = PriceLevelSnapshot::from_raw_parts(1000, 0, 0, order_count, orders);
let collected: Vec<_> = snapshot.iter_orders().collect();
assert_eq!(collected.len(), 2);
if let OrderType::Standard { id, .. } = **collected[0] {
assert_eq!(id, Id::from_u64(1));
} else {
panic!("Expected StandardOrder");
}
if let OrderType::IcebergOrder { id, .. } = **collected[1] {
assert_eq!(id, Id::from_u64(2));
} else {
panic!("Expected IcebergOrder");
}
}
#[test]
fn test_clone() {
let original = PriceLevelSnapshot::from_raw_parts(1000, 50, 150, 2, create_sample_orders());
let cloned = original.clone();
assert_eq!(cloned.price(), 1000);
assert_eq!(cloned.visible_quantity(), 50);
assert_eq!(cloned.hidden_quantity(), 150);
assert_eq!(cloned.order_count(), 2);
assert_eq!(cloned.orders().len(), 2);
}
#[test]
fn test_display() {
let snapshot = PriceLevelSnapshot::from_raw_parts(1000, 50, 150, 2, Vec::new());
let display_str = snapshot.to_string();
assert!(display_str.contains("price=1000"));
assert!(display_str.contains("visible_quantity=50"));
assert!(display_str.contains("hidden_quantity=150"));
assert!(display_str.contains("order_count=2"));
}
#[test]
fn test_from_str() {
let input =
"PriceLevelSnapshot:price=1000;visible_quantity=50;hidden_quantity=150;order_count=2";
let snapshot = PriceLevelSnapshot::from_str(input).unwrap();
assert_eq!(snapshot.price(), 1000);
assert_eq!(snapshot.visible_quantity(), 50);
assert_eq!(snapshot.hidden_quantity(), 150);
assert_eq!(snapshot.order_count(), 2);
assert!(snapshot.orders().is_empty()); }
#[test]
fn test_from_str_invalid_format() {
let input = "InvalidFormat";
let result = PriceLevelSnapshot::from_str(input);
assert!(result.is_err());
}
#[test]
fn test_from_str_missing_field() {
let input = "PriceLevelSnapshot:price=1000;visible_quantity=50;hidden_quantity=150";
let result = PriceLevelSnapshot::from_str(input);
assert!(result.is_err());
}
#[test]
fn test_from_str_invalid_field_value() {
let input = "PriceLevelSnapshot:price=invalid;visible_quantity=50;hidden_quantity=150;order_count=2";
let result = PriceLevelSnapshot::from_str(input);
assert!(result.is_err());
}
#[test]
fn test_roundtrip_display_fromstr() {
let original = PriceLevelSnapshot::from_raw_parts(1000, 50, 150, 2, Vec::new());
let string_representation = original.to_string();
let parsed = PriceLevelSnapshot::from_str(&string_representation).unwrap();
assert_eq!(parsed.price(), original.price());
assert_eq!(parsed.visible_quantity(), original.visible_quantity());
assert_eq!(parsed.hidden_quantity(), original.hidden_quantity());
assert_eq!(parsed.order_count(), original.order_count());
}
#[test]
fn test_snapshot_serialization_fields() {
let snapshot = PriceLevelSnapshot::from_raw_parts(10000, 200, 300, 5, Vec::new());
let serialized = serde_json::to_string(&snapshot).unwrap();
assert!(serialized.contains("\"price\":10000"));
assert!(serialized.contains("\"visible_quantity\":200"));
assert!(serialized.contains("\"hidden_quantity\":300"));
assert!(serialized.contains("\"order_count\":5"));
assert!(serialized.contains("\"orders\":[]"));
}
#[test]
fn test_snapshot_deserializer_duplicate_fields() {
let json = r#"{
"price": 10000,
"visible_quantity": 200,
"hidden_quantity": 300,
"order_count": 5,
"price": 20000,
"orders": []
}"#;
let result = serde_json::from_str::<PriceLevelSnapshot>(json);
assert!(result.is_err());
let err = result.unwrap_err().to_string();
assert!(err.contains("duplicate field"));
}
#[test]
fn test_snapshot_visitor_implementation() {
let json = r#"{
"price": 10000,
"visible_quantity": 200,
"hidden_quantity": 300,
"order_count": 5,
"orders": []
}"#;
let snapshot: PriceLevelSnapshot = serde_json::from_str(json).unwrap();
assert_eq!(snapshot.price(), 10000);
assert_eq!(snapshot.visible_quantity(), 200);
assert_eq!(snapshot.hidden_quantity(), 300);
assert_eq!(snapshot.order_count(), 5);
assert!(snapshot.orders().is_empty());
}
#[test]
fn test_snapshot_with_actual_orders() {
fn create_standard_order(id: u64, price: u128, quantity: u64) -> OrderType<()> {
OrderType::<()>::Standard {
id: Id::from_u64(id),
price: Price::new(price),
quantity: Quantity::new(quantity),
side: Side::Buy,
user_id: Hash32::zero(),
timestamp: TimestampMs::new(1616823000000),
time_in_force: TimeInForce::Gtc,
extra_fields: (),
}
}
fn create_iceberg_order(
id: u64,
price: u128,
visible_quantity: u64,
hidden_quantity: u64,
) -> OrderType<()> {
OrderType::<()>::IcebergOrder {
id: Id::from_u64(id),
price: Price::new(price),
visible_quantity: Quantity::new(visible_quantity),
hidden_quantity: Quantity::new(hidden_quantity),
side: Side::Buy,
user_id: Hash32::zero(),
timestamp: TimestampMs::new(1616823000000),
time_in_force: TimeInForce::Gtc,
extra_fields: (),
}
}
let orders = vec![
Arc::new(create_standard_order(1, 10000u128, 100)),
Arc::new(create_iceberg_order(2, 10000u128, 50, 250)),
];
let snapshot = PriceLevelSnapshot::from_raw_parts(10000, 150, 250, 2, orders);
let serialized = serde_json::to_string(&snapshot).unwrap();
assert!(serialized.contains("\"price\":10000"));
assert!(serialized.contains("\"visible_quantity\":150"));
assert!(serialized.contains("\"hidden_quantity\":250"));
assert!(serialized.contains("\"order_count\":2"));
assert!(serialized.contains("\"orders\":["));
assert!(serialized.contains("\"Standard\":{"));
assert!(serialized.contains("\"IcebergOrder\":{"));
let deserialized: PriceLevelSnapshot = serde_json::from_str(&serialized).unwrap();
assert_eq!(deserialized.price(), 10000);
assert_eq!(deserialized.visible_quantity(), 150);
assert_eq!(deserialized.hidden_quantity(), 250);
assert_eq!(deserialized.order_count(), 2);
assert_eq!(deserialized.orders().len(), 2);
if let OrderType::Standard { id, quantity, .. } = &*deserialized.orders()[0] {
assert_eq!(*id, Id::from_u64(1));
assert_eq!(*quantity, Quantity::new(100));
} else {
panic!("Expected Standard order");
}
if let OrderType::IcebergOrder {
id,
visible_quantity,
hidden_quantity,
..
} = &*deserialized.orders()[1]
{
assert_eq!(*id, Id::from_u64(2));
assert_eq!(*visible_quantity, Quantity::new(50));
assert_eq!(*hidden_quantity, Quantity::new(250));
} else {
panic!("Expected IcebergOrder");
}
}
}
#[cfg(test)]
mod pricelevel_snapshot_serialization_tests {
use crate::orders::{Hash32, Id, OrderType, Side, TimeInForce};
use crate::price_level::PriceLevelSnapshot;
use crate::utils::{Price, Quantity, TimestampMs};
use std::str::FromStr;
use std::sync::Arc;
fn create_sample_orders() -> Vec<Arc<OrderType<()>>> {
vec![
Arc::new(OrderType::Standard {
id: Id::from_u64(1),
price: Price::new(1000),
quantity: Quantity::new(10),
side: Side::Buy,
user_id: Hash32::zero(),
timestamp: TimestampMs::new(1616823000000),
time_in_force: TimeInForce::Gtc,
extra_fields: (),
}),
Arc::new(OrderType::IcebergOrder {
id: Id::from_u64(2),
price: Price::new(1000),
visible_quantity: Quantity::new(5),
hidden_quantity: Quantity::new(15),
side: Side::Sell,
user_id: Hash32::zero(),
timestamp: TimestampMs::new(1616823000001),
time_in_force: TimeInForce::Gtc,
extra_fields: (),
}),
Arc::new(OrderType::PostOnly {
id: Id::from_u64(3),
price: Price::new(1000),
quantity: Quantity::new(8),
side: Side::Buy,
user_id: Hash32::zero(),
timestamp: TimestampMs::new(1616823000002),
time_in_force: TimeInForce::Ioc,
extra_fields: (),
}),
]
}
fn create_sample_snapshot() -> PriceLevelSnapshot {
PriceLevelSnapshot::from_raw_parts(
1000,
15, 15, 3,
create_sample_orders(),
)
}
#[test]
fn test_snapshot_json_serialization() {
let snapshot = create_sample_snapshot();
let json = serde_json::to_string(&snapshot)
.expect("Failed to serialize PriceLevelSnapshot to JSON");
assert!(json.contains("\"price\":1000"));
assert!(json.contains("\"visible_quantity\":15"));
assert!(json.contains("\"hidden_quantity\":15"));
assert!(json.contains("\"order_count\":3"));
assert!(json.contains("\"orders\":["));
assert!(json.contains("\"Standard\":{"));
assert!(json.contains("\"id\":\"00000000-0000-0001-0000-000000000000\""));
assert!(json.contains("\"IcebergOrder\":{"));
assert!(json.contains("\"visible_quantity\":5"));
assert!(json.contains("\"hidden_quantity\":15"));
assert!(json.contains("\"PostOnly\":{"));
}
#[test]
fn test_snapshot_json_deserialization() {
let snapshot = create_sample_snapshot();
let json =
serde_json::to_string(&snapshot).expect("Failed to serialize PriceLevelSnapshot");
let deserialized: PriceLevelSnapshot = serde_json::from_str(&json)
.expect("Failed to deserialize PriceLevelSnapshot from JSON");
assert_eq!(deserialized.price(), 1000);
assert_eq!(deserialized.visible_quantity(), 15);
assert_eq!(deserialized.hidden_quantity(), 15);
assert_eq!(deserialized.order_count(), 3);
assert_eq!(deserialized.orders().len(), 3);
let standard_order = &deserialized.orders()[0];
match **standard_order {
OrderType::Standard {
id,
price,
quantity,
side,
..
} => {
assert_eq!(id, Id::from_u64(1));
assert_eq!(price, Price::new(1000));
assert_eq!(quantity, Quantity::new(10));
assert_eq!(side, Side::Buy);
}
_ => panic!("Expected Standard order"),
}
let iceberg_order = &deserialized.orders()[1];
match **iceberg_order {
OrderType::IcebergOrder {
id,
visible_quantity,
hidden_quantity,
side,
..
} => {
assert_eq!(id, Id::from_u64(2));
assert_eq!(visible_quantity, Quantity::new(5));
assert_eq!(hidden_quantity, Quantity::new(15));
assert_eq!(side, Side::Sell);
}
_ => panic!("Expected IcebergOrder"),
}
let post_only_order = &deserialized.orders()[2];
match **post_only_order {
OrderType::<()>::PostOnly {
id, quantity, side, ..
} => {
assert_eq!(id, Id::from_u64(3));
assert_eq!(quantity, Quantity::new(8));
assert_eq!(side, Side::Buy);
}
_ => panic!("Expected PostOnly order"),
}
}
#[test]
fn test_snapshot_string_format_serialization() {
let snapshot = create_sample_snapshot();
let display_str = snapshot.to_string();
assert!(display_str.starts_with("PriceLevelSnapshot:"));
assert!(display_str.contains("price=1000"));
assert!(display_str.contains("visible_quantity=15"));
assert!(display_str.contains("hidden_quantity=15"));
assert!(display_str.contains("order_count=3"));
}
#[test]
fn test_snapshot_string_format_deserialization() {
let input =
"PriceLevelSnapshot:price=1000;visible_quantity=15;hidden_quantity=15;order_count=3";
let snapshot =
PriceLevelSnapshot::from_str(input).expect("Failed to parse PriceLevelSnapshot");
assert_eq!(snapshot.price(), 1000);
assert_eq!(snapshot.visible_quantity(), 15);
assert_eq!(snapshot.hidden_quantity(), 15);
assert_eq!(snapshot.order_count(), 3);
assert!(snapshot.orders().is_empty());
}
#[test]
fn test_snapshot_string_format_invalid_inputs() {
let input = "PriceLevelSnapshot:visible_quantity=15;hidden_quantity=15;order_count=3";
let result = PriceLevelSnapshot::from_str(input);
assert!(result.is_err());
let input = "InvalidPrefix:price=1000;visible_quantity=15;hidden_quantity=15;order_count=3";
let result = PriceLevelSnapshot::from_str(input);
assert!(result.is_err());
let input =
"PriceLevelSnapshot:price=invalid;visible_quantity=15;hidden_quantity=15;order_count=3";
let result = PriceLevelSnapshot::from_str(input);
assert!(result.is_err());
let input =
"PriceLevelSnapshot:price=1000visible_quantity=15;hidden_quantity=15;order_count=3";
let result = PriceLevelSnapshot::from_str(input);
assert!(result.is_err());
let input = "PriceLevelSnapshot:price=1000;visible_quantity=15;hidden_quantity=15;order_count=3;unknown_field=value";
let result = PriceLevelSnapshot::from_str(input);
assert!(result.is_ok());
}
#[test]
fn test_snapshot_string_format_roundtrip() {
let original = PriceLevelSnapshot::from_raw_parts(1000, 15, 15, 3, Vec::new());
let string_representation = original.to_string();
let parsed = PriceLevelSnapshot::from_str(&string_representation)
.expect("Failed to parse PriceLevelSnapshot");
assert_eq!(parsed.price(), original.price());
assert_eq!(parsed.visible_quantity(), original.visible_quantity());
assert_eq!(parsed.hidden_quantity(), original.hidden_quantity());
assert_eq!(parsed.order_count(), original.order_count());
}
#[test]
fn test_snapshot_edge_cases() {
let snapshot = PriceLevelSnapshot::new(0);
let json = serde_json::to_string(&snapshot).expect("Failed to serialize");
let deserialized: PriceLevelSnapshot =
serde_json::from_str(&json).expect("Failed to deserialize");
assert_eq!(deserialized.price(), 0);
assert_eq!(deserialized.visible_quantity(), 0);
assert_eq!(deserialized.hidden_quantity(), 0);
assert_eq!(deserialized.order_count(), 0);
let snapshot = PriceLevelSnapshot::from_raw_parts(
u128::MAX,
u64::MAX,
u64::MAX,
usize::MAX,
Vec::new(),
);
let json = serde_json::to_string(&snapshot).expect("Failed to serialize max values");
let deserialized: PriceLevelSnapshot =
serde_json::from_str(&json).expect("Failed to deserialize max values");
assert_eq!(deserialized.price(), u128::MAX);
assert_eq!(deserialized.visible_quantity(), u64::MAX);
assert_eq!(deserialized.hidden_quantity(), u64::MAX);
assert_eq!(deserialized.order_count(), usize::MAX);
}
#[test]
fn test_snapshot_deserialization_unknown_field() {
let json = r#"{
"price": 1000,
"visible_quantity": 15,
"hidden_quantity": 15,
"order_count": 3,
"orders": [],
"unknown_field": "some value"
}"#;
let result = serde_json::from_str::<PriceLevelSnapshot>(json);
assert!(result.is_err());
let err = result.unwrap_err();
let err_string = err.to_string();
assert!(err_string.contains("unknown field"));
assert!(err_string.contains("unknown_field"));
assert!(err_string.contains("price"));
assert!(err_string.contains("visible_quantity"));
assert!(err_string.contains("hidden_quantity"));
assert!(err_string.contains("order_count"));
assert!(err_string.contains("orders"));
}
#[test]
fn test_snapshot_empty_orders() {
let snapshot = PriceLevelSnapshot::from_raw_parts(1000, 15, 15, 0, Vec::new());
let json = serde_json::to_string(&snapshot).expect("Failed to serialize");
let deserialized: PriceLevelSnapshot =
serde_json::from_str(&json).expect("Failed to deserialize");
assert_eq!(deserialized.price(), 1000);
assert_eq!(deserialized.orders().len(), 0);
}
#[test]
fn test_snapshot_with_many_order_types() {
let many_orders = vec![
Arc::new(OrderType::Standard {
id: Id::from_u64(1),
price: Price::new(1000),
quantity: Quantity::new(10),
side: Side::Buy,
user_id: Hash32::zero(),
timestamp: TimestampMs::new(1616823000000),
time_in_force: TimeInForce::Gtc,
extra_fields: (),
}),
Arc::new(OrderType::IcebergOrder {
id: Id::from_u64(2),
price: Price::new(1000),
visible_quantity: Quantity::new(5),
hidden_quantity: Quantity::new(15),
side: Side::Sell,
user_id: Hash32::zero(),
timestamp: TimestampMs::new(1616823000001),
time_in_force: TimeInForce::Gtc,
extra_fields: (),
}),
Arc::new(OrderType::PostOnly {
id: Id::from_u64(3),
price: Price::new(1000),
quantity: Quantity::new(8),
side: Side::Buy,
user_id: Hash32::zero(),
timestamp: TimestampMs::new(1616823000002),
time_in_force: TimeInForce::Ioc,
extra_fields: (),
}),
Arc::new(OrderType::Standard {
id: Id::from_u64(4),
price: Price::new(1000),
quantity: Quantity::new(12),
side: Side::Buy,
user_id: Hash32::zero(),
timestamp: TimestampMs::new(1616823000003),
time_in_force: TimeInForce::Fok,
extra_fields: (),
}),
Arc::new(OrderType::Standard {
id: Id::from_u64(5),
price: Price::new(1000),
quantity: Quantity::new(7),
side: Side::Sell,
user_id: Hash32::zero(),
timestamp: TimestampMs::new(1616823000004),
time_in_force: TimeInForce::Gtd(1617000000000),
extra_fields: (),
}),
Arc::new(OrderType::ReserveOrder {
id: Id::from_u64(6),
price: Price::new(1000),
visible_quantity: Quantity::new(3),
hidden_quantity: Quantity::new(12),
side: Side::Buy,
user_id: Hash32::zero(),
timestamp: TimestampMs::new(1616823000005),
time_in_force: TimeInForce::Gtc,
replenish_threshold: Quantity::new(1),
replenish_amount: Some(Quantity::new(2)),
auto_replenish: true,
extra_fields: (),
}),
];
let snapshot = PriceLevelSnapshot::from_raw_parts(
1000,
45, 27, many_orders.len(),
many_orders,
);
let json = serde_json::to_string(&snapshot).expect("Failed to serialize complex snapshot");
let deserialized: PriceLevelSnapshot =
serde_json::from_str(&json).expect("Failed to deserialize complex snapshot");
assert_eq!(deserialized.price(), 1000);
assert_eq!(deserialized.visible_quantity(), 45);
assert_eq!(deserialized.hidden_quantity(), 27);
assert_eq!(deserialized.order_count(), 6);
assert_eq!(deserialized.orders().len(), 6);
let order_types = deserialized
.orders()
.iter()
.map(|order| match **order {
OrderType::Standard { .. } => "Standard",
OrderType::IcebergOrder { .. } => "IcebergOrder",
OrderType::PostOnly { .. } => "PostOnly",
OrderType::ReserveOrder { .. } => "ReserveOrder",
_ => "Other",
})
.collect::<Vec<_>>();
let standard_count = order_types.iter().filter(|&&t| t == "Standard").count();
let iceberg_count = order_types.iter().filter(|&&t| t == "IcebergOrder").count();
let post_only_count = order_types.iter().filter(|&&t| t == "PostOnly").count();
let reserve_count = order_types.iter().filter(|&&t| t == "ReserveOrder").count();
assert_eq!(standard_count, 3); assert_eq!(iceberg_count, 1);
assert_eq!(post_only_count, 1);
assert_eq!(reserve_count, 1);
let reserve_order = deserialized
.orders()
.iter()
.find(|order| matches!(***order, OrderType::ReserveOrder { .. }))
.expect("Reserve order not found");
if let OrderType::ReserveOrder {
replenish_threshold,
auto_replenish,
..
} = **reserve_order
{
assert_eq!(replenish_threshold, Quantity::new(1));
assert!(auto_replenish);
}
let gtd_order = deserialized
.orders()
.iter()
.find(|order| {
matches!(
***order,
OrderType::Standard {
time_in_force: TimeInForce::Gtd(_),
..
}
)
})
.expect("GTD order not found");
if let OrderType::Standard {
time_in_force: TimeInForce::Gtd(expiry),
..
} = **gtd_order
{
assert_eq!(expiry, 1617000000000);
}
}
}