Ver no GitHub

Estratégia do painel de troca de símbolos

Visão geral

A Estratégia de Painel de Troca de Símbolos é uma conversão StockSharp do painel MQL "Painel de Troca de Símbolos". O especialista original atuou como um widget de gráfico que permitia aos traders digitar um símbolo, mudar o gráfico ativo para esse símbolo e monitorar informações de mercado em tempo real, como valores de OHLC, volume de ticks e spread. A estratégia convertida recria o mesmo fluxo de trabalho no ambiente StockSharp. Ele pode ser iniciado em qualquer título e fornece uma alternância manual para pular para outro instrumento enquanto registra continuamente as métricas de mercado mais relevantes.

Comportamento central

  • Assina dados de velas e cotações de nível um para o título ativo.
  • Registra cada vela concluída com abertura, máximo, mínimo, fechamento, volume total e o último spread computado.
  • Armazena cotações de compra/venda e obtém um spread atualizado que reflete a leitura do painel MQL.
  • Reage a solicitações de troca manual e substitui a segurança monitorada pelo identificador escolhido sem exigir a reinicialização da estratégia.
  • Mantém a segurança previamente selecionada para que trocas redundantes sejam ignoradas e ativações duplas acidentais não interrompam as assinaturas.

Parâmetros

Nome Tipo Descrição
TargetSecurityId string Identificador de segurança que deve ser ativado quando a solicitação de troca for acionada. Strings vazias são ignoradas com um aviso.
CandleType DataType Agregação de velas para atualizações periódicas (o padrão é velas de 1 hora, replicando o período do painel MQL).
SwapRequested bool Sinalizador manual que solicita uma mudança imediata para TargetSecurityId. Ele é redefinido para false após o processamento da tentativa de troca.

Assinaturas de dados

  • Assinatura Candle criada com CandleType para a segurança atualmente ativa.
  • Assinatura de nível um usada para rastrear cotações de compra/venda e calcular um valor de spread ao vivo.
  • As assinaturas são reiniciadas com segurança sempre que a segurança muda, garantindo que fluxos de dados obsoletos não sejam deixados em execução.

Fluxo de trabalho

  1. Quando a estratégia é iniciada ela resolve a segurança inicial de Strategy.Security ou, se faltar, de TargetSecurityId.
  2. Assinaturas de vela e nível um são abertas para esse instrumento.
  3. Cada vela concluída aciona uma mensagem de registro detalhada que reflete o texto mostrado nos rótulos originais do painel.
  4. As atualizações de nível um recebidas atualizam os valores de compra/venda em cache.
  5. Definir SwapRequested como true e fornecer um TargetSecurityId válido alterna imediatamente a segurança monitorada e reinicia as assinaturas.

Notas de uso

  • A estratégia foi projetada para monitoramento manual e não realiza pedidos.
  • O spread só é reportado quando os valores de compra e venda estão presentes e positivos.
  • Quando um símbolo inválido ou desconhecido é fornecido, um aviso é registrado e a solicitação é descartada sem interromper as assinaturas em execução.
  • Como a ferramenta original atualizava a IU uma vez por segundo, você pode diminuir o período da vela se precisar de atualizações de log mais frequentes.

Recursos originais MQL preservados

  • Troca manual de símbolos através de um identificador textual.
  • Exibição em tempo real de valores, volume e spread de OHLC para o símbolo escolhido.
  • Salvaguardas contra entradas vazias e adições falhadas do Market Watch (traduzidas em StockSharp avisos).

Diferenças da implementação MQL

  • A estratégia StockSharp usa mensagens de registro em vez de rótulos na tela. Isso corresponde ao fluxo de trabalho típico dentro de StockSharp enquanto ainda expõe as mesmas informações.
  • A troca de gráficos é implementada reatribuindo a segurança da estratégia e recriando assinaturas em vez de alterar uma janela de gráfico do terminal.
  • A lógica de atualização baseada em temporizador é substituída por eventos de conclusão de vela para permanecer alinhado com APIs StockSharp de alto nível.

Requisitos

  • Conector StockSharp com acesso aos títulos desejados.
  • Feed de dados de nível um para obter cotações de compra/venda para cálculo de spread.
using System;
using System.Linq;
using System.Collections.Generic;

using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Price monitoring strategy that logs OHLC metrics and trades on candle patterns.
/// Simplified from the "Symbol Swap Panel" MQL display widget.
/// </summary>
public class SymbolSwapPanelStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _maPeriod;

	private SimpleMovingAverage _sma;
	private decimal _entryPrice;
	private decimal _prevClose;

	/// <summary>
	/// Candle type for monitoring.
	/// </summary>
	public DataType CandleType
	{
		get => _candleType.Value;
		set => _candleType.Value = value;
	}

	/// <summary>
	/// Moving average period for trend signals.
	/// </summary>
	public int MaPeriod
	{
		get => _maPeriod.Value;
		set => _maPeriod.Value = value;
	}

	/// <summary>
	/// Initializes strategy parameters.
	/// </summary>
	public SymbolSwapPanelStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
			.SetDisplay("Candle Type", "Candle series for monitoring and signals", "General");

		_maPeriod = Param(nameof(MaPeriod), 20)
			.SetGreaterThanZero()
			.SetDisplay("MA Period", "Moving average period for entry signals", "Indicators");
	}

	/// <inheritdoc />
	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
	{
		yield return (Security, CandleType);
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_sma = null;
		_entryPrice = 0m;
		_prevClose = 0m;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		_sma = new SimpleMovingAverage { Length = MaPeriod };

		SubscribeCandles(CandleType)
			.Bind(_sma, ProcessCandle)
			.Start();
	}

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

		var price = candle.ClosePrice;
		var high = candle.HighPrice;
		var low = candle.LowPrice;

		// Log price info
		LogInfo(
			$"Time: {candle.CloseTime:O}, O: {candle.OpenPrice}, H: {high}, L: {low}, C: {price}, " +
			$"Vol: {candle.TotalVolume}, SMA: {smaValue:F5}");

		// Exit: reversal or profit target
		if (Position != 0 && _entryPrice > 0m)
		{
			var pnl = Position > 0
				? price - _entryPrice
				: _entryPrice - price;

			// Exit on trend reversal
			if ((Position > 0 && price < smaValue) ||
				(Position < 0 && price > smaValue))
			{
				if (Position > 0)
					SellMarket(Math.Abs(Position));
				else
					BuyMarket(Math.Abs(Position));

				_entryPrice = 0m;
				_prevClose = price;
				return;
			}
		}

		// Entry: follow MA trend with momentum confirmation
		if (Position == 0 && _prevClose > 0m)
		{
			if (price > smaValue && _prevClose <= smaValue)
			{
				BuyMarket();
				_entryPrice = price;
			}
			else if (price < smaValue && _prevClose >= smaValue)
			{
				SellMarket();
				_entryPrice = price;
			}
		}

		_prevClose = price;
	}
}