Ver en GitHub

Estrategia EMA SAR Power

Esta estrategia intradía combina medias móviles exponenciales rápidas y lentas con Parabolic SAR e indicadores Bulls/Bears Power. Solo opera durante las horas activas del mercado y requiere margen libre suficiente antes de entrar en cualquier posición.

El sistema va corto cuando la EMA rápida está por debajo de la EMA lenta, el Parabolic SAR se sitúa por encima del máximo de la vela, y Bears Power está subiendo mientras permanece negativo. Va largo cuando la EMA rápida está por encima de la EMA lenta, el Parabolic SAR está por debajo del mínimo de la vela, y Bulls Power está cayendo pero sigue positivo. Cada operación coloca un stop-loss amplio y un take-profit más cercano.

Filtro Dinámico de Margen

Antes de operar, la estrategia verifica el margen libre de la cartera. Dependiendo de su valor, el margen mínimo requerido aumenta escalonadamente: 600 → 1000 → 1300 → 1500 → 1800 → 2000 → 2500. La operación se omite cuando el margen libre cae por debajo del umbral actual.

Detalles

  • Criterios de entrada:
    • Corto: EMA3 < EMA34 && SAR > High && BearsPower < 0 && BearsPower > BearsPower[1].
    • Largo: EMA3 > EMA34 && SAR < Low && BullsPower > 0 && BullsPower < BullsPower[1].
  • Largo/Corto: Ambos lados.
  • Stop/Objetivo: Stop-loss en 2000 puntos, take-profit en 400 puntos.
  • Filtro de tiempo: Opera solo entre las 09:00 y las 16:59 hora del bróker.
  • Indicadores:
    • Medias Móviles Exponenciales (3, 34) sobre precio mediano.
    • Parabolic SAR (paso 0.02, máximo 0.2).
    • Bulls Power (13) y Bears Power (13).
  • Volumen predeterminado: 30 contratos.
  • Marco temporal: Velas de 15 minutos.
  • Filtros:
    • Categoría: Seguimiento de tendencia
    • Dirección: Ambos
    • Indicadores: Múltiples
    • Stops: Sí
    • Complejidad: Moderado
    • Marco temporal: Intradía
    • Estacionalidad: No
    • Redes neuronales: No
    • Divergencia: No
    • Nivel de riesgo: Alto
using System;
using System.Collections.Generic;

using Ecng.Common;

using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;

namespace StockSharp.Samples.Strategies;

/// <summary>
/// EMA crossover strategy with Parabolic SAR confirmation.
/// Buys when fast EMA above slow EMA and SAR below price.
/// Sells when fast EMA below slow EMA and SAR above price.
/// </summary>
public class EmaSarPowerStrategy : Strategy
{
	private readonly StrategyParam<int> _fastLength;
	private readonly StrategyParam<int> _slowLength;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevFast;
	private decimal _prevSlow;
	private bool _hasPrev;

	public int FastLength { get => _fastLength.Value; set => _fastLength.Value = value; }
	public int SlowLength { get => _slowLength.Value; set => _slowLength.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public EmaSarPowerStrategy()
	{
		_fastLength = Param(nameof(FastLength), 3)
			.SetGreaterThanZero()
			.SetDisplay("Fast EMA", "Fast EMA period", "Indicators");

		_slowLength = Param(nameof(SlowLength), 34)
			.SetGreaterThanZero()
			.SetDisplay("Slow EMA", "Slow EMA period", "Indicators");

		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Type of candles", "General");
	}

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

	protected override void OnReseted()
	{
		base.OnReseted();
		_prevFast = 0;
		_prevSlow = 0;
		_hasPrev = false;
	}

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

		var fastEma = new ExponentialMovingAverage { Length = FastLength };
		var slowEma = new ExponentialMovingAverage { Length = SlowLength };
		var sar = new ParabolicSar();

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(fastEma, slowEma, sar, ProcessCandle)
			.Start();

		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			DrawIndicator(area, fastEma);
			DrawIndicator(area, slowEma);
			DrawOwnTrades(area);
		}
	}

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

		if (!_hasPrev)
		{
			_prevFast = fast;
			_prevSlow = slow;
			_hasPrev = true;
			return;
		}

		// Buy: EMA crossover up + SAR below price
		if (_prevFast <= _prevSlow && fast > slow && sar < candle.LowPrice)
		{
			if (Position <= 0)
				BuyMarket();
		}
		// Sell: EMA crossover down + SAR above price
		else if (_prevFast >= _prevSlow && fast < slow && sar > candle.HighPrice)
		{
			if (Position >= 0)
				SellMarket();
		}

		_prevFast = fast;
		_prevSlow = slow;
	}
}