Ver no GitHub

Estratégia Swetten Strategy

Visão geral

Swetten é uma estratégia de breakout orientada por rede neural que foi originalmente distribuída para MetaTrader 4. Ela avalia o spread entre uma média móvel simples de longo prazo de 233 períodos e dez médias móveis mais rápidas calculadas em velas de um minuto. Os spreads são alimentados em uma rede de base radial que produz um nível de ativação de alta ou baixa. Quando a ativação é positiva a estratégia entra comprada, quando é negativa entra curta.

Mercado e Prazo

  • Projetado para os principais pares de FX (o código original era direcionado ao EURUSD).
  • A análise usa velas de um minuto e as decisões são tomadas apenas em velas concluídas.
  • Os sinais são avaliados a cada duas horas no início da hora (00:00, 02:00,…, 22:00 horário de troca). Não são abertas negociações aos sábados ou domingos.

Indicadores e recursos

  • Médias móveis simples com períodos: 233 (linha de base), 144, 89, 55, 34, 21, 13, 8, 5, 3, 2.
  • As entradas da rede neural são as diferenças entre a média de 233 períodos e cada média mais rápida.
  • Antes de passar para a rede, as entradas são fixadas em faixas treinadas, normalizadas e escalonadas com os mesmos coeficientes usados na DLL original.
  • A rede de base radial é replicada exatamente a partir da função EURUSDn exportada, consistindo em 38 recursos gaussianos cujas saídas são calculadas em média para obter a ativação final.

Regras de negociação

  1. Aguarde o fechamento de uma vela de um minuto que termina em uma hora par e cai em um dia da semana.
  2. Calcule a ativação da rede neural a partir dos spreads da média móvel.
  3. Se a ativação > 0 e a posição atual não for longa, envie uma compra de mercado para TradeVolume + abs(current position) lotes.
  4. Se ativação < 0 e a posição atual não for curta, envie uma venda no mercado para TradeVolume + abs(current position) lotes.
  5. As posições são protegidas por:
    • Um lucro fixo definido em etapas de preço (TakeProfitPoints).
    • Um stop loss fixo definido em etapas de preço (StopLossPoints).
    • Quando qualquer um dos níveis é tocado usando os extremos máximo/mínimo da vela, a posição é fechada por uma ordem de mercado.

Parâmetros

Nome Descrição Padrão
CandleType Série de velas usadas para cálculos. Período de 1 minuto
TradeVolume Volume base do pedido em lotes. 0,1
SlowPeriod Período da média móvel simples da linha de base. 233
TakeProfitPoints Distância alvo de lucro em etapas de preço. 150
StopLossPoints Distância de stop-loss em etapas de preço. 40

Notas de conversão

  • A rede neural baseada em DLL de MetaTrader foi totalmente portada para C# convertendo a função exportada em código gerenciado.
  • As saídas de proteção imitam as condições originais OrderClose, verificando os máximos e mínimos das velas em relação aos limites dos níveis de preço.
  • O gerenciamento de entradas acompanha o preço de preenchimento mais recente via OnNewMyTrade para alinhar as saídas com os preenchimentos reais.
  • Todos os comentários foram reescritos em inglês e o código usa APIs StockSharp de alto nível (SubscribeCandles, Bind) conforme exigido pelas diretrizes de conversão.
using System;

using Ecng.Common;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Swetten strategy: multi-SMA spread crossover system.
/// Uses fast SMA (5) and slow SMA (50) to generate trend signals.
/// Buys when fast crosses above slow, sells when fast crosses below slow.
/// </summary>
public class SwettenStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;

	private decimal _prevFast;
	private decimal _prevSlow;
	private bool _isReady;

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

	public int FastPeriod
	{
		get => _fastPeriod.Value;
		set => _fastPeriod.Value = value;
	}

	public int SlowPeriod
	{
		get => _slowPeriod.Value;
		set => _slowPeriod.Value = value;
	}

	public SwettenStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Candle type for strategy", "General");

		_fastPeriod = Param(nameof(FastPeriod), 8)
			.SetDisplay("Fast SMA", "Fast SMA period", "Indicators");

		_slowPeriod = Param(nameof(SlowPeriod), 34)
			.SetDisplay("Slow SMA", "Slow SMA period", "Indicators");
	}

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

		_prevFast = 0;
		_prevSlow = 0;
		_isReady = false;
	}

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

		_prevFast = 0;
		_prevSlow = 0;
		_isReady = false;

		var fast = new SMA { Length = FastPeriod };
		var slow = new SMA { Length = SlowPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(fast, slow, OnProcess)
			.Start();

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

	private void OnProcess(ICandleMessage candle, decimal fastVal, decimal slowVal)
	{
		if (candle.State != CandleStates.Finished)
			return;

		if (!_isReady)
		{
			_prevFast = fastVal;
			_prevSlow = slowVal;
			_isReady = true;
			return;
		}

		// Fast crosses above slow = buy
		if (_prevFast <= _prevSlow && fastVal > slowVal)
		{
			if (Position < 0)
				BuyMarket();
			if (Position <= 0)
				BuyMarket();
		}
		// Fast crosses below slow = sell
		else if (_prevFast >= _prevSlow && fastVal < slowVal)
		{
			if (Position > 0)
				SellMarket();
			if (Position >= 0)
				SellMarket();
		}

		_prevFast = fastVal;
		_prevSlow = slowVal;
	}
}