Ver en GitHub

Estrategia SMA Multi Hedge2

Esta estrategia opera un instrumento base mientras hace cobertura con un instrumento correlacionado. La dirección de la tendencia se determina mediante una Media Móvil Simple (SMA). Cuando la correlación entre los instrumentos base y de cobertura supera un umbral, ambos instrumentos se operan para formar un par neutral al mercado.

Cómo funciona

  1. Calcular la tendencia del instrumento base usando una SMA de longitud configurable.
  2. Medir la correlación entre los instrumentos base y de cobertura usando la diferencia entre el precio y su propia SMA.
  3. Si la correlación alcanza el nivel esperado, abrir posiciones en ambos instrumentos. La dirección de la cobertura puede seguir u oponerse a la base según la configuración.
  4. Las posiciones se cierran automáticamente cuando la ganancia combinada alcanza el valor objetivo.

Parámetros

  • SmaPeriod — período de la SMA usado para detectar la tendencia. Por defecto 20.
  • CorrelationPeriod — número de muestras usado para evaluar la correlación. Por defecto 20.
  • ExpectedCorrelation — correlación absoluta mínima requerida para activar la cobertura. Por defecto 0.8.
  • ProfitTarget — objetivo de ganancia total en unidades monetarias. Por defecto 30.
  • CandleType — tipo de datos para suscripción de velas. Por defecto marco temporal de 1 minuto.
  • FollowBase — si es verdadero, la cobertura opera en la misma dirección cuando la correlación es positiva.

Indicadores

  • SMA
  • Correlación (cálculo personalizado)

Notas

Este es un port simplificado de la estrategia MQL original. La gestión de riesgo y dinero debe ajustarse antes de operar en vivo.

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>
/// SMA trend direction strategy.
/// </summary>
public class SmaMultiHedge2Strategy : Strategy
{
	private readonly StrategyParam<int> _emaPeriod;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevEma1;
	private decimal _prevEma2;
	private int _count;

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

	public SmaMultiHedge2Strategy()
	{
		_emaPeriod = Param(nameof(EmaPeriod), 20)
			.SetGreaterThanZero()
			.SetDisplay("EMA Period", "EMA trend period", "Parameters");
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Candle type", "Parameters");
	}

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

	protected override void OnReseted()
	{
		base.OnReseted();
		_prevEma1 = 0;
		_prevEma2 = 0;
		_count = 0;
	}

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

		var ema = new ExponentialMovingAverage { Length = EmaPeriod };

		SubscribeCandles(CandleType)
			.Bind(ema, ProcessCandle)
			.Start();
	}

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

		_count++;
		if (_count < 3)
		{
			_prevEma2 = _prevEma1;
			_prevEma1 = emaVal;
			return;
		}

		var trend = 0;
		if (_prevEma2 < _prevEma1 && _prevEma1 < emaVal)
			trend = 1;
		else if (_prevEma2 > _prevEma1 && _prevEma1 > emaVal)
			trend = -1;

		_prevEma2 = _prevEma1;
		_prevEma1 = emaVal;

		if (trend == 1 && Position <= 0)
		{
			if (Position < 0) BuyMarket();
			BuyMarket();
		}
		else if (trend == -1 && Position >= 0)
		{
			if (Position > 0) SellMarket();
			SellMarket();
		}
	}
}