Ver en GitHub

Estrategia de Gráfico en Vivo Renko

Esta estrategia emula un gráfico clásico de ladrillos Renko y opera ante cambios en la dirección del ladrillo. Fue convertida del script de MetaTrader RenkoLiveChart_v600.

Lógica

La estrategia construye ladrillos Renko usando velas temporales terminadas. Cuando el precio se mueve al menos el tamaño de caja seleccionado desde el precio del último ladrillo, se forma un nuevo ladrillo. Se abre una posición larga en un ladrillo ascendente y una posición corta en un ladrillo descendente.

Parámetros

  • Candle Type – marco temporal de las velas de entrada utilizadas para la construcción de ladrillos.
  • Brick Size – paso de precio que define la altura de un ladrillo Renko.
  • Brick Offset – desplazamiento inicial en ladrillos aplicado al primer ladrillo.
  • Show Wicks – mostrar mechas en el gráfico al dibujar las velas.

Notas

  • Las operaciones se ejecutan solo en velas completadas.
  • La protección de posición se inicia automáticamente al arrancar la estrategia.
  • Esta implementación se centra en el comportamiento central de Renko e ignora las funciones avanzadas del script original, como el manejo de archivos externos.
using System;
using System.Collections.Generic;

using Ecng.Common;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Renko live chart emulation strategy.
/// </summary>
public class RenkoLiveChartStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<decimal> _brickSize;

	private decimal _renkoPrice;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public decimal BrickSize { get => _brickSize.Value; set => _brickSize.Value = value; }

	public RenkoLiveChartStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Working candle timeframe", "General");

		_brickSize = Param(nameof(BrickSize), 500m)
			.SetGreaterThanZero()
			.SetDisplay("Brick Size", "Renko brick size", "General");
	}

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

	protected override void OnReseted()
	{
		base.OnReseted();
		_renkoPrice = 0;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		SubscribeCandles(CandleType).Bind(ProcessCandle).Start();
	}

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

		var close = candle.ClosePrice;
		var size = BrickSize;

		if (_renkoPrice == 0m)
		{
			_renkoPrice = close;
			return;
		}

		var diff = close - _renkoPrice;
		if (Math.Abs(diff) < size)
			return;

		var direction = Math.Sign(diff);
		_renkoPrice += direction * size;

		if (direction > 0 && Position <= 0)
		{
			if (Position < 0) BuyMarket();
			BuyMarket();
		}
		else if (direction < 0 && Position >= 0)
		{
			if (Position > 0) SellMarket();
			SellMarket();
		}
	}
}