GitHub で見る

AIS3トレーディングロボットテンプレート

概要

AIS3 取引ロボット テンプレートは、調整された 2 つの時間枠に依存する MetaTrader ブレイクアウト システムです。主な時間枠 前のローソク足の構造をキャプチャし、二次的な時間枠で最近のボラティリティを測定して、後続の更新を制御します。 この StockSharp ポートは、元の注文サイジング、エントリー チェック、およびトレーリング ロジックを忠実に再現していますが、 高レベルの戦略 API の最上位にあるため、デザイナー、シェル、または任意のカスタム StockSharp ホスト内で実行できます。

取引ワークフロー

  • 市場データのサブスクリプション: この戦略は 2 つのローソク足シリーズをサブスクライブします。プライマリ シリーズ (デフォルトは 15 分) では、 以前のローソク足の高値、安値、終値、中間点、範囲。二次シリーズ (デフォルトは 1 分) は、使用された高速範囲を測定します。 トレーリングストップ用。ライブ注文ブックフィードは、現在の最高買値/売値を元の MQL MarketInfo と同期させます。 リクエスト。
  • ブレイクアウト検証:
    • ロングセットアップは、前回の終値が中間点を上回り、現在の売値が前回の終値を上抜けたときにトリガーされます。 高値に測定されたスプレッドを加えたものです。エントリー価格は現在のアスク価格です。
    • 短期セットアップでは、前の終値が中間点以下に留まり、入札が前の安値を突破する必要があります。エントリー価格 現在の入札額です。
    • 両方向はテンプレートからブローカーの安全性チェックを継承します: エントリーと予想されるストップ/ターゲットの間の距離 設定されたストップバッファを超える必要があり、ストップはエントリー価格の正しい側に留まる必要があります。 広がる。
  • 秘密保持命令:
    • ストップロス距離は primaryRange × StopMultiplier に等しく、上(ロングの場合)または下(ショートの場合)に固定されます。 統合マニュアルに記載されているブレイクアウトキャンドル。
    • 利食い距離は primaryRange × TakeMultiplier に等しく、エントリー価格から取引方向に配置されます。
  • 貿易管理:
    • ポジションがオープンしている場合、二次タイムフレーム範囲に TrailMultiplier を掛けた値がトレーリング ディスタンスを定義します。
    • トレーリングストップは取引が利益を上げている場合にのみ更新され、新しいレベルは設定されたフリーズおよびストップよりも遠いです。 バッファがあり、現在の停留所と提案された停留所の間の距離が TrailStepMultiplier × spread を超えています。これは、 テンプレートの要件では、ストップを変更する前に価格が少なくとも 1 トレイル ステップ進む必要があります。
    • ビッド/アスクが保存されたストップロスまたはテイクプロフィットレベルに達すると、ポジションは成行注文でクローズされます。

リスク管理

  • 口座引当金: AccountReserve はポートフォリオ資本の一部をロックしたままにします。戦略は新しいポジションを開くことを拒否します 予約資本が要求された注文予算を下回る場合。これは、リスクが発生するテンプレートの動作と一致します。 準備金は、連鎖的な損失からアカウントを守ります。
  • 注文リザーブ: OrderReserve は、取引ごとにリスクを負う可能性がある残りの資本の部分を管理します。ポジションサイズ は riskBudget / |entry - stop| として計算され、セキュリティ ボリューム ステップに合わせられます。ポートフォリオ指標がない場合、 利用可能な場合は、代わりにフォールバック BaseVolume パラメータが使用されます。
  • バッファの停止とフリーズ: StopBufferTicks および FreezeBufferTicks はブローカーの停止制限を変換します (例: MODE_STOPLEVEL) および MODE_FREEZELEVEL から MetaTrader) を証券価格ステップを使用して価格単位に変換します。彼らは戦略の発行を妨げます 為替制約に違反する注文、またはトレーリングストップをあまりにも積極的に動かすことによる注文。
  • 後続ステップ乗数: TrailStepMultiplier は、MQ4 テンプレートの acd.TrailStepping 定数をミラーリングします。それは保証します トレーリング更新は、新しいストップが前の値から少なくとも 1 スプレッド倍数離れている場合にのみ発生します。

パラメーター

パラメータ 説明
AccountReserve 安全準備金として保持される資本の割合 (0 ~ 0.95)。
OrderReserve 取引ごとのリスクバジェットに割り当てられる取引可能な株式の割合 (デフォルトでは 0 ~ 0.5)。
PrimaryCandleType ブレイクアウト検出の作業時間枠 (デフォルトは 15 分のローソク足)。
SecondaryCandleType トレーリング距離を制御するより速いタイムフレーム (デフォルトの 1 分ローソク足)。
TakeMultiplier テイクプロフィット注文を出すために使用されるプライマリレンジの乗数。
StopMultiplier 保護停止を計算するために使用される主範囲の乗数。
TrailMultiplier 後続距離を定義する二次範囲の乗数。
BaseVolume ポートフォリオ指標が利用できない場合のフォールバックポジションサイズ。
StopBufferTicks エントリーレベルとストップ/ターゲットレベルの間に維持する必要がある追加距離(価格ティック単位)。
FreezeBufferTicks ブローカーのフリーズ レベルに近すぎる更新の停止を回避する追加のバッファー。
TrailStepMultiplier 後続調整間の最小増分を定義するスプレッド乗数。

使用上の注意

  • ローソク足シリーズとレベル 1 またはオーダーブック ストリームの両方を戦略にフィードして、最良の買値/売値を利用できるようにします。ランニング ブレイクアウトチェックはスプレッドに依存するため、最後の取引データのみに基づいてブレイクアウトチェックを変更します。
  • デフォルトのパラメータ値は、MQ4 テンプレートの例 (TakeMultiplier = 1StopMultiplier = 2TrailMultiplier = 3)。取引する資産に合わせて調整したり、ブレイクアウトの強さを試したりしてください。
  • トレーリングストップは仮想的なものであり、注文は取引所で変更されません。トレーリング条件が満たされると、戦略は単純に 元のエキスパートアドバイザーが内部で停止を管理した方法を反映して、市場からの撤退を発行します。
  • この戦略を StockSharp の組み込み保護モジュール (コンストラクターですでに有効になっている) と組み合わせて、緊急事態を維持します ストラテジーが一時的に切断された場合でも、ストップロスの処理。
using System;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// AIS3 Trading Robot: breakout strategy with ATR-based stops and trailing.
/// Enters on breakout above/below previous candle range with EMA filter.
/// </summary>
public class Ais3TradingRobotTemplateStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _emaLength;
	private readonly StrategyParam<int> _atrLength;
	private readonly StrategyParam<decimal> _takeMultiplier;
	private readonly StrategyParam<decimal> _stopMultiplier;

	private decimal _prevHigh;
	private decimal _prevLow;
	private decimal _entryPrice;
	private decimal _stopPrice;

	public Ais3TradingRobotTemplateStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe.", "General");

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

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

		_takeMultiplier = Param(nameof(TakeMultiplier), 2.0m)
			.SetDisplay("Take Multiplier", "ATR multiplier for TP.", "Risk");

		_stopMultiplier = Param(nameof(StopMultiplier), 1.5m)
			.SetDisplay("Stop Multiplier", "ATR multiplier for SL.", "Risk");
	}

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

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

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

	public decimal TakeMultiplier
	{
		get => _takeMultiplier.Value;
		set => _takeMultiplier.Value = value;
	}

	public decimal StopMultiplier
	{
		get => _stopMultiplier.Value;
		set => _stopMultiplier.Value = value;
	}

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

		_prevHigh = 0;
		_prevLow = 0;
		_entryPrice = 0;
		_stopPrice = 0;
	}

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

		_prevHigh = 0;
		_prevLow = 0;
		_entryPrice = 0;
		_stopPrice = 0;

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

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(ema, 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 atrVal)
	{
		if (candle.State != CandleStates.Finished)
			return;

		if (_prevHigh == 0 || atrVal <= 0)
		{
			_prevHigh = candle.HighPrice;
			_prevLow = candle.LowPrice;
			return;
		}

		var close = candle.ClosePrice;
		var takeDistance = atrVal * TakeMultiplier;
		var stopDistance = atrVal * StopMultiplier;

		// Manage position
		if (Position > 0)
		{
			if (close - _entryPrice >= takeDistance)
			{
				SellMarket();
				_entryPrice = 0;
				_stopPrice = 0;
			}
			else if (_stopPrice > 0 && close <= _stopPrice)
			{
				SellMarket();
				_entryPrice = 0;
				_stopPrice = 0;
			}
			else
			{
				var trail = close - stopDistance;
				if (trail > _stopPrice) _stopPrice = trail;
			}
		}
		else if (Position < 0)
		{
			if (_entryPrice - close >= takeDistance)
			{
				BuyMarket();
				_entryPrice = 0;
				_stopPrice = 0;
			}
			else if (_stopPrice > 0 && close >= _stopPrice)
			{
				BuyMarket();
				_entryPrice = 0;
				_stopPrice = 0;
			}
			else
			{
				var trail = close + stopDistance;
				if (trail < _stopPrice || _stopPrice == 0) _stopPrice = trail;
			}
		}

		// Entry on breakout + EMA filter
		if (Position == 0)
		{
			if (close > _prevHigh && close > emaVal)
			{
				_entryPrice = close;
				_stopPrice = close - stopDistance;
				BuyMarket();
			}
			else if (close < _prevLow && close < emaVal)
			{
				_entryPrice = close;
				_stopPrice = close + stopDistance;
				SellMarket();
			}
		}

		_prevHigh = candle.HighPrice;
		_prevLow = candle.LowPrice;
	}
}