Ver en GitHub

Estrategia 2MA Bunny Cross Expert

La estrategia 2MA Bunny Cross Expert opera el cruce de dos medias móviles simples. Se abre una operación larga cuando la media rápida sube por encima de la lenta, mientras que se abre una operación corta cuando la media rápida cae por debajo de la lenta. Cualquier posición opuesta se cierra antes de abrir una nueva.

Detalles

  • Propósito: seguimiento de tendencia mediante el cruce de medias móviles
  • Operativa: largo y corto
  • Indicadores: Media móvil simple rápida y lenta
  • Stops: ninguno
  • Valores predeterminados:
    • CandleType = 1 minute
    • FastLength = 5
    • SlowLength = 20
using System;
using System.Linq;
using System.Collections.Generic;

using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Two moving average crossover strategy converted from "2MA Bunny Cross Expert".
/// Uses fast and slow simple moving averages to generate signals.
/// </summary>
public class TwoMaBunnyCrossStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastLength;
	private readonly StrategyParam<int> _slowLength;

	private SimpleMovingAverage _fastSma;
	private SimpleMovingAverage _slowSma;

	private decimal _prevFast;
	private decimal _prevSlow;

	/// <summary>
	/// Candle type for calculations.
	/// </summary>
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	/// <summary>
	/// Fast moving average length.
	/// </summary>
	public int FastLength { get => _fastLength.Value; set => _fastLength.Value = value; }

	/// <summary>
	/// Slow moving average length.
	/// </summary>
	public int SlowLength { get => _slowLength.Value; set => _slowLength.Value = value; }

	/// <summary>
	/// Initializes a new instance of <see cref="TwoMaBunnyCrossStrategy"/>.
	/// </summary>
	public TwoMaBunnyCrossStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe for candles", "General");

		_fastLength = Param(nameof(FastLength), 5)
			.SetGreaterThanZero()
			.SetDisplay("Fast MA Length", "Length of fast moving average", "Parameters")
			;

		_slowLength = Param(nameof(SlowLength), 20)
			.SetGreaterThanZero()
			.SetDisplay("Slow MA Length", "Length of slow moving average", "Parameters")
			;
	}

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

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

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

		_fastSma = new SMA { Length = FastLength };
		_slowSma = new SMA { Length = SlowLength };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(_fastSma, _slowSma, ProcessCandle)
			.Start();

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

	}

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

		if (fast > slow && candle.ClosePrice > slow && Position <= 0)
			BuyMarket();
		else if (fast < slow && candle.ClosePrice < slow && Position >= 0)
			SellMarket();

		_prevFast = fast;
		_prevSlow = slow;
	}
}