GitHub で見る

基本 Martingale EA 3

概要

基本的な Martingale EA 3 戦略は、三重指数移動平均 (TEMA) に基づくトレンド フィルターと ATR 駆動のマーチンゲール平均を組み合わせた MetaTrader 5 エキスパート アドバイザーを複製します。変換された StockSharp バージョンは、同じリスク パラメーター、取引ウィンドウ、資金管理ロジックを維持しながら、最適化のために戦略パラメーターを通じてすべてを公開します。

取引ロジック

  1. シグナル生成 – 選択した時間枠の完了したすべてのローソク足で、終値が TEMA 値と比較されます。インジケーターの上で閉じるとロングバスケットが開き、下で閉じるとショートバスケットが開きます。同時にアクティブにできるのは 1 つの方向のみです。
  2. 取引ウィンドウ – 新しいバスケットは StartHourEndHour (為替時間) の間でのみ許可されます。両方の時間が同じ場合、ウィンドウは常に開いているとみなされます。 MT5 の元の TradeAtNewBar スイッチと同様に、新しいバスケットをキャンドルごとに 1 つに制限するには、TradeAtNewBartrue に設定します。
  3. 平均グリッド – ポジションが存在すると、戦略は最悪/最良のエントリー価格からの距離を測定します。市場が少なくとも GridMultiplier × ATR だけ動くたびに、MaxAverageOrders に達するまで、Averaging で定義された方向 (平均下降または平均上昇) に追加注文が追加されます。新しい注文サイズは、選択したマーチンゲール モード (Multiply または Increment) に従います。
  4. 保護的出口 – オプションのストップロスとテイクプロフィットのレベルは、バスケット内の最初の注文から継承されます。さらに、トレーリングブロックは MT5 実装を模倣しています。TrailingStart ポイントの利益の後、ストップは price - TrailingStop (ショートの場合は price + TrailingStop) に移動し、TrailingStep によって締められます。
  5. フラット化 – ストップ、テイクプロフィット、またはトレーリングレベルに触れると、バスケット全体が市場でクローズされ、すべての平均カウンターがリセットされます。

パラメーター

パラメータ 種類 デフォルト 説明
CandleType DataType 上半期の時間枠 戦略を推進するキャンドルシリーズ。
StartVolume decimal 0.01 バスケット内の最初の注文の初期数量。
StopLossPoints decimal 20 価格ステップのストップロス距離。無効にするには、0 に設定します。
TakeProfitPoints decimal 20 価格ステップでの利食い距離。無効にするには、0 に設定します。
StartHour int 3 新しいバスケットを開始できる時間 (両端を含む)。
EndHour int 18 バスケットの作成が停止する時間 (排他的)。
TemaPeriod int 50 TEMA インジケーターの長さ。
BarsCalculated int 3 取引を開始する前に必要な完成したキャンドルの数。
AtrPeriod int 14 平均トゥルーレンジインジケーターの期間。
GridMultiplier decimal 0.75 グリッド間隔を定義する ATR 乗数。
MaxAverageOrders int 3 方向ごとの平均オーダーの最大数 (最初のオーダーを含む)。
Averaging 列挙型 AverageDown ドローダウンの平均化、利益の平均化、または追加のエントリーの無効化のいずれかを選択します。
Martin 列挙型 Multiply 乗算または増分マーチンゲール サイズ設定を選択します。
LotMultiplier decimal 1.5 Multiply マーチンゲール モードで使用される係数。
LotIncrement decimal 0.1 Increment マーチンゲール モードで使用される追加ボリューム。
TradeAtNewBar bool false 新しいバスケットは完成したキャンドルごとに 1 つに制限します。
TrailingStart int 100 トレーリングをアクティブにするために必要なポイントで利益を獲得します。
TrailingStop int 50 トレーリングストップの距離 (ポイント単位)。
TrailingStep int 30 トレーリングストップを再度移動する前の最小限の改善 (ポイント)。

変換メモ

  • StockSharp バージョンは、MT5 インジケーターのセットアップ (TEMA(50) + ATR(14)) を維持し、bar パラメーターを BarsCalculated として公開し、取引前に少なくとも指定されたローソク数を確保します。
  • 出来高処理では商品の MinVolumeMaxVolume、および VolumeStep が考慮されるため、ライブ取引では端数のマーチンゲール ステップであっても為替制限が尊重されます。
  • トレーリング ロジックは、元の損益分岐点とトレーリング ステップの動作に従いますが、StockSharp ポジションは商品によってネッティングされるため、集約されたポジション データを使用して実装されます。
  • StockSharp はすでにチャート パネルで順序と位置の視覚化を提供しているため、MT5 エキスパートからのチャート アノテーションは移植されませんでした。
namespace StockSharp.Samples.Strategies;

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

/// <summary>
/// Basic Martingale EA 3 strategy: WMA crossover with RSI filter.
/// Buys when WMA fast crosses above slow and RSI below midline, sells on opposite conditions.
/// </summary>
public class BasicMartingaleEa3Strategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private readonly StrategyParam<int> _rsiPeriod;

	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 int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }

	public BasicMartingaleEa3Strategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_fastPeriod = Param(nameof(FastPeriod), 5)
			.SetGreaterThanZero()
			.SetDisplay("Fast WMA", "Fast WMA period", "Indicators");
		_slowPeriod = Param(nameof(SlowPeriod), 15)
			.SetGreaterThanZero()
			.SetDisplay("Slow WMA", "Slow WMA period", "Indicators");
		_rsiPeriod = Param(nameof(RsiPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("RSI Period", "RSI period", "Indicators");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevFast = 0;
		_prevSlow = 0;
		_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 rsi = new RelativeStrengthIndex { Length = RsiPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(fast, slow, rsi, ProcessCandle).Start();
	}

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

		if (_hasPrev)
		{
			if (_prevFast <= _prevSlow && fastValue > slowValue && rsiValue < 45 && Position <= 0)
				BuyMarket();
			else if (_prevFast >= _prevSlow && fastValue < slowValue && rsiValue > 55 && Position >= 0)
				SellMarket();
		}
		else
		{
			if (fastValue > slowValue && rsiValue < 45 && Position <= 0)
				BuyMarket();
			else if (fastValue < slowValue && rsiValue > 55 && Position >= 0)
				SellMarket();
		}

		_prevFast = fastValue;
		_prevSlow = slowValue;
		_hasPrev = true;
	}
}