Easy Robot é um Expert Advisor que segue o impulso e negocia uma vez por vela horária concluída. Quando a vela anterior fecha em alta a estratégia abre uma nova posição comprada; quando fecha em baixa, abre uma posição curta. Apenas uma posição pode estar ativa a qualquer momento, espelhando totalmente a lógica MetaTrader 4 original.
Regras comerciais
Assine o tipo de vela horária selecionado pelo parâmetro CandleType (o padrão é H1).
Assim que a vela terminar, compare seu fechamento com a abertura:
Fechar > Aberto: envia uma ordem de compra a mercado se nenhuma posição estiver aberta.
Fechar <Abrir: envia uma ordem de venda a mercado se estiver estável.
O tamanho da posição usa a propriedade da estratégia Volume, exatamente como a versão MQL que dependia de CheckVolumeValue com um padrão de 0,01 lote.
Os níveis de stop-loss e take-profit dependem de um indicador Average True Range com período AtrPeriod (padrão 14):
Distância de parada = ATR * StopFactor.
Tome distância = ATR * TakeFactor.
Ambas as distâncias são normalizadas pela distância mínima de tick/pip, de modo que as ordens de proteção nunca são colocadas mais próximas do que a corretora permite.
As ordens protetoras são registradas imediatamente após a ordem de mercado através de SetStopLoss e SetTakeProfit, proporcionando o mesmo comportamento de OrderSend com os parâmetros sl e tp.
O rastreamento opcional é ativado quando UseTrailingStop é verdadeiro. Depois que a negociação acumula lucro TrailingStartPips (MetaTrader pips, ou seja, pontos ajustados para cotações decimais de 3/5), o stop é movido para mais perto por TrailingStepPips e é empurrado ainda mais somente quando novos extremos de lucro são alcançados. O trailing respeita a distância mínima de parada da corretora para evitar modificações inválidas.
As cotações para cálculos de stop usam o melhor bid/ask quando disponível, voltando ao último preço ou fechamento da vela, correspondendo às referências originais Bid/Ask.
Parâmetros
Nome
Padrão
Descrição
TakeFactor
4.2
Multiplicador de ATR para distância de lucro (mapeia para TakeFactor entrada em MQL).
StopFactor
4.9
Multiplicador ATR para distância de stop-loss (mapeia para StopFactor).
UseTrailingStop
verdade
Ativa o estilo de rastreamento MetaTrader (UseTstop).
TrailingStartPips
40
Lucro em pips antes do início do trailing (Tstart).
TrailingStepPips
19
Etapa Pip aplicada ao rastrear atualizações (Tstep).
AtrPeriod
14
período ATR de cálculo para dimensionamento de volatilidade.
CandleType
H1
Série de velas usada para sinais e entrada ATR.
Notas
A estratégia redefine os preços de entrada e stop armazenados sempre que a posição retorna a zero, garantindo um estado limpo para o próximo sinal.
A distância mínima de parada é estimada através do tamanho do pip do instrumento (ou da etapa de preço quando o tamanho do pip não está disponível). Isso reproduz o auxiliar SC do arquivo de inclusão MQL.
StartProtection() é chamado uma vez no início para que a plataforma possa gerenciar saídas de emergência, se necessário.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Easy Robot strategy: simple EMA + RSI trend following.
/// Buys when close above EMA and RSI above 50.
/// Sells when close below EMA and RSI below 50.
/// </summary>
public class EasyRobotStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<int> _rsiPeriod;
private bool _wasBullish;
private bool _hasPrevSignal;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
public EasyRobotStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_emaPeriod = Param(nameof(EmaPeriod), 50)
.SetGreaterThanZero()
.SetDisplay("EMA Period", "EMA period", "Indicators");
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("RSI Period", "RSI period", "Indicators");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_wasBullish = false;
_hasPrevSignal = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrevSignal = false;
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(ema, rsi, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal ema, decimal rsi)
{
if (candle.State != CandleStates.Finished) return;
var close = candle.ClosePrice;
var isBullish = close > ema && rsi > 50;
if (_hasPrevSignal && isBullish != _wasBullish)
{
if (isBullish && Position <= 0)
BuyMarket();
else if (!isBullish && close < ema && rsi < 50 && 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 ExponentialMovingAverage, RelativeStrengthIndex
from StockSharp.Algo.Strategies import Strategy
class easy_robot_strategy(Strategy):
def __init__(self):
super(easy_robot_strategy, self).__init__()
self._ema_period = self.Param("EmaPeriod", 50) \
.SetDisplay("EMA Period", "EMA period", "Indicators")
self._rsi_period = self.Param("RsiPeriod", 14) \
.SetDisplay("RSI Period", "RSI period", "Indicators")
self._ema = None
self._rsi = None
self._was_bullish = False
self._has_prev_signal = False
@property
def ema_period(self):
return self._ema_period.Value
@property
def rsi_period(self):
return self._rsi_period.Value
def OnReseted(self):
super(easy_robot_strategy, self).OnReseted()
self._ema = None
self._rsi = None
self._was_bullish = False
self._has_prev_signal = False
def OnStarted2(self, time):
super(easy_robot_strategy, self).OnStarted2(time)
self._ema = ExponentialMovingAverage()
self._ema.Length = self.ema_period
self._rsi = RelativeStrengthIndex()
self._rsi.Length = self.rsi_period
self._has_prev_signal = False
subscription = self.SubscribeCandles(DataType.TimeFrame(TimeSpan.FromMinutes(30)))
subscription.Bind(self._ema, self._rsi, self._process_candle)
subscription.Start()
def _process_candle(self, candle, ema_value, rsi_value):
if candle.State != CandleStates.Finished:
return
if not self._ema.IsFormed or not self._rsi.IsFormed:
return
close = float(candle.ClosePrice)
ema_val = float(ema_value)
rsi_val = float(rsi_value)
is_bullish = close > ema_val and rsi_val > 50.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 close < ema_val and rsi_val < 50.0 and self.Position >= 0:
self.SellMarket()
self._was_bullish = is_bullish
self._has_prev_signal = True
def CreateClone(self):
return easy_robot_strategy()