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
The strategy monitors finished candles of a configurable timeframe (1-minute by default) to work with exchange timestamps.
Each new trading day resets the setup state so only one straddle is prepared per session.
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.
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.
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
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.
Calibrate pip distances to accommodate the current volatility of GBP/USD or your preferred GBP pair.
Deploy the strategy on FX symbols that expose reliable bid/ask and price step metadata so that pip calculations remain accurate.
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;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import Highest, Lowest
from StockSharp.Algo.Strategies import Strategy
class gbp9_am_breakout_strategy(Strategy):
def __init__(self):
super(gbp9_am_breakout_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Timeframe", "General")
self._period = self.Param("Period", 12) \
.SetDisplay("Period", "Channel lookback period", "Indicators")
self._prev_high = None
self._prev_low = None
@property
def CandleType(self):
return self._candle_type.Value
@property
def Period(self):
return self._period.Value
def OnReseted(self):
super(gbp9_am_breakout_strategy, self).OnReseted()
self._prev_high = None
self._prev_low = None
def OnStarted2(self, time):
super(gbp9_am_breakout_strategy, self).OnStarted2(time)
self._prev_high = None
self._prev_low = None
highest = Highest()
highest.Length = self.Period
lowest = Lowest()
lowest.Length = self.Period
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(highest, lowest, self._on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, highest)
self.DrawIndicator(area, lowest)
self.DrawOwnTrades(area)
def _on_process(self, candle, high_value, low_value):
if candle.State != CandleStates.Finished:
return
hv = float(high_value)
lv = float(low_value)
close = float(candle.ClosePrice)
if self._prev_high is None or self._prev_low is None:
self._prev_high = hv
self._prev_low = lv
return
if close > self._prev_high and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif close < self._prev_low and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_high = hv
self._prev_low = lv
def CreateClone(self):
return gbp9_am_breakout_strategy()