A Estratégia de modelo básica RSI EA replica o MetaTrader 4 consultor especialista "Basic Rsi EA Template.mq4" (MQL/26750). Ele observa o Índice de Força Relativa (RSI) na série de velas selecionada e reage quando o impulso se estende para zonas de sobrecompra ou sobrevenda configuráveis. A conversão StockSharp mantém o fluxo de trabalho simples de uma posição e a lógica protetora de parada/tomada do robô original enquanto adota a assinatura de alto nível API.
Lógica da estratégia
Indicadores
Índice de Força Relativa (RSI) com período configurável calculado no tipo de vela escolhido.
Condições de Entrada
Configuração longa: quando RSI cai abaixo de OversoldLevel e a estratégia não tem posição aberta, ela envia uma ordem de compra a mercado para o OrderVolume configurado.
Configuração curta: quando RSI ultrapassa OverboughtLevel e a estratégia não tem posição aberta, ela envia uma ordem de venda a mercado para o OrderVolume configurado.
O algoritmo funciona em modo de compensação: apenas uma posição pode existir a qualquer momento. Se uma posição longa estiver ativa, a estratégia espera que ela feche antes de uma entrada curta (e vice-versa).
Condições de saída
Parada protetora: StopLossPips é convertido em uma distância de preço absoluta usando o tamanho do tick do instrumento. Assim que o preço atingir esse valor, o mecanismo de proteção integrado fecha a posição.
Take Profit: TakeProfitPips é processado da mesma maneira – quando o preço se move a favor pela distância configurada, a posição é fechada com lucro.
Não há saída adicional baseada em sinal ou à direita. A estratégia baseia-se puramente nas distâncias de proteção ou na intervenção manual para sair das negociações, refletindo o design minimalista do modelo original.
Tratamento de riscos e volumes
OrderVolume define o valor fixo enviado com cada ordem de mercado (padrão 0,01 lote, correspondendo à amostra MQL).
A estratégia não faz pirâmide nem hedge. Se um stop protetor ou take-profit fechar a negociação ativa, o algoritmo fica plano e aguarda o próximo gatilho RSI.
Parâmetros
CandleType: série de velas usada para geração de sinal (padrão: período de 1 minuto).
RsiPeriod: número de barras na janela RSI (padrão: 14).
OverboughtLevel: limite RSI que permite entradas curtas (padrão: 70).
OversoldLevel: limite RSI que permite entradas longas (padrão: 30).
StopLossPips: distância de parada em pips convertida em unidades de preço absoluto (padrão: 30 pips).
TakeProfitPips: meta de lucro em pips convertida em unidades de preço absoluto (padrão: 20 pips).
OrderVolume: volume fixo para ordens de mercado (padrão: 0,01).
Notas de implementação
Usa SubscribeCandles(...).Bind(rsi, ProcessCandle) para que os valores do indicador fluam diretamente para o método de processamento sem gerenciamento manual de buffer.
CreateProtectionUnit recria o tratamento de pip MQL: instrumentos com 3 ou 5 casas decimais usam um multiplicador de 10x para mapear pips para etapas de preço.
Todas as verificações dos indicadores são executadas em velas finalizadas para evitar múltiplas ordens na mesma barra.
A conversão pressupõe uma conta de compensação, ao contrário do modo de cobertura de MetaTrader. Consequentemente, as negociações opostas fecham a posição atual em vez de criar vários tickets.
Os comentários e registros embutidos estão em inglês para ajudar na manutenção futura.
Dicas de uso
Ajuste CandleType ao instrumento e período que você deseja negociar (por exemplo, mude para velas horárias para configurações de swing).
Ajuste StopLossPips e TakeProfitPips para que correspondam à volatilidade do instrumento; as distâncias de proteção são essenciais para o controle de riscos.
Combine a estratégia com portfólio StockSharp ou módulos de risco se precisar de gerenciamento financeiro avançado além da lógica do modelo.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Basic RSI template: buys when RSI is oversold, sells when RSI is overbought.
/// </summary>
public class BasicRsiEaTemplateStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<decimal> _overboughtLevel;
private readonly StrategyParam<decimal> _oversoldLevel;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int RsiPeriod
{
get => _rsiPeriod.Value;
set => _rsiPeriod.Value = value;
}
public decimal OverboughtLevel
{
get => _overboughtLevel.Value;
set => _overboughtLevel.Value = value;
}
public decimal OversoldLevel
{
get => _oversoldLevel.Value;
set => _oversoldLevel.Value = value;
}
public BasicRsiEaTemplateStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("RSI Period", "RSI calculation period", "Indicators");
_overboughtLevel = Param(nameof(OverboughtLevel), 70m)
.SetDisplay("Overbought Level", "RSI overbought threshold", "Indicators");
_oversoldLevel = Param(nameof(OversoldLevel), 30m)
.SetDisplay("Oversold Level", "RSI oversold threshold", "Indicators");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
decimal? prevRsi = null;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(rsi, (candle, rsiValue) =>
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
if (prevRsi.HasValue)
{
var crossBelowOversold = prevRsi.Value >= OversoldLevel && rsiValue < OversoldLevel;
var crossAboveOverbought = prevRsi.Value <= OverboughtLevel && rsiValue > OverboughtLevel;
if (crossBelowOversold && Position <= 0)
BuyMarket();
else if (crossAboveOverbought && Position >= 0)
SellMarket();
}
prevRsi = rsiValue;
})
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, rsi);
DrawOwnTrades(area);
}
}
}
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 basic_rsi_ea_template_strategy(Strategy):
def __init__(self):
super(basic_rsi_ea_template_strategy, self).__init__()
self._rsi_period = self.Param("RsiPeriod", 14) \
.SetDisplay("RSI Period", "RSI calculation period", "Indicators")
self._overbought_level = self.Param("OverboughtLevel", 70.0) \
.SetDisplay("Overbought Level", "RSI overbought threshold", "Indicators")
self._oversold_level = self.Param("OversoldLevel", 30.0) \
.SetDisplay("Oversold Level", "RSI oversold threshold", "Indicators")
self._rsi = None
self._prev_rsi = None
@property
def rsi_period(self):
return self._rsi_period.Value
@property
def overbought_level(self):
return self._overbought_level.Value
@property
def oversold_level(self):
return self._oversold_level.Value
def OnReseted(self):
super(basic_rsi_ea_template_strategy, self).OnReseted()
self._rsi = None
self._prev_rsi = None
def OnStarted2(self, time):
super(basic_rsi_ea_template_strategy, self).OnStarted2(time)
self._rsi = RelativeStrengthIndex()
self._rsi.Length = self.rsi_period
subscription = self.SubscribeCandles(DataType.TimeFrame(TimeSpan.FromMinutes(30)))
subscription.Bind(self._rsi, self._process_candle)
subscription.Start()
def _process_candle(self, candle, rsi_value):
if candle.State != CandleStates.Finished:
return
if not self._rsi.IsFormed:
return
rsi = float(rsi_value)
if self._prev_rsi is not None:
cross_below_oversold = self._prev_rsi >= self.oversold_level and rsi < self.oversold_level
cross_above_overbought = self._prev_rsi <= self.overbought_level and rsi > self.overbought_level
if cross_below_oversold and self.Position <= 0:
self.BuyMarket()
elif cross_above_overbought and self.Position >= 0:
self.SellMarket()
self._prev_rsi = rsi
def CreateClone(self):
return basic_rsi_ea_template_strategy()