113 lines
4.4 KiB
C#
113 lines
4.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using YLErp.Abstract;
|
|
using YLErp.DBModels;
|
|
using YLErp.Modules.TradeModule.AccumulatorOptionModule;
|
|
using YLErp.Modules.TradeModule.KnockOutModule.Dto;
|
|
|
|
namespace YLErp.Modules.TradeModule.KnockOutModule
|
|
{
|
|
/// <summary>
|
|
/// 累计期权敲出计算服务
|
|
/// </summary>
|
|
public class AccumulatorTradeKnockOutService : ITradeKnockOutService
|
|
{
|
|
/// <summary>
|
|
/// 获取敲出payoff
|
|
/// </summary>
|
|
/// <param name="td"></param>
|
|
/// <param name="underlyingPrice"></param>
|
|
/// <param name="_valueDate"></param>
|
|
/// <param name="_tradeExtendDataProvider"></param>
|
|
/// <returns></returns>
|
|
public GetKnockOutPayoffResult GetKnockOutPayoff(trade td, double underlyingPrice, DateTime _valueDate, ITradeExtendDataProvider _tradeExtendDataProvider)
|
|
{
|
|
var accumulatorOption = _tradeExtendDataProvider.GetTrade_Accumulator_Option(td.id);
|
|
if (accumulatorOption == null)
|
|
{
|
|
return new GetKnockOutPayoffResult { IsKnockOut = false };
|
|
}
|
|
td.trade_accumulator_option = accumulatorOption;
|
|
return GetKnockOutPayoff(td, underlyingPrice, _valueDate);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取敲出payoff
|
|
/// </summary>
|
|
/// <param name="td"></param>
|
|
/// <param name="underlyingPrice"></param>
|
|
/// <param name="_valueDate"></param>
|
|
/// <param name="accumulatorOption"></param>
|
|
/// <returns></returns>
|
|
public GetKnockOutPayoffResult GetKnockOutPayoff(trade td, double underlyingPrice, DateTime _valueDate)
|
|
{
|
|
GetKnockOutPayoffResult result = new GetKnockOutPayoffResult { IsKnockOut = false };
|
|
var accumulatorOption = td.trade_accumulator_option;
|
|
if (accumulatorOption == null)
|
|
{
|
|
return result;
|
|
}
|
|
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(td.UnderlyingCode);
|
|
var notional = accumulatorOption.AccumuTradeAmount * underlying.CountRatio;
|
|
var changeData = GetChangeDataOfSepecialDay(td.id, _valueDate);
|
|
CheckResult checkResult = null;
|
|
if (changeData != null)
|
|
{
|
|
//关键点:还原换月设置到交易时不要更新当前传入的trade和tradeAcc,因为这两个数据涉及到数据库更新
|
|
var tdClone = new trade();
|
|
YLAutoMapper.Map<trade, trade>(td, tdClone);
|
|
var tdAccClone = accumulatorOption.Clone();
|
|
tdClone.trade_accumulator_option = accumulatorOption;
|
|
TradeAccumulatorHelper.RestoreAccumulatorChangeData(tdClone, tdAccClone, changeData);
|
|
checkResult = TradeAccumulatorService.CheckAccumulatorPayoff(tdClone, tdAccClone, _valueDate, underlyingPrice, notional);
|
|
}
|
|
else
|
|
{
|
|
checkResult = TradeAccumulatorService.CheckAccumulatorPayoff(td, accumulatorOption, _valueDate, underlyingPrice, notional);
|
|
}
|
|
if (checkResult != null && "敲出".Equals(checkResult.SettlementMode) && accumulatorOption.EarlyTerminate)
|
|
{
|
|
result.IsKnockOut = true;
|
|
result.Payoff = 0;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// 获取累计期权换月设置
|
|
/// </summary>
|
|
/// <param name="tradeId"></param>
|
|
/// <param name="valueDate"></param>
|
|
/// <returns></returns>
|
|
private TradeAccumulatorChangeData GetChangeDataOfSepecialDay(int tradeId, DateTime valueDate)
|
|
{
|
|
using(var db = DbContextFactory.GetYLDbContext())
|
|
{
|
|
var query = from a in db.TradeAction.AsNoTracking()
|
|
where a.IsValid && a.TradeId == tradeId && a.ValueDate <= valueDate && a.ActionType == TradeActionType.AccumulatorChange
|
|
orderby a.ValueDate descending
|
|
select a.ActionData;
|
|
|
|
var actionData = query.FirstOrDefault();
|
|
if (string.IsNullOrEmpty(actionData))
|
|
{
|
|
return null;
|
|
}
|
|
return JsonHelper.Deserialize<TradeAccumulatorChangeData>(actionData);
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|