La estrategia heredada de captura de tendencias traslada el MetaTrader experto TrendCapture.mq4 al StockSharp API de alto nivel. La versión C# mantiene el conjunto de reglas original basado en la dirección Parabolic SAR, un filtro bajo ADX y una administración simple del dinero para equilibrar los gastos.
Ideas centrales
Procese las velas terminadas del período de tiempo seleccionado y envíelas a Parabolic SAR (0.02/0.2) y al índice direccional promedio (14).
Ingrese solo cuando ADX esté por debajo de AdxThreshold, lo que indica un mercado tranquilo donde SAR las reversiones son más confiables.
Recuerde la dirección y el resultado de la última operación cerrada: repita el mismo lado después de un ganador, gire hacia el lado opuesto después de un perdedor.
Aplique niveles de stop-loss y take-profit de distancia fija (configurados en puntos de precio) y mueva el stop al punto de equilibrio una vez que la operación gane BreakEvenGuard puntos.
Dimensione el volumen del pedido a partir del valor de la cartera disponible y MaximumRisk; recurrir a la estrategia Volume cuando la información de la cartera no esté disponible.
Parámetros
Nombre
Predeterminado
Descripción
SarStep
0,02
Paso de aceleración inicial Parabolic SAR.
SarMax
0,2
Aceleración máxima Parabolic SAR.
AdxPeriod
14
ADX período promedio.
AdxThreshold
20
Valor máximo ADX que aún permite una entrada nueva.
TakeProfitPoints
180
Distancia de obtención de beneficios en puntos de precio.
StopLossPoints
50
Distancia de stop-loss en puntos de precio.
BreakEvenGuard
5
Colchón de ganancias (en puntos) requerido antes de mover la parada a la entrada.
MaximumRisk
0,03
Fracción del margen libre utilizada para dimensionar la posición.
CandleType
velas de 1 hora
Plazo para cálculos de indicadores y señales comerciales.
Gestión de pedidos
Las entradas largas requieren un precio de cierre superior a SAR con un precio bajo de ADX; los cortos requieren un precio de cierre inferior a SAR con el mismo filtro ADX.
Los niveles de stop-loss y take-profit se recalculan en cada entrada y se evalúan en cada vela completa.
La activación del punto de equilibrio simplemente desplaza el tope al precio de entrada. Si no se configura ningún stop-loss (distancia cero o negativa), la guardia se ignora.
Indicadores
ParabolicSar para sesgo direccional.
AverageDirectionalIndex para el filtro de intensidad (solo se utiliza la línea principal ADX).
Notas
La estrategia utiliza BindEx para evitar el acceso directo al buffer, siguiendo las pautas del proyecto.
El cálculo del volumen basado en cartera respeta las restricciones de la junta directiva (LotStep, MinVolume, MaxVolume).
El historial comercial necesario para el sesgo de dirección se recopila a través de OnNewMyTrade, por lo que se siguen admitiendo rellenos parciales.
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
public class TrendCaptureLegacyStrategy : Strategy
{
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevFast; private decimal _prevSlow; private bool _hasPrev;
private int _cooldown;
public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public TrendCaptureLegacyStrategy()
{
_fastPeriod = Param(nameof(FastPeriod), 10).SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 30).SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(15).TimeFrame()).SetDisplay("Candle Type", "Candle timeframe", "General");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevFast = default;
_prevSlow = default;
_hasPrev = default;
_cooldown = default;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var fast = new ExponentialMovingAverage { Length = FastPeriod };
var slow = new ExponentialMovingAverage { Length = SlowPeriod };
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 (!IsFormedAndOnlineAndAllowTrading()) return;
if (!_hasPrev) { _prevFast = fast; _prevSlow = slow; _hasPrev = true; return; }
if (_cooldown > 0)
{
_cooldown--;
_prevFast = fast; _prevSlow = slow;
return;
}
if (_prevFast <= _prevSlow && fast > slow && Position <= 0)
{
var volume = Volume + Math.Abs(Position);
BuyMarket(volume);
_cooldown = 2;
}
else if (_prevFast >= _prevSlow && fast < slow && Position >= 0)
{
var volume = Volume + Math.Abs(Position);
SellMarket(volume);
_cooldown = 2;
}
_prevFast = fast; _prevSlow = slow;
}
}