Ir para o conteúdo

Codificar estratégias multi-timeframe

Frequentemente, as estratégias automatizadas precisam de considerar informações de diferentes timeframes antes de tomar uma decisão de negociação. Felizmente, o cTrader fornece muitas ferramentas que permitem que os algos acedam facilmente a dados de múltiplos timeframes. Neste vídeo e no artigo correspondente, explicaremos como pode usar estas ferramentas para criar um cBot eficaz.

Declarar parâmetros do cBot

Começaremos por declarar os parâmetros necessários para uma média móvel. Precisaremos do período, do timeframe e do tipo de média móvel.

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

Depois, podemos definir a média móvel.

1
private MovingAverage _ma1;

Podemos inicializar a média móvel no método OnStart(). Usaremos o método MarketData.GetBars() para obter as barras da primeira média móvel e passá-las para o construtor do indicador. O método GetBars() é útil para obter dados de barras para qualquer timeframe e qualquer símbolo de que precise.

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

Repetiremos o processo para as outras duas médias móveis. Pode simplesmente copiar e colar o código abaixo para prosseguir.

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

Implementar a lógica de negociação

Neste ponto, podemos implementar a lógica de negociação. A nossa estratégia manterá uma posição de compra quando todas as médias móveis estiverem a subir e uma posição de venda quando as médias móveis estiverem a cair. Aqui está o código para toda a lógica do lado da compra.

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

E aqui está o código para a lógica do lado da venda.

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

Testar a estratégia multi-timeframe

Por último, devemos testar o nosso novo cBot. Podemos ver que o cBot entra em posições quando as médias móveis estão sincronizadas na mesma direção e fica fora do mercado quando cada indicador aponta para uma direção diferente.