using Qdp.Pricing.Base.Enums; using YLErp.QdpModule; namespace YLErp.Modules.TradeModule.OrderModule { /// /// 扩展存储 /// class TradeSaveExtend : YLBaseService { private readonly bool isAddNew; public TradeSaveExtend(YLBaseService baseService, bool isAddNew) : base(baseService) { this.isAddNew = isAddNew; } /// /// 保存并写入数据库 /// public int Save(trade baseTrade, trade dbTrade, bool useSaveChange = true) { switch (baseTrade.TradeType == "结构化交易" ? baseTrade.StructureType : baseTrade.TradeType) { case "香草期权": case "合成价差期权": return 0; case "亚式期权": dbTrade.trade_asian_option = InnerSaveExtend(baseTrade, baseTrade.trade_asian_option); break; case "彩虹期权": dbTrade.trade_rainbow_option = InnerSaveExtend(baseTrade, baseTrade.trade_rainbow_option); break; case "障碍期权": dbTrade.trade_barrier_option = InnerSaveExtend(baseTrade, baseTrade.trade_barrier_option); break; case "二元期权": dbTrade.trade_binary_option = InnerSaveExtend(baseTrade, baseTrade.trade_binary_option); break; case "价差期权": dbTrade.trade_spread_option = InnerSaveExtend(baseTrade, baseTrade.trade_spread_option); break; case "双鲨期权": dbTrade.trade_double_sharkfin_option = InnerSaveExtend(baseTrade, baseTrade.trade_double_sharkfin_option); break; case "凤凰期权": if (string.IsNullOrEmpty(baseTrade.trade_autocall.KOObservationDates)) { if (dbTrade.trade_autocall==null) { dbTrade.trade_autocall = new trade_autocall(); } var autocallmonthlyDates = QdpObservationHelper.GetDatesWithFixedTerm(baseTrade.TradeDate ?? System.DateTime.Now, baseTrade.ExerciseDate ?? System.DateTime.Now, "1M", bdc: BusinessDayConvention.Following, alignEnd: true); dbTrade.trade_autocall.KOObservationDates = $"{string.Join(",", autocallmonthlyDates.Select(O => O.OtcFormatDate()))};" + $"{string.Join(",", autocallmonthlyDates.Select(O => baseTrade.trade_autocall.KOBarrier.OtcFormatFlex(2)))};" + $"{string.Join(",", autocallmonthlyDates.Select(O => baseTrade.trade_autocall.Coupon.OtcFormatFlex(2)))}"; baseTrade.trade_autocall.KOObservationDates = dbTrade.trade_autocall.KOObservationDates; } dbTrade.trade_autocall = InnerSaveExtend(baseTrade, baseTrade.trade_autocall); break; case "雪球期权": if (string.IsNullOrEmpty(baseTrade.trade_snowball.KOObservationDates)) { if (dbTrade.trade_snowball == null) { dbTrade.trade_snowball = new trade_snowball(); } var snowballmonthlyDates = QdpObservationHelper.GetDatesWithFixedTerm(baseTrade.TradeDate ?? System.DateTime.Now, baseTrade.ExerciseDate ?? System.DateTime.Now, "1M", bdc: BusinessDayConvention.Following, alignEnd: true); dbTrade.trade_snowball.KOObservationDates = $"{string.Join(",", snowballmonthlyDates.Select(O => O.OtcFormatDate()))};" + $"{string.Join(",", snowballmonthlyDates.Select(O => baseTrade.trade_snowball.KOBarrier.OtcFormatFlex(2)))};" + $"{string.Join(",", snowballmonthlyDates.Select(O => baseTrade.trade_snowball.KORebate.OtcFormatFlex(2)))}"; if (dbTrade.trade_snowball.KOPayoffType == KOPayoffTypeEnum.Rebate) { baseTrade.trade_snowball.KOObservationSettleDates = $"{string.Join(",", snowballmonthlyDates.Select(O => O.OtcFormatDate()))}"; } baseTrade.trade_snowball.KOObservationDates = dbTrade.trade_snowball.KOObservationDates; } dbTrade.trade_snowball = InnerSaveExtend(baseTrade, baseTrade.trade_snowball); break; case "区间累积期权": dbTrade.trade_rangeaccrual = InnerSaveExtend(baseTrade, baseTrade.trade_rangeaccrual); break; case "气囊结构": dbTrade.trade_airbag = InnerSaveExtend(baseTrade, baseTrade.trade_airbag); break; case "收益增强结构": dbTrade.trade_underlying_enhance = InnerSaveExtend(baseTrade, baseTrade.trade_underlying_enhance); break; case "远期": dbTrade.trade_forward = InnerSaveExtend(baseTrade, baseTrade.trade_forward); break; case "收益互换": if (baseTrade.trade_swap.IsGetFloatingProfit) { var underlyingManager = DataCacheProvider.GetUnderlyingDataSource().GetData(baseTrade.trade_swap.GetUnderlyingCode); var CountRatio = underlyingManager?.CountRatio ?? 1; baseTrade.trade_swap.GetNotional = baseTrade.trade_swap.GetTradeAmount * CountRatio; dbTrade.OriginalNotional = baseTrade.trade_swap.GetNotional; dbTrade.Notional = baseTrade.trade_swap.GetNotional ?? 0; dbTrade.TradeAmount = baseTrade.trade_swap.GetTradeAmount ?? 0; dbTrade.SpotPrice = baseTrade.trade_swap.GetSpotPrice; } if (baseTrade.trade_swap.IsPayFloatingProfit) { var underlyingManager = DataCacheProvider.GetUnderlyingDataSource().GetData(baseTrade.trade_swap.PayUnderlyingCode); var CountRatio = underlyingManager?.CountRatio ?? 1; baseTrade.trade_swap.PayNotional = baseTrade.trade_swap.PayTradeAmount * CountRatio; dbTrade.OriginalNotional = baseTrade.trade_swap.PayNotional; dbTrade.Notional = baseTrade.trade_swap.PayNotional ?? 0; dbTrade.TradeAmount = baseTrade.trade_swap.PayTradeAmount ?? 0; dbTrade.SpotPrice = baseTrade.trade_swap.PaySpotPrice; } DbContext.SaveChanges(); dbTrade.trade_swap = InnerSaveExtend(baseTrade, baseTrade.trade_swap); dbTrade.get_trade_swap_details = InnerSaveTradeSwapDetail(baseTrade, baseTrade.get_trade_swap_details, true); dbTrade.pay_trade_swap_details = InnerSaveTradeSwapDetail(baseTrade, baseTrade.pay_trade_swap_details, false); if (baseTrade.ParentTradeId > 0) { var detail = DbContext.trade_swap_detail.FirstOrDefault(x => x.TradeId == baseTrade.ParentTradeId && x.ChildTradeId == baseTrade.id); if (detail != null) { detail.LongShort = detail.IsForGet ? baseTrade.trade_swap.GetLongShort : baseTrade.trade_swap.PayLongShort; detail.Notional = detail.IsForGet ? baseTrade.trade_swap.GetNotional : baseTrade.trade_swap.PayNotional; detail.UnderlyingCode = detail.IsForGet ? baseTrade.trade_swap.GetUnderlyingCode : baseTrade.trade_swap.PayUnderlyingCode; detail.SpotPrice = detail.IsForGet ? baseTrade.trade_swap.GetSpotPrice : baseTrade.trade_swap.PaySpotPrice; detail.OriginalNotional = detail.Notional; } else { detail = new trade_swap_detail() { IsForGet = baseTrade.trade_swap.IsGetFloatingProfit }; detail.LongShort = detail.IsForGet ? baseTrade.trade_swap.GetLongShort : baseTrade.trade_swap.PayLongShort; detail.Notional = detail.IsForGet ? baseTrade.trade_swap.GetNotional : baseTrade.trade_swap.PayNotional; detail.UnderlyingCode = detail.IsForGet ? baseTrade.trade_swap.GetUnderlyingCode : baseTrade.trade_swap.PayUnderlyingCode; detail.SpotPrice = detail.IsForGet ? baseTrade.trade_swap.GetSpotPrice : baseTrade.trade_swap.PaySpotPrice; detail.OriginalNotional = detail.Notional; detail.TradeId = baseTrade.ParentTradeId; detail.ChildTradeId = baseTrade.id; DbContext.trade_swap_detail.Add(detail); } DbContext.SaveChanges(); } break; case "现金流交易": dbTrade.trade_cashflow = InnerSaveExtend(baseTrade, baseTrade.trade_cashflow); break; case "自定义交易": dbTrade.trade_custom = InnerSaveExtend(baseTrade, baseTrade.trade_custom); break; case "累计期权": dbTrade.trade_accumulator_option = InnerSaveExtend(baseTrade, baseTrade.trade_accumulator_option); break; case "Risky期权": dbTrade.trade_risky_option = InnerSaveExtend(baseTrade, baseTrade.trade_risky_option); break; default: return 0; } return useSaveChange ? DbContext.SaveChanges() : 0; } private List InnerSaveTradeSwapDetail(trade baseTrade, List tradeSwapDetails, bool isForGet) { if (tradeSwapDetails != null && tradeSwapDetails.Any()) { var tradeSwapDetailsExist = DbContext.trade_swap_detail.Where(x => x.TradeId == baseTrade.id && x.IsForGet == isForGet); DbContext.trade_swap_detail.RemoveRange(tradeSwapDetailsExist); tradeSwapDetails.ForEach(x => { x.ExerciseDate = baseTrade.ExerciseDate; x.IsForGet = isForGet; x.OriginalNotional = x.Notional; x.SwapTimeAndRate = isForGet ? baseTrade.trade_swap.PaySwapTimeAndRate : baseTrade.trade_swap.GetSwapTimeAndRate; x.TradeId = baseTrade.id; SetDBModelOpt(x); }); DbContext.trade_swap_detail.AddRange(tradeSwapDetails); DbContext.SaveChanges(); } return tradeSwapDetails; } //保存扩展数据 private T InnerSaveExtend(trade baseTrade, T extend) where T : TradeExtendBase { SetDBModelOpt(extend); extend.TradeId = baseTrade.id; var exist = isAddNew ? null : DbContext.Set().FirstOrDefault(n => n.TradeId == baseTrade.id); if (exist == null) { extend.id = 0; DbContext.Set().Add(extend); } else { extend.id = exist.id; UpdateEntity(exist, extend); } return extend; } } }