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

95 lines
4.2 KiB
C#

using Qdp.Pricing.Library.Options.Products.Autocall.Phoenix;
using YLErp.Abstract;
using YLErp.BLL;
using YLErp.Modules.CalculationModule;
using YLErp.Modules.TradeModule.KnockOutModule.Dto;
namespace YLErp.Modules.TradeModule.KnockOutModule
{
/// <summary>
/// 凤凰期权敲出计算服务
/// </summary>
public class AutocallTradeKnockOutService : ITradeKnockOutService
{
public GetKnockOutPayoffResult GetKnockOutPayoff(trade td, double underlyingPrice, DateTime _valueDate, ITradeExtendDataProvider _tradeExtendDataProvider)
{
var autocallOption = _tradeExtendDataProvider.GetTrade_Autocall_Option(td.id);
if (autocallOption == null)
{
return new GetKnockOutPayoffResult { IsKnockOut = false };
}
td.trade_autocall = autocallOption;
return GetKnockOutPayoff(td, underlyingPrice, _valueDate);
}
public GetKnockOutPayoffResult GetKnockOutPayoff(trade td, double underlyingPrice, DateTime _valueDate)
{
var result = new GetKnockOutPayoffResult { IsKnockOut = false };
var autocallOption = td.trade_autocall;
if (autocallOption == null)
{
return result;
}
//1、获取敲出观察日期
var optionTrade = QdpTradeBuilder.GetAutocallOptionTrade(td, autocallOption,
new OptionTradeParamRequest(valuedateBLL.SysRiskFreeRate()) { ParamOverride = x => { x.notional = td.Notional; } });
var autocall = (AutoCall)optionTrade.Instrument;
var kiBarrier = td.IsMoneynessOptionData ? autocallOption.KIBarrier * td.SpotPrice : autocallOption.KIBarrier;
var isCall = ConsGlobal.CallPut.IsCall(td.CallPut);
if (autocall.KOObsDates.Select(x => x.DateTime).Contains(_valueDate)) //当前日为观察日
{
//2、敲出判断
double koBarrier;
if (autocall.CustomizedKOBarriers != null && autocall.CustomizedKOBarriers.Length > 0)
{
var index = autocall.KOObsDates.Select(x => x.DateTime).ToList().IndexOf(_valueDate);
koBarrier = autocall.CustomizedKOBarriers[index];
}
else
{
koBarrier = autocallOption.KOBarrier;
}
if (td.IsMoneynessOptionData)
{
koBarrier *= td.SpotPrice ?? 1.0;
}
//看涨 - 向上敲出,看跌 - 向下敲出
var isKnockedOut = isCall ? underlyingPrice >= koBarrier : underlyingPrice <= koBarrier;
if (isKnockedOut)
{
result.IsKnockOut = true;
var couponBarrier = td.IsMoneynessOptionData ? autocallOption.CouponBarrier * td.SpotPrice : autocallOption.CouponBarrier;
if (isCall ? underlyingPrice >= couponBarrier : underlyingPrice <= couponBarrier) // 与派息障碍价格比较
{
var observation = autocall.GetEffectiveObservation(_valueDate, includeTradeStartDate: autocallOption.CouponIncludeStartDate == true && autocallOption.CouponDayCount != "Monthly");
if (observation != null)
{
result.Payoff = observation.PaymentAmount;
}
}
if (autocallOption.CouponPayType == CouponPayTypeEnum.AtCreated) //如果是产生时支付,持仓payoff为当日票息
{
return result;
}
//如果到期支付 或者 敲出支付 持仓payoff加上之前的票息
using (var db = DbContextFactory.GetYLDbContext())
{
var obsAmount = db.autocall_observation.Where(o => o.TradeId == td.id && o.EndDate != _valueDate).Sum(p => p.PaymentAmount);
result.Payoff += obsAmount;
}
return result;
}
}
return result;
}
}
}