GitHub で見る

Gridder EA戦略(MQL4から移植)

概要

元のGridderEAは、MetaTrader 4向けに設計されたマルチシンボルのグリッド取引エキスパートアドバイザーです。このStockSharp移植版は、段階的な間隔、適応的ロットサイズ、バスケットテイクプロフィット、緊急ヘッジという中核概念を保ちつつ、ホスト戦略が管理する単一銘柄に焦点を当てます。戦略は設定可能なローソク足ストリームを購読し、確定バーを監視し、価格が最後の参照水準からpipsで定義された距離だけ離れると平均化取引を開きます。

取引ロジック

  1. グリッド進行: 基本ステップ(pips)が、新しい取引を置く前に必要な最小価格変動を定義します。各追加注文は、ボラティリティ上昇時にグリッドを広げるため、このステップを幾何級数的または指数的に拡大できます。
  2. ロット進行: 最初の注文は初期数量を使います。後続注文は、設定されたロット進行モード(静的、幾何、指数)に従って前回数量を乗算します。
  3. バスケット目標: 未実現損益は、各オープン取引の価格偏差と銘柄ステップ値を組み合わせ、口座通貨で測定されます。合計利益がロットあたり目標を超えると、全ポジションを閉じます。同様に、ロットあたり目標損失は保護ストップとしてバスケットを清算できます。
  4. 緊急モード: 片側の取引数が緊急トリガーに達すると、戦略は累積数量の一部サイズでヘッジ取引を任意で開きます。これはMQL版の「Emergency Mode」を模倣し、ドローダウン抑制に役立ちます。
  5. ポジション保護: 起動時にStartProtection()を呼び出し、ベース戦略が予期しないポジション変化を監視し、取引所状態と再同期できるようにします。

StockSharp実装は大きな履歴コレクションの操作を避け、確定ローソク足のみを処理します。これは完了バーで動作する元エキスパートの挙動を反映します。

パラメーター

パラメーター 説明
Initial Volume 最初のグリッド注文の数量。
Volume Multiplier ロット進行が幾何または指数の場合に次の注文数量計算へ適用する係数。
Grid Step (pips) 連続するエントリー間の基本距離(pips)。
Step Multiplier ステップ進行が幾何または指数の場合のグリッド間隔スケール係数。
Target Profit / Lot ロットあたりの未実現利益目標。この目標に達すると全取引を閉じます。
Target Loss / Lot ロットあたりの未実現損失しきい値。到達するとドローダウンを抑えるため全取引を閉じます。
Max Orders Per Side 市場の各側で許可される平均化取引数を制限します。0で無効。
Allow Long / Allow Short 買い/売り脚を個別に有効または無効にします。
Step Mode ステップの増え方を決定します: 静的、幾何、指数。
Lot Mode 注文数量の増え方を決定します: 静的、幾何、指数。
Use Emergency Mode 大きすぎるバスケットから保護するヘッジロジックを有効にします。
Emergency Trigger ヘッジを起動する片側の注文数。
Hedge Volume Factor 緊急モード発動時にヘッジ注文として置く側全体数量の比率。
Candle Type グリッド計算に使うローソク足購読の時間軸。

元EAとの差異

  • 移植版は一度に1つの銘柄を管理します。複数銘柄を取引してMQLエキスパートのマルチシンボル動作を再現するには、複数の戦略インスタンスを接続してください。
  • MetaTraderの画面パネルやチャート注釈は再現されません。必要に応じてStockSharpチャートエリアでローソク足と自分の取引を可視化してください。
  • 資金管理プリセットと詳細な部分決済プロファイルは、統一されたバスケット損益ロジックへ簡略化されています。

使用上の注意

  1. コンストラクターパラメーター(UIまたは最適化インターフェイス)で希望するローソク足タイプ、数量、グリッド間隔を設定します。
  2. 銘柄がライブまたはシミュレーションボードへ接続されたら戦略を開始します。戦略は選択したローソク足を自動購読します。
  3. 緊急トリガーとヘッジ係数を監視し、回復フェーズの積極性を調整します。高いヘッジ係数はネットポジションをより速く中立へ戻しますが、収益性を下げます。
  4. 追加安全性のため、StockSharpのリスク制御(ポートフォリオ保護、最大ポジション監視など)と組み合わせてください。

緊急ヘッジ例

戦略が5つの平均化買い注文を段階的に大きな数量で開いているとします。緊急トリガーが5、ヘッジ数量係数が0.5の場合、5つ目の買いが約定した瞬間、戦略はロング合計数量の半分に相当する自動成行売りを送信します。これはバスケットを部分的にロックし、平均回帰の決済を待つMQLロジックを反映します。

最適化のヒント

  • Grid Step (pips)Volume Multiplierは一緒に最適化してください。小さいステップでは暴走するエクスポージャーを避けるため、保守的な乗数が必要です。
  • Target Profit / Lotを使い、閉じた取引履歴に頼らずMetaTraderのドル目標をStockSharp環境へ変換します。
  • 取引銘柄のボラティリティに応じてEmergency TriggerHedge Volume Factorを調整します。高ボラティリティでは通常、より早いヘッジが有利です。

安全推奨

  • 本番投入前にシミュレーターで徹底的にテストしてください。
  • 丸めた数量が実際のロット粒度に合うよう、ブローカー固有の契約サイズを監視してください。
  • グリッドが大きなポジションを蓄積し得るトレンド市場で壊滅的損失を防ぐため、stop-outルール(例: ホストロボット経由)と組み合わせてください。
using System;

using Ecng.Common;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Gridder EA strategy: BB mean reversion grid concept.
/// Buys when close < lower BB. Sells when close > upper BB.
/// </summary>
public class GridderEaStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _bbPeriod;

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

	public int BbPeriod
	{
		get => _bbPeriod.Value;
		set => _bbPeriod.Value = value;
	}

	public GridderEaStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");

		_bbPeriod = Param(nameof(BbPeriod), 20)
			.SetGreaterThanZero()
			.SetDisplay("BB Period", "Bollinger Bands period", "Indicators");
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		var bb = new BollingerBands { Length = BbPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.BindEx(bb, ProcessCandle)
			.Start();

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

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

		if (!IsFormedAndOnlineAndAllowTrading())
			return;

		var bbv = (BollingerBandsValue)bbVal;
		if (bbv.UpBand is not decimal upper ||
			bbv.LowBand is not decimal lower)
			return;

		var close = candle.ClosePrice;

		if (close < lower && Position <= 0)
		{
			BuyMarket();
		}
		else if (close > upper && Position >= 0)
		{
			SellMarket();
		}
	}
}