Logic de módulo con estrategia de filtro de EMA

El autor:¿ Qué pasa?, Fecha: 2023-12-13 15:55:07
Las etiquetas:

img

Resumen general

Esta estrategia combina operaciones aritméticas modulo y promedios móviles exponenciales para crear un fuerte filtro de aleatoriedad para determinar la dirección de la posición. Primero calcula el resto del precio dividido por un número establecido, y se genera una señal de negociación si el resto es 0, si esta señal está por debajo de la línea EMA, vaya corto; si está por encima, vaya largo. Esta estrategia integra la aleatoriedad de las operaciones matemáticas y la tendencia de juicio de los indicadores técnicos, haciendo uso de la validación cruzada entre indicadores de diferentes ciclos para filtrar efectivamente parte del ruido del mercado.

Estrategia lógica

  1. Establezca el valor de entrada de precio a para cerrar, modificable; establezca el divisor b para 4, modificable.
  2. Calcule el módulo del resto de a dividido por b, determine si el módulo es igual a 0.
  3. Establecer la longitud de la EMA (MALen) a 70 períodos por defecto como métrica para la tendencia a medio y largo plazo.
  4. Cuando el módulo es igual a 0, se genera un número par de señal de negociación. Combinado con la relación EMA, determina la dirección. Cuando el precio cruza por encima de la EMA, se genera una señal de compra; cuando el precio cruza por debajo de la EMA, se genera una señal de venta.
  5. Las entradas de negociación se abren largas o cortas en función de la dirección de la señal.
  6. Las condiciones de stop loss se establecen en base a 3 opciones: stop loss fijo, ATR stop loss, stop loss de oscilación de precios.
  7. El trailing stop puede activarse para obtener más ganancias, desactivado por defecto.

Análisis de ventajas

  1. La aleatoriedad de la aritmética modulo evita los efectos de las fluctuaciones de precios, combinada con el juicio de tendencia de las medias móviles, puede filtrar eficazmente las señales inválidas.
  2. La EMA como métrica de tendencia a medio y largo plazo combinada con señales modulo a corto plazo permite realizar una verificación multicapa y evitar señales falsas.
  3. Parámetros personalizables altamente flexibles, que pueden ajustarse para diferentes mercados para encontrar combinaciones óptimas de parámetros.
  4. Integra múltiples métodos de stop loss para controlar los riesgos. También se establecen condiciones de toma de ganancias para bloquear las ganancias.
  5. Apoya la apertura inversa directa de posiciones para cambiar de dirección sin problemas.

Análisis de riesgos

  1. La configuración incorrecta de los parámetros puede generar demasiadas señales de negociación, aumentando la frecuencia de negociación y los costes de deslizamiento.
  2. La EMA como única métrica de juicio de tendencia puede retrasarse, faltando momentos de reversión de precios.
  3. El método de stop loss fijo puede ser demasiado mecánico, incapaz de ajustarse a las fluctuaciones del mercado.
  4. La apertura inversa directa aumenta la frecuencia de los ajustes de posición, lo que aumenta los costes y los riesgos.

Direcciones de optimización

  1. Prueba diferentes promedios móviles en lugar de EMA, o combina EMA con otros MAs, para ver si se puede mejorar la tasa de rentabilidad.
  2. Intente combinar el filtro modulo con otras estrategias como bandas de Bollinger, patrones de velas, etc. para crear filtros más estables.
  3. Investigar métodos de stop loss adaptativos basados en los niveles de volatilidad del mercado para ajustar la distancia de stop.
  4. Establecer límites en el número de operaciones o umbrales de ganancias/pérdidas para restringir la frecuencia de la apertura inversa directa.

Conclusión

Esta estrategia combina efectivamente la aleatoriedad de las operaciones modulo y el juicio de tendencia de las medias móviles a través de ajustes flexibles de parámetros adaptados a diferentes entornos de mercado, lo que resulta en señales comerciales confiables. También integra varios mecanismos de parada para controlar los riesgos, así como tomar ganancias y paradas de seguimiento para bloquear las ganancias. La lógica general es clara y fácil de entender y modificar. Tiene un inmenso potencial práctico que vale la pena probar y optimizar aún más.


/*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)
 




Más.