@@ -63,6 +63,9 @@ public TradingService(ILogger<TradingService> logger, InvestApiClient investApi,
6363 Logger . LogInformation ( $ "EarlySellOwnedLotsDelta: { settings . EarlySellOwnedLotsDelta } ") ;
6464 Logger . LogInformation ( $ "EarlySellOwnedLotsMultiplier: { settings . EarlySellOwnedLotsMultiplier } ") ;
6565 Logger . LogInformation ( $ "LoadOperationsFrom: { settings . LoadOperationsFrom } ") ;
66+ Logger . LogInformation ( $ "EnableCustomBuyPrice: { settings . EnableCustomBuyPrice } ") ;
67+ Logger . LogInformation ( $ "CustomBuyPriceSpreadPercentage: { settings . CustomBuyPriceSpreadPercentage } ") ;
68+ Logger . LogInformation ( $ "MaxCustomBuyPriceSteps: { settings . MaxCustomBuyPriceSteps } ") ;
6669
6770 var currentTime = DateTime . UtcNow . TimeOfDay ;
6871 Logger . LogInformation ( $ "Current time: { currentTime } ") ;
@@ -472,15 +475,16 @@ await marketDataStream.RequestStream.WriteAsync(new MarketDataRequest
472475 {
473476 // Process potential buy order
474477 var ( cashBalance , _) = await GetCashBalance ( ) ;
475- var lotPrice = bestBid * LotSize ;
478+ var customBuyPrice = GetCustomBuyPrice ( bestBid , bestAsk ) ;
479+ var lotPrice = customBuyPrice * LotSize ;
476480 if ( cashBalance > lotPrice )
477481 {
478482 Logger . LogInformation ( $ "buy activated") ;
479- Logger . LogInformation ( $ "bid: { bestBid } , ask: { bestAsk } .") ;
483+ Logger . LogInformation ( $ "bid: { bestBid } , ask: { bestAsk } , customBuyPrice: { customBuyPrice } .") ;
480484 var lots = ( long ) ( cashBalance / lotPrice ) ;
481- var marketLotsAtTargetPrice = orderBook . Bids . FirstOrDefault ( o => o . Price == bestBid ) ? . Quantity ?? 0 ;
485+ var marketLotsAtTargetPrice = orderBook . Bids . FirstOrDefault ( o => o . Price == customBuyPrice ) ? . Quantity ?? 0 ;
482486 Logger . LogInformation ( $ "marketLotsAtTargetPrice: { marketLotsAtTargetPrice } ") ;
483- var response = await PlaceBuyOrder ( lots , bestBid ) ;
487+ var response = await PlaceBuyOrder ( lots , customBuyPrice ) ;
484488 Logger . LogInformation ( $ "buy complete") ;
485489 areOrdersPlaced = true ;
486490 }
@@ -519,16 +523,17 @@ await marketDataStream.RequestStream.WriteAsync(new MarketDataRequest
519523 if ( IsTimeToBuy ( ) )
520524 {
521525 var initialOrderPrice = MoneyValueToDecimal ( activeBuyOrder . InitialSecurityPrice ) ;
526+ var customBuyPrice = GetCustomBuyPrice ( bestBid , bestAsk ) ;
522527 if ( LotsSets . TryGetValue ( initialOrderPrice , out var boughtLots ) || LotsSets . Count == 0 )
523528 {
524- if ( initialOrderPrice != bestBid && bestBidOrder . Quantity > Settings . MinimumMarketOrderSizeToChangeBuyPrice )
529+ if ( initialOrderPrice != customBuyPrice && bestBidOrder . Quantity > Settings . MinimumMarketOrderSizeToChangeBuyPrice )
525530 {
526531 if ( boughtLots > 0 )
527532 {
528533 Logger . LogInformation ( $ "buy trades are in progress") ;
529534 continue ;
530535 }
531- Logger . LogInformation ( $ "bid: { bestBid } , ask: { bestAsk } .") ;
536+ Logger . LogInformation ( $ "bid: { bestBid } , ask: { bestAsk } , customBuyPrice: { customBuyPrice } .") ;
532537 Logger . LogInformation ( $ "initial buy order price: { initialOrderPrice } ") ;
533538 Logger . LogInformation ( $ "buy order price change activated") ;
534539 // Cancel order
@@ -541,13 +546,13 @@ await marketDataStream.RequestStream.WriteAsync(new MarketDataRequest
541546 SetCashBalance ( CashBalanceFree + CashBalanceLocked , 0 ) ;
542547 // Place new order
543548 var ( cashBalance , _) = await GetCashBalance ( ) ;
544- var lotPrice = bestBid * LotSize ;
549+ var lotPrice = customBuyPrice * LotSize ;
545550 if ( cashBalance > lotPrice )
546551 {
547552 var lots = ( long ) ( cashBalance / lotPrice ) ;
548- var marketLotsAtTargetPrice = orderBook . Bids . FirstOrDefault ( o => o . Price == bestBid ) ? . Quantity ?? 0 ;
553+ var marketLotsAtTargetPrice = orderBook . Bids . FirstOrDefault ( o => o . Price == customBuyPrice ) ? . Quantity ?? 0 ;
549554 Logger . LogInformation ( $ "marketLotsAtTargetPrice: { marketLotsAtTargetPrice } ") ;
550- var response = await PlaceBuyOrder ( lots , bestBid ) ;
555+ var response = await PlaceBuyOrder ( lots , customBuyPrice ) ;
551556 }
552557 SyncActiveOrders ( ) ;
553558 Logger . LogInformation ( $ "buy order price change is complete") ;
@@ -691,6 +696,28 @@ private decimal GetTargetSellPrice(decimal minimumSellPrice, decimal bestAsk)
691696 return targetSellPrice ;
692697 }
693698
699+ private decimal GetCustomBuyPrice ( decimal bestBid , decimal bestAsk )
700+ {
701+ if ( ! Settings . EnableCustomBuyPrice )
702+ {
703+ return bestBid ;
704+ }
705+
706+ var spread = bestAsk - bestBid ;
707+ var customBuyPrice = bestBid + ( spread * Settings . CustomBuyPriceSpreadPercentage / 100m ) ;
708+
709+ var maxPriceIncrease = Settings . MaxCustomBuyPriceSteps * PriceStep ;
710+ var maxAllowedPrice = bestBid + maxPriceIncrease ;
711+
712+ customBuyPrice = Math . Min ( customBuyPrice , maxAllowedPrice ) ;
713+ customBuyPrice = Math . Min ( customBuyPrice , bestAsk ) ;
714+
715+ customBuyPrice = Math . Max ( customBuyPrice , bestBid ) ;
716+
717+ Logger . LogInformation ( $ "CustomBuyPrice calculation: bestBid={ bestBid } , bestAsk={ bestAsk } , spread={ spread } , customBuyPrice={ customBuyPrice } ") ;
718+ return customBuyPrice ;
719+ }
720+
694721 protected override async Task ExecuteAsync ( CancellationToken cancellationToken )
695722 {
696723 var tasks = new [ ]
0 commit comments