Ver no GitHub

Estratégia de painel utilitário leve de negociação manual

Visão geral

A Estratégia do painel utilitário leve de negociação manual replica o comportamento do painel MT4 "Utilitário leve de negociação manual" usando a estratégia de alto nível StockSharp API. Ele expõe os mesmos controles interativos que os parâmetros de estratégia para que o operador possa alternar entre ordens de mercado, limite e stop, ajustar o cálculo automático de preços, configurar o gerenciamento de volume e anexar controles de risco sem depender de objetos gráficos personalizados.

A estratégia é projetada para negociação discricionária. Os pedidos são acionados manualmente alterando os parâmetros Send Buy Order ou Send Sell Order na IU. Cada comando é reconhecido imediatamente, enquanto a estratégia mantém todos os cálculos — como sugestões automáticas de preços e níveis de risco — sincronizados com dados de mercado em tempo real.

Principais recursos

  • Envio manual de pedidos para compradores e vendedores, com suporte para ordens de mercado, limite e stop.
  • Sugestão automática de preço que reflete a lógica do painel MT4, atualizando o limite proposto ou o preço stop do último fluxo de compra/venda.
  • Modo de preço manual opcional que permite ao operador digitar o nível de disparo desejado respeitando os tamanhos dos passos do instrumento.
  • Gerenciamento de volume com tamanho de lote global e volumes de compra/venda individuais quando a chave de controle de lote está habilitada.
  • Gerenciamento integrado de stop-loss e take-profit implementado na camada de estratégia para emular proteções anexadas a pedidos no MT4.
  • Feedback detalhado por meio de parâmetros que sempre refletem os últimos níveis de entrada calculados para ambos os lados.

Notas de conversão

  • Os objetos gráficos MT4 (botões, rótulos e caixas de edição) são substituídos por parâmetros de estratégia agrupados em seções lógicas para fácil acesso no Hydra/Terminal.
  • As paradas e metas de proteção são tratadas internamente, observando o preço de mercado ao vivo porque StockSharp não os incorpora em ordens pendentes da mesma forma que o MT4.
  • As compensações de preços expressas em pontos reutilizam os metadados do instrumento (PriceStep e VolumeStep) para que os limites e paradas sempre respeitem as restrições cambiais.

Uso

  1. Anexe a estratégia a um título e portfólio no Hydra ou Terminal.
  2. Configure o tamanho do lote padrão, parâmetros de risco e compensações de preço.
  3. Opcionalmente, habilite Lot Control para manter volumes independentes para os botões de compra e venda.
  4. Escolha o tipo de ordem (mercado, limite pendente ou stop pendente) e se o preço de gatilho deve seguir o mercado ou permanecer manual.
  5. Quando estiver pronto, alterne Send Buy Order ou Send Sell Order para true. A estratégia enviará o pedido correspondente e redefinirá o sinalizador para false depois de processado.
  6. O gestor de proteção fechará as posições abertas nos níveis de stop-loss ou take-profit configurados, calculados a partir do preço de entrada executado.

Arquivos

  • CS/ManualTradingLightweightUtilityPanelStrategy.cs – Implementação da estratégia em C#.
  • README.md – Documentação em inglês (este arquivo).
  • README_zh.md – Documentação em chinês simplificado.
  • README_ru.md – Documentação russa.
namespace StockSharp.Samples.Strategies;

using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;

/// <summary>
/// Manual Trading Panel strategy: SMA mean reversion with RSI filter.
/// Buys when close is below SMA and RSI is oversold, sells when above and overbought.
/// </summary>
public class ManualTradingLightweightUtilityPanelStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _smaPeriod;
	private readonly StrategyParam<int> _rsiPeriod;
	private readonly StrategyParam<int> _signalCooldownCandles;
	private int _candlesSinceTrade;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int SmaPeriod { get => _smaPeriod.Value; set => _smaPeriod.Value = value; }
	public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
	public int SignalCooldownCandles { get => _signalCooldownCandles.Value; set => _signalCooldownCandles.Value = value; }

	public ManualTradingLightweightUtilityPanelStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_smaPeriod = Param(nameof(SmaPeriod), 20)
			.SetGreaterThanZero()
			.SetDisplay("SMA Period", "SMA period", "Indicators");
		_rsiPeriod = Param(nameof(RsiPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("RSI Period", "RSI period", "Indicators");
		_signalCooldownCandles = Param(nameof(SignalCooldownCandles), 8)
			.SetGreaterThanZero()
			.SetDisplay("Signal Cooldown", "Bars to wait between trades", "Trading");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_candlesSinceTrade = SignalCooldownCandles;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_candlesSinceTrade = SignalCooldownCandles;
		var sma = new SimpleMovingAverage { Length = SmaPeriod };
		var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(sma, rsi, ProcessCandle).Start();
	}

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

		if (_candlesSinceTrade < SignalCooldownCandles)
			_candlesSinceTrade++;

		var close = candle.ClosePrice;

		if (close < sma && rsi < 35 && Position <= 0 && _candlesSinceTrade >= SignalCooldownCandles)
		{
			BuyMarket();
			_candlesSinceTrade = 0;
		}
		else if (close > sma && rsi > 65 && Position >= 0 && _candlesSinceTrade >= SignalCooldownCandles)
		{
			SellMarket();
			_candlesSinceTrade = 0;
		}
	}
}