La estrategia VR Smart Grid Lite Averaging es un sistema de promediado de red que sigue al asesor experto original MetaTrader 5. El algoritmo abre órdenes de mercado en la dirección de la vela alcista o bajista más reciente y construye una escalera estilo martingala cada vez que el precio se mueve en contra de la posición. Las distancias, los volúmenes y la lógica de salida se pueden ajustar para que coincidan con la implementación original de MQL.
Lógica de trading
En cada vela completa, la estrategia comprueba su dirección.
Una vela alcista permite una nueva orden de compra si el precio actual está al menos Order Step (pips) por debajo de la entrada de compra más baja existente.
Una vela bajista permite una nueva orden de venta si el precio actual está al menos Order Step (pips) por encima de la entrada de venta más alta existente.
El primer pedido para cada lado usa Start Volume. Cada pedido adicional duplica el volumen del pedido más lejano en ese lado, mientras que Max Volume limita el tamaño absoluto.
Cuando solo existe una posición en un lado, la operación se cierra una vez que el precio alcanza la distancia Take Profit (pips).
Con dos o más posiciones la lógica de cierre depende del Close Mode seleccionado:
Promedio: cierra los pedidos más altos y más bajos una vez que el precio alcanza su promedio ponderado más Minimal Profit (pips).
PartialClose: cierra por completo la orden más baja y reduce la orden más alta en Start Volume cuando el precio alcanza el objetivo combinado.
Gestión del riesgo
Los volúmenes se ajustan a los MinVolume, MaxVolume y StepVolume del broker para evitar el rechazo.
La llamada incorporada StartProtection() garantiza que la protección de la cuenta StockSharp esté activada antes de operar.
Parámetros
Nombre
Descripción
Take Profit (pips)
Distancia objetivo para posiciones abiertas individuales.
Start Volume
Volumen para el pedido inicial en cada dirección.
Max Volume
Volumen máximo permitido por pedido (0 desactiva el límite).
Close Mode
Elija entre salidas promediadas o cierres parciales.
Order Step (pips)
Movimiento adverso mínimo antes de agregar una nueva orden.
Minimal Profit (pips)
Colchón de beneficios adicional añadido a la salida promediada.
Candle Type
Serie de velas utilizadas para la generación de señales.
Notas
La estrategia utiliza únicamente órdenes de mercado; Las órdenes pendientes del EA original se emulan evaluando las condiciones de cada vela.
La implementación mantiene el estado por pedido para imitar la gestión basada en tickets de MetaTrader, incluidos cierres parciales y salidas selectivas.
Configure el tipo de vela y el tamaño del pip del símbolo para que coincida con el período de tiempo utilizado en el script MQL para un comportamiento consistente.
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()