A Estratégia da Sessão de Tóquio replica a lógica do consultor especialista MetaTrader TokyoSessionEA_v2.8 em StockSharp. O
A estratégia foi projetada para rompimento intradiário ou negociação de reversão à média em torno da sessão asiática (Tóquio). Ele captura um
referencia a vela em uma hora configurável, cria um canal de preço a partir dessa vela e avalia o rompimento ou recuperação
condições em outra hora alvo. Dependendo do modo de sinal escolhido, a estratégia pode negociar contrariamente ao
quebra de nível (movimentos de fade que se estendem além da faixa de referência) ou ao longo da direção de fuga.
A porta StockSharp concentra-se no uso de API de alto nível. Todos os cálculos de sinal são realizados dentro da assinatura da vela
manipulador, as paradas são gerenciadas por meio de StartProtection e cada ação é registrada por meio de LogInfo para manter o comportamento
transparente durante backtests e negociações ao vivo.
Lógica de negociação
Vela de referência – em TimeSetLevels (hora da corretora) a estratégia registra a máxima, a mínima e o fechamento da vela. Estes
os valores definem o canal da sessão e redefinem os sinalizadores de validação internos.
Validação de canal – cada vela finalizada entre a hora de referência e a hora de entrada pode invalidar o
sinal pendente dependendo da configuração:
CheckAllBars: se habilitado, o fechamento deve permanecer entre o máximo e o mínimo capturados.
ReCheckPrices: em TimeRecheckPrices o fechamento da vela é comparado com a média corrente para confirmar o impulso.
Avaliação de entrada – quando a vela que precede TimeCheckLevels fecha, a estratégia compara seu preço de fechamento
com as bordas do canal. Se o fechamento estiver dentro da faixa de distância configurada, a posição correspondente será aberta.
Saídas – as posições podem ser fechadas por três mecanismos:
CloseInSignal fecha uma negociação assim que o preço retorna dentro do canal (a lógica reflete o EA original).
CloseOrdersOnTime se estabiliza em TimeCloseOrders para evitar manter o risco na próxima sessão.
Stops de proteção, trailing stops e tratamento de ponto de equilíbrio são delegados ao subsistema de proteção StockSharp.
Parâmetros
Geral
Parâmetro
Descrição
CandleType
Série de velas usada para análise (o padrão é H1).
BrokerOffset
Diferença entre o horário do corretor e o GMT em horas.
Sinais
Parâmetro
Descrição
TypeOfSignals
ContraryTrend replica o esmaecimento do rompimento; AccordingTrend segue a direção do rompimento.
TimeSetLevels
Hora (0–23) em que a vela de referência é capturada.
TimeCheckLevels
Hora em que as condições de fuga são avaliadas.
TimeRecheckPrices
Hora adicional de verificação de impulso.
MinDistanceOfLevel
Distância mínima (em pips) entre o fechamento e o canal antes de permitir uma negociação.
MaxDistanceOfLevel
Distância máxima (em pips) do nível. Zero desativa o limite.
ReCheckPrices
Ativa/desativa o filtro de impulso adicional.
CheckAllBars
Requer que todos os fechamentos intermediários permaneçam dentro do canal.
Gestão de risco
Parâmetro
Descrição
CloseInSignal
Saia assim que o preço cruzar o limite do canal.
CloseOrdersOnTime
Achate posições após TimeCloseOrders.
TimeCloseOrders
Hora usada pela saída baseada em tempo.
UseTakeProfit, TakeProfit
Habilite e configure um take-profit fixo (pips).
UseStopLoss, StopLoss
Habilite e configure um stop-loss de proteção (pips).
UseTrailingStop, TrailingStop, TrailingStep
Ative o gerenciamento de trailing stop StockSharp (pips).
UseBreakEven, BreakEven, BreakEvenAfter
Mova o stop loss para o ponto de equilíbrio quando o lucro atingir a distância de gatilho.
Negociação
Parâmetro
Descrição
Volume
Volume básico do pedido. Ao inverter a direção, a posição oposta é fechada automaticamente.
MaxOrders
Número máximo de Volume blocos permitidos em uma direção. Defina como 0 para não ter limite.
Fluxo de trabalho
Implemente a estratégia em um instrumento com uma etapa de preço válida (Security.PriceStep).
Selecione o período desejado e configure as compensações de horário da corretora para alinhar a programação diária com a bolsa.
Ajuste os filtros de distância e validação para corresponder ao comportamento do EA original ou para se adaptar a diferentes mercados.
Configure parâmetros de risco. A porta StockSharp gerencia nativamente paradas e lógica de trilha por meio de StartProtection.
Comece a estratégia. As mensagens de registro reportarão os níveis capturados, negociações abertas e decisões de saída.
Diferenças da versão MetaTrader
Entradas de ponto flutuante baseadas em UseFloatingPoint e PipsFloatingPoint não são implementadas porque StockSharp
executa ordens de mercado no momento em que o sinal é gerado.
Os filtros de spread e slippage são omitidos porque as assinaturas de velas de alto nível não fornecem dados de compra/venda em nível de tick.
O gerenciamento automático de dinheiro (AutoLotSize, RiskFactor, lotes de recuperação, troca de símbolos predefinidos) é substituído pelo
parâmetros Volume e MaxOrders mais simples. O dimensionamento da posição deve ser ajustado diretamente nas configurações da estratégia.
Notificações sonoras e impressas são substituídas por mensagens LogInfo.
Todas as outras condições de sinal, portas de validação e saídas baseadas em tempo refletem o comportamento do EA original.
Notas
A configuração padrão está alinhada com o período H1 recomendado pelo consultor especialista original. Outros prazos
pode ser usado, mas a lógica baseada em horas assume que as durações das velas dividem uma hora igualmente.
Certifique-se de que o feed de dados forneça velas contínuas para o período selecionado. A falta de velas pode invalidar o
verificações de média e canal.
Como a estratégia fecha posições enviando ordens de mercado, as corretoras que exigem ordens limitadas ou detenção mínima
vezes podem precisar de adaptações adicionais.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Tokyo Session strategy: breakout from session range.
/// Tracks high/low during first hours, then buys breakout above high, sells below low.
/// </summary>
public class TokyoSessionStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _atrPeriod;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int AtrPeriod
{
get => _atrPeriod.Value;
set => _atrPeriod.Value = value;
}
public TokyoSessionStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_atrPeriod = Param(nameof(AtrPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("ATR Period", "ATR period for volatility filter", "Indicators");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var atr = new AverageTrueRange { Length = AtrPeriod };
var sessionHigh = decimal.MinValue;
var sessionLow = decimal.MaxValue;
var candleCount = 0;
var rangeSet = false;
decimal? prevClose = null;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(atr, (candle, atrVal) =>
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
candleCount++;
// Build range from first 4 candles (2 hours of 30min candles)
if (candleCount <= 4)
{
if (candle.HighPrice > sessionHigh)
sessionHigh = candle.HighPrice;
if (candle.LowPrice < sessionLow)
sessionLow = candle.LowPrice;
if (candleCount == 4)
rangeSet = true;
prevClose = candle.ClosePrice;
return;
}
if (!rangeSet)
{
prevClose = candle.ClosePrice;
return;
}
// Reset range every 48 candles (24 hours of 30min candles)
if (candleCount % 48 == 0)
{
sessionHigh = candle.HighPrice;
sessionLow = candle.LowPrice;
rangeSet = false;
candleCount = 0;
prevClose = candle.ClosePrice;
return;
}
var close = candle.ClosePrice;
if (prevClose.HasValue)
{
var crossAboveHigh = prevClose.Value <= sessionHigh && close > sessionHigh;
var crossBelowLow = prevClose.Value >= sessionLow && close < sessionLow;
if (crossAboveHigh && Position <= 0)
BuyMarket();
else if (crossBelowLow && Position >= 0)
SellMarket();
}
prevClose = close;
})
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
}
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 AverageTrueRange
from StockSharp.Algo.Strategies import Strategy
class tokyo_session_strategy(Strategy):
def __init__(self):
super(tokyo_session_strategy, self).__init__()
self._atr_period = self.Param("AtrPeriod", 14) \
.SetDisplay("ATR Period", "ATR period for volatility filter", "Indicators")
self._atr = None
self._session_high = None
self._session_low = None
self._candle_count = 0
self._range_set = False
self._prev_close = None
@property
def atr_period(self):
return self._atr_period.Value
def OnReseted(self):
super(tokyo_session_strategy, self).OnReseted()
self._atr = None
self._session_high = None
self._session_low = None
self._candle_count = 0
self._range_set = False
self._prev_close = None
def OnStarted2(self, time):
super(tokyo_session_strategy, self).OnStarted2(time)
self._atr = AverageTrueRange()
self._atr.Length = self.atr_period
self._session_high = -999999999.0
self._session_low = 999999999.0
self._candle_count = 0
self._range_set = False
subscription = self.SubscribeCandles(DataType.TimeFrame(TimeSpan.FromMinutes(30)))
subscription.Bind(self._atr, self._process_candle)
subscription.Start()
def _process_candle(self, candle, atr_value):
if candle.State != CandleStates.Finished:
return
if not self._atr.IsFormed:
return
self._candle_count += 1
high = float(candle.HighPrice)
low = float(candle.LowPrice)
close = float(candle.ClosePrice)
if self._candle_count <= 4:
if high > self._session_high:
self._session_high = high
if low < self._session_low:
self._session_low = low
if self._candle_count == 4:
self._range_set = True
self._prev_close = close
return
if not self._range_set:
self._prev_close = close
return
if self._candle_count % 48 == 0:
self._session_high = high
self._session_low = low
self._range_set = False
self._candle_count = 0
self._prev_close = close
return
if self._prev_close is not None:
cross_above = self._prev_close <= self._session_high and close > self._session_high
cross_below = self._prev_close >= self._session_low and close < self._session_low
if cross_above and self.Position <= 0:
self.BuyMarket()
elif cross_below and self.Position >= 0:
self.SellMarket()
self._prev_close = close
def CreateClone(self):
return tokyo_session_strategy()