Exemple #1
0
        /// <summary>
        /// Calculate the VWAP price
        /// </summary>
        /// <returns></returns>
        private double GetVWAP(string Symbol, enumOrderType orderType, enumSide side)
        {
            double VWAP = 0;

            if (orderType.Equals(enumOrderType.Market))
            {
                VWAP = Convert.ToDouble(Int16.MinValue); // For a market type, return a -32768
            }
            else
            {
                List <ExchangeOrder> liveOrders = null;
                int qty = 0;
                if (side.Equals(enumSide.Buy) && Sells.ContainsKey(Symbol))
                {
                    liveOrders = Sells[Symbol];
                }
                if (side.Equals(enumSide.Sell) && Buys.ContainsKey(Symbol))
                {
                    liveOrders = Buys[Symbol];
                }
                if (liveOrders == null)
                {
                    VWAP = Convert.ToDouble(Int16.MaxValue);
                }
                foreach (ExchangeOrder eo in liveOrders)
                {
                    VWAP += eo.Offer * eo.Volume;
                    qty  += eo.Volume;
                }
                if (!qty.Equals(0.0))
                {
                    VWAP /= qty;
                }
                else
                {
                    throw new DivideByZeroException(string.Format("Quantity becomes ZERO in GetVWAP, how come! Sybmol {0}, Side {1}", Symbol, side));
                }
            }
            return(VWAP);
        }
        public string PlaceAnOrder(string UserName, string UserId, string Symbol, string Volume, string Price, string OrderType, string OrderSide)
        {
            User          user            = null;
            string        message         = string.Empty;
            string        userId          = MatchMeDB.Instance.UserTable[Config.AdminUser].Id;
            enumStatus    status          = enumStatus.Unknown;
            enumSide      orderside       = enumSide.Invalid;
            enumOrderType ordertype       = enumOrderType.Invalid;
            double        price           = 0.0;
            int           volume          = 0;
            bool          exist           = false;
            double        requiredbalance = 0.0;
            double        remainbalance   = 0.0;
            string        symbol          = Symbol.ToUpper();

            try
            {
                Symbol = Symbol.ToUpper();
                if (!int.TryParse(Volume, out volume))
                {
                    message = string.Format("Error: Invalid Volume: {0}", volume);
                    status  = enumStatus.OrderPlaceError;
                }
                if (!status.Equals(enumStatus.OrderPlaceError) && !string.IsNullOrEmpty(symbol))
                {
                    List <Order> companies = MatchMeDB.Instance.OrderTable.ContainsKey(userId) ? MatchMeDB.Instance.OrderTable[userId] : new List <Order>();
                    exist = companies.Where(a => a.Symbol.Equals(symbol)).Count() > 0;
                    if (!exist)
                    {
                        message = string.Format("Error: The Company does not exist {0}", symbol);
                        status  = enumStatus.OrderPlaceError;
                    }
                }
                else
                {
                    message = string.Format("Error: The Company does not exist {0}", symbol);
                    status  = enumStatus.OrderPlaceError;
                }
                if (!status.Equals(enumStatus.OrderPlaceError) && !Enum.TryParse(OrderSide, true, out orderside))
                {
                    message = string.Format("Error: Invalid Order Side: {0}", OrderSide);
                    status  = enumStatus.OrderPlaceError;
                }
                if (!status.Equals(enumStatus.OrderPlaceError) && !Enum.TryParse(OrderType, true, out ordertype))
                {
                    message = string.Format("Error: Invalid Order Type: {0}", OrderType);
                    status  = enumStatus.OrderPlaceError;
                }
                if (!status.Equals(enumStatus.OrderPlaceError) && ordertype.Equals(enumOrderType.Market))
                {
                    price = Exchange.Instance.GetMarketPrice(orderside, symbol, volume);
                }
                if (!status.Equals(enumStatus.OrderPlaceError) && ordertype.Equals(enumOrderType.Limit))
                {
                    if (!double.TryParse(Price, out price))
                    {
                        message = string.Format("Error: Invalid Price: {0}", Price);
                        status  = enumStatus.OrderPlaceError;
                    }
                    if (!status.Equals(enumStatus.OrderPlaceError) && orderside.Equals(enumSide.Sell))
                    {
                        price = (-1) * Math.Abs(price);
                    }
                }

                if (!status.Equals(enumStatus.OrderPlaceError) && !string.IsNullOrEmpty(UserName))
                {
                    MatchMeDB.Instance.UserTable.TryGetValue(UserName, out user);
                    if (user == null)
                    {
                        message = string.Format("Error: Can't retrieve the User from the db via the keys. UserName{0}, UserId{1}", UserName, UserId);
                        status  = enumStatus.OrderPlaceError;
                    }
                }
                if (!status.Equals(enumStatus.OrderPlaceError) && string.IsNullOrEmpty(message) && exist)
                {
                    if (price > 0)
                    {
                        //price larger than zero means that it's a buy limit order or an order with valid market price
                        requiredbalance = price * volume + Config.Commission;
                    }
                    if (requiredbalance > user.Balance)
                    {
                        //check if balance is enough
                        remainbalance = requiredbalance - user.Balance;
                        message       = string.Format("Error: No Enough Balance: Remain balance {0}, Requires {1} to place the order", user.Balance, remainbalance);
                        status        = enumStatus.Rejected;
                    }
                    else
                    {
                        Order newOrder = new Order(symbol, volume, price, user.Id, ordertype, orderside);
                        if (orderside.Equals(enumSide.Sell))
                        {
                            status = Exchange.Instance.PlaceSell(newOrder);
                            if (status.Equals(enumStatus.Rejected))
                            {
                                message = string.Format("Error: Short Sell is not allowed. {0}", newOrder);
                            }
                        }
                        else if (orderside.Equals(enumSide.Buy))
                        {
                            status = Exchange.Instance.PlaceBuy(newOrder);
                        }
                        if (!status.Equals(enumStatus.OrderPlaceError) && string.IsNullOrEmpty(message))
                        {
                            message = "New Order Placed:" + MatchMeDB.Instance.Orders[newOrder.Id];
                            status  = enumStatus.OrderPlaced;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ServerLog.LogException(ex, string.Format("Place Order Failed, User {0}, Symbol {1}", user.ToString(), Symbol));
                message = ex.Message;
                status  = enumStatus.OrderPlaceError;
            }
            var result = new Dictionary <string, string> {
                { "status", status.ToString() }, { "message", message }
            };

            return(JsonConvert.SerializeObject(result));
        }