/// <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); }
/// <summary> /// /// </summary> /// <param name="order"></param> /// <param name="AdminMode">PlaceSell supports AdminMode to add company</param> public enumStatus PlaceSell(Order order, bool AdminMode = false) { if (!AdminMode && !CanSell(order)) { ServerLog.LogError("Exchange: ShortSell is not allowed"); return(enumStatus.Rejected); } if (MatchMeDB.Instance.AddOrder(order).Equals(enumStatus.OrderPlaced)) { order.OrderStatus = enumStatus.PendingNew; MatchMeDB.Instance.UpdateOrder(order); } if (!order.OrderSide.Equals(enumSide.Sell)) { ServerLog.LogError("Exchange: This is for the sell Orders, don't insert Others to here"); return(enumStatus.OrderPlaceError); } ExchangeOrder newExOrder = new ExchangeOrder(order.Volume, order.Price, order.Id, order.Created); List <ExchangeOrder> matchedBuy = new List <ExchangeOrder>(); MatchSell(order.Symbol, newExOrder, out matchedBuy); Order orderInDB = new Order(MatchMeDB.Instance.Orders[order.Id]); int matchedQuantity = matchedBuy != null && matchedBuy.Count > 0 ? matchedBuy.Sum(a => a.Volume) : 0; if (newExOrder.Volume.Equals(matchedQuantity)) { orderInDB.OrderStatus = enumStatus.Filled; } else { orderInDB.OrderStatus = matchedQuantity > 0 ? enumStatus.PartiallyFilled : enumStatus.New; if (!Sells.ContainsKey(order.Symbol)) { Sells[order.Symbol] = new List <ExchangeOrder>(); } Sells[order.Symbol].Add(newExOrder); } MatchMeDB.Instance.UpdateOrder(orderInDB); if (matchedQuantity > 0) { //Update balance and position; User user = new User(MatchMeDB.Instance.Users[orderInDB.UserID]); user.Balance -= newExOrder.Volume.Equals(matchedQuantity) ? matchedQuantity * order.Price + Config.Commission : matchedQuantity * order.Price; MatchMeDB.Instance.UpdateUser(user); Position position = MatchMeDB.Instance.GetPosition(orderInDB.UserID, orderInDB.Symbol); position.Quantity -= matchedQuantity; MatchMeDB.Instance.UpdatePosition(position); } foreach (ExchangeOrder matched in matchedBuy) { Order matchedInDB = new Order(MatchMeDB.Instance.Orders[matched.OrderId]); if (matchedInDB.Volume.Equals(matched.Volume)) { matchedInDB.OrderStatus = enumStatus.Filled; int index = buys[order.Symbol].Select(a => a.Id).ToList().IndexOf(matched.Id); buys[order.Symbol].RemoveAt(index); } else { int index = buys[order.Symbol].Select(a => a.Id).ToList().IndexOf(matched.Id); buys[order.Symbol][index].Volume -= matched.Volume; matchedInDB.OrderStatus = enumStatus.PartiallyFilled; matchedInDB.Volume -= matched.Volume; } User user = new User(MatchMeDB.Instance.Users[matchedInDB.UserID]); user.Balance -= user.UserName.Equals(Config.AdminUser) ? 0 : matchedInDB.Volume.Equals(matched.Volume) ? (matched.Volume * matched.Offer + Config.Commission) : matched.Volume * matched.Offer; MatchMeDB.Instance.UpdateUser(user); MatchMeDB.Instance.UpdateOrder(matchedInDB); Position position = MatchMeDB.Instance.GetPosition(matchedInDB.UserID, matchedInDB.Symbol); position.Quantity += matched.Volume; MatchMeDB.Instance.UpdatePosition(position); } return(enumStatus.OrderPlaced); //****************Jing Mai********** //if (!AdminMode) //{ // sells[order.Symbol].OrderBy(x => x.Offer).ThenBy(x => x.Created); // order.OrderStatus = enumStatus.PendingNew; // for (int vol = 1; vol <= order.Volume; vol++) // { // string MatcherOrderId = MatchMe(eo, order); // if (!string.IsNullOrEmpty(MatcherOrderId)) // FillOrders(order.Id, MatcherOrderId); // } //} }