View on GitHub

GBP 9 AM Breakout Strategy

Overview

The GBP 9 AM Breakout Strategy replicates the legacy MetaTrader "GBP9AM" expert advisor in StockSharp. The system prepares a straddle around the London open (9:00 local time) by placing buy-stop and sell-stop orders at configurable distances from the current price. It aims to capture the post-open momentum move while enforcing disciplined risk management through stop-loss and take-profit levels measured in pips.

Trading Logic

  1. The strategy monitors finished candles of a configurable timeframe (1-minute by default) to work with exchange timestamps.
  2. Each new trading day resets the setup state so only one straddle is prepared per session.
  3. Once the candle time reaches the configured "Look Hour" and "Look Minute", the strategy:
    • Cancels any remaining active orders and closes open positions to avoid conflicts.
    • Calculates pip-adjusted entry, stop-loss, and take-profit prices using the security's price step.
    • Places both a buy-stop and a sell-stop order at the specified pip distances from the latest close price.
  4. When one side fills, the opposite pending order is cancelled immediately. The strategy then tracks price action to exit the position once either the stop-loss or take-profit level is hit intraday.
  5. An optional daily "Close Hour" forces the strategy to flatten positions and remove pending orders at the end of the London session.

Parameters

Parameter Description
Volume Order size used for both sides of the straddle.
LookHour Exchange hour (0-23) that represents 9 AM London in your data feed.
LookMinute Minute offset within the look hour when orders should be prepared.
CloseHour Hour at which all positions and orders are forcefully closed.
UseCloseHour Enables or disables the automatic close hour behaviour.
TakeProfitPips Distance in pips from the entry price to the profit target for both directions.
BuyDistancePips Pip distance above the current price for the buy-stop order.
SellDistancePips Pip distance below the current price for the sell-stop order.
BuyStopLossPips Stop-loss distance in pips for long positions.
SellStopLossPips Stop-loss distance in pips for short positions.
CandleType Candle subscription used for timing and exit management (defaults to 1-minute time frame).

All pip distances automatically adapt to 3- or 5-digit FX quotes by multiplying the exchange price step by ten where needed, mirroring the original expert advisor.

Risk Management

  • The strategy always issues symmetrical stop-loss and take-profit targets around the trigger price to maintain a balanced risk profile.
  • End-of-day liquidation ensures the account does not carry overnight exposure unless the UseCloseHour parameter is disabled.
  • Because orders are restated only once per day, the strategy avoids over-trading during ranging sessions.

Usage Notes

  1. Set the LookHour to match 9 AM London time within your broker's time zone. For example, if the feed is UTC+1, use LookHour = 10.
  2. Calibrate pip distances to accommodate the current volatility of GBP/USD or your preferred GBP pair.
  3. Deploy the strategy on FX symbols that expose reliable bid/ask and price step metadata so that pip calculations remain accurate.
  4. Monitor broker margins: larger Volume values may require adjustments in account leverage just like the original MQL version did.

Files

  • CS/Gbp9AmBreakoutStrategy.cs – C# implementation using the StockSharp high-level API.
  • README.md – English documentation (this file).
  • README_ru.md – Russian documentation.
  • README_zh.md – Chinese documentation.

Python implementation is intentionally omitted per project requirements.

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;
	}
}