SR Breakout Strategy überwacht die von Donchian-Kanälen abgeleiteten Unterstützungs- und Widerstandsniveaus in zwei Zeitrahmen (H1 und H4). Wenn eine abgeschlossene Kerze über dem Widerstand oder unter der Unterstützung schließt, schreibt die Strategie eine informative Protokollmeldung. Die Implementierung spiegelt die Alarmierungslogik des ursprünglichen MQL4-Experten wider, ohne dass Aufträge erteilt werden müssen.
Wie es funktioniert
Es werden zwei Kerzenabonnements erstellt: eines für den 1-Stunden-Zeitraum und eines für den 4-Stunden-Zeitraum.
Jedes Abonnement ist an seinen eigenen DonchianChannels-Indikator mit einer konfigurierbaren Lookback-Länge (Standard 26) gebunden.
Sobald der Indikator gebildet ist, verfolgt die Strategie für jeden Zeitrahmen den vorherigen Kerzenschluss.
Bei jeder fertigen Kerze wird der aktuelle Schlusskurs mit den oberen und unteren Bändern von Donchian verglichen:
Wenn sich der Schlusskurs von unterhalb nach oberhalb des oberen Bandes bewegt, wird eine Meldung „Über dem Widerstand kreuzen“ protokolliert.
Wenn sich der Schlusskurs von oben nach unten über das untere Band bewegt, wird die Meldung „Unterschreitung der Unterstützung“ protokolliert.
Die Logik reproduziert das Benachrichtigungsverhalten des MQL4-Skripts, indem sie LogInfo-Einträge als Warnungen verwendet.
Parameter
Name
Beschreibung
Standard
LookbackLength
Anzahl der Kerzen, die zur Berechnung von Donchian Unterstützung/Widerstand verwendet werden.
26
Hour1CandleType
Kerzentyp für das einstündige Abonnement.
TimeFrame(1h)
Hour4CandleType
Kerzentyp für das Vier-Stunden-Abonnement.
TimeFrame(4h)
Signale
H1-Ausbruch – wird protokolliert, wenn der einstündige Schlusskurs der Kerze den Widerstand oder die Unterstützung überschreitet.
H4-Ausbruch – wird protokolliert, wenn der 4-Stunden-Kerzenschluss den Widerstand oder die Unterstützung überschreitet.
Notizen
Die Strategie dient ausschließlich der Alarmierung; es führt keine Trades aus.
Damit der Indikator Donchian ordnungsgemäß funktioniert, müssen beide Kerzenabonnements Hoch- und Tiefstdaten liefern.
Passen Sie die Lookback-Länge oder Kerzentypen an, um sie an andere Handelssitzungen oder Instrumente anzupassen.
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Support and resistance breakout strategy using Donchian channels.
/// Buys when price breaks above resistance (upper band), sells when breaks below support (lower band).
/// </summary>
public class SrBreakoutStrategy : Strategy
{
private readonly StrategyParam<int> _lookbackLength;
private readonly StrategyParam<DataType> _candleType;
private readonly Queue<decimal> _highHistory = new();
private readonly Queue<decimal> _lowHistory = new();
public int LookbackLength
{
get => _lookbackLength.Value;
set => _lookbackLength.Value = value;
}
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public SrBreakoutStrategy()
{
_lookbackLength = Param(nameof(LookbackLength), 20)
.SetGreaterThanZero()
.SetDisplay("Lookback", "Number of candles for Donchian channel", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
.SetDisplay("Candle Type", "Timeframe for analysis", "General");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_highHistory.Clear();
_lowHistory.Clear();
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished)
return;
if (_highHistory.Count < LookbackLength)
{
EnqueueCandle(candle);
return;
}
var highs = _highHistory.ToArray();
var lows = _lowHistory.ToArray();
var upper = GetMax(highs);
var lower = GetMin(lows);
var close = candle.ClosePrice;
var range = upper - lower;
var volume = Volume;
if (volume <= 0)
volume = 1;
var breakoutPadding = range * 0.05m;
// Break above resistance
if (close > upper + breakoutPadding)
{
if (Position <= 0)
BuyMarket(Position < 0 ? Math.Abs(Position) + volume : volume);
}
// Break below support
else if (close < lower - breakoutPadding)
{
if (Position >= 0)
SellMarket(Position > 0 ? Math.Abs(Position) + volume : volume);
}
EnqueueCandle(candle);
}
private void EnqueueCandle(ICandleMessage candle)
{
_highHistory.Enqueue(candle.HighPrice);
_lowHistory.Enqueue(candle.LowPrice);
if (_highHistory.Count > LookbackLength)
{
_highHistory.Dequeue();
_lowHistory.Dequeue();
}
}
private static decimal GetMax(IEnumerable<decimal> values)
{
var max = decimal.MinValue;
foreach (var value in values)
{
if (value > max)
max = value;
}
return max;
}
private static decimal GetMin(IEnumerable<decimal> values)
{
var min = decimal.MaxValue;
foreach (var value in values)
{
if (value < min)
min = value;
}
return min;
}
/// <inheritdoc />
protected override void OnReseted()
{
_highHistory.Clear();
_lowHistory.Clear();
base.OnReseted();
}
}