C# pour le trading algorithmique
Qu'est-ce que C#
C# est un langage de programmation orienté objet utilisé pour créer une large gamme de services et d'applications. Sa syntaxe claire et structurée le rend facile à apprendre et à lire, même pour les débutants, tout en offrant une approche structurée pour écrire du code compact et réutilisable.
Algorithmes C# en une minute !
- Même si vous n'avez jamais travaillé avec C# auparavant, créer et déployer votre premier bot ou indicateur ne prend que quelques minutes.
- Comme C# est facile à utiliser, vous pouvez rapidement réécrire tous les extraits de code de cette documentation pour les adapter à vos besoins.
- Lorsque vous utilisez C#, vous pouvez accéder à un grand nombre de bibliothèques contenant des classes et des méthodes prédéfinies. Ces méthodes peuvent gérer efficacement les tâches courantes, vous laissant libre de résoudre des problèmes de trading complexes.
- En C#, vous pouvez écrire du code qui ne bloque pas les threads du serveur lors de l'exécution. En d'autres termes, vous pouvez démarrer certaines tâches simultanément avec d'autres tâches.
Qu'est-ce que .NET ?
Pour que les programmes C# s'exécutent, leur code source doit être compilé en langage intermédiaire (IL). Ce code IL suit la spécification Common Language Infrastructure (CLI) et est ensuite compilé en instructions machine natives au moment de l'exécution. Le framework .NET fournit un environnement d'exécution virtuel basé sur des bibliothèques de classes étendues et le Common Language Runtime (CLR), l'implémentation par Microsoft de la CLI.
Sans entrer dans les subtilités techniques, .NET remplit les fonctions suivantes :
- Faciliter le développement et l'exécution d'applications : Le .NET SDK contient déjà plusieurs compilateurs et moteurs de génération intégrés, éliminant ainsi le besoin de créer des solutions personnalisées.
- Fournir des bibliothèques d'exécution : Lorsque vous ajoutez de nouveaux types de données ou collections à votre code, vous constaterez souvent que .NET offre déjà des classes et des méthodes appropriées pour la tâche.
Les bases de C#
Types de données et déclarations de variables
Les types de données sont un moyen de catégoriser les données afin que C# sache exactement comment traiter les variables et les propriétés. Dans les déclarations de variables/propriétés, les types de données précèdent toujours le nom de la variable/propriété.
1 | |
Vous pouvez également utiliser le mot-clé var pour éviter de spécifier un type de données.
1 | |
Objets et classes
Considérez les objets comme des abstractions d'entités tangibles ou intangibles. Ces entités peuvent avoir certaines caractéristiques (propriétés) et peuvent effectuer diverses opérations (méthodes). À leur tour, les classes servent de modèles pour la création d'objets.
Comme C# est un langage orienté objet, les classes peuvent également hériter de propriétés et de méthodes d'autres classes. Considérez l'exemple suivant dans lequel nous déclarons une nouvelle classe NewBot qui hérite de la classe Robot. Nous définissons également de nouvelles propriétés de classe.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | |
Types de données
Comme C# est un langage fortement typé, il est nécessaire de spécifier les types de données lors de la déclaration de variables et de propriétés de classe. En bref, les types de données constituent des classes uniques avec différents ensembles de comportements. Considérez les exemples suivants dans lesquels différents types de données sont spécifiés pour différentes propriétés de classe et paramètres associés.
1 2 | |
Dans le code ci-dessus, le type de données DataSeries représente une liste de valeurs en lecture seule et est donc généralement utilisé pour représenter les prix du marché.
Lorsqu'il est nécessaire de créer des paramètres à options multiples, vous pouvez utiliser le type de données intégré enum comme détaillé ci-dessous. Vous pouvez considérer les enum comme des classes spéciales qui contiennent diverses constantes.
1 2 3 4 5 6 7 8 9 | |
Pour accéder à une constante contenue dans un enum, utilisez la syntaxe suivante.
1 | |
Si un paramètre ou une propriété doit être un nombre, vous utiliserez le plus souvent les types de données int (entier) ou double (décimal). Bien que le type double ait moins de précision que le type decimal, il consomme également moins de ressources.
1 2 | |
Enfin, le type bool représente généralement une entrée oui ou non. Les valeurs oui et non correspondent respectivement à true et false.
1 2 | |
Espaces de noms
Les espaces de noms agissent comme des collections désignées de classes. Une fois que vous avez assigné une classe à un espace de noms, elle peut ensuite être accessible en utilisant la notation Namespace.ClassName. Nous allons assigner notre NewBot à l'espace de noms CoolTradingBots.
1 2 3 4 5 6 7 8 | |
Méthodes de classe
Les méthodes de classe sont définies après la déclaration de classe. Tous les objets de notre classe NewBot pourront appeler la méthode CustomTradeOperation(). Elle prend deux arguments, à savoir un objet Symbol et un objet double. Notre méthode est censée prendre un symbole et exécuter une sorte d'action de trading pour le volume spécifié
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
Bibliothèques de classes
Les bibliothèques de classes (et, par la suite, les méthodes de classe) peuvent être accessibles par leur espace de noms comme indiqué dans l'exemple ci-dessous.
1 | |
Alternativement, vous pouvez taper le mot-clé using au début de votre code pour désigner certains espaces de noms et éviter les redondances. Considérez l'extrait de code suivant.
1 2 3 | |
Instructions conditionnelles
Pour utiliser des instructions conditionnelles, utilisez un mot-clé suivi d'une expression entre parenthèses rondes. L'exemple ci-dessous utilise le mot-clé if pour finaliser notre méthode CustomTradingOperation(). Pour ce faire, nous utilisons la méthode EvaluateMarket() qui est définie dans l'espace de noms Analytics.Actions.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
Collections
Les collections sont définies comme des conteneurs qui peuvent stocker un ou plusieurs objets d'une classe particulière.
Les collections sont entièrement indexables, ce qui signifie que leurs membres peuvent être accessibles en passant une certaine valeur integer entre crochets. Considérez l'exemple suivant dans lequel la méthode Calculate() affiche les propriétés d'une barre accessible via son index.
1 2 3 4 5 | |
Créer des extensions cTrader
Dans l'extrait ci-dessous, nous créons un robot de trading de base en utilisant uniquement les connaissances couvertes dans les sections ci-dessus.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
Opérations synchrones et asynchrones
Comme indiqué précédemment, C# prend entièrement en charge les opérations asynchrones. Le diagramme ci-dessous définit un exemple de base de la façon dont les activités de trading sont effectuées en exécution synchrone.
graph TD
A(Détecter un signal<br>technique) ==> B(Exécuter un<br>ordre au marché)
B ==> C(Take Profit/<br>Stop Loss<br>atteint)
C ==> D(Clôturer la<br>position)
D ==> A L'exécution synchrone présente un inconvénient important. Dans l'exemple ci-dessus, l'action d'exécuter un ordre de marché occupe entièrement tous les threads du serveur, ce qui signifie que votre robot de trading est incapable de faire quoi que ce soit d'autre avant que cette opération ne soit terminée.
Ce n'est pas idéal lorsque vous voulez réagir rapidement aux événements du marché et à la volatilité. Idéalement, votre bot devrait être capable de stocker diverses actions ou de mettre certaines tâches en attente pour s'engager dans d'autres activités plus urgentes. Nous allons développer notre exemple pour mieux refléter la façon dont les opérations asynchrones sont effectuées.
graph TD
A([Détecter un signal<br>technique]) ==> B([Placer un<br>ordre 'Buy']) & C([Placer un<br>ordre 'Sell'<br>de couverture]) ==> D([Un ordre<br>atteint son<br>Take Profit/<br>Stop Loss])
D ==> E([Clôturer la<br>position])
E ==> A Dans l'exemple ci-dessus, notre robot de trading a simultanément placé des ordres dans les deux directions pour couvrir ses positions. Contrairement aux opérations synchrones, il n'est pas nécessaire d'attendre qu'une opération soit terminée avant de passer à une autre. Cela élargit considérablement les opportunités des développeurs pour créer des robots de trading efficaces et fiables.
Notez que l'exécution asynchrone est différente du multi-threading :
- Dans l'exécution asynchrone, toutes les tâches sont démarrées sur le même thread. Lorsqu'elles sont stockées ou mises en attente, elles libèrent ce thread et, lorsque leur exécution se poursuit plus tard, elle se produit sur un thread différent choisi dans le pool de threads.
- Lors du multi-threading, toutes les tâches démarrent sur des threads différents et poursuivent leur exécution sur leurs threads initiaux. Il n'y a pas de mélange de threads.
cTrader n'invoque jamais vos méthodes en parallèle, vous n'avez donc pas à vous soucier des problèmes de multi-threading.
