Files
zszq-trs/YLErpDAL/Model/Trade.cs
T
2025-10-15 15:08:37 +08:00

518 lines
16 KiB
C#

using Newtonsoft.Json;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using YieldChain.Helpers;
using YLErp.BLL;
using YLErp.DBModels.Attributes;
using YLErp.Helpers;
namespace YLErp.DBModels
{
[Table("trade")]
public partial class trade : OtcTrade, IDataTraceV2
{
public static string LogClass = "交易信息";
[NotMapped]
public IEnumerable<trade> SubTrades
{
get; set;
}
public override IEnumerable<OtcTrade> GetSubTrades()
{
return SubTrades;
}
/// <summary>
/// 前一交易日对冲波动率
/// </summary>
[NotMapped]
public double? YesterDayTradeSavedVol { get; set; }
/// <summary>
/// 活着的持仓交易 的持仓市值
/// </summary>
[NotMapped]
public string PV { get; set; }
/// <summary>
/// 实现盈亏
/// </summary>
[NotMapped]
public double? RealizedPnl { get; set; }
/// <summary>
/// 持仓盈亏
/// </summary>
[NotMapped]
public string PositionPnl { get; set; }
/// <summary>
/// 离系统工作日期差几天
/// </summary>
[NotMapped]
public int MaturityWorkDay
{
get
{
if (ExerciseDate == null)
{
return 999999;
}
return CalendarBLL.GetNonHolidayDays(ExerciseDate.Value);
}
}
/// <summary>
/// 匹配交易编号
/// </summary>
[NotMapped]
[DisplayName("匹配交易编号")]
public string PairTradeNumber { get; set; }
/// <summary>
/// 客户要求界面显示的份额,买*1,卖*-1
/// </summary>
[NotMapped]
public double? ShowNotional
{
get
{
if (BuySell == "卖出")
{
return Notional * -1;
}
else
{
return Notional;
}
}
}
/// <summary>
/// 离交易到期日还有几天
/// </summary>
[NotMapped]
public int MaturityDay
{
get
{
if (ExerciseDate == null)
{
return 999999;
}
return ExerciseDate.Value.Subtract(DateTime.Now.Date).Days;
}
}
[NotMapped]
public string TradeOpenVolatilityString
{
get
{
if (TradeType == "自定义交易")
{
return "";
}
return TradeOpenVolatility == null ? "0.00%" : (TradeOpenVolatility.Value * 100).ToString("0.00") + "%";
}
}
/// <summary>
/// 先前的状态,用来做比较
/// </summary>
[JsonIgnore]
[NotMapped]
public string TradeOldStatus { get; set; }
/// <summary>
/// 首次设置的期初价格(不受调整更新)
/// </summary>
[NotMapped]
[DisplayName("首次设置的期初价格")]
public double? InitialSpotPriceOriginal { get; set; }
[NotMapped]
[DisplayName("交易数量")]
public double? TradeOriginalAmount { get; set; }
[NotMapped]
[DisplayName("到期日期")]
public string ExerciseDateString
{
get
{
if (ExerciseDate != null)
{
return ExerciseDate.Value.ToString("yyyy-MM-dd");
}
else
{
return "";
}
}
}
[JsonIgnore]
[NotMapped]
[DisplayName("相对行权价")]
public string StrikeRelative => Strike == null ? "0" : Strike.Value.OtcFormatUmPrice(true);
[NotMapped]
[DisplayName("实际行权价")]
public double? ActualStrike
{
get
{
if (TradeType == "亚式期权" && trade_asian_option.StrikeType == "Floating")
{
return trade_asian_optionBLL.GetAsianStrikePrice(valuedateBLL.ValueDate, this);
}
return IsMoneynessOptionData ? (SpotPrice * Strike) : Strike;
}
}
/// <summary>
/// 实际行权价
/// 盯市报告用到
/// </summary>
[DisplayName("实际行权价")]
public string StrikeString => (IsMoneynessOptionData ? (SpotPrice ?? 0) * (Strike ?? 0) : (Strike ?? 0)).OtcFormatUmPrice();
[DisplayName("期权价格")]
public string TradeSinglePriceString
{
get
{
if (IsUsePremiumRate == true)
{
return (PremiumRate ?? 0).OtcFormat(OtcFormatFlag.premiumRateP);
}
else
{
return (TradeSinglePrice ?? 0).OtcFormat(OtcFormatFlag.tradeSinglePrice);
}
}
}
[DisplayName("成交日期")]
public string TradeDateString
{
get
{
if (TradeDate != null)
{
return TradeDate.Value.ToString("yyyy-MM-dd");
}
else
{
return "";
}
}
}
[NotMapped]
[DisplayName("交易手数")]
public double? LotsNewInfo { get; set; }
/// <summary>
/// 平仓单价
/// </summary>
[NotMapped]
public double? UnWindPrice { get; set; }
[NotMapped]
[DisplayName("名义本金")]
public double? StockEqvNotionalToShow => (OriginalStockEqvNotional ?? 0).OtcFormatValue(OtcFormatFlag.StockEqvNotional);
[DisplayName("收益结算")]
[NotMapped, TradeAuditChangeMsg]
public string SettlementTypeDesc => EnumHelper.GetDescriptionByName(SettlementType);
[NotMapped]
public string SettlementDesc { get; set; }
[DisplayName("标的品种")]
[NotMapped]
public int? VarietyId { get; set; }
/// <summary>
/// 组合标的的公式信息
/// </summary>
[NotMapped]
public string SyntheticUnderlyingTipsInfo { get; set; }
[NotMapped]
public string StrikeToShow => IsMoneynessOptionData ? StrikeRelative : (Strike ?? 0).OtcFormatUmPrice();
/// <summary>
/// 实时剩余份额
/// </summary>
[NotMapped]
[DisplayName("实时剩余份额")]
public double CurNotional { get; set; }
/// <summary>
/// 昨日剩余份额
/// </summary>
[NotMapped]
[DisplayName("昨日剩余份额")]
public double LastDayNotional { get; set; }
#region -- 申万
[NotMapped]
public double? Amount { get; set; }
[NotMapped]
public string ContractCode { get; set; }
#endregion -- 申万
[DisplayName("初始预付金率")]
[NotMapped]
public double? InitialMarginRatio { get; set; }
[DisplayName("标的价格")]
[NotMapped]
public double? UnderlyingPrice { get; set; }
[DisplayName("标的名称")]
[NotMapped]
public string UnderlyingName { set; get; }
[DisplayName("Delta手数")]
[NotMapped]
public double? DeltaInLots { get; set; }
/// <summary>
/// 平直期权(当前的 标的价格和行权价相等),价值状态列显示“ATM K/S , 如“ATM 100%”;
/// 虚值期权(看涨-标的当前价格低于行权价,看跌-标的价格高于行权价),价值状态显示“OTM K/S”
/// 市值期权 (看涨-标的当前价格高于行权价,看跌-标的价格低于行权价),价值状态显示 “ITM K/S”
/// K/S=行权价/标的价格带%格式;
/// </summary>
[DisplayName("价值状态")]
[NotMapped]
public string ValueStatus { get; set; }
[DisplayName("了结标的价格")]
[NotMapped]
public double? UnWindUnderlyingPrice { get; set; }
[DisplayName("权利金(了结)")]
[NotMapped]
public double? UnWindTradePrice { get; set; }
[DisplayName("了结数量")]
[NotMapped]
public double? UnWindTotalAmount { get; set; }
[DisplayName("了结总额")]
[NotMapped]
public double? UnWindFee { get; set; }
[DisplayName("了结次数")]
[NotMapped]
public int UnWindTimes { get; set; }
/// <summary>
/// 设置观察日价格后交易敲入敲出状态
/// </summary>
[NotMapped]
[DisplayName("设置观察日价格后交易敲入敲出状态")]
public string KnockInOutStatusObservation { get; set; }
/// <summary>
/// 除权除息系数
/// </summary>
[NotMapped]
[DisplayName("除权除息系数")]
public double DividendRatio { get; internal set; }
[DisplayName("簿记后生成的成交收益率")]
public decimal? InitYtm { get; set; }
public string GetDataTraceKeyInfo()
{
return "场外交易:" + TradeNumber;
}
public string Serialize(DateTime settleDate)
{
return TradeHelper2.Serialize(this, settleDate);
}
public static trade Deserialize(string tradeJson)
{
return TradeHelper2.Deserialize(tradeJson);
}
}
public class tradeGridSum
{
/// <summary>
/// 交易价格总数
/// </summary>
public double? TradePriceSum { get; set; }
/// <summary>
/// 持仓数量
/// </summary>
public double? TradeAmountSum { get; set; }
/// <summary>
/// 所有交易id
/// </summary>
public string AllTradeCashIds { get; set; }
}
public class TradeHelper2
{
static readonly IReadOnlyList<(string, Action<trade>)> _setNullProps;
static TradeHelper2()
{
(string, Action<trade>) setNullProp(Expression<Func<trade, object>> property)
{
var memberExp = (MemberExpression)property.Body;
var propInfo = (PropertyInfo)memberExp.Member;
var assignExp = Expression.Assign(memberExp, Expression.Convert(Expression.Constant(null), propInfo.PropertyType));
return (propInfo.Name, Expression.Lambda<Action<trade>>(assignExp, property.Parameters).Compile());
}
_setNullProps = new List<(string, Action<trade>)> {
setNullProp(t => t.eod_trade),
setNullProp(t => t.get_trade_swap_details),
setNullProp(t => t.pay_trade_swap_details),
setNullProp(t => t.SaveExt),
setNullProp(t => t.SubTrades),
setNullProp(t => t.trade_accumulator_option),
setNullProp(t => t.trade_airbag),
setNullProp(t => t.trade_asian_option),
setNullProp(t => t.trade_autocall),
setNullProp(t => t.trade_barrier_option),
setNullProp(t => t.trade_risky_option),
setNullProp(t => t.trade_double_sharkfin_option),
setNullProp(t => t.trade_binary_option),
setNullProp(t => t.trade_cash),
setNullProp(t => t.trade_cashflow),
setNullProp(t => t.trade_custom),
setNullProp(t => t.trade_double_sharkfin_option),
setNullProp(t => t.trade_forward),
setNullProp(t => t.trade_rainbow_option),
setNullProp(t => t.trade_rangeaccrual),
setNullProp(t => t.trade_snowball),
setNullProp(t => t.trade_spread_option),
setNullProp(t => t.trade_swap),
setNullProp(t => t.trade_underlying_enhance),
setNullProp(t => t.SalesCommission),
};
}
/// <summary>
/// 根据传入字符采取相应方式反序列化Trade对象
/// </summary>
public static trade Deserialize(string tradeJson)
{
trade result = null;
if (!string.IsNullOrEmpty(tradeJson))
{
if (!tradeJson.StartsWith("{"))
{
tradeJson = GZipHelper.DecompressBase64String(tradeJson);
}
result = JsonHelper.ToObject<trade>(tradeJson);
}
return result;
}
public static string Serialize(trade t, DateTime settleDate)
{
ReduceTradeExt(t);
tradeBLL.SetFieldsByTradeType(t, settleDate);
var str = JsonHelper.Serialize(t, true);
var buffer = GZipHelper.Compress(Encoding.UTF8.GetBytes(str));
str = Convert.ToBase64String(buffer);
return str;
}
/// <summary>
/// 清空不相关的子对象,精简整体体积
/// </summary>
/// <param name="t"></param>
public static void ReduceTradeExt(trade t)
{
var excludePropName = new List<string>();
if (t == null) { return; }
switch (t.TradeType)
{
case "亚式期权":
excludePropName.Add(nameof(t.trade_asian_option)); break;
case "二元期权":
excludePropName.Add(nameof(t.trade_binary_option)); break;
case "障碍期权":
excludePropName.Add(nameof(t.trade_barrier_option)); break;
case "Risky期权":
excludePropName.Add(nameof(t.trade_risky_option)); break;
case "彩虹期权":
excludePropName.Add(nameof(t.trade_rainbow_option)); break;
case "价差期权":
excludePropName.Add(nameof(t.trade_spread_option)); break;
case "双鲨期权":
excludePropName.Add(nameof(t.trade_double_sharkfin_option)); break;
case "凤凰期权":
excludePropName.Add(nameof(t.trade_autocall)); break;
case "雪球期权":
excludePropName.Add(nameof(t.trade_snowball)); break;
case "区间累积期权":
excludePropName.Add(nameof(t.trade_rangeaccrual)); break;
case "收益增强结构":
excludePropName.Add(nameof(t.trade_underlying_enhance)); break;
case "气囊结构":
excludePropName.Add(nameof(t.trade_airbag)); break;
case "远期":
excludePropName.Add(nameof(t.trade_forward)); break;
case "收益互换":
excludePropName.Add(nameof(t.trade_swap));
excludePropName.Add(nameof(t.get_trade_swap_details));
excludePropName.Add(nameof(t.pay_trade_swap_details));
break;
case "现金流交易":
excludePropName.Add(nameof(t.trade_cashflow));
break;
case "累计期权":
excludePropName.Add(nameof(t.trade_accumulator_option)); break;
case "自定义交易":
excludePropName.Add(nameof(t.trade_custom)); break;
case "结构化交易":
if (t.StructureType == "气囊结构")
{
excludePropName.Add(nameof(t.trade_airbag));
}
excludePropName.Add(nameof(t.SubTrades));
break;
}
if (t.SalesCommission?.SalesIds?.Any() ?? false)
{
t.SalesCommission = null;
}
foreach (var (propName, action) in _setNullProps)
{
if (!excludePropName.Contains(propName))
{
action(t);
}
}
}
}
}