From 759c8b9a587bfed45dbe3f7b2bceeee1f695d64b Mon Sep 17 00:00:00 2001 From: Jkorf Date: Mon, 9 Feb 2026 09:07:17 +0100 Subject: [PATCH] Fixed bug in UserDataTracker orders logic incorrectly setting order to canceled status --- .../UserData/ItemTrackers/FuturesOrderTracker.cs | 14 +++++++++++--- .../UserData/ItemTrackers/SpotOrderTracker.cs | 14 +++++++++++--- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/CryptoExchange.Net/Trackers/UserData/ItemTrackers/FuturesOrderTracker.cs b/CryptoExchange.Net/Trackers/UserData/ItemTrackers/FuturesOrderTracker.cs index b1923b1..fa451ed 100644 --- a/CryptoExchange.Net/Trackers/UserData/ItemTrackers/FuturesOrderTracker.cs +++ b/CryptoExchange.Net/Trackers/UserData/ItemTrackers/FuturesOrderTracker.cs @@ -129,6 +129,14 @@ namespace CryptoExchange.Net.Trackers.UserData.ItemTrackers // status changed from open to not open return true; + if (existingItem.Status != SharedOrderStatus.Open + && updateItem.Status != SharedOrderStatus.Open + && existingItem.Status != updateItem.Status) + { + _logger.LogWarning("Invalid order update detected for order {OrderId}; current status: {OldStatus}, new status: {NewStatus}", existingItem.OrderId, existingItem.Status, updateItem.Status); + return false; + } + if (existingItem.Status != SharedOrderStatus.Open && updateItem.Status == SharedOrderStatus.Open) // status changed from not open to open; stale return false; @@ -264,9 +272,9 @@ namespace CryptoExchange.Net.Trackers.UserData.ItemTrackers // Filter orders to only include where close time is after the start time var relevantOrders = closedOrdersResult.Data.Where(x => - x.UpdateTime != null && x.UpdateTime >= _startTime // Updated after the tracker start time - || x.CreateTime != null && x.CreateTime >= _startTime // Created after the tracker start time - || x.CreateTime == null && x.UpdateTime == null // Unknown time + (x.UpdateTime != null && x.UpdateTime >= _startTime) // Updated after the tracker start time + || (x.CreateTime != null && x.CreateTime >= _startTime) // Created after the tracker start time + || (x.CreateTime == null && x.UpdateTime == null) // Unknown time ).ToArray(); // Check for orders which are no longer returned in either open/closed and assume they're canceled without fill diff --git a/CryptoExchange.Net/Trackers/UserData/ItemTrackers/SpotOrderTracker.cs b/CryptoExchange.Net/Trackers/UserData/ItemTrackers/SpotOrderTracker.cs index da4aebd..7afe6a5 100644 --- a/CryptoExchange.Net/Trackers/UserData/ItemTrackers/SpotOrderTracker.cs +++ b/CryptoExchange.Net/Trackers/UserData/ItemTrackers/SpotOrderTracker.cs @@ -140,6 +140,14 @@ namespace CryptoExchange.Net.Trackers.UserData.ItemTrackers // status changed from open to not open return true; + if (existingItem.Status != SharedOrderStatus.Open + && updateItem.Status != SharedOrderStatus.Open + && existingItem.Status != updateItem.Status) + { + _logger.LogWarning("Invalid order update detected for order {OrderId}; current status: {OldStatus}, new status: {NewStatus}", existingItem.OrderId, existingItem.Status, updateItem.Status); + return false; + } + if (existingItem.Status != SharedOrderStatus.Open && updateItem.Status == SharedOrderStatus.Open) // status changed from not open to open; stale return false; @@ -278,9 +286,9 @@ namespace CryptoExchange.Net.Trackers.UserData.ItemTrackers // Filter orders to only include where close time is after the start time var relevantOrders = closedOrdersResult.Data.Where(x => - x.UpdateTime != null && x.UpdateTime >= _startTime // Updated after the tracker start time - || x.CreateTime != null && x.CreateTime >= _startTime // Created after the tracker start time - || x.CreateTime == null && x.UpdateTime == null // Unknown time + (x.UpdateTime != null && x.UpdateTime >= _startTime) // Updated after the tracker start time + || (x.CreateTime != null && x.CreateTime >= _startTime) // Created after the tracker start time + || (x.CreateTime == null && x.UpdateTime == null) // Unknown time ).ToArray(); // Check for orders which are no longer returned in either open/closed and assume they're canceled without fill