/// <summary> /// 创建一个今日成交记录 /// </summary> /// <param name="registerTable">登记表实体</param> /// <param name="intNum">分红过户量</param>里 /// <returns>今日成交实体</returns> private static XH_TodayTradeTableInfo GetTodayTradeTable(XH_MelonCutRegisterTableInfo registerTable, int intNum) { XH_TodayTradeTableInfo todayTradeTable = new XH_TodayTradeTableInfo(); todayTradeTable.TradeNumber = Guid.NewGuid().ToString(); todayTradeTable.BuySellTypeId = (int)GTA.VTS.Common.CommonObject.Types.TransactionDirection.Buying; todayTradeTable.StockAccount = registerTable.UserAccountDistributeLogo; todayTradeTable.TradeTypeId = (int)Types.DealRptType.DRTTransfer; todayTradeTable.CurrencyTypeId = registerTable.TradeCurrencyType; todayTradeTable.TradeUnitId = MCService.GetPriceUnit(registerTable.Code); todayTradeTable.TradeAmount = intNum; todayTradeTable.TradeTime = DateTime.Now; CM_BourseType bourseType = MCService.CommonPara.GetBourseTypeByCommodityCode(registerTable.Code); if (bourseType != null) { } CM_Commodity commodity = MCService.CommonPara.GetCommodityByCommodityCode(registerTable.Code); todayTradeTable.SpotCode = registerTable.Code; if (commodity != null) { } CM_BreedClass breedClass = MCService.CommonPara.GetBreedClassByCommodityCode(registerTable.Code); if (breedClass != null) { } return(todayTradeTable); }
/// <summary> /// 检查期货合约是否过期 /// Update by: 董鹏 /// Update Date: 2010-03-29 /// Desc: 此方法没有进行最后交易日判断,同时存在另一个相同的方法,此处改为调用该方法。 /// </summary> /// <param name="code"></param> /// <returns></returns> public static bool CheckQHContractIsExpired(string code) { #region 没有做最后交易日的判断 //int year; //int month; //GetAgreementTime(code, out year, out month); //DateTime now = DateTime.Now; ////合约已过期 //if (year < now.Year) //{ // return true; //} ////本年度合约 //if (year == now.Year) //{ // //合约已过期 // if (month < now.Month) // { // return true; // } //} //return false; #endregion return(MCService.IsExpireLastedTradeDate(code)); }
/// <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); }
/// <summary> /// 更新资金表记录 /// </summary> /// <param name="cash">分红信息</param> /// <param name="accountTable">要更新的资金表实体</param> /// <param name="intNum">分红金额</param> private static void SetAccountTable(XH_AccountHoldTableInfo accountTable, int intNum) { //if (accountTable.AvailableAmount < 0.00m) // accountTable.AvailableAmount = 0; //原有的量 decimal availableAmount = accountTable.AvailableAmount; //if (accountTable.CostPrice < 0.00m) // accountTable.CostPrice = 0; //原来的成本价 decimal costPrice = accountTable.CostPrice; //持仓均价=(持仓均价*持仓量+买入成交量*买入价)/(持仓量+买入成交量) decimal holdPrice = accountTable.HoldAveragePrice; accountTable.HoldAveragePrice = (decimal)(holdPrice * availableAmount + intNum * 0) / (availableAmount + intNum); decimal newCostprice = availableAmount * costPrice / (availableAmount + intNum); //新的量 accountTable.AvailableAmount = availableAmount + intNum; //新的成本价 accountTable.CostPrice = newCostprice; decimal newBreakevenPrice = MCService.GetHoldPrice(accountTable.Code, accountTable.CostPrice, accountTable.AvailableAmount); //新的保本价 accountTable.BreakevenPrice = newBreakevenPrice; }
/// <summary> /// Desc: 获取超过最小交割量整数倍的记录 /// Create by: 董鹏 /// Create Date: 2010-02-03 /// </summary> /// <param name="list">商品期货持仓实体列表</param> /// <param name="amtList">超量列表</param> /// <returns></returns> private List <QH_HoldAccountTableInfo> FindWillClosedContractNotModMinUnitLimit(List <QH_HoldAccountTableInfo> list, out Dictionary <int, decimal> dicAmount) { dicAmount = new Dictionary <int, decimal>(); List <QH_HoldAccountTableInfo> listReturn = new List <QH_HoldAccountTableInfo>(); LogHelper.WriteDebug("---->商品期货最小交割量整数倍限制验证"); foreach (QH_HoldAccountTableInfo item in list) { //获取持仓限制 try { PositionLimitValueInfo posInfo = MCService.GetPositionLimit(item.Contract); LogHelper.WriteDebug("-------->获取持仓限制,HistoryHoldAmount=" + item.HistoryHoldAmount + ",TodayHoldAmount=" + item.TodayHoldAmount + ",pLimit=" + posInfo.PositionValue + ",IsNoComputer=" + posInfo.IsNoComputer + ",IsMinMultiple=" + posInfo.IsMinMultiple + ",MinMultipleValue=" + posInfo.MinMultipleValue); if (posInfo.IsMinMultiple) { if (item.HistoryHoldAmount % posInfo.MinMultipleValue > 0) { LogHelper.WriteDebug("-------->持仓超过最小交割量整数倍限制,UserAccountDistributeLogo=" + item.UserAccountDistributeLogo + ",Contract=" + item.Contract + ",HistoryHoldAmount=" + item.HistoryHoldAmount + ",TodayHoldAmount=" + item.TodayHoldAmount + ",MinMultipleValue=" + posInfo.MinMultipleValue + "HistoryHoldAmount % pLimit=" + (item.HistoryHoldAmount % posInfo.MinMultipleValue)); listReturn.Add(item); dicAmount.Add(item.AccountHoldLogoId, (item.HistoryHoldAmount % posInfo.MinMultipleValue)); } } } catch (Exception ex) { LogHelper.WriteError(ex.Message, ex); } } return(listReturn); }
public CheckInfoServices( ILogger <CheckInfoServices> logger, MCService mcServices) { _logger = logger; _mcServices = mcServices; }
/// <summary> /// 股指期货委托规则检验 /// </summary> /// <param name="request">股指期货委托对象</param> /// <param name="errMsg">返回错误检验信息</param> /// <returns>是否成功</returns> public bool ValidateStockIndexFutureTradeRule(StockIndexFuturesOrderRequest request, ref string errMsg) { //目前股指期货的校验使用期货的校验 MercantileFuturesOrderRequest futuresOrderRequest = MCService.GetFuturesOrderRequest(request); return(ValidateFutureTradeRule(futuresOrderRequest, ref errMsg)); }
public override bool Validate(HKOrderRequest request, ref string strMessage) { bool result = false; string errMsg = "超过当前港股单笔最大委托量!"; string errCode = "GT-1251"; strMessage = errCode + ":" + errMsg; //int maxUnit = TradeRules.MaxLeaveQuantityUnit; int maxUnit = TradeRules.PriceUnit;//这与MaxLeaveQuantityUnit字段同相同的 Types.UnitType maxUnitType; try { maxUnitType = (Types.UnitType)maxUnit; } catch { return(false); } decimal scale = MCService.GetTradeUnitScale(Types.BreedClassTypeEnum.HKStock, request.Code, request.OrderUnitType); decimal scale2 = MCService.GetTradeUnitScale(Types.BreedClassTypeEnum.HKStock, request.Code, maxUnitType); var orderAmount = (decimal)request.OrderAmount * scale; //===Update By;李健华 2009-11-10 === // 因为港股规则里填写的最大委托量为手而之前的现货直接填写的为股,所以这里在要转换过来为股 //,而在这里验证的时候传入的都为股单位 //int? maxSingle = TradeRules.MaxLeaveQuantity; int?maxSingle = TradeRules.MaxLeaveQuantity; if (maxSingle.HasValue) { int perHand = MCService.HKTradeRulesProxy.GetHKPerHandThighOrShareByCode(request.Code, out strMessage); maxSingle = maxSingle.Value * perHand; //==================== decimal maxAmount = maxSingle.Value * scale2; if (orderAmount <= maxAmount) { result = true; strMessage = ""; } else { if (string.IsNullOrEmpty(strMessage)) { strMessage = errCode + ":" + errMsg; } } } 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); }
private bool HodingCheck(XH_AccountHoldTableInfo hold, XH_AccountHoldTableInfo_Delta change) { string strMessage = ""; bool result = false; if (Request.BuySell == GTA.VTS.Common.CommonObject.Types.TransactionDirection.Buying) { strMessage = "GT-2219:[现货委托持久化]买持仓检查,超过持仓限制"; int position = 0; decimal freezeAmount = 0; position = Convert.ToInt32(hold.AvailableAmount); freezeAmount = hold.FreezeAmount; if (ValidateCenter.ValidateStockMinVolumeOfBusiness(Request, position, ref strMessage)) { //获取持仓限制 Decimal pLimit = MCService.GetPositionLimit(Request.Code).PositionValue; //可用持仓+冻结量+委托量<持仓限制 result = pLimit >= position + freezeAmount + Convert.ToDecimal(Request.OrderAmount); } } else { strMessage = "GT-2220:[现货委托持久化]卖持仓检查,无持仓"; if (hold != null) { strMessage = "GT-2221:[现货委托持久化]卖持仓检查,无足够可用持仓"; int position = Convert.ToInt32(hold.AvailableAmount); //持仓帐户是否存在判断 if (ValidateCenter.ValidateStockMinVolumeOfBusiness(Request, position, ref strMessage)) { //已经统一使用撮合单位了 decimal orderAmount = Convert.ToDecimal(Request.OrderAmount); // *unitMultiple; //可用持仓>=委托量 result = hold.AvailableAmount >= orderAmount; } } } if (result) { strMessage = ""; } else { holdMessage = strMessage; } return(result); }
/// <summary> /// 用于故障恢复清算 /// </summary> /// <param name="recktime">要清算的日期</param> public static void DoFaultRecoveryClose(string recktime) { //add 2010-03-16 //2.可以清算时,先初始化所有的今日结算价 //3.检查当前持仓表中所有持仓合约都能获取得到结算价时再执行清算 //2. MCService.IniFutureTodayPreSettlementPriceRecovery(); //3. QH_HoldAccountTableDal dal = new QH_HoldAccountTableDal(); List <QH_HoldAccountTableInfo> models = dal.GetAllListArray(); decimal price; foreach (var item in models) { //如果持仓量有就要获取,如果都已经没有了持仓量证明已经清算完毕不再再清算 if (item.HistoryFreezeAmount + item.HistoryHoldAmount + item.TodayFreezeAmount + item.TodayHoldAmount > 0) { if (!MCService.GetFutureTodayPreSettlementPriceByCache(item.Contract, out price)) { LogHelper.WriteError("故障恢复期货清算获取今日结算价无法获取:" + item.Contract, new Exception("清算中止")); return; } } } //把是否正在做故障恢复清算状态修改回来为true,正在进行 ScheduleManager.IsFaultRecoveryFutureReckoning = true; ScheduleManager.CurrentFaultRecoveryFutureReckoningDate = DateTime.Parse(recktime); InternalDoClose(); //现货也设置清算完成,为了后面能提交现货的相关数据内存表中的数据 ScheduleManager.HasDoneStockReckoning = true; ScheduleManager.HasDoneFutureReckoning = true; ScheduleManager.ReckoningDoneNotify(); //证明已经故障恢复清算已经成功那么更新清算记录表记录 if (ScheduleManager.IsFutureReckoningErrorStopTrade == false) { //故障恢复清算完成修改清算日期标志,因为内部之前 的方法直接修改为当前的了,这里要修改回当招提交的数据日期 recktime = DateTime.Parse(recktime).ToShortDateString() + " " + DateTime.Now.ToString("HH:mm:ss"); StatusTableChecker.UpdateFutureReckoningDate(recktime, null); } //清空当前所有的缓存当前清算时添加的缓存数据 MCService.ClearFuterTodayPreSettlemmentPrice(); //把是否正在做故障恢复清算状态修改回来为false ScheduleManager.IsFaultRecoveryFutureReckoning = false; }
/// <summary> /// 重写实现验证委托量最小倍数方法 /// </summary> /// <param name="request"></param> /// <param name="strMessage"></param> /// <returns></returns> public override bool Validate(MercantileFuturesOrderRequest request, ref string strMessage) { //如果是开仓返回true,直接验证通过,因为开仓的时候已经在内部有处理 if (request.OpenCloseType == ReckoningCounter.Entity.Contants.Types.FutureOpenCloseType.OpenPosition) { return(true); } CM_BreedClass breedClass = MCService.CommonPara.GetBreedClassByBreedClassID(BreedClassID); bool result = true; if (breedClass != null && breedClass.BreedClassTypeID.HasValue) { int breedClassTypeID = breedClass.BreedClassTypeID.Value; int breedClassID = breedClass.BreedClassID; //如果是股指期货直接返回true if (breedClassTypeID == (int)Types.BreedClassTypeEnum.StockIndexFuture) { return(true); } //如果不是商品期货返回验证不通过 if (breedClassTypeID != (int)Types.BreedClassTypeEnum.CommodityFuture) { return(false); } } else { return(false); } PositionLimitValueInfo posInfo = MCService.GetPositionLimit(request.Code); //如果是最小交割单位的整数倍时 if (posInfo.IsMinMultiple) { if (((decimal)request.OrderAmount) % posInfo.MinMultipleValue != 0) { LogHelper.WriteDebug("===商品期货验证开仓最小交割单位倍数据: (request.OrderAmount % posInfo.MinMultipleValue)=(" + request.OrderAmount + " % " + posInfo.MinMultipleValue + ")=" + (((decimal)request.OrderAmount) % posInfo.MinMultipleValue)); strMessage = "GT-1354:[商品期货委托持久化]开仓持仓检查,持仓限制不是最小交割单位倍数"; result = false; } } return(result); }
public override bool Validate(StockOrderRequest request, ref string strMessage) { bool result = false; string errMsg = "超过当前现货单笔最大委托量!"; string errCode = "GT-1251"; strMessage = errCode + ":" + errMsg; int maxUnit = TradeRules.MaxLeaveQuantityUnit; Types.UnitType maxUnitType; try { maxUnitType = (Types.UnitType)maxUnit; } catch { return(false); } decimal scale = MCService.GetTradeUnitScale(request.Code, request.OrderUnitType); decimal scale2 = MCService.GetTradeUnitScale(request.Code, maxUnitType); var orderAmount = (decimal)request.OrderAmount * scale; int?maxSingle = TradeRules.MaxLeaveQuantity; if (maxSingle.HasValue) { decimal maxAmount = maxSingle.Value * scale2; if (orderAmount <= maxAmount) { result = true; strMessage = ""; } } return(result); }
/// <summary> /// 读取交易规则及基础数据 /// </summary> private static void DoBaseData() { //已经在ScheduleManger中初始化 //MCService.CommonPara.Reset(); //MCService.CommonPara.Initialize(); LogHelper.WriteInfo("------------证券开市处理-DoBaseData"); try { MCService.Reset(); AccountManager.Instance.Reset(); #region old code 注释 --李健华 2010-06-09 ////交易员工厂封装类进行重置 //VTTradersFactory.Reset(); //VTTradersFactory.GetStockTraders(); //VTTradersFactory.GetFutureTraders(); #endregion RealTimeMarketUtil.GetInstance().Reset(); LocalCommonValidater.Reset(); #region ===回推故障数据导入 Create by:李健华 Create date:2009-08-12=== FailureRecoveryFactory.XHReaderToDB(); #endregion ===回推故障数据导入 End=== var rescueManager = RescueManager.Instance; LogHelper.WriteInfo("------------完成证券开市处理-DoBaseData"); } catch (Exception ex) { LogHelper.WriteError(ex.ToString(), ex); LogHelper.WriteInfo("------------证券开市处理失败-DoBaseData"); } }
/// <summary> /// Desc: 获取超过最大持仓量的记录 /// Create by: 董鹏 /// Create Date: 2010-02-03 /// </summary> /// <param name="list">商品期货持仓实体列表</param> /// <param name="amtList">超量列表</param> /// <returns></returns> private List <QH_HoldAccountTableInfo> FindWillClosedContractOverMaxHoldLimit(List <QH_HoldAccountTableInfo> list, out Dictionary <int, decimal> dicAmount) { dicAmount = new Dictionary <int, decimal>(); List <QH_HoldAccountTableInfo> listReturn = new List <QH_HoldAccountTableInfo>(); LogHelper.WriteDebug("---->商品期货持仓限制验证"); foreach (QH_HoldAccountTableInfo item in list) { //获取持仓限制 try { PositionLimitValueInfo posInfo = MCService.GetPositionLimit(item.Contract); LogHelper.WriteDebug("-------->获取持仓限制,HistoryHoldAmount=" + item.HistoryHoldAmount + ",TodayHoldAmount=" + item.TodayHoldAmount + ",pLimit=" + posInfo.PositionValue + ",IsNoComputer=" + posInfo.IsNoComputer + ",IsMinMultiple=" + posInfo.IsMinMultiple + ",MinMultipleValue=" + posInfo.MinMultipleValue); Decimal pLimit = posInfo.PositionValue; if (pLimit < 0) { LogHelper.WriteDebug("-------->商品期货持仓限制验证,持仓限制小于0,不处理,pLimit=" + pLimit); continue; } //持仓大于持仓限制 if (item.HistoryHoldAmount > pLimit) { LogHelper.WriteDebug("-------->持仓大于持仓限制,UserAccountDistributeLogo=" + item.UserAccountDistributeLogo + ",Contract=" + item.Contract + ",HistoryHoldAmount=" + item.HistoryHoldAmount + ",TodayHoldAmount=" + item.TodayHoldAmount + ",pLimit=" + pLimit + ",HistoryHoldAmount - pLimit=" + (item.HistoryHoldAmount - pLimit)); listReturn.Add(item); dicAmount.Add(item.AccountHoldLogoId, item.HistoryHoldAmount - pLimit); } } catch (Exception ex) { LogHelper.WriteError(ex.Message, ex); } } return(listReturn); }
/// <summary> /// 计算预成交金额和预成交费用 /// </summary> /// <param name="strMessage">错误信息</param> /// <param name="predealCapital">预成交金额</param> /// <param name="predealCost">预成交费用</param> /// <returns>计算是否成功</returns> private bool PO_ComputePreCapital(ref string strMessage, ref decimal predealCapital, ref decimal predealCost) { bool result = false; predealCapital = 0; predealCost = 0; //如果量为0,直接返回0 if (Request.OrderAmount == 0) { return(true); } try { XHCostResult xhcr = null; //计价单位与交易单位倍数 decimal unitMultiple = MCService.GetTradeUnitScale(Request.Code, Request.OrderUnitType); float orderPrice = 0; //市价委托 if (Request.OrderWay == Types.OrderPriceType.OPTMarketPrice) { decimal orderPriceD = (decimal)Request.OrderPrice; var highLowRange = MCService.HLRangeProcessor.GetHighLowRangeValueByCommodityCode(Request.Code, orderPriceD); if (highLowRange != null) { if (highLowRange.RangeType == GTA.VTS.Common.CommonObject.Types.HighLowRangeType.HongKongPrice) //港股类型处理 { var hkrv = highLowRange.HongKongRangeValue; if (Request.BuySell == GTA.VTS.Common.CommonObject.Types.TransactionDirection.Buying) { orderPrice = Convert.ToSingle(hkrv.BuyHighRangeValue); } else { orderPrice = Convert.ToSingle(hkrv.SellHighRangeValue); } } else //其它类型处理 { orderPrice = Convert.ToSingle(highLowRange.HighRangeValue); } //以计价单位计算的委托量 int orderAmount = Convert.ToInt32(Request.OrderAmount);//*Convert.ToDouble(unitMultiple)); //预成交总金额 委托量 * 计价单位与交易单位倍数 * 委托价 predealCapital = orderAmount * Convert.ToDecimal(orderPrice) * unitMultiple; //预成交费用 xhcr = MCService.ComputeXHCost(Request.Code, orderPrice, orderAmount, Request.OrderUnitType, Request.BuySell); //预成交费用 predealCost = xhcr.CoseSum; result = true; } else { strMessage = "GT-2215:[现货委托持久化]商品无涨跌幅设置"; } } else //限价委托计算( 委托价*委托量 + 费用) { //成本计算器 xhcr = MCService.ComputeXHCost(Request); //预成交总金额 委托量 * 计价单位与交易单位倍数 * 委托价 predealCapital = Convert.ToDecimal(Request.OrderAmount) * unitMultiple * Convert.ToDecimal(Request.OrderPrice); //预成交费用 predealCost = xhcr.CoseSum; result = true; } } catch (Exception ex) { if (ex is VTException) { strMessage = ex.ToString(); } else { strMessage = "GT-2216:[现货委托持久化]成交金额及费用计算异常."; } LogHelper.WriteError(ex.Message, ex); } return(result); }
/// <summary> /// 进行持仓检查,对已经过期的合约按昨日结算价进行强制平仓 /// </summary> private void CheckHoldTable() { //LogHelper.WriteDebug("FutureDayChecker.CheckHoldTable开始检查持仓表"); OrderAccepter orderAccepter = OrderAccepterService.Service; QH_HoldAccountTableDal dal = new QH_HoldAccountTableDal(); string where = string.Format("UserAccountDistributeLogo = '{0}'", holdAccount.UserAccountDistributeLogo); List <QH_HoldAccountTableInfo> listCheck = dal.GetListArray(where); // DataRepository.QhHoldAccountTableProvider.GetByUserAccountDistributeLogo( // holdAccount.UserAccountDistributeLogo); if (Utils.IsNullOrEmpty(listCheck)) { return; } decimal price = 0; List <QH_HoldAccountTableInfo> list = new List <QH_HoldAccountTableInfo>(); //这里是要分开处理,已经是过期的合约前面就已经强行平仓掉就没有后面的持仓限制和最小单位整数倍的判断 foreach (var holdTable in listCheck) { //如果不是交易日,不进行强行平仓 add by 董鹏 2010-05-05 if (!CommonParaProxy.GetInstance().IsTradeDate(holdTable.Contract)) { continue; } if (MCService.IsExpireLastedTradeDate(holdTable.Contract)) { //在最后交易日 进行平仓 //string msg = ""; //bool canGetPrice = MCService.GetFutureYesterdayPreSettlementPrice(holdTable.Contract, out price, // ref msg); //if (!canGetPrice) //{ // string format = "FutureDayChecker.CheckHoldTable无法获取合约{0}的昨日收盘结算价,错误信息:{1}"; // string msg2 = string.Format(format, holdTable.Contract, msg); // LogHelper.WriteDebug(msg2); // continue; //} //每天清算后,持仓均价就是结算价 price = holdTable.HoldAveragePrice; #region 账户类型进行商品期货、股指期货平仓 add by 董鹏 2010-02-03 UA_UserAccountAllocationTableDal accDal = new UA_UserAccountAllocationTableDal(); var acc = accDal.GetModel(holdTable.UserAccountDistributeLogo); if (acc.AccountTypeLogo == (int)Types.AccountType.CommodityFuturesHoldCode) { //此处原来只有HistoryHoldAmount,造成未清算成功的持仓平不掉,因此加上TodayHoldAmount; //而TodayFreezeAmount清算是否成功都没有影响 -- update by 董鹏 2010-03-29 //CloseCommoditiesContract(orderAccepter, holdTable, (float)price, (float)(holdTable.HistoryHoldAmount + holdTable.TodayHoldAmount), Types.QHForcedCloseType.Expired); //平历史 CloseCommoditiesContract(orderAccepter, holdTable, (float)price, (float)holdTable.HistoryHoldAmount, Types.QHForcedCloseType.Expired, ReckoningCounter.Entity.Contants.Types.FutureOpenCloseType.ClosePosition); //平今 CloseCommoditiesContract(orderAccepter, holdTable, (float)price, (float)holdTable.TodayHoldAmount, Types.QHForcedCloseType.Expired, ReckoningCounter.Entity.Contants.Types.FutureOpenCloseType.CloseTodayPosition); } if (acc.AccountTypeLogo == (int)Types.AccountType.StockFuturesHoldCode) { CloseStockIndexContract(orderAccepter, holdTable, (float)price, true); } #endregion //CloseStockIndexContract(orderAccepter, holdTable, (float)price, true); } else { list.Add(holdTable); } } #region 商品期货进行持仓限制、最小交割单位整数倍检验,并平仓超出量 add by 董鹏 2010-02-04 if (holdAccount.AccountTypeLogo == (int)Types.AccountType.CommodityFuturesHoldCode) { LogHelper.WriteDebug("---->商品期货持仓限制、最小小交割单位整数倍验证,UserAccountDistributeLogo=" + holdAccount.UserAccountDistributeLogo); List <QH_HoldAccountTableInfo> listCloseContract; price = 0; //记录超出持仓限制的量:<持仓记录主键,超出量> Dictionary <int, decimal> dicAmount; // 超过最大持仓限制 listCloseContract = FindWillClosedContractOverMaxHoldLimit(list, out dicAmount); foreach (var holdTable in listCloseContract) { CloseCommoditiesContract(orderAccepter, holdTable, (float)price, (float)dicAmount[holdTable.AccountHoldLogoId], Types.QHForcedCloseType.OverHoldLimit, ReckoningCounter.Entity.Contants.Types.FutureOpenCloseType.ClosePosition); //进行了持仓限制平仓的不再进行最小交割单位验证,下次持仓检查的时候才进行。 list.Remove(holdTable); } //超出最小交割量整数倍 listCloseContract = FindWillClosedContractNotModMinUnitLimit(list, out dicAmount); foreach (var holdTable in listCloseContract) { CloseCommoditiesContract(orderAccepter, holdTable, (float)price, (float)dicAmount[holdTable.AccountHoldLogoId], Types.QHForcedCloseType.NotModMinUnit, ReckoningCounter.Entity.Contants.Types.FutureOpenCloseType.ClosePosition); } } #endregion //LogHelper.WriteDebug("FutureDayChecker.CheckHoldTable结束检查持仓表"); }
/// <summary> /// 重新过滤和组装保证金数据(这里是为了查找相关的最后交易日前第几日的问题) /// </summary> /// <param name="values">原保证金比例列表</param> /// <returns></returns> private static List <QH_CFBailScaleValue> AssemblingFilterCFBail(IList <QH_CFBailScaleValue> values) { string errCode = "GT-8485"; string errMsg = "保证金比例数据设置有异常。"; List <QH_CFBailScaleValue> list = new List <QH_CFBailScaleValue>(); Dictionary <int, DateTime> modifyTime = new Dictionary <int, DateTime>(); // List<QH_CFBailScaleValue> models = new List<QH_CFBailScaleValue>(); //QH_CFBailScaleValue[] kd = new QH_CFBailScaleValue[values.Count]; //values.CopyTo(kd, 0); //models = kd.ToList<QH_CFBailScaleValue>(); try { foreach (var item in values) { QH_CFBailScaleValue retList = new QH_CFBailScaleValue(); #region 重新定义一对象记录 //retList = item;//对象引用不能这样附值会把缓存的数据修改 retList.BailScale = item.BailScale; retList.BreedClassID = item.BreedClassID; retList.CFBailScaleValueID = item.CFBailScaleValueID; retList.DeliveryMonthType = item.DeliveryMonthType; retList.Ends = item.Ends; retList.LowerLimitIfEquation = item.LowerLimitIfEquation; retList.PositionBailTypeID = item.PositionBailTypeID; retList.RelationScaleID = item.RelationScaleID; retList.Start = item.Start; retList.UpperLimitIfEquation = item.UpperLimitIfEquation; #endregion #region linq查询方法 查询相关记录 //查询是否在关联的保证金比例列表,有则要计算当前日志(即月份的交易日期) var q = from c in values where c.RelationScaleID == item.CFBailScaleValueID select c; #endregion //如果关联的日期和类型交易日的记录才要转换 if (q != null && q.Count <QH_CFBailScaleValue>() > 0 && item.PositionBailTypeID == (int)Types.QHPositionBailType.ByTradeDays) { #region //如果关联的日期和类型交易日的记录才要转换 int end = 0; //如果设置无有值则为非法记录,并且不可能小于零也不可以大于22,因为一个月最多的有效交易日也就是二十二天 if (!item.Ends.HasValue || item.Ends.Value >= 22 || item.Ends.Value <= 0) { throw new VTException(errCode, errMsg); } end = item.Ends.Value; //获取当月共几天 int days = 0; List <DateTime> timeList = Utils.GetCurrentMothDay(out days); //最后交易日 //之前设置为1,没有考虑到记录不是交割月时而不用计算这个最后交易日的 int lastTrdeday = 31; //当记录是交割月的记录时处理最后交易日的问题 if (item.DeliveryMonthType == (int)Types.QHCFPositionMonthType.OnDelivery) { lastTrdeday = MCService.GetLastTradingDayByBreedClassId(item.BreedClassID.Value); } //记录最后交易日之后的日期的所有日期 List <DateTime> lastDayed = new List <DateTime>(); foreach (var model in timeList) { if (model.Day > lastTrdeday) { lastDayed.Add(model); } } //删除所有最后交易日之后的日期 foreach (var dayed in lastDayed) { timeList.Remove(dayed); } int countTradeDay = timeList.Count; if (countTradeDay < end) { throw new VTException(errCode, errMsg); } //计算开始最后交易日的开始时间(最后交易日前几天的开始时间) DateTime startTime = timeList[countTradeDay - end]; //关联的日期的结束时间 DateTime endTime = timeList[countTradeDay - 1 - end]; retList.Start = startTime.Day; retList.Ends = days; //item.Start = startTime.Day; //item.Ends = days; //记录有关联日期的最后日期记录,因为最后日期是由关联记录的开始日期决定 foreach (var modi in q) { if (!modifyTime.ContainsKey(modi.CFBailScaleValueID)) { modifyTime.Add(modi.CFBailScaleValueID, endTime); } } #endregion } else if (item.PositionBailTypeID == (int)Types.QHPositionBailType.ByTradeDays) { #region 否则如果是按交易日的记录要重新计算日期转为自然日 if (!item.Start.HasValue || !item.Ends.HasValue) { errMsg = "开始日期或者结束日期不能没有数值,不合规的日期设置"; throw new VTException(errCode, errMsg); } if (item.Start.Value > item.Ends.Value) { errMsg = "开始日期比结束日期大,不合规的日期设置"; throw new VTException(errCode, errMsg); } int start, end = 0; end = item.Ends.Value; start = item.Start.Value; //获取当月共几天 int days = 0; List <DateTime> timeList = Utils.GetCurrentMothDay(out days); //最后交易日 //之前设置为1,没有考虑到记录不是交割月时而不用计算这个最后交易日的 int lastTrdeday = 31; //当记录是交割月的记录时处理最后交易日的问题 if (item.DeliveryMonthType == (int)Types.QHCFPositionMonthType.OnDelivery) { lastTrdeday = MCService.GetLastTradingDayByBreedClassId(item.BreedClassID.Value); } //记录最后交易日之后的日期的所有日期 List <DateTime> lastDayed = new List <DateTime>(); foreach (var model in timeList) { if (model.Day > lastTrdeday) { lastDayed.Add(model); } } //删除所有最后交易日之后的日期 foreach (var dayed in lastDayed) { timeList.Remove(dayed); } int countTradeDay = timeList.Count; //计算开始最后交易日的开始时间(最后交易日前几天的开始时间) DateTime startTime = DateTime.Now; //关联的日期的结束时间 DateTime endTime = DateTime.Now; //如果开始日期比当前所有交易日总数大那么开始日期直接以最后交易日为开始日 if (start > countTradeDay || start <= 0) { startTime = timeList[countTradeDay - 1]; } else { //if (start <= 0) //{ // start = 1; //} startTime = timeList[start - 1]; } retList.Start = startTime.Day; //当结束日期比当前月所有交易日还大时,直接以当前月所拥有的自然最后日替换 if (end > countTradeDay || end <= 0) { //endTime = timeList[countTradeDay - 1]; retList.Ends = days; } else { endTime = timeList[end - 1]; retList.Ends = endTime.Day; } #endregion } list.Add(retList); } #region //修改已经在关联的日期 //修改已经在关联的日期 foreach (var item in modifyTime) { //var q = from c in list // where // c.CFBailScaleValueID == item.Key // select c; foreach (var model in list) { if (model.CFBailScaleValueID == item.Key) { //如果开始日期为null即为第一日,不为空则原始的日期 if (!model.Start.HasValue) { model.Start = 1; } model.Ends = item.Value.Day; } } } #endregion #region 写日志 //日志字符串 string txt = "品种类型:{0},控制类型:{1},交割类型:{2},开始:{3},结束:{4},比例:{5}"; foreach (var model in list) { //写日志 string txtWriter = string.Format(txt, model.BreedClassID, model.PositionBailTypeID, model.DeliveryMonthType, model.Start, model.Ends, model.BailScale); LogHelper.WriteDebug(txtWriter); } #endregion } catch (Exception ex) { LogHelper.WriteError(ex.Message, ex); throw new VTException(errCode, errMsg); } return(list); }
public override bool Validate(HKOrderRequest request, ref string strMessage) { string errMsg = "港股最小单位检验失败!"; string errCode = "GT-1250"; int unitID = (int)request.OrderUnitType; int tradeWayID = (int)request.BuySell; if (Utils.IsNullOrEmpty(MinVolumeOfBusinessList)) { strMessage = errCode + ":" + errMsg; return(false); } //======update 2009-11-08 李健华====== //港股只有手对股的转换,这里特殊处理,而进入此方法后的验证单位和量都转换成了股单位, //而对应的规则表(XH_MinVolumeOfBusiness表)中只有手的转换,因此这里要特殊转换 //判断是否包含有股的转换 ,没有就自行模拟加入 bool isThigh = false; List <ReckoningCounter.DAL.SpotTradingDevolveService.XH_MinVolumeOfBusiness> minVolumesList = new List <ReckoningCounter.DAL.SpotTradingDevolveService.XH_MinVolumeOfBusiness>(MinVolumeOfBusinessList); //minVolumesList = new List<ReckoningCounter.DAL.SpotTradingDevolveService.XH_MinVolumeOfBusiness>(MinVolumeOfBusinessList); // minVolumesList =MinVolumeOfBusinessList; foreach (var item in MinVolumeOfBusinessList) { if (item.UnitID == (int)Types.UnitType.Thigh) { isThigh = true; break; } } //判断是否包含有股的转换 ,没有就自行模拟加入 if (!isThigh) { HK_Commodity hkComm = MCService.HKTradeRulesProxy.GetHKCommodityByCommodityCode(request.Code); ReckoningCounter.DAL.SpotTradingDevolveService.XH_MinVolumeOfBusiness itembuy = new ReckoningCounter.DAL.SpotTradingDevolveService.XH_MinVolumeOfBusiness(); itembuy.UnitID = (int)Types.UnitType.Thigh; itembuy.VolumeOfBusiness = hkComm.PerHandThighOrShare; itembuy.TradeWayID = (int)Types.TransactionDirection.Buying; minVolumesList.Add(itembuy); ReckoningCounter.DAL.SpotTradingDevolveService.XH_MinVolumeOfBusiness itemSell = new ReckoningCounter.DAL.SpotTradingDevolveService.XH_MinVolumeOfBusiness(); itemSell.UnitID = (int)Types.UnitType.Thigh; itemSell.VolumeOfBusiness = hkComm.PerHandThighOrShare; itemSell.TradeWayID = (int)Types.TransactionDirection.Selling; minVolumesList.Add(itemSell); } var minVolumes = from minVolume in minVolumesList where minVolume.UnitID.Value == unitID && minVolume.TradeWayID.Value == tradeWayID select minVolume; //当此品种没有此交易单位时检验不通过。如权证 下单80股则检验失败(单位只有手和份) if (minVolumes.Count() == 0) { strMessage = errCode + ":" + errMsg; return(false); } //================== if (request.BuySell == Types.TransactionDirection.Buying) { foreach (ReckoningCounter.DAL.SpotTradingDevolveService.XH_MinVolumeOfBusiness volume in minVolumes) { if ((int)request.OrderUnitType == volume.UnitID) { if (request.OrderAmount < volume.VolumeOfBusiness.Value || (request.OrderAmount % volume.VolumeOfBusiness.Value != 0)) { strMessage = errCode + ":" + errMsg; return(false); } } } } //卖的话需要进行零股处理 else { //委托单位转换为计价单位 decimal scale = MCService.GetTradeUnitScale(Types.BreedClassTypeEnum.HKStock, request.Code, request.OrderUnitType); var amount = (decimal)request.OrderAmount * scale; //持仓单位(默认为撮合单位)转为计价单位 decimal scale2 = MCService.GetMatchUnitScale(Types.BreedClassTypeEnum.HKStock, request.Code); var position = m_Position * scale2; if (amount > position) { strMessage = errCode + ":" + "超过可用持仓"; return(false); } //港股最小单位零股检验 foreach (ReckoningCounter.DAL.SpotTradingDevolveService.XH_MinVolumeOfBusiness volume in minVolumes) { if ((int)request.OrderUnitType == volume.UnitID) { if (request.OrderAmount < volume.VolumeOfBusiness.Value || (request.OrderAmount % volume.VolumeOfBusiness.Value != 0)) { if (amount != position) { strMessage = errCode + ":" + errMsg; return(false); } } } } //港股最小单位零股检验 //int zeroScale = TradeRules.MinVolumeMultiples; //if (amount%zeroScale != 0) //{ // if (amount != position) // { // strMessage = errCode + ":" + errMsg; // return false; // } //} } return(true); }
public MCController(ILogger <MCController> logger, MCService mcService) { _logger = logger; _mcService = mcService; }
public static void DoClose() { //还没到收市,不处理 if (DateTime.Now.Hour < ScheduleManager.LastEndTime.Hour) { return; } if (DateTime.Now.Hour == ScheduleManager.LastEndTime.Hour) { if (DateTime.Now.Minute < ScheduleManager.LastEndTime.Minute) { return; } } LogHelper.WriteInfo("执行期货收市动作DoClose"); //===update 李健华 2009-12-14 //这里已经在现货清算中提交过,也再得新加载过,在清算完成后会统一再提交一次 //先关闭内存管理器 // MemoryDataManager.End(); //========== MCService.DoMarketCloseJob(); //add 2010-03-16 //1.发现前一日没有清算完成今日也不能清算 (这个不用了,系统自动清算只要把当日或者前一日的清算完成即可,系统只要保证没有清算完成不可下单操作即可) //2.可以清算时,先初始化所有的今日结算价 //3.检查当前持仓表中所有持仓合约都能获取得到结算价时再执行清算 //=============== //1. string errMsg = ""; bool isReck = false; DateTime recktime; isReck = StatusTableChecker.IsFutureTodayReckoning(out recktime, out errMsg); //if (!isReck) //{ // LogHelper.WriteError("今日期货清算不能执行清算,时间获取为:" + recktime, new Exception(errMsg)); // return; //} //2. //3. QH_HoldAccountTableDal dal = new QH_HoldAccountTableDal(); List <QH_HoldAccountTableInfo> models = dal.GetAllListArray(); decimal price; foreach (var item in models) { //如果持仓量有就要获取,如果都已经没有了持仓量证明已经清算完毕不再再清算 if (item.HistoryFreezeAmount + item.HistoryHoldAmount + item.TodayFreezeAmount + item.TodayHoldAmount > 0) { if (!MCService.GetFutureTodayPreSettlementPriceByCache(item.Contract, out price)) { //如果代码还是可以交易的代码则中止清算,已经过期忽略不理,内部清算的时候获取不到会不会修改持仓均价相关的内容 if (!MCService.IsExpireLastedTradeDate(item.Contract)) { //但当代码当日为非交易日时也可以放过 //如果发现前一日没有清算完成今日获取不到价格不能放过 if (!isReck || MCService.CommonPara.IsTradeDate(item.Contract, DateTime.Now)) { //为了防止每日重启程序时时间已经过了收市时间即到了清算时间所作的每次清算而已经清算成功的再设置为不清算成功 //如:20100402的五点时重启程序,这时已经四点半已经清算成功,那些这里再清算而又获取不到行情就会设置错误,而这里应该不设置,放过 //因为内部还会检查是否清算成功过 if (!StatusTableChecker.HasDoneFutureReckoning(DateTime.Now)) { LogHelper.WriteError("今日期货清算获取今日结算价无法获取:" + item.Contract, new Exception("清算中止")); //暂停交易 ScheduleManager.IsFutureReckoningErrorStopTrade = true; return; } } ////如果发现前一日没有清算完成今日获取不到价格不能放过 //else if (!isReck) //{ // LogHelper.WriteError("今日期货清算获取今日结算价无法获取:" + item.Contract, new Exception("前一日清算异常,今日清算中止")); // //暂停交易 // ScheduleManager.IsFutureReckoningErrorStopTrade = true; // return; //} } } } } //清算之前把所有柜台缓存的清算撮合ID的数据清除 QHCounterCache.Instance.ResetDictionary(); InternalDoClose(); ScheduleManager.HasDoneFutureReckoning = true; ScheduleManager.ReckoningDoneNotify(); ////过了收市时间,开始处理,延时5分钟,等现货做完后再做 //timer = new Timer(); //timer.Interval = 1*60*1000; //timer.Elapsed += delegate // { // timer.Enabled = false; // LogHelper.WriteInfo("执行期货收市动作DoClose"); // InternalDoClose(); // InternalDoClose(); // InternalDoClose(); // }; //timer.Enabled = true; //期货清算完成后把资金管理的相关账号清除,释放内存 AccountManager.Instance.Reset(); }
/// <summary> /// 买持仓检查 /// </summary> /// <param name="strMessage"></param> /// <param name="hkEntrustInfo"></param> /// <param name="request"></param> /// <returns></returns> private bool PO_HoldValidate_Buy(ref string strMessage, HK_TodayEntrustInfo hkEntrustInfo, HKOrderRequest request) { bool result = false; strMessage = ""; int position = 0; decimal freezeAmount = 0; //var ahtMemory = MemoryDataManager.HKHoldMemoryList.GetByAccountHoldLogoId(HoldingAccountId); //if (ahtMemory == null) //{ var ahtMemory = HKCommonLogic.GetHoldMemoryTable(hkEntrustInfo.HoldAccount, hkEntrustInfo.Code, hkEntrustInfo.CurrencyTypeID); //} if (ahtMemory != null && ahtMemory.Data != null) { var aht = ahtMemory.Data; position = Convert.ToInt32(aht.AvailableAmount); freezeAmount = aht.FreezeAmount; } else { position = 0; freezeAmount = 0; } HKStockMinVolumeOfBusinessCommand command = new HKStockMinVolumeOfBusinessCommand(BreedClassID, position); result = command.Validate(request, ref strMessage); // if (ValidateCenter.ValidateHKMinVolumeOfBusiness(request, position, ref strMessage)) if (result) { //获取持仓限制 Decimal pLimit = MCService.GetPositionLimit(request.Code, CommonObject.Types.BreedClassTypeEnum.HKStock).PositionValue; //可用持仓+冻结量+委托量<持仓限制 //这里是改单,所以要把之前的委托减去 result = pLimit >= position + freezeAmount + Convert.ToDecimal(request.OrderAmount - hkEntrustInfo.EntrustAmount); if (!result) { strMessage = "GT-2419:[港股改单委托验证]可用持仓+冻结量+委托量<持仓限制--港股改单委托失败"; } } else { strMessage += "--港股改单委托失败"; } //成功时需要清空错误信息。 if (result) { strMessage = ""; } return(result); }
public UploadMCDocumentController(ILogger <UploadMCDocumentController> logger, MCService mcServices) { _logger = logger; _mcServices = mcServices; }
/// <summary> /// 获取股指期货交易费用的实际方法,目前使用商品期货的计算方法 /// </summary> /// <param name="request">股指期货委托</param> /// <param name="cost">费用实体</param> /// <returns>股指期货交易费用结果</returns> private static QHCostResult InternalComputeGZQHCost(StockIndexFuturesOrderRequest request, QH_FutureCosts cost) { QHCostResult result = new QHCostResult(); //result.Code = result.Code; result.Code = request.Code; decimal orderPrice = (decimal)request.OrderPrice; //期货合约乘数300 decimal scale = MCService.GetTradeUnitScale(request.Code, request.OrderUnitType); //以计价单位计算的委托量 var orderAmount = (decimal)request.OrderAmount * scale; //成交额 var dealAmount = orderPrice * orderAmount; decimal cosing = 0; //按类型计算比例 switch ((Types.FutrueCostType)Enum.Parse(typeof(Types.FutrueCostType), cost.CostType.ToString())) { case Types.FutrueCostType.TradeUnitCharge: //与量有关的都是撮合单位,所以这里不用再把委托量*转换比例 //为了不改上面的代码这里直接再把原来转了的值再除 orderAmount = (decimal)orderAmount / scale; cosing = orderAmount * cost.TurnoverRateOfServiceCharge; break; case Types.FutrueCostType.TurnoverRateOfSerCha: //比例 decimal cosingScale = cost.TurnoverRateOfServiceCharge / 100; cosing = dealAmount * cosingScale; break; } cosing = Utils.Round(cosing); #region old code //decimal tradeVal = 0; ////成交单位比率 //if (cost.TradeUnitCharge.HasValue) //{ // decimal trade = cost.TradeUnitCharge.Value / 100; // tradeVal = orderAmount * trade; // tradeVal = Utils.Round(tradeVal); //} //decimal turnVal = 0; ////成交金额比率 //if (cost.TurnoverRateOfServiceCharge.HasValue) //{ // decimal turn = cost.TurnoverRateOfServiceCharge.Value / 100; // turnVal = turn * dealAmount; // turnVal = Utils.Round(turnVal); //} //result.Cosing = tradeVal + turnVal; #endregion result.Cosing = cosing; string format = "股指期货费用计算[代码={0},价格={1},数量={2},单位={3},方向={4},合约乘数={5},股指期货交易费用类型={6},费用比率={7}]"; string desc = string.Format(format, request.Code, request.OrderPrice, request.OrderAmount, request.OrderUnitType, request.BuySell, scale , cost.CostType + "--" + (cost.CostType == (int)Types.FutrueCostType.TradeUnitCharge ? "按成交量" : "按成交额") , cost.TurnoverRateOfServiceCharge); LogHelper.WriteDebug(desc + result); return(result); }
private static XHCostResult InternalComputeXHCost(StockOrderRequest request, XH_SpotCosts cost) { CM_BreedClass breedClass = MCService.CommonPara.GetBreedClassByCommodityCode(request.Code); XHCostResult result = new XHCostResult(); result.Code = request.Code; decimal orderPrice = (decimal)request.OrderPrice; //期货合约乘数300 decimal scale = MCService.GetTradeUnitScale(request.Code, request.OrderUnitType); //以计价单位计算的委托量 var orderAmount = (decimal)request.OrderAmount * scale; //成交额 var dealAmount = orderPrice * orderAmount; /// 1.印花税 decimal stamp = cost.StampDuty / 100; decimal stampStart = cost.StampDutyStartingpoint; if (cost.StampDutyTypeID.HasValue) { int stampType = cost.StampDutyTypeID.Value; #region old code //if (stampType == (int)Types.GetValueTypeEnum.SingleSell && // request.BuySell == Types.TransactionDirection.Selling) //{ // decimal stampVal = stamp * dealAmount; // if (stampVal < stampStart) // stampVal = stampStart; // stampVal = Utils.Round(stampVal); // result.StampDuty = stampVal; //} #endregion decimal stampVal = stamp * dealAmount; if (stampVal < stampStart) { stampVal = stampStart; } stampVal = Utils.Round(stampVal); switch ((Types.GetValueTypeEnum)stampType) { case Types.GetValueTypeEnum.Single: break; case Types.GetValueTypeEnum.Scope: break; case Types.GetValueTypeEnum.Turnover: break; case Types.GetValueTypeEnum.Thigh: break; case Types.GetValueTypeEnum.SingleBuy: if (request.BuySell == Types.TransactionDirection.Buying) { result.StampDuty = stampVal; } break; case Types.GetValueTypeEnum.SingleSell: if (request.BuySell == Types.TransactionDirection.Selling) { result.StampDuty = stampVal; } break; case Types.GetValueTypeEnum.TwoEdge: result.StampDuty = stampVal; break; case Types.GetValueTypeEnum.No: break; default: break; } } /// 2.佣金 //public decimal Commision { get; set; } if (cost.Commision.HasValue) { decimal comm = cost.Commision.Value / 100; decimal commVal = comm * dealAmount; decimal commStart = cost.CommisionStartingpoint; if (commVal < commStart) { commVal = commStart; } commVal = Utils.Round(commVal); result.Commision = commVal; } /// 3.过户费 //public decimal TransferToll { get; set; } decimal trans = cost.TransferToll / 100; int transType = cost.TransferTollTypeID; decimal transVal = 0; //过户费类型 [按股] [按成交额] switch (transType) { case (int)Types.GetValueTypeEnum.Thigh: transVal = trans * orderAmount; break; case (int)Types.GetValueTypeEnum.Turnover: transVal = trans * dealAmount; break; } transVal = Utils.Round(transVal); if (cost.TransferTollStartingpoint.HasValue) { decimal transStart = cost.TransferTollStartingpoint.Value; if (transVal < transStart) { transVal = transStart; } } transVal = Utils.Round(transVal); result.TransferToll = transVal; /// 4.交易手续费 //public decimal PoundageSingleValue { get; set; } if (cost.GetValueTypeID.HasValue) { int poundType = cost.GetValueTypeID.Value; //交易手续费单值 single double switch (poundType) { case (int)Types.GetValueTypeEnum.Single: decimal pound = cost.PoundageSingleValue.Value / 100; decimal poundValue = pound * dealAmount; poundValue = Utils.Round(poundValue); result.PoundageSingleValue = poundValue; break; case (int)Types.GetValueTypeEnum.Scope: //IList<XH_SpotRangeCost> costs = // MCService.SpotTradeRules.GetSpotRangeCostByBreedClassID(breedClass.BreedClassID); //foreach (XH_SpotRangeCost spotRangeCost in costs) //{ // //int fieldRangeID = spotRangeCost.FieldRangeID; // decimal pound2 = spotRangeCost.Value.Value; // pound2 = Utils.Round(pound2); // CM_FieldRange fieldRange = MCService.GetFieldRange(fieldRangeID); // //是否在当前字段范围内 // bool isExist = MCService.CheckFieldRange(dealAmount, fieldRange); // if (isExist) // { // result.PoundageSingleValue = pound2; // break; // } //} break; } } /// 5.监管费 //public decimal MonitoringFee { get; set; } if (cost.MonitoringFee.HasValue) { decimal monitor = cost.MonitoringFee.Value / 100; decimal monitorVal = monitor * dealAmount; monitorVal = Utils.Round(monitorVal); result.MonitoringFee = monitorVal; } /// 6.结算费 if (cost.ClearingFees.HasValue) { decimal clear = cost.ClearingFees.Value / 100; decimal clearval = clear * dealAmount; clearval = Utils.Round(clearval); result.ClearingFees = clearval; } /// 7.交易系统使用费(港股) if (cost.SystemToll.HasValue) { result.TradeSystemFees = cost.SystemToll.Value; } string format = "现货费用计算[代码={0},价格={1},数量={2},单位={3},方向={4}]"; string desc = string.Format(format, request.Code, request.OrderPrice, request.OrderAmount, request.OrderUnitType, request.BuySell); LogHelper.WriteDebug(desc + result); return(result); }
public override bool Validate(MercantileFuturesOrderRequest request, ref string strMessage) { //bool result = false; string errMsg = "期货最小委托量检验失败!"; string errCode = "GT-1351"; strMessage = errCode + ":" + errMsg; int?consignQuantumID = TradeRules.ConsignQuantumID; if (!consignQuantumID.HasValue) { return(false); } if (consignQuantum == null) { consignQuantum = MCService.FuturesTradeRules.GetConsignQuantumByConsignQuantumID(consignQuantumID.Value); } if (consignQuantum == null) { return(false); } if (!consignQuantum.MinConsignQuantum.HasValue) { return(false); } Types.UnitType marketUnitType; try { marketUnitType = (Types.UnitType)TradeRules.MarketUnitID; ; } catch { return(false); } decimal scale = MCService.GetTradeUnitScale(request.Code, request.OrderUnitType); decimal scale2 = MCService.GetTradeUnitScale(request.Code, marketUnitType); var orderAmount = (decimal)request.OrderAmount * scale; var minAmount = consignQuantum.MinConsignQuantum.Value * scale2; //进行最小委托量校验 if (orderAmount < minAmount) { return(false); } //最小委托量整数倍验证 if (orderAmount % minAmount != 0) { return(false); } string errMsg2 = "超过当前期货单笔最大委托量!"; string errCode2 = "GT-1352"; strMessage = errCode2 + ":" + errMsg2; singleRequestQuantityList = MCService.FuturesTradeRules.GetSingleRequestQuantityByConsignQuantumID(consignQuantumID.Value); QH_SingleRequestQuantity limit_SingleRequestQuantity = null; QH_SingleRequestQuantity market_SingleRequestQuantity = null; foreach (QH_SingleRequestQuantity singleRequestQuantity in singleRequestQuantityList) { if (singleRequestQuantity.ConsignInstructionTypeID.HasValue) { int val = singleRequestQuantity.ConsignInstructionTypeID.Value; if (val == (int)Entity.Contants.Types.OrderPriceType.OPTLimited) { limit_SingleRequestQuantity = singleRequestQuantity; } else if (val == (int)Entity.Contants.Types.OrderPriceType.OPTMarketPrice) { market_SingleRequestQuantity = singleRequestQuantity; } } } //进行最大委托量校验 switch (request.OrderWay) { case Entity.Contants.Types.OrderPriceType.OPTLimited: if (limit_SingleRequestQuantity == null) { return(false); } if (!limit_SingleRequestQuantity.MaxConsignQuanturm.HasValue) { return(false); } var maxLimitAmount = limit_SingleRequestQuantity.MaxConsignQuanturm.Value * scale2; if (orderAmount > maxLimitAmount) { return(false); } break; case Entity.Contants.Types.OrderPriceType.OPTMarketPrice: if (market_SingleRequestQuantity == null) { return(false); } if (!market_SingleRequestQuantity.MaxConsignQuanturm.HasValue) { return(false); } var maxMarketAmount = market_SingleRequestQuantity.MaxConsignQuanturm.Value * scale2; if (orderAmount > maxMarketAmount) { return(false); } break; } strMessage = ""; return(true); }
public override bool Validate(StockOrderRequest request, ref string strMessage) { string errMsg = "现货最小单位检验失败!"; string errCode = "GT-1250"; int unitID = (int)request.OrderUnitType; int tradeWayID = (int)request.BuySell; if (MinVolumeOfBusinessList == null) { strMessage = errCode + ":" + errMsg; return(false); } var minVolumes = from minVolume in MinVolumeOfBusinessList where minVolume.UnitID.Value == unitID && minVolume.TradeWayID.Value == tradeWayID select minVolume; ; //当此品种没有此交易单位时检验不通过。如权证 下单80股则检验失败(单位只有手和份) if (minVolumes.Count() == 0) { strMessage = errCode + ":" + errMsg; return(false); } if (request.BuySell == Types.TransactionDirection.Buying) { foreach (XH_MinVolumeOfBusiness volume in minVolumes) { if ((int)request.OrderUnitType == volume.UnitID) { if (request.OrderAmount < volume.VolumeOfBusiness.Value || (request.OrderAmount % volume.VolumeOfBusiness.Value != 0)) { strMessage = errCode + ":" + errMsg; return(false); } } } } //卖的话需要进行零股处理 else { //委托单位转换为计价单位 decimal scale = MCService.GetTradeUnitScale(request.Code, request.OrderUnitType); var amount = (decimal)request.OrderAmount * scale; //持仓单位(默认为撮合单位)转为计价单位 decimal scale2 = MCService.GetMatchUnitScale(request.Code); var position = m_Position * scale2; if (amount > position) { strMessage = errCode + ":" + "超过可用持仓"; return(false); } //现货最小单位零股检验 foreach (XH_MinVolumeOfBusiness volume in minVolumes) { if ((int)request.OrderUnitType == volume.UnitID) { if (request.OrderAmount < volume.VolumeOfBusiness.Value || (request.OrderAmount % volume.VolumeOfBusiness.Value != 0)) { if (amount != position) { strMessage = errCode + ":" + errMsg; return(false); } } } } //现货最小单位零股检验 //int zeroScale = TradeRules.MinVolumeMultiples; //if (amount%zeroScale != 0) //{ // if (amount != position) // { // strMessage = errCode + ":" + errMsg; // return false; // } //} } return(true); }
public PushDataToMC(ILogger <PushDataToMC> logger, MCService mCService) { _logger = logger; _mcService = mCService; }
/// <summary> /// 计算预成交金额和预成交费用 /// </summary> /// <param name="strMessage">错误信息</param> /// <param name="predealCapital">预成交金额</param> /// <param name="predealCost">预成交费用</param> /// <returns>计算是否成功</returns> private bool PO_ComputePreCapital(ref string strMessage, ref decimal predealCapital, ref decimal predealCost) { bool result = false; predealCapital = 0; predealCost = 0; //如果量为0,直接返回0 if (Request.OrderAmount == 0) { return(true); } try { HKCostResult xhcr = null; //计价单位与交易单位倍数 //update 李健华 2009-10-26 //decimal unitMultiple = MCService.GetTradeUnitScale(Request.Code, Request.OrderUnitType); decimal unitMultiple = MCService.GetTradeUnitScale(Types.BreedClassTypeEnum.HKStock, Request.Code, Request.OrderUnitType); //========= //float orderPrice = 0; //成本计算器 xhcr = MCService.ComputeHKCost(Request); //预成交总金额 委托量 * 计价单位与交易单位倍数 * 委托价 predealCapital = Convert.ToDecimal(Request.OrderAmount) * unitMultiple * Convert.ToDecimal(Request.OrderPrice); //预成交费用 predealCost = xhcr.CoseSum; result = true; #region 旧逻辑-港股无市价单,必须有价格 /* * //市价委托(TODO:待重写) * if (Request.OrderWay == Types.HKPriceType.LO) * { * decimal orderPriceD = (decimal) Request.OrderPrice; * var highLowRange = MCService.HLRangeProcessor.GetHighLowRangeValueByCommodityCode(Request.Code, * orderPriceD); * if (highLowRange != null) * { * if (highLowRange.RangeType == Types.HighLowRangeType.HongKongPrice) //港股类型处理 * { * var hkrv = highLowRange.HongKongRangeValue; * if (Request.BuySell == Types.TransactionDirection.Buying) * { * orderPrice = Convert.ToSingle(hkrv.BuyHighRangeValue); * } * else * { * orderPrice = Convert.ToSingle(hkrv.SellHighRangeValue); * } * } * else //其它类型处理 * { * orderPrice = Convert.ToSingle(highLowRange.HighRangeValue); * } * * //以计价单位计算的委托量 * int orderAmount = Convert.ToInt32(Request.OrderAmount); //*Convert.ToDouble(unitMultiple)); * * //预成交总金额 委托量 * 计价单位与交易单位倍数 * 委托价 * predealCapital = orderAmount*Convert.ToDecimal(orderPrice)*unitMultiple; * //预成交费用 * xhcr = MCService.ComputeHKCost(Request.Code, orderPrice, orderAmount, * Request.OrderUnitType, Request.BuySell); * //预成交费用 * predealCost = xhcr.CoseSum; * result = true; * } * else * { * strMessage = "GT-2415:[港股委托持久化]商品无涨跌幅设置"; * } * } * else //限价委托计算( 委托价*委托量 + 费用) * { * //成本计算器 * xhcr = MCService.ComputeHKCost(Request); * //预成交总金额 委托量 * 计价单位与交易单位倍数 * 委托价 * predealCapital = Convert.ToDecimal(Request.OrderAmount)*unitMultiple* * Convert.ToDecimal(Request.OrderPrice); * //预成交费用 * predealCost = xhcr.CoseSum; * result = true; * } * * */ #endregion } catch (Exception ex) { if (ex is VTException) { strMessage = ex.ToString(); } else { strMessage = "GT-2416:[港股委托持久化]成交金额及费用计算异常."; } LogHelper.WriteError(ex.Message, ex); } return(result); }