Ver en GitHub

Estrategia RobotPower M5

Esta estrategia combina los indicadores Bulls Power y Bears Power en un gráfico de 5 minutos. Abre posiciones cuando el impulso combinado de toros y osos cruza cero y gestiona las salidas con objetivos fijos y un trailing stop.

Cómo funciona

  • Indicadores: Bulls Power y Bears Power con un período compartido BullBearPeriod.
  • Marco temporal: velas de 5 minutos por defecto (CandleType).

Reglas de entrada

  • Entrada larga: Cuando BullsPower + BearsPower > 0 y no hay posición abierta, comprar a mercado.
  • Entrada corta: Cuando BullsPower + BearsPower < 0 y no hay posición abierta, vender a mercado.

Reglas de salida

  • Take Profit: Cerrar la posición cuando el precio se mueve TakeProfit unidades en la dirección de la operación.
  • Stop Loss: Cerrar la posición si el precio se mueve contra la posición StopLoss unidades.
  • Trailing Stop: Después de la entrada, el stop loss sigue al precio por TrailingStep una vez que el precio avanza más del doble de esa distancia.

Parámetros

  • BullBearPeriod – período para los cálculos de Bulls Power y Bears Power.
  • TrailingStep – tamaño del paso al ajustar el trailing stop.
  • TakeProfit – distancia desde la entrada hasta el nivel de take profit.
  • StopLoss – distancia desde la entrada hasta el nivel de stop loss.
  • CandleType – marco temporal de las velas para el cálculo de señales.

Tamaño de posición

Utiliza la propiedad Volume de la estrategia para el tamaño de la orden.

Notas

Diseñada con fines educativos y sirve como ejemplo de conversión de una estrategia MQL a la API de StockSharp.

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>
/// Bulls and Bears Power crossover strategy with trailing stop.
/// Buys when Bulls Power plus Bears Power is positive and sells when negative.
/// Applies fixed take profit and stop loss with trailing adjustment.
/// </summary>
public class RobotPowerM5Strategy : Strategy
{
	private readonly StrategyParam<int> _bullBearPeriod;
	private readonly StrategyParam<decimal> _trailingStep;
	private readonly StrategyParam<decimal> _takeProfit;
	private readonly StrategyParam<decimal> _stopLoss;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _stopPrice;
	private decimal _takePrice;

	/// <summary>
	/// Period for Bulls Power and Bears Power.
	/// </summary>
	public int BullBearPeriod
	{
		get => _bullBearPeriod.Value;
		set => _bullBearPeriod.Value = value;
	}

	/// <summary>
	/// Trailing step distance.
	/// </summary>
	public decimal TrailingStep
	{
		get => _trailingStep.Value;
		set => _trailingStep.Value = value;
	}

	/// <summary>
	/// Take profit distance in price units.
	/// </summary>
	public decimal TakeProfit
	{
		get => _takeProfit.Value;
		set => _takeProfit.Value = value;
	}

	/// <summary>
	/// Stop loss distance in price units.
	/// </summary>
	public decimal StopLoss
	{
		get => _stopLoss.Value;
		set => _stopLoss.Value = value;
	}

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

	/// <summary>
	/// Initializes a new instance of <see cref="RobotPowerM5Strategy"/>.
	/// </summary>
	public RobotPowerM5Strategy()
	{
		_bullBearPeriod = Param(nameof(BullBearPeriod), 5)
			.SetGreaterThanZero()
			.SetDisplay("Bull/Bear Period", "Bulls and Bears Power period", "Indicators");

		_trailingStep = Param(nameof(TrailingStep), 10m)
			.SetGreaterThanZero()
			.SetDisplay("Trailing Step", "Trailing stop step size", "Risk");

		_takeProfit = Param(nameof(TakeProfit), 150m)
			.SetGreaterThanZero()
			.SetDisplay("Take Profit", "Take profit distance", "Risk");

		_stopLoss = Param(nameof(StopLoss), 105m)
			.SetGreaterThanZero()
			.SetDisplay("Stop Loss", "Stop loss distance", "Risk");

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

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

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

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

		_stopPrice = 0m;
		_takePrice = 0m;

		var bulls = new BullPower { Length = BullBearPeriod };
		var bears = new BearPower { Length = BullBearPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(bulls, bears, ProcessCandle)
			.Start();

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

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

		var sum = bullsValue + bearsValue;

		if (Position == 0)
		{
			if (sum > 0)
			{
				BuyMarket();
				_stopPrice = candle.ClosePrice - StopLoss;
				_takePrice = candle.ClosePrice + TakeProfit;
			}
			else if (sum < 0)
			{
				SellMarket();
				_stopPrice = candle.ClosePrice + StopLoss;
				_takePrice = candle.ClosePrice - TakeProfit;
			}
			return;
		}

		if (Position > 0)
		{
			if (candle.LowPrice <= _stopPrice || candle.HighPrice >= _takePrice)
			{
				SellMarket();
				_stopPrice = 0m;
				_takePrice = 0m;
				return;
			}

			if (candle.ClosePrice - _stopPrice > 2 * TrailingStep)
				_stopPrice = candle.ClosePrice - TrailingStep;
		}
		else if (Position < 0)
		{
			if (candle.HighPrice >= _stopPrice || candle.LowPrice <= _takePrice)
			{
				BuyMarket();
				_stopPrice = 0m;
				_takePrice = 0m;
				return;
			}

			if (_stopPrice - candle.ClosePrice > 2 * TrailingStep)
				_stopPrice = candle.ClosePrice + TrailingStep;
		}
	}
}