Ver en GitHub

Estrategia de Correo de Estado y Alerta al Cerrar Orden

Esta estrategia monitorea la cuenta e informa sobre eventos importantes:

  • Envía una notificación de estado diaria en un minuto especificado.
  • Informa sobre cada orden cerrada con información básica de la operación.

Está basada en el experto MQL StatusMailandAlertOnOrderClose.mq4 y muestra cómo gestionar notificaciones en StockSharp.

Parámetros

Nombre Descripción
SendReportEmail Habilitar notificación de estado diaria.
StatusEmailMinute Minuto de la hora para enviar el mensaje de estado.
SendClosedEmail Habilitar notificaciones cuando se cierran órdenes.
StartBalance Saldo inicial de la cuenta usado para el cálculo de beneficios.
CandleType Marco temporal usado para verificar el reloj. Normalmente configurado a 1 minuto.

Lógica

  1. Suscribirse a velas del marco temporal elegido.
  2. Cuando finaliza una vela, comprobar si es el minuto especificado y enviar un mensaje de informe.
  3. En cada nueva operación, notificar si se ha cerrado una orden.

Estos mensajes se registran mediante AddInfo, pero pueden reemplazarse por cualquier mecanismo de notificación deseado.

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 with status tracking.
/// </summary>
public class StatusMailAndAlertOnOrderCloseStrategy : 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 StatusMailAndAlertOnOrderCloseStrategy()
	{
		_fastLength = Param(nameof(FastLength), 9)
			.SetGreaterThanZero()
			.SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
		_slowLength = Param(nameof(SlowLength), 26)
			.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 fast = new ExponentialMovingAverage { Length = FastLength };
		var slow = new ExponentialMovingAverage { Length = SlowLength };
		SubscribeCandles(CandleType).Bind(fast, slow, ProcessCandle).Start();
	}

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

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

		_prevFast = fast; _prevSlow = slow;
	}
}