GitHub で見る

ROC 戦略

概要

ROC 戦略は、MQL/26938/ROC.mq4 に保存されている MetaTrader エキスパート アドバイザーの StockSharp ポートです。単一のシンボルで動作し、一連の線形加重移動平均 (LWMA)、カスタム変化率 (ROC) モデル、より高いタイムフレームのモメンタム、および月次の MACD フィルターを使用して価格アクションを評価します。損益分岐点、ピップベースのトレーリングストップ、株式保護、通貨ベースの利益目標などの元の資金管理機能は維持されます。

エントリーロジック

  1. この戦略は 3 つのデータ ストリームをサブスクライブします。
    • CandleType プロパティによって定義されるプライマリ取引ローソク足。
    • 14期間モメンタムオシレーターのより高い時間枠(取引時間枠に従って自動的に選択されます)。
    • MACD 確認フィルターの月ごとのローソク足。
  2. ポジションをオープンするには、終了した取引ローソクごとに次の条件が満たされる必要があります。
    • カスタム ROC モデルは、買いの場合は上昇トレンド (Line4 < Line5)、売りの場合は下降トレンド (Line4 > Line5) をレポートする必要があります。
    • 一般的な価格に基づいて計算された高速 LWMA は、買いの場合は低速 LWMA より上で、売りの場合は下で取引される必要があります。
    • より高い時間枠から取得した最後の 3 つのモメンタム測定値のいずれかが、設定された買いまたは売りのしきい値 (100 からの絶対偏差) を超える必要があります。
    • 月次の MACD メインラインは、買いの場合はシグナルラインより上に、売りの場合はシグナルラインより下にある必要があります。
    • ポジションのサイジングは MaxTrades の制限を尊重し、オプションで IncreaseFactor がゼロより大きい場合、連続損失後の次の取引量をスケーリングします。

終了ロジック

  • 従来のストップロス注文と利食い注文は、ポジションサイズが変更されるとすぐに MetaTrader ポイントで予測されます。
  • オプションの損益分岐点ブロックは、ポイント単位のトリガー距離に達すると、エントリー価格に設定されたオフセットを加えた値に保護ストップを移動します。
  • ピップベースのトレーリングストップは、ローソク足が閉じるたびにストップ値を引き締めます。
  • 資金管理チェックは、通貨目標またはパーセント目標に達するとポジションをクローズし、利益が TakeProfitMoney を超えた後に StopLossMoney を超える引き戻しを検出することで変動利益を追跡することができます。
  • エクイティストップは、変動ドローダウンを記録された最高のエクイティと比較し、許容パーセンテージを超えた場合にポジションを清算します。
  • ExitStrategytrue に設定すると、緊急出口ルーチンが実行され、市場での現在のポジションが閉じられます。

パラメーター

名前 説明
LotSize 各シグナルでオープンされた基本取引量。
IncreaseFactor 連続して負けたトレードの後、次のボリュームを再計算します。
FastMaPeriod / SlowMaPeriod LWMA トレンド フィルターの長さ。
PeriodMa0, PeriodMa1, BarsV, AverBars, KCoefficient カスタム ROC トレンド モデルを定義します。
MomentumBuyThreshold, MomentumSellThreshold より高いタイムフレームのモメンタム フィルターで使用される 100 からの最小絶対偏差。
StopLossSteps, TakeProfitSteps 初期保護距離は MetaTrader ポイントで表されます。
TrailingStopSteps Pip ベースのトレーリング ストップ。
UseBreakEven, BreakEvenTriggerSteps, BreakEvenOffsetSteps 損益分岐点モジュールを構成します。
UseTpInMoney, TpInMoney, UseTpInPercent, TpInPercent 金額とパーセントに基づいたテイクプロフィットターゲット。
EnableMoneyTrailing, TakeProfitMoney, StopLossMoney Money トレーリングモジュールパラメータ。
UseEquityStop, TotalEquityRisk 株式保護の設定。
MaxTrades 方向ごとのスケールインの最大数。
ExitStrategy 有効にすると、即座にフラットな位置が強制されます。

注意事項

  • モメンタム指標のより高い時間枠は、MetaTrader コードの元の switch ステートメントと一致するように、取引時間枠から自動的に導出されます。
  • すべてのインジケーターの計算では高レベルの Bind API が使用されるため、手動のデータ リクエストは必要ありません。
  • この戦略はネッティングのみです。ショートを保持している間に新しいロングシグナルが現れると、ロングに入る前にショートエクスポージャーが最初にクローズされ、非ヘッジ口座の元の EA の動作を反映します。
namespace StockSharp.Samples.Strategies;

using System;

using Ecng.Common;

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

/// <summary>
/// Rate of Change strategy: uses ROC indicator with WMA trend filter.
/// Buys when ROC crosses above zero and fast WMA > slow WMA.
/// Sells when ROC crosses below zero and fast WMA less than slow WMA.
/// </summary>
public class RocStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _rocPeriod;
	private readonly StrategyParam<int> _fastMaPeriod;
	private readonly StrategyParam<int> _slowMaPeriod;

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

	public int RocPeriod
	{
		get => _rocPeriod.Value;
		set => _rocPeriod.Value = value;
	}

	public int FastMaPeriod
	{
		get => _fastMaPeriod.Value;
		set => _fastMaPeriod.Value = value;
	}

	public int SlowMaPeriod
	{
		get => _slowMaPeriod.Value;
		set => _slowMaPeriod.Value = value;
	}

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

		_rocPeriod = Param(nameof(RocPeriod), 12)
			.SetGreaterThanZero()
			.SetDisplay("ROC Period", "Rate of Change period", "Indicators");

		_fastMaPeriod = Param(nameof(FastMaPeriod), 5)
			.SetGreaterThanZero()
			.SetDisplay("Fast WMA", "Fast WMA period", "Indicators");

		_slowMaPeriod = Param(nameof(SlowMaPeriod), 20)
			.SetGreaterThanZero()
			.SetDisplay("Slow WMA", "Slow WMA period", "Indicators");
	}

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

		var roc = new RateOfChange { Length = RocPeriod };
		var fastMa = new WeightedMovingAverage { Length = FastMaPeriod };
		var slowMa = new WeightedMovingAverage { Length = SlowMaPeriod };

		decimal? prevRoc = null;

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(roc, fastMa, slowMa, (candle, rocVal, fastMaVal, slowMaVal) =>
			{
				if (candle.State != CandleStates.Finished)
					return;

				if (!IsFormedAndOnlineAndAllowTrading())
					return;

				if (prevRoc.HasValue)
				{
					if (prevRoc.Value <= 0 && rocVal > 0 && fastMaVal > slowMaVal && Position <= 0)
						BuyMarket();
					else if (prevRoc.Value >= 0 && rocVal < 0 && fastMaVal < slowMaVal && Position >= 0)
						SellMarket();
				}

				prevRoc = rocVal;
			})
			.Start();

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