using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using YLErp.Abstract; using YLErp.DBModels; using YLErp.Modules.TradeModule.AccumulatorOptionModule; using YLErp.Modules.TradeModule.KnockOutModule.Dto; namespace YLErp.Modules.TradeModule.KnockOutModule { /// /// 累计期权敲出计算服务 /// public class AccumulatorTradeKnockOutService : ITradeKnockOutService { /// /// 获取敲出payoff /// /// /// /// /// /// public GetKnockOutPayoffResult GetKnockOutPayoff(trade td, double underlyingPrice, DateTime _valueDate, ITradeExtendDataProvider _tradeExtendDataProvider) { var accumulatorOption = _tradeExtendDataProvider.GetTrade_Accumulator_Option(td.id); if (accumulatorOption == null) { return new GetKnockOutPayoffResult { IsKnockOut = false }; } td.trade_accumulator_option = accumulatorOption; return GetKnockOutPayoff(td, underlyingPrice, _valueDate); } /// /// 获取敲出payoff /// /// /// /// /// /// public GetKnockOutPayoffResult GetKnockOutPayoff(trade td, double underlyingPrice, DateTime _valueDate) { GetKnockOutPayoffResult result = new GetKnockOutPayoffResult { IsKnockOut = false }; var accumulatorOption = td.trade_accumulator_option; if (accumulatorOption == null) { return result; } var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(td.UnderlyingCode); var notional = accumulatorOption.AccumuTradeAmount * underlying.CountRatio; var changeData = GetChangeDataOfSepecialDay(td.id, _valueDate); CheckResult checkResult = null; if (changeData != null) { //关键点:还原换月设置到交易时不要更新当前传入的trade和tradeAcc,因为这两个数据涉及到数据库更新 var tdClone = new trade(); YLAutoMapper.Map(td, tdClone); var tdAccClone = accumulatorOption.Clone(); tdClone.trade_accumulator_option = accumulatorOption; TradeAccumulatorHelper.RestoreAccumulatorChangeData(tdClone, tdAccClone, changeData); checkResult = TradeAccumulatorService.CheckAccumulatorPayoff(tdClone, tdAccClone, _valueDate, underlyingPrice, notional); } else { checkResult = TradeAccumulatorService.CheckAccumulatorPayoff(td, accumulatorOption, _valueDate, underlyingPrice, notional); } if (checkResult != null && "敲出".Equals(checkResult.SettlementMode) && accumulatorOption.EarlyTerminate) { result.IsKnockOut = true; result.Payoff = 0; } return result; } /// /// 获取累计期权换月设置 /// /// /// /// private TradeAccumulatorChangeData GetChangeDataOfSepecialDay(int tradeId, DateTime valueDate) { using(var db = DbContextFactory.GetYLDbContext()) { var query = from a in db.TradeAction.AsNoTracking() where a.IsValid && a.TradeId == tradeId && a.ValueDate <= valueDate && a.ActionType == TradeActionType.AccumulatorChange orderby a.ValueDate descending select a.ActionData; var actionData = query.FirstOrDefault(); if (string.IsNullOrEmpty(actionData)) { return null; } return JsonHelper.Deserialize(actionData); } } } }