Ver no GitHub

Estratégia criptográfica

Visão geral

A Cryptos Strategy é uma versão StockSharp de alto nível do consultor especialista MetaTrader4 original cryptos.mq4. Ele se concentra no par ETH/USD, combinando bandas Bollinger com uma média móvel ponderada linear (LWMA) para capturar rompimentos da compressão de volatilidade. A estratégia rastreia altos e baixos em um número configurável de velas e calcula dinamicamente as metas de lucro como um múltiplo do intervalo detectado.

Lógica de negociação

  1. Detecção de tendência – quando o preço de fechamento toca a banda superior Bollinger, a estratégia muda para uma tendência curta, e quando a banda inferior é tocada, ela muda para uma tendência longa. O toque da banda também congela os valores de swing atuais, desativando as atualizações automáticas de altos/baixos.
  2. Condições de entrada
    • Abra uma posição curta quando o preço de fechamento cair abaixo do LWMA, a tendência for curta e não houver posição curta ativa.
    • Abra uma posição longa quando o preço de fechamento subir acima do LWMA, o viés for longo e não houver posição longa ativa.
  3. Projeção de alcance – oscilações máximas e mínimas (automáticas ou congeladas manualmente) definem a distância do LWMA. Esta distância, expressa em ticks, é multiplicada pelo índice de take-profit para calcular as metas de lucro e o tamanho da posição com base no risco.
  4. Controle de risco – a estratégia define níveis de take-profit e stop-loss por negociação. Para posições compradas, o stop é colocado abaixo do swing low; para shorts, acima do balanço alto. Stops e metas são recalculados para cada entrada e aplicados dentro do ciclo estratégico.
  5. Saídas finais – se uma posição longa fechar abaixo da banda inferior Bollinger (ou uma posição curta acima da banda superior), a posição aberta será achatada imediatamente, imitando o comportamento final do EA original.

Parâmetros

Parâmetro Descrição
CandleType Tipo de dados da série de velas usada para todos os cálculos de indicadores.
BollingerPeriod, BollingerWidth Multiplicador de comprimento e desvio padrão das bandas Bollinger.
MaPeriod Período da média móvel ponderada linear com base nos preços medianos.
LookbackCandles Número de velas examinadas para determinar a oscilação automática de alta/baixa.
TakeProfitRatio Multiplicador de intervalo usado para metas de lucro ao negociar ETH/USD.
AlternativeTakeProfitRatio Multiplicador de alcance aplicado a todos os outros símbolos.
RiskPerTrade Quantidade de capital (na moeda de cotação) que a calculadora de volume tenta arriscar em cada negociação.
ValueIndex, CryptoValueIndex Multiplicadores convertendo risco em volume para símbolos não criptográficos e criptográficos, respectivamente.
MinVolume, MaxVolume Limites rígidos para o tamanho da posição após o alinhamento para trocar etapas de volume.
MinRangeTicks Faixa projetada mínima permitida em ticks para evitar paradas de distância zero.
SpreadPoints Substituição manual do spread em ticks (detectado automaticamente a partir do melhor lance/pergunta, se disponível).
GlobalTrend Substituição manual de polarização: 1 força uma configuração curta, 2 força uma configuração longa, 0 deixa a estratégia decidir.
AutoHighLow Quando habilitado, os pontos de oscilação são recalculados em cada vela; quando desativados, eles ficam congelados até o próximo toque na banda.
ManualBuyTrigger, ManualSellTrigger Defina como true para solicitar uma entrada longa ou curta imediata (redefinida após a execução).
SkipBuys, SkipSells Desative a abertura de novas posições longas ou curtas.

Dimensionamento de posições

A estratégia replica a lógica MT4: volume = RiskPerTrade / rangeTicks * valueIndex. O resultado é alinhado a VolumeStep e, em seguida, recortado entre MinVolume/MaxVolume e os limites impostos pela exchange do instrumento.

Notas de uso

  • A estratégia verifica o valor do portfólio no início. Se o saldo for inferior a RiskPerTrade * 3, a negociação será desativada e um aviso será registrado, correspondendo à verificação de segurança de EA.
  • Os gatilhos manuais e os controles de polarização possibilitam a sincronização com decisões discricionárias durante a negociação ao vivo.
  • ETH/USD usa automaticamente CryptoValueIndex e TakeProfitRatio; outros instrumentos recorrem aos parâmetros alternativos.
  • As paradas e os alvos são aplicados dentro do ciclo estratégico, portanto, nenhum módulo de proteção adicional é necessário.
using System;

using Ecng.Common;

using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Simplified from "Cryptos" MetaTrader expert.
/// Uses Bollinger Bands with a WMA trend filter. Buys when price is below WMA
/// and touches lower band; sells when price is above WMA and touches upper band.
/// </summary>
public class CryptosStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _wmaPeriod;
	private readonly StrategyParam<int> _bollingerPeriod;
	private readonly StrategyParam<decimal> _bollingerWidth;

	private ExponentialMovingAverage _bandEma;
	private ExponentialMovingAverage _trendEma;

	public DataType CandleType
	{
		get => _candleType.Value;
		set => _candleType.Value = value;
	}

	public int WmaPeriod
	{
		get => _wmaPeriod.Value;
		set => _wmaPeriod.Value = value;
	}

	public int BollingerPeriod
	{
		get => _bollingerPeriod.Value;
		set => _bollingerPeriod.Value = value;
	}

	public decimal BollingerWidth
	{
		get => _bollingerWidth.Value;
		set => _bollingerWidth.Value = value;
	}

	public CryptosStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe for signals", "General");

		_wmaPeriod = Param(nameof(WmaPeriod), 55)
			.SetGreaterThanZero()
			.SetDisplay("WMA Period", "Weighted moving average period", "Indicators");

		_bollingerPeriod = Param(nameof(BollingerPeriod), 20)
			.SetGreaterThanZero()
			.SetDisplay("BB Period", "Bollinger Bands period", "Indicators");

		_bollingerWidth = Param(nameof(BollingerWidth), 2m)
			.SetGreaterThanZero()
			.SetDisplay("BB Width", "Bollinger Bands deviation", "Indicators");
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		_bandEma = new ExponentialMovingAverage { Length = BollingerPeriod };
		_trendEma = new ExponentialMovingAverage { Length = WmaPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(_bandEma, _trendEma, ProcessCandle)
			.Start();

		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			DrawIndicator(area, _bandEma);
			DrawIndicator(area, _trendEma);
			DrawOwnTrades(area);
		}
	}

	private void ProcessCandle(ICandleMessage candle, decimal bandValue, decimal trendValue)
	{
		if (candle.State != CandleStates.Finished)
			return;

		if (!_bandEma.IsFormed || !_trendEma.IsFormed)
			return;

		var close = candle.ClosePrice;
		var bandOffset = bandValue * (BollingerWidth / 100m);
		var upperBand = bandValue + bandOffset;
		var lowerBand = bandValue - bandOffset;

		var volume = Volume;
		if (volume <= 0)
			volume = 1;

		// Buy: price below WMA, touches lower band
		if (close < trendValue && close <= lowerBand)
		{
			if (Position <= 0)
				BuyMarket(Position < 0 ? Math.Abs(Position) + volume : volume);
		}
		// Sell: price above WMA, touches upper band
		else if (close > trendValue && close >= upperBand)
		{
			if (Position >= 0)
				SellMarket(Position > 0 ? Math.Abs(Position) + volume : volume);
		}

		// Exit at WMA cross
		if (Position > 0 && close >= upperBand)
			SellMarket(Position);
		else if (Position < 0 && close <= lowerBand)
			BuyMarket(Math.Abs(Position));
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		_bandEma = null;
		_trendEma = null;

		base.OnReseted();
	}
}