GitHub で見る

平均足巻き込み戦略

概要

この戦略は、単一の StockSharp の高レベル戦略内で両方向を組み合わせることにより、MetaTrader の 5 人の専門家 heiken ashi engulf ea buy mt5.mq5heiken ashi engulf sell ea mt5.mq5 の動作を再現します。登録されたタイムフレームから古典的な平均足ローソク足を再構築し、巻き込みパターンを待ち、移動平均アライメントと 2 つの RSI ベースのフィルターでそれを確認し、最後に MetaTrader ピップスで表されるオプションの固定ストップロスとテイクプロフィット距離を使用して市場ポジションを開きます。

変換により、元の「買い」構成と「売り」構成が分離されたままになるため、それぞれの側を個別に最適化できます。方向セレクターを使用すると、トレーダーは強気のみ、弱気のみ、または両方のプレイブックを同時に実行できます。

取引ロジック

平均足の再構築

  1. 完成したローソク足ごとに、戦略は以前の合成始値と終値 (標準 MT アルゴリズム) を使用して平均足の始値、高値、安値、終値を構築します。
  2. 2 つの過去の平均足ローソク足 (shift = 1shift = 2) は、MetaTrader コードからの Shift パラメータをエミュレートするために保存されています。

長いセットアップ

  1. オープンポジションは許可されません (NoOpenedOrders ブロックに相当)。
  2. 最新の平均足ローソク足は強気であり、前の平均足ローソク足は弱気である必要があります (ChosenCandleType = 1PreviousCandleType = 2)。
  3. 最新の実際のローソク足は、その前のローソク足の高値 (Close[1] > High[2]) を上回って終了する必要がありますが、その前のローソク足は弱気でなければなりません (Close[2] < Open[2])。
  4. 最新のローソク足の平均足終値は、ベースライン移動平均 (iMA、パラメータ BuyBaselineMethod/Period) を上回っている必要があります。
  5. 高速トレンド MA は低速トレンド MA (BuyFastBuySlow) を上回っている必要があります。
  6. 2 つの RSI フィルターは、指定されたローソク数の設定された制限内に値を維持する必要があります (例外カウンターを含む、IndicatorWithinLimits ブロックと同じロジック)。
  7. すべての条件が合格した場合、戦略はリクエストされた数量を購入し、設定されたストップロスとテイクプロフィットの距離をピップから価格単位に変換し、SetStopLoss / SetTakeProfit を通じて保護注文を設定します。オプションのログ メッセージは、MetaTrader アラートを複製します。

短いセットアップ

短いロジックは、反対の比較を行う長いルールを反映しています。

  1. フラットな位置。
  2. 最新の平均足ローソク足は弱気で、前の平均足ローソク足は強気です。
  3. 最新の実際のローソク足は、その前のローソク足の安値 (Close[1] < Low[2]) を下回って終了し、その前のローソク足は強気です。
  4. 平均足の終値は弱気のベースラインMAを下回ったままですが、速いMAは遅いMAを下回ったままです。
  5. 両方の RSI フィルターは、独自のシフト/ピリオド/例外構成を使用して、その境界内に留まります。
  6. 成行売り注文が出され、ショートのストップロス/テイクプロフィット距離が適用されます。

パラメーター

名前 デフォルト 説明
CandleType H1 すべてのインジケーターとシグナルに使用される時間枠。
Direction 両方 巻き込みプレイブックのどちら側をアクティブにするか (BuyOnlySellOnlyBoth)。
BuyVolume 0.01 ロングトレードのロットサイズ。
BuyStopLossPips 50 ロングのエントリーとストップロスの間には MetaTrader ピップがあります。 0 は固定停止を無効にします。
BuyTakeProfitPips 50 ロングのエントリーとテイクプロフィットの間には MetaTrader ピップがあります。 0 は固定ターゲットを無効にします。
BuyBaselinePeriod / BuyBaselineMethod 20 / 指数関数的 MA は強気の平均足ローソク足 (ミラー inp1_Ro_*) と比較しました。
BuyFastPeriod / BuyFastMethod 20 / 指数関数的 高速トレンド MA (inp12_Lo_*)。
BuySlowPeriod / BuySlowMethod 30 / 指数関数的 スロートレンド MA (inp12_Ro_*)。
BuyPrimaryRsi* 14、シフト 1、ウィンドウ 2、例外 0、制限 [0;100] 最初の RSI フィルタ (inp13_* と一致)。
BuySecondaryRsi* 5、シフト 2、ウィンドウ 3、例外 0、制限 [0;100] 2 番目の RSI フィルター (inp14_*)。
SellVolume 0.01 短期取引のロットサイズ。
SellStopLossPips 50 ショートのエントリーとストップロスの間は MetaTrader ピップです。
SellTakeProfitPips 50 ショートのエントリーとテイクプロフィットの間の MetaTrader ピップ。
SellBaselinePeriod / SellBaselineMethod 20 / 指数関数的 弱気セットアップのベースライン MA (inp15_*)。
SellFastPeriod / SellFastMethod 20 / 指数関数的 高速トレンド MA (inp26_Lo_*)。
SellSlowPeriod / SellSlowMethod 30 / 指数関数的 スロートレンド MA (inp26_Ro_*)。
SellPrimaryRsi* 14、シフト 1、ウィンドウ 2、例外 0、制限 [0;100] ショートパンツ用の最初の RSI フィルタ (inp27_*)。
SellSecondaryRsi* 5、シフト 2、ウィンドウ 3、例外 0、制限 [0;100] ショートパンツ用の 2 番目の RSI フィルタ (inp28_*)。
AlertTitle 「警告メッセージ」 取引が開始されるときにログに書き込まれるテキスト。
SendNotification 本当の MetaTrader ポップアップ/通知を置き換える情報ログ メッセージを有効にします。

リスク管理

  • ストップロスとテイクプロフィットの距離は、MetaTrader ピップから価格単位に変換されます。変換では、セキュリティ ティック サイズに応じて値が自動的にスケーリングされます (3/5 桁の引用符のサポートが含まれます)。
  • 新しい取引が実行されると、予想される結果のポジションが SetStopLoss / SetTakeProfit に渡され、元の仮想/実際のストップ配置を模倣します。
  • ソース EA には追加の末尾ロジックが存在しないため、何も導入されません。

注意事項

  • RSI フィルタは、MetaTrader ビルダーと同じ「例外のあるウィンドウ」ロジックを使用します。利用可能なローソク足の数が不十分な場合、十分な履歴が収集されるまで取引シグナルは無視されます。
  • 平均足の値はローソクごとにキャッシュされるため、インジケーターのシフト (Shift + CandlesShift) は元の .mq5 ファイルの動作と一致します。
  • DirectionBuyOnly または SellOnly に設定すると、パラメータを変更せずに反対側が完全に無効になり、最適化中に役立ちます。
namespace StockSharp.Samples.Strategies;

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

/// <summary>
/// Heiken Ashi Engulf strategy: WMA crossover with candle direction filter.
/// Buys when price crosses above WMA with bullish candle, sells on bearish cross below.
/// </summary>
public class HeikenAshiEngulfStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _period;

	private decimal _prevClose;
	private decimal _prevWma;
	private bool _hasPrev;

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

	public HeikenAshiEngulfStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_period = Param(nameof(Period), 50)
			.SetGreaterThanZero()
			.SetDisplay("Period", "WMA period", "Indicators");
	}

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

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevClose = 0;
		_prevWma = 0;
		_hasPrev = false;
		var wma = new ExponentialMovingAverage { Length = Period };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(wma, ProcessCandle).Start();
	}

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

		if (_hasPrev)
		{
			var bullish = candle.ClosePrice > candle.OpenPrice;
			var bearish = candle.ClosePrice < candle.OpenPrice;

			if (_prevClose <= _prevWma && candle.ClosePrice > wmaValue && bullish && Position <= 0)
				BuyMarket();
			else if (_prevClose >= _prevWma && candle.ClosePrice < wmaValue && bearish && Position >= 0)
				SellMarket();
		}

		_prevClose = candle.ClosePrice;
		_prevWma = wmaValue;
		_hasPrev = true;
	}
}