Files
zszq-trs/YLErpDAL/Modules/TradeModule/ObservationModule/OptionObservationService_Snowball.cs
T
2024-05-09 14:06:26 +08:00

145 lines
5.5 KiB
C#

using System.Diagnostics;
using YLErp.Modules.TradeModule.ExoticOptionModule;
namespace YLErp.Modules.TradeModule.ObservationModule
{
/// <summary>
/// 雪球期权观察
/// </summary>
partial class OptionObservationService
{
/// <summary>
/// 雪球期权
/// </summary>
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<double?>(() => 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;
}
/// <summary>
/// 雪球期权
/// </summary>
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;
}
}
}