GitHub で見る

MAリバース戦略

概要

MA リバース戦略は、単純な MetaTrader 4 エキスパート アドバイザー「MA_Reverse」の StockSharp 変換です。オリジナルロボット 入札価格が 14 期間の単純移動平均 (SMA) を上回るか下回る期間を監視します。 1 回で十分に長く連続した後 方向に合わせて、短期的な反転に賭けてポジションをオープンします。 StockSharp ポートは、数をカウントすることで同じ考え方を維持します。 SMA の上または下で終了し、設定されたしきい値になるとすぐに成行注文を実行する、連続した終了したローソク足の数 に達しました。

取引ロジック

  • 選択した時間枠のローソク足をサブスクライブし、SmaPeriod で定義された期間で単純移動平均を計算します。
  • ローソク足の終値が上にある間増加する整数カウンター (StreakThreshold はターゲットの長さを制御します) を維持します 移動平均が減少し、終値が移動平均を下回ったままになります。移動平均をタッチするとカウンターがリセットされます。
  • カウンタが StreakThreshold に達し、終値が少なくとも MinimumDeviation を SMA 上にある場合、戦略は 市場注文。移動平均からの長期にわたる強気の上昇は平均反転する可能性が高いと仮定しています。
  • カウンタが -StreakThreshold に達し、終値が少なくとも MinimumDeviation よりも SMA を下回っている場合、ロジックは 行動し、ロングポジションをオープンします。
  • 毎回の取引後、カウンターはソース EA と同様に実行値を維持するため、すぐに取引の測定を開始できます。 次の連続。

注文管理

  • 市場エントリーでは、TradeVolume パラメーターを使用します。ブックに反対のポジションがある場合、戦略はまずそれをクローズし、 次に、反転が MetaTrader の動作と一致するように、単一の成行注文で新しい取引を開始します。
  • グローバルテイクプロフィットは、StockSharp の StartProtection ヘルパーを通じて設定されます。距離は TakeProfitPoints に等しい 証券価格ステップを乗算し、MQL コードから「30 * ポイント」の利益目標を再現します。ターゲットに命中すると、 ポジションは成行注文でクローズされます。
  • 元のエキスパートにはストップロスが実装されていないため、ポートには何も追加されません。リスク管理は完全に担当します テイクプロフィットとユーザーの資金管理設定によって異なります。

パラメーター

パラメータ 説明
TradeVolume すべての市場参入に使用されるロットサイズ。この値は、方向を切り替えるときに反転のサイズを調整するためにも使用されます。
SmaPeriod 単純移動平均で使用されるローソク足の数。デフォルトは、EA の 14 期間移動平均と一致します。
StreakThreshold 反転注文が許可される前に、SMA の片側に留まる必要がある連続終値の数。
MinimumDeviation ブレイクアウト条件を確認する、終値と SMA の間の最小絶対距離。
TakeProfitPoints 価格ステップで表される利食い距離。これに商品の PriceStep を掛けて、絶対価格オフセットを取得します。
CandleType SMA を計算し、ストリークカウンターを評価するために使用されるローソク足のタイプ (タイムフレーム)。

注意事項

  • カウンタ ロジックは、SubscribeCandles が提供する完成したキャンドルで動作するため、実装が堅牢になり、 履歴テストと互換性があります。ローソク足が正常である限り、動作はティックベースの MetaTrader バージョンと一致します。 短期の小旅行を捉えるのに十分な粒度です。
  • StockSharp はデフォルトでポジションを集約するため、複数の連続するエントリは単一のポジションとして管理されます。 変動テイクプロフィットディスタンス。これは、MetaTrader がすべての注文で同じテイクプロフィットを行うのと同じです。 現在の平均エントリー価格からの距離は一定のままです。
  • バインディング インフラストラクチャがインジケーターを管理するため、ストラテジーは独自のインジケーターを Strategy.Indicators に追加しません。 寿命は自動的に延長されます。
  • TakeProfitPoints パラメータが有効になるように、特定のブローカー シンボルの価格ステップと出来高の設定を常に検証してください。 希望の絶対ターゲット サイズを生成します。
using System;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Moving average reversal strategy converted from the MetaTrader MA_Reverse expert advisor.
/// Counts how many consecutive closes remain on one side of the SMA and opens a trade once the streak is long enough.
/// </summary>
public class MaReverseStrategy : Strategy
{
	private readonly StrategyParam<int> _smaPeriod;
	private readonly StrategyParam<int> _streakThreshold;
	private readonly StrategyParam<decimal> _minimumDeviation;
	private readonly StrategyParam<DataType> _candleType;

	private int _streak;

	public MaReverseStrategy()
	{
		_smaPeriod = Param(nameof(SmaPeriod), 14)
			.SetDisplay("SMA Period", "Number of candles used by the moving average.", "Indicator");

		_streakThreshold = Param(nameof(StreakThreshold), 3)
			.SetDisplay("Streak Threshold", "Number of consecutive closes required before reversing.", "Logic");

		_minimumDeviation = Param(nameof(MinimumDeviation), 0.0001m)
			.SetDisplay("Minimum Deviation", "Minimum distance between price and SMA to confirm the reversal.", "Logic");

		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe used for SMA calculation.", "General");
	}

	public int SmaPeriod
	{
		get => _smaPeriod.Value;
		set => _smaPeriod.Value = value;
	}

	public int StreakThreshold
	{
		get => _streakThreshold.Value;
		set => _streakThreshold.Value = value;
	}

	public decimal MinimumDeviation
	{
		get => _minimumDeviation.Value;
		set => _minimumDeviation.Value = value;
	}

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

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_streak = 0;
	}

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

		_streak = 0;

		var sma = new SimpleMovingAverage { Length = SmaPeriod };

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

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

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

		var closePrice = candle.ClosePrice;
		var deviation = closePrice - smaValue;

		if (deviation == 0m)
		{
			_streak = 0;
			return;
		}

		if (deviation > 0m)
		{
			// Price above SMA
			if (_streak < 0)
				_streak = 0;
			_streak++;

			if (_streak >= StreakThreshold && deviation > MinimumDeviation)
			{
				// Long streak above SMA => sell (reversal)
				if (Position >= 0)
				{
					SellMarket();
					_streak = 0;
				}
			}
		}
		else
		{
			// Price below SMA
			if (_streak > 0)
				_streak = 0;
			_streak--;

			if (-_streak >= StreakThreshold && -deviation > MinimumDeviation)
			{
				// Long streak below SMA => buy (reversal)
				if (Position <= 0)
				{
					BuyMarket();
					_streak = 0;
				}
			}
		}
	}
}