using System.Diagnostics; using YLErp.Modules.TradeModule.ExoticOptionModule; namespace YLErp.Modules.TradeModule.ObservationModule { /// /// 雪球期权观察 /// partial class OptionObservationService { /// /// 雪球期权 /// private CheckObservationResult CheckSnowballKioStatus(trade td, DateTime valueDate, double price) { var tdEx = td.trade_snowball; if (tdEx.PrepaymentUsed) { return CheckSnowballKioStatusForSpecial(td, tdEx, valueDate, price); } var result = new CheckObservationResult { UnderlyingCode = td.UnderlyingCode }; var (blKI, blKO) = IsObservationDay(td, valueDate, tdEx.ObservationDates, tdEx.KOObservationDates); result.IsObservationDay = (tdEx.KIPayoffType != KIPayoffTypeEnum.None && blKI) || blKO; if (tdEx.IsInitialKnockedIn) { result.IsObservationDay = blKO; } if (result.IsObservationDay) { //若所有条件都未满足的默认值处理 if (tdEx.KnockInOutStatusCn == "已敲入") { result.KnockInOutStatusObservation = "敲入"; } else { result.KnockInOutStatusObservation = "观察中"; } result.KOBarrier = TradeObservationHelper.GetPriceByDate(tdEx.KOObservationDates, valueDate) ?? tdEx.KOBarrier; if (td.IsMoneynessOptionData) { result.KOBarrier *= td.SpotPrice ?? 0; } var kiBarrier = new Lazy(() => td.IsMoneynessOptionData ? tdEx.KIBarrier * td.SpotPrice : tdEx.KIBarrier); if (ConsGlobal.CallPut.IsCall(td.OptionType)) { //向上敲出向下敲入 if (blKO && price >= result.KOBarrier.Value) { result.KnockInOutStatusObservation = "敲出"; } else if (blKI && price <= kiBarrier.Value && tdEx.KIPayoffType != KIPayoffTypeEnum.None) { result.KnockInOutStatusObservation = "敲入"; } } else { //向下敲出向上敲入 if (blKO && price <= result.KOBarrier.Value) { result.KnockInOutStatusObservation = "敲出"; } else if (blKI && price >= kiBarrier.Value && tdEx.KIPayoffType != KIPayoffTypeEnum.None) { result.KnockInOutStatusObservation = "敲入"; } } if (result.KnockInOutStatusObservation == "敲出" && tdEx.KOPayoffType != KOPayoffTypeEnum.Rebate) { var kOOptionPayoff = new TradeSnowballService(this).GetKOOptionPayoff(td, tdEx, valueDate, price); result.CheckData["snowball_ExerciseMoneyAtKO"] = kOOptionPayoff.OtcFormatMoney(); //交割金额 } } else { result.KOBarrier = tdEx.KOBarrier; if (td.IsMoneynessOptionData) { result.KOBarrier *= td.SpotPrice ?? 0; } } //结算金额 var defaultAmount = new TradeSnowballBLL(this).GetDefaultAmount(td, tdEx, valueDate, price); result.CheckData["结算金额"] = defaultAmount.OtcFormatMoney(); return result; } /// /// 雪球期权 /// private CheckObservationResult CheckSnowballKioStatusForSpecial(OtcTrade td, trade_snowball tdEx, DateTime valueDate, double price) { Debug.Assert(tdEx.PrepaymentUsed); var result = new CheckObservationResult { UnderlyingCode = td.UnderlyingCode, IsObservationDay = true, KnockInOutStatusObservation = tdEx.KnockInOutStatusCn == "已敲入" ? "敲入" : "观察中", KOBarrier = td.IsMoneynessOptionData ? tdEx.KOBarrier * (td.SpotPrice ?? 0) : tdEx.KOBarrier }; var res = new TradeSnowballBLL(this).GetDefaultAmountForSpecialSnowball(td, tdEx, valueDate, price); switch (res.ResultType) { case SnowballObservationResultType.NonObservationDay: result.IsObservationDay = false; break; case SnowballObservationResultType.KnockedIn: result.KnockInOutStatusObservation = "敲入"; break; case SnowballObservationResultType.KoPayoff: result.KnockInOutStatusObservation = "敲出"; break; case SnowballObservationResultType.KiPayoffAtEndDate: result.KnockInOutStatusObservation = "敲入"; break; case SnowballObservationResultType.Monitoring: case SnowballObservationResultType.NkiPayoffAtEndDate: break; } result.KOBarrier = res.KoBarrier; result.CheckData["结算金额"] = res.PaymentAmount.OtcFormatMoney(); return result; } } }