Files
zszq-trs/UnitTestProject/Modules/CalcModules/SnowballOptionCalcTest.cs
T
2024-05-09 14:06:26 +08:00

165 lines
6.5 KiB
C#

using Qdp.ComputeService.Data.CommonModels.ValuationParams.Equity;
using Qdp.Pricing.Library.Options.Products.Autocall.Snowball;
using YLErp.BLL.Calculation;
using YLErp.BLL.Calculation.Engine;
using YLErp.Modules.CalculationModule;
using YLErp.Modules.TradeModule;
using YLErp.QdpModule;
namespace YLErp.Modules.CalcModules
{
/// <summary>
/// 雪球期权计算测试
/// </summary>
[TestClass]
public class SnowballOptionCalcTest : UnitTestBase
{
[TestMethod("雪球期权-行权价和执行价近似相等时计算非常慢")]
public void SnowballOptionCalcTest1()
{
var data = DeserializeFormData<OtcOptionTradeFullFormData>("TradeJson\\SnowballTrade1.txt");
Assert.IsTrue(data.trades != null && data.trades.Any());
var tdfull = data.trades.First();
var tdconv = TradeConverter.ConvertOptionTrade(tdfull);
var sw = new System.Diagnostics.Stopwatch();
sw.Start();
//为解决慢的问题,TradeRiskCalcUtil类加了优化处理方法:OptimizeSpotPrice
var result = OptionCalculatorV2.GetOptionValueResult(new DateTime(2021, 5, 12), tdconv, new OptionValueCalcRequest(0.04)
{
spotPrices = new[] { 6512.0501 },
vols = new[] { 0.18 },
pricingRequest = QdpModule.QdpPricingRequest.BASIC_GREEKS
}, out _);
sw.Stop();
Console.WriteLine($"耗时{sw.ElapsedMilliseconds / 1000}秒,pv:{result.Pv}");
Assert.IsTrue(sw.ElapsedMilliseconds < 10 * 1000);
}
[TestMethod("雪球期权计算--海通认为算的不对")]
public void SnowballOptionCalcTest2()
{
var json = ReadResourceFile("TradeJson\\SnowballTrade2.json");
var td = JsonHelper.Deserialize<trade>(json);
Assert.IsNotNull(td);
var result = OptionCalculatorV2.GetOptionValueResult(new DateTime(2021, 5, 28), td, new OptionValueCalcRequest(0)
{
spotPrices = new[] { 13660d },
vols = new[] { 0.254561403508772 }
}, out _);
Assert.IsTrue(Math.Abs(Math.Abs(result.Pv) - 213772.8) < 10);
}
[TestMethod("雪球期权计算--和Excel模板算的不一致")]
public void SnowballOptionCalcTest3()
{
var optionTrade = QdpTradeBuilder.GetSnowballOptionTrade(new SnowballOptionTradeParam
{
annualizedFactor = 1,
annualizedOptionPayoff = true,
annualizedPremiumRate = null,
barrierStatus = "",
buysell = "Buy",
callput = Qdp.Pricing.Base.Enums.OptionType.Put,
coupon = 0.3149,
couponDayCount = "Act365",
couponPaymentDateStr = "2022-04-06,2022-05-05,2022-06-06,2022-07-04",
dividendRate = 0.015,
dividends = null,
endDate = new Qdp.Foundation.Implementations.Date(2022, 7, 4),
exerciseDate = new Qdp.Foundation.Implementations.Date(2022, 7, 4),
exerciseType = null,
hasNightMarket = false,
initialSpotPrice = 100,
isAnnualized = false,
isFixedCoupon = false,
isForwardTrade = false,
isMoneynessOption = false,
kiBarrier = 120,
kiOptionType = Qdp.Pricing.Base.Enums.OptionType.CallSpread,
koBarrier = 100,
koBarrierAdjustStep = 0,
koObservationDateStr = "2022-04-06,2022-05-05,2022-06-06,2022-07-04",
koOptionType = Qdp.Pricing.Base.Enums.OptionType.Coupon,
koRebate = 0.3149,
koStrike = -1,
notional = 1,
observationDateStr = null,
optionType = Qdp.Pricing.Base.Enums.OptionType.Put,
participationRate = 1,
preciseTimeMode = false,
principalRate = 0,
riskFreeRate = 0.015,
settlementDate = new Qdp.Foundation.Implementations.Date(2022, 7, 4),
spreadStrikeAtKO = -1,
spreadStrikeAtMaturity = 100,
startDate = new Qdp.Foundation.Implementations.Date(2022, 3, 4),
strike = 120,
timeToMaturityDays = double.NaN,
tradeDate = new Qdp.Foundation.Implementations.Date(2022, 3, 4),
tradeId = "111111",
underlyingInstrumentType = "Stock",
underlyingTickers = new[] { "000001.sz" },
useOptionPayoffAtKO = false,
useOptionPayoffAtMaturity = true,
volSurfaceNames = new[] { "2222" }
}, SnowBallOptionMode.SimpleSnowball);
var option = optionTrade.Instrument as SimpleSnowball;
var factory = OptionEngineFactory.GetEngineFactory("SnowBall");
var engine = factory.GetEngine(null, option.Exercise);
var tenors = new string[]
{
"1D",
"2M",
"1Y"
};
var strikes = new double[]
{
0.95,
1.0,
1.05,
};
var vols = new double[3, 3];
var singleVols = new List<SingleVol>();
for (var i = 0; i < vols.GetLength(0); ++i)
{
for (var j = 0; j < vols.GetLength(1); ++j)
{
vols[i, j] = 0.2;
singleVols.Add(new SingleVol()
{
Strike = strikes[j],
Expire = tenors[i],
Vol = 0.44
});
}
}
using var mp = new MarketProxy(new DateTime(2022, 3, 4), 0.015);
mp.SetVolSurface("2222", new VolatilityImpl { VolTable = singleVols });
mp.SetStockPrice("000001.sz", 100);
var _dividendCurveName = Guid.NewGuid().ToString();
var dividendCurve = CalculatorHelper.CreateConstantRiskFreeCurve(_dividendCurveName, 0.015);
mp.SetYieldCurve(_dividendCurveName, dividendCurve);
var pps = new OptionValuationParameters(_dividendCurveName,
_dividendCurveName, "2222", "000001.sz");
var results = optionTrade.CalculateRisks(mp.QdpMarket, Qdp.Pricing.Base.Implementations.PricingRequest.Pv
, engine, pps);
Assert.IsTrue(Math.Abs(results.Pv) > 1);
}
}
}