GitHub で見る

GBP 午前9時ブレイクアウト戦略

概要

GBP 午前9時ブレイクアウト戦略は、MetaTraderの旧エキスパートアドバイザー「GBP9AM」をStockSharpで再現したものです。このシステムはロンドンオープン(現地時間9:00)前後にストラドルを準備し、現在の価格から設定可能な距離にbuy-stopとsell-stop注文を発注します。ストップロスとテイクプロフィットレベル(pips単位)による規律ある資金管理を維持しながら、オープン後のモメンタム相場の捕捉を目指します。

トレードロジック

  1. 戦略は設定可能なタイムフレーム(デフォルトは1分足)の確定済みローソク足を監視し、取引所のタイムスタンプに基づいて動作します。
  2. 各新規取引日はセットアップ状態をリセットし、セッションごとに1つのストラドルのみを準備します。
  3. ローソク足の時刻が設定された「Look Hour」および「Look Minute」に達すると、戦略は以下を実行します:
    • 残存するアクティブな注文をキャンセルし、競合を避けるためにオープンポジションをクローズします。
    • 証券のプライスステップを使用して、pip調整された入場・ストップロス・テイクプロフィット価格を計算します。
    • 最新クローズ価格から指定されたpips距離にbuy-stopとsell-stopの両方を発注します。
  4. 一方が約定すると、反対側のペンディング注文は即座にキャンセルされます。その後、戦略はストップロスまたはテイクプロフィットレベルに達した時点でポジションを手仕舞いするために価格動向を追跡します。
  5. オプションの日次「Close Hour」は、ロンドンセッション終了時に戦略がポジションを解消し、ペンディング注文を削除するよう強制します。

パラメーター

パラメーター 説明
Volume ストラドルの両側に使用する注文サイズ。
LookHour データフィードにおけるロンドン午前9時を表す取引所時間(0-23)。
LookMinute 注文を準備すべきlook hour内の分オフセット。
CloseHour すべてのポジションと注文が強制的にクローズされる時間。
UseCloseHour 自動クローズ時間の動作を有効または無効にします。
TakeProfitPips 両方向の入場価格からプロフィットターゲットまでのpips距離。
BuyDistancePips buy-stop注文の現在価格からのpips距離(上方)。
SellDistancePips sell-stop注文の現在価格からのpips距離(下方)。
BuyStopLossPips ロングポジションのストップロス距離(pips)。
SellStopLossPips ショートポジションのストップロス距離(pips)。
CandleType タイミングとエグジット管理に使用するローソク足サブスクリプション(デフォルト:1分足)。

すべてのpips距離は、必要に応じて取引所プライスステップに10を乗じることで、3桁または5桁のFX相場に自動的に適応します。これは元のエキスパートアドバイザーを踏襲しています。

リスク管理

  • 戦略は常にトリガー価格周辺に対称的なストップロスとテイクプロフィットターゲットを設定し、バランスの取れたリスクプロファイルを維持します。
  • 日末清算により、UseCloseHourパラメーターが無効でない限り、口座が翌日へのエクスポージャーを抱えないことを保証します。
  • 注文は1日1回のみ再発注されるため、戦略はレンジ相場でのオーバートレードを避けます。

使用上の注意

  1. ブローカーのタイムゾーンでロンドン午前9時と一致するようLookHourを設定してください。例えば、フィードがUTC+1の場合はLookHour = 10を使用します。
  2. GBP/USDまたはお好みのGBPペアの現在のボラティリティに合わせてpips距離を調整してください。
  3. pips計算が正確であり続けるよう、信頼性の高いbid/askとプライスステップメタデータを公開するFXシンボルに戦略をデプロイしてください。
  4. ブローカーの証拠金を監視してください:大きなVolume値は、元のMQLバージョンと同様に、口座レバレッジの調整が必要になる場合があります。

ファイル

  • CS/Gbp9AmBreakoutStrategy.cs – StockSharpの高レベルAPIを使用したC#実装。
  • README.md – 英語ドキュメント(このファイル)。
  • README_ru.md – ロシア語ドキュメント。
  • README_zh.md – 中国語ドキュメント。

Python実装はプロジェクト要件に従い意図的に省略されています。

using System;
using System.Collections.Generic;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Session breakout strategy using Highest/Lowest channel.
/// Trades on breakouts above/below the previous channel levels.
/// </summary>
public class Gbp9AmBreakoutStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _period;

	private decimal? _prevHigh;
	private decimal? _prevLow;

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

	public int Period
	{
		get => _period.Value;
		set => _period.Value = value;
	}

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

		_period = Param(nameof(Period), 12)
			.SetGreaterThanZero()
			.SetDisplay("Period", "Channel lookback period", "Indicators");
	}

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
	{
		return [(Security, CandleType)];
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevHigh = null;
		_prevLow = null;
	}

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

		_prevHigh = null;
		_prevLow = null;

		var highest = new Highest { Length = Period };
		var lowest = new Lowest { Length = Period };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(highest, lowest, ProcessCandle)
			.Start();

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

	private void ProcessCandle(ICandleMessage candle, decimal high, decimal low)
	{
		if (candle.State != CandleStates.Finished)
			return;

		if (!IsFormedAndOnlineAndAllowTrading())
		{
			_prevHigh = high;
			_prevLow = low;
			return;
		}

		var close = candle.ClosePrice;

		if (_prevHigh == null || _prevLow == null)
		{
			_prevHigh = high;
			_prevLow = low;
			return;
		}

		if (close > _prevHigh.Value && Position <= 0)
		{
			if (Position < 0)
				BuyMarket();
			BuyMarket();
		}
		else if (close < _prevLow.Value && Position >= 0)
		{
			if (Position > 0)
				SellMarket();
			SellMarket();
		}

		_prevHigh = high;
		_prevLow = low;
	}
}