From 79fd55b53868afd689a31ab8092fd5ea164c5cc3 Mon Sep 17 00:00:00 2001 From: Joaquin Bejar Date: Tue, 24 Feb 2026 17:45:29 +0100 Subject: [PATCH 1/3] Bump version to 0.7.0 and upgrade to Rust 2024 edition --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 87955c0..67501d7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pricelevel" -version = "0.6.0" +version = "0.7.0" edition = "2024" authors = ["Joaquin Bejar "] description = "A high-performance, lock-free price level implementation for limit order books in Rust. This library provides the building blocks for creating efficient trading systems with support for multiple order types and concurrent access patterns." From 3b7504deadc9bfd2f7a4f348eb1954340d8786d1 Mon Sep 17 00:00:00 2001 From: Joaquin Bejar Date: Tue, 24 Feb 2026 17:47:35 +0100 Subject: [PATCH 2/3] Mark dependencies as workspace-managed in `Cargo.toml`. --- Cargo.toml | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 67501d7..0143b5c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,15 +28,15 @@ include = [ ] [dependencies] -tracing = "0.1" -tracing-subscriber = { version = "0.3" } -serde_json = "1.0" -serde = { version = "1.0", features = ["derive"] } -crossbeam = "0.8" -uuid = { version = "1.20", features = ["v4", "v5", "serde"] } -ulid = { version = "1.2", features = ["serde"] } -dashmap = "6.1" -sha2 = "0.10" +tracing = { workspace = true } +tracing-subscriber = { workspace = true } +serde_json = { workspace = true } +serde = { workspace = true, features = ["derive"] } +crossbeam = { workspace = true } +uuid = { workspace = true, features = ["v4", "v5", "serde"] } +ulid = { workspace = true, features = ["serde"] } +dashmap = { workspace = true } +sha2 = { workspace = true } [dev-dependencies] @@ -63,4 +63,12 @@ members = [ [workspace.dependencies] pricelevel = { path = "." } -tracing = "0.1.41" +tracing = "0.1" +tracing-subscriber = { version = "0.3" } +serde_json = "1.0" +serde = { version = "1.0", features = ["derive"] } +crossbeam = "0.8" +uuid = { version = "1.21", features = ["v4", "v5", "serde"] } +ulid = { version = "1.2", features = ["serde"] } +dashmap = "6.1" +sha2 = "0.10" From 0077f749c5dff118259e8ae77e2f09d6b0901ca9 Mon Sep 17 00:00:00 2001 From: Joaquin Bejar Date: Tue, 24 Feb 2026 17:56:43 +0100 Subject: [PATCH 3/3] #17: rename Transaction domain to Trade across execution API --- src/execution/list.rs | 99 ++++++++------- src/execution/match_result.rs | 42 +++---- src/execution/mod.rs | 3 +- src/execution/tests/list_trade.rs | 51 ++++++++ src/execution/tests/match_result_trade.rs | 61 +++++++++ src/execution/tests/mod.rs | 4 +- src/execution/tests/transaction.rs | 146 +++++++++++----------- src/execution/transaction.rs | 48 +++---- src/lib.rs | 2 +- src/price_level/level.rs | 18 +-- src/price_level/tests/level.rs | 44 +++---- 11 files changed, 317 insertions(+), 201 deletions(-) create mode 100644 src/execution/tests/list_trade.rs create mode 100644 src/execution/tests/match_result_trade.rs diff --git a/src/execution/list.rs b/src/execution/list.rs index 2c4250f..17911bd 100644 --- a/src/execution/list.rs +++ b/src/execution/list.rs @@ -1,78 +1,81 @@ use crate::errors::PriceLevelError; -use crate::execution::transaction::Transaction; +use crate::execution::transaction::Trade; use serde::{Deserialize, Serialize}; use std::fmt; use std::str::FromStr; -/// A wrapper for a vector of transactions to implement custom serialization +/// A wrapper for a vector of trades to implement custom serialization #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct TransactionList { - pub transactions: Vec, +pub struct TradeList { + /// Ordered collection of trades. + pub trades: Vec, } -impl TransactionList { - /// Create a new empty transaction list +impl TradeList { + /// Create a new empty trade list pub fn new() -> Self { - Self { - transactions: Vec::new(), - } + Self { trades: Vec::new() } } - /// Create a transaction list from an existing vector - pub fn from_vec(transactions: Vec) -> Self { - Self { transactions } + /// Create a trade list from an existing vector + pub fn from_vec(trades: Vec) -> Self { + Self { trades } } - /// Add a transaction to the list - pub fn add(&mut self, transaction: Transaction) { - self.transactions.push(transaction); + /// Add a trade to the list + pub fn add(&mut self, trade: Trade) { + self.trades.push(trade); } /// Get a reference to the underlying vector - pub fn as_vec(&self) -> &Vec { - &self.transactions + pub fn as_vec(&self) -> &Vec { + &self.trades } - /// Convert into a vector of transactions - pub fn into_vec(self) -> Vec { - self.transactions + /// Convert into a vector of trades + pub fn into_vec(self) -> Vec { + self.trades } + /// Returns `true` when the list does not contain any trades. + #[must_use] pub fn is_empty(&self) -> bool { - self.transactions.is_empty() + self.trades.is_empty() } + /// Returns the number of trades in the list. + #[must_use] pub fn len(&self) -> usize { - self.transactions.len() + self.trades.len() } } -impl Default for TransactionList { +impl Default for TradeList { fn default() -> Self { Self::new() } } -impl fmt::Display for TransactionList { +impl fmt::Display for TradeList { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "Transactions:[")?; + write!(f, "Trades:[")?; - for (i, transaction) in self.transactions.iter().enumerate() { + for (i, trade) in self.trades.iter().enumerate() { if i > 0 { write!(f, ",")?; } - write!(f, "{transaction}")?; + write!(f, "{trade}")?; } write!(f, "]") } } -impl FromStr for TransactionList { +impl FromStr for TradeList { type Err = PriceLevelError; fn from_str(s: &str) -> Result { - if !s.starts_with("Transactions:[") || !s.ends_with("]") { + if !s.starts_with("Trades:[") || !s.ends_with("]") { return Err(PriceLevelError::InvalidFormat); } @@ -86,51 +89,51 @@ impl FromStr for TransactionList { let content = &s[content_start + 1..content_end]; if content.is_empty() { - return Ok(TransactionList::new()); + return Ok(TradeList::new()); } - let mut transactions = Vec::new(); - let mut current_transaction = String::new(); + let mut trades = Vec::new(); + let mut current_trade = String::new(); let mut bracket_depth = 0; for c in content.chars() { match c { ',' if bracket_depth == 0 => { - if !current_transaction.is_empty() { - let transaction = Transaction::from_str(¤t_transaction)?; - transactions.push(transaction); - current_transaction.clear(); + if !current_trade.is_empty() { + let trade = Trade::from_str(¤t_trade)?; + trades.push(trade); + current_trade.clear(); } } '[' => { bracket_depth += 1; - current_transaction.push(c); + current_trade.push(c); } ']' => { bracket_depth -= 1; - current_transaction.push(c); + current_trade.push(c); } - _ => current_transaction.push(c), + _ => current_trade.push(c), } } - if !current_transaction.is_empty() { - let transaction = Transaction::from_str(¤t_transaction)?; - transactions.push(transaction); + if !current_trade.is_empty() { + let trade = Trade::from_str(¤t_trade)?; + trades.push(trade); } - Ok(TransactionList { transactions }) + Ok(TradeList { trades }) } } -impl From> for TransactionList { - fn from(transactions: Vec) -> Self { - Self::from_vec(transactions) +impl From> for TradeList { + fn from(trades: Vec) -> Self { + Self::from_vec(trades) } } -impl From for Vec { - fn from(list: TransactionList) -> Self { +impl From for Vec { + fn from(list: TradeList) -> Self { list.into_vec() } } diff --git a/src/execution/match_result.rs b/src/execution/match_result.rs index 37f7269..7c8e3ad 100644 --- a/src/execution/match_result.rs +++ b/src/execution/match_result.rs @@ -1,6 +1,6 @@ use crate::errors::PriceLevelError; -use crate::execution::list::TransactionList; -use crate::execution::transaction::Transaction; +use crate::execution::list::TradeList; +use crate::execution::transaction::Trade; use crate::orders::OrderId; use serde::{Deserialize, Serialize}; use std::fmt; @@ -12,8 +12,8 @@ pub struct MatchResult { /// The ID of the incoming order that initiated the match pub order_id: OrderId, - /// List of transactions that resulted from the match - pub transactions: TransactionList, + /// List of trades that resulted from the match + pub trades: TradeList, /// Remaining quantity of the incoming order after matching pub remaining_quantity: u64, @@ -30,18 +30,18 @@ impl MatchResult { pub fn new(order_id: OrderId, initial_quantity: u64) -> Self { Self { order_id, - transactions: TransactionList::new(), + trades: TradeList::new(), remaining_quantity: initial_quantity, is_complete: false, filled_order_ids: Vec::new(), } } - /// Add a transaction to this match result - pub fn add_transaction(&mut self, transaction: Transaction) { - self.remaining_quantity = self.remaining_quantity.saturating_sub(transaction.quantity); + /// Add a trade to this match result + pub fn add_trade(&mut self, trade: Trade) { + self.remaining_quantity = self.remaining_quantity.saturating_sub(trade.quantity); self.is_complete = self.remaining_quantity == 0; - self.transactions.add(transaction); + self.trades.add(trade); } /// Add a filled order ID to track orders removed from the book @@ -51,12 +51,12 @@ impl MatchResult { /// Get the total executed quantity pub fn executed_quantity(&self) -> u64 { - self.transactions.as_vec().iter().map(|t| t.quantity).sum() + self.trades.as_vec().iter().map(|t| t.quantity).sum() } /// Get the total value executed pub fn executed_value(&self) -> u128 { - self.transactions + self.trades .as_vec() .iter() .map(|t| t.price * (t.quantity as u128)) @@ -81,7 +81,7 @@ impl fmt::Display for MatchResult { "MatchResult:order_id={};remaining_quantity={};is_complete={}", self.order_id, self.remaining_quantity, self.is_complete )?; - write!(f, ";transactions={}", self.transactions)?; + write!(f, ";trades={}", self.trades)?; write!(f, ";filled_order_ids=[")?; for (i, order_id) in self.filled_order_ids.iter().enumerate() { if i > 0 { @@ -122,7 +122,7 @@ impl FromStr for MatchResult { let mut order_id_str = None; let mut remaining_quantity_str = None; let mut is_complete_str = None; - let mut transactions_str = None; + let mut trades_str = None; let mut filled_order_ids_str = None; let mut pos = "MatchResult:".len(); @@ -151,13 +151,13 @@ impl FromStr for MatchResult { is_complete_str = Some(value); pos = next_pos; } - "transactions" => { - if !s[pos..].starts_with("Transactions:[") { + "trades" => { + if !s[pos..].starts_with("Trades:[") { return Err(PriceLevelError::InvalidFormat); } let mut bracket_depth = 1; - let mut i = pos + "Transactions:[".len(); + let mut i = pos + "Trades:[".len(); while i < s.len() && bracket_depth > 0 { if s[i..].starts_with(']') { @@ -178,7 +178,7 @@ impl FromStr for MatchResult { return Err(PriceLevelError::InvalidFormat); } - transactions_str = Some(&s[pos..=i]); + trades_str = Some(&s[pos..=i]); pos = i + 1; if pos < s.len() && s[pos..].starts_with(';') { pos += 1; @@ -230,8 +230,8 @@ impl FromStr for MatchResult { .ok_or_else(|| PriceLevelError::MissingField("remaining_quantity".to_string()))?; let is_complete_str = is_complete_str .ok_or_else(|| PriceLevelError::MissingField("is_complete".to_string()))?; - let transactions_str = transactions_str - .ok_or_else(|| PriceLevelError::MissingField("transactions".to_string()))?; + let trades_str = + trades_str.ok_or_else(|| PriceLevelError::MissingField("trades".to_string()))?; let filled_order_ids_str = filled_order_ids_str .ok_or_else(|| PriceLevelError::MissingField("filled_order_ids".to_string()))?; @@ -256,7 +256,7 @@ impl FromStr for MatchResult { value: is_complete_str.to_string(), })?; - let transactions = TransactionList::from_str(transactions_str)?; + let trades = TradeList::from_str(trades_str)?; let filled_order_ids = if filled_order_ids_str == "[]" { Vec::new() @@ -280,7 +280,7 @@ impl FromStr for MatchResult { Ok(MatchResult { order_id, - transactions, + trades, remaining_quantity, is_complete, filled_order_ids, diff --git a/src/execution/mod.rs b/src/execution/mod.rs index c839aff..332d8f0 100644 --- a/src/execution/mod.rs +++ b/src/execution/mod.rs @@ -4,5 +4,6 @@ mod list; mod match_result; mod tests; +pub use list::TradeList; pub use match_result::MatchResult; -pub use transaction::Transaction; +pub use transaction::Trade; diff --git a/src/execution/tests/list_trade.rs b/src/execution/tests/list_trade.rs new file mode 100644 index 0000000..f7052bf --- /dev/null +++ b/src/execution/tests/list_trade.rs @@ -0,0 +1,51 @@ +#[cfg(test)] +mod tests { + use crate::execution::list::TradeList; + use crate::execution::transaction::Trade; + use crate::orders::{OrderId, Side}; + use std::str::FromStr; + use uuid::Uuid; + + fn parse_uuid(input: &str) -> Uuid { + match Uuid::parse_str(input) { + Ok(value) => value, + Err(error) => panic!("failed to parse uuid: {error}"), + } + } + + fn sample_trade() -> Trade { + Trade { + trade_id: parse_uuid("6ba7b810-9dad-11d1-80b4-00c04fd430c8"), + taker_order_id: OrderId::from_u64(1), + maker_order_id: OrderId::from_u64(2), + price: 10_000, + quantity: 5, + taker_side: Side::Buy, + timestamp: 1_616_823_000_000, + } + } + + #[test] + fn trade_list_display_and_parse_roundtrip() { + let mut list = TradeList::new(); + list.add(sample_trade()); + + let rendered = list.to_string(); + assert!(rendered.starts_with("Trades:[")); + assert!(rendered.contains("Trade:trade_id=")); + + let parsed = match TradeList::from_str(&rendered) { + Ok(value) => value, + Err(error) => panic!("failed to parse trade list: {error:?}"), + }; + + assert_eq!(parsed.len(), 1); + assert_eq!(parsed.as_vec()[0].trade_id, list.as_vec()[0].trade_id); + } + + #[test] + fn trade_list_from_str_rejects_old_prefix() { + let result = TradeList::from_str("Transactions:[]"); + assert!(result.is_err()); + } +} diff --git a/src/execution/tests/match_result_trade.rs b/src/execution/tests/match_result_trade.rs new file mode 100644 index 0000000..20451e8 --- /dev/null +++ b/src/execution/tests/match_result_trade.rs @@ -0,0 +1,61 @@ +#[cfg(test)] +mod tests { + use crate::execution::match_result::MatchResult; + use crate::execution::transaction::Trade; + use crate::orders::{OrderId, Side}; + use std::str::FromStr; + use uuid::Uuid; + + fn parse_uuid(input: &str) -> Uuid { + match Uuid::parse_str(input) { + Ok(value) => value, + Err(error) => panic!("failed to parse uuid: {error}"), + } + } + + fn sample_trade(quantity: u64) -> Trade { + Trade { + trade_id: parse_uuid("6ba7b810-9dad-11d1-80b4-00c04fd430c8"), + taker_order_id: OrderId::from_u64(10), + maker_order_id: OrderId::from_u64(20), + price: 1_000, + quantity, + taker_side: Side::Buy, + timestamp: 1_616_823_000_000, + } + } + + #[test] + fn add_trade_updates_remaining_and_trades() { + let mut result = MatchResult::new(OrderId::from_u64(10), 100); + result.add_trade(sample_trade(25)); + + assert_eq!(result.remaining_quantity, 75); + assert_eq!(result.trades.len(), 1); + assert!(!result.is_complete); + } + + #[test] + fn display_and_parse_use_trades_field() { + let mut result = MatchResult::new(OrderId::from_u64(10), 100); + result.add_trade(sample_trade(40)); + + let rendered = result.to_string(); + assert!(rendered.contains(";trades=Trades:[Trade:")); + + let parsed = match MatchResult::from_str(&rendered) { + Ok(value) => value, + Err(error) => panic!("failed to parse match result: {error:?}"), + }; + + assert_eq!(parsed.trades.len(), 1); + assert_eq!(parsed.remaining_quantity, 60); + } + + #[test] + fn from_str_rejects_old_transactions_field() { + let old_payload = "MatchResult:order_id=1;remaining_quantity=1;is_complete=false;transactions=Transactions:[];filled_order_ids=[]"; + let parsed = MatchResult::from_str(old_payload); + assert!(parsed.is_err()); + } +} diff --git a/src/execution/tests/mod.rs b/src/execution/tests/mod.rs index c482985..61f45c6 100644 --- a/src/execution/tests/mod.rs +++ b/src/execution/tests/mod.rs @@ -1,3 +1,3 @@ -mod list; -mod match_result; +mod list_trade; +mod match_result_trade; mod transaction; diff --git a/src/execution/tests/transaction.rs b/src/execution/tests/transaction.rs index 981a24a..9056b68 100644 --- a/src/execution/tests/transaction.rs +++ b/src/execution/tests/transaction.rs @@ -1,17 +1,17 @@ #[cfg(test)] mod tests { use crate::errors::PriceLevelError; - use crate::execution::transaction::Transaction; + use crate::execution::transaction::Trade; use crate::orders::{OrderId, Side}; use std::str::FromStr; use std::time::{SystemTime, UNIX_EPOCH}; use uuid::Uuid; - fn create_test_transaction() -> Transaction { + fn create_test_trade() -> Trade { let uuid = Uuid::parse_str("6ba7b810-9dad-11d1-80b4-00c04fd430c8").unwrap(); - Transaction { - transaction_id: uuid, + Trade { + trade_id: uuid, taker_order_id: OrderId::from_u64(1), maker_order_id: OrderId::from_u64(2), price: 10000, @@ -23,11 +23,11 @@ mod tests { #[test] fn test_transaction_display() { - let transaction = create_test_transaction(); + let transaction = create_test_trade(); let display_str = transaction.to_string(); - assert!(display_str.starts_with("Transaction:")); - assert!(display_str.contains("transaction_id=6ba7b810-9dad-11d1-80b4-00c04fd430c8")); + assert!(display_str.starts_with("Trade:")); + assert!(display_str.contains("trade_id=6ba7b810-9dad-11d1-80b4-00c04fd430c8")); assert!(display_str.contains("taker_order_id=00000000-0000-0001-0000-000000000000")); assert!(display_str.contains("maker_order_id=00000000-0000-0002-0000-000000000000")); assert!(display_str.contains("price=10000")); @@ -38,10 +38,10 @@ mod tests { #[test] fn test_transaction_from_str_valid() { - let input = "Transaction:transaction_id=6ba7b810-9dad-11d1-80b4-00c04fd430c8;taker_order_id=00000000-0000-0001-0000-000000000000;maker_order_id=00000000-0000-0002-0000-000000000000;price=10000;quantity=5;taker_side=BUY;timestamp=1616823000000"; - let transaction = Transaction::from_str(input).unwrap(); + let input = "Trade:trade_id=6ba7b810-9dad-11d1-80b4-00c04fd430c8;taker_order_id=00000000-0000-0001-0000-000000000000;maker_order_id=00000000-0000-0002-0000-000000000000;price=10000;quantity=5;taker_side=BUY;timestamp=1616823000000"; + let transaction = Trade::from_str(input).unwrap(); let uuid = Uuid::parse_str("6ba7b810-9dad-11d1-80b4-00c04fd430c8").unwrap(); - assert_eq!(transaction.transaction_id, uuid); + assert_eq!(transaction.trade_id, uuid); assert_eq!(transaction.taker_order_id, OrderId::from_u64(1)); assert_eq!(transaction.maker_order_id, OrderId::from_u64(2)); assert_eq!(transaction.price, 10000); @@ -53,19 +53,19 @@ mod tests { #[test] fn test_transaction_from_str_invalid_format() { let input = "InvalidFormat"; - let result = Transaction::from_str(input); + let result = Trade::from_str(input); assert!(result.is_err()); - let input = "Transaction;transaction_id=12345"; - let result = Transaction::from_str(input); + let input = "Trade;trade_id=12345"; + let result = Trade::from_str(input); assert!(result.is_err()); } #[test] fn test_transaction_from_str_missing_field() { // Missing quantity field - let input = "Transaction:transaction_id=6ba7b810-9dad-11d1-80b4-00c04fd430c8;taker_order_id=00000000-0000-0001-0000-000000000000;maker_order_id=00000000-0000-0002-0000-000000000000;price=10000;taker_side=BUY;timestamp=1616823000000"; - let result = Transaction::from_str(input); + let input = "Trade:trade_id=6ba7b810-9dad-11d1-80b4-00c04fd430c8;taker_order_id=00000000-0000-0001-0000-000000000000;maker_order_id=00000000-0000-0002-0000-000000000000;price=10000;taker_side=BUY;timestamp=1616823000000"; + let result = Trade::from_str(input); assert!(result.is_err()); match result.unwrap_err() { @@ -78,37 +78,37 @@ mod tests { #[test] fn test_transaction_from_str_invalid_field_value() { - // Invalid transaction_id (not a number) - let input = "Transaction:transaction_id=abc;taker_order_id=1;maker_order_id=2;price=10000;quantity=5;taker_side=BUY;timestamp=1616823000000"; - let result = Transaction::from_str(input); + // Invalid trade_id + let input = "Trade:trade_id=abc;taker_order_id=1;maker_order_id=2;price=10000;quantity=5;taker_side=BUY;timestamp=1616823000000"; + let result = Trade::from_str(input); assert!(result.is_err()); match result.unwrap_err() { PriceLevelError::InvalidFieldValue { field, value } => { - assert_eq!(field, "transaction_id"); + assert_eq!(field, "trade_id"); assert_eq!(value, "abc"); } err => panic!("Expected InvalidFieldValue error, got {err:?}"), } // Invalid taker_order_id - let input = "Transaction:transaction_id=12345;taker_order_id=abc;maker_order_id=2;price=10000;quantity=5;taker_side=BUY;timestamp=1616823000000"; - let result = Transaction::from_str(input); + let input = "Trade:trade_id=12345;taker_order_id=abc;maker_order_id=2;price=10000;quantity=5;taker_side=BUY;timestamp=1616823000000"; + let result = Trade::from_str(input); assert!(result.is_err()); // Invalid side - let input = "Transaction:transaction_id=12345;taker_order_id=1;maker_order_id=2;price=10000;quantity=5;taker_side=INVALID;timestamp=1616823000000"; - let result = Transaction::from_str(input); + let input = "Trade:trade_id=12345;taker_order_id=1;maker_order_id=2;price=10000;quantity=5;taker_side=INVALID;timestamp=1616823000000"; + let result = Trade::from_str(input); assert!(result.is_err()); } #[test] fn test_transaction_round_trip() { - let original = create_test_transaction(); + let original = create_test_trade(); let string_representation = original.to_string(); - let parsed = Transaction::from_str(&string_representation).unwrap(); + let parsed = Trade::from_str(&string_representation).unwrap(); - assert_eq!(parsed.transaction_id, original.transaction_id); + assert_eq!(parsed.trade_id, original.trade_id); assert_eq!(parsed.taker_order_id, original.taker_order_id); assert_eq!(parsed.maker_order_id, original.maker_order_id); assert_eq!(parsed.price, original.price); @@ -120,7 +120,7 @@ mod tests { #[test] fn test_maker_side() { // Test when taker is buyer - let mut transaction = create_test_transaction(); + let mut transaction = create_test_trade(); transaction.taker_side = Side::Buy; assert_eq!(transaction.maker_side(), Side::Sell); @@ -131,7 +131,7 @@ mod tests { #[test] fn test_total_value() { - let mut transaction = create_test_transaction(); + let mut transaction = create_test_trade(); transaction.price = 10000; transaction.quantity = 5; @@ -144,14 +144,14 @@ mod tests { } #[test] - fn test_new_transaction() { + fn test_new_trade() { let now = SystemTime::now() .duration_since(UNIX_EPOCH) .unwrap() .as_millis() as u64; let uuid = Uuid::parse_str("6ba7b810-9dad-11d1-80b4-00c04fd430c8").unwrap(); - let transaction = Transaction::new( + let transaction = Trade::new( uuid, OrderId::from_u64(1), OrderId::from_u64(2), @@ -160,7 +160,7 @@ mod tests { Side::Buy, ); - assert_eq!(transaction.transaction_id, uuid); + assert_eq!(transaction.trade_id, uuid); assert_eq!(transaction.taker_order_id, OrderId::from_u64(1)); assert_eq!(transaction.maker_order_id, OrderId::from_u64(2)); assert_eq!(transaction.price, 10000); @@ -181,12 +181,12 @@ mod tests { #[test] fn test_transaction_from_str_all_fields() { - let input = "Transaction:transaction_id=6ba7b810-9dad-11d1-80b4-00c04fd430c8;taker_order_id=00000000-0000-0001-0000-000000000000;maker_order_id=00000000-0000-0002-0000-000000000000;price=10000;quantity=5;taker_side=BUY;timestamp=1616823000000"; + let input = "Trade:trade_id=6ba7b810-9dad-11d1-80b4-00c04fd430c8;taker_order_id=00000000-0000-0001-0000-000000000000;maker_order_id=00000000-0000-0002-0000-000000000000;price=10000;quantity=5;taker_side=BUY;timestamp=1616823000000"; - let transaction = Transaction::from_str(input).unwrap(); + let transaction = Trade::from_str(input).unwrap(); let uuid = Uuid::parse_str("6ba7b810-9dad-11d1-80b4-00c04fd430c8").unwrap(); - assert_eq!(transaction.transaction_id, uuid); + assert_eq!(transaction.trade_id, uuid); assert_eq!(transaction.taker_order_id, OrderId::from_u64(1)); assert_eq!(transaction.maker_order_id, OrderId::from_u64(2)); assert_eq!(transaction.price, 10000); @@ -199,7 +199,7 @@ mod tests { fn test_transaction_get_field_helper() { // Simulate get_field function being used in the from_str implementation let mut fields = std::collections::HashMap::new(); - fields.insert("transaction_id", "6ba7b810-9dad-11d1-80b4-00c04fd430c8"); + fields.insert("trade_id", "6ba7b810-9dad-11d1-80b4-00c04fd430c8"); fields.insert("price", "10000"); // Test successful field retrieval @@ -211,7 +211,7 @@ mod tests { }; assert_eq!( - get_field("transaction_id").unwrap(), + get_field("trade_id").unwrap(), "6ba7b810-9dad-11d1-80b4-00c04fd430c8" ); assert_eq!(get_field("price").unwrap(), "10000"); @@ -255,15 +255,15 @@ mod tests { #[cfg(test)] mod transaction_serialization_tests { - use crate::execution::transaction::Transaction; + use crate::execution::transaction::Trade; use crate::orders::{OrderId, Side}; use std::str::FromStr; use uuid::Uuid; - fn create_test_transaction() -> Transaction { + fn create_test_trade() -> Trade { let uuid = Uuid::parse_str("6ba7b810-9dad-11d1-80b4-00c04fd430c8").unwrap(); - Transaction { - transaction_id: uuid, + Trade { + trade_id: uuid, taker_order_id: OrderId::from_u64(1), maker_order_id: OrderId::from_u64(2), price: 10000, @@ -275,9 +275,9 @@ mod transaction_serialization_tests { #[test] fn test_serde_json_serialization() { - let transaction = create_test_transaction(); + let transaction = create_test_trade(); let json = serde_json::to_string(&transaction).unwrap(); - assert!(json.contains("\"transaction_id\":\"6ba7b810-9dad-11d1-80b4-00c04fd430c8\"")); + assert!(json.contains("\"trade_id\":\"6ba7b810-9dad-11d1-80b4-00c04fd430c8\"")); assert!(json.contains("\"taker_order_id\":\"00000000-0000-0001-0000-000000000000\"")); assert!(json.contains("\"maker_order_id\":\"00000000-0000-0002-0000-000000000000\"")); assert!(json.contains("\"price\":10000")); @@ -289,7 +289,7 @@ mod transaction_serialization_tests { #[test] fn test_serde_json_deserialization() { let json = r#"{ - "transaction_id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8", + "trade_id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8", "taker_order_id": "00000000-0000-0001-0000-000000000000", "maker_order_id": "00000000-0000-0002-0000-000000000000", "price": 10000, @@ -298,9 +298,9 @@ mod transaction_serialization_tests { "timestamp": 1616823000000 }"#; - let transaction: Transaction = serde_json::from_str(json).unwrap(); + let transaction: Trade = serde_json::from_str(json).unwrap(); let uuid = Uuid::parse_str("6ba7b810-9dad-11d1-80b4-00c04fd430c8").unwrap(); - assert_eq!(transaction.transaction_id, uuid); + assert_eq!(transaction.trade_id, uuid); assert_eq!(transaction.taker_order_id, OrderId::from_u64(1)); assert_eq!(transaction.maker_order_id, OrderId::from_u64(2)); assert_eq!(transaction.price, 10000); @@ -311,13 +311,13 @@ mod transaction_serialization_tests { #[test] fn test_serde_json_round_trip() { - let original = create_test_transaction(); + let original = create_test_trade(); let json = serde_json::to_string(&original).unwrap(); - let deserialized: Transaction = serde_json::from_str(&json).unwrap(); + let deserialized: Trade = serde_json::from_str(&json).unwrap(); - assert_eq!(deserialized.transaction_id, original.transaction_id); + assert_eq!(deserialized.trade_id, original.trade_id); assert_eq!(deserialized.taker_order_id, original.taker_order_id); assert_eq!(deserialized.maker_order_id, original.maker_order_id); assert_eq!(deserialized.price, original.price); @@ -328,11 +328,11 @@ mod transaction_serialization_tests { #[test] fn test_custom_display_format() { - let transaction = create_test_transaction(); + let transaction = create_test_trade(); let display_str = transaction.to_string(); - assert!(display_str.starts_with("Transaction:")); - assert!(display_str.contains("transaction_id=6ba7b810-9dad-11d1-80b4-00c04fd430c8")); + assert!(display_str.starts_with("Trade:")); + assert!(display_str.contains("trade_id=6ba7b810-9dad-11d1-80b4-00c04fd430c8")); assert!(display_str.contains("taker_order_id=00000000-0000-0001-0000-000000000000")); assert!(display_str.contains("maker_order_id=00000000-0000-0002-0000-000000000000")); assert!(display_str.contains("price=10000")); @@ -343,10 +343,10 @@ mod transaction_serialization_tests { #[test] fn test_from_str_valid() { - let input = "Transaction:transaction_id=6ba7b810-9dad-11d1-80b4-00c04fd430c8;taker_order_id=00000000-0000-0001-0000-000000000000;maker_order_id=00000000-0000-0002-0000-000000000000;price=10000;quantity=5;taker_side=BUY;timestamp=1616823000000"; - let transaction = Transaction::from_str(input).unwrap(); + let input = "Trade:trade_id=6ba7b810-9dad-11d1-80b4-00c04fd430c8;taker_order_id=00000000-0000-0001-0000-000000000000;maker_order_id=00000000-0000-0002-0000-000000000000;price=10000;quantity=5;taker_side=BUY;timestamp=1616823000000"; + let transaction = Trade::from_str(input).unwrap(); let uuid = Uuid::parse_str("6ba7b810-9dad-11d1-80b4-00c04fd430c8").unwrap(); - assert_eq!(transaction.transaction_id, uuid); + assert_eq!(transaction.trade_id, uuid); assert_eq!(transaction.taker_order_id, OrderId::from_u64(1)); assert_eq!(transaction.maker_order_id, OrderId::from_u64(2)); assert_eq!(transaction.price, 10000); @@ -358,47 +358,47 @@ mod transaction_serialization_tests { #[test] fn test_from_str_invalid_format() { let input = "InvalidFormat"; - let result = Transaction::from_str(input); + let result = Trade::from_str(input); assert!(result.is_err()); - let input = "TransactionX:transaction_id=12345;taker_order_id=1;maker_order_id=2;price=10000;quantity=5;taker_side=BUY;timestamp=1616823000000"; - let result = Transaction::from_str(input); + let input = "TradeX:trade_id=12345;taker_order_id=1;maker_order_id=2;price=10000;quantity=5;taker_side=BUY;timestamp=1616823000000"; + let result = Trade::from_str(input); assert!(result.is_err()); - let input = "Transaction:"; - let result = Transaction::from_str(input); + let input = "Trade:"; + let result = Trade::from_str(input); assert!(result.is_err()); } #[test] fn test_from_str_missing_field() { - let input = "Transaction:taker_order_id=1;maker_order_id=2;price=10000;quantity=5;taker_side=BUY;timestamp=1616823000000"; - let result = Transaction::from_str(input); + let input = "Trade:taker_order_id=1;maker_order_id=2;price=10000;quantity=5;taker_side=BUY;timestamp=1616823000000"; + let result = Trade::from_str(input); assert!(result.is_err()); - let input = "Transaction:transaction_id=12345;taker_order_id=1;maker_order_id=2;quantity=5;taker_side=BUY;timestamp=1616823000000"; - let result = Transaction::from_str(input); + let input = "Trade:trade_id=12345;taker_order_id=1;maker_order_id=2;quantity=5;taker_side=BUY;timestamp=1616823000000"; + let result = Trade::from_str(input); assert!(result.is_err()); } #[test] fn test_from_str_invalid_field_value() { - let input = "Transaction:transaction_id=abc;taker_order_id=1;maker_order_id=2;price=10000;quantity=5;taker_side=BUY;timestamp=1616823000000"; - let result = Transaction::from_str(input); + let input = "Trade:trade_id=abc;taker_order_id=1;maker_order_id=2;price=10000;quantity=5;taker_side=BUY;timestamp=1616823000000"; + let result = Trade::from_str(input); assert!(result.is_err()); - let input = "Transaction:transaction_id=12345;taker_order_id=1;maker_order_id=2;price=10000;quantity=5;taker_side=INVALID;timestamp=1616823000000"; - let result = Transaction::from_str(input); + let input = "Trade:trade_id=12345;taker_order_id=1;maker_order_id=2;price=10000;quantity=5;taker_side=INVALID;timestamp=1616823000000"; + let result = Trade::from_str(input); assert!(result.is_err()); } #[test] fn test_custom_serialization_round_trip() { - let original = create_test_transaction(); + let original = create_test_trade(); let string_representation = original.to_string(); - let parsed = Transaction::from_str(&string_representation).unwrap(); + let parsed = Trade::from_str(&string_representation).unwrap(); - assert_eq!(parsed.transaction_id, original.transaction_id); + assert_eq!(parsed.trade_id, original.trade_id); assert_eq!(parsed.taker_order_id, original.taker_order_id); assert_eq!(parsed.maker_order_id, original.maker_order_id); assert_eq!(parsed.price, original.price); @@ -409,7 +409,7 @@ mod transaction_serialization_tests { #[test] fn test_maker_side_when_taker_is_buyer() { - let mut transaction = create_test_transaction(); + let mut transaction = create_test_trade(); transaction.taker_side = Side::Buy; assert_eq!(transaction.maker_side(), Side::Sell); @@ -417,7 +417,7 @@ mod transaction_serialization_tests { #[test] fn test_maker_side_when_taker_is_seller() { - let mut transaction = create_test_transaction(); + let mut transaction = create_test_trade(); transaction.taker_side = Side::Sell; assert_eq!(transaction.maker_side(), Side::Buy); @@ -425,7 +425,7 @@ mod transaction_serialization_tests { #[test] fn test_total_value_calculation() { - let mut transaction = create_test_transaction(); + let mut transaction = create_test_trade(); transaction.price = 10000; transaction.quantity = 5; diff --git a/src/execution/transaction.rs b/src/execution/transaction.rs index e0f1308..38e9511 100644 --- a/src/execution/transaction.rs +++ b/src/execution/transaction.rs @@ -6,11 +6,11 @@ use std::str::FromStr; use std::time::{SystemTime, UNIX_EPOCH}; use uuid::Uuid; -/// Represents a completed transaction between two orders +/// Represents a completed trade between two orders #[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)] -pub struct Transaction { - /// Unique transaction ID - pub transaction_id: Uuid, +pub struct Trade { + /// Unique trade ID + pub trade_id: Uuid, /// ID of the aggressive order that caused the match pub taker_order_id: OrderId, @@ -18,23 +18,23 @@ pub struct Transaction { /// ID of the passive order that was in the book pub maker_order_id: OrderId, - /// Price at which the transaction occurred + /// Price at which the trade occurred pub price: u128, - /// Quantity that was traded + /// Quantity traded pub quantity: u64, /// Side of the taker order pub taker_side: Side, - /// Timestamp when the transaction occurred + /// Timestamp when the trade occurred pub timestamp: u64, } -impl Transaction { - /// Create a new transaction +impl Trade { + /// Create a new trade pub fn new( - transaction_id: Uuid, + trade_id: Uuid, taker_order_id: OrderId, maker_order_id: OrderId, price: u128, @@ -47,7 +47,7 @@ impl Transaction { .as_millis() as u64; Self { - transaction_id, + trade_id, taker_order_id, maker_order_id, price, @@ -65,18 +65,18 @@ impl Transaction { } } - /// Returns the total value of this transaction + /// Returns the total value of this trade pub fn total_value(&self) -> u128 { self.price * (self.quantity as u128) } } -impl fmt::Display for Transaction { +impl fmt::Display for Trade { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "Transaction:transaction_id={};taker_order_id={};maker_order_id={};price={};quantity={};taker_side={};timestamp={}", - self.transaction_id, + "Trade:trade_id={};taker_order_id={};maker_order_id={};price={};quantity={};taker_side={};timestamp={}", + self.trade_id, self.taker_order_id, self.maker_order_id, self.price, @@ -87,12 +87,12 @@ impl fmt::Display for Transaction { } } -impl FromStr for Transaction { +impl FromStr for Trade { type Err = PriceLevelError; fn from_str(s: &str) -> Result { let parts: Vec<&str> = s.split(':').collect(); - if parts.len() != 2 || parts[0] != "Transaction" { + if parts.len() != 2 || parts[0] != "Trade" { return Err(PriceLevelError::InvalidFormat); } @@ -131,14 +131,14 @@ impl FromStr for Transaction { }) }; - // Parse transaction_id - let transaction_id_str = get_field("transaction_id")?; - let transaction_id = match Uuid::from_str(transaction_id_str) { + // Parse trade_id + let trade_id_str = get_field("trade_id")?; + let trade_id = match Uuid::from_str(trade_id_str) { Ok(id) => id, Err(_) => { return Err(PriceLevelError::InvalidFieldValue { - field: "transaction_id".to_string(), - value: transaction_id_str.to_string(), + field: "trade_id".to_string(), + value: trade_id_str.to_string(), }); } }; @@ -181,8 +181,8 @@ impl FromStr for Transaction { let timestamp_str = get_field("timestamp")?; let timestamp = parse_u64("timestamp", timestamp_str)?; - Ok(Transaction { - transaction_id, + Ok(Trade { + trade_id, taker_order_id, maker_order_id, price, diff --git a/src/lib.rs b/src/lib.rs index e181b93..af61e05 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -143,7 +143,7 @@ mod errors; mod execution; pub use errors::PriceLevelError; -pub use execution::{MatchResult, Transaction}; +pub use execution::{MatchResult, Trade, TradeList}; pub use orders::DEFAULT_RESERVE_REPLENISH_AMOUNT; pub use orders::PegReferenceType; pub use orders::{Hash32, OrderId, OrderType, OrderUpdate, Side, TimeInForce}; diff --git a/src/price_level/level.rs b/src/price_level/level.rs index f8f0b05..4361e67 100644 --- a/src/price_level/level.rs +++ b/src/price_level/level.rs @@ -2,7 +2,7 @@ use crate::UuidGenerator; use crate::errors::PriceLevelError; -use crate::execution::{MatchResult, Transaction}; +use crate::execution::{MatchResult, Trade}; use crate::orders::{OrderId, OrderType, OrderUpdate}; use crate::price_level::order_queue::OrderQueue; use crate::price_level::{PriceLevelSnapshot, PriceLevelSnapshotPackage, PriceLevelStatistics}; @@ -142,7 +142,7 @@ impl PriceLevel { /// /// This function attempts to match the incoming order quantity against the orders present in the /// `OrderQueue`. It iterates through the queue, matching orders until the incoming quantity is - /// fully filled or the queue is exhausted. Transactions are generated for each successful match, + /// fully filled or the queue is exhausted. Trades are generated for each successful match, /// and filled orders are removed from the queue. The function also updates the visible and hidden /// quantity counters and records statistics for each execution. /// @@ -150,19 +150,19 @@ impl PriceLevel { /// /// * `incoming_quantity`: The quantity of the incoming order to be matched. /// * `taker_order_id`: The ID of the incoming order (the "taker" order). - /// * `transaction_id_generator`: An atomic counter used to generate unique transaction IDs. + /// * `trade_id_generator`: An atomic counter used to generate unique trade IDs. /// /// # Returns /// /// A `MatchResult` object containing the results of the matching operation, including a list of - /// generated transactions, the remaining unmatched quantity, a flag indicating whether the + /// generated trades, the remaining unmatched quantity, a flag indicating whether the /// incoming order was completely filled, and a list of IDs of orders that were completely filled /// during the matching process. pub fn match_order( &self, incoming_quantity: u64, taker_order_id: OrderId, - transaction_id_generator: &UuidGenerator, + trade_id_generator: &UuidGenerator, ) -> MatchResult { let mut result = MatchResult::new(taker_order_id, incoming_quantity); let mut remaining = incoming_quantity; @@ -177,10 +177,10 @@ impl PriceLevel { self.visible_quantity.fetch_sub(consumed, Ordering::AcqRel); // Use UUID generator directly - let transaction_id = transaction_id_generator.next(); + let trade_id = trade_id_generator.next(); - let transaction = Transaction::new( - transaction_id, + let trade = Trade::new( + trade_id, taker_order_id, order_arc.id(), self.price, @@ -188,7 +188,7 @@ impl PriceLevel { order_arc.side().opposite(), ); - result.add_transaction(transaction); + result.add_trade(trade); // If the order was completely executed, add it to filled_order_ids if updated_order.is_none() { diff --git a/src/price_level/tests/level.rs b/src/price_level/tests/level.rs index b98eaeb..ed835a4 100644 --- a/src/price_level/tests/level.rs +++ b/src/price_level/tests/level.rs @@ -452,8 +452,8 @@ mod tests { assert_eq!(price_level.visible_quantity(), 0); assert_eq!(price_level.order_count(), 0); - assert_eq!(match_result.transactions.len(), 1); - let transaction = &match_result.transactions.as_vec()[0]; + assert_eq!(match_result.trades.len(), 1); + let transaction = &match_result.trades.as_vec()[0]; assert_eq!(transaction.taker_order_id, taker_id); assert_eq!(transaction.maker_order_id, OrderId::from_u64(1)); assert_eq!(transaction.price, 10000); @@ -489,8 +489,8 @@ mod tests { assert_eq!(price_level.order_count(), 1); // Verificar las transacciones generadas - assert_eq!(match_result.transactions.len(), 1); - let transaction = &match_result.transactions.as_vec()[0]; + assert_eq!(match_result.trades.len(), 1); + let transaction = &match_result.trades.as_vec()[0]; assert_eq!(transaction.taker_order_id, taker_id); assert_eq!(transaction.maker_order_id, OrderId::from_u64(1)); assert_eq!(transaction.price, 10000); @@ -523,8 +523,8 @@ mod tests { assert_eq!(price_level.visible_quantity(), 0); assert_eq!(price_level.order_count(), 0); - assert_eq!(match_result.transactions.len(), 1); - let transaction = &match_result.transactions.as_vec()[0]; + assert_eq!(match_result.trades.len(), 1); + let transaction = &match_result.trades.as_vec()[0]; assert_eq!(transaction.taker_order_id, taker_id); assert_eq!(transaction.maker_order_id, OrderId::from_u64(1)); assert_eq!(transaction.price, 10000); @@ -560,10 +560,10 @@ mod tests { assert_eq!(price_level.visible_quantity(), 50); assert_eq!(price_level.hidden_quantity(), 50); // Hidden quantity reduced assert_eq!(price_level.order_count(), 1); - assert_eq!(match_result.transactions.len(), 1); + assert_eq!(match_result.trades.len(), 1); // Assertions about the generated transaction - let transaction = &match_result.transactions.as_vec()[0]; + let transaction = &match_result.trades.as_vec()[0]; assert_eq!(transaction.taker_order_id, taker_id); assert_eq!(transaction.maker_order_id, OrderId::from_u64(1)); assert_eq!(transaction.price, 10000); @@ -579,7 +579,7 @@ mod tests { assert_eq!(price_level.visible_quantity(), 50); // Visible quantity replenished assert_eq!(price_level.hidden_quantity(), 0); // Hidden quantity reduced assert_eq!(price_level.order_count(), 1); - let transaction = &match_result.transactions.as_vec()[0]; + let transaction = &match_result.trades.as_vec()[0]; assert_eq!(transaction.taker_order_id, taker_id); assert_eq!(transaction.maker_order_id, OrderId::from_u64(1)); @@ -620,10 +620,10 @@ mod tests { assert_eq!(price_level.visible_quantity(), 50); assert_eq!(price_level.hidden_quantity(), 100); // Hidden quantity reduced assert_eq!(price_level.order_count(), 1); - assert_eq!(match_result.transactions.len(), 1); + assert_eq!(match_result.trades.len(), 1); // Assertions about the generated transaction - let transaction = &match_result.transactions.as_vec()[0]; + let transaction = &match_result.trades.as_vec()[0]; assert_eq!(transaction.taker_order_id, taker_id); assert_eq!(transaction.maker_order_id, OrderId::from_u64(1)); assert_eq!(transaction.price, 10000); @@ -639,7 +639,7 @@ mod tests { assert_eq!(price_level.visible_quantity(), 50); // Visible quantity replenished assert_eq!(price_level.hidden_quantity(), 50); // Hidden quantity reduced assert_eq!(price_level.order_count(), 1); - let transaction = &match_result.transactions.as_vec()[0]; + let transaction = &match_result.trades.as_vec()[0]; assert_eq!(transaction.taker_order_id, taker_id); assert_eq!(transaction.maker_order_id, OrderId::from_u64(1)); @@ -929,10 +929,10 @@ mod tests { assert_eq!(price_level.visible_quantity(), 20); // 100 - 80 = 20 assert_eq!(price_level.hidden_quantity(), 100); // Hidden quantity unchanged (still above threshold) assert_eq!(price_level.order_count(), 1); - assert_eq!(match_result.transactions.len(), 1); + assert_eq!(match_result.trades.len(), 1); // Validate the transaction details - let transaction = &match_result.transactions.as_vec()[0]; + let transaction = &match_result.trades.as_vec()[0]; assert_eq!(transaction.taker_order_id, taker_id); assert_eq!(transaction.maker_order_id, OrderId::from_u64(1)); assert_eq!(transaction.price, 10000); @@ -950,7 +950,7 @@ mod tests { assert_eq!(price_level.hidden_quantity(), 20); // 100 - 80 (replenish amount) = 20 assert_eq!(price_level.order_count(), 1); - let transaction = &match_result.transactions.as_vec()[0]; + let transaction = &match_result.trades.as_vec()[0]; assert_eq!(transaction.taker_order_id, taker_id); assert_eq!(transaction.maker_order_id, OrderId::from_u64(1)); assert_eq!(transaction.price, 10000); @@ -971,16 +971,16 @@ mod tests { assert_eq!(match_result.filled_order_ids[0], OrderId::from_u64(1)); // Verify the correct number and sizes of transactions - assert_eq!(match_result.transactions.len(), 2); // One for visible, one for hidden + assert_eq!(match_result.trades.len(), 2); // One for visible, one for hidden - let transaction1 = &match_result.transactions.as_vec()[0]; + let transaction1 = &match_result.trades.as_vec()[0]; assert_eq!(transaction1.taker_order_id, taker_id); assert_eq!(transaction1.maker_order_id, OrderId::from_u64(1)); assert_eq!(transaction1.price, 10000); assert_eq!(transaction1.quantity, 90); // First consumes all visible assert_eq!(transaction1.taker_side, Side::Buy); - let transaction2 = &match_result.transactions.as_vec()[1]; + let transaction2 = &match_result.trades.as_vec()[1]; assert_eq!(transaction2.taker_order_id, taker_id); assert_eq!(transaction2.maker_order_id, OrderId::from_u64(1)); assert_eq!(transaction2.price, 10000); @@ -1137,19 +1137,19 @@ mod tests { assert_eq!(price_level.visible_quantity(), 10); // 25 - (140 - 50 - 75) = 10 assert_eq!(price_level.order_count(), 1); - assert_eq!(match_result.transactions.len(), 3); + assert_eq!(match_result.trades.len(), 3); - let transaction1 = &match_result.transactions.as_vec()[0]; + let transaction1 = &match_result.trades.as_vec()[0]; assert_eq!(transaction1.taker_order_id, taker_id); assert_eq!(transaction1.maker_order_id, OrderId::from_u64(1)); assert_eq!(transaction1.quantity, 50); - let transaction2 = &match_result.transactions.as_vec()[1]; + let transaction2 = &match_result.trades.as_vec()[1]; assert_eq!(transaction2.taker_order_id, taker_id); assert_eq!(transaction2.maker_order_id, OrderId::from_u64(2)); assert_eq!(transaction2.quantity, 75); - let transaction3 = &match_result.transactions.as_vec()[2]; + let transaction3 = &match_result.trades.as_vec()[2]; assert_eq!(transaction3.taker_order_id, taker_id); assert_eq!(transaction3.maker_order_id, OrderId::from_u64(3)); assert_eq!(transaction3.quantity, 15);