GitHub で見る

Arttrader v1.5 戦略

概要

Arttrader v1.5戦略は、元のMetaTrader 5エキスパートアドバイザーから変換されたトレンドフォローシステムです。上位時間軸の指数移動平均(EMA)傾斜フィルターと短期価格アクションエントリーモデルを組み合わせています。StockSharpバージョンは、ソースコードのリスク管理動作を維持しており、大きなローソク足ギャップの厳格な処理、注文の時間窓、価格距離に基づく緊急出口が含まれています。

2つのローソク足ストリームが同時に使用されます:

  • 取引ローソク足(デフォルト5分)はエントリー、エグジット、およびすべての価格ベースのフィルターを生成します。
  • トレンドローソク足(デフォルト1時間)は上位時間軸トレンドの傾斜を測定するEMAを供給します。

戦略はネットポジションで単一銘柄を取引します。反対シグナルが現れると、既存のエクスポージャーがフラット化され、シグナル方向に新しい成行注文が送信されます。

シグナルロジック

  1. EMA傾斜フィルター
    • ローソク足始値の時間足EMAはSlopeSmallからSlopeLargeの間の傾斜を持つ必要があります(銘柄ポイント値で価格単位に変換されます)。
    • ロングトレードは正の傾斜、ショートトレードは負の傾斜が必要です。
  2. バー内タイミング
    • シグナルは、MT5のTimeCurrent()チェックを反映して、現在の時間内にMinutesBegin分が経過した後にのみ考慮されます。
  3. 価格アクション確認
    • ロングエントリーは、安値付近で終わる下落または中立ローソク足が必要です(SlipBeginは許容距離を定義します)。
    • ショートエントリーは、高値付近で終わる上昇または中立ローソク足が必要です。
  4. ジャンプフィルター
    • 最後の6本のローソク足内でBigJump(調整ポイント)より大きい単一ローソク足始値ギャップは、ロングとショートの両シグナルをキャンセルします。
    • DoubleJumpより大きい2ローソク足始値ギャップもシグナルをキャンセルし、ボラタイルなスパイク中の取引を防ぎます。

エグジットロジック

  1. 時間制御型スマートストップ
    • MT5のスプレッド処理を模倣するためにオプションのAdjustオフセット付きで参照エントリー価格が保存されます。
    • 終値がポジションに対して少なくともStopLoss動くと、戦略はMinutesEnd分の時間が経過し、ローソク足が回復パターンを示す(SlipEnd要件)まで待ちます。満たされると、ポジションは成行で閉じられます。
  2. 緊急ストップ
    • ローソク足レンジが記録されたフィル価格からEmergencyLoss離れた位置に触れると、ポジションは即座に閉じられます。これは元のエキスパートのブローカー側ストップロスを反映しています。
  3. テイクプロフィット
    • TakeProfit距離に触れるローソク足は即座のエグジットをトリガーします。
  4. ボリューム安全策
    • 前のローソク足の総ボリュームがMinVolumeを超えない場合、流動性の低い期間の取引を避けるために現在のポジションが閉じられます。

パラメーター

名前 デフォルト 説明
Volume 1 成行注文ボリューム。エントリーと反対のポジションを反転させるためにも使用されます。
EmaPeriod 11 トレンド時間軸で計算されるEMAの長さ(始値ソース)。
BigJump 30 連続する始値間の最大許容単一ローソク足ギャップ(価格ステップを使用して変換)。
DoubleJump 55 1本のローソク足で区切られた始値間の最大許容ギャップ。
StopLoss 20 時間制御エグジットロジックを有効にするポイント単位の損失。
EmergencyLoss 50 エントリーからのハードストップ距離、到達時に即座に実行されます。
TakeProfit 25 エントリーからの利益目標距離。
SlopeSmall 5 新規トレードに必要な最小EMA傾斜(ロングは正、ショートは負)。
SlopeLarge 8 トレードに許可される最大EMA傾斜の大きさ。
MinutesBegin 25 新規エントリーが評価される前の時間の先頭からの分。
MinutesEnd 25 時間制御ストップロジックが出口を取れる前の時間の先頭からの分。
SlipBegin 0 エントリー検証中に使用されるローソク足終値と極値の最大距離。
SlipEnd 0 ストップ確認中のローソク足終値と極値の最大距離。
MinVolume 0 前のローソク足の最小ボリューム;より低い値は出口を強制します。
Adjust 1 内部エントリー参照価格を保存するときに適用される調整。
CandleType 5分の時間軸 エントリーとエグジットに使用される取引ローソク足。
TrendCandleType 1時間の時間軸 EMA傾斜フィルターを供給するローソク足タイプ。

すべての価格ベースのパラメーターは銘柄ポイント値で乗算されます。3桁または5桁の小数を持つFXシンボルの場合、コードはMetaTraderバージョンで使用されるpip処理に対応するために自動的にポイントを10倍にします。

実装上の注意

  • 両方の成行エントリーメソッドは、必要に応じて既存のポジションを逆転させるのに十分なボリュームでBuyMarketまたはSellMarketを呼び出します。
  • 戦略は取引とトレンドのローソク足タイプが異なる場合にのみSubscribeCandlesを2回使用します。両方のパラメーターが等しい場合、単一のサブスクリプションがEMAとトレードロジックの両方を供給します。
  • StockSharpは成行執行に保護注文を自動的に添付しないため、緊急ストップとテイクプロフィット管理はプロセス内で実装されています。
  • 高レベルAPIが全体を通して使用されています(Bindサブスクリプション、StartProtection、チャートヘルパー)。これにより、コードが簡潔に保たれ、リポジトリの慣例に従います。

使用上のヒント

  • 異なるセッション構造を持つ銘柄に合わせてMinutesBeginMinutesEndを調整します。デフォルト値は主要Forex通貨ペアのような時間ごとのリズムを持つ銘柄向けに設計されています。
  • 突然のボリューム不足が悪い執行と一致する市場ではMinVolumeを増やしてください(例:ピット時間外の商品)。
  • ジャンプフィルターはわずか6本のローソク足に依存するため、取引時間軸が大きすぎないことを確認してください。そうでないとフィルターが過度に許容的になる可能性があります。
  • EMA傾斜フィルターは銘柄ポイント値に対して敏感です。選択したシンボルに対してBigJumpStopLossなどのパラメーターが正しくスケールされていることを常に確認してください。
using System;
using System.Collections.Generic;

using Ecng.Common;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Arttrader v1.5 strategy (simplified).
/// Uses EMA slope on a higher timeframe to filter entries,
/// with candle pattern confirmation on the trading timeframe.
/// </summary>
public class ArttraderV15Strategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<DataType> _trendCandleType;
	private readonly StrategyParam<int> _emaPeriod;

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

	public DataType TrendCandleType
	{
		get => _trendCandleType.Value;
		set => _trendCandleType.Value = value;
	}

	public int EmaPeriod
	{
		get => _emaPeriod.Value;
		set => _emaPeriod.Value = value;
	}

	public ArttraderV15Strategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
			.SetDisplay("Candle Type", "Trading candles", "General");

		_trendCandleType = Param(nameof(TrendCandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Trend Candle Type", "Trend candles for EMA", "General");

		_emaPeriod = Param(nameof(EmaPeriod), 11)
			.SetGreaterThanZero()
			.SetDisplay("EMA Period", "EMA period on trend timeframe", "Indicators");
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		var ema = new ExponentialMovingAverage { Length = EmaPeriod };
		decimal currentEma = 0;
		decimal previousEma = 0;
		bool hasCurrentEma = false;
		bool hasPreviousEma = false;

		// Subscribe to trend timeframe for EMA slope
		var trendSub = SubscribeCandles(TrendCandleType);
		trendSub
			.Bind(ema, (ICandleMessage candle, decimal emaVal) =>
			{
				if (candle.State != CandleStates.Finished)
					return;

				if (hasCurrentEma)
				{
					previousEma = currentEma;
					hasPreviousEma = true;
				}

				currentEma = emaVal;
				hasCurrentEma = true;
			})
			.Start();

		// Subscribe to trading timeframe for signals
		var tradeSub = SubscribeCandles(CandleType);
		tradeSub
			.Bind((ICandleMessage candle) =>
			{
				if (candle.State != CandleStates.Finished)
					return;

				if (!IsFormedAndOnlineAndAllowTrading())
					return;

				if (!hasPreviousEma)
					return;

				var emaSlope = currentEma - previousEma;
				var close = candle.ClosePrice;
				var open = candle.OpenPrice;

				// Long: EMA slope positive, bearish candle (close < open), close near low
				if (emaSlope > 0 && close <= open && Position <= 0)
					BuyMarket();
				// Short: EMA slope negative, bullish candle (close > open), close near high
				else if (emaSlope < 0 && close >= open && Position >= 0)
					SellMarket();
			})
			.Start();

		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, tradeSub);
			DrawIndicator(area, ema);
			DrawOwnTrades(area);
		}
	}
}