Aller au contenu

Coder des stratégies multi-périodes

Souvent, les stratégies automatisées doivent prendre en compte les informations de différentes périodes avant de prendre une décision de trading. Heureusement, cTrader fournit de nombreux outils qui permettent aux algos d'accéder facilement aux données de plusieurs périodes. Dans cette vidéo et son article correspondant, nous expliquerons comment vous pouvez utiliser ces outils pour créer un cBot efficace.

Déclarer les paramètres du cBot

Nous commencerons par déclarer les paramètres nécessaires pour une moyenne mobile. Nous aurons besoin de la période, de la période du graphique et du type de moyenne mobile.

1
2
3
4
5
6
7
8
[Parameter("MA 1 Period", DefaultValue = 14, Group = "Moving Averages")]
        public int MA1Period { get; set; }

[Parameter("MA 1 Timeframe", DefaultValue = "Hour", Group = "Moving Averages")]
public TimeFrame MA1Timeframe { get; set; }

[Parameter("MA 1 Type", Group = "Moving Averages")]
public MovingAverageType MA1Type { get; set; }

Ensuite, nous pouvons définir la moyenne mobile.

1
private MovingAverage _ma1;

Nous pouvons initialiser la moyenne mobile dans la méthode OnStart(). Nous utiliserons la méthode MarketData.GetBars() pour obtenir les barres de la première moyenne mobile et les transmettre au constructeur de l'indicateur. La méthode GetBars() est utile pour obtenir des données de barres pour n'importe quelle période et n'importe quel symbole dont vous avez besoin.

1
_ma1 = Indicators.MovingAverage(MarketData.GetBars(MA1Timeframe).ClosePrices, MA1Period, MA1Type);

Nous répéterons le processus pour les deux autres moyennes mobiles. Vous pouvez simplement copier et coller le code ci-dessous pour continuer.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
Parameter("MA 1 Period", DefaultValue = 14, Group = "Moving Averages")]
public int MA1Period { get; set; }

[Parameter("MA 1 Timeframe", DefaultValue = "Hour", Group = "Moving Averages")]
public TimeFrame MA1Timeframe { get; set; }

[Parameter("MA 1 Type", Group = "Moving Averages")]
public MovingAverageType MA1Type { get; set; }

[Parameter("MA 2 Period", DefaultValue = 14, Group = "Moving Averages")]
public int MA2Period { get; set; }

[Parameter("MA 2 Timeframe", DefaultValue = "Hour2", Group = "Moving Averages")]
public TimeFrame MA2Timeframe { get; set; }

[Parameter("MA 2 Type", Group = "Moving Averages")]
public MovingAverageType MA2Type { get; set; }

[Parameter("MA 3 Period", DefaultValue = 14, Group = "Moving Averages")]
public int MA3Period { get; set; }

[Parameter("MA 3 Timeframe", DefaultValue = "Hour4", Group = "Moving Averages")]
public TimeFrame MA3Timeframe { get; set; }

[Parameter("MA 3 Type", Group = "Moving Averages")]
public MovingAverageType MA3Type { get; set; }

private MovingAverage _ma1;
private MovingAverage _ma2;
private MovingAverage _ma3;

protected override void OnStart()
{
    _ma1 = Indicators.MovingAverage(MarketData.GetBars(MA1Timeframe).ClosePrices, MA1Period, MA1Type);
    _ma2 = Indicators.MovingAverage(MarketData.GetBars(MA2Timeframe).ClosePrices, MA2Period, MA2Type);
    _ma3 = Indicators.MovingAverage(MarketData.GetBars(MA3Timeframe).ClosePrices, MA3Period, MA3Type);
}

Implémenter la logique de trading

À ce stade, nous pouvons implémenter la logique de trading. Notre stratégie maintiendra une position longue lorsque toutes les moyennes mobiles sont en hausse et une position courte lorsque les moyennes mobiles sont en baisse. Voici le code pour toute la logique d'achat.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
if (_ma1.Result.IsRising() && _ma2.Result.IsRising() && _ma3.Result.IsRising())
{
    if (Positions.Count(p => p.SymbolName == SymbolName && p.TradeType == TradeType.Buy) == 0)
        ExecuteMarketOrder(TradeType.Buy, SymbolName, 100000);
}
else
{
    foreach (var position in Positions.Where(p => p.SymbolName == SymbolName && p.TradeType == TradeType.Buy))
    {
        position.Close();
    }
}

Et voici le code pour la logique de vente.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
if (_ma1.Result.IsFalling() && _ma2.Result.IsFalling() && _ma3.Result.IsFalling())
{
    if (Positions.Count(p => p.SymbolName == SymbolName && p.TradeType == TradeType.Sell) == 0)
        ExecuteMarketOrder(TradeType.Sell, SymbolName, 100000);
}
else
{
    foreach (var position in Positions.Where(p => p.SymbolName == SymbolName && p.TradeType == TradeType.Sell))
    {
        position.Close();
    }
}

Backtester la stratégie multi-périodes

Enfin, nous devons backtester notre nouveau cBot. Nous pouvons voir que le cBot entre en position lorsque les moyennes mobiles sont synchronisées dans la même direction et reste hors du marché lorsque chaque indicateur pointe dans une direction différente.