/// <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); // } //} }
/// <summary> /// Place a buy order /// </summary> /// <param name="order"></param> public enumStatus PlaceBuy(Order order) { if (MatchMeDB.Instance.AddOrder(order).Equals(enumStatus.OrderPlaced)) { order.OrderStatus = enumStatus.PendingNew; MatchMeDB.Instance.UpdateOrder(order); } if (!order.OrderSide.Equals(enumSide.Buy)) { ServerLog.LogError("Exchange: This is for the buy Orders, don't insert Others to here"); throw new InvalidOperationException("Exchange: This is for the Buy Orders, don't insert Others to here"); } ExchangeOrder newExOrder = new ExchangeOrder(order.Volume, order.Price, order.Id, order.Created); List <ExchangeOrder> matchedSell = new List <ExchangeOrder>(); MatchBuy(order.Symbol, newExOrder, out matchedSell); Order orderInDB = new Order(MatchMeDB.Instance.Orders[order.Id]); int matchedQuantity = matchedSell != null && matchedSell.Count > 0 ? matchedSell.Sum(a => a.Volume) : 0; if (newExOrder.Volume.Equals(matchedQuantity)) { orderInDB.OrderStatus = enumStatus.Filled; } else { orderInDB.OrderStatus = matchedQuantity > 0 ? enumStatus.PartiallyFilled : enumStatus.New; if (!Buys.ContainsKey(order.Symbol)) { Buys[order.Symbol] = new List <ExchangeOrder>(); } Buys[order.Symbol].Add(newExOrder); } MatchMeDB.Instance.UpdateOrder(orderInDB); if (matchedQuantity > 0) { //Update Balance and balance; 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 matchedSell) { Order matchedInDB = new Order(MatchMeDB.Instance.Orders[matched.OrderId]); if (matchedInDB.Volume.Equals(matched.Volume)) { matchedInDB.OrderStatus = enumStatus.Filled; int index = sells[order.Symbol].Select(a => a.Id).ToList().IndexOf(matched.Id); sells[order.Symbol].RemoveAt(index); } else { int index = sells[order.Symbol].Select(a => a.Id).ToList().IndexOf(matched.Id); sells[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 (!buys.ContainsKey(order.Symbol)) //{ // eo = new ExchangeOrder(1, order.Price, order.Id, order.Created); // List<ExchangeOrder> orderList = new List<ExchangeOrder>(); // orderList.Add(eo); // buys.Add(order.Symbol, orderList); // for (int vol = 2; vol <= order.Volume; vol++) // { // buys[order.Symbol].Add(eo); // } //} //else //{ // eo = new ExchangeOrder(1, order.Price, order.Id, order.Created); // for (int vol = 1; vol <= order.Volume; vol++) // { // buys[order.Symbol].Add(eo); // } //} //buys[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); //} //*********************************** }