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

213 lines
12 KiB
C#

using Qdp.Pricing.Base.Enums;
using YLErp.QdpModule;
namespace YLErp.Modules.TradeModule.OrderModule
{
/// <summary>
/// 扩展存储
/// </summary>
class TradeSaveExtend : YLBaseService
{
private readonly bool isAddNew;
public TradeSaveExtend(YLBaseService baseService, bool isAddNew)
: base(baseService)
{
this.isAddNew = isAddNew;
}
/// <summary>
/// 保存并写入数据库
/// </summary>
public int Save(trade baseTrade, trade dbTrade, bool useSaveChange = true)
{
switch (baseTrade.TradeType == "结构化交易" ? baseTrade.StructureType : baseTrade.TradeType)
{
case "香草期权":
case "合成价差期权":
return 0;
case "亚式期权":
dbTrade.trade_asian_option = InnerSaveExtend(baseTrade, baseTrade.trade_asian_option);
break;
case "彩虹期权":
dbTrade.trade_rainbow_option = InnerSaveExtend(baseTrade, baseTrade.trade_rainbow_option);
break;
case "障碍期权":
dbTrade.trade_barrier_option = InnerSaveExtend(baseTrade, baseTrade.trade_barrier_option);
break;
case "二元期权":
dbTrade.trade_binary_option = InnerSaveExtend(baseTrade, baseTrade.trade_binary_option);
break;
case "价差期权":
dbTrade.trade_spread_option = InnerSaveExtend(baseTrade, baseTrade.trade_spread_option);
break;
case "双鲨期权":
dbTrade.trade_double_sharkfin_option = InnerSaveExtend(baseTrade, baseTrade.trade_double_sharkfin_option);
break;
case "凤凰期权":
if (string.IsNullOrEmpty(baseTrade.trade_autocall.KOObservationDates))
{
if (dbTrade.trade_autocall==null)
{
dbTrade.trade_autocall = new trade_autocall();
}
var autocallmonthlyDates = QdpObservationHelper.GetDatesWithFixedTerm(baseTrade.TradeDate ?? System.DateTime.Now, baseTrade.ExerciseDate ?? System.DateTime.Now, "1M", bdc: BusinessDayConvention.Following, alignEnd: true);
dbTrade.trade_autocall.KOObservationDates = $"{string.Join(",", autocallmonthlyDates.Select(O => O.OtcFormatDate()))};" +
$"{string.Join(",", autocallmonthlyDates.Select(O => baseTrade.trade_autocall.KOBarrier.OtcFormatFlex(2)))};" +
$"{string.Join(",", autocallmonthlyDates.Select(O => baseTrade.trade_autocall.Coupon.OtcFormatFlex(2)))}";
baseTrade.trade_autocall.KOObservationDates = dbTrade.trade_autocall.KOObservationDates;
}
dbTrade.trade_autocall = InnerSaveExtend(baseTrade, baseTrade.trade_autocall);
break;
case "雪球期权":
if (string.IsNullOrEmpty(baseTrade.trade_snowball.KOObservationDates))
{
if (dbTrade.trade_snowball == null)
{
dbTrade.trade_snowball = new trade_snowball();
}
var snowballmonthlyDates = QdpObservationHelper.GetDatesWithFixedTerm(baseTrade.TradeDate ?? System.DateTime.Now, baseTrade.ExerciseDate ?? System.DateTime.Now, "1M", bdc: BusinessDayConvention.Following, alignEnd: true);
dbTrade.trade_snowball.KOObservationDates = $"{string.Join(",", snowballmonthlyDates.Select(O => O.OtcFormatDate()))};" +
$"{string.Join(",", snowballmonthlyDates.Select(O => baseTrade.trade_snowball.KOBarrier.OtcFormatFlex(2)))};" +
$"{string.Join(",", snowballmonthlyDates.Select(O => baseTrade.trade_snowball.KORebate.OtcFormatFlex(2)))}";
if (dbTrade.trade_snowball.KOPayoffType == KOPayoffTypeEnum.Rebate)
{
baseTrade.trade_snowball.KOObservationSettleDates = $"{string.Join(",", snowballmonthlyDates.Select(O => O.OtcFormatDate()))}";
}
baseTrade.trade_snowball.KOObservationDates = dbTrade.trade_snowball.KOObservationDates;
}
dbTrade.trade_snowball = InnerSaveExtend(baseTrade, baseTrade.trade_snowball);
break;
case "区间累积期权":
dbTrade.trade_rangeaccrual = InnerSaveExtend(baseTrade, baseTrade.trade_rangeaccrual);
break;
case "气囊结构":
dbTrade.trade_airbag = InnerSaveExtend(baseTrade, baseTrade.trade_airbag);
break;
case "收益增强结构":
dbTrade.trade_underlying_enhance = InnerSaveExtend(baseTrade, baseTrade.trade_underlying_enhance);
break;
case "远期":
dbTrade.trade_forward = InnerSaveExtend(baseTrade, baseTrade.trade_forward);
break;
case "收益互换":
if (baseTrade.trade_swap.IsGetFloatingProfit)
{
var underlyingManager = DataCacheProvider.GetUnderlyingDataSource().GetData(baseTrade.trade_swap.GetUnderlyingCode);
var CountRatio = underlyingManager?.CountRatio ?? 1;
baseTrade.trade_swap.GetNotional = baseTrade.trade_swap.GetTradeAmount * CountRatio;
dbTrade.OriginalNotional = baseTrade.trade_swap.GetNotional;
dbTrade.Notional = baseTrade.trade_swap.GetNotional ?? 0;
dbTrade.TradeAmount = baseTrade.trade_swap.GetTradeAmount ?? 0;
dbTrade.SpotPrice = baseTrade.trade_swap.GetSpotPrice;
}
if (baseTrade.trade_swap.IsPayFloatingProfit)
{
var underlyingManager = DataCacheProvider.GetUnderlyingDataSource().GetData(baseTrade.trade_swap.PayUnderlyingCode);
var CountRatio = underlyingManager?.CountRatio ?? 1;
baseTrade.trade_swap.PayNotional = baseTrade.trade_swap.PayTradeAmount * CountRatio;
dbTrade.OriginalNotional = baseTrade.trade_swap.PayNotional;
dbTrade.Notional = baseTrade.trade_swap.PayNotional ?? 0;
dbTrade.TradeAmount = baseTrade.trade_swap.PayTradeAmount ?? 0;
dbTrade.SpotPrice = baseTrade.trade_swap.PaySpotPrice;
}
DbContext.SaveChanges();
dbTrade.trade_swap = InnerSaveExtend(baseTrade, baseTrade.trade_swap);
dbTrade.get_trade_swap_details = InnerSaveTradeSwapDetail(baseTrade, baseTrade.get_trade_swap_details, true);
dbTrade.pay_trade_swap_details = InnerSaveTradeSwapDetail(baseTrade, baseTrade.pay_trade_swap_details, false);
if (baseTrade.ParentTradeId > 0)
{
var detail = DbContext.trade_swap_detail.FirstOrDefault(x => x.TradeId == baseTrade.ParentTradeId && x.ChildTradeId == baseTrade.id);
if (detail != null)
{
detail.LongShort = detail.IsForGet ? baseTrade.trade_swap.GetLongShort : baseTrade.trade_swap.PayLongShort;
detail.Notional = detail.IsForGet ? baseTrade.trade_swap.GetNotional : baseTrade.trade_swap.PayNotional;
detail.UnderlyingCode = detail.IsForGet ? baseTrade.trade_swap.GetUnderlyingCode : baseTrade.trade_swap.PayUnderlyingCode;
detail.SpotPrice = detail.IsForGet ? baseTrade.trade_swap.GetSpotPrice : baseTrade.trade_swap.PaySpotPrice;
detail.OriginalNotional = detail.Notional;
}
else
{
detail = new trade_swap_detail()
{
IsForGet = baseTrade.trade_swap.IsGetFloatingProfit
};
detail.LongShort = detail.IsForGet ? baseTrade.trade_swap.GetLongShort : baseTrade.trade_swap.PayLongShort;
detail.Notional = detail.IsForGet ? baseTrade.trade_swap.GetNotional : baseTrade.trade_swap.PayNotional;
detail.UnderlyingCode = detail.IsForGet ? baseTrade.trade_swap.GetUnderlyingCode : baseTrade.trade_swap.PayUnderlyingCode;
detail.SpotPrice = detail.IsForGet ? baseTrade.trade_swap.GetSpotPrice : baseTrade.trade_swap.PaySpotPrice;
detail.OriginalNotional = detail.Notional;
detail.TradeId = baseTrade.ParentTradeId;
detail.ChildTradeId = baseTrade.id;
DbContext.trade_swap_detail.Add(detail);
}
DbContext.SaveChanges();
}
break;
case "现金流交易":
dbTrade.trade_cashflow = InnerSaveExtend(baseTrade, baseTrade.trade_cashflow);
break;
case "自定义交易":
dbTrade.trade_custom = InnerSaveExtend(baseTrade, baseTrade.trade_custom);
break;
case "累计期权":
dbTrade.trade_accumulator_option = InnerSaveExtend(baseTrade, baseTrade.trade_accumulator_option);
break;
case "Risky期权":
dbTrade.trade_risky_option = InnerSaveExtend(baseTrade, baseTrade.trade_risky_option);
break;
default: return 0;
}
return useSaveChange ? DbContext.SaveChanges() : 0;
}
private List<trade_swap_detail> InnerSaveTradeSwapDetail(trade baseTrade, List<trade_swap_detail> tradeSwapDetails, bool isForGet)
{
if (tradeSwapDetails != null && tradeSwapDetails.Any())
{
var tradeSwapDetailsExist = DbContext.trade_swap_detail.Where(x => x.TradeId == baseTrade.id && x.IsForGet == isForGet);
DbContext.trade_swap_detail.RemoveRange(tradeSwapDetailsExist);
tradeSwapDetails.ForEach(x =>
{
x.ExerciseDate = baseTrade.ExerciseDate;
x.IsForGet = isForGet;
x.OriginalNotional = x.Notional;
x.SwapTimeAndRate = isForGet ? baseTrade.trade_swap.PaySwapTimeAndRate : baseTrade.trade_swap.GetSwapTimeAndRate;
x.TradeId = baseTrade.id;
SetDBModelOpt(x);
});
DbContext.trade_swap_detail.AddRange(tradeSwapDetails);
DbContext.SaveChanges();
}
return tradeSwapDetails;
}
//保存扩展数据
private T InnerSaveExtend<T>(trade baseTrade, T extend) where T : TradeExtendBase
{
SetDBModelOpt(extend);
extend.TradeId = baseTrade.id;
var exist = isAddNew ? null : DbContext.Set<T>().FirstOrDefault(n => n.TradeId == baseTrade.id);
if (exist == null)
{
extend.id = 0;
DbContext.Set<T>().Add(extend);
}
else
{
extend.id = exist.id;
UpdateEntity(exist, extend);
}
return extend;
}
}
}