using Qdp.Pricing.Base.Implementations; using YLErp.BLL.Calculation.V2; using YLErp.BLL.Calculation.V2.Parameter; using YLErp.QdpModule; namespace YLErp.Modules.CalcModules { /// /// 中银国际的POC测试,TradeDayCount和CurveDayCount请使用Act365测试 /// [TestClass] public class BocInternationalTest { private readonly DateTime ValueDate = new(2019, 11, 26); private readonly DateTime MaturityDate = new(2019, 12, 26); private readonly string UnderlyingTicker = "000300"; private readonly underlying_manager Underlying = new() { QuotationDate = new DateTime(2019, 11, 26), UnderlyingCode = "000300", UnderlyingInstrumentType = "Stock" }; private readonly string userId = Guid.NewGuid().ToString(); private const double SPOT = 3899.0; private const double VOL = 0.2; private const double RISKFREE_RATE = 0.05; private const double DIVIDEND_RATE = 0.01; private const double NOTIONAL = 1000000.0 / 3899.0; [TestMethod] public void EuropeanVanillaTest() { PS.ResetConfig("{\"SkewMapVolConstruction\":\"false\"}"); var call = new trade() { TradeType = "香草期权", TradeDate = ValueDate, MaturityDate = MaturityDate, ExerciseDate = MaturityDate, OptionType = "看涨", ExerciseMode = "European", BuySell = "Buy", UnderlyingInstrumentType = "Stock", Strike = 1.03, Notional = NOTIONAL, IsMoneynessOption = "是", SpotPrice = SPOT, }; var put = new trade() { TradeType = "香草期权", TradeDate = ValueDate, MaturityDate = MaturityDate, ExerciseDate = MaturityDate, OptionType = "看跌", ExerciseMode = "European", BuySell = "Buy", UnderlyingInstrumentType = "Stock", Strike = 0.97, Notional = NOTIONAL, IsMoneynessOption = "是", SpotPrice = SPOT, }; var parameter = new VanillaOptionParameter() { ValueDate = ValueDate, Volatility = VOL, SpotPrices = new Dictionary() { { UnderlyingTicker, SPOT } }, RiskFreeRate = RISKFREE_RATE, DividendRate = DIVIDEND_RATE }; var callResult = ValueCalculator.CalculateTradeValue( userId, call, Underlying, parameter, PricingRequest.Pv); Assert.AreEqual(12246.342761701024, callResult.Pv, 1e-8); var putResult = ValueCalculator.CalculateTradeValue( userId, put, Underlying, parameter, PricingRequest.Pv); Assert.AreEqual(9677.6310645714639, putResult.Pv, 1e-8); } [TestMethod] public void VanillaStrategyTest() { PS.ResetConfig("{\"SkewMapVolConstruction\":\"false\"}"); // 牛市价差 var leg1 = new trade() { TradeType = "香草期权", TradeDate = ValueDate, MaturityDate = MaturityDate, ExerciseDate = MaturityDate, OptionType = "看涨", ExerciseMode = "European", BuySell = "Buy", UnderlyingInstrumentType = "Stock", Strike = 0.98, Notional = NOTIONAL, IsMoneynessOption = "是", SpotPrice = SPOT, }; var leg2 = new trade() { TradeType = "香草期权", TradeDate = ValueDate, MaturityDate = MaturityDate, ExerciseDate = MaturityDate, OptionType = "看涨", ExerciseMode = "European", BuySell = "Buy", UnderlyingInstrumentType = "Stock", Strike = 1.03, Notional = NOTIONAL, IsMoneynessOption = "是", SpotPrice = SPOT, }; var parameter = new VanillaOptionParameter() { ValueDate = ValueDate, Volatility = VOL, SpotPrices = new Dictionary() { { UnderlyingTicker, SPOT } }, RiskFreeRate = RISKFREE_RATE, DividendRate = DIVIDEND_RATE }; var result1 = ValueCalculator.CalculateTradeValue(userId, leg1, Underlying, parameter, PricingRequest.Pv); var result2 = ValueCalculator.CalculateTradeValue(userId, leg2, Underlying, parameter, PricingRequest.Pv); Assert.AreEqual(23808.69577353201, result1.Pv - result2.Pv, 1e-8); // 熊市价差 leg1 = new trade() { TradeType = "香草期权", TradeDate = ValueDate, MaturityDate = MaturityDate, ExerciseDate = MaturityDate, OptionType = "看跌", ExerciseMode = "European", BuySell = "Buy", UnderlyingInstrumentType = "Stock", Strike = 0.98, Notional = NOTIONAL, IsMoneynessOption = "是", SpotPrice = SPOT, }; leg2 = new trade() { TradeType = "香草期权", TradeDate = ValueDate, MaturityDate = MaturityDate, ExerciseDate = MaturityDate, OptionType = "看跌", ExerciseMode = "European", BuySell = "Buy", UnderlyingInstrumentType = "Stock", Strike = 1.03, Notional = NOTIONAL, IsMoneynessOption = "是", SpotPrice = SPOT, }; result1 = ValueCalculator.CalculateTradeValue(userId, leg1, Underlying, parameter, PricingRequest.Pv); result2 = ValueCalculator.CalculateTradeValue(userId, leg2, Underlying, parameter, PricingRequest.Pv); Assert.AreEqual(25986.246414678219, result2.Pv - result1.Pv, 1e-8); } [TestMethod] public void EuropeanBinaryTest() { PS.ResetConfig("{\"SkewMapVolConstruction\":\"false\"}"); var call = new trade() { TradeType = "二元期权", TradeDate = ValueDate, MaturityDate = MaturityDate, ExerciseDate = MaturityDate, OptionType = "看涨", ExerciseMode = "European", BuySell = "Buy", UnderlyingInstrumentType = "Stock", Strike = 1.03, Notional = NOTIONAL, IsMoneynessOption = "是", SpotPrice = SPOT, trade_binary_option = new trade_binary_option() { PayoffType = "CashOrNothing", CashOrNothingAmount = SPOT * 0.05, RebateType = "AtHit" } }; var put = new trade() { TradeType = "二元期权", TradeDate = ValueDate, MaturityDate = MaturityDate, ExerciseDate = MaturityDate, OptionType = "看跌", ExerciseMode = "European", BuySell = "Buy", UnderlyingInstrumentType = "Stock", Strike = 0.97, Notional = NOTIONAL, IsMoneynessOption = "是", SpotPrice = SPOT, trade_binary_option = new trade_binary_option() { PayoffType = "CashOrNothing", CashOrNothingAmount = SPOT * 0.05, RebateType = "AtHit" } }; var parameter = new BinaryOptionParameter() { ValueDate = ValueDate, Volatility = VOL, SpotPrices = new Dictionary() { { UnderlyingTicker, SPOT } }, RiskFreeRate = RISKFREE_RATE, DividendRate = DIVIDEND_RATE }; var callResult = ValueCalculator.CalculateTradeValue(userId, call, Underlying, parameter, PricingRequest.Pv); var putResult = ValueCalculator.CalculateTradeValue(userId, put, Underlying, parameter, PricingRequest.Pv); Assert.AreEqual(15594.939923929795, callResult.Pv, 1e-8); Assert.AreEqual(14329.866102278227, putResult.Pv, 1e-8); } [TestMethod] public void AmericanVanillaTest() { PS.ResetConfig("{\"SkewMapVolConstruction\":\"false\"}"); var call = new trade() { TradeType = "香草期权", TradeDate = ValueDate, MaturityDate = MaturityDate, ExerciseDate = MaturityDate, OptionType = "看涨", ExerciseMode = "American", BuySell = "Buy", UnderlyingInstrumentType = "Stock", Strike = 1.03, Notional = NOTIONAL, IsMoneynessOption = "是", SpotPrice = SPOT, }; var put = new trade() { TradeType = "香草期权", TradeDate = ValueDate, MaturityDate = MaturityDate, ExerciseDate = MaturityDate, OptionType = "看跌", ExerciseMode = "American", BuySell = "Buy", UnderlyingInstrumentType = "Stock", Strike = 0.97, Notional = NOTIONAL, IsMoneynessOption = "是", SpotPrice = SPOT, }; var parameter = new VanillaOptionParameter() { ValueDate = ValueDate, Volatility = VOL, SpotPrices = new Dictionary() { { UnderlyingTicker, SPOT } }, RiskFreeRate = RISKFREE_RATE, DividendRate = DIVIDEND_RATE }; var callResult = ValueCalculator.CalculateTradeValue(userId, call, Underlying, parameter, PricingRequest.Pv); var putResult = ValueCalculator.CalculateTradeValue(userId, put, Underlying, parameter, PricingRequest.Pv); Assert.AreEqual(12282.946028031403, callResult.Pv, 1e-8); Assert.AreEqual(9763.3711407456285, putResult.Pv, 1e-8); } [TestMethod] public void AsianTest() { PS.ResetConfig("{\"SkewMapVolConstruction\":\"false\"}"); var call = new trade() { TradeType = "亚式期权", TradeDate = ValueDate, MaturityDate = MaturityDate, ExerciseDate = MaturityDate, OptionType = "看涨", ExerciseMode = "European", BuySell = "Buy", UnderlyingInstrumentType = "Stock", Strike = 1.03, Notional = NOTIONAL, IsMoneynessOption = "是", SpotPrice = SPOT, trade_asian_option = new trade_asian_option() { StrikeType = "Fixed", PayoffType = "ArithmeticAverage", AveragingPeriodStartDate = ValueDate } }; var put = new trade() { TradeType = "亚式期权", TradeDate = ValueDate, MaturityDate = MaturityDate, ExerciseDate = MaturityDate, OptionType = "看跌", ExerciseMode = "European", BuySell = "Buy", UnderlyingInstrumentType = "Stock", Strike = 0.97, Notional = NOTIONAL, IsMoneynessOption = "是", SpotPrice = SPOT, trade_asian_option = new trade_asian_option() { StrikeType = "Fixed", PayoffType = "ArithmeticAverage", AveragingPeriodStartDate = ValueDate } }; var parameter = new AsianOptionParameter() { ValueDate = ValueDate, Volatility = VOL, SpotPrices = new Dictionary() { { UnderlyingTicker, SPOT } }, RiskFreeRate = RISKFREE_RATE, DividendRate = DIVIDEND_RATE, Fixings = null }; var callResult = ValueCalculator.CalculateTradeValue(userId, call, Underlying, parameter, PricingRequest.Pv); var putResult = ValueCalculator.CalculateTradeValue(userId, put, Underlying, parameter, PricingRequest.Pv); Assert.AreEqual(3427.8986213282096, callResult.Pv, 1e-8); Assert.AreEqual(2618.116861274927, putResult.Pv, 1e-3); } [TestMethod] public void RangeAccrualTest() { PS.ResetConfig("{\"SkewMapVolConstruction\":\"false\"}"); var option = new trade() { TradeType = "区间累积期权", TradeDate = ValueDate, MaturityDate = MaturityDate, ExerciseDate = MaturityDate, OptionType = "看涨", ExerciseMode = "European", BuySell = "Buy", UnderlyingInstrumentType = "Stock", Notional = NOTIONAL, IsMoneynessOption = "是", SpotPrice = SPOT, trade_rangeaccrual = new trade_rangeaccrual() { LowerRange = 0.975, UpperRange = 1.025, BonusRate = 0.06 } }; var parameter = new RangeAccrualParameter() { ValueDate = ValueDate, Volatility = VOL, SpotPrices = new Dictionary() { { UnderlyingTicker, SPOT } }, RiskFreeRate = RISKFREE_RATE, DividendRate = DIVIDEND_RATE, Fixings = null }; var result = ValueCalculator.CalculateTradeValue(userId, option, Underlying, parameter, PricingRequest.Pv); Assert.AreEqual(29620.042479889609, result.Pv, 1e-8); } [TestMethod] public void AmericanBinaryTest() { PS.ResetConfig("{\"SkewMapVolConstruction\":\"false\"}"); var option1 = new trade() { TradeType = "二元期权", TradeDate = ValueDate, MaturityDate = MaturityDate, ExerciseDate = MaturityDate, OptionType = "看涨", ExerciseMode = "American", BuySell = "Buy", UnderlyingInstrumentType = "Stock", Strike = 1.03, Notional = NOTIONAL, IsMoneynessOption = "是", SpotPrice = SPOT, trade_binary_option = new trade_binary_option() { PayoffType = "UpOneTouch", CashOrNothingAmount = SPOT * 0.05, RebateType = "AtHit" } }; var option2 = new trade() { TradeType = "二元期权", TradeDate = ValueDate, MaturityDate = MaturityDate, ExerciseDate = MaturityDate, OptionType = "看涨", ExerciseMode = "American", BuySell = "Buy", UnderlyingInstrumentType = "Stock", Strike = 1.03, Notional = NOTIONAL, IsMoneynessOption = "是", SpotPrice = SPOT, trade_binary_option = new trade_binary_option() { PayoffType = "UpOneTouch", CashOrNothingAmount = SPOT * 0.05, RebateType = "AtEnd" } }; var option3 = new trade() { TradeType = "二元期权", TradeDate = ValueDate, MaturityDate = MaturityDate, ExerciseDate = MaturityDate, OptionType = "看跌", ExerciseMode = "American", BuySell = "Buy", UnderlyingInstrumentType = "Stock", Strike = 0.97, Notional = NOTIONAL, IsMoneynessOption = "是", SpotPrice = SPOT, trade_binary_option = new trade_binary_option() { PayoffType = "DownOneTouch", CashOrNothingAmount = SPOT * 0.05, RebateType = "AtHit" } }; var option4 = new trade() { TradeType = "二元期权", TradeDate = ValueDate, MaturityDate = MaturityDate, ExerciseDate = MaturityDate, OptionType = "看跌", ExerciseMode = "American", BuySell = "Buy", UnderlyingInstrumentType = "Stock", Strike = 0.97, Notional = NOTIONAL, IsMoneynessOption = "是", SpotPrice = SPOT, trade_binary_option = new trade_binary_option() { PayoffType = "DownOneTouch", CashOrNothingAmount = SPOT * 0.05, RebateType = "AtEnd" } }; var parameter = new BinaryOptionParameter() { ValueDate = ValueDate, Volatility = VOL, SpotPrices = new Dictionary() { { UnderlyingTicker, SPOT } }, RiskFreeRate = RISKFREE_RATE, DividendRate = DIVIDEND_RATE }; var result1 = ValueCalculator.CalculateTradeValue(userId, option1, Underlying, parameter, PricingRequest.Pv); var result2 = ValueCalculator.CalculateTradeValue(userId, option2, Underlying, parameter, PricingRequest.Pv); var result3 = ValueCalculator.CalculateTradeValue(userId, option3, Underlying, parameter, PricingRequest.Pv); var result4 = ValueCalculator.CalculateTradeValue(userId, option4, Underlying, parameter, PricingRequest.Pv); Assert.AreEqual(30715.28279692346, result1.Pv, 1e-10); Assert.AreEqual(30630.600069456796, result2.Pv, 1e-10); Assert.AreEqual(29268.976807251885, result3.Pv, 1e-10); Assert.AreEqual(29189.216364369575, result4.Pv, 1e-10); } [TestMethod] public void AmericanBinaryDoubleTouchTest() { PS.ResetConfig("{\"SkewMapVolConstruction\":\"false\"}"); var option1 = new trade() { TradeType = "二元期权", TradeDate = ValueDate, MaturityDate = MaturityDate, ExerciseDate = MaturityDate, OptionType = "看涨", ExerciseMode = "American", BuySell = "Buy", UnderlyingInstrumentType = "Stock", Strike = 0.9, Notional = NOTIONAL, IsMoneynessOption = "是", SpotPrice = SPOT, trade_binary_option = new trade_binary_option() { PayoffType = "DoubleOneTouch", UpperBarrier = 1.1, CashOrNothingAmount = SPOT * 0.1, RebateType = "AtHit" } }; var option2 = new trade() { TradeType = "二元期权", TradeDate = ValueDate, MaturityDate = MaturityDate, ExerciseDate = MaturityDate, OptionType = "看涨", ExerciseMode = "American", BuySell = "Buy", UnderlyingInstrumentType = "Stock", Strike = 0.9, Notional = NOTIONAL, IsMoneynessOption = "是", SpotPrice = SPOT, trade_binary_option = new trade_binary_option() { PayoffType = "DoubleNoTouch", UpperBarrier = 1.1, CashOrNothingAmount = SPOT * 0.1, RebateType = "AtEnd" } }; var parameter = new BinaryOptionParameter() { ValueDate = ValueDate, Volatility = VOL, SpotPrices = new Dictionary() { { UnderlyingTicker, SPOT } }, RiskFreeRate = RISKFREE_RATE, DividendRate = DIVIDEND_RATE }; var result1 = ValueCalculator.CalculateTradeValue(userId, option1, Underlying, parameter, PricingRequest.Pv); var result2 = ValueCalculator.CalculateTradeValue(userId, option2, Underlying, parameter, PricingRequest.Pv); Assert.AreEqual(16339.046613388811, result1.Pv, 1e-10); Assert.AreEqual(83270.814664408739, result2.Pv, 1e-10); } [TestMethod] public void BarrierTest() { PS.ResetConfig("{\"SkewMapVolConstruction\":\"false\"}"); var option1 = new trade() { TradeType = "障碍期权", TradeDate = ValueDate, MaturityDate = MaturityDate, ExerciseDate = MaturityDate, OptionType = "看涨", ExerciseMode = "European", BuySell = "Buy", UnderlyingInstrumentType = "Stock", Strike = 1.05, Notional = NOTIONAL, IsMoneynessOption = "是", SpotPrice = SPOT, trade_barrier_option = new trade_barrier_option() { BarrierType = "UpAndOut", BarrierPrice = 1.1, Discrete = "离散", Rebate = SPOT * 0.05, RebateType = "AtHit" } }; var option2 = new trade() { TradeType = "障碍期权", TradeDate = ValueDate, MaturityDate = MaturityDate, ExerciseDate = MaturityDate, OptionType = "看涨", ExerciseMode = "European", BuySell = "Buy", UnderlyingInstrumentType = "Stock", Strike = 1.05, Notional = NOTIONAL, IsMoneynessOption = "是", SpotPrice = SPOT, trade_barrier_option = new trade_barrier_option() { BarrierType = "UpAndOut", BarrierPrice = 1.1, Discrete = "离散", Rebate = SPOT * 0.05, RebateType = "AtEnd" } }; var option3 = new trade() { TradeType = "障碍期权", TradeDate = ValueDate, MaturityDate = MaturityDate, ExerciseDate = MaturityDate, OptionType = "看跌", ExerciseMode = "European", BuySell = "Buy", UnderlyingInstrumentType = "Stock", Strike = 0.95, Notional = NOTIONAL, IsMoneynessOption = "是", SpotPrice = SPOT, trade_barrier_option = new trade_barrier_option() { BarrierType = "DownAndOut", BarrierPrice = 0.9, Discrete = "离散", Rebate = SPOT * 0.05, RebateType = "AtHit" } }; var option4 = new trade() { TradeType = "障碍期权", TradeDate = ValueDate, MaturityDate = MaturityDate, ExerciseDate = MaturityDate, OptionType = "看跌", ExerciseMode = "European", BuySell = "Buy", UnderlyingInstrumentType = "Stock", Strike = 0.95, Notional = NOTIONAL, IsMoneynessOption = "是", SpotPrice = SPOT, trade_barrier_option = new trade_barrier_option() { BarrierType = "DownAndOut", BarrierPrice = 0.9, Discrete = "离散", Rebate = SPOT * 0.05, RebateType = "AtEnd" } }; var parameter = new BarrierOptionParameter() { ValueDate = ValueDate, Volatility = VOL, SpotPrices = new Dictionary() { { UnderlyingTicker, SPOT } }, RiskFreeRate = RISKFREE_RATE, DividendRate = DIVIDEND_RATE }; var result1 = ValueCalculator.CalculateTradeValue(userId, option1, Underlying, parameter, PricingRequest.Pv); var result2 = ValueCalculator.CalculateTradeValue(userId, option2, Underlying, parameter, PricingRequest.Pv); var result3 = ValueCalculator.CalculateTradeValue(userId, option3, Underlying, parameter, PricingRequest.Pv); var result4 = ValueCalculator.CalculateTradeValue(userId, option4, Underlying, parameter, PricingRequest.Pv); Assert.AreEqual(6434.9341859467013, result1.Pv, 1e-10); Assert.AreEqual(6430.1233648704419, result2.Pv, 1e-10); Assert.AreEqual(4836.0864487604222, result3.Pv, 1e-10); Assert.AreEqual(4833.45426819408, result4.Pv, 1e-10); } [TestMethod] public void DoubleSharkFinTest() { PS.ResetConfig("{\"SkewMapVolConstruction\":\"false\"}"); var option1 = new trade() { TradeType = "双鲨期权", TradeDate = ValueDate, MaturityDate = MaturityDate, ExerciseDate = MaturityDate, OptionType = "看涨", ExerciseMode = "European", BuySell = "Buy", UnderlyingInstrumentType = "Stock", Strike = 0.95, Notional = NOTIONAL, IsMoneynessOption = "是", SpotPrice = SPOT, trade_double_sharkfin_option = new trade_double_sharkfin_option() { StrikeHigh = 1.05, StrikeLow = 0.95, BarrierHigh = 1.1, BarrierLow = 0.9, Rebate = SPOT * 0.04, RebateHigh = SPOT * 0.06, RebateType = "AtHit" } }; var option2 = new trade() { TradeType = "双鲨期权", TradeDate = ValueDate, MaturityDate = MaturityDate, ExerciseDate = MaturityDate, OptionType = "看涨", ExerciseMode = "European", BuySell = "Buy", UnderlyingInstrumentType = "Stock", Strike = 0.95, Notional = NOTIONAL, IsMoneynessOption = "是", SpotPrice = SPOT, trade_double_sharkfin_option = new trade_double_sharkfin_option() { StrikeHigh = 1.05, StrikeLow = 0.95, BarrierHigh = 1.1, BarrierLow = 0.9, Rebate = SPOT * 0.04, RebateHigh = SPOT * 0.06, RebateType = "AtEnd" } }; var parameter = new DoubleSharkFinOptionParameter() { ValueDate = ValueDate, Volatility = VOL, SpotPrices = new Dictionary() { { UnderlyingTicker, SPOT } }, RiskFreeRate = RISKFREE_RATE, DividendRate = DIVIDEND_RATE }; var result1 = ValueCalculator.CalculateTradeValue(userId, option1, Underlying, parameter, PricingRequest.Pv); var result2 = ValueCalculator.CalculateTradeValue(userId, option2, Underlying, parameter, PricingRequest.Pv); Assert.AreEqual(12366.591429397329, result1.Pv, 1e-8); Assert.AreEqual(12356.036818992074, result2.Pv, 1e-8); } [TestMethod] public void SnowballTest() { PS.ResetConfig("{\"SkewMapVolConstruction\":\"false\"}"); var maturityDate = new DateTime(2020, 2, 24); var option1 = new trade() { TradeType = "雪球期权", TradeDate = ValueDate, MaturityDate = maturityDate, ExerciseDate = maturityDate, OptionType = "看涨", ExerciseMode = "European", BuySell = "Buy", UnderlyingInstrumentType = "Stock", Strike = 1.0, Notional = NOTIONAL, IsMoneynessOption = "是", SpotPrice = SPOT, ParticipationRate = 1, trade_snowball = new trade_snowball() { KOBarrier = 1.03, KIBarrier = 1.0, Coupon = 0.0, KORebate = 0.1, //KOBarrierAdjustStep = 0.0, //UseOptionPayoffAtMaturity = false, KOObservationDates = QdpObservationHelper.GetObservationDateString(ValueDate, maturityDate, "1W") } }; var option2 = new trade() { TradeType = "雪球期权", TradeDate = ValueDate, MaturityDate = maturityDate, ExerciseDate = maturityDate, OptionType = "看涨", ExerciseMode = "European", BuySell = "Buy", UnderlyingInstrumentType = "Stock", Strike = 1.0, Notional = NOTIONAL, IsMoneynessOption = "是", SpotPrice = SPOT, ParticipationRate = 1.0, trade_snowball = new trade_snowball() { KOBarrier = 1.03, KIBarrier = 1.0, Coupon = 0.0, KORebate = 0.1, //KOBarrierAdjustStep = -0.01, //UseOptionPayoffAtMaturity = false, KOObservationDates = QdpObservationHelper.GetObservationDateString(ValueDate, maturityDate, "1W") } }; var option3 = new trade() { TradeType = "雪球期权", TradeDate = ValueDate, MaturityDate = maturityDate, ExerciseDate = maturityDate, OptionType = "看涨", ExerciseMode = "European", BuySell = "Buy", UnderlyingInstrumentType = "Stock", Strike = 0.98, Notional = NOTIONAL, IsMoneynessOption = "是", SpotPrice = SPOT, ParticipationRate = 1.0, trade_snowball = new trade_snowball() { KOBarrier = 1.03, KIBarrier = 1.0, Coupon = 0.0, KORebate = 0.1, //KOBarrierAdjustStep = 0.0, //UseOptionPayoffAtMaturity = true, KOObservationDates = QdpObservationHelper.GetObservationDateString(ValueDate, maturityDate, "1W") } }; var parameter = new SnowballParameter() { ValueDate = ValueDate, Volatility = VOL, SpotPrices = new Dictionary() { { UnderlyingTicker, SPOT } }, RiskFreeRate = RISKFREE_RATE, DividendRate = DIVIDEND_RATE }; var result1 = ValueCalculator.CalculateTradeValue(userId, option1, Underlying, parameter, PricingRequest.Pv); var result2 = ValueCalculator.CalculateTradeValue(userId, option2, Underlying, parameter, PricingRequest.Pv); var result3 = ValueCalculator.CalculateTradeValue(userId, option3, Underlying, parameter, PricingRequest.Pv); Assert.AreEqual(256.05315398303719, result1.Pv, 1.0); Assert.AreEqual(257.09573597682572, result2.Pv, 1.0); Assert.AreEqual(256.11164110697115, result3.Pv, 1.0); } [TestMethod] public void PhoenixAutocallTest() { PS.ResetConfig("{\"SkewMapVolConstruction\":\"false\"}"); var maturityDate = new DateTime(2020, 2, 24); var option1 = new trade() { TradeType = "凤凰期权", TradeDate = ValueDate, MaturityDate = maturityDate, ExerciseDate = maturityDate, OptionType = "看跌", ExerciseMode = "European", BuySell = "Buy", UnderlyingInstrumentType = "Stock", Strike = 1.0, Notional = NOTIONAL, IsMoneynessOption = "是", SpotPrice = SPOT, ParticipationRate = 1, trade_autocall = new trade_autocall() { KOBarrier = 1.03, KIBarrier = 0.8, CouponBarrier = 0.8, Coupon = 0.05, CouponPayType = CouponPayTypeEnum.AtCreated, IncludeCouponAfterKI = false, KOObservationDates = QdpObservationHelper.GetObservationDateString(ValueDate, maturityDate, "1M") } }; var option2 = new trade() { TradeType = "凤凰期权", TradeDate = ValueDate, MaturityDate = maturityDate, ExerciseDate = maturityDate, OptionType = "看跌", ExerciseMode = "European", BuySell = "Buy", UnderlyingInstrumentType = "Stock", Strike = 1.0, Notional = NOTIONAL, IsMoneynessOption = "是", SpotPrice = SPOT, ParticipationRate = 1, trade_autocall = new trade_autocall() { KOBarrier = 1.03, KIBarrier = 0.8, CouponBarrier = 1.03, Coupon = 0.05, CouponPayType = CouponPayTypeEnum.AtCreated, IncludeCouponAfterKI = false, KOObservationDates = QdpObservationHelper.GetObservationDateString(ValueDate, maturityDate, "1M") } }; //ki to put spread var option4 = new trade() { TradeType = "凤凰期权", TradeDate = ValueDate, MaturityDate = maturityDate, ExerciseDate = maturityDate, OptionType = "看跌", ExerciseMode = "European", BuySell = "Buy", UnderlyingInstrumentType = "Stock", Strike = 1.0, Notional = NOTIONAL, IsMoneynessOption = "是", SpotPrice = SPOT, ParticipationRate = 1, trade_autocall = new trade_autocall() { KOBarrier = 1.03, KIBarrier = 0.8, CouponBarrier = 0.8, Coupon = 0.05, CouponPayType = CouponPayTypeEnum.AtCreated, IncludeCouponAfterKI = false, SpreadStrike = 0.8, KOObservationDates = QdpObservationHelper.GetObservationDateString(ValueDate, maturityDate, "1M") } }; var parameter = new AutocallParameter() { ValueDate = ValueDate, Volatility = VOL, SpotPrices = new Dictionary() { { UnderlyingTicker, SPOT } }, RiskFreeRate = RISKFREE_RATE, DividendRate = DIVIDEND_RATE }; var result1 = ValueCalculator.CalculateTradeValue(userId, option1, Underlying, parameter, PricingRequest.Pv); //var result2 = ValueCalculator.CalculateTradeValue(userId, option2, Underlying, parameter, PricingRequest.Pv); var result4 = ValueCalculator.CalculateTradeValue(userId, option4, Underlying, parameter, PricingRequest.Pv); Assert.AreEqual(3250, result1.Pv, 10); //Assert.AreEqual(2328.39, result2.Pv, 10); Assert.AreEqual(3519, result4.Pv, 10); } } }