private OrderBook BuildOrderBook(ProExchange.JSON.API.Notifications.OrderBook response) { var orderbook = new OrderBook { Version = response.Version }; foreach (var data in response.List) { orderbook.Sides[(int)data.Side.SimplifyOrderSide()].Add(data.Price, new OrderBookDetail(data.Price) { Quantity = data.Size }); } return orderbook; }
public void Update(ProExchange.JSON.API.Notifications.OrderBook response) { lock (this) { OrderBook orderbook; var isNew = orderbooks.TryGetValue(response.Symbol, out orderbook); switch (response.Type) { case OrderBookType.FULL: orderbook = new OrderBook(); orderbooks[response.Symbol] = orderbook; break; case OrderBookType.INCREMENTAL: var next = NextVersion(orderbook); if (next != response.Version) RequestFullOrderBook(response.Symbol); break; default: return; } foreach (var data in response.List) { var side = orderbook.Sides[(int)data.Side.SimplifyOrderSide()]; OrderBookDetail detail; if (!side.TryGetValue(data.Price, out detail)) { detail = new OrderBookDetail(data.Price); side.Add(detail.Price, detail); } detail.Quantity += data.Size; if (detail.Quantity == 0) side.Remove(detail.Price); } orderbook.Version = response.Version; } }
internal Instrument(SmartQuant.Instruments.Instrument instrument) { this.instrument = instrument; this.book = new OrderBook(instrument.OrderBook); this.AltIDGroups = new AltIDGroupList(this); }
/// <summary> /// Update the logger - you can call this periodically if you don't want to call Start to run the logger in a background thread. /// </summary> public void Update() { ExchangeTrade[] newTrades; HashSet <decimal> tmpTradeIds; try { if (Symbol == "*") { // get all symbols Tickers = API.GetTickers().ToArray(); tickerWriter.Write(Tickers.Count); foreach (KeyValuePair <string, ExchangeTicker> ticker in Tickers) { tickerWriter.Write(ticker.Key); ticker.Value.ToBinary(tickerWriter); } } else { // make API calls first, if they fail we will try again later Tickers = new KeyValuePair <string, ExchangeTicker>[1] { new KeyValuePair <string, ExchangeTicker>(Symbol, API.GetTicker(Symbol)) }; OrderBook = API.GetOrderBook(Symbol); Trades = API.GetRecentTrades(Symbol).OrderBy(t => t.Timestamp).ToArray(); // all API calls succeeded, we can write to files // write system date / time sysTimeWriter.Write(DateTime.UtcNow.Ticks); // write ticker Tickers.First().Value.ToBinary(tickerWriter); // write order book OrderBook.ToBinary(bookWriter); // new trades only newTrades = Trades.Where(t => !tradeIds.Contains(t.Id)).ToArray(); // write new trades tradeWriter.Write(newTrades.Length); foreach (ExchangeTrade trade in newTrades) { trade.ToBinary(tradeWriter); } // track trade ids for the latest set of trades foreach (ExchangeTrade trade in Trades) { tradeIds2.Add(trade.Id); } tmpTradeIds = tradeIds; tradeIds = tradeIds2; tradeIds2 = tmpTradeIds; tradeIds2.Clear(); } DataAvailable?.Invoke(this); } catch (Exception ex) { Error?.Invoke(this, ex); } }
private void AssertOrderBookUpdate(SymbolViewModel symbolViewModel, OrderBook orderBook, Model.Preferences preferences) { // Assert - Last Update Id Assert.AreEqual(symbolViewModel.OrderBook.LastUpdateId, orderBook.LastUpdateId); // Assert - TopAsks Assert.AreEqual(symbolViewModel.OrderBook.TopAsks.Count, preferences.OrderBookDisplayCount); var topAsks = orderBook.Asks.Take(preferences.OrderBookDisplayCount).Reverse().ToList(); for (int i = 0; i < preferences.OrderBookDisplayCount; i++) { Assert.AreEqual(symbolViewModel.OrderBook.TopAsks[i].Price, topAsks[i].Price); Assert.AreEqual(symbolViewModel.OrderBook.TopAsks[i].Quantity, topAsks[i].Quantity); } // Assert - TopBids Assert.AreEqual(symbolViewModel.OrderBook.TopBids.Count, preferences.OrderBookDisplayCount); var topBids = orderBook.Bids.Take(preferences.OrderBookDisplayCount).ToList(); for (int i = 0; i < preferences.OrderBookDisplayCount; i++) { Assert.AreEqual(symbolViewModel.OrderBook.TopBids[i].Price, topBids[i].Price); Assert.AreEqual(symbolViewModel.OrderBook.TopBids[i].Quantity, topBids[i].Quantity); } // Assert - ChartAsks Assert.AreEqual(symbolViewModel.OrderBook.ChartAsks.Count, preferences.OrderBookChartDisplayCount); var chartAsks = orderBook.Asks.Take(preferences.OrderBookChartDisplayCount).ToList(); for (int i = 0; i < preferences.OrderBookChartDisplayCount; i++) { Assert.AreEqual(symbolViewModel.OrderBook.ChartAsks[i].Price, chartAsks[i].Price); Assert.AreEqual(symbolViewModel.OrderBook.ChartAsks[i].Quantity, chartAsks[i].Quantity); } // Assert ChartBids Assert.AreEqual(symbolViewModel.OrderBook.ChartBids.Count, preferences.OrderBookChartDisplayCount); var chartBids = orderBook.Bids.Take(preferences.OrderBookChartDisplayCount).Reverse <OrderBookPriceLevel>().ToList(); for (int i = 0; i < preferences.OrderBookChartDisplayCount; i++) { Assert.AreEqual(symbolViewModel.OrderBook.ChartBids[i].Price, chartBids[i].Price); Assert.AreEqual(symbolViewModel.OrderBook.ChartBids[i].Quantity, chartBids[i].Quantity); } // Assert ChartAggregateAsks Assert.AreEqual(symbolViewModel.OrderBook.ChartAggregatedAsks.Count, preferences.OrderBookChartDisplayCount); var runningTotal = 0m; for (int i = 0; i < preferences.OrderBookChartDisplayCount; i++) { if (i == 0) { runningTotal = chartAsks[i].Quantity; } else { runningTotal = chartAsks[i].Quantity + runningTotal; } Assert.AreEqual(symbolViewModel.OrderBook.ChartAggregatedAsks[i].Price, chartAsks[i].Price); Assert.AreEqual(symbolViewModel.OrderBook.ChartAggregatedAsks[i].Quantity, runningTotal); } // Assert ChartAggregateBids Assert.AreEqual(symbolViewModel.OrderBook.ChartAggregatedBids.Count, preferences.OrderBookChartDisplayCount); var aggregatedBidsList = orderBook.Bids.Take(preferences.OrderBookChartDisplayCount).Select(p => new OrderBookPriceLevel { Price = p.Price, Quantity = p.Quantity }).ToList(); for (int i = 0; i < preferences.OrderBookChartDisplayCount; i++) { if (i > 0) { aggregatedBidsList[i].Quantity = aggregatedBidsList[i].Quantity + aggregatedBidsList[i - 1].Quantity; } } var reversedAggregateBidsList = aggregatedBidsList.Reverse <OrderBookPriceLevel>().ToList(); for (int i = 0; i < preferences.OrderBookChartDisplayCount; i++) { Assert.AreEqual(symbolViewModel.OrderBook.ChartAggregatedBids[i].Price, reversedAggregateBidsList[i].Price); Assert.AreEqual(symbolViewModel.OrderBook.ChartAggregatedBids[i].Quantity, reversedAggregateBidsList[i].Quantity); } }
private async Task UpdateExecution() { if (this.executionCycle != null) { this.updatingExecution = true; int selectedIndex = this.CurrencyCyclesListView.SelectedIndex; CurrencyCycleListViewItem item = executionCycle.Value; ArbitragePath arbitragePath = item.ArbitragePath; Ticker[,] tickers = this.tickers; decimal sourceQuantity = 0.1m; List <ExecutionListViewItem> items = new List <ExecutionListViewItem>(); for (int i = 1; i < arbitragePath.Currencies.Count; i++) { string sourceCurrency = arbitragePath.Currencies[i - 1]; string destinationCurrency = arbitragePath.Currencies[i]; int sourceCurrencyIndex = item.Exchange.Currencies.IndexOf(sourceCurrency); int destinationCurrencyIndex = item.Exchange.Currencies.IndexOf(destinationCurrency); TradeType type; (string, string)tradingPair; switch (item.Exchange.TradingPairs[item.Exchange.Currencies.IndexOf(destinationCurrency), item.Exchange.Currencies.IndexOf(sourceCurrency)]) { case TradingPairType.Buy: type = TradeType.Buy; tradingPair = (destinationCurrency, sourceCurrency); break; case TradingPairType.Sell: type = TradeType.Sell; tradingPair = (sourceCurrency, destinationCurrency); break; case TradingPairType.Invalid: default: throw new InvalidOperationException(); } Ticker ticker = tickers[item.Exchange.Currencies.IndexOf(tradingPair.Item1), item.Exchange.Currencies.IndexOf(tradingPair.Item2)]; OrderBook orderBook = await item.Exchange.GetOrderBook(tradingPair); decimal destinationQuantity; OrderBookEntry buyOrder = orderBook.Bids[0]; OrderBookEntry sellOrder = orderBook.Asks[0]; if (type == TradeType.Buy) { // destinationQuantity = sourceQuantity / ticker.LowestAskPrice * (1m - item.Exchange.FeePercentage * 0.01m); // sellOrder.Price = ticker.LowestAskPrice; (destinationQuantity, sellOrder) = orderBook.ComputeBuyQuantity(sourceQuantity).Value; ticker.LowestAskPrice = sellOrder.Price; } else { // destinationQuantity = sourceQuantity * ticker.HighestBidPrice * (1m - item.Exchange.FeePercentage * 0.01m); // buyOrder.Price = ticker.HighestBidPrice; (destinationQuantity, buyOrder) = orderBook.ComputeSellCost(sourceQuantity).Value; ticker.HighestBidPrice = buyOrder.Price; } items.Add(new ExecutionListViewItem { Exchange = item.Exchange, TradingPair = tradingPair, Type = type, Price = type == TradeType.Buy ? ticker.LowestAskPrice : ticker.HighestBidPrice, Ticker = ticker, OrderBook = orderBook, BuyOrder = buyOrder, SellOrder = sellOrder, SourceQuantity = sourceQuantity, DestinationQuantity = destinationQuantity }); sourceQuantity = destinationQuantity; } if (this.CurrencyCyclesListView.SelectedIndex == selectedIndex) { await this.Dispatcher.InvokeAsync(() => { this.ExecutionListView.Items.Clear(); items.ForEach(x => this.ExecutionListView.Items.Add(x)); }); } this.updatingExecution = false; } else { this.ExecutionListView.Items.Clear(); } }
private static void SortBids(OrderBook orderBook) { orderBook.Bids = orderBook.Bids.OrderByDescending(it => it.Price).ToList(); }
private VolSurface GetVolSurface(SortedDictionary<DateTime, RiskFreeRate> riskFreeRates, OrderBook underlyingOrderBook, List<OptionMarketData> optionsMarketData) { double businessDaysInTheYear = 252; VolSurface volSurface = new VolSurface(); double spot = underlyingOrderBook.GetPriceMid(); foreach (OptionMarketData option in optionsMarketData) { RiskFreeRate riskFreeRate = null; riskFreeRates.TryGetValue(option.OptionInfo.ExpiryDate, out riskFreeRate); double timeToMaturity = riskFreeRate.BusinessDays / businessDaysInTheYear; double bid = (option.OrderBook.Bid != null) ? option.OrderBook.Bid.Value : 0.00; double bidSize = (option.OrderBook.BidSize != null) ? option.OrderBook.BidSize.Value : 0.00; ; double ask = (option.OrderBook.Ask != null) ? option.OrderBook.Ask.Value : 0.00; ; double askSize = (option.OrderBook.AskSize != null) ? option.OrderBook.AskSize.Value : 0.00; ; BlackScholes bs = new BlackScholes(); double bidImpliedVolatility = 0.00; double askImpliedVolatility = 0.00; if (bid > 0.00 && bidSize > 0.00) bidImpliedVolatility = bs.GetImpliedVolatility(option.OptionInfo.Type, bid, spot, option.OptionInfo.Strike, riskFreeRate.Rate, timeToMaturity); if (ask > 0.00 && askSize > 0.00) askImpliedVolatility = bs.GetImpliedVolatility(option.OptionInfo.Type, ask, spot, option.OptionInfo.Strike, riskFreeRate.Rate, timeToMaturity); if (!(bidImpliedVolatility > 0.0000)) bidImpliedVolatility = 0.00; if (!(askImpliedVolatility > 0.0000)) askImpliedVolatility = 0.00; VolQuote volQuote = new VolQuote(bidSize, askSize, bidImpliedVolatility, askImpliedVolatility); volSurface.Update(option.OptionInfo.ExpiryDate, option.OptionInfo.Strike, option.OptionInfo.Type, volQuote); } return volSurface; }
/// <summary> /// Удаляет запись из стакана. /// </summary> /// <param name="replId">replId записи из plaza2 для удаления.</param> /// <param name="p2Ob">Мэп replId на OrderBookItem.</param> /// <param name="ob">Объект стакана.</param> private void RemoveOrderBookItem(long replId, Dictionary <long, OrderBookItem> p2Ob, OrderBook ob) { ob.Items.Remove(p2Ob[replId]); p2Ob.Remove(replId); }
/// <summary> /// Вставляет с сортировкой запись в стакан. /// </summary> /// <param name="replId">replId записи из plaza2.</param> /// <param name="p2Ob">Мэп replId на OrderBookItem.</param> /// <param name="ob">Объект стакана.</param> /// <param name="obi">Запись в стакане.</param> private void InsertOrderBookItemSorted(long replId, Dictionary <long, OrderBookItem> p2Ob, OrderBook ob, OrderBookItem obi) { p2Ob.Add(replId, obi); var indexToInsert = 0; if (ob.Items.Count > 0) { for (indexToInsert = 0; indexToInsert < ob.Items.Count; indexToInsert++) { if (obi.Price > ob.Items[indexToInsert].Price) { break; } } } ob.Items.Insert(indexToInsert, obi); }
private void ProcessOrderBookUpdates() { LogManager.BreakScope(); const int numberOfCyclesToFireEvent = 10; // каждые 10 циклов нижлежащего while мы райзим эвент об обновлении стаканов var cyclesCount = 0; while (!cancellationTokenSource.Token.WaitHandle.WaitOne(10)) { if (++cyclesCount > numberOfCyclesToFireEvent) { cyclesCount = 0; FireUpdatedOrderBooks(); } CGateOrderBookUpdate record; while (orderBooksUdatesQueue.TryDequeue(out record)) { // вызываем событие обновления стаканов если в потоке пришло сообщение об окончании блока обновлений if (record.Type == CGateOrderBookUpdateType.StreamDataEnd) { FireUpdatedOrderBooks(); continue; } if (record.Type == CGateOrderBookUpdateType.ClearTable) { ClearOrderBooks(record); FireUpdatedOrderBooks(); continue; } //revisionsDictionary[record.ReplId] = record.ReplRev; RememberUpdatedInstrument(record.IsinId); int obItemIsinId; var instrumentChanged = false; if (!obRowsOnInstruments.TryGetValue(record.ReplId, out obItemIsinId)) { obRowsOnInstruments.Add(record.ReplId, record.IsinId); } else if (record.IsinId != obItemIsinId) { RememberUpdatedInstrument(obItemIsinId); obRowsOnInstruments[record.ReplId] = record.IsinId; instrumentChanged = true; } Dictionary <long, OrderBookItem> p2ob; OrderBook ob; if (!plaza2OrderBooks.TryGetValue(record.IsinId, out p2ob)) { p2ob = new Dictionary <long, OrderBookItem>(); plaza2OrderBooks.Add(record.IsinId, p2ob); } if (!orderBooks.TryGetValue(record.IsinId, out ob)) { var instrument = instrumentResolver.GetInstrument(record.InstrumentCode); ob = new OrderBook { Instrument = instrument.Instrument }; orderBooks.Add(record.IsinId, ob); } // если произошла смена инструмента у записи, то её нужно удалить из того стакана, в котором она была раньше if (instrumentChanged) { Dictionary <long, OrderBookItem> p2obToDeleteRecord; OrderBook obToDeleteRecord; if (plaza2OrderBooks.TryGetValue(obItemIsinId, out p2obToDeleteRecord) && orderBooks.TryGetValue(obItemIsinId, out obToDeleteRecord)) { if (p2obToDeleteRecord.ContainsKey(record.ReplId)) { obToDeleteRecord.Items.Remove(p2obToDeleteRecord[record.ReplId]); p2obToDeleteRecord.Remove(record.ReplId); } } } OrderBookItem obi; if (!p2ob.TryGetValue(record.ReplId, out obi) && record.Price != 0m && record.Quantity != 0 && record.ReplAct == 0) { obi = new OrderBookItem { Price = record.Price, Quantity = record.Quantity, Operation = record.Operation }; // ишем место, куда приткнуть новую котировку InsertOrderBookItemSorted(record.ReplId, p2ob, ob, obi); } else if (obi != null) { if (record.Price == 0 || record.Quantity == 0 || record.ReplAct > 0) { RemoveOrderBookItem(record.ReplId, p2ob, ob); } else { var needSort = obi.Price != record.Price || obi.Operation != record.Operation; obi.Price = record.Price; obi.Operation = record.Operation; obi.Quantity = record.Quantity; if (needSort) { RemoveOrderBookItem(record.ReplId, p2ob, ob); InsertOrderBookItemSorted(record.ReplId, p2ob, ob, obi); } } } } } }
private async Task CallCommand() { string selectedCommand = listBoxCommands.SelectedItem.ToString(); switch (selectedCommand) { case "Получить исторические данные": try { AppendText2TextBox(textBoxLogsWindow, "Подписываемся на получение исторических данных..." + Environment.NewLine); _quik.Candles.Subscribe(tool.ClassCode, tool.SecurityCode, CandleInterval.M15).Wait(); AppendText2TextBox(textBoxLogsWindow, "Проверяем состояние подписки..." + Environment.NewLine); isSubscribedToolCandles = _quik.Candles.IsSubscribed(tool.ClassCode, tool.SecurityCode, CandleInterval.M15).Result; if (isSubscribedToolCandles) { AppendText2TextBox(textBoxLogsWindow, "Получаем исторические данные..." + Environment.NewLine); toolCandles = _quik.Candles.GetAllCandles(tool.ClassCode, tool.SecurityCode, CandleInterval.M15).Result; AppendText2TextBox(textBoxLogsWindow, "Выводим исторические данные в таблицу..." + Environment.NewLine); toolCandlesTable = new FormOutputTable(toolCandles); toolCandlesTable.Show(); _quik.Candles.NewCandle += OnNewCandleDo; } else { AppendText2TextBox(textBoxLogsWindow, "Неудачная попытка подписки на исторические данные." + Environment.NewLine); } } catch { AppendText2TextBox(textBoxLogsWindow, "Ошибка получения исторических данных." + Environment.NewLine); } break; case "Выставить лимитрированную заявку (без сделки)": try { decimal priceInOrder = Math.Round(tool.LastPrice - tool.LastPrice / 20, tool.PriceAccuracy); AppendText2TextBox(textBoxLogsWindow, "Выставляем заявку на покупку, по цене:" + priceInOrder + " ..." + Environment.NewLine); order = await _quik.Orders.SendLimitOrder(tool.ClassCode, tool.SecurityCode, tool.AccountID, Operation.Buy, priceInOrder, 1).ConfigureAwait(false); if (order.OrderNum > 0) { AppendText2TextBox(textBoxLogsWindow, "Заявка выставлена. ID транзакции - " + order.TransID + Environment.NewLine); AppendText2TextBox(textBoxLogsWindow, "Заявка выставлена. Номер заявки - " + order.OrderNum + Environment.NewLine); Text2TextBox(textBoxOrderNumber, order.OrderNum.ToString()); } else { AppendText2TextBox(textBoxLogsWindow, "Неудачная попытка размещения заявки. Error: " + order.RejectReason + Environment.NewLine); } } catch (Exception er) { textBoxLogsWindow.AppendText("Ошибка процедуры размещения заявки. Error: " + er.Message + Environment.NewLine); } break; case "Выставить лимитрированную заявку (c выполнением!!!)": try { decimal priceInOrder = Math.Round(tool.LastPrice + tool.Step * 5, tool.PriceAccuracy); AppendText2TextBox(textBoxLogsWindow, "Выставляем заявку на покупку, по цене:" + priceInOrder + " ..." + Environment.NewLine); long transactionID = (await _quik.Orders.SendLimitOrder(tool.ClassCode, tool.SecurityCode, tool.AccountID, Operation.Buy, priceInOrder, 1).ConfigureAwait(false)).TransID; if (transactionID > 0) { AppendText2TextBox(textBoxLogsWindow, "Заявка выставлена. ID транзакции - " + transactionID + Environment.NewLine); Thread.Sleep(500); try { listOrders = _quik.Orders.GetOrders().Result; foreach (Order _order in listOrders) { if (_order.TransID == transactionID && _order.ClassCode == tool.ClassCode && _order.SecCode == tool.SecurityCode) { AppendText2TextBox(textBoxLogsWindow, "Заявка выставлена. Номер заявки - " + _order.OrderNum + Environment.NewLine); Text2TextBox(textBoxOrderNumber, _order.OrderNum.ToString()); order = _order; } else { Text2TextBox(textBoxOrderNumber, "---"); } } } catch { AppendText2TextBox(textBoxLogsWindow, "Ошибка получения номера заявки." + Environment.NewLine); } } else { AppendText2TextBox(textBoxLogsWindow, "Неудачная попытка выставления заявки." + Environment.NewLine); } } catch { AppendText2TextBox(textBoxLogsWindow, "Ошибка выставления заявки." + Environment.NewLine); } break; case "Выставить рыночную заявку (c выполнением!!!)": try { decimal priceInOrder = Math.Round(tool.LastPrice + tool.Step * 5, tool.PriceAccuracy); AppendText2TextBox(textBoxLogsWindow, "Выставляем рыночную заявку на покупку..." + Environment.NewLine); long transactionID = (await _quik.Orders.SendMarketOrder(tool.ClassCode, tool.SecurityCode, tool.AccountID, Operation.Buy, 1).ConfigureAwait(false)).TransID; if (transactionID > 0) { AppendText2TextBox(textBoxLogsWindow, "Заявка выставлена. ID транзакции - " + transactionID + Environment.NewLine); Thread.Sleep(500); try { listOrders = _quik.Orders.GetOrders().Result; foreach (Order _order in listOrders) { if (_order.TransID == transactionID && _order.ClassCode == tool.ClassCode && _order.SecCode == tool.SecurityCode) { textBoxLogsWindow.AppendText("Заявка выставлена. Номер заявки - " + _order.OrderNum + Environment.NewLine); Text2TextBox(textBoxOrderNumber, _order.OrderNum.ToString()); order = _order; } else { Text2TextBox(textBoxOrderNumber, "---"); } } } catch { AppendText2TextBox(textBoxLogsWindow, "Ошибка получения номера заявки." + Environment.NewLine); } } else { AppendText2TextBox(textBoxLogsWindow, "Неудачная попытка выставления заявки." + Environment.NewLine); } } catch { AppendText2TextBox(textBoxLogsWindow, "Ошибка выставления заявки." + Environment.NewLine); } break; case "Удалить активную заявку": try { if (order != null && order.OrderNum > 0) { AppendText2TextBox(textBoxLogsWindow, "Удаляем заявку на покупку с номером - " + order.OrderNum + " ..." + Environment.NewLine); } long x = _quik.Orders.KillOrder(order).Result; AppendText2TextBox(textBoxLogsWindow, "Результат - " + x + " ..." + Environment.NewLine); Text2TextBox(textBoxOrderNumber, ""); } catch { AppendText2TextBox(textBoxLogsWindow, "Ошибка удаления заявки." + Environment.NewLine); } break; case "Получить информацию по бумаге": try { AppendText2TextBox(textBoxLogsWindow, "Получаем таблицу информации..." + Environment.NewLine); listSecurityInfo = new List <SecurityInfo> { _quik.Class.GetSecurityInfo(tool.ClassCode, tool.SecurityCode).Result }; if (listSecurityInfo.Count > 0) { AppendText2TextBox(textBoxLogsWindow, "Выводим данные в таблицу..." + Environment.NewLine); toolCandlesTable = new FormOutputTable(listSecurityInfo); toolCandlesTable.Show(); } else { AppendText2TextBox(textBoxLogsWindow, "Информация по бумаге '" + tool.Name + "' отсутствует." + Environment.NewLine); } } catch { AppendText2TextBox(textBoxLogsWindow, "Ошибка получения лимитов." + Environment.NewLine); } break; case "Получить таблицу лимитов по бумаге": try { AppendText2TextBox(textBoxLogsWindow, "Получаем таблицу лимитов..." + Environment.NewLine); listDepoLimits = _quik.Trading.GetDepoLimits(tool.SecurityCode).Result; if (listDepoLimits.Count > 0) { AppendText2TextBox(textBoxLogsWindow, "Выводим данные лимитов в таблицу..." + Environment.NewLine); toolCandlesTable = new FormOutputTable(listDepoLimits); toolCandlesTable.Show(); } else { AppendText2TextBox(textBoxLogsWindow, "Бумага '" + tool.Name + "' в таблице лимитов отсутствует." + Environment.NewLine); } } catch { AppendText2TextBox(textBoxLogsWindow, "Ошибка получения лимитов." + Environment.NewLine); } break; case "Получить таблицу лимитов по всем бумагам": try { AppendText2TextBox(textBoxLogsWindow, "Получаем таблицу лимитов..." + Environment.NewLine); listDepoLimits = _quik.Trading.GetDepoLimits().Result; if (listDepoLimits.Count > 0) { AppendText2TextBox(textBoxLogsWindow, "Выводим данные лимитов в таблицу..." + Environment.NewLine); toolCandlesTable = new FormOutputTable(listDepoLimits); toolCandlesTable.Show(); } } catch { AppendText2TextBox(textBoxLogsWindow, "Ошибка получения лимитов." + Environment.NewLine); } break; case "Получить таблицу по фьючерсным лимитам": try { AppendText2TextBox(textBoxLogsWindow, "Получаем таблицу фьючерсных лимитов..." + Environment.NewLine); futLimit = _quik.Trading.GetFuturesLimit(tool.FirmID, tool.AccountID, 0, "SUR").Result; if (futLimit != null) { listFuturesLimits = new List <FuturesLimits> { futLimit }; AppendText2TextBox(textBoxLogsWindow, "Выводим данные лимитов в таблицу..." + Environment.NewLine); toolCandlesTable = new FormOutputTable(listFuturesLimits); toolCandlesTable.Show(); } else { Console.WriteLine("futuresLimit = null"); } } catch { AppendText2TextBox(textBoxLogsWindow, "Ошибка получения лимитов." + Environment.NewLine); } break; case "Получить таблицу заявок": try { AppendText2TextBox(textBoxLogsWindow, "Получаем таблицу заявок..." + Environment.NewLine); listOrders = _quik.Orders.GetOrders().Result; if (listOrders.Count > 0) { AppendText2TextBox(textBoxLogsWindow, "Выводим данные о заявках в таблицу..." + Environment.NewLine); toolCandlesTable = new FormOutputTable(listOrders); toolCandlesTable.Show(); } } catch { AppendText2TextBox(textBoxLogsWindow, "Ошибка получения заявок." + Environment.NewLine); } break; case "Получить таблицу сделок": try { AppendText2TextBox(textBoxLogsWindow, "Получаем таблицу сделок..." + Environment.NewLine); listTrades = _quik.Trading.GetTrades().Result; if (listTrades.Count > 0) { AppendText2TextBox(textBoxLogsWindow, "Выводим данные о сделках в таблицу..." + Environment.NewLine); toolCandlesTable = new FormOutputTable(listTrades); toolCandlesTable.Show(); } } catch { AppendText2TextBox(textBoxLogsWindow, "Ошибка получения сделок." + Environment.NewLine); } break; case "Получить таблицу `Клиентский портфель`": try { AppendText2TextBox(textBoxLogsWindow, "Получаем таблицу `Клиентский портфель`..." + Environment.NewLine); listPortfolio = new List <PortfolioInfoEx>(); if (classCode == "SPBFUT") { listPortfolio.Add(_quik.Trading.GetPortfolioInfoEx(tool.FirmID, tool.AccountID, 0).Result); } else { listPortfolio.Add(_quik.Trading.GetPortfolioInfoEx(tool.FirmID, clientCode, 2).Result); } if (listPortfolio.Count > 0) { AppendText2TextBox(textBoxLogsWindow, "Выводим данные о портфеле в таблицу..." + Environment.NewLine); toolCandlesTable = new FormOutputTable(listPortfolio); toolCandlesTable.Show(); } else { AppendText2TextBox(textBoxLogsWindow, "В таблице `Клиентский портфель` отсутствуют записи." + Environment.NewLine); } } catch { AppendText2TextBox(textBoxLogsWindow, "Ошибка получения клиентского портфеля." + Environment.NewLine); } break; case "Получить таблицы денежных лимитов": try { AppendText2TextBox(textBoxLogsWindow, "Получаем таблицу денежных лимитов..." + Environment.NewLine); listMoneyLimits = new List <MoneyLimit> { _quik.Trading.GetMoney(clientCode, tool.FirmID, "EQTV", "SUR").Result }; if (listMoneyLimits.Count > 0) { AppendText2TextBox(textBoxLogsWindow, "Выводим данные о денежных лимитах в таблицу..." + Environment.NewLine); toolCandlesTable = new FormOutputTable(listMoneyLimits); toolCandlesTable.Show(); } AppendText2TextBox(textBoxLogsWindow, "Получаем расширение таблицы денежных лимитов..." + Environment.NewLine); listMoneyLimitsEx = new List <MoneyLimitEx> { _quik.Trading.GetMoneyEx(tool.FirmID, clientCode, "EQTV", "SUR", 2).Result }; if (listMoneyLimitsEx.Count > 0) { AppendText2TextBox(textBoxLogsWindow, "Выводим данные о денежных лимитах в таблицу..." + Environment.NewLine); toolCandlesTable = new FormOutputTable(listMoneyLimitsEx); toolCandlesTable.Show(); } } catch { AppendText2TextBox(textBoxLogsWindow, "Ошибка получения денежных лимитов." + Environment.NewLine); } break; //case "Получить стакан заявок (не обновляемый)": // try // { // if (toolOrderBook != null) // { // AppendText2TextBox(textBoxLogsWindow, "Получаем данные о стакане с помощью функции GetQuoteLevel2..." + Environment.NewLine); // OrderBook orderBookCurrent = _quik.OrderBook.GetQuoteLevel2(tool.ClassCode, tool.SecurityCode).Result; // AppendText2TextBox(textBoxLogsWindow, "Выводим данные о стакане заявок в таблицу..." + Environment.NewLine); // //Console.WriteLine("Count offer = " + orderBookCurrent.offer_count); // //toolOrderBookTable = new FormOrderBook(toolOrderBook); // //toolOrderBookTable = new FormOrderBook(orderBookCurrent); // //toolOrderBookTable = new FormOrderBook(); // //toolOrderBookTable.Show(); // } // } // catch { AppendText2TextBox(textBoxLogsWindow, "Ошибка получения денежных лимитов." + Environment.NewLine); } // break; case "Связка ParamRequest + OnParam + GetParamEx2": try { AppendText2TextBox(textBoxLogsWindow, "Подписываемся на получение обновляемого параметра 'BID', через ParamRequest..." + Environment.NewLine); bool pReq = _quik.Trading.ParamRequest(tool.ClassCode, tool.SecurityCode, ParamNames.BID).Result; if (pReq) { AppendText2TextBox(textBoxLogsWindow, "Подписываемся на колбэк 'OnParam'..." + Environment.NewLine); _quik.Events.OnParam += OnParamDo; } else { AppendText2TextBox(textBoxLogsWindow, "Неудачная попытка подписки на обновление параметра..." + Environment.NewLine); } } catch { AppendText2TextBox(textBoxLogsWindow, "Ошибка работы в связке ParamRequest + OnParam + GetParamEx2." + Environment.NewLine); } break; case "CancelParamRequest": try { AppendText2TextBox(textBoxLogsWindow, "Отменяем подписку на получение обновляемого параметра 'BID', через ParamRequest..." + Environment.NewLine); bool pReq = _quik.Trading.CancelParamRequest(tool.ClassCode, tool.SecurityCode, ParamNames.BID).Result; if (pReq) { AppendText2TextBox(textBoxLogsWindow, "Отменяем подписку на колбэк 'OnParam'..." + Environment.NewLine); _quik.Events.OnParam -= OnParamDo; } else { AppendText2TextBox(textBoxLogsWindow, "Неудачная попытка отписки на обновление параметра..." + Environment.NewLine); } } catch { AppendText2TextBox(textBoxLogsWindow, "Ошибка работы в связке ParamRequest + OnParam + GetParamEx2." + Environment.NewLine); } break; case "Отменить заказ на получение стакана": try { AppendText2TextBox(textBoxLogsWindow, "Отменяем заказ на получение с сервера стакана по указанному классу и инструменту..." + Environment.NewLine); bool resultUnsub = await _quik.OrderBook.Unsubscribe(tool.ClassCode, tool.SecurityCode).ConfigureAwait(false); int count = 0; while (!resultUnsub && count < 10) { Thread.Sleep(500); resultUnsub = await _quik.OrderBook.Unsubscribe(tool.ClassCode, tool.SecurityCode).ConfigureAwait(false); count++; } int i = 0; while (isSubscribedToolOrderBook && i < 10) { Thread.Sleep(500); isSubscribedToolOrderBook = _quik.OrderBook.IsSubscribed(tool.ClassCode, tool.SecurityCode).Result; i++; } if (isSubscribedToolOrderBook) { //toolOrderBook = new OrderBook(); AppendText2TextBox(textBoxLogsWindow, "Отмена подписки на стакан не удалась." + Environment.NewLine); } else { toolOrderBook = null; AppendText2TextBox(textBoxLogsWindow, "Отмена подписки на стакан прошла успешно." + Environment.NewLine); bid = 0; offer = 0; Text2TextBox(textBoxBestBid, "-"); Text2TextBox(textBoxBestOffer, "-"); } } catch { AppendText2TextBox(textBoxLogsWindow, "Ошибка в функции отмены заказа стакана." + Environment.NewLine); } break; case "Выставить стоп-заявку типа тейк-профит и стоп-лимит": try { AppendText2TextBox(textBoxLogsWindow, "Подписываемся на событие OnStopOrder..." + Environment.NewLine); _quik.Events.OnStopOrder += OnStopOrderDo; decimal priceInOrder = Math.Round(tool.LastPrice, tool.PriceAccuracy); StopOrder orderNew = new StopOrder() { Account = tool.AccountID, ClassCode = tool.ClassCode, ClientCode = clientCode, SecCode = secCode, Offset = 5, OffsetUnit = OffsetUnits.PRICE_UNITS, Spread = 0.1M, SpreadUnit = OffsetUnits.PERCENTS, StopOrderType = StopOrderType.TakeProfitStopLimit, Condition = Condition.LessOrEqual, ConditionPrice = Math.Round(priceInOrder - 50 * tool.Step, tool.PriceAccuracy), ConditionPrice2 = Math.Round(priceInOrder + 40 * tool.Step, tool.PriceAccuracy), Price = Math.Round(priceInOrder + 45 * tool.Step, tool.PriceAccuracy), Operation = Operation.Buy, Quantity = 1 }; AppendText2TextBox(textBoxLogsWindow, "Выставляем стоп-заявку на покупку, по цене:" + priceInOrder + " ..." + Environment.NewLine); long transID = await _quik.StopOrders.CreateStopOrder(orderNew).ConfigureAwait(false); if (transID > 0) { AppendText2TextBox(textBoxLogsWindow, "Заявка выставлена. ID транзакции - " + transID + Environment.NewLine); Thread.Sleep(500); try { var listStopOrders = _quik.StopOrders.GetStopOrders().Result; foreach (StopOrder stopOrder in listStopOrders) { if (stopOrder.TransId == transID && stopOrder.ClassCode == tool.ClassCode && stopOrder.SecCode == tool.SecurityCode) { AppendText2TextBox(textBoxLogsWindow, "Стоп-заявка выставлена. Номер стоп-заявки - " + stopOrder.OrderNum + Environment.NewLine); } } } catch { AppendText2TextBox(textBoxLogsWindow, "Ошибка получения номера стоп-заявки." + Environment.NewLine); } } else { AppendText2TextBox(textBoxLogsWindow, "Неудачная попытка выставления стоп-заявки." + Environment.NewLine); } } catch { AppendText2TextBox(textBoxLogsWindow, "Ошибка выставления стоп-заявки." + Environment.NewLine); } break; } }
void Run() { try { secCode = textBoxSecCode.Text; textBoxLogsWindow.AppendText("Определяем код класса инструмента " + secCode + ", по списку классов" + "..." + Environment.NewLine); try { classCode = _quik.Class.GetSecurityClass("SPBFUT,TQBR,TQBS,TQNL,TQLV,TQNE,TQOB", secCode).Result; } catch { textBoxLogsWindow.AppendText("Ошибка определения класса инструмента. Убедитесь, что тикер указан правильно" + Environment.NewLine); } if (classCode != null && classCode != "") { textBoxClassCode.Text = classCode; textBoxLogsWindow.AppendText("Определяем код клиента..." + Environment.NewLine); clientCode = _quik.Class.GetClientCode().Result; textBoxClientCode.Text = clientCode; textBoxLogsWindow.AppendText("Создаем экземпляр инструмента " + secCode + "|" + classCode + "..." + Environment.NewLine); tool = new Tool(_quik, secCode, classCode); if (tool != null && tool.Name != null && tool.Name != "") { textBoxLogsWindow.AppendText("Инструмент " + tool.Name + " создан." + Environment.NewLine); textBoxAccountID.Text = tool.AccountID; textBoxFirmID.Text = tool.FirmID; textBoxShortName.Text = tool.Name; textBoxLot.Text = Convert.ToString(tool.Lot); textBoxStep.Text = Convert.ToString(tool.Step); textBoxGuaranteeProviding.Text = Convert.ToString(tool.GuaranteeProviding); textBoxLastPrice.Text = Convert.ToString(tool.LastPrice); textBoxQty.Text = Convert.ToString(GetPositionT2(_quik, tool, clientCode)); textBoxLogsWindow.AppendText("Подписываемся на стакан..." + Environment.NewLine); _quik.OrderBook.Subscribe(tool.ClassCode, tool.SecurityCode).Wait(); isSubscribedToolOrderBook = _quik.OrderBook.IsSubscribed(tool.ClassCode, tool.SecurityCode).Result; if (isSubscribedToolOrderBook) { toolOrderBook = new OrderBook(); textBoxLogsWindow.AppendText("Подписка на стакан прошла успешно." + Environment.NewLine); textBoxLogsWindow.AppendText("Подписываемся на колбэк 'OnQuote'..." + Environment.NewLine); _quik.Events.OnQuote += OnQuoteDo; timerRenewForm.Enabled = true; listBoxCommands.SelectedIndex = 0; listBoxCommands.Enabled = true; buttonCommandRun.Enabled = true; } else { textBoxLogsWindow.AppendText("Подписка на стакан не удалась." + Environment.NewLine); textBoxBestBid.Text = "-"; textBoxBestOffer.Text = "-"; timerRenewForm.Enabled = false; listBoxCommands.Enabled = false; buttonCommandRun.Enabled = false; } textBoxLogsWindow.AppendText("Подписываемся на колбэк 'OnFuturesClientHolding'..." + Environment.NewLine); _quik.Events.OnFuturesClientHolding += OnFuturesClientHoldingDo; textBoxLogsWindow.AppendText("Подписываемся на колбэк 'OnDepoLimit'..." + Environment.NewLine); _quik.Events.OnDepoLimit += OnDepoLimitDo; } buttonRun.Enabled = false; } } catch { textBoxLogsWindow.AppendText("Ошибка получения данных по инструменту." + Environment.NewLine); } }
/// <summary> /// Gets the order book. /// </summary> /// <param name="pair">The pair.</param> public OrderBook GetOrderBook(string pair) { var param = new Dictionary <string, string>(); param.Add("pair", pair); var res = QueryPublic("Depth", param); var obj = (JObject)JsonConvert.DeserializeObject(res); var ret = new OrderBook(); try { ret.asks = new List <OrderBookOrder>(); ret.bids = new List <OrderBookOrder>(); var result = obj["result"].Value <JObject>(); var pairLevel = result[pair].Value <JObject>(); var asks = pairLevel["asks"].Value <JArray>(); foreach (var o in asks) { var j = 0; var order = new OrderBookOrder(); foreach (var i in o) { if (j == 0) { order.price = (decimal)i; } else if (j == 1) { order.volume = (decimal)i; } else if (j == 2) { order.timestamp = (decimal)i; } j++; } ret.asks.Add(order); } var bids = pairLevel["bids"].Value <JArray>(); foreach (var o in bids) { var j = 0; var order = new OrderBookOrder(); foreach (var i in o) { if (j == 0) { order.price = (decimal)i; } else if (j == 1) { order.volume = (decimal)i; } else if (j == 2) { order.timestamp = (decimal)i; } j++; } ret.bids.Add(order); } } catch (Exception ex) { Logger.WriteLine(ex.Message); throw; } return(ret); }
public Execution buyorsell(Order order) { OrderBookService orderBookService = new OrderBookService(); OrderBook orderBook = orderBookService.FindOrderBookById(order.OrderBookId); List <OrderBook> orderBookList = new OrderBookService().FindOrderBookBySymbol(orderBook.Symbol); int orginQuantity = order.Quantity; //买 if (order.IsBuy) { orderBookList.Sort(delegate(OrderBook x, OrderBook y) { return(x.Price.CompareTo(y.Price)); }); var total = 0; foreach (OrderBook Q in orderBookList) { total += Q.Quantity; } Execution exection = new Execution(); exection.Trades = new List <Trade>(); exection.Order = order; if (order.Quantity < total) { int i = 0; while (order.Quantity > 0) { if (order.Quantity > orderBookList[i].Quantity) { exection.Trades.Add(new Trade { Id = i, Price = orderBookList[i].Price, Quantity = orderBookList[i].Quantity, IsSuccess = true }); } else { exection.Trades.Add(new Trade { Id = i, Price = orderBookList[i].Price, Quantity = order.Quantity, IsSuccess = true }); } order.Quantity = order.Quantity - orderBookList[i].Quantity; i++; } order.Quantity = orginQuantity; order.Status = "Completed"; } else { int i = 0; int n = order.Quantity - total; while (order.Quantity > 0 && order.Quantity > n) { if (order.Quantity > orderBookList[i].Quantity) { exection.Trades.Add(new Trade { Id = i, Price = orderBookList[i].Price, Quantity = orderBookList[i].Quantity, IsSuccess = true }); } else { exection.Trades.Add(new Trade { Id = i, Price = orderBookList[i].Price, Quantity = order.Quantity, IsSuccess = true }); } order.Quantity = order.Quantity - orderBookList[i].Quantity; i++; } order.Quantity = orginQuantity; order.Status = "Completed"; } exection.DateTime = DateTime.Now; return(exection); } //卖 else { orderBookList.Sort(delegate(OrderBook x, OrderBook y) { return(y.Price.CompareTo(x.Price)); }); var total = 0; foreach (OrderBook Q in orderBookList) { total += Q.Quantity; } Execution exection = new Execution(); exection.Trades = new List <Trade>(); if (order.Quantity < total) { int i = 0; while (order.Quantity > 0) { if (order.Quantity > orderBookList[i].Quantity) { exection.Trades.Add(new Trade { Id = i, Price = orderBookList[i].Price, Quantity = orderBookList[i].Quantity, IsSuccess = true }); } else { exection.Trades.Add(new Trade { Id = i, Price = orderBookList[i].Price, Quantity = order.Quantity, IsSuccess = true }); } order.Quantity = order.Quantity - orderBookList[i].Quantity; i++; } order.Status = "Completed"; order.Quantity = orginQuantity; } else { int i = 0; int n = order.Quantity - total; while (order.Quantity > 0 && order.Quantity > n) { if (order.Quantity > orderBookList[i].Quantity) { exection.Trades.Add(new Trade { Id = i, Price = orderBookList[i].Price, Quantity = orderBookList[i].Quantity, IsSuccess = true }); } else { exection.Trades.Add(new Trade { Id = i, Price = orderBookList[i].Price, Quantity = order.Quantity, IsSuccess = true }); } order.Quantity = order.Quantity - orderBookList[i].Quantity; i++; } order.Status = "Completed"; order.Quantity = orginQuantity; } exection.DateTime = DateTime.Now; return(exection); } }
public void FetchSellData() { try { _sellBook = _sellLink.GetOrderBook(); } catch (Exception e) { Log("ERROR obtaining orderbook: " + e.Message, 0); _sellBook = null; } }
public OrderBook getOrderBook() { OrderBook ret = new OrderBook(ContextModulePINVOKE.Portfolio_getOrderBook(swigCPtr), false); return ret; }
public async Task InsertAsync(OrderBook model, string symbol) { string colecao = string.Format("{0}_{1}", typeof(OrderBook).Name, symbol); await _repository.InsertAsync(model, colecao); }
private List<OptionMarketData> GetOptionsMarketData(string filePath) { List<OptionMarketData> resultList = new List<OptionMarketData>(); string line; System.IO.StreamReader file = new System.IO.StreamReader(filePath); while ((line = file.ReadLine()) != null) { string[] tokens = line.Split(';'); string symbol = tokens[0]; OptionType optionType = (tokens[1].Equals("C")) ? OptionType.Call : OptionType.Put; double strike = Double.Parse(tokens[2], CultureInfo.InvariantCulture); DateTime maturity = DateTime.ParseExact(tokens[3], "yyyyMMdd", null); OptionInfo optionInfo = new OptionInfo(symbol, string.Empty, optionType, strike, maturity); double? bid = null; double? bidSize = null; double? ask = null; double? askSize = null; if (tokens[4] != string.Empty) bid = Double.Parse(tokens[4], CultureInfo.InvariantCulture); if (tokens[5] != string.Empty) bidSize = Double.Parse(tokens[5], CultureInfo.InvariantCulture); if (tokens[6] != string.Empty) ask = Double.Parse(tokens[6], CultureInfo.InvariantCulture); if (tokens[7] != string.Empty) askSize = Double.Parse(tokens[7], CultureInfo.InvariantCulture); OrderBook orderBook = new OrderBook(symbol, bid, ask, bidSize, askSize); OptionMarketData marketData = new OptionMarketData(optionInfo, orderBook); resultList.Add(marketData); } file.Close(); return resultList; }
public void Setup() { Book = new OrderBook(); }
/// <summary> /// 结算 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void imgb_Salary_Click(object sender, ImageClickEventArgs e) { if (Session["Cart"] == null || ((DataTable)Session["Cart"]).Rows.Count==0) { Response.Write("<script>alert('您的购物车为空,请先将图书放入购物车!');document.location='BookList.aspx';</script>"); return; } Order order = new Order(); order.OrderDate = DateTime.Now; if (this.ltrSalary.Text != String.Empty) { order.TotalPrice = Convert.ToDecimal(this.ltrSalary.Text); } order.User = user; order = OrderManager.AddOrder(order); OrderBook orderbook=new OrderBook(); Book book = new Book(); Order orders = new Order(); foreach (DataRow dr in ((DataTable)Session["Cart"]).Rows) { book.Id = Convert.ToInt32(dr["BookId"]); orders.Id = order.Id; orderbook.Book = book; orderbook.Order = orders; orderbook.Quantity = Convert.ToInt32(dr["Number"]); orderbook.UnitPrice = Convert.ToDecimal(dr["UnitPrice"]); OrderBookManager.AddOrderBook(orderbook); } Session.Remove("Cart"); Response.Write("<script>alert('结算成功,请等待审批订单');window.location='BookList.aspx'</script>"); }
public OnTradeEventArgs(OrderBook book, Quantity quantity, int cost) { Book = book; Quantity = quantity; Cost = cost; }
public void ApplySnapshot(JObject jObject, Ticker ticker) { ticker.OrderBook.BeginUpdate(); try { ticker.OrderBook.Clear(); OrderBook orderBook = ticker.OrderBook; JArray jbids = jObject.Value <JArray>("Z"); JArray jasks = jObject.Value <JArray>("S"); List <OrderBookEntry> entries = orderBook.Asks; List <OrderBookEntry> entriesInverted = orderBook.AsksInverted; for (int i = 0; i < jasks.Count; i++) { JObject item = (JObject)jasks[i]; entries.Add(new OrderBookEntry() { ValueString = item.Value <string>("R"), AmountString = item.Value <string>("Q") }); if (entriesInverted != null) { entriesInverted.Insert(0, new OrderBookEntry() { ValueString = item.Value <string>("R"), AmountString = item.Value <string>("Q") }); } } entries = orderBook.Bids; for (int i = 0; i < jbids.Count; i++) { JObject item = (JObject)jbids[i]; entries.Add(new OrderBookEntry() { ValueString = item.Value <string>("R"), AmountString = item.Value <string>("Q") }); } } finally { ticker.OrderBook.IsDirty = false; ticker.OrderBook.EndUpdate(); } ticker.TradeHistory.Clear(); JArray jtrades = jObject.Value <JArray>("f"); foreach (JObject item in jtrades) { TradeInfoItem t = new TradeInfoItem(null, ticker); t.AmountString = item.Value <string>("Q"); t.RateString = item.Value <string>("P"); t.Time = new DateTime(Convert.ToInt64(item.Value <string>("T"))).ToLocalTime(); t.TimeString = t.Time.ToLongTimeString(); t.Total = t.Rate * t.Amount; t.Type = (item.Value <string>("OT")) == "BUY" ? TradeType.Buy : TradeType.Sell; ticker.TradeHistory.Add(t); } if (ticker.HasTradeHistorySubscribers) { ticker.RaiseTradeHistoryChanged(new TradeHistoryChangedEventArgs() { NewItems = ticker.TradeHistory }); } }
/// <summary> /// Fetch pending or registered order details /// </summary> /// <param name="base_name">The type of trading base-currency of which information you want to query for.</param> /// <param name="quote_name">The type of trading quote-currency of which information you want to query for.</param> /// <param name="limits">maximum number of items (optional): default 20</param> /// <param name="args">Add additional attributes for each exchange</param> /// <returns></returns> public override async Task <OrderBooks> FetchOrderBooks(string base_name, string quote_name, int limits = 20, Dictionary <string, object> args = null) { var _result = new OrderBooks(base_name, quote_name); var _market = await this.LoadMarket(_result.marketId); if (_market.success == true) { publicClient.ExchangeInfo.ApiCallWait(TradeType.Public); var _params = new Dictionary <string, object>(); { _params.Add("market", _market.result.symbol); _params.Add("size", limits); publicClient.MergeParamsAndArgs(_params, args); } var _json_value = await publicClient.CallApiGet1Async("/v1/depth", _params); #if DEBUG _result.rawJson = _json_value.Content; #endif var _json_result = publicClient.GetResponseMessage(_json_value.Response); if (_json_result.success == true) { var _ob = publicClient.DeserializeObject <ZOrderBook>(_json_value.Content); { var _ob_asks = _ob.asks.OrderBy(o => o.price).Take(limits).ToList(); var _ob_bids = _ob.bids.OrderByDescending(o => o.price).Take(limits).ToList(); var _orderbook = new OrderBook { asks = new List <IOrderBookItem>(), bids = new List <IOrderBookItem>() }; foreach (var _ask in _ob_asks) { _ask.amount = _ask.price * _ask.quantity; _ask.count = 1; _orderbook.asks.Add(_ask); } foreach (var _bid in _ob_bids) { _bid.amount = _bid.price * _bid.quantity; _bid.count = 1; _orderbook.bids.Add(_bid); } _result.result = _orderbook; _result.result.symbol = _market.result.symbol; _result.result.timestamp = CUnixTime.NowMilli; _result.result.nonce = CUnixTime.Now; } } _result.SetResult(_json_result); } else { _result.SetResult(_market); } return(_result); }
/// <summary> /// Display the order book with the specifed writer (e.g. Console.Out). /// </summary> /// <param name="orderBook"></param> /// <param name="writer"></param> /// <param name="limit"></param> public static void Print(this OrderBook orderBook, TextWriter writer, int limit = 25) { if (orderBook == null) { throw new ArgumentNullException(nameof(orderBook)); } if (limit <= 0) { throw new ArgumentException("Print limit must be greater than zero.", nameof(limit)); } var asks = orderBook.Asks.Take(limit).Reverse(); var bids = orderBook.Bids.Take(limit); foreach (var ask in asks) { var bars = new StringBuilder("|"); if (ask.Quantity > 50) { bars.Append("--------------------- 50 + ---------------------"); } else { var size = ask.Quantity; while (size-- >= 1) { bars.Append("-"); } while (bars.Length < 51) { bars.Append(" "); } } writer.WriteLine($" {ask.Price.ToString("0.00000000").PadLeft(14)} {ask.Quantity.ToString("0.00000000").PadLeft(15)} {bars}"); } writer.WriteLine(); writer.WriteLine($" {orderBook.MidMarketPrice().ToString("0.0000000000").PadLeft(16)} {orderBook.Spread().ToString("0.00000000").PadLeft(17)} Spread"); writer.WriteLine(); foreach (var bid in bids) { var bars = new StringBuilder("|"); if (bid.Quantity > 50) { bars.Append("--------------------- 50 + ---------------------"); } else { var size = bid.Quantity; while (size-- >= 1) { bars.Append("-"); } while (bars.Length < 51) { bars.Append(" "); } } writer.WriteLine($" {bid.Price.ToString("0.00000000").PadLeft(14)} {bid.Quantity.ToString("0.00000000").PadLeft(15)} {bars}"); } }
internal void MatchOrder(MatchOrderEventEntry matchOrder) { _logger.LogDebug("Called match order @ version number " + matchOrder.VersionNumber); // Old incorrect way: // In order to find actionOrderId, we must go a little roundabout way // var matchOrderRelatedCreateOrder = _eventHistoryRepository.Events<CreateOrderEventEntry>().Find( // Builders<CreateOrderEventEntry>.Filter.Eq(e => e.VersionNumber, matchOrder.VersionNumber) // ).First(); // var actionOrderId = matchOrderRelatedCreateOrder.Id; var now = matchOrder.EntryTime; // Action order is not used in case it's a market order var actionOrder = OrderBook.Find( Builders <OrderBookEntry> .Filter.Eq(e => e.CreatedOnVersionId, matchOrder.VersionNumber) ).SingleOrDefault(); var targetOrder = OrderBook.Find( Builders <OrderBookEntry> .Filter.Eq(e => e.CreatedOnVersionId, matchOrder.TargetOrderOnVersionNumber) ).Single(); AssertMatchOrderQty(matchOrder, actionOrder, targetOrder); if (actionOrder != null) { if (matchOrder.ActionOrderQtyRemaining == 0) { OrderBook.DeleteOne( Builders <OrderBookEntry> .Filter.Eq(e => e.CreatedOnVersionId, matchOrder.VersionNumber) ); // The entire order quantity was filled InsertOrderHistoryEntry(actionOrder.Qty, actionOrder, OrderStatus.Filled, now); } else { OrderBook.UpdateOne( Builders <OrderBookEntry> .Filter.Eq(e => e.CreatedOnVersionId, matchOrder.VersionNumber), Builders <OrderBookEntry> .Update.Set( e => e.FilledQty, actionOrder.Qty - matchOrder.ActionOrderQtyRemaining) ); } } else if ( // This condition can be completely deleted without a worry, it's just a double-check ((CreateOrderEventEntry)_eventHistoryService .FindByVersionNumber(matchOrder.VersionNumber) .First() ).Type != OrderType.Market ) { // We don't have to update the OrderHistoryEntry, because it already contains the matched quantity throw new Exception( $"Match order id {matchOrder.Id} did not have action being a limit order, and it was not a market order"); } if (matchOrder.TargetOrderQtyRemaining == 0) { OrderBook.DeleteOne( Builders <OrderBookEntry> .Filter.Eq(e => e.CreatedOnVersionId, matchOrder.TargetOrderOnVersionNumber) ); // The entire order quantity was filled InsertOrderHistoryEntry(targetOrder.Qty, targetOrder, OrderStatus.Filled, now); } else { OrderBook.UpdateOne( Builders <OrderBookEntry> .Filter.Eq( e => e.CreatedOnVersionId, matchOrder.TargetOrderOnVersionNumber), Builders <OrderBookEntry> .Update.Set( e => e.FilledQty, targetOrder.Qty - matchOrder.TargetOrderQtyRemaining) ); } TransactionHistory.InsertMany( new[] { new TransactionHistoryEntry { ExecutionTime = now, User = matchOrder.ActionUser, AccountId = matchOrder.ActionAccountId, Instrument = matchOrder.Instrument, Side = targetOrder.Side == OrderSide.Buy ? OrderSide.Sell : OrderSide.Buy, OrderId = actionOrder?.Id, // The entire quantity was filled FilledQty = matchOrder.Qty, Price = targetOrder.LimitPrice, }, new TransactionHistoryEntry { ExecutionTime = now, User = targetOrder.User, AccountId = targetOrder.AccountId, Instrument = targetOrder.Instrument, Side = targetOrder.Side, OrderId = targetOrder.Id, // The entire quantity was filled FilledQty = matchOrder.Qty, Price = targetOrder.LimitPrice, } } ); _logger.LogDebug("Persisted match order @ version number " + matchOrder.VersionNumber); }
/// <summary> /// 通知買賣報價 /// </summary> private static void MrWangConnection_OnOrderBookData(OrderBook orderBook) { Console.WriteLine($"Symbol:{orderBook.Symbol}" + $" Bid:{orderBook.BidPrice} x {orderBook.BidQty}" + $" Ask:{orderBook.AskPrice} x {orderBook.AskQty}"); }
internal void CreateOrder(CreateOrderEventEntry createOrder) { _logger.LogDebug("Called create order @ version number " + createOrder.VersionNumber); switch (createOrder.Type) { case OrderType.Limit: var limitOrder = new OrderBookEntry { EntryTime = createOrder.EntryTime, CreatedOnVersionId = createOrder.VersionNumber, User = createOrder.User, AccountId = createOrder.AccountId, Instrument = createOrder.Instrument, Qty = createOrder.Qty, Side = createOrder.Side, FilledQty = 0m, LimitPrice = createOrder.LimitPrice.Value, // TODO from stop loss and take profit //ChildrenIds DurationType = createOrder.DurationType, Duration = createOrder.Duration, }; OrderBook.InsertOne(limitOrder); break; case OrderType.Stop: var stopOrder = new HiddenOrderEntry { EntryTime = createOrder.EntryTime, CreatedOnVersionId = createOrder.VersionNumber, User = createOrder.User, AccountId = createOrder.AccountId, Instrument = createOrder.Instrument, Qty = createOrder.Qty, Side = createOrder.Side, StopPrice = createOrder.StopPrice.Value, // TODO from stop loss and take profit //ChildrenIds DurationType = createOrder.DurationType, Duration = createOrder.Duration, }; HiddenOrders.InsertOne(stopOrder); break; case OrderType.Market: OrderHistory.InsertOne( new OrderHistoryEntry { CreateTime = createOrder.EntryTime, CloseTime = createOrder.EntryTime, User = createOrder.User, AccountId = createOrder.AccountId, Instrument = createOrder.Instrument, Qty = createOrder.Qty, Side = createOrder.Side, // Closed market order Type = OrderType.Market, // The market order will be filled by the following match orders FilledQty = createOrder.FilledMarketOrderQty, // The most expensive accepted limit price will be shown to the user LimitPrice = createOrder.LimitPrice.Value, StopPrice = null, // TODO from stop loss and take profit //ChildrenIds DurationType = createOrder.DurationType, Duration = createOrder.Duration, Status = OrderStatus.Filled, } ); break; default: throw new ArgumentOutOfRangeException(nameof(createOrder.Type)); } _logger.LogDebug("Persisted create order @ version number " + createOrder.VersionNumber); }
private void DisplayOrderBook(OrderBook obj) { AppendReceiverBox($"OrderBook[0] - Price: {obj.List[0].Price}, Side: {obj.List[0].Side}, Size: {obj.List[0].Size}"); }
private async Task SendData(decimal ask, decimal bid, string assetPair, bool crossIsInternal, DateTime timestamp) { if (_lastPrices.TryGetValue(assetPair, out var prevTickPrice) && ask == prevTickPrice.Ask && bid == prevTickPrice.Bid) { prevTickPrice = null; } if (prevTickPrice != null) { var prevMid = (prevTickPrice.Ask + prevTickPrice.Bid) / 2; var mid = (ask + bid) / 2; if (_setting.DangerChangePriceKoef > 0 && Math.Abs(mid - prevMid) >= _setting.DangerChangePriceKoef * mid) { var context = new { AssetPair = assetPair, PrevTickPrice = prevTickPrice, Ask = ask, Bid = bid }; _log.Error(nameof(SendData), context: context.ToJson(), message: "Danger change price, skip action"); return; } } var asks = new List <OrderBookItem>() { new OrderBookItem(ask, _setting.FakeVolume) }; var bids = new List <OrderBookItem>() { new OrderBookItem(bid, _setting.FakeVolume) }; var orderBook = new OrderBook(InternalName, assetPair, timestamp, asks, bids); var tickPrice = new TickPrice() { Source = InternalName, Asset = assetPair, Timestamp = orderBook.Timestamp, Ask = ask, Bid = bid }; if (!crossIsInternal) { await _orderBookProvider.Send(orderBook); await _tickPriceProvider.Send(tickPrice); } _lastPrices[tickPrice.Asset] = tickPrice; await _tickPriceStore.Handle(tickPrice); }
public void FetchBuyData() { try { _buyBook = _buyLink.GetOrderBook(); } catch (Exception e) { Log("ERROR obtaining orderbook: " + e.Message, 0); _buyBook = null; } }
public static void AddOrderBook(OrderBook orderbook) { #region 添加订单详情 OrderBookServer.AddOrderBook(orderbook); #endregion }
internal static HandleRef getCPtr(OrderBook obj) { return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; }
public static OrderBookDto mapToDtoOrderBook(OrderBook orderBook) { return(new OrderBookDto(orderBook.kolvo, orderBook.bookId)); }
public void ChangeOffer() { OrderBook book = new OrderBook(); book.ChangeOrder(10, 1, MDEntryType.BID); }
/// <summary> /// 通知買賣報價 /// </summary> private static void MrWangConnection_OnOrderBookData(OrderBook orderBook) { }
private int NextVersion(OrderBook orderbook) { return (orderbook.Version == Int16.MaxValue) ? 0 : orderbook.Version + 1; }
public async Task Write(OrderBook orderBook) { OrderBooks.Add(orderBook); }
private OrderBook GetUnderlyingMarketData(string filePath) { OrderBook marketData = null; string line; System.IO.StreamReader file = new System.IO.StreamReader(filePath); while ((line = file.ReadLine()) != null) { string[] tokens = line.Split(';'); string name = tokens[0]; double? bid = null; double? bidSize = null; double? ask = null; double? askSize = null; if (tokens[1] != string.Empty) bid = Double.Parse(tokens[1], CultureInfo.InvariantCulture); if (tokens[2] != string.Empty) bidSize = Double.Parse(tokens[2], CultureInfo.InvariantCulture); if (tokens[3] != string.Empty) ask = Double.Parse(tokens[3], CultureInfo.InvariantCulture); if (tokens[4] != string.Empty) askSize = Double.Parse(tokens[4], CultureInfo.InvariantCulture); marketData = new OrderBook(name, bid, ask, bidSize, askSize); } file.Close(); return marketData; }
public Order[] GetOrderBook(CurrencyName ins1, CurrencyName ins2) { bool getAsks = true; if (ins1 != CurrencyName.BTC) { ins2 = ins1; ins1 = CurrencyName.BTC; getAsks = false; } string insName1 = ins1.ToString(); string insName2 = ins2.ToString(); if (ins1 == CurrencyName.BCH) { insName1 = "BCC"; } if (ins2 == CurrencyName.BCH) { insName2 = "BCC"; } if (ins1 == CurrencyName.DSH) { insName1 = "DASH"; } if (ins2 == CurrencyName.DSH) { insName2 = "DASH"; } var json = GetQuery(String.Format("{0}public/getorderbook?market={1}-{2}&type=both", BaseUri, insName1, insName2)); var response = JsonConvert.DeserializeObject <BittrexOrderBook>(json); var orderBook = new OrderBook { Currency = ins2 }; if (getAsks) { int askLen = response.Result.Sell.Length; if (askLen > OrderBookLimit) { askLen = OrderBookLimit; } orderBook.Asks = new Order[askLen]; for (int i = 0; i < orderBook.Asks.Length; i++) { var ask = response.Result.Sell[i]; orderBook.Asks[i] = new Order { Price = ask.Rate, Amount = ask.Quantity }; } return(orderBook.Asks); } else { int bidLen = response.Result.Buy.Length; if (bidLen > OrderBookLimit) { bidLen = OrderBookLimit; } orderBook.Bids = new Order[bidLen]; for (int i = 0; i < orderBook.Bids.Length; i++) { var bid = response.Result.Buy[i]; orderBook.Bids[i] = new Order { Price = bid.Rate, Amount = bid.Quantity }; } return(orderBook.Bids); } }
internal void OnQuoteCall(OrderBook orderBook) { if (OnQuote != null) OnQuote(orderBook); }
private static string GetKey(OrderBook orderBook) => GetKey(orderBook.AssetPairId);
private static OrderBook OrderBook(JObject value, int count) { var result = new OrderBook(); result.Bids.AddRange(OrderBook(value, "bids", count)); result.Asks.AddRange(OrderBook(value, "asks", count)); return result; }
private static void SortAsks(OrderBook orderBook) { orderBook.Asks = orderBook.Asks.OrderBy(it => it.Price).ToList(); }