Einfache WPR-Strategie für benutzerdefinierte Cloud
Überblick
Die WPR Custom Cloud Simple Strategy ist ein StockSharp-Port des MetaTrader-Expertenberaters WPR Custom Cloud Simple.mq5. Der EA überwacht den %R-Oszillator von Larry Williams und eröffnet Geschäfte, wenn der Indikator den überverkauften oder überkauften Bereich verlässt. Diese C#-Version behält das ursprüngliche Design des Handels nur bei neuen Kerzen bei, kehrt die Position um, wenn ein entgegengesetztes Signal erscheint, und vermeidet Stop-Loss- oder Take-Profit-Orders genau wie die Referenzimplementierung.
Handelslogik
Abonnieren Sie den konfigurierten Zeitrahmen (CandleType) und füttern Sie einen WilliamsR-Indikator mit den eingehenden Kerzen.
Warten Sie, bis die Kerze fertig ist. Die Strategie wirkt sich niemals auf unvollständige Balken aus.
Speichern Sie die letzten beiden abgeschlossenen %R-Werte. Sie spiegeln die Messwerte wpr[1] und wpr[2] von MetaTrader wider.
Signale an Kreuzungen erzeugen:
Long Setup: Der vorherige Balken schließt über OversoldLevel, während der Balken davor unter diesem Niveau lag. Dadurch wird die Bedingung „Ausstieg aus Überverkauft“ (wpr[2] < level und wpr[1] > level) aus EA neu erstellt.
Kurze Einrichtung: Der vorherige Balken schließt unter OverboughtLevel, während der frühere Balken darüber lag, was mit der ursprünglichen wpr[2] > level- und wpr[1] < level-Prüfung übereinstimmt.
Wenn ein Long-Setup auftritt, glätten Sie das Short-Engagement und kaufen Sie ein Nettovolumen. Wenn ein Short-Setup ausgelöst wird, glätten Sie die Long-Seite und verkaufen Sie ein Nettovolumen. Da StockSharp mit Nettopositionen arbeitet, reproduziert das Senden von BuyMarket/SellMarket mit Volume + |Position| perfekt den Close-and-Reverse-Ablauf vom Sicherungskonto von MetaTrader.
Es werden keine zusätzlichen Ausgänge verwendet; Ein neuer entgegengesetzter Crossover ist die einzige Möglichkeit, Geschäfte abzuschließen, genau wie im ursprünglichen Berater.
Parameter
Name
Typ
Standard
MetaTrader Gegenstück
Beschreibung
WprPeriod
int
14
Inp_WPR_Period
Lookback-Länge für die Williams %R-Berechnung.
OverboughtLevel
decimal
-20
Inp_WPR_Level1
Schwellenwert, der den überkauften Bereich definiert. Eine Unterschreitung löst Shorts aus.
OversoldLevel
decimal
-80
Inp_WPR_Level2
Schwellenwert, der den überverkauften Bereich definiert. Ein Überschreiten dieser Grenze löst Long-Positionen aus.
CandleType
DataType
1-stündiger Zeitrahmen
InpWorkingPeriod
Kerzenserien, die zur Aktualisierung des Indikators und zur Auswertung von Signalen verwendet werden.
Volume
decimal
Basisvolumen der Strategie
InpLots
Losgröße für Marktaufträge. Die Strategie gleicht die aktuelle Nettoposition automatisch aus, bevor ein neuer Trade eröffnet wird.
Unterschiede zum Original EA
StockSharp arbeitet mit Nettopositionen. Die Schließung des gegenteiligen Risikos erfolgt durch Erhöhung des Marktauftragsvolumens, sodass das Verhalten dem Absicherungsmodell ohne zusätzliche Buchhaltungsstrukturen wie STRUCT_POSITION entspricht.
Alle Hilfsklassen zur Auftragsverwaltung (CTrade, CPositionInfo, Margenprüfungen usw.) werden durch die integrierten Risikokontrollen von StockSharp ersetzt. Die Strategie basiert auf Strategy.Volume und den Austauschmetadaten anstelle manueller Berechnungen der freien Marge.
Die Protokollierung wird vereinfacht. Die Version StockSharp vermeidet ausführliche Print-Anweisungen, da die High-Level-Version API bereits Bestellstatusaktualisierungen bereitstellt.
Schutzanordnungen werden absichtlich weggelassen, um das „Schließen bei entgegengesetztem Signal“-Design der Quelle EA widerzuspiegeln.
Anwendungstipps
Passen Sie CandleType an den gleichen Zeitrahmen an, den Sie in MetaTrader verwendet haben, um die Crossover-Häufigkeit vergleichbar zu halten.
Williams %R-Schwellenwerte sind negative Werte. Wenn Sie OverboughtLevel näher an Null heranrücken, werden Short-Einträge seltener, während eine Verschiebung von OversoldLevel in Richtung -100 Long-Einträge seltener macht.
Die Strategie geht davon aus, dass Volume bereits den Mindestschritt- und Netting-Regeln des Brokers entspricht. Passen Sie das Basisvolumen in der Benutzeroberfläche oder per Code an, bevor Sie mit dem Live-Handel beginnen.
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Williams %R cloud breakout strategy converted from the MetaTrader expert advisor.
/// Looks for %R crossings above -80 to go long and below -20 to go short.
/// Positions are reversed when an opposite signal appears.
/// </summary>
public class WprCustomCloudSimpleStrategy : Strategy
{
private readonly StrategyParam<int> _wprPeriod;
private readonly StrategyParam<decimal> _overboughtLevel;
private readonly StrategyParam<decimal> _oversoldLevel;
private readonly StrategyParam<DataType> _candleType;
private WilliamsR _williamsR;
private decimal? _previousWpr;
private decimal? _olderWpr;
public int WprPeriod
{
get => _wprPeriod.Value;
set => _wprPeriod.Value = value;
}
public decimal OverboughtLevel
{
get => _overboughtLevel.Value;
set => _overboughtLevel.Value = value;
}
public decimal OversoldLevel
{
get => _oversoldLevel.Value;
set => _oversoldLevel.Value = value;
}
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public WprCustomCloudSimpleStrategy()
{
_wprPeriod = Param(nameof(WprPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("WPR Period", "Williams %R lookback length", "Williams %R");
_overboughtLevel = Param(nameof(OverboughtLevel), -10m)
.SetDisplay("Overbought Level", "%R level that marks overbought conditions", "Williams %R");
_oversoldLevel = Param(nameof(OversoldLevel), -90m)
.SetDisplay("Oversold Level", "%R level that marks oversold conditions", "Williams %R");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
.SetDisplay("Candle Type", "Timeframe used for Williams %R", "Data");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_williamsR = new WilliamsR { Length = WprPeriod };
_previousWpr = null;
_olderWpr = null;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(_williamsR, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, _williamsR);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal wprValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!_williamsR.IsFormed)
{
_olderWpr = _previousWpr;
_previousWpr = wprValue;
return;
}
if (_previousWpr is not null && _olderWpr is not null)
{
var prev = _previousWpr.Value;
var prevPrev = _olderWpr.Value;
var crossedAboveOversold = prevPrev < OversoldLevel && prev > OversoldLevel;
var crossedBelowOverbought = prevPrev > OverboughtLevel && prev < OverboughtLevel;
var volume = Volume;
if (volume <= 0)
volume = 1;
if (crossedAboveOversold)
{
if (Position <= 0)
BuyMarket(Position < 0 ? Math.Abs(Position) + volume : volume);
}
else if (crossedBelowOverbought)
{
if (Position >= 0)
SellMarket(Position > 0 ? Math.Abs(Position) + volume : volume);
}
}
_olderWpr = _previousWpr;
_previousWpr = wprValue;
}
/// <inheritdoc />
protected override void OnReseted()
{
_williamsR = null;
_previousWpr = null;
_olderWpr = null;
base.OnReseted();
}
}