Vai al contenuto

Codifica strategie multi-timeframe

Spesso, le strategie automatizzate devono considerare informazioni provenienti da diversi periodi di tempo prima di prendere una decisione di trading. Fortunatamente, cTrader fornisce numerosi strumenti che consentono agli algoritmi di accedere facilmente ai dati da più periodi di tempo. In questo video e nel relativo articolo, spiegheremo come puoi utilizzare questi strumenti per creare un cBot efficace.

Dichiara i parametri del cBot

Inizieremo dichiarando i parametri necessari per una media mobile. Avremo bisogno del periodo, del periodo di tempo e del tipo di media 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; }

Quindi, possiamo definire la media mobile.

1
private MovingAverage _ma1;

Possiamo inizializzare la media mobile nel metodo OnStart(). Useremo il metodo MarketData.GetBars() per ottenere le barre della prima media mobile e passarle al costruttore dell'indicatore. Il metodo GetBars() è utile per ottenere i dati delle barre per qualsiasi periodo di tempo e qualsiasi simbolo di cui hai bisogno.

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

Ripeteremo il processo per le altre due medie mobili. Puoi semplicemente copiare e incollare il codice qui sotto per procedere.

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

Implementare la logica di trading

A questo punto, possiamo implementare la logica di trading. La nostra strategia manterrà una posizione long quando tutte le medie mobili sono in aumento e una posizione short quando le medie mobili sono in calo. Ecco il codice per tutta la logica lato acquisto.

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

Ed ecco il codice per la logica lato vendita.

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

Eseguire il backtest della strategia multi-timeframe

Infine, dovremmo eseguire il backtest del nostro nuovo cBot. Possiamo vedere che il cBot entra in posizioni quando le medie mobili sono sincronizzate nella stessa direzione e rimane fuori dal mercato quando ogni indicatore punta in una direzione diversa.