Files
zszq-trs/YLErpDAL/Modules/ApiModule/PricingModule/OptionPricingApiService.cs
T
2024-05-09 14:06:26 +08:00

128 lines
5.4 KiB
C#

using Qdp.Foundation.Implementations;
using Qdp.Pricing.Base.Enums;
using Qdp.Pricing.Base.Implementations;
using Qdp.Pricing.Base.Utilities;
using Qdp.Pricing.Library.Base.Curves.Interfaces;
using Qdp.Pricing.Library.Common.Interfaces;
using Qdp.Pricing.Library.Common.Market;
using Qdp.Pricing.Library.Options.MonteCarlo;
using Qdp.Pricing.Library.Options.Products.Asian;
using YLErp.BLL.Calculation;
using YLErp.Enums;
using YLErp.Modules.ApiModule.PricingModule.CustomizedAsianPricing;
using YLErp.Modules.CalculationModule;
using YLErp.Modules.PricingModule;
using YLErp.QdpModule;
namespace YLErp.Modules.ApiModule.PricingModule
{
/// <summary>
/// 期权定价api服务
/// </summary>
public partial class OptionPricingApiService
{
/// <summary>
/// 获取期权定价结果
/// </summary>
public CalcOptionPriceResult GetOptionPrice(OptionPricingModelV2 req)
{
if (req.ExtendFields != null && req.ExtendFields.Count > 0)
{
var dic = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
foreach (var kv in req.ExtendFields)
{
dic[kv.Key] = req.ExtendFields[kv.Key];
}
req.ExtendFields = dic;
}
OptionPricingApiHelper.CheckPricingRequestData(req);
string fixings = null;
if (req.ExtendFields != null)
{
req.ExtendFields.TryGetValue("fixings", out fixings);
}
var result = new PriceCalcService(OptUserInfo.SystemUser).CalcOptionPrice(req, req.IsCalcMargin
, CalcScenarioEnum.Pricing, req.IsCalcGreeks, fixings: fixings);
return result;
}
public CalcOptionPriceResult GetCustomizedAsianOptionPrice(CustomizedAsianPricingModel req)
{
var startDate = new Date(req.StartDate.Value);
var maturityDate = new Date(req.ExerciseDate.Value);
var callPut = req.CallPut.ToUpper() == "PUT" ? OptionType.Put : OptionType.Call;
var lockObsStartDate = new Date(req.LockObsStartDate);
var lockObsEndDate = new Date(req.LockObsEndDate);
var lockStartDate = new Date(req.LockStartDate);
var calendar = CalendarImpl.Get("chn");
var dayCount = CalculatorHelper.GetTradeDayCount().ToDayCountImpl();
var option = new EnhancedAsianOptionWithLockAndBarrier(
startDate,
maturityDate,
OptionExercise.European,
callPut,
strike: req.Strike.Value,
lockPrice: req.LockPrice,
barrierPrice: req.BarrierPrice.HasValue ? req.BarrierPrice.Value : double.NaN, // 13659.26,
isLocked: req.IsLocked,
lockObsStartDate: lockObsStartDate,
lockObsEndDate: lockObsEndDate,
lockStartDate: lockStartDate,
underlyingInstrumentType: InstrumentType.CommodityFutures,
calendar: calendar,
dayCount: dayCount,
payoffCcy: CurrencyCode.CNY,
settlementCcy: CurrencyCode.CNY,
exerciseDates: new Date[] { maturityDate },
observationDates: calendar.BizDaysBetweenDatesExcluStartDay(lockObsEndDate, maturityDate).ToArray(),
fixings: QdpHelper.ParseFixingsFromString(req.Fixings),
avgPriceRate: req.AvgPriceRate.HasValue ? req.AvgPriceRate.Value : 1.0,
finalPriceSpread: req.FinalPriceSpread.HasValue ? req.FinalPriceSpread.Value : 0.0,
notional: req.Notional);
var mcEngine = new GbmMonteCarloEngine(5000, 1e-3, 1e-6, 1, true);
var vol = req.Vol.Value;
var spot = req.SpotPrice.Value;
var r = req.RiskFreeRate.Value;
var q = req.DividendRate.Value;
var valueDate = new Date(req.ValueDate.Value);
//var market = TestHelper.CreateMarket(valueDate, vol: vol, spot: spot, riskFreeRate: r, dividendRate: q);
var marketProxy = new MarketProxy(valueDate, r);
marketProxy.SetVolSurface("volsurf", vol);
var volsurf = marketProxy.QdpMarket.VolSurfaces["volsurf"];
var dividendCurveName = Guid.NewGuid().ToString();
var dividendCurve = CalculatorHelper.CreateConstantRiskFreeCurve(dividendCurveName, q);
marketProxy.SetYieldCurve(dividendCurveName, dividendCurve);
var market = new MarketCondition(
x => x.ValuationDate.Value = marketProxy.QdpMarket.ReferenceDate,
x => x.DiscountCurve.Value = marketProxy.QdpMarket.YieldCurves[MarketProxy.RiskFreeDiscountCurve],
x => x.DividendCurves.Value = new Dictionary<string, IYieldCurve> { { "", marketProxy.QdpMarket.YieldCurves[dividendCurveName] } },
x => x.VolSurfaces.Value = new Dictionary<string, IVolSurface> { { "", volsurf } },
x => x.SpotPrices.Value = new Dictionary<string, double> { { "", spot } }
);
var result = mcEngine.Calculate(option, market, QdpPricingRequest.BASIC_GREEKS);
return new CalcOptionPriceResult()
{
CalcId = req.CalcId,
calcResult = new TradeValueResult(result)
};
}
}
}