numerai-tools 0.6.1.dev0__tar.gz → 0.6.1.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.6.1.dev0 → numerai_tools-0.6.1.dev1}/PKG-INFO +1 -19
- {numerai_tools-0.6.1.dev0 → numerai_tools-0.6.1.dev1}/README.md +1 -18
- {numerai_tools-0.6.1.dev0 → numerai_tools-0.6.1.dev1}/numerai_tools/scoring.py +5 -30
- {numerai_tools-0.6.1.dev0 → numerai_tools-0.6.1.dev1}/numerai_tools/signals.py +0 -7
- {numerai_tools-0.6.1.dev0 → numerai_tools-0.6.1.dev1}/pyproject.toml +1 -1
- {numerai_tools-0.6.1.dev0 → numerai_tools-0.6.1.dev1}/LICENSE +0 -0
- {numerai_tools-0.6.1.dev0 → numerai_tools-0.6.1.dev1}/numerai_tools/__init__.py +0 -0
- {numerai_tools-0.6.1.dev0 → numerai_tools-0.6.1.dev1}/numerai_tools/py.typed +0 -0
- {numerai_tools-0.6.1.dev0 → numerai_tools-0.6.1.dev1}/numerai_tools/submissions.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: numerai-tools
|
|
3
|
-
Version: 0.6.1.
|
|
3
|
+
Version: 0.6.1.dev1
|
|
4
4
|
Summary: A collection of open-source tools to help interact with Numerai, model data, and automate submissions.
|
|
5
5
|
License: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -43,21 +43,3 @@ pip install numerai-tools
|
|
|
43
43
|
- The `submissions.py` module provides helper functions to ensure your submissions are valid and formatted correctly. Use this in your automated prediction pipelines to ensure uploads don't fail.
|
|
44
44
|
|
|
45
45
|
- The `signals.py` module provides code specific to Numerai Signals such as churn and turnover. Use this to ensure your Signals submissions are properly formatted.
|
|
46
|
-
|
|
47
|
-
## Configurable neutralized weights
|
|
48
|
-
|
|
49
|
-
`generate_neutralized_weights`, `alpha`, and `meta_portfolio_contribution` accept
|
|
50
|
-
a `power` argument applied after ranking and gaussianization. The default is `1`.
|
|
51
|
-
Pass `power=1.5` when reproducing historical Alpha or MPC definitions:
|
|
52
|
-
|
|
53
|
-
```python
|
|
54
|
-
from numerai_tools.scoring import generate_neutralized_weights
|
|
55
|
-
|
|
56
|
-
weights = generate_neutralized_weights(
|
|
57
|
-
predictions,
|
|
58
|
-
neutralizers,
|
|
59
|
-
sample_weights,
|
|
60
|
-
power=1.5,
|
|
61
|
-
)
|
|
62
|
-
```
|
|
63
|
-
|
|
@@ -12,21 +12,4 @@ pip install numerai-tools
|
|
|
12
12
|
|
|
13
13
|
- The `submissions.py` module provides helper functions to ensure your submissions are valid and formatted correctly. Use this in your automated prediction pipelines to ensure uploads don't fail.
|
|
14
14
|
|
|
15
|
-
- The `signals.py` module provides code specific to Numerai Signals such as churn and turnover. Use this to ensure your Signals submissions are properly formatted.
|
|
16
|
-
|
|
17
|
-
## Configurable neutralized weights
|
|
18
|
-
|
|
19
|
-
`generate_neutralized_weights`, `alpha`, and `meta_portfolio_contribution` accept
|
|
20
|
-
a `power` argument applied after ranking and gaussianization. The default is `1`.
|
|
21
|
-
Pass `power=1.5` when reproducing historical Alpha or MPC definitions:
|
|
22
|
-
|
|
23
|
-
```python
|
|
24
|
-
from numerai_tools.scoring import generate_neutralized_weights
|
|
25
|
-
|
|
26
|
-
weights = generate_neutralized_weights(
|
|
27
|
-
predictions,
|
|
28
|
-
neutralizers,
|
|
29
|
-
sample_weights,
|
|
30
|
-
power=1.5,
|
|
31
|
-
)
|
|
32
|
-
```
|
|
15
|
+
- The `signals.py` module provides code specific to Numerai Signals such as churn and turnover. Use this to ensure your Signals submissions are properly formatted.
|
|
@@ -161,7 +161,7 @@ def min_max_normalize(s: pd.Series) -> pd.Series:
|
|
|
161
161
|
|
|
162
162
|
def variance_normalize(df: pd.DataFrame) -> pd.DataFrame:
|
|
163
163
|
"""Scale a df such that all columns have std == 1."""
|
|
164
|
-
return
|
|
164
|
+
return df / np.std(df, axis=0)
|
|
165
165
|
|
|
166
166
|
|
|
167
167
|
def weight_normalize(s: S1) -> S1:
|
|
@@ -446,14 +446,7 @@ def tie_kept_rank__gaussianize__pow_1_5(df: pd.DataFrame) -> pd.DataFrame:
|
|
|
446
446
|
Returns:
|
|
447
447
|
pd.DataFrame - the resulting data after applying the 3 functions
|
|
448
448
|
"""
|
|
449
|
-
return
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
def _tie_kept_rank__gaussianize__power(
|
|
453
|
-
df: pd.DataFrame, power_value: float
|
|
454
|
-
) -> pd.DataFrame:
|
|
455
|
-
"""Tie-kept rank, gaussianize, then apply a configurable power."""
|
|
456
|
-
return power(gaussian(tie_kept_rank(df)), power_value)
|
|
449
|
+
return power(gaussian(tie_kept_rank(df)), 1.5)
|
|
457
450
|
|
|
458
451
|
|
|
459
452
|
def tie_kept_rank__gaussianize__neutralize__variance_normalize(
|
|
@@ -575,21 +568,11 @@ def generate_neutralized_weights(
|
|
|
575
568
|
neutralizers: pd.DataFrame,
|
|
576
569
|
sample_weights: pd.Series,
|
|
577
570
|
center_and_normalize: bool = False,
|
|
578
|
-
power: float = 1,
|
|
579
571
|
) -> pd.DataFrame:
|
|
580
|
-
"""Convert predictions into neutralized, sample-weighted portfolio weights.
|
|
581
|
-
|
|
582
|
-
Arguments:
|
|
583
|
-
predictions: prediction columns to transform
|
|
584
|
-
neutralizers: factors to neutralize the transformed predictions against
|
|
585
|
-
sample_weights: per-row weights applied during and after neutralization
|
|
586
|
-
center_and_normalize: center and normalize the resulting portfolio weights
|
|
587
|
-
power: exponent applied after ranking and gaussianization; defaults to 1
|
|
588
|
-
"""
|
|
589
572
|
assert not predictions.isna().any().any(), "Predictions contain NaNs"
|
|
590
573
|
assert not neutralizers.isna().any().any(), "Normalization factors contain NaNs"
|
|
591
574
|
assert not sample_weights.isna().any(), "Weights contain NaNs"
|
|
592
|
-
ranked_predictions =
|
|
575
|
+
ranked_predictions = tie_kept_rank__gaussianize__pow_1_5(predictions)
|
|
593
576
|
ranked_predictions, neutralizers, sample_weights = filter_sort_index_many(
|
|
594
577
|
[ranked_predictions, neutralizers, sample_weights]
|
|
595
578
|
)
|
|
@@ -609,7 +592,6 @@ def alpha(
|
|
|
609
592
|
neutralizers: pd.DataFrame,
|
|
610
593
|
sample_weights: pd.Series,
|
|
611
594
|
targets: pd.Series,
|
|
612
|
-
power: float = 1,
|
|
613
595
|
) -> pd.Series:
|
|
614
596
|
"""Calculates the "alpha" score:
|
|
615
597
|
- rank, normalize, and power the signal
|
|
@@ -621,13 +603,10 @@ def alpha(
|
|
|
621
603
|
neutralizers: pd.DataFrame - the neutralization columns
|
|
622
604
|
sample_weights: pd.Series - the universe sampling weights
|
|
623
605
|
targets: pd.Series - the live targets to evaluate against
|
|
624
|
-
power: float - exponent applied after ranking and gaussianization
|
|
625
606
|
"""
|
|
626
607
|
targets = center(targets)
|
|
627
608
|
predictions, targets = filter_sort_index(predictions, targets)
|
|
628
|
-
weights = generate_neutralized_weights(
|
|
629
|
-
predictions, neutralizers, sample_weights, power=power
|
|
630
|
-
)
|
|
609
|
+
weights = generate_neutralized_weights(predictions, neutralizers, sample_weights)
|
|
631
610
|
alpha_scores = weights.apply(lambda w: w @ targets) / len(targets)
|
|
632
611
|
return alpha_scores
|
|
633
612
|
|
|
@@ -638,7 +617,6 @@ def meta_portfolio_contribution(
|
|
|
638
617
|
neutralizers: pd.DataFrame,
|
|
639
618
|
sample_weights: pd.Series,
|
|
640
619
|
targets: pd.Series,
|
|
641
|
-
power: float = 1,
|
|
642
620
|
) -> pd.Series:
|
|
643
621
|
"""Calculates the "meta portfolio" gradient w.r.t. stakes:
|
|
644
622
|
- rank, normalize, and power each signal
|
|
@@ -654,7 +632,6 @@ def meta_portfolio_contribution(
|
|
|
654
632
|
neutralizers: pd.DataFrame - the neutralization columns
|
|
655
633
|
sample_weights: pd.Series - the universe sampling weights
|
|
656
634
|
targets: pd.Series - the live targets to evaluate against
|
|
657
|
-
power: float - exponent applied after ranking and gaussianization
|
|
658
635
|
"""
|
|
659
636
|
# Align predictions and targets on the same index / universe
|
|
660
637
|
predictions, targets = filter_sort_index(predictions, targets)
|
|
@@ -667,9 +644,7 @@ def meta_portfolio_contribution(
|
|
|
667
644
|
assert np.isclose(stake_weights.sum(), 1), "Stakes must sum to 1"
|
|
668
645
|
|
|
669
646
|
# Generate neutralized weights W(predictions, neutralizers, sample_weights)
|
|
670
|
-
weights = generate_neutralized_weights(
|
|
671
|
-
predictions, neutralizers, sample_weights, power=power
|
|
672
|
-
)
|
|
647
|
+
weights = generate_neutralized_weights(predictions, neutralizers, sample_weights)
|
|
673
648
|
|
|
674
649
|
# Extract aligned matrices/vectors
|
|
675
650
|
w = cast(np.ndarray, weights[stakes.index].values) # W ∈ R^{N×K}
|
|
@@ -81,7 +81,6 @@ def calculate_max_churn_and_turnover(
|
|
|
81
81
|
prev_subs: dict[str, pd.Series],
|
|
82
82
|
prev_neutralizers: dict[str, pd.DataFrame],
|
|
83
83
|
prev_sample_weights: dict[str, pd.Series],
|
|
84
|
-
power: float = 1.5,
|
|
85
84
|
) -> Tuple[float, float]:
|
|
86
85
|
"""Calculate the maximum churn and turnover of the current submission with respect to previous submissions.
|
|
87
86
|
This function iterates over previous submissions and calculates churn and turnover for each submission
|
|
@@ -125,10 +124,6 @@ def calculate_max_churn_and_turnover(
|
|
|
125
124
|
Series is indexed on the same type of tickers/ids as the current submission.
|
|
126
125
|
We expect each of these to cover the full universe of their respective eras.
|
|
127
126
|
|
|
128
|
-
power: float
|
|
129
|
-
- exponent applied after ranking and gaussianization. Defaults to 1.5
|
|
130
|
-
to preserve the legacy Signals turnover definition.
|
|
131
|
-
|
|
132
127
|
Returns:
|
|
133
128
|
prev_week_max_churn -- the maximum churn from previous submissions
|
|
134
129
|
prev_week_max_turnover -- the maximum turnover from previous submissions
|
|
@@ -157,7 +152,6 @@ def calculate_max_churn_and_turnover(
|
|
|
157
152
|
curr_neutralizer,
|
|
158
153
|
curr_sample_weight,
|
|
159
154
|
center_and_normalize=True,
|
|
160
|
-
power=power,
|
|
161
155
|
)[curr_sub.name]
|
|
162
156
|
for datestamp in prev_subs:
|
|
163
157
|
prev_sub = prev_subs[datestamp]
|
|
@@ -187,7 +181,6 @@ def calculate_max_churn_and_turnover(
|
|
|
187
181
|
prev_neutralizer,
|
|
188
182
|
prev_sample_weight,
|
|
189
183
|
center_and_normalize=True,
|
|
190
|
-
power=power,
|
|
191
184
|
)[prev_sub.name]
|
|
192
185
|
try:
|
|
193
186
|
churn_val = abs(churn(curr_sub, prev_sub))
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "numerai-tools"
|
|
3
|
-
version = "0.6.1.
|
|
3
|
+
version = "0.6.1.dev1"
|
|
4
4
|
description = "A collection of open-source tools to help interact with Numerai, model data, and automate submissions."
|
|
5
5
|
authors = [
|
|
6
6
|
{name = "Numerai Engineering",email = "engineering@numer.ai"}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|