private bool TryCloseDeals(double bottomBid, double topAsk, double spreadToClose) { if (spreadToClose > SpreadClosePosition) { return(false); } if (OpenedOrders.Count == 0) { return(false); } //StatisticalArbitrageOrderInfo order = GetOpenedOrderWithMaxSpread(); foreach (StatisticalArbitrageOrderInfo order in OpenedPairs) { if (order.Spread < SpreadClosePosition) { continue; } double actualLongCloseBid = Long.GetActualBidByAmount(order.LongAmount); double actualShortCloseAsk = Short.GetActualAskByAmount(order.ShortAmount); double spread = actualShortCloseAsk - actualLongCloseBid; if (spread > SpreadClosePosition) { continue; } double actualSellAmount = GetActualBottomBidAmount(actualLongCloseBid); double actualBuyAmount = GetActualShortAskAmount(actualShortCloseAsk); double finalSellAmount = Math.Min(actualSellAmount, order.LongAmount); double koeffSell = finalSellAmount / order.LongAmount; double finalBuyAmount = Math.Min(actualBuyAmount, order.ShortAmount); double koeffBuy = finalBuyAmount / order.ShortAmount; double koeff = Math.Min(koeffBuy, koeffSell); finalSellAmount *= koeff; finalBuyAmount *= koeff; TradingResult closeLong = MarketSell(Long, bottomBid, finalSellAmount); TradingResult closeShort = MarketBuy(Short, topAsk, finalBuyAmount); order.LongAmount -= closeLong.Amount; order.ShortAmount -= closeShort.Amount; //double eInc = (1 / order.LongValue - 1 / order.ShortValue) * finalBuyAmount; //Earned += eInc; LastItem = new StatisticalArbitrageHistoryItem(); LastItem.Time = DataProvider.CurrentTime; LastItem.Earned = Earned; LastItem.LongAmount = finalSellAmount; LastItem.LongAsk = Long.OrderBook.LowestAsk; LastItem.LongBid = bottomBid; LastItem.ShortAsk = topAsk; LastItem.ShortBid = Short.OrderBook.HighestBid; LastItem.ShortAmount = finalBuyAmount; LastItem.Close = true; LastItem.Index = StrategyData.Count; LastItem.Mark = "CLOSE"; LastItem.ClosedPositions.Add(order.LongPosition); LastItem.ClosedPositions.Add(order.ShortPosition); StrategyData.Add(LastItem); CloseLongPosition(order.LongPosition, closeLong); CloseShortPosition(order.ShortPosition, closeShort); if (order.LongAmount <= 0 && order.ShortAmount <= 0) { OpenedPairs.Remove(order); OnOrderClosed(LastItem); } else { throw new Exception("Partial Close Not Implemented"); } } return(true); }