GitHub で見る

多通貨テンプレート戦略

概要

多通貨テンプレート戦略は、MetaTrader 4 エキスパート アドバイザー 多通貨テンプレート v4 の変換です。オリジナルの EMA クロスオーバー エントリー ロジックを、マーチンゲール スタイルの平均化、ピップベースの保護レベル、および StockSharp の高レベル API を使用したトレーリング管理とともに再現します。デフォルトの時間枠は 5 分足のローソク足ですが、パラメーターを通じて変更できます。

トレードロジック

  • 2 つの指数移動平均 (EMA 20 と EMA 50) が、選択した時間枠の終了したローソク足ごとに計算されます。
  • 高速の EMA (20) が低速の EMA (50) を上回って終了すると、ロングシグナルが表示されます。速い EMA が遅い EMA を下回って終了すると、短いシグナルが表示されます。
  • Order Method パラメータは、戦略が両方のシグナルに作用するか、取引をロングのみまたはショートのみの操作に制限するかを決定します。
  • 維持されるネット ポジションは方向ごとに 1 つだけです。新しいシグナルが到着すると、ストラテジーは要求されたサイドをオープンする前に反対のポジションをクローズします。

ポジション管理

  • ストップロス / テイクプロフィット – 距離は MetaTrader ピップスで入力されます。これらは証券価格ステップを使用して価格単位に変換され、4 桁および 5 桁の外国為替記号の元の処理が再現されます。
  • トレーリングストップ – 価格が Trailing Stop (pts) までポジションに有利に動くと有効になり、Trailing Step (pts) がさらに改善するたびに引き締められます。
  • Martingale 平均 – 有効にすると、現在のポジションに対して Step (pts) ごとに追加の成行注文が送信されます。それぞれの新しい注文量は Lot Multiplier によって調整され、ポジションがクローズされるまでこのプロセスが繰り返されます。
  • 平均テイクプロフィット – 2 つ以上の平均注文がオープンしている場合、テイクプロフィットターゲットはオプションで加重ポジション価格に Average TP Offset (pts) を加えた値を使用して、MetaTrader の「TP 平均」動作をエミュレートできます。

パラメーター

名前 説明 デフォルト
注文方法 取引方向 (買いと売り、買いのみ、売りのみ)。 売買
ボリューム(ロット) 基本市場注文サイズ。 0.01
ストップロス (pips) プロテクティブストップ距離(MetaTrader ピップス)。 50
利益確定 (pips) 利益目標距離 (MetaTrader ピップ単位)。 100
トレーリングストップ (ポイント) トレーリング ストップのアクティブ化しきい値 (MetaTrader ポイント単位)。 15
トレーリングステップ (ポイント) トレーリングストップを移動する前に、最小限の改善が必要です。 5
Martingale を有効にする ボリュームの増加に応じて平均化ダウン/アップを有効にします。 本当の
ロット乗数 すべての新しい平均化注文に適用されるボリューム乗数。 1.2
ステップ (ポイント) 次の平均注文を出すまでの MetaTrader ポイントの距離。 150
平均テイクプロフィット 複数の注文が存在する場合、固定または平均のテイクプロフィットを切り替えます。 本当の
平均 TP オフセット (pts) MetaTrader ポイントのオフセットが平均テイクプロフィットに適用されます。 20
キャンドルの種類 インジケーターの計算に使用されるローソク足のタイプ (時間枠)。 5分キャンドル

元のExpert Advisorとの違い

  • StockSharp は、個々の MetaTrader チケットを管理する代わりに、ネット ポジションを実行します。マーチンゲール モジュールは、個別のチケット固有のターゲットを添付するのではなく、ネット ポジション サイズを増やします。
  • マルチシンボル取引は、証券ごとに 1 つずつ、複数の戦略インスタンスを起動することによって実現する必要があります。元のエキスパート アドバイザは、1 つの EA インスタンス内の組み込みの複数通貨リストをサポートしていました。
  • 資金管理チェック (CheckMoneyForTradeCheckVolumeValue) とブローカー固有の制限は、StockSharp の注文検証に置き換えられます。

使用上の注意

  1. セキュリティメタデータ (価格ステップと小数点) が商品と一致していることを確認して、ピップ変換が正確な状態を維持できるようにします。
  2. トレーリング ストップとマーチンゲール ロジックは、デフォルトでローソク足の終値に作用します。より反応的な動作を行うには、追加のデータ ソース (相場または取引) をフックし、そこから管理ヘルパーを呼び出します。
  3. 成行注文が使用されるため、スリッページ制御は接続されているブローカーまたはシミュレーターに委任されます。
namespace StockSharp.Samples.Strategies;

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

/// <summary>
/// Multi Currency Template strategy: EMA crossover with trend confirmation.
/// Buys when fast EMA crosses above slow EMA, sells on the opposite cross.
/// </summary>
public class MultiCurrencyTemplateStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;

	private decimal _prevFast;
	private decimal _prevSlow;
	private bool _hasPrev;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
	public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }

	public MultiCurrencyTemplateStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_fastPeriod = Param(nameof(FastPeriod), 20)
			.SetGreaterThanZero()
			.SetDisplay("Fast Period", "Fast EMA period", "Indicators");
		_slowPeriod = Param(nameof(SlowPeriod), 50)
			.SetGreaterThanZero()
			.SetDisplay("Slow Period", "Slow EMA period", "Indicators");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevFast = 0m;
		_prevSlow = 0m;
		_hasPrev = false;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_hasPrev = false;
		var fast = new ExponentialMovingAverage { Length = FastPeriod };
		var slow = new ExponentialMovingAverage { Length = SlowPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(fast, slow, ProcessCandle).Start();
	}

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

		if (_hasPrev)
		{
			if (_prevFast <= _prevSlow && fast > slow && Position <= 0) BuyMarket();
			else if (_prevFast >= _prevSlow && fast < slow && Position >= 0) SellMarket();
		}

		_prevFast = fast;
		_prevSlow = slow;
		_hasPrev = true;
	}
}