Example #1
0
    def test_shrinkage_coef(self):
        """Dynamic vs at construction."""
        n_samples = 3
        n_channels = 4
        n_assets = 5

        x = torch.rand((n_samples, n_channels, n_assets)) * 100

        layer_1 = CovarianceMatrix(sqrt=False,
                                   shrinkage_strategy='diagonal',
                                   shrinkage_coef=0.3)
        layer_2 = CovarianceMatrix(sqrt=False,
                                   shrinkage_strategy='diagonal',
                                   shrinkage_coef=None)

        assert torch.allclose(
            layer_1(x), layer_2(x, 0.3 * torch.ones(n_samples, dtype=x.dtype)))

        x_ = torch.rand((n_channels, n_assets)) * 100
        x_stacked = torch.stack([x_, x_, x_], dim=0)

        res_1 = layer_1(x_stacked)
        res_2 = layer_2(x_stacked, torch.tensor([0.2, 0.3, 0.6]))

        assert torch.allclose(res_1[0], res_1[1])
        assert torch.allclose(res_1[1], res_1[2])
        assert torch.allclose(res_1[2], res_1[0])

        assert not torch.allclose(res_2[0], res_2[1])
        assert not torch.allclose(res_2[1], res_2[2])
        assert not torch.allclose(res_2[2], res_2[0])
Example #2
0
    def test_n_parameters(self, sqrt):
        layer = CovarianceMatrix()

        n_parameters = sum(p.numel() for p in layer.parameters()
                           if p.requires_grad)

        assert n_parameters == 0
Example #3
0
    def test_wrong_construction(self):
        with pytest.raises(ValueError):
            CovarianceMatrix(shrinkage_strategy='fake')

        with pytest.raises(ValueError):
            layer = CovarianceMatrix(shrinkage_coef=None)
            layer(torch.ones(1, 5, 2))
Example #4
0
    def test_basic(self, Xy_dummy, sqrt, shrinkage_strategy):
        X, _, _, _ = Xy_dummy
        n_samples, n_channels, lookback, n_assets = X.shape

        X_ = X.mean(dim=1)

        if n_channels == 1:
            with pytest.raises(ZeroDivisionError):
                CovarianceMatrix(sqrt, shrinkage_strategy=shrinkage_strategy)(X_)
        else:
            out = CovarianceMatrix(sqrt, shrinkage_strategy=shrinkage_strategy)(X_)

            assert out.shape == (n_samples, n_assets, n_assets)
Example #5
0
    def test_sqrt_works(self):
        n_samples = 3
        n_channels = 4
        n_assets = 5

        x = torch.rand((n_samples, n_channels, n_assets)) * 100

        cov = CovarianceMatrix(sqrt=False)(x)
        cov_sqrt = CovarianceMatrix(sqrt=True)(x)

        assert (n_samples, n_assets, n_assets) == cov.shape == cov_sqrt.shape

        for i in range(n_samples):
            assert torch.allclose(cov[i], cov_sqrt[i] @ cov_sqrt[i], atol=1e-2)
Example #6
0
 def __init__(
     self,
     n_external,
     n_assets,
     n_channels=5,
     hidden_size=32,
     max_weight=0.15,
     force_symmetric=True,
     p=0.2,
 ):
     super().__init__()
     self.force_symmetric = force_symmetric
     self.matrix = torch.nn.Parameter(torch.eye(n_assets),
                                      requires_grad=True)
     self.exp_returns = torch.nn.Parameter(torch.zeros(n_assets),
                                           requires_grad=True)
     self.norm_layer = torch.nn.InstanceNorm2d(n_channels, affine=True)
     self.collapse_external = AverageCollapse()
     self.transform_layer = RNN(n_channels, hidden_size=hidden_size)
     self.dropout_layer = torch.nn.Dropout(p=p)
     self.dropout_layer2 = torch.nn.Dropout(p=p)
     self.time_collapse_layer = AttentionCollapse(n_channels=hidden_size)
     self.conv1 = Conv(n_input_channels=hidden_size,
                       n_output_channels=1,
                       method="1D")
     # self.conv2 = Conv(n_input_channels=3, n_output_channels=1, method="1D")
     self.linear_transform = torch.nn.Linear(n_external, n_assets)
     self.linear_2 = torch.nn.Linear(n_external, n_assets)
     self.covariance_layer = CovarianceMatrix(sqrt=False,
                                              shrinkage_strategy="diagonal")
     self.gamma_sqrt = torch.nn.Parameter(torch.ones(1), requires_grad=True)
     self.alpha = torch.nn.Parameter(torch.ones(1), requires_grad=True)
     self.preliminar_weights_layer = NumericalMarkowitz(
         n_assets, max_weight=max_weight)
Example #7
0
    def stupid_compute(w, y):
        """Straightforward implementation with list comprehensions."""
        from deepdow.layers import CovarianceMatrix

        n_samples, n_assets = w.shape
        covar = CovarianceMatrix(sqrt=False)(y[:, 0, ...])  # returns_channel=0

        var = torch.cat([(w[[i]] @ covar[i]) @ w[[i]].permute(1, 0)
                         for i in range(n_samples)],
                        dim=0)
        vol = torch.sqrt(var)

        lhs = vol / n_assets
        rhs = torch.cat([(1 / vol[i]) * w[[i]] * (w[[i]] @ covar[i])
                         for i in range(n_samples)],
                        dim=0)

        res = torch.tensor([((lhs[i] - rhs[i])**2).sum()
                            for i in range(n_samples)])

        return res