101 lines
3.8 KiB
C#
101 lines
3.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using YLErp.Abstract;
|
|
using YLErp.BLL.Eod;
|
|
using YLErp.BLL;
|
|
using YLErp.Modules.TradeModule.KnockOutModule.Dto;
|
|
using YLErp.QdpModule;
|
|
|
|
namespace YLErp.Modules.TradeModule.KnockOutModule
|
|
{
|
|
/// <summary>
|
|
/// 双鲨期权敲出计算服务
|
|
/// </summary>
|
|
public class DoubleSharkTradeKnockOutService : ITradeKnockOutService
|
|
{
|
|
public GetKnockOutPayoffResult GetKnockOutPayoff(trade td, double underlyingPrice, DateTime _valueDate, ITradeExtendDataProvider _tradeExtendDataProvider)
|
|
{
|
|
|
|
var sharkOption = _tradeExtendDataProvider.GetTrade_Double_SharkFin_Option(td.id);
|
|
if (sharkOption == null)
|
|
{
|
|
return new GetKnockOutPayoffResult { IsKnockOut = false };
|
|
}
|
|
td.trade_double_sharkfin_option= sharkOption;
|
|
return GetKnockOutPayoff(td, underlyingPrice, _valueDate);
|
|
}
|
|
|
|
public GetKnockOutPayoffResult GetKnockOutPayoff(trade td, double underlyingPrice, DateTime _valueDate)
|
|
{
|
|
GetKnockOutPayoffResult result = new GetKnockOutPayoffResult { IsKnockOut = false };
|
|
var sharkOption = td.trade_double_sharkfin_option;
|
|
if (sharkOption == null)
|
|
{
|
|
return result;
|
|
}
|
|
if (sharkOption.IsDiscrete)
|
|
{
|
|
var observationDates = QdpHelper.GetObservationDatesFromString(sharkOption.ObservationDates);
|
|
if (observationDates != null && observationDates.Length > 0 && !observationDates.Contains(_valueDate))
|
|
{
|
|
return result; //无需观察时直接返回
|
|
}
|
|
}
|
|
|
|
var barrierHigh = td.IsMoneynessOptionData ? sharkOption.BarrierHigh * td.SpotPrice : sharkOption.BarrierHigh;
|
|
var barrierLow = td.IsMoneynessOptionData ? sharkOption.BarrierLow * td.SpotPrice : sharkOption.BarrierLow;
|
|
if (underlyingPrice >= barrierHigh || underlyingPrice <= barrierLow) //敲出判断条件
|
|
{
|
|
var useRebate = underlyingPrice <= barrierLow;
|
|
result.IsKnockOut = true;
|
|
result.Payoff = CalcDoubleSharkTradeKnockOutPayoff(td, sharkOption, underlyingPrice, useRebate);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 计算双鲨期权 敲出 收益
|
|
/// </summary>
|
|
/// <param name="td"></param>
|
|
/// <param name="sharkOption"></param>
|
|
/// <param name="underlyingPrice"></param>
|
|
/// <param name="useRebate"></param>
|
|
/// <returns></returns>
|
|
private double CalcDoubleSharkTradeKnockOutPayoff(trade td, trade_double_sharkfin_option sharkOption, double underlyingPrice, bool useRebate)
|
|
{
|
|
double rebate, rebateRate;
|
|
|
|
var spotPrice = td.SpotPrice ?? 0;
|
|
|
|
if (td.IsUsePremiumRate == true)
|
|
{
|
|
rebateRate = (useRebate ? sharkOption.RebateRate : sharkOption.RebateHighRate) ?? 0;
|
|
rebate = rebateRate * spotPrice;
|
|
}
|
|
else
|
|
{
|
|
rebate = (useRebate ? sharkOption.Rebate : sharkOption.RebateHigh) ?? 0;
|
|
rebateRate = spotPrice > 0 ? rebate / spotPrice : 0;
|
|
}
|
|
|
|
|
|
|
|
var payoff = td.Notional * rebate + ((td.Notional / td.OriginalNotional * td.OriginalPrincipalSum) ?? 0);
|
|
if (valuedateBLL.SystemDate.UnwindAmountAngle == 1)
|
|
{
|
|
payoff = payoff * (td.BuySell == "卖出" ? -1 : 1);
|
|
}
|
|
else
|
|
{
|
|
payoff = payoff * EodOperationBase.GetSign(td.BuySell);
|
|
}
|
|
return payoff;
|
|
}
|
|
}
|
|
}
|