GitHub で見る

RobotPowerM5 Meta4 V12 戦略

概要

RobotPowerM5 Meta4 V12 戦略は、MetaTrader 4 Expert Advisor RobotPowerM5_meta4V12.mq4 の C# ポートです。オリジナルの EA 5 分足の外国為替チャート用に設計されており、強気のパワーと弱気のパワーのバランスを評価して、新しいチャートかどうかを決定します。 ロングまたはショートポジションをオープンする必要があります。 StockSharp バージョンは、一度に 1 つの位置の動作を維持し、ポイントを再現します。 ベースのストップロス/テイクプロフィット設定と、市場に達したら徐々に利益を確定させるトレーリングストップロジックを再実装します。 貿易に有利な動きをする。

取引ロジック

  1. インジケーターエンジン
    • デフォルトでは 5 分足のローソク足が登録されています (時間枠は CandleType パラメーターで設定可能です)。
    • StockSharp インジケーターのペア、BullsPowerBearsPower は、設定された 平均化期間。
    • 結合された値 BullsPower + BearsPower は、 MQL コード。常に最後に完全に閉じたバーで動作します。
  2. エントリールール
    • オープンなポジションがなく、ブルズ/ベアズパワーの遅延合計がプラスの場合、成行買い注文が発行されます。
    • オープンなポジションがなく、遅延合計が マイナスの場合、成行売り注文が発行されます。
    • ポジションがアクティブな間はシグナルは無視されます。取引は保護的出口を通じてのみ管理されます。
  3. ボリューム処理
    • Volume パラメータは、リクエストされたロットサイズを表します。これは BuyMarket / SellMarket に直接渡されるため、 必要に応じて、コネクタを使用して機器のロットステップに丸めます。

リスク管理

  • ストップロス – 最初のストップは平均約定価格から StopLossPoints MetaTrader ポイント離れた位置に配置されます。レベルは ローソク足の安値(ロングの場合)または高値(ショートの場合)で監視されます。かつては市場で戦略を終了したことがある。
  • 利益確定 – 利益目標はエントリーから TakeProfitPoints ポイントで、ローソク足の高値/安値に基づいて評価されます。 ターゲットがバー内にヒットしたときに MT4 がポジションを閉じる方法。
  • トレーリング ストップ – 価格が取引に有利に動いた後、TrailingStopPoints を超えてトレーリング ストップが有効になります。 ロングポジションの場合、ストップはreferencePrice - trailingDistanceにシフトされ、基準はローソク足の最大値になります。 近くて高い。ショートの場合、ローソク足の終値と安値の最小値を使用して、ストップは referencePrice + trailingDistance に従います。 これは、最初に OrderModify で実装された EA のトレーリング動作を再現します。

パラメーター

名前 説明 デフォルト 注意事項
BullBearPeriod ブルズパワーインジケーターとベアズパワーインジケーターの両方に供給される平均期間。 5 値を増やすと、運動量フィルターが滑らかになります。
Volume エントリーごとにリクエストされたロットサイズ。 1 実際の取引量はブローカーのロットステップと制限によって異なります。
StopLossPoints 初期保護停止距離 (MetaTrader ポイント)。 45 ハードストップロスを無効にするには、0 に設定します。
TakeProfitPoints MetaTrader ポイント単位のテイクプロフィット距離。 150 固定利益目標なしで取引するには、0 に設定します。
TrailingStopPoints 取引が利益を上げた後にトレーリングストップが使用する距離。 15 末尾を無効にするには、0 に設定します。
CandleType インジケーターの計算に使用される時間枠。 5m time frame 必要に応じて、他の DataType を選択できます。

実装メモ

  • この戦略は、すべてのリスク レベル (ストップロス、テイクプロフィット、トレーリング ストップ) を内部に保存し、ローソク足の時点で市場終了を発行します。 価格のしきい値に違反したことを確認します。これは、注文がティックごとに変更される MT4 のアプローチを反映しています。
  • インジケーターのサブスクリプションは Subscription.Bind を介して接続され、ブルズ パワーとベアーズ パワーの両方を単一のコールバックに供給します。
  • ポイント サイズは Security.PriceStep から導出され、ティックで引用する商品とのパラメーターの互換性を維持します。 ピップス、またはセント。
  • エントリーチェックでは常に 以前の インジケーター値が使用され、部分的に形成されたローソク足が注文をトリガーしないようにします。

MQL バージョンとの違い

  • 取引管理では、所定のストップロス注文を変更する代わりに、明示的な市場退場を使用します。これは全体的により堅牢です 異なる StockSharp コネクタを使用しても同じ結果が得られます。
  • パラメータ範囲は、無効な値(負の末尾のストップなど)が含まれないように、StrategyParam ヘルパーによって検証されます。 構成時に拒否されました。
  • 詳細なロギング フック、チャート出力、およびキャンドル サブスクリプションは、手動ティック ループの代わりに、StockSharp の高レベルの API を利用します。
  • MT4 スクリプトに存在するエキスパート識別子の文字列は、StockSharp では必要ないため、省略されています。
using System;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// RobotPowerM5: RSI momentum with EMA filter and ATR stops.
/// </summary>
public class RobotPowerM5Meta4V12Strategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _rsiLength;
	private readonly StrategyParam<int> _emaLength;
	private readonly StrategyParam<int> _atrLength;

	private decimal _prevRsi;
	private decimal _entryPrice;
	private int _cooldown;

	public RobotPowerM5Meta4V12Strategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe.", "General");

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

		_emaLength = Param(nameof(EmaLength), 50)
			.SetDisplay("EMA Length", "Trend filter.", "Indicators");

		_atrLength = Param(nameof(AtrLength), 14)
			.SetDisplay("ATR Length", "ATR period.", "Indicators");
	}

	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;
	}

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

		_prevRsi = 0;
		_entryPrice = 0;
		_cooldown = 0;
	}

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

		_prevRsi = 0;
		_entryPrice = 0;
		_cooldown = 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();

		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 || atrVal <= 0)
		{
			_prevRsi = rsiVal;
			return;
		}

		if (_cooldown > 0) { _cooldown--; _prevRsi = rsiVal; return; }

		var close = candle.ClosePrice;

		if (Position > 0)
		{
			if (close >= _entryPrice + atrVal * 2.5m || close <= _entryPrice - atrVal * 1.5m || rsiVal > 80)
			{
				SellMarket();
				_entryPrice = 0;
				_cooldown = 10;
			}
		}
		else if (Position < 0)
		{
			if (close <= _entryPrice - atrVal * 2.5m || close >= _entryPrice + atrVal * 1.5m || rsiVal < 20)
			{
				BuyMarket();
				_entryPrice = 0;
				_cooldown = 10;
			}
		}

		if (Position == 0)
		{
			if (rsiVal > 65 && _prevRsi <= 65 && close > emaVal)
			{
				_entryPrice = close;
				BuyMarket();
				_cooldown = 10;
			}
			else if (rsiVal < 35 && _prevRsi >= 35 && close < emaVal)
			{
				_entryPrice = close;
				SellMarket();
				_cooldown = 10;
			}
		}

		_prevRsi = rsiVal;
	}
}