Rapport intermédiaire sur le développement de l'IA et l'optimisation des performances du code

Image du titre de l'histoire

Le bot de poker est mort, vive le BitSurfer ! - Non, sérieusement, que s'est-il passé ?

Le PokerBot et le Poker Advisor étaient deux projets très intéressants, et j'ai beaucoup appris des deux ! Le PokerAdvisor prend les cartes à l'écran, les introduit automatiquement dans une IA et prédit le résultat de la main. Alors que le Pokerbot était prévu pour jouer lui-même - tout était préparé, mais le poker en ligne était à peu près interdit en Suisse.

Il était donc temps de passer à autre chose. Mais quel aurait pu être le prochain grand défi ?

Tableau des prix des bitcoins

Je suis tombé sur Coinbase, un courtier en crypto, où je m'intéressais surtout à Bitcoin.

Ils disposent d'une API qui vous permet de connecter votre logiciel de trading préféré, comme Metatrader ou autre. Mais non.

Le plan, bien sûr, n'est pas de s'interfacer avec notre logiciel commercial préféré. C'était plutôt mon idée de construire ma propre interface à partir de zéro en gardant mes besoins à l'esprit. C'était incroyablement dur et la courbe d'apprentissage était très raide, mais cela en valait certainement la peine.

La première version alpha est prête. L'interface est très moche, mais la forme suit la fonction. Mon idée d'un logiciel bien conçu n'est pas avant tout une interface utilisateur fantaisiste. Je veux plutôt que mon logiciel fasse simplement son travail. Absolument. En arrière-plan. Rien à installer, rien à faire devant l'écran et à dire au logiciel ce qu'il doit faire ensuite. Il suffit de le lancer et de le regarder avec fascination.

L'interface consiste essentiellement en une visualisation des données du marché ainsi que des données d'entrée normalisées pour l'IA.

Qu'ai-je appris ? Il fallait d'abord que je me connecte à Coinbase. J'ai beaucoup appris sur les API et heureusement, avec les paquets disponibles, c'était assez facile.

Introduction à l'aspect performance de la programmation

J'ai dû apprendre beaucoup de choses sur la structuration des données pour l'IA, et cela impliquait essentiellement beaucoup de connaissances sur les performances du code. Au point qu'il devient complètement fou. Il s'agissait surtout du fait que je travaille encore sur ma machine de 7 ans que j'ai récupérée de ma formation. Il a bien vieilli, mais on peut vraiment sentir l'âge.... De mon prochain ordinateur imminent, je peux m'attendre à une performance environ 10 fois supérieure pour mes cas d'utilisation ! Le processeur seul est environ 400% plus rapide s'il consomme beaucoup de threads (ce que je fais).

Je me suis retrouvé dans la situation suivante :

Mon code prend environ une semaine pour traiter 8 ans de données (chaque point de données est 2s ~ 126.000.000 points de prix). En attendant, la prochaine génération de processeurs et de cartes graphiques n'est plus qu'à quelques mois et est très prometteuse.

La quantité de données à traiter est immense, et je me suis donc lancé dans l'optimisation des performances du code. J'avais déjà une certaine expérience des travailleurs à plusieurs fils pour gérer plusieurs tâches simultanément. En conséquence, j'avais déjà un peu moins de 3,5x de performance puisque mon CPU a 4 cœurs. Il fallait désormais deux jours pour traiter des données datant de huit ans. C'était encore trop. Quand je fais des backtests, je veux voir les résultats. Et je les veux rapides.

J'ai dû me pencher davantage sur l'optimisation des performances et j'ai développé ma propre abstraction de travailleur basée sur la tâche en C#. En gros, il met en œuvre une méthode de fabrication que j'ai apprise lors de mon stage à l'INA Lahr. C'est comme avoir une machine (ou un travailleur) avec une file d'attente d'entrée et une file d'attente de sortie. La file d'attente agit comme un tampon et peut aider chaque noyau d'ordinateur à répartir le travail de manière égale. C'est comme un pipeline modulaire et évolutif où les travailleurs peuvent prendre des articles dans une file d'attente ou un sac et les traiter.

Cela a également donné un grand coup de pouce aux performances. J'étais maintenant capable de traiter toutes les données en une nuit environ, mais j'ai décidé de les reproduire encore plus loin, juste pour voir jusqu'où cela pouvait aller. Je me suis abonné à une extension de Visual Studio "dotTrace" qui fonctionne très bien pour trouver les goulots d'étranglement dans le code. Vous pouvez enregistrer une trace et voir ensuite, fonction par fonction, le temps qu'elle prend pour s'exécuter. J'ai trouvé une caractéristique à laquelle je ne m'attendais pas du tout : le constructeur de la chaîne de sortie a étranglé tout le pipeline. Vous pouvez en savoir plus à ce sujet dans lequestion sur le débordement de la pile

Dans l'ensemble, le processus est assez simple :

  1. Identifier la plus grande charge de puissance
  2. L'éliminer
  3. Continuez à le faire jusqu'à ce que vous obteniez une performance raisonnable.

Dans l'exemple ci-dessus, il s'agirait du processus CLR worker avec ID 10584. Cela semble un peu déroutant à ce stade, mais JetBrains a l'arbre d'appel sur la droite où l'on peut voir quelle fonction est utilisée :

Conclusions et enseignements

Je sais qu'il y aurait plus de pouvoir dans ce domaine, mais pour l'instant je suis assez content du résultat.

Actuellement, deux ans passent en moins de quatre minutes, et j'ai changé de vitesse si l'on veut observer les actions de plus près.

Capture d'écran du backtester

La ligne d'équité ainsi que les statistiques sont également sauvegardées. Il est possible de simuler / exécuter autant de comptes et de stratégies que vous le souhaitez, avec seulement une petite baisse de performance.

J'ai déjà essayé différentes stratégies avec des indicateurs, etc. Sans résultats prometteurs. Après tout, j'ai trouvé une stratégie gagnante qui ne fait rien de tout cela à la place. Elle ne suit pas la tendance et ne parie pas contre elle. Il n'essaie pas de prédire quoi que ce soit. Ni le point d'entrée parfait, ni la sortie parfaite. C'est assez simple, mais je n'entrerai pas dans les détails de la stratégie. Sortez des sentiers battus et vous trouverez peut-être quelque chose.

augmentation de la ligne d'équité

C'est un rendement annuel énorme de 20 %. Pour être juste, j'aurais fait plus de place avec la stratégie d'achat et de conservation, mais d'un autre côté, je ne prévois rien, nous n'avons pas ces pics (et ces chutes) insensés.

Maintenant, c'est quelque chose sur lequel je peux m'appuyer et voir ce qui est possible et ce qui ne l'est pas. Une simulation de marché complète dans le bac à sable. Un environnement de test aux possibilités presque illimitées.

C'est tout pour aujourd'hui, et j'espère que vous avez apprécié l'aperçu de certains de mes projets en cours.