Ver en GitHub

Estrategia de Continuación de Tendencia

Esta estrategia identifica la continuación de la tendencia prevaleciente usando un par de medias móviles exponenciales sobre los datos de precio. Se abre una posición larga cuando la EMA rápida cruza por encima de la EMA lenta, señalando una continuación alcista. Se abre una posición corta cuando la EMA rápida cruza por debajo de la EMA lenta.

Parámetros

  • Fast EMA Length – período para la EMA rápida (por defecto: 20).
  • Candle Type – marco temporal de las velas (por defecto: 4 horas).
  • Stop Loss – stop loss protector aplicado mediante StartProtection (por defecto: 1000).
  • Take Profit – objetivo de beneficio aplicado mediante StartProtection (por defecto: 2000).

Cómo funciona

  1. Al inicio, la estrategia se suscribe a la serie de velas seleccionada y crea dos indicadores EMA.
  2. Cada vela completada se procesa para detectar cruces entre la EMA rápida y la lenta.
  3. Un cruce de abajo hacia arriba abre una posición larga y cierra cualquier posición corta. El cruce opuesto abre una posición corta y cierra cualquier posición larga.
  4. La gestión del riesgo se maneja mediante los parámetros integrados de stop loss y take profit.

Este ejemplo es una conversión simplificada del experto MQL original Exp_TrendContinuation.

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>
/// Trend continuation strategy based on fast and slow EMA cross.
/// Opens long when fast EMA crosses above slow EMA, short on opposite.
/// </summary>
public class TrendContinuationStrategy : Strategy
{
	private readonly StrategyParam<int> _length;
	private readonly StrategyParam<DataType> _candleType;

	private decimal? _prevFast;
	private decimal? _prevSlow;

	public int Length
	{
		get => _length.Value;
		set => _length.Value = value;
	}

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

	public TrendContinuationStrategy()
	{
		_length = Param(nameof(Length), 20)
			.SetGreaterThanZero()
			.SetDisplay("Fast EMA Length", "Period for the fast EMA", "Indicators");

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

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

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

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		_prevFast = _prevSlow = null;

		var fast = new ExponentialMovingAverage { Length = Length };
		var slow = new ExponentialMovingAverage { Length = Length * 2 };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(fast, slow, ProcessCandle)
			.Start();

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

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

		if (!IsFormedAndOnlineAndAllowTrading())
			return;

		if (_prevFast.HasValue && _prevSlow.HasValue)
		{
			if (_prevFast < _prevSlow && fast >= slow && Position <= 0)
				BuyMarket();

			if (_prevFast > _prevSlow && fast <= slow && Position >= 0)
				SellMarket();
		}

		_prevFast = fast;
		_prevSlow = slow;
	}
}