Exemple #1
0
 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;
              }
        }
Exemple #13
0
 /// <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);