Spaces:
Runtime error
Runtime error
import numerapi | |
from numerapi import utils | |
from project_tools import project_config, project_utils | |
from typing import List, Dict | |
import pandas as pd | |
import numpy as np | |
napi = numerapi.NumerAPI() | |
# def get_round | |
# depreciated | |
# def get_model_history(model): | |
# res = napi.daily_user_performances(model) | |
# res = pd.DataFrame.from_dict(res) | |
# res['payoutPending'] = res['payoutPending'].astype(np.float64) | |
# res['payoutSettled'] = res['payoutSettled'].astype(np.float64) | |
# res['stakeValue'] = res['stakeValue'].astype(np.float64) | |
# res['deltaRatio'] = res['payoutPending'] / res['stakeValue'] | |
# res['realised_pl'] = project_utils.series_reverse_cumsum(res['payoutSettled']) | |
# res['floating_pl'] = project_utils.series_reverse_cumsum(res['payoutPending']) - res['realised_pl'] | |
# res['current_stake'] = res['stakeValue'] - res['floating_pl'] | |
# rename_dict = {'stakeValue':'floating_stake'} | |
# res = res.rename(columns=rename_dict) | |
# # res['equity'] = res['stakeValue'] + res['floating_pl'] | |
# # cols = res.columns.tolist() | |
# # res = res[['model'] + cols] | |
# | |
# res['model'] = model | |
# cols = ['model', 'date', 'current_stake', 'floating_stake', 'payoutPending', 'floating_pl', 'realised_pl'] | |
# res = res[cols] | |
# return res | |
def get_portfolio_overview(models, onlylatest=True): | |
res_df = [] | |
for m in models: | |
# try: | |
print(f'extracting information for model {m}') | |
if onlylatest: | |
mdf = get_model_history_v3(m).loc[0:0] | |
else: | |
mdf = get_model_history_v3(m) | |
res_df.append(mdf) | |
# except: | |
# print(f'no information for model {m} is available') | |
if len(res_df)>0: | |
res_df = pd.concat(res_df, axis=0) | |
# res_df['date'] = res_df['date'].dt.date | |
if onlylatest: | |
return res_df.sort_values(by='floating_pl', ascending=False).reset_index(drop=True) | |
else: | |
return res_df.reset_index(drop=True) | |
else: | |
return None | |
def get_competitions(tournament=8): | |
"""Retrieves information about all competitions | |
Args: | |
tournament (int, optional): ID of the tournament, defaults to 8 | |
-- DEPRECATED there is only one tournament nowadays | |
Returns: | |
list of dicts: list of rounds | |
Each round's dict contains the following items: | |
* datasetId (`str`) | |
* number (`int`) | |
* openTime (`datetime`) | |
* resolveTime (`datetime`) | |
* participants (`int`): number of participants | |
* prizePoolNmr (`decimal.Decimal`) | |
* prizePoolUsd (`decimal.Decimal`) | |
* resolvedGeneral (`bool`) | |
* resolvedStaking (`bool`) | |
* ruleset (`string`) | |
Example: | |
>>> NumerAPI().get_competitions() | |
[ | |
{'datasetId': '59a70840ca11173c8b2906ac', | |
'number': 71, | |
'openTime': datetime.datetime(2017, 8, 31, 0, 0), | |
'resolveTime': datetime.datetime(2017, 9, 27, 21, 0), | |
'participants': 1287, | |
'prizePoolNmr': Decimal('0.00'), | |
'prizePoolUsd': Decimal('6000.00'), | |
'resolvedGeneral': True, | |
'resolvedStaking': True, | |
'ruleset': 'p_auction' | |
}, | |
.. | |
] | |
""" | |
# self.logger.info("getting rounds...") | |
query = ''' | |
query($tournament: Int!) { | |
rounds(tournament: $tournament) { | |
number | |
resolveTime | |
openTime | |
resolvedGeneral | |
resolvedStaking | |
} | |
} | |
''' | |
arguments = {'tournament': tournament} | |
result = napi.raw_query(query, arguments) | |
rounds = result['data']['rounds'] | |
# convert datetime strings to datetime.datetime objects | |
for r in rounds: | |
utils.replace(r, "openTime", utils.parse_datetime_string) | |
utils.replace(r, "resolveTime", utils.parse_datetime_string) | |
utils.replace(r, "prizePoolNmr", utils.parse_float_string) | |
utils.replace(r, "prizePoolUsd", utils.parse_float_string) | |
return rounds | |
def daily_submissions_performances(username: str) -> List[Dict]: | |
"""Fetch daily performance of a user's submissions. | |
Args: | |
username (str) | |
Returns: | |
list of dicts: list of daily submission performance entries | |
For each entry in the list, there is a dict with the following | |
content: | |
* date (`datetime`) | |
* correlation (`float`) | |
* roundNumber (`int`) | |
* mmc (`float`): metamodel contribution | |
* fnc (`float`): feature neutral correlation | |
* correlationWithMetamodel (`float`) | |
Example: | |
>>> api = NumerAPI() | |
>>> api.daily_user_performances("uuazed") | |
[{'roundNumber': 181, | |
'correlation': -0.011765912, | |
'date': datetime.datetime(2019, 10, 16, 0, 0), | |
'mmc': 0.3, | |
'fnc': 0.1, | |
'correlationWithMetamodel': 0.87}, | |
... | |
] | |
""" | |
query = """ | |
query($username: String!) { | |
v2UserProfile(username: $username) { | |
dailySubmissionPerformances { | |
date | |
correlation | |
corrPercentile | |
roundNumber | |
mmc | |
mmcPercentile | |
fnc | |
fncPercentile | |
correlationWithMetamodel | |
} | |
} | |
} | |
""" | |
arguments = {'username': username} | |
data = napi.raw_query(query, arguments)['data']['v2UserProfile'] | |
performances = data['dailySubmissionPerformances'] | |
# convert strings to python objects | |
for perf in performances: | |
utils.replace(perf, "date", utils.parse_datetime_string) | |
# remove useless items | |
performances = [p for p in performances | |
if any([p['correlation'], p['fnc'], p['mmc']])] | |
return performances | |
def daily_submissions_performances_V3(modelname: str) -> List[Dict]: | |
query = """ | |
query($modelName: String!) { | |
v3UserProfile(modelName: $modelName) { | |
roundModelPerformances{ | |
roundNumber | |
roundResolveTime | |
corr | |
corrPercentile | |
mmc | |
mmcMultiplier | |
mmcPercentile | |
tc | |
tcPercentile | |
tcMultiplier | |
fncV3 | |
fncV3Percentile | |
corrWMetamodel | |
payout | |
roundResolved | |
roundResolveTime | |
corrMultiplier | |
mmcMultiplier | |
selectedStakeValue | |
} | |
stakeValue | |
nmrStaked | |
} | |
} | |
""" | |
arguments = {'modelName': modelname} | |
data = napi.raw_query(query, arguments)['data']['v3UserProfile'] | |
performances = data['roundModelPerformances'] | |
# convert strings to python objects | |
for perf in performances: | |
utils.replace(perf, "date", utils.parse_datetime_string) | |
# remove useless items | |
performances = [p for p in performances | |
if any([p['corr'], p['tc'], p['mmc']])] | |
return performances | |
def get_lb_models(limit=20000, offset=0): | |
query = """ | |
query($limit: Int, $offset: Int){ | |
v2Leaderboard(limit:$limit, offset:$offset){ | |
username | |
} | |
} | |
""" | |
arguments = {'limit':limit, 'offset':offset} | |
data = napi.raw_query(query, arguments)['data']['v2Leaderboard'] | |
model_list = [i['username'] for i in data] | |
return model_list | |
def get_round_model_performance(roundNumber: int, model: str): | |
query = """ | |
query($roundNumber: Int!, $username: String!) { | |
roundSubmissionPerformance(roundNumber: $roundNumber, username: $username) { | |
corrMultiplier | |
mmcMultiplier | |
roundDailyPerformances{ | |
correlation | |
mmc | |
corrPercentile | |
mmcPercentile | |
payoutPending | |
} | |
selectedStakeValue | |
} | |
} | |
""" | |
arguments = {'roundNumber': roundNumber,'username': model} | |
data = napi.raw_query(query, arguments)['data']['roundSubmissionPerformance'] | |
latest_performance = data['roundDailyPerformances'][-1] #[-1] ### issue with order | |
res = {} | |
res['model'] = model | |
res['roundNumber'] = roundNumber | |
res['corrMultiplier'] = data['corrMultiplier'] | |
res['mmcMultiplier'] = data['mmcMultiplier'] | |
res['selectedStakeValue'] = data['selectedStakeValue'] | |
for key in latest_performance.keys(): | |
res[key] = latest_performance[key] | |
return res | |
def get_user_profile(username: str) -> List[Dict]: | |
"""Fetch daily performance of a user's submissions. | |
Args: | |
username (str) | |
Returns: | |
list of dicts: list of daily submission performance entries | |
For each entry in the list, there is a dict with the following | |
content: | |
* date (`datetime`) | |
* correlation (`float`) | |
* roundNumber (`int`) | |
* mmc (`float`): metamodel contribution | |
* fnc (`float`): feature neutral correlation | |
* correlationWithMetamodel (`float`) | |
Example: | |
>>> api = NumerAPI() | |
>>> api.daily_user_performances("uuazed") | |
[{'roundNumber': 181, | |
'correlation': -0.011765912, | |
'date': datetime.datetime(2019, 10, 16, 0, 0), | |
'mmc': 0.3, | |
'fnc': 0.1, | |
'correlationWithMetamodel': 0.87}, | |
... | |
] | |
""" | |
query = """ | |
query($username: String!) { | |
v2UserProfile(username: $username) { | |
dailySubmissionPerformances { | |
date | |
correlation | |
corrPercentile | |
roundNumber | |
mmc | |
mmcPercentile | |
fnc | |
fncPercentile | |
correlationWithMetamodel | |
} | |
} | |
} | |
""" | |
arguments = {'username': username} | |
data = napi.raw_query(query, arguments)['data']#['v2UserProfile'] | |
# performances = data['dailySubmissionPerformances'] | |
# # convert strings to python objects | |
# for perf in performances: | |
# utils.replace(perf, "date", utils.parse_datetime_string) | |
# # remove useless items | |
# performances = [p for p in performances | |
# if any([p['correlation'], p['fnc'], p['mmc']])] | |
return data | |
def download_dataset(filename: str, dest_path: str = None, | |
round_num: int = None) -> None: | |
""" Download specified file for the current active round. | |
Args: | |
filename (str): file to be downloaded | |
dest_path (str, optional): complate path where the file should be | |
stored, defaults to the same name as the source file | |
round_num (int, optional): tournament round you are interested in. | |
defaults to the current round | |
tournament (int, optional): ID of the tournament, defaults to 8 | |
Example: | |
>>> filenames = NumerAPI().list_datasets() | |
>>> NumerAPI().download_dataset(filenames[0]}") | |
""" | |
if dest_path is None: | |
dest_path = filename | |
query = """ | |
query ($filename: String! | |
$round: Int) { | |
dataset(filename: $filename | |
round: $round) | |
} | |
""" | |
args = {'filename': filename, "round": round_num} | |
dataset_url = napi.raw_query(query, args)['data']['dataset'] | |
utils.download_file(dataset_url, dest_path, show_progress_bars=True) | |
# function using V3UserProfile | |
def model_payout_history(model): | |
napi = numerapi.NumerAPI() | |
query = """ | |
query($model: String!) { | |
v3UserProfile(modelName: $model) { | |
roundModelPerformances{ | |
payout | |
roundNumber | |
roundResolved | |
roundResolveTime | |
corrMultiplier | |
mmcMultiplier | |
selectedStakeValue | |
} | |
stakeValue | |
nmrStaked | |
} | |
} | |
""" | |
arguments = {'model': model} | |
payout_info = napi.raw_query(query, arguments)['data']['v3UserProfile']['roundModelPerformances'] | |
payout_info = pd.DataFrame.from_dict(payout_info) | |
payout_info = payout_info[~pd.isnull(payout_info['payout'])].reset_index(drop=True) | |
return payout_info | |
def get_model_history_v3(model): | |
res = model_payout_history(model) | |
res = pd.DataFrame.from_dict(res) | |
res['payout'] = res['payout'].astype(np.float64) | |
res['current_stake'] = res['selectedStakeValue'].astype(np.float64) | |
res['payout_cumsum'] = project_utils.series_reverse_cumsum(res['payout']) | |
res['date'] = pd.to_datetime(res['roundResolveTime']).dt.date | |
res['realised_pl'] = res['payout_cumsum'] | |
latest_realised_pl = res[res['roundResolved'] == True]['payout_cumsum'].values[0] | |
res.loc[res['roundResolved'] == False, 'realised_pl'] = latest_realised_pl | |
res['floating_pl'] = 0 | |
payoutPending_values = res[res['roundResolved'] == False]['payout'].values | |
payoutPending_cumsum = payoutPending_values[::-1].cumsum()[::-1] | |
res.loc[res['roundResolved'] == False, 'floating_pl'] = payoutPending_cumsum | |
res['model'] = model | |
# res['floating_pl'] = res['current_stake'] + res['payoutPending'] | |
res['floating_stake'] = res['current_stake'] + res['floating_pl'] | |
cols = ['model', 'date', 'current_stake', 'floating_stake', 'payout', 'floating_pl', 'realised_pl', 'roundResolved', | |
'roundNumber'] | |
res = res[cols] | |
return res | |