Esta estratégia é uma conversão StockSharp do especialista original MetaTrader 4 localizado em MQL/7687/Gbp9am.mq4. Ele recria a rotina de rompimento das 9h de Londres, que arma duas ordens pendentes em torno do preço atual e mantém no máximo uma negociação ativa durante a sessão.
Ideia de negociação
Nas horas e minutos configurados, a estratégia considera o último fechamento da vela como um instantâneo do preço.
Um stop de compra é colocado acima do preço instantâneo e um stop de venda é colocado abaixo dele. Ambas as ordens compartilham o mesmo volume e carregam níveis de stop loss individuais juntamente com uma distância de take-profit compartilhada.
Quando uma das ordens é atendida, a outra é cancelada imediatamente, de modo que apenas uma posição fica ativa.
A posição aberta é gerenciada com níveis sintéticos de stop-loss e take-profit que são verificados em cada vela concluída.
Uma hora de encerramento diária pode ser habilitada para nivelar qualquer exposição restante e remover ordens pendentes após a sessão de Londres.
Se ambas as ordens pendentes forem removidas sem negociação, ou se o horário do mercado se afastar da hora de observação, a estratégia será rearmada no dia seguinte exatamente como na versão MetaTrader.
As compensações de pip são aproximadas usando a etapa de preço do instrumento. Se o corretor fornecer pips fracionários (3 ou 5 dígitos decimais), a lógica será automaticamente dimensionada para incrementos típicos de 0,1 pip.
Referência de parâmetro
Parâmetro
Descrição
Volume
Volume de ordens (lotes) compartilhado por ambas as ordens pendentes.
LookHour
Horário de troca que representa 9h, horário de Londres.
LookMinute
Minuto dentro da hora de visualização em que o instantâneo é tirado.
CloseHour
Hora em que todas as posições e ordens pendentes são fechadas à força.
UseCloseHour
Habilita ou desabilita o procedimento de encerramento diário.
TakeProfitPips
Distância alvo em pips, aplicada simetricamente em ambas as direções.
BuyDistancePips
Compensação em pips entre o preço instantâneo e a entrada de stop de compra.
SellDistancePips
Compensação em pips entre o preço instantâneo e a entrada do stop de venda.
BuyStopLossPips
Distância de stop-loss em pips para negociações longas.
SellStopLossPips
Distância de stop-loss em pips para negociação a descoberto.
CandleType
Série de velas usada para gerenciamento de tempo e parada (padrão 1 minuto).
Notas comportamentais
A estratégia ignora velas inacabadas para evitar múltiplos gatilhos dentro da mesma barra.
Os preços dos pedidos são arredondados para o tick válido mais próximo usando a etapa do preço do título.
O portão de rearme reflete o sinalizador clear_to_send do especialista MQL: uma vez que o straddle diário é colocado, nenhuma nova ordem é enviada até que ambas as ordens pendentes desapareçam enquanto o mercado estiver fora da hora de visualização ou o relógio alcance a hora anterior ao próximo sinal.
Quando UseCloseHour está ativado, a estratégia sai de qualquer negociação aberta com uma ordem de mercado e limpa as ordens pendentes quando a hora de fechamento é atingida.
Os cálculos de pip baseiam-se em velas históricas, portanto, as distâncias exatas de stop/alvo podem diferir ligeiramente do ambiente MetaTrader baseado em ticks, especialmente em símbolos com grandes spreads.
Gestão de risco
A conversão mantém as paradas e metas estáticas originais. Não há parada móvel ou lógica de escala. A proteção de posição é ativada em OnStarted para que desconexões inesperadas não deixem a conta desprotegida.
Uso
Configure os valores Volume, LookHour e LookMinute para corresponder ao fuso horário de troca do seu feed de dados.
Ajuste os parâmetros de distância para refletir a estrutura de spread da sua corretora.
Anexe a estratégia a um símbolo GBPUSD (ou outro par FX de sua escolha) e inicie-a antes da sessão de Londres.
Monitore as negociações resultantes no gráfico StockSharp que é desenhado automaticamente após o início.
A implementação segue as diretrizes de AGENTS.md: ela usa a assinatura de vela de alto nível API, emprega parâmetros de estratégia com metadados de UI e evita pesquisas de histórico de baixo nível.
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>
/// GBP 9AM strategy - session high/low breakout.
/// Buys when close crosses above the Highest channel.
/// Sells when close crosses below the Lowest channel.
/// Uses midpoint crossing for exits.
/// </summary>
public class Gbp9AmStrategy : Strategy
{
private readonly StrategyParam<int> _channelPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevClose;
private decimal _prevMid;
private bool _hasPrev;
public int ChannelPeriod { get => _channelPeriod.Value; set => _channelPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public Gbp9AmStrategy()
{
_channelPeriod = Param(nameof(ChannelPeriod), 12)
.SetDisplay("Channel Period", "Highest/Lowest lookback", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
protected override void OnReseted() { base.OnReseted(); _prevClose = 0m; _prevMid = 0m; _hasPrev = false; }
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var highest = new Highest { Length = ChannelPeriod };
var lowest = new Lowest { Length = ChannelPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(highest, lowest, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal highest, decimal lowest)
{
if (candle.State != CandleStates.Finished)
return;
var close = candle.ClosePrice;
var mid = (highest + lowest) / 2;
if (!_hasPrev)
{
_prevClose = close;
_prevMid = mid;
_hasPrev = true;
return;
}
if (_prevClose <= _prevMid && close > mid && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
else if (_prevClose >= _prevMid && close < mid && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
_prevClose = close;
_prevMid = mid;
}
}
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_strategy(Strategy):
def __init__(self):
super(gbp9_am_strategy, self).__init__()
self._channel_period = self.Param("ChannelPeriod", 12).SetDisplay("Channel Period", "Highest/Lowest lookback", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))).SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_close = 0.0
self._prev_mid = 0.0
self._has_prev = False
@property
def channel_period(self): return self._channel_period.Value
@property
def candle_type(self): return self._candle_type.Value
def OnReseted(self):
super(gbp9_am_strategy, self).OnReseted()
self._prev_close = 0.0
self._prev_mid = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(gbp9_am_strategy, self).OnStarted2(time)
self._has_prev = False
highest = Highest()
highest.Length = self.channel_period
lowest = Lowest()
lowest.Length = self.channel_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(highest, lowest, self.process_candle).Start()
def process_candle(self, candle, highest, lowest):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
mid = (float(highest) + float(lowest)) / 2.0
if not self._has_prev:
self._prev_close = close
self._prev_mid = mid
self._has_prev = True
return
if self._prev_close <= self._prev_mid and close > mid and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif self._prev_close >= self._prev_mid and close < mid and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_close = close
self._prev_mid = mid
def CreateClone(self):
return gbp9_am_strategy()