RangeEA Weekly Grid Strategy es un sistema de cuadrícula de orden límite convertido del asesor experto MetaTrader original. El algoritmo identifica la corriente.
rango de negociación semanal y lo completa con un número configurable de órdenes límite pendientes. Cada orden utiliza stop-loss dinámico y
compensaciones de toma de ganancias escaladas en relación con la distancia entre el precio límite y el precio de mercado actual, respetando al mismo tiempo
distancias mínimas expresadas en puntos. Las ganancias se pueden bloquear cerrando todo el libro una vez que el capital de la cartera crece en un
porcentaje predefinido.
La implementación aprovecha el alto nivel de StockSharp API: las velas impulsan la lógica de decisión, las órdenes pendientes se gestionan con el
Los métodos de ayuda estratégica y los controles de riesgo se exponen como parámetros listos para la optimización.
Lógica de trading
Suscríbete a dos transmisiones de velas:
Un período de tiempo definido por el usuario (1 hora por defecto) que impulsa el mantenimiento de la red.
Velas semanales que se utilizan para estimar el rango de negociación actual.
Para cada vela semanal terminada, actualice el máximo más alto y el mínimo más bajo de las últimas dos semanas. Su diferencia se convierte
el rango de negociación activo.
En cada vela comercial terminada:
Respete la ventana comercial configurada (StartTradeHour a EndTradeHour).
Opcionalmente, restablezca la cuadrícula al comienzo de cada día de negociación.
Si no existen órdenes límite pendientes, distribuya las nuevas órdenes uniformemente entre el rango bajo y el rango alto.
Después de que ya se hayan ejecutado dos órdenes, reemplace la penúltima ejecución con una nueva orden al mismo precio cuando la cuadrícula
se reduce a NumberOfOrders - 2 elementos.
Supervise continuamente el patrimonio de la cuenta y liquide todo cuando se alcance el porcentaje de ganancia configurado.
Cuando se cierre la ventana de negociación y CloseAllAtEndTrade esté habilitado, cancele todas las órdenes pendientes y salga de las posiciones existentes.
Parámetros
Nombre
Descripción
Predeterminado
CandleType
Plazo de negociación utilizado para activar el mantenimiento de la red.
velas de 1 hora
WeeklyCandleType
Plazo utilizado para derivar los límites del rango.
velas de 1 semana
StartTradeHour
Hora del día en la que se podrán realizar nuevos pedidos.
0
EndTradeHour
Hora del día en que se detiene la negociación.
24
CloseAllAtEndTrade
Cierre todas las órdenes y posiciones fuera de la ventana de negociación.
cierto
MaxOpenOrders
Número máximo de órdenes y posiciones simultáneas.
5
NumberOfOrders
Número de órdenes límite en la grilla.
10
OrderVolume
Volumen utilizado para cada pedido.
0,01
ResetOrdersDaily
Reconstruya la red al comienzo de cada día de negociación.
cierto
StopLossPoints
Distancia mínima de stop-loss en puntos.
60
TakeProfitPoints
Distancia mínima de toma de ganancias en puntos.
60
StopLossMultiplier
Multiplicador aplicado a la distancia dinámica de stop-loss.
3
TakeProfitMultiplier
Multiplicador aplicado a la distancia dinámica de toma de ganancias.
1
TargetPercentage
Porcentaje de ganancia patrimonial que desencadena la liquidación.
8
Gestión del riesgo
La estrategia respeta el límite MaxOpenOrders para mantener bajo control el número de órdenes y posiciones activas.
Los niveles de stop-loss y take-profit siempre están al menos a la cantidad configurada de puntos de la entrada y, opcionalmente, pueden ser
ampliado por los parámetros del multiplicador.
La opción de reinicio diario evita que las órdenes obsoletas se transfieran a una nueva sesión.
Un objetivo de capital a nivel de cartera permite que la estrategia asegure ganancias al aplanar el libro.
Notas
Asegúrese de que el valor seleccionado proporcione velas semanales; de lo contrario, la estrategia no puede calcular el rango.
Cuando utilice instrumentos con niveles de precios no estándar, ajuste la configuración basada en puntos para que coincida con el tamaño del tick subyacente.
La optimización de NumberOfOrders, OrderVolume y los multiplicadores de parada/toma ayudan a adaptar la cuadrícula a diferentes niveles de
volatilidad.
using System;
using System.Collections.Generic;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Range based grid strategy that detects the trading range from recent price action
/// and places buy/sell limit orders at grid levels within the range.
/// Buys at lower grid levels, sells at upper grid levels.
/// </summary>
public class RangeWeeklyGridStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _rangePeriod;
private readonly StrategyParam<int> _gridLevels;
private decimal _rangeHigh;
private decimal _rangeLow;
private bool _rangeSet;
private decimal _entryPrice;
private DateTimeOffset _lastTradeTime;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int RangePeriod
{
get => _rangePeriod.Value;
set => _rangePeriod.Value = value;
}
public int GridLevels
{
get => _gridLevels.Value;
set => _gridLevels.Value = value;
}
public RangeWeeklyGridStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Primary candle type", "General");
_rangePeriod = Param(nameof(RangePeriod), 100)
.SetDisplay("Range Period", "Number of candles to determine range", "Logic");
_gridLevels = Param(nameof(GridLevels), 5)
.SetDisplay("Grid Levels", "Number of grid levels within the range", "Logic");
}
protected override void OnReseted()
{
base.OnReseted();
_rangeHigh = 0;
_rangeLow = 0;
_rangeSet = false;
_entryPrice = 0;
_lastTradeTime = default;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var highest = new Highest { Length = RangePeriod };
var lowest = new Lowest { Length = RangePeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(highest, lowest, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal highestValue, decimal lowestValue)
{
if (candle.State != CandleStates.Finished)
return;
if (highestValue <= 0 || lowestValue <= 0 || highestValue <= lowestValue)
return;
_rangeHigh = highestValue;
_rangeLow = lowestValue;
_rangeSet = true;
if (!_rangeSet)
return;
var range = _rangeHigh - _rangeLow;
if (range <= 0)
return;
// Cooldown: at least 1 day between trades
if (_lastTradeTime != default && candle.CloseTime - _lastTradeTime < TimeSpan.FromDays(1))
return;
var gridStep = range / (GridLevels + 1);
var close = candle.ClosePrice;
var mid = (_rangeHigh + _rangeLow) / 2;
// Buy when price is in lower portion of range
if (close <= _rangeLow + gridStep && Position <= 0)
{
BuyMarket();
_entryPrice = close;
_lastTradeTime = candle.CloseTime;
}
// Sell when price is in upper portion of range
else if (close >= _rangeHigh - gridStep && Position >= 0)
{
SellMarket();
_entryPrice = close;
_lastTradeTime = candle.CloseTime;
}
// Take profit at mid-range
else if (Position > 0 && close >= mid)
{
SellMarket();
_lastTradeTime = candle.CloseTime;
}
else if (Position < 0 && close <= mid)
{
BuyMarket();
_lastTradeTime = candle.CloseTime;
}
}
}
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 Highest, Lowest
from StockSharp.Algo.Strategies import Strategy
class range_weekly_grid_strategy(Strategy):
def __init__(self):
super(range_weekly_grid_strategy, self).__init__()
self._range_period = self.Param("RangePeriod", 100).SetDisplay("Range Period", "Candles to determine range", "Logic")
self._grid_levels = self.Param("GridLevels", 5).SetDisplay("Grid Levels", "Grid levels within range", "Logic")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))).SetDisplay("Candle Type", "Primary candle type", "General")
@property
def CandleType(self): return self._candle_type.Value
@CandleType.setter
def CandleType(self, value): self._candle_type.Value = value
def OnStarted2(self, time):
super(range_weekly_grid_strategy, self).OnStarted2(time)
highest = Highest()
highest.Length = self._range_period.Value
lowest = Lowest()
lowest.Length = self._range_period.Value
sub = self.SubscribeCandles(self.CandleType)
sub.Bind(highest, lowest, self.OnProcess).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, sub)
self.DrawOwnTrades(area)
def OnProcess(self, candle, highest_val, lowest_val):
if candle.State != CandleStates.Finished:
return
if highest_val <= 0 or lowest_val <= 0 or highest_val <= lowest_val:
return
rng = highest_val - lowest_val
if rng <= 0:
return
grid_step = rng / (self._grid_levels.Value + 1)
close = candle.ClosePrice
mid = (highest_val + lowest_val) / 2.0
if close <= lowest_val + grid_step and self.Position <= 0:
self.BuyMarket()
elif close >= highest_val - grid_step and self.Position >= 0:
self.SellMarket()
elif self.Position > 0 and close >= mid:
self.SellMarket()
elif self.Position < 0 and close <= mid:
self.BuyMarket()
def CreateClone(self):
return range_weekly_grid_strategy()