Files
zszq-trs/YLErpDAL/Modules/TradeModule/ExoticOptionModule/TradeAsianOptionBLL.cs
T
2024-05-09 14:06:26 +08:00

200 lines
7.7 KiB
C#

using Qdp.Foundation.Implementations;
using Qdp.Pricing.Base.Utilities;
using YLErp.Models;
using YLErp.Modules;
using YLErp.Modules.CalculationModule;
namespace YLErp.BLL
{
public class trade_asian_optionBLL
{
/// <summary>
/// 计算亚式期权Floating类型交易的浮动行权价
/// </summary>
public static double? GetAsianStrikePrice(DateTime valueDate, trade trade)
{
var baseReq = AsianOptionFixingService.GetRequest(valueDate, trade);
var strikeReq = new AsianOptionStrikeRequest(baseReq)
{
IsMoneynessOption = trade.IsMoneynessOptionData,
SpotPrice = trade.SpotPrice,
Strike = trade.Strike,
};
tradeBLL.SetFieldsByTradeType(trade);
return GetAsianStrikePrice(strikeReq, trade.trade_asian_option);
}
/// <summary>
/// 获取亚式期权行权价
/// </summary>
public static double? GetAsianStrikePrice(AsianOptionStrikeRequest request, trade_asian_option asianOption)
{
if (request is null)
{
return null;
}
if (asianOption is null)
{
using (var db = DbContextFactory.GetYLDbContext())
{
asianOption = request.TradeId > 0 ? db.trade_asian_option.AsNoTracking().FirstOrDefault(n => n.TradeId == request.TradeId) : null;
}
if (asianOption is null)
{
return null;
}
}
if ("Floating".Equals(asianOption.StrikeType, StringComparison.OrdinalIgnoreCase))
{
var fixings = AsianOptionFixingService.GetFixingString(request, asianOption);
if (string.IsNullOrWhiteSpace(fixings))
{
return null;
}
var fixingValues = fixings.Split(QdpConsts.Semilicon).Select(x =>
{
var splits = x.Split(QdpConsts.Comma);
return Tuple.Create(splits[0].ToDate(), double.Parse(splits[1]));
}).ToDictionary(x => x.Item1, x => x.Item2);
if ("GeometricAverage".Equals(asianOption.PayoffType))
{
var n = fixingValues.Count;
return Math.Pow(fixingValues.Select(x => x.Value).Aggregate(func: (result, item) => result * item), 1.0 / n);
}
else if ("ArithmeticAverage".Equals(asianOption.PayoffType)
|| "DiscreteArithmeticAverage".Equals(asianOption.PayoffType)
|| "EnhancedArithmeticAverage".Equals(asianOption.PayoffType))
{
return fixingValues.Select(x => x.Value).Average();
}
}
return request.IsMoneynessOption ? (request.SpotPrice * request.Strike) : request.Strike;
}
//TODO:除权除息
/// <summary>
/// 计算亚式期权Fix类型交易的浮动行权价
/// </summary>
public static double? GetAsianFinalPrice(trade trade, DateTime? valueDate = null)
{
if (trade is null)
{
return null;
}
if (valueDate == null)
{
valueDate = valuedateBLL.ValueDate;
}
tradeBLL.SetFieldsByTradeType(trade);
var asianOption = trade.trade_asian_option;
if (asianOption is null)
{
using (var db = DbContextFactory.GetYLDbContext())
{
trade.trade_asian_option = asianOption = db.trade_asian_option.AsNoTracking().FirstOrDefault(n => n.TradeId == trade.id);
}
if (asianOption is null)
{
return null;
}
}
if ("Fixed".Equals(asianOption.StrikeType, StringComparison.OrdinalIgnoreCase))
{
var fixings = AsianOptionFixingService.GetFixingString(valueDate.Value, trade);
if (string.IsNullOrWhiteSpace(fixings))
{
return null;
}
var fixingValues = fixings.Split(QdpConsts.Semilicon).Select(x =>
{
var splits = x.Split(QdpConsts.Comma);
return Tuple.Create(splits[0].ToDate(), double.Parse(splits[1]));
}).ToDictionary(x => x.Item1, x => x.Item2);
if ("GeometricAverage".Equals(asianOption.PayoffType))
{
var n = fixingValues.Count;
return Math.Pow(fixingValues.Select(x => x.Value).Aggregate(func: (result, item) => result * item), 1.0 / n);
}
else if ("ArithmeticAverage".Equals(asianOption.PayoffType)
|| "DiscreteArithmeticAverage".Equals(asianOption.PayoffType))
{
return fixingValues.Select(x => x.Value).Average();
}
}
return null;
}
/// <summary>
/// 获取亚式期权 均价起算日之后的均价 未到均价起算日则返回Null
/// </summary>
public static double? GetAsianAveragePrice(trade trade)
{
if (trade.trade_asian_option == null)
{
tradeBLL.SetFieldsByTradeType(trade);
}
if (null != trade.trade_asian_option)
{
var fixings = AsianOptionFixingService.GetFixingString(valuedateBLL.ValueDate, trade);
if (!string.IsNullOrWhiteSpace(fixings))
{
var fixingValues = string.IsNullOrEmpty(fixings)
? new Dictionary<Date, double>() :
fixings.Split(QdpConsts.Semilicon)
.Select(x =>
{
var splits = x.Split(QdpConsts.Comma);
return Tuple.Create(splits[0].ToDate(), double.Parse(splits[1]));
}).ToDictionary(x => x.Item1, x => x.Item2);
if ("GeometricAverage".Equals(trade.trade_asian_option.PayoffType))
{
var n = fixingValues.Count;
return Math.Pow(fixingValues.Select(x => x.Value).Aggregate(func: (result, item) => result * item), 1.0 / n);
}
else if ("ArithmeticAverage".Equals(trade.trade_asian_option.PayoffType) || "DiscreteArithmeticAverage".Equals(trade.trade_asian_option.PayoffType))
{
return fixingValues.Select(x => x.Value).Average();
}
}
}
return null;
}
}
public class AsianOptionStrikeRequest : AsianFixingRequest
{
public AsianOptionStrikeRequest(FixingRequestBase baseReq) : base(baseReq)
{
}
public AsianOptionStrikeRequest(DateTime valueDate, int tradeId, string instrumentType, string underlyingCode, DateTime exerciseDate, SettlementTypeEnum settlementType)
: base(valueDate, tradeId, instrumentType, underlyingCode, exerciseDate, settlementType)
{
}
public bool IsMoneynessOption { get; set; }
public double? Strike { get; set; }
public double? SpotPrice { get; set; }
}
}