GitHub で見る

接続戦略

概要

  • 出典: MetaTrader 5 スクリプト IsConnected.mq5 (フォルダー MQL/35056) から変換。
  • 目的: コネクタのステータスを継続的に監視し、オンライン/オフラインの移行をタイムスタンプと稼働時間/ダウンタイムの継続時間とともにレポートします。
  • タイプ: 注文の実行ではなくインフラストラクチャの監視に重点を置いたユーティリティ戦略。

行動

  1. この戦略が開始されると、監視モジュールが初期化されたことがすぐにログに記録され、現在のコネクタの状態がキャプチャされます。
  2. バックグラウンド タイマーは、CheckIntervalSeconds ごとに Connector.IsConnected フラグをチェックします (デフォルト: 1 秒)。
  3. 状態が変化すると、次のような戦略がとられます。
    • 戦略 CurrentTime を使用して移行の瞬間を保存します。
    • 新しい状態をログに記録します (Online または Offline)。
    • 以前の状態がどれくらい続いたかを報告します (切断されるまでのオンライン時間、または再接続までのオフライン時間)。
  4. 戦略が停止すると、タイマーがキャンセルされ、最後の既知の状態が記録されるため、オペレーターはシャットダウン時に接続がアップしたかダウンしたかを知ることができます。

パラメーター

名前 種類 デフォルト 説明
CheckIntervalSeconds int 1 連続する接続チェック間の間隔 (秒単位)。ゼロより大きくなければなりません。

ロギングの詳細

  • すべてのメッセージは、Print ステートメントに依存する MetaTrader 実装と一致するように、英語の LogInfo で記述されます。
  • 時間間隔はインバリアント カルチャを使用してフォーマットされ、開始タイムスタンプと前の状態で費やされた時間の両方が含まれます。

元のスクリプトとの違い

  • MQL5 からのビジー待機ループは、戦略スレッドをブロックしないマネージド タイマーに置き換えられます。
  • StockSharp バージョンでは、重複したステータス行を出力する代わりに、稼働時間/ダウンタイムのメトリクスとともに構造化されたステータスの変化をレポートします。
  • 変換では、OnStoppedOnReseted の両方でタイマーを停止することで、正常な廃棄が処理されます。
namespace StockSharp.Samples.Strategies;

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

/// <summary>
/// IsConnected strategy: Parabolic SAR trend following.
/// Buys when close above SAR, sells when close below SAR.
/// </summary>
public class IsConnectedStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<decimal> _acceleration;
	private readonly StrategyParam<decimal> _accelerationMax;

	private decimal _prevSar;
	private decimal _prevClose;
	private bool _hasPrev;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public decimal Acceleration { get => _acceleration.Value; set => _acceleration.Value = value; }
	public decimal AccelerationMax { get => _accelerationMax.Value; set => _accelerationMax.Value = value; }

	public IsConnectedStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_acceleration = Param(nameof(Acceleration), 0.01m)
			.SetDisplay("Acceleration", "SAR acceleration factor", "Indicators");
		_accelerationMax = Param(nameof(AccelerationMax), 0.1m)
			.SetDisplay("Acceleration Max", "SAR max acceleration", "Indicators");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevSar = 0;
		_prevClose = 0;
		_hasPrev = false;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevSar = 0;
		_prevClose = 0;
		_hasPrev = false;
		var sar = new ParabolicSar { Acceleration = Acceleration, AccelerationMax = AccelerationMax };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(sar, ProcessCandle).Start();
	}

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

		if (_hasPrev)
		{
			if (_prevClose <= _prevSar && candle.ClosePrice > sarValue && Position <= 0)
				BuyMarket();
			else if (_prevClose >= _prevSar && candle.ClosePrice < sarValue && Position >= 0)
				SellMarket();
		}

		_prevClose = candle.ClosePrice;
		_prevSar = sarValue;
		_hasPrev = true;
	}
}