A RSI Estratégia de Alerta reproduz o comportamento do consultor especialista MetaTrader 5 "RSI Alerta" dentro da estrutura StockSharp. O bot original observou leituras do Índice de Força Relativa (RSI) que cruzaram níveis profundamente sobrevendidos (≤20) ou sobrecomprados (≥80) e enviaram imediatamente notificações de alerta ao abrir posições de mercado. A versão convertida mantém esta filosofia orientada a eventos: ela escuta velas concluídas, avalia o RSI e inverte automaticamente a posição enviando ordens de mercado quando os limites configurados são atingidos.
Lógica de negociação
Assine a série de velas configurada (padrão: período de 1 minuto) e insira os preços de fechamento em um indicador RelativeStrengthIndex.
Ignore as velas incompletas e espere até que o indicador RSI esteja totalmente formado. Isso reflete o especialista MQL, que avaliou as condições apenas uma vez por nova barra.
Gere sinais de negociação:
Sinal de compra – RSI ≤ OversoldLevel. A estratégia fecha qualquer exposição curta e abre uma posição longa com o volume configurado.
Sinal de venda – RSI ≥ OverboughtLevel. A estratégia fecha qualquer exposição longa e abre uma posição curta com o volume configurado.
Os pedidos são sempre feitos com BuyMarket/SellMarket, portanto, não há níveis de pedidos pendentes, stop-loss ou take-profit. A implementação MetaTrader permitia entradas SL/TP opcionais, mas por padrão dependia de gerenciamento manual. A porta StockSharp concentra-se na conversão de alerta para negociação e deixa o gerenciamento de risco para módulos externos (por exemplo, StartProtection() ou controles em nível de portfólio).
A estratégia permanece estável entre os sinais. Quando um gatilho oposto aparece, ele inverte a posição adicionando volume suficiente para nivelar a exposição existente antes de entrar na nova direção, exatamente como o EA original fez ao disparar alertas consecutivos.
Parâmetros
Parâmetro
Padrão
Descrição
OrderVolume
0,01
Tamanho da negociação para ordens de mercado. Ao reverter, a estratégia adiciona o valor necessário para cobrir a posição existente antes de entrar novamente.
RsiPeriod
30
RSI período médio. Deve ser um número inteiro positivo.
OverboughtLevel
80
Limite de RSI que emite um sinal de venda. Pode ser otimizado para ajustar a agressividade.
OversoldLevel
20
Limite de RSI que emite um sinal de compra.
CandleType
1 minuto TimeFrameCandle
Fonte de dados Candle usada para cálculo de RSI. Altere-o para analisar prazos maiores.
Todos os parâmetros são expostos por meio de StrategyParam<T> para que apareçam no designer StockSharp, possam ser salvos em predefinições XML e suportem cenários de otimização.
Notas de implementação
O StockSharp API de alto nível é usado em todo: as velas são obtidas por meio de SubscribeCandles() e o RSI é atualizado por meio de subscription.Bind(indicator, callback). Não é necessário nenhum manuseio manual de buffer ou cópia histórica.
A propriedade base Strategy.Volume é sincronizada com o parâmetro OrderVolume para que a reversão de posição funcione corretamente mesmo que o usuário altere o tamanho do lote em tempo de execução.
Os comentários embutidos e a documentação XML são escritos em inglês para atender aos requisitos do projeto.
A saída do gráfico é opcional, mas suportada: quando a estratégia é executada dentro do designer, ela traça as velas de preço, as negociações executadas e os valores do indicador RSI.
Dicas de uso
Combine a estratégia com módulos externos de stop-loss/take-profit se for necessário controle automatizado de risco.
Otimize os limites RSI ao se adaptar a mercados com diferentes regimes de volatilidade.
Aumente o intervalo de tempo da vela para configurações de swing ou mantenha a série padrão de 1 minuto para alertas de estilo scalping, como no script original.
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;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// RSI alert strategy converted from the original MetaTrader expert advisor.
/// Buys when RSI drops below the oversold threshold and sells when RSI rises above the overbought threshold.
/// </summary>
public class RsiAlertStrategy : Strategy
{
private readonly StrategyParam<decimal> _orderVolume;
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<decimal> _overboughtLevel;
private readonly StrategyParam<decimal> _oversoldLevel;
private readonly StrategyParam<DataType> _candleType;
private RelativeStrengthIndex _rsi;
/// <summary>
/// Order volume used for market trades.
/// </summary>
public decimal OrderVolume
{
get => _orderVolume.Value;
set
{
_orderVolume.Value = value;
Volume = value; // Keep the base strategy volume aligned with the parameter value.
}
}
/// <summary>
/// RSI averaging period.
/// </summary>
public int RsiPeriod
{
get => _rsiPeriod.Value;
set => _rsiPeriod.Value = value;
}
/// <summary>
/// RSI level that triggers short trades.
/// </summary>
public decimal OverboughtLevel
{
get => _overboughtLevel.Value;
set => _overboughtLevel.Value = value;
}
/// <summary>
/// RSI level that triggers long trades.
/// </summary>
public decimal OversoldLevel
{
get => _oversoldLevel.Value;
set => _oversoldLevel.Value = value;
}
/// <summary>
/// Candle type supplying prices to the RSI indicator.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Initializes a new instance of <see cref="RsiAlertStrategy"/> with default parameters.
/// </summary>
public RsiAlertStrategy()
{
_orderVolume = Param(nameof(OrderVolume), 0.01m)
.SetGreaterThanZero()
.SetDisplay("Order Volume", "Order size used for market trades", "Trading")
;
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("RSI Period", "Number of bars for RSI calculation", "Indicator")
;
_overboughtLevel = Param(nameof(OverboughtLevel), 70m)
.SetDisplay("Overbought Level", "RSI threshold that triggers short signals", "Indicator")
;
_oversoldLevel = Param(nameof(OversoldLevel), 30m)
.SetDisplay("Oversold Level", "RSI threshold that triggers long signals", "Indicator")
;
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Type of candles that feed the RSI", "General");
Volume = OrderVolume;
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_rsi = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
Volume = OrderVolume; // Ensure the strategy uses the configured volume on each start.
_rsi = new RelativeStrengthIndex
{
Length = RsiPeriod
};
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(_rsi, ProcessCandle)
.Start();
StartProtection(
takeProfit: new Unit(2, UnitTypes.Percent),
stopLoss: new Unit(1, UnitTypes.Percent));
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;
var buySignal = rsiValue <= OversoldLevel;
var sellSignal = rsiValue >= OverboughtLevel;
if (buySignal && Position == 0)
{
BuyMarket();
}
else if (sellSignal && Position == 0)
{
SellMarket();
}
}
}