Перейти к содержанию

Программируйте мультитаймфреймовые стратегии

Часто автоматизированным стратегиям необходимо учитывать информацию с разных таймфреймов перед принятием торгового решения. К счастью, cTrader предоставляет множество инструментов, которые позволяют алгоритмам легко получать доступ к данным с нескольких таймфреймов. В этом видео и соответствующей статье мы объясним, как вы можете использовать эти инструменты для создания эффективного сиБота.

Объявите параметры сиБота

Начнем с объявления необходимых параметров для скользящей средней. Нам понадобятся период, таймфрейм и тип скользящей средней.

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; }

Затем мы можем определить скользящую среднюю.

1
private MovingAverage _ma1;

Мы можем инициализировать скользящую среднюю в методе OnStart(). Мы будем использовать метод MarketData.GetBars() для получения баров первой скользящей средней и передачи их в конструктор индикатора. Метод GetBars() полезен для получения данных баров для любого таймфрейма и любого необходимого вам инструмента.

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

Мы повторим процесс для двух других скользящих средних. Вы можете просто скопировать и вставить приведенный ниже код, чтобы продолжить.

 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);
}

Реализуйте торговую логику

На этом этапе мы можем реализовать торговую логику. Наша стратегия будет удерживать позицию на покупку, когда все скользящие средние растут, и позицию на продажу, когда скользящие средние падают. Вот код для всей логики покупки.

 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();
    }
}

А вот код для логики продажи.

 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();
    }
}

Протестируйте мультитаймфреймовую стратегию

Наконец, мы должны протестировать наш новый сиБот. Мы видим, что сиБот открывает позиции, когда скользящие средние синхронизированы в одном направлении, и остается вне рынка, когда каждый индикатор указывает на разное направление.