RangeEA Weekly Grid Strategy é um sistema de grade de ordem limite convertido do consultor especialista MetaTrader original. O algoritmo identifica a corrente
faixa de negociação semanal e a preenche com um número configurável de ordens com limite pendentes. Cada pedido usa stop-loss dinâmico e
compensações de take-profit escalonadas em relação à distância entre o preço limite e o preço de mercado atual, respeitando também
distâncias mínimas expressas em pontos. Os lucros podem ser bloqueados fechando todo o livro assim que o patrimônio do portfólio crescer
porcentagem predefinida.
A implementação aproveita o API de alto nível de API: velas conduzem a lógica de decisão, pedidos pendentes são gerenciados com o
métodos auxiliares de estratégia e controles de risco são expostos como parâmetros prontos para otimização.
Lógica de negociação
Assine dois streams de velas:
Um período de tempo definido pelo usuário (1 hora por padrão) que orienta a manutenção da rede.
Velas semanais que são usadas para estimar a faixa de negociação atual.
Para cada vela semanal concluída, atualize a máxima mais alta e a mínima mais baixa das últimas duas semanas. A diferença deles torna-se
a faixa de negociação ativa.
Em cada vela de negociação finalizada:
Respeite a janela de negociação configurada (StartTradeHour a EndTradeHour).
Opcionalmente, redefina a grade no início de cada dia de negociação.
Se não existirem ordens com limite pendentes, distribua as novas ordens uniformemente entre o intervalo mínimo e o intervalo máximo.
Depois que duas ordens já tiverem sido executadas, substitua o penúltimo preenchimento por uma nova ordem com o mesmo preço quando a grade
diminui para NumberOfOrders - 2 itens.
Monitore continuamente o patrimônio da conta e liquide tudo quando o percentual de lucro configurado for atingido.
Quando a janela de negociação fechar e CloseAllAtEndTrade estiver ativado, cancele todas as ordens pendentes e saia das posições existentes.
Parâmetros
Nome
Descrição
Padrão
CandleType
Prazo de negociação usado para acionar a manutenção da rede.
Velas de 1 hora
WeeklyCandleType
Período usado para derivar os limites do intervalo.
velas de 1 semana
StartTradeHour
Hora do dia em que novos pedidos podem ser feitos.
0
EndTradeHour
Hora do dia em que a negociação é interrompida.
24
CloseAllAtEndTrade
Feche todas as ordens e posições fora da janela de negociação.
verdade
MaxOpenOrders
Número máximo de ordens e posições simultâneas.
5
NumberOfOrders
Número de ordens limitadas na grade.
10
OrderVolume
Volume utilizado para cada pedido.
0,01
ResetOrdersDaily
Reconstrua a grade no início de cada dia de negociação.
verdade
StopLossPoints
Distância mínima de stop-loss em pontos.
60
TakeProfitPoints
Distância mínima de take-profit em pontos.
60
StopLossMultiplier
Multiplicador aplicado à distância dinâmica de stop-loss.
3
TakeProfitMultiplier
Multiplicador aplicado à distância dinâmica do take-profit.
1
TargetPercentage
Porcentagem de ganho patrimonial que desencadeia a liquidação.
8
Gestão de risco
A estratégia respeita o limite MaxOpenOrders para manter o número de ordens e posições ativas sob controle.
Os níveis de stop-loss e take-profit estão sempre a pelo menos o número configurado de pontos de distância da entrada e podem opcionalmente ser
estendido pelos parâmetros do multiplicador.
A opção de redefinição diária evita que pedidos obsoletos sejam transferidos para uma nova sessão.
Uma meta de patrimônio no nível do portfólio permite que a estratégia obtenha lucros ao nivelar a carteira.
Notas
Certifique-se de que o título selecionado forneça velas semanais; caso contrário, a estratégia não poderá calcular o intervalo.
Ao usar instrumentos com etapas de preços não padronizadas, ajuste as configurações baseadas em pontos para corresponder ao tamanho do tick subjacente.
Otimizar NumberOfOrders, OrderVolume e os multiplicadores stop/take ajuda a adaptar a grade a diferentes níveis de
volatilidade.
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()