FiveMinuteRsiCciStrategy — порт советника MetaTrader 4 5Mins Rsi Cci EA.mq4 на платформу StockSharp. Оригинальный алгоритм торгует пятиминутные свечи, комбинируя пробой уровней RSI с фильтром из сглаженной/экспоненциальной средних по цене открытия и полярностью двух индикаторов CCI. Перенос сохраняет торговые правила и использует высокоуровневый API StockSharp для подписки на данные, расчёта индикаторов и управления рисками.
Логика торговли
Подписка на выбранный таймфрейм (по умолчанию 5 минут) и одновременный пересчёт пяти индикаторов: RSI, сглаженной MA по цене открытия, EMA по цене открытия, а также быстрого и медленного CCI от типичной цены.
Анализируется только закрытая свеча, когда нет открытой позиции и текущий спред меньше MaxSpreadPoints (значение переводится в денежные единицы).
Сигнал на покупку формируется при выполнении условий:
сглаженная MA находится выше EMA;
RSI между предыдущей и текущей свечой пересекает уровень BullishRsiLevel снизу вверх;
оба значения CCI положительные.
Сигнал на продажу требует обратных условий (MA ниже EMA, RSI пробивает BearishRsiLevel сверху вниз, оба CCI отрицательны).
Объём сделки воспроизводит динамическую формулу советника: LotCoefficient × sqrt(Equity / EquityDivisor) с округлением к VolumeStep и учётом ограничений VolumeMin/VolumeMax инструмента.
Метод StartProtection автоматически добавляет стоп-лосс, тейк-профит и трейлинг-стоп, преобразуя метатрейдеровские пункты в абсолютные ценовые смещения.
Параметры
Параметр
Значение по умолчанию
Описание
CandleType
TimeSpan.FromMinutes(5).TimeFrame()
Таймфрейм для расчёта индикаторов и сигналов.
RsiPeriod
14
Количество свечей в расчёте RSI.
FastSmmaPeriod
2
Период быстрой сглаженной средней по цене открытия.
SlowEmaPeriod
6
Период медленной EMA по цене открытия.
FastCciPeriod
34
Период быстрого CCI от типичной цены (H+L+C)/3.
SlowCciPeriod
175
Период медленного CCI от типичной цены.
BullishRsiLevel
55
Уровень RSI, который должен быть пробит снизу вверх для допуска лонгов.
BearishRsiLevel
45
Уровень RSI, который должен быть пробит сверху вниз для допуска шортов.
StopLossPoints
60
Дистанция стоп-лосса в пунктах MetaTrader (0 — без стопа).
TakeProfitPoints
0
Дистанция тейк-профита в пунктах MetaTrader (0 оставляет тейк отключённым, как в оригинале).
TrailingStopPoints
20
Дистанция трейлинг-стопа в пунктах MetaTrader (0 отключает трейлинг).
Делитель внутри квадратного корня (sqrt(Equity / EquityDivisor)).
MaxSpreadPoints
18
Максимально допустимый спред в пунктах MetaTrader.
Особенности
Фильтр по спреду использует поток Level1. Пока нет котировок best bid/ask, стратегия ожидает и не открывает позицию.
Пересчёт пунктов в цену учитывает PriceStep и точность инструмента; для пяти- и трёхзнаковых символов шаг умножается на 10, что соответствует значению Point в MetaTrader.
Защитные приказы обслуживает встроенный движок StockSharp c рыночными выходами, что повторяет поведение OrderModify в исходном советнике.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Five Minute RSI CCI strategy: RSI momentum with CCI trend confirmation.
/// Buys when RSI above level and CCI positive, sells when RSI below level and CCI negative.
/// </summary>
public class FiveMinuteRsiCciStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<int> _cciPeriod;
private readonly StrategyParam<decimal> _bullishLevel;
private readonly StrategyParam<decimal> _bearishLevel;
private bool _wasBullish;
private bool _hasPrevSignal;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
public int CciPeriod { get => _cciPeriod.Value; set => _cciPeriod.Value = value; }
public decimal BullishLevel { get => _bullishLevel.Value; set => _bullishLevel.Value = value; }
public decimal BearishLevel { get => _bearishLevel.Value; set => _bearishLevel.Value = value; }
public FiveMinuteRsiCciStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("RSI Period", "RSI period", "Indicators");
_cciPeriod = Param(nameof(CciPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("CCI Period", "CCI period", "Indicators");
_bullishLevel = Param(nameof(BullishLevel), 55m)
.SetDisplay("Bullish RSI Level", "RSI above this for buy", "Signals");
_bearishLevel = Param(nameof(BearishLevel), 45m)
.SetDisplay("Bearish RSI Level", "RSI below this for sell", "Signals");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_wasBullish = false;
_hasPrevSignal = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrevSignal = false;
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var cci = new CommodityChannelIndex { Length = CciPeriod };
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;
var isBullish = rsiValue > BullishLevel && cciValue > 0;
if (_hasPrevSignal && isBullish != _wasBullish)
{
if (isBullish && Position <= 0)
BuyMarket();
else if (!isBullish && rsiValue < BearishLevel && cciValue < 0 && Position >= 0)
SellMarket();
}
_wasBullish = isBullish;
_hasPrevSignal = true;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import RelativeStrengthIndex, CommodityChannelIndex
from StockSharp.Algo.Strategies import Strategy
class five_minute_rsi_cci_strategy(Strategy):
def __init__(self):
super(five_minute_rsi_cci_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(30)))
self._rsi_period = self.Param("RsiPeriod", 14)
self._cci_period = self.Param("CciPeriod", 14)
self._bullish_level = self.Param("BullishLevel", 55.0)
self._bearish_level = self.Param("BearishLevel", 45.0)
self._was_bullish = False
self._has_prev_signal = False
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def RsiPeriod(self):
return self._rsi_period.Value
@RsiPeriod.setter
def RsiPeriod(self, value):
self._rsi_period.Value = value
@property
def CciPeriod(self):
return self._cci_period.Value
@CciPeriod.setter
def CciPeriod(self, value):
self._cci_period.Value = value
@property
def BullishLevel(self):
return self._bullish_level.Value
@BullishLevel.setter
def BullishLevel(self, value):
self._bullish_level.Value = value
@property
def BearishLevel(self):
return self._bearish_level.Value
@BearishLevel.setter
def BearishLevel(self, value):
self._bearish_level.Value = value
def OnReseted(self):
super(five_minute_rsi_cci_strategy, self).OnReseted()
self._was_bullish = False
self._has_prev_signal = False
def OnStarted2(self, time):
super(five_minute_rsi_cci_strategy, self).OnStarted2(time)
self._has_prev_signal = False
rsi = RelativeStrengthIndex()
rsi.Length = self.RsiPeriod
cci = CommodityChannelIndex()
cci.Length = self.CciPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(rsi, cci, self._process_candle).Start()
def _process_candle(self, candle, rsi_value, cci_value):
if candle.State != CandleStates.Finished:
return
is_bullish = float(rsi_value) > self.BullishLevel and float(cci_value) > 0
if self._has_prev_signal and is_bullish != self._was_bullish:
if is_bullish and self.Position <= 0:
self.BuyMarket()
elif not is_bullish and float(rsi_value) < self.BearishLevel and float(cci_value) < 0 and self.Position >= 0:
self.SellMarket()
self._was_bullish = is_bullish
self._has_prev_signal = True
def CreateClone(self):
return five_minute_rsi_cci_strategy()