GitHub で見る

ダフ屋 EMA のシンプルな戦略

概要

ダフ屋 EMA シンプル戦略 は、MetaTrader エキスパート アドバイザー ScalperEMAEASimple を変換したものです。高速/低速の指数移動平均、確率的オシレーター、平均方向性インデックス (ADX) フィルターの組み合わせを使用して、既存のトレンド内の短期間のプルバック エントリーを特定します。この戦略は、流動的なFXペアの日中スキャルピング向けに設計されていますが、ピップベースのリスク管理が理にかなっているあらゆる商品に適用できます。

この実装は、StockSharp の高レベルの API に従い、終了したキャンドルのみを評価します。すべての計算は履歴データを再処理することなく段階的に実行されるため、ロジックはライブ取引に適しています。

インジケータースタック

  • 高速 EMA (FastEmaPeriod) – 短期的な勢いを検出します。
  • スロー EMA (SlowEmaPeriod) – 一般的なトレンドの方向を定義します。
  • Stochastic オシレーター (StochasticLengthStochasticKPeriodStochasticDPeriod) – 売られすぎ/買われすぎの境界付近での勢いの反転を追跡します。
  • 平均方向性インデックス – トレンドが過度に強くなった場合(AdxThresholdを上回るADX)、取引を拒否します。

確率オシレーターは、%K ラインが売られ過ぎレベルを上回ったとき (長いセットアップ)、または買われすぎレベルを下回ったとき (短いセットアップ) に必ず確認シグナルを発します。 EMA ペアは方向性フィルターを提供し、ADX コンポーネントはエントリーが暴走トレンドではなく穏やかなリトレースメントに制限されるようにします。

エントリーロジック

  1. ローソク足は遅い EMA のトレンド側で閉じる必要があり、速い EMA はその方向と一致する必要があります (ロングの場合は fast > slow、ショートの場合は fast < slow)。
  2. ローソク足とスロー EMA の間の距離は、ローソク足の範囲よりも小さく、前の 3 つの距離よりも狭い必要があります。この動作により、元の MQL コードからプルバック検出ループが再作成されます。
  3. ローソク本体が速い EMA を通過するか、速い EMA 自体が遅い EMA を通過します。この状態はブレイクアウトのトリガーとして機能します。
  4. 確率的オシレーターは、最後の ConditionWindowBars ローソク足内の極端なゾーンからクロスバックして勢いを確認する必要があります。
  5. ADX は AdxThreshold 未満に維持する必要があり、ボラティリティが急激に加速した場合の取引を妨げます。
  6. 少なくとも SignalCooldownBars 個のローソク足が、同じ方向の 2 つの連続するシグナル間を通過する必要があります。

すべてのチェックに合格すると、戦略は反対のエクスポージャーを閉じ、検出された方向に新しい成行注文を開きます。

出口ロジックとリスク管理

  • 最初のストップロスは、エントリー価格から StopLossPips (商品のピップサイズを使用して価格に変換) に設定されます。
  • 未実現利益が TrailingActivationPips に達すると、トレーリング ストップは自動的に TrailingDistancePips の距離を維持します。
  • 反対のシグナルは、新たな取引を確立する前にフラットポジションを強制します。

すべての保護注文は、リスク管理を現在のポジション量と同期させるために、StockSharp の SetStopLoss ヘルパーを通じて管理されます。

パラメーター

パラメータ 説明
Volume 各シグナルの基本取引量。この戦略は、方向を変えるときに完全な反転を確実にするために、既存のエクスポージャーを自動的に追加します。
FastEmaPeriod / SlowEmaPeriod 指数移動平均の期間の長さ。
StochasticLength, StochasticKPeriod, StochasticDPeriod オリジナルの EA のデフォルトをミラーリングした Stochastic オシレーター構成。
StochasticOversold / StochasticOverbought リトレースメントゾーンを定義する極端なレベル。
AdxThreshold 取引を拒否する前に許可される最大値は ADX です。
SignalCooldownBars 同じ方向の連続する信号間の最小バー。
ConditionWindowBars リトレースメント、EMA ブレイクアウト、確率的確認が一致する必要があるバーの数。
StopLossPips ピップ単位で表される初期のストップロス距離。
TrailingDistancePips トレーリングストップが作動すると維持される距離。
TrailingActivationPips トレーリングストップを発動する利益の閾値。
CandleType すべてのインジケーターに使用されているキャンドルシリーズ。デフォルトは 5 分の時間枠です。

実装メモ

  • Pip 変換は手段 PriceStep に依存します。小数点以下 3 桁または 5 桁の商品の場合、ピップ係数は MetaTrader の規則に合わせて 10 倍されます。
  • この戦略は完了したローソク足のみを処理するため、実行は各バーの終了後に行われます。
  • 内部状態変数には、履歴全体をスキャンせずに元のエキスパート アドバイザーが使用したルックバック ウィンドウを再現するために、リトレースメント、EMA ブレイクアウト、および確率的確認の最後のインデックスが保存されます。

使用法

  1. 構成されたセキュリティとポートフォリオを使用して、戦略を Connector または Trader インスタンスにアタッチします。
  2. 証券に pip から価格への変換に有効な PriceStep があることを確認してください。
  3. 金融商品のボラティリティに応じてパラメーターを調整します。遅い EMA は、ソース EA と一致するようにデフォルトで 740 に設定されていますが、より速い市場では設定を短くするとメリットが得られる場合があります。
  4. 戦略を開始します。上記の条件が満たされると、成行注文と保護注文が自動的に生成されます。

免責事項: この戦略は教育目的で移植されたものです。ライブキャピタルを取引する前に、徹底的なフォワードテストとリスク分析を行うことをお勧めします。

using System;

using Ecng.Common;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// EMA scalper strategy combining fast/slow EMA trend with stochastic momentum.
/// Buys when fast EMA > slow EMA and stochastic is oversold.
/// Sells when fast EMA below slow EMA and stochastic is overbought.
/// </summary>
public class ScalperEmaSimpleStrategy : Strategy
{
	private readonly StrategyParam<int> _fastEmaPeriod;
	private readonly StrategyParam<int> _slowEmaPeriod;
	private readonly StrategyParam<decimal> _stochOversold;
	private readonly StrategyParam<decimal> _stochOverbought;
	private readonly StrategyParam<DataType> _candleType;

	public int FastEmaPeriod
	{
		get => _fastEmaPeriod.Value;
		set => _fastEmaPeriod.Value = value;
	}

	public int SlowEmaPeriod
	{
		get => _slowEmaPeriod.Value;
		set => _slowEmaPeriod.Value = value;
	}

	public decimal StochOversold
	{
		get => _stochOversold.Value;
		set => _stochOversold.Value = value;
	}

	public decimal StochOverbought
	{
		get => _stochOverbought.Value;
		set => _stochOverbought.Value = value;
	}

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

	public ScalperEmaSimpleStrategy()
	{
		_fastEmaPeriod = Param(nameof(FastEmaPeriod), 20)
			.SetDisplay("Fast EMA", "Fast EMA period", "Indicators");

		_slowEmaPeriod = Param(nameof(SlowEmaPeriod), 50)
			.SetDisplay("Slow EMA", "Slow EMA period", "Indicators");

		_stochOversold = Param(nameof(StochOversold), 10m)
			.SetDisplay("Stochastic Oversold", "Oversold level", "Indicators");

		_stochOverbought = Param(nameof(StochOverbought), 90m)
			.SetDisplay("Stochastic Overbought", "Overbought level", "Indicators");

		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
			.SetDisplay("Candle Type", "Primary candle series", "General");
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		var fastEma = new ExponentialMovingAverage { Length = FastEmaPeriod };
		var slowEma = new ExponentialMovingAverage { Length = SlowEmaPeriod };
		var stochK = new StochasticK { Length = 14 };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(fastEma, slowEma, stochK, ProcessCandle)
			.Start();

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

	private void ProcessCandle(ICandleMessage candle, decimal fastValue, decimal slowValue, decimal stochK)
	{
		if (candle.State != CandleStates.Finished)
			return;

		// Buy: uptrend (fast > slow) + stochastic oversold
		if (fastValue > slowValue && stochK < StochOversold && Position <= 0)
		{
			BuyMarket(Position < 0 ? Math.Abs(Position) + 1 : 1);
		}
		// Sell: downtrend (fast < slow) + stochastic overbought
		else if (fastValue < slowValue && stochK > StochOverbought && Position >= 0)
		{
			SellMarket(Position > 0 ? Math.Abs(Position) + 1 : 1);
		}
	}
}