Exemplo n.º 1
0
        public string Transfer(DataRow sideA, DataRow sideB, IContractCall contract, bool isPartial)
        {
            //SELLER SHOWS DECREASE IN UNITS AND INCREASE IN TOKEN BALANCE
            //BUYER SHOWS INCREASE IN UNITS AND DECREASE IN TOKEN BALANCE
            //TOKENS MOVED FROM BUYER ACCOUNT TO SELLER ACCOUNT

            //WHO IS THE BUYER/SELLER
            DataRow buyer  = Convert.ToInt32(sideA["TradeTypeId"]) == (int)TradeType.Buy ? sideA : sideB;
            DataRow seller = Convert.ToInt32(sideA["TradeTypeId"]) == (int)TradeType.Sell ? sideA : sideB;

            int buyerQuantity  = Convert.ToInt32(buyer["UnsetQuantity"]);
            int sellerQuantity = Convert.ToInt32(seller["UnsetQuantity"]);

            if (isPartial)
            {
                //IF SELLER IS SELLING MORE THAN ASKING, SELLER QUANTITY IS THE BUYERS QUANTITY
                if (buyerQuantity < sellerQuantity)
                {
                    sellerQuantity = buyerQuantity;
                }
                //IF BUYER IS BUYING MORE THAN ASKING, BUYER QUANTITY IS THE SELLERS QUANTITY
                else if (buyerQuantity > sellerQuantity)
                {
                    buyerQuantity = sellerQuantity;
                }
            }

            string buyerPK       = Convert.ToString(buyer["PublicKey"]);
            int    buyerUserId   = Convert.ToInt32(buyer["UserId"]);
            int    buyerEntityId = Convert.ToInt32(buyer["EntityId"]);
            double buyerAmount   = Convert.ToDouble(buyer["Price"]) * buyerQuantity;

            string sellerPK       = Convert.ToString(seller["PublicKey"]);
            int    sellerUserId   = Convert.ToInt32(seller["UserId"]);
            int    sellerEntityId = Convert.ToInt32(seller["EntityId"]);

            Task <string> txResult = contract.SendTokensFromAsync(buyerPK, sellerPK, buyerAmount, opts.GasAmount);

            txResult.Wait();
            var result = txResult.Result;

            SetUnits(buyerUserId, buyerEntityId, buyerQuantity);
            SetUnits(sellerUserId, sellerEntityId, sellerQuantity * -1);

            return(result);
        }
Exemplo n.º 2
0
 public void MarginTransfer(Order newOrder, int userId, int entityId, IContractCall contract, Guid orderId)
 {
     //SHORT SELL: FOR EVERY 1 UNIT LETS TRANSFER $100 INTO THEIR MARGIN ACCOUNT
     if (newOrder.TradeTypeId == (int)TradeType.ShortSell)
     {
         double        transferAmount = Convert.ToDouble(newOrder.Quantity) * 100D;
         Task <string> txResult       = contract.TransferMargin(newOrder.PublicKey, newOrder.PublicKey, transferAmount, (int)MarginMove.BalanceToMargin, opts.GasAmount);
         txResult.Wait();
         var result = txResult.Result;
         //INSERT INTO DATABASE
         List <SqlParameter> prms = new List <SqlParameter>
         {
             new SqlParameter("@ORDERID", orderId),
             new SqlParameter("@USERID", userId),
             new SqlParameter("@PUBLICKEY", newOrder.PublicKey),
             new SqlParameter("@ENTITYID", entityId),
             new SqlParameter("@TRADETYPEID", newOrder.TradeTypeId),
             new SqlParameter("@PRICE", newOrder.Price),
             new SqlParameter("@QUANTITY", newOrder.Quantity),
             new SqlParameter("@TXHASH", result),
         };
         DBUtility.ExecuteQuery(opts.ConnectionString, "spInsertMargin", prms);
     }
 }
Exemplo n.º 3
0
        public DataTable MatchOrders(IContractCall contract, int entityId, DataRow newOrder, DataTable orderBook, out bool updated, out MarketData marketData)
        {
            updated = false;
            DataTable updatedOrders = orderBook.Clone();

            marketData             = new MarketData();
            marketData.EntityId    = entityId;
            marketData.Volume      = 0;
            marketData.MarketPrice = null;

            foreach (DataRow dr in orderBook.Rows)
            {
                int     quant    = Convert.ToInt32(dr["Quantity"]);
                int     newQuant = Convert.ToInt32(newOrder["Quantity"]);
                decimal price    = Convert.ToDecimal(dr["Price"]);
                decimal newPrice = Convert.ToDecimal(newOrder["Price"]);
                marketData.LastTradeTime  = Convert.ToDateTime(newOrder["Date"]);
                marketData.LastTradePrice = Convert.ToDecimal(newOrder["Price"]);
                updated = true;

                //SAFETY CHECK, LETS CHECK IF QUANTITY == 0, THEN IT'S FILLED, BREAK
                if (newQuant == 0)
                {
                    break;
                }

                //1. NEW ORDER HAS SAME AMOUNT AS THE FIRST ROW IN THE BOOK
                else if (newQuant == quant)
                {
                    var txResult = Transfer(newOrder, dr, contract, false);
                    dr["Quantity"] = 0;
                    dr["Status"]   = (int)Status.Filled;
                    dr["TxHash"]   = txResult;
                    updatedOrders.ImportRow(dr);
                    newOrder["Quantity"]   = 0;
                    newOrder["Status"]     = (int)Status.Filled;
                    newOrder["TxHash"]     = txResult;
                    marketData.Volume      = marketData.Volume + quant;
                    marketData.MarketPrice = (price < newPrice) ? price : newPrice;
                    break;
                }

                //2. NEW ORDER HAS MORE SHARES THAN THE FIRST ROW IN THE BOOK
                else if (newQuant > quant)
                {
                    var txResult = Transfer(newOrder, dr, contract, true);
                    dr["Quantity"] = 0;
                    dr["Status"]   = (int)Status.Filled;
                    dr["TxHash"]   = txResult;
                    updatedOrders.ImportRow(dr);
                    newOrder["Quantity"]   = newQuant - quant;
                    newOrder["Status"]     = (int)Status.Partial;
                    newOrder["TxHash"]     = txResult;
                    marketData.Volume      = marketData.Volume + quant;
                    marketData.MarketPrice = (price < newPrice) ? price : newPrice;
                }

                //3. NEW ORDER HAS LESS SHARES THAN THE FIRST ROW IN THE BOOK
                else if (newQuant < quant)
                {
                    var txResult = Transfer(newOrder, dr, contract, true);
                    dr["Quantity"] = quant - newQuant;
                    dr["Status"]   = (int)Status.Partial;
                    dr["TxHash"]   = txResult;
                    updatedOrders.ImportRow(dr);
                    newOrder["Quantity"]   = 0;
                    newOrder["Status"]     = (int)Status.Filled;
                    newOrder["TxHash"]     = txResult;
                    marketData.Volume      = marketData.Volume + newQuant;
                    marketData.MarketPrice = (price < newPrice) ? price : newPrice;
                    break;
                }
            }

            orderBook.Rows.Add(newOrder);
            updatedOrders.ImportRow(newOrder);
            return(updatedOrders);
        }
Exemplo n.º 4
0
        public MarketOrders AddNewOrder(Order newOrder, IContractCall contract)
        {
            Guid     orderId  = Guid.NewGuid();
            DBMarket dBMarket = new DBMarket(opts, this.userId, this.entityId);

            //BEFORE WE MATCH, LETS CHECK IF WE NEED TO MOVE MONEY TO MARGIN (SHORT SELLS)
            MarginTransfer(newOrder, this.userId, this.entityId, contract, orderId);

            using (SqlConnection con = new SqlConnection(opts.ConnectionString))
            {
                using (SqlCommand cmd = new SqlCommand("spSelectOrdersForMatch", con))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.Add(new SqlParameter("@ENTITYID", entityId));
                    cmd.Parameters.Add(new SqlParameter("@TRADETYPEID", newOrder.TradeTypeId));
                    cmd.Parameters.Add(new SqlParameter("@PRICE", newOrder.Price));
                    using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
                    {
                        using (DataTable dt = new DataTable())
                        {
                            sda.Fill(dt);

                            DataRow row = dt.NewRow();
                            row["OrderId"]       = orderId;
                            row["UserId"]        = userId;
                            row["EntityId"]      = entityId;
                            row["TradeTypeId"]   = newOrder.TradeTypeId;
                            row["Price"]         = newOrder.Price;
                            row["Date"]          = DateTime.Now;
                            row["Quantity"]      = newOrder.Quantity;
                            row["UnsetQuantity"] = newOrder.UnsetQuantity;
                            row["PublicKey"]     = newOrder.PublicKey;
                            row["Status"]        = (int)Status.Open;

                            bool       updated;
                            MarketData marketData;
                            DataTable  updatedOrders = MatchOrders(contract, entityId, row, dt, out updated, out marketData);

                            //NEW ORDERS (SOME MAY ALREADY HAVE MATCHES)
                            sda.InsertCommand = new SqlCommandBuilder(sda).GetInsertCommand();

                            //ORDERS NEED TO BE UPDATED
                            if (updated)
                            {
                                sda.UpdateCommand = new SqlCommandBuilder(sda).GetUpdateCommand();
                            }

                            //RUNNING NEW ORDERS AND UPDATES AGAINST DB
                            sda.Update(dt);

                            //UPDATE THE MARKET DATA DATABASE TABLE, RETURNING CHANGE IN PRICE + VOLUME
                            marketData = dBMarket.UpdateMarketData(marketData);

                            //MARKET DATA AND FINAL ORDERBOOK RETURN
                            return(new MarketOrders {
                                MarketData = marketData, Orders = updatedOrders
                            });
                        }
                    }
                }
            }
        }