numerapi 2.17.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.17.0 → numerapi-2.19.0}/PKG-INFO +1 -2
- {numerapi-2.17.0 → numerapi-2.19.0}/README.md +0 -1
- {numerapi-2.17.0 → numerapi-2.19.0}/numerapi/__init__.py +1 -0
- {numerapi-2.17.0 → numerapi-2.19.0}/numerapi/base_api.py +188 -44
- numerapi-2.19.0/numerapi/cryptoapi.py +8 -0
- {numerapi-2.17.0 → numerapi-2.19.0}/numerapi/numerapi.py +2 -88
- {numerapi-2.17.0 → numerapi-2.19.0}/numerapi/signalsapi.py +18 -49
- {numerapi-2.17.0 → numerapi-2.19.0}/numerapi.egg-info/PKG-INFO +1 -2
- {numerapi-2.17.0 → numerapi-2.19.0}/numerapi.egg-info/SOURCES.txt +1 -0
- {numerapi-2.17.0 → numerapi-2.19.0}/setup.py +1 -1
- {numerapi-2.17.0 → numerapi-2.19.0}/LICENSE +0 -0
- {numerapi-2.17.0 → numerapi-2.19.0}/numerapi/cli.py +0 -0
- {numerapi-2.17.0 → numerapi-2.19.0}/numerapi/utils.py +0 -0
- {numerapi-2.17.0 → numerapi-2.19.0}/numerapi.egg-info/dependency_links.txt +0 -0
- {numerapi-2.17.0 → numerapi-2.19.0}/numerapi.egg-info/entry_points.txt +0 -0
- {numerapi-2.17.0 → numerapi-2.19.0}/numerapi.egg-info/requires.txt +0 -0
- {numerapi-2.17.0 → numerapi-2.19.0}/numerapi.egg-info/top_level.txt +0 -0
- {numerapi-2.17.0 → numerapi-2.19.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: numerapi
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.19.0
|
|
4
4
|
Summary: Automatically download and upload data for the Numerai machine learning competition
|
|
5
5
|
Home-page: https://github.com/uuazed/numerapi
|
|
6
6
|
Maintainer: uuazed
|
|
@@ -11,7 +11,6 @@ Description: [](ht
|
|
|
11
11
|
[](https://pypi.python.org/pypi/numerapi)
|
|
12
12
|
[](https://pepy.tech/project/numerapi)
|
|
13
13
|
[](http://numerapi.readthedocs.io/en/stable/?badge=stable)
|
|
14
|
-
[](https://requires.io/github/uuazed/numerapi/requirements/?branch=master)
|
|
15
14
|
|
|
16
15
|
# Numerai Python API
|
|
17
16
|
Automatically download and upload data for the Numerai machine learning
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
[](https://pypi.python.org/pypi/numerapi)
|
|
4
4
|
[](https://pepy.tech/project/numerapi)
|
|
5
5
|
[](http://numerapi.readthedocs.io/en/stable/?badge=stable)
|
|
6
|
-
[](https://requires.io/github/uuazed/numerapi/requirements/?branch=master)
|
|
7
6
|
|
|
8
7
|
# Numerai Python API
|
|
9
8
|
Automatically download and upload data for the Numerai machine learning
|
|
@@ -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
|
|
|
@@ -294,6 +294,37 @@ class Api:
|
|
|
294
294
|
utils.replace(data, "availableNmr", utils.parse_float_string)
|
|
295
295
|
return data
|
|
296
296
|
|
|
297
|
+
def models_of_account(self, account) -> Dict[str, str]:
|
|
298
|
+
"""Get all models (name and id) of an account
|
|
299
|
+
|
|
300
|
+
Args:
|
|
301
|
+
account (str): account name
|
|
302
|
+
|
|
303
|
+
Returns:
|
|
304
|
+
dict: modelname->model_id mapping, string->string
|
|
305
|
+
|
|
306
|
+
Example:
|
|
307
|
+
>>> api = NumerAPI()
|
|
308
|
+
>>> NumerAPI().models_of_account("uuazed")
|
|
309
|
+
{'uuazed': '9b157d9b-ce61-4ab5-9413-413f13a0c0a6', ...}
|
|
310
|
+
"""
|
|
311
|
+
query = """
|
|
312
|
+
query($username: Str!
|
|
313
|
+
$tournament: Int) {
|
|
314
|
+
accountProfile(username: $username
|
|
315
|
+
tournament: $tournament){
|
|
316
|
+
models {
|
|
317
|
+
id
|
|
318
|
+
displayName
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
"""
|
|
323
|
+
args = {"username": account, "tournament": self.tournament_id}
|
|
324
|
+
data = self.raw_query(query, args)['data']['accountProfile']['models']
|
|
325
|
+
return {item["displayName"]: item["id"]
|
|
326
|
+
for item in sorted(data, key=lambda x: x["displayName"])}
|
|
327
|
+
|
|
297
328
|
def get_models(self, tournament: int = None) -> Dict:
|
|
298
329
|
"""Get mapping of account model names to model ids for convenience
|
|
299
330
|
|
|
@@ -624,6 +655,7 @@ class Api:
|
|
|
624
655
|
* validationFncV4 (`float`)
|
|
625
656
|
* validationIcV2 (`float`)
|
|
626
657
|
* validationRic (`float`)
|
|
658
|
+
* validationBmc (`float`)
|
|
627
659
|
* validationCorrPlusMmcStd (`float`)
|
|
628
660
|
* validationMmcMean (`float`)
|
|
629
661
|
* validationCorrStdRating (`float`)
|
|
@@ -655,6 +687,7 @@ class Api:
|
|
|
655
687
|
* validationCorrV4CorrWExamplePreds (`float`)
|
|
656
688
|
* validationCorrV4MaxDrawdown (`float`)
|
|
657
689
|
* validationCorrV4Mean (`float`)
|
|
690
|
+
* validationBmcMean (`float`)
|
|
658
691
|
* validationCorrV4Sharpe (`float`)
|
|
659
692
|
* validationCorrV4Std (`float`)
|
|
660
693
|
* validationFeatureNeutralCorrV3Mean (`float`)
|
|
@@ -706,6 +739,7 @@ class Api:
|
|
|
706
739
|
validationFncV4
|
|
707
740
|
validationIcV2
|
|
708
741
|
validationRic
|
|
742
|
+
validationBmc
|
|
709
743
|
}
|
|
710
744
|
status
|
|
711
745
|
trainedOnVal
|
|
@@ -736,6 +770,7 @@ class Api:
|
|
|
736
770
|
validationMmcSharpeRating
|
|
737
771
|
validationMmcStd
|
|
738
772
|
validationMmcStdRating
|
|
773
|
+
validationBmcMean
|
|
739
774
|
|
|
740
775
|
validationAdjustedSharpe
|
|
741
776
|
validationApy
|
|
@@ -1165,49 +1200,6 @@ class Api:
|
|
|
1165
1200
|
"""
|
|
1166
1201
|
return self.stake_change(nmr, 'increase', model_id)
|
|
1167
1202
|
|
|
1168
|
-
def set_stake_type(self, model_id: str = None,
|
|
1169
|
-
corr_multiplier: int = 0,
|
|
1170
|
-
tc_multiplier: float = 0,
|
|
1171
|
-
take_profit: bool = False) -> Dict:
|
|
1172
|
-
"""Change stake type by model.
|
|
1173
|
-
|
|
1174
|
-
Args:
|
|
1175
|
-
model_id (str): Target model UUID (required for accounts with
|
|
1176
|
-
multiple models)
|
|
1177
|
-
corrMultiplier (int): multiplier of correlation for returns
|
|
1178
|
-
tcMultiplier (float): multiplier of TC for returns
|
|
1179
|
-
takeProfit (bool): determines whether payouts are returned to usr
|
|
1180
|
-
wallet or automatically staked to next round.
|
|
1181
|
-
|
|
1182
|
-
Returns:
|
|
1183
|
-
dict with confirmation that payout selection has been updated
|
|
1184
|
-
|
|
1185
|
-
Example:
|
|
1186
|
-
>>> api = NumerAPI(secret_key="..", public_id="..")
|
|
1187
|
-
>>> model = api.get_models()['uuazed']
|
|
1188
|
-
>>> api.set_stake_type(model, 1, 3)
|
|
1189
|
-
{'data': {'v2ChangePayoutSelection': 'payout selection updated'}}
|
|
1190
|
-
"""
|
|
1191
|
-
query = """mutation ($corrMultiplier: Float!
|
|
1192
|
-
$modelId: String!
|
|
1193
|
-
$takeProfit: Boolean!
|
|
1194
|
-
$tcMultiplier: Float!
|
|
1195
|
-
$tournamentNumber: Int!) {
|
|
1196
|
-
v2ChangePayoutSelection(corrMultiplier: $corrMultiplier
|
|
1197
|
-
modelId: $modelId
|
|
1198
|
-
takeProfit: $takeProfit
|
|
1199
|
-
tcMultiplier: $tcMultiplier
|
|
1200
|
-
tournamentNumber: $tournamentNumber)}
|
|
1201
|
-
"""
|
|
1202
|
-
args = {'modelId': model_id,
|
|
1203
|
-
'corrMultiplier': corr_multiplier,
|
|
1204
|
-
'tcMultiplier': tc_multiplier,
|
|
1205
|
-
'takeProfit': take_profit,
|
|
1206
|
-
'tournamentNumber': self.tournament_id}
|
|
1207
|
-
result = self.raw_query(query, args, authorization=True)
|
|
1208
|
-
|
|
1209
|
-
return result
|
|
1210
|
-
|
|
1211
1203
|
def check_round_open(self) -> bool:
|
|
1212
1204
|
"""Check if a round is currently open.
|
|
1213
1205
|
|
|
@@ -1284,6 +1276,83 @@ class Api:
|
|
|
1284
1276
|
is_new_round = open_time > now - datetime.timedelta(hours=hours)
|
|
1285
1277
|
return is_new_round
|
|
1286
1278
|
|
|
1279
|
+
def get_account_leaderboard(
|
|
1280
|
+
self, limit: int = 50, offset: int = 0) -> List[Dict]:
|
|
1281
|
+
"""Get the current account leaderboard
|
|
1282
|
+
|
|
1283
|
+
Args:
|
|
1284
|
+
limit (int): number of items to return (optional, defaults to 50)
|
|
1285
|
+
offset (int): number of items to skip (optional, defaults to 0)
|
|
1286
|
+
|
|
1287
|
+
Returns:
|
|
1288
|
+
list of dicts: list of leaderboard entries
|
|
1289
|
+
|
|
1290
|
+
Each dict contains the following items:
|
|
1291
|
+
|
|
1292
|
+
* username (`str`)
|
|
1293
|
+
* displayName (`str`)
|
|
1294
|
+
* rank (`int`)
|
|
1295
|
+
* nmrStaked (`decimal.Decimal`)
|
|
1296
|
+
* v2Corr20 (`float`)
|
|
1297
|
+
* cort20 (`float`)
|
|
1298
|
+
* corrV4 (`float`)
|
|
1299
|
+
* fncV4 (`float`)
|
|
1300
|
+
* icV2 (`float`)
|
|
1301
|
+
* mmc (`float`)
|
|
1302
|
+
* ric (`float`)
|
|
1303
|
+
* return1y (`float`)
|
|
1304
|
+
* return3m (`float`)
|
|
1305
|
+
* returnAllTime (`float`)
|
|
1306
|
+
* return1yNmr (`decimal.Decimal`)
|
|
1307
|
+
* return3mNmr (`decimal.Decimal`)
|
|
1308
|
+
* returnAllTimeNmr (`decimal.Decimal`)
|
|
1309
|
+
|
|
1310
|
+
Example:
|
|
1311
|
+
>>> numerapi.NumerAPI().get_account_leaderboard()
|
|
1312
|
+
[{'username': 'leonidas',
|
|
1313
|
+
'rank': 1,
|
|
1314
|
+
'nmrStaked': Decimal('3034.00'),
|
|
1315
|
+
...
|
|
1316
|
+
}]
|
|
1317
|
+
"""
|
|
1318
|
+
query = '''
|
|
1319
|
+
query($limit: Int!
|
|
1320
|
+
$offset: Int!
|
|
1321
|
+
$tournament: Int) {
|
|
1322
|
+
accountLeaderboard(limit: $limit
|
|
1323
|
+
offset: $offset
|
|
1324
|
+
tournament: $tournament) {
|
|
1325
|
+
displayName
|
|
1326
|
+
nmrStaked
|
|
1327
|
+
rank
|
|
1328
|
+
username
|
|
1329
|
+
v2Corr20
|
|
1330
|
+
cort20
|
|
1331
|
+
corJ60
|
|
1332
|
+
corrV4
|
|
1333
|
+
fncV4
|
|
1334
|
+
icV2
|
|
1335
|
+
mmc
|
|
1336
|
+
ric
|
|
1337
|
+
return1y
|
|
1338
|
+
return3m
|
|
1339
|
+
returnAllTime
|
|
1340
|
+
return1yNmr
|
|
1341
|
+
return3mNmr
|
|
1342
|
+
returnAllTimeNmr
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
'''
|
|
1346
|
+
args = {'limit': limit, 'offset': offset,
|
|
1347
|
+
"tournament": self.tournament_id}
|
|
1348
|
+
data = self.raw_query(query, args)['data']['accountLeaderboard']
|
|
1349
|
+
for item in data:
|
|
1350
|
+
utils.replace(item, "nmrStaked", utils.parse_float_string)
|
|
1351
|
+
utils.replace(item, "return1yNmr", utils.parse_float_string)
|
|
1352
|
+
utils.replace(item, "return3mNmr", utils.parse_float_string)
|
|
1353
|
+
utils.replace(item, "returnAllTimeNmr", utils.parse_float_string)
|
|
1354
|
+
return data
|
|
1355
|
+
|
|
1287
1356
|
def modelid_to_modelname(self, model_id: str) -> str:
|
|
1288
1357
|
"""Get model name from a model_id.
|
|
1289
1358
|
|
|
@@ -1559,3 +1628,78 @@ class Api:
|
|
|
1559
1628
|
dest_path = data["filename"]
|
|
1560
1629
|
path = utils.download_file(data["url"], dest_path)
|
|
1561
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
|
|
@@ -24,9 +19,6 @@ class NumerAPI(base_api.Api):
|
|
|
24
19
|
information and much more.
|
|
25
20
|
"""
|
|
26
21
|
|
|
27
|
-
PUBLIC_DATASETS_URL = \
|
|
28
|
-
"https://numerai-public-datasets.s3-us-west-2.amazonaws.com"
|
|
29
|
-
|
|
30
22
|
def __init__(self, *args, **kwargs):
|
|
31
23
|
base_api.Api.__init__(self, *args, **kwargs)
|
|
32
24
|
self.tournament_id = 8
|
|
@@ -248,86 +240,8 @@ class NumerAPI(base_api.Api):
|
|
|
248
240
|
_ = model_id
|
|
249
241
|
self.logger.warning("Method submission_status is DEPRECATED and will be removed soon.")
|
|
250
242
|
|
|
251
|
-
def upload_predictions(self, file_path: str = "predictions.csv",
|
|
252
|
-
tournament: int = 8,
|
|
253
|
-
model_id: str = None,
|
|
254
|
-
df: pd.DataFrame = None,
|
|
255
|
-
data_datestamp: int = None,
|
|
256
|
-
timeout: Union[None, float, Tuple[float, float]] = (10, 600),
|
|
257
|
-
) -> str:
|
|
258
|
-
"""Upload predictions from file.
|
|
259
|
-
Will read TRIGGER_ID from the environment if this model is enabled with
|
|
260
|
-
a Numerai Compute cluster setup by Numerai CLI.
|
|
261
|
-
|
|
262
|
-
Args:
|
|
263
|
-
file_path (str): CSV file with predictions that will get uploaded
|
|
264
|
-
tournament (int): ID of the tournament (optional, defaults to 8)
|
|
265
|
-
-- DEPRECATED there is only one tournament nowadays
|
|
266
|
-
model_id (str): Target model UUID (required for accounts with
|
|
267
|
-
multiple models)
|
|
268
|
-
df (pandas.DataFrame): pandas DataFrame to upload, if function is
|
|
269
|
-
given df and file_path, df will be uploaded.
|
|
270
|
-
data_datestamp (int): Data lag, in case submission is done using
|
|
271
|
-
data from the previous day(s).
|
|
272
|
-
timeout (float|tuple(float,float)): waiting time (connection timeout,
|
|
273
|
-
read timeout)
|
|
274
|
-
|
|
275
|
-
Returns:
|
|
276
|
-
str: submission_id
|
|
277
|
-
|
|
278
|
-
Example:
|
|
279
|
-
>>> api = NumerAPI(secret_key="..", public_id="..")
|
|
280
|
-
>>> model_id = api.get_models()['uuazed']
|
|
281
|
-
>>> api.upload_predictions("prediction.cvs", model_id=model_id)
|
|
282
|
-
'93c46857-fed9-4594-981e-82db2b358daf'
|
|
283
|
-
>>> # upload from pandas DataFrame directly:
|
|
284
|
-
>>> api.upload_predictions(df=predictions_df, model_id=model_id)
|
|
285
|
-
"""
|
|
286
|
-
self.logger.info("uploading predictions...")
|
|
287
|
-
|
|
288
|
-
# write the pandas DataFrame as a binary buffer if provided
|
|
289
|
-
buffer_csv = None
|
|
290
|
-
|
|
291
|
-
if df is not None:
|
|
292
|
-
buffer_csv = BytesIO(df.to_csv(index=False).encode())
|
|
293
|
-
buffer_csv.name = file_path
|
|
294
|
-
|
|
295
|
-
upload_auth = self._upload_auth(
|
|
296
|
-
'submission_upload_auth', file_path, tournament, model_id)
|
|
297
|
-
|
|
298
|
-
# get compute id if available and pass it along
|
|
299
|
-
headers = {"x_compute_id": os.getenv("NUMERAI_COMPUTE_ID")}
|
|
300
|
-
with open(file_path, 'rb') if df is None else buffer_csv as file:
|
|
301
|
-
requests.put(
|
|
302
|
-
upload_auth['url'], data=file.read(), headers=headers,
|
|
303
|
-
timeout=timeout)
|
|
304
|
-
create_query = '''
|
|
305
|
-
mutation($filename: String!
|
|
306
|
-
$tournament: Int!
|
|
307
|
-
$modelId: String
|
|
308
|
-
$triggerId: String,
|
|
309
|
-
$dataDatestamp: Int) {
|
|
310
|
-
create_submission(filename: $filename
|
|
311
|
-
tournament: $tournament
|
|
312
|
-
modelId: $modelId
|
|
313
|
-
triggerId: $triggerId
|
|
314
|
-
source: "numerapi"
|
|
315
|
-
dataDatestamp: $dataDatestamp) {
|
|
316
|
-
id
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
'''
|
|
320
|
-
arguments = {'filename': upload_auth['filename'],
|
|
321
|
-
'tournament': tournament,
|
|
322
|
-
'modelId': model_id,
|
|
323
|
-
'triggerId': os.getenv('TRIGGER_ID', None),
|
|
324
|
-
'dataDatestamp': data_datestamp}
|
|
325
|
-
create = self.raw_query(create_query, arguments, authorization=True)
|
|
326
|
-
submission_id = create['data']['create_submission']['id']
|
|
327
|
-
return submission_id
|
|
328
|
-
|
|
329
243
|
def get_leaderboard(self, limit: int = 50, offset: int = 0) -> List[Dict]:
|
|
330
|
-
"""Get the current leaderboard
|
|
244
|
+
"""Get the current model leaderboard
|
|
331
245
|
|
|
332
246
|
Args:
|
|
333
247
|
limit (int): number of items to return (optional, defaults to 50)
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
from typing import List, Dict, Tuple, Union
|
|
4
4
|
import os
|
|
5
|
-
import codecs
|
|
6
5
|
import decimal
|
|
7
6
|
from io import BytesIO
|
|
8
7
|
|
|
@@ -12,13 +11,9 @@ import pandas as pd
|
|
|
12
11
|
from numerapi import base_api
|
|
13
12
|
from numerapi import utils
|
|
14
13
|
|
|
15
|
-
SIGNALS_DOM = "https://numerai-signals-public-data.s3-us-west-2.amazonaws.com"
|
|
16
|
-
|
|
17
14
|
|
|
18
15
|
class SignalsAPI(base_api.Api):
|
|
19
16
|
""""API for Numerai Signals"""
|
|
20
|
-
TICKER_UNIVERSE_URL = f"{SIGNALS_DOM}/latest_universe.csv"
|
|
21
|
-
HISTORICAL_DATA_URL = f"{SIGNALS_DOM}/signals_train_val_bbg.csv"
|
|
22
17
|
|
|
23
18
|
def __init__(self, *args, **kwargs):
|
|
24
19
|
base_api.Api.__init__(self, *args, **kwargs)
|
|
@@ -87,7 +82,8 @@ class SignalsAPI(base_api.Api):
|
|
|
87
82
|
def upload_predictions(self, file_path: str = "predictions.csv",
|
|
88
83
|
model_id: str = None,
|
|
89
84
|
df: pd.DataFrame = None,
|
|
90
|
-
|
|
85
|
+
data_datestamp: int = None,
|
|
86
|
+
timeout: Union[None, float, Tuple[float, float]] = (10, 600)
|
|
91
87
|
) -> str:
|
|
92
88
|
"""Upload predictions from file.
|
|
93
89
|
Will read TRIGGER_ID from the environment if this model is enabled with
|
|
@@ -123,45 +119,35 @@ class SignalsAPI(base_api.Api):
|
|
|
123
119
|
buffer_csv = BytesIO(df.to_csv(index=False).encode())
|
|
124
120
|
buffer_csv.name = file_path
|
|
125
121
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
submissionUploadSignalsAuth(filename: $filename
|
|
130
|
-
modelId: $modelId) {
|
|
131
|
-
filename
|
|
132
|
-
url
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
'''
|
|
136
|
-
|
|
137
|
-
arguments = {'filename': os.path.basename(file_path),
|
|
138
|
-
'modelId': model_id}
|
|
139
|
-
submission_resp = self.raw_query(auth_query, arguments,
|
|
140
|
-
authorization=True)
|
|
141
|
-
auth = submission_resp['data']['submissionUploadSignalsAuth']
|
|
122
|
+
upload_auth = self._upload_auth(
|
|
123
|
+
'submissionUploadSignalsAuth', file_path,
|
|
124
|
+
self.tournament_id, model_id)
|
|
142
125
|
|
|
143
126
|
# get compute id if available and pass it along
|
|
144
127
|
headers = {"x_compute_id": os.getenv("NUMERAI_COMPUTE_ID")}
|
|
145
128
|
|
|
146
129
|
with open(file_path, 'rb') if df is None else buffer_csv as file:
|
|
147
|
-
requests.put(
|
|
130
|
+
requests.put(upload_auth['url'], data=file.read(),
|
|
148
131
|
headers=headers, timeout=timeout)
|
|
149
132
|
create_query = '''
|
|
150
133
|
mutation($filename: String!
|
|
151
134
|
$modelId: String
|
|
152
|
-
$triggerId: String
|
|
135
|
+
$triggerId: String
|
|
136
|
+
$ddataDatestamp: Int) {
|
|
153
137
|
createSignalsSubmission(filename: $filename
|
|
154
138
|
modelId: $modelId
|
|
155
139
|
triggerId: $triggerId
|
|
156
|
-
source: "numerapi"
|
|
140
|
+
source: "numerapi"
|
|
141
|
+
dataDatestamp: $dataDatestamp) {
|
|
157
142
|
id
|
|
158
143
|
firstEffectiveDate
|
|
159
144
|
}
|
|
160
145
|
}
|
|
161
146
|
'''
|
|
162
|
-
arguments = {'filename':
|
|
147
|
+
arguments = {'filename': upload_auth['filename'],
|
|
163
148
|
'modelId': model_id,
|
|
164
|
-
'triggerId': os.getenv('TRIGGER_ID', None)
|
|
149
|
+
'triggerId': os.getenv('TRIGGER_ID', None),
|
|
150
|
+
'dataDatestamp': data_datestamp}
|
|
165
151
|
create = self.raw_query(create_query, arguments, authorization=True)
|
|
166
152
|
return create['data']['createSignalsSubmission']['id']
|
|
167
153
|
|
|
@@ -312,31 +298,14 @@ class SignalsAPI(base_api.Api):
|
|
|
312
298
|
>>> SignalsAPI().ticker_universe()
|
|
313
299
|
["MSFT", "AMZN", "APPL", ...]
|
|
314
300
|
"""
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
iterator = codecs.iterdecode(result.iter_lines(), 'utf-8')
|
|
318
|
-
tickers = [t.strip() for t in iterator if t != 'bloomberg_ticker']
|
|
319
|
-
return tickers
|
|
301
|
+
path = self.download_dataset("signals/v1.0/live.parquet")
|
|
302
|
+
return pd.read_parquet(path).numerai_ticker.tolist()
|
|
320
303
|
|
|
321
|
-
def download_validation_data(self
|
|
304
|
+
def download_validation_data(self) -> None:
|
|
322
305
|
"""download CSV file with historical targets and ticker universe
|
|
323
|
-
|
|
324
|
-
Returns:
|
|
325
|
-
str: filename
|
|
326
|
-
|
|
327
|
-
Example:
|
|
328
|
-
>>> SignalsAPI().download_validation_data()
|
|
329
|
-
signals_train_val_bbg.csv
|
|
330
306
|
"""
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
dest_filename = "numerai_signals_historical.csv"
|
|
334
|
-
|
|
335
|
-
path = os.path.join(self.global_data_dir, dest_filename)
|
|
336
|
-
|
|
337
|
-
utils.download_file(
|
|
338
|
-
self.HISTORICAL_DATA_URL, path, self.show_progress_bars)
|
|
339
|
-
return path
|
|
307
|
+
self.logger.warning("'download_validation_data' is DEPRECATED.")
|
|
308
|
+
self.logger.warning("Please use 'download_dataset' and 'list_datasets'")
|
|
340
309
|
|
|
341
310
|
def stake_get(self, username) -> decimal.Decimal:
|
|
342
311
|
"""get current stake for a given users
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: numerapi
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.19.0
|
|
4
4
|
Summary: Automatically download and upload data for the Numerai machine learning competition
|
|
5
5
|
Home-page: https://github.com/uuazed/numerapi
|
|
6
6
|
Maintainer: uuazed
|
|
@@ -11,7 +11,6 @@ Description: [](ht
|
|
|
11
11
|
[](https://pypi.python.org/pypi/numerapi)
|
|
12
12
|
[](https://pepy.tech/project/numerapi)
|
|
13
13
|
[](http://numerapi.readthedocs.io/en/stable/?badge=stable)
|
|
14
|
-
[](https://requires.io/github/uuazed/numerapi/requirements/?branch=master)
|
|
15
14
|
|
|
16
15
|
# Numerai Python API
|
|
17
16
|
Automatically download and upload data for the Numerai machine learning
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|