518 lines
16 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|