using Org.BouncyCastle.Ocsp; using System.Data; using YLErp.BLL; using YLErp.Commons; using YLErp.Configuration.Enums; using YLErp.DBModels; using YLErp.DBModels.Enums; using YLErp.DBModels.Helpers; using YLErp.Helpers; using YLErp.Model; using YLErp.Model.Enum; using YLErp.Modules.TradeModule.DealModule; using YLErp.Modules.TradeModule.OrderModule; using YLErp.QdpModule; namespace YLErp.Modules.TradeModule.ForwardModule { public class ForwardTradeImportService : TradeCashService { public ForwardTradeImportService(OptUserInfo userInfo) : base(userInfo) { } public void ImportFromExcel(Stream streamIn, string TypeName, out int totalNum, out int successNum) { totalNum = 0; successNum = 0; var rowIndex = 0; try { var ds = Office.ExcelHelper.ReadExcelAsDataSet(streamIn, new[] { 0 }, 0); if (ds.Tables.Count < 1 || ds.Tables[0].Rows.Count < 2) { throw new ServiceException("读取导入数据失败:数据为空") { Tag = "111" }; } var table = ds.Tables[0]; var reader = new DataRowReader(table, 0); rowIndex = 1; totalNum = table.Rows.Count - rowIndex; foreach (var row in table.Rows.Cast().Skip(1)) { using (var trans = BeginTransaction()) { rowIndex++; if (row.ItemArray.All(n => string.IsNullOrWhiteSpace(n?.ToString()))) { totalNum--; continue; } reader.SetDataRow(row); switch (TypeName) { case "远期交易": HandleForwardTrade(reader, ForwardTradePriceModel.STANDARD);//标准模式导入 break; case "远期交易挂钩标的": HandleForwardTrade(reader, ForwardTradePriceModel.HOOK_PRICE);//挂钩标的模式导入 break; default: HandleFinishForwardTrade(reader);//批量了结导入 break; } successNum++; trans.Commit(); } } } catch (ServiceException se) { if (se.Tag != null) { throw; } throw new ServiceException($"已成功导入{successNum}条;\n第{rowIndex}行,{se.Message}"); } catch (Exception ex) { LogFactory.GetLogger(TypeName).Error(ex); throw new ServiceException($"已成功导入{successNum}条,\n第{rowIndex}行,发生错误:{ex.Message}", ex); } } #region 远期交易导入 /// /// 处理每行数据 /// /// public void HandleForwardTrade(DataRowReader reader, ForwardTradePriceModel priceModel) { OtcTradeForward td = new OtcTradeForward(); td = MapForwardTrade(reader, priceModel); var otcOptionTradeFullEx = new OtcOptionTradeFullEx { ClientName = td.ClientName }; new OtcOptionSaveChecker(this).CheckAssetBook(td).CheckTrader(td).CheckClient(otcOptionTradeFullEx); td.ClientId = otcOptionTradeFullEx.ClientId; CalculatedForwardFieldValue(td, reader); td.TradeType = "远期"; var mapTd = TradeConverter.ConvertForward(td); new TradeSaveService(OptUser).SaveTrade(mapTd, TradeSourceEnum.导入交易); } public OtcTradeForward MapForwardTrade(DataRowReader reader, ForwardTradePriceModel priceModel) { var td = new OtcTradeForward { TradeNumber = reader.GetString("交易编号", false), AssetBookName = reader.GetString("簿记账户名称", true), TraderName = reader.GetString("交易员名称", true), ClientName = reader.GetString("交易对手方名称", true), StructureType = reader.GetString("结构类型", true), //UnderlyingCode = reader.GetString("标的代码", true), //BasisUnderlyingCode = reader.GetString("挂钩标的代码", false), //BasisGap = reader.GetDouble("基差", false), BuySell = reader.GetString("交易方向", true), OptionType = reader.GetString("多空方向", false), TradeAmount = reader.GetDouble("成交数量", false) ?? 0, Lots = reader.GetDouble("手数", false), Strike = reader.GetDouble("交割价格", true), //SpotPrice = reader.GetDouble("期初标的价格", true) ?? 0, AnnualMarginRate = reader.GetPercent("年化预付金成本", false) ?? 0, AnnualStoragePrice = reader.GetDouble("年化仓储成本", false) ?? 0, NoRiskRate = reader.GetPercent("无风险利率", false) ?? 0, MarginTemplateName = reader.GetString("预付金模板", false), TradeDate = reader.GetDate("成交日期", true), ExerciseDate = reader.GetDate("到期日期", true), SettlementDate = reader.GetDate("结算日期", true), ObservationDates = reader.GetString("均价结算日", false), Comments = reader.GetString("备注", false) }; string IsSupplyForwardValue = reader.GetString("是否补偿远期价值", true); if (IsSupplyForwardValue == "补偿" || IsSupplyForwardValue == "是") { td.MetaDic.Add("IsSupplyForwardValue", "1"); } else if (IsSupplyForwardValue == "支付") { td.MetaDic.Add("IsSupplyForwardValue", "-1"); } else if (IsSupplyForwardValue == "否") { td.MetaDic.Add("IsSupplyForwardValue", "0"); } else { //添加拓展字段 是否补充远期价值,Type2:默认值 -1,其他默认值 0 if (PS.Config.ErpElement.ForwardValueIsSupplyOrPay == YLErp.Configuration.Enums.ForwardValueIsSupplyOrPay.Type2) { td.MetaDic.Add("IsSupplyForwardValue", "-1"); } else { td.MetaDic.Add("IsSupplyForwardValue", "0"); } } if (priceModel == ForwardTradePriceModel.STANDARD) { td.UnderlyingCode = reader.GetString("标的1代码", true); //判断是否组合标的 var synthetic = DataCacheProvider.GetUnderlyingDataSource().GetSyntheticUnderlying(td.UnderlyingCode); if (synthetic != null) { var model = synthetic.GetSyntheticPriceModel(); var basisUnderlyingCode = reader.GetString("标的2代码", false); var basisUnderlyingPrice = reader.GetString("标的2期初价格", false); if (!string.IsNullOrEmpty(basisUnderlyingCode) || !string.IsNullOrEmpty(basisUnderlyingPrice)) { throw new ServiceException("[组合标的]标的2代码必须为空"); } var codeSet = synthetic.GetUnderlyingCodes().ToHashSet(StringComparer.OrdinalIgnoreCase); double SpotPrice = 0; List spList = new List(); for (var i = 1; i <= 4; i++) { var code = reader.GetString("组合标的" + i + "代码", false); if (string.IsNullOrWhiteSpace(code)) { continue; } if (!codeSet.Remove(code)) { throw new ServiceException($"[组合标的]{i}_代码 填写错误,组合标的中不存在此标的:{code}"); } var curSportprice = reader.GetDouble("组合标的" + i + "期初价格", true).Value; var curUC = model.SuList.FirstOrDefault(n => n.UnderlyingCode == code); if (curUC != null) { curUC.Price = curSportprice; SpotPrice += curUC.Price * curUC.Coefficient; } } if (codeSet.Any()) { throw new ServiceException("[组合标的]未填写完整"); } spList.Add(SpotPrice.OtcFormatUmPrice()); td.SpotPrice = SpotPrice; td.MetaDic["期初信息"] = spList.ToJson(); td.MetaDic["组合标的"] = model.ToJson(); } else { double SpotPrice = reader.GetDouble("标的1期初价格", true) ?? 0; td.BasisUnderlyingCode = reader.GetString("标的2代码", false); double? SpotPrice2 = reader.GetDouble("标的2期初价格", false); //string[] sp = new string[] { SpotPrice.OtcFormatUmPrice(), SpotPrice2 }; List spList = new List(); spList.Add(SpotPrice.ToString("0.####")); if (!string.IsNullOrEmpty(td.BasisUnderlyingCode)) { if (SpotPrice2 == null) { throw new ServiceException("填写标的2代码,则必须填写标的2期初价格"); } else { spList.Add((SpotPrice2 ?? 0).ToString("0.####")); } } td.SpotPrice = (double)((decimal)SpotPrice - (decimal)(SpotPrice2 ?? 0)); td.MetaDic["期初信息"] = spList.ToJson(); } } else { td.UnderlyingCode = reader.GetString("标的代码", true); td.BasisUnderlyingCode = reader.GetString("挂钩标的代码", false); td.BasisGap = reader.GetDouble("基差", false); GetSpotPrice(td); } //var um = DataCacheProvider.GetUnderlyingDataSource().GetData(td.UnderlyingCode); if (PS.Config.Is浙期) { var flag = false; var codes = new List(); codes.Add(td.UnderlyingCode); codes.Add(td.BasisUnderlyingCode); //判断标的是否为现货 flag = UndelyingHelper.IsCodesExistsCommoditySpot(codes, (um) => { return um.UnderlyingInstrumentType == "CommoditySpot" ? true : false; }); if (flag) { var dateStr = reader.GetDate("实际到期日期", false) ?? td.ExerciseDate; td.MetaDic["ActualExerciseDate"] = dateStr.Value.ToString("yyyy-MM-dd"); } } //DateTime.TryParse(dateStr, out var date); switch (td.BuySell) { case "Buy": td.BuySell = "买入"; break; case "Sell": td.BuySell = "卖出"; break; case "买入": case "卖出": break; default: throw new ServiceException("交易方向 填写错误:" + td.BuySell); } td.OptionType = GetOptionType(td.OptionType, td.BuySell); if (string.IsNullOrEmpty(td.MarginTemplateName)) { td.MarginTemplateName = "系统默认"; td.MarginRate = 0; td.PositionMarginRate = 0; } else { var marginTemplateList = GetMarginTemplateItems(); if (marginTemplateList.Any(a => a.Name.Equals(td.MarginTemplateName))) { switch (td.MarginTemplateName) { case "系统默认": td.MarginType = MarginTypeEnum.DEFAULT; td.MarginRate = 0; td.PositionMarginRate = 0; break; case "无预付金": td.MarginType = MarginTypeEnum.NONE; td.MarginRate = 0; td.PositionMarginRate = 0; break; default: break; } var MarginRate = reader.GetDouble("初始预付金率", false); var PositionMarginRate = reader.GetDouble("持仓预付金率", false); td.MarginRate = MarginRate ?? 0; td.PositionMarginRate = PositionMarginRate ?? 0; var marginTemplate = marginTemplateList.Where(a => a.Name.Equals(td.MarginTemplateName)).FirstOrDefault(); td.MarginType = (MarginTypeEnum)marginTemplate.MarginType; if (MarginRate == null) { td.MarginRate = marginTemplate.InitialMarginRatio ?? 0; } if (PositionMarginRate == null) { td.PositionMarginRate = marginTemplate.PositionMarginRatio ?? 0; } } else { throw new ServiceException("预付金模板填写错误:" + td.MarginTemplateName); } } if (QdpCalendarHelper.IsHoliday((DateTime)td.TradeDate)) { throw new ServiceException("成交日期:" + td.TradeDate + ",不能为节假日"); } if (QdpCalendarHelper.IsHoliday((DateTime)td.ExerciseDate)) { throw new ServiceException("到期日期:" + td.ExerciseDate + ",不能为节假日"); } if (QdpCalendarHelper.IsHoliday((DateTime)td.SettlementDate)) { throw new ServiceException("结算日期:" + td.SettlementDate + ",不能为节假日"); } if (td.TradeDate > td.ExerciseDate) { throw new ServiceException("交易日应该在到期日之前"); } if (td.SettlementDate < td.ExerciseDate) { throw new ServiceException("结算日期不能小于到期日期"); } if (!string.IsNullOrEmpty(td.ObservationDates)) { DateTime dt = new DateTime(); if (td.ObservationDates.Contains(',')) { string[] arrayDate = td.ObservationDates.Split(','); if (!arrayDate.Any(a => DateTime.TryParse(a, out dt))) throw new ServiceException("均价结算日日期格式填写错误" + td.ObservationDates); } else { if (!DateTime.TryParse(td.ObservationDates, out dt)) throw new ServiceException("均价结算日日期格式填写错误" + td.ObservationDates); } } #region 观察频率写入metadic表中 string termStr = null; var ruleStr = reader.GetString("观察周期", false); if (!string.IsNullOrWhiteSpace(ruleStr)) { switch (ruleStr) { case "每日": termStr = "1D"; break; case "每周": termStr = "1W"; break; case "每月": termStr = "1M"; break; case "每年": termStr = "1Y"; break; } if (termStr == null) { var strs = ruleStr.Split(new[] { ',' }); termStr = strs[0].Trim(); } //敲入观察周期写入metadic中 td.MetaDic["敲入观察周期"] = termStr; } #endregion return td; } public string GetOptionType(string OptionType, string BuySell = "") { switch (OptionType) { case "多头": case "Call": return "看涨"; case "空头": case "Put": return "看跌"; case "看涨": case "看跌": return OptionType; case "": case null: return BuySell == "买入" ? "看涨" : "看跌"; default: throw new ServiceException("多空方向 填写错误:" + OptionType); } } /// /// 计算远期字段值 /// /// /// public void CalculatedForwardFieldValue(OtcTradeForward td, DataRowReader reader) { var um = DataCacheProvider.GetUnderlyingDataSource().GetData(td.UnderlyingCode); if (um == null) { throw new ServiceException("系统中不存在,导入的标的1代码"); } else if (!string.IsNullOrEmpty(td.BasisUnderlyingCode)) { if (DataCacheProvider.GetUnderlyingDataSource().GetData(td.BasisUnderlyingCode) == null) { throw new ServiceException("系统中不存在,导入的标的2代码"); } } //GetSpotPrice(td); GetCountRatio(td); GetNotional_TradeAmount_Lots(td, um); GetForwardValue(td); GetOpenCommission_TradePrice(td, reader, null, null); } /// /// 获取期初价格 /// /// public void GetSpotPrice(OtcTradeForward td) { //计算期初价格 期初价格 = 挂钩标的价格 + 基差 if (!string.IsNullOrWhiteSpace(td.BasisUnderlyingCode)) { var umBasis = DataCacheProvider.GetUnderlyingDataSource().GetData(td.BasisUnderlyingCode); td.SpotPrice = umBasis.Price + (td.BasisGap ?? 0); } else { var umBasis = DataCacheProvider.GetUnderlyingDataSource().GetData(td.BasisUnderlyingCode); td.SpotPrice = umBasis.Price; } } public void GetCountRatio(OtcTradeForward td) { var CountRatio = td.CountRatio ?? 0; if (CountRatio < 1) { CountRatio = DataCacheProvider.GetUnderlyingDataSource().GetData(td.UnderlyingCode)?.CountRatio ?? 1; } td.CountRatio = CountRatio; } /// /// 获取份额,成交数量,手数 /// /// /// public void GetNotional_TradeAmount_Lots(OtcTradeForward td, underlying_manager um) { if (td.Lots < 0) throw new ServiceException("手数不能为负数"); if (td.TradeAmount < 0) throw new ServiceException("成交数量不能为负数"); if (td.TradeAmount == 0 && td.Lots == 0) throw new ServiceException("成交数量与手数,两者必须填写一个"); if (td.Lots > 0) { td.Notional = (double)td.Lots * um.ContractSize; td.TradeAmount = td.Notional / (double)td.CountRatio; } else if (td.TradeAmount > 0) { td.Notional = td.TradeAmount * (double)td.CountRatio; td.Lots = td.Notional / um.ContractSize; } td.OriginalNotional = td.Notional; } /// /// 获取远期价值 /// (交割价格- 期初价格) * 成交数量 * CountRatio *(多-1,空1)]*(买入1,卖出 - 1) /// /// public void GetForwardValue(OtcTradeForward td) { var OptionType = GetOptionType(td.OptionType, td.BuySell); var ForwardValue = (td.Strike - td.SpotPrice) * td.TradeAmount * td.CountRatio * (OptionType == "看涨" ? -1 : 1) * (td.BuySell == "买入" ? 1 : -1); td.ForwardValue = ForwardValue ?? 0; } /// /// 获取远期价值 /// /// /// /// /// /// /// /// public double GetForwardValue(double Strike, double SpotPrice, double TradeAmount, int CountRatio, string OptionType, string BuySell) { OptionType = GetOptionType(OptionType, BuySell); return (Strike - SpotPrice) * TradeAmount * CountRatio * (OptionType == "看涨" ? -1 : 1) * (BuySell == "买入" ? 1 : -1); } /// /// 获取远期价值 /// /// /// /// /// /// /// /// public double GetForwardValue(double Strike, double SpotPrice, double OriginalNotional, string OptionType, string BuySell) { OptionType = GetOptionType(OptionType, BuySell); return (Strike - SpotPrice) * OriginalNotional * (OptionType == "看涨" ? -1 : 1) * (BuySell == "买入" ? 1 : -1); } /// /// 获取开仓费用,开仓总费用 /// /// public void GetOpenCommission_TradePrice(OtcTradeForward td, DataRowReader reader, double? OpenCommission, double? TradePrice) { if (reader != null) { OpenCommission = reader.GetDouble("开仓费用", false); TradePrice = reader.GetDouble("开仓总费用", false); } if (OpenCommission == null && TradePrice == null) { throw new ServiceException("开仓费用与开仓总费用,两者必须填写一个"); } var supplyPrice = td.MetaDic["IsSupplyForwardValue"] == "1" ? td.ForwardValue : td.MetaDic["IsSupplyForwardValue"] == "-1" ? -td.ForwardValue : 0; //补偿远期价值+开仓费用 if (OpenCommission != null && TradePrice == null) { td.TradePrice = supplyPrice + OpenCommission * td.Lots; td.OpenCommission = OpenCommission.Value; } //开仓费用 = (开仓总费用 -(补充远期价值))/ 手数 else if ((OpenCommission != null && TradePrice != null) || (OpenCommission == null && TradePrice != null)) { td.TradePrice = TradePrice; td.OpenCommission = ((td.TradePrice - supplyPrice) / td.Lots) ?? 0; } } #endregion #region 远期交易批量了结导入 public void HandleFinishForwardTrade(DataRowReader reader) { TradeCashImportReq tcReq = MapFinishForward(reader); var td = DbContext.trade.FirstOrDefault(t => t.TradeNumber == tcReq.TradeNumber && t.ValidState != "InValid"); if (td == null) { throw new ServiceException("交易数据 不存在,交易编号:" + tcReq.TradeNumber); } if (td.TradeStatus != ConsTrade.确认成交) { throw new ServiceException("只有交易状态为‘确认成交’,才能进行批量了结导入"); } td.trade_cash = DbContext.trade_cash.FirstOrDefault(t => t.TradeId == td.id && t.Action == "系统操作-期权费" && t.ValidState != "InValid" && t.IsDeleted == false); var otcTradeForward = new TradeForwardService(OptUser).GetDetail(td.id); if ((tcReq.UnwindTradeAmount ?? 0) == 0 && tcReq.UnwindType == "部分平仓") { throw new ServiceException("平仓数量不能为0或空值"); } if (tcReq.UnwindTradeAmount > td.TradeAmount) { throw new ServiceException("平仓数量不能大于持仓数量"); } else if (tcReq.UnwindTradeAmount < td.TradeAmount && tcReq.UnwindType == "全部平仓") { throw new ServiceException("全部平仓时,平仓数量等于持仓数量"); } if (tcReq.UnwindPriceCheck == null && tcReq.UnwindFee == null) { throw new ServiceException("当每手平仓费用未填,则平仓总费用必填"); } CheckValueDate(td, tcReq.ValueDate); var um = DataCacheProvider.GetUnderlyingDataSource().GetData(td.UnderlyingCode); var CountRatio = td.CountRatio ?? 0; if (CountRatio < 1) { CountRatio = um?.CountRatio ?? 1; } td.CountRatio = CountRatio; var eodpriceProvider = new YLErp.Modules.DataProviderModule.EodPriceProvider((DateTime)tcReq.ValueDate); if (tcReq.FinalPrice == null) { tcReq.FinalPrice = eodpriceProvider.GetPrice(td.UnderlyingCode, SettlementTypeEnum.ClosePrice);//平仓当天标的价格; } if (tcReq.UnwindTradeAmount == td.TradeAmount && tcReq.UnwindType == "部分平仓") { tcReq.UnwindType = "全部平仓"; } if (tcReq.UnwindType == "全部平仓") { tcReq.UnwindTradeAmount = td.TradeAmount; } var unwindNotional = tcReq.UnwindTradeAmount * td.CountRatio; double extraAmount = ComputeExtraAmount(td, tcReq) ?? 0; tcReq.UnwindForwardValue = GetForwardValue(otcTradeForward.Strike ?? 0, tcReq.FinalPrice ?? 0, tcReq.UnwindTradeAmount ?? 0, td.CountRatio ?? 1, td.OptionType, td.BuySell); tcReq.UnwindRatio = (unwindNotional ?? 0) / (td.OriginalNotional ?? 0); var supplyPrice = otcTradeForward.MetaDic["IsSupplyForwardValue"] == "1" ? otcTradeForward.ForwardValue : otcTradeForward.MetaDic["IsSupplyForwardValue"] == "-1" ? -otcTradeForward.ForwardValue : 0; if (tcReq.UnwindFee == null) { tcReq.UnwindPriceCheck = tcReq.UnwindPriceCheck ?? 0; //平仓的总费用 =远期收益+每手平仓费用×平仓手数-(开仓时补偿的远期价值)×平仓数量/成交数量+预付金成本 //其中开仓时补偿的远期价值 = 持仓价值(期初)*Flag var unwindPrice = (tcReq.UnwindPriceCheck * td.Lots * tcReq.UnwindRatio) ?? 0; tcReq.UnwindFee = tcReq.UnwindForwardValue + unwindPrice - supplyPrice * tcReq.UnwindRatio + extraAmount; } else { tcReq.UnwindFee = tcReq.UnwindFee ?? 0; //平仓费用 = (平仓的总费用 +(开仓时补偿的远期价值* 平仓比例)- 远期收益 - 预付金成本)/ (平仓比例 *手数) tcReq.UnwindPriceCheck = (tcReq.UnwindFee + supplyPrice * tcReq.UnwindRatio - tcReq.UnwindForwardValue - extraAmount) / (otcTradeForward.Lots * tcReq.UnwindRatio); } TradeCashReq req = new TradeCashReq(); req.ValidState = "Valid"; req.UnwindFee = tcReq.UnwindFee ?? 0; req.Notional = td.Notional; req.TradeAmount = td.TradeAmount; req.UnwindPrice = tcReq.UnwindPriceCheck; req.FinalPrice = tcReq.FinalPrice; req.UnwindType = tcReq.UnwindType; req.UnwindNotional = (tcReq.UnwindTradeAmount * td.CountRatio) ?? 0; req.UnwindPercentRate = td.OriginalNotional > 0 ? (req.UnwindNotional / td.OriginalNotional) ?? 0 : 0; req.UnwindPricePercentRate = TradeHelper.GetPremiumRateByTradeSinglePrice(req.UnwindPrice, td.SpotPrice); req.ExtraAmount = extraAmount; req.ValueDate = tcReq.ValueDate; //增加现金交割交易记录 var tc = CloseTrade_TradeCashSave(td, req, false, !false, !false); new TradeCashService(this).SaveTradeCashDetail(tc); td.TradeSource = TradeSourceEnum.导入交易.ToString(); td.OptId = UserId; td.OptName = UserName; td.OptDate = DateTime.Now; td.StockEqvNotional -= (double)(td.OriginalStockEqvNotional * tc.UnwindPercentRate); td.Notional -= (double)(td.OriginalNotional * tc.NotionalPercentRate); td.TradeAmount = td.Notional / um.CountRatio; td.UnWindNotional = tc.UnwindNotional; td.UnWindDate = tc.ValueDate; if (tc.UnwindType == "全部平仓" || (((decimal)(td.OriginalNotional ?? 0) - (decimal)req.UnwindNotional) == 0 && tc.UnwindType == "部分平仓")) { td.TradeStatus = ConsTrade.已平仓; tc.IsLastAction = true; } else { td.TradeStatus = ConsTrade.确认成交; td.HasPartialUnWind = 1; tc.IsLastAction = false; } DbContext.SaveChanges(); //增加出入金记录 var ee = new ClientCashinCashoutBLL(this).CloseTrade_ClientCashInCashOutSave(td, tc, tc.ValueDate); //删除E/Bod数据 RemoveEodTradeAndFutureInfo(false, td.id, tc.ValueDate); AddTradeAuditLog(td.id); } public TradeCashImportReq MapFinishForward(DataRowReader reader) { var tc = new TradeCashImportReq { TradeNumber = reader.GetString("交易编号", true), UnwindType = reader.GetString("平仓类型", true), UnwindTradeAmount = reader.GetDouble("平仓数量", false), ValueDate = (DateTime)reader.GetDate("平仓日期", true), FinalPrice = reader.GetDouble("标的价格", false), UnwindPriceCheck = reader.GetDouble("每手平仓费用", false), UnwindFee = reader.GetDouble("平仓总费用", false) }; if (QdpCalendarHelper.IsHoliday((DateTime)tc.ValueDate)) { throw new ServiceException("平仓日期:" + tc.ValueDate + ",不能为节假日"); } return tc; } /// /// 验证平仓日期 /// /// /// /// public void CheckValueDate(trade td, DateTime ValueDate) { if (td.TradeDate > ValueDate) { throw new ServiceException("平仓日期必须要大于或等于成交日期"); } if (ValueDate > td.ExerciseDate) { throw new ServiceException("平仓日期必须要小于或等于到期日期"); } if (ValueDate > valuedateBLL.ValueDate) { throw new ServiceException("平仓日期必须要小于或等于系统日期"); } } /// /// 计算预付金成本 /// /// /// /// public double? ComputeExtraAmount(trade td, TradeCashImportReq tcReq) { var valueDate = valuedateBLL.ValueDate; if (valueDate > td.ExerciseDate) { valueDate = td.ExerciseDate.Value; } var lastMarginRecord = DbContext.eod_forward_margin.Where(f => f.TradeId == td.id && f.ValueDate < SystemValueDate).OrderByDescending(x => x.ValueDate).FirstOrDefault(); if (lastMarginRecord != null) { var totaldays = (valuedateBLL.ValueDate.Date - lastMarginRecord.ValueDate.Date).TotalDays; double HolidayMargin = lastMarginRecord.SettlePrice * lastMarginRecord.MarginRate * lastMarginRecord.AnnualRate * totaldays / 365; var unwindAmount = tcReq.UnwindTradeAmount; var holidayMarginTotal = unwindAmount * HolidayMargin; var lastMargin = (lastMarginRecord.MarginSum - lastMarginRecord.CloseMarginSum) * ((unwindAmount) / lastMarginRecord.Notional) + lastMarginRecord.CloseMarginSum; return lastMargin + holidayMarginTotal; } return 0; } /// /// 计算 交易员角度的远期价值 /// /// /// /// /// /// /// public double ComputForwardValue(string buySell, string optionType, double strike, double FinalPrice, double unwindNotional) { //(行权价-标的价格)* 平仓份额 decimal ForwardValue = 0; if ((buySell == "卖出" && optionType == "看跌") || (buySell == "买入" && optionType == "看涨")) { ForwardValue = ((decimal)strike - (decimal)FinalPrice) * (decimal)unwindNotional; } else if ((buySell == "卖出" && optionType == "看涨") || (buySell == "买入" && optionType == "看跌")) { ForwardValue = -(((decimal)strike - (decimal)FinalPrice) * (decimal)unwindNotional); } return (double)ForwardValue; } public void AddTradeAuditLog(int TradeId) { var auditLog = new TradeAuditLog { TradeId = TradeId, Changes = null, DataType = "00", OptType = "批量了结-平仓", OptId = UserId, OptName = UserName, OptDate = OptDate, AuditFlag = TradeAuditFlag.operation }; //记录审核日志 DbContext.TradeAuditLog.Add(auditLog); DbContext.SaveChanges(); } public List GetMarginTemplateItems() { var marginTemplates = DbContext.margin_template.ToList(); List strList = new List(); strList = marginTemplates; strList.Add(new margin_template { Name = "系统默认", MarginType = (int)MarginTypeEnum.DEFAULT, InitialMarginRatio = 0, PositionMarginRatio = 0 }); strList.Add(new margin_template { Name = "无预付金", MarginType = (int)MarginTypeEnum.NONE, InitialMarginRatio = 0, PositionMarginRatio = 0 }); return strList; } #endregion } }