Pairs-Trading-Strategie
Überblick
PairsTradingStrategy ist eine Pairs-Trading-Strategie auf Basis statistischer Arbitrage zwischen zwei verwandten Instrumenten. Sie verfolgt den Spread zwischen den Preisen zweier Assets und eröffnet Positionen, wenn der Spread deutlich vom Mittelwert abweicht, in Erwartung einer Rückkehr zum Mittelwert.
Hauptkomponenten
Die Strategie erbt von Strategy und verwendet Parameter zur Konfiguration:
public class PairsTradingStrategy : Strategy
{
private readonly StrategyParam<int> _spreadLength;
private readonly StrategyParam<decimal> _entryThreshold;
private readonly StrategyParam<decimal> _exitThreshold;
private readonly StrategyParam<DataType> _candleType;
// Letzte Preise für jedes Instrument
private decimal? _lastPrice1;
private decimal? _lastPrice2;
}
Strategieparameter
Die Strategie erlaubt die Anpassung der folgenden Parameter:
- SpreadLength - Periode zur Berechnung des Spread-Mittelwerts und der Standardabweichung (Standardwert 20)
- EntryThreshold - Z-Score-Schwellenwert für den Positionseinstieg (Standardwert 2.0)
- ExitThreshold - Z-Score-Schwellenwert für den Positionsausstieg (Standardwert 0.5)
- CandleType - Kerzentyp, mit dem gearbeitet wird (standardmäßig 5 Minuten)
Alle Parameter stehen mit festgelegten Wertebereichen für die Optimierung zur Verfügung.
Initialisierung der Strategie
In der Methode OnStarted2 werden Indikatoren erstellt und Kerzenabonnements für zwei Instrumente eingerichtet:
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
// Zwei Instrumente für Pairs Trading abrufen
var securities = GetWorkingSecurities().ToArray();
if (securities.Length < 2)
throw new InvalidOperationException("Zwei Instrumente müssen angegeben werden.");
var sec1 = securities[0].sec;
var sec2 = securities[1].sec;
// Indikatoren zur Berechnung von Spread-Mittelwert und Standardabweichung
var sma = new SimpleMovingAverage { Length = SpreadLength };
var stdDev = new StandardDeviation { Length = SpreadLength };
_lastPrice1 = null;
_lastPrice2 = null;
// Kerzen des ersten Instruments abonnieren
SubscribeCandles(CandleType, security: sec1)
.Bind(c =>
{
if (c.State != CandleStates.Finished)
return;
_lastPrice1 = c.ClosePrice;
})
.Start();
// Kerzen des zweiten Instruments mit Spread-Verarbeitung abonnieren
SubscribeCandles(CandleType, security: sec2)
.Bind(c =>
{
if (c.State != CandleStates.Finished)
return;
_lastPrice2 = c.ClosePrice;
if (_lastPrice1 == null)
return;
ProcessSpread(_lastPrice1.Value, _lastPrice2.Value, sma, stdDev);
})
.Start();
}
Spread-Verarbeitung
Die Methode ProcessSpread berechnet den Z-Score des Spreads und erzeugt Handelssignale:
private void ProcessSpread(decimal price1, decimal price2,
SimpleMovingAverage sma, StandardDeviation stdDev)
{
// Spread als Preisdifferenz berechnen
var spread = price1 - price2;
// Indikatoren verarbeiten
var smaValue = sma.Process(new DecimalIndicatorValue(sma, spread));
var devValue = stdDev.Process(new DecimalIndicatorValue(stdDev, spread));
if (!sma.IsFormed || !stdDev.IsFormed)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var mean = smaValue.ToDecimal();
var dev = devValue.ToDecimal();
if (dev == 0)
return;
// Z-Score berechnen: Spread-Abweichung vom Mittelwert in Einheiten der Standardabweichung
var zScore = (spread - mean) / dev;
// Spread zu hoch: erstes Instrument verkaufen, zweites kaufen
if (zScore > EntryThreshold && Position >= 0)
{
SellMarket(Volume + Math.Abs(Position));
}
// Spread zu niedrig: erstes Instrument kaufen, zweites verkaufen
else if (zScore < -EntryThreshold && Position <= 0)
{
BuyMarket(Volume + Math.Abs(Position));
}
// Rückkehr zum Mittelwert: Position schließen
else if (Math.Abs(zScore) < ExitThreshold && Position != 0)
{
ClosePosition();
}
}
Handelslogik
- Verkaufssignal: Der Z-Score des Spreads überschreitet den Einstiegsschwellenwert (Standardwert 2.0), wenn keine Short-Position vorhanden ist.
- Kaufsignal: Der Z-Score des Spreads fällt unter den negativen Einstiegsschwellenwert (Standardwert -2.0), wenn keine Long-Position vorhanden ist.
- Position schließen: Der absolute Z-Score-Wert fällt unter den Ausstiegsschwellenwert (Standardwert 0.5) und signalisiert, dass der Spread zum Mittelwert zurückkehrt.
Funktionen
- Die Strategie arbeitet mit zwei Instrumenten, die über die Methode
GetWorkingSecurities()abgerufen werden. - Der Spread wird als Differenz der Schlusskurse von Kerzen aus zwei Instrumenten berechnet.
- Der Z-Score wird verwendet, um die Spread-Abweichung vom Mittelwert zu normalisieren.
- Die Strategie implementiert das klassische Mean-Reversion-Konzept.
- Die Strategie arbeitet nur mit abgeschlossenen Kerzen.
- Parameteroptimierung wird unterstützt, um optimale Strategieeinstellungen zu finden.