using YLErp.BLL.Calculation; using YLErp.DBModels; using YLErp.Modules.DataProviderModule; using YLErp.Modules.MarginModule; using YLErp.Modules.UnderlyingModule; using YLErp.Modules.VolatilityModule; using YLErp.QdpModule; namespace YLErp.Web.Controllers { public class underlying_managerController : BaseController { public static List GetVarieties() { return VarietyBLL.GetAllvarietyModel().Where(x => x.VarietyCode != "组合标的") .Select(x => new SelectListItem { Text = x.ShortName, Value = x.id.ToString() }).ToList(); } [MyAuthorize("基础参数管理-标的管理")] public ActionResult underlying_managerList() { return View(); } [HttpPost] public JsonResult underlying_managerQuery(UnderlyingManagerReq req) { var bll = new underlying_managerBLL(); var sList = bll.SearchList(req); return Json(sList); } /// /// 根据主键获取 /// [HttpPost] public JsonResult underlying_managerGetById(int id, DateTime? exerciseDate = null) { var data = DataCacheProvider.GetUnderlyingDataSource().GetData(id); if (data.IsCommoditySpot() && exerciseDate != null) { data.Price = CalculatorHelper.GetCommoditySpotPriceByValueDate(valuedateBLL.ValueDate, exerciseDate.Value, false, data.UnderlyingCode); } data.Variety = yldb.variety.Find(data.UnderlyingTypeId); if (data.UnderlyingInstrumentType != ConsGlobal.InstrumentType.CommodityFutures) { data.MaturityDate = DateTime.Today.AddYears(3); } return Json(data); } /// /// 根据品种id获取盯市主力合约 /// [HttpPost] public JsonResult GetMainUnderlyingByVarietyId(int id) { var variety = yldb.variety.Where(n => n.id == id).Select(n => new { n.VarietyCode }).FirstOrDefault(); var mainUnderlyingCode = variety == null ? "" : variety.VarietyCode == "AU99" ? "AU9999" : variety.VarietyCode + "00"; var data = yldb.underlying_manager.Where(x => x.UnderlyingTypeId == id && x.UnderlyingCode == mainUnderlyingCode).FirstOrDefault(); data = data ?? new underlying_manager(); return Json(data); } private double priceByTradeid(int tradeId, DateTime tradeDate) { var trade = yldb.trade.Where(O => O.id == tradeId).FirstOrDefault(); var p1 = underlyingGetByCode(trade.UnderlyingCode, tradeDate); if (PS.Config.ErpElement.ForwardTradePriceModel == Configuration.Enums.ForwardTradePriceModel.STANDARD && !string.IsNullOrWhiteSpace(trade.BasisUnderlyingCode)) { var p2 = underlyingGetByCode(trade.BasisUnderlyingCode, tradeDate); p1 -= p2; } return p1; } /// /// 获取报价参数和合约信息 /// private double underlyingGetByCode(string underlyingCode, DateTime? tradeDate = null) { var data = DataCacheProvider.GetUnderlyingDataSource().GetData(underlyingCode); if (data != null) { if (tradeDate != null && tradeDate != valuedateBLL.ValueDate) { if (EodPriceQueryService.TryGetEodPrice(Convert.ToDateTime(tradeDate), data.UnderlyingCode, out var eodPrice)) { return eodPrice.ClosePrice; } } else { DataCacheProvider.GetUnderlyingDataSource().TryGetPrice(data.UnderlyingCode, out var price); return price; } } return 0; } /// /// 获取报价参数和合约信息 /// [HttpPost] public JsonResult underlyingGetById(int id, string voltype, DateTime? tradeDate = null) { var data = yldb.underlying_manager.Find(id); if (data != null) { var retUnderlying = new underlying_managershow { underlying_manager = data }; // 获取不超过到期日的实行日 // 1个月,2周,1周,到日期这样的规则向前计算 if (!tradeDate.HasValue) { tradeDate = valuedateBLL.ValueDate; } data.ExerciseDate = QdpCalendarHelper.GetUnderlyingExerciseDate(data.MaturityDate ?? DateTime.Today.AddMonths(1), tradeDate.Value); retUnderlying.underlying_manager.Variety = VarietyBLL.GetAllvarietyModel().FirstOrDefault(v => v.id == data.UnderlyingTypeId); retUnderlying.rules = new UnderlyingParameterService(CurUser).InitialUnderlyingParameter(data.id); if (!string.IsNullOrEmpty(voltype)) { var request = new SingleVolatilityRequest { QuotationDate = tradeDate.Value, UnderlyingCode = data.UnderlyingCode, TradeVolWithBidAsk = false, UserGroup = CurUser.UserGroup, VolType = voltype }; retUnderlying.vols = new VolatilityQueryService(CurUser).GetVolatility(request, true).FirstOrDefault(); //retUnderlying.vols = VolatilityApiHelper.GetVols(tradeDate.Value, new List { voltype }, new List { data.UnderlyingCode }, CurUser.UserGroup).FirstOrDefault(); } if (data.IsBasket() || data.IsSynthetic()) { DataCacheProvider.GetUnderlyingDataSource().TryGetPrice(data.UnderlyingCode, out var price); retUnderlying.underlying_manager.Price = price; } if (tradeDate != null && tradeDate != valuedateBLL.ValueDate) { if (EodPriceQueryService.TryGetEodPrice(Convert.ToDateTime(tradeDate), data.UnderlyingCode, out var eodPrice)) { retUnderlying.underlying_manager.Price = eodPrice.ClosePrice; } } return Json(retUnderlying); } else { return JsonError("标的信息缺失"); } } public JsonResult TryGetTradeForwardFinalPrice(int tradeId, int underlyingId, string voltype, DateTime? tradeDate = null) { var message = ""; if (!tradeDate.HasValue) { tradeDate = valuedateBLL.ValueDate; } var observationDates = (from tf in yldb.trade_forward join t in yldb.trade on tf.TradeId equals t.id where t.id == tradeId select tf.ObservationDates).FirstOrDefault(); if (string.IsNullOrEmpty(observationDates)) { return JsonSuccess("", new { Price = priceByTradeid(tradeId, tradeDate.Value) }); } var observationDatesList = QdpHelper.GetObservationDatesFromString(observationDates).ToList(); observationDatesList.Sort(); var dateStart = observationDatesList.FirstOrDefault(); if (dateStart >= DateTime.Now) { //获取实时价格 return JsonSuccess("", new { Price = priceByTradeid(tradeId, tradeDate.Value) }); } var dateEnd = observationDatesList.LastOrDefault().AddDays(1); var tradeDates = QdpCalendarHelper.AllBizDays(dateStart, dateEnd); tradeDates = observationDatesList.Intersect(tradeDates).ToList(); var trade = yldb.trade.Where(O => O.id == tradeId).FirstOrDefault(); var Prices = EodPriceQueryService.GetEodPriceByUnserialDates(tradeDates, underlyingId); if (Prices == null || !Prices.Any()) { message += string.Join(",", tradeDates.Select(o => o.ToShortDateString())) + ":无价格"; return JsonError(message + ";均价计算失败"); } if (PS.Config.ErpElement.ForwardTradePriceModel == Configuration.Enums.ForwardTradePriceModel.STANDARD && !string.IsNullOrWhiteSpace(trade.BasisUnderlyingCode)) { var bUmId = DataCacheProvider.GetUnderlyingDataSource().GetData(trade.BasisUnderlyingCode).id; var P2s = EodPriceQueryService.GetEodPriceByUnserialDates(tradeDates, bUmId); if (Prices.Count != P2s.Count) { return JsonError("均价计算失败,标的1和标的2价格数量不一致!"); } for (var i = 0; i < Prices.Count; i++) { if (Prices[i].ValueDate != P2s[i].ValueDate) { return JsonError("均价计算失败,标的1和标的2价格序列日期不一致!"); } Prices[i].ClosePrice -= P2s[i].ClosePrice; } } var NoPriceDate = tradeDates.Except(Prices.Select(o => o.ValueDate)); if (NoPriceDate.Count() > 0) { message += string.Join(",", NoPriceDate.Select(o => o.ToShortDateString())) + ":无价格"; } var price = Prices.Select(o => o.ClosePrice).Average(); if (!string.IsNullOrWhiteSpace(message)) { message += ";已从计算中剔除"; } //return var retUnderlying = new { Price = price, message }; return JsonSuccess(message, retUnderlying); } public JsonResult GetUnderlyingPrices(List underlyings, DateTime valuedate) { var underlyingCodes = underlyings.Select(x => x.UnderlyingCode).ToArray(); underlyings = DataCacheProvider.GetUnderlyingDataSource() .AsQueryable().Where(x => underlyingCodes.Contains(x.UnderlyingCode)).ToList(); if (valuedate < valuedateBLL.ValueDate) { var eodPriceProvider = new EodPriceProvider(valuedate).Initialize(underlyingCodes); foreach (var underlying in underlyings) { underlying.Price = eodPriceProvider.GetPrice(underlying.UnderlyingCode, SettlementTypeEnum.ClosePrice); } } return JsonSuccessData(underlyings); } /// /// 获取报价参数和合约信息 /// public JsonResult GetUnderlyingPriceByCode(string code, int tradeId = 0, DateTime? valuedate = null) { var data = DataCacheProvider.GetUnderlyingDataSource().GetData(code); if (data == null) { return JsonError("标的信息缺失"); } var price = data.Price ?? 0; var systemDate = valuedateBLL.ValueDate; var trade = yldb.trade.Where(n => n.id == tradeId)?.FirstOrDefault(); var settlementFlag = (int?)trade?.SettlementFlag ?? 0; var settlementType = (int?)trade?.SettlementType ?? 0; //厦门象屿参考价时10点15分切换交易日 if (PS.Config.Company == Configuration.CompanyEnum.厦门象屿 && settlementType == (int)SettlementTypeEnum.ReferencePrice) { systemDate = Modules.SpecialModule.XiaMenXiangYuHelper.GetRefernceValueDate(); } if (valuedate == null || valuedate > systemDate) { return JsonSuccessData(data.Price); } if (data.IsBond()) { //系统日期当天优先取日终价格如果取不到则使用行情价格 if (EodPriceQueryService.TryGetBondEodPrice(valuedate.Value, code, out var eodPrice)) { price = eodPrice.GetPrice((SettlementTypeEnum)settlementType); } else { price = price * Convert.ToDouble(ConsGlobal.bondPriceMultiple); } return JsonSuccessData(price); } else { //系统日期当天优先取日终价格如果取不到则使用行情价格 if (EodPriceQueryService.TryGetEodPrice(valuedate.Value, code, out var eodPrice)) { price = eodPrice.GetPrice((SettlementTypeEnum)settlementType); return JsonSuccessData(price); } } if (valuedate != systemDate) { return JsonError("获取不到日终价格"); } return JsonSuccessData(price); } /// /// 获取报价参数和合约信息 /// [HttpPost] public JsonResult syntheticUnderlyingGetByCode(string underlyingCode, DateTime? tradeDate = null) { var data = DataCacheProvider.GetUnderlyingDataSource().GetData(underlyingCode); if (data != null) { new UnderlyingParameterService(CurUser).InitialUnderlyingParameter(data.id); var retData = new underlying_managershow(); // 获取不超过到期日的实行日 // 1个月,2周,1周,到日期这样的规则向前计算 if (!tradeDate.HasValue) { tradeDate = valuedateBLL.ValueDate; } data.ExerciseDate = QdpCalendarHelper.GetUnderlyingExerciseDate(data.MaturityDate ?? DateTime.Today, tradeDate.Value); var synthetic = new SyntheticUnderlyingPriceService(CurUser).GetPriceModel(underlyingCode); data.Price = synthetic.Price; retData.synthetic = synthetic; retData.underlying_manager = data; retData.underlying_manager.Variety = VarietyBLL.GetAllvarietyModel() .FirstOrDefault(x => x.id == data.UnderlyingTypeId) ?? new Variety { VarietyCode = "组合标的", VarietyName = "组合标的", ShortName = "" }; return JsonSuccess(null, retData); } else { return JsonError("标的信息缺失"); } } /// /// 更新underlying_manager /// [HttpPost] public JsonResult UpdateById(int id, UnderlyingManagerReq data) { new underlying_managerBLL().UpdateSingle(id, data); //启用时如果没有波动率,设置波动率为规则 OTC-5469 return JsonSuccess("更新成功", data); } /// /// 批量更新underlying_manager /// public JsonResult UpdateByIds(int[] ids, UnderlyingManagerReq data) { if (ids == null && ids.Length == 0) { return JsonError("请选择要更新的标的", data); } var launchState = data.LaunchState; if (data.isCheckAll) { //id从条件中选 var bll = new underlying_managerBLL(); var userVarieties = CurUser.GetUserVarietyIds(); data.rows = 9999999; data.page = 1; data.LaunchState = null;//查询时,不需要根据这个 var sList = bll.SearchList(data, userVarieties); ids = sList.rows.Select(r => r.id).ToArray(); } var unlist = yldb.underlying_manager.Where(u => ids.Contains(u.id)).ToList(); unlist.ForEach(x => x.LaunchState = launchState); yldb.SaveChanges(); return JsonSuccess("更新成功", data); } /// /// 启用/取消启用所有ST股 /// public JsonResult UpdateLaunchStateForSTStock(UnderlyingManagerReq data) { var allST = yldb.underlying_manager.Where(x => x.UnderlyingInstrumentType == "Stock" && x.UnderlyingName.Contains("ST")); foreach (var u in allST) { u.LaunchState = data.LaunchState; } yldb.SaveChanges(); return JsonSuccess("更新成功"); } public ActionResult underlying_managerView(string enid) { var intid = DataProtectHelper.DecryptInt(enid); var r = new UnderlyingDalService(CurUser).GetDetail(intid); var blocks = yldb.UnderlyingBlockConfig.Select(n => new { n.id, n.Name }).ToArray(); foreach (var item in blocks) { ViewData["block" + item.id] = item.Name; } new Modules.DicForTranslationModule.DicForTranslationService(CurUser).GetTransWord(r); return View(r); } public ActionResult underlying_managerEdit(string enid) { var model = new UnderlyingEditModel { Markets = JsDataModel.GetMarkets() }; if (string.IsNullOrEmpty(enid) || enid == "0") { model.Underlying = new underlying_manager() { VolumeStep = 1 //新增默认步进数量为1 }; } else { var intid = DataProtectHelper.DecryptInt(enid); var udm = yldb.underlying_manager.Find(intid); if (udm == null) { return ShowError("数据不存在"); } if (udm.IsFutures()) { if (udm.MaturityDate == null && !string.IsNullOrEmpty(udm.UnderlyingCode)) { udm.MaturityDate = QdpHelper.defaultMaturityDateFromContract(udm.UnderlyingCode); } } else if (udm.IsBond()) { model.Bond = JsonHelper.Deserialize(udm.ExJson); } model.Underlying = udm; } new Modules.DicForTranslationModule.DicForTranslationService(CurUser).GetTransWord(model.Underlying); return View(model); } [HttpPost] public JsonResult underlying_managerEditJson(UnderlyingSaveModel model) { if (model == null) { return JsonError("数据不能为空"); } if (string.IsNullOrEmpty(model.UnderlyingInstrumentType)) { return JsonError("资产类型 必须填写"); } if (ConsGlobal.InstrumentType.IsBond(model.UnderlyingInstrumentType)) { model.ExJson = JsonHelper.Serialize(model.Bond); } var r = new UnderlyingDalService(CurUser).SaveUnderlyingData(model); YLErp.Modules.UnderlyingModule.UnderlyingHelper.ClearMarginRateCache(model.UnderlyingCode); return JsonSuccess("更新成功", r); } public JsonResult GetUnderlyingByCode(string code) { if (string.IsNullOrWhiteSpace(code)) { return JsonError("请输入代码"); } var underlying = underlying_managerBLL.GetAllLiveunderlying_managerModel().FirstOrDefault(u => u.UnderlyingCode == code); if (underlying == null) { return JsonError("系统中没有相关的标的"); } return JsonSuccess("", underlying); } /// /// 预付金参数 /// public ActionResult MarginParams() { return View(); } /// /// 导入预付金参数 /// public ActionResult ImportMarginParams(IFormFile file) { MarginParamsImportResult result = null; if (Path.GetExtension(file?.FileName)?.ToLowerInvariant() != ".xlsx") { ViewData["ERROR"] = "请上传xlsx格式文件"; } else { try { using var openStream = file.OpenReadStream(); result = new MarginParamsImportService(CurUser).ImportUnderlying(openStream); } catch (Exception ex) { LogFactory.GetLogger("ImportMarginParams").Error(ex); ViewData["ERROR"] = "导入出错:" + ex.Message; } } return View("MarginParams", result); } /// /// 导入标的 /// public JsonResult UploadUnderlying() { if (Request.Form.Files.Count == 0) { return JsonError("上传文件不存在"); } var file = Request.Form.Files[0]; if (!System.IO.Path.GetExtension(file.FileName).Equals(".xlsx", StringComparison.OrdinalIgnoreCase)) { return JsonError("请上传Excel(.xlsx)格式文件"); } using var openStream = file.OpenReadStream(); new UnderlyingImportService(CurUser).ImportExcel(openStream, out var TotalNum, out var SuccessNum); return Json(new { success = true, totalNum = TotalNum, successNum = SuccessNum, }); } /// /// 导出预付金参数 /// public ActionResult ExportMarginParams() { var bytes = new MarginParamsExportService(CurUser).UnderlyingExport(); return File(bytes, xlsxMimeType, "标的预付金参数.xlsx"); } public JsonResult SubmitParameters(IEnumerable datas) { _ = new UnderlyingParameterService(CurUser).SaveDatas(datas); return JsonSuccess("更新成功", datas); } public ActionResult pop_parameterEdit(int under_id) { var Underlying = yldb.underlying_manager.Find(under_id); ViewBag.Underlying = Underlying; ViewBag.Underlying_Params = new UnderlyingParameterService(CurUser).InitialUnderlyingParameter(under_id); return View(Underlying); } public JsonResult AjaxSetUnderlyingPrice(int id, double price) { var um = yldb.underlying_manager.Find(id); if (um == null) { throw new ServiceException("没有找到标的"); } um.Price = price; yldb.SaveChanges(); return JsonSuccess(); } } }