La Estrategia de parada de canal CCI USD/CHF es una StockSharp implementación de alto nivel del MetaTrader 4 asesores expertos UsdChf_new. La estrategia escucha las rupturas del índice de canales de productos básicos (CCI) en el marco temporal del cuarto semestre y despliega órdenes stop pendientes por encima o por debajo del precio actual. Una vez que se completa una orden, la posición está protegida por las mismas reglas de administración de dinero basadas en pips utilizadas en el robot original: un stop loss fijo, cancelación opcional de órdenes pendientes obsoletas, reubicación del punto de equilibrio y gestión de trailing stop.
Esta conversión mantiene el flujo de ejecución original pero adopta el flujo de trabajo idiomático StockSharp: suscripciones de velas, vinculaciones de indicadores y asistentes de órdenes de alto nivel (BuyStop, SellStop, BuyMarket, SellMarket). Todas las distancias de riesgo todavía están configuradas en pips para que los usuarios de Forex sigan siendo familiares.
Lógica de trading
Indicador y señales
Calcule un CCI con el período configurado en velas H4 terminadas.
Supervise los límites del canal: +CCI Channel y -CCI Channel.
Detecta cruces del valor actual con el valor anterior para generar señales.
Cruzar hacia arriba a través de -CCI Channel prepara una parada de compra por encima del precio.
Cruzar hacia abajo a través de +CCI Channel prepara una parada de venta por debajo del precio.
Órdenes pendientes
Las órdenes stop se compensan desde el cierre de la vela en Entry Indent (pips) y se redondean al paso del instrumento.
Sólo puede haber una orden pendiente activa a la vez. Crear uno nuevo cancela el lado opuesto.
Si el mercado se aleja más de Cancel Distance (pips), la orden pendiente se cancela para evitar perseguir el precio.
Gestión de posiciones
Las posiciones ocupadas heredan la distancia de stop loss original.
Cuando la operación gana al menos Break Even (pips), el stop de protección se mueve al precio de entrada.
Después de que la ganancia excede Trailing Stop (pips), el stop sigue el precio manteniendo la brecha configurada.
Los cruces opuestos de CCI fuerzan una salida de posición y colocan una nueva orden de parada en la nueva dirección.
Parámetros
Parámetro
Descripción
Predeterminado
Optimizable
CandleType
Serie de velas utilizada para los cálculos CCI (predeterminado H4).
plazo de 4 horas
No
CciPeriod
CCI período promedio.
73
si
CciChannel
Nivel absoluto CCI que forma los límites del canal.
120
si
EntryIndentPips
Distancia (en pips) entre el precio de mercado y la orden stop pendiente.
30
si
StopLossPips
Distancia inicial de stop loss en pips.
95
si
CancelDistancePips
Gap máximo antes de cancelar órdenes pendientes.
30
si
TrailingStopPips
Distancia de trailing stop una vez activado.
110
si
BreakEvenPips
Beneficio requerido antes de que la parada se mueva al nivel de entrada.
60
si
Todas las distancias de pips se convierten en compensaciones de precios utilizando el instrumento PriceStep y Decimals. Para los símbolos Forex de 3/5 dígitos, el pip equivale a diez pasos de precio; de lo contrario, equivale a un solo paso.
Notas de uso
Adjunte la estrategia a un valor USD/CHF (o cualquier instrumento donde la gestión de riesgos basada en pips sea relevante).
Establezca el volumen de operaciones deseado a través de la propiedad base Strategy.Volume.
Opcionalmente, ajuste los parámetros basados en pips para que coincidan con las especificaciones del contrato del corredor.
Ejecute pruebas retrospectivas en Designer/Tester para validar el comportamiento antes de publicarlo.
Notas de conversión
El experto MetaTrader recorrió los grupos de pedidos sin procesar. En StockSharp la estrategia almacena referencias a las órdenes pendientes activas y en su lugar utiliza ayudas de cancelación de alto nivel.
El stop loss, el punto de equilibrio y el seguimiento se implementan mediante salidas de mercado explícitas porque la modificación de las órdenes del corredor no forma parte del API de alto nivel.
Todos los comentarios en línea se tradujeron al inglés y se ampliaron para mayor claridad.
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
public class UsdChfNewStrategy : Strategy
{
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<int> _cooldownCandles;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevFast;
private decimal _prevSlow;
private bool _hasPrev;
private int _cooldownRemaining;
public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
public int CooldownCandles { get => _cooldownCandles.Value; set => _cooldownCandles.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public UsdChfNewStrategy()
{
_fastPeriod = Param(nameof(FastPeriod), 20).SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 80).SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
_cooldownCandles = Param(nameof(CooldownCandles), 100).SetDisplay("Cooldown", "Candles between signals", "General");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame()).SetDisplay("Candle Type", "Candle timeframe", "General");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevFast = default;
_prevSlow = default;
_hasPrev = default;
_cooldownRemaining = default;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevFast = 0;
_prevSlow = 0;
_hasPrev = false;
_cooldownRemaining = 0;
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 (!_hasPrev) { _prevFast = fast; _prevSlow = slow; _hasPrev = true; return; }
if (_cooldownRemaining > 0)
{
_cooldownRemaining--;
_prevFast = fast;
_prevSlow = slow;
return;
}
if (_prevFast <= _prevSlow && fast > slow && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
_cooldownRemaining = CooldownCandles;
}
else if (_prevFast >= _prevSlow && fast < slow && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
_cooldownRemaining = CooldownCandles;
}
_prevFast = fast;
_prevSlow = slow;
}
}