Estrategia de comercio del patrón de estrellas de martillo y tiro

El autor:¿ Qué pasa?, Fecha: 2023-09-28 11:11:35
Las etiquetas:

Resumen general

Esta estrategia comercial utiliza patrones de velas para predecir el movimiento futuro de los precios. Los martillos y las estrellas fugaces son patrones simples pero poderosos utilizados ampliamente para detectar inversiones de tendencia.

Estrategia lógica

La estrategia se basa en los siguientes principios fundamentales:

  1. El indicador ATR filtra los mercados que no están en tendencia al exigir que el tamaño de la vela esté dentro de un rango establecido de valores ATR.

  2. El nivel de retroceso de Fibonacci del 33,3% marca el punto que distingue un martillo (cierra arriba) de una estrella fugaz (cierra abajo).

  3. La confirmación adicional requiere que el patrón se complete (precio de cierre por encima/por debajo de abierto) en una barra no confirmada.

  4. Los niveles de stop loss y take profit se fijan en función del ATR y de una relación riesgo/beneficio al momento de la entrada.

Al combinar ATR, Fibonacci y reconocimiento de patrones, la estrategia se adhiere a los principios comunes del comercio de tendencias.

Análisis de ventajas

Las principales ventajas de esta estrategia son:

  1. La lógica simple hace que sea fácil de entender y aplicar.

  2. El comercio de patrones intradiarios a corto plazo permite períodos de retención flexibles.

  3. Los filtros ATR ayudan a controlar el riesgo en mercados volátiles.

  4. Puntos de stop loss y take profit inteligentes basados en una relación riesgo/beneficio para controlar el riesgo de manera efectiva.

  5. Las señales comerciales automatizadas agilizan la entrada y la gestión de posiciones.

  6. El mercado transversal aplicable a muchos pares de divisas demuestra robustez.

Análisis de riesgos

También hay varios riesgos a tener en cuenta:

  1. El comercio de patrones tiene una probabilidad de señales falsas en las que no se debe confiar ciegamente.

  2. Los costos de negociación como las comisiones no se tienen en cuenta, comiendo en las ganancias reales.

  3. El aumento de la frecuencia de las operaciones de negociación intradiaria a corto plazo puede acarrear mayores costes de deslizamiento.

  4. Los parámetros ATR optimizados se basan en datos históricos y pueden no seguir siendo siempre aplicables.

  5. El riesgo de negociación automática es que la ejecución de la orden haya fracasado y debe implementarse un mecanismo de nueva tentativa.

  6. La mala configuración de stop loss y take profit podría llevar a una sobre-negociación o dejar dinero sobre la mesa.

Oportunidades de optimización

Algunas maneras de mejorar potencialmente la estrategia:

  1. Filtros adicionales como el volumen para aumentar la efectividad del patrón.

  2. Incorporar comisiones en el ajuste de parada y objetivo.

  3. Optimizar dinámicamente los parámetros ATR para adaptarse a las condiciones cambiantes del mercado.

  4. Evaluar el rendimiento de los parámetros individualmente para cada par de divisas.

  5. Añadir mecanismos de búsqueda automática para reducir el riesgo de ejecución de órdenes fallidas.

  6. Utilice modelos de aprendizaje automático para identificar mejor patrones válidos.

  7. Introduzca un mecanismo de detención para obtener más ganancias.

Conclusión

En resumen, esta estrategia de negociación integra indicadores técnicos comúnmente utilizados con una lógica simple para una implementación sencilla. Con una optimización de parámetros robusta y control de riesgos, tiene potencial para una rentabilidad consistente. Sin embargo, los operadores deben permanecer atentos a los riesgos y mantener una frecuencia comercial razonable para evitar el exceso de negociación. La estrategia sirve como un marco básico para una mayor innovación para alcanzar nuevos niveles de rendimiento comercial.


/*backtest
start: 2023-08-28 00:00:00
end: 2023-09-27 00:00:00
period: 2h
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/
// © ZenAndTheArtOfTrading / PineScriptMastery
// Last Updated: 28th April, 2021
// @version=4
strategy("Hammers & Stars Strategy [v1.0]", shorttitle="HSS[v1.0]", overlay=true)

// Get user input
atrMinFilterSize = input(title=">= ATR Filter", type=input.float, defval=0.0, minval=0.0, tooltip="Minimum size of entry candle compared to ATR", group="Strategy Settings")
atrMaxFilterSize = input(title="<= ATR Filter", type=input.float, defval=3.0, minval=0.0, tooltip="Maximum size of entry candle compared to ATR", group="Strategy Settings")
stopMultiplier   = input(title="Stop Loss ATR", type=input.float, defval=1.0, tooltip="Stop loss multiplier (x ATR)", group="Strategy Settings")
rr               = input(title="R:R", type=input.float, defval=1.0, tooltip="Risk:Reward profile", group="Strategy Settings")
fibLevel         = input(title="Fib Level", type=input.float, defval=0.333, tooltip="Used to calculate upper/lower third of candle. (For example, setting it to 0.5 will mean hammers must close >= 50% mark of the total candle size)", group="Strategy Settings")
i_startTime      = input(title="Start Date Filter", defval=timestamp("01 Jan 2000 13:30 +0000"), type=input.time, tooltip="Date & time to begin trading from", group="Strategy Settings")
i_endTime        = input(title="End Date Filter", defval=timestamp("1 Jan 2099 19:30 +0000"), type=input.time, tooltip="Date & time to stop trading", group="Strategy Settings")
oandaDemo        = input(title="Use Oanda Demo?", type=input.bool, defval=false, tooltip="If turned on then oandapractice broker prefix will be used for AutoView alerts (demo account). If turned off then live account will be used", group="AutoView Oanda Settings")
limitOrder       = input(title="Use Limit Order?", type=input.bool, defval=true, tooltip="If turned on then AutoView will use limit orders. If turned off then market orders will be used", group="AutoView Oanda Settings")
gtdOrder         = input(title="Days To Leave Limit Order", type=input.integer, minval=0, defval=2, tooltip="This is your GTD setting (good til day)", group="AutoView Oanda Settings")
accountBalance   = input(title="Account Balance", type=input.float, defval=1000.0, step=100, tooltip="Your account balance (used for calculating position size)", group="AutoView Oanda Settings")
accountCurrency  = input(title="Account Currency", type=input.string, defval="USD", options=["AUD", "CAD", "CHF", "EUR", "GBP", "JPY", "NZD", "USD"], tooltip="Your account balance currency (used for calculating position size)", group="AutoView Oanda Settings")
riskPerTrade     = input(title="Risk Per Trade %", type=input.float, defval=2.0, step=0.5, tooltip="Your risk per trade as a % of your account balance", group="AutoView Oanda Settings")

// Set up AutoView broker prefix
var broker = oandaDemo ? "oandapractice" : "oanda"

// See if this bar's time happened within date filter
dateFilter = true

// Get ATR
atr = atr(14)

// Check ATR filter
atrMinFilter = abs(high - low) >= (atrMinFilterSize * atr) or atrMinFilterSize == 0.0
atrMaxFilter = abs(high - low) <= (atrMaxFilterSize * atr) or atrMaxFilterSize == 0.0
atrFilter = atrMinFilter and atrMaxFilter

// Calculate 33.3% fibonacci level for current candle
bullFib = (low - high) * fibLevel + high
bearFib = (high - low) * fibLevel + low

// Determine which price source closes or opens highest/lowest
lowestBody = close < open ? close : open
highestBody = close > open ? close : open

// Determine if we have a valid setup
validHammer = lowestBody >= bullFib and atrFilter and close != open and not na(atr)
validStar = highestBody <= bearFib and atrFilter and close != open and not na(atr)

// Check if we have confirmation for our setup
validLong = validHammer and strategy.position_size == 0 and dateFilter and barstate.isconfirmed
validShort = validStar and strategy.position_size == 0 and dateFilter and barstate.isconfirmed

//------------- DETERMINE POSITION SIZE -------------//
// Get account inputs
var tradePositionSize = 0.0
var pair = syminfo.basecurrency + "/" + syminfo.currency

// Check if our account currency is the same as the base or quote currency (for risk $ conversion purposes)
accountSameAsCounterCurrency = accountCurrency == syminfo.currency
accountSameAsBaseCurrency = accountCurrency == syminfo.basecurrency

// Check if our account currency is neither the base or quote currency (for risk $ conversion purposes)
accountNeitherCurrency = not accountSameAsCounterCurrency and not accountSameAsBaseCurrency

// Get currency conversion rates if applicable
conversionCurrencyPair = accountSameAsCounterCurrency ? syminfo.tickerid : accountNeitherCurrency ? accountCurrency + syminfo.currency : accountCurrency + syminfo.currency
conversionCurrencyRate = security(symbol=syminfo.type == "forex" ? "BTC_USDT:swap" : "BTC_USDT:swap", resolution="D", expression=close)

// Calculate position size
getPositionSize(stopLossSizePoints) =>
    riskAmount = (accountBalance * (riskPerTrade / 100)) * (accountSameAsBaseCurrency or accountNeitherCurrency ? conversionCurrencyRate : 1.0)
    riskPerPoint = (stopLossSizePoints * syminfo.pointvalue)
    positionSize = (riskAmount / riskPerPoint) / syminfo.mintick
    round(positionSize)
    
// Custom function to convert pips into whole numbers
toWhole(number) =>
    return = atr(14) < 1.0 ? (number / syminfo.mintick) / (10 / syminfo.pointvalue) : number
    return := atr(14) >= 1.0 and atr(14) < 100.0 and syminfo.currency == "JPY" ? return * 100 : return
//------------- END POSITION SIZE CODE -------------//

// Calculate our stop distance & size for the current bar
stopSize = atr * stopMultiplier
longStopPrice = low < low[1] ? low - stopSize : low[1] - stopSize
longStopDistance = close - longStopPrice
longTargetPrice = close + (longStopDistance * rr)
shortStopPrice = high > high[1] ? high + stopSize : high[1] + stopSize
shortStopDistance = shortStopPrice - close
shortTargetPrice = close - (shortStopDistance * rr)

// Save trade stop & target & position size if a valid setup is detected
var tradeStopPrice = 0.0
var tradeTargetPrice = 0.0

// Set up our GTD (good-til-day) order info
gtdTime = time + (gtdOrder * 1440 * 60 * 1000) // 86,400,000ms per day
gtdYear = year(gtdTime)
gtdMonth = month(gtdTime)
gtdDay = dayofmonth(gtdTime)
gtdString = " dt=" + tostring(gtdYear) + "-" + tostring(gtdMonth) + "-" + tostring(gtdDay)

// Detect valid long setups & trigger alert
if validLong
    tradeStopPrice := longStopPrice
    tradeTargetPrice := longTargetPrice
    tradePositionSize := getPositionSize(toWhole(longStopDistance) * 10)
    // Trigger AutoView long alert
    alert(message="e=" + broker + " b=long q="
     + tostring(tradePositionSize) 
     + " s=" + pair
     + " t=" + (limitOrder ? "limit fp=" + tostring(close) : "market")
     + " fsl=" + tostring(tradeStopPrice)
     + " ftp=" + tostring(tradeTargetPrice)
     + (gtdOrder != 0 and limitOrder ? gtdString : ""), 
     freq=alert.freq_once_per_bar_close)
   
// Detect valid short setups & trigger alert
if validShort
    tradeStopPrice := shortStopPrice
    tradeTargetPrice := shortTargetPrice
    tradePositionSize := getPositionSize(toWhole(shortStopDistance) * 10)
    // Trigger AutoView short alert
    alert(message="e=" + broker + " b=short q="
     + tostring(tradePositionSize)
     + " s=" + pair
     + " t=" + (limitOrder ? "limit fp=" + tostring(close) : "market")
     + " fsl=" + tostring(tradeStopPrice)
     + " ftp=" + tostring(tradeTargetPrice)
     + (gtdOrder != 0 and limitOrder ? gtdString : ""),
     freq=alert.freq_once_per_bar_close)

// Enter trades whenever a valid setup is detected
strategy.entry(id="Long", long=strategy.long, when=validLong)
strategy.entry(id="Short", long=strategy.short, when=validShort)

// Exit trades whenever our stop or target is hit
strategy.exit(id="Long Exit", from_entry="Long", limit=tradeTargetPrice, stop=tradeStopPrice, when=strategy.position_size > 0)
strategy.exit(id="Short Exit", from_entry="Short", limit=tradeTargetPrice, stop=tradeStopPrice, when=strategy.position_size < 0)

// Draw trade data
plot(strategy.position_size != 0 or validLong or validShort ? tradeStopPrice : na, title="Trade Stop Price", color=color.red, style=plot.style_linebr, transp=0)
plot(strategy.position_size != 0 or validLong or validShort ? tradeTargetPrice : na, title="Trade Target Price", color=color.green, style=plot.style_linebr, transp=0)
plot(strategy.position_size != 0 or validLong or validShort ? tradePositionSize : na, color=color.purple, transp=100, title="AutoView Position Size")

// Draw price action setup arrows
plotshape(validLong ? 1 : na, style=shape.triangleup, location=location.belowbar, color=color.green, title="Bullish Setup")
plotshape(validShort ? 1 : na, style=shape.triangledown, location=location.abovebar, color=color.red, title="Bearish Setup")

Más.