public Order(int accountUid, enumSide side, int price, int amount) { Uid = UidCount; UidCount++; AccountUid = accountUid; Time = DateTime.UtcNow.ToString(); Side = side; Price = price; Amount = amount; if (price == SellMarketOrderPrice || price == BuyMarketOrderPrice) { FufillType = enumFufillType.MKT; } else { FufillType = enumFufillType.LMT; } }
public Order(string symbol, int volume, double price, string userId, enumOrderType orderType, enumSide orderSide) : this() { Symbol = symbol; Volume = volume; if (orderSide.Equals(enumSide.Buy)) { Price = Math.Abs(price); } if (orderSide.Equals(enumSide.Sell)) { Price = -Math.Abs(price); } UserID = userId; OrderType = orderType; OrderSide = orderSide; OrderStatus = enumStatus.Initial; //OrderType = enumOrderType.Market; //OrderSide = enumSide.Buy; }
/// <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); }
//private string MatchMe(ExchangeOrder eo, Order order) //{ // //return string.Empty; // List<ExchangeOrder> liveOrders = null; // string OrderId = string.Empty; // if (order.OrderSide.Equals(enumSide.Buy) && Sells.ContainsKey(order.Symbol)) // liveOrders = sells[order.Symbol]; // if (order.OrderSide.Equals(enumSide.Sell) && Buys.ContainsKey(order.Symbol)) // liveOrders = buys[order.Symbol]; // if (order.OrderType == enumOrderType.Market) // { // foreach (ExchangeOrder target in liveOrders) // { // OrderId = target.Id; // break; // } // } // else // { // foreach (ExchangeOrder target in liveOrders) // { // if (order.OrderSide.Equals(enumSide.Buy) && target.Offer >= eo.Offer) // { // OrderId = target.Id; break; // } // else if (order.OrderSide.Equals(enumSide.Sell) && target.Offer <= eo.Offer) // { // OrderId = target.Id; break; // } // } // } // return OrderId; //} public double GetMarketPrice(enumSide side, string Symbol, int volume) { double marketPrice = side.Equals(enumSide.Buy) ? 65535.0 : 0.0; if (side.Equals(enumSide.Buy) && sells.ContainsKey(Symbol)) { marketPrice = sells[Symbol].OrderByDescending(a => a.Offer).FirstOrDefault().Offer; } if (side.Equals(enumSide.Sell) && buys.ContainsKey(Symbol)) { marketPrice = buys[Symbol].OrderBy(a => a.Offer).FirstOrDefault().Offer; } if (side.Equals(enumSide.Buy)) { marketPrice = Math.Abs(marketPrice); } if (side.Equals(enumSide.Sell)) { marketPrice = -Math.Abs(marketPrice); } return(marketPrice); }
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)); }