GitHub で見る

平滑化された MA 方向性戦略

この戦略は、MQL/8615 フォルダの MetaTrader 4 エキスパート oc08_vy_m0moqesu15 の StockSharp の高レベルの API 移植です。オリジナルのエキスパートは、そのポジションを単一の平滑移動平均 (SMMA) に合わせて、固定のストップロスとテイクプロフィットのレベルをすべての注文に付加します。 C# バージョンは、慣用的な StockSharp コンポーネントを採用しながら、同じ方向の動作を維持します。

取引アイデア

  • 方向性バイアス: 平滑化移動平均を上回る終値は上昇傾向を示します。以下で終了すると、下降トレンドのシグナルとなります。
  • ポジションの調整: この戦略は、常に検出されたトレンドの方向に単一のポジションを維持しようとします。市場が反転すると、即座にポジションが逆転します。
  • リスク管理: すべてのエントリーは、価格ステップで表されるストップロスとテイクプロフィットのオフセットによって保護されます。 StockSharp の StartProtection ヘルパーは、元の MQ4 コードの手動 SL/TP 割り当てを置き換えます。
  • 約定スタイル: 注文はローソク足の終値で成行注文として送信され、MetaTrader エキスパートの OrdersTotal()==0 ロジックを複製します。

仕組み

  1. 開始時に、戦略は設定された時間枠のローソク足をサブスクライブし、SmoothedMovingAverage インジケーターを選択した期間にバインドします。
  2. ローソク足が終了すると、インジケーターの値がローソク足の終値と比較されます。
  3. 終値が SMMA より高く、戦略がフラットまたはショートの場合、ショート エクスポージャー (存在する場合) をカバーするサイズの市場買いを送信し、ロング ポジションをオープンします。
  4. 終値が SMMA より低く、戦略がフラットまたはロングの場合、ロング エクスポージャー (存在する場合) をカバーするサイズの市場売りを送信し、ショート ポジションをオープンします。
  5. 保護的なストップロスとテイクプロフィットの距離は、現在のセキュリティ PriceStep を使用して開始時に 1 回設定されます。両方のオフセットがゼロに設定されている場合、保護は無効になります。
  6. チャート出力 (ローソク足、インジケーター、トレード) は、チャート領域を公開する環境内でストラテジーが実行されるときに自動的に描画されます。

パラメーター

名前 デフォルト 説明
StopLossPoints 100 価格ステップのストップロス距離。停止を無効にするには、0 に設定します。
TakeProfitPoints 100 価格ステップでの利食い距離。ターゲットを無効にするには、0 に設定します。
MaPeriod 12 傾向を測定するために使用される平滑化移動平均の期間。
TradeVolume 1 成行注文量。このストラテジーは、開始時にこの値も Strategy.Volume に書き込みます。
CandleType 15分の時間枠 インジケーターとシグナルを駆動するローソクのタイプ (タイムフレーム)。

すべてのパラメータは、StockSharp デザイナー/ランナーを通じて構成可能であり、自動テストの最適化範囲が含まれています。

MetaTrader バージョンとの違い

  • 証拠金ベースのロットサイジング (Lots/Prots) は固定の TradeVolume パラメータに置き換えられます。これにより、動作の決定性が保たれ、StockSharp のポートフォリオ抽象化との互換性が保たれます。
  • Stop-loss and take-profit are handled by StartProtection instead of manual order amendments, matching the original offsets but using StockSharp primitives.
  • この戦略は、MQ4 の New_Bar フラグを反映して、時期尚早の取引を避けるために未終了のローソク足を無視します。

実践メモ

  • 接続されているセキュリティが有効な PriceStep を提供していることを確認してください。そうでない場合、戦略は SL/TP 距離を計算するときに 1 の単位ステップに戻ります。
  • インジケーターの長さはすべてのローソク足の現在のパラメーター値と同期され、ライブパラメーター調整が可能になります。
  • 元の動作を再現するには、MQ4 エキスパートをホストしたチャートと同じ時間枠を設定し、取引量を希望の契約サイズと一致させます。
using System;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Smoothed MA directional strategy. Goes long when price is above the MA, short when below.
/// </summary>
public class SmoothedMaDirectionalStrategy : Strategy
{
	private readonly StrategyParam<int> _maPeriod;
	private readonly StrategyParam<DataType> _candleType;

	public SmoothedMaDirectionalStrategy()
	{
		_maPeriod = Param(nameof(MaPeriod), 12)
			.SetDisplay("MA Period", "Number of bars for the moving average.", "Indicators");

		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Time frame used for price analysis.", "General");
	}

	public int MaPeriod
	{
		get => _maPeriod.Value;
		set => _maPeriod.Value = value;
	}

	public DataType CandleType
	{
		get => _candleType.Value;
		set => _candleType.Value = value;
	}

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

		var ma = new SimpleMovingAverage { Length = MaPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(ma, ProcessCandle)
			.Start();

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

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

		var closePrice = candle.ClosePrice;

		if (closePrice > maValue && Position <= 0)
		{
			// Price above MA - go long
			if (Position < 0)
				BuyMarket(); // Close short
			BuyMarket(); // Open long
		}
		else if (closePrice < maValue && Position >= 0)
		{
			// Price below MA - go short
			if (Position > 0)
				SellMarket(); // Close long
			SellMarket(); // Open short
		}
	}
}