Sistema de rompimento diário para GBPUSD que combina uma EMA calculada em máximas, filtros RSI, confirmação de momentum MACD e gestão de risco baseada em ATR. O script reproduz o comportamento de quatro tomadas de lucro e ponto de equilíbrio da versão MetaTrader original.
Dados Principais
Mercado: GBP/USD spot ou CFD
Período: Candles diários (configurável)
Direção: Comprado e vendido
Estilo de posição: Escalonamento multi-alvo com stop-loss compartilhado
Instrumentos Usados: EMA (High), RSI, linha principal MACD, ATR
Configuração de Indicadores
EMA em preços Máximos – comprimento padrão 6, aproxima o nível dinâmico de rompimento.
RSI – comprimento padrão 10, define os corredores de sobrecompra/sobrevenda usados como filtros de momentum.
Linha principal MACD – rápido 5, lento 21, sinal 14. Apenas a linha principal é usada para medir a inclinação do momentum.
ATR – comprimento 28, fornece stops e alvos dependentes de volatilidade.
Lógica de Entrada
Entradas Compradas
A barra diária anterior abre abaixo da EMA (High) e fecha acima dela (confirmação de cruzamento ascendente).
O RSI permanece entre 60 e 80 – previne trades durante momentum fraco e evita rallys sobreextendidos.
A linha principal do MACD satisfaz uma de duas verificações de momentum:
O valor dois barras atrás é negativo (indicando que a tendência recentemente se tornou positiva), ou
A redução relativa no MACD absoluto entre as últimas duas barras supera o limiar configurável MacdDiffBuy (padrão 0.5).
Se todas as condições forem atendidas, quatro ordens iguais de compra de mercado são colocadas (0.1 lotes cada uma por padrão). Qualquer exposição vendida existente é zerada antes de enviar o novo lote.
Entradas Vendidas
A barra abre acima da EMA (High) e fecha abaixo dela.
O RSI está entre 25 e 39 – espelha os limiares do lado comprado.
O MACD dois barras atrás é positivo ou a mudança relativa no MACD absoluto entre as últimas duas barras está acima de MacdDiffSell (padrão 0.15).
Na confirmação, a estratégia zera os comprados existentes, depois envia quatro vendas iguais de mercado.
Gestão de Trades
Stop Inicial: Stop ATR compartilhado calculado a partir do fechamento de entrada. Comprados usam entry - ATR * StopLossMultiplier (padrão 1.6). Vendidos usam entry + ATR * StopLossMultiplier.
Alvos de Lucro: Quatro níveis incrementais baseados em ATR por direção: múltiplos 1.0, 1.5, 2.0 e 2.5 escalados pelo parâmetro TakeProfitMultiplier (padrão 1). Cada nível fecha um quarto da posição original através de uma ordem de mercado quando o preço passa pelo nível.
Comportamento de Ponto de Equilíbrio: Após cada saída parcial, o stop protetor para a posição restante é movido para o preço alvo mais recente. Isso imita o EA original que modifica os stop-losses para o preço de take-profit executado sempre que um trade TP ocorre.
Tratamento de Stop: Se o preço tocar o nível protetor intrabar (usando máxima/mínima do candle), a posição restante é fechada imediatamente a mercado.
Notas de Controle de Risco
A estratégia não piramida além do lote de quatro entradas. Um novo sinal é ignorado enquanto a exposição permanece na mesma direção.
O ATR deve ser positivo; os sinais são ignorados se o indicador de volatilidade ainda não se formou.
Mudanças de parâmetros em tempo de execução afetam apenas ordens futuras; o volume por ordem é capturado na entrada para o escalonamento correto nas saídas.
Parâmetros
Nome
Descrição
Padrão
OrderVolume
Volume por ordem individual de mercado no lote
0.1
EmaPeriod
Comprimento de EMA aplicado a máximas de candle
6
RsiPeriod
Período médio do RSI
10
AtrPeriod
Período médio do ATR
28
StopLossMultiplier
Múltiplo ATR para o stop protetor
1.6
TakeProfitMultiplier
Múltiplo ATR base para alvos de lucro
1.0
MacdFastPeriod
Comprimento de EMA rápida do MACD
5
MacdSlowPeriod
Comprimento de EMA lenta do MACD
21
MacdSignalPeriod
Comprimento de EMA de sinal do MACD
14
MacdDiffBuyThreshold
Melhoria mínima de inclinação MACD para trades comprados
0.5
MacdDiffSellThreshold
Melhoria mínima de inclinação MACD para trades vendidos
0.15
RsiUpperLimit
RSI máximo permitido antes de uma entrada comprada
80
RsiUpperLevel
RSI mínimo necessário para uma entrada comprada
60
RsiLowerLevel
RSI máximo permitido para uma entrada vendida
39
RsiLowerLimit
RSI mínimo necessário antes de vendidos
25
CandleType
Período usado para a assinatura de candles
1 Day
Dicas de Implantação
Otimizar os limiares de RSI e MACD juntos; afrouxar os corredores RSI sem ajustar os filtros de aceleração MACD pode criar sinais falsos.
Como as saídas parciais dependem dos extremos do candle, dados precisos de valores máximos/mínimos são importantes para backtests realistas.
Sempre operar com capital suficiente para lidar com quatro ordens simultâneas por sinal.
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Alexav D1 Profit GBPUSD strategy (simplified). Uses EMA crossover with RSI
/// filter for breakout entries with ATR-based stop/take management.
/// </summary>
public class AlexavD1ProfitGbpUsdStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _emaFastLength;
private readonly StrategyParam<int> _emaSlowLength;
private readonly StrategyParam<int> _rsiLength;
private readonly StrategyParam<decimal> _rsiUpperLevel;
private readonly StrategyParam<decimal> _rsiLowerLevel;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int EmaFastLength
{
get => _emaFastLength.Value;
set => _emaFastLength.Value = value;
}
public int EmaSlowLength
{
get => _emaSlowLength.Value;
set => _emaSlowLength.Value = value;
}
public int RsiLength
{
get => _rsiLength.Value;
set => _rsiLength.Value = value;
}
public decimal RsiUpperLevel
{
get => _rsiUpperLevel.Value;
set => _rsiUpperLevel.Value = value;
}
public decimal RsiLowerLevel
{
get => _rsiLowerLevel.Value;
set => _rsiLowerLevel.Value = value;
}
public AlexavD1ProfitGbpUsdStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candles", "General");
_emaFastLength = Param(nameof(EmaFastLength), 6)
.SetGreaterThanZero()
.SetDisplay("EMA Fast", "Fast EMA period", "Indicators");
_emaSlowLength = Param(nameof(EmaSlowLength), 21)
.SetGreaterThanZero()
.SetDisplay("EMA Slow", "Slow EMA period", "Indicators");
_rsiLength = Param(nameof(RsiLength), 10)
.SetGreaterThanZero()
.SetDisplay("RSI Length", "RSI period", "Indicators");
_rsiUpperLevel = Param(nameof(RsiUpperLevel), 65m)
.SetDisplay("RSI Upper", "Max RSI for buy", "Filters");
_rsiLowerLevel = Param(nameof(RsiLowerLevel), 35m)
.SetDisplay("RSI Lower", "Min RSI for sell", "Filters");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var emaFast = new ExponentialMovingAverage { Length = EmaFastLength };
var emaSlow = new ExponentialMovingAverage { Length = EmaSlowLength };
decimal prevFast = 0, prevSlow = 0;
var hasPrev = false;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(emaFast, emaSlow, (ICandleMessage candle, decimal fastVal, decimal slowVal) =>
{
if (candle.State != CandleStates.Finished)
return;
if (!hasPrev)
{
prevFast = fastVal;
prevSlow = slowVal;
hasPrev = true;
return;
}
if (!IsFormedAndOnlineAndAllowTrading())
{
prevFast = fastVal;
prevSlow = slowVal;
return;
}
var close = candle.ClosePrice;
// EMA fast crosses above slow - buy signal
var bullishCross = prevFast <= prevSlow && fastVal > slowVal;
// EMA fast crosses below slow - sell signal
var bearishCross = prevFast >= prevSlow && fastVal < slowVal;
if (bullishCross && Position <= 0)
BuyMarket();
else if (bearishCross && Position >= 0)
SellMarket();
prevFast = fastVal;
prevSlow = slowVal;
})
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, emaFast);
DrawIndicator(area, emaSlow);
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 DataType, CandleStates
from StockSharp.Algo.Indicators import ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class alexav_d1_profit_gbp_usd_strategy(Strategy):
def __init__(self):
super(alexav_d1_profit_gbp_usd_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Candles", "General")
self._ema_fast_length = self.Param("EmaFastLength", 6) \
.SetDisplay("EMA Fast", "Fast EMA period", "Indicators")
self._ema_slow_length = self.Param("EmaSlowLength", 21) \
.SetDisplay("EMA Slow", "Slow EMA period", "Indicators")
self._prev_fast = 0.0
self._prev_slow = 0.0
self._has_prev = False
@property
def CandleType(self):
return self._candle_type.Value
@property
def EmaFastLength(self):
return self._ema_fast_length.Value
@property
def EmaSlowLength(self):
return self._ema_slow_length.Value
def OnReseted(self):
super(alexav_d1_profit_gbp_usd_strategy, self).OnReseted()
self._prev_fast = 0.0
self._prev_slow = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(alexav_d1_profit_gbp_usd_strategy, self).OnStarted2(time)
self._prev_fast = 0.0
self._prev_slow = 0.0
self._has_prev = False
ema_fast = ExponentialMovingAverage()
ema_fast.Length = self.EmaFastLength
ema_slow = ExponentialMovingAverage()
ema_slow.Length = self.EmaSlowLength
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(ema_fast, ema_slow, self._on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, ema_fast)
self.DrawIndicator(area, ema_slow)
self.DrawOwnTrades(area)
def _on_process(self, candle, fast_value, slow_value):
if candle.State != CandleStates.Finished:
return
fv = float(fast_value)
sv = float(slow_value)
if not self._has_prev:
self._prev_fast = fv
self._prev_slow = sv
self._has_prev = True
return
if self._prev_fast <= self._prev_slow and fv > sv and self.Position <= 0:
self.BuyMarket()
elif self._prev_fast >= self._prev_slow and fv < sv and self.Position >= 0:
self.SellMarket()
self._prev_fast = fv
self._prev_slow = sv
def CreateClone(self):
return alexav_d1_profit_gbp_usd_strategy()