GitHub で見る

Up3x1 プレミアム 2vM 戦略

概要

この戦略は、MetaTrader 4 エキスパート アドバイザー up3x1_Premium_2vM を直接移植したものです。単一のシンボルを取引し、常に最大 1 つのポジションをオープンしたままにします。エントリーは、平滑化移動平均、強いローソク足の範囲、毎日の深夜ブレイクアウトフィルターの組み合わせに依存します。リスクは、価格ポイントで表される固定のテイクプロフィットとストップロスの距離によって管理されます。また、オプションのトレーリング ストップは、市場がポジションに有利に動くとストップを継続的に引き締めるオリジナルの EA の動作を再現します。

仕組み

  1. 主要な時間枠は構成可能です。 EA は元々チャートの時間枠を使用していました。期間 12 と 26 の 2 つの平滑移動平均 (SMMA) は、典型的な価格を使用してローソク足サブスクリプションにバインドされています。
  2. 別の日次ローソク足ストリームは、深夜ブレイクアウト フィルターと 10 期間日次単純移動平均の MQL ロジックで使用される D1 データを再構築します。
  3. フラットの場合、戦略は前の 2 つの完了したローソク足とキャッシュされた SMMA 値を評価します。
    • ロング バイアス: 両方の始値が増加する間に速い SMMA が遅い SMMA を上抜けるか、最後のローソク足が設定されたレンジしきい値を上回る強気の実体を示すか、または最新の日次ローソク足が大きなレンジを経て強気で閉じるかのいずれかです。オリジナルの EA では、日次の SMA を売値と比較しました。条件は常に true と評価されるため、互換性のために保存されています。
    • ショート バイアス: 弱気のレンジとクロスオーバーを使用したロング ルールの対称条件。
    • ロング条件が満たされると、成行買いが発行されます。それ以外の場合、空売り条件が成立した場合は成行売りが行われます。要求されたロット サイズは、注文を送信する前に証券ボリューム ステップに正規化されます。
  4. ポジションがオープンしている間、戦略は前のローソク足からの高速/低速 SMMA 値を監視します。それらの絶対差が ConvergenceTolerance を下回ると、ポジションはクローズされ、エキスパートアドバイザーでの均等性チェックが再現されます。
  5. 後続のモジュールは、平均エントリー価格を追跡します。価格がトレーリングディスタンスを超えて移動すると、設定されたギャップを維持するためにストップレベルが前進します。そのレベルにタッチするとポジションが即座に閉じられ、MQL からの繰り返しの OrderModify 呼び出しがエミュレートされます。

パラメーター

名前 デフォルト 説明
CandleType TimeFrame(1h) エントリーに使用される主な時間枠。
FastMaPeriod 12 高速平滑移動平均の長さ (典型的な価格)。
SlowMaPeriod 26 低速平滑移動平均の長さ (典型的な価格)。
RangeThreshold 0.0060 運動量フィルターに必要な最小ローソク足範囲。
BodyThreshold 0.0050 範囲条件の最小キャンドル本体サイズ。
DailyRangeThreshold 0.0060 真夜中のブレイクアウトフィルターの最新の日次ローソク足の最小開閉距離。
TakeProfitPoints 150 価格ポイントで表される利食い距離。無効にするには、0 に設定します。
StopLossPoints 100 価格ポイントで表されるストップロス距離。無効にするには、0 に設定します。
TrailingStopPoints 10 価格とトレーリングストップの間の距離。末尾を無効にするには、0 に設定します。
TradeVolume 0.05 出来高を正規化する前の成行注文に使用されるロットサイズ。
ConvergenceTolerance 0.00001 ポジション清算を引き起こす SMMA 間の最大差。

注意事項

  • この戦略では、毎日の SMA 比較が常に true になるという元の EA の特徴が維持され、MQL ソースとの機能の同等性が保証されます。
  • ストップロス注文とテイクプロフィット注文は StartProtection を通じて登録されるため、利用可能な場合にはブローカーのステップ サイズに自動的に適応します。
  • 後続ロジックには、正の TrailingStopPoints 値と有効な Security.PriceStep の両方が必要です。どちらかの情報が欠落している場合、ストップは追跡されません。
  • ボリュームの正規化では、交換制約 (VolumeStepVolumeMinVolumeMax) が尊重されます。カスタム ロジックの追加後に、TradeVolume の負の値を使用して、パーセントベースのサイジングをエミュレートできます。
using System;

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

namespace StockSharp.Samples.Strategies;

public class Up3x1Premium2VmStrategy : Strategy
{
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private readonly StrategyParam<int> _cooldownCandles;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevFast;
	private decimal _prevSlow;
	private bool _hasPrev;
	private int _cooldownRemaining;

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

	public Up3x1Premium2VmStrategy()
	{
		_fastPeriod = Param(nameof(FastPeriod), 20).SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
		_slowPeriod = Param(nameof(SlowPeriod), 80).SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
		_cooldownCandles = Param(nameof(CooldownCandles), 100).SetDisplay("Cooldown", "Candles between signals", "General");
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame()).SetDisplay("Candle Type", "Candle timeframe", "General");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevFast = default;
		_prevSlow = default;
		_hasPrev = default;
		_cooldownRemaining = default;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevFast = 0;
		_prevSlow = 0;
		_hasPrev = false;
		_cooldownRemaining = 0;

		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) { _prevFast = fast; _prevSlow = slow; _hasPrev = true; return; }

		if (_cooldownRemaining > 0)
		{
			_cooldownRemaining--;
			_prevFast = fast;
			_prevSlow = slow;
			return;
		}

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