public object aspect_total(object rowObject) { ExchangeOrder order = (ExchangeOrder)rowObject; if (order.market.Contains("USD")) { return(order.total.ToString("C")); } else { return(order.total.ToString("N8")); } }
public void TestAskComparer() { var askComparer = OrderComparer.DescAskComparer(); var o1 = new ExchangeOrder(1, 1, OrderSide.Sell, OrderType.Limit, 10, 10); var o2 = new ExchangeOrder(2, 1, OrderSide.Sell, OrderType.Limit, 9, 10); var c1 = askComparer.Compare(o1, o2); Assert.AreEqual(1, c1, string.Format("AskComparer: lower price should win over higher price. {0} vs {1}", o1.Price, o2.Price)); var c2 = askComparer.Compare(o2, o1); Assert.AreEqual(-1, c2, "AskComparer: price comparison not symmetric"); Thread.Sleep(TimeSpan.FromTicks(10000)); //otherwhise timestamp comparison is not precise enough var o3 = new ExchangeOrder(3, 1, OrderSide.Sell, OrderType.Limit, 10, 10); var c3 = askComparer.Compare(o1, o3); //this test does not always pass. if timespan between c1 and c2 is too small. Assert.AreEqual(-1, c3, string.Format("AskComparer: Timestamp comparison failed. {0} vs {1}", o1.UTCTimestamp.Ticks, o3.UTCTimestamp.Ticks)); var c4 = askComparer.Compare(o3, o1); Assert.AreEqual(1, c4, "BidComparer: Timestamp comparison not symmetric"); //try to get two orders with the same timestamp. //depending on environment, it could take a variable amout of time. Try 10 times and then give up var o4 = new ExchangeOrder(4, 1, OrderSide.Sell, OrderType.Limit, 10, 10); var o5 = new ExchangeOrder(5, 1, OrderSide.Sell, OrderType.Limit, 10, 9); int counter = 0; while (o4.UTCTimestamp != o5.UTCTimestamp && counter < 10) { o4 = new ExchangeOrder(4, 1, OrderSide.Sell, OrderType.Limit, 10, 10); o5 = new ExchangeOrder(5, 1, OrderSide.Sell, OrderType.Limit, 10, 9); counter++; } if (counter == 10) { Assert.Inconclusive("failed to create two orders with the same timestamp. Could not test RemainingVolume comparison"); } else { var c5 = askComparer.Compare(o4, o5); Assert.AreEqual(-1, c5, string.Format("AskComparer: If price and timestamp are equal, the order with the most remaining volume should win. {0} vs {1}", o4.RemainingVolume, o5.RemainingVolume)); } }
public CoinBuy(ExchangeOrder exchangeOrder) { this.ClosedDate = exchangeOrder.ClosedDate; this.Exchange = exchangeOrder.Exchange; this.ExchangeOrderId = exchangeOrder.ExchangeOrderId; this.FilledQuantity = exchangeOrder.FilledQuantity; this.OrderId = exchangeOrder.OrderId; this.Pair = exchangeOrder.Pair; this.PlaceDate = exchangeOrder.PlaceDate; this.Price = exchangeOrder.Price; this.Quantity = exchangeOrder.Quantity; this.Side = exchangeOrder.Side; this.Status = exchangeOrder.Status; }
internal void AddNewOrderToDb(ExchangeOrder order, Ticker ticker, TradeSettings tradeSettings, TradingPairInfo pairInfo) { _orderRepository.Add(new Order { BuyId = order.Id, CurrencyPairId = GetCurrencyPairId(order.PairCode), //CurrencyPair = _currencyPairRepository.First(p => p.PairCode == order.PairCode), //todo: check with concrete repository BuyAmount = order.Amount, BuyPrice = order.Price, SellAmount = tradeSettings.GetSellBaseAmount(ticker, pairInfo), SellPrice = tradeSettings.GetSellBasePrice(ticker, pairInfo) }); _orderRepository.Save(); }
private void ListView_FormatCell(object sender, FormatCellEventArgs e) { if (e.ColumnIndex == column_exchange.Index) { ExchangeOrder item = (ExchangeOrder)e.Model; if (item.type == "buy") { e.SubItem.BackColor = PreferenceManager.preferences.Theme.Green; } else { e.SubItem.BackColor = PreferenceManager.preferences.Theme.Red; } } }
public static Order ToOrder(this ExchangeOrder externalOrder) { Order order = new Order(); order.Symbol = externalOrder.Symbol; order.OrderStatusCode = externalOrder.Status.Code; order.Amount = externalOrder.ExecutedQuantity; order.Id = externalOrder.OrderId; order.ExchangeOrderId = long.Parse(externalOrder.ExchangeOrderId); order.OrderSideCode = externalOrder.OrderSideCode.Code; order.OrderTypeCode = externalOrder.OrderTypeCode.Code; order.FillPoliticsCode = externalOrder.FillPoliticsCode.Code; order.Price = externalOrder.Price; return(order); }
/// <summary> /// Convert an OrderResponse to an ExchangeOrder /// </summary> /// <param name="orderResponse">OrderResponse to convert</param> /// <returns>new ExchangeOrder object</returns> public ExchangeOrder OrderResponseToExchangeOrder(OrderResponse orderResponse, Exchange exchange) { var exchangeOrder = new ExchangeOrder { Exchange = exchange, FilledQuantity = orderResponse.FilledQuantity, OrderId = orderResponse.OrderId, Pair = orderResponse.Pair, PlaceDate = orderResponse.TransactTime, Price = orderResponse.Price, Quantity = orderResponse.OrderQuantity, Side = (Side)orderResponse.Side }; return(exchangeOrder); }
/// <summary> /// Convert an OrderResponse to an ExchangeOrder /// </summary> /// <param name="orderResponse">OrderResponse to convert</param> /// <returns>new ExchangeOrder object</returns> public ExchangeOrder OrderResponseToExchangeOrder(ExchangeHub.Contracts.OrderResponse orderResponse) { var exchangeOrder = new ExchangeOrder { Exchange = StringToExchange(currentExchange), FilledQuantity = orderResponse.FilledQuantity, OrderId = orderResponse.OrderId, Pair = orderResponse.Pair, PlaceDate = orderResponse.TransactTime, Price = orderResponse.Price, Quantity = orderResponse.OrderQuantity, Side = (Side)orderResponse.Side }; return(exchangeOrder); }
public async Task <IOrderedEnumerable <ExchangeOrder> > LookforExecution(ExchangeOrder order) { //var builder = Builders<ExchangeOrder>.Filter; //var filter = builder.Eq("Order.TokenName", order.Order.TokenName) // & builder.Ne("State", DealState.Placed); //if (order.Order.BuySellType == OrderType.Buy) //{ // filter &= builder.Eq("Order.BuySellType", OrderType.Sell); // filter &= builder.Lte("Order.Price", order.Order.Price); //} //else //{ // filter &= builder.Eq("Order.BuySellType", OrderType.Buy); // filter &= builder.Gte("Order.Price", order.Order.Price); //} IAsyncCursor <ExchangeOrder> found; if (order.Order.BuySellType == OrderType.Buy) { found = await _queue.FindAsync(a => a.Order.TokenName == order.Order.TokenName && a.State != DealState.Placed && a.Order.BuySellType == OrderType.Sell && a.Order.Price <= order.Order.Price); } else { found = await _queue.FindAsync(a => a.Order.TokenName == order.Order.TokenName && a.State != DealState.Placed && a.Order.BuySellType == OrderType.Buy && a.Order.Price >= order.Order.Price); } var matches0 = await found.ToListAsync(); if (order.Order.BuySellType == OrderType.Buy) { var matches = matches0.OrderBy(a => a.Order.Price); return(matches); } else { var matches = matches0.OrderByDescending(a => a.Order.Price); return(matches); } }
public void InitExchangePrice(ExchangeOrder order, ExchangePricesEventArgs args, OrderSide type) { Action <int, OrderSide> init = (i, type_) => { if (order.Price != 0) { if (type_ == OrderSide.BID) { //if ((GetPrice(args, i) - order.Price) / order.Price > 0.001) { order.Price = GetPrice(args, i); order.Amount = GetAmount(args, i); } } else if (type_ == OrderSide.ASK) { //if ((order.Price - GetPrice(args, i)) / order.Price > 0.001) { order.Price = GetPrice(args, i); order.Amount = GetAmount(args, i); } } } else { order.Price = GetPrice(args, i); order.Amount = GetAmount(args, i); } }; if (type == OrderSide.BID) { init(0, type); } else if (type == OrderSide.ASK) { init(1, type); } else { Utils.ThrowIf(true, "BOTH order type"); } }
private Entities.Trade.ExchangeOrder ContractToEntity(ExchangeOrder contract) { var entity = new Entities.Trade.ExchangeOrder { Id = contract.ExchangeOrderId, ClosedDate = contract.ClosedDate, Exchange = contract.Exchange, FilledQuantity = contract.FilledQuantity, OrderId = contract.OrderId, Pair = contract.Pair, Price = contract.Price, PlaceDate = contract.PlaceDate, Quantity = contract.Quantity, Side = contract.Side, Status = contract.Status }; return(entity); }
private ExchangeOrder EntityToContract(Entities.Trade.ExchangeOrder entity) { var contract = new ExchangeOrder { ExchangeOrderId = entity.Id, ClosedDate = entity.ClosedDate, Exchange = entity.Exchange, FilledQuantity = entity.FilledQuantity, OrderId = entity.OrderId, Pair = entity.Pair, Price = entity.Price, PlaceDate = entity.PlaceDate, Quantity = entity.Quantity, Side = entity.Side, Status = entity.Status }; return(contract); }
public object aspect_rate(object rowObject) { ExchangeOrder order = (ExchangeOrder)rowObject; /* * if (order.market.Contains("USD")) * { * return order.rate.ToString("C"); * } * else * { * double rate = order.rate * 100000000; * return rate + "B"; * } */ //List<ExchangeTicker> list = Tickers.Where(item => item.exchange == order.exchange).ToList(); //LogManager.AddLogMessage(Name, "aspect_spread", order.exchange + " | " + order.symbol + " | " + order.market + " | " + order.rate + " | " + list.Count, LogManager.LogMessageType.DEBUG); ExchangeTicker ticker = Tickers.FirstOrDefault(item => item.exchange == order.exchange && item.symbol == order.symbol && item.market == order.market); if (ticker != null) { if (order.market.Contains("USD")) { return(ticker.last.ToString("C") + " / " + order.rate.ToString("C")); } else { decimal rate = Convert.ToDecimal(order.rate) * 100000000; decimal last = ticker.last * 100000000; return(last.ToString("N0") + " / " + rate.ToString("N0")); } //column_symbol.Width += //LogManager.AddLogMessage(Name, "aspect_spread", "rate=" + order.rate + " | " + ticker.last, LogManager.LogMessageType.DEBUG); //return 0; } else { //LogManager.AddLogMessage(Name, "aspect_spread", "NO TICKER=" + order.exchange + " | " + order.symbol + " | " + order.market, LogManager.LogMessageType.DEBUG); return(0); } }
public void TestSubmittedOrdersAreAddedToStreams() { var testScheduler = new TestScheduler(); var mockExchangeClient = new MockClient(1, testScheduler); var orderStream = mockExchangeClient.OrderStream; var orderBookStream = mockExchangeClient.OrderBookStream; var sourceOrderList = new List <ExchangeOrder>(); var order1 = new ExchangeOrder(1, 1, OrderSide.Buy, OrderType.Limit, 10, 5); var order2 = new ExchangeOrder(2, 1, OrderSide.Sell, OrderType.Limit, 11, 6); sourceOrderList.Add(order1); sourceOrderList.Add(order2); var resultOrderList = new List <ExchangeOrder>(); var resultOrderBookList = new List <IOrderBook>(); var orderStreamSubscription = orderStream.Subscribe(resultOrderList.Add); var orderBookStreamSubscription = orderBookStream.Subscribe(resultOrderBookList.Add); testScheduler.Start(); mockExchangeClient.Connect(); foreach (var order in sourceOrderList) { //do not wait for result. mockExchangeClient.SubmitOrder(order.OSide, order.OType, order.Price, order.Size); } mockExchangeClient.Disconnect(); testScheduler.Stop(); //test number of orders pushed Assert.AreEqual(sourceOrderList.Count, resultOrderList.Count); //test number of resulting orderbooks //there should be as many as orders Assert.AreEqual(sourceOrderList.Count, resultOrderBookList.Count); }
public static ExchangeOrder ToOrder(this BinanceCanceledOrder externalOrder) { if (externalOrder == null) { return(null); } ExchangeOrder order = new ExchangeOrder(); order.Symbol = externalOrder.Symbol; order.Status = externalOrder.Status.ToStatus(); order.OriginalQuantity = externalOrder.OriginalQuantity; order.OrderId = long.Parse(externalOrder.ClientOrderId); order.ExchangeOrderId = externalOrder.OrderId.ToString(); order.OrderSideCode = externalOrder.Side.ToCode(); order.OrderTypeCode = externalOrder.Type.ToCode(); order.FillPoliticsCode = externalOrder.TimeInForce.ToCode(); order.ExecutedQuantity = externalOrder.ExecutedQuantity; order.Price = externalOrder.Price; return(order); }
public Task <Order> Update(ExchangeOrder entity, IDbConnection connection, IDbTransaction transaction = null) { const string query = @" update Orders set orderStatusCode = @orderStatusCode, exchangeOrderId = @exchangeOrderId, updated = @updated, where id = @id; returning *; " ; return(connection.QueryFirstAsync <Order>(query, new { orderStatusCode = entity.Status.Code, exchangeOrderId = entity.ExchangeOrderId, updated = entity.TransactTime }, transaction)); }
public async Task <CancelKey> AddOrderAsync(ExchangeAccount acct, TokenTradeOrder order) { order.CreatedTime = DateTime.Now; var item = new ExchangeOrder() { ExchangeAccountId = acct.Id, Order = order, CanDeal = true, State = DealState.Placed, ClientIP = null }; await _queue.InsertOneAsync(item); OnNewOrder?.Invoke(this, new EventArgs()); var key = new CancelKey() { State = OrderState.Placed, Key = item.Id.ToString(), Order = order }; return(key); }
public BitstampOrderEventArgs(ExchangeOrder order) { Order = order; }
public decimal OpenMarketOrder(decimal orderSize, ExchangeOrderSide side) { var nexus = simulator.Nexus; var baseSymbol = baseToken.Symbol; var baseDecimals = baseToken.Decimals; var quoteSymbol = quoteToken.Symbol; var quoteDecimals = quoteToken.Decimals; var orderToken = side == Buy ? quoteToken : baseToken; var orderSizeBigint = UnitConversion.ToBigInteger(orderSize, orderToken.Decimals); var OpenerBaseTokensInitial = simulator.Nexus.RootChain.GetTokenBalance(simulator.Nexus.RootStorage, baseSymbol, user.Address); var OpenerQuoteTokensInitial = simulator.Nexus.RootChain.GetTokenBalance(simulator.Nexus.RootStorage, quoteSymbol, user.Address); BigInteger OpenerBaseTokensDelta = 0; BigInteger OpenerQuoteTokensDelta = 0; //get the starting balance for every address on the opposite side of the orderbook, so we can compare it to the final balance of each of those addresses var otherSide = side == Buy ? Sell : Buy; var startingOppositeOrderbook = (ExchangeOrder[])simulator.Nexus.RootChain.InvokeContract(simulator.Nexus.RootStorage, "exchange", "GetOrderBook", baseSymbol, quoteSymbol, otherSide).ToObject(); var OtherAddressesTokensInitial = new Dictionary <Address, BigInteger>(); //******************************************************************************************************************************************************************************* //*** the following method to check token balance state only works for the scenario of a single new exchange order per block that triggers other pre-existing exchange orders *** //******************************************************************************************************************************************************************************* foreach (var oppositeOrder in startingOppositeOrderbook) { if (OtherAddressesTokensInitial.ContainsKey(oppositeOrder.Creator) == false) { var targetSymbol = otherSide == Buy ? baseSymbol : quoteSymbol; OtherAddressesTokensInitial.Add(oppositeOrder.Creator, simulator.Nexus.RootChain.GetTokenBalance(simulator.Nexus.RootStorage, targetSymbol, oppositeOrder.Creator)); } } //-------------------------- simulator.BeginBlock(); var tx = simulator.GenerateCustomTransaction(user, ProofOfWork.None, () => ScriptUtils.BeginScript().AllowGas(user.Address, Address.Null, 1, 9999) .CallContract("exchange", "OpenMarketOrder", user.Address, baseSymbol, quoteSymbol, orderSizeBigint, side). SpendGas(user.Address).EndScript()); simulator.EndBlock(); var txCost = simulator.Nexus.RootChain.GetTransactionFee(tx); BigInteger escrowedAmount = orderSizeBigint; //take into account the transfer of the owner's wallet to the chain address if (side == Buy) { OpenerQuoteTokensDelta -= escrowedAmount; } else if (side == Sell) { OpenerBaseTokensDelta -= escrowedAmount; } //take into account tx cost in case one of the symbols is the FuelToken if (baseSymbol == DomainSettings.FuelTokenSymbol) { OpenerBaseTokensDelta -= txCost; } else if (quoteSymbol == DomainSettings.FuelTokenSymbol) { OpenerQuoteTokensDelta -= txCost; } var events = nexus.FindBlockByTransaction(tx).GetEventsForTransaction(tx.Hash); var ordersCreated = events.Count(x => x.Kind == EventKind.OrderCreated && x.Address == user.Address); var wasNewOrderCreated = ordersCreated >= 1; Assert.IsTrue(wasNewOrderCreated, "No orders were created"); var ordersClosed = events.Count(x => x.Kind == EventKind.OrderClosed && x.Address == user.Address); var wasNewOrderClosed = ordersClosed == 1; var wasNewOrderCancelled = events.Count(x => x.Kind == EventKind.OrderCancelled && x.Address == user.Address) == 1; var createdOrderEvent = events.First(x => x.Kind == EventKind.OrderCreated); var createdOrderUid = Serialization.Unserialize <BigInteger>(createdOrderEvent.Data); ExchangeOrder createdOrderPostFill = new ExchangeOrder(); //---------------- //verify the order does not exist in the orderbook //in case the new order was IoC and it wasnt closed, order should have been cancelled if (wasNewOrderClosed == false) { Assert.IsTrue(wasNewOrderCancelled, "Non closed order did not get cancelled"); } else //if the new order was closed if (wasNewOrderClosed) { Assert.IsTrue(wasNewOrderCancelled == false, "Closed order also got cancelled"); } //check that the order no longer exists on the orderbook try { simulator.Nexus.RootChain.InvokeContract(simulator.Nexus.RootStorage, "exchange", "GetExchangeOrder", createdOrderUid); Assert.IsTrue(false, "Market order exists on the orderbooks"); } catch (Exception e) { //purposefully empty, this is the expected code-path } //------------------ //validate that everyone received their tokens appropriately BigInteger escrowedUsage = 0; //this will hold the amount of the escrowed amount that was actually used in the filling of the order //for IoC orders, we need to make sure that what wasn't used gets returned properly //for non IoC orders, we need to make sure that what wasn't used stays on the orderbook BigInteger baseTokensReceived = 0, quoteTokensReceived = 0; var OtherAddressesTokensDelta = new Dictionary <Address, BigInteger>(); //******************************************************************************************************************************************************************************* //*** the following method to check token balance state only works for the scenario of a single new exchange order per block that triggers other pre-existing exchange orders *** //******************************************************************************************************************************************************************************* //calculate the expected delta of the balances of all addresses involved var tokenExchangeEvents = events.Where(x => x.Kind == EventKind.TokenReceive); foreach (var tokenExchangeEvent in tokenExchangeEvents) { var eventData = Serialization.Unserialize <TokenEventData>(tokenExchangeEvent.Data); if (tokenExchangeEvent.Address == user.Address) { if (eventData.symbol == baseSymbol) { baseTokensReceived += eventData.value; } else if (eventData.symbol == quoteSymbol) { quoteTokensReceived += eventData.value; } } else { Assert.IsTrue(OtherAddressesTokensInitial.ContainsKey(tokenExchangeEvent.Address), "Address that was not on this orderbook received tokens"); if (OtherAddressesTokensDelta.ContainsKey(tokenExchangeEvent.Address)) { OtherAddressesTokensDelta[tokenExchangeEvent.Address] += eventData.value; } else { OtherAddressesTokensDelta.Add(tokenExchangeEvent.Address, eventData.value); } escrowedUsage += eventData.value; //the tokens other addresses receive come from the escrowed amount of the order opener } } OpenerBaseTokensDelta += baseTokensReceived; OpenerQuoteTokensDelta += quoteTokensReceived; var expectedRemainingEscrow = escrowedAmount - escrowedUsage; switch (side) { case Buy: Assert.IsTrue(Abs(OpenerQuoteTokensDelta) == escrowedUsage - (quoteSymbol == DomainSettings.FuelTokenSymbol ? txCost : 0)); break; case Sell: Assert.IsTrue(Abs(OpenerBaseTokensDelta) == escrowedUsage - (baseSymbol == DomainSettings.FuelTokenSymbol ? txCost : 0)); break; } //get the actual final balance of all addresses involved and make sure it matches the expected deltas var OpenerBaseTokensFinal = simulator.Nexus.RootChain.GetTokenBalance(simulator.Nexus.RootStorage, baseSymbol, user.Address); var OpenerQuoteTokensFinal = simulator.Nexus.RootChain.GetTokenBalance(simulator.Nexus.RootStorage, quoteSymbol, user.Address); Assert.IsTrue(OpenerBaseTokensFinal == OpenerBaseTokensDelta + OpenerBaseTokensInitial); Assert.IsTrue(OpenerQuoteTokensFinal == OpenerQuoteTokensDelta + OpenerQuoteTokensInitial); foreach (var entry in OtherAddressesTokensInitial) { var otherAddressInitialTokens = entry.Value; BigInteger delta = 0; if (OtherAddressesTokensDelta.ContainsKey(entry.Key)) { delta = OtherAddressesTokensDelta[entry.Key]; } var targetSymbol = otherSide == Buy ? baseSymbol : quoteSymbol; var otherAddressFinalTokens = simulator.Nexus.RootChain.GetTokenBalance(simulator.Nexus.RootStorage, targetSymbol, entry.Key); Assert.IsTrue(otherAddressFinalTokens == delta + otherAddressInitialTokens); } return(side == Buy?UnitConversion.ToDecimal(baseTokensReceived, baseToken.Decimals) : UnitConversion.ToDecimal(quoteTokensReceived, quoteToken.Decimals)); }
public void TestAggregatedOrderBook() { #region Check Union of sorted sets is still sorted var o11 = new ExchangeOrder(1, 1, OrderSide.Buy, OrderType.Limit, 10, 5); var o12 = new ExchangeOrder(2, 1, OrderSide.Buy, OrderType.Limit, 9, 4); var o13 = new ExchangeOrder(3, 1, OrderSide.Sell, OrderType.Limit, 12, 6); var o14 = new ExchangeOrder(4, 1, OrderSide.Sell, OrderType.Limit, 11, 7); var orderBook1 = new MockOrderBook(1).PlaceOrder(o11) .PlaceOrder(o12) .PlaceOrder(o13) .PlaceOrder(o14); var o21 = new ExchangeOrder(5, 2, OrderSide.Buy, OrderType.Limit, 10.5m, 5.5m); var o22 = new ExchangeOrder(6, 2, OrderSide.Buy, OrderType.Limit, 9.5m, 4.5m); var o23 = new ExchangeOrder(7, 2, OrderSide.Sell, OrderType.Limit, 12.5m, 5.5m); var o24 = new ExchangeOrder(8, 2, OrderSide.Sell, OrderType.Limit, 11.5m, 6.5m); var orderBook2 = new MockOrderBook(2).PlaceOrder(o21) .PlaceOrder(o22) .PlaceOrder(o23) .PlaceOrder(o24); var aggregatedOrderBook = new AggregatedOrderBook().InsertBook(orderBook1) .InsertBook(orderBook2); Assert.AreEqual(5, aggregatedOrderBook.Bids[0].ID); Assert.AreEqual(1, aggregatedOrderBook.Bids[1].ID); Assert.AreEqual(6, aggregatedOrderBook.Bids[2].ID); Assert.AreEqual(2, aggregatedOrderBook.Bids[3].ID); Assert.AreEqual(4, aggregatedOrderBook.Asks[0].ID); Assert.AreEqual(8, aggregatedOrderBook.Asks[1].ID); Assert.AreEqual(3, aggregatedOrderBook.Asks[2].ID); Assert.AreEqual(7, aggregatedOrderBook.Asks[3].ID); #endregion #region Check replacing an order book var o222 = o22.WithUpdatedRemainingVolume(1); var o232 = o23.WithUpdatedRemainingVolume(0.5m); var o242 = o24.WithUpdatedRemainingVolume(0.2m); var o25 = new ExchangeOrder(9, 2, OrderSide.Sell, OrderType.Limit, 13, 10); var orderBook22 = new MockOrderBook(2).PlaceOrder(o222) .PlaceOrder(o232) .PlaceOrder(o242) .PlaceOrder(o25); var aggregatedOrderBook2 = aggregatedOrderBook.InsertBook(orderBook22); Assert.AreEqual(1, aggregatedOrderBook2.Bids[0].ID); Assert.AreEqual(6, aggregatedOrderBook2.Bids[1].ID); Assert.AreEqual(3.5m, aggregatedOrderBook2.Bids[1].RemainingVolume); Assert.AreEqual(2, aggregatedOrderBook2.Bids[2].ID); Assert.AreEqual(4, aggregatedOrderBook2.Asks[0].ID); Assert.AreEqual(8, aggregatedOrderBook2.Asks[1].ID); Assert.AreEqual(6.3m, aggregatedOrderBook2.Asks[1].RemainingVolume); Assert.AreEqual(3, aggregatedOrderBook2.Asks[2].ID); Assert.AreEqual(7, aggregatedOrderBook2.Asks[3].ID); Assert.AreEqual(5, aggregatedOrderBook2.Asks[3].RemainingVolume); Assert.AreEqual(9, aggregatedOrderBook2.Asks[4].ID); #endregion #region Check arbitrage scanning var o31 = new ExchangeOrder(1, 3, OrderSide.Buy, OrderType.Limit, 12, 5); var o32 = new ExchangeOrder(2, 3, OrderSide.Buy, OrderType.Limit, 9, 7); var o33 = new ExchangeOrder(3, 3, OrderSide.Sell, OrderType.Limit, 13, 4); var o34 = new ExchangeOrder(4, 3, OrderSide.Sell, OrderType.Limit, 14, 6); var orderBook3 = new MockOrderBook(3).PlaceOrder(o31) .PlaceOrder(o32) .PlaceOrder(o33) .PlaceOrder(o34); var o41 = new ExchangeOrder(5, 4, OrderSide.Buy, OrderType.Limit, 10.5m, 2); var o42 = new ExchangeOrder(6, 4, OrderSide.Buy, OrderType.Limit, 8, 6); var o43 = new ExchangeOrder(7, 4, OrderSide.Sell, OrderType.Limit, 11, 8); var o44 = new ExchangeOrder(8, 4, OrderSide.Sell, OrderType.Limit, 13.5m, 2); var orderBook4 = new MockOrderBook(4).PlaceOrder(o41) .PlaceOrder(o42) .PlaceOrder(o43) .PlaceOrder(o44); var aggregatedOrderBook3 = new AggregatedOrderBook().InsertBook(orderBook3) .InsertBook(orderBook4); var arbitrage = aggregatedOrderBook3.LookForArbitrage(); Assert.AreEqual(5, arbitrage.BuyDico[4]); Assert.AreEqual(5, arbitrage.SellDico[3]); #endregion #region Check arbitrage scanning 2 var o51 = new ExchangeOrder(1, 5, OrderSide.Buy, OrderType.Limit, 13, 5); var o52 = new ExchangeOrder(2, 5, OrderSide.Buy, OrderType.Limit, 12.8m, 2); var o53 = new ExchangeOrder(3, 5, OrderSide.Buy, OrderType.Limit, 12.7m, 6); var o54 = new ExchangeOrder(4, 5, OrderSide.Buy, OrderType.Limit, 12, 4); var orderBook5 = new MockOrderBook(5).PlaceOrder(o51) .PlaceOrder(o52) .PlaceOrder(o53) .PlaceOrder(o54); var o61 = new ExchangeOrder(1, 6, OrderSide.Sell, OrderType.Limit, 12.5m, 10); var o62 = new ExchangeOrder(2, 6, OrderSide.Sell, OrderType.Limit, 13, 4); var orderBook6 = new MockOrderBook(6).PlaceOrder(o61) .PlaceOrder(o62); var o71 = new ExchangeOrder(1, 7, OrderSide.Sell, OrderType.Limit, 12, 7); var o72 = new ExchangeOrder(2, 7, OrderSide.Sell, OrderType.Limit, 12.7m, 5); var orderBook7 = new MockOrderBook(7).PlaceOrder(o71) .PlaceOrder(o72); var aggregatedOrderBook4 = new AggregatedOrderBook().InsertBook(orderBook5) .InsertBook(orderBook6) .InsertBook(orderBook7); var arbitrage2 = aggregatedOrderBook4.LookForArbitrage(); Assert.AreEqual(7, arbitrage2.BuyDico[7]); Assert.AreEqual(6, arbitrage2.BuyDico[6]); Assert.AreEqual(13, arbitrage2.SellDico[5]); #endregion }
public async static void updateExchangeOrderList(bool clear = false) { List <ExchangeOrder> list = new List <ExchangeOrder>(); List <GDAXOrder> orders = await getOrdersList(); if (orders.Count > 0) { if (clear) { ClearOrders(Name); } foreach (GDAXOrder order in orders) { //LogManager.AddLogMessage(Name, "updateExchangeOrderList", order.symbol + " | " + order.market + " | " + order.type, LogManager.LogMessageType.DEBUG); string[] pairSplit = order.product_id.Split('-'); bool open = false; if (order.status == "open") { open = true; } ExchangeOrder eOrder = new ExchangeOrder() { exchange = Name, id = order.id, type = order.side, rate = order.price, amount = order.size, total = order.price * order.size, market = pairSplit[1], symbol = pairSplit[0], date = order.created_at, open = open }; processOrder(eOrder); } } /* * Thread.Sleep(1000); * * List<BittrexOrderHistoryItem> trades = getOrderHistoryList(); * foreach (BittrexOrderHistoryItem trade in trades) * { * //LogManager.AddLogMessage(Name, "updateExchangeOrderList", trade.Exchange + " | " + trade. + " | " + trade.type, LogManager.LogMessageType.DEBUG); * string[] orderTypeSplit = trade.OrderType.Split('_'); * string[] pairSplit = trade.Exchange.Split('-'); * * ExchangeOrder eOrder = new ExchangeOrder() * { * exchange = Name, * id = trade.OrderUuid, * type = orderTypeSplit[1].ToLower(), * rate = trade.Limit, * amount = trade.Quantity, * total = trade.Price, * market = pairSplit[0], * symbol = pairSplit[1], * date = trade.TimeStamp, * open = false * }; * processOrder(eOrder); * } */ //LogManager.AddLogMessage(Name, "updateExchangeOrderList", "COUNT=" + Orders.Count, LogManager.LogMessageType.DEBUG); }
public void TestSortedSetOfOrders() { //ATTENTION sorted set is in descending order. [best order, ..., worst order] var bids = ImmutableSortedSet.Create(comparer: OrderComparer.DescBidComparer()); var b1 = new ExchangeOrder(1, 1, OrderSide.Buy, OrderType.Limit, 10, 10); bids = bids.Add(b1); var b2 = new ExchangeOrder(2, 1, OrderSide.Buy, OrderType.Limit, 9, 3); bids = bids.Add(b2); Assert.AreEqual(1, bids[0].ID); Assert.AreEqual(2, bids[1].ID); var b3 = new ExchangeOrder(3, 1, OrderSide.Buy, OrderType.Limit, 11, 5); bids = bids.Add(b3); Assert.AreEqual(3, bids[0].ID); Assert.AreEqual(1, bids[1].ID); Assert.AreEqual(2, bids[2].ID); var b4 = new ExchangeOrder(4, 1, OrderSide.Buy, OrderType.Limit, 10, 8); bids = bids.Add(b4); Assert.AreEqual(3, bids[0].ID); Assert.AreEqual(1, bids[1].ID); Assert.AreEqual(4, bids[2].ID); Assert.AreEqual(2, bids[3].ID); var b5 = new ExchangeOrder(5, 1, OrderSide.Buy, OrderType.Limit, 9.5m, 4); bids = bids.Add(b5); Assert.AreEqual(3, bids[0].ID); Assert.AreEqual(1, bids[1].ID); Assert.AreEqual(4, bids[2].ID); Assert.AreEqual(5, bids[3].ID); Assert.AreEqual(2, bids[4].ID); var asks = ImmutableSortedSet.Create(comparer: OrderComparer.DescAskComparer()); var a1 = new ExchangeOrder(1, 1, OrderSide.Sell, OrderType.Limit, 10, 10); asks = asks.Add(a1); var a2 = new ExchangeOrder(2, 1, OrderSide.Sell, OrderType.Limit, 11, 4); asks = asks.Add(a2); Assert.AreEqual(1, asks[0].ID); Assert.AreEqual(2, asks[1].ID); var a3 = new ExchangeOrder(3, 1, OrderSide.Sell, OrderType.Limit, 9, 5); asks = asks.Add(a3); Assert.AreEqual(3, asks[0].ID); Assert.AreEqual(1, asks[1].ID); Assert.AreEqual(2, asks[2].ID); var a4 = new ExchangeOrder(4, 1, OrderSide.Sell, OrderType.Limit, 10, 8); asks = asks.Add(a4); Assert.AreEqual(3, asks[0].ID); Assert.AreEqual(1, asks[1].ID); Assert.AreEqual(4, asks[2].ID); Assert.AreEqual(2, asks[3].ID); var a5 = new ExchangeOrder(5, 1, OrderSide.Sell, OrderType.Limit, 10.5m, 2); asks = asks.Add(a5); Assert.AreEqual(3, asks[0].ID); Assert.AreEqual(1, asks[1].ID); Assert.AreEqual(4, asks[2].ID); Assert.AreEqual(5, asks[3].ID); Assert.AreEqual(2, asks[4].ID); }
public void TestMockOrderBook() { var orderBook = new MockOrderBook(1); var b1 = new ExchangeOrder(1, 1, OrderSide.Buy, OrderType.Limit, 10, 10); orderBook = orderBook.PlaceOrder(b1); Assert.AreEqual(1, orderBook.Orders.Count); Assert.AreEqual(1, orderBook.Bids.Count); Assert.AreEqual(0, orderBook.Asks.Count); var b2 = new ExchangeOrder(2, 1, OrderSide.Buy, OrderType.Limit, 11, 10); orderBook = orderBook.PlaceOrder(b2); Assert.AreEqual(2, orderBook.Orders.Count); Assert.AreEqual(2, orderBook.Bids.Count); Assert.AreEqual(0, orderBook.Asks.Count); var a1 = new ExchangeOrder(3, 1, OrderSide.Sell, OrderType.Limit, 10.5m, 5); orderBook = orderBook.PlaceOrder(a1); //all orders, even completed, should be contained in the dictionary Assert.AreEqual(3, orderBook.Orders.Count); //best bid was only half filled Assert.AreEqual(2, orderBook.Bids.Count); //the sell order was fully filled. asks should be empty Assert.AreEqual(0, orderBook.Asks.Count); Assert.AreEqual(5, orderBook.Bids[0].RemainingVolume); //check the order dictionary is update Assert.AreEqual(5, orderBook.Orders[2].RemainingVolume); Assert.AreEqual(0, orderBook.Orders[3].RemainingVolume); var a2 = new ExchangeOrder(4, 1, OrderSide.Sell, OrderType.Limit, 10, 7); orderBook = orderBook.PlaceOrder(a2); Assert.AreEqual(4, orderBook.Orders.Count); //best bid was fully filled Assert.AreEqual(1, orderBook.Bids.Count); //the ask was fully filled Assert.AreEqual(0, orderBook.Asks.Count); //the next best bid was partially filled Assert.AreEqual(8, orderBook.Bids[0].RemainingVolume); Assert.AreEqual(0, orderBook.Orders[2].RemainingVolume); Assert.AreEqual(0, orderBook.Orders[4].RemainingVolume); Assert.AreEqual(8, orderBook.Orders[1].RemainingVolume); var b3 = new ExchangeOrder(5, 1, OrderSide.Buy, OrderType.Limit, 9, 10); orderBook = orderBook.PlaceOrder(b3); var a3 = new ExchangeOrder(6, 1, OrderSide.Sell, OrderType.Limit, 10, 10); orderBook = orderBook.PlaceOrder(a3); Assert.AreEqual(6, orderBook.Orders.Count); //the best bid was totally filled Assert.AreEqual(1, orderBook.Bids.Count); Assert.AreEqual(0, orderBook.Orders[1].RemainingVolume); Assert.AreEqual(1, orderBook.Asks.Count); Assert.AreEqual(2, orderBook.Orders[6].RemainingVolume); //the second bid was not touched because too low Assert.AreEqual(10, orderBook.Bids[0].RemainingVolume); }
private static BaseOrder ImportOrder(string importString) { string[] orderData = importString.Split(new char[] { ',' }, StringSplitOptions.None); BaseOrder newOrder = CreateOrder(orderData[1], !string.IsNullOrWhiteSpace(orderData[3])); Currency coinParse; decimal amountParse; Location locationParse; // Parse the order instant newOrder.OrderInstant = DateTime.Parse(orderData[0]); // Parse the trading location if (!Enum.TryParse <Location>(orderData[7], out locationParse)) { throw new OrderImportDataException(); } newOrder.Location = locationParse; // Parse the trade currency type if (!Enum.TryParse <Currency>(orderData[4], out coinParse)) { throw new OrderImportDataException(); } newOrder.TradeCurrency = coinParse; // Parse the trade amount (used for deposits/withdrawals as well) if (!decimal.TryParse(orderData[5], out amountParse)) { throw new OrderImportDataException(); } newOrder.TradeAmount = amountParse; // Extra parsing for buy/sell orders if (newOrder is ExchangeOrder) { ExchangeOrder newExchangeOrder = (ExchangeOrder)newOrder; // Parse the base currency type if (!Enum.TryParse <Currency>(orderData[2], out coinParse)) { throw new OrderImportDataException(); } newExchangeOrder.BaseCurrency = coinParse; // Parse the base amount if (!decimal.TryParse(orderData[3], out amountParse)) { throw new OrderImportDataException(); } newExchangeOrder.BaseAmount = amountParse; // Parse the fee amount (stored in the base currency) if (!decimal.TryParse(orderData[6], out amountParse)) { throw new OrderImportDataException(); } newExchangeOrder.BaseFee = amountParse; } return(newOrder); }
public async Task <ExchangeOrder> Send(Order order, ExchangeConfig config) { ExchangeOrder exchangeOrder = null; PairConfig pairConfig = config.Pairs.FirstOrDefault(x => x.Symbol.Equals(order.Symbol)); if (order.UpdateRequired) { using (BinanceClient client = new BinanceClient(new BinanceClientOptions() { ApiCredentials = new ApiCredentials(config.ApiKey, config.ApiSecret) })) { if (order.OrderStatusCode == OrderStatusCode.PENDING) { (bool success, string error, BinancePlacedOrder order)result;; if (order.OrderTypeCode == OrderTypeCode.MKT.Code) { if (pairConfig.IsTestMode) { WebCallResult <BinancePlacedOrder> orderResult = await client.PlaceTestOrderAsync(order.Symbol, (OrderSide)order.OrderSideCode, OrderType.Market, order.Amount.Value, null, order.Id.ToString(), null, TimeInForce.GoodTillCancel); result = (orderResult.Success, orderResult.Error.Message, orderResult.Data); } else { WebCallResult <BinancePlacedOrder> orderResult = await client.PlaceOrderAsync(order.Symbol, (OrderSide)order.OrderSideCode, OrderType.Market, order.Amount.Value, null, order.Id.ToString(), null, TimeInForce.GoodTillCancel); result = (orderResult.Success, orderResult.Error.Message, orderResult.Data); } } else if (order.OrderTypeCode == OrderTypeCode.LMT.Code) { if (pairConfig.IsTestMode) { WebCallResult <BinancePlacedOrder> orderResult = await client.PlaceTestOrderAsync(order.Symbol, (OrderSide)order.OrderSideCode, OrderType.Limit, order.Amount.Value, null, order.Id.ToString(), order.Price, TimeInForce.GoodTillCancel); result = (orderResult.Success, orderResult.Error.Message, orderResult.Data); } else { WebCallResult <BinancePlacedOrder> orderResult = await client.PlaceOrderAsync(order.Symbol, (OrderSide)order.OrderSideCode, OrderType.Limit, order.Amount.Value, null, order.Id.ToString(), order.Price, TimeInForce.GoodTillCancel); result = (orderResult.Success, orderResult.Error.Message, orderResult.Data); } } else if (order.OrderTypeCode == OrderTypeCode.LST.Code) { if (pairConfig.IsTestMode) { // OCO Order can't be used in test mode WebCallResult <BinancePlacedOrder> orderResult = await client.PlaceTestOrderAsync(order.Symbol, (OrderSide)order.OrderSideCode, OrderType.Limit, order.Amount.Value, null, order.Id.ToString(), order.Price, TimeInForce.GoodTillCancel); result = (orderResult.Success, orderResult.Error.Message, orderResult.Data); } else { if (order.OrderSideCode == OrderSideCode.BUY.Code) { // For now let's use limit standard order WebCallResult <BinancePlacedOrder> orderResult = await client.PlaceOrderAsync(order.Symbol, OrderSide.Buy, OrderType.Limit, order.Amount.Value, null, order.Id.ToString(), order.Price, TimeInForce.GoodTillCancel); result = (orderResult.Success, orderResult.Error.Message, orderResult.Data); } else { WebCallResult <BinanceOrderList> orderResult = await client.PlaceOCOOrderAsync(order.Symbol, OrderSide.Sell, order.Amount.Value, order.Price.Value, order.StopLoss.Value); result = (orderResult.Success, orderResult.Error.Message, orderResult.Data.OrderReports.First()); } } } else { throw new Exception($"{order.Id} selected order type isn't supported"); } if (!result.success) { throw new Exception(result.error); } exchangeOrder = result.order.ToOrder(); _logger.LogInformation($"{Exchange.Description} - Order {order.Id} has been processed with status: {result.order.Status}"); } else if (order.OrderStatusCode == OrderStatusCode.CANCELED) { WebCallResult <BinanceCanceledOrder> cancelResult = await client.CancelOrderAsync(order.Symbol, order.ExchangeOrderId); if (!cancelResult.Success) { throw new Exception(cancelResult.Error.Message); } exchangeOrder = cancelResult.Data.ToOrder(); _logger.LogInformation($"{Exchange.Description} - Order {order.Id} has been processed with status: {cancelResult.Data.Status}"); } else { throw new Exception($"{Exchange.Description} - Can't update update order {order.Id}: wrong status"); } } } return(exchangeOrder); }