Ver no GitHub

Estratégia de Médias Móveis VR BUCH

Visão Geral

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

  1. 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.
  2. 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.
  3. 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

  1. Coloque a estratégia em um contêiner de estratégia StockSharp ou executor de amostras.
  2. Configure o instrumento desejado, o período (Candle Type) e o volume da ordem.
  3. Ajuste as configurações da média móvel para corresponder ao template original do MetaTrader se necessário.
  4. 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;
	}
}