public async Task <bool> SellStock(UserStocks stock, decimal price)
        {
            var user = await _context.Users.FirstOrDefaultAsync(u => u.Id == stock.UserId);

            UserStocks checkingStock = await _context.UserStocks.Where(us => us.UserId == stock.UserId && us.CompanyCode == stock.CompanyCode).FirstOrDefaultAsync();

            if (checkingStock == null)
            {
                throw new Exception("You do not have any units of this company");
            }

            var stockExchnage = await _context.Users.FirstOrDefaultAsync(u => u.Username.ToLower() == Extensions.STOCK_EXCHANGE);

            var stockExchnageStocks = await _context.UserStocks.FirstOrDefaultAsync(us => us.UserId == stockExchnage.Id && us.CompanyCode == stock.CompanyCode);

            stockExchnageStocks.OwnedUnits += stock.OwnedUnits;

            if (stock.OwnedUnits > checkingStock.OwnedUnits)
            {
                throw new Exception("You have too few units");
            }
            else if (stock.OwnedUnits == checkingStock.OwnedUnits)
            {
                _context.UserStocks.Remove(checkingStock);
            }
            else
            {
                checkingStock.OwnedUnits -= stock.OwnedUnits;
            }

            user.AvailableMoney += stock.OwnedUnits * price;
            await _context.SaveChangesAsync();

            return(true);
        }
Esempio n. 2
0
        public async Task <IActionResult> SellStock(UserStocks stock)
        {
            var id = int.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value);

            stock.UserId = id;
            FpResponse unitsPrice = await Extensions.GetUnitsValue();

            decimal unitPrice = Extensions.RoundDown(unitsPrice.items.Select(i => i.Price).FirstOrDefault(), 2);

            var fpStockData = unitsPrice.items.FirstOrDefault(x => x.Code == stock.CompanyCode);

            if (fpStockData == null)
            {
                return(BadRequest("There is no company with this name"));
            }
            else if (stock.OwnedUnits % fpStockData.Unit != 0)
            {
                return(BadRequest("Wrong quantity of units"));
            }

            var sellStock = await _repo.SellStock(stock, unitPrice);

            if (sellStock == false)
            {
                return(BadRequest("Wrong data!"));
            }
            return(Ok(true));
        }
 // Get User Portolio Information from the database
 public void UpdateUserPortfolio(String user, String symbol, String quantity)
 {
     if (dbContext.UserStock.Where(c => c.user.Equals(user) && c.symbol.Equals(symbol)).Count() == 0)
     {
         UserStocks stock = new UserStocks();
         stock.user     = user;
         stock.symbol   = symbol;
         stock.quantity = quantity;
         dbContext.UserStock.Add(stock);
     }
     else
     {
         IQueryable <UserStocks> userStockList = dbContext.UserStock.Where(c => c.user.Equals(user) && c.symbol.Equals(symbol));
         String oldQuantity             = userStockList.First().quantity;
         userStockList.First().quantity = (int.Parse(oldQuantity) + int.Parse(quantity)) + "";
     }
     dbContext.SaveChanges();
 }
        public async Task <bool> BuyStock(UserStocks stock, decimal price)
        {
            var user = await _context.Users.FirstOrDefaultAsync(u => u.Id == stock.UserId);

            var stockExchnage = await _context.Users.FirstOrDefaultAsync(u => u.Username.ToLower() == Extensions.STOCK_EXCHANGE);

            var stockExchnageStocks = await _context.UserStocks.FirstOrDefaultAsync(us => us.UserId == stockExchnage.Id && us.CompanyCode == stock.CompanyCode);

            if (stockExchnageStocks.OwnedUnits < stock.OwnedUnits)
            {
                throw new Exception("Stock exchnage have too few units");
            }
            else
            {
                stockExchnageStocks.OwnedUnits -= stock.OwnedUnits;
            }

            if (stock.OwnedUnits * price > user.AvailableMoney)
            {
                throw new Exception("You have too few money");
            }
            user.AvailableMoney -= stock.OwnedUnits * price;
            UserStocks checkingStock = await _context.UserStocks.Where(us => us.UserId == stock.UserId && us.CompanyCode == stock.CompanyCode).FirstOrDefaultAsync();

            if (checkingStock == null)
            {
                await _context.UserStocks.AddAsync(stock);
            }
            else
            {
                checkingStock.OwnedUnits += stock.OwnedUnits;
            }
            await _context.SaveChangesAsync();

            return(true);
        }
Esempio n. 5
0
        /// <summary>
        /// ������֤���Ʊ
        /// </summary>
        /// <param name="SZRate"></param>
        /// <param name="userFund"></param>
        /// <param name="userOrder"></param>
        /// <param name="userStock"></param>
        /// <param name="dBoughtAmount"></param>
        /// <returns></returns>
        private bool BuySZ(ref SjshqDBFRecord SZRate, ref UserFund userFund, ref UserOrders userOrder, ref UserStocks userStock, out double dBoughtAmount)
        {
            try
            {
                dBoughtAmount = 0;
                if (userOrder.UserID != userFund.UserID || userStock.UserID != userFund.UserID)
                    return false;
                else if (!userOrder.Side || userOrder.OrdStatus != OrderStatus.Waiting || userFund.UserID != userOrder.UserID)
                    return false;
                else if (userOrder.OrderVolume < 0)
                    return false;
                else if (SZRate.SellingVal1 < 0.001 || SZRate.LatestPrice < 0.001)
                    return false;
                UserFund tmpFund = userFund;
                UserOrders tmpOrder = userOrder;
                UserStocks tmpStock = userStock;
                dBoughtAmount = Common.ConvertPrice((tmpOrder.OrderVolume * SZRate.SellingVal1) * (1 + defaultBuyTax));
                if (Common.ComparePrice(userFund.Cash, dBoughtAmount) >= 0)
                {
                    tmpFund.UsableCash += Common.ConvertPrice((tmpOrder.OrderVolume * tmpOrder.OrderPrice) * (1 + defaultBuyTax));
                    tmpFund.UsableCash -= Common.ConvertPrice(dBoughtAmount);

                    Synchronizer.FundHistory fundHistory = new Synchronizer.FundHistory(); fundHistory.Initialize();
                    fundHistory.UserID = userFund.UserID; fundHistory.OrderID = userOrder.OrderID;
                    fundHistory.OriginalCash = Common.ConvertPrice(userFund.Cash);
                    tmpFund.Cash -= Common.ConvertPrice(dBoughtAmount);
                    fundHistory.ChangedCash = Common.ConvertPrice(tmpFund.Cash - fundHistory.OriginalCash);
                    fundHistory.Curr = tmpOrder.Curr;
                    Common.DBSync.FundChanged(fundHistory, userFund.UserID);

                    if (tmpStock.Volume + tmpOrder.OrderVolume > 0)
                        tmpStock.AveragePrice = Common.ConvertPrice(
                            ((tmpStock.AveragePrice * tmpStock.Volume) + (SZRate.SellingVal1 * tmpOrder.OrderVolume))
                            / (tmpStock.Volume + tmpOrder.OrderVolume) * (1 + defaultBuyTax));
                    else
                        tmpStock.AveragePrice = 0;
                    tmpStock.Volume += tmpOrder.OrderVolume;
                    tmpStock.Curr = tmpOrder.Curr;

                    if (GetStockType(tmpOrder.StockCode, StockMarket.Shenzhen) == StockType.SZ_Warrant)
                        tmpStock.Sellable = true;
                    else
                        tmpStock.Sellable = false;
                    if (tmpFund.UsableCash < 0)
                        tmpFund.UsableCash = 0;
                }
                else
                {
                    tmpOrder.UpdatedDate = DateTime.Now;
                    tmpOrder.OrdStatus = OrderStatus.Failure;
                    Common.DBSync.RecordError(tmpOrder, "(SZ)���㣺Currency-" + userFund.Curr.ToString().Trim() + "/Cash-" +
                        userFund.Cash.ToString("f3").Trim() + "/Cost-" + dBoughtAmount.ToString("f3").Trim());
                }

                if (tmpOrder.OrdStatus != OrderStatus.Failure)
                {
                    tmpOrder.TradePrice = Common.ConvertPrice(SZRate.SellingVal1);
                    if (tmpOrder.OrdType == OrderType.ImmediateOrder)
                        tmpOrder.OrderPrice = 0;
                    tmpOrder.UpdatedDate = DateTime.Now;
                    tmpOrder.OrdStatus = OrderStatus.Finished;
                    userFund = tmpFund;
                    userStock = tmpStock;
                }
                userOrder = tmpOrder;
                if (userOrder.OrdStatus == OrderStatus.Finished)
                    return true;
                else
                    return false;
            }
            catch
            {
                dBoughtAmount = 0;
                return false;
            }
        }
Esempio n. 6
0
 /// <summary>
 /// �����û���Ʊ
 /// </summary>
 /// <param name="listUserStocks"></param>
 /// <param name="userStock"></param>
 /// <returns></returns>
 private bool UpdateUserStock(ref List<UserStocks> listUserStocks, UserStocks userStock)
 {
     try
     {
         if (listUserStocks == null)
             return false;
         bool bExist = false;
         for (int i = 0; i < listUserStocks.Count; i++)
         {
             if (listUserStocks[i].UserID == userStock.UserID
                 && string.Compare(userStock.StockCode.Trim()
                 , listUserStocks[i].StockCode.Trim()) == 0
                 && userStock.Market == listUserStocks[i].Market
                 && userStock.Sellable == listUserStocks[i].Sellable)
             {
                 bExist = true;
                 if (userStock.Volume > 0)
                     listUserStocks[i] = userStock;
                 else
                     listUserStocks.RemoveAt(i--);
                 break;
             }
         }
         if (!bExist && userStock.Volume > 0)
             listUserStocks.Add(userStock);
         return true;
     }
     catch
     {
         return false;
     }
 }
Esempio n. 7
0
        /// <summary>
        /// ������ת����
        /// </summary>
        private void Trading()
        {
            try
            {
                ushort uFlag = 0;
                List<int> listUserOrdersKeys = new List<int>();
                //�ʽ𣬶������ֹɽԲ�Ϊ��ʱ��ϵͳ�������
                while (bTrading && mapUserFund != null && mapUserOrders != null && mapUserStocks != null)
                {
                    try
                    {
                        if (!Management.Work || Common.IsWeekend)
                        {
                            Thread.Sleep(30000);
                            continue;
                        }
                        else
                        {
                            //���ڽӿڿ���ʱ��
                            if (Common.IsInInterfaceQuotationTime)
                            {
                                //ͳ�ƻ����еļ�ʱ�������޼۶���������������ί����
                                int ICount = 0, LCount = 0, CCount = 0;
                                if (++uFlag % 500 == 0 && GetTotalWaitingOrdersCount(out ICount, out LCount, out CCount))
                                {
                                    Common.Log("--- Orders in Buffer (Total: " + (ICount + LCount + CCount) + ") ---" + Environment.NewLine +
                                        "[ImmediateOrder=" + ICount + "] [LimitedOrder=" + LCount + "] [CancelOrder=" + CCount + "]");
                                    uFlag = 0;
                                }
                            }
                            //���ڽ���ʱ�Σ�����ʱ��ֱ�Ӻ���
                            if (DateTime.Now.TimeOfDay < Common.BeginAMTS
                                || DateTime.Now.TimeOfDay > Common.EndPMTS.Add(new TimeSpan(0, 5, 0)))
                            {
                                Thread.Sleep(30000);
                                continue;
                            }
                        }
                        //���������Ϣ
                        if (Common.stkQuotation != null && mapUserOrders.Count > 0 && Common.stkQuotation.GetSnapShot())
                        {
                            int nOrderID = -1;
                            listUserOrdersKeys.Clear();
                            Show2003DBFRecord SHRate = new Show2003DBFRecord(); SHRate.Clear();
                            SjshqDBFRecord SZRate = new SjshqDBFRecord(); SZRate.Clear();
                            foreach (object objKey in mapUserOrders.Keys)
                            {
                                if (objKey == null)
                                    continue;
                                nOrderID = Convert.ToInt32(objKey);
                                if (nOrderID < 0 || !mapUserOrders.ContainsKey(nOrderID))
                                    continue;
                                listUserOrdersKeys.Add(nOrderID);//���붩��ID�������������
                            }
                            //�Լ��뵽����������еĶ������д���
                            foreach (int OrderKey in listUserOrdersKeys)
                            {
                                try
                                {
                                    if (!mapUserOrders.ContainsKey(OrderKey))
                                        continue;
                                    UserOrders userOrder = mapUserOrders[OrderKey];

                                    if (!mapUserFund.ContainsKey(userOrder.UserID))
                                        continue;
                                    Dictionary<byte, UserFund> mapCurrFund = mapUserFund[userOrder.UserID];

                                    if (!mapCurrFund.ContainsKey((byte)userOrder.Curr))
                                        continue;
                                    UserFund userFund = mapCurrFund[(byte)userOrder.Curr];

                                    if (userOrder.StockCode == null
                                        || userOrder.StockCode.Trim().Length <= 0
                                        || userOrder.Market == StockMarket.Unknown
                                        || userOrder.OrdStatus == OrderStatus.Unknown)
                                    {
                                        mapUserOrders.Remove(OrderKey);
                                    }
                                    else if (userOrder.OrdStatus != OrderStatus.Waiting
                                        && userOrder.OrdStatus != OrderStatus.Cancelling)
                                    {
                                        continue;
                                    }
                                    else
                                    {
                                        if (userOrder.ExpiredDate < DateTime.Now
                                            && (userOrder.OrdStatus == OrderStatus.Waiting
                                            || userOrder.OrdStatus == OrderStatus.Cancelling))
                                        {
                                            #region �ö����ѹ���
                                            userOrder.OrdStatus = OrderStatus.Failure;
                                            userOrder.UpdatedDate = DateTime.Now;
                                            Common.DBSync.RecordError(userOrder, "���ڶ�����" + userOrder.ExpiredDate.ToString("yyyy-MM-dd HH:mm:ss").Trim());
                                            if (userOrder.OrdType == TradingSystem.OrderType.LimitedOrder)
                                            {
                                                userFund.UsableCash += Common.ConvertPrice((userOrder.OrderPrice * userOrder.OrderVolume) * (1 + Common.stkTrading.defaultBuyTax));
                                                if (!Common.DBSync.FundUpdate(userFund, userOrder.UserID))
                                                    continue;
                                                SetUserFund(userFund.UserID, userFund);
                                            }
                                            if (Common.DBSync.OrderChanged(mapCurrFund[(byte)userFund.Curr], userOrder, new UserStocks()))
                                            {
                                                lock (mapUserFund)
                                                    mapUserFund[userOrder.UserID] = mapCurrFund;
                                                lock (mapUserOrders)
                                                    mapUserOrders[OrderKey] = userOrder;
                                                Common.Debug("Order Status Changed [" + userOrder.OrdStatus.ToString() + "] [UserID=" + userOrder.UserID + "] [OrderID=" + userOrder.OrderID + "].");
                                            }
                                            #endregion
                                        }
                                        else if (userOrder.OrdStatus == OrderStatus.Cancelling)
                                        {
                                            #region ȡ������
                                            if (userOrder.OrdType == OrderType.LimitedOrder)
                                            {
                                                userOrder.OrdStatus = OrderStatus.Cancelled;
                                                userOrder.UpdatedDate = DateTime.Now;
                                                if (Common.DBSync.OrderChanged(mapCurrFund[(byte)userFund.Curr], userOrder, new UserStocks()))
                                                {
                                                    mapUserOrders[userOrder.OrderID] = userOrder;
                                                    if (userOrder.Side)
                                                    {
                                                        UserFund usableFund = mapCurrFund[(byte)userFund.Curr];
                                                        usableFund.UsableCash += Common.ConvertPrice((userOrder.OrderVolume * userOrder.OrderPrice) * (1 + defaultBuyTax));
                                                        SetUserFund(usableFund.UserID, usableFund);
                                                        Common.DBSync.FundUpdate(usableFund, userOrder.UserID);
                                                    }
                                                    Common.Debug("Order Status Changed [" + userOrder.OrdStatus.ToString() + "] [UserID=" + userOrder.UserID + "] [OrderID=" + userOrder.OrderID + "].");
                                                }
                                                else
                                                {
                                                    userOrder.OrdStatus = OrderStatus.Failure;
                                                    userOrder.UpdatedDate = DateTime.Now;
                                                    lock (mapUserOrders)
                                                        mapUserOrders[userOrder.OrderID] = userOrder;
                                                    Common.DBSync.RecordError(userOrder, "����ʧ�ܣ��û�ID-" + userOrder.UserID + "������ID-" + userOrder.OrderID);
                                                }
                                            }
                                            else
                                            {
                                                userOrder.OrdStatus = OrderStatus.Failure;
                                                userOrder.UpdatedDate = DateTime.Now;
                                                lock (mapUserOrders)
                                                    mapUserOrders[userOrder.OrderID] = userOrder;
                                                Common.DBSync.RecordError(userOrder, "��Ч�������û�ID-" + userOrder.UserID + "������ID-" + userOrder.OrderID);
                                            }
                                            #endregion
                                        }
                                        else if (userOrder.OrdStatus == OrderStatus.Waiting &&
                                          !Common.stkQuotation.GetStkRate(userOrder.StockCode, userOrder.Market, out SHRate, out SZRate))
                                        {
                                            #region �޷��������
                                            userOrder.OrdStatus = OrderStatus.Failure;
                                            userOrder.UpdatedDate = DateTime.Now;
                                            Common.DBSync.RecordError(userOrder, "�޷�������飺" + userOrder.StockCode.Trim() + "-" + userOrder.Market.ToString().Trim());
                                            if (userOrder.OrdType == TradingSystem.OrderType.LimitedOrder)
                                            {
                                                userFund.UsableCash += Common.ConvertPrice((userOrder.OrderPrice * userOrder.OrderVolume) * (1 + Common.stkTrading.defaultBuyTax));
                                                SetUserFund(userFund.UserID, userFund);
                                                if (!Common.DBSync.FundUpdate(userFund, userOrder.UserID))
                                                    continue;
                                            }
                                            if (Common.DBSync.OrderChanged(mapCurrFund[(byte)userFund.Curr], userOrder, new UserStocks()))
                                            {
                                                lock (mapUserFund)
                                                    mapUserFund[userOrder.UserID] = mapCurrFund;
                                                lock (mapUserOrders)
                                                    mapUserOrders[OrderKey] = userOrder;
                                                Common.Debug("Order Status Changed [" + userOrder.OrdStatus.ToString() + "] [UserID=" + userOrder.UserID + "] [OrderID=" + userOrder.OrderID + "].");
                                            }
                                            #endregion
                                        }
                                        else if (userOrder.OrdStatus == OrderStatus.Waiting &&
                                            (userOrder.Market == StockMarket.Shanghai && (SHRate.LatestPrice < 0.001 || SHRate.OpenPrice < 0.001))
                                            || (userOrder.Market == StockMarket.Shenzhen && (SZRate.LatestPrice < 0.001 || SZRate.OpenPrice < 0.001)))
                                        {
                                            #region �ù�Ʊͣ��
                                            userOrder.OrdStatus = OrderStatus.Failure;
                                            userOrder.UpdatedDate = DateTime.Now;
                                            Common.DBSync.RecordError(userOrder, "ͣ�ƹ�Ʊ��" + userOrder.StockCode.Trim() + "-" + userOrder.Market.ToString().Trim());
                                            if (userOrder.OrdType == TradingSystem.OrderType.LimitedOrder)
                                            {
                                                userFund.UsableCash += Common.ConvertPrice((userOrder.OrderPrice * userOrder.OrderVolume) * (1 + Common.stkTrading.defaultBuyTax));
                                                SetUserFund(userFund.UserID, userFund);
                                                if (!Common.DBSync.FundUpdate(userFund, userOrder.UserID))
                                                    continue;
                                            }
                                            if (Common.DBSync.OrderChanged(mapCurrFund[(byte)userFund.Curr], userOrder, new UserStocks()))
                                            {
                                                lock (mapUserFund)
                                                    mapUserFund[userOrder.UserID] = mapCurrFund;
                                                lock (mapUserOrders)
                                                    mapUserOrders[OrderKey] = userOrder;
                                                Common.Debug("Order Status Changed [" + userOrder.OrdStatus.ToString() + "] [UserID=" + userOrder.UserID + "] [OrderID=" + userOrder.OrderID + "].");
                                            }
                                            #endregion
                                        }
                                        else
                                        {
                                            if (userOrder.OrdStatus == OrderStatus.Waiting)
                                            {
                                                double dBargainAmount = 0;
                                                List<UserStocks> listUserStocks = new List<UserStocks>();
                                                if (mapUserStocks.ContainsKey(userOrder.UserID))
                                                    listUserStocks = mapUserStocks[userOrder.UserID];
                                                else
                                                    mapUserStocks[userOrder.UserID] = new List<UserStocks>();
                                                UserStocks userStock = new UserStocks(); userStock.Initialize();
                                                bool bExist = false;
                                                for (int i = 0; i < listUserStocks.Count; i++)
                                                {
                                                    if (listUserStocks[i].UserID == userOrder.UserID
                                                        && string.Compare(userOrder.StockCode.Trim()
                                                        , listUserStocks[i].StockCode.Trim()) == 0
                                                        && userOrder.Market == listUserStocks[i].Market
                                                        && ((!userOrder.Side && listUserStocks[i].Sellable)
                                                        || (userOrder.Side && !listUserStocks[i].Sellable)))
                                                    {
                                                        bExist = true;
                                                        userStock = listUserStocks[i];
                                                        break;
                                                    }
                                                }
                                                if (!bExist)
                                                {
                                                    userStock.UserID = userOrder.UserID;
                                                    userStock.StockCode = userOrder.StockCode.Trim();
                                                    userStock.Market = userOrder.Market;
                                                    userStock.Sellable = false;
                                                }

                                                switch (userOrder.OrdType)
                                                {
                                                    #region  �м۽���
                                                    case OrderType.ImmediateOrder:
                                                        {
                                                            Common.Debug("--- [ImmediateOrder] Received. ---");
                                                            if (userOrder.Side)
                                                            {
                                                                // ����
                                                                if (userOrder.Market == StockMarket.Shanghai)
                                                                {
                                                                    if (SHRate.SellingVal1 < 0.001 || Common.ComparePrice(SHRate.HighestPrice, SHRate.LowestPrice) <= 0)
                                                                    {
                                                                        userOrder.OrderPrice = SHRate.SellingVal1;
                                                                        if (Common.ComparePrice(userFund.UsableCash, (SHRate.SellingVal1 * userOrder.OrderVolume) * (1 + defaultBuyTax)) < 0)
                                                                        {
                                                                            userOrder.OrdStatus = OrderStatus.Failure;
                                                                            userOrder.UpdatedDate = DateTime.Now;
                                                                        }
                                                                        else
                                                                        {
                                                                            userOrder.OrdType = OrderType.LimitedOrder;
                                                                            Common.DBSync.OrderChanged(userFund, userOrder, new UserStocks());
                                                                            userFund.UsableCash -= Common.ConvertPrice((userOrder.OrderPrice * userOrder.OrderVolume) * (1 + defaultBuyTax) + 0.0099);
                                                                            Common.DBSync.FundUpdate(userFund, userOrder.UserID);
                                                                            mapCurrFund[(byte)userFund.Curr] = userFund;
                                                                            mapUserFund[userOrder.UserID] = mapCurrFund;
                                                                            mapUserOrders[OrderKey] = userOrder;
                                                                            Common.Debug("Order Type Changed [" + userOrder.OrdType.ToString() + "] [UserID=" + userOrder.UserID + "] [OrderID=" + userOrder.OrderID + "].");
                                                                        }
                                                                    }
                                                                    else
                                                                    {
                                                                        userOrder.OrderPrice = SHRate.SellingVal1;
                                                                        if (Common.ComparePrice(userFund.UsableCash, (SHRate.SellingVal1 * userOrder.OrderVolume) * (1 + defaultBuyTax)) < 0)
                                                                        {
                                                                            userOrder.OrdStatus = OrderStatus.Failure;
                                                                            userOrder.UpdatedDate = DateTime.Now;
                                                                        }
                                                                        else if (BuySH(ref SHRate, ref userFund, ref userOrder, ref userStock, out dBargainAmount))
                                                                        {
                                                                            UpdateUserStock(ref listUserStocks, userStock);
                                                                            userFund.UsableCash -= Common.ConvertPrice((SHRate.SellingVal1 * userOrder.OrderVolume) * (1 + defaultBuyTax) + 0.0099);
                                                                            Common.DBSync.FundUpdate(userFund, userOrder.UserID);
                                                                        }
                                                                    }
                                                                }
                                                                else if (userOrder.Market == StockMarket.Shenzhen)
                                                                {
                                                                    if (SZRate.SellingVal1 < 0.001 || Common.ComparePrice(SZRate.HighestPrice, SZRate.LowestPrice) <= 0)
                                                                    {
                                                                        userOrder.OrderPrice = SZRate.SellingVal1;
                                                                        if (Common.ComparePrice(userFund.UsableCash, (SZRate.SellingVal1 * userOrder.OrderVolume) * (1 + defaultBuyTax)) < 0)
                                                                        {
                                                                            userOrder.OrdStatus = OrderStatus.Failure;
                                                                            userOrder.UpdatedDate = DateTime.Now;
                                                                        }
                                                                        else
                                                                        {
                                                                            userOrder.OrdType = OrderType.LimitedOrder;
                                                                            Common.DBSync.OrderChanged(userFund, userOrder, new UserStocks());
                                                                            userFund.UsableCash -= Common.ConvertPrice((userOrder.OrderPrice * userOrder.OrderVolume) * (1 + defaultBuyTax) + 0.0099);
                                                                            Common.DBSync.FundUpdate(userFund, userOrder.UserID);
                                                                            mapCurrFund[(byte)userFund.Curr] = userFund;
                                                                            mapUserFund[userOrder.UserID] = mapCurrFund;
                                                                            mapUserOrders[OrderKey] = userOrder;
                                                                            Common.Debug("Order Type Changed [" + userOrder.OrdType.ToString() + "] [UserID=" + userOrder.UserID + "] [OrderID=" + userOrder.OrderID + "].");
                                                                        }
                                                                    }
                                                                    else
                                                                    {
                                                                        userOrder.OrderPrice = SHRate.SellingVal1;
                                                                        if (Common.ComparePrice(userFund.UsableCash, (SHRate.SellingVal1 * userOrder.OrderVolume) * (1 + defaultBuyTax)) < 0)
                                                                        {
                                                                            userOrder.OrdStatus = OrderStatus.Failure;
                                                                            userOrder.UpdatedDate = DateTime.Now;
                                                                        }
                                                                        else if (BuySZ(ref SZRate, ref userFund, ref userOrder, ref userStock, out dBargainAmount))
                                                                        {
                                                                            UpdateUserStock(ref listUserStocks, userStock);
                                                                            userFund.UsableCash -= Common.ConvertPrice((SZRate.SellingVal1 * userOrder.OrderVolume) * (1 + defaultBuyTax) + 0.0099);
                                                                            Common.DBSync.FundUpdate(userFund, userOrder.UserID);
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                            else
                                                            {
                                                                // ���
                                                                if (userOrder.Market == StockMarket.Shanghai)
                                                                {
                                                                    if (SHRate.BuyingVal1 < 0.001 || Common.ComparePrice(SHRate.HighestPrice, SHRate.LowestPrice) <= 0)
                                                                    {
                                                                        userOrder.OrderPrice = SHRate.BuyingVal1;
                                                                        userOrder.OrdType = OrderType.LimitedOrder;
                                                                        Common.DBSync.OrderChanged(userFund, userOrder, new UserStocks());
                                                                        mapUserOrders[OrderKey] = userOrder;
                                                                        Common.Debug("Order Type Changed [" + userOrder.OrdType.ToString() + "] [UserID=" + userOrder.UserID + "] [OrderID=" + userOrder.OrderID + "].");
                                                                    }
                                                                    else if (SellSH(ref SHRate, ref userFund, ref userOrder, ref userStock, out dBargainAmount))
                                                                    {
                                                                        userOrder.OrderPrice = SHRate.BuyingVal1;
                                                                        UpdateUserStock(ref listUserStocks, userStock);
                                                                        Common.DBSync.FundUpdate(userFund, userOrder.UserID);
                                                                    }
                                                                }
                                                                else if (userOrder.Market == StockMarket.Shenzhen)
                                                                {
                                                                    if (SZRate.BuyingVal1 < 0.001 || Common.ComparePrice(SZRate.HighestPrice, SZRate.LowestPrice) <= 0)
                                                                    {
                                                                        userOrder.OrderPrice = SZRate.BuyingVal1;
                                                                        userOrder.OrdType = OrderType.LimitedOrder;
                                                                        Common.DBSync.OrderChanged(userFund, userOrder, new UserStocks());
                                                                        mapUserOrders[OrderKey] = userOrder;
                                                                        Common.Debug("Order Type Changed [" + userOrder.OrdType.ToString() + "] [UserID=" + userOrder.UserID + "] [OrderID=" + userOrder.OrderID + "].");
                                                                    }
                                                                    else if (SellSZ(ref SZRate, ref userFund, ref userOrder, ref userStock, out dBargainAmount))
                                                                    {
                                                                        userOrder.OrderPrice = SZRate.BuyingVal1;
                                                                        UpdateUserStock(ref listUserStocks, userStock);
                                                                        Common.DBSync.FundUpdate(userFund, userOrder.UserID);
                                                                    }
                                                                }
                                                            }
                                                        }
                                                        break;
                                                    #endregion
                                                    #region �޼۽���
                                                    case OrderType.LimitedOrder:
                                                        {
                                                            if (userOrder.Side)
                                                            {
                                                                // ����
                                                                if (userOrder.Market == StockMarket.Shanghai && SHRate.SellingVal1 >= 0.001
                                                                    && Common.ComparePrice(SHRate.HighestPrice, SHRate.LowestPrice) > 0
                                                                    && Common.ComparePrice(SHRate.SellingVal1, userOrder.OrderPrice) <= 0)
                                                                {
                                                                    if (IsOrderValid(ref SHRate, ref userFund, ref userOrder) &&
                                                                        BuySH(ref SHRate, ref userFund, ref userOrder, ref userStock, out dBargainAmount))
                                                                        UpdateUserStock(ref listUserStocks, userStock);
                                                                    Common.DBSync.FundUpdate(userFund, userOrder.UserID);
                                                                }
                                                                else if (userOrder.Market == StockMarket.Shenzhen && SZRate.SellingVal1 >= 0.001
                                                                    && Common.ComparePrice(SZRate.HighestPrice, SZRate.LowestPrice) > 0
                                                                    && Common.ComparePrice(SZRate.SellingVal1, userOrder.OrderPrice) <= 0)
                                                                {
                                                                    if (IsOrderValid(ref SZRate, ref userFund, ref userOrder) &&
                                                                        BuySZ(ref SZRate, ref userFund, ref userOrder, ref userStock, out dBargainAmount))
                                                                        UpdateUserStock(ref listUserStocks, userStock);
                                                                    Common.DBSync.FundUpdate(userFund, userOrder.UserID);
                                                                }
                                                            }
                                                            else
                                                            {
                                                                // ���
                                                                if (userOrder.Market == StockMarket.Shanghai && SHRate.BuyingVal1 >= 0.001
                                                                    && Common.ComparePrice(SHRate.HighestPrice, SHRate.LowestPrice) > 0
                                                                    && Common.ComparePrice(SHRate.BuyingVal1, userOrder.OrderPrice) >= 0)
                                                                {
                                                                    if (IsOrderValid(ref SHRate, ref userFund, ref userOrder) &&
                                                                        SellSH(ref SHRate, ref userFund, ref userOrder, ref userStock, out dBargainAmount))
                                                                        UpdateUserStock(ref listUserStocks, userStock);
                                                                    Common.DBSync.FundUpdate(userFund, userOrder.UserID);
                                                                }
                                                                else if (userOrder.Market == StockMarket.Shenzhen
                                                                    && SZRate.BuyingVal1 >= 0.001 && Common.ComparePrice(SZRate.HighestPrice, SZRate.LowestPrice) > 0
                                                                    && Common.ComparePrice(SZRate.BuyingVal1, userOrder.OrderPrice) >= 0)
                                                                {
                                                                    if (IsOrderValid(ref SZRate, ref userFund, ref userOrder) &&
                                                                        SellSZ(ref SZRate, ref userFund, ref userOrder, ref userStock, out dBargainAmount))
                                                                        UpdateUserStock(ref listUserStocks, userStock);
                                                                    Common.DBSync.FundUpdate(userFund, userOrder.UserID);
                                                                }
                                                            }
                                                        }
                                                        break;
                                                    #endregion
                                                    default:
                                                        {
                                                            userOrder.OrdStatus = OrderStatus.Failure;
                                                            userOrder.UpdatedDate = DateTime.Now;
                                                            Common.DBSync.RecordError(userOrder, "δ֪�Ķ������ͣ�" + userOrder.OrdType.ToString().Trim());
                                                            lock (mapUserOrders)
                                                                mapUserOrders[OrderKey] = userOrder;
                                                        }
                                                        break;
                                                }

                                                if (userOrder.OrdStatus != OrderStatus.Waiting
                                                    && Common.DBSync.OrderChanged(userFund, userOrder, userStock))
                                                {
                                                    SetUserFund(userFund.UserID, userFund);
                                                    lock (mapUserOrders)
                                                        mapUserOrders[OrderKey] = userOrder;
                                                    lock (mapUserStocks)
                                                        mapUserStocks[userOrder.UserID] = listUserStocks;
                                                    Common.Debug("Order Status Changed [" + userOrder.OrdStatus.ToString() + "] [UserID=" + userOrder.UserID + "] [OrderID=" + userOrder.OrderID + "].");
                                                }
                                            }
                                            else
                                                Common.Log("Illegal Order Status [" + userOrder.OrdStatus.ToString() + "] [UserID=" + userOrder.UserID + "] [OrderID=" + userOrder.OrderID + "].");
                                        }
                                    }
                                }
                                catch (Exception err)
                                {
                                    Common.Log(err);
                                }
                            }
                        }

                        lock (listNewUserFund)
                        {
                            if (listNewUserFund.Count > 0)
                            {
                                for (int i = 0; i < listNewUserFund.Count; i++)
                                {
                                    if (!mapUserFund.ContainsKey(listNewUserFund[i].UserID))
                                    {
                                        mapUserFund[listNewUserFund[i].UserID] = new Dictionary<byte, UserFund>();
                                        Dictionary<byte, UserFund> mapCurrFund = mapUserFund[listNewUserFund[i].UserID];
                                        mapCurrFund[(byte)listNewUserFund[i].Curr] = listNewUserFund[i];
                                        mapUserFund[listNewUserFund[i].UserID] = mapCurrFund;
                                    }
                                    else if (!mapUserFund[listNewUserFund[i].UserID].ContainsKey((byte)listNewUserFund[i].Curr))
                                    {
                                        Dictionary<byte, UserFund> mapCurrFund = mapUserFund[listNewUserFund[i].UserID];
                                        mapCurrFund[(byte)listNewUserFund[i].Curr] = listNewUserFund[i];
                                        mapUserFund[listNewUserFund[i].UserID] = mapCurrFund;
                                    }
                                }
                                listNewUserFund.Clear();
                            }
                        }

                        lock (listNewUserOrders)
                        {
                            if (listNewUserOrders.Count > 0)
                            {
                                for (int i = 0; i < listNewUserOrders.Count; i++)
                                {
                                    if (!mapUserOrders.ContainsKey(listNewUserOrders[i].OrderID))
                                        mapUserOrders[listNewUserOrders[i].OrderID] = listNewUserOrders[i];
                                }
                                listNewUserOrders.Clear();
                            }
                        }
                    }
                    catch (Exception err)
                    {
                        Common.Log(err);
                    }
                    Thread.Sleep(1000);
                }
            }
            catch (Exception err)
            {
                Common.Log(err);
                if (Common.DBSync != null)
                    Common.DBSync.Uninitialize(mapUserFund, mapUserOrders, mapUserStocks);
                Common.Log("Error: The Trading Thread Has Crashed !");
            }
        }
Esempio n. 8
0
        /// <summary>
        /// �����֤���Ʊ
        /// </summary>
        /// <param name="SZRate"></param>
        /// <param name="userFund"></param>
        /// <param name="userOrder"></param>
        /// <param name="userStock"></param>
        /// <param name="dSoldAmount"></param>
        /// <returns></returns>
        private bool SellSZ(ref SjshqDBFRecord SZRate, ref UserFund userFund, ref UserOrders userOrder, ref UserStocks userStock, out double dSoldAmount)
        {
            try
            {
                dSoldAmount = 0;
                if (userOrder.UserID != userFund.UserID || userStock.UserID != userFund.UserID)
                    return false;
                else if (userOrder.Side || userOrder.OrdStatus != OrderStatus.Waiting || userFund.UserID != userOrder.UserID)
                    return false;
                else if (userOrder.OrderVolume < 0)
                    return false;
                else if (SZRate.BuyingVal1 < 0.001 || SZRate.LatestPrice < 0.001)
                    return false;
                UserFund tmpFund = userFund;
                UserOrders tmpOrder = userOrder;
                UserStocks tmpStock = userStock;
                dSoldAmount = Common.ConvertPrice((tmpOrder.OrderVolume * SZRate.BuyingVal1) * (1 - defaultSellTax));
                if (tmpStock.Volume >= tmpOrder.OrderVolume)
                {
                    tmpStock.Volume -= tmpOrder.OrderVolume;

                    Synchronizer.FundHistory fundHistory = new Synchronizer.FundHistory(); fundHistory.Initialize();
                    fundHistory.UserID = userFund.UserID; fundHistory.OrderID = userOrder.OrderID;
                    fundHistory.OriginalCash = Common.ConvertPrice(userFund.Cash);
                    tmpFund.Cash += Common.ConvertPrice(dSoldAmount);
                    fundHistory.ChangedCash = Common.ConvertPrice(tmpFund.Cash - fundHistory.OriginalCash);
                    fundHistory.Curr = tmpOrder.Curr;
                    Common.DBSync.FundChanged(fundHistory, userFund.UserID);

                    tmpFund.UsableCash += Common.ConvertPrice(dSoldAmount);
                    if (tmpStock.Volume > 0)
                        tmpStock.AveragePrice = Common.ConvertPrice(
                            ((tmpStock.AveragePrice * tmpStock.Volume) + (SZRate.BuyingVal1 * tmpOrder.OrderVolume))
                            / (tmpStock.Volume + tmpOrder.OrderVolume) * (1 + defaultSellTax));
                    else
                        tmpStock.AveragePrice = 0;
                    if (tmpFund.Cash < 0)
                        tmpFund.Cash = 0;
                    if (tmpFund.UsableCash < 0)
                        tmpFund.UsableCash = 0;
                }
                else
                {
                    tmpOrder.UpdatedDate = DateTime.Now;
                    tmpOrder.OrdStatus = OrderStatus.Failure;
                    Common.DBSync.RecordError(tmpOrder, "(SZ)��ɲ��㣺Volume" +
                        tmpStock.Volume.ToString().Trim() + "/Cost-" + tmpOrder.OrderVolume.ToString().Trim());
                }

                if (tmpOrder.OrdStatus != OrderStatus.Failure)
                {
                    tmpOrder.TradePrice = Common.ConvertPrice(SZRate.BuyingVal1);
                    if (tmpOrder.OrdType == OrderType.ImmediateOrder)
                        tmpOrder.OrderPrice = 0;
                    tmpOrder.UpdatedDate = DateTime.Now;
                    tmpOrder.OrdStatus = OrderStatus.Finished;
                    userFund = tmpFund;
                    userStock = tmpStock;
                }
                userOrder = tmpOrder;
                if (userOrder.OrdStatus == OrderStatus.Finished)
                    return true;
                else
                    return false;
            }
            catch
            {
                dSoldAmount = 0;
                return false;
            }
        }
Esempio n. 9
0
        public StockSellStatus SellStock(string userId, SellStockViewModel sellStockModel)
        {
            // check if user change the form data, provided stock value has to exists in database
            StockValue sellingStockValue = GetStockForCodeAndValue(
                sellStockModel.Code, sellStockModel.Unit, sellStockModel.Price);

            if (sellingStockValue == null)
            {
                return(StockSellStatus.Unknown);
            }
            decimal totalCost = sellStockModel.AmountToSell / sellingStockValue.Unit * sellingStockValue.Price;

            // case 1: User does not have enough stock
            User       seller             = _db.UserApp.Where(x => x.Id.Equals(userId)).FirstOrDefault();
            UserStocks stockOwnedBySeller = seller.Stocks
                                            .Where(x => x.StockID == sellingStockValue.StockID)
                                            .FirstOrDefault();

            if (stockOwnedBySeller == null || stockOwnedBySeller.Amount < sellStockModel.AmountToSell)
            {
                return(StockSellStatus.UserHasNotEnoughStocks);
            }

            // case 2: Stock value data have changed - there was an update
            StockDetails latestStockDetails = GetLatestStockDetails(sellStockModel.Code);
            bool         isSellerSellingStockByLatestPrice = AreDatesTheSameComparisonLikeHuman(
                latestStockDetails.PublicationDate, sellingStockValue.PublicationDate);

            if (isSellerSellingStockByLatestPrice == false)
            {
                return(StockSellStatus.StockValueDataHaveChanged);
            }

            using (var dbContextTransaction = _db.Database.BeginTransaction())
            {
                try
                {
                    // then 1: Add money to User wallet
                    seller.Money += totalCost;

                    // then 2: Subtract specified amount of stock from UserStocks
                    stockOwnedBySeller.Amount -= sellStockModel.AmountToSell;
                    if (stockOwnedBySeller.Amount == 0)
                    {
                        _db.UserStocks.Remove(stockOwnedBySeller);
                    }

                    //then 3: Increase available stock amount
                    _db.Stock.Attach(sellingStockValue.Stock);
                    _db.Entry(sellingStockValue.Stock).Reload();
                    sellingStockValue.Stock.AvailableAmount += sellStockModel.AmountToSell;
                    _db.Entry(sellingStockValue.Stock).State = System.Data.Entity.EntityState.Modified;

                    // save and commit
                    _db.SaveChanges();
                    dbContextTransaction.Commit();
                    return(StockSellStatus.Success); // everything went well, so finally success
                }
                catch (Exception e)
                {
                    _logger.Error("Transaction error during selling stock. Error " + e.Message);
                    _logger.Error("Rollback...");
                    dbContextTransaction.Rollback();
                }
            }

            return(StockSellStatus.Unknown);
        }
Esempio n. 10
0
        public StockBuyStatus BuyStock(string userId, BuyStockViewModel buyStockModel)
        {
            // check if user change the form data, provided stock value has to exists in database
            StockValue purchasingStockValue = GetStockForCodeAndValue(buyStockModel.Code, buyStockModel.Unit, buyStockModel.Price);

            if (purchasingStockValue == null)
            {
                return(StockBuyStatus.Unknown);
            }
            decimal totalCost = buyStockModel.AmountToBuy / purchasingStockValue.Unit * purchasingStockValue.Price;

            // case 1: User does not have enough money
            User buyer = _db.UserApp.Where(x => x.Id.Equals(userId) && x.Money >= totalCost)
                         .FirstOrDefault();

            if (buyer == null)
            {
                return(StockBuyStatus.UserHasNotEnoughMoney);
            }
            // case 2: Stock Exchange does not have enough stock
            if (purchasingStockValue.Stock.AvailableAmount < buyStockModel.AmountToBuy)
            {
                return(StockBuyStatus.AmountNotAvailable);
            }

            // case 3: Stock value data have changed - there was an update
            StockDetails latestStockDetails = GetLatestStockDetails(buyStockModel.Code);
            bool         isBuyerBuyingStockByLatestPrice = AreDatesTheSameComparisonLikeHuman(
                latestStockDetails.PublicationDate, purchasingStockValue.PublicationDate);

            if (isBuyerBuyingStockByLatestPrice == false)
            {
                return(StockBuyStatus.StockValueDataHaveChanged);
            }

            using (var dbContextTransaction = _db.Database.BeginTransaction())
            {
                try
                {
                    // then 1: Subtract money from User wallet
                    buyer.Money -= totalCost;

                    // then 2: Add specified amount of stock to UserStocks
                    UserStocks stockOwnedByBuyer = buyer.Stocks.FirstOrDefault(
                        x => x.StockID == purchasingStockValue.StockID);
                    if (stockOwnedByBuyer != null)
                    {
                        stockOwnedByBuyer.Amount          += buyStockModel.AmountToBuy;
                        _db.Entry(stockOwnedByBuyer).State = System.Data.Entity.EntityState.Modified;
                    }
                    else
                    {
                        stockOwnedByBuyer = new UserStocks
                        {
                            UserID  = userId,
                            StockID = purchasingStockValue.StockID,
                            Amount  = buyStockModel.AmountToBuy
                        };
                        _db.UserStocks.Add(stockOwnedByBuyer);
                    }

                    // then 3: Decrease available stock amount
                    _db.Stock.Attach(purchasingStockValue.Stock);
                    _db.Entry(purchasingStockValue.Stock).Reload();
                    if (purchasingStockValue.Stock.AvailableAmount < buyStockModel.AmountToBuy)
                    {
                        _logger.Info("Rollback");
                        dbContextTransaction.Rollback();
                        return(StockBuyStatus.AmountNotAvailable);
                    }
                    purchasingStockValue.Stock.AvailableAmount -= buyStockModel.AmountToBuy;
                    _db.Entry(purchasingStockValue.Stock).State = System.Data.Entity.EntityState.Modified;

                    // save and commit
                    _db.SaveChanges();
                    dbContextTransaction.Commit();
                    return(StockBuyStatus.Success); // everything went well, so finally success
                }
                catch (Exception e)
                {
                    _logger.Error("Transaction error during buying stock. Error:" + e.Message);
                    _logger.Error("Rollback...");
                    dbContextTransaction.Rollback();
                }
            }

            return(StockBuyStatus.Unknown);
        }