1
0
mirror of https://github.com/JKorf/CryptoExchange.Net synced 2026-02-16 14:13:46 +00:00

Added AddTrackedSymbolsAsync and RemoveTrackedSymbolAsync methods to UserDataTracker, updated minimal fromTime filter in UserDataTracker to 5 seconds

This commit is contained in:
Jkorf 2026-02-16 09:11:01 +01:00
parent 1471a4733f
commit 7dcf5cd6ea
10 changed files with 154 additions and 12 deletions

View File

@ -65,5 +65,18 @@ namespace CryptoExchange.Net.Trackers.UserData.Interfaces
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
Task StopAsync(); Task StopAsync();
/// <summary>
/// Add symbols to the list of symbols for which data is being tracked
/// </summary>
/// <param name="symbols">Symbols to add</param>
void AddTrackedSymbolsAsync(IEnumerable<SharedSymbol> symbols);
/// <summary>
/// Remove a symbol from the list of symbols for which data is being tracked.
/// Note that the symbol will be added again if new data for that symbol is received, unless the OnlyTrackProvidedSymbols option has been set to true.
/// </summary>
/// <param name="symbol">Symbol to remove</param>
void RemoveTrackedSymbolAsync(SharedSymbol symbol);
} }
} }

View File

@ -61,5 +61,18 @@ namespace CryptoExchange.Net.Trackers.UserData.Interfaces
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
Task StopAsync(); Task StopAsync();
/// <summary>
/// Add symbols to the list of symbols for which data is being tracked
/// </summary>
/// <param name="symbols">Symbols to add</param>
void AddTrackedSymbolsAsync(IEnumerable<SharedSymbol> symbols);
/// <summary>
/// Remove a symbol from the list of symbols for which data is being tracked.
/// Note that the symbol will be added again if new data for that symbol is received, unless the OnlyTrackProvidedSymbols option has been set to true.
/// </summary>
/// <param name="symbol">Symbol to remove</param>
void RemoveTrackedSymbolAsync(SharedSymbol symbol);
} }
} }

View File

@ -47,6 +47,20 @@ namespace CryptoExchange.Net.Trackers.UserData.ItemTrackers
_requiresSymbolParameterOpenOrders = restClient.GetOpenFuturesOrdersOptions.RequiredOptionalParameters.Any(x => x.Name == "Symbol"); _requiresSymbolParameterOpenOrders = restClient.GetOpenFuturesOrdersOptions.RequiredOptionalParameters.Any(x => x.Name == "Symbol");
} }
internal void ClearDataForSymbol(SharedSymbol symbol)
{
foreach (var order in _store)
{
if (order.Value.SharedSymbol!.TradingMode == symbol.TradingMode
&& order.Value.SharedSymbol.BaseAsset == symbol.BaseAsset
&& order.Value.SharedSymbol.QuoteAsset == symbol.QuoteAsset
&& order.Value.SharedSymbol.DeliverTime == symbol.DeliverTime)
{
_store.TryRemove(order.Key, out _);
}
}
}
/// <inheritdoc /> /// <inheritdoc />
protected override bool Update(SharedFuturesOrder existingItem, SharedFuturesOrder updateItem) protected override bool Update(SharedFuturesOrder existingItem, SharedFuturesOrder updateItem)
{ {
@ -376,8 +390,8 @@ namespace CryptoExchange.Net.Trackers.UserData.ItemTrackers
if (DateTime.UtcNow - fromTime < TimeSpan.FromSeconds(1)) if (DateTime.UtcNow - fromTime < TimeSpan.FromSeconds(1))
{ {
// Set it to at least a seconds in the past to prevent issues // Set it to at least 5 seconds in the past to prevent issues when local time isn't in sync
fromTime = DateTime.UtcNow.AddSeconds(-1); fromTime = DateTime.UtcNow.AddSeconds(-5);
} }
_logger.LogTrace("{DataType}.{Symbol} UserDataTracker poll startTime filter based on {Source}: {Time:yyyy-MM-dd HH:mm:ss.fff}", _logger.LogTrace("{DataType}.{Symbol} UserDataTracker poll startTime filter based on {Source}: {Time:yyyy-MM-dd HH:mm:ss.fff}",

View File

@ -43,6 +43,20 @@ namespace CryptoExchange.Net.Trackers.UserData.ItemTrackers
_exchangeParameters = exchangeParameters; _exchangeParameters = exchangeParameters;
} }
internal void ClearDataForSymbol(SharedSymbol symbol)
{
foreach (var order in _store)
{
if (order.Value.SharedSymbol!.TradingMode == symbol.TradingMode
&& order.Value.SharedSymbol.BaseAsset == symbol.BaseAsset
&& order.Value.SharedSymbol.QuoteAsset == symbol.QuoteAsset
&& order.Value.SharedSymbol.DeliverTime == symbol.DeliverTime)
{
_store.TryRemove(order.Key, out _);
}
}
}
/// <inheritdoc /> /// <inheritdoc />
protected override string GetKey(SharedUserTrade item) => item.Id; protected override string GetKey(SharedUserTrade item) => item.Id;
/// <inheritdoc /> /// <inheritdoc />
@ -120,8 +134,8 @@ namespace CryptoExchange.Net.Trackers.UserData.ItemTrackers
var now = DateTime.UtcNow; var now = DateTime.UtcNow;
if (now - fromTime < TimeSpan.FromSeconds(1)) if (now - fromTime < TimeSpan.FromSeconds(1))
{ {
// Set it to at least a seconds in the past to prevent issues // Set it to at least 5 seconds in the past to prevent issues when local time isn't in sync
fromTime = now.AddSeconds(-1); fromTime = DateTime.UtcNow.AddSeconds(-5);
} }
_logger.LogTrace("{DataType} UserDataTracker poll startTime filter based on {Source}: {Time:yyyy-MM-dd HH:mm:ss.fff}", DataType, source, fromTime); _logger.LogTrace("{DataType} UserDataTracker poll startTime filter based on {Source}: {Time:yyyy-MM-dd HH:mm:ss.fff}", DataType, source, fromTime);

View File

@ -119,7 +119,7 @@ namespace CryptoExchange.Net.Trackers.UserData.ItemTrackers
{ {
toRemove ??= new List<SharedPosition>(); toRemove ??= new List<SharedPosition>();
toRemove.Add(item); toRemove.Add(item);
_logger.LogWarning("Ignoring {DataType} update for {Key}, no SharedSymbol set", DataType, GetKey(item)); _logger.LogTrace("Ignoring {DataType} update for {Key}, no SharedSymbol set", DataType, item.Symbol);
} }
else if (!_symbolTracker.ShouldProcess(symbolModel.SharedSymbol)) else if (!_symbolTracker.ShouldProcess(symbolModel.SharedSymbol))
{ {

View File

@ -47,6 +47,19 @@ namespace CryptoExchange.Net.Trackers.UserData.ItemTrackers
_requiresSymbolParameterOpenOrders = restClient.GetOpenSpotOrdersOptions.RequiredOptionalParameters.Any(x => x.Name == "Symbol"); _requiresSymbolParameterOpenOrders = restClient.GetOpenSpotOrdersOptions.RequiredOptionalParameters.Any(x => x.Name == "Symbol");
} }
internal void ClearDataForSymbol(SharedSymbol symbol)
{
foreach(var order in _store)
{
if (order.Value.SharedSymbol!.TradingMode == symbol.TradingMode
&& order.Value.SharedSymbol.BaseAsset == symbol.BaseAsset
&& order.Value.SharedSymbol.QuoteAsset == symbol.QuoteAsset)
{
_store.TryRemove(order.Key, out _);
}
}
}
/// <inheritdoc /> /// <inheritdoc />
protected override bool Update(SharedSpotOrder existingItem, SharedSpotOrder updateItem) protected override bool Update(SharedSpotOrder existingItem, SharedSpotOrder updateItem)
{ {
@ -388,8 +401,8 @@ namespace CryptoExchange.Net.Trackers.UserData.ItemTrackers
if (DateTime.UtcNow - fromTime < TimeSpan.FromSeconds(1)) if (DateTime.UtcNow - fromTime < TimeSpan.FromSeconds(1))
{ {
// Set it to at least a seconds in the past to prevent issues // Set it to at least 5 seconds in the past to prevent issues when local time isn't in sync
fromTime = DateTime.UtcNow.AddSeconds(-1); fromTime = DateTime.UtcNow.AddSeconds(-5);
} }
_logger.LogTrace("{DataType}.{Symbol} UserDataTracker poll startTime filter based on {Source}: {Time:yyyy-MM-dd HH:mm:ss.fff}", _logger.LogTrace("{DataType}.{Symbol} UserDataTracker poll startTime filter based on {Source}: {Time:yyyy-MM-dd HH:mm:ss.fff}",

View File

@ -43,6 +43,19 @@ namespace CryptoExchange.Net.Trackers.UserData.ItemTrackers
_exchangeParameters = exchangeParameters; _exchangeParameters = exchangeParameters;
} }
internal void ClearDataForSymbol(SharedSymbol symbol)
{
foreach (var trade in _store)
{
if (trade.Value.SharedSymbol!.TradingMode == symbol.TradingMode
&& trade.Value.SharedSymbol.BaseAsset == symbol.BaseAsset
&& trade.Value.SharedSymbol.QuoteAsset == symbol.QuoteAsset)
{
_store.TryRemove(trade.Key, out _);
}
}
}
/// <inheritdoc /> /// <inheritdoc />
protected override string GetKey(SharedUserTrade item) => item.Id; protected override string GetKey(SharedUserTrade item) => item.Id;
/// <inheritdoc /> /// <inheritdoc />
@ -117,8 +130,8 @@ namespace CryptoExchange.Net.Trackers.UserData.ItemTrackers
if (DateTime.UtcNow - fromTime < TimeSpan.FromSeconds(1)) if (DateTime.UtcNow - fromTime < TimeSpan.FromSeconds(1))
{ {
// Set it to at least a seconds in the past to prevent issues // Set it to at least 5 seconds in the past to prevent issues when local time isn't in sync
fromTime = DateTime.UtcNow.AddSeconds(-1); fromTime = DateTime.UtcNow.AddSeconds(-5);
} }
_logger.LogTrace("{DataType} UserDataTracker poll startTime filter based on {Source}: {Time:yyyy-MM-dd HH:mm:ss.fff}", DataType, source, fromTime); _logger.LogTrace("{DataType} UserDataTracker poll startTime filter based on {Source}: {Time:yyyy-MM-dd HH:mm:ss.fff}", DataType, source, fromTime);

View File

@ -38,10 +38,9 @@ namespace CryptoExchange.Net.Trackers.UserData.Objects
/// <summary> /// <summary>
/// Update the tracked symbol list with potential new symbols /// Update the tracked symbol list with potential new symbols
/// </summary> /// </summary>
/// <param name="symbols"></param> public void UpdateTrackedSymbols(IEnumerable<SharedSymbol> symbols, bool addByUser = false)
public void UpdateTrackedSymbols(IEnumerable<SharedSymbol> symbols)
{ {
if (_onlyTrackProvidedSymbols) if (!addByUser && _onlyTrackProvidedSymbols)
return; return;
lock (_symbolLock) lock (_symbolLock)
@ -56,5 +55,18 @@ namespace CryptoExchange.Net.Trackers.UserData.Objects
} }
} }
} }
/// <summary>
/// Remove a symbol from the list
/// </summary>
public void RemoveTrackedSymbol(SharedSymbol symbol)
{
lock (_symbolLock)
{
var symbolToRemove = _trackedSymbols.SingleOrDefault(x => x.TradingMode == symbol.TradingMode && x.BaseAsset == symbol.BaseAsset && x.QuoteAsset == symbol.QuoteAsset);
if (symbolToRemove != null)
_trackedSymbols.Remove(symbolToRemove);
}
}
} }
} }

View File

@ -154,5 +154,30 @@ namespace CryptoExchange.Net.Trackers.UserData
interval = result ? TimeSpan.FromMinutes(30) : TimeSpan.FromMinutes(5); interval = result ? TimeSpan.FromMinutes(30) : TimeSpan.FromMinutes(5);
} }
} }
/// <summary>
/// Add symbols to the list of symbols for which data is being tracked
/// </summary>
/// <param name="symbols">Symbols to add</param>
public void AddTrackedSymbolsAsync(IEnumerable<SharedSymbol> symbols)
{
if (symbols.Any(x => x.TradingMode == TradingMode.Spot))
throw new ArgumentException("Spot symbol not allowed in futures tracker", nameof(symbols));
SymbolTracker.UpdateTrackedSymbols(symbols, true);
}
/// <summary>
/// Remove a symbol from the list of symbols for which data is being tracked.
/// Note that the symbol will be added again if new data for that symbol is received, unless the OnlyTrackProvidedSymbols option has been set to true.
/// </summary>
/// <param name="symbol">Symbol to remove</param>
public void RemoveTrackedSymbolAsync(SharedSymbol symbol)
{
SymbolTracker.RemoveTrackedSymbol(symbol);
((FuturesOrderTracker)Orders).ClearDataForSymbol(symbol);
((FuturesUserTradeTracker)Trades).ClearDataForSymbol(symbol);
}
} }
} }

View File

@ -127,5 +127,30 @@ namespace CryptoExchange.Net.Trackers.UserData
interval = result ? TimeSpan.FromMinutes(30) : TimeSpan.FromMinutes(5); interval = result ? TimeSpan.FromMinutes(30) : TimeSpan.FromMinutes(5);
} }
} }
/// <summary>
/// Add symbols to the list of symbols for which data is being tracked
/// </summary>
/// <param name="symbols">Symbols to add</param>
public void AddTrackedSymbolsAsync(IEnumerable<SharedSymbol> symbols)
{
if (symbols.Any(x => x.TradingMode != TradingMode.Spot))
throw new ArgumentException("Futures symbol not allowed in spot tracker", nameof(symbols));
SymbolTracker.UpdateTrackedSymbols(symbols, true);
}
/// <summary>
/// Remove a symbol from the list of symbols for which data is being tracked. Also removes stored data for that symbol.
/// Note that the symbol will be added again if new data for that symbol is received, unless the OnlyTrackProvidedSymbols option has been set to true.
/// </summary>
/// <param name="symbol">Symbol to remove</param>
public void RemoveTrackedSymbolAsync(SharedSymbol symbol)
{
SymbolTracker.RemoveTrackedSymbol(symbol);
((SpotOrderTracker)Orders).ClearDataForSymbol(symbol);
((SpotUserTradeTracker)Trades).ClearDataForSymbol(symbol);
}
} }
} }