The Creation Of Numerai Payouts With Flutter

Bouwe Ceunen
Axons
Published in
6 min readJun 3, 2021

First things first, what is Numerai, and what is Numerai Payouts? Numerai is an AI-driven hedge fund. You can make predictions with the help of machine learning on obfuscated data, upload these to Numerai, and based on how good or bad they are, get some profit or take some loss. Numerai Payouts is a community-made app to track all your pending payouts across all your different models.

Numerai Payouts

Components

There are several components to make this work. There’s a public Numerai Payouts API that acts as an intermediate layer between the Numerai Payouts app and the internal Numerai API to do the aggregation of all the payouts of the different models of the user.

API

This safeguards potentially breaking changes on Numerai’s side. Deploying a new version of the app can easily take a few days because of App Store and Play Store delays. By decoupling the internal Numerai API from the Numerai Payouts app, it’s possible to deploy a new version of the intermediate Numerai Payouts API in a few seconds if needed. This also ensures that the format of the incoming messages to the app stays the same to reduce errors. It’s possible to group all models based on each round or each model.

curl --silent https://api.numeraipayouts.com/accounts?model=ceunen&group=MODEL

The API is made in Bottle, which is a production-grade and fast Python web framework. To see all possible options, go to Numerai Payouts API and copy-paste everything here https://editor.swagger.io. It has the OpenAPI Specification.

Android/iOS App

The actual app is made with Flutter. It’s possible to create a mobile application written in the language Dart that runs on iOS, as well as on Android. For some more details on working with Flutter, you can always read my other story where I explain the pros and cons of working with it.

Push Notifications

A socket service written in Nodejs is constantly listening on the Rocketchat API of Numerai, more specifically on the #daily-scores and #daily-scores-signals channels. In these channels, updates are posted when daily scores are out. With the help of FCM (Firebase Cloud Messaging) and its integration with Flutter, it’s possible to send push notifications to all app users when daily scores are available.

Daily Scores Push Notification

Website

You can visit the site at https://numeraipayouts.com. This was made with Nodejs and the Express framework to make easy web applications.

Tooling

A lot of tooling also helps to maintain and deploy all components. I will list some here ranging from error handling, deploying, and sending out the daily scores push notifications.

Fastlane

App deployment can be cumbersome, building binaries, signing them, uploading all metadata, setting the right version, etc. It’s easy to make a mistake when manually releasing an app to the App Store or Google Play. This is where Fastlane comes in. You define a so-called Fastfile in which you specify all different operations that need to be executed and what files and metadata need to be uploaded. It has also automatic versioning and automatic screenshot taking.

fastlane app_store --verbose && fastlane play_store --verbose

It’s also super easy to upload your beta builds to for example Testflight and App Center. This enables you to first test a new update and install it on your phone only before publishing it for your entire user base.

fastlane test_flight --verbose && fastlane app_center --verbose

Sentry

Error handling and performance monitoring has been made easy by Sentry. It automatically measures the duration of all API calls and will notify you when your app crashed with additional logging. Note that some people have up to 15 models, so calls can take a long time as you see below.

Sentry Performance Graphs

Firebase Cloud Messaging

FCM or Firebase Cloud Messaging makes it easy to send push notifications. It integrates well with Flutter and if your volume is low, it’s even free. It requires a great deal of setting up and debugging is quite hard if your message is not received. I’ve followed this post to get everything working.

Fixer

Fixer provides, in their words; Foreign exchange rates and currency
conversion JSON API.
It is free for up to 250 requests per month. For the use case of Numerai Payouts, it’s not needed to have frequent exchange rate updates. It is currently updated every 4 hours.

http://data.fixer.io/api/latest?access_key={FIXER_API_KEY}&symbols=USD,CNY,AUD,GBP,ZAR,JPY,MXN,CAD

Infrastructure

Every component besides the app, of course, runs on Kubernetes. Feel free to take a look at my story of the journey on maintaining Kubernetes clusters. There are several Deployments, a Cronjob, and a Statefulset to maintain all components needed to ensure the correct working of Numerai Payouts.

Deployment

The frontend Deployment is the actual website, it does not have much traffic so 2 pods are enough to provide some redundancy during cluster upgrades where one pod may go down.

The backend Deployment is the actual API to which Numerai Payouts makes a request to get the aggregated payouts that then can be shown to the user. It’s important here to scale it to 10 pods for when peak load arrives when the daily scores are out. It is stateless so it’s very easy to scale if needed.

Cronjob

Numerai Rate Refresh

A cronjob runs every 4 hours to update the currency rates of EUR /USD / JPY / CAD / BTC etc. The price of 1 NMR in USD is retrieved from the Numerai API, the BTC price from blockchain.com, and the other rates from Fixer, as previously mentioned. With these currency rates, you can adjust in what currency you would like to view your payouts in the app.

Statefulset

Numerai Sockets

I opted to use a Statefulset for listening to the Rocketchat API for daily push notifications because they get a fixed sequence number assigned as pod name. It is designed in a way that the current date modulo the pod number will be responsible for sending out the notification (e.g 15 % 4 = 3, in this case, pod 3 is responsible for sending, so it works in a round-robin fashion each day). If the other pods sense that the pod responsible is not running, they will assign a new leader in charge of sending the notifications. This to make sure that there’s always one pod sending out notifications. To ensure that, if a pod goes down or a rolling upgrade is happening of Kubernetes, multiple instances are running to make sure push notifications will still be sent. It is loosely based on the Raft protocol also used in etcd for example.

TL;DR

Numerai is an AI-driven hedge fund. You do predictions with the help of machine learning on obfuscated data, upload these to Numerai, and based on how good or bad they are, you will get some profit or take some loss. Numerai Payouts is a community-made app to track all your pending payouts across all your different models. The app itself is made in Flutter, an intermediate API is available that runs on Kubernetes along with a cronjob for exchange rate conversion and a socket service listener on the RocketChat API of Numerai to send out daily scores push notifications.

--

--