DreamBot é uma versão StockSharp do MetaTrader 4 consultor especialista "DreamBot". A estratégia monitora o oscilador do Índice de Força em velas horárias e espera que o impulso ultrapasse os limites de alta ou baixa. Quando o Índice de Força cruza acima do nível de alta depois de estar abaixo dele na barra anterior, a estratégia abre uma posição longa. Quando o Índice de Força cruza abaixo do nível de baixa depois de estar acima dele, a estratégia abre uma posição curta. A negociação ocorre apenas quando não existe posição, refletindo a lógica de posição única do robô original.
Lógica de negociação
Assine as velas H1 e calcule um Índice de Força suavizado (comprimento 13 por padrão).
Acompanhe os dois últimos valores completos do Índice de Força. Os sinais são gerados usando os valores da barra anteriores, exatamente como a implementação MT4 (iForce com deslocamento 1 e 2).
Insira comprado quando o Índice de Força na vela anterior estiver acima de BullsThreshold e o valor de duas velas atrás estiver abaixo do limite, desde que nenhuma posição esteja aberta.
Digite short quando o índice de força na vela anterior estiver abaixo de BearsThreshold e o valor de duas velas atrás estiver acima do limite, desde que nenhuma posição esteja aberta.
O trailing stop opcional replica o EA original: quando o lucro excede TrailingStepPoints, um nível de stop é puxado para TrailingStartPoints longe do preço e segue avanços adicionais.
Gestão de risco
StartProtection anexa ordens clássicas de stop-loss e take-profit usando a distância de MetaTrader "pontos" convertida por meio da etapa de preço do instrumento.
A proteção móvel é baseada no mercado: quando o nível móvel calculado é violado, a estratégia envia uma ordem de mercado para fechar a posição imediatamente.
O rastreamento de posição captura o preço de entrada ponderado pelo volume para que a lógica final se alinhe com preenchimentos parciais e reversões.
Parâmetros
Parâmetro
Descrição
ForcePeriod
Período de suavização do índice de força (padrão 13).
TakeProfitPoints
Distância de lucro em MetaTrader pontos.
StopLossPoints
Distância de stop-loss em MetaTrader pontos.
BullsThreshold
Limite do Índice de Força de Alta que permite entradas longas.
BearsThreshold
Limite do Índice de Força de Baixa que permite entradas curtas.
EnableTrailing
Ativa a lógica de trailing stop.
TrailingStartPoints
Distância (em pontos) mantida entre o preço e o trailing stop uma vez ativado.
TrailingStepPoints
Lucro (em pontos) necessário antes da ativação do trailing stop.
CandleType
Prazo usado para cálculos do Índice de Força (o padrão é velas H1).
Notas
A validação do parâmetro evita que o gatilho final (TrailingStepPoints) exceda a distância final (TrailingStartPoints), correspondendo à verificação de segurança MetaTrader.
A aplicação do nível de parada do EA original (corretor MODE_STOPLEVEL) é aproximada por meio das conversões de etapas de preço de StockSharp. Dependendo das restrições do corretor, poderá ser necessária validação adicional.
Todos os comentários e registros do código são fornecidos em inglês, conforme solicitado pelas diretrizes de conversão.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// DreamBot strategy: Force Index momentum with EMA trend filter.
/// Buys when Force Index positive and close above EMA, sells when negative and below EMA.
/// </summary>
public class DreamBotStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<int> _signalCooldownCandles;
private decimal _prevClose;
private bool _hasPrevClose;
private bool _wasBullish;
private int _candlesSinceTrade;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
public int SignalCooldownCandles { get => _signalCooldownCandles.Value; set => _signalCooldownCandles.Value = value; }
public DreamBotStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_emaPeriod = Param(nameof(EmaPeriod), 100)
.SetGreaterThanZero()
.SetDisplay("EMA Period", "EMA trend filter period", "Indicators");
_signalCooldownCandles = Param(nameof(SignalCooldownCandles), 6)
.SetGreaterThanZero()
.SetDisplay("Signal Cooldown", "Bars to wait between trades", "Trading");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevClose = 0m;
_hasPrevClose = false;
_wasBullish = false;
_candlesSinceTrade = SignalCooldownCandles;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrevClose = false;
_candlesSinceTrade = SignalCooldownCandles;
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(ema, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal emaValue)
{
if (candle.State != CandleStates.Finished) return;
if (_candlesSinceTrade < SignalCooldownCandles)
_candlesSinceTrade++;
var close = candle.ClosePrice;
var volume = candle.TotalVolume;
if (_hasPrevClose && volume > 0)
{
// Simple force index: (close - prevClose) * volume
var forceIndex = (close - _prevClose) * volume;
var isBullish = forceIndex > 0 && close > emaValue;
if (isBullish && !_wasBullish && Position <= 0 && _candlesSinceTrade >= SignalCooldownCandles)
{
BuyMarket();
_candlesSinceTrade = 0;
}
else if (!isBullish && forceIndex < 0 && close < emaValue && _wasBullish && Position >= 0 && _candlesSinceTrade >= SignalCooldownCandles)
{
SellMarket();
_candlesSinceTrade = 0;
}
_wasBullish = isBullish;
}
_prevClose = close;
_hasPrevClose = 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
from StockSharp.Algo.Strategies import Strategy
class dream_bot_strategy(Strategy):
def __init__(self):
super(dream_bot_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(60)))
self._ema_period = self.Param("EmaPeriod", 100)
self._signal_cooldown_candles = self.Param("SignalCooldownCandles", 6)
self._prev_close = 0.0
self._has_prev_close = False
self._was_bullish = False
self._candles_since_trade = 6
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def EmaPeriod(self):
return self._ema_period.Value
@EmaPeriod.setter
def EmaPeriod(self, value):
self._ema_period.Value = value
@property
def SignalCooldownCandles(self):
return self._signal_cooldown_candles.Value
@SignalCooldownCandles.setter
def SignalCooldownCandles(self, value):
self._signal_cooldown_candles.Value = value
def OnReseted(self):
super(dream_bot_strategy, self).OnReseted()
self._prev_close = 0.0
self._has_prev_close = False
self._was_bullish = False
self._candles_since_trade = self.SignalCooldownCandles
def OnStarted2(self, time):
super(dream_bot_strategy, self).OnStarted2(time)
self._has_prev_close = False
self._candles_since_trade = self.SignalCooldownCandles
ema = ExponentialMovingAverage()
ema.Length = self.EmaPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(ema, self._process_candle).Start()
def _process_candle(self, candle, ema_value):
if candle.State != CandleStates.Finished:
return
if self._candles_since_trade < self.SignalCooldownCandles:
self._candles_since_trade += 1
close = float(candle.ClosePrice)
volume = float(candle.TotalVolume)
ema_val = float(ema_value)
if self._has_prev_close and volume > 0:
force_index = (close - self._prev_close) * volume
is_bullish = force_index > 0 and close > ema_val
if is_bullish and not self._was_bullish and self.Position <= 0 and self._candles_since_trade >= self.SignalCooldownCandles:
self.BuyMarket()
self._candles_since_trade = 0
elif not is_bullish and force_index < 0 and close < ema_val and self._was_bullish and self.Position >= 0 and self._candles_since_trade >= self.SignalCooldownCandles:
self.SellMarket()
self._candles_since_trade = 0
self._was_bullish = is_bullish
self._prev_close = close
self._has_prev_close = True
def CreateClone(self):
return dream_bot_strategy()