private async Task ExecuteOrders(TraderOrderBase order1, TraderOrderBase order2) { var exchangeVolume = GetExchangeVolume(order1, order2); var price = GetOrderPrice(order1, order2); var instrument = GlobalSettings.FinanceInstruments[order1.Asset]; var marketOrderExchangeVolume = order1.BaseCurrency == instrument.Base ? exchangeVolume * price : exchangeVolume / price; var limitOrderExchangeVolume = order2.BaseCurrency == instrument.Base ? exchangeVolume * price : exchangeVolume / price; if (!await CheckIfEnoughBalance(order1, marketOrderExchangeVolume)) { order1.Status = OrderStatus.Canceled; order1.FailReason = OrderFailReason.NotEnoughFunds; await _ordersRepository.UpdateOrderAsync(order1); return; } if (!await CheckIfEnoughBalance(order2, limitOrderExchangeVolume)) { order2.Status = OrderStatus.Canceled; order2.FailReason = OrderFailReason.NotEnoughFunds; await _ordersRepository.UpdateOrderAsync(order2); return; } order1.Exchanged += exchangeVolume; order2.Exchanged += exchangeVolume; order1.AddExchangingOrder(order2.Id); order2.AddExchangingOrder(order1.Id); if (order1.IsOrderFullfiled()) order1.Status = OrderStatus.Done; await _ordersRepository.UpdateOrderAsync(order1); if (order2.IsOrderFullfiled()) order2.Status = OrderStatus.Done; await _ordersRepository.UpdateOrderAsync(order2); await ChangeBalance(order1, marketOrderExchangeVolume); await ChangeBalance(order2, limitOrderExchangeVolume); }
public async Task RegisterTradeOrderAsync(TraderOrderBase order) { await HandleCommonStuff(order); await _ordersRepository.RegisterOrderAsync(order); await _orderExecuter.Execute(); }
private static double GetExchangeVolume(TraderOrderBase order1, TraderOrderBase order2) { return order1.FullVolume > order2.FullVolume ? order2.FullVolume : order1.FullVolume; }
private static double GetOrderPrice(TraderOrderBase order1, TraderOrderBase order2) { var limit1 = order1 as LimitOrder; var limit2 = order2 as LimitOrder; if (limit1 == null && limit2 != null) return limit2.Price; if (limit2 == null && limit1 != null) return limit1.Price; if (limit1 == null && limit2 == null) throw new Exception("Both orders are market. Something is defenetly wrong."); return limit1.Id < limit2.Id ? limit1.Price : limit2.Price; }
private async Task ChangeBalance(TraderOrderBase order, double exchangedVolume) { var instrument = GlobalSettings.FinanceInstruments[order.Asset]; if (order.Action == OrderAction.Buy) { await _srvBalanceAccess.ChangeBalance(order.TraderId, instrument.Quoting, order.Volume); await _srvBalanceAccess.ChangeBalance(order.TraderId, instrument.Base, -exchangedVolume); } else { await _srvBalanceAccess.ChangeBalance(order.TraderId, instrument.Quoting, -order.Volume); await _srvBalanceAccess.ChangeBalance(order.TraderId, instrument.Base, exchangedVolume); } await UpdateBalanceChange(order.TraderId); }
private async Task<bool> CheckIfEnoughBalance(TraderOrderBase order, double exchangedVolume) { var instrument = GlobalSettings.FinanceInstruments[order.Asset]; var balances = await _srvBalanceAccess.GetCurrencyBalances(order.TraderId); if (order.Action == OrderAction.Buy) return (balances.GetBalance(instrument.Base) - exchangedVolume) >= 0; return (balances.GetBalance(instrument.Quoting) - order.Volume) >= 0; }
private async Task ExecuteOrders(TraderOrderBase order1, TraderOrderBase order2) { var exchangeVolume = GetExchangeVolume(order1, order2); var price = GetOrderPrice(order1, order2); var assetPair = _assetPairsCachedReader.Get(order1.Asset); var marketOrderExchangeVolume = order1.BaseCurrency == assetPair.BaseAssetId ? exchangeVolume * price : exchangeVolume / price; var limitOrderExchangeVolume = order2.BaseCurrency == assetPair.BaseAssetId ? exchangeVolume * price : exchangeVolume / price; if (!await CheckIfEnoughBalance(assetPair, order1, marketOrderExchangeVolume)) { order1.Status = OrderStatus.Canceled; order1.FailReason = OrderFailReason.NotEnoughFunds; await _ordersRepository.UpdateOrderAsync(order1); return; } if (!await CheckIfEnoughBalance(assetPair, order2, limitOrderExchangeVolume)) { order2.Status = OrderStatus.Canceled; order2.FailReason = OrderFailReason.NotEnoughFunds; await _ordersRepository.UpdateOrderAsync(order2); return; } order1.Exchanged += exchangeVolume; order2.Exchanged += exchangeVolume; order1.AddExchangingOrder(order2.Id); order2.AddExchangingOrder(order1.Id); if (order1.IsOrderFullfiled()) order1.Status = OrderStatus.Done; await _ordersRepository.UpdateOrderAsync(order1); if (order2.IsOrderFullfiled()) order2.Status = OrderStatus.Done; await _ordersRepository.UpdateOrderAsync(order2); await ChangeBalance(assetPair, order1, marketOrderExchangeVolume); await ChangeBalance(assetPair, order2, limitOrderExchangeVolume); await NotifyOrderBookChanged(assetPair.Id); }
private async Task ChangeBalance(IAssetPair assetPair, TraderOrderBase order, double exchangedVolume) { if (order.Action == OrderAction.Buy) { await _srvBalanceAccess.ChangeBalance(order.TraderId, assetPair.QuotingAssetId, order.Volume); await _srvBalanceAccess.ChangeBalance(order.TraderId, assetPair.BaseAssetId, -exchangedVolume); } else { await _srvBalanceAccess.ChangeBalance(order.TraderId, assetPair.QuotingAssetId, -order.Volume); await _srvBalanceAccess.ChangeBalance(order.TraderId, assetPair.BaseAssetId, exchangedVolume); } await UpdateBalanceChange(order.TraderId); }
private async Task<bool> CheckIfEnoughBalance(IAssetPair assetPair, TraderOrderBase order, double exchangedVolume) { var balances = await _srvBalanceAccess.GetCurrencyBalances(order.TraderId); if (order.Action == OrderAction.Buy) return (balances.GetBalance(assetPair.BaseAssetId) - exchangedVolume) >= 0; return (balances.GetBalance(assetPair.QuotingAssetId) - order.Volume) >= 0; }