Esta estratégia porta o assessor especializado MetaTrader "1H EUR_USD" para a API de alto nível do StockSharp. Ela opera o par EUR/USD em velas horárias usando médias móveis duplas e detecção de oscilações MACD. As entradas requerem tanto um filtro de tendência (MA rápida acima/abaixo da MA lenta) quanto um padrão de fundo duplo/topo duplo MACD combinado com um rompimento de máximos ou mínimos recentes. O risco é controlado com stop loss, take profit baseados em pips e um trailing stop incremental que espelha a lógica do EA original.
Detalhes
Mercado: Projetado para EUR/USD no período de 1 hora, mas pode ser aplicado a qualquer instrumento que produza velas padrão.
Critérios de entrada:
Comprado:
A MA rápida está acima da MA lenta (tipo selecionável entre SMA, EMA, SMMA, LWMA).
A linha principal MACD forma qualquer uma das seguintes oscilações altistas completamente abaixo da linha zero:
MACD[-1] > MACD[-2] < MACD[-3] com MACD[-2] < 0 e o fechamento atual rompe o máximo da vela anterior.
MACD[-2] > MACD[-3] < MACD[-4] com MACD[-3] < 0 e o fechamento atual rompe o máximo de duas velas atrás.
Vendido:
A MA rápida está abaixo da MA lenta.
A linha principal MACD forma as oscilações baixistas espelhadas completamente acima da linha zero e o preço fecha abaixo do mínimo anterior relevante.
Critérios de saída:
Take profit e stop loss baseados em pips são anexados imediatamente após a entrada.
O trailing stop se ativa apenas após o preço se mover favoravelmente por TrailingStop + TrailingStep pips e então segue o preço a uma distância de TrailingStop pips, seguindo a lógica de modificação gradual do EA.
Ordens de proteção se ativam no máximo/mínimo intraperiodo da vela.
Gestão de posição:
Usa o volume de operação configurado; reverter posições fecha o lado oposto antes de abrir o novo.
As operações compradas e vendidas compartilham os mesmos cálculos de pip (o tamanho do pip se adapta automaticamente a cotações de 4/5 dígitos).
Indicadores:
Médias móveis rápida e lenta com tipo selecionável (Simples, Exponencial, Suavizado, Ponderado Linear) e deslocamento horizontal opcional.
MACD clássico (comprimentos de EMA rápida/lenta/sinal).
Parâmetros:
TradeVolume – tamanho de lote base enviado com cada ordem.
StopLossPips, TakeProfitPips – distâncias de proteção em pips (defina como zero para desabilitar).
TrailingStopPips, TrailingStepPips – configuração de rastreamento; o passo de rastreamento deve permanecer positivo quando o rastreamento está ativo.
FastMaLength, FastMaShift, FastMaType – configurações da MA rápida.
SlowMaLength, SlowMaShift, SlowMaType – configurações da MA lenta.
CandleType – período para processamento (padrão de 1 hora).
LookbackPeriod – preservado por compatibilidade com as entradas MQL; não altera a lógica porque o EA original também o deixou sem uso.
Notas
O comportamento do trailing stop espelha a versão MQL: nenhum ajuste ocorre até que tanto a distância de rastreamento quanto o passo de rastreamento sejam superados pelo lucro não realizado.
A estratégia assume que o passo de preço é igual ao ponto de cotação; se o instrumento tem 3 ou 5 dígitos decimais, o código escala automaticamente o tamanho do pip por 10.
Os comentários dentro do fonte C# explicam cada bloco-chave em inglês para facilitar a manutenção e extensão.
using System;
using System.Collections.Generic;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// 1H EUR/USD style strategy using EMA with RSI confirmation.
/// </summary>
public class OneHourEurUsdStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<int> _rsiPeriod;
private decimal? _prevRsi;
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 OneHourEurUsdStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
.SetDisplay("Candle Type", "Timeframe", "General");
_emaPeriod = Param(nameof(EmaPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("EMA Period", "Trend EMA period", "Indicators");
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("RSI Period", "RSI period", "Indicators");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevRsi = null;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevRsi = null;
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ema, rsi, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, ema);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal emaVal, decimal rsiVal)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
{
_prevRsi = rsiVal;
return;
}
if (_prevRsi == null)
{
_prevRsi = rsiVal;
return;
}
var close = candle.ClosePrice;
// Price above EMA + RSI crosses 50 up
if (close > emaVal && _prevRsi.Value <= 50 && rsiVal > 50 && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
// Price below EMA + RSI crosses 50 down
else if (close < emaVal && _prevRsi.Value >= 50 && rsiVal < 50 && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
_prevRsi = rsiVal;
}
}
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 one_hour_eur_usd_strategy(Strategy):
def __init__(self):
super(one_hour_eur_usd_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))) \
.SetDisplay("Candle Type", "Timeframe", "General")
self._ema_period = self.Param("EmaPeriod", 20) \
.SetDisplay("EMA Period", "Trend EMA period", "Indicators")
self._rsi_period = self.Param("RsiPeriod", 14) \
.SetDisplay("RSI Period", "RSI period", "Indicators")
self._prev_rsi = None
@property
def CandleType(self):
return self._candle_type.Value
@property
def EmaPeriod(self):
return self._ema_period.Value
@property
def RsiPeriod(self):
return self._rsi_period.Value
def OnReseted(self):
super(one_hour_eur_usd_strategy, self).OnReseted()
self._prev_rsi = None
def OnStarted2(self, time):
super(one_hour_eur_usd_strategy, self).OnStarted2(time)
self._prev_rsi = None
ema = ExponentialMovingAverage()
ema.Length = self.EmaPeriod
rsi = RelativeStrengthIndex()
rsi.Length = self.RsiPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(ema, rsi, self._on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, ema)
self.DrawOwnTrades(area)
def _on_process(self, candle, ema_value, rsi_value):
if candle.State != CandleStates.Finished:
return
rv = float(rsi_value)
if not self.IsFormedAndOnlineAndAllowTrading():
self._prev_rsi = rv
return
if self._prev_rsi is None:
self._prev_rsi = rv
return
close = float(candle.ClosePrice)
ev = float(ema_value)
# Price above EMA + RSI crosses 50 up
if close > ev and self._prev_rsi <= 50 and rv > 50 and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
# Price below EMA + RSI crosses 50 down
elif close < ev and self._prev_rsi >= 50 and rv < 50 and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_rsi = rv
def CreateClone(self):
return one_hour_eur_usd_strategy()