Diese Strategie emuliert einen klassischen Renko-Brick-Chart und handelt bei Richtungsänderungen der Bricks. Sie wurde aus dem MetaTrader-Skript RenkoLiveChart_v600 konvertiert.
Logik
Die Strategie baut Renko-Bricks aus abgeschlossenen zeitbasierten Kerzen. Wenn der Preis mindestens die gewählte Box-Größe vom letzten Brick-Preis abweicht, wird ein neuer Brick gebildet. Eine Long-Position wird bei einem aufwärts gerichteten Brick eröffnet und eine Short-Position bei einem abwärts gerichteten Brick.
Parameter
Candle Type – Zeitrahmen der Eingabekerzen, die für den Brick-Aufbau verwendet werden.
Brick Size – Preisschritt, der die Höhe eines Renko-Bricks definiert.
Brick Offset – anfänglicher Versatz in Bricks, der auf den ersten Brick angewendet wird.
Show Wicks – Dochte auf dem Chart beim Zeichnen von Kerzen anzeigen.
Hinweise
Trades werden nur auf abgeschlossenen Kerzen ausgeführt.
Der Positionsschutz wird beim Start der Strategie automatisch gestartet.
Diese Implementierung konzentriert sich auf das Kern-Renko-Verhalten und ignoriert erweiterte Funktionen des Originalskripts, wie das Handling externer Dateien.
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();
}
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Strategies import Strategy
class renko_live_chart_strategy(Strategy):
def __init__(self):
super(renko_live_chart_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Working candle timeframe", "General")
self._brick_size = self.Param("BrickSize", 500.0) \
.SetDisplay("Brick Size", "Renko brick size", "General")
self._renko_price = 0.0
@property
def candle_type(self):
return self._candle_type.Value
@property
def brick_size(self):
return self._brick_size.Value
def OnReseted(self):
super(renko_live_chart_strategy, self).OnReseted()
self._renko_price = 0.0
def OnStarted2(self, time):
super(renko_live_chart_strategy, self).OnStarted2(time)
self.SubscribeCandles(self.candle_type).Bind(self.process_candle).Start()
def process_candle(self, candle):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
size = float(self.brick_size)
if self._renko_price == 0.0:
self._renko_price = close
return
diff = close - self._renko_price
if abs(diff) < size:
return
direction = 1 if diff > 0 else -1
self._renko_price += direction * size
if direction > 0 and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif direction < 0 and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
def CreateClone(self):
return renko_live_chart_strategy()