A Estratégia Trendcapture é uma versão StockSharp de alto nível do MetaTrader consultor especialista MQL/7772/Trendcapture.mq4. O EA original observa a direção da tendência Parabolic SAR e espera que um ambiente ADX fraco entre em novas posições. Após cada negociação fechada, ele decide se mantém ou inverte a direção da negociação, dependendo do lucro realizado, e uma vez que uma posição aberta ganha alguns pontos, ela puxa o stop para o ponto de equilíbrio.
Esta porta mantém o comportamento intacto enquanto depende dos auxiliares de ordem e ligações de indicadores de StockSharp. Todos os sinais são processados em velas concluídas em um período configurável.
Lógica de negociação
Configuração do indicador
Parabolic SAR (ParabolicSar) com etapa e limite de aceleração configuráveis.
Índice direcional médio (AverageDirectionalIndex) para o valor de força da tendência principal.
Seleção de entrada
Apenas uma posição pode ser aberta por vez.
Uma entrada longa é permitida quando:
A direção desejada (derivada da última negociação fechada) aponta para compra.
A vela atual fecha acima do valor SAR.
A linha principal ADX está abaixo de 20, indicando o regime de variação exigido pelo código original.
Uma entrada curta reflete as regras (a direção desejada aponta para a venda, preço de fechamento abaixo de SAR, ADX abaixo de 20).
Gerenciamento de saídas
Após cada preenchimento, a estratégia envia ordens de stop-loss e take-profit em distâncias StopLossPoints e TakeProfitPoints (convertidas por meio da etapa de preço do título).
Quando o lucro flutuante atinge GuardPoints, o stop ativo é reemitido ao preço de entrada para garantir um piso de equilíbrio.
O fechamento de negociações aciona uma atualização de direção: negociações lucrativas mantêm o mesmo viés, negociações perdedoras ou planas o invertem, reproduzindo a verificação OrderProfit() do especialista.
Parâmetros
Parâmetro
Descrição
Padrão
CandleType
Tipo de dados Candle usado para cálculos de indicadores.
Período de 1 hora
SarStep
Fator de aceleração inicial de Parabolic SAR.
0.02
SarMax
Fator de aceleração máximo para Parabolic SAR.
0.2
AdxPeriod
Período de suavização de ADX.
14
TakeProfitPoints
Distância de lucro expressa em etapas de preço.
180
StopLossPoints
Distância de stop-loss expressa em etapas de preço.
50
GuardPoints
Limite de lucro (em etapas de preço) necessário antes de mover o stop para o ponto de equilíbrio.
5
MaximumRisk
Fator de escala de volume; 0.03 reproduz o tamanho original do lote.
0.03
Notas de uso
Certifique-se de que o título selecionado exponha PriceStep (ou pelo menos MinStep) para que as distâncias dos pontos sejam convertidas em valores de preço corretamente.
A propriedade base Volume representa o tamanho do lote usado quando MaximumRisk é igual a 0.03. Aumentar o fator de risco dimensiona o volume enviado proporcionalmente.
Como o EA negocia no mercado e coloca imediatamente ordens de proteção, não há entradas pendentes no livro quando a estratégia está ociosa.
O guarda do ponto de equilíbrio cancela e reemite o stop de proteção ao preço de entrada; isso reflete a chamada OrderModify original que moveu o stop loss para o ponto de equilíbrio.
Arquivos
CS/TrendcaptureStrategy.cs – implementação StockSharp de alto nível do Trendcapture EA.
README_zh.md – Tradução chinesa deste documento.
README_ru.md – Tradução russa deste documento.
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>
/// Trendcapture strategy - EMA trend with ADX strength filter.
/// Buys when close is above EMA and ADX indicates trending.
/// Sells when close is below EMA and ADX indicates trending.
/// </summary>
public class TrendcaptureStrategy : Strategy
{
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<int> _adxPeriod;
private readonly StrategyParam<decimal> _adxThreshold;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevClose;
private decimal _prevEma;
private bool _hasPrev;
public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
public int AdxPeriod { get => _adxPeriod.Value; set => _adxPeriod.Value = value; }
public decimal AdxThreshold { get => _adxThreshold.Value; set => _adxThreshold.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public TrendcaptureStrategy()
{
_emaPeriod = Param(nameof(EmaPeriod), 20)
.SetDisplay("EMA Period", "EMA lookback", "Indicators");
_adxPeriod = Param(nameof(AdxPeriod), 14)
.SetDisplay("ADX Period", "ADX lookback", "Indicators");
_adxThreshold = Param(nameof(AdxThreshold), 30m)
.SetDisplay("ADX Threshold", "Minimum ADX for trending", "Levels");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
protected override void OnReseted() { base.OnReseted(); _prevClose = 0m; _prevEma = 0m; _hasPrev = false; }
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var fast = new ExponentialMovingAverage { Length = EmaPeriod };
var slow = new ExponentialMovingAverage { Length = EmaPeriod * 3 };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(fast, slow, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow)
{
if (candle.State != CandleStates.Finished) return;
if (!_hasPrev) { _prevClose = fast; _prevEma = slow; _hasPrev = true; return; }
if (_prevClose <= _prevEma && fast > slow && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
else if (_prevClose >= _prevEma && fast < slow && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
_prevClose = fast; _prevEma = slow;
}
}
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 trendcapture_strategy(Strategy):
def __init__(self):
super(trendcapture_strategy, self).__init__()
self._ema_period = self.Param("EmaPeriod", 20).SetDisplay("EMA Period", "EMA lookback", "Indicators")
self._adx_period = self.Param("AdxPeriod", 14).SetDisplay("ADX Period", "ADX lookback", "Indicators")
self._adx_threshold = self.Param("AdxThreshold", 30.0).SetDisplay("ADX Threshold", "Minimum ADX for trending", "Levels")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))).SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_fast = 0.0; self._prev_slow = 0.0; self._has_prev = False
@property
def ema_period(self): return self._ema_period.Value
@property
def candle_type(self): return self._candle_type.Value
def OnReseted(self):
super(trendcapture_strategy, self).OnReseted()
self._prev_fast = 0.0; self._prev_slow = 0.0; self._has_prev = False
def OnStarted2(self, time):
super(trendcapture_strategy, self).OnStarted2(time)
self._has_prev = False
fast = ExponentialMovingAverage(); fast.Length = self.ema_period
slow = ExponentialMovingAverage(); slow.Length = self.ema_period * 3
sub = self.SubscribeCandles(self.candle_type)
sub.Bind(fast, slow, self.process_candle).Start()
def process_candle(self, candle, fast, slow):
if candle.State != CandleStates.Finished: return
f = float(fast); s = float(slow)
if not self._has_prev: self._prev_fast = f; self._prev_slow = s; self._has_prev = True; return
if self._prev_fast <= self._prev_slow and f > s and self.Position <= 0:
if self.Position < 0: self.BuyMarket()
self.BuyMarket()
elif self._prev_fast >= self._prev_slow and f < s and self.Position >= 0:
if self.Position > 0: self.SellMarket()
self.SellMarket()
self._prev_fast = f; self._prev_slow = s
def CreateClone(self): return trendcapture_strategy()