Files
zszq-trs/Framework/YLErp.Core/DBModels/Helpers/TradeHelper.cs
T
2024-05-09 14:06:26 +08:00

651 lines
24 KiB
C#

using Newtonsoft.Json;
using YLErp.DBModels.Consts;
using YLErp.DBModels.Enums;
namespace YLErp.DBModels.Helpers
{
/// <summary>
/// 交易帮助类
/// </summary>
public static class TradeHelper
{
/// <summary>
/// 获取敲入敲出中文描述
/// </summary>
public static string GetKnockInOutStatusCn(string knockInOutStatus)
{
switch (knockInOutStatus)
{
case "KnockedIn":
return "已敲入";
case "KnockedOut":
return "已敲出";
default:
return "观察中";
}
}
/// <summary>
/// 获取行权模式中文描述
/// </summary>
public static string GetExerciseModeCn(string exerciseMode)
{
switch (exerciseMode)
{
case "American": return "美式";
case "European": return "欧式";
default: return string.Empty;
}
}
/// <summary>
/// 获取CallPut
/// </summary>
public static string GetCallPut(string OptionType)
{
switch (OptionType)
{
case "看涨":
case "Call":
case "多头":
return "Call";
case "看跌":
case "Put":
case "空头":
return "Put";
default: return string.Empty;
}
}
/// <summary>
/// 根据系统中TradeType转换为QDP可用TradeType
/// </summary>
public static string ConvertQDPTradeType(string buySell)
{
switch (buySell)
{
case "买入":
return "Buy";
case "卖出":
return "Sell";
case "多头开仓":
return "OpenLong";
case "多头平仓":
return "CloseLong";
case "空头开仓":
return "OpenShort";
case "空头平仓":
return "CloseShort";
default:
return buySell;
}
}
/// <summary>
/// 获取枚举型的交易状态
/// </summary>
public static EnumTradeStatus GetTradeStatus(string tradeStatus)
{
switch (tradeStatus)
{
case ConsTrade.新增待确认:
return EnumTradeStatus.added;
case ConsTrade.修改待确认:
return EnumTradeStatus.modified;
case ConsTrade.审批中:
return EnumTradeStatus.approval;
case ConsTrade.确认成交:
return EnumTradeStatus.confirmed;
case ConsTrade.已到期:
return EnumTradeStatus.expired;
case ConsTrade.已执行:
return EnumTradeStatus.exercised;
case ConsTrade.已平仓:
return EnumTradeStatus.closed;
case ConsTrade.平仓待复核:
return EnumTradeStatus.checkToClose;
case ConsTrade.行权待复核:
return EnumTradeStatus.checkToExercise;
case ConsTrade.提前终止拒绝:
return EnumTradeStatus.rejectEarlyClose;
default: return EnumTradeStatus.unknown;
}
}
/// <summary>
/// 获取枚举的交易状态文字
/// </summary>
public static string GetTradeStatus(EnumTradeStatus tradeStatus)
{
switch (tradeStatus)
{
case EnumTradeStatus.added:
return ConsTrade.新增待确认;
case EnumTradeStatus.modified:
return ConsTrade.修改待确认;
case EnumTradeStatus.approval:
return ConsTrade.审批中;
case EnumTradeStatus.confirmed:
return ConsTrade.确认成交;
case EnumTradeStatus.expired:
return ConsTrade.已到期;
case EnumTradeStatus.exercised:
return ConsTrade.已执行;
case EnumTradeStatus.closed:
return ConsTrade.已平仓;
case EnumTradeStatus.checkToClose:
return ConsTrade.平仓待复核;
case EnumTradeStatus.checkToExercise:
return ConsTrade.行权待复核;
case EnumTradeStatus.rejectEarlyClose:
return ConsTrade.提前终止拒绝;
default: return "未知";
}
}
/// <summary>
/// 获取交易类型大类
/// </summary>
public static TradeTypeFlag GetTradeType1(string tradeType)
{
if (string.IsNullOrWhiteSpace(tradeType))
{
throw new ArgumentException("参数不能为空", nameof(tradeType));
}
switch (tradeType)
{
case "股票": return TradeTypeFlag.Stocks;
case "商品期货": return TradeTypeFlag.Futures;
case "商品现货": return TradeTypeFlag.Spots;
case "场内期权": return TradeTypeFlag.Options;
case "远期": return TradeTypeFlag.OtcForward;
default: return TradeTypeFlag.OtcOptions;
}
}
/// <summary>
/// 获取持仓份额
/// </summary>
public static double GetPositionNotional(string buySell, double notional)
{
if (string.IsNullOrWhiteSpace(buySell))
{
throw new ArgumentException("参数不能为空", nameof(buySell));
}
switch (buySell)
{
case "买入":
case "多头开仓":
case "空头平仓":
return notional;
case "卖出":
case "多头平仓":
case "空头开仓":
return -notional;
default: throw new NotSupportedException("未知的交易方向:" + buySell);
}
}
/// <summary>
/// 获取持仓份额
/// </summary>
public static double GetPositionNotional(TradeSideFlag tradeSide, double notional)
{
switch (tradeSide)
{
case TradeSideFlag.LongOpen:
case TradeSideFlag.ShortClose:
return notional;
case TradeSideFlag.ShortOpen:
case TradeSideFlag.LongClose:
return -notional;
default: throw new NotSupportedException("未知的交易方向:" + tradeSide.ToString());
}
}
/// <summary>
/// 获取交易方向
/// </summary>
public static TradeSideFlag GetTradeSide(string buySell)
{
if (string.IsNullOrWhiteSpace(buySell))
{
throw new ArgumentException("参数不能为空", nameof(buySell));
}
switch (buySell)
{
case "long":
case "买入":
case "多头开仓":
return TradeSideFlag.LongOpen;
case "卖出":
case "多头平仓":
return TradeSideFlag.LongClose;
case "short":
case "空头开仓":
return TradeSideFlag.ShortOpen;
case "空头平仓":
return TradeSideFlag.ShortClose;
default: throw new NotSupportedException("未知的交易方向:" + buySell);
}
}
/// <summary>
/// 获取持仓类型
/// </summary>
public static PositionTypeFlag GetPositionType(string buySell)
{
if (string.IsNullOrWhiteSpace(buySell))
{
throw new ArgumentException("参数不能为空", nameof(buySell));
}
switch (buySell)
{
case "long":
case "买入":
case "多头开仓":
case "多头平仓":
return PositionTypeFlag.Long;
case "short":
case "卖出":
case "空头开仓":
case "空头平仓":
return PositionTypeFlag.Short;
default: throw new NotSupportedException("未知的交易方向:" + buySell);
}
}
/// <summary>
/// 获取持仓类型
/// </summary>
public static PositionTypeFlag GetPositionType(TradeSideFlag tradeSide)
{
switch (tradeSide)
{
case TradeSideFlag.LongOpen:
case TradeSideFlag.LongClose:
return PositionTypeFlag.Long;
case TradeSideFlag.ShortOpen:
case TradeSideFlag.ShortClose:
return PositionTypeFlag.Short;
default: throw new NotSupportedException("未知的交易方向:" + tradeSide.ToString());
}
}
/// <summary>
/// 通过有效名义本金获取名义本金
/// </summary>
public static double GetStockEqvNotional(double? stockEqvNotionalReal, double? participationRate, double? annualizeFactor)
{
if ((participationRate ?? 1) == 0 || (annualizeFactor ?? 1) == 0)
{
return 0;
}
else
{
return (stockEqvNotionalReal ?? 0) / participationRate.Value / (annualizeFactor ?? 1);
}
}
/// <summary>
/// 通过名义本金获取有效名义本金
/// </summary>
public static double GetStockEqvNotionalReal(double? stockEqvNotional, double? participationRate, double? annualizeFactor)
{
return (stockEqvNotional ?? 0) * (participationRate ?? 1) * (annualizeFactor ?? 1);
}
/// <summary>
/// 通过名义本金获取名义本金与有效名义本金的比例
/// </summary>
public static double GetStockEqvNotionalMultiply(double? stockEqvNotional, double? participationRate, double? annualizeFactor)
{
if (stockEqvNotional.HasValue)
{
var stockEqvNotionalReal = stockEqvNotional.Value * (participationRate ?? 1) * (annualizeFactor ?? 1);
return stockEqvNotionalReal > 0 ? stockEqvNotional.Value / stockEqvNotionalReal : 0;
}
return 0;
}
/// <summary>
/// 通过权利金总额获取权利金费率
/// </summary>
public static double GetPremiumRateByTradePrice(double? tradePrice, double? stockEqvNotional, double? participationRate, double? principalSum, double? annualizeFactor, string buySell, string tradeType, bool isOpen)
{
if ((stockEqvNotional ?? 0) != 0 && (annualizeFactor ?? 1) != 0 && (participationRate ?? 1) != 0)
{
if (!isOpen)
{
return ((tradePrice ?? 0) - (principalSum ?? 0) * (buySell == "卖出" ? -1 : 1)) / stockEqvNotional.Value / (annualizeFactor ?? 1) / participationRate.Value;
}
else
{
return ((tradePrice ?? 0) - (principalSum ?? 0)) / stockEqvNotional.Value / (annualizeFactor ?? 1) / participationRate.Value;
}
}
else
{
return 0;
}
}
/// <summary>
/// 通过权利金单价获取权利金费率
/// </summary>
public static double GetPremiumRateByTradeSinglePrice(double? tradeSinglePrice, double? spotPrice)
{
if ((spotPrice ?? 0) == 0)
{
return 0;
}
else
{
return (tradeSinglePrice ?? 0) / Math.Abs(spotPrice.Value);
}
}
/// <summary>
/// 通过权利金费率获取权利金总额
/// </summary>
public static double GetTradePriceByPremiumRate(double? premiumRate, double? stockEqvNotional, double? participationRate, double? principalSum, double? annualizeFactor, string buySell, string tradeType, bool isOpen)
{
//了结情况下的场景
if (!isOpen)
{
return (stockEqvNotional ?? 0) * (annualizeFactor ?? 1) * (premiumRate ?? 0) * (participationRate ?? 1) + (principalSum ?? 0) * (buySell == "卖出" ? -1 : 1);
}
else
{
return (stockEqvNotional ?? 0) * (annualizeFactor ?? 1) * (premiumRate ?? 0) * (participationRate ?? 1) + (principalSum ?? 0);
}
}
public static double GetTradePriceBySinglePrice(double? tradeSinglePrice, double? notional, double? principalSum, string buySell, string tradeType, bool isOpen)
{
//了结情况下的场景
if (!isOpen)
{
return (tradeSinglePrice ?? 0) * (notional ?? 0) + (principalSum ?? 0) * (buySell == "卖出" ? -1 : 1);
}
else
{
return (tradeSinglePrice ?? 0) * (notional ?? 0) + (principalSum ?? 0);
}
}
public static double GetAmountByPaymentAmount(double paymentAmount, double? principalSum, string buySell)
{
return paymentAmount + (principalSum ?? 0) * (buySell == "卖出" ? -1 : 1);
}
public static double GetTradeSinglePriceByPremiumRate(double? premiumRate, double? spotPrice)
{
return Math.Abs(spotPrice ?? 0) * (premiumRate ?? 0);
}
public static double GetTradeSinglePriceByTradePrice(double? tradePrice, double? notional, double? principalSum, string buySell, string tradeType, bool isOpen)
{
if ((notional ?? 0) == 0)
{
return 0;
}
else
{
if (!isOpen)
{
return ((tradePrice ?? 0) - (principalSum ?? 0) * (buySell == "卖出" ? -1 : 1)) / notional.Value;
}
else
{
return ((tradePrice ?? 0) - (principalSum ?? 0)) / notional.Value;
}
}
}
/// <summary>
/// 根据保坻收益率,换算单个标的保底收益
/// </summary>
/// <param name="stockEqvNotional"></param>
/// <param name="principalRate"></param>
/// <param name="notional"></param>
/// <param name="annualizeFactor"></param>
/// <returns></returns>
public static double GetSinglePrincipal(double stockEqvNotional, double? principalRate, double notional, double? annualizeFactor)
{
if (notional == 0) return 0;
double principalSum = GetRateToPrincipalSum(stockEqvNotional, principalRate, annualizeFactor);
return principalSum / notional;
}
/// <summary>
/// 根据保坻收益率,计算保底收益总额
/// </summary>
/// <param name="stockEqvNotional"></param>
/// <param name="principalRate"></param>
/// <param name="annualizeFactor"></param>
/// <returns></returns>
public static double GetRateToPrincipalSum(double stockEqvNotional, double? principalRate, double? annualizeFactor)
{
return (annualizeFactor ?? 1) * stockEqvNotional * (principalRate ?? 0);
}
/// <summary>
/// 获取单个标的保底收益,换算保坻收益率
/// </summary>
/// <param name="stockEqvNotional"></param>
/// <param name="singlePrincipal"></param>
/// <param name="notional"></param>
/// <param name="annualizeFactor"></param>
/// <returns></returns>
public static double GetPrincipalRate(double stockEqvNotional, double? singlePrincipal, double notional, double? annualizeFactor)
{
if (stockEqvNotional == 0) return 0;
double principalSum = GetSingleToPrincipalSum(notional, singlePrincipal);
return principalSum / ((annualizeFactor ?? 1) * stockEqvNotional);
}
/// <summary>
/// 根据单个标的保底收益,计算保底收益总额
/// </summary>
/// <param name="notional"></param>
/// <param name="singlePrincipal"></param>
/// <returns></returns>
public static double GetSingleToPrincipalSum(double notional, double? singlePrincipal)
{
return (singlePrincipal ?? 0) * notional;
}
/// <summary>
/// 根据保底收益总额,计算真实的保底收益率
/// </summary>
/// <param name="stockEqvNotional"></param>
/// <param name="principalSum"></param>
/// <param name="annualizeFactor"></param>
/// <returns></returns>
public static double GetPrincipalRateReal(double stockEqvNotional, double? principalSum, double? annualizeFactor)
{
if (stockEqvNotional == 0) return 0;
return principalSum == null ? 0 : (principalSum ?? 0) / ((annualizeFactor ?? 1) * stockEqvNotional);
}
/// <summary>
/// 根据持仓名义本金计算持仓保底收益总额
/// </summary>
/// <param name="stockEqvNotional"></param>
/// <param name="originalstockEqvNotional"></param>
/// <param name="principalSum"></param>
/// <returns></returns>
public static double GetPrincipalSumReal(double stockEqvNotional, double? originalstockEqvNotional, double? principalSum)
{
return stockEqvNotional / (originalstockEqvNotional ?? 0) * (principalSum ?? 0);
}
/// <summary>
/// 根据收益总额计算了结总额
/// <para>了结总额=收益总额-保底收益总额*(支付-1)</para>
/// </summary>
/// <param name="tcAmount">TradeCash.Amount</param>
/// <param name="principalSum">保底收益总额</param>
/// <param name="isBuy">开仓是否买入</param>
/// <returns>了结总额</returns>
public static double GetUnwindPrice(double tcAmount, double principalSum, bool isBuy)
{
return tcAmount - principalSum * (isBuy ? 1 : -1);
}
/// <summary>
/// 根据交易TradeCash判断该笔资金的操作行为状态
/// 非完成该行为的当前交易状态
/// </summary>
/// <param name="trade"></param>
/// <param name="tradeCash"></param>
/// <returns></returns>
public static string GetTradeStatus(OtcTradeBase trade, trade_cash tradeCash)
{
if (tradeCash.Action == "系统操作-平仓费" && (tradeCash.UnwindType == "部分平仓" || tradeCash.UnwindType == "全部平仓"))
{
return "已平仓";
}
else if (tradeCash.Action == "系统操作-行权费" && tradeCash.ExerciseWay == "到期行权" && tradeCash.UnwindType == "到期")
{
return "已到期";
}
else if ((tradeCash.Action == "系统操作-平仓费" && tradeCash.UnwindType == "部分行权") || tradeCash.Action == "系统操作-行权费")
{
return "已行权";
}
//剩余的可能性应该是敲出或者到期的票息或者到期互换交易,展示交易最终了结状态
else
{
return trade.TradeStatus;
}
}
/// <summary>
/// 获取已完结的tradecash记录
/// </summary>
/// <param name="tc"></param>
/// <returns></returns>
public static IQueryable<trade_cash> GetSettleTradeCash(IQueryable<trade_cash> tc)
{
return tc.Where(O =>
(O.Action == "系统操作-平仓费" && (O.UnwindType == null || (O.UnwindType == "部分平仓" && (O.Notional - O.UnwindNotional) < 0.000001) || (O.UnwindType != "部分平仓" && O.UnwindType != "部分行权"))) ||
O.Action == "系统操作-行权费" || O.IsLastAction);
}
/// <summary>
/// 交易是否已了结
/// </summary>
public static bool IsTradeFinished(OtcTradeBase td)
{
return ConsTrade.TradeCompleteStatus.Contains(td?.TradeStatus);
}
/// <summary>
/// 获取亚式期权均价计算模式中文描述
/// </summary>
public static string GetAsianPayoffTypeCn(string payoffType)
{
switch (payoffType)
{
case "ArithmeticAverage":
return "算术平均";
case "GeometricAverage":
return "几何平均";
case "DiscreteArithmeticAverage":
return "算术平均(离散)";
case "EnhancedArithmeticAverage":
return "增强算术平均";
default: return payoffType;
}
}
/// <summary>
/// 获取亚式期权行权价类型中文描述
/// </summary>
public static string GetAsianStrikeTypeCn(string StrikeType)
{
switch (StrikeType)
{
case "Fixed":
return "固定行权价";
case "Floating":
return "浮动行权价";
case "Segmented":
return "分段式";
default: return StrikeType;
}
}
/// <summary>
/// 获取补偿支付中文描述
/// </summary>
public static string GetRebateTypeCn(string rebateType)
{
switch (rebateType)
{
case "AtHit":
return "立即";
case "AtEnd":
return "递延";
default: return rebateType;
}
}
/// <summary>
/// 判断行权价是否必须
/// </summary>
public static bool IsStrikeRequired(OtcOptionTradeFull td)
{
return !(td.TradeType == "自定义交易" || td.TradeType == "现金流交易"
|| td.TradeType == "雪球期权" || td.TradeType == "凤凰期权"
|| td.IsGroup == 1
|| td.TradeType == "亚式期权" && td.StrikeType == "Floating");
}
/// <summary>
/// 从交易元数据中获取组合标的期初价格
/// </summary>
public static SyntheticPriceModel GetSyntheticPriceModel(OtcTradeBase td)
{
if (td == null) return null;
if (td.MetaDic.TryGetValue(ConsTradeMetaKey.SyntheticUnderlying, out var meta) && !string.IsNullOrWhiteSpace(meta))
{
return JsonConvert.DeserializeObject<SyntheticPriceModel>(meta);
}
return null;
}
/// <summary>
/// 从观察频率中获取观察日
/// </summary>
public static string GetObDates(string obStr)
{
if (string.IsNullOrWhiteSpace(obStr))
{
return "每日";
}
var index = obStr.IndexOf(";");
return index > 0 ? obStr.Substring(0, index) : obStr;
}
/// <summary>
/// 从观察频率中获取观察价格
/// </summary>
public static string GetObPrices(string obStr)
{
if (string.IsNullOrWhiteSpace(obStr))
{
return "每日";
}
var index = obStr.IndexOf(";");
return index > 0 ? obStr.Substring(index + 1) : string.Empty;
}
}
}