O AlphaTradingBot é uma estratégia de negociação diária baseada no indicador Zigzag e na sequência de Fibonacci. A estratégia identifica os pontos altos (HH) e baixos (LL) do mercado para determinar a tendência, e usa retracements e expansões de Fibonacci para definir pontos de entrada, take-profits e stop-losses.
O AlphaTradingBot é uma estratégia intradiária de acompanhamento de tendências baseada no indicador Zigzag e retracements de Fibonacci. Determina tendências através de pontos altos e baixos e entra durante retracements de tendências, com o objetivo de buscar uma maior taxa de ganho e relação risco-recompensa. As vantagens da estratégia estão em sua forte capacidade de captura de tendências, lógica clara de retracement e risco mensurável, mas também enfrenta riscos como excesso de negociação, julgamento errado da tendência e mau desempenho em mercados de faixa.
/*backtest start: 2024-04-20 00:00:00 end: 2024-04-27 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/ // © javierfish //@version=5 strategy(title = 'Augusto Bot v1.2', shorttitle='🤑 🤖 v1.2', overlay = true, pyramiding=0, initial_capital=100000, default_qty_value=1) lb = input.int(5, title='Pivot Bars Count', minval=1) rb = lb var color supcol = color.lime var color rescol = color.red // srlinestyle = line.style_dotted srlinewidth = 1 changebarcol = true bcolup = color.blue bcoldn = color.black intDesde = input(timestamp('2023-01-01T00:00:00'), 'Desde', group='Rango de fechas') intHasta = input(timestamp('2023-12-31T23:59:59'), 'Hasta', group='Rango de fechas') blnFechas = true blnShorts = input.bool(false, " Shorts", group="Trading", tooltip = 'Checked = Shorts. No Checked = Longs') blnLongs = not blnShorts pctRisk = input.float(1, 'Riesgo %', 0.1, 100,step = .1, group='Trading', tooltip = 'Porcentaje del total de su cuenta que está dispuesto a arriesgar en cada trade') RR = input.float(2, 'Ratio de Ganancia X', 1, 10, .5, tooltip = 'Proporción de Take Profit contra Stop Loss', group='Trading') retro = input.float(40, 'Retroceso %', 1, 100, 10, tooltip = 'Porcentaje de Fibonacci que debe alcanzar el precio para considerar un retroceso', group='Fibonacci') fibSL = input.float(72, 'Stop Loss %', 1, 100, 5, tooltip = 'Porcentaje de Fibonacci que debe alcanzar el precio para considerar perdido un trade', group='Fibonacci') blnDebug = input.bool(false, 'Debug', tooltip = 'Mostrar información de depuración como estatus y línea de tendencia') showsupres = blnDebug blnEnLong = strategy.position_size > 0 blnEnShort = strategy.position_size < 0 blnEnTrade = blnEnLong or blnEnShort ph = ta.pivothigh(lb, rb) pl = ta.pivotlow(lb, rb) iff_1 = pl ? -1 : na // Trend direction hl = ph ? 1 : iff_1 iff_2 = pl ? pl : na // similar to zigzag but may have multiple highs/lows zz = ph ? ph : iff_2 valuewhen_1 = ta.valuewhen(hl, hl, 1) valuewhen_2 = ta.valuewhen(zz, zz, 1) zz := pl and hl == -1 and valuewhen_1 == -1 and pl > valuewhen_2 ? na : zz valuewhen_3 = ta.valuewhen(hl, hl, 1) valuewhen_4 = ta.valuewhen(zz, zz, 1) zz := ph and hl == 1 and valuewhen_3 == 1 and ph < valuewhen_4 ? na : zz valuewhen_5 = ta.valuewhen(hl, hl, 1) valuewhen_6 = ta.valuewhen(zz, zz, 1) hl := hl == -1 and valuewhen_5 == 1 and zz > valuewhen_6 ? na : hl valuewhen_7 = ta.valuewhen(hl, hl, 1) valuewhen_8 = ta.valuewhen(zz, zz, 1) hl := hl == 1 and valuewhen_7 == -1 and zz < valuewhen_8 ? na : hl zz := na(hl) ? na : zz findprevious() => // finds previous three points (b, c, d, e) float loc1 = na float loc2 = na float loc3 = na float loc4 = na if not na(hl) ehl = hl == 1 ? -1 : 1 loc1 := 0.0 loc2 := 0.0 loc3 := 0.0 loc4 := 0.0 xx = 0 for x = 1 to 1000 by 1 if hl[x] == ehl and not na(zz[x]) loc1 := zz[x] xx := x + 1 break ehl := hl for x = xx to 1000 by 1 if hl[x] == ehl and not na(zz[x]) loc2 := zz[x] xx := x + 1 break ehl := hl == 1 ? -1 : 1 for x = xx to 1000 by 1 if hl[x] == ehl and not na(zz[x]) loc3 := zz[x] xx := x + 1 break ehl := hl for x = xx to 1000 by 1 if hl[x] == ehl and not na(zz[x]) loc4 := zz[x] break [loc1, loc2, loc3, loc4] [loc1, loc2, loc3, loc4] = findprevious() a = fixnan(zz) b = loc1 c = loc2 d = loc3 e = loc4 _hh = zz and a > b and a > c and c > b and c > d _ll = zz and a < b and a < c and c < b and c < d _hl = zz and (a >= c and b > c and b > d and d > c and d > e or a < b and a > c and b < d) _lh = zz and (a <= c and b < c and b < d and d < c and d < e or a > b and a < c and b > d) plotshape(blnDebug and _hl, text='HL', title='Higher Low', style=shape.labelup, color=color.lime, textcolor=color.new(color.black, 0), location=location.belowbar, offset=-rb) plotshape(blnDebug and _hh, text='HH', title='Higher High', style=shape.labeldown, color=color.lime, textcolor=color.new(color.black, 0), location=location.abovebar, offset=-rb) plotshape(blnDebug and _ll, text='LL', title='Lower Low', style=shape.labelup, color=color.red, textcolor=color.new(color.white, 0), location=location.belowbar, offset=-rb) plotshape(blnDebug and _lh, text='LH', title='Lower High', style=shape.labeldown, color=color.red, textcolor=color.new(color.white, 0), location=location.abovebar, offset=-rb) float res = na float sup = na res := _lh ? zz : res[1] sup := _hl ? zz : sup[1] int trend = na iff_3 = close < sup ? -1 : nz(trend[1]) trend := close > res ? 1 : iff_3 res := trend == 1 and _hh or trend == -1 and _lh ? zz : res sup := trend == 1 and _hl or trend == -1 and _ll ? zz : sup rechange = res != res[1] suchange = sup != sup[1] var line resline = na var line supline = na if showsupres if rechange line.set_x2(resline, bar_index) line.set_extend(resline, extend=extend.none) resline := line.new(x1=bar_index - rb, y1=res, x2=bar_index, y2=res, color=rescol, extend=extend.right, width=srlinewidth) resline if suchange line.set_x2(supline, bar_index) line.set_extend(supline, extend=extend.none) supline := line.new(x1=bar_index - rb, y1=sup, x2=bar_index, y2=sup, color=supcol, extend=extend.right, width=srlinewidth) supline iff_4 = trend == 1 ? bcolup : bcoldn barcolor(color=changebarcol and blnDebug ? iff_4 : na) usdCalcRisk = strategy.equity * pctRisk / 100 usdRisk = usdCalcRisk > 0 ? usdCalcRisk : 0 blnOrder = strategy.opentrades > 0 var entryPrice = close var hhVal = high var lhVal = high var hlVal = low var llVal = low var longTP = high var longSL = low var shortTP = low var shortSL = high var lowest = low var highest = high var status = 0 var closedTrades = strategy.closedtrades var currSignal = '' var prevSignal = currSignal if _hh hhVal := a prevSignal := currSignal currSignal := 'HH' else if _lh lhVal := a prevSignal := currSignal currSignal := 'LH' else if _hl hlVal := a prevSignal := currSignal currSignal := 'HL' else if _ll llVal := a prevSignal := currSignal currSignal := 'LL' fibo(fibTop, fibLow) => diff = fibTop - fibLow fib50 = 0.0 if status % 2 == 1 // Estatus pares son longs fib50 := fibLow + (diff * (1 - (retro / 100))) // Longs else fib50 := fibLow + (diff * (retro / 100)) fib70UP = fibLow + (diff * (1 - (fibSL / 100))) // Fibo 61.8% up fib70DW = fibLow + (diff * (fibSL / 100)) // Fibo 61.8% down [fib50, fib70UP, fib70DW] currLowest = ta.lowest(low, lb + 1) // El menor low de las últimas n barras currHighest = ta.highest(high, lb + 1) // El mayor high de las últimas n barras // status 0. En espera de un LL para longs o un HH para shorts if status == 0 and blnFechas closedTrades := strategy.closedtrades if _ll and blnLongs status := 1 else if _hh and blnShorts status := 2 // -------- LONGS -------- // status 1. Longs. En espera de un nuevo nivel superior (HH o LH) else if status == 1 closedTrades := strategy.closedtrades if _hh or _lh highest := currHighest else if _hl lowest := currLowest if high > highest status := 5 highest := high [fib50, fibUP, fibDW] = fibo(highest, lowest) entryPrice := fib50 if low <= entryPrice and close <= open // Si la vela roja que rebasó el reciente nivel superior también cruzó el precio de entrada se ingresa a un trade inmediatamente entryPrice := close longSL := fibUP // Reajuste de SL para long diff = entryPrice - longSL longTP := entryPrice + diff * RR // Reajuste de TP para long lotSize = usdRisk / diff if entryPrice > longSL strategy.entry('🚀 1', strategy.long, limit = entryPrice, qty = lotSize, alert_message = 'long ' + ' ' + syminfo.ticker + ' p=' + str.tostring(entryPrice) + ' tp=' + str.tostring(longTP) + ' sl=' + str.tostring(longSL) + ' q=' + str.tostring(pctRisk) + '%') strategy.exit('lx', '🚀 1', limit = longTP, stop = longSL, comment_loss = '💥', comment_profit = '✅', alert_message = 'bal') else status := 3 [fib50, fibUP, fibDW] = fibo(highest, lowest) entryPrice := fib50 else if low < llVal status := 0 // status 3. Longs. En espera de que aparezca un HL else if status == 3 if _hl lowest := currLowest if _lh or _ll or low < hlVal strategy.cancel_all() status := _ll ? 1 : 0 // Si fue un nuevo LL comienza a formarse un nuevo setup alcista else if high > highest status := 5 highest := high [fib50, fibUP, fibDW] = fibo(highest, lowest) entryPrice := fib50 if low <= entryPrice entryPrice := close longSL := fibUP // Reajuste de SL para long diff = entryPrice - longSL longTP := entryPrice + diff * RR // Reajuste de TP para long lotSize = usdRisk / diff if not blnEnLong and entryPrice > longSL strategy.cancel_all() strategy.entry('🚀 3', strategy.long, limit = entryPrice, qty = lotSize, alert_message = 'long ' + ' ' + syminfo.ticker + ' p=' + str.tostring(entryPrice) + ' tp=' + str.tostring(longTP) + ' sl=' + str.tostring(longSL) + ' q=' + str.tostring(pctRisk) + '%') strategy.exit('lx', '🚀 3', limit = longTP, stop = longSL, comment_loss = '💥', comment_profit = '✅', alert_message = 'bal') // status 5. Longs. Crecimiento del fibo en espera de que se rebase el nivel superior y se toque el entry price para entrar a un trade else if status == 5 if strategy.closedtrades > closedTrades // Caso trade abre y cierra en una misma vela status := 0 else if blnEnLong status := 7 else if _lh or _ll or low < llVal // Caso invalidación por nuevo bajo nivel strategy.cancel_all() status := _ll ? 1 : 0 // Si fue un nuevo LL comienza a formarse un nuevo setup alcista else if high > highest // Caso de rebase de niveles superiores highest := high [fib50, fibUP, fibDW] = fibo(highest, lowest) entryPrice := fib50 longSL := fibUP // Reajuste de SL para long diff = entryPrice - longSL longTP := entryPrice + diff * RR // Reajuste de TP para long lotSize = usdRisk / diff if not blnEnLong and entryPrice > longSL // Orden limit de long con su TP y SL strategy.cancel_all() strategy.entry('🚀 5', strategy.long, limit = entryPrice, qty = lotSize, alert_message = 'long ' + ' ' + syminfo.ticker + ' p=' + str.tostring(entryPrice) + ' tp=' + str.tostring(longTP) + ' sl=' + str.tostring(longSL) + ' q=' + str.tostring(pctRisk) + '%') strategy.exit('lx', '🚀 5', limit = longTP, stop = longSL, comment_loss = '💥', comment_profit = '✅', alert_message = 'bal') // status 7. Longs. En espera que finalice el trade else if status == 7 blnOrder := false if not blnEnLong strategy.cancel_all() if currSignal == 'HH' and blnShorts // Si se finaliza un trade e inmediatamente se presenta un HH debe comenzarse la formación de un setup bajista status := 2 else status := 0 // -------- SHORTS -------- // status 2. Shorts. En espera de un nuevo nivel inferior (LL o HL) else if status == 2 closedTrades := strategy.closedtrades if _ll or _hl lowest := currLowest else if _lh highest := currHighest if low < lowest status := 6 lowest := low [fib50, fibUP, fibDW] = fibo(highest, lowest) entryPrice := fib50 if high >= entryPrice and close > open // Si la vela verde que rebasó el reciente nivel inferior tambien cruzó el precio de entrada se ingresa a un trade inmediatamente entryPrice := close shortSL := fibDW diff = shortSL - entryPrice shortTP := entryPrice - diff * RR lotSize = usdRisk / diff if entryPrice < shortSL strategy.entry('🐻 2', strategy.short, limit = entryPrice, qty = lotSize, alert_message = 'short ' + ' ' + syminfo.ticker + ' p=' + str.tostring(entryPrice) + ' tp=' + str.tostring(shortTP) + ' sl=' + str.tostring(shortSL) + ' q=' + str.tostring(pctRisk) + '%') strategy.exit('sx', '🐻 2', limit = shortTP, stop = shortSL, comment_loss = '☠️', comment_profit = '❎', alert_message = 'bal') else status := 4 [fib50, fibUP, fibDW] = fibo(highest, lowest) entryPrice := fib50 else if high > hhVal status := 0 // status 4. Shorts. En espera de que aparezca un LH else if status == 4 if _lh highest := currHighest if _hl or _hh or high > lhVal strategy.cancel_all() status := _hh ? 2 : 0 // Si fue un nuevo HH comienza a formarse un nuevo setup bajista else if low < lowest status := 6 lowest := low [fib50, fibUP, fibDW] = fibo(highest, lowest) entryPrice := fib50 if high >= entryPrice entryPrice := close shortSL := fibDW diff = shortSL - entryPrice shortTP := entryPrice - diff * RR lotSize = usdRisk / diff if not blnEnShort and entryPrice < shortSL strategy.cancel_all() strategy.entry('🐻 4', strategy.short, limit = entryPrice, qty = lotSize, alert_message = 'short ' + ' ' + syminfo.ticker + ' p=' + str.tostring(entryPrice) + ' tp=' + str.tostring(shortTP) + ' sl=' + str.tostring(shortSL) + ' q=' + str.tostring(pctRisk) + '%') strategy.exit('sx', '🐻 4', limit = shortTP, stop = shortSL, comment_loss = '☠️', comment_profit = '❎', alert_message = 'bal') // status 6. Shorts. Crecimiento del fibo en espera de que se rebase el nivel inferior y se toque el entry price para entrar a un trade else if status == 6 if strategy.closedtrades > closedTrades // Caso trade abre y cierra en una misma vela status := 0 else if blnEnShort status := 8 else if _hl or _hh or high > hhVal strategy.cancel_all() status := _hh ? 2 : 0 // Si fue un nuevo HH comienza a formarse un nuevo setup bajista else if low < lowest // Caso de rebase de niveles inferiores lowest := low [fib50, fibUP, fibDW] = fibo(highest, lowest) entryPrice := fib50 shortSL := fibDW diff = shortSL - entryPrice shortTP := entryPrice - diff * RR lotSize = usdRisk / diff if entryPrice < shortSL strategy.cancel_all() strategy.entry('🐻 6', strategy.short, limit = entryPrice, qty = lotSize, alert_message = 'short ' + ' ' + syminfo.ticker + ' p=' + str.tostring(entryPrice) + ' tp=' + str.tostring(shortTP) + ' sl=' + str.tostring(shortSL) + ' q=' + str.tostring(pctRisk) + '%') strategy.exit('sx', '🐻 6', limit = shortTP, stop = shortSL, comment_loss = '☠️', comment_profit = '❎', alert_message = 'bal') // status 8. Shorts. En espera que finalice el trade else if status == 8 blnOrder := false if not blnEnShort strategy.cancel_all() if currSignal == 'LL' and blnLongs // Si inmediatamente después de finalizar un trade existe un LL debe comenzarse un setup alcista status := 1 else status := 0 plotchar(blnDebug and status == 0 and blnFechas, '0', '0', location.abovebar, color.yellow, size = size.tiny) plotchar(blnDebug and status == 1 and blnFechas, '1', '1', location.abovebar, color.yellow, size = size.tiny) plotchar(blnDebug and status == 2 and blnFechas, '2', '2', location.abovebar, color.yellow, size = size.tiny) plotchar(blnDebug and status == 3 and blnFechas, '3', '3', location.abovebar, color.yellow, size = size.tiny) plotchar(blnDebug and status == 4 and blnFechas, '4', '4', location.abovebar, color.yellow, size = size.tiny) plotchar(blnDebug and status == 5 and blnFechas, '5', '5', location.abovebar, color.yellow, size = size.tiny) plotchar(blnDebug and status == 6 and blnFechas, '6', '6', location.abovebar, color.yellow, size = size.tiny) plotchar(blnDebug and status == 7 and blnFechas, '7', '7', location.abovebar, color.yellow, size = size.tiny) plotchar(blnDebug and status == 8 and blnFechas, '8', '8', location.abovebar, color.yellow, size = size.tiny) plot(highest, 'highest', (status == 5 or status[1] == 5) and blnLongs ? color.new(color.orange, 50) : na, 1, plot.style_stepline) plot(entryPrice, 'entryPrice', (status == 5 or status[1] == 5) and blnLongs ?color.new(color.white, 50) : na, 1, plot.style_stepline) plot(lowest, 'lowest', (status == 3 or status == 5 or status[1] == 5) and blnLongs ? color.new(color.yellow, 50) : na, 1, plot.style_stepline) plot(lowest, 'currLowest', (status == 6 or status[1] == 6) and blnShorts ? color.new(color.orange, 50) : na, 1, plot.style_stepline) plot(entryPrice, 'currEntryPrice', (status == 6 or status[1] == 6) and blnShorts ?color.new(color.white, 50) : na, 1, plot.style_stepline) plot(highest, 'currHighest', (status == 4 or status == 6 or status[1] == 6) and blnShorts ?color.new(color.yellow, 50) : na, 1, plot.style_stepline) exitLong = barstate.isconfirmed and blnEnLong and time >= intHasta exitShort = barstate.isconfirmed and blnEnShort and time >= intHasta if exitLong strategy.cancel_all() strategy.close_all(comment = close > strategy.position_avg_price ? '✅' : '💥') status := 0 if exitShort strategy.cancel_all() strategy.close_all(comment = close < strategy.position_avg_price ? '❎' : '☠️') status := 0 plot(zz, 'Zigzag', blnDebug ? color.white : na, offset = lb * -1) rayaTradeLong = strategy.position_size == strategy.position_size[1] and (strategy.position_size > 0) and blnLongs tpPlLong = plot(longTP, color = rayaTradeLong ? color.teal : na) epPlLong = plot(entryPrice, color= rayaTradeLong ? color.white : na) slPlLong = plot(longSL, color = rayaTradeLong ? color.maroon : na) fill(tpPlLong, epPlLong, color= rayaTradeLong ? color.new(color.teal, 85) : na) fill(epPlLong, slPlLong, color= rayaTradeLong ? color.new(color.maroon, 85) : na) rayaTradeShort = strategy.position_size == strategy.position_size[1] and strategy.position_size < 0 and blnShorts tpPlShort = plot(shortTP, color = rayaTradeShort ? color.teal : na) epPlShort = plot(entryPrice, color=rayaTradeShort ? color.white : na) slPlShort = plot(shortSL, color=rayaTradeShort ? color.maroon : na) fill(tpPlShort, epPlShort, color=rayaTradeShort ? color.new(color.teal, 85) : na) fill(epPlShort, slPlShort, color=rayaTradeShort ? color.new(color.maroon, 85) : na)