MetaTrader 4 consultor especialista GLFX reescrito para StockSharp de alto nível API. A porta preserva a ideia original de combinar confirmações de prazos mais elevados com portões rígidos de gestão de dinheiro, ao mesmo tempo que remove a enorme coleção de filtros raramente usados que dependiam de indicadores externos.
Lógica de negociação
A estratégia funciona em um período primário (padrão M15) e, opcionalmente, cria um período de confirmação subindo a escada clássica MetaTrader (M15 → M30 → H1 → H4 → D1 → W1 → MN).
Um período de tempo maior RSI (período padrão 57) rastreia se o momentum está aumentando ou diminuindo. Uma confirmação de compra aparece quando RSI sobe, mas permanece abaixo do teto de sobrecompra configurado. Uma confirmação de venda exige que RSI diminua enquanto permanece acima do piso de sobrevenda.
Uma média móvel simples de período de tempo mais alto (período padrão 60) detecta se o preço está se afastando da média. Uma confirmação de alta precisa que o MA suba enquanto permanece acima do fechamento atual (preço voltando para uma tendência de alta). Uma confirmação de baixa reflete essa lógica.
Cada filtro ativado contribui com +1 para sentimento de alta ou -1 para sentimento de baixa. O total deve atingir o número de filtros ativos para contar como um sinal válido. Os contadores lembram quantos sinais consecutivos de força total apareceram (SignalsRepeat). Se a força combinada cair abaixo do limite e SignalsReset estiver ativado, os contadores serão reiniciados.
Quando a estratégia é plana e as opções de entrada longa/curta permitem isso, o próximo contador concluído aciona uma ordem de mercado com o Volume configurado. Os níveis estáticos de stop-loss e take-profit são convertidos de pips em compensações de preço usando o tamanho do tick do instrumento.
Se uma posição já estiver aberta, fortes sinais opostos podem fechá-la antecipadamente (AllowLongExit / AllowShortExit). Caso contrário, as saídas dependem da parada ou destino gerenciado por StartProtection().
A porta não reproduz o Quantum opcional do EA original, sentimento do Twitter, correlação de barra aberta, teste de conjunto ou escadas avançadas de gerenciamento de dinheiro. Esses módulos exigiam indicadores personalizados adicionais ou estado do corretor que não existem em StockSharp.
Parâmetros
Parâmetro
Padrão
Descrição
CandleType
M15
Prazo de trabalho para avaliação de preços.
HigherTimeFrameShift
1
Número de etapas MT4 usadas para construir o prazo de confirmação. 0 mantém o prazo atual.
UseRsiSignal
verdade
Ative a confirmação de prazo superior RSI.
RsiPeriod
57
Período da confirmação RSI.
RsiUpperThreshold
65
Desative novos longos quando RSI exceder esse valor.
RsiLowerThreshold
25
Desative novos shorts quando RSI ficar abaixo desse valor.
UseMaSignal
verdade
Habilite a confirmação da média móvel em prazos mais altos.
MaPeriod
60
Período da média móvel de confirmação.
SignalsRepeat
1
Número de sinais consecutivos de força total necessários antes de abrir uma negociação.
SignalsReset
verdade
Redefina os contadores quando o sinal combinado perder impulso.
TakeProfitPips
308
Distância de lucro expressa em pips. Defina como 0 para desativar.
StopLossPips
290
Distância de stop-loss expressa em pips. Defina como 0 para desativar.
Volume
0,1
Tamanho do pedido utilizado para novas posições (lotes).
AllowLongEntry / AllowShortEntry
verdade
Chaves de permissão para abertura de negociações longas ou curtas.
AllowLongExit / AllowShortExit
verdade
Permitir o fechamento automático da exposição existente em sinais opostos.
Notas de uso
Escolha instrumentos com um tamanho de tick confiável para que a conversão do pip permaneça precisa. Os pares Forex com três ou cinco casas decimais são mapeados automaticamente para MetaTrader "pontos" multiplicando a etapa de preço por dez.
Defina HigherTimeFrameShift como 0 se quiser executar tudo no mesmo período. Neste caso, os indicadores são alimentados pelo fluxo de velas primário para evitar assinaturas duplicadas.
Se você precisar do comportamento legado de manter as negociações abertas independentemente dos sinais opostos, desative o sinalizador Allow*Exit correspondente.
O escalonamento de gerenciamento de dinheiro (configurações MMC_*), módulos finais e filtros de saída exóticos do script original foram omitidos intencionalmente. Implemente-os sobre este núcleo limpo, se necessário.
TP/SL estático com grande biblioteca de módulos finais
TP/SL estático via StartProtection()
Gestão de dinheiro
Escala incremental de lote e escadas de perda
Parâmetro de volume fixo
Dependências externas
Indicadores personalizados (Quantum, TSI, carregamento de conjunto baseado em arquivo)
Nenhum
O resultado é uma estratégia compacta e sustentável que mantém o comportamento reconhecível do GLFX – aguardando a confirmação da tendência em um gráfico mais lento e entrando somente após acordo repetido – ao mesmo tempo que é fácil de estender usando a estrutura 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;
}
}