using System.Linq.Expressions; using YLErp.Abstract; using YLErp.Abstract.DataProviders; using YLErp.Commons; using YLErp.DBModels; using YLErp.Modules.CalculationModule; using YLErp.Modules.CalculationModule.Abstract; using YLErp.Modules.DataProviderModule; using YLErp.Modules.EodModule; using YLErp.Modules.TradeRiskCalcModule.Abstract; namespace YLErp.Modules.TradeRiskCalcModule { class TradeRiskCalcTestContextBase { public DateTime ValueDate { get; } public bool IsEodSettle { get; } public bool UseClosePrice { get; } public TraceWrap Trace { get; } protected TradeRiskCalcTestContextBase(TradeRiskCalcTestRequest request) { if (request is null) { throw new ArgumentNullException(nameof(request)); } ValueDate = request.ValueDate; IsEodSettle = request.IsEodSettle; UseClosePrice = request.UseClosePrice; Trace = new TraceWrap("实时风险调试"); } } class TradeRiskCalcTestContext : TradeRiskCalcTestContextBase, ITradeRiskCalcContext { readonly TradeRiskCalcTestRequest2 _request2; public TradeRiskCalcTestContext(TradeRiskCalcTestRequest request, TradeRiskCalcTestRequest2 request2) : base(request) { _request2 = request2 ?? throw new ArgumentNullException(nameof(request)); VolType = request.VolType; Trace.WriteLine("当前交易日:" + ValueDate); PreValueDate = QdpModule.QdpCalendarHelper.GetNonHolidayDefore(request.ValueDate.AddDays(-1)); PreSettleDate = BLL.Eod.EodOperationBase.GetLastSettlementDate(ValueDate, true); Trace.WriteLine("上一交易日:" + PreSettleDate); OptionCalcDataProvider = new OptionCalcDataProvider(this); YdEodPriceProvider = new EodPriceProvider(PreSettleDate); YdTradeHisDataProvider = new TradeHisDataProvider(PreSettleDate); YdEodPositionDataProvider = new YdEodPositionDataProvider().Initialize(_request2, PreSettleDate, OptionCalcDataProvider.UnderlyingDataProvider); } public string VolType { get; } public DateTime PreValueDate { get; } public DateTime PreSettleDate { get; } public IOptionCalcDataProvider OptionCalcDataProvider { get; } public IEodPriceProvider YdEodPriceProvider { get; } public ITradeHisDataProvider YdTradeHisDataProvider { get; } public bool HasError { get; private set; } public void AddError(string error) { HasError = true; Trace.WriteLine("[ERROR]发生错误:" + error); } IPriceProvider _ExchangeOptionPriceProvider; public IHedgePnlCalcContext CreateHedgePnlCalcContext(IOtcTradeValueCalcContext optionValueCaclContext) { if (_ExchangeOptionPriceProvider == null) { if (IsEodSettle) { _ExchangeOptionPriceProvider = new EodExchangeOptionPriceProvider(ValueDate, UseClosePrice); } else { _ExchangeOptionPriceProvider = new ExchangeOptionPriceProvider(); } } return new HedgePnlCalcContext(optionValueCaclContext, new ExchangeTradeCommissionCalc(), _ExchangeOptionPriceProvider); } OptionCalcDataProvider _OptionCalcDataProvider; public IOtcTradeValueCalcContext CreateOptionValueCalcContext(double sysRiskFreeRate) { if (_OptionCalcDataProvider == null) { _OptionCalcDataProvider = new OptionCalcDataProvider(this); } return new OptionValueCalcContext(VolType, IsEodSettle, ValueDate, sysRiskFreeRate, _OptionCalcDataProvider) { Trace = Trace, CalcScenario = Enums.CalcScenarioEnum.RealtimeRisk }; } public IEnumerable GetErrors() { throw new NotImplementedException(); } public IEnumerable GetTrade_Cashes(IEnumerable tradeIds) { using (var db = DbContextFactory.GetYLDbContext()) { //在使用时会判断ValidState(猜测是为新增待确认的交易) return db.trade_cash.Where(t => tradeIds.Contains(t.TradeId) && !t.IsDeleted).ToList(); } } public ITradeRiskEodPositionDataProvider YdEodPositionDataProvider { get; } } class YdEodPositionDataProvider : ITradeRiskEodPositionDataProvider { readonly Dictionary _positionVolOtcTradeDic; readonly Dictionary _hedgeVolOtcTradeDic; readonly List _exchangeTradeList; public YdEodPositionDataProvider() { _positionVolOtcTradeDic = new Dictionary(); _hedgeVolOtcTradeDic = new Dictionary(); _exchangeTradeList = new List(); } private Expression> CreatePredicate(TradeRiskCalcTestRequest2 _request2) where T : EodTradePosition { var predicate = PredicateBuilder.True(); if (_request2.TradeId > 0) { predicate = predicate.And(n => n.TradeId == _request2.TradeId); } else { if (_request2.ClientId > 0) { predicate = predicate.And(n => n.ClientId == _request2.ClientId); } if (_request2.UnderlyingCodes != null && _request2.UnderlyingCodes.Any()) { predicate = predicate.And(n => _request2.UnderlyingCodes.Contains(n.UnderlyingCode, StringComparer.OrdinalIgnoreCase)); } if (!string.IsNullOrEmpty(_request2.TradeType)) { predicate = predicate.And(n => _request2.TradeType.Equals(n.TradeType, StringComparison.OrdinalIgnoreCase)); } if (_request2.AssetBookId > 0) { predicate = predicate.And(n => n.BookId == _request2.AssetBookId); } } return predicate; } public YdEodPositionDataProvider Initialize(TradeRiskCalcTestRequest2 request, DateTime positionDate, IUnderlyingDataProvider underlyingDataProvider) { if (underlyingDataProvider is null) { throw new ArgumentNullException(nameof(underlyingDataProvider)); } var where = CreatePredicate(request); _exchangeTradeList.Capacity = 500; var service = new EodSettlementService(OptUserInfo.SystemUser); var eodPositions = service.GetEodTradePosition(positionDate, where); foreach (var item in eodPositions) { if (item.Position.TradeId > 0) { _positionVolOtcTradeDic[item.Position.TradeId] = item; } else if (item.Position.TradeType == "商品期货") { var un = underlyingDataProvider.GetUnderlying(item.Position.UnderlyingCode); if (un == null || un.MaturityDate.HasValue && DateTime.Compare(un.MaturityDate.Value, positionDate) > 0) { _exchangeTradeList.Add(item.Position); } } else { _exchangeTradeList.Add(item.Position); } } _exchangeTradeList.TrimExcess(); var where2 = CreatePredicate(request).And(x => x.TradeId > 0); //对冲波动率计算出来的日终持仓 var eodPositions2 = service.GetEodTradePosition(positionDate, where2); foreach (var item in eodPositions2) { if (item.Position.TradeId > 0) { _hedgeVolOtcTradeDic[item.Position.TradeId] = item; } } return this; } /// /// 根据交易ID和波动率类型获取场外交易 /// /// /// 对冲|持仓 /// public EodTradePositionAndRisk GetOtcTradePositionData(int tradeId, string volType) { if (volType == "对冲") { return _hedgeVolOtcTradeDic.TryGetValue(tradeId, out var item) ? item : null; } else { return _positionVolOtcTradeDic.TryGetValue(tradeId, out var item) ? item : null; } } public IEnumerable GetExchangeTradePositionList(string volType) => _exchangeTradeList; } }