Modulo lógica com estratégia de filtro EMA

Autora:ChaoZhang, Data: 2023-12-13 15:55:07
Tags:

img

Resumo

Esta estratégia combina operações aritméticas modulo e médias móveis exponenciais para criar um forte filtro de aleatoriedade para determinar a direção da posição. Ele primeiro calcula o restante do preço dividido por um número definido e um sinal de negociação é gerado se o restante for 0, se este sinal estiver abaixo da linha EMA, vá curto; se estiver acima, vá longo. Esta estratégia integra a aleatoriedade das operações matemáticas e a tendência de julgamento dos indicadores técnicos, fazendo uso da validação cruzada entre indicadores de diferentes ciclos para filtrar efetivamente parte do ruído do mercado.

Estratégia lógica

  1. Defina o valor de entrada de preço a para fechar, modificável; defina o divisor b para 4, modificável.
  2. Calcule o módulo de restante de a dividido por b, determine se o módulo é igual a 0.
  3. Definir a duração da EMA (MALen) para 70 períodos por defeito como métrica para a tendência de médio a longo prazo.
  4. Quando o módulo é igual a 0, um sinal de negociação é gerado. Combinado com a relação EMA, ele determina a direção. Quando o preço cruza acima da EMA, um sinal de compra é gerado; quando o preço cruza abaixo da EMA, um sinal de venda é gerado.
  5. As entradas de negociação são abertas longas ou curtas com base na direção do sinal.
  6. As condições de stop loss são definidas com base em 3 opções: stop loss fixo, ATR stop loss, price swing stop loss.
  7. O trailing stop pode ser ativado para bloquear mais lucros, desativado por padrão.

Análise das vantagens

  1. A aleatoriedade da aritmética modulo evita os efeitos das flutuações de preços, combinado com o julgamento da tendência das médias móveis, pode efetivamente filtrar sinais inválidos.
  2. A EMA como métrica para a tendência de médio a longo prazo, combinada com sinais modulo de curto prazo, permite a verificação de várias camadas e evita sinais falsos.
  3. Parâmetros altamente flexíveis e personalizáveis, podem ser ajustados para diferentes mercados para encontrar combinações ótimas de parâmetros.
  4. Integra vários métodos de stop loss para controlar riscos.
  5. Suporta abertura reversa direta de posições para mudança de direção sem problemas.

Análise de riscos

  1. A configuração inadequada dos parâmetros pode gerar demasiados sinais de negociação, aumentando a frequência de negociação e os custos de deslizamento.
  2. A EMA como única métrica de julgamento da tendência pode atrasar, faltando momentos de reversão de preços.
  3. O método de stop loss fixo pode ser demasiado mecânico, incapaz de se ajustar às flutuações do mercado.
  4. A abertura reversa direta aumenta a frequência dos ajustamentos de posição, aumentando os custos e os riscos.

Orientações de otimização

  1. Teste diferentes médias móveis em vez da EMA, ou combine a EMA com outras MAs, para ver se a taxa de rentabilidade pode ser melhorada.
  2. Tente combinar o filtro modulo com outras estratégias como Bandas de Bollinger, padrões de velas etc para criar filtros mais estáveis.
  3. Pesquisar métodos de stop loss adaptativos com base nos níveis de volatilidade do mercado para ajustar a distância de stop.
  4. Estabelecer limites ao número de operações ou limiares de lucro/perda para restringir a frequência da abertura reversa direta.

Conclusão

Esta estratégia combina efetivamente a aleatoriedade das operações modulo e o julgamento da tendência das médias móveis através de ajustes flexíveis de parâmetros atendidos a diferentes ambientes de mercado, resultando em sinais de negociação confiáveis.


/*backtest
start: 2023-11-12 00:00:00
end: 2023-12-12 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © tweakerID

// To understand this strategy first we need to look into the Modulo (%) operator. The modulo returns the remainder numerator 
// of a division's quotient (the result). If we do 5 / 3, we get 1 and 2/3 as a result, where the remainder is 2 (two thirds, in this case). This can be
// used for many things, for example to determine when a number divides evenly into another number. If we divide 3/3, our result is 1,
// with no remainder numerator, hence our modulo result is 0. In this strategy, we compare a given number (divisor, user defined) with the
// the closing price of every candle (dividend, modifiable from the inputs panel) to determine if the result between their division is an even number. 
// If the answer is true, we have an entry signal. If this signal occurs below the EMA (length is defined by the user) we go short and
// viceversa for longs. This logic can be reversed. In this case, the modulo works as a random-like filter for a moving average strategy
// that usually struggles when the market is ranging.

//@version=4

//@version=4
strategy("Modulo Logic + EMA Strat", 
     overlay=true, 
     default_qty_type=strategy.percent_of_equity, 
     default_qty_value=100, 
     initial_capital=10000, 
     commission_value=0.04, 
     calc_on_every_tick=false, 
     slippage=0)

direction = input(0, title = "Strategy Direction", type=input.integer, minval=-1, maxval=1)
strategy.risk.allow_entry_in(direction == 0 ? strategy.direction.all : (direction < 0 ? strategy.direction.short : strategy.direction.long))

/////////////////////// STRATEGY INPUTS ////////////////////////////////////////
title1=input(true, "-----------------Strategy Inputs-------------------")  

a=input(close, title="Dividend")
b=input(4, title="Divisor")
usemod=input(true, title="Use Modulo Logic")
MALen=input(70, title="EMA Length")

/////////////////////// BACKTESTER /////////////////////////////////////////////
title2=input(true, "-----------------General Inputs-------------------")  

// Backtester General Inputs
i_SL=input(true, title="Use Stop Loss and Take Profit")
i_SLType=input(defval="ATR Stop", title="Type Of Stop", options=["Strategy Stop", "Swing Lo/Hi", "ATR Stop"])
i_SPL=input(defval=10, title="Swing Point Lookback")
i_PercIncrement=input(defval=3, step=.1, title="Swing Point SL Perc Increment")*0.01
i_ATR = input(14, title="ATR Length")
i_ATRMult = input(4, step=.1, title="ATR Multiple")
i_TPRRR = input(1, step=.1, title="Take Profit Risk Reward Ratio")
TS=input(false, title="Trailing Stop")

// Bought and Sold Boolean Signal
bought = strategy.position_size > strategy.position_size[1] 
 or strategy.position_size < strategy.position_size[1]

// Price Action Stop and Take Profit
LL=(lowest(i_SPL))*(1-i_PercIncrement)
HH=(highest(i_SPL))*(1+i_PercIncrement)
LL_price = valuewhen(bought, LL, 0)
HH_price = valuewhen(bought, HH, 0)
entry_LL_price = strategy.position_size > 0 ? LL_price : na 
entry_HH_price = strategy.position_size < 0 ? HH_price : na 
tp=strategy.position_avg_price + (strategy.position_avg_price - entry_LL_price)*i_TPRRR
stp=strategy.position_avg_price - (entry_HH_price - strategy.position_avg_price)*i_TPRRR

// ATR Stop
ATR=atr(i_ATR)*i_ATRMult
ATRLong = ohlc4 - ATR
ATRShort = ohlc4 + ATR
ATRLongStop = valuewhen(bought, ATRLong, 0)
ATRShortStop = valuewhen(bought, ATRShort, 0)
LongSL_ATR_price = strategy.position_size > 0 ? ATRLongStop : na 
ShortSL_ATR_price = strategy.position_size < 0 ? ATRShortStop : na 
ATRtp=strategy.position_avg_price + (strategy.position_avg_price - LongSL_ATR_price)*i_TPRRR
ATRstp=strategy.position_avg_price - (ShortSL_ATR_price - strategy.position_avg_price)*i_TPRRR


// Strategy Stop

float LongStop = na
float ShortStop = na
float StratTP = na
float StratSTP = na

/////////////////////// STRATEGY LOGIC /////////////////////////////////////////

modulo=a%b
evennumber=modulo==0
MA=ema(close, MALen)
plot(MA)

BUY=usemod ? evennumber and close > MA : close > MA
SELL=usemod ? evennumber and close < MA : close < MA

//Trading Inputs
DPR=input(true, "Allow Direct Position Reverse")
reverse=input(false, "Reverse Trades")

// Entries
if reverse
    if not DPR
        strategy.entry("long", strategy.long, when=SELL and strategy.position_size == 0)
        strategy.entry("short", strategy.short, when=BUY and strategy.position_size == 0)
    else     
        strategy.entry("long", strategy.long, when=SELL)
        strategy.entry("short", strategy.short, when=BUY)
else
    if not DPR 
        strategy.entry("long", strategy.long, when=BUY and strategy.position_size == 0)
        strategy.entry("short", strategy.short, when=SELL and strategy.position_size == 0)
    else
        strategy.entry("long", strategy.long, when=BUY)
        strategy.entry("short", strategy.short, when=SELL)


SL= i_SLType == "Swing Lo/Hi" ? entry_LL_price : i_SLType == "ATR Stop" ? LongSL_ATR_price : LongStop
SSL= i_SLType == "Swing Lo/Hi" ? entry_HH_price : i_SLType == "ATR Stop" ? ShortSL_ATR_price : ShortStop
TP= i_SLType == "Swing Lo/Hi" ? tp : i_SLType == "ATR Stop" ? ATRtp : StratTP
STP= i_SLType == "Swing Lo/Hi" ? stp : i_SLType == "ATR Stop" ? ATRstp : StratSTP

//TrailingStop
dif=(valuewhen(strategy.position_size>0 and strategy.position_size[1]<=0, high,0))
 -strategy.position_avg_price
trailOffset     = strategy.position_avg_price - SL
var tstop = float(na)
if strategy.position_size > 0
    tstop := high- trailOffset - dif
    if tstop<tstop[1]
        tstop:=tstop[1]
else
    tstop := na
StrailOffset     = SSL - strategy.position_avg_price
var Ststop = float(na)
Sdif=strategy.position_avg_price-(valuewhen(strategy.position_size<0 
 and strategy.position_size[1]>=0, low,0))
if strategy.position_size < 0
    Ststop := low+ StrailOffset + Sdif
    if Ststop>Ststop[1]
        Ststop:=Ststop[1]
else
    Ststop := na

strategy.exit("TP & SL", "long", limit=TP, stop=TS? tstop : SL, when=i_SL)
strategy.exit("TP & SL", "short", limit=STP, stop=TS? Ststop : SSL, when=i_SL)

/////////////////////// PLOTS //////////////////////////////////////////////////

plot(i_SL and strategy.position_size > 0 and not TS ? SL : i_SL and strategy.position_size > 0 and TS ? tstop : na , title='SL', style=plot.style_cross, color=color.red)
plot(i_SL and strategy.position_size < 0 and not TS ? SSL : i_SL and strategy.position_size < 0 and TS ? Ststop : na , title='SSL', style=plot.style_cross, color=color.red)
plot(i_SL and strategy.position_size > 0 ? TP : na, title='TP', style=plot.style_cross, color=color.green)
plot(i_SL and strategy.position_size < 0 ? STP : na, title='STP', style=plot.style_cross, color=color.green)
// Draw price action setup arrows
plotshape(BUY ? 1 : na, style=shape.triangleup, location=location.belowbar, 
 color=color.green, title="Bullish Setup", size=size.auto)
plotshape(SELL ? 1 : na, style=shape.triangledown, location=location.abovebar, 
 color=color.red, title="Bearish Setup", size=size.auto)
 




Mais.