using YLErp.BLL.MarginCalculation; namespace YLErp.Modules.TradeRiskCalcModule { /// /// 实时预付金计算服务 /// public class RealTimeMarginService : YLBaseService { static int _runingFlag; static IEnumerable _results; public RealTimeMarginService(OptUserInfo userInfo) : base(userInfo) { } /// /// 获取实时预付金计算结果(1分钟执行一次) /// public IEnumerable GetRealTimeMarginResult() { if (Interlocked.Increment(ref _runingFlag) == 1) { Task.Run(() => InnerGetRealTimeMarginResult()); } return _results ?? Enumerable.Empty(); } private void InnerGetRealTimeMarginResult() { try { var query = from t in DbContext.trade.AsNoTracking() where t.ClientId > 0 && t.TradeType != "远期"&& t.TradeType != "现金流交易" && t.ValidState != "Invalid" && !ConsTrade.TradeCompleteStatus.Contains(t.TradeStatus) select t; var tds = query.ToArray(); var results = new List(tds.Length); foreach (var td in tds) { var result = new RealTimeMarginResult { BuySell = td.BuySell, ClientName = td.ClientName, ExerciseDate = td.ExerciseDate?.ToString("yyyy-MM-dd"), SpotPrice = td.SpotPrice, Strike = td.Strike, TradeDate = td.TradeDate?.ToString("yyyy-MM-dd"), TradeType = td.TradeType, TradeNumber = td.TradeNumber, UnderlyingCode = td.UnderlyingCode, StockEqvNotionalReal = td.StockEqvNotionalReal }; try { var countRatio = UnderlyingDataProvider.GetCountRatio(td.UnderlyingCode); var notional = td.SpotPrice.HasValue && td.SpotPrice.Value != 0 ? td.StockEqvNotionalReal / td.SpotPrice.Value : 0; result.TradeAmount = notional / countRatio; var PositionAmountPercent = 0d; if (td.OriginalStockEqvNotional.HasValue && td.OriginalStockEqvNotional != 0) { PositionAmountPercent = td.StockEqvNotional / td.OriginalStockEqvNotional.Value; result.PositionAmountPercent = PositionAmountPercent.ToString("P4"); } if (td.IsUsePremiumRate == true) { result.PositionAmount = result.TradeAmount * PositionAmountPercent; } else { result.PositionAmount = td.TradeAmount; } var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(td.UnderlyingCode); if (underlying == null) { result.ErrorMsg = "找不到标的信息"; } else { var buysell = td.BuySell; td.BuySell = "买入"; td.VolType = "报价Bid"; //关于交易id的多义性: 1.组合交易需要真实的交易id;2.考虑到波动率不能获取持仓波动率,将id赋值为0;3.定价页面结构化交易子交易id会赋值-1和-2 var req = new GetTradeMarginReq { realTradeId = td.id, trade = td, hasOptionInfo = true, price = (underlying.Price ?? 0) }; result.Margin = MarginDefault.GetTradeMargin(req); } } catch (Exception ex) { LogFactory.GetLogger("RealTimeMarginService").Error("计算实时预付金", ex); result.ErrorMsg = ex.GetBaseException().Message; } results.Add(result); } _results = results; } catch (Exception ex) { LogFactory.GetLogger("RealTimeMarginService").Error("计算实时预付金", ex); } finally { Thread.Sleep(30 * 1000); Interlocked.Exchange(ref _runingFlag, 0); } } } /// /// 实时预付金数据 /// public class RealTimeMarginResult { /// /// 交易编号 /// public string TradeNumber { get; set; } /// /// 交易对手方 /// public string ClientName { get; set; } /// /// 交易日期 /// public string TradeDate { get; set; } /// /// 到期日期 /// public string ExerciseDate { get; set; } /// /// 交易方向 /// public string BuySell { get; set; } /// /// 结构类型 /// public string TradeType { get; set; } /// /// 标的代码 /// public string UnderlyingCode { get; set; } /// /// 期初价格 /// public double? SpotPrice { get; set; } /// /// 行权价 /// public double? Strike { get; set; } /// /// 交易数量 /// public double? TradeAmount { get; set; } /// /// 实际名义金额 /// public double? StockEqvNotionalReal { get; set; } /// /// 持仓数量 /// public double? PositionAmount { get; set; } /// /// 持仓比例 /// public string PositionAmountPercent { get; set; } /// /// 预付金 /// public double Margin { get; set; } /// /// 计算预付金错误信息 /// public string ErrorMsg { get; set; } } }