GG-RSI-CCI-Strategie
Diese Strategie repliziert den GG-RSI-CCI MetaTrader Expert Advisor mithilfe der StockSharp High-Level-API. Sie kombiniert die Indikatoren Relative Strength Index (RSI) und Commodity Channel Index (CCI), jeweils geglättet durch zwei gleitende Durchschnitte. Eine Position wird eröffnet, wenn beide Indikatoren in dieselbe Richtung zeigen.
Logik
- Indikatoren
- RSI und CCI mit demselben Zeitraum berechnen.
- Jeden Indikator mit einem schnellen und einem langsamen gleitenden Durchschnitt glätten.
- Signale
- Kaufen wenn der schnelle RSI über dem langsamen RSI liegt und der schnelle CCI über dem langsamen CCI liegt.
- Verkaufen wenn der schnelle RSI unter dem langsamen RSI liegt und der schnelle CCI unter dem langsamen CCI liegt.
- Wenn der Modus auf
Flatgesetzt ist, schließt jeder neutrale Zustand die aktuelle Position.
- Risikomanagement
- Die Strategie ruft
StartProtectioneinmalig beim Start auf. Stop-Loss- und Take-Profit-Niveaus können über den Risikomanager der Plattform konfiguriert werden.
- Die Strategie ruft
Parameter
| Name | Beschreibung |
|---|---|
CandleType |
Zeitrahmen für die Berechnungen. |
Length |
RSI- und CCI-Periode. |
FastPeriod |
Schnelle Glättungsperiode. |
SlowPeriod |
Langsame Glättungsperiode. |
Volume |
Auftragsvolumen. |
AllowBuyOpen |
Long-Positionen öffnen aktivieren. |
AllowSellOpen |
Short-Positionen öffnen aktivieren. |
AllowBuyClose |
Short-Positionen schließen aktivieren. |
AllowSellClose |
Long-Positionen schließen aktivieren. |
Mode |
Trend schließt nur bei entgegengesetzten Signalen; Flat schließt auch bei neutralen Signalen. |
Hinweise
Die Strategie verarbeitet nur abgeschlossene Kerzen und verwendet High-Level-Auftragshelfer (BuyMarket / SellMarket). Sie vermeidet direkten Zugriff auf Indikatorpuffer und speichert den Status intern.
using System;
using System.Linq;
using System.Collections.Generic;
using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
using StockSharp.Algo;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Strategy based on the GG-RSI-CCI indicator.
/// </summary>
public class GgRsiCciStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _length;
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<bool> _allowBuyOpen;
private readonly StrategyParam<bool> _allowSellOpen;
private readonly StrategyParam<bool> _allowBuyClose;
private readonly StrategyParam<bool> _allowSellClose;
private readonly StrategyParam<SignalModes> _mode;
private SimpleMovingAverage _rsiFast = null!;
private SimpleMovingAverage _rsiSlow = null!;
private SimpleMovingAverage _cciFast = null!;
private SimpleMovingAverage _cciSlow = null!;
private int _prevSignal;
/// <summary>
/// Defines how positions are closed.
/// </summary>
public enum SignalModes
{
/// <summary>Position is closed only on opposite signal.</summary>
Trend,
/// <summary>Position is closed on any neutral signal.</summary>
Flat,
}
public GgRsiCciStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
.SetDisplay("Candle Type", "Time frame for indicator calculation.", "General");
_length = Param(nameof(Length), 8)
.SetGreaterThanZero()
.SetDisplay("Length", "RSI and CCI period.", "Indicators");
_fastPeriod = Param(nameof(FastPeriod), 3)
.SetGreaterThanZero()
.SetDisplay("Fast Period", "Fast smoothing period.", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 8)
.SetGreaterThanZero()
.SetDisplay("Slow Period", "Slow smoothing period.", "Indicators");
_allowBuyOpen = Param(nameof(AllowBuyOpen), true)
.SetDisplay("Allow Buy", "Permit opening long positions.", "Permissions");
_allowSellOpen = Param(nameof(AllowSellOpen), true)
.SetDisplay("Allow Sell", "Permit opening short positions.", "Permissions");
_allowBuyClose = Param(nameof(AllowBuyClose), true)
.SetDisplay("Close Short", "Permit closing short positions.", "Permissions");
_allowSellClose = Param(nameof(AllowSellClose), true)
.SetDisplay("Close Long", "Permit closing long positions.", "Permissions");
_mode = Param(nameof(Mode), SignalModes.Trend)
.SetDisplay("Mode", "Closing style.", "Trading");
}
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int Length
{
get => _length.Value;
set => _length.Value = value;
}
public int FastPeriod
{
get => _fastPeriod.Value;
set => _fastPeriod.Value = value;
}
public int SlowPeriod
{
get => _slowPeriod.Value;
set => _slowPeriod.Value = value;
}
public bool AllowBuyOpen
{
get => _allowBuyOpen.Value;
set => _allowBuyOpen.Value = value;
}
public bool AllowSellOpen
{
get => _allowSellOpen.Value;
set => _allowSellOpen.Value = value;
}
public bool AllowBuyClose
{
get => _allowBuyClose.Value;
set => _allowBuyClose.Value = value;
}
public bool AllowSellClose
{
get => _allowSellClose.Value;
set => _allowSellClose.Value = value;
}
public SignalModes Mode
{
get => _mode.Value;
set => _mode.Value = value;
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_rsiFast?.Reset();
_rsiSlow?.Reset();
_cciFast?.Reset();
_cciSlow?.Reset();
_prevSignal = -1;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var rsi = new RelativeStrengthIndex { Length = Length };
var cci = new CommodityChannelIndex { Length = Length };
_rsiFast = new SimpleMovingAverage { Length = FastPeriod };
_rsiSlow = new SimpleMovingAverage { Length = SlowPeriod };
_cciFast = new SimpleMovingAverage { Length = FastPeriod };
_cciSlow = new SimpleMovingAverage { Length = SlowPeriod };
_prevSignal = -1;
var subscription = SubscribeCandles(CandleType);
subscription.Bind(rsi, cci, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal rsiValue, decimal cciValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var rsiFast = _rsiFast.Process(new DecimalIndicatorValue(_rsiFast, rsiValue, candle.OpenTime)).ToDecimal();
var rsiSlow = _rsiSlow.Process(new DecimalIndicatorValue(_rsiSlow, rsiValue, candle.OpenTime)).ToDecimal();
var cciFast = _cciFast.Process(new DecimalIndicatorValue(_cciFast, cciValue, candle.OpenTime)).ToDecimal();
var cciSlow = _cciSlow.Process(new DecimalIndicatorValue(_cciSlow, cciValue, candle.OpenTime)).ToDecimal();
int signal;
if (rsiFast > rsiSlow && cciFast > cciSlow && cciValue > 0m)
signal = 2;
else if (rsiFast < rsiSlow && cciFast < cciSlow && cciValue < 0m)
signal = 0;
else
signal = 1;
if (signal == 2)
{
if (AllowSellClose && Position < 0)
BuyMarket(Math.Abs(Position));
if (AllowBuyOpen && Position <= 0 && _prevSignal != 2)
BuyMarket(Volume + Math.Abs(Position));
}
else if (signal == 0)
{
if (AllowBuyClose && Position > 0)
SellMarket(Position);
if (AllowSellOpen && Position >= 0 && _prevSignal != 0)
SellMarket(Volume + Math.Abs(Position));
}
else if (Mode == SignalModes.Flat)
{
if (AllowBuyClose && Position > 0)
SellMarket(Position);
if (AllowSellClose && Position < 0)
BuyMarket(Math.Abs(Position));
}
_prevSignal = signal;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Math
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import (
CommodityChannelIndex, RelativeStrengthIndex, SimpleMovingAverage,
)
from StockSharp.Algo.Strategies import Strategy
from indicator_extensions import *
# Signal mode constants
MODE_TREND = 0
MODE_FLAT = 1
class gg_rsi_cci_strategy(Strategy):
def __init__(self):
super(gg_rsi_cci_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))) \
.SetDisplay("Candle Type", "Time frame for indicator calculation.", "General")
self._length = self.Param("Length", 8) \
.SetDisplay("Length", "RSI and CCI period.", "Indicators")
self._fast_period = self.Param("FastPeriod", 3) \
.SetDisplay("Fast Period", "Fast smoothing period.", "Indicators")
self._slow_period = self.Param("SlowPeriod", 8) \
.SetDisplay("Slow Period", "Slow smoothing period.", "Indicators")
self._allow_buy_open = self.Param("AllowBuyOpen", True) \
.SetDisplay("Allow Buy", "Permit opening long positions.", "Permissions")
self._allow_sell_open = self.Param("AllowSellOpen", True) \
.SetDisplay("Allow Sell", "Permit opening short positions.", "Permissions")
self._allow_buy_close = self.Param("AllowBuyClose", True) \
.SetDisplay("Close Short", "Permit closing short positions.", "Permissions")
self._allow_sell_close = self.Param("AllowSellClose", True) \
.SetDisplay("Close Long", "Permit closing long positions.", "Permissions")
self._mode = self.Param("Mode", MODE_TREND) \
.SetDisplay("Mode", "Closing style.", "Trading")
self._rsi_fast = None
self._rsi_slow = None
self._cci_fast = None
self._cci_slow = None
self._prev_signal = -1
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def Length(self):
return self._length.Value
@Length.setter
def Length(self, value):
self._length.Value = value
@property
def FastPeriod(self):
return self._fast_period.Value
@FastPeriod.setter
def FastPeriod(self, value):
self._fast_period.Value = value
@property
def SlowPeriod(self):
return self._slow_period.Value
@SlowPeriod.setter
def SlowPeriod(self, value):
self._slow_period.Value = value
@property
def AllowBuyOpen(self):
return self._allow_buy_open.Value
@AllowBuyOpen.setter
def AllowBuyOpen(self, value):
self._allow_buy_open.Value = value
@property
def AllowSellOpen(self):
return self._allow_sell_open.Value
@AllowSellOpen.setter
def AllowSellOpen(self, value):
self._allow_sell_open.Value = value
@property
def AllowBuyClose(self):
return self._allow_buy_close.Value
@AllowBuyClose.setter
def AllowBuyClose(self, value):
self._allow_buy_close.Value = value
@property
def AllowSellClose(self):
return self._allow_sell_close.Value
@AllowSellClose.setter
def AllowSellClose(self, value):
self._allow_sell_close.Value = value
@property
def Mode(self):
return self._mode.Value
@Mode.setter
def Mode(self, value):
self._mode.Value = value
def OnStarted2(self, time):
super(gg_rsi_cci_strategy, self).OnStarted2(time)
rsi = RelativeStrengthIndex()
rsi.Length = self.Length
cci = CommodityChannelIndex()
cci.Length = self.Length
self._rsi_fast = SimpleMovingAverage()
self._rsi_fast.Length = self.FastPeriod
self._rsi_slow = SimpleMovingAverage()
self._rsi_slow.Length = self.SlowPeriod
self._cci_fast = SimpleMovingAverage()
self._cci_fast.Length = self.FastPeriod
self._cci_slow = SimpleMovingAverage()
self._cci_slow.Length = self.SlowPeriod
self._prev_signal = -1
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(rsi, cci, self.ProcessCandle).Start()
def ProcessCandle(self, candle, rsi_value, cci_value):
if candle.State != CandleStates.Finished:
return
if not self.IsFormedAndOnlineAndAllowTrading():
return
rsi_val = float(rsi_value)
cci_val = float(cci_value)
rsi_fast = float(process_float(self._rsi_fast, rsi_val, candle.OpenTime, True))
rsi_slow = float(process_float(self._rsi_slow, rsi_val, candle.OpenTime, True))
cci_fast = float(process_float(self._cci_fast, cci_val, candle.OpenTime, True))
cci_slow = float(process_float(self._cci_slow, cci_val, candle.OpenTime, True))
if rsi_fast > rsi_slow and cci_fast > cci_slow and cci_val > 0.0:
signal = 2
elif rsi_fast < rsi_slow and cci_fast < cci_slow and cci_val < 0.0:
signal = 0
else:
signal = 1
pos = self.Position
if signal == 2:
if self.AllowSellClose and pos < 0:
self.BuyMarket(abs(pos))
if self.AllowBuyOpen and pos <= 0 and self._prev_signal != 2:
self.BuyMarket(self.Volume + abs(self.Position))
elif signal == 0:
if self.AllowBuyClose and pos > 0:
self.SellMarket(pos)
if self.AllowSellOpen and pos >= 0 and self._prev_signal != 0:
self.SellMarket(self.Volume + abs(self.Position))
elif self.Mode == MODE_FLAT:
if self.AllowBuyClose and pos > 0:
self.SellMarket(pos)
if self.AllowSellClose and pos < 0:
self.BuyMarket(abs(pos))
self._prev_signal = signal
def OnReseted(self):
super(gg_rsi_cci_strategy, self).OnReseted()
if self._rsi_fast is not None:
self._rsi_fast.Reset()
if self._rsi_slow is not None:
self._rsi_slow.Reset()
if self._cci_fast is not None:
self._cci_fast.Reset()
if self._cci_slow is not None:
self._cci_slow.Reset()
self._prev_signal = -1
def CreateClone(self):
return gg_rsi_cci_strategy()