Easy Robot ist ein dem Momentum folgender Expert Advisor, der einmal pro abgeschlossener stündlicher Kerze handelt. Wenn die vorherige Kerze bullisch schließt, eröffnet die Strategie eine neue Long-Position; Wenn es bärisch schließt, eröffnet es einen Short. Es kann jeweils nur eine Position aktiv sein, was die ursprüngliche Logik von MetaTrader 4 vollständig widerspiegelt.
Handelsregeln
Abonnieren Sie den stündlichen Kerzentyp, der durch den Parameter CandleType ausgewählt wird (standardmäßig H1).
Sobald eine Kerze fertig ist, vergleichen Sie ihren Schlusskurs mit dem Eröffnungskurs:
Schließen > Öffnen: Senden Sie eine Marktkauforder, wenn keine Position offen ist.
Schließen < Öffnen: Senden Sie einen Marktverkaufsauftrag, wenn der Kurs unverändert bleibt.
Die Positionsgröße verwendet die Strategieeigenschaft Volume, genau wie die MQL-Version, die auf CheckVolumeValue basierte, mit einem Standardwert von 0,01 Lots.
Stop-Loss- und Take-Profit-Level basieren auf einem Average True Range-Indikator mit der Periode AtrPeriod (Standard 14):
Stoppdistanz = ATR * StopFactor.
Nehmen Sie Abstand = ATR * TakeFactor.
Beide Abstände werden durch den minimalen Tick-/Pip-Abstand normalisiert, sodass Schutzaufträge niemals näher platziert werden, als der Broker zulässt.
Schutzaufträge werden unmittelbar nach der Marktorder über SetStopLoss und SetTakeProfit registriert und bieten das gleiche Verhalten wie OrderSend mit den Parametern sl und tp.
Optionales Trailing wird aktiviert, wenn UseTrailingStop wahr ist. Nachdem der Handel TrailingStartPips-Gewinne angehäuft hat (MetaTrader Pips, d. h. Punkte angepasst an 3/5 Dezimalkurse), wird der Stop um TrailingStepPips näher gerückt und nur dann weiter verschoben, wenn neue Gewinnextremwerte erreicht werden. Beim Trailing wird der minimale Stoppabstand des Brokers berücksichtigt, um ungültige Änderungen zu vermeiden.
Quotes für Stop-Berechnungen verwenden den besten Geld-/Briefkurs, sofern verfügbar, und fallen auf den letzten Preis oder Kerzenschluss zurück, der mit den ursprünglichen Bid/Ask-Referenzen übereinstimmt.
Parameter
Name
Standard
Beschreibung
TakeFactor
4.2
ATR-Multiplikator für Take-Profit-Distanz (entspricht der TakeFactor-Eingabe in MQL).
StopFactor
4.9
ATR-Multiplikator für die Stop-Loss-Distanz (entspricht StopFactor).
UseTrailingStop
wahr
Aktiviert das Nachstellen im MetaTrader-Stil (UseTstop).
TrailingStartPips
40
Profitieren Sie in Pips, bevor das Trailing beginnen kann (Tstart).
TrailingStepPips
19
Beim Nachstellen von Aktualisierungen wird ein Pip-Schritt angewendet (Tstep).
AtrPeriod
14
ATR Berechnungszeitraum für die Volatilitätsgröße.
CandleType
H1
Kerzenserie, die für Signale und den ATR-Eingang verwendet wird.
Notizen
Die Strategie setzt die gespeicherten Einstiegs- und Stop-Preise jedes Mal zurück, wenn die Position auf Null zurückkehrt, und stellt so einen sauberen Zustand für das nächste Signal sicher.
Der minimale Stoppabstand wird über die Pip-Größe des Instruments geschätzt (oder über den Preisschritt, wenn die Pip-Größe nicht verfügbar ist). Dadurch wird der SC-Helper aus der MQL-Include-Datei reproduziert.
StartProtection() wird beim Start einmal aufgerufen, damit die Plattform bei Bedarf Notausgänge verwalten kann.
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()