A estratégia Hpcs Inter7 é um sistema de breakout de bandas Bollinger convertido do MetaTrader 4 consultor especialista _HPCS_Inter7_MT4_EA_V01_We.mq4. O algoritmo monitora bandas Bollinger padrão calculadas na série de velas selecionada. Quando o preço ultrapassa as bandas, ele interpreta isso como um rompimento de impulso e abre uma posição na direção do rompimento. Para cada nova entrada, a estratégia coloca imediatamente as metas de stop loss e takeprofit a uma distância fixa do preço de entrada para replicar o comportamento original do consultor especialista.
Lógica de negociação
Entrada curta: Quando a vela anterior fechou acima da banda inferior e a última vela fechada terminou abaixo da banda inferior, a estratégia abre uma venda no mercado. Isso recria a condição original Close[0] < LowerBand[0] && Close[1] > LowerBand[1].
Entrada longa: Quando a vela anterior fechou abaixo da banda superior e a última vela fechada terminou acima da banda superior, a estratégia abre uma compra no mercado. Isso replica Close[0] > UpperBand[0] && Close[1] < UpperBand[1] da implementação MQL.
Negociação única por vela: O algoritmo lembra o horário de abertura da vela que gerou a última ordem. Um novo sinal na mesma vela é ignorado para evitar negociações duplicadas, espelhando a variável de guarda gdt_Candle de MQL4.
Ordens de proteção: Imediatamente após a abertura de uma nova posição, a estratégia chama SetStopLoss e SetTakeProfit usando a distância configurada. Ambos são colocados simetricamente em torno do preço de entrada para que a posição tenha sempre metas de risco e recompensa predefinidas.
Parâmetros
Nome
Descrição
Padrão
Otimizável
BollingerLength
Número de velas usadas para construir as bandas Bollinger.
20
Sim
BollingerDeviation
Multiplicador de desvio padrão para a largura das bandas Bollinger.
2
Sim
CandleType
Série de velas usada para cálculos (o padrão é o período de 1 minuto).
Velas de 1 minuto
Não
ProtectionDistancePoints
Distância Stop Loss e Take Profit expressa em etapas de preço.
10
Sim
Notas adicionais
A estratégia usa o StockSharp API de alto nível (SubscribeCandles().Bind(...)) e não armazena matrizes de histórico personalizadas.
StartProtection() é ativado no início para que a plataforma gerencie automaticamente as ordens de proteção feitas por SetStopLoss e SetTakeProfit.
O tamanho da posição é controlado pela propriedade base Strategy.Volume, assim como o consultor especialista original que negociou um volume fixo de um lote.
A estratégia foi projetada para instrumentos FX onde o EA original foi implantado, mas pode ser usada em qualquer segurança que forneça sinais de banda Bollinger significativos e um valor PriceStep válido.
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Strategy converted from _HPCS_Inter7_MT4_EA_V01_We.mq4.
/// Sells when price crosses below the lower Bollinger band and buys when price crosses above the upper band.
/// </summary>
public class HpcsInter7Strategy : Strategy
{
private readonly StrategyParam<int> _bollingerLength;
private readonly StrategyParam<decimal> _bollingerDeviation;
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<decimal> _bandPercent;
private decimal? _prevClose;
private decimal? _prevLower;
private decimal? _prevUpper;
/// <summary>
/// Initializes a new instance of the <see cref="HpcsInter7Strategy"/> class.
/// </summary>
public HpcsInter7Strategy()
{
_bollingerLength = Param(nameof(BollingerLength), 20)
.SetGreaterThanZero()
.SetDisplay("Bollinger Length", "Number of candles included in the Bollinger Bands calculation", "Indicators");
_bollingerDeviation = Param(nameof(BollingerDeviation), 2m)
.SetGreaterThanZero()
.SetDisplay("Bollinger Deviation", "Standard deviation multiplier for the Bollinger Bands", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
.SetDisplay("Candle Type", "Time frame used for Bollinger Bands", "General");
_bandPercent = Param(nameof(BandPercent), 0.01m)
.SetGreaterThanZero()
.SetDisplay("Band Percent", "MA percentage band width", "Indicators");
}
/// <summary>
/// Bollinger Bands length.
/// </summary>
public int BollingerLength
{
get => _bollingerLength.Value;
set => _bollingerLength.Value = value;
}
/// <summary>
/// Bollinger Bands deviation multiplier.
/// </summary>
public decimal BollingerDeviation
{
get => _bollingerDeviation.Value;
set => _bollingerDeviation.Value = value;
}
/// <summary>
/// Candle type used for calculations.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public decimal BandPercent
{
get => _bandPercent.Value;
set => _bandPercent.Value = value;
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevClose = null;
_prevLower = null;
_prevUpper = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevClose = null;
_prevLower = null;
_prevUpper = null;
var bollinger = new ExponentialMovingAverage { Length = BollingerLength };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(bollinger, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, bollinger);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal middle)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var upper = middle * (1 + BandPercent);
var lower = middle * (1 - BandPercent);
if (_prevClose.HasValue && _prevLower.HasValue && _prevUpper.HasValue)
{
// Downward cross through the lower band - open short
if (_prevClose.Value > _prevLower.Value && candle.ClosePrice < lower && Position >= 0)
{
SellMarket();
}
// Upward cross through the upper band - open long
else if (_prevClose.Value < _prevUpper.Value && candle.ClosePrice > upper && Position <= 0)
{
BuyMarket();
}
}
_prevClose = candle.ClosePrice;
_prevLower = lower;
_prevUpper = upper;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class hpcs_inter7_strategy(Strategy):
def __init__(self):
super(hpcs_inter7_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(60)))
self._bollinger_length = self.Param("BollingerLength", 20)
self._band_percent = self.Param("BandPercent", 0.01)
self._prev_close = 0.0
self._prev_lower = 0.0
self._prev_upper = 0.0
self._has_prev = False
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def BollingerLength(self):
return self._bollinger_length.Value
@BollingerLength.setter
def BollingerLength(self, value):
self._bollinger_length.Value = value
@property
def BandPercent(self):
return self._band_percent.Value
@BandPercent.setter
def BandPercent(self, value):
self._band_percent.Value = value
def OnReseted(self):
super(hpcs_inter7_strategy, self).OnReseted()
self._prev_close = 0.0
self._prev_lower = 0.0
self._prev_upper = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(hpcs_inter7_strategy, self).OnStarted2(time)
self._prev_close = 0.0
self._prev_lower = 0.0
self._prev_upper = 0.0
self._has_prev = False
ema = ExponentialMovingAverage()
ema.Length = self.BollingerLength
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(ema, self._process_candle).Start()
def _process_candle(self, candle, middle_value):
if candle.State != CandleStates.Finished:
return
middle = float(middle_value)
band_pct = float(self.BandPercent)
upper = middle * (1.0 + band_pct)
lower = middle * (1.0 - band_pct)
close = float(candle.ClosePrice)
if self._has_prev:
# Downward cross through lower band - short
if self._prev_close > self._prev_lower and close < lower and self.Position >= 0:
self.SellMarket()
# Upward cross through upper band - long
elif self._prev_close < self._prev_upper and close > upper and self.Position <= 0:
self.BuyMarket()
self._prev_close = close
self._prev_lower = lower
self._prev_upper = upper
self._has_prev = True
def CreateClone(self):
return hpcs_inter7_strategy()