GitHub で見る

Connect Disconnect Sound Alert Strategy

Overview

The Connect Disconnect Sound Alert Strategy continuously monitors the connection status of the strategy connector and logs every transition between online and offline states. The original MQL5 expert played audio files when the MetaTrader terminal was connected or disconnected. This C# conversion keeps the core logic – detecting connection changes – and exposes hooks that allow the StockSharp runtime to record events and durations. The strategy can be used as a lightweight watchdog that informs the operator about connectivity problems without placing any orders.

Key Features

  • Periodically polls the connector state using a configurable interval.
  • Detects both connection and disconnection events and writes detailed log entries.
  • Records how long the terminal stayed online or offline (optional).
  • Skips notification sounds on the very first check to mirror the MQL behavior.

Parameters

Name Default Description
CheckIntervalSeconds 1 Number of seconds between connector status checks. Must be greater than zero.
LogDurations true When enabled, the strategy logs the time span that the connection stayed online or offline after each transition.

All parameters are exposed through StrategyParam<T> so they can be modified from the UI or during optimization.

How It Works

  1. When the strategy starts it stores the current connector state and, optionally, logs the initial status.
  2. A System.Threading.Timer periodically calls an internal handler that compares the current connection flag with the previous value.
  3. If the state changed, the strategy logs the transition. The very first notification is marked as "initial" and does not represent an actual sound alert (matching the original expert advisor logic).
  4. Optional duration logs show how long the previous state lasted, helping the operator evaluate connection stability.
  5. The timer is automatically disposed when the strategy stops or resets.

Usage Notes

  • Attach the strategy to any connector-enabled StockSharp terminal. It does not interact with market data or place orders.
  • Keep the default polling interval for near real-time monitoring. Increase the value if you only need coarse updates.
  • The strategy uses the StockSharp logging subsystem (LogInfo). Configure log listeners or dashboards to see the notifications.
  • To add actual sound alerts, connect a notification service in your host application and play audio when log messages arrive.

Safety Considerations

  • The strategy validates the polling interval and throws an exception if it is not positive.
  • Timer callbacks use the strategy CurrentTime to ensure consistent timestamps even when historical data replay is used.
  • All resources are released on stop/reset to avoid background timers after the strategy is disabled.
using System;

using Ecng.Common;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Connection alert strategy with SMA crossover trading.
/// Buys when fast SMA crosses above slow SMA, sells on cross below.
/// </summary>
public class ConnectDisconnectSoundAlertStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;

	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 ConnectDisconnectSoundAlertStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");

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

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

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

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

		decimal? prevFast = null;
		decimal? prevSlow = null;

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(fast, slow, (candle, fastVal, slowVal) =>
			{
				if (candle.State != CandleStates.Finished)
					return;

				if (!IsFormedAndOnlineAndAllowTrading())
					return;

				if (prevFast.HasValue && prevSlow.HasValue)
				{
					var crossUp = prevFast.Value <= prevSlow.Value && fastVal > slowVal;
					var crossDown = prevFast.Value >= prevSlow.Value && fastVal < slowVal;

					if (crossUp && Position <= 0)
						BuyMarket();
					else if (crossDown && Position >= 0)
						SellMarket();
				}

				prevFast = fastVal;
				prevSlow = slowVal;
			})
			.Start();

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