Esta estratégia é uma versão StockSharp do MetaTrader 4 consultor especialista "PROphet". O EA original avalia a negociação recente
percorre quatro velas históricas e usa essas faixas ponderadas para acionar novas negociações. Mantém posições abertas apenas entre os
nas sessões europeia e norte-americana e segue o stop loss sempre que o preço se move uma distância fixa a favor da negociação. O StockSharp
a implementação mantém toda essa mecânica enquanto os adapta ao modelo de compensação usado pelos portfólios StockSharp.
Lógica de negociação
Assine o prazo configurado (CandleType, padrão M5) e processe apenas velas concluídas.
Mantenha as três velas concluídas mais recentemente para reproduzir a indexação High[i] e Low[i] usada pela versão MQL.
Calcule o gatilho longo Qu(X1, X2, X3, X4) e o gatilho curto Qu(Y1, Y2, Y3, Y4) em cada barra. Cada termo multiplica um
intervalo ponderado (por exemplo |High[1] - Low[2]|) pelo peso correspondente menos cem, exatamente como no código original.
Permitir novas entradas somente quando a hora atual estiver entre TradeStartHour e TradeEndHour (inclusive). Isso imita o homem
janela de negociação normal do especialista MQL (das 10h00 às 18h00 por padrão).
Utilize uma única ordem de mercado cujo volume neutralize qualquer exposição oposta antes de abrir a nova posição. Isso reflete o Mag
ic Filtros de número da implementação MetaTrader.
Gerenciamento de risco e rastreamento
A estratégia converte as distâncias de parada baseadas em pontos MetaTrader em unidades de preço por meio do instrumento PriceStep. Os padrões (B uyStopLossPoints = 68, SellStopLossPoints = 72) corresponde às variáveis externas MQL.
Assim que o lance (para negociações longas) ou o pedido (para negociações curtas) ultrapassar o stop existente em spread + 2 * stopDistance, o
O trailing stop é avançado para currentPrice ± stopDistance, usando dados de nível 1 ao vivo, quando disponíveis.
As negociações abertas são fechadas à força após ExitHour. O valor padrão (18) reproduz o comportamento original de fechamento da posição
s depois das 18:00, horário do servidor.
As saídas protetoras usam ordens de mercado porque o API de alto nível de StockSharp não gera ordens de stop automaticamente. Isso mantém
comportamento determinístico entre corretores.
Parâmetros
Parâmetro
Descrição
AllowBuy
Permite negociações longas.
AllowSell
Permite negociações curtas.
X1, X2, X3, X4
Pesos aplicados aos componentes do intervalo do lado longo dentro da fórmula Qu.
BuyStopLossPoints
Distância de stop-loss para negociações longas expressa em MetaTrader pontos.
Y1, Y2, Y3, Y4
Pesos aplicados aos componentes do intervalo menor dentro da fórmula Qu.
SellStopLossPoints
Distância de stop-loss para negociações curtas expressa em MetaTrader pontos.
TradeVolume
Volume base (lotes) utilizado para novas entradas. O volume extra é adicionado automaticamente para fechar a exposição oposta.
TradeStartHour
Primeira hora da janela de negociação (inclusive).
TradeEndHour
Última hora da janela de negociação (inclusive).
ExitHour
Hora após a qual todas as negociações abertas são fechadas.
CandleType
Prazo das velas utilizadas para análise.
Notas
StockSharp carteiras são compensadas por padrão. Quando um novo sinal aparece, a estratégia adiciona o volume necessário para nivelar o ex
posição atual antes de abrir a nova negociação, que reproduz o design de posição única por direção da experiência MetaTrader
Rt.
O script MQL usou a propagação de símbolos relatada por MarketInfo. A porta recupera o spread dos dados de nível 1 quando disponível
e, caso contrário, volta a uma única etapa de preço.
Como o trailing stop é avaliado no fechamento de cada vela finalizada, pode ocorrer derrapagem em comparação com o stop no nível do tick
atualizações realizadas pelo EA original.
using System;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Translation of the MetaTrader "PROphet" expert advisor.
/// Uses a range-weighted signal from previous candles to enter trades.
/// </summary>
public class ProphetStrategy : Strategy
{
private readonly StrategyParam<int> _x1;
private readonly StrategyParam<int> _x2;
private readonly StrategyParam<int> _x3;
private readonly StrategyParam<int> _x4;
private readonly StrategyParam<DataType> _candleType;
private ICandleMessage _candle1;
private ICandleMessage _candle2;
private ICandleMessage _candle3;
private decimal _entryPrice;
public ProphetStrategy()
{
_x1 = Param(nameof(X1), 9)
.SetDisplay("X1", "Weight applied to |High[1] - Low[2]|.", "Signal");
_x2 = Param(nameof(X2), 29)
.SetDisplay("X2", "Weight applied to |High[3] - Low[2]|.", "Signal");
_x3 = Param(nameof(X3), 94)
.SetDisplay("X3", "Weight applied to |High[2] - Low[1]|.", "Signal");
_x4 = Param(nameof(X4), 125)
.SetDisplay("X4", "Weight applied to |High[2] - Low[3]|.", "Signal");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
.SetDisplay("Candle Type", "Timeframe for calculations.", "General");
}
public int X1 { get => _x1.Value; set => _x1.Value = value; }
public int X2 { get => _x2.Value; set => _x2.Value = value; }
public int X3 { get => _x3.Value; set => _x3.Value = value; }
public int X4 { get => _x4.Value; set => _x4.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_candle1 = null;
_candle2 = null;
_candle3 = null;
_entryPrice = 0;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished)
return;
// Shift history
_candle3 = _candle2;
_candle2 = _candle1;
_candle1 = candle;
if (_candle1 == null || _candle2 == null || _candle3 == null)
return;
// Manage position - simple exit on reversal signal
if (Position > 0)
{
var sellSignal = CalculateSignal(true);
if (sellSignal > 0)
{
SellMarket();
_entryPrice = 0;
}
}
else if (Position < 0)
{
var buySignal = CalculateSignal(false);
if (buySignal > 0)
{
BuyMarket();
_entryPrice = 0;
}
}
// Entry
if (Position == 0)
{
var buySignal = CalculateSignal(false);
var sellSignal = CalculateSignal(true);
if (buySignal > 0 && buySignal > sellSignal)
{
BuyMarket();
_entryPrice = candle.ClosePrice;
}
else if (sellSignal > 0 && sellSignal > buySignal)
{
SellMarket();
_entryPrice = candle.ClosePrice;
}
}
}
private decimal CalculateSignal(bool isSell)
{
var term1 = Math.Abs(_candle1.HighPrice - _candle2.LowPrice);
var term2 = Math.Abs(_candle3.HighPrice - _candle2.LowPrice);
var term3 = Math.Abs(_candle2.HighPrice - _candle1.LowPrice);
var term4 = Math.Abs(_candle2.HighPrice - _candle3.LowPrice);
if (isSell)
{
// For sell, use inverted weights
return (100 - X1) * term1 + (100 - X2) * term2 + (X3 - 100) * term3 + (X4 - 100) * term4;
}
// For buy, use standard weights
return (X1 - 100) * term1 + (X2 - 100) * term2 + (100 - X3) * term3 + (100 - X4) * term4;
}
}