Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 61 additions & 1 deletion csharp/TraderBot/TradingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,29 @@ protected void UpdateCashBalance(OrderTrades orderTrades)
if(orderTrades.Direction == OrderDirection.Buy)
{
SetCashBalance(CashBalanceFree, CashBalanceLocked - cashBalanceDelta);
Logger.LogInformation($"Buy execution: {trade.Quantity} lots at {trade.Price}, total cost: {cashBalanceDelta}");
}
else if (orderTrades.Direction == OrderDirection.Sell)
{
SetCashBalance(CashBalanceFree + cashBalanceDelta, CashBalanceLocked);

// Track realized profit/loss for sell trades
if (ActiveSellOrderSourcePrice.TryGetValue(orderTrades.OrderId, out var sourcePrice))
{
var realizedProfitLoss = (trade.Price - sourcePrice) * trade.Quantity;
if (realizedProfitLoss < 0)
{
Logger.LogWarning($"Loss realized: SELL EXECUTED at LOSS. Source price: {sourcePrice}, execution price: {trade.Price}, lots: {trade.Quantity}, realized loss: {Math.Abs(realizedProfitLoss)}, total revenue: {cashBalanceDelta}");
}
else
{
Logger.LogInformation($"Profit realized: sell executed at profit. Source price: {sourcePrice}, execution price: {trade.Price}, lots: {trade.Quantity}, realized profit: {realizedProfitLoss}, total revenue: {cashBalanceDelta}");
}
}
else
{
Logger.LogInformation($"Sell execution: {trade.Quantity} lots at {trade.Price}, total revenue: {cashBalanceDelta} (source price not tracked)");
}
}
}
}
Expand Down Expand Up @@ -461,6 +480,17 @@ await marketDataStream.RequestStream.WriteAsync(new MarketDataRequest
var targetSellPrice = GetTargetSellPrice(minimumSellPrice, bestAsk);
var marketLotsAtTargetPrice = orderBook.Asks.FirstOrDefault(o => o.Price == targetSellPrice)?.Quantity ?? 0;
Logger.LogInformation($"marketLotsAtTargetPrice: {marketLotsAtTargetPrice}");

var actualProfitLoss = targetSellPrice - maxPrice;
if (actualProfitLoss < 0)
{
Logger.LogWarning($"Loss detection: placing sell order at LOSS. Source price: {maxPrice}, target sell price: {targetSellPrice}, actual loss: {Math.Abs(actualProfitLoss)}, lots: {totalAmount}");
}
else
{
Logger.LogInformation($"Profit tracking: placing sell order at profit. Source price: {maxPrice}, target sell price: {targetSellPrice}, profit: {actualProfitLoss}, lots: {totalAmount}");
}

var response = await PlaceSellOrder(totalAmount, targetSellPrice);
ActiveSellOrderSourcePrice[response.OrderId] = maxPrice;
Logger.LogInformation($"sell complete");
Expand Down Expand Up @@ -611,6 +641,15 @@ await marketDataStream.RequestStream.WriteAsync(new MarketDataRequest
continue;
}
// Place new order at top bid price
var earlySellProfitLoss = topBid - sourcePrice;
if (earlySellProfitLoss < 0)
{
Logger.LogWarning($"Loss detection: EARLY SELL at LOSS. Source price: {sourcePrice}, top bid price: {topBid}, actual loss: {Math.Abs(earlySellProfitLoss)}, lots: {activeSellOrder.LotsRequested}");
}
else
{
Logger.LogInformation($"Early sell profit tracking: source price: {sourcePrice}, top bid price: {topBid}, profit: {earlySellProfitLoss}, lots: {activeSellOrder.LotsRequested}");
}
var response = await PlaceSellOrder(activeSellOrder.LotsRequested, topBid);
SyncActiveOrders();
Logger.LogInformation($"early sell is complete");
Expand All @@ -636,6 +675,17 @@ await marketDataStream.RequestStream.WriteAsync(new MarketDataRequest
var targetSellPrice = GetTargetSellPrice(minimumSellPrice, bestAsk);
var marketLotsAtTargetPrice = orderBook.Asks.FirstOrDefault(o => o.Price == targetSellPrice)?.Quantity ?? 0;
Logger.LogInformation($"marketLotsAtTargetPrice: {marketLotsAtTargetPrice}");

var priceChangeProfitLoss = targetSellPrice - sourcePrice;
if (priceChangeProfitLoss < 0)
{
Logger.LogWarning($"Loss detection: PRICE CHANGE to LOSS position. Source price: {sourcePrice}, new target price: {targetSellPrice}, actual loss: {Math.Abs(priceChangeProfitLoss)}, lots: {activeSellOrder.LotsRequested}");
}
else
{
Logger.LogInformation($"Price change profit tracking: source price: {sourcePrice}, new target price: {targetSellPrice}, profit: {priceChangeProfitLoss}, lots: {activeSellOrder.LotsRequested}");
}

var response = await PlaceSellOrder(activeSellOrder.LotsRequested, targetSellPrice);
ActiveSellOrderSourcePrice[response.OrderId] = sourcePrice;
SyncActiveOrders();
Expand Down Expand Up @@ -680,7 +730,17 @@ private void SetCashBalance(decimal free, decimal locked)
private decimal GetMinimumSellPrice(decimal sourcePrice)
{
var minimumSellPrice = sourcePrice + Settings.MinimumProfitSteps * PriceStep;
// Logger.LogInformation($"minimumSellPrice: {minimumSellPrice}");
var profitLoss = minimumSellPrice - sourcePrice;

if (Settings.MinimumProfitSteps < 0)
{
Logger.LogWarning($"Loss detection: selling at loss allowed. Source price: {sourcePrice}, minimum sell price: {minimumSellPrice}, potential loss: {Math.Abs(profitLoss)} ({Settings.MinimumProfitSteps} price steps)");
}
else
{
Logger.LogInformation($"Profit calculation: source price: {sourcePrice}, minimum sell price: {minimumSellPrice}, minimum profit: {profitLoss} ({Settings.MinimumProfitSteps} price steps)");
}

return minimumSellPrice;
}

Expand Down
Loading