145 lines
5.5 KiB
C#
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;
|
|
}
|
|
|
|
}
|
|
}
|