Easy Robot es un asesor experto que sigue el impulso y opera una vez por cada vela horaria completada. Cuando la vela anterior cierra alcista, la estrategia abre una nueva posición larga; cuando cierra bajista abre en corto. Sólo una posición puede estar activa en cualquier momento, reflejando completamente la lógica original MetaTrader 4.
Reglas comerciales
Suscríbase al tipo de vela horaria seleccionado por el parámetro CandleType (el valor predeterminado es H1).
Una vez que se termina una vela, compara su cierre con su apertura:
Cerrar > Abrir: envía una orden de compra de mercado si no hay ninguna posición abierta.
Cerrar < Abrir: enviar una orden de venta de mercado si está plano.
El tamaño de la posición utiliza la propiedad de la estrategia Volume, exactamente igual que la versión MQL que se basó en CheckVolumeValue con un valor predeterminado de 0,01 lotes.
Los niveles de stop-loss y take-profit se basan en un indicador Average True Range con período AtrPeriod (predeterminado 14):
Distancia de parada = ATR * StopFactor.
Tomar distancia = ATR * TakeFactor.
Ambas distancias están normalizadas por la distancia mínima tick/pip, por lo que las órdenes de protección nunca se colocan más cerca de lo que permite el corredor.
Las órdenes de protección se registran inmediatamente después de la orden de mercado a través de SetStopLoss y SetTakeProfit, proporcionando el mismo comportamiento que OrderSend con los parámetros sl y tp.
El seguimiento opcional se activa cuando UseTrailingStop es verdadero. Después de que la operación acumula ganancias de TrailingStartPips (MetaTrader pips, es decir, puntos ajustados por cotizaciones de 3/5 decimales), la parada se acerca con TrailingStepPips y se empuja más solo cuando se alcanzan nuevos extremos de ganancias. El seguimiento respeta la distancia mínima de parada del corredor para evitar modificaciones no válidas.
Las cotizaciones para los cálculos de stop utilizan la mejor oferta/demanda cuando esté disponible, retrocediendo al último precio o cierre de vela, coincidiendo con las referencias originales Bid/Ask.
Parámetros
Nombre
Predeterminado
Descripción
TakeFactor
4.2
multiplicador ATR para la distancia de obtención de beneficios (se asigna a la entrada TakeFactor en MQL).
StopFactor
4.9
multiplicador ATR para la distancia de stop-loss (se asigna a StopFactor).
UseTrailingStop
cierto
Habilita el seguimiento estilo MetaTrader (UseTstop).
TrailingStartPips
40
Beneficio en pips antes de que pueda comenzar el seguimiento (Tstart).
TrailingStepPips
19
Paso de pip aplicado al rastrear actualizaciones (Tstep).
AtrPeriod
14
periodo ATR de cálculo para el dimensionamiento de la volatilidad.
CandleType
H1
Serie de velas utilizada para señales y entrada ATR.
Notas
La estrategia restablece los precios de entrada y parada almacenados cada vez que la posición vuelve a cero, asegurando un estado limpio para la siguiente señal.
La distancia mínima de parada se estima mediante el tamaño del pip del instrumento (o el paso del precio cuando el tamaño del pip no está disponible). Esto reproduce el ayudante SC del archivo de inclusión MQL.
StartProtection() se llama una vez al inicio para que la plataforma pueda gestionar las salidas de emergencia si es necesario.
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()