Главная
/
Примеры стратегий
Открыть на GitHub
Стратегия RSI Sign
Данная стратегия является конвертацией советника iRSISign из MQL5 в высокоуровневый API StockSharp. Она использует комбинацию индикаторов RSI и ATR для генерации торговых сигналов.
Система обрабатывает только завершённые свечи выбранного таймфрейма. Когда значение RSI пересекает снизу вверх нижний уровень, открывается длинная позиция или закрывается короткая. Если RSI опускается ниже верхнего уровня, стратегия открывает короткую позицию или закрывает текущую длинную. ATR рассчитывается лишь для контекста, имитируя оригинальный индикатор, который смещал стрелки сигналов на величину ATR.
Подробности
Условия входа :
Покупка : предыдущее значение RSI было ниже DownLevel, текущее пересекло его сверху вниз.
Продажа : предыдущее значение RSI было выше UpLevel, текущее опустилось ниже него.
Направления : длинные и короткие позиции могут быть включены отдельно.
Условия выхода :
Противоположный сигнал закрывает позицию, если соответствующий флаг закрытия активирован.
Стопы : не реализованы. Управление рисками может быть добавлено отдельно.
Параметры по умолчанию :
RsiPeriod = 14
AtrPeriod = 14
UpLevel = 70
DownLevel = 30
CandleType = часовые свечи
Фильтры :
Категория: импульсная
Направление: оба
Индикаторы: RSI, ATR
Стопы: нет
Сложность: базовая
Таймфрейм: гибкий
Сезонность: нет
Нейросети: нет
Дивергенция: нет
Уровень риска: средний
Параметры
Имя
Описание
RsiPeriod
Период RSI.
AtrPeriod
Период ATR.
UpLevel
Верхний порог RSI для сигналов продажи.
DownLevel
Нижний порог RSI для сигналов покупки.
CandleType
Таймфрейм свечей для расчётов.
BuyOpen
Разрешить открытие длинных позиций.
SellOpen
Разрешить открытие коротких позиций.
BuyClose
Разрешить закрытие длинных позиций противоположным сигналом.
SellClose
Разрешить закрытие коротких позиций противоположным сигналом.
Стратегия предназначена в качестве учебного примера, демонстрирующего перенос логики MQL5 в стратегию StockSharp.
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// RSI based signal strategy.
/// Opens long when RSI crosses above the down level.
/// Opens short when RSI crosses below the up level.
/// </summary>
public class RsiSignStrategy : Strategy
{
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<decimal> _upLevel;
private readonly StrategyParam<decimal> _downLevel;
private readonly StrategyParam<DataType> _candleType;
private decimal? _previousRsi;
public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
public decimal UpLevel { get => _upLevel.Value; set => _upLevel.Value = value; }
public decimal DownLevel { get => _downLevel.Value; set => _downLevel.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public RsiSignStrategy()
{
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("RSI Period", "Length of RSI indicator", "Indicator");
_upLevel = Param(nameof(UpLevel), 70m)
.SetDisplay("RSI Upper Level", "Sell when RSI falls below this value", "Indicator");
_downLevel = Param(nameof(DownLevel), 30m)
.SetDisplay("RSI Lower Level", "Buy when RSI rises above this value", "Indicator");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Timeframe used for indicator calculations", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_previousRsi = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_previousRsi = null;
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(rsi, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, rsi);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal rsiValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var prevRsi = _previousRsi;
_previousRsi = rsiValue;
if (prevRsi is null)
return;
// RSI crosses above lower level -> buy signal
if (prevRsi <= DownLevel && rsiValue > DownLevel && Position <= 0)
BuyMarket();
// RSI crosses below upper level -> sell signal
else if (prevRsi >= UpLevel && rsiValue < UpLevel && Position >= 0)
SellMarket();
}
}
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
from StockSharp.Algo.Strategies import Strategy
class rsi_sign_strategy(Strategy):
def __init__(self):
super(rsi_sign_strategy, self).__init__()
self._rsi_period = self.Param("RsiPeriod", 14) \
.SetDisplay("RSI Period", "Length of RSI indicator", "Indicator")
self._up_level = self.Param("UpLevel", 70.0) \
.SetDisplay("RSI Upper Level", "Sell when RSI falls below this value", "Indicator")
self._down_level = self.Param("DownLevel", 30.0) \
.SetDisplay("RSI Lower Level", "Buy when RSI rises above this value", "Indicator")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Timeframe used for indicator calculations", "General")
self._previous_rsi = None
@property
def rsi_period(self):
return self._rsi_period.Value
@property
def up_level(self):
return self._up_level.Value
@property
def down_level(self):
return self._down_level.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(rsi_sign_strategy, self).OnReseted()
self._previous_rsi = None
def OnStarted2(self, time):
super(rsi_sign_strategy, self).OnStarted2(time)
self._previous_rsi = None
rsi = RelativeStrengthIndex()
rsi.Length = self.rsi_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(rsi, self.process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, rsi)
self.DrawOwnTrades(area)
def process_candle(self, candle, rsi_value):
if candle.State != CandleStates.Finished:
return
rsi_value = float(rsi_value)
prev_rsi = self._previous_rsi
self._previous_rsi = rsi_value
if prev_rsi is None:
return
down_lvl = float(self.down_level)
up_lvl = float(self.up_level)
if prev_rsi <= down_lvl and rsi_value > down_lvl and self.Position <= 0:
self.BuyMarket()
elif prev_rsi >= up_lvl and rsi_value < up_lvl and self.Position >= 0:
self.SellMarket()
def CreateClone(self):
return rsi_sign_strategy()