public Trade(int amount, decimal price, Order buyOrder, Order sellOrder) { this.amount = amount; this.price = price; this.stockId = buyOrder.StockId; this.buyerId = buyOrder.BrokerId; this.buyOrderId = buyOrder.Id; this.sellerId = sellOrder.BrokerId; this.sellOrderId = sellOrder.Id; this.executed = DateTime.Now; }
protected override PriceCalculationRow[] CreateTable(Order[] buyList, Order[] sellList) { IList<PriceCalculationRow> table = new List<PriceCalculationRow>(); Order[] sortedBuyList = buyList.OrderByDescending(o => o.ProposedPrice).ToArray(); // FIXME: u SpPgsql netreba Order[] sortedSellList = sellList.OrderBy(o => o.ProposedPrice).ToArray(); // FIXME: u SpPgsql netreba InsertBuyOrders(sortedBuyList, table); InsertSellOrders(sortedSellList, table); return table.ToArray(); }
public decimal GetPrice(Order[] buyList, Order[] sellList, decimal tickSize, decimal lastPrice) { this.tickSize = tickSize; this.lastPrice = lastPrice; if (buyList.Length == 0 || sellList.Length == 0) { Recorder.Instance.WriteLine("No buy or sell orders. Current price is equal to the last price."); return lastPrice; } /// Výpočet protnutí nabídky a poptávky jsem přesunul na databázi. Order[] filteredBuyList = buyList; Order[] filteredSellList = sellList; PriceCalculationRow[] table = CreateTable(filteredBuyList, filteredSellList); return GetPriceByMaximumTradeableVolume(table); }
public override void AddOrder(Order order) { XDocument document = XDocument.Load(FileName); XElement ordersElement = document.Root.Element(OrdersElementName); XElement newOrderElement = new XElement("order"); newOrderElement.Add(new XElement("id", order.Id)); newOrderElement.Add(new XElement("type", order.Type)); newOrderElement.Add(new XElement("stockId", order.StockId)); newOrderElement.Add(new XElement("brokerId", order.BrokerId)); newOrderElement.Add(new XElement("amount", order.Amount)); newOrderElement.Add(new XElement("price", order.ProposedPrice)); newOrderElement.Add(new XElement("received", order.Received)); ordersElement.Add(newOrderElement); using (XmlWriter writer = new XmlTextWriter(FileName, Encoding.UTF8)) { document.WriteTo(writer); } }
public override void AddOrder(Order order) { using (OdbcCommand command = new OdbcCommand()) { command.Connection = connection; int orderTypeId = (order.Type == OrderType.BuyOrder) ? Constants.BuyOrderId : Constants.SellOrderId; string query = string.Format("SELECT insert_order({0}, {1}, {2}, {3}, {4})", orderTypeId, order.BrokerId, order.StockId, order.Amount, order.ProposedPrice.ToString(CultureInfo.CreateSpecificCulture("en-US"))); command.CommandText = query; using (OdbcDataReader reader = command.ExecuteReader(CommandBehavior.SingleResult)) { if (reader.HasRows) { order.Id = reader.GetInt32(0); } reader.Close(); } } }
public override void AddOrder(Order order) { int orderTypeId = (order.Type == OrderType.BuyOrder) ? 1 : 2; string queryTemplate = "INSERT INTO {0} " + string.Format("(oid, bid, sid, amount, price, received) VALUES " + "({0}, {1}, {2}, {3}, {4}, TIMESTAMP '{5}');", orderTypeId, order.BrokerId, order.StockId, order.Amount, order.ProposedPrice.ToString(CultureInfo.CreateSpecificCulture("en-US")), order.Received); OdbcCommand command = new OdbcCommand(); OdbcTransaction transaction = null; DateTime now = DateTime.Now; try { transaction = connection.BeginTransaction(); command.Connection = connection; command.Transaction = transaction; command.CommandText = string.Format(queryTemplate, "live_orders"); command.ExecuteNonQuery(); command.CommandText = string.Format(queryTemplate, "archived_orders"); command.ExecuteNonQuery(); transaction.Commit(); } catch (Exception ex) { Console.WriteLine(ex.Message); try { transaction.Rollback(); } catch { } } }
/// <summary> /// Vloží do (prázdné) tabulky <code>table</code> objednávky na nákup seřazené SESTUPNĚ. /// Tato metoda musí být volána před vložením objednávek na prodej! /// </summary> /// <param name="buyList">Seznam objednávek na nákup.</param> /// <param name="table">Tabulka, do které mají být objednávky vloženy.</param> private void InsertBuyOrders(Order[] buyList, IList<PriceCalculationRow> table) { PriceCalculationRow previousRow = null; int aggregatePreviousRowsQuantity = 0; foreach (Order buyOrder in buyList) { decimal price = buyOrder.ProposedPrice; int amount = buyOrder.Amount; if (previousRow == null || previousRow.Price != price) // vkladame novou cenu { PriceCalculationRow row = new PriceCalculationRow(price); row.AggregateBuyQuantity = amount + aggregatePreviousRowsQuantity; table.Add(row); previousRow = row; } else // takova cena uz existuje { previousRow.AggregateBuyQuantity += amount; } aggregatePreviousRowsQuantity = previousRow.AggregateBuyQuantity; } }
public Trade[] MatchOrders(Order[] buyList, Order[] sellList, decimal price) { // TODO: razeni by se dalo delat jen jednou, vyuziva to i IosPriceCalculator... - nejaky preprocesor // Tady se akorat navic rovna podle druhyho kriteria: casu // TODO: a vubec, stacilo by seznam zkratit podle spocitane price (je serazeny, tak useknout) Order[] sortedBuyList = buyList.Where(o => o.ProposedPrice >= price) .OrderByDescending(o => o.ProposedPrice).ThenBy(o => o.Received).ToArray(); Order[] sortedSellList = sellList.Where(o => o.ProposedPrice <= price) .OrderBy(o => o.ProposedPrice).ThenBy(o => o.Received).ToArray(); if (sortedBuyList.Length == 0) // pak je i sortedSellList.Length == 0 return new Trade[0]; IList<Trade> result = new List<Trade>(); int buyListIndex = 0; int sellListIndex = 0; do { Order buyOrder = sortedBuyList[buyListIndex]; Order sellOrder = sortedSellList[sellListIndex]; if (buyOrder.Amount > sellOrder.Amount) { int amount = sellOrder.Amount; Trade trade = new Trade(amount, price, buyOrder, sellOrder); result.Add(trade); buyOrder.Amount -= amount; sellOrder.Amount = 0; sellListIndex++; } else if (buyOrder.Amount < sellOrder.Amount) { int amount = buyOrder.Amount; Trade trade = new Trade(amount, price, buyOrder, sellOrder); result.Add(trade); sellOrder.Amount -= buyOrder.Amount; buyOrder.Amount = 0; buyListIndex++; } else // == { int amount = buyOrder.Amount; Trade trade = new Trade(amount, price, buyOrder, sellOrder); result.Add(trade); buyOrder.Amount = 0; buyListIndex++; sellOrder.Amount = 0; sellListIndex++; } } while (buyListIndex < sortedBuyList.Length && sellListIndex < sortedSellList.Length); // NAPAD: zapis do DB, co se prodalo komu. Tam, kde zbylo Q = 0, to je jasny, // k tomu zapsat zvlast posledni pouzity indexy, pokud Q != 0. ... To ale nepouzivam. return result.ToArray(); }
private Order[] SelectOrders(int stockId, OrderType type) { IList<Order> orderList = new List<Order>(); int orderTypeId = (type == OrderType.BuyOrder) ? 1 : 2; string query = "SELECT id, bid, amount, price, received FROM live_orders WHERE oid = " + orderTypeId + " AND sid = " + stockId; OdbcCommand command = new OdbcCommand(query, connection); OdbcDataReader reader = command.ExecuteReader(); while (reader.Read()) { Order order = new Order(); order.Id = reader.GetInt32(0); order.Type = type; order.StockId = stockId; order.BrokerId = reader.GetInt32(1); order.Amount = reader.GetInt32(2); order.ProposedPrice = reader.GetDecimal(3); order.Received = reader.GetDateTime(4); orderList.Add(order); } reader.Close(); return orderList.ToArray(); }
private Order[] SelectOrders(OrderType orderType) { XDocument document = XDocument.Load(FileName); XElement ordersElement = document.Root.Element(OrdersElementName); IList<Order> orderList = new List<Order>(); foreach (XElement orderElement in ordersElement.Elements()) { OrderType type = (OrderType)Enum.Parse(typeof(OrderType), orderElement.Element("type").Value); if (type == orderType) { Order order = new Order(); order.Id = int.Parse(orderElement.Element("id").Value); order.Type = type; order.StockId = int.Parse(orderElement.Element("stockId").Value); order.BrokerId = int.Parse(orderElement.Element("brokerId").Value); order.Amount = int.Parse(orderElement.Element("amount").Value); order.ProposedPrice = decimal.Parse(orderElement.Element("price").Value, new CultureInfo("en-US")); order.Received = DateTime.Parse(orderElement.Element("received").Value); orderList.Add(order); } } return orderList.ToArray(); }
private Order[] SelectOrders(OrderType type, string methodName, int stockId) { IList<Order> orders = new List<Order>(); using (OdbcCommand command = new OdbcCommand()) { command.Connection = connection; command.CommandText = string.Format("SELECT id, broker_id, stock_id, amount, price, received FROM {0}({1});", methodName, stockId); using (OdbcDataReader reader = command.ExecuteReader()) { while (reader.Read()) { //id, bid, sid, amount, price, received Order order = new Order(); order.Type = type; order.Id = reader.GetInt32(0); order.BrokerId = reader.GetInt32(1); order.StockId = reader.GetInt32(2); order.Amount = reader.GetInt32(3); order.ProposedPrice = reader.GetDecimal(4); order.Received = reader.GetDateTime(5); orders.Add(order); } reader.Close(); } } return orders.ToArray(); }
/// <summary> /// Vloží do tabulky <code>table</code> objednávky na prodej seřazené VZESTUPNĚ. /// Tato metoda může být volána po vložení objednávek na nákup. /// Výsledkem je sestupně seřazená tabulka podle ceny. /// </summary> /// <param name="sellList">Seznam objednávek na prodej.</param> /// <param name="table">Tabulka, do které mají být objednávky vloženy.</param> private void InsertSellOrders(Order[] sellList, IList<PriceCalculationRow> table) { int rowIndex = table.Count - 1; PriceCalculationRow lastRow = table[rowIndex]; int aggregatePreviousRowsQuantity = 0; foreach (Order sellOrder in sellList) { decimal price = sellOrder.ProposedPrice; int amount = sellOrder.Amount; /// Zapsani prodejniho mnozstvi, posun v tabulce nahoru (tj. k vyssi cene) while (lastRow.Price < price && rowIndex > 0) { lastRow.AggregateSellQuantity = aggregatePreviousRowsQuantity; rowIndex--; lastRow = table[rowIndex]; } /// Narazili jsme na cenu, ktera nebyla obsazena v "buy" tabulce, musi se vlozit if (lastRow.Price > price) { PriceCalculationRow newRow = new PriceCalculationRow(price); newRow.AggregateBuyQuantity = lastRow.AggregateBuyQuantity; // nakup jako za vyssi cenu rowIndex++; // posunem se o krok zpatky, niz v tabulce lastRow = newRow; table.Insert(rowIndex, newRow); } /// Cenu jsme v tabulce nasli, nebo ji vlozili. V kazdem pripade pro ni zvysime mnozstvi. /// Zapis mnozstvi probehne v cyklu posunu po tabulce aggregatePreviousRowsQuantity += amount; } /// Na zaver vyplnime mnozstvi pro vsechny zbyvajiji nejvyssi ceny z "buy" tabulky for (int index = 0; index <= rowIndex; index++) { table[index].AggregateSellQuantity = aggregatePreviousRowsQuantity; } }
/// <summary> /// Vloží požadavek na nákup či prodej akcií. /// </summary> public abstract void AddOrder(Order order);
protected abstract PriceCalculationRow[] CreateTable(Order[] buyList, Order[] sellList);