numerai-tools 0.4.0.dev2__tar.gz → 0.4.2.dev1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {numerai_tools-0.4.0.dev2 → numerai_tools-0.4.2.dev1}/PKG-INFO +1 -1
- {numerai_tools-0.4.0.dev2 → numerai_tools-0.4.2.dev1}/numerai_tools/scoring.py +18 -13
- {numerai_tools-0.4.0.dev2 → numerai_tools-0.4.2.dev1}/numerai_tools/signals.py +28 -1
- {numerai_tools-0.4.0.dev2 → numerai_tools-0.4.2.dev1}/numerai_tools.egg-info/PKG-INFO +1 -1
- {numerai_tools-0.4.0.dev2 → numerai_tools-0.4.2.dev1}/numerai_tools.egg-info/requires.txt +0 -1
- {numerai_tools-0.4.0.dev2 → numerai_tools-0.4.2.dev1}/setup.py +1 -2
- {numerai_tools-0.4.0.dev2 → numerai_tools-0.4.2.dev1}/tests/test_scoring.py +2 -2
- {numerai_tools-0.4.0.dev2 → numerai_tools-0.4.2.dev1}/tests/test_signals.py +8 -1
- {numerai_tools-0.4.0.dev2 → numerai_tools-0.4.2.dev1}/LICENSE +0 -0
- {numerai_tools-0.4.0.dev2 → numerai_tools-0.4.2.dev1}/README.md +0 -0
- {numerai_tools-0.4.0.dev2 → numerai_tools-0.4.2.dev1}/numerai_tools/__init__.py +0 -0
- {numerai_tools-0.4.0.dev2 → numerai_tools-0.4.2.dev1}/numerai_tools/py.typed +0 -0
- {numerai_tools-0.4.0.dev2 → numerai_tools-0.4.2.dev1}/numerai_tools/submissions.py +0 -0
- {numerai_tools-0.4.0.dev2 → numerai_tools-0.4.2.dev1}/numerai_tools.egg-info/SOURCES.txt +0 -0
- {numerai_tools-0.4.0.dev2 → numerai_tools-0.4.2.dev1}/numerai_tools.egg-info/dependency_links.txt +0 -0
- {numerai_tools-0.4.0.dev2 → numerai_tools-0.4.2.dev1}/numerai_tools.egg-info/top_level.txt +0 -0
- {numerai_tools-0.4.0.dev2 → numerai_tools-0.4.2.dev1}/setup.cfg +0 -0
- {numerai_tools-0.4.0.dev2 → numerai_tools-0.4.2.dev1}/tests/test_submissions.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: numerai_tools
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.2.dev1
|
|
4
4
|
Summary: A collection of open-source tools to help interact with Numerai, model data, and automate submissions.
|
|
5
5
|
Home-page: https://github.com/numerai/numerai-tools
|
|
6
6
|
Maintainer: Numerai
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from typing import List, Tuple, Union, Optional, TypeVar
|
|
2
2
|
|
|
3
|
-
import torch
|
|
4
3
|
import numpy as np
|
|
5
4
|
import pandas as pd # type: ignore
|
|
6
5
|
from scipy import stats # type: ignore
|
|
@@ -582,10 +581,11 @@ def meta_portfolio_contribution(
|
|
|
582
581
|
targets: pd.Series,
|
|
583
582
|
) -> pd.Series:
|
|
584
583
|
"""Calculates the "meta portfolio" score:
|
|
585
|
-
- rank, normalize, and power
|
|
586
|
-
- convert signal into neutralized weights
|
|
584
|
+
- rank, normalize, and power each signal
|
|
585
|
+
- convert each signal into neutralized weights
|
|
586
|
+
- generate the stake-weighted portfolio
|
|
587
|
+
- calculate the gradient of the portfolio w.r.t. the stakes
|
|
587
588
|
- multiplying the weights by the targets
|
|
588
|
-
|
|
589
589
|
Arguments:
|
|
590
590
|
predictions: pd.DataFrame - the predictions to evaluate
|
|
591
591
|
stakes: pd.Series - the stakes to use as weights
|
|
@@ -599,22 +599,27 @@ def meta_portfolio_contribution(
|
|
|
599
599
|
predictions, neutralizers, sample_weights, targets = filter_sort_index_many(
|
|
600
600
|
[predictions, neutralizers, sample_weights, targets]
|
|
601
601
|
)
|
|
602
|
-
|
|
603
602
|
stake_weights = weight_normalize(stakes.fillna(0))
|
|
604
603
|
assert np.isclose(stake_weights.sum(), 1), "Stakes must sum to 1"
|
|
605
|
-
|
|
606
604
|
weights = tie_kept_rank__gaussianize__pow_1_5(predictions).apply(
|
|
607
605
|
lambda s_prime: generate_neutralized_weights(
|
|
608
606
|
s_prime, neutralizers, sample_weights
|
|
609
607
|
)
|
|
610
608
|
)
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
t = torch.tensor(targets.values)
|
|
609
|
+
w = weights[stakes.index].values
|
|
610
|
+
s = stake_weights.values
|
|
611
|
+
t = targets.values
|
|
615
612
|
swp = w @ s
|
|
616
613
|
swp = swp - swp.mean()
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
614
|
+
swp_abs_sum = np.sum(np.abs(swp))
|
|
615
|
+
swp_sign = np.sign(swp)
|
|
616
|
+
alpha_unnormalized_swp_grad = (
|
|
617
|
+
1
|
|
618
|
+
/ np.power(swp_abs_sum, 2)
|
|
619
|
+
* (swp_abs_sum * t - swp_sign * np.dot(swp, t)).reshape(-1, 1)
|
|
620
|
+
)
|
|
621
|
+
zero_mean_jac_vec_prod = (
|
|
622
|
+
alpha_unnormalized_swp_grad - alpha_unnormalized_swp_grad.mean()
|
|
623
|
+
)
|
|
624
|
+
mpc = (w.T @ zero_mean_jac_vec_prod).squeeze()
|
|
620
625
|
return pd.Series(mpc, index=stakes.index)
|
|
@@ -19,7 +19,8 @@ def churn(
|
|
|
19
19
|
|
|
20
20
|
For 2 given series with overlapping indices, churn is 1 - Spearman Correlation.
|
|
21
21
|
If top_bottom is provided, the churn is calculated as the average of the % of
|
|
22
|
-
tickers that stay in the top and bottom predictions.
|
|
22
|
+
tickers that stay in the top and bottom predictions. This is only relevant when
|
|
23
|
+
the series are rank signals and not portfolio weights.
|
|
23
24
|
|
|
24
25
|
Arguments:
|
|
25
26
|
s1: pd.Series - the first series to compare
|
|
@@ -43,3 +44,29 @@ def churn(
|
|
|
43
44
|
assert s1.std() > 0, "s1 must have non-zero standard deviation"
|
|
44
45
|
assert s2.std() > 0, "s2 must have non-zero standard deviation"
|
|
45
46
|
return 1 - spearman_correlation(s1, s2)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def turnover(
|
|
50
|
+
s1: pd.Series,
|
|
51
|
+
s2: pd.Series,
|
|
52
|
+
):
|
|
53
|
+
"""Calculate the turnover between two series. Turnover is the total change in weights between
|
|
54
|
+
the two series divided by 2.
|
|
55
|
+
|
|
56
|
+
For 2 given series with overlapping indices, join the series on index, fill nans with zeroes
|
|
57
|
+
and calculate turnover as the absolute total difference between the two series divided by 2.
|
|
58
|
+
This is only relevant when the series are portfolio weights and not rank signals.
|
|
59
|
+
|
|
60
|
+
Arguments:
|
|
61
|
+
s1: pd.Series - the first series to compare
|
|
62
|
+
s2: pd.Series - the second series to compare
|
|
63
|
+
top_bottom: Optional[int] - the number of top and bottom predictions to use
|
|
64
|
+
when calculating the correlation. Results in
|
|
65
|
+
2*top_bottom predictions.
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
float - the turnover between the two series
|
|
69
|
+
"""
|
|
70
|
+
s1, s2 = filter_sort_index(s1, s2)
|
|
71
|
+
turnover = (s1 - s2).abs().sum() / 2
|
|
72
|
+
return turnover
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: numerai-tools
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.2.dev1
|
|
4
4
|
Summary: A collection of open-source tools to help interact with Numerai, model data, and automate submissions.
|
|
5
5
|
Home-page: https://github.com/numerai/numerai-tools
|
|
6
6
|
Maintainer: Numerai
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from setuptools import setup
|
|
2
2
|
from setuptools import find_packages
|
|
3
3
|
|
|
4
|
-
VERSION = "0.4.
|
|
4
|
+
VERSION = "0.4.2.dev1"
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
def load(path):
|
|
@@ -43,6 +43,5 @@ if __name__ == "__main__":
|
|
|
43
43
|
"numpy>=2.0.0,<3.0.0",
|
|
44
44
|
"scipy>=1.13.0,<2.0.0",
|
|
45
45
|
"scikit-learn>=1.5.0,<2.0.0",
|
|
46
|
-
"torch",
|
|
47
46
|
],
|
|
48
47
|
)
|
|
@@ -318,8 +318,8 @@ class TestScoring(unittest.TestCase):
|
|
|
318
318
|
[5, 1],
|
|
319
319
|
]
|
|
320
320
|
)
|
|
321
|
-
v = pd.Series([
|
|
322
|
-
t = pd.Series([1,
|
|
321
|
+
v = pd.Series([1, 0.5, 1, 0.5, 1]).T
|
|
322
|
+
t = pd.Series([1, 0, 1, 0, 1]).T
|
|
323
323
|
score = alpha(s, N, v, t)
|
|
324
324
|
np.testing.assert_allclose(score, 0.0, atol=1e-14, rtol=1e-14)
|
|
325
325
|
|
|
@@ -3,7 +3,7 @@ import unittest
|
|
|
3
3
|
import numpy as np
|
|
4
4
|
import pandas as pd # type: ignore
|
|
5
5
|
|
|
6
|
-
from numerai_tools.signals import churn
|
|
6
|
+
from numerai_tools.signals import churn, turnover
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class TestSignals(unittest.TestCase):
|
|
@@ -39,6 +39,13 @@ class TestSignals(unittest.TestCase):
|
|
|
39
39
|
tmp = churn(self.up, self.constant, top_bottom=2)
|
|
40
40
|
assert np.isclose(tmp, 0), tmp
|
|
41
41
|
|
|
42
|
+
def test_turnover(self):
|
|
43
|
+
assert np.isclose(turnover(self.up, self.up), 0)
|
|
44
|
+
assert np.isclose(turnover(self.up, self.up_down), 3)
|
|
45
|
+
assert np.isclose(turnover(self.up, self.oscillate), 4.5)
|
|
46
|
+
assert np.isclose(turnover(self.up, self.down), 6)
|
|
47
|
+
assert np.isclose(turnover(self.up, self.constant), 3.5)
|
|
48
|
+
|
|
42
49
|
|
|
43
50
|
if __name__ == "__main__":
|
|
44
51
|
unittest.main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{numerai_tools-0.4.0.dev2 → numerai_tools-0.4.2.dev1}/numerai_tools.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|