
A estratégia de negociação de grelha adaptativa é uma estratégia quantitativa baseada em um sistema de negociação de grelha que se adapta às mudanças no mercado, ajustando automaticamente a posição da linha de grelha. A estratégia usa vários indicadores técnicos para calcular os melhores pontos de negociação e atualizar a grelha de acordo com a mudança dinâmica dos preços.
A estratégia baseia-se nos seguintes componentes centrais e princípios de funcionamento:
Mecanismos de suavização: A estratégia primeiro trata o preço de forma suave, com suporte a vários tipos de médias móveis (retorno linear, SMA, EMA, VWMA e TEMA), permitindo aos usuários escolher o método de suavização adequado de acordo com suas preferências.
Parâmetro de atraso (Laziness)Esta é uma inovação fundamental da estratégia, através da introdução da função de atraso lz ((), que atualiza os sinais apenas quando a variação de preço excede uma determinada porcentagem, filtrando efetivamente o ruído do mercado.
Mecanismo de construção da grade:
Logística de geração de sinais:
Mecanismo de controle de transação:
Atualização da grelha dinâmicaQuando a média móvel preguiçosa (LMA) muda, toda a estrutura da grelha é reajustada para que a estratégia se adapte a uma nova faixa de preços.
A estratégia usa uma matriz para armazenar os preços de cada linha de grade, e determina pontos de compra e venda específicos através do cálculo do preço e do cruzamento das linhas de grade, levando em consideração várias restrições para evitar transações desnecessárias.
Forte adaptaçãoA maior vantagem da estratégia é a capacidade de ajustar automaticamente a posição da grade de acordo com as mudanças do mercado, sem a necessidade de intervenção humana. Através de parâmetros de flexibilidade e mecanismo de ajuste de pontos de foco, a grade pode se mover com a mudança da tendência de preços, mantendo-se sempre relevante.
Filtro de ruídoA introdução do parâmetro de atraso (Laziness) é uma inovação que assegura que o ajuste da grelha só é acionado quando a mudança de preço é suficientemente significativa, reduzindo efetivamente a resposta ao ruído do mercado e aumentando a estabilidade da estratégia.
Personalização flexívelA estratégia oferece uma ampla variedade de configurações de parâmetros, incluindo o número de grades, o intervalo de grades, as preferências de direção, o tipo de smoothing, etc., que o usuário pode ajustar de acordo com diferentes características do mercado e estilo de negociação pessoal.
Áreas de negociação visuais: A estratégia mostra os blocos de negociação atualmente ativos através do preenchimento de cores, permitindo que os comerciantes tenham uma visão intuitiva da posição dos preços atuais na grelha, facilitando a tomada de decisões.
Controle de RiscoA estratégia estabelece um mecanismo natural de controle de risco para evitar transações desfavoráveis em condições de mercado extremas, limitando as transações a apenas uma rede específica.
Logística de entrada e saída unificadaO uso da mesma linha de grade como sinal de compra e venda mantém a consistência e a previsibilidade da lógica de negociação.
Risco de rupturaA estratégia é essencialmente uma estratégia de negociação intermitente, que pode enfrentar perdas persistentes em mercados de forte tendência. A estratégia pode aumentar continuamente a posição na direção errada quando o preço quebra o limite inferior da grelha e continua a se mover em um só sentido. A solução é adicionar o componente de identificação de tendências ou suspender a negociação da grelha quando a tendência é confirmada.
Sensibilidade do parâmetroO desempenho da estratégia é altamente dependente da configuração de parâmetros, especialmente o parâmetro de atraso (Laziness) e o parâmetro de elasticidade (Elasticity). Parâmetros inadequados podem levar a ajustes de grelha tardios ou excessivamente sensíveis. Recomenda-se otimizar esses parâmetros por meio de retrospectiva em diferentes ambientes de mercado.
Risco de uma pirâmide de posiçõesA estratégia permite várias entradas na mesma direção (pyramiding = 4), o que pode levar a uma excessiva alavancagem e concentração de risco em condições de mercado extremas. Deve-se considerar a criação de limites máximos de posse e gestão de posições dinâmicas.
Ponto de deslizamento e efeitos da taxaAs estratégias de negociação de grades geralmente envolvem negociações frequentes, e na execução real, os pontos de deslizamento e as taxas de comissão podem afetar significativamente a lucratividade da estratégia. Esses fatores precisam ser incluídos na retrospectiva e podem ser necessários para ajustar o intervalo de grades para equilibrar a frequência de negociação com o custo.
Tratamento de conflitos de sinalQuando os sinais de compra e venda aparecem simultaneamente, a estratégia atual opta por ignorar os dois sinais, o que pode levar a perder oportunidades de negociação importantes. Pode-se considerar a resolução de conflitos de sinais com base em indicadores de mercado adicionais ou padrões de preços.
Ajustes de parâmetros de adaptaçãoA estratégia pode ser ainda mais otimizada para ajustar automaticamente o intervalo de grade e os parâmetros de atraso de acordo com a volatilidade do mercado. Por exemplo, aumentar o intervalo de grade em mercados de alta volatilidade e reduzir o intervalo de grade em mercados de baixa volatilidade, permitindo que a estratégia se adapte melhor a diferentes condições de mercado.
Integração de componentes de identificação de tendênciasA estratégia atual pode não funcionar bem em mercados de tendência, pode ser introduzido um indicador de identificação de tendência (como o ADX, o cruzamento de médias móveis, etc.) para ajustar automaticamente a direção de negociação ou suspender a grelha de negociação quando uma tendência forte é identificada.
Gestão de posições dinâmicasA estratégia atual usa tamanho de posição fixo, mas pode ser melhorada para gerenciamento de posições dinâmicas baseadas em cálculos de risco, como ajustar o tamanho da posição de acordo com o ATR ou distribuir fundos de acordo com a porcentagem de valor líquido da conta.
Análise de Multi-Framas de TempoIntrodução da análise de múltiplos quadros temporais, usando a direção de tendências de períodos de tempo mais longos para filtrar os sinais de negociação, executando a grelha de negociação apenas na direção de tendências de quadros temporais maiores.
Mecanismo de stop loss perfeitoA estratégia atual não possui um mecanismo de stop loss definido, podendo ser adicionado um stop global baseado na situação do mercado em geral, ou um stop loss separado para cada nível de grade, para limitar o máximo de perdas em uma única transação.
Otimização do tempo de entrada e saídaA estratégia pode integrar o volume de negócios ou a dinâmica de preços, otimizando o tempo de entrada e saída específico através de condições de filtragem adicionais quando o sinal da grade é acionado, aumentando a taxa de sucesso.
Integração de aprendizagem de máquina: Pode-se considerar o uso de algoritmos de aprendizagem de máquina para otimizar a posição da grade e a seleção de parâmetros, prever a melhor configuração da grade por meio de modelos de treinamento de dados históricos e melhorar ainda mais a adaptabilidade da estratégia.
A estratégia de negociação de grelha auto-adaptável resolve a falta de flexibilidade da estratégia de negociação de grelha tradicional por meio de uma função de atraso inovadora e um mecanismo de ajuste de grelha dinâmico. Ela é capaz de se adaptar automaticamente às mudanças no mercado, capturar oportunidades de negociação em diferentes faixas de preços e controlar o comportamento de negociação por meio de vários parâmetros.
Apesar de existirem problemas potenciais, como risco de ruptura de intervalo e sensibilidade de parâmetros, a estratégia tem potencial para obter um desempenho estável em vários ambientes de mercado, através da integração de direções de otimização, como identificação de tendências e ajustes de parâmetros dinâmicos. Na aplicação prática, é recomendável verificar o desempenho da estratégia primeiro por meio de um feedback abrangente, especialmente em diferentes condições de mercado, e ajustar os parâmetros de acordo com as características de cada tipo de transação para obter o melhor efeito.
//@version=5
// This source code is subject to the terms of the Mozilla Public License 2.0 https://mozilla.org/MPL/2.0/
// ©mvs1231 || xxattaxx
strategy(title='Grid Bot Auto Strategy', shorttitle='GridBot', initial_capital = 100000, overlay=true, pyramiding=4, default_qty_type = strategy.fixed, default_qty_value = 0, commission_value = 0.04, commission_type = strategy.commission.percent, margin_long = 0, margin_short = 0, process_orders_on_close = true)
//----<User Inputs>------------------------------------------------------------------------------//
iLen = input.int(7, 'Smoothing Length(7)', minval=1)
iMA = input.string('lreg', 'Smoothing Type', options=['lreg', 'sma', 'ema', 'vwma', 'tema'])
iLZ = input.float(4.0, 'Laziness(4%)', step=.25) / 100
iELSTX = input(50.0, 'Elasticity(50)')
iGI = input.float(2.0, 'Grid Interval(2%)', step=.25) / 100
iGrids = input.int(6, 'Number of Grids', options=[2, 4, 6, 8])
iCool = input.int(2, 'Cooldown(2)', minval=0)
iDir = input.string('neutral', 'Direction', options=['neutral', 'up', 'down'])
iGT = input.int(70, 'Grid Line Transparency(100 to hide)', minval=0, maxval=100)
iFT = input.int(90, 'Fill Transparency(100 to hide)', minval=0, maxval=100)
iSS = input.string('small', 'Signal Size', options=['small', 'large'])
iReset = input(true, 'Reset Buy/Sell Index When Grids Change')
iEXTR = input(true, 'Use Highs/Lows for Signals')
iMT = input(true, 'Show Min Tick')
iRFC = input(false, 'Reverse Fill Colors')
qty_ent = iGrids/2
qty_pos = strategy.initial_capital / qty_ent / 2 / open
//----<Colors>-----------------------------------------------------------------------------------//
RedGrid = color.new(color.red, iGT)
GreenGrid = color.new(color.green, iGT)
Crimson = #DC143C
LimeGreen = #32CD32
//----<Variables>--------------------------------------------------------------------------------//
NextUP = 0.0
NextDN = 0.0
LastSignal = 0
LastSignal_Index = 0
AP = 0.0
G = iGrids
Buy = false
Sell = false
UpperLimit = 0.0
LowerLimit = 0.0
SignalLine = 0.0
CurrentGrid = 0.0
BuyLine = 0.0
SellLine = 0.0
DIR = 0
MeaningOfLife = 42
//----<Calculations>-----------------------------------------------------------------------------//
//Lazy Formula
lz(x, lzf) =>
LZ = 0.0
s = math.sign(x)
LZ := x == nz(x[1], x) ? x : x > nz(LZ[1] + lzf * LZ[1] * s, x) ? x : x < nz(LZ[1] - lzf * LZ[1] * s, x) ? x : LZ[1]
LZ
//Smoothing
LR = ta.linreg(close, iLen, 0)
SMA = ta.sma(close, iLen)
EMA = ta.ema(close, iLen)
VWMA = ta.vwma(close, iLen)
TEMA = ta.ema(ta.ema(ta.ema(close, iLen), iLen), iLen)
MA = iMA == 'lreg' ? LR : iMA == 'sma' ? SMA : iMA == 'ema' ? EMA : iMA == 'vwma' ? VWMA : TEMA
//Make Lazy
LMA = lz(MA, iLZ)
//Calculate Elasticity
ELSTX = syminfo.mintick * iELSTX
//Show Mintick
if iMT and barstate.islast
table.cell(table.new(position.top_right, 1, 1), 0, 0, str.tostring(syminfo.mintick))
//Anchor Point
AP := MA > LMA ? AP[1] + ELSTX : MA < LMA ? AP[1] - ELSTX : AP[1]
AP := AP >= NextUP[1] ? NextUP[1] : AP
AP := AP <= NextDN[1] ? NextDN[1] : AP
//Reset if Next Level Reached or AP is crossed
AP := LMA != LMA[1] ? LMA : AP
//Next Gridlines
NextUP := LMA != LMA[1] ? LMA + LMA * iGI : NextUP[1]
NextDN := LMA != LMA[1] ? LMA - LMA * iGI : NextDN[1]
//Grid Interval
GI = AP * iGI
//----<Grid Array>-------------------------------------------------------------------------------//
a_grid = array.new_float(9)
for x = -4 to 4 by 1
array.set(a_grid, x + 4, AP + GI * x)
Get_Array_Values(ArrayName, index) =>
value = array.get(ArrayName, index)
value
//----<Set Static Grids>-------------------------------------------------------------------------//
G0 = Get_Array_Values(a_grid, 0) //Upper4
G1 = Get_Array_Values(a_grid, 1) //Upper3
G2 = Get_Array_Values(a_grid, 2) //Upper2
G3 = Get_Array_Values(a_grid, 3) //Upper1
G4 = Get_Array_Values(a_grid, 4) //Center
G5 = Get_Array_Values(a_grid, 5) //Lower1
G6 = Get_Array_Values(a_grid, 6) //Lower2
G7 = Get_Array_Values(a_grid, 7) //Lower3
G8 = Get_Array_Values(a_grid, 8) //Lower4
//----<Set Upper and Lower Limits>---------------------------------------------------------------//
UpperLimit := G >= 8 ? G8 : G >= 6 ? G7 : G >= 4 ? G6 : G5
LowerLimit := G >= 8 ? G0 : G >= 6 ? G1 : G >= 4 ? G2 : G3
//----<Calculate Signals>------------------------------------------------------------------------//
Get_Signal_Index() =>
Value = 0.0
Buy_Index = 0
Sell_Index = 0
start = 4 - G / 2
end = 4 + G / 2
for x = start to end by 1
Value := Get_Array_Values(a_grid, x)
if iEXTR
Sell_Index := low[1] < Value and high >= Value ? x : Sell_Index
Buy_Index := high[1] > Value and low <= Value ? x : Buy_Index
Buy_Index
else
Sell_Index := close[1] < Value and close >= Value ? x : Sell_Index
Buy_Index := close[1] > Value and close <= Value ? x : Buy_Index
Buy_Index
[Buy_Index, Sell_Index]
[BuyLine_Index, SellLine_Index] = Get_Signal_Index()
//----<Signals>----------------------------------------------------------------------------------//
Buy := BuyLine_Index > 0 ? true : Buy
Sell := SellLine_Index > 0 ? true : Sell
//No repeat trades at current level
Buy := low >= SignalLine[1] - GI ? false : Buy
Sell := high <= SignalLine[1] + GI ? false : Sell
//No trades outside of grid limits
Buy := close > UpperLimit ? false : Buy
Buy := close < LowerLimit ? false : Buy
Sell := close < LowerLimit ? false : Sell
Sell := close > UpperLimit ? false : Sell
//Direction Filter (skip one signal if against market direction)
DIR := iDir == 'up' ? 1 : iDir == 'down' ? -1 : 0
Buy := DIR == -1 and low >= SignalLine[1] - GI * 2 ? false : Buy
Sell := DIR == 1 and high <= SignalLine[1] + GI * 2 ? false : Sell
//Conflicting Signals
if Buy and Sell
Buy := false
Sell := false
LastSignal_Index := LastSignal_Index[1]
LastSignal_Index
//----<Cooldown>---------------------------------------------------------------------------------//
y = 0
for i = 1 to iCool by 1
if Buy[i] or Sell[i]
y := 0
break
y += 1
y
CoolDown = y
Buy := CoolDown < iCool ? false : Buy
Sell := CoolDown < iCool ? false : Sell
//----<Trackers>---------------------------------------------------------------------------------//
LastSignal := Buy ? 1 : Sell ? -1 : LastSignal[1]
LastSignal_Index := Buy ? BuyLine_Index : Sell ? SellLine_Index : LastSignal_Index[1]
SignalLine := Get_Array_Values(a_grid, LastSignal_Index)
//Reset to Center Grid when LMA changes
if iReset
SignalLine := LMA < LMA[1] ? UpperLimit : SignalLine
SignalLine := LMA > LMA[1] ? LowerLimit : SignalLine
SignalLine
BuyLine := Get_Array_Values(a_grid, BuyLine_Index)
SellLine := Get_Array_Values(a_grid, SellLine_Index)
//----<Plot Grids>--------------------------//
color apColor = na
apColor := MA < AP ? color.new(color.red, iGT) : MA > AP ? color.new(color.green, iGT) : apColor[1]
apColor := LMA != LMA[1] ? na : apColor
plot(G >= 8 ? G0 : na, color=GreenGrid)
plot(G >= 6 ? G1 : na, color=GreenGrid)
plot(G >= 4 ? G2 : na, color=GreenGrid)
plot(G >= 2 ? G3 : na, color=GreenGrid)
plot(G4, color=apColor, linewidth=4) // Center
plot(G >= 2 ? G5 : na, color=RedGrid)
plot(G >= 4 ? G6 : na, color=RedGrid)
plot(G >= 6 ? G7 : na, color=RedGrid)
plot(G >= 8 ? G8 : na, color=RedGrid)
//fill
LineAbove = SignalLine == UpperLimit ? SignalLine : SignalLine + GI
LineBelow = SignalLine == LowerLimit ? SignalLine : SignalLine - GI
a = plot(LineAbove, color=color.new(color.red, 100), style=plot.style_circles)
b = plot(LineBelow, color=color.new(color.green, 100), style=plot.style_circles)
boxColor = LastSignal == 1 ? color.new(color.green, iFT) : color.new(color.red, iFT)
if iRFC
boxColor := LastSignal == -1 ? color.new(color.green, iFT) : color.new(color.red, iFT)
boxColor
fill(a, b, color=boxColor)
//----<Plot Signals>-----------------------------------------------------------------------------//
plotchar(Buy and iSS == 'small', 'Buy', color=color.new(LimeGreen, 0), size=size.tiny, location=location.belowbar, char='▲')
plotchar(Sell and iSS == 'small', 'Sell', color=color.new(Crimson, 0), size=size.tiny, location=location.abovebar, char='▼')
plotchar(Buy and iSS == 'large', 'Buy', color=color.new(LimeGreen, 0), size=size.small, location=location.belowbar, char='▲')
plotchar(Sell and iSS == 'large', 'Sell', color=color.new(Crimson, 0), size=size.small, location=location.abovebar, char='▼')
//----<Alerts>-----------------------------------------------------------------------------------//
alertcondition(condition=Buy, title='buy', message='buy')
alertcondition(condition=Sell, title='sell', message='sell')
//-----------------------------------------------------------------------------------------------//
if strategy.position_size >= 0 and Buy
strategy.entry("Long", strategy.long, qty = qty_pos)
if strategy.position_size <= 0 and Sell
strategy.entry("Short", strategy.short, qty = qty_pos)
if strategy.position_size > 0 and Sell
strategy.close("Long", qty = qty_pos)
if strategy.position_size < 0 and Buy
strategy.close("Short", qty = qty_pos)