MetaTrader 4 asesor experto GLFX reescrito para el alto nivel de StockSharp API. El puerto conserva la idea original de combinar confirmaciones con plazos más altos con controles estrictos de administración de dinero, al tiempo que elimina la colección masiva de filtros raramente utilizados que dependían de indicadores externos.
Lógica comercial
La estrategia funciona en un período de tiempo principal (predeterminado M15) y, opcionalmente, crea un período de tiempo de confirmación subiendo por la clásica escalera MetaTrader (M15 → M30 → H1 → H4 → D1 → W1 → MN).
Un período de tiempo más alto RSI (período predeterminado 57) rastrea si el impulso aumenta o disminuye. Aparece una confirmación de compra cuando RSI sube pero permanece por debajo del límite de sobrecompra configurado. Una confirmación de venta requiere que RSI baje mientras se mantiene por encima del piso de sobreventa.
Un promedio móvil simple de marco temporal más alto (período predeterminado 60) detecta si el precio se está alejando de la media. Una confirmación alcista necesita que el MA suba mientras se mantiene por encima del cierre actual (el precio regresa a una tendencia alcista). Una confirmación bajista refleja esta lógica.
Cada filtro habilitado contribuye +1 para el sentimiento alcista o -1 para el sentimiento bajista. El total debe alcanzar el número de filtros activos para contar como una señal válida. Los contadores recuerdan cuántas señales consecutivas de potencia completa aparecieron (SignalsRepeat). Si la fuerza combinada cae por debajo del umbral y SignalsReset está habilitado, los contadores se reinician.
Cuando la estrategia es plana y los interruptores de entrada larga/corta lo permiten, el siguiente contador completado activa una orden de mercado con el Volume configurado. Los niveles estáticos de stop-loss y take-profit se convierten de pips en compensaciones de precios utilizando el tamaño del tick del instrumento.
Si una posición ya está abierta, fuertes señales opuestas pueden cerrarla antes (AllowLongExit / AllowShortExit). De lo contrario, las salidas dependen de la parada o el destino administrado por StartProtection().
El puerto no reproduce el Quantum opcional, el sentimiento de Twitter, la correlación de barra abierta, las pruebas de conjuntos o las escaleras avanzadas de administración de dinero del EA original. Esos módulos requerían indicadores personalizados adicionales o estados de intermediario que no existen en StockSharp.
Parámetros
Parámetro
Predeterminado
Descripción
CandleType
M15
Plazo de trabajo para la evaluación de precios.
HigherTimeFrameShift
1
Número de pasos de MT4 utilizados para crear el plazo de confirmación. 0 mantiene el período de tiempo actual.
UseRsiSignal
cierto
Habilite la confirmación de plazo mayor RSI.
RsiPeriod
57
Periodo de la confirmación RSI.
RsiUpperThreshold
65
Deshabilite nuevos longs una vez que RSI supere este valor.
RsiLowerThreshold
25
Deshabilite nuevos cortos una vez que RSI caiga por debajo de este valor.
UseMaSignal
cierto
Habilite la confirmación de promedio móvil de períodos de tiempo más altos.
MaPeriod
60
Período de la media móvil de confirmación.
SignalsRepeat
1
Número de señales consecutivas de máxima potencia necesarias antes de abrir una operación.
SignalsReset
cierto
Reinicie los contadores cuando la señal combinada pierda impulso.
TakeProfitPips
308
Distancia de toma de ganancias expresada en pips. Establezca en 0 para desactivar.
StopLossPips
290
Distancia de stop-loss expresada en pips. Establezca en 0 para desactivar.
Volume
0.1
Tamaño de pedido utilizado para nuevas posiciones (lotes).
AllowLongEntry / AllowShortEntry
cierto
Cambios de permiso para abrir operaciones largas o cortas.
AllowLongExit / AllowShortExit
cierto
Permitir el cierre automático de la exposición existente en señales opuestas.
Notas de uso
Elija instrumentos con un tamaño de tick confiable para que la conversión de pips siga siendo precisa. Los pares de Forex con tres o cinco decimales se asignan automáticamente a MetaTrader "puntos" multiplicando el paso del precio por diez.
Establezca HigherTimeFrameShift en 0 si desea ejecutar todo en el mismo período de tiempo. En este caso, los indicadores se alimentan del flujo de velas principal para evitar suscripciones duplicadas.
Si necesita el comportamiento heredado de mantener las operaciones abiertas independientemente de las señales opuestas, desactive el indicador Allow*Exit correspondiente.
Se omitieron intencionalmente la escala de administración de dinero (configuraciones MMC_*), los módulos de seguimiento y los filtros de salida exóticos del script original. Implementarlos encima de este núcleo limpio si es necesario.
TP/SL estático con gran biblioteca de módulos finales
TP/SL estático vía StartProtection()
gestión del dinero
Escalamiento incremental de lotes y escalas de pérdidas
Parámetro de volumen fijo
Dependencias externas
Indicadores personalizados (Quantum, TSI, carga de conjuntos basada en archivos)
Ninguno
El resultado es una estrategia compacta y fácil de mantener que mantiene el comportamiento reconocible de GLFX (esperando la confirmación de la tendencia en un gráfico más lento y entrando solo después de un acuerdo repetido) y al mismo tiempo es fácil de ampliar utilizando el marco StockSharp.
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// GLFX strategy: RSI + SMA confirmation for entry.
/// Requires consecutive confirmations before trading.
/// </summary>
public class GlfxStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<decimal> _rsiUpper;
private readonly StrategyParam<decimal> _rsiLower;
private readonly StrategyParam<int> _maPeriod;
private readonly StrategyParam<int> _signalsRepeat;
private decimal _prevRsi;
private decimal _prevMa;
private int _buyCount;
private int _sellCount;
private decimal _entryPrice;
public GlfxStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
.SetDisplay("Candle Type", "Timeframe.", "General");
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetDisplay("RSI Period", "RSI period.", "Indicators");
_rsiUpper = Param(nameof(RsiUpper), 65m)
.SetDisplay("RSI Upper", "Overbought level.", "Indicators");
_rsiLower = Param(nameof(RsiLower), 35m)
.SetDisplay("RSI Lower", "Oversold level.", "Indicators");
_maPeriod = Param(nameof(MaPeriod), 60)
.SetDisplay("MA Period", "SMA period.", "Indicators");
_signalsRepeat = Param(nameof(SignalsRepeat), 2)
.SetDisplay("Signals Repeat", "Consecutive confirmations needed.", "Signals");
}
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int RsiPeriod
{
get => _rsiPeriod.Value;
set => _rsiPeriod.Value = value;
}
public decimal RsiUpper
{
get => _rsiUpper.Value;
set => _rsiUpper.Value = value;
}
public decimal RsiLower
{
get => _rsiLower.Value;
set => _rsiLower.Value = value;
}
public int MaPeriod
{
get => _maPeriod.Value;
set => _maPeriod.Value = value;
}
public int SignalsRepeat
{
get => _signalsRepeat.Value;
set => _signalsRepeat.Value = value;
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevRsi = 0;
_prevMa = 0;
_buyCount = 0;
_sellCount = 0;
_entryPrice = 0;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var ma = new SimpleMovingAverage { Length = MaPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(rsi, ma, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, ma);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal rsiVal, decimal maVal)
{
if (candle.State != CandleStates.Finished)
return;
if (_prevRsi == 0 || _prevMa == 0)
{
_prevRsi = rsiVal;
_prevMa = maVal;
return;
}
var close = candle.ClosePrice;
// RSI signal: rising and below upper = bullish, falling and above lower = bearish
var rsiSignal = 0;
if (rsiVal > _prevRsi && rsiVal < RsiUpper)
rsiSignal = 1;
else if (rsiVal < _prevRsi && rsiVal > RsiLower)
rsiSignal = -1;
// MA signal: price above rising MA = bullish, below falling MA = bearish
var maSignal = 0;
if (maVal > _prevMa && close > maVal)
maSignal = 1;
else if (maVal < _prevMa && close < maVal)
maSignal = -1;
// Both signals must agree
if (rsiSignal > 0 && maSignal > 0)
{
_buyCount++;
_sellCount = 0;
}
else if (rsiSignal < 0 && maSignal < 0)
{
_sellCount++;
_buyCount = 0;
}
else
{
_buyCount = 0;
_sellCount = 0;
}
// Exit on opposite signal
if (Position > 0 && _sellCount >= SignalsRepeat)
{
SellMarket();
_entryPrice = 0;
_buyCount = 0;
_sellCount = 0;
}
else if (Position < 0 && _buyCount >= SignalsRepeat)
{
BuyMarket();
_entryPrice = 0;
_buyCount = 0;
_sellCount = 0;
}
// Entry after required confirmations
if (Position == 0)
{
if (_buyCount >= SignalsRepeat)
{
_entryPrice = close;
BuyMarket();
_buyCount = 0;
_sellCount = 0;
}
else if (_sellCount >= SignalsRepeat)
{
_entryPrice = close;
SellMarket();
_buyCount = 0;
_sellCount = 0;
}
}
_prevRsi = rsiVal;
_prevMa = maVal;
}
}