using YLErp.Configuration; using YLErp.Modules.DataProviderModule; namespace YLErp.Modules.EodModule.SettlementModule { public class EodSettlementContextV2 : EodSettlementContextBase { List _otcTrades; TradeCashDataProvider _tradeCashProvider; //节假日不需要处理的交易 IEnumerable _holidayTrades; HashSet _holidayTradeIds; EodCurrencyProvider _currencyProvider; IEnumerable _currencyCodes; public EodSettlementContextV2(EodSettlementRequest request, SettlementConfig settlementConfig, CancellationToken cancellationToken) : base(request, cancellationToken) { SettlementConfig = settlementConfig ?? throw new ArgumentNullException(nameof(settlementConfig)); } /// /// 结算配置 /// public SettlementConfig SettlementConfig { get; } /// /// 衍生品交易 /// public List OtcTrades { get { if (_otcTrades == null) { lock (this) { if (_otcTrades == null) { _otcTrades = InitOtcTrades(); } } } return _otcTrades; } } /// /// 节假日不需要处理的交易 /// public IEnumerable HolidayTrades { get { if (_holidayTrades == null) { lock (this) { if (_holidayTrades == null) { _holidayTrades = OtcTrades.Where(n => { var un = DataCacheProvider.GetUnderlyingDataSource().GetData(n.UnderlyingCode); if (string.IsNullOrEmpty(un?.MarketCode)) { return false; } return ExchangeStatus.IsHoliday(un.MarketCode); }).ToArray(); } } } return _holidayTrades; } } /// /// 初始化缓存(重置缓存) /// public List InitOtcTrades(bool isGuoJunNeedBesideSwapTrade = false) { var list = new EodSettleDataQueryService(UserInfo) .GetOtcTrades(SettleDate, PredicateBuilder.GetOtcTradePredicate(isGuoJunNeedBesideSwapTrade), out _tradeCashProvider); var hisDataProvider = new TradeHisDataProvider(SettleDate).Initialize(); var underlyingIds = list.Where(O => O.DividendRate == null).Select(O => O.UnderlyingId); var umDividendDict = DbContextFactory.GetYLDbContext().UnderlyingDividend .Where(O => underlyingIds.Contains(O.UnderlyingId) && O.ValueDate <= SettleDate).ToList() .GroupBy(O => O.UnderlyingId) .ToDictionary(K => K.Key, V => V.OrderByDescending(O => O.ValueDate).FirstOrDefault().DividendRate); var recordlist = DbContextFactory.GetYLDbContext().dividendrate_record.Where(x => SettleDate >= x.ValueDate).ToList(); foreach (var item in list) { var noRiskRate = hisDataProvider.GetNoRiskRate(item.id); var dividendRate = hisDataProvider.GetDividendRate(item.id); //国元固收默认从全局配置里取分红率,如果TradeHisData里有分红率,则根据生效时间取最优 if (recordlist != null && recordlist.Any()) { var record = recordlist.Where(x => x.UnderlyingCode.Split(',').Any(code => code == item.UnderlyingCode) && x.TradeType.Contains(item.TradeType) && (x.OptionType == item.OptionType || x.OptionType == "全部")).OrderByDescending(x => x.OptDate).OrderByDescending(x => x.ValueDate); if (record.Any()) { dividendRate = record.FirstOrDefault()?.DividendRate; } } //如果修改过无风险利率或分红率,且和eodTrade中不匹配,则移除该交易来自EodTrade的标记; if (((noRiskRate ?? 0) > 0 && noRiskRate.GetValueOrDefault() != item.NoRiskRate.GetValueOrDefault()) || (dividendRate.HasValue && dividendRate.GetValueOrDefault() != item.DividendRate.GetValueOrDefault())) { item.MetaDic.Remove("from_eod_trade"); } item.NoRiskRate = noRiskRate ?? item.NoRiskRate ?? BLL.valuedateBLL.RiskFreeRate; item.DividendRate = dividendRate ?? item.DividendRate; if (item.DividendRate == null) { item.DividendRate = umDividendDict.TryGetValue(item.UnderlyingId, out var value) ? value : DataCacheProvider.GetUnderlyingDataSource().GetData(item.UnderlyingCode)?.DividendRate ?? item.NoRiskRate; } } _otcTrades = list; return list; } /// /// 交易资金流水数据提供 /// public ITradeCashDataProvider TradeCashProvider => _tradeCashProvider ?? (_tradeCashProvider = new TradeCashDataProvider()); /// /// 是否当前结算日期时交易所为节假日的交易 /// public bool IsHolidayTrade(int tradeId) { if (_holidayTradeIds == null) { _holidayTradeIds = HolidayTrades.Select(n => n.id).ToHashSet(); } return _holidayTradeIds.Contains(tradeId); } /// /// 获取日终汇率提供对象 /// public EodCurrencyProvider EodCurrencyProvider { get { if (_currencyProvider == null) { _currencyProvider = new EodCurrencyProvider(SettleDate, seekPreDay: false); } return _currencyProvider; } } /// /// 多币种代码(所有代码都大写) /// public IEnumerable CurrencyCodes { get { if (_currencyCodes == null) { _currencyCodes = DbContextFactory.GetYLDbContext().currency .Where(n => n.StartDate == null || n.StartDate.Value <= SettleDate) .Select(n => n.CurrencyCode).AsEnumerable() .Select(n => n.ToUpperInvariant()).ToArray(); if (_currencyCodes == null || !_currencyCodes.Any()) { _currencyCodes = new string[] { string.Empty }; } } return _currencyCodes; } } } }