This strategy ports the MetaTrader 4 utility "Auto Trading Publish" to StockSharp. Instead of submitting market orders, the
strategy focuses on controlling when trading is allowed. It monitors the market clock via a candle subscription and flips the
AutoTradingActive flag whenever the configured start or stop hour is reached. The flag mirrors the behaviour of the original
utility which programmatically toggled the MT4 "AutoTrading" button.
Trading logic
Subscribe to a lightweight candle stream (one-minute candles by default) to keep track of market time even if no trades are
done.
When a finished candle reports the configured StartHour, enable the AutoTradingActive flag and log the event.
When a finished candle reports the configured StopHour, disable the AutoTradingActive flag and log the event.
Suppress duplicate toggles inside the same hour so the log does not flood when multiple candles or ticks arrive during that
hour.
Parameters
Parameter
Description
StartHour
Hour of the day (0-23) that enables auto trading.
StopHour
Hour of the day (0-23) that disables auto trading.
CandleType
Timeframe used to poll the market clock. Smaller frames react faster.
Usage notes
The strategy does not send orders; it only exposes the AutoTradingActive property, which other strategies or control panels
can observe to decide when to submit trades.
When the start and stop hour are the same, the stop event runs after the start event, leaving trading disabled—identical to the
original expert advisor.
Choose a candle timeframe that matches how quickly you need the toggle to happen. A one-minute timeframe is a good balance
between responsiveness and resource usage.
Differences vs. MetaTrader version
MT4 toggled a global platform button through Windows messages. StockSharp exposes a strategy-level flag instead, making the
behaviour easier to integrate with complex setups.
The StockSharp port runs entirely within the high-level API, making it easy to combine with charting or other helper
strategies without low-level message hooks.
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Auto Trading Publish strategy: SMA crossover + RSI confirmation.
/// Buys when close crosses above SMA and RSI is below 40.
/// Sells when close crosses below SMA and RSI is above 60.
/// </summary>
public class AutoTradingPublishStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _smaPeriod;
private readonly StrategyParam<int> _rsiPeriod;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int SmaPeriod
{
get => _smaPeriod.Value;
set => _smaPeriod.Value = value;
}
public int RsiPeriod
{
get => _rsiPeriod.Value;
set => _rsiPeriod.Value = value;
}
public AutoTradingPublishStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(15).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_smaPeriod = Param(nameof(SmaPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("SMA Period", "SMA period", "Indicators");
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("RSI Period", "RSI period", "Indicators");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var sma = new SimpleMovingAverage { Length = SmaPeriod };
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
decimal? prevClose = null;
decimal? prevSma = null;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(sma, rsi, (candle, smaVal, rsiVal) =>
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var close = candle.ClosePrice;
if (prevClose.HasValue && prevSma.HasValue)
{
var crossUp = prevClose.Value <= prevSma.Value && close > smaVal;
var crossDown = prevClose.Value >= prevSma.Value && close < smaVal;
if (crossUp && rsiVal < 55m && Position <= 0)
BuyMarket();
else if (crossDown && rsiVal > 45m && Position >= 0)
SellMarket();
}
prevClose = close;
prevSma = smaVal;
})
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, sma);
DrawOwnTrades(area);
}
}
}
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 CandleStates
from StockSharp.Algo.Indicators import SimpleMovingAverage, RelativeStrengthIndex
from StockSharp.Algo.Strategies import Strategy
from datatype_extensions import *
class auto_trading_publish_strategy(Strategy):
"""
Auto Trading Publish strategy: SMA crossover + RSI confirmation.
Buys when close crosses above SMA and RSI is below 55.
Sells when close crosses below SMA and RSI is above 45.
"""
def __init__(self):
super(auto_trading_publish_strategy, self).__init__()
self._candle_type = self.Param("CandleType", tf(15)) \
.SetDisplay("Candle Type", "Candle timeframe", "General")
self._sma_period = self.Param("SmaPeriod", 20) \
.SetGreaterThanZero() \
.SetDisplay("SMA Period", "SMA period", "Indicators")
self._rsi_period = self.Param("RsiPeriod", 14) \
.SetGreaterThanZero() \
.SetDisplay("RSI Period", "RSI period", "Indicators")
self._prev_close = None
self._prev_sma = None
@property
def CandleType(self): return self._candle_type.Value
@CandleType.setter
def CandleType(self, v): self._candle_type.Value = v
@property
def SmaPeriod(self): return self._sma_period.Value
@SmaPeriod.setter
def SmaPeriod(self, v): self._sma_period.Value = v
@property
def RsiPeriod(self): return self._rsi_period.Value
@RsiPeriod.setter
def RsiPeriod(self, v): self._rsi_period.Value = v
def OnReseted(self):
super(auto_trading_publish_strategy, self).OnReseted()
self._prev_close = None
self._prev_sma = None
def OnStarted2(self, time):
super(auto_trading_publish_strategy, self).OnStarted2(time)
self._prev_close = None
self._prev_sma = None
sma = SimpleMovingAverage()
sma.Length = self.SmaPeriod
rsi = RelativeStrengthIndex()
rsi.Length = self.RsiPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(sma, rsi, self.ProcessCandle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, sma)
self.DrawOwnTrades(area)
def ProcessCandle(self, candle, sma_val, rsi_val):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
if self._prev_close is not None and self._prev_sma is not None:
cross_up = self._prev_close <= self._prev_sma and close > sma_val
cross_down = self._prev_close >= self._prev_sma and close < sma_val
if cross_up and rsi_val < 55 and self.Position <= 0:
self.BuyMarket()
elif cross_down and rsi_val > 45 and self.Position >= 0:
self.SellMarket()
self._prev_close = close
self._prev_sma = sma_val
def CreateClone(self):
"""!! REQUIRED!! Creates a new instance of the strategy."""
return auto_trading_publish_strategy()