128 lines
5.4 KiB
C#
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)
|
|
};
|
|
}
|
|
}
|
|
}
|