Ver en GitHub

Estrategia objetivo diaria

Descripción general

DailyTargetStrategy replica el MetaTrader 4 asesores expertos "Daily Target". La estrategia mantiene el comercio de posiciones abiertas hasta las ganancias y pérdidas combinadas para el día calendario actual alcanzan un objetivo de ganancias configurado o superan un límite máximo de pérdidas. como Tan pronto como se alcanza cualquiera de los umbrales, todas las órdenes activas se cancelan y la posición se aplana, de modo que la negociación permanece en pausa hasta el comienza el día siguiente.

Lógica de trading

  1. Puesta en marcha
    • La estrategia llama a ResetDailySnapshot durante OnStarted para almacenar la fecha actual y la línea base de PnL realizada.
    • SubscribeLevel1() ofrece actualizaciones de oferta/demanda que son necesarias para evaluar las ganancias flotantes con precisión.
    • SubscribeTrades() captura el último precio ejecutado y proporciona un respaldo cuando faltan cotizaciones.
    • Un tick Timer de un minuto garantiza que se detecten cambios de fecha incluso cuando no lleguen datos de mercado.
  2. Evaluación PnL
    • EvaluateDailyThresholds vuelve a calcular el PnL realizado (} actual menos la línea base almacenada) y agrega el PnL flotante calculado a partir de la última oferta/demanda o del último precio comercial.
    • Si el PnL diario total cruza el objetivo configurado o cae por debajo del límite de pérdida negativa, la estrategia llama TriggerDailyStop.
  3. Salida de emergencia
    • TriggerDailyStop escribe una entrada de registro informativa, cancela todas las órdenes pendientes y envía la orden de mercado adecuada a aplanar la exposición larga o corta restante.
    • _dailyStopTriggered impide el reingreso durante el mismo día. Cuando cambia la fecha del calendario, ResetDailySnapshot borra esto marca y registra una nueva línea base de PnL.

Parámetros

Nombre Predeterminado Descripción
DailyTarget 10 Objetivo de beneficio en la moneda de la cartera. Las operaciones se detienen por el resto del día una vez que el PnL diario total alcanza o excede este valor.
DailyMaxLoss 0 Pérdida máxima tolerada en la moneda de la cartera. Establezca en cero para desactivar el filtro de pérdida. La negociación se detiene durante el día una vez que el PnL diario total cae por debajo del umbral negativo.

Notas

  • La estrategia solo administra el Security principal asignado a la instancia de la estrategia, reflejando el comportamiento de un solo símbolo del MQL experto.
  • PnL flotante utiliza la mejor oferta para posiciones largas y la mejor demanda para posiciones cortas. Si no hay cotización disponible, la última operación El precio actúa como un respaldo para evitar detener la evaluación.
  • No se proporciona ningún puerto Python; En este paquete solo se incluye la implementación de alto nivel de C#.
namespace StockSharp.Samples.Strategies;

using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;

/// <summary>
/// Daily Target strategy: TEMA crossover.
/// Buys when fast TEMA crosses above slow TEMA, sells on cross below.
/// </summary>
public class DailyTargetStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;

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

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
	public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }

	public DailyTargetStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_fastPeriod = Param(nameof(FastPeriod), 10)
			.SetGreaterThanZero()
			.SetDisplay("Fast TEMA", "Fast TEMA period", "Indicators");
		_slowPeriod = Param(nameof(SlowPeriod), 30)
			.SetGreaterThanZero()
			.SetDisplay("Slow TEMA", "Slow TEMA period", "Indicators");
	}

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

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevFast = 0;
		_prevSlow = 0;
		_hasPrev = false;
		var fast = new ExponentialMovingAverage { Length = FastPeriod };
		var slow = new ExponentialMovingAverage { Length = SlowPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(fast, slow, ProcessCandle).Start();
	}

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

		if (_hasPrev)
		{
			if (_prevFast <= _prevSlow && fastValue > slowValue && Position <= 0)
				BuyMarket();
			else if (_prevFast >= _prevSlow && fastValue < slowValue && Position >= 0)
				SellMarket();
		}
		else
		{
			if (fastValue > slowValue && Position <= 0)
				BuyMarket();
			else if (fastValue < slowValue && Position >= 0)
				SellMarket();
		}

		_prevFast = fastValue;
		_prevSlow = slowValue;
		_hasPrev = true;
	}
}