Estratégia de ponto de equilíbrio True Scalper Profit Lock
Visão geral
A estratégia True Scalper Profit Lock é uma conversão do consultor especialista MetaTrader 4 TrueScalperProfitLock.mq4. Ele combina um cruzamento de média móvel exponencial de curto prazo com filtros de polaridade baseados em RSI para entradas de tempo. A estratégia foi projetada para ambientes de scalping de alta frequência, onde as posições são gerenciadas ativamente usando um stop de proteção, um nível fixo de take-profit e um bloqueio de equilíbrio opcional.
Lógica de negociação
Filtro de tendência: Um EMA de 3 períodos calculado na vela fechada anterior deve ser negociado acima (para compras) ou abaixo (para vendas) de um EMA de 7 períodos da mesma barra. A distância entre as médias deve exceder uma etapa de preço para evitar condições de mercado planas.
RSI confirmação: O EA original oferece dois modos de validação. O método A espera que o período de 2 RSI cruze o limite configurado entre as duas velas fechadas mais recentes. O método B simplesmente verifica se o RSI de duas velas atrás está acima ou abaixo do limite. Ambos os modos podem ser usados de forma independente ou em conjunto, com o Método B habilitado por padrão.
Direção da ordem: As negociações longas exigem que o EMA rápido esteja acima do EMA lento, enquanto o RSI indica condições de sobrevenda (RSI < threshold). As negociações curtas refletem a lógica e esperam leituras de sobrecompra.
Gerenciamento de posição
Proteção inicial: Na entrada, a estratégia calcula um stop-loss e um take-profit de distância fixa usando a etapa de preço do título. Ambos os parâmetros seguem os valores padrão da versão MetaTrader (90 e 44 pontos respectivamente).
Bloqueio de lucro: Quando ativado, o stop loss é movido para o ponto de equilíbrio mais uma compensação configurável quando o preço avança na distância BreakEvenTriggerPoints. Isso reflete o comportamento "ProfitLock" do EA original.
Temporizadores de abandono: Dois mecanismos opcionais fecham negociações após um número predefinido de velas concluídas (AbandonBars). O Método A inverte a posição imediatamente definindo um sinalizador de entrada oposto, enquanto o Método B apenas fecha e aguarda por novos sinais do indicador.
Gerenciamento de dinheiro: A fórmula de dimensionamento do lote corresponde ao script original: o tamanho da posição é derivado do saldo do portfólio, porcentagem de risco, tipo de conta (mini vs. padrão) e limites de negociação ao vivo. Definir UseMoneyManagement como false reverte para o parâmetro de volume fixo.
Parâmetros
Parâmetro
Descrição
CandleType
Prazo das velas processadas.
FixedVolume
Volume base do pedido quando o gerenciamento de dinheiro está desativado.
TakeProfitPoints / StopLossPoints
Meta de lucro e stop protetor nas etapas de preço.
UseRsiMethodA / UseRsiMethodB
Ative os métodos de confirmação RSI correspondentes a EA.
RsiThreshold
Nível RSI usado por ambos os modos de confirmação.
AbandonMethodA / AbandonMethodB
Habilite as variantes lógicas de abandono.
AbandonBars
Número de velas concluídas antes que a lógica de abandono seja acionada.
Número máximo de negociações simultâneas (o comportamento padrão é uma posição aberta).
Notas de uso
A estratégia avalia apenas velas concluídas para permanecer consistente com o especialista MetaTrader, que depende de lookbacks de barra shift.
Ative ou desative os métodos RSI para reproduzir a configuração exata usada no modelo original.
A lógica de ponto de equilíbrio e abandono depende dos máximos/mínimos das velas para detectar quedas de preços. Ao executar em prazos mais altos, considere o potencial de ultrapassagens intra-barras.
A gestão de dinheiro requer uma conexão de portfólio que forneça o BeginValue. Se não estiver disponível, a estratégia volta ao volume fixo.
Arquivos
CS/TrueScalperProfitLockBreakEvenStrategy.cs – Implementação da estratégia em C#.
README_zh.md – documentação chinesa.
README_ru.md – Documentação russa.
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// True Scalper strategy - RSI overbought/oversold reversal.
/// Buys when RSI drops below oversold level.
/// Sells when RSI rises above overbought level.
/// </summary>
public class TrueScalperProfitLockBreakEvenStrategy : Strategy
{
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<decimal> _overbought;
private readonly StrategyParam<decimal> _oversold;
private readonly StrategyParam<int> _cooldownCandles;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevRsi;
private bool _hasPrev;
private int _cooldownRemaining;
public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
public decimal Overbought { get => _overbought.Value; set => _overbought.Value = value; }
public decimal Oversold { get => _oversold.Value; set => _oversold.Value = value; }
public int CooldownCandles { get => _cooldownCandles.Value; set => _cooldownCandles.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public TrueScalperProfitLockBreakEvenStrategy()
{
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetDisplay("RSI Period", "RSI lookback", "Indicators");
_overbought = Param(nameof(Overbought), 75m)
.SetDisplay("Overbought", "RSI overbought", "Levels");
_oversold = Param(nameof(Oversold), 25m)
.SetDisplay("Oversold", "RSI oversold", "Levels");
_cooldownCandles = Param(nameof(CooldownCandles), 10)
.SetDisplay("Cooldown", "Candles to wait between signals", "General");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevRsi = default;
_hasPrev = default;
_cooldownRemaining = default;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevRsi = 0;
_hasPrev = false;
_cooldownRemaining = 0;
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(rsi, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal rsi)
{
if (candle.State != CandleStates.Finished) return;
if (!_hasPrev) { _prevRsi = rsi; _hasPrev = true; return; }
if (_cooldownRemaining > 0)
{
_cooldownRemaining--;
_prevRsi = rsi;
return;
}
var oversold = Oversold;
var overbought = Overbought;
if (_prevRsi >= oversold && rsi < oversold && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
_cooldownRemaining = CooldownCandles;
}
else if (_prevRsi <= overbought && rsi > overbought && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
_cooldownRemaining = CooldownCandles;
}
_prevRsi = rsi;
}
}