538 lines
27 KiB
C#
538 lines
27 KiB
C#
using YLErp.BLL;
|
||
using YLErp.BLL.Eod;
|
||
using YLErp.Configuration;
|
||
using YLErp.Modules.CalculationModule;
|
||
|
||
namespace YLErp.Modules.TradeModule.OrderModule
|
||
{
|
||
/// <summary>
|
||
/// 不要再合并3.9
|
||
/// </summary>
|
||
public class TradeTerminationAbstractService
|
||
{
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
public static string GetAbstractInfoText(trade_cash tc, trade td, bool isUnwind, bool useHeader = false, bool derive = false)
|
||
{
|
||
var items = isUnwind ? GetUnwindAbstractInfoItems(tc, td).ToList() : GetExerciseAbstractInfoItems(tc, td).ToList();
|
||
|
||
var bodyIndent = string.Empty;
|
||
|
||
if (items.Any())
|
||
{
|
||
//var maxLen = items.Max(n => n.text.Length);
|
||
//bodyIndent = new string(' ', maxLen + 1);
|
||
//items = items.Select(n => (n.text == "#" ? bodyIndent : n.text.PadLeft(maxLen, ' '), n.value)).ToList();
|
||
|
||
items = items.Select(n => (n.text == "#" ? new string(' ', 5) : n.text, n.value)).ToList();
|
||
}
|
||
|
||
var headIndent = bodyIndent.Length > 3 ? bodyIndent.Substring(0, bodyIndent.Length - 3) : string.Empty;
|
||
|
||
var list = new List<(string text, string value)>();
|
||
|
||
if (derive == true)
|
||
{
|
||
list = new List<(string text, string value)>() {
|
||
(headIndent, PS.Config.CompanyName),
|
||
(headIndent, "【场外了结记录摘要】"),
|
||
(string.Empty, "####")
|
||
};
|
||
}
|
||
else
|
||
{
|
||
list = new List<(string text, string value)>();
|
||
}
|
||
|
||
|
||
list.AddRange(items);
|
||
return string.Join("\r\n", list.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)> GetUnwindAbstractInfoItems(trade_cash tc, trade td)
|
||
{
|
||
if (td.TradeType == "远期")
|
||
{
|
||
return GetUnwindAbstractInfoItems_Forward(tc, td);
|
||
}
|
||
|
||
if (td.TradeType == "雪球期权")
|
||
{
|
||
return GetUnwindAbstractInfoItems_snowball(tc, td, true);
|
||
}
|
||
|
||
if (td.TradeType == "现金流交易")
|
||
{
|
||
return GetUnwindAbstractInfoItems_cashflow(tc, td);
|
||
}
|
||
|
||
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(td.UnderlyingCode);
|
||
var QuoteUnitString = " 元/" + (PS.Config.IsUseDisplayNotional ? underlying.QuoteUnitString : underlying.TradeUnitString);
|
||
var IsUsePremiumRate = td.IsUsePremiumRate == true;
|
||
var SpotPrice = underlying.UnderlyingInstrumentType == "CommodityFutures" ? td.SpotPrice : td.InitialSpotPrice;
|
||
var strikeFmt = new Func<double?, string>(d => d.OtcFormatUmPrice(td.IsMoneynessOption == "是"));
|
||
|
||
var premiumFmt = IsUsePremiumRate
|
||
? new Func<double?, string>(d => OtcFormatExtensions.OtcFormat(d, OtcFormatFlag.premiumRateP))
|
||
: new Func<double?, string>(d => OtcFormatExtensions.OtcFormat(d, OtcFormatFlag.tradeSinglePrice));
|
||
|
||
var tradeAmount = td.TradeAmount.OtcFormatNotional() + (td.UnderlyingInstrumentType == "Stock"
|
||
? " 股" : " " + td.QuoteUnitSingle);
|
||
var tradeType = GetTradeType(td);
|
||
var istrade_barrier = td.TradeType == "障碍期权";
|
||
//如果是组合标的
|
||
if (underlying.UnderlyingType == "组合标的")
|
||
{
|
||
if (!string.IsNullOrWhiteSpace(td.SyntheticUnderlyingTipsInfo))
|
||
{
|
||
td.UnderlyingCode = td.SyntheticUnderlyingTipsInfo;
|
||
}
|
||
else
|
||
{
|
||
td.UnderlyingCode = synthetic_underlyingBLL.GetUnderlyingTipsInfo(td.UnderlyingCode);
|
||
}
|
||
}
|
||
var list = new List<(string, string)>();
|
||
if (PS.Config.Is厦门象屿)
|
||
{
|
||
list.Add(("平仓信息", ""));
|
||
}
|
||
list.AddRange(new[]{
|
||
("交易编号", td.TradeNumber),
|
||
("开仓日期", td.TradeDate.OtcFormatDate()),
|
||
("开仓方向", td.ClientName),
|
||
("#", td.BuySell == "买入" ? "卖出" : "买入"),
|
||
("期权类型",(PS.Config.Is光大光子 && td.TradeType=="自定义交易")?td.StructureIntroduction : tradeType),
|
||
("标的代码",td.UnderlyingCode),
|
||
});
|
||
if (istrade_barrier)
|
||
{
|
||
list.Add(("观察频率", td.trade_barrier_option.ObservationDates ?? "每日观察"));
|
||
list.Add(("报价单位", QuoteUnitString));
|
||
list.Add(("障碍水平", strikeFmt(td.trade_barrier_option.BarrierPrice)));
|
||
}
|
||
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(("执行价格", strikeFmt(td.Strike)));
|
||
list.Add(("到期日期", actualExerciseDate.OtcFormatDate()));
|
||
if (istrade_barrier)
|
||
{
|
||
list.Add(("补偿金额", IsUsePremiumRate ? premiumFmt(td.trade_barrier_option.RebateRate) : strikeFmt(td.trade_barrier_option.Rebate)));
|
||
list.Add(("高障碍补偿金额", IsUsePremiumRate ? premiumFmt(td.trade_barrier_option.RebateHighRate) : strikeFmt(td.trade_barrier_option.RebateHigh)));
|
||
list.Add(("补偿支付", td.trade_barrier_option.RebateTypeCn));
|
||
}
|
||
list.Add(("平仓日期", tc.ValueDate.OtcFormatDate()));
|
||
|
||
bool ActualHasMinusValueOptions = valuedateBLL.SystemDate.UnwindSinglePriceAngle == 1 ? ConsTrade.HasMinusValueOptions.Contains(td.TradeType) : !ConsTrade.HasMinusValueOptions.Contains(td.TradeType);
|
||
|
||
if (IsUsePremiumRate)
|
||
{
|
||
list.Add(("标的价格", td.SpotPrice.OtcFormatUmPrice() + " (开仓)"));
|
||
list.Add((new string(' ', 5), tc.FinalPrice.OtcFormatUmPrice() + " (平仓)"));
|
||
|
||
var premiumRate = td.PremiumRate * (valuedateBLL.SystemDate.UnwindSinglePriceAngle == 1 ? EodOperationBase.GetSign(td.BuySell) : 1);
|
||
list.Add(("期权费率", premiumFmt(premiumRate) + " (开仓) "));
|
||
|
||
//计算出交易员角度的值
|
||
var unwindPricePercentRate = tc.UnwindPricePercentRate * (ActualHasMinusValueOptions ? 1 : EodOperationBase.GetSign(td.BuySell));
|
||
//结算视角需要客户视角
|
||
unwindPricePercentRate *= (valuedateBLL.SystemDate.UnwindSinglePriceAngle == 1 ? -1 : 1);
|
||
list.Add((new string(' ', 5), premiumFmt(unwindPricePercentRate) + "(平仓)"));
|
||
}
|
||
else
|
||
{
|
||
using (var db = DbContextFactory.GetYLDbContext())
|
||
{
|
||
list.Add(("标的价格", td.SpotPrice.OtcFormatUmPrice() + " (开仓)"));
|
||
list.Add((new string(' ', 5), tc.FinalPrice.OtcFormatUmPrice() + " (平仓)"));
|
||
|
||
var openPrice = td.TradeSinglePrice * (valuedateBLL.SystemDate.UnwindSinglePriceAngle == 1 ? EodOperationBase.GetSign(td.BuySell) : 1);
|
||
list.Add((" 权利金", premiumFmt(openPrice) + " (开仓) "));
|
||
|
||
//计算出交易员角度的值
|
||
var unwindPrice = tc.UnwindPrice * (ActualHasMinusValueOptions ? 1 : EodOperationBase.GetSign(td.BuySell));
|
||
//结算视角需要客户视角
|
||
unwindPrice *= (valuedateBLL.SystemDate.UnwindSinglePriceAngle == 1 ? -1 : 1);
|
||
list.Add((new string(' ', 5), premiumFmt(unwindPrice) + "(平仓)"));
|
||
}
|
||
}
|
||
var amount = tc.Amount * (valuedateBLL.SystemDate.UnwindAmountAngle == 1 ? -1 : EodOperationBase.GetSign(td.BuySell));
|
||
if (IsUsePremiumRate)
|
||
{
|
||
list.AddRange(new[] {
|
||
("平仓比例", tc.UnwindPercentRate.OtcFormatPercent()),
|
||
("平仓总额", (amount).OtcFormatMoney()+"元"),
|
||
("实现盈亏",(-TradeCalcHelper.CalcChildTradeSumWinLoss(td,tc,IsUsePremiumRate,underlying.CountRatio)).OtcFormatMoney()+" 元")
|
||
});
|
||
}
|
||
else
|
||
{
|
||
list.AddRange(new[] {
|
||
("平仓数量",(td.UnderlyingInstrumentType=="Stock"?tc.UnwindNotional.OtcFormatNotional()+"股":
|
||
tc.UnwindTradeAmount.OtcFormatNotional(underlying.CountRatio,PS.Config.IsUseDisplayNotional)+ " " +(td.QuoteUnitSingle == "吨" &&PS.Config.IsUseDisplayNotional&& underlying.UnderlyingType == "鸡蛋" ? "半吨":td.QuoteUnitSingle) )),
|
||
("平仓总额", (amount).OtcFormatMoney()+"元"),
|
||
("实现盈亏",(-TradeCalcHelper.CalcChildTradeSumWinLoss(td,tc,IsUsePremiumRate,underlying.CountRatio)).OtcFormatMoney()+" 元")
|
||
});
|
||
}
|
||
return list;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 生成行权摘要
|
||
/// </summary>
|
||
public static IEnumerable<(string text, string value)> GetExerciseAbstractInfoItems(trade_cash tc, trade td)
|
||
{
|
||
|
||
if (td.TradeType == "雪球期权")
|
||
{
|
||
return GetUnwindAbstractInfoItems_snowball(tc, td, false);
|
||
}
|
||
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(td.UnderlyingCode);
|
||
var IsUsePremiumRate = td.IsUsePremiumRate == true;
|
||
var QuoteUnitString = "";
|
||
if (underlying != null)
|
||
{
|
||
QuoteUnitString = " 元/" + (PS.Config.IsUseDisplayNotional ? underlying.QuoteUnitString : underlying.TradeUnitString);
|
||
var SpotPrice = underlying.UnderlyingInstrumentType == "CommodityFutures" ? td.SpotPrice : td.InitialSpotPrice;
|
||
}
|
||
///行权价格式
|
||
var strikeFmt = new Func<double?, string>(d => d.OtcFormatUmPrice(td.IsMoneynessOption == "是"));
|
||
|
||
var premiumFmt = IsUsePremiumRate
|
||
? new Func<double?, string>(d => OtcFormatExtensions.OtcFormat(d, OtcFormatFlag.premiumRateP))
|
||
: new Func<double?, string>(d => OtcFormatExtensions.OtcFormat(d, OtcFormatFlag.tradeSinglePrice));
|
||
var single = new Func<double?, string>(d => OtcFormatExtensions.OtcFormat(d, OtcFormatFlag.tradeSinglePrice));
|
||
var tradeAmount = td.TradeAmount.OtcFormatNotional() + (td.UnderlyingInstrumentType == "Stock"
|
||
? " 股" : " " + td.QuoteUnitSingle);
|
||
var istrade_barrier = td.TradeType == "障碍期权";
|
||
var actionName = "行权";
|
||
|
||
//如果是组合标的
|
||
if (underlying != null)
|
||
{
|
||
if (underlying.UnderlyingType == "组合标的")
|
||
{
|
||
if (!string.IsNullOrWhiteSpace(td.SyntheticUnderlyingTipsInfo))
|
||
{
|
||
td.UnderlyingCode = td.SyntheticUnderlyingTipsInfo;
|
||
}
|
||
else
|
||
{
|
||
td.UnderlyingCode = synthetic_underlyingBLL.GetUnderlyingTipsInfo(td.UnderlyingCode);
|
||
}
|
||
}
|
||
}
|
||
var list = new List<(string, string)>();
|
||
if (PS.Config.Is厦门象屿)
|
||
{
|
||
list.Add(("行权信息", ""));
|
||
}
|
||
list.AddRange(new[] {
|
||
("交易编号", td.TradeNumber),
|
||
("开仓日期", td.TradeDate.OtcFormatDate()),
|
||
("开仓方向", td.ClientName),
|
||
("#", td.BuySell == "买入" ? "卖出" : "买入"),
|
||
("期权类型", td.StructureType!=null?td.StructureType: GetTradeType(td)),
|
||
("标的代码",td.UnderlyingCode),
|
||
});
|
||
if (istrade_barrier)
|
||
{
|
||
list.Add(("观察频率", td.trade_barrier_option.ObservationDates ?? "每日观察"));
|
||
list.Add(("报价单位", QuoteUnitString));
|
||
list.Add(("障碍水平", strikeFmt(td.trade_barrier_option.BarrierPrice)));
|
||
}
|
||
if (td.TradeType != "雪球期权" && td.TradeType != "凤凰期权")
|
||
{
|
||
list.Add(("执行价格", strikeFmt(td.Strike)));
|
||
}
|
||
list.Add(("到期日期", td.ExerciseDate.OtcFormatDate()));
|
||
if (istrade_barrier)
|
||
{
|
||
tradeBLL.SetFieldsByTradeType(td);
|
||
list.Add(("补偿金额", IsUsePremiumRate ? premiumFmt(td.trade_barrier_option.RebateRate) : premiumFmt(td.trade_barrier_option.Rebate)));
|
||
list.Add(("高障碍补偿金额", IsUsePremiumRate ? premiumFmt(td.trade_barrier_option.RebateHighRate) : strikeFmt(td.trade_barrier_option.RebateHigh)));
|
||
list.Add(("补偿支付", td.trade_barrier_option.RebateTypeCn));
|
||
}
|
||
if (IsUsePremiumRate)
|
||
{
|
||
list.Add(("期权费率", premiumFmt(td.PremiumRate) + " (开仓) "));
|
||
}
|
||
else
|
||
{
|
||
list.Add((" 权利金", premiumFmt(td.TradeSinglePrice ?? 0) + " (开仓) "));
|
||
}
|
||
|
||
list.Add(($"{actionName}日期", tc.ValueDate.ToString("yyyy-MM-dd")));
|
||
if (td.UnderlyingInstrumentType == "CommodityFutures")
|
||
{
|
||
list.Add(("标的价格", td.SpotPrice.OtcFormatUmPrice() + " (开仓)"));
|
||
list.Add((new string(' ', 5), (tc.FinalPrice ?? 0).OtcFormatUmPrice() + (PS.Config.Is厦门象屿 ? "(到期)" : "(行权)")));
|
||
}
|
||
else
|
||
{
|
||
list.Add(("标的价格", td.InitialSpotPrice.OtcFormatUmPrice() + " (开仓)"));
|
||
list.Add((new string(' ', 5), tc.FinalPrice.OtcFormatUmPrice() + $" ({actionName})"));
|
||
}
|
||
var UnwindPrice = 0.00;
|
||
if (tc.UnwindPrice == null)
|
||
{
|
||
UnwindPrice = 0.00;
|
||
}
|
||
else
|
||
{
|
||
UnwindPrice = Math.Abs(tc.UnwindPrice.Value);
|
||
}
|
||
if (underlying != null)
|
||
{
|
||
list.AddRange(new[] {
|
||
($"{actionName}收益",single(UnwindPrice)+ " 元"),
|
||
($"{actionName}数量",(tc.IsLastAction? tc.Notional / underlying.CountRatio: (tc.UnwindTradeAmount!=null?tc.UnwindTradeAmount:0.0000)).OtcFormatNotional(underlying.CountRatio,PS.Config.IsUseDisplayNotional)+ " " +(PS.Config.IsUseDisplayNotional ? underlying.QuoteUnitString : underlying.TradeUnitString)),
|
||
($"{actionName}总额",(-tc.Amount).OtcFormatMoney()+ " 元"),
|
||
});
|
||
}
|
||
list.Add(("实现盈亏", (-TradeCalcHelper.CalcChildTradeSumWinLoss(td, tc)).OtcFormatMoney() + " 元"));
|
||
return list;
|
||
}
|
||
|
||
private static string GetTradeType(trade td)
|
||
{
|
||
var result = "";
|
||
switch (td.StructureType ?? td.TradeType)
|
||
{
|
||
case "远期":
|
||
case "掉期":
|
||
result = (td.StructureType.TrimToNull() ?? td.TradeType) + (td.OptionType == "看涨" || td.OptionType == "多头" ? "多头" : "空头");
|
||
break;
|
||
case "二元期权":
|
||
result = td.ExerciseMode == "American" ? td.ExerciseModeCn + td.TradeType.Replace("期权", "") + "期权" : td.ExerciseModeCn + td.TradeType.Replace("期权", "") + td.OptionType + "期权";
|
||
break;
|
||
case "雪球期权":
|
||
result = "雪球 " + td.OptionType;
|
||
break;
|
||
case "双鲨期权":
|
||
result = td.ExerciseModeCn + td.TradeType.Replace("期权", "") + td.OptionType + "期权";
|
||
break;
|
||
case "亚式期权":
|
||
case "香草期权":
|
||
case "障碍期权":
|
||
case "合成价差期权":
|
||
case "累计期权":
|
||
if (td.ParentTradeId == 0)
|
||
{
|
||
result = PS.Config.Is瑞达 && td.TradeType == "香草期权" ? td.ExerciseModeCn + td.OptionType + "期权" : td.ExerciseModeCn + td.TradeType.Replace("期权", "") + td.OptionType + "期权";
|
||
}
|
||
else
|
||
{
|
||
var tradelists = DbContextFactory.GetYLDbContext().trade.Where(x => x.id == td.ParentTradeId).FirstOrDefault();
|
||
result = tradelists?.StructureType ?? tradelists?.TradeType ?? td.StructureType ?? td.TradeType;
|
||
}
|
||
break;
|
||
case "现金流交易":
|
||
result = td.TradeType;
|
||
break;
|
||
default:
|
||
result = td.TradeType;
|
||
switch (td.TradeType)
|
||
{
|
||
case "结构化交易":
|
||
result = td.StructureType;
|
||
break;
|
||
case "凤凰期权":
|
||
case ConsGlobal.TradeType.CashFlow:
|
||
case ConsGlobal.TradeType.Forward:
|
||
case ConsGlobal.TradeType.PayoffSwap:
|
||
break;
|
||
case "自定义交易":
|
||
result = td.StructureIntroduction.TrimToNull() ?? td.StructureType.TrimToNull() ?? td.TradeType;
|
||
break;
|
||
case "气囊结构":
|
||
case "区间累积期权":
|
||
case "收益增强结构":
|
||
result = td.ExerciseModeCn + td.TradeType;
|
||
break;
|
||
default:
|
||
result = td.ExerciseModeCn + td.TradeType.Replace("期权", "") + td.OptionType + "期权";
|
||
break;
|
||
}
|
||
break;
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 雪球期权生成交易摘要
|
||
/// </summary>
|
||
public static IEnumerable<(string text, string value)> GetUnwindAbstractInfoItems_snowball(trade_cash tc, trade td, bool isUnwind)
|
||
{
|
||
var snowball = td.trade_snowball;
|
||
if (snowball == null)
|
||
{
|
||
throw new ServiceException("雪球期权扩展信息不存在,无法生成交易摘要");
|
||
}
|
||
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(td.UnderlyingCode);
|
||
var QuoteUnitString = " 元/" + (PS.Config.IsUseDisplayNotional ? underlying.QuoteUnitString : underlying.TradeUnitString);
|
||
var IsUsePremiumRate = td.IsUsePremiumRate == true;
|
||
var SpotPrice = underlying.UnderlyingInstrumentType == "CommodityFutures" ? td.SpotPrice : td.InitialSpotPrice;
|
||
|
||
var strikeFmt = td.IsMoneynessOption == "是"
|
||
? new Func<double?, string>(d => OtcFormatExtensions.OtcFormat(d, OtcFormatFlag.percent))
|
||
: new Func<double?, string>(d => OtcFormatExtensions.OtcFormatFlex(d, 2, 4));
|
||
|
||
|
||
var premiumFmt = IsUsePremiumRate
|
||
? new Func<double?, string>(d => OtcFormatExtensions.OtcFormat(d, OtcFormatFlag.premiumRateP))
|
||
: new Func<double?, string>(d => OtcFormatExtensions.OtcFormat(d, OtcFormatFlag.tradeSinglePrice));
|
||
|
||
var tradeAmount = td.TradeAmount.OtcFormatNotional() + (td.UnderlyingInstrumentType == "Stock"
|
||
? " 股" : " " + td.QuoteUnitSingle);
|
||
|
||
var list = new List<(string, string)>();
|
||
|
||
var action = tc.Action.Substring(5, 2);
|
||
|
||
if (PS.Config.Is厦门象屿)
|
||
{
|
||
list.Add(($"{action}信息", ""));
|
||
}
|
||
|
||
list.AddRange(new[] {
|
||
("交易编号", td.TradeNumber),
|
||
("开仓日期", td.TradeDate.OtcFormatDate()),
|
||
("开仓方向", td.ClientName),
|
||
("#", td.BuySell == "买入" ? "卖出" : "买入"),
|
||
("期权类型", GetTradeType(td)),
|
||
("标的名称",td.UnderlyingAssetName),
|
||
("标的代码",td.UnderlyingCode),
|
||
("名义本金",OtcFormatExtensions.OtcFormat(td.StockEqvNotionalToShow, OtcFormatFlag.StockEqvNotional))
|
||
});
|
||
if (snowball.KORebate > 0)
|
||
{
|
||
list.Add((" 票息", snowball.KORebate.OtcFormatPercent()));
|
||
}
|
||
//var suffix = isUnwind ? " (平仓)" : "(行权)";
|
||
var action_2 = $"({action})";
|
||
list.Add(("期初价格", td.SpotPrice.OtcFormatUmPrice()));
|
||
|
||
if (!snowball.IsInitialKnockedIn)
|
||
{
|
||
list.Add(("敲入价格", strikeFmt(snowball.KIBarrier)));
|
||
}
|
||
else
|
||
{
|
||
list.Add(("初始敲入", "是"));
|
||
}
|
||
list.Add(("敲出价格", strikeFmt(snowball.KOBarrier)));
|
||
list.Add(("执行价格", strikeFmt(td.Strike)));
|
||
list.Add(("到期日期", td.ExerciseDate.OtcFormatDate()));
|
||
list.Add(("终止价格", tc.FinalPrice.OtcFormatUmPrice() + action_2));
|
||
list.Add(("终止日期", tc.ValueDate.OtcFormatDate()));
|
||
|
||
var amount = tc.Amount * (valuedateBLL.SystemDate.UnwindAmountAngle == 1 ? -1 : EodOperationBase.GetSign(td.BuySell));
|
||
list.Add(("结算金额", (amount).OtcFormatMoney() + "元"));
|
||
return list;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 远期平仓摘要
|
||
/// </summary>
|
||
public static IEnumerable<(string text, string value)> GetUnwindAbstractInfoItems_Forward(trade_cash tc, trade td)
|
||
{
|
||
var snowball = td.trade_forward;
|
||
|
||
|
||
if (snowball == null)
|
||
{
|
||
throw new ServiceException("远期扩展信息不存在,无法生成交易摘要");
|
||
}
|
||
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(td.UnderlyingCode);
|
||
var QuoteUnitString = " 元/" + (PS.Config.IsUseDisplayNotional ? underlying.QuoteUnitString : underlying.TradeUnitString);
|
||
var IsUsePremiumRate = td.IsUsePremiumRate == true;
|
||
var strikeFmt = new Func<double?, string>(d => d.OtcFormatUmPrice(td.IsMoneynessOption == "是"));
|
||
|
||
var premiumFmt = IsUsePremiumRate
|
||
? new Func<double?, string>(d => OtcFormatExtensions.OtcFormat(d, OtcFormatFlag.premiumRateP))
|
||
: new Func<double?, string>(d => OtcFormatExtensions.OtcFormat(d, OtcFormatFlag.tradeSinglePrice));
|
||
|
||
var tradeAmount = td.TradeAmount.OtcFormatNotional() + (td.UnderlyingInstrumentType == "Stock"
|
||
? " 股" : " " + td.QuoteUnitSingle);
|
||
|
||
var winloss = TradeCalcHelper.CalcWinLoss(tradeType: td.TradeType, buySell: td.BuySell, tradePrice: td.TradePrice ?? 0, tcUnwindPercent: tc.UnwindPercentRate ?? (tc.UnwindNotional / td.OriginalNotional) ?? 0, tcAmount: tc.Amount);
|
||
|
||
var list = new List<(string, string)>();
|
||
if (PS.Config.Is厦门象屿)
|
||
{
|
||
list.Add(("平仓信息", ""));
|
||
}
|
||
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.TradeNumber),
|
||
("开仓日期", td.TradeDate.OtcFormatDate()),
|
||
("开仓方向", td.ClientName),
|
||
("#", td.BuySell == "买入" ? "卖出" : "买入"),
|
||
("结构类型", (td.StructureType.TrimToNull()??td.TradeType) + (td.OptionType == "看涨" ? "多头" : "空头")),
|
||
("标的代码",td.UnderlyingCode),
|
||
("执行价格",td.Strike.OtcFormatUmPrice(td.IsMoneynessOption == "是")),
|
||
("到期日期", actualExerciseDate.OtcFormatDate()),
|
||
("平仓日期", tc.ValueDate.OtcFormatDate()),
|
||
("标的价格", td.SpotPrice.OtcFormatUmPrice()),
|
||
(new string(' ', 5),tc.FinalPrice.OtcFormatUmPrice() + "(平仓)"),
|
||
("平仓数量",td.UnderlyingInstrumentType=="Stock"?tc.UnwindNotional.OtcFormatNotional()+"股":
|
||
tc.UnwindTradeAmount.OtcFormatNotional(underlying.CountRatio,PS.Config.IsUseDisplayNotional)+ " " +(td.QuoteUnitSingle == "吨" && underlying.UnderlyingType == "鸡蛋" ? "半吨":td.QuoteUnitSingle)),
|
||
("平仓总额", (-tc.Amount).OtcFormatMoney() + "元"), //客户角度,故为相反金额
|
||
("实现盈亏",(-winloss).OtcFormatMoney() + " 元")
|
||
});
|
||
return list;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 现金流平仓摘要
|
||
/// </summary>
|
||
public static IEnumerable<(string text, string value)> GetUnwindAbstractInfoItems_cashflow(trade_cash tc, trade td)
|
||
{
|
||
var cashflow = td.trade_cashflow;
|
||
if (cashflow == null)
|
||
{
|
||
throw new ServiceException("现金流扩展信息不存在,无法生成交易摘要");
|
||
}
|
||
|
||
var list = new List<(string, string)>();
|
||
if (PS.Config.Is厦门象屿)
|
||
{
|
||
list.Add(("平仓信息", ""));
|
||
}
|
||
//客户角度,故为相反金额
|
||
var amount = tc.Amount * (valuedateBLL.SystemDate.UnwindAmountAngle == 1 ? -1 : EodOperationBase.GetSign(td.BuySell));
|
||
list.AddRange(new[] {
|
||
("交易编号", td.TradeNumber),
|
||
("开仓日期", td.TradeDate.OtcFormatDate()),
|
||
("开仓方向", td.ClientName),
|
||
("#", td.BuySell == "买入" ? "卖出" : "买入"),
|
||
("平仓日期", tc.ValueDate.OtcFormatDate()),
|
||
("名义本金",(tc.UnwindPercentRate * td.OriginalStockEqvNotional).OtcFormatNotional() + "元"),
|
||
("平仓总额", (amount).OtcFormatMoney() + "元"),
|
||
});
|
||
return list;
|
||
}
|
||
}
|
||
}
|