/// <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)); }