Numerai APIとnumerapiライブラリのraw_queryメソッド

この記事は、[Numerai Advent Calendar 2020](https://adventar.org/calendars/5031) 12月12日の記事です。

# 内容

* Numerai APIの概要説明
* numerapiに備わっている各種メソッドがNumerai APIの最新仕様に追いついてない場合は、numerapiの`raw_query`メソッドでGraphQLクエリを実行することで、最新APIを実行できます。
    * 元ネタの関連ツイート
        * https://twitter.com/murenoha/status/1317440144719319040

# Numerai GraphQL API

* Getting Started
    * https://medium.com/numerai/getting-started-with-numerais-new-tournament-api-77396e895e72
* 基本的にはNumeraiのWebサイト https://numer.ai は、Numerai GraphQL APIで構築されているので、サイトで表示されているデータはAPIで取得できます。
    * リーダーボードページのデータ取得でAPIが実行されている様子
        * リクエスト
        ![numerai_site_request.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628739/0392f845-f4c7-5cc8-a285-f66faf684910.png)
        * レスポンス
        ![numerai_site_response.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628739/4759b951-e396-ee2b-9884-c8e91b32cf38.png)
    * Numeraiは、サイト構築で開発したAPIをユーザにも公開してくれています。
* Numerai GraphQL APIのエンドポイントURL
    * https://api-tournament.numer.ai/
* GraphiQL Workspace
    * 上記URLをブラウザで開いて、ここでクエリを書いてデータを取得することもできます。
    ![numerai_graphiql.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628739/e20c52da-544c-f142-6fdf-05004f4429f7.png)
* curlコマンド
    * リーダーボードデータを取得する例
        * パラメータは`rank`と`username`のみ取得。100個に限定。

    ```shell
curl -X POST -H 'Content-Type: application/json' https://api-tournament.numer.ai -d '{ "query": "{ v2Leaderboard(limit: 100) { rank username } } }" }'
    ```

    * 診断データを取得する例
        * 対象モデルの所有者のみが取得できるプライベートなデータは認証情報が必要です。
        * `YOUR_PUBLIC_ID`、`YOUR_SECRET_KEY`、`YOUR_MODEL_ID` はご自身のもので埋めてください。
            * 認証情報は https://numer.ai/submit 、もしくは、https://numer.ai/account の「VIEW API KEYS」で確認できます。
            * モデルIDは https://numer.ai/models のモデル名の下に記載されたIDです。
            * `YOUR_PUBLIC_ID`と`YOUR_SECRET_KEY`の間に`$`が入るので、抜けにご注意ください。
        * ラウンド番号と`validationSharpe`のみ取得。

    ```shell
curl -X POST -H 'Content-Type: application/json' -H 'Authorization: Token YOUR_PUBLIC_ID$YOUR_SECRET_KEY' https://api-tournament.numer.ai -d '{ "query": "{ model(modelId: \"YOUR_MODEL_ID\") { submissions { round { number } validationSharpe } } }" }'
    ```

# numerapi

* curlコマンドでデータ取得可能ですが、プログラムから実行する場合は numerapi などのAPIクライアントライブラリを使うと便利です。GraphQLクエリをラップした便利なメソッド群が用意されています。
    * GitHub: https://github.com/uuazed/numerapi
        * 基本的な使い方は https://github.com/uuazed/numerapi/blob/master/README.md
    * Doc: https://numerapi.readthedocs.io/en/latest/api/numerapi.html

* リーダーボードデータ取得の例

    ```python
import numerapi
api = numerapi.NumerAPI()
response = api.get_leaderboard(100)
    ```

* 診断データ取得の例

    ```python
    import numerapi
    api = numerapi.NumerAPI('YOUR_PUBLIC_ID', 'YOUR_SECRET_KEY')
    model_id = api.get_models()['YOUR_MODEL_NAME']
    status = api.submission_status(model_id)
    ```

# numerapiに備わっているメソッド以外のクエリを実行したい場合

* 例えば、最近リーダーボードに導入された3ヶ月リターン、1年リターンのデータは `return_13Weeks`と`return_52Weeks` のパラメータで取得できます。
    * 余談だが、`return_13Weeks`と`return_52Weeks`だけスネークケースなのはなぜだろう？

    ```shell
    curl -X POST -H 'Content-Type: application/json' https://api-tournament.numer.ai -d '{ "query": "{ v2Leaderboard(limit: 100) { rank username return_13Weeks return_52Weeks } } }" }'
    ```

* しかし、numerapiの`get_leaderboard`メソッドが最新APIのパラメータ仕様に追いついてない場合があります。
    * 12月12日現在、`return_13Weeks`と`return_52Weeks`は未サポート
    * レスポンスパラメータ
        * https://github.com/uuazed/numerapi/blob/master/numerapi/numerapi.py#L1085
* そんな時は、`raw_query`メソッドで直接GraphQLクエリを実行することで、最新パラメータを実行できます。

    ```python
    api = numerapi.NumerAPI()
    query = '''
        query {
            v2Leaderboard(limit: 100) {
                rank
                username
                return_13Weeks
                return_52Weeks
        }
    }'''
    response = api.raw_query(query)
    ```

以上です。