Example #1
0
    def test_dtype(self, dtype):
        liability = EuropeanOption(BrownianStock(dtype=dtype))
        assert liability.dtype == dtype
        liability.simulate()
        assert liability.payoff().dtype == dtype

        liability = EuropeanOption(BrownianStock()).to(dtype=dtype)
        liability.simulate()
        assert liability.payoff().dtype == dtype
Example #2
0
    def test_compute_loss(self):
        torch.manual_seed(42)
        deriv = EuropeanOption(BrownianStock())
        hedger = Hedger(Naked(),
                        ["log_moneyness", "expiry_time", "volatility"])

        result = hedger.compute_loss(deriv)
        expect = EntropicRiskMeasure()(-deriv.payoff())
        assert torch.allclose(result, expect)
Example #3
0
 def test_repr(self):
     liability = EuropeanOption(BrownianStock(), maturity=1.0)
     expect = "EuropeanOption(BrownianStock(...), maturity=1.00e+00)"
     assert repr(liability) == expect
     liability = EuropeanOption(BrownianStock(), maturity=1.0, call=False)
     expect = "EuropeanOption(BrownianStock(...), call=False, maturity=1.00e+00)"
     assert repr(liability) == expect
     liability = EuropeanOption(BrownianStock(), maturity=1.0, strike=2.0)
     expect = "EuropeanOption(BrownianStock(...), strike=2.0, maturity=1.00e+00)"
     assert repr(liability) == expect
Example #4
0
 def test_payoff(self):
     liability = EuropeanOption(BrownianStock(), strike=2.0)
     liability.underlier.prices = torch.tensor([
         [1.0, 1.0, 1.0, 1.0],
         [1.0, 1.0, 1.0, 1.0],
         [1.9, 2.0, 2.1, 3.0],
     ])
     result = liability.payoff()
     expect = torch.tensor([0.0, 0.0, 0.1, 1.0])
     assert torch.allclose(result, expect)
Example #5
0
    def test_compute_pnl(self):
        torch.manual_seed(42)
        deriv = EuropeanOption(BrownianStock())
        hedger = Hedger(Naked(), ["zero"])

        pnl = hedger.compute_pnl(deriv)
        payoff = deriv.payoff()
        assert torch.allclose(pnl, -payoff)

        result = hedger.compute_pnl(deriv)
        expect = -deriv.payoff()
        assert torch.allclose(result, expect)
Example #6
0
    def test_shape(self):
        torch.distributions.Distribution.set_default_validate_args(False)

        deriv = EuropeanOption(BrownianStock())

        N = 2
        M_1 = 5
        M_2 = 6
        H_in = 3

        x = torch.empty((N, M_1, M_2, H_in))
        m = Hedger(MultiLayerPerceptron(), ["zero"])
        assert m(x).size() == torch.Size((N, M_1, M_2, 1))

        model = BlackScholes(deriv)
        m = Hedger(model, model.features())
        x = torch.empty((N, M_1, M_2, len(model.features())))
        assert m(x).size() == torch.Size((N, M_1, M_2, 1))

        model = WhalleyWilmott(deriv)
        m = Hedger(model, model.features())
        x = torch.empty((N, M_1, M_2, len(model.features())))
        assert m(x).size() == torch.Size((N, M_1, M_2, 1))

        model = Naked()
        m = Hedger(model, ["zero"])
        x = torch.empty((N, M_1, M_2, 10))
        assert m(x).size() == torch.Size((N, M_1, M_2, 1))
Example #7
0
    def test_repr(self):
        hedger = Hedger(Linear(2, 1), ["moneyness", "expiry_time"])
        assert repr(hedger) == (
            "Hedger(\n"
            "  features=['moneyness', 'expiry_time'],\n"
            "  (model): Linear(in_features=2, out_features=1, bias=True)\n"
            "  (criterion): EntropicRiskMeasure()\n"
            ")")

        liability = EuropeanOption(BrownianStock())
        model = BlackScholes(liability)
        hedger = Hedger(model, model.features())
        assert repr(hedger) == (
            "Hedger(\n"
            "  features=['log_moneyness', 'expiry_time', 'volatility'],\n"
            "  (model): BSEuropeanOption()\n"
            "  (criterion): EntropicRiskMeasure()\n"
            ")")

        hedger = Hedger(naked, ["moneyness", "expiry_time"])
        assert repr(hedger) == ("Hedger(\n"
                                "  model=naked,\n"
                                "  features=['moneyness', 'expiry_time'],\n"
                                "  (criterion): EntropicRiskMeasure()\n"
                                ")")
Example #8
0
    def test_repr(self):
        m = BSEuropeanOption()
        assert repr(m) == "BSEuropeanOption()"

        liability = EuropeanOption(BrownianStock(), strike=1.1, call=False)
        m = BSEuropeanOption(liability)
        assert repr(m) == "BSEuropeanOption(call=False, strike=1.1)"
Example #9
0
    def test(self):
        liability = EuropeanOption(BrownianStock())
        liability.simulate()

        module = torch.nn.Linear(2, 1)
        x1, x2 = Moneyness(), ExpiryTime()
        f = ModuleOutput(module, [x1, x2]).of(liability)

        result = f[0]
        expect = module(torch.cat([x1[0], x2[0]], 1))
        assert torch.allclose(result, expect)
        result = f[1]
        expect = module(torch.cat([x1[1], x2[1]], 1))
        assert torch.allclose(result, expect)
        result = f[2]
        expect = module(torch.cat([x1[2], x2[2]], 1))
        assert torch.allclose(result, expect)
Example #10
0
    def test_init(self):
        liability = EuropeanOption(BrownianStock())
        m = BlackScholes(liability)
        assert m.__class__ == BSEuropeanOption
        assert m.strike == 1.0
        assert m.call

        liability = EuropeanOption(BrownianStock(), strike=2.0, call=False)
        m = BlackScholes(liability)
        assert m.__class__ == BSEuropeanOption
        assert m.strike == 2.0
        assert not m.call

        liability = LookbackOption(BrownianStock())
        m = BlackScholes(liability)
        assert m.__class__ == BSLookbackOption
        assert m.strike == 1.0
        assert m.call
Example #11
0
    def test_parity(self, volatility, strike, maturity, n_paths, init_price):
        """
        Test put-call parity.
        """
        stock = BrownianStock(volatility)
        co = EuropeanOption(stock, strike=strike, maturity=maturity, call=True)
        po = EuropeanOption(stock,
                            strike=strike,
                            maturity=maturity,
                            call=False)
        co.simulate(n_paths=n_paths, init_price=init_price)
        po.simulate(n_paths=n_paths, init_price=init_price)

        s = stock.prices[-1, :]
        c = co.payoff()
        p = po.payoff()

        assert ((c - p) == s - strike).all()
Example #12
0
    def test(self):
        liability = EuropeanOption(BrownianStock())
        liability.underlier.prices = torch.tensor([
            [1.0, 2.0, 3.0, 1.0],
            [1.5, 1.0, 4.0, 1.1],
            [2.0, 1.0, 5.0, 1.2],
            [3.0, 1.0, 6.0, 1.3],
        ])
        f = Barrier(2.0, up=True).of(liability)

        result = f[0]
        expect = torch.tensor([0.0, 1.0, 1.0, 0.0]).reshape(-1, 1)
        assert torch.allclose(result, expect)
        result = f[1]
        expect = torch.tensor([0.0, 1.0, 1.0, 0.0]).reshape(-1, 1)
        assert torch.allclose(result, expect)
        result = f[2]
        expect = torch.tensor([1.0, 1.0, 1.0, 0.0]).reshape(-1, 1)
        assert torch.allclose(result, expect)
        result = f[3]
        expect = torch.tensor([1.0, 1.0, 1.0, 0.0]).reshape(-1, 1)
        assert torch.allclose(result, expect)

        liability = EuropeanOption(BrownianStock())
        liability.underlier.prices = torch.tensor([
            [3.0, 1.0, 6.0, 1.3],
            [2.0, 1.0, 5.0, 1.2],
            [1.5, 1.0, 4.0, 1.1],
            [1.0, 2.0, 3.0, 1.0],
        ])
        f = Barrier(2.0, up=False).of(liability)

        result = f[0]
        expect = torch.tensor([0.0, 1.0, 0.0, 1.0]).reshape(-1, 1)
        assert torch.allclose(result, expect)
        result = f[1]
        expect = torch.tensor([1.0, 1.0, 0.0, 1.0]).reshape(-1, 1)
        assert torch.allclose(result, expect)
        result = f[2]
        expect = torch.tensor([1.0, 1.0, 0.0, 1.0]).reshape(-1, 1)
        assert torch.allclose(result, expect)
        result = f[3]
        expect = torch.tensor([1.0, 1.0, 0.0, 1.0]).reshape(-1, 1)
        assert torch.allclose(result, expect)
Example #13
0
    def test_example(self):
        from pfhedge import Hedger
        from pfhedge.instruments import BrownianStock
        from pfhedge.instruments import EuropeanOption

        liability = EuropeanOption(BrownianStock())
        model = BSEuropeanOption()
        hedger = Hedger(model, model.features())
        price = hedger.price(liability)
        assert torch.allclose(price, torch.tensor(0.0221), atol=1e-4)
Example #14
0
    def test_repr(self):
        liability = EuropeanOption(BrownianStock())
        m = WhalleyWilmott(liability)
        assert repr(m) == ("WhalleyWilmott(\n"
                           "  (bs): BSEuropeanOption()\n"
                           "  (clamp): Clamp()\n"
                           ")")

        liability = EuropeanOption(BrownianStock())
        m = WhalleyWilmott(liability, a=2)
        assert repr(m) == ("WhalleyWilmott(\n"
                           "  a=2\n"
                           "  (bs): BSEuropeanOption()\n"
                           "  (clamp): Clamp()\n"
                           ")")

        liability = LookbackOption(BrownianStock())
        m = WhalleyWilmott(liability)
        assert repr(m) == ("WhalleyWilmott(\n"
                           "  (bs): BSLookbackOption()\n"
                           "  (clamp): Clamp()\n"
                           ")")
Example #15
0
    def test(self, volatility):
        liability = EuropeanOption(BrownianStock(volatility=volatility))
        liability.underlier.prices = torch.arange(1.0, 7.0).reshape(3, 2)

        f = Volatility().of(liability)

        result = f[0]
        expect = torch.full((2, 1), volatility)
        assert torch.allclose(result, expect)
        result = f[1]
        expect = torch.full((2, 1), volatility)
        assert torch.allclose(result, expect)
        result = f[2]
        expect = torch.full((2, 1), volatility)
        assert torch.allclose(result, expect)
Example #16
0
    def test_forward(self):
        m = BSEuropeanOption()
        x = torch.tensor([0.0, 1.0, 0.2]).reshape(1, -1)
        result = m(x).item()
        assert np.isclose(result, 0.5398278962)

        m = BSEuropeanOption(call=False)
        x = torch.tensor([0.0, 1.0, 0.2]).reshape(1, -1)
        result = m(x).item()
        assert np.isclose(result, -0.4601721)

        liability = EuropeanOption(BrownianStock(), call=False)
        m = BSEuropeanOption(liability)
        x = torch.tensor([0.0, 1.0, 0.2]).reshape(1, -1)
        result = m(x).item()
        assert np.isclose(result, -0.4601721)
Example #17
0
    def test(self):
        torch.manual_seed(42)
        liability = EuropeanOption(BrownianStock())
        liability.underlier.prices = torch.arange(1.0, 7.0).reshape(3, 2)

        f = Zero().of(liability)

        result = f[0]
        expect = torch.zeros((2, 1))
        assert torch.allclose(result, expect)
        result = f[1]
        expect = torch.zeros((2, 1))
        assert torch.allclose(result, expect)
        result = f[2]
        expect = torch.zeros((2, 1))
        assert torch.allclose(result, expect)
Example #18
0
    def test(self):
        maturity = 3 / 365
        dt = 1 / 365
        liability = EuropeanOption(BrownianStock(dt=dt), maturity=maturity)
        liability.underlier.prices = torch.arange(1.0, 7.0).reshape(3, 2)

        f = ExpiryTime().of(liability)

        result = f[0]
        expect = torch.full((2, 1), 3 / 365)
        assert torch.allclose(result, expect)
        result = f[1]
        expect = torch.full((2, 1), 2 / 365)
        assert torch.allclose(result, expect)
        result = f[2]
        expect = torch.full((2, 1), 1 / 365)
        assert torch.allclose(result, expect)
Example #19
0
    def test_shape(self):
        torch.distributions.Distribution.set_default_validate_args(False)

        deriv = EuropeanOption(BrownianStock())
        m = WhalleyWilmott(deriv)

        N = 10
        H_in = len(m.features())
        M_1 = 11
        M_2 = 12

        x = torch.empty((N, H_in))
        assert m(x).size() == torch.Size((N, 1))

        x = torch.empty((N, M_1, H_in))
        assert m(x).size() == torch.Size((N, M_1, 1))

        x = torch.empty((N, M_1, M_2, H_in))
        assert m(x).size() == torch.Size((N, M_1, M_2, 1))
Example #20
0
    def test(self, strike):
        liability = EuropeanOption(BrownianStock(), strike=strike)
        liability.underlier.prices = torch.arange(1.0, 7.0).reshape(3, 2)
        # tensor([[1., 2.],
        #         [3., 4.],
        #         [5., 6.]])
        f = LogMoneyness().of(liability)

        result = f[0]
        expect = torch.tensor([[1.0], [2.0]]) / strike
        expect = torch.log(expect)
        assert torch.allclose(result, expect)
        result = f[1]
        expect = torch.tensor([[3.0], [4.0]]) / strike
        expect = torch.log(expect)
        assert torch.allclose(result, expect)
        result = f[2]
        expect = torch.tensor([[5.0], [6.0]]) / strike
        expect = torch.log(expect)
        assert torch.allclose(result, expect)
Example #21
0
    def test(self, strike):
        liability = EuropeanOption(BrownianStock(), strike=strike)
        liability.underlier.prices = torch.tensor([
            [1.0, 2.0, 3.0],
            [2.0, 3.0, 2.0],
            [1.5, 4.0, 1.0],
        ])

        f = MaxLogMoneyness().of(liability)

        result = f[0]
        expect = torch.tensor([[1.0], [2.0], [3.0]]) / strike
        expect = torch.log(expect)
        assert torch.allclose(result, expect)
        result = f[1]
        expect = torch.tensor([[2.0], [3.0], [3.0]]) / strike
        expect = torch.log(expect)
        assert torch.allclose(result, expect)
        result = f[2]
        expect = torch.tensor([[2.0], [4.0], [3.0]]) / strike
        expect = torch.log(expect)
        assert torch.allclose(result, expect)
Example #22
0
    def test(self, volatility):
        torch.manual_seed(42)
        liability = EuropeanOption(BrownianStock(volatility))
        liability.underlier.prices = torch.arange(1.0, 7.0).reshape(3, 2)
        hedger = Hedger(Linear(2, 1), ["moneyness", "expiry_time"])
        hedger.features = [
            feature.of(liability) for feature in hedger.features
        ]

        f = PrevHedge().of(liability, hedger)

        result = f[0]
        expect = torch.zeros((2, 1))
        assert torch.allclose(result, expect)
        h = hedger(torch.cat([feature[0] for feature in hedger.features], 1))
        result = f[1]
        expect = h.reshape(-1, 1)
        assert torch.allclose(result, expect)
        h = hedger(torch.cat([feature[1] for feature in hedger.features], 1))
        result = f[2]
        expect = h.reshape(-1, 1)
        assert torch.allclose(result, expect)
Example #23
0
def test_net():
    liability = EuropeanOption(BrownianStock(cost=1e-4))
    model = MultiLayerPerceptron()
    hedger = Hedger(model, ["log_moneyness", "expiry_time", "volatility", "prev_hedge"])
    _ = hedger.fit(liability, n_paths=100, n_epochs=10)
    _ = hedger.price(liability)
Example #24
0
def test_ww():
    liability = EuropeanOption(BrownianStock(cost=1e-4))
    model = WhalleyWilmott(liability)
    hedger = Hedger(model, model.features())
    _ = hedger.price(liability)
Example #25
0
def test_bs():
    liability = EuropeanOption(BrownianStock(cost=1e-4))
    model = BlackScholes(liability)
    hedger = Hedger(model, model.features())
    _ = hedger.price(liability)
Example #26
0
 def test_dtype(self, dtype):
     liability = EuropeanOption(BrownianStock()).to(dtype)
     m = Linear(2, 1).to(liability.dtype)
     f = ModuleOutput(m, [Moneyness(), ExpiryTime()])
     self.assert_same_dtype(f, liability, dtype)
Example #27
0
 def test_dtype(self, dtype):
     liability = EuropeanOption(BrownianStock())
     self.assert_same_dtype(Barrier(1.0), liability, dtype)
Example #28
0
 def test_dtype(self, dtype):
     liability = EuropeanOption(BrownianStock())
     self.assert_same_dtype(LogMoneyness(), liability, dtype)
Example #29
0
import torch

sys.path.append("..")

from pfhedge import Hedger  # noqa: E402
from pfhedge.instruments import BrownianStock  # noqa: E402
from pfhedge.instruments import EuropeanOption  # noqa: E402
from pfhedge.nn import ExpectedShortfall
from pfhedge.nn import MultiLayerPerceptron  # noqa: E402

if __name__ == "__main__":
    torch.manual_seed(42)

    # Prepare a derivative to hedge
    deriv = EuropeanOption(BrownianStock(cost=1e-4))

    # Expected shortfall with the quantile level of 10%
    expected_shortfall = ExpectedShortfall(0.1)

    # Create your hedger
    model = MultiLayerPerceptron()
    hedger = Hedger(
        model,
        ["log_moneyness", "expiry_time", "volatility", "prev_hedge"],
        criterion=expected_shortfall,
    )

    # Fit and price
    hedger.fit(deriv, n_paths=10000, n_epochs=200)
    price = hedger.price(deriv, n_paths=10000)
Example #30
0
 def test_device(self, device):
     liability = EuropeanOption(BrownianStock(device=device))
     assert liability.device == torch.device(device)