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 | |