Umwandlung des ursprünglichen MQL4 „RndTrade“-Expertenberaters in eine StockSharp-High-Level-Strategie, die völlig zufällige Markteintritte durchführt und diese nach einer festgelegten Haltedauer wieder verlässt.
Kernlogik
Abonnieren Sie den konfigurierten Kerzentyp (standardmäßig 1-Minuten-Kerzen) und warten Sie auf abgeschlossene Balken.
Wenn die Strategie flach ist, generieren Sie eine Zufallszahl. Ein Wert über 0,5 löst einen Marktkauf aus, andernfalls einen Marktverkauf, jeweils unter Verwendung des konfigurierten Handelsvolumens.
Notieren Sie die Kerzenzeit des Einstiegs und halten Sie die Position für die ausgewählte Haltedauer (standardmäßig vier Stunden) offen.
Nach Ablauf der Haltezeit schließen Sie die gesamte Position mit der entsprechenden Marktorder.
Parameter
Name
Beschreibung
Standard
CandleType
Datentyp von Kerzen, die die Zufallsentscheidungslogik auslösen.
1 Minute Kerzen
TradeVolume
Für jede zufällige Marktorder verwendetes Volumen.
1
HoldDuration
Zeitspanne, um jede geöffnete Zufallsposition aktiv zu halten, bevor sie geschlossen wird.
4 Stunden
Zusätzliche Hinweise
Der Zufallsgenerator wird automatisch neu gesetzt, wenn die Strategie beginnt, das MQL4-Verhalten der Verwendung der Ortszeit als Startwert nachzuahmen.
Es werden nur Marktaufträge verwendet, die den ursprünglichen Expertenberater widerspiegeln, der Geschäfte ohne ausstehende Aufträge sofort ausführte.
Es sind keine zusätzlichen Indikatoren oder historischen Puffer erforderlich; Die Strategie basiert nur auf den Zeitstempeln der eingehenden Kerzen und dem internen Timer.
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
public class RndTradeRandomHoldStrategy : Strategy
{
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<int> _momentumPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevMom; private bool _hasPrev;
private int _cooldown;
public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
public int MomentumPeriod { get => _momentumPeriod.Value; set => _momentumPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public RndTradeRandomHoldStrategy()
{
_emaPeriod = Param(nameof(EmaPeriod), 14).SetDisplay("EMA Period", "EMA filter", "Indicators");
_momentumPeriod = Param(nameof(MomentumPeriod), 10).SetDisplay("Momentum", "Momentum period", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(15).TimeFrame()).SetDisplay("Candle Type", "Candle timeframe", "General");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevMom = default;
_hasPrev = default;
_cooldown = default;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
var mom = new Momentum { Length = MomentumPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(ema, mom, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal ema, decimal mom)
{
if (candle.State != CandleStates.Finished) return;
if (!IsFormedAndOnlineAndAllowTrading()) return;
var close = candle.ClosePrice;
if (!_hasPrev) { _prevMom = mom; _hasPrev = true; return; }
if (_cooldown > 0)
{
_cooldown--;
_prevMom = mom;
return;
}
if (close > ema && _prevMom <= 0 && mom > 0 && Position <= 0)
{
var volume = Volume + Math.Abs(Position);
BuyMarket(volume);
_cooldown = 2;
}
else if (close < ema && _prevMom >= 0 && mom < 0 && Position >= 0)
{
var volume = Volume + Math.Abs(Position);
SellMarket(volume);
_cooldown = 2;
}
_prevMom = mom;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Math
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import ExponentialMovingAverage, Momentum
from StockSharp.Algo.Strategies import Strategy
from datatype_extensions import *
from indicator_extensions import *
class rnd_trade_random_hold_strategy(Strategy):
def __init__(self):
super(rnd_trade_random_hold_strategy, self).__init__()
self._ema_period = self.Param("EmaPeriod", 14).SetDisplay("EMA Period", "EMA filter", "Indicators")
self._momentum_period = self.Param("MomentumPeriod", 10).SetDisplay("Momentum", "Momentum period", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(15))).SetDisplay("Candle Type", "Candle timeframe", "General")
@property
def CandleType(self): return self._candle_type.Value
@CandleType.setter
def CandleType(self, value): self._candle_type.Value = value
def OnReseted(self):
super(rnd_trade_random_hold_strategy, self).OnReseted()
self._prev_mom = 0
self._has_prev = False
self._cooldown = 0
def OnStarted2(self, time):
super(rnd_trade_random_hold_strategy, self).OnStarted2(time)
self._prev_mom = 0
self._has_prev = False
self._cooldown = 0
ema = ExponentialMovingAverage()
ema.Length = self._ema_period.Value
mom = Momentum()
mom.Length = self._momentum_period.Value
sub = self.SubscribeCandles(self.CandleType)
sub.Bind(ema, mom, self.OnProcess).Start()
def OnProcess(self, candle, ema_val, mom_val):
if candle.State != CandleStates.Finished:
return
if not self.IsFormedAndOnlineAndAllowTrading():
return
close = candle.ClosePrice
if not self._has_prev:
self._prev_mom = mom_val
self._has_prev = True
return
if self._cooldown > 0:
self._cooldown -= 1
self._prev_mom = mom_val
return
if close > ema_val and self._prev_mom <= 0 and mom_val > 0 and self.Position <= 0:
volume = self.Volume + abs(self.Position)
self.BuyMarket(volume)
self._cooldown = 2
elif close < ema_val and self._prev_mom >= 0 and mom_val < 0 and self.Position >= 0:
volume = self.Volume + abs(self.Position)
self.SellMarket(volume)
self._cooldown = 2
self._prev_mom = mom_val
def CreateClone(self):
return rnd_trade_random_hold_strategy()