A Estratégia de Entradas Potenciais replica a lógica do consultor especialista EA_PotentialEntries.mq5 original. Ele analisa pares das velas finalizadas mais recentes e emite negociações quando aparecem padrões específicos de reversão ou impulso de duas velas. A estratégia funciona em uma direção de cada vez (alta ou baixa), selecionável através do parâmetro Pattern Side. Os níveis de stop de proteção são recalculados em cada entrada para espelhar o posicionamento original do stop MetaTrader no extremo do par de velas analisado.
A implementação usa o API de alto nível de StockSharp: ele assina o tipo de vela configurado, processa o fluxo dentro de ProcessCandle, abre posições com BuyMarket/SellMarket e fecha negociações por meio de saídas de mercado quando o preço stop rastreado internamente é violado. Os gráficos renderizam a série de velas junto com as negociações estratégicas para uma rápida inspeção visual.
Dados e parâmetros
Grupo
Nome
Descrição
Geral
Lado padrão
Direção da varredura de padrão: Bullish procura reversões de alta, Bearish procura reversões de baixa.
Negociação
Volume comercial
Tamanho da ordem de mercado usado para cada entrada. A estratégia nivela a exposição oposta antes de abrir uma nova posição.
Geral
Tipo de vela
Série de velas usadas para reconhecimento de padrões (padrão: velas horárias).
Lógica de negociação
A estratégia avalia a vela finalizada mais recente (C1) juntamente com a vela anterior (C2). Todas as medidas do pavio e do corpo são calculadas em unidades de preço.
Modo de alta
Quando Pattern Side = Bullish, as seguintes configurações acionam uma entrada longa:
Martelo de alta
C1 fecha acima de sua abertura, enquanto C2 está em baixa.
O pavio inferior de C1 é pelo menos o dobro do corpo e mais que o triplo do pavio superior.
Uma ordem de compra de mercado é enviada e o nível de stop é definido para o menor dos mínimos de C1 e C2.
Martelo Invertido de Alta
C1 é otimista e C2 é baixista.
O pavio superior de C1 tem pelo menos o dobro do corpo e pelo menos o triplo do pavio inferior.
Executa a mesma ordem e lógica de parada da configuração do martelo.
Construtor de impulso de alta
C1 e C2 estão otimistas.
O intervalo de C1 é maior que o intervalo de C2, e o corpo de C1 é pelo menos duas vezes o corpo de C2.
Abre uma posição longa com stop abaixo do mínimo mínimo do par.
Modo de baixa
Quando Pattern Side = Bearish, as seguintes configurações acionam uma entrada curta:
Estrela cadente
C1 fecha abaixo de sua abertura enquanto C2 está otimista.
O pavio superior de C1 tem pelo menos o dobro do corpo e pelo menos o triplo do pavio inferior.
Uma ordem de venda a mercado é enviada com o stop colocado acima da máxima mais alta de C1 e C2.
Homem Enforcado
C1 é de baixa e C2 é de alta.
O pavio inferior de C1 é pelo menos o dobro do corpo e mais que o triplo do pavio superior.
Abre uma posição curta e usa a mesma lógica de stop da estrela cadente.
Construtor de impulso de baixa
C1 e C2 estão em baixa.
O corpo de C1 é maior que o corpo de C2, e o intervalo de C1 é pelo menos duas vezes o intervalo de C2.
Entra vendido e armazena o stop acima da máxima máxima das velas analisadas.
Gerenciamento de parada e tratamento de posição
Apenas um modo direcional está ativo por vez. Antes de entrar numa negociação, a estratégia fecha qualquer posição na direção oposta.
Cada entrada registra um preço stop no extremo do par de velas. Na chegada de cada nova vela finalizada, a estratégia verifica se a mínima (para posições compradas) ou a máxima (para posições vendidas) viola o nível armazenado e fecha a posição com uma ordem de mercado, se acionada.
Quando nenhuma posição está aberta, o valor de parada armazenado é apagado, garantindo que os níveis obsoletos nunca sejam reutilizados.
Notas de uso
Escolha o modo Bullish ou Bearish dependendo se você deseja procurar oportunidades longas ou curtas.
As velas horárias padrão podem ser substituídas por qualquer outro tipo de dados de vela disponível.
Ainda não há porta Python, conforme solicitado. Somente a implementação C# é fornecida.
A estratégia não estabelece metas de lucro. As saídas dependem exclusivamente da lógica de parada baseada em velas ou de intervenção manual.
namespace StockSharp.Samples.Strategies;
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Potential Entries strategy: two-candle reversal patterns with RSI confirmation.
/// Detects bullish/bearish reversals and trades with RSI filter.
/// </summary>
public class PotentialEntriesStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<int> _signalCooldownCandles;
private readonly List<ICandleMessage> _candles = new();
private int _candlesSinceTrade;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
public int SignalCooldownCandles { get => _signalCooldownCandles.Value; set => _signalCooldownCandles.Value = value; }
public PotentialEntriesStrategy()
{
_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");
_signalCooldownCandles = Param(nameof(SignalCooldownCandles), 6)
.SetGreaterThanZero()
.SetDisplay("Signal Cooldown", "Bars to wait between trades", "Trading");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_candles.Clear();
_candlesSinceTrade = SignalCooldownCandles;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_candles.Clear();
_candlesSinceTrade = SignalCooldownCandles;
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(rsi, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal rsiValue)
{
if (candle.State != CandleStates.Finished) return;
if (_candlesSinceTrade < SignalCooldownCandles)
_candlesSinceTrade++;
_candles.Add(candle);
if (_candles.Count > 5)
_candles.RemoveAt(0);
if (_candles.Count >= 2)
{
var curr = _candles[^1];
var prev = _candles[^2];
// Bullish reversal: prev bearish, curr bullish with higher close
var bullish = prev.OpenPrice > prev.ClosePrice
&& curr.ClosePrice > curr.OpenPrice
&& curr.ClosePrice > prev.OpenPrice;
// Bearish reversal: prev bullish, curr bearish with lower close
var bearish = prev.ClosePrice > prev.OpenPrice
&& curr.OpenPrice > curr.ClosePrice
&& curr.ClosePrice < prev.OpenPrice;
if (bullish && rsiValue < 50 && Position <= 0 && _candlesSinceTrade >= SignalCooldownCandles)
{
BuyMarket();
_candlesSinceTrade = 0;
}
else if (bearish && rsiValue > 50 && Position >= 0 && _candlesSinceTrade >= SignalCooldownCandles)
{
SellMarket();
_candlesSinceTrade = 0;
}
}
}
}
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 potential_entries_strategy(Strategy):
def __init__(self):
super(potential_entries_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(30)))
self._rsi_period = self.Param("RsiPeriod", 14)
self._signal_cooldown_candles = self.Param("SignalCooldownCandles", 6)
self._candles = []
self._candles_since_trade = 6
@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 SignalCooldownCandles(self):
return self._signal_cooldown_candles.Value
@SignalCooldownCandles.setter
def SignalCooldownCandles(self, value):
self._signal_cooldown_candles.Value = value
def OnReseted(self):
super(potential_entries_strategy, self).OnReseted()
self._candles.clear()
self._candles_since_trade = self.SignalCooldownCandles
def OnStarted2(self, time):
super(potential_entries_strategy, self).OnStarted2(time)
self._candles.clear()
self._candles_since_trade = self.SignalCooldownCandles
rsi = RelativeStrengthIndex()
rsi.Length = self.RsiPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(rsi, self._process_candle).Start()
def _process_candle(self, candle, rsi_value):
if candle.State != CandleStates.Finished:
return
if self._candles_since_trade < self.SignalCooldownCandles:
self._candles_since_trade += 1
self._candles.append(candle)
if len(self._candles) > 5:
self._candles.pop(0)
if len(self._candles) >= 2:
curr = self._candles[-1]
prev = self._candles[-2]
bullish = (float(prev.OpenPrice) > float(prev.ClosePrice)
and float(curr.ClosePrice) > float(curr.OpenPrice)
and float(curr.ClosePrice) > float(prev.OpenPrice))
bearish = (float(prev.ClosePrice) > float(prev.OpenPrice)
and float(curr.OpenPrice) > float(curr.ClosePrice)
and float(curr.ClosePrice) < float(prev.OpenPrice))
if bullish and float(rsi_value) < 50 and self.Position <= 0 and self._candles_since_trade >= self.SignalCooldownCandles:
self.BuyMarket()
self._candles_since_trade = 0
elif bearish and float(rsi_value) > 50 and self.Position >= 0 and self._candles_since_trade >= self.SignalCooldownCandles:
self.SellMarket()
self._candles_since_trade = 0
def CreateClone(self):
return potential_entries_strategy()