Ver en GitHub

Gestión de Riesgo y Tamaño de Posición - Ejemplo con MACD

La estrategia Gestión de Riesgo y Tamaño de Posición - Ejemplo con MACD demuestra el dimensionamiento dinámico de posiciones basado en la equidad actual. Se basa en cruces de MACD de un marco temporal superior combinados con un filtro de tendencia de media móvil.

Detalles

  • Criterios de entrada: La línea MACD cruza por encima/debajo de la línea de señal con confirmación de tendencia.
  • Largo/Corto: Ambas direcciones.
  • Criterios de salida: Cruce MACD opuesto.
  • Stops: Ninguno.
  • Valores predeterminados:
    • InitialBalance = 10000m
    • LeverageEquity = true
    • MarginFactor = -0.5m
    • Quantity = 3.5m
    • MacdMaType = MovingAverageTypeEnum.EMA
    • FastMaLength = 11
    • SlowMaLength = 26
    • SignalMaLength = 9
    • MacdTimeFrame = TimeSpan.FromMinutes(30)
    • TrendMaType = MovingAverageTypeEnum.EMA
    • TrendMaLength = 55
    • TrendTimeFrame = TimeSpan.FromDays(1)
    • CandleType = TimeSpan.FromMinutes(5).TimeFrame()
  • Filtros:
    • Categoría: Seguimiento de tendencia
    • Dirección: Ambos
    • Indicadores: MACD, Moving Average
    • Stops: No
    • Complejidad: Intermedio
    • Marco temporal: Intradía (5m)
    • Estacionalidad: No
    • Redes neuronales: No
    • Divergencia: No
    • Nivel de riesgo: Medio
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>
/// Risk management MACD strategy using EMA crossover.
/// </summary>
public class RiskManagementAndPositionsizeMacdExampleStrategy : Strategy
{
	private readonly StrategyParam<int> _slowLength;
	private readonly StrategyParam<DataType> _candleType;

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

	public RiskManagementAndPositionsizeMacdExampleStrategy()
	{
		_slowLength = Param(nameof(SlowLength), 40)
			.SetGreaterThanZero()
			.SetDisplay("Slow Length", "Slow EMA period", "General");

		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Candle type", "General");
	}

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

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		var fast = new ExponentialMovingAverage { Length = 14 };
		var slow = new ExponentialMovingAverage { Length = SlowLength };
		var prevF = 0m; var prevS = 0m; var init = false;
		var lastSignal = DateTimeOffset.MinValue;
		var cooldown = TimeSpan.FromMinutes(360);
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(fast, slow, (candle, f, s) =>
		{
			if (candle.State != CandleStates.Finished) return;
			if (!fast.IsFormed || !slow.IsFormed) return;
			if (!init) { prevF = f; prevS = s; init = true; return; }
			if (candle.OpenTime - lastSignal >= cooldown)
			{
				if (prevF <= prevS && f > s && Position <= 0) { BuyMarket(); lastSignal = candle.OpenTime; }
				else if (prevF >= prevS && f < s && Position >= 0) { SellMarket(); lastSignal = candle.OpenTime; }
			}
			prevF = f; prevS = s;
		}).Start();
		var area = CreateChartArea();
		if (area != null) { DrawCandles(area, subscription); DrawIndicator(area, fast); DrawIndicator(area, slow); DrawOwnTrades(area); }
	}
}