Technologie

Pourquoi j'ai choisi C pour le backtesting – M. Emmanuel

Pourquoi j'ai choisi C pour le backtesting - M. Emmanuel


Les leçons d'un voyage pour construire un moteur de backtest intraday

1*ipfqN2R7RY YcRWvTjIqDQ@2x - Pourquoi j'ai choisi C pour le backtesting - M. Emmanuel

Au cours de la dernière année, j'ai préparé un moteur / cadre de backtesting pour simuler des stratégies intraday sur des marchés de produits dérivés.

Le voyage a inclus différentes langues, plusieurs itérations, de petites erreurs, de grosses erreurs, de très bons choix, “coentreprises " et promenades solitaires. D’autres, j’ai pris à la fois un excellent et un terrible conseil

Bien que rétrospectivement le résultat semble évident, la vérité est que trouver la bonne approche est un processus itératif. C’est juste après avoir essayé beaucoup de choses et après plusieurs itérations avec de vrais exemples autour de ce problème quand les choses deviennent claires.

Comprendre les besoins en matière de simulation des stratégies n’est pas simple. Votre expérience de programmation antérieure - le cas échéant - pourrait ne pas être aussi utile que vous pourriez le penser. Les besoins et les exigences pour backtester / simuler les stratégies quantitatives du marché sont quelque peu différents et, à mon humble avis, ils partagent de nombreuses racines avec l'approche de ce qui était traditionnellement la simulation scientifique réalisée dans les centres de recherche et les universités. C’est vrai au moins pour l’ensemble des problèmes sur lesquels je travaille (le secteur du commerce quantitatif est très important et je n’ai absolument pas le droit de parler de toutes les approches, stratégies et besoins).

J'ai couvert le voyage dans quelques articles. D'après les articles, je dirais que les deux plus pertinents sont ceux sur la manière de stocker des données de marché et celui sur les différentes langues que j'ai évaluées. Si vous trouvez cet article intéressant, je pense que vous trouverez également ces deux éléments intéressants.

Dans mon dernier article, j'ai déjà abordé les différentes langues évaluées. Le dernier était Julia et j’étais vraiment enthousiasmé par son potentiel, mais dès que j’ai avancé dans le langage (j’ai implémenté la dernière version de mon moteur de backtest dans Julia), je me suis rendu compte que ce qui compte vraiment dans le backtesting / simulation est un ensemble de routines / méthodes / fonctions et un référentiel commun de données, ainsi que des outils de débogage appropriés.

Julia était une découverte prometteuse. Le message de fournir des performances C avec la simplicité de Python / Numpy / Pandas était très attrayant. Cependant, comme je travaillais plus longtemps sur le projet, je me suis vite rendu compte que certains aspects du langage n’étaient pas si intuitifs et que la performance en C n’était pas facile pour un nouveau programmeur. Ne faites pas d'erreur, c'est un langage de programmation exceptionnel, mais après avoir approfondi un peu plus le problème auquel je suis confronté, ma conclusion est que le vénérable C est toujours le meilleur choix.

Je ne saurais trop insister sur la pertinence d’une approche simple et d’outils de débogage adéquats en tant qu’éléments clés pour réussir dans ce type de projet. Ces deux éléments sont plus importants que le choix de la langue. La raison pour avoir besoin d'un IDE approprié est que les routines ont tendance à être petites, mais denses et profondément algorithmiques, il est donc très facile de faire des erreurs. Sans outils de débogage appropriés, le projet peut facilement stagner.

Un IDE approprié est un élément clé du développement d’un moteur de backtesting / simulation. Les méthodes ont tendance à être concises, mais denses et très algorithmiques, aussi des outils de débogage appropriés sont-ils plus nécessaires que pratiques.

Ce besoin d'un IDE correct était l'une des principales raisons pour lesquelles je suis tombé en C - qui était ironiquement à l'origine de mon voyage - mais cette fois en utilisant des outils Microsoft.

Avec de meilleurs outils, plus d’expérience dans mon sac à dos et une vue simplifiée du problème et de la solution, C s’est révélé un bien meilleur collègue de travail. Le point avec C est que vous devez traiter correctement la complexité du projet. Si le projet est trop complexe, il sera vraiment difficile de le gérer en C et il sera probablement bloqué, mais si vous parvenez à aborder à la fois le problème et la solution d'un point de vue simplifié, C est un excellent compagnon.

L’autre grande leçon est que nous toujours ont tendance à trop compliquer les choses. Il y a quelques jours, un collègue qui travaillait dans l'industrie de la haute vitesse depuis 10 ans a partagé cette réflexion avec moi après que je lui ai montré une capture d'écran sur la rapidité de la dernière itération de mon moteur C ++ et sur la simplicité de la structure de données. J'ai réalisé à quel point le succès de cette dernière itération reposait sur la possibilité de simplifier le moteur.

La complexité est toujours un problème. Certaines langues (celles de haut niveau) résistent mieux à la complexité. Ils ne feront que rendre le projet plus cahoteux et plus long. Mais dans d'autres langages, tels que C, la complexité éliminera définitivement toute chance de succès, car la nature du langage rend impossible la gestion de programmes complexes.

En ce qui concerne la complexité des logiciels, la version IBM de leur système d'exploitation OS / 360 tente de fonctionner sur toutes les séries de machines IBM pour résoudre toutes sortes de problèmes. La recherche d'un système d'exploitation polyvalent dérivé de millions de lignes de code d'assemblage et de dizaines de milliers de bogues, nécessitant des mises à jour constantes. Les expériences du projet sont décrites de manière incisive par Frederick Brooks dans son livre classique "Le mois mythique".

Au début du voyage, je pensais doter le moteur de boulons et de boutons illimités, capable de gérer de nombreuses configurations. Mais est-ce que cela a du sens? Ma dernière itération est assez simple, suppose un utilisateur averti qui va mettre des valeurs saines sur les paramètres et qui va essayer les valeurs par défaut le plus souvent. En suivant ce chemin, une version de base d'un moteur ne contiendra que 1000 ou 2000 lignes de code, y compris les blancs et les commentaires, et il sera très facile à expliquer aux autres et à étendre. Si vous avez besoin de quelque chose de spécifique, vous aurez toujours le temps de coder une routine spécifique pour la gérer. cette.

L'approche consistant à utiliser une simple bibliothèque (que j'ai déjà mentionnée et testée dans mon article précédent) reste le meilleur moyen que j'ai trouvé pour résoudre le problème. La bibliothèque peut être une bibliothèque liée de manière dynamique (une DLL), ce qui signifie que la langue supérieure peut être un langage de niveau supérieur (plus adapté à la gestion de la totalité du flux de travail / de la sortie graphique de la simulation). Si vous souhaitez toujours utiliser C ++ pour cette couche, vous pouvez le faire facilement, mais si vous vous sentez mieux en utilisant Python, Java, C # ou Visual Basic, la DLL vous permettra de le faire tout en laissant C à la tâche difficile.

Après tous ces mois, je vois un moteur de simulation comme les méthodes d’appel exposées par un noyau de système d’exploitation, car un moteur de backtesting dans le trading quantitatif est beaucoup plus similaire à celui d’autre chose.

Ce point de vue est subjectif, mais j’estime que c’est toujours un avis éclairé. L’expérience mise au cours de ce parcours inclut la programmation - à l’occasion - depuis 1987, l’apprentissage des stratégies de trading au cours des trois dernières années et la mise au point de solutions de codage et de test pour chaque problème. Bien qu'un professionnel expérimenté du secteur ait définitivement plus d'expérience, il reste néanmoins un certain effort à faire pour obtenir au moins quelques points valables.

J'ai également toujours essayé de rassembler le plus de connaissances possible au cours des quelques occasions que j'ai eues pour parler à des personnes expérimentées dans ce secteur. À mon avis, cela a fortement stimulé la manière dont j'ai résolu le problème. Je pense que sans ces petites contributions, j'aborderais toujours le problème sous le mauvais angle.

Il convient également de mentionner que l'approche dépend fortement des besoins. Ce n’est pas la même chose de traiter des données quotidiennes que d’établir des données de marché de niveau III pour HFT, les besoins et les solutions sont différents.

Maintenant que les avertissements appropriés ont été faits, nous pouvons examiner les points à retenir:

  1. Passez aux mains des solutions graphiques avec des capacités de backtesting (Metatrader / Pro Real Time /…). Comme un collègue responsable d'un fonds quantitatif m'a dit une fois: personne dans l'industrie ne les utilise. Et maintenant je comprends clairement pourquoi.
  2. Des progiciels de backtesting / simulation dédiés (tels qu'Amibroker) peuvent accélérer la façon dont vous abordez un problème, mais ils sont trop restreints dans la façon dont ils effectuent les simulations et la courbe d'apprentissage pour les stratégies de complexité moyenne est forte. Ce sont tout simplement de meilleurs outils que des solutions graphiques. De leur côté, je dirai également que des personnes sérieuses du domaine quantitatif les utilisent, mais pour autant que je sache, elles utilisent généralement des données quotidiennes. Mon point de vue personnel: ne touchez pas à ceux-là aussi, surtout si vous voulez tester des stratégies plus exotiques ou y aller en infra-journalier.
  3. Développer une grande plate-forme / infrastructure polyvalente et personnalisée. Cela ne fonctionne pas, cela prend beaucoup de temps et vous finirez par créer un outil moins optimal car il essaie d’être trop polyvalent. L'une des tâches sur lesquelles nous travaillions était une plate-forme générale de back-test Java, et après 9 mois, j'ai réalisé que le projet n'avançait pas assez vite et qu'il ne répondait pas aussi bien aux besoins spécifiques. alors que les projets secondaires C / Python beaucoup plus limités et modestes montraient déjà des résultats et des voies de recherche prometteurs. Nous récupérons des concepts réutilisables et des blocs de code de ce projet pour les utiliser comme outils auxiliaires. Les petits projets sont faciles à faire avancer.
  4. Développez une solution entièrement Python personnalisée à l'aide de Jupyter Notebooks. Cela fonctionne, mais il sera lié et associé à la stratégie particulière que vous testez. Vous obtenez des résultats, mais la réutilisation de composants est difficile, l’expérience de débogage est médiocre et, à mesure que les simulations gagnent en complexité, la gestion des ordinateurs portables devient difficile. Peu importe combien j'aime la simplicité et la polyvalence de Python, je commence à penser que l'écosystème Python est peut-être un peu surestimé.
  5. Développer une petite bibliothèque / moteur avec les blocs de construction couramment utilisés dans la simulation. C’est, à mon avis, la bonne approche. Vous allez vous retrouver avec un ensemble commun de composants réutilisables. Même s’il est vrai que vous aurez probablement besoin de plus de méthodes, pour autant que vous testez plus de stratégies, c’est un moyen d’obtenir des gains rapides tout en faisant un bon investissement en termes de temps pour les travaux futurs. En développant ceci, n'oubliez pas de réduire la portée de la bibliothèque et d'éviter l'objectif général. Cela signifie que si vous testez des stratégies intrajournalières, concentrez-vous dessus. Et que, si vos données durent 1 minute, n’envisagez même pas ce qui se passe lorsque vous devez simuler des données de ticks ou commencez à penser que vous voudrez peut-être également consulter les tendances hebdomadaires. Si vous en avez besoin, utilisez un autre moteur et fusionnez les résultats.
  6. La langue compte. C / C ++ est mon choix final pour le noyau de simulation. J'ai aimé les aspects de toutes les autres langues, mais je ne peux pas obtenir la même performance que celle obtenue en C. Julia était prometteuse, et elle peut probablement correspondre à la performance en C lorsqu'elle est correctement codée, mais pour le codeur moyen - et je suis un codeur assez moyen - il est beaucoup plus facile d'écrire du code C rapide. C est aussi plus rapide à apprendre car c’est un langage de bas niveau et a de bien meilleurs outils de débogage et d’IDE. Soyons clairs sur ce point: Fortran, Julia et Python sont tous des langages exceptionnels. Python peut être un bon choix pour les données quotidiennes, mais à mon avis, il n’a pas bien fonctionné en intraday. Fortran était très rapide, il est facile à apprendre et à lire que C, mais, autant que je sache, il n’existe pas de bon compilateur / IDE gratuit pour cette langue et elle n’est pas aussi largement utilisée dans l’industrie que ne le faisait C. Julia. au début, mais je n’ai pas aimé cela beaucoup au moment de faire avancer le projet. Le débogage était à nouveau difficile et certains aspects du langage n'étaient pas si intuitifs.
  7. L'IDE et le débogage sont encore plus importants que la langue. Ne considérez pas le débogage de bas niveau (gdb, etc.) ou les langues sans un IDE approprié. J'ai passé beaucoup de temps à travailler sur une station de travail BSD et j'ai finalement transféré tout mon développement sous Windows simplement parce que développer C / C ++ avec Visual Studio est beaucoup plus simple que tout. Une fois que vous avez terminé, vous pouvez toujours transférer le code sur la plate-forme de votre choix.
  8. L'utilisation de deux langues: une au niveau de la couche de flux de travail / présentation et une autre pour la simulation (qui sera généralement C, car elle est rapide et facile à compiler en tant que bibliothèque dynamique ou statique) est un bon choix. Cela complique un peu la transaction de données entre deux couches, mais vous pouvez obtenir le meilleur des deux mondes et obtenir une encapsulation simple mais efficace (qui englobe l’ensemble du moteur dans une seule entité consommée par la couche supérieure). En résumé, cela n’apporte, à mon avis, aucun avantage pratique.
  9. Il n’est pas nécessaire de disposer d’une base de données si vous utilisez C. Je me suis concentré sur le fait d’en avoir une depuis le début et je n’en utilise actuellement aucune. Mon prochain projet concerne la gestion des données de ticks et je ne l'envisage absolument pas non plus (même lorsque le stockage et le traitement des données de ticks sont beaucoup plus complexes). Malgré leur attrait, je ne suis pas intéressé par la KDB + ni par aucune autre technologie, à moins que quelqu'un ne me demande quels sont les avantages réels de leur utilisation (je parle des avantages réels du projet, pas des avantages techniques, ni des abstractions informatiques). Plus j'utilise, plus j'aime utiliser l'ancienne approche par lots de l'ordinateur central: chargez les données avant le début de la simulation, simulez les données en mémoire et obtenez les résultats. De nos jours, un ordinateur de bureau usagé ex-leasing bon marché a plus de puissance de calcul que plusieurs superordinateurs Cray des années 80 combinés: vous avez juste besoin d’utiliser efficacement cette énorme puissance informatique que Dieu a mise sur votre bureau.
  10. Ne restez pas coincé avec les tendances de Data Science. Les ordinateurs portables, les frameworks parallèles distribués, les API Cloud et tous les Mumbo-Jumbo sont tous superbes et je suis sûr qu'ils occupent une place bien méritée dans le secteur, mais leur courbe d'apprentissage et leurs frais généraux de calcul sont plus souvent un fardeau qu'une aide. . Soyons clairs: un simple moteur intrajournalier peut parfaitement être écrit en ANSI C89 et il sera aussi rapide que possible. Il sera simple d’écrire, de comprendre et d’étendre, et ne nécessitera pas de ressources connaissant dix API et technologies différentes. L’industrie et les médias regorgent de cadres, de couches et de middleware prometteurs pour la Lune, et parfois tu as vraiment besoin d'euxBien souvent, leur utilisation est davantage motivée par les tendances que par les besoins réels et ils finissent par ne fournir que des frais généraux, des courbes d’apprentissage raides et de la douleur.
  11. Diviser et conquérir. Besoin d'une solution de cartographie pour valider la stratégie? Programmez un petit outil auxiliaire pour cette tâche. Besoin de charger des données personnalisées? Ecrivez un programme parallèle pour transformer ces données spécifiques. Ce concept d’écriture de petits programmes enchaînés n’est certes pas nouveau et il a toujours été mis en avant dans le monde UNIX, mais il est parfois oublié. Plus vos tâches / programmes sont petits, plus vous avez de chances de les exécuter efficacement. Écrire de petits programmes coopératifs est plus facile que de créer une seule application monolithique. Le concept d'utilisation d'une DLL en tant que moteur simplifie cette tâche.

Au final, les concepts récurrents de «moins est plus" et "rester simple ” travaille toujours. Pensez simplement à la solution la plus simple possible et réutilisable, et une fois que vous aurez simplifié les choses, réfléchissez à la manière de la rendre encore plus simple. Si quelque chose n'est pas clairement réutilisable, ne pensez pas comment l'abréger pour le rendre réutilisable, écrivez simplement un outil ou une méthode auxiliaire pour répondre à ce besoin spécifique. Ce paradigme fonctionne dans la plupart des cas en technologie: ne jamais avoir peur de le faire aussi simple.

Afficher plus

SupportIvy

SupportIvy.com : Un lieu pour partager le savoir et mieux comprendre le monde. Meilleure plate-forme de support gratuit pour vous, Documentation &Tutoriels par les experts.

Articles similaires

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Bouton retour en haut de la page
Fermer