def test_bermudan_option(self): asof_date = '5/8/2015' data = [{ 'MaturityDate': '1/15/2016', 'ObjectId': 'BermudanOption', 'OptionType': 'Call', 'Strike': 130, 'PricingEngine': "->BermudanEngine", "ListOfDate": ['11/15/2015', '12/15/2015', '1/15/2016'], 'Template': 'Instrument.Derivative.BermudanOption' }, { 'AsOfDate': asof_date, 'Basis': 'ACTUAL/365Fixed', 'Calendar': 'UnitedStates', 'DiscountRate': 0.001, 'DividendRate': 0.0163, 'ObjectId': 'BSMProcess', 'Spot': 127.62, 'Template': 'Process.Equity.BlackScholesMerton', 'Volatility': 0.20 }, { 'GeneralBlackScholesProcess': '->BSMProcess', 'ObjectId': 'BermudanEngine', 'Template': 'Engine.Equity.FdBermudan' }] controller = Controller(data) controller.process(asof_date) option = controller.object("BermudanOption") npv = option.NPV() self.assertAlmostEqual(npv, 6.808761233089867)
def test_bermudan_option(self): asof_date = '5/8/2015' data = [ {'MaturityDate': '1/15/2016', 'ObjectId': 'BermudanOption', 'OptionType': 'Call', 'Strike': 130, 'PricingEngine': "->BermudanEngine", "ListOfDate": ['11/15/2015','12/15/2015','1/15/2016'], 'Template': 'Instrument.Derivative.BermudanOption'}, {'AsOfDate': asof_date, 'Basis': 'ACTUAL/365Fixed', 'Calendar': 'UnitedStates', 'DiscountRate': 0.001, 'DividendRate': 0.0163, 'ObjectId': 'BSMProcess', 'Spot': 127.62, 'Template': 'Process.Equity.BlackScholesMerton', 'Volatility': 0.20}, {'GeneralBlackScholesProcess': '->BSMProcess', 'ObjectId': 'BermudanEngine', 'Template': 'Engine.Equity.FdBermudan'} ] controller = Controller(data) controller.process(asof_date) option = controller.object("BermudanOption") npv = option.NPV() self.assertAlmostEqual(npv, 6.808761233089867)
def test_swaption_helpers(self): asof_date = "7/5/2016" data = [ { F.FORWARD_RATE.id: 0.01, F.ASOF_DATE.id: asof_date, F.DISCOUNT_BASIS.id: "30/360", F.CURRENCY.id: "USD", F.OBJECT_ID.id: "USD.Flat.Curve", F.TEMPLATE.id: T.TS_YIELD_FLAT }, { F.TEMPLATE.id: T.INDEX_IBOR_USDLIBOR.id, F.TENOR.id: "3M", F.OBJECT_ID.id: "USDLibor3M", F.YIELD_CURVE.id: "->USD.Flat.Curve" }, { F.TEMPLATE.id: T.INSTRUMENT_DERIVATIVE_SWAPTION_HELPER.id, F.MATURITY_TENOR.id: "1Y", F.UNDERLYING_MATURITY_TENOR.id: "5Y", F.DISCOUNT_CURVE.id: "->USD.Flat.Curve", F.VOLATILITY.id: 0.15, F.OBJECT_ID.id: "SWPN1", F.CURRENCY.id: "USD", F.INDEX.id: "->USDLibor3M" } ] res = Controller(data) res.process(asof_date) swpn = res.object("SWPN1") self.assertIsInstance(swpn, ql.SwaptionHelper)
def test_us_bond_curve(self): res = Controller([self._bond_data]) asof_date = qlc.to_date(self._bond_data[F.ASOF_DATE.id]) res.process(asof_date) curve = res.object("Curve") self.assertIsInstance(curve, ql.YieldTermStructure) tenors = range(0,13,1) + [60, 90, 120, 240, 300, 359, 360] # reference vals = [1,0.999818753,0.999586047,0.999330996,0.998969924,0.998519955,0.998012046, 0.997480698,0.996973715,0.996446467,0.995819544,0.995147323,0.994527808, 0.94416047,0.895823056,0.848952274,0.654149304,0.553888921,0.459284189, 0.458072534] # last observed vals = [1.0, 0.9998187481880838, 0.9995860408491943, 0.9993309911166345, 0.998969919388518, 0.9985199520192828, 0.9980120452385237, 0.9974638785194306, 0.9969737149981466, 0.9964464679686021, 0.9957564702629885, 0.9951473260058783, 0.9945282870008731, 0.9440478657964286, 0.8958540539792529, 0.8489512443374962, 0.6541478087480587, 0.553887387818232, 0.45928271508412133, 0.45770699043771784] calendar = ql.UnitedStates(ql.UnitedStates.GovernmentBond) for i, t in enumerate(tenors): p = ql.Period(t, ql.Months) d = calendar.advance(asof_date, ql.Period(t, ql.Months),ql.ModifiedFollowing) o = curve.discount(d) v = vals[i] self.assertAlmostEqual(o, v, 15, msg="("+str(t)+","+str(d)+","+str(o)+","+str(v)+")")
def test_graph_dependency(self): res = Controller(self._bond_data) asof_date = qlc.to_date(self._bond_data[0][Field.ASOF_DATE.id]) res.process(asof_date) curve = res.object("USD.Bond.Curve") self.assertIsInstance(curve, ql.YieldTermStructure) bond = res.object("Inst1") price = bond.cleanPrice() self.assertEqual(price, 99.98642361111114) return
def test_duplicate_id_error(self): data = self._bond_data + [self._bond_data[-1]] error = "" try: res = Controller(data) asof_date = qlc.to_date(self._bond_data[0][Field.ASOF_DATE.id]) res.process(asof_date) except ValueError as e: error = e.message self.assertEqual(error, 'Duplicate ObjectId BondEngine found') return
def test_dependency_cycles_err(self): data = copy.deepcopy(self._bond_data) data[-1]['DiscountCurve'] = "->Inst2" error = "" try: res = Controller(data) asof_date = qlc.to_date(self._bond_data[0][Field.ASOF_DATE.id]) res.process(asof_date) except ValueError as e: error = e.message self.assertEqual(error, "Found cycles in dependencies [['Inst2', 'BondEngine']]") return
def test_datatype_check_err(self): data = copy.deepcopy(self._bond_data) data[-2]['PricingEngine'] = "->USD.Bond.Curve" error = "" try: res = Controller(data) asof_date = qlc.to_date(self._bond_data[0][Field.ASOF_DATE.id]) res.process(asof_date) except ValueError as e: error = e.message self.assertEqual(error, 'Incompatible data type for field PricingEngine in object Inst3') return
def test_vol_curve(self): asof_date = "8/15/2016" data = [{ 'AsOfDate': asof_date, 'Basis': "ACT/ACT", 'ListOfDate': ["8/15/2017", "8/15/2018", "8/15/2019"], 'ListOfVolatility': [0.45, 0.45, 0.45], 'ObjectId': "BlackVolCurve", 'Template': 'TermStructure.Volatility.BlackCurve' }] c = Controller(data) c.process(asof_date) obj = c.object("BlackVolCurve") self.assertIsInstance(obj, ql.BlackVarianceCurve)
def test_dependency_cycles_err(self): data = copy.deepcopy(self._bond_data) data[-1]['DiscountCurve'] = "->Inst2" error = "" try: res = Controller(data) asof_date = qlc.to_date(self._bond_data[0][Field.ASOF_DATE.id]) res.process(asof_date) except ValueError as e: error = e.message self.assertEqual( error, "Found cycles in dependencies [['Inst2', 'BondEngine']]") return
def test_constant_vol(self): asof_date = "8/15/2016" data = [{ 'AsOfDate': "8/15/2016", 'Basis': "ACT/ACT", 'Calendar': "UnitedStates", 'ObjectId': "BlackConstantVol", 'Template': "TermStructure.Volatility.BlackConstant", 'Volatility': 0.45 }] c = Controller(data) c.process(asof_date) obj = c.object("BlackConstantVol") self.assertIsInstance(obj, ql.BlackConstantVol)
def test_constant_vol(self): asof_date = "8/15/2016" data =[ {'AsOfDate': "8/15/2016", 'Basis': "ACT/ACT", 'Calendar': "UnitedStates", 'ObjectId': "BlackConstantVol", 'Template': "TermStructure.Volatility.BlackConstant", 'Volatility': 0.45} ] c = Controller(data) c.process(asof_date) obj = c.object("BlackConstantVol") self.assertIsInstance(obj, ql.BlackConstantVol)
def test_vol_curve(self): asof_date = "8/15/2016" data = [ {'AsOfDate': asof_date, 'Basis': "ACT/ACT", 'ListOfDate': ["8/15/2017", "8/15/2018","8/15/2019"], 'ListOfVolatility': [0.45, 0.45, 0.45], 'ObjectId': "BlackVolCurve", 'Template': 'TermStructure.Volatility.BlackCurve'} ] c = Controller(data) c.process(asof_date) obj = c.object("BlackVolCurve") self.assertIsInstance(obj, ql.BlackVarianceCurve)
def test_datatype_check_err(self): data = copy.deepcopy(self._bond_data) data[-2]['PricingEngine'] = "->USD.Bond.Curve" error = "" try: res = Controller(data) asof_date = qlc.to_date(self._bond_data[0][Field.ASOF_DATE.id]) res.process(asof_date) except ValueError as e: error = e.message self.assertEqual( error, 'Incompatible data type for field PricingEngine in object Inst3') return
def test_vol_surface(self): asof_date = "8/15/2016" data = [ {'Basis': 'ACT/ACT', 'Calendar': 'UnitedStates', 'ListOfDate': ["8/15/2017", "8/15/2018","8/15/2019"], 'ListOfListOfVolatility': [["0.45", "0.45"], ["0.45","0.45"], ["0.45", "0.45"]], 'ListOfStrike': ["100", "110"], 'ObjectId': 'BlackVolSurface', 'AsOfDate': asof_date, 'Template': 'TermStructure.Volatility.BlackSurface'} ] c = Controller(data) c.process(asof_date) obj = c.object("BlackVolSurface") self.assertIsInstance(obj, ql.BlackVarianceSurface)
def test_flat_forward(self): asof_date = "7/22/2016" data = [{ F.FORWARD_RATE.id: 0.01, F.ASOF_DATE.id: asof_date, F.DISCOUNT_BASIS.id: "30/360", F.CURRENCY.id: "USD", F.OBJECT_ID.id: "USD.Flat.Curve", F.TEMPLATE.id: T.TS_YIELD_FLAT }] res = Controller(data) res.process(asof_date) curve = res.object("USD.Flat.Curve") observed = [curve.discount(d) for d in [0.0, 0.25, 0.5, 1.0]] expected = [1.0, 0.99750312239746, 0.9950124791926824, 0.9900498337491681] self.assertListEqual(observed, expected)
def test_dependency_cycles_err(self): data = copy.deepcopy(self._bond_data) data[-1]['DiscountCurve'] = "->Inst2" error = "" try: res = Controller(data) asof_date = qlc.to_date(self._bond_data[0][Field.ASOF_DATE.id]) res.process(asof_date) except ValueError as e: error = e.args[0] # Error message is indeterministic could be either of the below # [['Inst2', 'BondEngine']] # [['BondEngine', 'BondEngine']] self.assertTrue(error.startswith("Found cycles in dependencies ")) self.assertTrue("'Inst2'" in error) self.assertTrue("'BondEngine'" in error)
def test_context(self): curve_data = [self._bond_data[0]] rest_data = self._bond_data[1:] res = Controller(curve_data) asof_date = qlc.to_date(self._bond_data[0][Field.ASOF_DATE.id]) res.process(asof_date) context = res.data res = Controller(rest_data, context=context) res.process(asof_date) bond = res.object("Inst1") price = bond.cleanPrice() self.assertEqual(price, 99.98642361111114) return
def test_us_bond_curve(self): res = Controller([self._bond_data]) asof_date = qlc.to_date(self._bond_data[F.ASOF_DATE.id]) res.process(asof_date) curve = res.object("Curve") self.assertIsInstance(curve, ql.YieldTermStructure) tenors = range(0,13,1) + [60, 90, 120, 240, 300, 359, 360] vals = [1.0, 0.995463027383, 0.944034654878, 0.895839444646, 0.848938836737, 0.654147091, 0.553886881, 0.459282459, 0.458070805] calendar = ql.UnitedStates(ql.UnitedStates.GovernmentBond) for t in tenors: p = ql.Period(t, ql.Months) d = calendar.advance(asof_date, ql.Period(t, ql.Months),ql.ModifiedFollowing) o = curve.discount(d) #self.assertAlmostEqual(o, v, 10, msg="("+str(t)+","+str(d)+","+str(o)+","+str(v)+")") print t, d, o
def test_us_bond_curve(self): res = Controller([self._bond_data]) asof_date = qlc.to_date(self._bond_data[F.ASOF_DATE.id]) res.process(asof_date) curve = res.object("Curve") self.assertIsInstance(curve, ql.YieldTermStructure) tenors = list(range(0,13,1)) + [60, 90, 120, 240, 300, 359, 360] vals = [1.0, 0.995463027383, 0.944034654878, 0.895839444646, 0.848938836737, 0.654147091, 0.553886881, 0.459282459, 0.458070805] calendar = ql.UnitedStates(ql.UnitedStates.GovernmentBond) for t in tenors: p = ql.Period(t, ql.Months) d = calendar.advance(asof_date, ql.Period(t, ql.Months),ql.ModifiedFollowing) o = curve.discount(d) #self.assertAlmostEqual(o, v, 10, msg="("+str(t)+","+str(d)+","+str(o)+","+str(v)+")") print(t, d, o)
def test_eur_libor(self): asof_date = "8/15/2016" data = [{ F.FORWARD_RATE.id: 0.01, F.ASOF_DATE.id: asof_date, F.DISCOUNT_BASIS.id: "30/360", F.CURRENCY.id: "EUR", F.OBJECT_ID.id: "EUR.Flat.Curve", F.TEMPLATE.id: T.TS_YIELD_FLAT }, { F.TEMPLATE.id: T.INDEX_IBOR_EURLIBOR.id, F.TENOR.id: "3M", F.OBJECT_ID.id: "EURLibor3M", F.YIELD_CURVE.id: "->EUR.Flat.Curve" }] res = Controller(data) res.process(asof_date) index = res.object("EURLibor3M") self.assertIsInstance(index, ql.EURLibor)
def test_discount_curve(self): data = { "ListOfDate": ["7/5/2016", "8/1/2016", "9/1/2016", "10/1/2016"], "ListOfDiscountFactor": [1.0, 0.99, 0.98, 0.97], "DiscountBasis": "30/360", 'Template': 'TermStructure.Yield.DiscountCurve', "Currency": "USD", "ObjectId": "Curve", "DiscountCalendar": "UnitedStates.GovernmentBond" } res = Controller([data]) asof_date = qlc.to_date("7/5/2016") res.process(asof_date) dcurve = res.object("Curve") data2 = res.object_data("Curve") observed = [dcurve.discount(d) for d in data2["ListOfDate"]] expected = data["ListOfDiscountFactor"] self.assertListEqual(observed, expected)
def test_zero_curve(self): data = { "ListOfDate": ["7/5/2016", "8/1/2016", "9/1/2016", "10/1/2016"], "ListOfZeroRate": [0.0, 0.001,0.002, 0.003], "DiscountBasis": "30/360", 'Template': 'TermStructure.Yield.ZeroCurve', "Currency": "USD", "ObjectId": "Curve", "DiscountCalendar": "UnitedStates.GovernmentBond" } res = Controller([data]) asof_date = qlc.to_date("7/5/2016") ret = res.process(asof_date) zcurve = res.object("Curve") data2 = res.object_data("Curve") observed = [zcurve.discount(d) for d in data2["ListOfDate"]] expected = [1.0, 0.9999277803857397, 0.9996889372789323, 0.9992835900775519] self.assertListEqual(observed, expected)
def test_vol_surface(self): asof_date = "8/15/2016" data = [{ 'Basis': 'ACT/ACT', 'Calendar': 'UnitedStates', 'ListOfDate': ["8/15/2017", "8/15/2018", "8/15/2019"], 'ListOfListOfVolatility': [["0.45", "0.45"], ["0.45", "0.45"], ["0.45", "0.45"]], 'ListOfStrike': ["100", "110"], 'ObjectId': 'BlackVolSurface', 'AsOfDate': asof_date, 'Template': 'TermStructure.Volatility.BlackSurface' }] c = Controller(data) c.process(asof_date) obj = c.object("BlackVolSurface") self.assertIsInstance(obj, ql.BlackVarianceSurface)
def test_hw1f_model(self): asof_date = "7/5/2016" data = [ { F.FORWARD_RATE.id: 0.01, F.ASOF_DATE.id: asof_date, F.DISCOUNT_BASIS.id: "30/360", F.CURRENCY.id: "USD", F.OBJECT_ID.id: "USD.Flat.Curve", F.TEMPLATE.id: T.TS_YIELD_FLAT }, { F.TEMPLATE.id: T.MODEL_YIELD_HW1F, F.ALPHA.id: 0.1, F.SIGMA1.id: 0.05, F.OBJECT_ID.id: "HW1FModel", F.YIELD_CURVE.id: "->USD.Flat.Curve", F.CURRENCY.id: "USD" }] res = Controller(data) res.process(asof_date) model = res.object("HW1FModel") params = list(model.params()) self.assertListEqual(params, [0.1, 0.05])
F.CURRENCY.id: "USD", F.TEMPLATE.id: T.TS_YIELD_ZERO, F.OBJECT_ID.id: "USD.Zero.Curve"}, { F.OBJECT_ID.id: "BondEngine", F.DISCOUNT_CURVE.id: "->USD.Zero.Curve", F.TEMPLATE.id: T.ENG_BOND_DISCOUNTING.id}, { F.ASOF_DATE.id: '2016-01-15', F.COUPON.id: 0.06, F.COUPON_FREQ.id: "Semiannual", F.CURRENCY.id: 'USD', F.PAYMENT_BASIS.id: '30/360', F.ISSUE_DATE.id: '2015-01-15', F.MATURITY_DATE.id: '2016-01-15', F.ACCRUAL_CALENDAR.id: "UnitedStates", F.ACCRUAL_DAY_CONVENTION.id: "Unadjusted", F.DATE_GENERATION.id: "Backward", F.END_OF_MONTH.id: False, F.OBJECT_ID.id: "USD.TBond", F.PRICING_ENGINE.id: "->BondEngine", F.TEMPLATE.id: T.INST_BOND_TBOND.id} ] res = Controller(data) asof_date = "1/15/2015" ret = res.process(asof_date) tbond = res.object("USD.TBond") print tbond.NPV()
def test_swaption_hw1f_calibration(self): asof_date = "7/5/2016" data = [ { F.FORWARD_RATE.id: 0.01, F.ASOF_DATE.id: asof_date, F.DISCOUNT_BASIS.id: "30/360", F.CURRENCY.id: "USD", F.OBJECT_ID.id: "USD.Flat.Curve", F.TEMPLATE.id: T.TS_YIELD_FLAT }, { F.TEMPLATE.id: T.INDEX_IBOR_USDLIBOR.id, F.TENOR.id: "3M", F.OBJECT_ID.id: "USDLibor3M", F.YIELD_CURVE.id: "->USD.Flat.Curve" }, { F.TEMPLATE.id: T.MODEL_YIELD_HW1F, F.OBJECT_ID.id: "HW1FModel", F.YIELD_CURVE.id: "->USD.Flat.Curve", F.CURRENCY.id: "USD", F.SOLVER.id: "LEASTSQUARES", F.CALIBRATE.id: "True", F.INSTRUMENT_COLLECTION.id: [ { F.TEMPLATE.id: T.INSTRUMENT_DERIVATIVE_SWAPTION_HELPER.id, F.MATURITY_TENOR.id: "1Y", F.UNDERLYING_MATURITY_TENOR.id: "5Y", F.DISCOUNT_CURVE.id: "->USD.Flat.Curve", F.VOLATILITY.id: 0.15, F.OBJECT_ID.id: "SWPN1", F.CURRENCY.id: "USD", F.INDEX.id: "->USDLibor3M" }, { F.TEMPLATE.id: T.INSTRUMENT_DERIVATIVE_SWAPTION_HELPER.id, F.MATURITY_TENOR.id: "2Y", F.UNDERLYING_MATURITY_TENOR.id: "4Y", F.DISCOUNT_CURVE.id: "->USD.Flat.Curve", F.VOLATILITY.id: 0.16, F.OBJECT_ID.id: "SWPN2", F.CURRENCY.id: "USD", F.INDEX.id: "->USDLibor3M" }, { F.TEMPLATE.id: T.INSTRUMENT_DERIVATIVE_SWAPTION_HELPER.id, F.MATURITY_TENOR.id: "3Y", F.UNDERLYING_MATURITY_TENOR.id: "3Y", F.DISCOUNT_CURVE.id: "->USD.Flat.Curve", F.VOLATILITY.id: 0.17, F.OBJECT_ID.id: "SWPN3", F.CURRENCY.id: "USD", F.INDEX.id: "->USDLibor3M" }, { F.TEMPLATE.id: T.INSTRUMENT_DERIVATIVE_SWAPTION_HELPER.id, F.MATURITY_TENOR.id: "4Y", F.UNDERLYING_MATURITY_TENOR.id: "1Y", F.DISCOUNT_CURVE.id: "->USD.Flat.Curve", F.VOLATILITY.id: 0.1432, F.OBJECT_ID.id: "SWPN4", F.CURRENCY.id: "USD", F.INDEX.id: "->USDLibor3M" } ] } ] methods = ["LM", "LeastSquares", "DifferentialEvolution"] for m in methods: data[-1][F.SOLVER.id] = m res = Controller(data) res.process(asof_date) model = res.object("HW1FModel") #print model.params() self.assertIsInstance(model, ql.HullWhite) # check constraints data[-1][F.ALPHA.id] = 0.001 for m in methods[1:]: data[-1][F.SOLVER.id] = m res = Controller(data) res.process(asof_date) model = res.object("HW1FModel") alpha, sigma1 = model.params() self.assertAlmostEqual(alpha, 0.001, 10) self.assertIsInstance(model, ql.HullWhite)
F.CURRENCY.id: "USD", F.TEMPLATE.id: T.TS_YIELD_ZERO, F.OBJECT_ID.id: "USD.Zero.Curve" }, { F.OBJECT_ID.id: "BondEngine", F.DISCOUNT_CURVE.id: "->USD.Zero.Curve", F.TEMPLATE.id: T.ENGINE_BOND_DISCOUNTING.id }, { F.ASOF_DATE.id: '2016-01-15', F.COUPON.id: 0.06, F.COUPON_FREQ.id: "Semiannual", F.CURRENCY.id: 'USD', F.PAYMENT_BASIS.id: '30/360', F.ISSUE_DATE.id: '2015-01-15', F.MATURITY_DATE.id: '2016-01-15', F.ACCRUAL_CALENDAR.id: "UnitedStates", F.ACCRUAL_DAY_CONVENTION.id: "Unadjusted", F.DATE_GENERATION.id: "Backward", F.END_OF_MONTH.id: False, F.OBJECT_ID.id: "USD.TBond", F.PRICING_ENGINE.id: "->BondEngine", F.TEMPLATE.id: T.INSTRUMENT_BOND_TBOND.id }] res = Controller(data) asof_date = "1/15/2015" ret = res.process(asof_date) tbond = res.object("USD.TBond") print tbond.NPV()