Aller au contenu

Comment ajouter des méthodes à l'API cTrader

Les méthodes d'extension sont un outil crucial si vous souhaitez ajouter de nouvelles fonctionnalités à l'API cTrader. En utilisant une syntaxe relativement simple, vous pouvez ajouter de nouveaux comportements à n'importe quelle classe d'API prédéfinie, telle que Symbol ou Position. Après avoir défini une méthode d'extension, vous pouvez l'appeler depuis n'importe quel objet de la classe que vous avez étendue.

Cas d'utilisation des méthodes d'extension

Tout d'abord, nous allons effectuer une démonstration rapide de la raison pour laquelle vous pourriez vouloir utiliser des méthodes d'extension.

En utilisant un cBot, nous voulons pouvoir accéder à la taille d'une position donnée en lots car cette information affecte directement notre stratégie de trading préférée. Pour ce faire, nous pouvons essayer d'initialiser une variable de la classe Position puis essayer d'accéder à sa méthode Lots().

1
2
Position position = Positions.Last();
Print(position.Lots());

Si nous tapons simplement le code tel quel, nous recevrons une erreur suggérant que l'accesseur Lots() n'existe pas dans l'API. Mais que se passerait-il s'il existait un moyen d'ajouter une nouvelle méthode à un membre d'API existant sans affecter les autres fonctionnalités ?

En supposant que cette méthode existe, nous aurions pu créer un cBot simple qui, à chaque barre, itérerait sur une liste de toutes les positions actuelles et imprimerait leur taille en lots dans le journal. Nous définirions la méthode OnBar() comme suit.

1
2
3
4
5
6
protected override void OnBar()
{
    foreach (var position in Positions) {
        Print(position.Lots());
    }
}

Les méthodes d'extension nous permettent d'ajouter la fonctionnalité Lots() en quelques lignes de code seulement, puis de la réutiliser quand nous le souhaitons sur n'importe quel objet de la classe Position. Ci-dessous, nous expliquons comment vous pouvez en créer une et fournissons plusieurs exemples d'algos les utilisant.

Comment fonctionnent les méthodes d'extension

Lorsque vous travaillez avec des méthodes d'extension, gardez à l'esprit les règles suivantes.

  • Les méthodes d'extension sont toujours statiques.

Pour déclarer une méthode statique, il vous suffit d'utiliser le mot-clé static. Ci-dessous, déclarez la méthode Lots() avec un corps vide.

1
2
3
4
public static class MyExtensions {
    public static double Lots() {}

}
  • Les méthodes d'extension peuvent avoir n'importe quel nombre d'arguments, mais le premier argument doit toujours désigner le type de données/classe pour lequel la méthode est censée être appelée, précédé du mot-clé this.

Nous ajouterons un objet de la classe Position comme premier et seul argument de la méthode Lots(). Comme un objet Position contient également des informations sur le symbole pour lequel la position est ouverte, nous n'avons besoin d'aucun autre argument.

1
2
3
public static class MyExtensions {
    public static double Lots(this Position position) {}
}
  • Les méthodes d'extension peuvent contenir toute logique adaptée aux arguments fournis.

Il n'est pas nécessaire d'utiliser une syntaxe spéciale lors de la définition du corps d'une méthode d'extension. Nous pouvons la traiter comme n'importe quelle autre méthode et, par conséquent, pouvons définir son corps comme suit.

1
2
3
4
5
public static class MyExtensions {
    public static double Lots(this Position position) {
        return position.VolumeInUnits / position.Symbol.LotSize;
    }
}
  • Les méthodes d'extension peuvent être appelées comme des méthodes d'instance ou des méthodes statiques.

Il existe deux façons possibles d'appeler notre méthode d'extension dans le code d'un cBot.

Lors de l'utilisation de la syntaxe de méthode d'instance, nous appelons la méthode depuis n'importe quel objet approprié du type Position.

1
2
var position = Positions.Last();
Print(position.Lots());

Lors de l'utilisation de la syntaxe de méthode statique, nous pouvons appeler notre méthode d'extension après avoir entièrement spécifié sa classe statique correspondante.

1
2
var position = Positions.Last();
Print(MyExtensions.Lots(position));

C'est à vous de déterminer quelle méthode d'appel des méthodes d'extension est la plus pratique.

Signatures de méthode

Lorsque vous utilisez la syntaxe d'instance, évitez les cas où vos méthodes d'extension ont les mêmes signatures que les méthodes API intégrées (telles que Position.Close()). Dans ces situations, une méthode intégrée sera appelée chaque fois que vous tenterez d'appeler une méthode d'extension avec la signature correspondante.

IntelliSense

Lorsque nous tentons d'appeler une méthode d'extension, IntelliSense utilise une icône spéciale pour la distinguer des membres API intégrés.

Pour démontrer notre nouvelle méthode en action, nous pouvons créer un cBot qui place trois ordres au démarrage, chacun avec un volume différent. À chaque barre, le cBot affiche le volume de toutes les positions actuellement ouvertes en lots.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
protected override void OnStart()
{
    ExecuteMarketOrder(TradeType.Buy, SymbolName, 10000);
    ExecuteMarketOrder(TradeType.Buy, SymbolName, 100000);
    ExecuteMarketOrder(TradeType.Buy, SymbolName, 50000);
}

protected override void OnBar()
{
    foreach (var position in Positions) {
        Print(position.Lots());
    }
}

Après avoir construit et lancé notre cBot, nous devrions voir les valeurs correctes s'afficher dans le journal.

Utiliser les méthodes d'extension dans les cBots

Nous allons maintenant essayer de créer un cBot plus complexe. À chaque barre, notre algorithme parcourra la liste des positions actuellement ouvertes et ajustera leurs niveaux de stop loss afin qu'ils soient au seuil de rentabilité. Pour ce faire, nous devrons créer une méthode d'extension BreakEven() pour la classe Position.

Nous créons un nouveau cBot et le renommons. Ensuite, nous supprimons tout le code dont nous n'avons pas besoin et ajoutons la classe MyExtensions.

1
2
3
public static class MyExtensions {

}

Notre code pour la méthode BreakEven() est relativement simple. Nous vérifions si une position a un stop loss, si son profit brut est supérieur à zéro et si le stop loss actuellement défini n'est pas égal au cours d'entrée de la position. Si toutes ces conditions sont vraies, nous modifions le stop loss de la position afin qu'il soit égal au cours d'entrée de la position.

1
2
3
4
5
6
7
public static class MyExtensions {
    public static void BreakEven(this Position position) {
        if (position.StopLoss is not null && position.GrossProfit > 0 && position.StopLoss != position.EntryPrice) {
            position.ModifyStopLossPrice(position.EntryPrice);
        }
    }
}

Dans le cBot lui-même, nous n'avons pas besoin d'utiliser d'autre méthode que OnBar(). À chaque barre, nous demandons au cBot d'effectuer une opération simple, à savoir itérer sur la collection Positions et appeler la nouvelle méthode BreakEven() pour chaque élément qu'elle contient.

1
2
3
4
5
6
protected override void OnBar() 
{
    foreach (var position in Positions) {
        position.BreakEven();
    }
}

Après avoir construit et lancé notre cBot, nous pouvons le voir en action. Il peut être un assistant de trading utile, en particulier lors de la gestion de nombreuses positions ouvertes.

Utiliser les méthodes d'extension dans les indicateurs

Nous allons également créer un indicateur utile qui s'appuie sur les méthodes d'extension. L'indicateur mesurera la volatilité en traçant le pourcentage de variation du prix d'un symbole sur chaque barre par rapport au prix d'ouverture de cette barre.

Pour ce faire, nous allons créer un nouvel indicateur et le renommer. Dans la fenêtre de l'éditeur de code, nous allons créer la classe MyExtensions pour étendre la classe Bar.

1
2
3
public static class MyExtensions {

}

Nous ajouterons également la méthode PercentageChange(). Dans la variable priceChange, nous soustrayons le prix de clôture d'une barre de son prix d'ouverture. La méthode renvoie notre variation de prix divisée par le prix d'ouverture et multipliée par 100.

1
2
3
4
5
6
7
8
public static class MyExtensions 
{
    public static double PercentageChange(this Bar bar) 
    {
        var priceChange = bar.Open - bar.Close;
        return priceChange / bar.Open * 100;
    }
}

Dans le code de l'indicateur lui-même, nous n'avons pas besoin de la méthode Initialize() ni des paramètres inutiles. Dans le corps de la méthode Calculate(), nous appelons simplement notre nouvelle méthode PercentageChange() sur chaque barre.

1
2
3
4
5
6
7
8
[Output("Main")]
public IndicatorDataSeries Result { get; set; }


public override void Calculate(int index)
{
    Result[index] = Bars[index].PercentageChange();
}

Ensuite, nous enregistrons et construisons notre indicateur. Après avoir créé une instance de celui-ci, nous devrions voir les variations de pourcentage correctes tracées. Elles peuvent être utilisées pour déterminer la volatilité à court et à long terme, au profit de toutes sortes de stratégies de trading.

Résumé

Pour conclure, les méthodes d'extension sont un outil précieux si vous souhaitez créer du code réutilisable qui ajoute de nouvelles fonctionnalités à l'API cTrader. Nous recommandons vivement d'expérimenter avec les méthodes d'extension car elles peuvent rendre vos algorithmes plus efficaces et plus faciles à maintenir.