A Estratégia de Médias Móveis VR BUCH é um port direto do consultor especialista MetaTrader VR---BUCH. Ela negocia reversões de tendência usando duas médias móveis configuráveis e um filtro de preço de vela. A versão StockSharp mantém o fluxo de sinal original: a estratégia fecha as posições abertas quando um setup oposto aparece e só abre uma nova posição depois que a exposição anterior está completamente fechada.
A implementação depende das assinaturas de velas de alto nível do StockSharp, indicadores de média móvel nativos e auxiliares de ordens em tempo real. Todos os valores de indicadores são processados em velas terminadas e a estratégia evita buffers históricos manuais, exceto por um pequeno buffer circular que reproduz os parâmetros de deslocamento do MetaTrader.
Lógica de Negociação
Cálculo de indicadores
Uma média móvel rápida e uma lenta são calculadas no tipo de vela selecionado.
Cada média móvel pode usar uma fonte de preço e método de suavização diferentes (simples, exponencial, suavizado, ponderado).
Deslocamentos horizontais opcionais reproduzem o parâmetro ma_shift do MetaTrader referenciando valores de velas passadas.
Detecção de sinais
Um setup de compra ocorre quando a MA rápida deslocada está acima da MA lenta deslocada e o preço de confirmação selecionado está acima da MA rápida.
Um setup de venda ocorre quando a MA rápida deslocada está abaixo da MA lenta deslocada e o preço de confirmação está abaixo da MA rápida.
Gerenciamento de posição
Se uma posição já estiver aberta, um sinal oposto primeiro fecha o saldo plano. Novas entradas são avaliadas em sinais subsequentes apenas quando a posição líquida retorna a zero.
Quando não há posição, a estratégia envia uma ordem de mercado com o volume configurado na direção do sinal ativo.
Nenhum nível de stop-loss ou take-profit está incluído por padrão. Os usuários podem combinar a estratégia com blocos de proteção do StockSharp (StartProtection) ou gerenciadores de risco externos, se necessário.
Parâmetros
Parâmetro
Descrição
Fast Period
Comprimento da média móvel rápida.
Fast Shift
Número de velas usadas para deslocar o valor da MA rápida para o passado.
Fast Price
Componente de preço da vela usado para a MA rápida (fechamento, abertura, máximo, mínimo, mediano, típico, ponderado).
Fast Method
Método de suavização para a MA rápida (simples, exponencial, suavizado, ponderado).
Slow Period
Comprimento da média móvel lenta.
Slow Shift
Número de velas usadas para deslocar o valor da MA lenta.
Slow Price
Componente de preço da vela para a MA lenta.
Slow Method
Método de suavização para a MA lenta.
Signal Price
Preço da vela usado para confirmar a entrada (padrão é o fechamento).
Candle Type
Período ou tipo de vela personalizado usado para os cálculos.
Volume
Volume da ordem para novas negociações.
Notas de Uso
Sinais são avaliados apenas em velas terminadas para evitar ruído intra-barra.
A estratégia espera que o conector de negociação forneça dados históricos suficientes para aquecer ambas as médias móveis e seus buffers de deslocamento.
O preço ponderado usa a fórmula ((High + Low + 2 * Close) / 4), correspondendo à opção PRICE_WEIGHTED do MetaTrader.
O nome da classe e o namespace seguem as convenções do projeto StockSharp, permitindo compilação perfeita dentro da solução AlgoTrading.
Como Executar
Coloque a estratégia em um contêiner de estratégia StockSharp ou executor de amostras.
Configure o instrumento desejado, o período (Candle Type) e o volume da ordem.
Ajuste as configurações da média móvel para corresponder ao template original do MetaTrader se necessário.
Inicie a estratégia. Ela vai assinar velas, desenhar indicadores nos gráficos (se disponível) e colocar ordens de mercado com base na lógica descrita.
Para uso em portfólio ou com múltiplos símbolos, duplique a instância da estratégia por instrumento e atribua instrumentos dedicados.
using System;
using System.Collections.Generic;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// VR BUCH strategy. Uses Highest/Lowest channel breakout.
/// </summary>
public class VrBuchStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _period;
private decimal? _prevHigh;
private decimal? _prevLow;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int Period
{
get => _period.Value;
set => _period.Value = value;
}
public VrBuchStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Timeframe", "General");
_period = Param(nameof(Period), 14)
.SetGreaterThanZero()
.SetDisplay("Period", "Channel period", "Indicators");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevHigh = null;
_prevLow = null;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevHigh = null;
_prevLow = null;
var highest = new Highest { Length = Period };
var lowest = new Lowest { Length = Period };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(highest, lowest, ProcessCandle).Start();
var area = CreateChartArea();
if (area != null) { DrawCandles(area, subscription); DrawOwnTrades(area); }
}
private void ProcessCandle(ICandleMessage candle, decimal high, decimal low)
{
if (candle.State != CandleStates.Finished) return;
if (!IsFormedAndOnlineAndAllowTrading()) { _prevHigh = high; _prevLow = low; return; }
if (_prevHigh == null || _prevLow == null) { _prevHigh = high; _prevLow = low; return; }
var close = candle.ClosePrice;
if (close > _prevHigh.Value && Position <= 0) { if (Position < 0) BuyMarket(); BuyMarket(); }
else if (close < _prevLow.Value && Position >= 0) { if (Position > 0) SellMarket(); SellMarket(); }
_prevHigh = high; _prevLow = low;
}
}
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 Highest, Lowest
from StockSharp.Algo.Strategies import Strategy
class vr_buch_strategy(Strategy):
def __init__(self):
super(vr_buch_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Timeframe", "General")
self._period = self.Param("Period", 14) \
.SetDisplay("Period", "Channel period", "Indicators")
self._prev_high = None
self._prev_low = None
@property
def CandleType(self):
return self._candle_type.Value
@property
def Period(self):
return self._period.Value
def OnReseted(self):
super(vr_buch_strategy, self).OnReseted()
self._prev_high = None
self._prev_low = None
def OnStarted2(self, time):
super(vr_buch_strategy, self).OnStarted2(time)
self._prev_high = None
self._prev_low = None
highest = Highest()
highest.Length = self.Period
lowest = Lowest()
lowest.Length = self.Period
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(highest, lowest, self._on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def _on_process(self, candle, high_value, low_value):
if candle.State != CandleStates.Finished:
return
hv = float(high_value)
lv = float(low_value)
if self._prev_high is None or self._prev_low is None:
self._prev_high = hv
self._prev_low = lv
return
close = float(candle.ClosePrice)
if close > self._prev_high and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif close < self._prev_low and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_high = hv
self._prev_low = lv
def CreateClone(self):
return vr_buch_strategy()