Beispiel #1
0
        public string AddUser(string UserName, string Balance, string jsonInput)
        {
            User       user    = null;
            string     message = string.Empty;
            enumStatus status  = enumStatus.Unknown;
            double     balance = 0.0;

            try
            {
                if (!double.TryParse(Balance, out balance))
                {
                    message = string.Format("Error: Invalid Balance: {0}", Balance);
                }
                if (!string.IsNullOrEmpty(jsonInput))
                {
                    user = new User(jsonInput);
                }
                else
                {
                    user = new User(UserName, balance);
                }

                if (MatchMeDB.Instance.UserTable.ContainsKey(user.UserName) || MatchMeDB.Instance.Users.ContainsKey(user.Id))
                {
                    string existingUser = MatchMeDB.Instance.UserTable[user.UserName].ToString();
                    message = string.Format("Error: duplicate user. Existing User: {0} New User (rejected): {1}", existingUser, user.ToString());
                }
                if (string.IsNullOrEmpty(message))
                {
                    status = MatchMeDB.Instance.AddUser(user);
                    if (status.Equals(enumStatus.UserAdded))
                    {
                        message = string.Format("User Added: {0}", user.ToString());
                    }
                }
            }
            catch (Exception ex)
            {
                ServerLog.LogException(ex, string.Format("Add User: {0}", user.ToString()));
                message = ex.Message;
                status  = enumStatus.UserAddFailed;
            }
            var result = new Dictionary <string, string> {
                { "status", status.ToString() },
                { "message", message }
            };

            return(JsonConvert.SerializeObject(result));
        }
Beispiel #2
0
        public void Start()
        {
            AppDomain.CurrentDomain.UnhandledException += (o, ea) =>
            {
                if (ea.ExceptionObject is Exception)
                {
                    ServerLog.LogException(ea.ExceptionObject as Exception, "Unhandled exception handler called");
                }
                else
                {
                    ServerLog.LogError("Unhandled exception handler called with unrecognized exception objhect");
                }
            };

            ServerLog.LogInfo("Starting MatchMe Host");
            listener.Start();
            listener.BeginGetContext(OnContext, null);
        }
Beispiel #3
0
        private void ExceptionRespond(HttpListenerContext context, Exception e, int code, DateTime reqStartTime)
        {
            byte[] message = serverCharSet.GetBytes(
                string.Format("An {0} exception was thrown.\n{1}\n{2}", e.GetType(), e.Message, e.StackTrace));
            ServerLog.LogException(e, "An exception was thrown rendering URL " + context.Request.Url);

            System.Threading.Interlocked.Add(ref totalBytesOut, message.Length);
            if (code == 500)
            {
                System.Threading.Interlocked.Increment(ref total500s);
            }
            else if (code == 550)
            {
                System.Threading.Interlocked.Increment(ref total550s);
            }

            Respond(context, message, code, reqStartTime, "text/plain");
        }
Beispiel #4
0
        private void Respond(HttpListenerContext context, byte[] buffer, int returnCode, DateTime reqStartTime, string contentType = "text/plain")
        {
            int len = buffer != null ? buffer.Length : 0;

            try
            {
                context.Response.AddHeader("Cache-Control", "no-cache");
                context.Response.AddHeader("Content-Type", contentType);
                context.Response.AddHeader("Access-Control-Allow-Origin", "*");
                context.Response.ContentEncoding = serverCharSet;
                context.Response.ContentLength64 = len;
                context.Response.StatusCode      = returnCode;
                context.Response.OutputStream.Write(buffer, 0, len);
                context.Response.ContentType = contentType;

                ServerLog.LogHttpRequest(context.Request, returnCode, len, string.Empty, (int)((startTime - DateTime.Now).TotalMilliseconds));
                System.Threading.Interlocked.Add(ref totalBytesOut, buffer.Length);
                System.Threading.Interlocked.Increment(ref total200s);
            }
            catch (HttpListenerException hle)
            {
                ServerLog.LogException(hle, "Exception while returning data to http client");
            }
        }
Beispiel #5
0
        private void OnContext(IAsyncResult ar)
        {
            DateTime reqStartTime = DateTime.Now;

            HttpListenerContext context;

            try
            {
                context = listener.EndGetContext(ar);
            }
            catch (HttpListenerException)
            {
                ServerLog.LogInfo("HttpListener has been shut down");
                return;
            }

            if (!stopping)
            {
                listener.BeginGetContext(OnContext, null);
            }

            var processWebRequest = new Task(() =>
            {
                System.Threading.Interlocked.Increment(ref totalRequests);
                byte[] json           = null;
                int httpStatus        = 200;
                string redirectUrl    = null;
                string outContentType = "application/json";
                try
                {
                    string processor;
                    string command;
                    string jsonInput;

                    string module;
                    string contentType;
                    string source;
                    string agent;


                    var args = ParseUrl(context.Request, out processor, out command, out jsonInput, out module, out contentType, out source, out agent);

                    if (module == "test")
                    {
                        if (processor == "util")
                        {
                            if (command == "stats")
                            {
                                StatRespond(context, reqStartTime);
                            }
                            else if (command == "health")
                            {
                                HealthRespond(context, reqStartTime);
                            }
                            else
                            {
                                throw new ApplicationException(string.Format("Unknown util command: {0}", command));
                            }
                            return;
                        }
                    }
                    else if (module == "action")
                    {
                        string jsonString = actionProcessor.Execute(command, args, jsonInput, contentType, source, agent, out outContentType, out redirectUrl, out httpStatus);
                        if (jsonString == null)
                        {
                            jsonString = "";
                        }

                        json = Encoding.UTF8.GetBytes(jsonString);
                    }
                    else if (module == "db")
                    {
                        string jsonString = dataProcessor.Execute(command, args, jsonInput, contentType, source, agent, out outContentType, out redirectUrl, out httpStatus);
                        if (jsonString == null)
                        {
                            jsonString = "";
                        }

                        json = Encoding.UTF8.GetBytes(jsonString);
                    }
                    else
                    {
                        throw new ApplicationException(string.Format("Unknown module: {0}", module));
                    }
                }
                catch (Exception e)
                {
                    ExceptionRespond(context, e, 500, reqStartTime);
                    return;
                }

                if (redirectUrl != null)
                {
                    RespondRedirect(context, redirectUrl);
                }
                else
                {
                    Respond(context, json, httpStatus, reqStartTime, outContentType);
                }
            });

            lock (runningTasks)
            {
                if (stopping)
                {
                    Respond(context,
                            serverCharSet.GetBytes("MatchMe is shutting down.")
                            , 500, reqStartTime);
                    return;
                }

                runningTasks.Add(processWebRequest);
            }

            processWebRequest.ContinueWith(t =>
            {
                lock (runningTasks)
                {
                    runningTasks.Remove(t);
                }

                if (t.IsFaulted)
                {
                    ServerLog.LogException(t.Exception.InnerException, "Exception was unhandled in task");
                }
            });


            processWebRequest.Start();
        }
Beispiel #6
0
        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));
        }
Beispiel #7
0
        public string AddCompany(string Symbol, string Volume, string Price)
        {
            if (!MatchMeDB.Instance.UserTable.ContainsKey(Config.AdminUser))
            {
                User user = new User(Config.AdminUser, 0.0);
                MatchMeDB.Instance.AddUser(user);
            }
            string        message = string.Empty;
            double        price   = Config.DefaultPrice;
            int           volume  = Config.DefaultVolume;
            string        userId  = MatchMeDB.Instance.GetUserId(Config.AdminUser);
            var           status  = enumStatus.Unknown;
            enumOrderType ordertype;
            enumSide      orderside;

            try
            {
                Symbol = Symbol.ToUpper();
                if (string.IsNullOrEmpty(Price) || !double.TryParse(Price, out price))
                {
                    ServerLog.LogInfo(message);
                }
                if (string.IsNullOrEmpty(message) && (string.IsNullOrEmpty(Volume) || !int.TryParse(Volume, out volume)))
                {
                    ServerLog.LogInfo(message);
                }
                List <Order> companies = MatchMeDB.Instance.OrderTable.ContainsKey(userId) ? MatchMeDB.Instance.OrderTable[userId] : new List <Order>();
                foreach (Order company in companies)
                {
                    if (company.Symbol.Equals(Symbol))
                    {
                        message = string.Format("Error: duplicate company. Existing User: {0} New Company Symbol (rejected): {1}", company, Symbol);
                        status  = enumStatus.CompanyAddFailed;
                    }
                }
                ordertype = enumOrderType.Market;
                orderside = enumSide.Sell;
                price     = -Math.Abs(price);
                Order newOrder = new Order(Symbol, volume, price, userId, ordertype, orderside);
                if (string.IsNullOrEmpty(message) &&
                    Exchange.Instance.PlaceSell(newOrder, true).Equals(enumStatus.OrderPlaced))
                {
                    Position position = MatchMeDB.Instance.GetPosition(userId, Symbol);
                    position.Quantity = volume;
                    MatchMeDB.Instance.UpdatePosition(position);
                    message = string.Format("Company Created: {0}, Volume: {1}, Price: {2}", newOrder.Symbol, newOrder.Volume, newOrder.Price);
                    status  = enumStatus.CompanyAdded;
                }
            }
            catch (Exception ex)
            {
                ServerLog.LogException(ex, string.Format("Add Company, Symbol {0}, Volume {1}, Price", Symbol, Volume, price.ToString()));
                message = ex.Message;
                status  = enumStatus.CompanyAddFailed;
            }
            var result = new Dictionary <string, string> {
                { "status", status.ToString() },
                { "message", message }
            };

            return(JsonConvert.SerializeObject(result));
        }
Beispiel #8
0
        public string AdjustBalance(string UserName, string UserId, string AdjustAmount)
        {
            User       user    = null;
            string     message = string.Empty;
            enumStatus status  = enumStatus.Unknown;
            double     adjustAmount;

            try
            {
                if (!double.TryParse(AdjustAmount, out adjustAmount))
                {
                    message = string.Format("Error: Invalid adjustment: {0}", adjustAmount);
                    status  = enumStatus.BalanceAdjustFailed;
                }
                if (!string.IsNullOrEmpty(UserName))
                {
                    MatchMeDB.Instance.UserTable.TryGetValue(UserName, out user);
                }
                if (user == null && !string.IsNullOrEmpty(UserId))
                {
                    string userDoc = string.Empty;
                    MatchMeDB.Instance.Users.TryGetValue(UserId, out userDoc);
                    if (userDoc != null)
                    {
                        user = new User(userDoc);
                    }
                }
                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.BalanceAdjustFailed;
                }
                else
                {
                    //We found the User in DB, so we update it!
                    user.Balance += adjustAmount;
                    if (user.Balance < 0)
                    {
                        message = string.Format("Error: Balance less than 0. UserName{0}, UserId{1}", UserName, user.Balance);
                        status  = enumStatus.BalanceAdjustFailed;
                    }
                    status = MatchMeDB.Instance.UpdateUser(user);
                    if (status.Equals(enumStatus.BalanceAdjusted))
                    {
                        message = string.Format("Balance Adjusted. {0}", user.ToString());
                    }
                }
            }
            catch (Exception ex)
            {
                ServerLog.LogException(ex, string.Format("Add User: {0}", user.ToString()));
                message = ex.Message;
                status  = enumStatus.BalanceAdjustFailed;
            }
            var result = new Dictionary <string, string> {
                { "status", status.ToString() },
                { "message", message }
            };

            return(JsonConvert.SerializeObject(result));
        }