Strategie für akustische Warnungen bei Verbindung und Trennung
Überblick
Die Connect Disconnect Sound Alert Strategy überwacht kontinuierlich den Verbindungsstatus des Strategie-Connectors und protokolliert jeden Übergang zwischen Online- und Offline-Status. Der ursprüngliche MQL5-Experte spielte Audiodateien ab, wenn das MetaTrader-Terminal angeschlossen oder getrennt wurde. Diese C#-Konvertierung behält die Kernlogik – das Erkennen von Verbindungsänderungen – bei und macht Hooks verfügbar, die es der StockSharp-Laufzeit ermöglichen, Ereignisse und Dauer aufzuzeichnen. Die Strategie kann als leichter Watchdog verwendet werden, der den Betreiber über Verbindungsprobleme informiert, ohne dass er Befehle erteilen muss.
Hauptmerkmale
Fragt den Connector-Status regelmäßig in einem konfigurierbaren Intervall ab.
Erkennt sowohl Verbindungs- als auch Trennungsereignisse und schreibt detaillierte Protokolleinträge.
Zeichnet auf, wie lange das Terminal online oder offline blieb (optional).
Überspringt Benachrichtigungstöne bei der allerersten Prüfung, um das Verhalten von MQL widerzuspiegeln.
Parameter
Name
Standard
Beschreibung
CheckIntervalSeconds
1
Anzahl der Sekunden zwischen den Connector-Statusprüfungen. Muss größer als Null sein.
LogDurations
true
Wenn die Strategie aktiviert ist, protokolliert sie die Zeitspanne, in der die Verbindung nach jedem Übergang online oder offline blieb.
Alle Parameter werden über StrategyParam<T> verfügbar gemacht, sodass sie über die Benutzeroberfläche oder während der Optimierung geändert werden können.
Wie es funktioniert
Wenn die Strategie startet, speichert sie den aktuellen Connector-Status und protokolliert optional den Anfangsstatus.
Ein System.Threading.Timer ruft regelmäßig einen internen Handler auf, der das aktuelle Verbindungsflag mit dem vorherigen Wert vergleicht.
Wenn sich der Zustand ändert, protokolliert die Strategie den Übergang. Die allererste Benachrichtigung ist als „initial“ gekennzeichnet und stellt keinen tatsächlichen akustischen Alarm dar (entspricht der ursprünglichen Expert Advisor-Logik).
Optionale Dauerprotokolle zeigen, wie lange der vorherige Zustand gedauert hat, und helfen dem Betreiber, die Verbindungsstabilität zu beurteilen.
Der Timer wird automatisch entsorgt, wenn die Strategie stoppt oder zurückgesetzt wird.
Nutzungshinweise
Hängen Sie die Strategie an jedes Connector-fähige StockSharp-Terminal an. Es interagiert nicht mit Marktdaten und erteilt keine Aufträge.
Behalten Sie das Standardabfrageintervall bei, um eine Überwachung nahezu in Echtzeit zu ermöglichen. Erhöhen Sie den Wert, wenn Sie nur grobe Aktualisierungen benötigen.
Die Strategie verwendet das Protokollierungssubsystem StockSharp (LogInfo). Konfigurieren Sie Protokoll-Listener oder Dashboards, um die Benachrichtigungen anzuzeigen.
Um tatsächliche akustische Warnungen hinzuzufügen, verbinden Sie einen Benachrichtigungsdienst in Ihrer Hostanwendung und spielen Sie Audio ab, wenn Protokollmeldungen eingehen.
Sicherheitsüberlegungen
Die Strategie validiert das Abfrageintervall und löst eine Ausnahme aus, wenn es nicht positiv ist.
Timer-Rückrufe verwenden die Strategie CurrentTime, um konsistente Zeitstempel sicherzustellen, selbst wenn die Wiedergabe historischer Daten verwendet wird.
Alle Ressourcen werden beim Stoppen/Zurücksetzen freigegeben, um Hintergrundtimer nach der Deaktivierung der Strategie zu vermeiden.
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);
}
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import SimpleMovingAverage
from StockSharp.Algo.Strategies import Strategy
class connect_disconnect_sound_alert_strategy(Strategy):
"""
SMA crossover strategy. Buys when fast SMA crosses above slow SMA.
"""
def __init__(self):
super(connect_disconnect_sound_alert_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Candle timeframe", "General")
self._fast_period = self.Param("FastPeriod", 10) \
.SetDisplay("Fast SMA", "Fast SMA period", "Indicators")
self._slow_period = self.Param("SlowPeriod", 30) \
.SetDisplay("Slow SMA", "Slow SMA period", "Indicators")
self._prev_fast = 0.0
self._prev_slow = 0.0
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(connect_disconnect_sound_alert_strategy, self).OnReseted()
self._prev_fast = 0.0
self._prev_slow = 0.0
def OnStarted2(self, time):
super(connect_disconnect_sound_alert_strategy, self).OnStarted2(time)
fast = SimpleMovingAverage()
fast.Length = self._fast_period.Value
slow = SimpleMovingAverage()
slow.Length = self._slow_period.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(fast, slow, self.on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, fast)
self.DrawIndicator(area, slow)
self.DrawOwnTrades(area)
def on_process(self, candle, fast_val, slow_val):
if candle.State != CandleStates.Finished:
return
if self._prev_fast != 0.0 and self._prev_slow != 0.0:
cross_up = self._prev_fast <= self._prev_slow and fast_val > slow_val
cross_down = self._prev_fast >= self._prev_slow and fast_val < slow_val
if cross_up and self.Position <= 0:
self.BuyMarket()
elif cross_down and self.Position >= 0:
self.SellMarket()
self._prev_fast = fast_val
self._prev_slow = slow_val
def CreateClone(self):
return connect_disconnect_sound_alert_strategy()