1289 lines
56 KiB
C#
1289 lines
56 KiB
C#
using YLErp.BLL;
|
||
using YLErp.Configuration;
|
||
using YLErp.Modules.CalculationModule;
|
||
|
||
namespace YLErp.Modules.TradeModule.OrderModule
|
||
{
|
||
/// <summary>
|
||
/// 交易简讯服务
|
||
/// </summary>
|
||
public partial class TradeAbstractService : YLBaseService
|
||
{
|
||
public TradeAbstractService(YLBaseService baseService) : base(baseService)
|
||
{
|
||
}
|
||
|
||
public TradeAbstractService(OptUserInfo userInfo) : base(userInfo)
|
||
{
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取交易简讯数据
|
||
/// </summary>
|
||
public string GetTradeAbstractInfoText(int tradeId, bool throwIfNotFoundTrade)
|
||
{
|
||
var td = DbContext.trade.FirstOrDefault(n => n.id == tradeId);
|
||
if (td == null)
|
||
{
|
||
if (throwIfNotFoundTrade)
|
||
{
|
||
throw new ServiceException("交易数据不存在,id:" + tradeId);
|
||
}
|
||
return null;
|
||
}
|
||
tradeBLL.SetFieldsByTradeType(new[] { td });
|
||
return GetTradeAbstractInfoText(td);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取交易简讯数据
|
||
/// </summary>
|
||
public static string GetTradeAbstractInfoText(trade td)
|
||
{
|
||
var items = GetTradeAbstractInfoItems(td);
|
||
return string.Join("\r\n", items.Select(
|
||
n => string.IsNullOrEmpty(n.text) ? n.value : n.text.EndsWith(" ") ? n.text + n.value : n.text + ":" + n.value));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取交易简讯数据
|
||
/// </summary>
|
||
public static IEnumerable<(string text, string value)> GetTradeAbstractInfoItems(trade td)
|
||
{
|
||
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(td.UnderlyingCode);
|
||
var wrap = new InnerWrap(underlying, td);
|
||
|
||
IEnumerable<(string text, string value)> bodyList;
|
||
|
||
switch (td.TradeType == "结构化交易" ? td.StructureType : td.TradeType)
|
||
{
|
||
case "亚式期权":
|
||
bodyList = GenerateTradeAbstract_Asian(td, wrap);
|
||
break;
|
||
case "障碍期权":
|
||
bodyList = GenerateTradeAbstract_Barrier(td, wrap);
|
||
break;
|
||
case "远期":
|
||
case "掉期":
|
||
bodyList = GenerateTradeAbstract_Forward(td, wrap);
|
||
break;
|
||
case "二元期权":
|
||
bodyList = GenerateTradeAbstract_binary(td, wrap);
|
||
break;
|
||
case "雪球期权":
|
||
bodyList = GenerateTradeAbstract_snowball(td, wrap);
|
||
break;
|
||
case "凤凰期权":
|
||
bodyList = GenerateTradeAbstract_autocall(td, wrap);
|
||
break;
|
||
case "双鲨期权":
|
||
bodyList = GenerateTradeAbstract_double_sharkfin(td, wrap);
|
||
break;
|
||
case "香草期权":
|
||
case "合成价差期权":
|
||
bodyList = GenerateTradeAbstract_Vanilla(td, wrap);
|
||
break;
|
||
case "现金流交易":
|
||
bodyList = GenerateTradeAbstract_Cashflow(td);
|
||
break;
|
||
case "累计期权":
|
||
bodyList = GenerateTradeAbstract_Accumulator(td, wrap);
|
||
break;
|
||
case "Risky期权":
|
||
bodyList = GenerateTradeAbstract_Risky(td, wrap);
|
||
break;
|
||
default:
|
||
bodyList = GenerateTradeAbstract_Defalt(td, wrap);
|
||
break;
|
||
}
|
||
|
||
var bodyIndent = string.Empty;
|
||
|
||
if (PS.Config.Is厦门象屿)
|
||
{
|
||
bodyList = bodyList.Prepend(("开仓信息", ""));
|
||
}
|
||
|
||
if (bodyList.Any())
|
||
{
|
||
//var maxLen = bodyList.Max(n => n.text.Length);
|
||
//bodyIndent = new string(' ', maxLen + 1);
|
||
//bodyList = bodyList.Select(n => (n.text == "#" ? bodyIndent : n.text.PadLeft(maxLen, ' '), n.value)).ToArray();
|
||
|
||
bodyList = bodyList.Select(n => (n.text == "#" ? new string(' ', 5) : n.text, n.value)).ToArray();
|
||
}
|
||
|
||
var headIndent = bodyIndent.Length > 3 ? bodyIndent.Substring(0, bodyIndent.Length - 3) : string.Empty;
|
||
|
||
var list = new List<(string text, string value)>() {
|
||
(headIndent, PS.Config.CompanyName),
|
||
(headIndent, "【场外成交记录摘要】"),
|
||
(string.Empty, "####")
|
||
};
|
||
|
||
list.AddRange(bodyList);
|
||
|
||
return list;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 其他期权生成交易摘要
|
||
/// </summary>
|
||
private static IEnumerable<(string text, string value)> GenerateTradeAbstract_Defalt(trade td, InnerWrap wrap)
|
||
{
|
||
if (td is null)
|
||
{
|
||
throw new ArgumentNullException(nameof(td));
|
||
}
|
||
|
||
if (wrap is null)
|
||
{
|
||
throw new ArgumentNullException(nameof(wrap));
|
||
}
|
||
|
||
var list = new List<(string, string)> {
|
||
("交易编号", td.TradeNumber),
|
||
("成交日期", td.TradeDate.OtcFormatDate()),
|
||
("买卖方向", td.ClientName),
|
||
("#", td.BuySell == "买入" ? "卖出" : "买入"),
|
||
};
|
||
|
||
if (wrap.Underlying == null)
|
||
{
|
||
return list;
|
||
}
|
||
|
||
list.Add(("标的代码", td.UnderlyingCode));
|
||
|
||
td.TradeOriginalAmount = td.OriginalNotional / wrap.CountRatio;
|
||
|
||
var tradeType = td.TradeType;
|
||
|
||
switch (tradeType)
|
||
{
|
||
case "结构化交易":
|
||
tradeType = td.StructureType;
|
||
break;
|
||
case "凤凰期权":
|
||
case ConsGlobal.TradeType.CashFlow:
|
||
case ConsGlobal.TradeType.Forward:
|
||
case ConsGlobal.TradeType.PayoffSwap:
|
||
break;
|
||
case "雪球期权":
|
||
tradeType = td.OptionType + "雪球";
|
||
break;
|
||
case "自定义交易":
|
||
tradeType = td.StructureIntroduction.TrimToNull() ?? td.StructureType.TrimToNull() ?? td.TradeType;
|
||
break;
|
||
case "气囊结构":
|
||
case "区间累积期权":
|
||
case "收益增强结构":
|
||
tradeType = td.ExerciseModeCn + tradeType;
|
||
break;
|
||
default:
|
||
tradeType = td.ExerciseModeCn + tradeType.Replace("期权", "") + td.OptionType + "期权";
|
||
break;
|
||
}
|
||
|
||
list.Add(("期权类型", tradeType));
|
||
|
||
if (td.TradeType == "合成价差期权" && !string.IsNullOrWhiteSpace(td.SyntheticUnderlyingTipsInfo))
|
||
{
|
||
td.UnderlyingCode = td.SyntheticUnderlyingTipsInfo;
|
||
}
|
||
|
||
if (wrap.UnderlyingInstrumentType == "Stock")
|
||
{
|
||
list.Add(("标的名称", wrap.UnderlyingName));
|
||
}
|
||
|
||
list.Add(("标的价格", td.SpotPrice.OtcFormatUmPrice() + (PS.Config.Is浙期 ? " 元" : "")));
|
||
|
||
if ((td.TradeType != "亚式期权" || td.trade_asian_option.StrikeType != "Floating") && td.TradeType != "雪球期权")
|
||
{
|
||
list.Add(("执行价格", wrap.strikeFmt(td.Strike) + (PS.Config.Is浙期 ? " 元" : "")));
|
||
}
|
||
var actualExerciseDate = td.ExerciseDate;
|
||
if (td.MetaDic == null || td.MetaDic.Count == 0)
|
||
{
|
||
var exerciseDate = new TradeMetaService(OptUserInfo.SystemUser).GetTradeMeta(td.id, "ActualExerciseDate");
|
||
if (!string.IsNullOrWhiteSpace(exerciseDate) && DateTime.TryParse(exerciseDate, out var tempDate))
|
||
{
|
||
actualExerciseDate = tempDate;
|
||
}
|
||
}
|
||
list.Add(("到期日期", actualExerciseDate.OtcFormatDate()));
|
||
|
||
if (wrap.IsUsePremiumRate)
|
||
{
|
||
list.Add(("期权费率", wrap.premiumFmt(td.PremiumRate)));
|
||
}
|
||
else
|
||
{
|
||
list.Add(("权利金", wrap.premiumFmt(td.TradeSinglePrice ?? 0) + " " + (td.UnderlyingInstrumentType.Contains("Commodity") ? wrap.QuoteUnitString : "")));
|
||
list.Add(("成交数量", td.TradeOriginalAmount.OtcFormatNotional(wrap.CountRatio, PS.Config.IsUseDisplayNotional) + (PS.Config.IsUseDisplayNotional ? wrap.QuoteUnit : wrap.TradeUnitString)));
|
||
}
|
||
|
||
if (PS.Config.Is方顿)
|
||
{
|
||
list.Add(("保底收益总额", td.OriginalPrincipalSum.OtcFormatMoney() + " 元"));
|
||
}
|
||
|
||
if (PS.Config.Company == CompanyEnum.厦门象屿 || PS.Config.Is润和)
|
||
{
|
||
list.Add(("成交总额", td.TradePrice.OtcFormatMoney() + " 元"));
|
||
}
|
||
else
|
||
{
|
||
list.AddRange(new[] {
|
||
("成交总额", td.TradePrice.OtcFormatMoney() + " 元"),
|
||
("名义本金", td.StockEqvNotionalToShow.OtcFormatMoney()+ (PS.Config.Is浙期 ? " 元" : "")),
|
||
("参与率", td.ParticipationRate.OtcFormatPercent()),
|
||
});
|
||
}
|
||
|
||
if (tradeType == "凤凰期权")
|
||
{
|
||
var koInfo = "";
|
||
var coInfo = "";
|
||
if (!string.IsNullOrWhiteSpace(td.trade_autocall.KOObservationDates))
|
||
{
|
||
|
||
koInfo = String.Join(",", td.trade_autocall.KOObservationDates.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries)[0]);
|
||
var KOObservationDates = QdpModule.QdpHelper.ParseAutocallCustomizedInfo(td.trade_autocall.KOObservationDates);
|
||
if (PS.Config.Is浙期)
|
||
{
|
||
for (var i = 0; i < KOObservationDates.Item1.Length; i++)
|
||
{
|
||
string splitStr = ", ";
|
||
if (i == KOObservationDates.Item1.Length - 1)
|
||
{
|
||
splitStr = "";
|
||
}
|
||
var couponInfo = KOObservationDates.Item3[i].OtcFormat(OtcFormatFlag.percent) + splitStr;
|
||
coInfo += KOObservationDates.Item1[i].DateTime.ToString("yyyy-MM-dd") + couponInfo;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
coInfo = String.Join(",", td.trade_autocall.CouponObservation.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries)[0]);
|
||
}
|
||
}
|
||
list.Add(("敲出观察日期", koInfo));
|
||
list.Add(("票息支付日", coInfo));
|
||
}
|
||
|
||
return list;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 其他期权生成交易摘要
|
||
/// </summary>
|
||
private static IEnumerable<(string text, string value)> GenerateTradeAbstract_Risky(trade td, InnerWrap wrap)
|
||
{
|
||
if (td is null)
|
||
{
|
||
throw new ArgumentNullException(nameof(td));
|
||
}
|
||
|
||
if (wrap is null)
|
||
{
|
||
throw new ArgumentNullException(nameof(wrap));
|
||
}
|
||
|
||
var dbrisky = td.trade_risky_option;
|
||
|
||
var list = new List<(string, string)> {
|
||
("交易编号", td.TradeNumber),
|
||
("成交日期", td.TradeDate.OtcFormatDate()),
|
||
("买卖方向", td.ClientName),
|
||
("#", td.BuySell == "买入" ? "卖出" : "买入"),
|
||
};
|
||
|
||
if (wrap.Underlying == null)
|
||
{
|
||
return list;
|
||
}
|
||
|
||
list.Add(("标的代码", td.UnderlyingCode));
|
||
|
||
td.TradeOriginalAmount = td.OriginalNotional / wrap.CountRatio;
|
||
|
||
var tradeType = td.ExerciseModeCn + td.TradeType.Replace("期权", "") + td.OptionType + "期权";
|
||
|
||
list.Add(("期权类型", tradeType));
|
||
|
||
if (wrap.UnderlyingInstrumentType == "Stock")
|
||
{
|
||
list.Add(("标的名称", wrap.UnderlyingName));
|
||
}
|
||
|
||
list.Add(("标的价格", td.SpotPrice.OtcFormatUmPrice() + (PS.Config.Is浙期 ? " 元" : "")));
|
||
|
||
list.Add(("执行价格", wrap.strikeFmt(dbrisky.Strike1) + (PS.Config.Is浙期 ? " 元" : "")));
|
||
list.Add(("执行价格2", wrap.strikeFmt(dbrisky.Strike2) + (PS.Config.Is浙期 ? " 元" : "")));
|
||
list.Add(("执行价格3", wrap.strikeFmt(dbrisky.Strike3) + (PS.Config.Is浙期 ? " 元" : "")));
|
||
|
||
list.Add(("参与率", dbrisky.ParticipationRate1.OtcFormatPercent()));
|
||
list.Add(("参与率2", dbrisky.ParticipationRate2.OtcFormatPercent()));
|
||
list.Add(("参与率3", dbrisky.ParticipationRate3.OtcFormatPercent()));
|
||
|
||
list.Add(("到期日期", td.ExerciseDate.OtcFormatDate()));
|
||
|
||
if (wrap.IsUsePremiumRate)
|
||
{
|
||
list.Add(("期权费率", wrap.premiumFmt(td.PremiumRate)));
|
||
}
|
||
else
|
||
{
|
||
list.Add(("权利金", wrap.premiumFmt(td.TradeSinglePrice ?? 0) + " " + (td.UnderlyingInstrumentType.Contains("Commodity") ? wrap.QuoteUnitString : "")));
|
||
var tradeampunt = TradeCalcHelper.GetTradeAmountV(td).OtcFormatNotional(wrap.CountRatio, PS.Config.IsUseDisplayNotional);
|
||
list.Add(("成交数量", tradeampunt));
|
||
}
|
||
|
||
if (PS.Config.Is方顿)
|
||
{
|
||
list.Add(("保底收益总额", td.OriginalPrincipalSum.OtcFormatMoney() + " 元"));
|
||
}
|
||
|
||
if (PS.Config.Company == CompanyEnum.厦门象屿 || PS.Config.Is润和)
|
||
{
|
||
list.Add(("成交总额", td.TradePrice.OtcFormatMoney() + " 元"));
|
||
}
|
||
else
|
||
{
|
||
list.AddRange(new[] {
|
||
("成交总额", td.TradePrice.OtcFormatMoney() + " 元"),
|
||
("名义本金", td.StockEqvNotionalToShow.OtcFormatMoney()+ (PS.Config.Is浙期 ? " 元" : "")),
|
||
});
|
||
}
|
||
return list;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 凤凰期权生成交易摘要
|
||
/// </summary>
|
||
private static IEnumerable<(string text, string value)> GenerateTradeAbstract_autocall(trade td, InnerWrap wrap)
|
||
{
|
||
if (td is null)
|
||
{
|
||
throw new ArgumentNullException(nameof(td));
|
||
}
|
||
|
||
if (wrap is null)
|
||
{
|
||
throw new ArgumentNullException(nameof(wrap));
|
||
}
|
||
|
||
var autocall = td.trade_autocall;
|
||
if (autocall == null)
|
||
{
|
||
throw new ServiceException("凤凰期权扩展信息不存在,无法生成交易摘要");
|
||
}
|
||
|
||
td.TradeOriginalAmount = td.OriginalNotional / wrap.CountRatio;
|
||
|
||
var list = new List<(string, string)> {
|
||
("交易编号", td.TradeNumber),
|
||
("成交日期", td.TradeDate.OtcFormatDate()),
|
||
("开仓方向", td.ClientName),
|
||
("#", td.BuySell == "买入" ? "卖出" : "买入"),
|
||
};
|
||
|
||
if (PS.Config.Company != CompanyEnum.厦门象屿 && !PS.Config.Is润和)
|
||
{
|
||
list.AddRange(new[] {
|
||
("名义本金", OtcFormatExtensions.OtcFormat(td.StockEqvNotionalToShow, OtcFormatFlag.StockEqvNotional))
|
||
});
|
||
}
|
||
list.Add(("期权类型", "凤凰期权 " + td.OptionType));
|
||
list.Add(("标的代码", td.UnderlyingCode));
|
||
if (wrap.UnderlyingInstrumentType == "Stock")
|
||
{
|
||
list.Add(("标的名称", wrap.UnderlyingName));
|
||
}
|
||
list.Add(("标的价格", td.SpotPrice.OtcFormatUmPrice() + "(开仓)"));
|
||
//if (td.TradeType != "自定义交易" && (td.TradeType != "亚式期权" || td.trade_asian_option.StrikeType != "Floating") && td.TradeType != "雪球期权")
|
||
//{
|
||
// list.Add(("执行价格", wrap.strikeFmt(td.Strike) + (PS.Config.Is浙期 ? " 元" : "")));
|
||
//}
|
||
|
||
//if (!wrap.IsUsePremiumRate)
|
||
//{
|
||
// list.Add(("成交数量", td.TradeOriginalAmount.OtcFormatNotional(wrap.CountRatio, PS.Config.IsUseDisplayNotional) + (PS.Config.IsUseDisplayNotional ? wrap.QuoteUnit : wrap.TradeUnitString)));
|
||
//}
|
||
|
||
if (PS.Config.Is方顿)
|
||
{
|
||
list.Add(("保底收益总额", td.OriginalPrincipalSum.OtcFormatMoney() + " 元"));
|
||
}
|
||
|
||
|
||
|
||
|
||
list.Add(("敲入价格", wrap.strikeFmt(autocall.KIBarrier) + (PS.Config.Is浙期 ? " 元" : "")));
|
||
|
||
list.Add(("敲出价格", wrap.strikeFmt(autocall.KOBarrier) + (PS.Config.Is浙期 ? " 元" : "")));
|
||
|
||
|
||
switch (autocall.KIPayoffType)
|
||
{
|
||
case KIPayoffTypeEnum.None:
|
||
break;
|
||
case KIPayoffTypeEnum.ToCallOption:
|
||
list.Add(("执行价格一", wrap.strikeFmt(autocall.SpreadStrike1)));
|
||
break;
|
||
case KIPayoffTypeEnum.ToPutOption:
|
||
list.Add(("执行价格一", wrap.strikeFmt(autocall.SpreadStrike1)));
|
||
break;
|
||
case KIPayoffTypeEnum.ToCallSpreadOption:
|
||
list.Add(("执行价格一", wrap.strikeFmt(autocall.SpreadStrike)));
|
||
list.Add(("执行价格二", wrap.strikeFmt(autocall.SpreadStrike1)));
|
||
break;
|
||
case KIPayoffTypeEnum.ToPutSpreadOption:
|
||
list.Add(("执行价格一", wrap.strikeFmt(autocall.SpreadStrike)));
|
||
list.Add(("执行价格二", wrap.strikeFmt(autocall.SpreadStrike1)));
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
var kiObsInfo = "每日观察";
|
||
if (!string.IsNullOrWhiteSpace(autocall.ObservationDates))
|
||
{
|
||
kiObsInfo = autocall.ObservationDates;
|
||
}
|
||
|
||
|
||
list.Add(("票息率", autocall.Coupon.OtcFormat(OtcFormatFlag.percent)));
|
||
list.Add(("票息年化", autocall.IsFixedCoupon ? "否" : "是"));
|
||
|
||
if (!string.IsNullOrWhiteSpace(kiObsInfo))
|
||
{
|
||
list.Add(("敲入观察日期", kiObsInfo));
|
||
}
|
||
var koInfo = "";
|
||
var coInfo = "";
|
||
if (!string.IsNullOrWhiteSpace(autocall.KOObservationDates))
|
||
{
|
||
if (PS.Config.Is浙期)
|
||
{
|
||
var KOObservationDates = string.IsNullOrEmpty(td.trade_autocall.CouponObservation) ? QdpModule.QdpHelper.ParseAutocallCustomizedInfo(TradeObservationHelper.GetAutocallKOObservationAndCoupon(td.trade_autocall.KOObservationDates, td.trade_autocall.CouponBarrier).Item1) : QdpModule.QdpHelper.ParseAutocallCustomizedInfo(td.trade_autocall.CouponObservation);
|
||
|
||
if (KOObservationDates.Item1 != null)
|
||
{
|
||
for (var i = 0; i < KOObservationDates.Item1.Length; i++)
|
||
{
|
||
string splitStr = ", ";
|
||
if (i == KOObservationDates.Item1.Length - 1)
|
||
{
|
||
splitStr = "";
|
||
}
|
||
var couponInfo = ":" + KOObservationDates.Item3[i].OtcFormat(OtcFormatFlag.percent) + splitStr;
|
||
koInfo += KOObservationDates.Item1[i].DateTime.ToString("yyyy-MM-dd") + couponInfo;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
var KOObservationDatesArr = td.trade_autocall.KOObservationDates.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
|
||
if (KOObservationDatesArr.Length != 2 && KOObservationDatesArr.Length > 0)
|
||
{
|
||
var ko = TradeObservationHelper.GetAutocallKOObservationAndCoupon(td.trade_autocall.KOObservationDates, td.trade_autocall.CouponBarrier);
|
||
td.trade_autocall.CouponObservation = ko.Item1;
|
||
td.trade_autocall.KOObservationDates = ko.Item2;
|
||
KOObservationDatesArr = ko.Item2.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
|
||
if (KOObservationDatesArr.Any())
|
||
{
|
||
koInfo = String.Join(",", KOObservationDatesArr[0]);
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
koInfo = String.Join(",", td.trade_autocall.KOObservationDates.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries)[0]);
|
||
}
|
||
coInfo = String.Join(",", td.trade_autocall.CouponObservation.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries)[0]);
|
||
}
|
||
|
||
}
|
||
|
||
list.Add(("到期日期", td.ExerciseDate.OtcFormatDate()));
|
||
list.Add(("敲出观察日期", koInfo));
|
||
if (coInfo.Length > 0)
|
||
{
|
||
list.Add(("票息支付日", coInfo));
|
||
}
|
||
|
||
return list;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 生成双鲨期权交易摘要
|
||
/// </summary>
|
||
private static IEnumerable<(string text, string value)> GenerateTradeAbstract_double_sharkfin(trade td, InnerWrap wrap)
|
||
{
|
||
if (td is null)
|
||
{
|
||
throw new ArgumentNullException(nameof(td));
|
||
}
|
||
|
||
if (wrap is null)
|
||
{
|
||
throw new ArgumentNullException(nameof(wrap));
|
||
}
|
||
|
||
var dbshark = td.trade_double_sharkfin_option;
|
||
if (dbshark == null)
|
||
{
|
||
throw new ServiceException("双鲨期权扩展信息不存在,无法生成交易摘要");
|
||
}
|
||
|
||
td.TradeOriginalAmount = td.OriginalNotional / wrap.CountRatio;
|
||
|
||
var tradeType = td.ExerciseModeCn + td.TradeType.Replace("期权", "") + td.OptionType + "期权";
|
||
var list = new List<(string, string)> {
|
||
("交易编号", td.TradeNumber),
|
||
("成交日期", td.TradeDate.OtcFormatDate()),
|
||
("买卖方向", td.ClientName),
|
||
("#", td.BuySell == "买入" ? "卖出" : "买入"),
|
||
("标的代码", td.UnderlyingCode),
|
||
};
|
||
if (wrap.UnderlyingInstrumentType == "Stock")
|
||
{
|
||
list.Add(("标的名称", wrap.UnderlyingName));
|
||
}
|
||
list.Add(("期权类型", tradeType));
|
||
list.Add(("标的价格", td.SpotPrice.OtcFormatUmPrice() + (PS.Config.Is浙期 ? " 元" : "")));
|
||
if (td.TradeType != "自定义交易" && (td.TradeType != "亚式期权" || td.trade_asian_option.StrikeType != "Floating") && td.TradeType != "雪球期权")
|
||
{
|
||
list.Add(("执行价格", wrap.strikeFmt(td.Strike) + (PS.Config.Is浙期 ? " 元" : "")));
|
||
}
|
||
|
||
list.Add(("到期日期", td.ExerciseDate.OtcFormatDate()));
|
||
|
||
if (wrap.IsUsePremiumRate)
|
||
{
|
||
list.Add(("期权费率", wrap.premiumFmt(td.PremiumRate)));
|
||
}
|
||
else
|
||
{
|
||
list.Add(("权利金", wrap.premiumFmt(td.TradeSinglePrice ?? 0) + " " + (td.UnderlyingInstrumentType.Contains("Commodity") ? wrap.QuoteUnitString : "")));
|
||
list.Add(("成交数量", td.TradeOriginalAmount.OtcFormatNotional(wrap.CountRatio, PS.Config.IsUseDisplayNotional) + (PS.Config.IsUseDisplayNotional ? wrap.QuoteUnit : wrap.TradeUnitString)));
|
||
}
|
||
|
||
if (PS.Config.Is方顿)
|
||
{
|
||
list.Add(("保底收益总额", td.OriginalPrincipalSum.OtcFormatMoney() + " 元"));
|
||
}
|
||
if (PS.Config.Company == CompanyEnum.厦门象屿 || PS.Config.Is润和)
|
||
{
|
||
list.AddRange(new[] {
|
||
("成交总额", td.TradePrice.OtcFormatMoney() + " 元")
|
||
});
|
||
list.AddRange(new[] {
|
||
("高障碍价格",wrap.strikeFmt( dbshark.BarrierHigh)+ (PS.Config.Is浙期 ? " 元" : "")),
|
||
("低障碍价格", wrap.strikeFmt(dbshark.BarrierLow)+ (PS.Config.Is浙期 ? " 元" : "")),
|
||
("高行权价",wrap. strikeFmt(dbshark.StrikeHigh)+ (PS.Config.Is浙期 ? " 元" : "")),
|
||
("连离类型", dbshark.Discrete),
|
||
("补偿金额", wrap.premiumFmt(wrap.IsUsePremiumRate? dbshark.RebateRate:dbshark.Rebate)+ " 元"),
|
||
("高障碍补偿金额",wrap. premiumFmt(wrap.IsUsePremiumRate? dbshark.RebateHighRate:dbshark.RebateHigh)+ " 元") });
|
||
}
|
||
else
|
||
{
|
||
list.AddRange(new[] {
|
||
("成交总额", td.TradePrice.OtcFormatMoney() + " 元"),
|
||
("名义本金", td.StockEqvNotionalToShow.OtcFormatMoney()+ (PS.Config.Is浙期 ? " 元" : "")),
|
||
("参与率", td.ParticipationRate.OtcFormatPercent()),
|
||
});
|
||
list.AddRange(new[] {
|
||
("高障碍价格",wrap.strikeFmt( dbshark.BarrierHigh)+ (PS.Config.Is浙期 ? " 元" : "")),
|
||
("低障碍价格", wrap.strikeFmt(dbshark.BarrierLow)+ (PS.Config.Is浙期 ? " 元" : "")),
|
||
("高行权价",wrap. strikeFmt(dbshark.StrikeHigh)+ (PS.Config.Is浙期 ? " 元" : "")),
|
||
("连离类型", dbshark.Discrete),
|
||
("补偿金额", wrap.premiumFmt(wrap.IsUsePremiumRate? dbshark.RebateRate:dbshark.Rebate)+ " 元"),
|
||
("高障碍补偿金额",wrap. premiumFmt(wrap.IsUsePremiumRate? dbshark.RebateHighRate:dbshark.RebateHigh)+ " 元"),
|
||
("高参与率", dbshark.CallParticipationRate.OtcFormatPercent()),
|
||
("低参与率", dbshark.PutParticipationRate.OtcFormatPercent()),
|
||
});
|
||
}
|
||
|
||
|
||
return list;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 生成二元期权交易摘要
|
||
/// </summary>
|
||
private static IEnumerable<(string text, string value)> GenerateTradeAbstract_binary(trade td, InnerWrap wrap)
|
||
{
|
||
if (td is null)
|
||
{
|
||
throw new ArgumentNullException(nameof(td));
|
||
}
|
||
|
||
if (wrap is null)
|
||
{
|
||
throw new ArgumentNullException(nameof(wrap));
|
||
}
|
||
|
||
var binary = td.trade_binary_option;
|
||
if (binary == null)
|
||
{
|
||
throw new ServiceException("二元期权扩展信息不存在,无法生成交易摘要");
|
||
}
|
||
|
||
td.TradeOriginalAmount = td.OriginalNotional / wrap.CountRatio;
|
||
|
||
var tradeType = td.ExerciseMode == "American" ? td.ExerciseModeCn + td.TradeType.Replace("期权", "") + "期权" : td.ExerciseModeCn + td.TradeType.Replace("期权", "") + td.OptionType + "期权";
|
||
var list = new List<(string, string)> {
|
||
("交易编号", td.TradeNumber),
|
||
("成交日期", td.TradeDate.OtcFormatDate()),
|
||
("买卖方向", td.ClientName),
|
||
("#", td.BuySell == "买入" ? "卖出" : "买入"),
|
||
("标的代码", td.UnderlyingCode),
|
||
};
|
||
if (wrap.UnderlyingInstrumentType == "Stock")
|
||
{
|
||
list.Add(("标的名称", wrap.UnderlyingName));
|
||
}
|
||
list.Add(("期权类型", tradeType));
|
||
list.Add(("标的价格", td.SpotPrice.OtcFormatUmPrice() + (PS.Config.Is浙期 ? " 元" : "")));
|
||
if (td.TradeType != "自定义交易" && (td.TradeType != "亚式期权" || td.trade_asian_option.StrikeType != "Floating") && td.TradeType != "雪球期权")
|
||
{
|
||
list.Add(("执行价格", wrap.strikeFmt(td.Strike) + (PS.Config.Is浙期 ? " 元" : "")));
|
||
}
|
||
|
||
list.Add(("到期日期", td.ExerciseDate.OtcFormatDate()));
|
||
|
||
if (wrap.IsUsePremiumRate)
|
||
{
|
||
list.Add(("期权费率", wrap.premiumFmt(td.PremiumRate)));
|
||
}
|
||
else
|
||
{
|
||
list.Add(("权利金", wrap.premiumFmt(td.TradeSinglePrice ?? 0) + " " + (td.UnderlyingInstrumentType.Contains("Commodity") ? wrap.QuoteUnitString : "")));
|
||
list.Add(("成交数量", td.TradeOriginalAmount.OtcFormatNotional(wrap.CountRatio, PS.Config.IsUseDisplayNotional) + (PS.Config.IsUseDisplayNotional ? wrap.QuoteUnit : wrap.TradeUnitString)));
|
||
}
|
||
|
||
if (PS.Config.Is方顿)
|
||
{
|
||
list.Add(("保底收益总额", td.OriginalPrincipalSum.OtcFormatMoney() + " 元"));
|
||
}
|
||
|
||
if (PS.Config.Company == CompanyEnum.厦门象屿 || PS.Config.Is润和)
|
||
{
|
||
list.Add(("成交总额", td.TradePrice.OtcFormatMoney() + " 元"));
|
||
}
|
||
else
|
||
{
|
||
list.AddRange(new[] {
|
||
("成交总额", td.TradePrice.OtcFormatMoney() + " 元"),
|
||
("名义本金", td.StockEqvNotionalToShow.OtcFormatMoney()+ (PS.Config.Is浙期 ? " 元" : "")),
|
||
("参与率", td.ParticipationRate.OtcFormatPercent()),
|
||
});
|
||
}
|
||
list.AddRange(new[] {
|
||
("二元类型", binary.PayoffType),
|
||
("补偿金额", wrap.premiumFmt(wrap.IsUsePremiumRate ? binary.CashOrNothingAmountRate : binary.CashOrNothingAmount)+ " 元")
|
||
});
|
||
|
||
if (binary.PayoffType.Contains("Double"))
|
||
{
|
||
list.Add(("高障碍价格", wrap.strikeFmt(binary.UpperBarrier) + " 元"));
|
||
list.Add(("高障碍补偿金额", wrap.premiumFmt(wrap.IsUsePremiumRate ? binary.CashOrNothingAmountHighRate : binary.CashOrNothingAmountHigh) + " 元"));
|
||
}
|
||
|
||
if (td.ExerciseMode == "American")
|
||
{
|
||
list.AddRange(new[] {
|
||
("观察方式", binary.MonitorType),
|
||
("补偿支付", binary.RebateTypeCn),
|
||
("观察频率", binary.ObservationDates??"每日观察"),
|
||
});
|
||
}
|
||
list.AddRange(new[] {
|
||
("补偿按敲出日年化", binary.RebateAnnualizedAtKO ? "是": "否"),
|
||
("补偿计息规则", binary.RebateAnnualizedAtKO ? binary.RebateDayCount : "")
|
||
});
|
||
return list;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 生成障碍期权交易摘要
|
||
/// </summary>
|
||
private static IEnumerable<(string text, string value)> GenerateTradeAbstract_Barrier(trade td, InnerWrap wrap)
|
||
{
|
||
if (td is null)
|
||
{
|
||
throw new ArgumentNullException(nameof(td));
|
||
}
|
||
|
||
if (wrap is null)
|
||
{
|
||
throw new ArgumentNullException(nameof(wrap));
|
||
}
|
||
|
||
var barrier = td.trade_barrier_option;
|
||
if (barrier == null)
|
||
{
|
||
throw new ServiceException("障碍期权扩展信息不存在,无法生成交易摘要");
|
||
}
|
||
|
||
var list = GenerateTradeAbstract_Vanilla(td, wrap).ToList();
|
||
|
||
list.AddRange(new (string, string)[] {
|
||
("障碍类型", barrier.BarrierType),
|
||
("观察频率", barrier.ObservationDates??"每日观察"),
|
||
//("报价单位", wrap.QuoteUnitString),
|
||
("障碍水平", wrap.strikeFmt(barrier.BarrierPrice)),
|
||
});
|
||
if (barrier.BarrierType.Contains("双"))
|
||
{
|
||
list.Add(("高障碍水平", wrap.strikeFmt(barrier.UpperBarrierPrice)));
|
||
}
|
||
if (barrier.BarrierType == "双障碍敲出")
|
||
{
|
||
list.AddRange(new (string, string)[] {
|
||
// ("连离类型", barrier.Discrete),
|
||
("补偿金额", wrap.premiumFmt(wrap.IsUsePremiumRate ?barrier.RebateRate : barrier.Rebate)+ (wrap.IsUsePremiumRate ?"":" 元")),
|
||
("高障碍补偿金额", wrap.premiumFmt(wrap.IsUsePremiumRate ?barrier.RebateHighRate : barrier.RebateHigh)+ (wrap.IsUsePremiumRate ?"":" 元")),
|
||
("补偿支付", barrier.RebateTypeCn),
|
||
// ("补偿按敲出日年化", barrier.RebateAnnualizedAtKO ? "是": "否"),
|
||
//("补偿计息规则", barrier.RebateAnnualizedAtKO ? barrier.RebateDayCount : "")
|
||
});
|
||
}
|
||
else
|
||
{
|
||
list.AddRange(new (string, string)[] {
|
||
//("连离类型", barrier.Discrete),
|
||
("补偿金额", wrap.premiumFmt(wrap.IsUsePremiumRate ?barrier.RebateRate : barrier.Rebate)+ (wrap.IsUsePremiumRate ?"":" 元")),
|
||
("补偿支付", barrier.RebateTypeCn),
|
||
//("补偿按敲出日年化", barrier.RebateAnnualizedAtKO ? "是": "否"),
|
||
// ("补偿计息规则", barrier.RebateAnnualizedAtKO ? barrier.RebateDayCount : "")
|
||
});
|
||
}
|
||
return list;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 生成亚式期权交易摘要
|
||
/// </summary>
|
||
private static IEnumerable<(string text, string value)> GenerateTradeAbstract_Asian(trade td, InnerWrap wrap)
|
||
{
|
||
if (td is null)
|
||
{
|
||
throw new ArgumentNullException(nameof(td));
|
||
}
|
||
|
||
if (wrap is null)
|
||
{
|
||
throw new ArgumentNullException(nameof(wrap));
|
||
}
|
||
|
||
var asian = td.trade_asian_option;
|
||
if (asian == null)
|
||
{
|
||
throw new ServiceException("亚式期权扩展信息不存在,无法生成交易摘要");
|
||
}
|
||
|
||
td.TradeOriginalAmount = td.OriginalNotional / wrap.CountRatio;
|
||
|
||
var tradeType = td.ExerciseModeCn + td.TradeType.Replace("期权", "") + td.OptionType + "期权";
|
||
|
||
var list = new List<(string, string)> {
|
||
("交易编号", td.TradeNumber),
|
||
("成交日期", td.TradeDate.OtcFormatDate()),
|
||
("买卖方向", td.ClientName),
|
||
("#", td.BuySell == "买入" ? "卖出" : "买入"),
|
||
("标的代码", td.UnderlyingCode),
|
||
};
|
||
if (wrap.UnderlyingInstrumentType == "Stock")
|
||
{
|
||
list.Add(("标的名称", wrap.UnderlyingName));
|
||
}
|
||
list.Add(("期权类型", tradeType));
|
||
list.Add(("标的价格", td.SpotPrice.OtcFormatUmPrice() + (PS.Config.Is浙期 ? " 元" : "")));
|
||
|
||
if (asian.StrikeType != "Floating")
|
||
{
|
||
list.Add(("执行价格", wrap.strikeFmt(td.Strike) + (PS.Config.Is浙期 ? " 元" : "")));
|
||
}
|
||
|
||
list.Add(("到期日期", td.ExerciseDate.OtcFormatDate()));
|
||
|
||
if (wrap.IsUsePremiumRate)
|
||
{
|
||
list.Add(("期权费率", wrap.premiumFmt(td.PremiumRate)));
|
||
}
|
||
else
|
||
{
|
||
list.Add(("权利金", wrap.premiumFmt(td.TradeSinglePrice ?? 0) + " " + (td.UnderlyingInstrumentType.Contains("Commodity") ? wrap.QuoteUnitString : "")));
|
||
list.Add(("成交数量", td.TradeOriginalAmount.OtcFormatNotional(wrap.CountRatio, PS.Config.IsUseDisplayNotional) + (PS.Config.IsUseDisplayNotional ? wrap.QuoteUnit : wrap.TradeUnitString)));
|
||
}
|
||
|
||
if (PS.Config.Is方顿)
|
||
{
|
||
list.Add(("保底收益总额", td.OriginalPrincipalSum.OtcFormatMoney() + " 元"));
|
||
}
|
||
|
||
if (PS.Config.Company == CompanyEnum.厦门象屿 || PS.Config.Is润和)
|
||
{
|
||
list.Add(("成交总额", td.TradePrice.OtcFormatMoney() + " 元"));
|
||
}
|
||
else
|
||
{
|
||
list.AddRange(new[] {
|
||
("成交总额", td.TradePrice.OtcFormatMoney() + " 元"),
|
||
("名义本金", td.StockEqvNotionalToShow.OtcFormatMoney()+ (PS.Config.Is浙期 ? " 元" : "")),
|
||
("参与率", td.ParticipationRate.OtcFormatPercent()),
|
||
});
|
||
}
|
||
|
||
list.AddRange(new[] {
|
||
("均价起算日", asian.AveragingPeriodStartDate.OtcFormatDate()),
|
||
("均价计算", asian.PayoffTypeCn.Replace("(离散)", "")),
|
||
("行权价类型", asian.StrikeTypeCn),
|
||
});
|
||
if (asian.PayoffTypeCn.Contains("增强"))
|
||
{
|
||
list.Add(("结算类型", asian.SettleMode == "AtEnd" ? "递延" : "立即"));
|
||
}
|
||
list.Add(("杠杆率", asian.StrikeGearingFactor.OtcFormatPercent()));
|
||
return list;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 生成香草交易摘要
|
||
/// <para>默认交易摘要</para>
|
||
/// </summary>
|
||
private static IEnumerable<(string text, string value)> GenerateTradeAbstract_Vanilla(trade td, InnerWrap wrap)
|
||
{
|
||
if (td is null)
|
||
{
|
||
throw new ArgumentNullException(nameof(td));
|
||
}
|
||
|
||
if (wrap is null)
|
||
{
|
||
throw new ArgumentNullException(nameof(wrap));
|
||
}
|
||
|
||
td.TradeOriginalAmount = td.OriginalNotional / wrap.CountRatio;
|
||
|
||
var tradeType = PS.Config.Is瑞达 && td.TradeType == "香草期权" ? td.ExerciseModeCn + td.OptionType + "期权" : td.ExerciseModeCn + td.TradeType.Replace("期权", "") + td.OptionType + "期权";
|
||
|
||
//如果是组合标的
|
||
if (wrap.CommodityCode == "组合标的")
|
||
{
|
||
if (!string.IsNullOrWhiteSpace(td.SyntheticUnderlyingTipsInfo))
|
||
{
|
||
td.UnderlyingCode = td.SyntheticUnderlyingTipsInfo;
|
||
}
|
||
else
|
||
{
|
||
td.UnderlyingCode = synthetic_underlyingBLL.GetUnderlyingTipsInfo(td.UnderlyingCode);
|
||
}
|
||
}
|
||
var list = new List<(string, string)> {
|
||
("交易编号", td.TradeNumber),
|
||
("成交日期", td.TradeDate.OtcFormatDate()),
|
||
("买卖方向", td.ClientName),
|
||
("#", td.BuySell == "买入" ? "卖出" : "买入"),
|
||
("标的代码", td.UnderlyingCode),
|
||
};
|
||
if (wrap.UnderlyingInstrumentType == "Stock")
|
||
{
|
||
list.Add(("标的名称", wrap.UnderlyingName));
|
||
}
|
||
if (td.ParentTradeId > 0 && td.IsGroup == 0)
|
||
{
|
||
list.Add(("期权类型", td.StructureType));
|
||
list.Add(("标的价格", td.SpotPrice.OtcFormatUmPrice() + (PS.Config.Is浙期 ? " 元" : "")));
|
||
list.Add(("执行价格", wrap.strikeFmt(td.Strike) + (PS.Config.Is浙期 ? " 元" : "")));
|
||
}
|
||
else
|
||
{
|
||
if (td.ParentTradeId > 0)
|
||
{
|
||
var tradelists = DbContextFactory.GetYLDbContext().trade.Where(x => x.ParentTradeId == td.ParentTradeId).OrderBy(x => x.TradeNumber).ToList();
|
||
list.Add(("期权类型", tradeType));
|
||
list.Add(("标的价格", td.SpotPrice.OtcFormatUmPrice() + (PS.Config.Is浙期 ? " 元" : "")));
|
||
int i = 1;
|
||
foreach (var item in tradelists)
|
||
{
|
||
var key = "执行价格" + NumberHelper.CurrToChnInt(i);
|
||
list.Add((key, wrap.strikeFmt(item.Strike) + (PS.Config.Is浙期 ? " 元" : "")));
|
||
i++;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
list.Add(("期权类型", tradeType));
|
||
list.Add(("标的价格", td.SpotPrice.OtcFormatUmPrice() + (PS.Config.Is浙期 ? " 元" : "")));
|
||
list.Add(("执行价格", wrap.strikeFmt(td.Strike) + (PS.Config.Is浙期 ? " 元" : "")));
|
||
}
|
||
}
|
||
|
||
|
||
list.Add(("到期日期", td.ExerciseDate.OtcFormatDate()));
|
||
|
||
if (wrap.IsUsePremiumRate)
|
||
{
|
||
list.Add(("期权费率", wrap.premiumFmt(td.PremiumRate)));
|
||
}
|
||
else
|
||
{
|
||
list.Add(("权利金", wrap.premiumFmt(td.TradeSinglePrice ?? 0) + " " + (td.UnderlyingInstrumentType.Contains("Commodity") ? wrap.QuoteUnitString : "")));
|
||
list.Add(("成交数量", td.TradeOriginalAmount.OtcFormatNotional(wrap.CountRatio, PS.Config.IsUseDisplayNotional) + (PS.Config.IsUseDisplayNotional ? wrap.QuoteUnit : wrap.TradeUnitString)));
|
||
}
|
||
|
||
if (PS.Config.Is方顿)
|
||
{
|
||
list.Add(("保底收益总额", td.OriginalPrincipalSum.OtcFormatMoney() + " 元"));
|
||
}
|
||
|
||
list.Add(("成交总额", (td.TradePrice ?? 0).OtcFormatMoney() + " 元"));
|
||
if (PS.Config.Company != CompanyEnum.厦门象屿 && !PS.Config.Is润和)
|
||
{
|
||
if (td.TradeType == "障碍期权")
|
||
{
|
||
list.Add(("名义本金", td.StockEqvNotionalToShow.OtcFormatMoney() + (PS.Config.Is浙期 ? " 元" : "")));
|
||
}
|
||
else
|
||
{
|
||
list.Add(("名义本金", td.StockEqvNotionalToShow.OtcFormatMoney() + (PS.Config.Is浙期 ? " 元" : "")));
|
||
}
|
||
|
||
if (td.TradeType != "累计期权")
|
||
{
|
||
if (td.IsGroup == 2 && td.StructureType.Contains("折价") && td.ParticipationRate < 1)
|
||
{
|
||
list.Add(("参与率", (1 - td.ParticipationRate).OtcFormatPercent()));
|
||
}
|
||
else
|
||
{
|
||
list.Add(("参与率", td.ParticipationRate.OtcFormatPercent()));
|
||
}
|
||
}
|
||
}
|
||
|
||
return list;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 生成远期交易摘要
|
||
/// </summary>
|
||
private static IEnumerable<(string text, string value)> GenerateTradeAbstract_Forward(trade td, InnerWrap wrap)
|
||
{
|
||
if (td is null)
|
||
{
|
||
throw new ArgumentNullException(nameof(td));
|
||
}
|
||
|
||
if (wrap is null)
|
||
{
|
||
throw new ArgumentNullException(nameof(wrap));
|
||
}
|
||
//var forwardTrade = DbContextFactory.GetYLDbContext(null).trade_forward.FirstOrDefault(a=>a.TradeId == td.)
|
||
|
||
td.TradeOriginalAmount = td.OriginalNotional / wrap.CountRatio;
|
||
|
||
var tradeType = (td.StructureType.TrimToNull() ?? td.TradeType) + (td.OptionType == "看涨" || td.OptionType == "多头" ? "多头" : "空头");
|
||
|
||
//如果是组合标的
|
||
if (wrap.CommodityCode == "组合标的")
|
||
{
|
||
if (!string.IsNullOrWhiteSpace(td.SyntheticUnderlyingTipsInfo))
|
||
{
|
||
td.UnderlyingCode = td.SyntheticUnderlyingTipsInfo;
|
||
}
|
||
else
|
||
{
|
||
td.UnderlyingCode = synthetic_underlyingBLL.GetUnderlyingTipsInfo(td.UnderlyingCode);
|
||
}
|
||
}
|
||
var underlyingCode = td.UnderlyingCode + (!string.IsNullOrWhiteSpace(td.BasisUnderlyingCode) ? ("-" + td.BasisUnderlyingCode) : "");
|
||
var list = new List<(string, string)> {
|
||
("交易编号", td.TradeNumber),
|
||
("成交日期", td.TradeDate.OtcFormatDate()),
|
||
("成交方向", td.ClientName),
|
||
("#", td.BuySell == "买入" ? "卖出" : "买入"),
|
||
("期权类型", tradeType),
|
||
("标的代码",underlyingCode ),
|
||
};
|
||
|
||
if (wrap.UnderlyingInstrumentType == "Stock")
|
||
{
|
||
list.Add(("标的名称", wrap.UnderlyingName));
|
||
}
|
||
var actualExerciseDate = td.ExerciseDate;
|
||
if (td.MetaDic == null || td.MetaDic.Count == 0)
|
||
{
|
||
var exerciseDate = new TradeMetaService(OptUserInfo.SystemUser).GetTradeMeta(td.id, "ActualExerciseDate");
|
||
if (!string.IsNullOrWhiteSpace(exerciseDate) && DateTime.TryParse(exerciseDate, out var tempDate))
|
||
{
|
||
actualExerciseDate = tempDate;
|
||
}
|
||
}
|
||
list.AddRange(new[] {
|
||
("标的价格", td.SpotPrice.OtcFormatUmPrice() + (PS.Config.Is浙期 ? " 元" : "")),
|
||
("执行价格",wrap.strikeFmt(td.Strike) + (PS.Config.Is浙期 ? " 元" : "")),
|
||
("到期日期", actualExerciseDate.OtcFormatDate()),
|
||
("远期价值", (-td.trade_forward.ForwardValue).OtcFormatMoney() + " 元"),
|
||
("成交数量", td.TradeOriginalAmount.OtcFormatNotional(wrap.CountRatio,PS.Config.IsUseDisplayNotional) + (PS.Config.IsUseDisplayNotional ? wrap.QuoteUnit :wrap.TradeUnitString)),
|
||
("成交总额", (-td.TradePrice).OtcFormatMoney() + " 元"),
|
||
("名义本金", td.StockEqvNotionalToShow.OtcFormatMoney()+ (PS.Config.Is浙期 ? " 元" : "")),
|
||
});
|
||
|
||
if (PS.Config.Company == CompanyEnum.厦门象屿 || PS.Config.Is润和)
|
||
{
|
||
list.Remove(("名义本金", td.StockEqvNotionalToShow.OtcFormatMoney() + (PS.Config.Is浙期 ? " 元" : "")));
|
||
}
|
||
|
||
if (!string.IsNullOrEmpty(td.trade_forward.ObservationDates))
|
||
{
|
||
var trade_forward = td.trade_forward;
|
||
var ObservationDateStr_2 = getObservationDate(trade_forward.ObservationDates);
|
||
list.Add(("结算价格", ObservationDateStr_2));
|
||
}
|
||
|
||
|
||
return list;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 生成现金流交易摘要
|
||
/// </summary>
|
||
private static IEnumerable<(string text, string value)> GenerateTradeAbstract_Cashflow(trade td)
|
||
{
|
||
if (td is null)
|
||
{
|
||
throw new ArgumentNullException(nameof(td));
|
||
}
|
||
|
||
var list = new List<(string, string)> {
|
||
("交易编号", td.TradeNumber),
|
||
("成交日期", td.TradeDate.OtcFormatDate()),
|
||
("成交方向", td.ClientName),
|
||
("#", td.BuySell == "买入" ? "卖出" : "买入"),
|
||
("期权类型", td.TradeType),
|
||
};
|
||
if (PS.Config.Company == CompanyEnum.厦门象屿 || PS.Config.Is润和)
|
||
{
|
||
list.AddRange(new[] {
|
||
("到期日期", td.ExerciseDate.OtcFormatDate()),
|
||
("利率", td.trade_cashflow.ProfitRate.OtcFormatPercent()),
|
||
("利率类型", td.trade_cashflow.RateType.ToString()),
|
||
("计息日历规则", td.trade_cashflow.ProfitDayCount),
|
||
});
|
||
}
|
||
else
|
||
{
|
||
list.AddRange(new[] {
|
||
("到期日期", td.ExerciseDate.OtcFormatDate()),
|
||
("名义本金", td.StockEqvNotionalToShow.OtcFormatMoney()+ (PS.Config.Is浙期 ? " 元" : "")),
|
||
("利率", td.trade_cashflow.ProfitRate.OtcFormatPercent()),
|
||
("利率类型", td.trade_cashflow.RateType.ToString()),
|
||
("计息日历规则", td.trade_cashflow.ProfitDayCount),
|
||
});
|
||
}
|
||
|
||
if (td.trade_cashflow.DepositType == CashflowDepositTypeEnum.资金收益)
|
||
{
|
||
list.Add(("返还比例", td.trade_cashflow.PrepayRatio.OtcFormatPercent()));
|
||
}
|
||
return list;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 生成累计期权交易摘要
|
||
/// </summary>
|
||
private static IEnumerable<(string text, string value)> GenerateTradeAbstract_Accumulator(trade td, InnerWrap wrap)
|
||
{
|
||
if (td is null)
|
||
{
|
||
throw new ArgumentNullException(nameof(td));
|
||
}
|
||
|
||
if (wrap is null)
|
||
{
|
||
throw new ArgumentNullException(nameof(wrap));
|
||
}
|
||
|
||
var ext = td.trade_accumulator_option;
|
||
if (ext == null)
|
||
{
|
||
throw new ServiceException("累计期权扩展信息不存在,无法生成交易摘要");
|
||
}
|
||
|
||
var list = GenerateTradeAbstract_Vanilla(td, wrap).ToList();
|
||
|
||
list.AddRange(new (string, string)[]
|
||
{
|
||
("敲出障碍价格",wrap.strikeFmt( ext.KOBarrier)+ (PS.Config.Is浙期 ? " 元" : "")),
|
||
("累计类型", ext.AccumuType),
|
||
("累计结构类型", ext.AccumulatorStructureType==AccumulatorStructureTypeEnum.Segmented?"三段式":"标准"),
|
||
("上端收益类型", ext.PayoffType)
|
||
});
|
||
if (ext.AccumulatorStructureType == AccumulatorStructureTypeEnum.Segmented)
|
||
{
|
||
list.Remove(list.Find(l => l.text == "执行价格"));
|
||
list.Add(("执行价格1", wrap.strikeFmt(td.Strike.Value)));
|
||
list.Add(("执行价格2", wrap.strikeFmt(ext.Strike2.Value)));
|
||
list.Add(("执行价格3", wrap.strikeFmt(ext.Strike3.Value)));
|
||
if (ext.PayoffType == "固定")
|
||
{
|
||
if (td.OptionType == "看涨")
|
||
{
|
||
list.Add(("乘数1", ext.Multiplier.Value.ToString("F2")));
|
||
}
|
||
else
|
||
{
|
||
list.Add(("乘数3", ext.Multiplier3.Value.ToString("F2")));
|
||
}
|
||
list.Add(("票息", OtcFormatExtensions.OtcFormat(ext.Coupon, ext.CouponPercent ? OtcFormatFlag.premiumRateP : OtcFormatFlag.tradePrice)));
|
||
list.Add(("票息2", OtcFormatExtensions.OtcFormat(ext.Coupon2, ext.CouponPercent ? OtcFormatFlag.premiumRateP : OtcFormatFlag.tradePrice)));
|
||
}
|
||
else
|
||
{
|
||
list.Add(("乘数1", ext.Multiplier.Value.ToString("F2")));
|
||
list.Add(("乘数2", ext.Multiplier2.Value.ToString("F2")));
|
||
list.Add(("乘数3", ext.Multiplier3.Value.ToString("F2")));
|
||
}
|
||
list.Add(("敲出是否终止", ext.EarlyTerminate ? "是" : "否"));
|
||
list.Add(("结算方式1", ext.SettlementMode));
|
||
list.Add(("结算方式2", ext.SettlementMode2));
|
||
list.Add(("结算方式3", ext.SettlementMode3));
|
||
}
|
||
else
|
||
{
|
||
if (ext.PayoffType == "固定")
|
||
{
|
||
list.Add(("票息", OtcFormatExtensions.OtcFormat(ext.Coupon, ext.CouponPercent ? OtcFormatFlag.premiumRateP : OtcFormatFlag.tradePrice)));
|
||
//list.Add(("票息是否年化", ext.IsFixedCoupon ? "否" : "是"));
|
||
//list.Add(("票息日历规则", ext.CouponDayCount));
|
||
}
|
||
if (PS.Config.ErpElement.AccumulatorShowMultiplier1)
|
||
{
|
||
list.Add(("杠杆倍数", (td.OptionType == "看涨" ? ext.PutMultiplier : ext.CallMultiplier).ToString("F2")));
|
||
}
|
||
else
|
||
{
|
||
list.Add(("看涨乘数", ext.CallMultiplier.ToString("F2")));
|
||
list.Add(("看跌乘数", ext.PutMultiplier.ToString("F2")));
|
||
}
|
||
|
||
//list.Add(("沽购数量", td.TradeAmount.ToString("F2") + wrap.TradeUnitString));
|
||
list.Add(("敲出是否终止", ext.EarlyTerminate ? "是" : "否"));
|
||
list.Add(("结算方式", ext.SettlementMode));
|
||
}
|
||
var koInfo = "";
|
||
if (!string.IsNullOrWhiteSpace(ext.KOObservationDates))
|
||
{
|
||
var KOObservationDates = QdpModule.QdpHelper.ParseAutocallCustomizedInfo(ext.KOObservationDates);
|
||
for (var i = 0; i < KOObservationDates.Item1.Length; i++)
|
||
{
|
||
string splitStr = ", ";
|
||
if (i == KOObservationDates.Item1.Length - 1)
|
||
{
|
||
splitStr = "";
|
||
}
|
||
var couponInfo = PS.Config.Is浙期 && KOObservationDates.Item3 != null && ext.PayoffType == "固定" ? ":" + KOObservationDates.Item3[i].OtcFormat(OtcFormatFlag.percent) + splitStr : splitStr;
|
||
koInfo += KOObservationDates.Item1[i].DateTime.ToString("yyyy-MM-dd") + couponInfo;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
koInfo = "每日";
|
||
}
|
||
|
||
list.Add(("观察日期", koInfo));
|
||
|
||
return list;
|
||
}
|
||
|
||
private static string getObservationDate(string ObservationDateStr)
|
||
{
|
||
var observationDateStr = "";
|
||
var yyyy = "";
|
||
var days = ObservationDateStr.Split(',');
|
||
foreach (var day in days)
|
||
{
|
||
if (Convert.ToDateTime(day).ToString("yyyy年") != yyyy)
|
||
{
|
||
observationDateStr += Convert.ToDateTime(day).ToString("yyyy年M月d日") + "、";
|
||
yyyy = Convert.ToDateTime(day).ToString("yyyy年");
|
||
}
|
||
else
|
||
{
|
||
observationDateStr += Convert.ToDateTime(day).ToString("M月d日") + "、";
|
||
}
|
||
}
|
||
observationDateStr = observationDateStr.Substring(0, observationDateStr.Length - 1);
|
||
observationDateStr += NumberHelper.CurrToChnInt(days.Count());
|
||
observationDateStr += "个交易日,Mysteel每天最后公布的标的物价格的算术平均价";
|
||
return observationDateStr;
|
||
}
|
||
|
||
class InnerWrap
|
||
{
|
||
public InnerWrap(underlying_manager underlying, OtcTradeBase td)
|
||
{
|
||
Underlying = underlying;
|
||
|
||
if (underlying != null)
|
||
{
|
||
TradeUnitString = " " + underlying.TradeUnitString;
|
||
QuoteUnitString = " 元/" + underlying.QuoteUnitString;
|
||
}
|
||
|
||
if (td != null)
|
||
{
|
||
IsUsePremiumRate = td.IsUsePremiumRate == true;
|
||
|
||
strikeFmt = td.IsMoneynessOption == "是"
|
||
? new Func<double?, string>(d => OtcFormatExtensions.OtcFormat(d, OtcFormatFlag.percent))
|
||
: new Func<double?, string>(d => OtcFormatExtensions.OtcFormatFlex(d, 2, 4));
|
||
|
||
premiumFmt = IsUsePremiumRate
|
||
? new Func<double?, string>(d => OtcFormatExtensions.OtcFormat(d, OtcFormatFlag.premiumRateP))
|
||
: new Func<double?, string>(d => OtcFormatExtensions.OtcFormat(d, OtcFormatFlag.tradeSinglePrice));
|
||
}
|
||
else
|
||
{
|
||
strikeFmt = new Func<double?, string>(d => OtcFormatExtensions.OtcFormatFlex(d, 2, 4));
|
||
premiumFmt = new Func<double?, string>(d => OtcFormatExtensions.OtcFormat(d, OtcFormatFlag.tradeSinglePrice));
|
||
}
|
||
}
|
||
|
||
//-------Trade------------------------
|
||
|
||
public bool IsUsePremiumRate { get; }
|
||
|
||
public Func<double?, string> strikeFmt { get; }
|
||
|
||
public Func<double?, string> premiumFmt { get; }
|
||
|
||
//-------Underlying------------------------
|
||
|
||
public underlying_manager Underlying { get; }
|
||
|
||
public string UnderlyingName => Underlying?.UnderlyingName;
|
||
|
||
public string UnderlyingInstrumentType => Underlying?.UnderlyingInstrumentType;
|
||
|
||
public string CommodityCode => Underlying?.CommodityCode;
|
||
|
||
public string TradeUnitString { get; }
|
||
|
||
public string QuoteUnitString { get; }
|
||
|
||
public string QuoteUnit => " " + (Underlying?.QuoteUnit == "500千克" ? "半吨" : Underlying?.QuoteUnit);
|
||
|
||
public int CountRatio => Underlying?.CountRatio ?? 1;
|
||
}
|
||
}
|
||
}
|