From b64009361a13abef98738bacfb1ccd1f3dd73589 Mon Sep 17 00:00:00 2001 From: konard Date: Thu, 11 Sep 2025 12:03:54 +0300 Subject: [PATCH 1/3] Initial commit with task details for issue #224 Adding CLAUDE.md with task information for AI processing. This file will be removed when the task is complete. Issue: https://github.com/linksplatform/Bot/issues/224 --- CLAUDE.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..f821196b --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,5 @@ +Issue to solve: https://github.com/linksplatform/Bot/issues/224 +Your prepared branch: issue-224-c1707416 +Your prepared working directory: /tmp/gh-issue-solver-1757581429232 + +Proceed. \ No newline at end of file From 34366c79c9bf45fa18b252c056e69f626c9bca5e Mon Sep 17 00:00:00 2001 From: konard Date: Thu, 11 Sep 2025 12:04:10 +0300 Subject: [PATCH 2/3] Remove CLAUDE.md - PR created successfully --- CLAUDE.md | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index f821196b..00000000 --- a/CLAUDE.md +++ /dev/null @@ -1,5 +0,0 @@ -Issue to solve: https://github.com/linksplatform/Bot/issues/224 -Your prepared branch: issue-224-c1707416 -Your prepared working directory: /tmp/gh-issue-solver-1757581429232 - -Proceed. \ No newline at end of file From e92e804d28b692427ed3030da03385ecb93040bd Mon Sep 17 00:00:00 2001 From: konard Date: Thu, 11 Sep 2025 12:12:21 +0300 Subject: [PATCH 3/3] Implement buy prevention logic for trader bot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add MaxSpreadPercentToBuy and MinimumCombinedLiquidityToBuy settings - Add IsMarketConditionsSuitableForBuying method to check market conditions - Prevent buying when bid-ask spread is too wide (configurable threshold) - Prevent buying when market liquidity is too low (configurable threshold) - Apply conditions to both initial buy orders and buy order price changes - Update configuration files with sensible default values (1.0% max spread, 1M minimum liquidity) Fixes #224 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- csharp/TraderBot/TradingService.cs | 32 +++++++++++++++++++++++--- csharp/TraderBot/TradingSettings.cs | 2 ++ csharp/TraderBot/appsettings.TMON.json | 4 +++- csharp/TraderBot/appsettings.TRUR.json | 4 +++- 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/csharp/TraderBot/TradingService.cs b/csharp/TraderBot/TradingService.cs index 0302809b..7042de61 100644 --- a/csharp/TraderBot/TradingService.cs +++ b/csharp/TraderBot/TradingService.cs @@ -63,6 +63,8 @@ public TradingService(ILogger logger, InvestApiClient investApi, Logger.LogInformation($"EarlySellOwnedLotsDelta: {settings.EarlySellOwnedLotsDelta}"); Logger.LogInformation($"EarlySellOwnedLotsMultiplier: {settings.EarlySellOwnedLotsMultiplier}"); Logger.LogInformation($"LoadOperationsFrom: {settings.LoadOperationsFrom}"); + Logger.LogInformation($"MaxSpreadPercentToBuy: {settings.MaxSpreadPercentToBuy}"); + Logger.LogInformation($"MinimumCombinedLiquidityToBuy: {settings.MinimumCombinedLiquidityToBuy}"); var currentTime = DateTime.UtcNow.TimeOfDay; Logger.LogInformation($"Current time: {currentTime}"); @@ -468,7 +470,7 @@ await marketDataStream.RequestStream.WriteAsync(new MarketDataRequest } if (!areOrdersPlaced) { - if (IsTimeToBuy()) + if (IsTimeToBuy() && IsMarketConditionsSuitableForBuying(bestBid, bestAsk, orderBook)) { // Process potential buy order var (cashBalance, _) = await GetCashBalance(); @@ -516,7 +518,7 @@ await marketDataStream.RequestStream.WriteAsync(new MarketDataRequest else if (ActiveBuyOrders.Count == 1) { var activeBuyOrder = ActiveBuyOrders.Single().Value; - if (IsTimeToBuy()) + if (IsTimeToBuy() && IsMarketConditionsSuitableForBuying(bestBid, bestAsk, orderBook)) { var initialOrderPrice = MoneyValueToDecimal(activeBuyOrder.InitialSecurityPrice); if (LotsSets.TryGetValue(initialOrderPrice, out var boughtLots) || LotsSets.Count == 0) @@ -569,7 +571,7 @@ await marketDataStream.RequestStream.WriteAsync(new MarketDataRequest } else { - Logger.LogInformation($"It is not time to buy, cancelling buy order"); + Logger.LogInformation($"Conditions not suitable for buying, cancelling buy order"); // Cancel order if (!await TryCancelOrder(activeBuyOrder.OrderId)) { @@ -652,6 +654,30 @@ private bool IsTimeToBuy() { var currentTime = DateTime.UtcNow.TimeOfDay; return currentTime > MinimumTimeToBuy && currentTime < MaximumTimeToBuy; + } + + private bool IsMarketConditionsSuitableForBuying(decimal bestBid, decimal bestAsk, OrderBook orderBook) + { + // Check if spread is not too wide + var spread = bestAsk - bestBid; + var spreadPercent = (spread / bestBid) * 100; + if (spreadPercent > Settings.MaxSpreadPercentToBuy) + { + Logger.LogInformation($"Spread too wide for buying: {spreadPercent:F2}% (max allowed: {Settings.MaxSpreadPercentToBuy}%)"); + return false; + } + + // Check combined liquidity at best bid and ask + var bestBidOrder = orderBook.Bids.FirstOrDefault(); + var bestAskOrder = orderBook.Asks.FirstOrDefault(); + var combinedLiquidity = (bestBidOrder?.Quantity ?? 0) + (bestAskOrder?.Quantity ?? 0); + if (combinedLiquidity < Settings.MinimumCombinedLiquidityToBuy) + { + Logger.LogInformation($"Insufficient liquidity for buying: {combinedLiquidity} (minimum required: {Settings.MinimumCombinedLiquidityToBuy})"); + return false; + } + + return true; } private async Task<(decimal, decimal)> GetCashBalance(bool forceRemote = false) diff --git a/csharp/TraderBot/TradingSettings.cs b/csharp/TraderBot/TradingSettings.cs index 884a25df..cc520e4d 100644 --- a/csharp/TraderBot/TradingSettings.cs +++ b/csharp/TraderBot/TradingSettings.cs @@ -17,4 +17,6 @@ public class TradingSettings public long EarlySellOwnedLotsDelta { get; set; } public decimal EarlySellOwnedLotsMultiplier { get; set; } public DateTime LoadOperationsFrom { get; set; } + public decimal MaxSpreadPercentToBuy { get; set; } + public long MinimumCombinedLiquidityToBuy { get; set; } } \ No newline at end of file diff --git a/csharp/TraderBot/appsettings.TMON.json b/csharp/TraderBot/appsettings.TMON.json index c7b66d7a..06bddedc 100644 --- a/csharp/TraderBot/appsettings.TMON.json +++ b/csharp/TraderBot/appsettings.TMON.json @@ -24,6 +24,8 @@ "MaximumTimeToBuy": "23:59:59", "EarlySellOwnedLotsDelta": 300000, "EarlySellOwnedLotsMultiplier": 0, - "LoadOperationsFrom": "2025-03-01T00:00:01.3389860Z" + "LoadOperationsFrom": "2025-03-01T00:00:01.3389860Z", + "MaxSpreadPercentToBuy": 1.0, + "MinimumCombinedLiquidityToBuy": 1000000 } } diff --git a/csharp/TraderBot/appsettings.TRUR.json b/csharp/TraderBot/appsettings.TRUR.json index 1dc848e6..9fdc4760 100644 --- a/csharp/TraderBot/appsettings.TRUR.json +++ b/csharp/TraderBot/appsettings.TRUR.json @@ -24,6 +24,8 @@ "MaximumTimeToBuy": "14:45:00", "EarlySellOwnedLotsDelta": 300000, "EarlySellOwnedLotsMultiplier": 0, - "LoadOperationsFrom": "2025-03-01T00:00:01.3389860Z" + "LoadOperationsFrom": "2025-03-01T00:00:01.3389860Z", + "MaxSpreadPercentToBuy": 1.0, + "MinimumCombinedLiquidityToBuy": 1000000 } }