GitHub で見る

ARD 注文管理 Stochastic 戦略

概要

Ard Order Management 戦略は、MetaTrader の専門家 ARD_ORDER_MANAGEMENT_EA-BETA_1 を StockSharp に転換したものです。元のスクリプトは、新しい注文を出す前に既存のポジションを繰り返し決済することに重点を置き、手動でストップロスとテイクプロフィットを更新するためのヘルパー ルーチンを提供していました。 StockSharp バージョンは、この規律を維持しながら、Stochastic オシレーターに基づくインジケーター駆動の自動化を追加します。

デフォルトの設定は 5 分足チャートでの日中外国為替取引を対象としていますが、ローソク足のタイプは完全に構成可能です。すべての取引ロジックは完成したローソク足で実行され、ソースエキスパートのバー終了時の実行スタイルに忠実に保たれます。

取引ロジック

  • 構成可能なルックバック信号、および減速周期を備えたStochasticオシレーターは、指向性信号を生成します(デフォルト: 5/3/3)。
  • %K が 購入しきい値 (デフォルトでは 80) を上回ってクローズすると、ストラテジーは未決注文をキャンセルし、未決済のショートエクスポージャーをクローズし、設定されたボリュームでロングポジションを入力します。
  • %K が 売りしきい値 (デフォルトでは 20) を下回ってクローズされると、すべての未決注文がキャンセルされ、オープンのロングエクスポージャーがクローズされ、新しいショートがオープンされます。
  • 戦略は、反対の信号が発せられるか、保護出口がトリガーされるまで、新しい位置に留まります。

注文とリスクの管理

  • 新しいエントリーが行われるたびに、この戦略は現在のポジションを完全にフラットにする成行注文を発行し、EA の open_order(CLOSE) の動作を再現します。
  • StartProtection は、StopLossPips および TakeProfitPips パラメータに従って、最初のストップロス注文とテイクプロフィット注文を自動的に送信します。
  • オプションのトレーリング ロジックは、EA の MODIFY 分岐をエミュレートします。終了した各ローソク足は、動的なストップ レベル (ModifyStopLossPips) と変動利益目標 (ModifyTakeProfitPips) を更新できます。価格がいずれかのトレーリングレベルに達すると、利益を確保するかリスクを制限するためにポジションがクローズされます。
  • ピップ変換では、金融商品の PriceStep (小数ピップ外国為替シンボルの 10 倍の調整を含む) が使用されるため、距離ベースのパラメーターは市場全体で一貫したものになります。

パラメーター

  • 出来高 – 新規エントリーの取引高。反対のポジションを閉じるために追加のサイズが自動的に追加されます。
  • TakeProfitPips / StopLossPips – 内蔵保護モジュールに渡される初期保護距離。どちらの順序も無効にするには、0 に設定します。
  • ModifyTakeProfitPips / ModifyStopLossPips – キャンドルごとに再計算されるトレーリング オフセット (ピップ単位)。後続更新を無効にするには、0 に設定します。
  • StochasticPeriod / SignalPeriod / SlowingPeriod – 元のエキスパートからの iStochastic 呼び出しをミラーリングしたオシレーター構成。
  • BuyThreshold / SellThreshold – ロング/ショートの反転を引き起こす買われ過ぎ/売られ過ぎのレベル。
  • CandleType – インジケーターを駆動するタイムフレームまたはカスタム ローソク足データ ソース。

各パラメータは適切な最適化範囲を公開しているため、StockSharp オプティマイザーで代替設定をバックテストできます。

使用上の注意

  • ピップベースのストップが意味のある流動性商品(主要外国為替ペア、インデックスCFD、流動性先物)で最も効果的です。
  • 低速市場で取引する場合は、ノイズや誤った反転を減らすために時間枠を長くします。
  • ライブアカウントで実行する場合は、構成されたボリュームがブローカーの最小値とステップサイズを尊重していることを確認してください。
  • Modify* パラメータをゼロのままにすることで後続ロジックを無効にでき、ソース EA の静的な順序維持を効果的に再現できます。
  • より選択的なエントリが必要な場合は、追加のフィルター (トレンド、ボラティリティ、セッション) と組み合わせてください。コードにより、拡張可能なプロパティが公開されます。

変換の詳細

  • ソースファイル: MQL/9041/ARD_ORDER_MANAGEMENT_EA-BETA_1.mq4
  • コメント化された start() ルーチンで示唆されている Stochastic トリガー ロジックを再作成しました。
  • StockSharp の高レベルの API を通じて、オープン前クローズの規律と保護注文の配置を維持しました。
  • 実装のインジケーター駆動およびイベントベースを維持しながら、EA の手動 MODIFY ブロックを反映するオプションの末尾 exit を追加しました。
using System;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Ard Order Management Stochastic: RSI overbought/oversold reversal
/// with EMA trend filter and ATR-based trailing stops.
/// </summary>
public class ArdOrderManagementStochasticStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _rsiLength;
	private readonly StrategyParam<int> _emaLength;
	private readonly StrategyParam<int> _atrLength;
	private readonly StrategyParam<decimal> _buyThreshold;
	private readonly StrategyParam<decimal> _sellThreshold;

	private decimal _prevRsi;

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

		_rsiLength = Param(nameof(RsiLength), 10)
			.SetDisplay("RSI Length", "RSI period.", "Indicators");

		_emaLength = Param(nameof(EmaLength), 14)
			.SetDisplay("EMA Length", "EMA trend filter period.", "Indicators");

		_atrLength = Param(nameof(AtrLength), 10)
			.SetDisplay("ATR Length", "ATR period for stops.", "Indicators");

		_buyThreshold = Param(nameof(BuyThreshold), 30m)
			.SetDisplay("Buy Threshold", "RSI oversold level for buy.", "Signals");

		_sellThreshold = Param(nameof(SellThreshold), 70m)
			.SetDisplay("Sell Threshold", "RSI overbought level for sell.", "Signals");
	}

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

	public int RsiLength
	{
		get => _rsiLength.Value;
		set => _rsiLength.Value = value;
	}

	public int EmaLength
	{
		get => _emaLength.Value;
		set => _emaLength.Value = value;
	}

	public int AtrLength
	{
		get => _atrLength.Value;
		set => _atrLength.Value = value;
	}

	public decimal BuyThreshold
	{
		get => _buyThreshold.Value;
		set => _buyThreshold.Value = value;
	}

	public decimal SellThreshold
	{
		get => _sellThreshold.Value;
		set => _sellThreshold.Value = value;
	}

	/// <inheritdoc />
	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();

		_prevRsi = 0;
	}

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

		_prevRsi = 0;

		var rsi = new RelativeStrengthIndex { Length = RsiLength };
		var ema = new ExponentialMovingAverage { Length = EmaLength };
		var atr = new AverageTrueRange { Length = AtrLength };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(rsi, ema, atr, ProcessCandle)
			.Start();

		StartProtection(
			takeProfit: new Unit(2, UnitTypes.Percent),
			stopLoss: new Unit(1, UnitTypes.Percent)
		);

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

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

		if (_prevRsi == 0)
		{
			_prevRsi = rsiVal;
			return;
		}

		// Entry: RSI crosses threshold
		if (Position == 0)
		{
			if (rsiVal < BuyThreshold && _prevRsi >= BuyThreshold)
			{
				BuyMarket();
			}
			else if (rsiVal > SellThreshold && _prevRsi <= SellThreshold)
			{
				SellMarket();
			}
		}

		_prevRsi = rsiVal;
	}
}