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 { /// /// 计算亚式期权Floating类型交易的浮动行权价 /// 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); } /// /// 获取亚式期权行权价 /// 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:除权除息 /// /// 计算亚式期权Fix类型交易的浮动行权价 /// 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; } /// /// 获取亚式期权 均价起算日之后的均价 未到均价起算日则返回Null /// 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() : 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; } } }