La estrategia up3x1 Krohabor D es una conversión del MetaTrader 4 asesores expertos up3x1_Krohabor_D.mq4. Mantiene la idea original de alinear tres promedios móviles simples desplazados (SMA) para detectar rupturas de continuación de tendencia en el período de tiempo activo. La implementación de C# utiliza StockSharp API de alto nivel con suscripciones de velas y enlaces de indicadores, al tiempo que adapta la gestión de riesgos y posiciones al entorno .NET.
Lógica de trading
Se calculan tres SMA sobre los precios de cierre del instrumento:
Rápido SMA (24 barras predeterminadas)
Medio SMA (predeterminado 60 barras)
Lento SMA (predeterminado 120 barras)
Cada media móvil avanza según un número configurable de velas completadas (el valor predeterminado es 6). La estrategia compara el valor desplazado actual y el valor de la vela anterior para cada promedio.
Requisitos de entrada larga:
Tanto el valor lento actual como el anterior SMA permanecen por debajo de los valores actual y anterior rápido/medio SMA, lo que indica una separación alcista.
El medio SMA está cayendo en relación con el rápido SMA (medio anterior por encima del rápido anterior, medio actual por debajo del rápido actual).
Entrada corta refleja la lógica larga con todas las comparaciones invertidas.
Sólo se puede abrir una posición a la vez. Cuando no hay ninguna posición activa, la estrategia espera una nueva señal de entrada; en caso contrario gestiona las salidas.
Reglas de salida y protección
Las órdenes de protección iniciales se simulan monitoreando los máximos y mínimos de las velas:
La distancia de stop-loss se expresa en pasos de precio (por defecto 110 puntos) y se aplica una vez que se abre una posición.
La distancia de obtención de beneficios utiliza la misma representación (5 puntos por defecto).
Un trailing stop (predeterminado de 10 puntos) se activa una vez que las ganancias no realizadas superan el umbral configurado. El stop sigue el mercado a favor de la posición abierta sin retroceder nunca.
Las salidas de reversión de media móvil cierran la operación cuando el SMA rápido vuelve a cruzar los promedios medio y lento, imitando la lógica de cierre del EA original.
La reducción dinámica del volumen después de pérdidas consecutivas replica el comportamiento del script MT4: el tamaño de la operación disminuye proporcionalmente al número de operaciones perdedoras respetando un volumen mínimo.
Parámetros
Nombre
Descripción
FastPeriod
Período del ayuno SMA.
MediumPeriod
Período del medio SMA.
SlowPeriod
Periodo de la lentitud SMA.
MaShift
Número de velas completadas utilizadas para avanzar todas las medias móviles.
Volume
Volumen base de pedidos para nuevas entradas.
MinVolume
Volumen mínimo permitido después de ajustes basados en pérdidas.
LossReductionFactor
El divisor se aplica cuando se reduce el volumen después de operaciones perdedoras consecutivas.
StopLossPoints
Distancia de stop-loss medida en pasos de precio.
TakeProfitPoints
Distancia de obtención de beneficios medida en incrementos de precios.
TrailingPoints
Distancia del trailing-stop y umbral de activación en pasos de precio.
CandleType
Tipo de datos de vela (período de tiempo) utilizado para el análisis.
Notas
La estrategia utiliza SubscribeCandles junto con Bind para transmitir las salidas de los indicadores, evitando la recuperación manual del valor del indicador.
El comportamiento de stop-loss, take-profit y trailing se implementa dentro del ciclo estratégico para permanecer independiente del corredor. En entornos comerciales reales, puede reemplazar estos bloques con órdenes de protección reales si es necesario.
Todos los comentarios dentro del código fuente están escritos en inglés para cumplir con las pautas del proyecto.
No se proporcionan pruebas automatizadas; utilice backtesting dentro de StockSharp para validar conjuntos de parámetros para sus instrumentos.
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
public class Up3x1KrohaborShiftStrategy : Strategy
{
private readonly StrategyParam<int> _channelPeriod;
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevClose; private decimal _prevMid; private bool _hasPrev;
private int _cooldown;
public int ChannelPeriod { get => _channelPeriod.Value; set => _channelPeriod.Value = value; }
public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public Up3x1KrohaborShiftStrategy()
{
_channelPeriod = Param(nameof(ChannelPeriod), 20).SetDisplay("Channel Period", "Channel lookback", "Indicators");
_emaPeriod = Param(nameof(EmaPeriod), 14).SetDisplay("EMA Period", "EMA filter", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame()).SetDisplay("Candle Type", "Candle timeframe", "General");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevClose = default;
_prevMid = default;
_hasPrev = default;
_cooldown = default;
}
/// <inheritdoc />
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var highest = new Highest { Length = ChannelPeriod };
var lowest = new Lowest { Length = ChannelPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(highest, lowest, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal highest, decimal lowest)
{
if (candle.State != CandleStates.Finished) return;
if (!IsFormedAndOnlineAndAllowTrading()) return;
var close = candle.ClosePrice;
var mid = (highest + lowest) / 2;
if (!_hasPrev) { _prevClose = close; _prevMid = mid; _hasPrev = true; return; }
if (_cooldown > 0)
{
_cooldown--;
_prevClose = close; _prevMid = mid;
return;
}
if (_prevClose <= _prevMid && close > mid && Position <= 0)
{
var volume = Volume + Math.Abs(Position);
BuyMarket(volume);
_cooldown = 6;
}
else if (_prevClose >= _prevMid && close < mid && Position >= 0)
{
var volume = Volume + Math.Abs(Position);
SellMarket(volume);
_cooldown = 6;
}
_prevClose = close; _prevMid = mid;
}
}