GitHub で見る

AIS5トレードマシン

概要

AIS5 Trade Machine は、MetaTrader 4 エキスパート アドバイザー AIS5TM.mq4 を StockSharp のハイレベル戦略 API に移植します。オリジナル このプログラムは、2 つの時間枠で市場プロファイルのヒストグラムを構築し、半自動実行コンソールを提供することに重点を置いています。の StockSharp バージョンは、ティックボリュームの集計から強い価格ゾーンと弱い価格ゾーンを強調表示するというアイデアを維持し、それを 平均トゥルーレンジ (ATR) に基づく適応型リスク制御を備えた自動ブレイクアウト システム。

この戦略は 2 つのローソク足ストリームをサブスクライブします。

  • プロファイルの時間枠 (デフォルトは 15 分) で、強いゾーンと弱いゾーンを検出するためにボリュームを蓄積します。
  • これらのゾーンから離れた出来高が確認されたブレイクアウトを探す 取引時間枠 (デフォルトは 1 分)。

ポジションは、ATR 比例ストップとスケーラブルなターゲットによって保護されます。体積収縮は早期終了を引き起こし、 MT4 コードにある監視規律。

戦略ロジック

ボリューム ゾーンの検出 (プロファイルの時間枠)

  • 終了した各上位タイムフレーム ローソク足は、ティック量の 2 つの単純移動平均 (SMA) を更新します。
  • ローソクの出来高が設定可能な乗数 (Strong Volume Mult) の平均を超えた場合、ローソクは 強いゾーン とラベル付けされます。 ローソク足の終値が直近の強い水準となります。
  • ローソクの出来高が設定された分割器で割られた平均を下回る場合、ローソクは 弱いゾーン というラベルが付けられます。 (Weak Volume Divider)。そのローソク足の終値が直近の弱い水準となります。
  • 完成したキャンドルのみが参加します。この戦略では、プロファイル SMA が完全に形成されるまで、ゾーンが無視されます。これは時期尚早を避けるためです。 ウォームアップ期間中の信号。

ブレイクアウトエントリー(取引時間枠)

  • 下のタイムフレームは、ボリューム SMA と ATR インジケーターの両方の形成が完了するのを待ちます。
  • 長いセットアップでは、ゾーンベースポイントとゾーンベースポイント**の合計により、終値が最新の強いレベルを超える必要があります。 ゾーン ステップ ポイント バッファー (商品の価格ステップを介して変換)。キャンドルはまた、相対的にボリュームスパイクを提供する必要があります 日中平均まで。
  • 短いセットアップでは、最新の弱いレベル周辺のロジックが反映され、結合されたバッファを超えたブレークダウンが必要となり、確認が必要になります。 ボリュームの拡大。
  • オリジナルの MT4 エキスパートでは、手動コマンドと多次グリッドが許可されていました。 StockSharp ポートは単一位置モデルを保持するため、 ブレイクアウトは、現在のネット ポジションがフラットの場合にのみ実行されます。

出口管理

  • エントリー時に、戦略は約定価格を保存し、ATR ベースの保護ストップを計算します (ATR に ATR Multiplier を乗算し、 ベース ゾーン バッファーによってクランプされます)、停止距離に弱いボリューム ディバイダーを乗算した値としてターゲットを設定します。これにより、 リスクと報酬をボリューム構造に合わせて調整します。
  • ポジションがオープンしている間、戦略は終了した各取引ローソク足を監視します。
    • 価格が利益目標または保護ストップに達すると、ポジションは直ちにフラット化されます。
    • いずれかのレベルに達する前にティックボリュームが弱いボリュームしきい値を下回った場合、取引は回避するために早期に終了します。 非アクティブゾーンに留まります。
  • ネットポジションがゼロに戻ると内部状態がリセットされ、次のブレークアウトを最初から評価できるようになります。

パラメーター

  • プロファイル キャンドル – ボリューム プロファイルをフィードするキャンドル タイプ (デフォルト: 15 分キャンドル)。
  • トレーディングローソク足 – ブレイクアウトとエグジットに使用される下限の時間枠 (デフォルト: 1 分ローソク足)。
  • 出来高ルックバック – 出来高SMAとATR期間の両方のローソク足の数。
  • Strong Volume Mult – 強いゾーンをマークする平均ボリュームを超える乗数 (MQL の Parameter.1 にマッピングされます)。
  • 弱いボリュームディバイダー – 弱いゾーンをマークし、利益目標のサイズを決定する、平均ボリュームの下のディバイダー( Parameter.2)。
  • ATR 乗数 – 適応停止距離を計算するときに ATR に適用されるスケール係数 (Parameter.3 にマップ)。
  • ゾーン ベース ポイント – ブレークアウトをチェックする前にゾーン レベルに追加されるポイントの最小バッファー (ZoneBasePoints にマップ)。
  • ゾーン ステップ ポイント – エントリーが開始される前にゾーンからの距離を広げるポイント単位の追加のブレイクアウト バッファー トリガーされます (ZoneStepPoints にマッピングされます)。
  • ボリューム – 基本の Strategy クラスから継承されます。市場エントリーの注文サイズを定義します。

追加の注意事項

  • 証券で指定されていない場合、戦略は自動的にデフォルトの価格ステップ 0.0001 に戻ります。これにより、 ほとんどの FX シンボルと互換性のあるポイントベースのパラメーター。
  • すべてのインジケーターの計算は、完全に閉じたバーで機能する MT4 実装と一致する完成したローソク足に依存します。
  • オリジナルの EA とは異なり、手動のコントロール パネルやファイルベースのプロファイル ローダーはありません。ゾーンはライブから純粋に再構築されます ポートを自己完結型に保つためのキャンドル データ。
  • StockSharp バージョンには Python 翻訳が含まれていません。
using System;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// AIS5 Trade Machine: EMA breakout with RSI filter and ATR stops.
/// </summary>
public class Ais5TradeMachineStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _emaLength;
	private readonly StrategyParam<int> _rsiLength;
	private readonly StrategyParam<int> _atrLength;

	private decimal _prevClose;
	private decimal _entryPrice;

	public Ais5TradeMachineStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(8).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe.", "General");

		_emaLength = Param(nameof(EmaLength), 20)
			.SetDisplay("EMA Length", "Trend filter.", "Indicators");

		_rsiLength = Param(nameof(RsiLength), 14)
			.SetDisplay("RSI Length", "RSI period.", "Indicators");

		_atrLength = Param(nameof(AtrLength), 14)
			.SetDisplay("ATR Length", "ATR period.", "Indicators");
	}

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

	public int EmaLength
	{
		get => _emaLength.Value;
		set => _emaLength.Value = value;
	}

	public int RsiLength
	{
		get => _rsiLength.Value;
		set => _rsiLength.Value = value;
	}

	public int AtrLength
	{
		get => _atrLength.Value;
		set => _atrLength.Value = value;
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();

		_prevClose = 0;
		_entryPrice = 0;
	}

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

		_prevClose = 0;
		_entryPrice = 0;

		var ema = new ExponentialMovingAverage { Length = EmaLength };
		var rsi = new RelativeStrengthIndex { Length = RsiLength };
		var atr = new AverageTrueRange { Length = AtrLength };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(ema, rsi, atr, ProcessCandle)
			.Start();

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

	private void ProcessCandle(ICandleMessage candle, decimal emaVal, decimal rsiVal, decimal atrVal)
	{
		if (candle.State != CandleStates.Finished)
			return;

		var close = candle.ClosePrice;

		if (_prevClose == 0 || atrVal <= 0)
		{
			_prevClose = close;
			return;
		}

		if (Position > 0)
		{
			if (close >= _entryPrice + atrVal * 2.5m || close <= _entryPrice - atrVal * 1.5m || rsiVal > 75)
			{
				SellMarket();
				_entryPrice = 0;
			}
		}
		else if (Position < 0)
		{
			if (close <= _entryPrice - atrVal * 2.5m || close >= _entryPrice + atrVal * 1.5m || rsiVal < 25)
			{
				BuyMarket();
				_entryPrice = 0;
			}
		}

		if (Position == 0)
		{
			if (close > emaVal && _prevClose <= emaVal && rsiVal > 50)
			{
				_entryPrice = close;
				BuyMarket();
			}
			else if (close < emaVal && _prevClose >= emaVal && rsiVal < 50)
			{
				_entryPrice = close;
				SellMarket();
			}
		}

		_prevClose = close;
	}
}