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);
}
}
}