Die VR Smart Grid Lite Averaging-Strategie ist ein Grid-Averaging-System, das dem ursprünglichen MetaTrader 5 Expert Advisor folgt. Der Algorithmus öffnet Marktaufträge in Richtung der letzten bullischen oder bärischen Kerze und baut eine Leiter im Martingal-Stil auf, wenn sich der Preis gegen die Position bewegt. Entfernungen, Volumina und Ausgangslogik können so angepasst werden, dass sie der ursprünglichen MQL-Implementierung entsprechen.
Handelslogik
Bei jeder abgeschlossenen Kerze überprüft die Strategie ihre Richtung.
Eine bullische Kerze ermöglicht eine neue Kauforder, wenn der aktuelle Preis mindestens Order Step (pips) unter dem niedrigsten bestehenden Kaufeinstieg liegt.
Eine bärische Kerze ermöglicht einen neuen Verkaufsauftrag, wenn der aktuelle Preis mindestens Order Step (pips) über dem höchsten bestehenden Verkaufseintrag liegt.
Die erste Bestellung für jede Seite verwendet Start Volume. Jede weitere Ordnung verdoppelt das Volumen der am weitesten entfernten Ordnung auf dieser Seite, während Max Volume die absolute Größe begrenzt.
Wenn auf einer Seite nur eine einzige Position vorhanden ist, wird der Handel geschlossen, sobald der Preis die Distanz Take Profit (pips) erreicht.
Bei zwei oder mehr Positionen hängt die Abschlusslogik vom ausgewählten Close Mode ab:
Durchschnitt – schließt die höchsten und niedrigsten Orders, sobald der Preis ihren gewichteten Durchschnitt plus Minimal Profit (pips) erreicht.
PartialClose – schließt die niedrigste Order vollständig und reduziert die höchste Order um Start Volume, wenn der Preis das gemischte Ziel erreicht.
Risikomanagement
Die Volumina werden an die MinVolume, MaxVolume und StepVolume des Brokers angepasst, um eine Ablehnung zu vermeiden.
Der integrierte StartProtection()-Aufruf stellt sicher, dass der Kontoschutz von StockSharp vor dem Handel aktiviert wird.
Parameter
Name
Beschreibung
Take Profit (pips)
Zieldistanz für einzelne offene Positionen.
Start Volume
Volumen für die Erstbestellung in jede Richtung.
Max Volume
Maximal zulässiges Volumen pro Bestellung (0 deaktiviert das Limit).
Close Mode
Wählen Sie zwischen durchschnittlichen Exits oder teilweisen Schließungen.
Order Step (pips)
Minimale Gegenbewegung vor dem Hinzufügen einer neuen Bestellung.
Minimal Profit (pips)
Zusätzlicher Gewinnpuffer zum durchschnittlichen Ausstieg hinzugefügt.
Candle Type
Kerzenserie zur Signalerzeugung.
Notizen
Die Strategie verwendet nur Marktaufträge; Ausstehende Aufträge des ursprünglichen EA werden durch die Auswertung der Bedingungen für jede Kerze emuliert.
Die Implementierung behält den Status pro Bestellung bei, um die Ticket-basierte Verwaltung von MetaTrader nachzuahmen, einschließlich teilweiser Schließungen und selektiver Ausgänge.
Konfigurieren Sie den Kerzentyp und die Symbol-Pip-Größe so, dass sie mit dem im MQL-Skript verwendeten Zeitrahmen übereinstimmen, um ein konsistentes Verhalten zu gewährleisten.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// VR Smart Grid Lite Averaging: grid with averaging approach using Bollinger Bands.
/// Buys near lower band, sells near upper band.
/// </summary>
public class VrSmartGridLiteAveragingStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _bbPeriod;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int BbPeriod
{
get => _bbPeriod.Value;
set => _bbPeriod.Value = value;
}
public VrSmartGridLiteAveragingStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_bbPeriod = Param(nameof(BbPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("BB Period", "Bollinger Bands period", "Indicators");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var bb = new BollingerBands { Length = BbPeriod };
decimal? prevClose = null;
decimal? prevMid = null;
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(bb, (candle, bbVal) =>
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var bbv = (BollingerBandsValue)bbVal;
if (bbv.UpBand is not decimal upper || bbv.LowBand is not decimal lower)
return;
var close = candle.ClosePrice;
var mid = (upper + lower) / 2m;
if (prevClose.HasValue && prevMid.HasValue)
{
var crossBelow = prevClose.Value >= prevMid.Value && close < mid;
var crossAbove = prevClose.Value <= prevMid.Value && close > mid;
if (crossBelow && Position <= 0)
BuyMarket();
else if (crossAbove && Position >= 0)
SellMarket();
}
prevClose = close;
prevMid = mid;
})
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, bb);
DrawOwnTrades(area);
}
}
}
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.Indicators import BollingerBands
from StockSharp.Algo.Strategies import Strategy
from datatype_extensions import *
from indicator_extensions import *
class vr_smart_grid_lite_averaging_strategy(Strategy):
"""Bollinger Bands grid averaging: buy below midline, sell above midline."""
def __init__(self):
super(vr_smart_grid_lite_averaging_strategy, self).__init__()
self._bb_period = self.Param("BbPeriod", 20).SetGreaterThanZero().SetDisplay("BB Period", "Bollinger Bands period", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(30))).SetDisplay("Candle Type", "Timeframe", "General")
@property
def CandleType(self): return self._candle_type.Value
@CandleType.setter
def CandleType(self, value): self._candle_type.Value = value
def OnReseted(self):
super(vr_smart_grid_lite_averaging_strategy, self).OnReseted()
self._prev_close = None
self._prev_mid = None
def OnStarted2(self, time):
super(vr_smart_grid_lite_averaging_strategy, self).OnStarted2(time)
self._prev_close = None
self._prev_mid = None
bb = BollingerBands()
bb.Length = self._bb_period.Value
sub = self.SubscribeCandles(self.CandleType)
sub.BindEx(bb, self.OnProcess).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, sub)
self.DrawIndicator(area, bb)
self.DrawOwnTrades(area)
def OnProcess(self, candle, bb_val):
if candle.State != CandleStates.Finished:
return
if not bb_val.IsFormed:
return
# Extract upper and lower bands
upper = None
lower = None
for key in bb_val.InnerValues:
name = str(key.Key.Name) if hasattr(key.Key, 'Name') else str(key.Key)
val = float(key.Value)
name_lower = name.lower()
if 'up' in name_lower:
upper = val
elif 'low' in name_lower or 'down' in name_lower:
lower = val
if upper is None or lower is None:
return
close = float(candle.ClosePrice)
mid = (upper + lower) / 2.0
if self._prev_close is not None and self._prev_mid is not None:
cross_below = self._prev_close >= self._prev_mid and close < mid
cross_above = self._prev_close <= self._prev_mid and close > mid
if cross_below and self.Position <= 0:
self.BuyMarket()
elif cross_above and self.Position >= 0:
self.SellMarket()
self._prev_close = close
self._prev_mid = mid
def CreateClone(self):
return vr_smart_grid_lite_averaging_strategy()