public ArbitrageData CalculateWithTransaction(ArbitrageTransaction arbitrageTransaction) { if (arbitrageTransaction == null) { throw new ArgumentNullException(nameof(arbitrageTransaction)); } if (arbitrageTransaction.OriginalOrderType == null) { throw new ArgumentNullException(nameof(arbitrageTransaction.OriginalOrderType)); } if (arbitrageTransaction.OriginalOrderType == OrderType.BUY_LIMIT) { var baseCurrencyFee = arbitrageTransaction.CommisionPaid; var baseCurrencyGet = arbitrageTransaction.Volume - baseCurrencyFee; var quoteCurrencyLost = arbitrageTransaction.Price * arbitrageTransaction.Volume; decimal finalBaseCurrencyQty = this.FinalBaseCurrencyQuantity + baseCurrencyGet; decimal finalQuoteCurrencyQty = this.FinalQuoteCurrencyQuantity - quoteCurrencyLost; return(new ArbitrageData( this.BaseCurrency, this.QuoteCurrency, this.OriginalBaseCurrencyQuantity, this.OriginalQuoteCurrencyQuantity, finalBaseCurrencyQty, finalQuoteCurrencyQty )); } else if (arbitrageTransaction.OriginalOrderType == OrderType.SELL_LIMIT) { var quoteCurrencyFee = arbitrageTransaction.CommisionPaid; var quoteCurrencyGet = arbitrageTransaction.Volume - quoteCurrencyFee; var baseCurrencyLost = arbitrageTransaction.Volume; decimal finalBaseCurrencyQty = this.FinalBaseCurrencyQuantity - baseCurrencyLost; decimal finalQuoteCurrencyQty = this.FinalQuoteCurrencyQuantity + quoteCurrencyGet; return(new ArbitrageData( this.BaseCurrency, this.QuoteCurrency, this.OriginalBaseCurrencyQuantity, this.OriginalQuoteCurrencyQuantity, finalBaseCurrencyQty, finalQuoteCurrencyQty )); } else { throw new ArgumentOutOfRangeException($"Arbitrage order type \"{arbitrageTransaction.OriginalOrderType}\" is currently not supported."); } }
public void OrderFilled(Order order) { if (order == null) { throw new ArgumentNullException(nameof(order)); } if (order.ArbitrageId != this.ArbitrageId) { throw new InvalidOperationException($"Created order's arbitrage Id \"{order.ArbitrageId}\" doesn't match the simple arbitrage's Id \"{this.ArbitrageId}\"."); } if (order.BaseCurrency != this.ArbitrageData.BaseCurrency || order.QuoteCurrency != this.ArbitrageData.QuoteCurrency) { throw new InvalidOperationException($"The base currency or quote currency between the filled order and the simple arbitrage must be the same."); } if (this.Status.Id == SimpleArbitrageStatus.Opened.Id || this.Status.Id == SimpleArbitrageStatus.OrderFullFilled.Id || this.Status.Id == SimpleArbitrageStatus.Closed.Id) { throw new InvalidOperationException("Order can only be filled when the simple arbitrage's status is in \"OrderPartiallyCreated\" or \"OrderFullCreated\" or \"OrderPartiallyFilled\"."); } var orderFilledAmounts = this.GetOrderFilledAmounts(order.OrderId); var trxVolume = order.QuantityFilled - orderFilledAmounts; if (trxVolume <= 0) { throw new InvalidOperationException("The transaction volume must more than zero."); } var orderPaidFees = this.GetOrderPaidFees(order.OrderId); var trxCommisionFees = order.CommisionPaid - orderPaidFees; if (trxCommisionFees < 0) { throw new InvalidOperationException("The transaction fee should be zero or above."); } var transaction = new ArbitrageTransaction( this.ArbitrageId, order.ExchangeId, order.OrderType.Id, order.BaseCurrency, order.QuoteCurrency, order.Price, trxVolume, trxCommisionFees ); this._transactions.Add(transaction); this.ArbitrageData = this.ArbitrageData.CalculateWithTransaction(transaction); if (order.OrderType == OrderType.BUY_LIMIT) { if (this.GetOrderFilledAmounts(order.OrderId) >= this.BuyOrder.Quantity) { if (this.Status.Id == SimpleArbitrageStatus.OrderPartiallyFilled.Id) { //this.Status = SimpleArbitrageStatus.OrderFullFilled; this._simpleArbitrageStatusId = SimpleArbitrageStatus.OrderFullFilled.Id; } else { //this.Status = SimpleArbitrageStatus.OrderPartiallyFilled; this._simpleArbitrageStatusId = SimpleArbitrageStatus.OrderPartiallyFilled.Id; } } } if (order.OrderType == OrderType.SELL_LIMIT) { if (this.GetOrderFilledAmounts(order.OrderId) >= this.SellOrder.Quantity) { if (this.Status.Id == SimpleArbitrageStatus.OrderPartiallyFilled.Id) { //this.Status = SimpleArbitrageStatus.OrderFullFilled; this._simpleArbitrageStatusId = SimpleArbitrageStatus.OrderFullFilled.Id; } else { //this.Status = SimpleArbitrageStatus.OrderPartiallyFilled; this._simpleArbitrageStatusId = SimpleArbitrageStatus.OrderPartiallyFilled.Id; } } } }