numerapi 2.18.0__tar.gz → 2.19.0__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.
- {numerapi-2.18.0 → numerapi-2.19.0}/PKG-INFO +1 -1
- {numerapi-2.18.0 → numerapi-2.19.0}/numerapi/__init__.py +1 -0
- {numerapi-2.18.0 → numerapi-2.19.0}/numerapi/base_api.py +80 -1
- numerapi-2.19.0/numerapi/cryptoapi.py +8 -0
- {numerapi-2.18.0 → numerapi-2.19.0}/numerapi/numerapi.py +1 -84
- {numerapi-2.18.0 → numerapi-2.19.0}/numerapi/signalsapi.py +15 -24
- {numerapi-2.18.0 → numerapi-2.19.0}/numerapi.egg-info/PKG-INFO +1 -1
- {numerapi-2.18.0 → numerapi-2.19.0}/numerapi.egg-info/SOURCES.txt +1 -0
- {numerapi-2.18.0 → numerapi-2.19.0}/setup.py +1 -1
- {numerapi-2.18.0 → numerapi-2.19.0}/LICENSE +0 -0
- {numerapi-2.18.0 → numerapi-2.19.0}/README.md +0 -0
- {numerapi-2.18.0 → numerapi-2.19.0}/numerapi/cli.py +0 -0
- {numerapi-2.18.0 → numerapi-2.19.0}/numerapi/utils.py +0 -0
- {numerapi-2.18.0 → numerapi-2.19.0}/numerapi.egg-info/dependency_links.txt +0 -0
- {numerapi-2.18.0 → numerapi-2.19.0}/numerapi.egg-info/entry_points.txt +0 -0
- {numerapi-2.18.0 → numerapi-2.19.0}/numerapi.egg-info/requires.txt +0 -0
- {numerapi-2.18.0 → numerapi-2.19.0}/numerapi.egg-info/top_level.txt +0 -0
- {numerapi-2.18.0 → numerapi-2.19.0}/setup.cfg +0 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import os
|
|
4
4
|
import datetime
|
|
5
5
|
import logging
|
|
6
|
-
from typing import Dict, List
|
|
6
|
+
from typing import Dict, List, Union, Tuple
|
|
7
7
|
from io import BytesIO
|
|
8
8
|
import pytz
|
|
9
9
|
|
|
@@ -655,6 +655,7 @@ class Api:
|
|
|
655
655
|
* validationFncV4 (`float`)
|
|
656
656
|
* validationIcV2 (`float`)
|
|
657
657
|
* validationRic (`float`)
|
|
658
|
+
* validationBmc (`float`)
|
|
658
659
|
* validationCorrPlusMmcStd (`float`)
|
|
659
660
|
* validationMmcMean (`float`)
|
|
660
661
|
* validationCorrStdRating (`float`)
|
|
@@ -686,6 +687,7 @@ class Api:
|
|
|
686
687
|
* validationCorrV4CorrWExamplePreds (`float`)
|
|
687
688
|
* validationCorrV4MaxDrawdown (`float`)
|
|
688
689
|
* validationCorrV4Mean (`float`)
|
|
690
|
+
* validationBmcMean (`float`)
|
|
689
691
|
* validationCorrV4Sharpe (`float`)
|
|
690
692
|
* validationCorrV4Std (`float`)
|
|
691
693
|
* validationFeatureNeutralCorrV3Mean (`float`)
|
|
@@ -737,6 +739,7 @@ class Api:
|
|
|
737
739
|
validationFncV4
|
|
738
740
|
validationIcV2
|
|
739
741
|
validationRic
|
|
742
|
+
validationBmc
|
|
740
743
|
}
|
|
741
744
|
status
|
|
742
745
|
trainedOnVal
|
|
@@ -767,6 +770,7 @@ class Api:
|
|
|
767
770
|
validationMmcSharpeRating
|
|
768
771
|
validationMmcStd
|
|
769
772
|
validationMmcStdRating
|
|
773
|
+
validationBmcMean
|
|
770
774
|
|
|
771
775
|
validationAdjustedSharpe
|
|
772
776
|
validationApy
|
|
@@ -1624,3 +1628,78 @@ class Api:
|
|
|
1624
1628
|
dest_path = data["filename"]
|
|
1625
1629
|
path = utils.download_file(data["url"], dest_path)
|
|
1626
1630
|
return path
|
|
1631
|
+
|
|
1632
|
+
def upload_predictions(self, file_path: str = "predictions.csv",
|
|
1633
|
+
model_id: str = None,
|
|
1634
|
+
df: pd.DataFrame = None,
|
|
1635
|
+
data_datestamp: int = None,
|
|
1636
|
+
timeout: Union[None, float, Tuple[float, float]] = (10, 600)
|
|
1637
|
+
) -> str:
|
|
1638
|
+
"""Upload predictions from file.
|
|
1639
|
+
Will read TRIGGER_ID from the environment if this model is enabled with
|
|
1640
|
+
a Numerai Compute cluster setup by Numerai CLI.
|
|
1641
|
+
|
|
1642
|
+
Args:
|
|
1643
|
+
file_path (str): CSV file with predictions that will get uploaded
|
|
1644
|
+
model_id (str): Target model UUID (required for accounts with
|
|
1645
|
+
multiple models)
|
|
1646
|
+
df (pandas.DataFrame): pandas DataFrame to upload, if function is
|
|
1647
|
+
given df and file_path, df will be uploaded.
|
|
1648
|
+
data_datestamp (int): Data lag, in case submission is done using
|
|
1649
|
+
data from the previous day(s).
|
|
1650
|
+
timeout (float|tuple(float,float)): waiting time (connection timeout,
|
|
1651
|
+
read timeout)
|
|
1652
|
+
|
|
1653
|
+
Returns:
|
|
1654
|
+
str: submission_id
|
|
1655
|
+
|
|
1656
|
+
Example:
|
|
1657
|
+
>>> api = NumerAPI(secret_key="..", public_id="..")
|
|
1658
|
+
>>> model_id = api.get_models()['uuazed']
|
|
1659
|
+
>>> api.upload_predictions("prediction.cvs", model_id=model_id)
|
|
1660
|
+
'93c46857-fed9-4594-981e-82db2b358daf'
|
|
1661
|
+
>>> # upload from pandas DataFrame directly:
|
|
1662
|
+
>>> api.upload_predictions(df=predictions_df, model_id=model_id)
|
|
1663
|
+
"""
|
|
1664
|
+
self.logger.info("uploading predictions...")
|
|
1665
|
+
|
|
1666
|
+
# write the pandas DataFrame as a binary buffer if provided
|
|
1667
|
+
buffer_csv = None
|
|
1668
|
+
|
|
1669
|
+
if df is not None:
|
|
1670
|
+
buffer_csv = BytesIO(df.to_csv(index=False).encode())
|
|
1671
|
+
buffer_csv.name = file_path
|
|
1672
|
+
|
|
1673
|
+
upload_auth = self._upload_auth(
|
|
1674
|
+
'submission_upload_auth', file_path, self.tournament_id, model_id)
|
|
1675
|
+
|
|
1676
|
+
# get compute id if available and pass it along
|
|
1677
|
+
headers = {"x_compute_id": os.getenv("NUMERAI_COMPUTE_ID")}
|
|
1678
|
+
with open(file_path, 'rb') if df is None else buffer_csv as file:
|
|
1679
|
+
requests.put(
|
|
1680
|
+
upload_auth['url'], data=file.read(), headers=headers,
|
|
1681
|
+
timeout=timeout)
|
|
1682
|
+
create_query = '''
|
|
1683
|
+
mutation($filename: String!
|
|
1684
|
+
$tournament: Int!
|
|
1685
|
+
$modelId: String
|
|
1686
|
+
$triggerId: String,
|
|
1687
|
+
$dataDatestamp: Int) {
|
|
1688
|
+
create_submission(filename: $filename
|
|
1689
|
+
tournament: $tournament
|
|
1690
|
+
modelId: $modelId
|
|
1691
|
+
triggerId: $triggerId
|
|
1692
|
+
source: "numerapi"
|
|
1693
|
+
dataDatestamp: $dataDatestamp) {
|
|
1694
|
+
id
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
'''
|
|
1698
|
+
arguments = {'filename': upload_auth['filename'],
|
|
1699
|
+
'tournament': self.tournament_id,
|
|
1700
|
+
'modelId': model_id,
|
|
1701
|
+
'triggerId': os.getenv('TRIGGER_ID', None),
|
|
1702
|
+
'dataDatestamp': data_datestamp}
|
|
1703
|
+
create = self.raw_query(create_query, arguments, authorization=True)
|
|
1704
|
+
submission_id = create['data']['create_submission']['id']
|
|
1705
|
+
return submission_id
|
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
"""API for Numerai Classic"""
|
|
2
2
|
|
|
3
|
-
import os
|
|
4
3
|
import decimal
|
|
5
|
-
from typing import List, Dict
|
|
6
|
-
from io import BytesIO
|
|
7
|
-
|
|
8
|
-
import requests
|
|
9
|
-
import pandas as pd
|
|
4
|
+
from typing import List, Dict
|
|
10
5
|
|
|
11
6
|
from numerapi import utils
|
|
12
7
|
from numerapi import base_api
|
|
@@ -245,84 +240,6 @@ class NumerAPI(base_api.Api):
|
|
|
245
240
|
_ = model_id
|
|
246
241
|
self.logger.warning("Method submission_status is DEPRECATED and will be removed soon.")
|
|
247
242
|
|
|
248
|
-
def upload_predictions(self, file_path: str = "predictions.csv",
|
|
249
|
-
tournament: int = 8,
|
|
250
|
-
model_id: str = None,
|
|
251
|
-
df: pd.DataFrame = None,
|
|
252
|
-
data_datestamp: int = None,
|
|
253
|
-
timeout: Union[None, float, Tuple[float, float]] = (10, 600),
|
|
254
|
-
) -> str:
|
|
255
|
-
"""Upload predictions from file.
|
|
256
|
-
Will read TRIGGER_ID from the environment if this model is enabled with
|
|
257
|
-
a Numerai Compute cluster setup by Numerai CLI.
|
|
258
|
-
|
|
259
|
-
Args:
|
|
260
|
-
file_path (str): CSV file with predictions that will get uploaded
|
|
261
|
-
tournament (int): ID of the tournament (optional, defaults to 8)
|
|
262
|
-
-- DEPRECATED there is only one tournament nowadays
|
|
263
|
-
model_id (str): Target model UUID (required for accounts with
|
|
264
|
-
multiple models)
|
|
265
|
-
df (pandas.DataFrame): pandas DataFrame to upload, if function is
|
|
266
|
-
given df and file_path, df will be uploaded.
|
|
267
|
-
data_datestamp (int): Data lag, in case submission is done using
|
|
268
|
-
data from the previous day(s).
|
|
269
|
-
timeout (float|tuple(float,float)): waiting time (connection timeout,
|
|
270
|
-
read timeout)
|
|
271
|
-
|
|
272
|
-
Returns:
|
|
273
|
-
str: submission_id
|
|
274
|
-
|
|
275
|
-
Example:
|
|
276
|
-
>>> api = NumerAPI(secret_key="..", public_id="..")
|
|
277
|
-
>>> model_id = api.get_models()['uuazed']
|
|
278
|
-
>>> api.upload_predictions("prediction.cvs", model_id=model_id)
|
|
279
|
-
'93c46857-fed9-4594-981e-82db2b358daf'
|
|
280
|
-
>>> # upload from pandas DataFrame directly:
|
|
281
|
-
>>> api.upload_predictions(df=predictions_df, model_id=model_id)
|
|
282
|
-
"""
|
|
283
|
-
self.logger.info("uploading predictions...")
|
|
284
|
-
|
|
285
|
-
# write the pandas DataFrame as a binary buffer if provided
|
|
286
|
-
buffer_csv = None
|
|
287
|
-
|
|
288
|
-
if df is not None:
|
|
289
|
-
buffer_csv = BytesIO(df.to_csv(index=False).encode())
|
|
290
|
-
buffer_csv.name = file_path
|
|
291
|
-
|
|
292
|
-
upload_auth = self._upload_auth(
|
|
293
|
-
'submission_upload_auth', file_path, tournament, model_id)
|
|
294
|
-
|
|
295
|
-
# get compute id if available and pass it along
|
|
296
|
-
headers = {"x_compute_id": os.getenv("NUMERAI_COMPUTE_ID")}
|
|
297
|
-
with open(file_path, 'rb') if df is None else buffer_csv as file:
|
|
298
|
-
requests.put(
|
|
299
|
-
upload_auth['url'], data=file.read(), headers=headers,
|
|
300
|
-
timeout=timeout)
|
|
301
|
-
create_query = '''
|
|
302
|
-
mutation($filename: String!
|
|
303
|
-
$tournament: Int!
|
|
304
|
-
$modelId: String
|
|
305
|
-
$triggerId: String,
|
|
306
|
-
$dataDatestamp: Int) {
|
|
307
|
-
create_submission(filename: $filename
|
|
308
|
-
tournament: $tournament
|
|
309
|
-
modelId: $modelId
|
|
310
|
-
triggerId: $triggerId
|
|
311
|
-
source: "numerapi"
|
|
312
|
-
dataDatestamp: $dataDatestamp) {
|
|
313
|
-
id
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
'''
|
|
317
|
-
arguments = {'filename': upload_auth['filename'],
|
|
318
|
-
'tournament': tournament,
|
|
319
|
-
'modelId': model_id,
|
|
320
|
-
'triggerId': os.getenv('TRIGGER_ID', None),
|
|
321
|
-
'dataDatestamp': data_datestamp}
|
|
322
|
-
create = self.raw_query(create_query, arguments, authorization=True)
|
|
323
|
-
submission_id = create['data']['create_submission']['id']
|
|
324
|
-
return submission_id
|
|
325
|
-
|
|
326
243
|
def get_leaderboard(self, limit: int = 50, offset: int = 0) -> List[Dict]:
|
|
327
244
|
"""Get the current model leaderboard
|
|
328
245
|
|
|
@@ -82,7 +82,8 @@ class SignalsAPI(base_api.Api):
|
|
|
82
82
|
def upload_predictions(self, file_path: str = "predictions.csv",
|
|
83
83
|
model_id: str = None,
|
|
84
84
|
df: pd.DataFrame = None,
|
|
85
|
-
|
|
85
|
+
data_datestamp: int = None,
|
|
86
|
+
timeout: Union[None, float, Tuple[float, float]] = (10, 600)
|
|
86
87
|
) -> str:
|
|
87
88
|
"""Upload predictions from file.
|
|
88
89
|
Will read TRIGGER_ID from the environment if this model is enabled with
|
|
@@ -118,45 +119,35 @@ class SignalsAPI(base_api.Api):
|
|
|
118
119
|
buffer_csv = BytesIO(df.to_csv(index=False).encode())
|
|
119
120
|
buffer_csv.name = file_path
|
|
120
121
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
submissionUploadSignalsAuth(filename: $filename
|
|
125
|
-
modelId: $modelId) {
|
|
126
|
-
filename
|
|
127
|
-
url
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
'''
|
|
131
|
-
|
|
132
|
-
arguments = {'filename': os.path.basename(file_path),
|
|
133
|
-
'modelId': model_id}
|
|
134
|
-
submission_resp = self.raw_query(auth_query, arguments,
|
|
135
|
-
authorization=True)
|
|
136
|
-
auth = submission_resp['data']['submissionUploadSignalsAuth']
|
|
122
|
+
upload_auth = self._upload_auth(
|
|
123
|
+
'submissionUploadSignalsAuth', file_path,
|
|
124
|
+
self.tournament_id, model_id)
|
|
137
125
|
|
|
138
126
|
# get compute id if available and pass it along
|
|
139
127
|
headers = {"x_compute_id": os.getenv("NUMERAI_COMPUTE_ID")}
|
|
140
128
|
|
|
141
129
|
with open(file_path, 'rb') if df is None else buffer_csv as file:
|
|
142
|
-
requests.put(
|
|
130
|
+
requests.put(upload_auth['url'], data=file.read(),
|
|
143
131
|
headers=headers, timeout=timeout)
|
|
144
132
|
create_query = '''
|
|
145
133
|
mutation($filename: String!
|
|
146
134
|
$modelId: String
|
|
147
|
-
$triggerId: String
|
|
135
|
+
$triggerId: String
|
|
136
|
+
$ddataDatestamp: Int) {
|
|
148
137
|
createSignalsSubmission(filename: $filename
|
|
149
138
|
modelId: $modelId
|
|
150
139
|
triggerId: $triggerId
|
|
151
|
-
source: "numerapi"
|
|
140
|
+
source: "numerapi"
|
|
141
|
+
dataDatestamp: $dataDatestamp) {
|
|
152
142
|
id
|
|
153
143
|
firstEffectiveDate
|
|
154
144
|
}
|
|
155
145
|
}
|
|
156
146
|
'''
|
|
157
|
-
arguments = {'filename':
|
|
147
|
+
arguments = {'filename': upload_auth['filename'],
|
|
158
148
|
'modelId': model_id,
|
|
159
|
-
'triggerId': os.getenv('TRIGGER_ID', None)
|
|
149
|
+
'triggerId': os.getenv('TRIGGER_ID', None),
|
|
150
|
+
'dataDatestamp': data_datestamp}
|
|
160
151
|
create = self.raw_query(create_query, arguments, authorization=True)
|
|
161
152
|
return create['data']['createSignalsSubmission']['id']
|
|
162
153
|
|
|
@@ -307,8 +298,8 @@ class SignalsAPI(base_api.Api):
|
|
|
307
298
|
>>> SignalsAPI().ticker_universe()
|
|
308
299
|
["MSFT", "AMZN", "APPL", ...]
|
|
309
300
|
"""
|
|
310
|
-
path = self.download_dataset("signals/
|
|
311
|
-
return pd.
|
|
301
|
+
path = self.download_dataset("signals/v1.0/live.parquet")
|
|
302
|
+
return pd.read_parquet(path).numerai_ticker.tolist()
|
|
312
303
|
|
|
313
304
|
def download_validation_data(self) -> None:
|
|
314
305
|
"""download CSV file with historical targets and ticker universe
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|