Example #1
0
    def test_edge_case(self, dtype_device, use_rets, edge_case):
        dtype, device = dtype_device

        n_samples = 2
        n_assets = 4
        n_clusters = 1 if edge_case == 'single_cluster' else n_assets

        single_ = torch.rand(n_assets, n_assets, dtype=dtype, device=device)
        single = single_ @ single_.t()
        covmat = torch.stack([single for _ in range(n_samples)], dim=0)
        rets = torch.rand(n_samples, n_assets, dtype=dtype, device=device) if use_rets else None

        true_weights = AnalyticalMarkowitz()(covmat, rets=rets)
        pred_weights = NCO(n_clusters=n_clusters)(covmat, rets=rets)

        assert torch.allclose(pred_weights, true_weights, atol=1e-3)
        assert true_weights.device == pred_weights.device
        assert true_weights.dtype == pred_weights.dtype
Example #2
0
    def test_reproducible(self, dtype_device, use_rets):
        dtype, device = dtype_device

        n_samples = 2
        n_assets = 6
        n_clusters = 3

        single_ = torch.rand(n_assets, n_assets, dtype=dtype, device=device)
        single = single_ @ single_.t()
        covmat = torch.stack([single for _ in range(n_samples)], dim=0)
        rets = torch.rand(n_samples, n_assets, dtype=dtype, device=device) if use_rets else None

        layer = NCO(n_clusters=n_clusters, random_state=2)
        weights_1 = layer(covmat, rets=rets)
        weights_2 = layer(covmat, rets=rets)

        assert torch.allclose(weights_1, weights_2)
        assert weights_1.device == weights_2.device
        assert weights_1.dtype == weights_2.dtype
Example #3
0
 def __init__(
     self,
     n_assets,
     max_weight=0.2,
     force_symmetric=False,
     n_clusters=5,
     n_init=100,
     init="random",
     random_state=None,
 ):
     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
     )  # torch.FloatTensor(n_assets).uniform_(-0.001, 0.001))#torch.tensor(exp_returns), requires_grad=True) #torch.zeros(n_assets), requires_grad=True)
     torch.nn.init.uniform_(self.exp_returns, a=-0.0005, b=0.0005)
     # self.gamma_sqrt = torch.nn.Parameter(torch.ones(1), requires_grad=True)
     # self.alpha = torch.nn.Parameter(torch.ones(1), requires_grad=True)
     # self.n_clusters = torch.nn.Parameter() # TODO: TRY TO IMPLEMENT THIS DIFFERENTIABLE.
     self.portfolio_opt_layer = NCO(n_clusters, n_init, init, random_state)