Ver no GitHub

Estratégia de bomba-relógio

O Time Bomb replica o consultor especialista MetaTrader que dispara um único pedido sempre que o preço explode em uma direção dentro de um janela curta e configurável. A estratégia observa as melhores cotações de compra/venda em tempo real e mede o número de pips cobertos entre o último preço de referência e a cotação mais recente. Se a distância necessária for percorrida com rapidez suficiente, abre-se uma ordem de mercado em a direção do rompimento e arma imediatamente os níveis ocultos de stop-loss e take-profit expressos em pips.

A implementação atua apenas quando nenhuma posição está aberta no momento, espelhando a lógica do bloco original que impedia a sobreposição negócios. As referências de preço são redefinidas quando um sinal é acionado ou quando a janela de observação expira, de modo que cada explosão de a volatilidade produz no máximo uma única negociação por lado. Os níveis de stop-loss e take-profit são mantidos internamente e aplicados por a estratégia em si porque StockSharp não coloca automaticamente ordens de proteção para execuções de mercado.

Detalhes

  • Critérios de entrada:
    • Longo: A melhor venda aumenta em pelo menos BuyPipsInTime pips em comparação com o preço de referência armazenado e a movimentação termina dentro de BuyTimeToWait segundos. Uma ordem de compra com tamanho BuyVolume é enviada assim que a condição for atendida.
    • Short: o melhor lance cai pelo menos SellPipsInTime pips em comparação com o preço de referência armazenado e a mudança termina dentro de SellTimeToWait segundos. Uma ordem de venda com tamanho SellVolume é enviada assim que a condição for atendida.
  • Longo/Curto: Ambas as direções são suportadas, mas apenas uma posição pode existir por vez.
  • Critérios de saída:
    • Longo: A posição fecha quando o melhor lance atinge o preço calculado de stop-loss ou take-profit.
    • Short: A posição fecha quando a melhor oferta atinge o stop-loss calculado ou a melhor oferta atinge o nível de take-profit.
  • Paradas: as paradas de proteção ocultas são tratadas pela estratégia. As distâncias são definidas em pips e traduzidas em preços usando o tamanho do passo do símbolo atual.
  • Valores padrão:
    • SellPipsInTime = 5 pips, SellTimeToWait = 10 segundos, SellVolume = 0,01 lotes.
    • SellStopLossPips = 20 pips, SellTakeProfitPips = 20 pips.
    • BuyPipsInTime = 5 pips, BuyTimeToWait = 10 segundos, BuyVolume = 0,01 lotes.
    • BuyStopLossPips = 20 pips, BuyTakeProfitPips = 20 pips.
  • Filtros:
    • Categoria: Breakout/momentum.
    • Direção: Simétrica (longa e curta).
    • Indicadores: Apenas movimento de preços brutos, sem osciladores.
    • Paradas: Sim (distâncias fixas de pip por lado).
    • Complexidade: Baixa – detector de fuga único com rastreamento de estado simples.
    • Prazo: intradiário, reage aos impulsos de nível de tick uma vez por segundo.
    • Sazonalidade: Não.
    • Redes neurais: Não.
    • Divergência: Não.
    • Nível de risco: Depende das distâncias de pip configuradas; os incumprimentos correspondem ao risco médio nos principais pares de FX.

Entradas

Nome Descrição
SellPipsInTime Distância mínima descendente em pips que deve ser percorrida antes de abrir uma posição curta.
SellTimeToWait Segundos permitiram que o movimento descendente fosse concluído.
SellVolume Volume de negociação para sinais de venda.
SellStopLossPips Distância de stop-loss para posições curtas, expressa em pips.
SellTakeProfitPips Distância de take-profit para posições curtas, expressa em pips.
BuyPipsInTime Distância mínima ascendente em pips que deve ser percorrida antes de abrir uma posição longa.
BuyTimeToWait Segundos permitidos para que o movimento ascendente fosse concluído.
BuyVolume Volume de negociação para sinais de compra.
BuyStopLossPips Distância de stop-loss para posições longas, expressa em pips.
BuyTakeProfitPips Distância de take-profit para posições longas, expressa em pips.

Notas

  • A estratégia depende das melhores atualizações de compra/venda; garantir que o feed de dados forneça cotações precisas de nível um.
  • Definir qualquer distância de pip ou janela de tempo para zero desativa o sinal correspondente porque o preço de referência é redefinido em vez de gerando negócios.
  • Como os níveis de proteção são gerenciados internamente, desconexões inesperadas podem deixar posições sem paradas bruscas. Considere combinando a estratégia com controles de risco externos durante a execução ao vivo.
namespace StockSharp.Samples.Strategies;

using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;

/// <summary>
/// Time Bomb strategy: Momentum zero-line crossover.
/// Buys when momentum crosses above zero, sells when momentum crosses below zero.
/// </summary>
public class TimeBombStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _period;
	private readonly StrategyParam<int> _signalCooldownCandles;

	private decimal _prevMom;
	private int _candlesSinceTrade;
	private bool _hasPrev;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int Period { get => _period.Value; set => _period.Value = value; }
	public int SignalCooldownCandles { get => _signalCooldownCandles.Value; set => _signalCooldownCandles.Value = value; }

	public TimeBombStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_period = Param(nameof(Period), 10)
			.SetGreaterThanZero()
			.SetDisplay("Period", "Momentum period", "Indicators");
		_signalCooldownCandles = Param(nameof(SignalCooldownCandles), 4)
			.SetGreaterThanZero()
			.SetDisplay("Signal Cooldown", "Bars to wait between trades", "Trading");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevMom = 0;
		_candlesSinceTrade = SignalCooldownCandles;
		_hasPrev = false;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevMom = 0;
		_candlesSinceTrade = SignalCooldownCandles;
		_hasPrev = false;
		var mom = new Momentum { Length = Period };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(mom, ProcessCandle).Start();
	}

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

		if (_candlesSinceTrade < SignalCooldownCandles)
			_candlesSinceTrade++;

		if (_hasPrev)
		{
			if (_prevMom <= 0 && momValue > 0 && Position <= 0 && _candlesSinceTrade >= SignalCooldownCandles)
			{
				BuyMarket();
				_candlesSinceTrade = 0;
			}
			else if (_prevMom >= 0 && momValue < 0 && Position >= 0 && _candlesSinceTrade >= SignalCooldownCandles)
			{
				SellMarket();
				_candlesSinceTrade = 0;
			}
		}

		_prevMom = momValue;
		_hasPrev = true;
	}
}