Ver en GitHub

Estrategia de Ruptura Bw WiseMan-1

Esta estrategia es un port de StockSharp del asesor experto MetaTrader Exp_BW-wiseMan-1. Automatiza la lógica de ruptura WiseMan-1 de Bill Williams construida alrededor del indicador Alligator. Las señales se producen cada vez que una vela completada escapa de las mandíbulas del Alligator y simultáneamente rompe los extremos de oscilación más recientes. El modo contrario opcional intercambia las señales para que la estrategia pueda desvanecerse de las mismas rupturas.

Idea principal

  • Calcular el Alligator de Bill Williams usando medias móviles suavizadas del precio mediano (alto + bajo) / 2.
  • Desplazar las líneas de mandíbula, dientes y labios hacia adelante por desplazamientos configurables para coincidir con la visualización del indicador original.
  • Confirmar una ruptura solo cuando la vela actual se expande más allá de los máximos o mínimos de los últimos N barras, asegurando que el movimiento sea más fuerte que el ruido reciente.
  • Retrasar la ejecución por el número seleccionado de velas completadas para que el trader pueda operar en señales más antiguas si lo desea.

Reglas de trading

Dirección larga

  1. La barra debe terminar por debajo de las tres líneas del Alligator (precio alto menor que mandíbula, dientes y labios).
  2. El precio de cierre necesita estar en la mitad superior de la vela, es decir, por encima de la mediana de la vela.
  3. El mínimo de la vela debe ser estrictamente menor que los mínimos de las barras Back anteriores.
  4. Cuando la señal se activa después del retraso SignalBar:
    • Cerrar cualquier corto abierto si Close Short está habilitado.
    • Abrir una nueva posición larga si Enable Long está habilitado y no hay ninguna posición actualmente abierta.

Dirección corta

  1. La barra debe terminar por encima de las tres líneas del Alligator (precio bajo mayor que mandíbula, dientes y labios).
  2. El precio de cierre debe estar en la mitad inferior de la vela, es decir, por debajo de la mediana de la vela.
  3. El máximo de la vela tiene que ser mayor que los máximos de las barras Back anteriores.
  4. Cuando la señal se activa:
    • Cerrar cualquier largo existente si Close Long está habilitado.
    • Abrir una nueva posición corta si Enable Short está habilitado y no hay posición actual.

Modo contrario

Establecer Counter-Trend Mode en true intercambia las señales de compra y venta para que la estrategia tome operaciones contra la dirección de ruptura del Alligator.

Parámetros

  • Candle Type – marco temporal usado para construir velas y calcular todos los valores del indicador (predeterminado: 1 hora).
  • Counter-Trend Mode – invertir la lógica de ruptura para operar contra la tendencia primaria (predeterminado: habilitado, siguiendo el EA original).
  • Breakout Depth (Back) – número de barras anteriores comparadas con el máximo/mínimo actual al validar una ruptura (predeterminado: 2).
  • Jaw Length / Shift – longitud de la media móvil suavizada y desplazamiento hacia adelante para la línea de mandíbula (predeterminados: 13 / 8).
  • Teeth Length / Shift – longitud de la media móvil suavizada y desplazamiento hacia adelante para la línea de dientes (predeterminados: 8 / 5).
  • Lips Length / Shift – longitud de la media móvil suavizada y desplazamiento hacia adelante para la línea de labios (predeterminados: 5 / 3).
  • Signal Bar – número de velas ya terminadas para esperar antes de ejecutar una señal detectada (predeterminado: 1).
  • Enable Long / Enable Short – interruptores para abrir nuevas posiciones largas o cortas.
  • Close Long / Close Short – interruptores para cerrar posiciones opuestas cuando se activa la señal.

Notas

  • La estrategia se basa únicamente en órdenes de mercado y no establece niveles duros de stop-loss o take-profit. Cualquier salida es impulsada por la señal opuesta o deshabilitando el interruptor de cierre relevante.
  • Todos los cálculos se realizan en velas terminadas; los datos parciales intrabar se ignoran para mantener la consistencia con el experto MetaTrader fuente.
  • El volumen se hereda de la configuración de estrategia de StockSharp. Ajuste el volumen base en la configuración de la plataforma si necesita un tamaño de posición diferente.
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>
/// Bill Williams Wiseman 1 strategy using Alligator-style triple EMA crossover.
/// </summary>
public class BwWiseman1Strategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _jawPeriod;
	private readonly StrategyParam<int> _teethPeriod;
	private readonly StrategyParam<int> _lipsPeriod;

	private decimal? _prevLips;
	private decimal? _prevTeeth;

	public DataType CandleType
	{
		get => _candleType.Value;
		set => _candleType.Value = value;
	}

	public int JawPeriod
	{
		get => _jawPeriod.Value;
		set => _jawPeriod.Value = value;
	}

	public int TeethPeriod
	{
		get => _teethPeriod.Value;
		set => _teethPeriod.Value = value;
	}

	public int LipsPeriod
	{
		get => _lipsPeriod.Value;
		set => _lipsPeriod.Value = value;
	}

	public BwWiseman1Strategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe", "General");

		_jawPeriod = Param(nameof(JawPeriod), 34)
			.SetGreaterThanZero()
			.SetDisplay("Jaw Period", "Slow EMA (Jaw)", "Indicators");

		_teethPeriod = Param(nameof(TeethPeriod), 13)
			.SetGreaterThanZero()
			.SetDisplay("Teeth Period", "Medium EMA (Teeth)", "Indicators");

		_lipsPeriod = Param(nameof(LipsPeriod), 5)
			.SetGreaterThanZero()
			.SetDisplay("Lips Period", "Fast EMA (Lips)", "Indicators");
	}

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
	{
		return [(Security, CandleType)];
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevLips = null;
		_prevTeeth = null;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		_prevLips = null;
		_prevTeeth = null;

		var jaw = new SmoothedMovingAverage { Length = JawPeriod };
		var teeth = new SmoothedMovingAverage { Length = TeethPeriod };
		var lips = new SmoothedMovingAverage { Length = LipsPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(jaw, teeth, lips, ProcessCandle)
			.Start();

		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			DrawIndicator(area, jaw);
			DrawIndicator(area, teeth);
			DrawIndicator(area, lips);
			DrawOwnTrades(area);
		}
	}

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

		if (!IsFormedAndOnlineAndAllowTrading())
		{
			_prevLips = lipsVal;
			_prevTeeth = teethVal;
			return;
		}

		if (_prevLips == null || _prevTeeth == null)
		{
			_prevLips = lipsVal;
			_prevTeeth = teethVal;
			return;
		}

		// Lips crosses above teeth → buy
		if (_prevLips.Value <= _prevTeeth.Value && lipsVal > teethVal)
		{
			if (Position < 0)
				BuyMarket();
			if (Position <= 0)
				BuyMarket();
		}
		// Lips crosses below teeth → sell
		else if (_prevLips.Value >= _prevTeeth.Value && lipsVal < teethVal)
		{
			if (Position > 0)
				SellMarket();
			if (Position >= 0)
				SellMarket();
		}

		_prevLips = lipsVal;
		_prevTeeth = teethVal;
	}
}