GitHub で見る

ティプ MACD EA 戦略

概要

この戦略は、MQL4 の Tipu MACD EA の高レベルの StockSharp 移植です。これは、MACD ベースのシグナルを使用して単一のシンボルを取引し、元のエキスパートアドバイザーの機能を反映しています。

  • 2 つの構成可能な時間枠を備えたオプションの取引時間フィルター。
  • MACD のゼロラインと信号ラインのクロスオーバー エントリ。EMA の長さとシフトを調整できます。
  • テイクプロフィット、ストップロス、トレーリングストップ、損益分岐点を含む自動ポジション管理。
  • ソースコードの「最大ロット」設定をエミュレートするボリュームキャッピング。

すべての操作は成行注文を使用します。プロテクティブレベルは内部で追跡され、ローソク足がストップロスまたはテイクプロフィットレベルを突破すると注文がクローズされます。

取引ロジック

  1. 構成されたローソク足タイプをサブスクライブし、MovingAverageConvergenceDivergenceSignal インジケーター (MACD ライン + シグナル ライン) を計算します。
  2. 選択したシフト (MacdShift 0 = 現在のローソク足、1 = 前のローソク足) を使用して MACD の値を評価し、クロスオーバー シグナルを構築します。
    • ゼロラインクロスオーバー (オプション) – MACD がゼロを上回ったときに買い、下回ったときに売ります。
    • シグナルラインのクロスオーバー (オプション) – MACD がシグナルラインの上を横切ったときに買い、下を横切ったときに売ります。
  3. ポジションをオープンする前に、フィルターが有効になっている場合、現在の時間が 2 つの時間枠の少なくとも 1 つに属していることを確認してください。
  4. 長い信号が表示された場合:
    • ヘッジが無効でショートがオープンしている場合は、オプションでショートをクローズするか (CloseOnReverseSignal)、または新しい取引をスキップします。
    • TradeVolume と残りの数量のうち小さい方の成行注文を、MaxPositionVolume に達するまで発注します。
    • ロングエントリースナップショットを更新し、有効になっている場合は保護停止/テイクレベルを計算します。
  5. ショートシグナルが現れたら、売り注文の対称ロジックに従います。
  6. ポジションが有効な間、次のことが行われます。
    • 終了した各ローソク足のストップとターゲットを監視し、いずれかのレベルに違反した場合は取引を終了します。
    • トレーリングが有効で、価格が TrailingPips + TrailingCushionPips 進んだ場合、ストップを移動して価格から TrailingPips の距離を維持します。
    • 損益分岐点モジュールが有効になり、利益が RiskFreePips を超えたら、ストップをエントリー価格に移動します。

パラメーター

名前 説明
CandleType MACD の計算に使用されるローソク足シリーズ。
TradeVolume 各市場参入のボリューム (ロット)。
MaxPositionVolume 許容される最大累積長時間または短時間露光。
UseTimeFilter デュアルウィンドウ取引時間フィルターを有効にします。
Zone1StartHour, Zone1EndHour 最初の取引ウィンドウの開始/終了時間 (為替時間を含む)。
Zone2StartHour, Zone2EndHour 2 番目の取引ウィンドウの開始時間と終了時間。
FastPeriod, SlowPeriod, SignalPeriod MACD の高速 EMA、低速 EMA、信号の長さは SMA です。
MacdShift 0 = 現在のバーを評価、1 = 前のバーを評価します (MQL iShift と一致)。
UseZeroCross MACD のゼロラインクロスエントリを有効にします。
UseSignalCross MACD とシグナルラインのクロスエントリーを有効にします。
AllowHedging 最初に反対側を閉じることなく、長時間露光と短時間露光の両方を構築できます。
CloseOnReverseSignal 新しいシグナルが現れたときに反対のポジションを閉じます (ヘッジが無効な場合に使用されます)。
UseTakeProfit, TakeProfitPips 利食い距離 (pips) を有効にして設定します。
UseStopLoss, StopLossPips ストップロス距離 (pips) を有効にして設定します。
UseTrailingStop, TrailingPips, TrailingCushionPips トレーリング管理を有効にし、トレーリング距離とクッション (pips) を設定します。
UseRiskFree, RiskFreePips 利益が指定されたピップを超えたら、ストップを損益分岐点に移動します。

使用上の注意

  • MetaTrader で使用される時間枠 (デフォルトは 15 分足) に一致するようにローソクのタイプを構成します。
  • pip サイズは Security.PriceStep から導出されます。機器にこのメタデータがない場合は、デフォルトの 0.0001 が使用されます。
  • この戦略は成行注文の即時執行を前提としています。ライブで実行するときは、必要に応じて適切な滑り処理を行ってください。
  • ゼロラインエントリとシグナルラインエントリの両方が無効になっている場合、ストラテジはアイドル状態のままです。
namespace StockSharp.Samples.Strategies;

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

/// <summary>
/// Tipu MACD EA strategy: MACD signal line crossover.
/// Buys when MACD crosses above signal, sells when crosses below.
/// </summary>
public class TipuMacdEaStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private readonly StrategyParam<int> _signalPeriod;
	private readonly StrategyParam<int> _signalCooldownCandles;

	private decimal _prevMacd;
	private decimal _prevSignal;
	private int _candlesSinceTrade;
	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 int SignalPeriod { get => _signalPeriod.Value; set => _signalPeriod.Value = value; }
	public int SignalCooldownCandles { get => _signalCooldownCandles.Value; set => _signalCooldownCandles.Value = value; }

	public TipuMacdEaStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_fastPeriod = Param(nameof(FastPeriod), 12)
			.SetGreaterThanZero()
			.SetDisplay("MACD Fast", "MACD fast EMA period", "Indicators");
		_slowPeriod = Param(nameof(SlowPeriod), 26)
			.SetGreaterThanZero()
			.SetDisplay("MACD Slow", "MACD slow EMA period", "Indicators");
		_signalPeriod = Param(nameof(SignalPeriod), 9)
			.SetGreaterThanZero()
			.SetDisplay("Signal Period", "MACD signal period", "Indicators");
		_signalCooldownCandles = Param(nameof(SignalCooldownCandles), 4)
			.SetGreaterThanZero()
			.SetDisplay("Signal Cooldown", "Bars to wait between trades", "Trading");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevMacd = 0;
		_prevSignal = 0;
		_candlesSinceTrade = SignalCooldownCandles;
		_hasPrev = false;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevMacd = 0;
		_prevSignal = 0;
		_candlesSinceTrade = SignalCooldownCandles;
		_hasPrev = false;
		var macd = new MovingAverageConvergenceDivergenceSignal
		{
			Macd = { ShortMa = { Length = FastPeriod }, LongMa = { Length = SlowPeriod } },
			SignalMa = { Length = SignalPeriod }
		};
		var subscription = SubscribeCandles(CandleType);
		subscription.BindEx(macd, ProcessCandle).Start();
	}

	private void ProcessCandle(ICandleMessage candle, IIndicatorValue macdValue)
	{
		if (candle.State != CandleStates.Finished) return;
		if (!macdValue.IsFinal) return;

		if (_candlesSinceTrade < SignalCooldownCandles)
			_candlesSinceTrade++;

		if (macdValue is not MovingAverageConvergenceDivergenceSignalValue typed) return;
		if (typed.Macd is not decimal macdMain || typed.Signal is not decimal signal) return;

		if (_hasPrev)
		{
			if (_prevMacd <= _prevSignal && macdMain > signal && Position <= 0 && _candlesSinceTrade >= SignalCooldownCandles)
			{
				BuyMarket();
				_candlesSinceTrade = 0;
			}
			else if (_prevMacd >= _prevSignal && macdMain < signal && Position >= 0 && _candlesSinceTrade >= SignalCooldownCandles)
			{
				SellMarket();
				_candlesSinceTrade = 0;
			}
		}

		_prevMacd = macdMain;
		_prevSignal = signal;
		_hasPrev = true;
	}
}