/// <summary> /// Filter orders that are already calculated /// </summary> /// <returns></returns> private List <Order> GetOrdersForCalculation() { //read orders synchronously var openOrders = _orderReader.GetActive(); //prepare the list of orders var lastInvocationTime = CalcLastInvocationTime(); var calculatedIds = _overnightSwapCache.GetAll().Where(x => x.IsSuccess && x.Time >= lastInvocationTime) .Select(x => x.OpenOrderId).ToHashSet(); //select only non-calculated orders, changed before current invocation time var filteredOrders = openOrders.Where(x => !calculatedIds.Contains(x.Id) && x.OpenDate <= lastInvocationTime).ToList(); //detect orders for which last calculation failed and it was closed var failedClosedOrders = _overnightSwapHistoryRepository.GetAsync(lastInvocationTime, _currentStartTimestamp) .GetAwaiter().GetResult() .Where(x => !x.IsSuccess).Select(x => x.OpenOrderId) .Except(openOrders.Select(y => y.Id)).ToList(); if (failedClosedOrders.Any()) { _log.WriteErrorAsync(nameof(OvernightSwapService), nameof(GetOrdersForCalculation), new Exception( $"Overnight swap calculation failed for some orders and they were closed before recalculation: {string.Join(", ", failedClosedOrders)}."), DateTime.UtcNow).GetAwaiter().GetResult(); } return(filteredOrders); }
public async Task OvernightSwapCalculation_Success() { _bestPriceConsumer.SendEvent(this, new BestPriceChangeEventArgs(new InstrumentBidAskPair { Instrument = "BTCUSD", Bid = 9000M, Ask = 9010M })); await _accountAssetsRepository.AddOrReplaceAsync(new AccountAssetPair { TradingConditionId = MarginTradingTestsUtils.TradingConditionId, BaseAssetId = "USD", Instrument = "BTCUSD", LeverageInit = 100, LeverageMaintenance = 150, SwapLong = 100, SwapShort = 100, OvernightSwapLong = 1, OvernightSwapShort = 1 }); await _accountAssetsManager.UpdateAccountAssetsCache(); var accountId = (await _fakeMarginTradingAccountsRepository.GetAllAsync("1")) .First(x => x.ClientId == "1" && x.BaseAssetId == "USD").Id; _ordersCache.ActiveOrders.Add(new Order { Id = "1", AccountId = accountId, Instrument = "BTCUSD", ClientId = "1", TradingConditionId = "1", AccountAssetId = "USD", Volume = 1, OpenDate = new DateTime(2017, 01, 01, 20, 50, 0), CloseDate = new DateTime(2017, 01, 02, 20, 50, 0), MatchedOrders = new MatchedOrderCollection(new List <MatchedOrder> { new MatchedOrder() { Volume = 1 } }), LegalEntity = "LYKKETEST", }); var accountBalance = (await _fakeMarginTradingAccountsRepository.GetAsync(accountId)).Balance; _overnightSwapService.CalculateAndChargeSwaps(); var calc = _overnightSwapCache.GetAll().First(); Assert.AreEqual(24.68493151M, calc.Value); Assert.True(calc.IsSuccess); Assert.AreEqual(accountBalance - 24.68493151M, (await _fakeMarginTradingAccountsRepository.GetAsync(accountId)).Balance); }
/// <summary> /// Filter orders that are already calculated /// </summary> /// <returns></returns> private IEnumerable <Order> GetOrdersForCalculation() { //read orders syncronously var openOrders = _orderReader.GetActive(); //prepare the list of orders var lastInvocationTime = CalcLastInvocationTime; var lastCalculation = _overnightSwapCache.GetAll().Where(x => x.Time > lastInvocationTime).ToList(); var calculatedIds = lastCalculation.Where(x => x.IsSuccess).SelectMany(x => x.OpenOrderIds).ToHashSet(); var filteredOrders = openOrders.Where(x => !calculatedIds.Contains(x.Id)); //detect orders for which last calculation failed and it was closed var failedClosedOrders = lastCalculation.Where(x => !x.IsSuccess).SelectMany(x => x.OpenOrderIds) .Except(openOrders.Select(y => y.Id)).ToList(); if (failedClosedOrders.Any()) { _log.WriteErrorAsync(nameof(OvernightSwapService), nameof(GetOrdersForCalculation), new Exception( $"Overnight swap calculation failed for some orders and they were closed before recalculation: {string.Join(", ", failedClosedOrders)}."), DateTime.UtcNow).GetAwaiter().GetResult(); } return(filteredOrders); }
public async Task OvernightSwapCalculation_Success() { var dsMock = Mock.Get(Container.Resolve <IDateService>()); dsMock.Setup(d => d.Now()).Returns(new DateTime(2017, 1, 2)); await _accountAssetsRepository.AddOrReplaceAsync(new AccountAssetPair { TradingConditionId = MarginTradingTestsUtils.TradingConditionId, BaseAssetId = "USD", Instrument = "BTCUSD", LeverageInit = 100, LeverageMaintenance = 150, SwapLong = 100, SwapShort = 100, OvernightSwapLong = 1, OvernightSwapShort = 1 }); await _accountAssetsManager.UpdateAccountAssetsCache(); var accountId = (await _fakeMarginTradingAccountsRepository.GetAllAsync("1")) .First(x => x.ClientId == "1" && x.BaseAssetId == "USD").Id; _ordersCache.ActiveOrders.Add(new Order { Id = "1", AccountId = accountId, Instrument = "BTCUSD", ClientId = "1", TradingConditionId = "1", AccountAssetId = "USD", Volume = 1, OpenDate = new DateTime(2017, 01, 01, 20, 50, 0), MatchedOrders = new MatchedOrderCollection(new List <MatchedOrder> { new MatchedOrder() { Volume = 1 } }), LegalEntity = "LYKKETEST", }); _ordersCache.ActiveOrders.Add(new Order { Id = "2", AccountId = accountId, Instrument = "BTCUSD", ClientId = "1", TradingConditionId = "1", AccountAssetId = "USD", Volume = 1, OpenDate = new DateTime(2017, 01, 02, 20, 50, 0), MatchedOrders = new MatchedOrderCollection(new List <MatchedOrder> { new MatchedOrder() { Volume = 1 } }), LegalEntity = "LYKKETEST", }); const decimal swapValue = 0.00273973M; var initialAccountBalance = (await _fakeMarginTradingAccountsRepository.GetAsync(accountId)).Balance; _overnightSwapService.CalculateAndChargeSwaps(); var calculations = _overnightSwapCache.GetAll(); Assert.AreEqual(1, calculations.Count); //only order 1 should be calculated var singleCalc = calculations.First(); Assert.AreEqual(swapValue, singleCalc.Value); Assert.True(singleCalc.IsSuccess); Assert.AreEqual(initialAccountBalance - swapValue, (await _fakeMarginTradingAccountsRepository.GetAsync(accountId)).Balance); //move few hours later and calculate again dsMock.Setup(d => d.Now()).Returns(new DateTime(2017, 1, 2, 2, 0, 0)); //nothing should change calculations = _overnightSwapCache.GetAll(); Assert.AreEqual(1, calculations.Count); Assert.AreEqual(initialAccountBalance - swapValue, (await _fakeMarginTradingAccountsRepository.GetAsync(accountId)).Balance); _overnightSwapService.CalculateAndChargeSwaps(); //move to next day and calculate again dsMock.Setup(d => d.Now()).Returns(new DateTime(2017, 1, 3)); _overnightSwapService.CalculateAndChargeSwaps(); calculations = _overnightSwapCache.GetAll(); Assert.AreEqual(2, calculations.Count); // both order 1 and order 2 should be calculated Assert.AreEqual(initialAccountBalance - swapValue * 3, (await _fakeMarginTradingAccountsRepository.GetAsync(accountId)).Balance); }