AlphaTradingBot是一款基于Zigzag指标和fibonacci数列的日内交易策略。该策略通过识别市场的高点(HH)和低点(LL)来判断趋势,并结合fibonacci回撤和扩张来设置入场点位、止盈和止损。该策略只在设定的日期区间内运行,可以分别做多和做空,具有一定的趋势把握能力和盈亏比把控。
AlphaTradingBot是一款基于zigzag指标和fibonacci回撤的趋势跟踪日内策略。它通过高低点判断趋势,并在趋势回撤时入场,以追求更高的胜率和盈亏比。该策略的优势在于趋势把握能力强,回撤逻辑清晰,风险可测,但同时也存在过度交易、趋势判断偏差、震荡行情表现欠佳等风险。未来可从技术指标、仓位管理、止盈止损、市场情绪等方面对该策略进行优化,以提升策略的稳健性和盈利性。
/*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)