Esempio n. 1
0
        /// <summary>
        /// 创建一个今日委托记录
        /// </summary>
        /// <param name="registerTable">登记表实体</param>
        /// <param name="intNum">分红过户量</param>里
        /// <returns>今日委托实体</returns>
        private static XH_TodayEntrustTableInfo GetHistoryEntrustTable(XH_MelonCutRegisterTableInfo registerTable, int intNum)
        {
            XH_TodayEntrustTableInfo todayEntrustTable = new XH_TodayEntrustTableInfo();

            todayEntrustTable.EntrustNumber  = XHCommonLogic.BuildXHOrderNo();
            todayEntrustTable.CurrencyTypeId = registerTable.TradeCurrencyType;
            todayEntrustTable.TradeUnitId    = MCService.GetPriceUnit(registerTable.Code);
            todayEntrustTable.EntrustAmount  = intNum;
            todayEntrustTable.EntrustPrice   = 0;
            todayEntrustTable.EntrustTime    = DateTime.Now;
            todayEntrustTable.OfferTime      = DateTime.Now;

            todayEntrustTable.BuySellTypeId = (int)GTA.VTS.Common.CommonObject.Types.TransactionDirection.Buying;
            todayEntrustTable.OrderStatusId = (int)Types.OrderStateType.DOSDealed;
            todayEntrustTable.StockAccount  = registerTable.UserAccountDistributeLogo;//持仓账号,在分红记录中都是持仓账号
            //====通过持仓账号查询相关联的资金账号
            UA_UserAccountAllocationTableDal  dal    = new UA_UserAccountAllocationTableDal();
            UA_UserAccountAllocationTableInfo uaUser = dal.GetUserHoldAccountByUserCapitalAccount(registerTable.UserAccountDistributeLogo);

            todayEntrustTable.CapitalAccount = uaUser.UserAccountDistributeLogo;
            //=====
            todayEntrustTable.PortfolioLogo     = "";
            todayEntrustTable.SpotCode          = registerTable.Code;
            todayEntrustTable.TradeAmount       = intNum;
            todayEntrustTable.TradeAveragePrice = 0;
            todayEntrustTable.CancelAmount      = 0;
            todayEntrustTable.IsMarketValue     = false;
            todayEntrustTable.OrderMessage      = "股票分红生成委托记录";
            todayEntrustTable.McOrderId         = Guid.NewGuid().ToString();

            return(todayEntrustTable);
        }
        private bool PO_HoldValidate_Sell(ref string strMessage)
        {
            bool result = false;

            strMessage = "GT-2220:[现货委托持久化]卖持仓检查,无持仓";

            var ahtMemory = MemoryDataManager.XHHoldMemoryList.GetByHoldAccountAndCurrencyType(HoldingAccount, Code,
                                                                                               CurrencyType);

            if (ahtMemory == null)
            {
                ahtMemory = XHCommonLogic.GetHoldMemoryTable(HoldingAccount, Code, CurrencyType);
            }

            if (ahtMemory == null)
            {
                return(false);
            }

            var aht = ahtMemory.Data;

            if (aht == null)
            {
                return(false);
            }

            /*update 李健华 2009-12-11===========
             * 当程序没有加载持仓时第一次为-1,那么这里在内部从数据库获取持仓表的主键持仓账户ID时获取到了数据并加载到了内
             * 存表中,那么这里也应把持仓账户ID附值回这里,要不然在数据库提交时会有主外键的冲突,如果不设置数据库的主外键那么
             *这里可以不用修改,因为后面清算的时候是以委托编号去查询相关的冻结记录
             */
            if (HoldingAccountId == -1)
            {
                HoldingAccountId = aht.AccountHoldLogoId;
            }
            //======================

            strMessage = "GT-2221:[现货委托持久化]卖持仓检查,无足够可用持仓";
            int position = Convert.ToInt32(aht.AvailableAmount);

            //持仓帐户是否存在判断
            if (ValidateCenter.ValidateStockMinVolumeOfBusiness(Request, position, ref strMessage))
            {
                //已经统一使用撮合单位了
                decimal orderAmount = Convert.ToDecimal(Request.OrderAmount); // *unitMultiple;
                //可用持仓>=委托量
                result = aht.AvailableAmount >= orderAmount;
            }

            if (result)
            {
                strMessage = "";
            }

            return(result);
        }
        private bool PO_HoldValidate_Buy(ref string strMessage)
        {
            bool result = false;

            strMessage = "GT-2219:[现货委托持久化]买持仓检查,超过持仓限制";

            int     position     = 0;
            decimal freezeAmount = 0;


            var ahtMemory = MemoryDataManager.XHHoldMemoryList.GetByAccountHoldLogoId(HoldingAccountId);

            if (ahtMemory == null)
            {
                ahtMemory = XHCommonLogic.GetHoldMemoryTable(HoldingAccount, Code, CurrencyType);
            }

            if (ahtMemory != null)
            {
                var aht = ahtMemory.Data;
                if (aht != null)
                {
                    /*update 李健华 2009-12-11===========
                     * 当程序没有加载持仓时第一次为-1,那么这里在内部从数据库获取持仓表的主键持仓账户ID时获取到了数据并加载到了内
                     * 存表中,那么这里也应把持仓账户ID附值回这里,要不然在数据库提交时会有主外键的冲突,如果不设置数据库的主外键那么
                     *这里可以不用修改,因为后面清算的时候是以委托编号去查询相关的冻结记录
                     */
                    if (HoldingAccountId == -1)
                    {
                        HoldingAccountId = aht.AccountHoldLogoId;
                    }
                    //======================
                    position     = Convert.ToInt32(aht.AvailableAmount);
                    freezeAmount = aht.FreezeAmount;
                }
            }

            if (ValidateCenter.ValidateStockMinVolumeOfBusiness(Request, position, ref strMessage))
            {
                //获取持仓限制
                Decimal pLimit = MCService.GetPositionLimit(Request.Code).PositionValue;
                //可用持仓+冻结量+委托量<持仓限制
                result = pLimit >= position + freezeAmount +
                         Convert.ToDecimal(Request.OrderAmount);
            }

            //成功时需要清空错误信息。
            if (result)
            {
                strMessage = "";
            }

            return(result);
        }
        /// <summary>
        /// 检验并持久化柜台委托单
        /// </summary>
        /// <param name="strMessage">错误消息</param>
        /// <param name="outEntity">柜台持久化后的对象</param>
        /// <returns>是否成功</returns>
        private bool PersistentOrder(ref XH_TodayEntrustTableInfo outEntity, ref string strMessage)
        {
            #region 初始化参数

            //取代码对应品种的交易币种
            if (!GetCurrencyType())
            {
                strMessage = "GT-2226:[现货委托持久化]无法获取交易币种";
                return(false);
            }

            if (CurrencyType == -1)
            {
                strMessage = "GT-2226:[现货委托持久化]无法获取交易币种";
                return(false);
            }

            //预成交金额
            decimal predealCapital = 0;
            //预成交费用
            decimal predealCost = 0;

            //预成交总金额(根据买卖的不同,不一定=predealCapital+predealCost)
            decimal preDealSum = 0;

            //资金及持仓帐户
            string strHoldingAccount;
            string strCapitalAccount;

            //依据交易员及委托信息取对应资金及持仓帐户
            if (!CheckAccount(out strCapitalAccount, out strHoldingAccount, out strMessage))
            {
                return(false);
            }

            GetAccountId(strCapitalAccount, strHoldingAccount);

            if (CapitalAccountId == -1)
            {
                strMessage = "GT-2227:[现货委托持久化]无法获取资金帐号ID";
                return(false);
            }

            #endregion

            #region 检查

            try
            {
                //计算预成交金额和预成交费用
                if (!this.PO_ComputePreCapital(ref strMessage, ref predealCapital, ref predealCost))
                {
                    PO_ValidateFailureProcess(ref strMessage);
                    return(false);
                }

                //四舍五入
                predealCapital = Utils.Round(predealCapital);
                predealCost    = Utils.Round(predealCost);

                //1.资金检查
                if (
                    !this.PO_CapitalValidate(predealCost, predealCapital, ref strMessage))
                {
                    PO_ValidateFailureProcess(ref strMessage);
                    return(false);
                }

                //2.持仓检查
                if (!PO_HoldValidate(ref strMessage))
                {
                    PO_ValidateFailureProcess(ref strMessage);
                    return(false);
                }
            }
            catch (Exception ex)
            {
                strMessage = ex.Message;
                PO_ValidateFailureProcess(ref strMessage);
                return(false);
            }

            #endregion

            #region 创建委托(处理失败时要删除此条委托)

            try
            {
                EntrustNumber = XHCommonLogic.BuildXhOrder(ref outEntity, Request, HoldingAccount, CapitalAccount,
                                                           CurrencyType,
                                                           ref strMessage);
            }
            catch (Exception ex)
            {
                DeleteEntrust(EntrustNumber);
                LogHelper.WriteError(ex.Message, ex);
                strMessage = "GT-2225:[现货委托持久化]无法创建委托";
                LogHelper.WriteDebug(strMessage + ":" + outEntity);

                return(false);
            }

            #endregion

            #region Persist流程

            //persistent流程
            //1.资金处理,可用资金减去预成交总金额,总冻结资金加上预成交总金额
            //2.冻结资金处理,生成一条冻结记录
            //3.持仓处理:只有卖出时才会有持仓处理,可用持仓减少委托量,总冻结持仓增加委托量
            //4.持仓冻结处理:只有卖出时才会有持仓冻结处理,生成一条冻结记录

            //实际处理:
            //2.4放在一个事务中进行,当成功后再进行1.3的处理
            bool isSuccess = false;

            #region 资金预处理


            var caMemory = MemoryDataManager.XHCapitalMemoryList.GetByCapitalAccountLogo(CapitalAccountId);

            if (caMemory == null)
            {
                strMessage = "GT-2211:[现货委托持久化]资金帐户不存在:" + CapitalAccount;

                return(false);
            }

            if (Request.BuySell == GTA.VTS.Common.CommonObject.Types.TransactionDirection.Buying)
            {
                //预成交总金额 = 预成交金额 + 预成交费用
                preDealSum = predealCapital + predealCost;
            }
            else
            {
                //预成交总金额 = 预成交费用(卖不需要加金额)
                preDealSum = predealCost;
            }

            XH_CapitalAccountTable_DeltaInfo capitalDelta = new XH_CapitalAccountTable_DeltaInfo();
            capitalDelta.CapitalAccountLogo      = caMemory.Data.CapitalAccountLogo;
            capitalDelta.AvailableCapitalDelta   = -preDealSum;
            capitalDelta.FreezeCapitalTotalDelta = preDealSum;

            //return caMemory.AddDelta(-preDealCapitalAmount, preDealCapitalAmount, 0, 0);
            //return caMemory.AddDelta(capitalDelta);

            #endregion

            #region 持仓预处理(买入不处理)
            decimal                       orderAmount = Convert.ToDecimal(Request.OrderAmount);
            XHHoldMemoryTable             ahtMemory   = null;
            XH_AccountHoldTableInfo_Delta holdDelta   = null;
            if (Request.BuySell == GTA.VTS.Common.CommonObject.Types.TransactionDirection.Selling)
            {
                ahtMemory = MemoryDataManager.XHHoldMemoryList.GetByAccountHoldLogoId(HoldingAccountId);
                if (ahtMemory == null)
                {
                    ahtMemory = XHCommonLogic.GetHoldMemoryTable(HoldingAccount, Code, CurrencyType);
                }

                if (ahtMemory == null)
                {
                    strMessage = "GT-2212:[现货委托持久化]持仓帐户不存在:" + HoldingAccount;
                    return(false);
                }

                holdDelta = new XH_AccountHoldTableInfo_Delta();
                var holdData = ahtMemory.Data;
                holdDelta.AccountHoldLogoId    = holdData.AccountHoldLogoId;
                holdDelta.AvailableAmountDelta = -orderAmount;
                holdDelta.FreezeAmountDelta    = orderAmount;
                holdDelta.Data = holdData;
            }

            #endregion

            #region 数据库提交动作

            bool     isCapitalSuccess = false;
            bool     isHoldingSuccess = false;
            Database database         = DatabaseFactory.CreateDatabase();
            try
            {
                using (DbConnection connection = database.CreateConnection())
                {
                    connection.Open();
                    DbTransaction transaction = connection.BeginTransaction();
                    try
                    {
                        ReckoningTransaction tm = new ReckoningTransaction();
                        tm.Database    = database;
                        tm.Transaction = transaction;
                        //1.资金处理
                        //首先提交资金到数据库
                        isCapitalSuccess = caMemory.CheckAndAddDelta(CapitalCheck, capitalDelta, database, transaction);
                        if (!isCapitalSuccess)
                        {
                            strMessage = "GT-2218:[现货委托持久化]资金检查,无足够可用资金";
                            throw new CheckException("XHCapitalMemoryTable.CheckAddAddDelta失败");
                        }

                        //2.冻结资金处理,生成一条冻结记录
                        PO_BuildCapitalFreezeRecord(predealCapital, predealCost, Request.BuySell, tm);

                        //3.持仓冻结处理:只有卖出是才会有持仓处理
                        if (Request.BuySell ==
                            GTA.VTS.Common.CommonObject.Types.TransactionDirection.Selling)
                        {
                            //持仓冻结处理,生成一条冻结记录
                            PO_BuildHoldFreezeRecord(tm);
                        }

                        //4.持仓处理
                        if (Request.BuySell == GTA.VTS.Common.CommonObject.Types.TransactionDirection.Selling)
                        {
                            isHoldingSuccess = ahtMemory.CheckAndAddDelta(HodingCheck, holdDelta, tm.Database, tm.Transaction);
                            if (!isHoldingSuccess)
                            {
                                strMessage  = holdMessage;
                                holdMessage = "";
                                throw new CheckException("XHHoldingMemoryTable.CheckAddAddDelta失败");
                            }
                        }

                        transaction.Commit();
                        isSuccess = true;
                    }
                    catch (Exception ex)
                    {
                        transaction.Rollback();
                        LogHelper.WriteError(ex.Message, ex);
                        if (!(ex is CheckException))
                        {
                            strMessage = "GT-2213:[现货委托持久化]持久化失败,无法提交到数据库";
                        }
                        isSuccess = false;
                    }
                }
            }
            catch (Exception ex)
            {
                strMessage = "GT-2214:[现货委托持久化]持久化失败";
                LogHelper.WriteError(ex.Message, ex);
            }

            //事务失败
            if (!isSuccess)
            {
                DeleteEntrust(EntrustNumber);

                if (isCapitalSuccess)
                {
                    caMemory.RollBackMemory(capitalDelta);
                }

                if (Request.BuySell == GTA.VTS.Common.CommonObject.Types.TransactionDirection.Selling)
                {
                    if (isHoldingSuccess)
                    {
                        ahtMemory.RollBackMemory(holdDelta);
                    }
                }


                return(false);
            }

            //if(isSuccess)
            //{
            //    //当提交资金、持仓 到数据库成功后,同步到内存
            //    caMemory.AddDeltaToMemory(capitalDelta);
            //    if (Request.BuySell == CommonObject.Types.TransactionDirection.Selling)
            //    {
            //        ahtMemory.AddDeltaToMemory(holdDelta);
            //    }
            //}
            //else
            //{
            //    DeleteEntrust(EntrustNumber);
            //    return false;
            //}

            #endregion


            #endregion

            return(true);
        }