Ver no GitHub

Estratégia ComFracti

Visão geral

ComFracti é uma estratégia direcional traduzida do consultor especialista MT4 "ComFracti". A lógica combina confirmação fractal de vários períodos de tempo com RSI e filtros estocásticos, enquanto filtros opcionais de média móvel, parabólico SAR, canal e perceptron controlam o alinhamento de tendência. A implementação C# negocia uma única posição por vez e avalia sinais em velas concluídas usando StockSharp APIs de alto nível.

Lógica de negociação

  • Sinal primário
    • Confirma uma configuração de alta quando o período atual e o período superior produzem um sinal fractal de alta.
    • Confirma uma configuração de baixa quando ambos os intervalos de tempo produzem um sinal fractal de baixa.
    • RSI (3 períodos padrão no período mais alto) deve ficar abaixo de 50 - RsiLevelBuy para posições longas ou acima de 50 + RsiLevelSell para posições curtas quando o filtro RSI estiver ativado.
    • O oscilador estocástico (período %K 5 padrão com suavização %D 3/3) deve estar abaixo de 50 - StochasticLevelBuy para posições compradas ou acima de 50 + StochasticLevelSell para posições vendidas quando o filtro estocástico estiver ativado.
  • Filtros opcionais
    • EMA inclinação: o EMA no período de tempo do filtro deve estar subindo para posições compradas e caindo para posições vendidas.
    • Parabolic SAR: o valor SAR deve ficar abaixo da barra aberta para posições compradas ou acima para posições vendidas.
    • Quebra de canal: compara a barra anterior com um canal adaptativo no estilo Donchian; Os mínimos anteriores devem permanecer acima do piso do canal para posições compradas, enquanto os máximos anteriores devem permanecer abaixo do teto para posições vendidas.
    • Perceptron: uma soma ponderada das diferenças recentes entre máximos e mínimos deve ser positiva para posições compradas e negativa para posições vendidas.
  • Gerenciamento de posição
    • Apenas uma posição está ativa por vez; a estratégia fecha a exposição existente antes de abrir uma nova negociação na direção oposta.
    • As distâncias fixas de stop-loss e take-profit são expressas em pontos de instrumento.
    • Um trailing stop opcional se move na direção do lucro quando o buffer móvel é atingido (quando ProfitTrailing é verdadeiro).
    • Quando CloseOnOppositeSignal está ativado, a estratégia sai mais cedo se o sinal primário oposto aparecer.

Gestão de risco

  • O tamanho da posição base é igual ao parâmetro BaseVolume (padrão 0,1 lote). Quando AccountMicro está ativado, o volume é dividido por dez.
  • Se UseMoneyManagement estiver ativado, a estratégia arrisca RiskPercent do valor da conta por negociação, usando a distância de stop-loss configurada e o valor do passo do instrumento para aproximar o tamanho da posição. O volume calculado é limitado por MinimumVolume.

Parâmetros

Nome Descrição
TakeProfitPoints, StopLossPoints Distâncias de take-profit e stop-loss em pontos de instrumento.
UseTrailingStop, TrailingStopPoints, ProfitTrailing Controles de trailing stop (distância e se o trailing requer lucro aberto).
BaseVolume, UseMoneyManagement, RiskPercent, AccountMicro, MinimumVolume Configuração de dimensionamento de posição.
UseFractals, FractalShift* Ativa a confirmação fractal e define os deslocamentos da barra para inspecionar nos prazos atuais e superiores.
UseRsi, RsiLevelBuy, RsiLevelSell, RsiType RSI filtros de compensação e prazo.
UseStochastic, StochasticPeriod*, StochasticLevel* Stochastic períodos e limites do oscilador.
UseMaFilter, MaPeriod EMA configuração de filtro no período de filtro.
UsePsarFilter, PsarStep Parabolic SAR configuração de filtro.
UseChannelFilter, ChannelLookback, ChannelK Parâmetros de filtro de ruptura de canal.
UsePerceptronFilter, PerceptronV1PerceptronV4 Pesos do filtro Perceptron (0–100, centrado em 50).
CandleType, HigherFractalType, FilterType Prazos de dados usados pela estratégia.

Notas

  • A estratégia processa apenas velas finalizadas, portanto o comportamento pode diferir ligeiramente do consultor especialista original orientado por ticks.
  • O rastreador fractal reproduz a lógica fractal de cinco barras do MT4 e permite ao usuário alterar qual barra histórica é avaliada, correspondendo aos parâmetros sh1/ sh2 do MT4.
  • A gestão de dinheiro depende da avaliação do portfólio disponível em StockSharp; quando nenhuma avaliação está disponível, a estratégia volta ao volume base fixo.
using System;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// ComFracti: Fractal detection with RSI confirmation and ATR stops.
/// </summary>
public class ComFractiStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _rsiLength;
	private readonly StrategyParam<int> _emaLength;
	private readonly StrategyParam<int> _atrLength;

	private decimal _entryPrice;
	private decimal _h1, _h2, _h3, _h4, _h5;
	private decimal _l1, _l2, _l3, _l4, _l5;
	private int _barCount;

	public ComFractiStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe.", "General");

		_rsiLength = Param(nameof(RsiLength), 14)
			.SetDisplay("RSI Length", "RSI period.", "Indicators");

		_emaLength = Param(nameof(EmaLength), 50)
			.SetDisplay("EMA Length", "Trend filter.", "Indicators");

		_atrLength = Param(nameof(AtrLength), 14)
			.SetDisplay("ATR Length", "ATR period.", "Indicators");
	}

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

	public int RsiLength
	{
		get => _rsiLength.Value;
		set => _rsiLength.Value = value;
	}

	public int EmaLength
	{
		get => _emaLength.Value;
		set => _emaLength.Value = value;
	}

	public int AtrLength
	{
		get => _atrLength.Value;
		set => _atrLength.Value = value;
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();

		_entryPrice = 0;
		_barCount = 0;
		_h1 = _h2 = _h3 = _h4 = _h5 = 0;
		_l1 = _l2 = _l3 = _l4 = _l5 = 0;
	}

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

		_entryPrice = 0;
		_barCount = 0;
		_h1 = _h2 = _h3 = _h4 = _h5 = 0;
		_l1 = _l2 = _l3 = _l4 = _l5 = 0;

		var rsi = new RelativeStrengthIndex { Length = RsiLength };
		var ema = new ExponentialMovingAverage { Length = EmaLength };
		var atr = new AverageTrueRange { Length = AtrLength };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(rsi, ema, atr, ProcessCandle)
			.Start();

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

	private void ProcessCandle(ICandleMessage candle, decimal rsiVal, decimal emaVal, decimal atrVal)
	{
		if (candle.State != CandleStates.Finished)
			return;

		_h5 = _h4; _h4 = _h3; _h3 = _h2; _h2 = _h1;
		_h1 = candle.HighPrice;
		_l5 = _l4; _l4 = _l3; _l3 = _l2; _l2 = _l1;
		_l1 = candle.LowPrice;
		_barCount++;

		if (_barCount < 5 || atrVal <= 0)
			return;

		var close = candle.ClosePrice;

		var fractalUp = _h3 > _h1 && _h3 > _h2 && _h3 > _h4 && _h3 > _h5;
		var fractalDown = _l3 < _l1 && _l3 < _l2 && _l3 < _l4 && _l3 < _l5;

		if (Position > 0)
		{
			if (close >= _entryPrice + atrVal * 3m || close <= _entryPrice - atrVal * 2m || (fractalUp && rsiVal > 65))
			{
				SellMarket();
				_entryPrice = 0;
			}
		}
		else if (Position < 0)
		{
			if (close <= _entryPrice - atrVal * 3m || close >= _entryPrice + atrVal * 2m || (fractalDown && rsiVal < 35))
			{
				BuyMarket();
				_entryPrice = 0;
			}
		}

		if (Position == 0)
		{
			if (fractalDown && rsiVal < 55)
			{
				_entryPrice = close;
				BuyMarket();
			}
			else if (fractalUp && rsiVal > 45)
			{
				_entryPrice = close;
				SellMarket();
			}
		}
	}
}