
La estrategia multibar simétrica estudia la probabilidad de movimiento de varias barras, identifica las señales de tendencia y realiza operaciones invertidas cuando se produce una señal de reversión. La estrategia se aplica principalmente a las operaciones de corto y medio plazo.
La estrategia establece primero el tiempo de inicio y el tiempo de finalización de las estadísticas para extraer los datos históricos. Luego, establece el tiempo de negociación para identificar las líneas K que cumplen con los requisitos. La estrategia calcula la probabilidad de que ocurra una subida o caída simultánea entre las líneas K 2 y 7. Si la subida o caída alcanza un umbral proporcional, se genera una señal de negociación.
Por ejemplo, la estrategia estadística de la probabilidad de una caída dentro de las 3 líneas K. Si la probabilidad de caída es inferior al 50%, las 3 líneas K actuales son elegibles, generando una señal de pesimismo. La estrategia permite configurar parámetros estadísticos de 2 a 7 líneas K.
En concreto, la lógica de la estrategia es la siguiente:
Establezca un rango de tiempo de retracción, incluidas las fechas de inicio y finalización, y el rango de tiempo de negociación.
Cálculo del número de subidas y bajadas de la misma línea K entre 2 y 7 raíces.
Calcula la probabilidad de que el número de líneas K adyacentes continúe subiendo o bajando.
Si la probabilidad es inferior al 50%, se considera que la línea K actual corresponde a la forma de la señal de reversión.
En el rango de tiempo de negociación, se genera una señal de alza o baja.
Realizar retroalimentación para comprobar el efecto de la estrategia.
El riesgo puede reducirse de la siguiente manera:
La estrategia puede ser optimizada en los siguientes aspectos:
Optimización del número de líneas K. Se pueden probar diferentes parámetros de 2 a 10 para seleccionar el parámetro óptimo.
Optimización de la inversión de los umbrales. Se puede probar entre un 40% y un 60% de diferentes parámetros, teniendo en cuenta los cambios en el mercado.
Aumentar las estrategias de stop loss. Se puede establecer un punto de stop loss después de la formación de la señal, para controlar el riesgo.
En combinación con otros indicadores. Por ejemplo, puede combinarse con indicadores como el RSI para verificar la señal de inversión.
Aumentar la variedad de futuros, divisas, etc.; realizar pruebas para los diferentes parámetros de las variedades de transacciones.
Optimización progresiva. Ajuste gradualmente los parámetros para encontrar la combinación óptima de parámetros.
Añadir un modelo de aprendizaje automático que use algoritmos para buscar automáticamente los parámetros óptimos.
La estrategia multibar para identificar posibles señales de reversión mediante el análisis estadístico de la probabilidad de la línea K de la cadena múltiple, permite un procesamiento de señales más preciso. Sin embargo, los efectos de la estrategia están relacionados con la selección de parámetros y requieren una optimización adecuada. Además, la señal de reversión en sí misma puede ser mal interpretada y requiere verificación en combinación con otros factores.
/*backtest
start: 2023-10-16 00:00:00
end: 2023-10-17 00:00:00
period: 5m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
// BO - Bar's direction Signal - Backtesting
//anch.v43
// © inno14
//@version=4
strategy("BO - Bar's direction Signal - Backtesting", pyramiding=15)
// === INPUT PERIOD OF TIME ===
Date = input(true, title = "=== Periods Counting ===")
FromDay = input(defval = 1, title = "From Day", minval = 1, maxval = 31)
FromMonth = input(defval = 1, title = "From Month", minval = 1, maxval = 12)
FromYear = input(defval = 2020, title = "From Year", minval = 2017)
ToDay = input(defval = 1, title = "To Day", minval = 1, maxval = 31)
ToMonth = input(defval = 1, title = "To Month", minval = 1, maxval = 12)
ToYear = input(defval = 9999, title = "To Year", minval = 2017)
// === DATE RANGE ===
start = timestamp(FromYear, FromMonth, FromDay, 00, 00) // backtest start window
finish = timestamp(ToYear, ToMonth, ToDay, 23, 59) // backtest finish window
window() => time >= start and time <= finish ? true : false // create function "within window of time"
// === Trading Time ===
CTimeDvM = input(true, title = "=== Trading Time ===")
Time_zone = input(7,title="Time Zone")
FromHourDvM = input(defval = 05, title = "From Hour", minval = 00, maxval = 23)
FromMinuteDvM = input(defval = 00, title = "From Minute", minval = 00, maxval = 59)
ToHourDvM = input(defval = 04, title = "To Hour", minval = 00, maxval = 23)
ToMinuteDvM = input(defval = 59, title = "To Minute", minval = 00, maxval = 59)
GMT_FHDvM=FromHourDvM<Time_zone?FromHourDvM-Time_zone+24:FromHourDvM-Time_zone
GMT_THDvM=ToHourDvM<Time_zone?ToHourDvM-Time_zone+24:ToHourDvM-Time_zone
fhDvM= (GMT_FHDvM<10?"0"+tostring(GMT_FHDvM):tostring(GMT_FHDvM))
fmDvM= (FromMinuteDvM<10?"0"+tostring(FromMinuteDvM):tostring(FromMinuteDvM))
thDvM= (GMT_THDvM<10?"0"+tostring(GMT_THDvM):tostring(GMT_THDvM))
tmDvM= (ToMinuteDvM<10?"0"+tostring(ToMinuteDvM):tostring(ToMinuteDvM))
WorkingHourDvM = fhDvM+fmDvM+"-"+thDvM+tmDvM
t0_DvM = time(timeframe.period, WorkingHourDvM)
htrtime = input(true,title="Highlight Tradingtime")
bgcolor(htrtime? t0_DvM? color.gray : na:na, title="Trading Time", transp=90)
// === Date Backtesting ===
Date1 = input(true, title = "=== Date Backtesting ===")
FromDay1 = input(defval = 1, title = "From Day", minval = 1, maxval = 31)
FromMonth1 = input(defval = 1, title = "From Month", minval = 1, maxval = 12)
FromYear1 = input(defval = 2020, title = "From Year", minval = 2017)
ToDay1 = input(defval = 1, title = "To Day", minval = 1, maxval = 31)
ToMonth1 = input(defval = 1, title = "To Month", minval = 1, maxval = 12)
ToYear1 = input(defval = 9999, title = "To Year", minval = 2017)
// === DATE RANGE ===
start1 = timestamp(FromYear1, FromMonth1, FromDay1, 00, 00) // backtest start window
finish1 = timestamp(ToYear1, ToMonth1, ToDay1, 23, 59) // backtest finish window
window1() => time >= start1 and time <= finish1 ? true : false // create function "within window of time"
// === Setup ===
Setup = input(true, title = "=== Setup Options ===")
set1 = input(true, title = "Reversal after 2 bars same direction")
set2 = input(true, title = "Reversal after 3 bars same direction")
set3 = input(true, title = "Reversal after 4 bars same direction")
set4 = input(true, title = "Reversal after 5 bars same direction")
set5 = input(true, title = "Reversal after 6 bars same direction")
// Calculate hours, minutes, and seconds till close
timeLeft = barstate.isrealtime ?
(time_close - timenow) / 1000 :
na
minutesLeft = floor((timeLeft % 3600) / 60)
secondsLeft = timeLeft % 60
// truncate() truncates a given number
// to a certain number of decimals
truncate(number, decimals) =>
factor = pow(10, decimals)
int(number * factor) / factor
//count 2
redv2=window()?1:0
bluev2=window()?1:0
mchange2 = close[0]<open[0] and close[1]<open[1] and t0_DvM?-1:0
pchange2 = close[0]>open[0] and close[1]>open[1] and t0_DvM?1:0
blue2 = cum(pchange2 > 0 ? bluev2 : 0 * bluev2)
red2 = cum(mchange2 < 0 ? redv2 : 0 * redv2)
//count 3
redv3=window()?1:0
bluev3=window()?1:0
mchange3 = close[0]<open[0] and close[1]<open[1] and close[2]<open[2] and t0_DvM?-1:0
pchange3 = close[0]>open[0] and close[1]>open[1] and close[2]>open[2] and t0_DvM?1:0
blue3 = cum(pchange3 > 0 ? bluev3 : 0 * bluev3)
red3 = cum(mchange3 < 0 ? redv3 : 0 * redv3)
//count 4
redv4=window()?1:0
bluev4=window()?1:0
mchange4 = close[0]<open[0] and close[1]<open[1] and close[2]<open[2] and close[3]<open[3] and t0_DvM?-1:0
pchange4 = close[0]>open[0] and close[1]>open[1] and close[2]>open[2] and close[3]>open[3] and t0_DvM?1:0
blue4 = cum(pchange4 > 0 ? bluev4 : 0 * bluev4)
red4 = cum(mchange4 < 0 ? redv4 : 0 * redv4)
//count 5
redv5=window()?1:0
bluev5=window()?1:0
mchange5 = close[0]<open[0] and close[1]<open[1] and close[2]<open[2] and close[3]<open[3] and close[4]<open[4] and t0_DvM?-1:0
pchange5 = close[0]>open[0] and close[1]>open[1] and close[2]>open[2] and close[3]>open[3] and close[4]>open[4] and t0_DvM?1:0
blue5 = cum(pchange5 > 0 ? bluev5 : 0 * bluev5)
red5 = cum(mchange5 < 0 ? redv5 : 0 * redv5)
//count 6
redv6=window()?1:0
bluev6=window()?1:0
mchange6 = close[0]<open[0] and close[1]<open[1] and close[2]<open[2] and close[3]<open[3] and close[4]<open[4] and close[5]<open[5] and t0_DvM?-1:0
pchange6 = close[0]>open[0] and close[1]>open[1] and close[2]>open[2] and close[3]>open[3] and close[4]>open[4] and close[5]>open[5] and t0_DvM?1:0
blue6 = cum(pchange6 > 0 ? bluev6 : 0 * bluev6)
red6 = cum(mchange6 < 0 ? redv6 : 0 * redv6)
//count 7
redv7=window()?1:0
bluev7=window()?1:0
mchange7 = close[0]<open[0] and close[1]<open[1] and close[2]<open[2] and close[3]<open[3] and close[4]<open[4] and close[5]<open[5] and close[6]<open[6] and t0_DvM?-1:0
pchange7 = close[0]>open[0] and close[1]>open[1] and close[2]>open[2] and close[3]>open[3] and close[4]>open[4] and close[5]>open[5] and close[6]>open[6] and t0_DvM?1:0
blue7 = cum(pchange7 > 0 ? bluev7 : 0 * bluev7)
red7 = cum(mchange7 < 0 ? redv7 : 0 * redv7)
//Percent 3rd bar has same direction
pred3=(red3/red2)*100
pblue3=(blue3/blue2)*100
//2->3
p23_blue_xloc=0
p23_red_xloc=2
p23_lable_xloc=round((p23_blue_xloc+p23_red_xloc)/2)
p23_label_yloc=1.0*100
blue2_100=100
red2_100=100
plot(blue2_100, style=plot.style_columns, offset=p23_blue_xloc, color=color.blue, transp=60, show_last=1)
plot(red2_100, style=plot.style_columns, offset=-p23_red_xloc, color=color.red, transp=60, show_last=1)
plot(pblue3, style=plot.style_columns, offset=p23_blue_xloc, color=color.blue, transp=40, show_last=1)
plot(pred3, style=plot.style_columns, offset=-p23_red_xloc, color=color.red, transp=40, show_last=1)
// label_pred_23=label.new(bar_index[p23_red_xloc],pred3,style=label.style_none,text=tostring(truncate(pred3,2))+"%")
// label.delete(label_pred_23[1])
//label_2dn=label.new(bar_index[p23_red_xloc],red2,style=label.style_none,text="2 bars downward: "+tostring(red2))
//label.delete(label_2dn[1])
// label_pblue_23=label.new(bar_index[p23_blue_xloc],pblue3,style=label.style_none,text=tostring(truncate(pblue3,2))+"%")
// label.delete(label_pblue_23[1])
//label_2up=label.new(bar_index[p23_blue_xloc],blue2,style=label.style_none,text="2 bars upward: "+tostring(blue2))
//label.delete(label_2up[1])
// label_23=label.new(bar_index[p23_lable_xloc],p23_label_yloc,style=label.style_labeldown,text="3 bars same direction", color=color.orange)
// label.delete(label_23[1])
//Percent 4th bar has same direction
pred4=(red4/red3)*100
pblue4=(blue4/blue3)*100
//3->4
p34_blue_xloc=4
p34_red_xloc=6
p34_lable_xloc=round((p34_blue_xloc+p34_red_xloc)/2)
p34_label_yloc=1.0*100
blue3_100=100
red3_100=100
plot(blue3_100, style=plot.style_columns, offset=-p34_blue_xloc, color=color.blue, transp=60, show_last=1)
plot(red3_100, style=plot.style_columns, offset=-p34_red_xloc, color=color.red, transp=60, show_last=1)
plot(pblue4, style=plot.style_columns, offset=-p34_blue_xloc, color=color.blue, transp=40, show_last=1)
plot(pred4, style=plot.style_columns, offset=-p34_red_xloc, color=color.red, transp=40, show_last=1)
// label_pred_34=label.new(bar_index[p34_red_xloc],pred4,style=label.style_none,text=tostring(truncate(pred4,2))+"%")
// label.delete(label_pred_34[1])
// //label_3dn=label.new(bar_index[p34_red_xloc],red3,style=label.style_none,text="3 bars downward: "+tostring(red3))
// //label.delete(label_3dn[1])
// label_pblue_34=label.new(bar_index[p34_blue_xloc],pblue4,style=label.style_none,text=tostring(truncate(pblue4,2))+"%")
// label.delete(label_pblue_34[1])
// //label_3up=label.new(bar_index[p34_blue_xloc],blue3,style=label.style_none,text="3 bars upward: "+tostring(blue3))
// //label.delete(label_3up[1])
// label_34=label.new(bar_index[p34_lable_xloc],p34_label_yloc,style=label.style_labeldown,text="4 bars same direction", color=color.orange)
// label.delete(label_34[1])
//Percent 5th bar has same direction
pred5=(red5/red4)*100
pblue5=(blue5/blue4)*100
//4->5
p45_blue_xloc=8
p45_red_xloc=10
p45_lable_xloc=round((p45_blue_xloc+p45_red_xloc)/2)
p45_label_yloc=1.0*100
blue4_100=100
red4_100=100
plot(blue4_100, style=plot.style_columns, offset=-p45_blue_xloc, color=color.blue, transp=60, show_last=1)
plot(red4_100, style=plot.style_columns, offset=-p45_red_xloc, color=color.red, transp=60, show_last=1)
plot(pblue5, style=plot.style_columns, offset=-p45_blue_xloc, color=color.blue, transp=40, show_last=1)
plot(pred5, style=plot.style_columns, offset=-p45_red_xloc, color=color.red, transp=40, show_last=1)
// label_pred_45=label.new(bar_index[p45_red_xloc],pred5,style=label.style_none,text=tostring(truncate(pred5,2))+"%")
// label.delete(label_pred_45[1])
// //label_4dn=label.new(bar_index[p45_red_xloc],red4,style=label.style_none,text="4 bars downward: "+tostring(red4))
// //label.delete(label_4dn[1])
// label_pblue_45=label.new(bar_index[p45_blue_xloc],pblue5,style=label.style_none,text=tostring(truncate(pblue5,2))+"%")
// label.delete(label_pblue_45[1])
// //label_4up=label.new(bar_index[p45_blue_xloc],blue4,style=label.style_none,text="4 bars upward: "+tostring(blue4))
// //label.delete(label_4up[1])
// label_45=label.new(bar_index[p45_lable_xloc],p45_label_yloc,style=label.style_labeldown,text="5 bars same direction", color=color.orange)
// label.delete(label_45[1])
//Percent 6th bar has same direction
pred6=(red6/red5)*100
pblue6=(blue6/blue5)*100
//5->6
p56_blue_xloc=12
p56_red_xloc=14
p56_lable_xloc=round((p56_blue_xloc+p56_red_xloc)/2)
p56_label_yloc=1.0*100
blue5_100=100
red5_100=100
plot(blue5_100, style=plot.style_columns, offset=-p56_blue_xloc, color=color.blue, transp=60, show_last=1)
plot(red5_100, style=plot.style_columns, offset=-p56_red_xloc, color=color.red, transp=60, show_last=1)
plot(pblue6, style=plot.style_columns, offset=-p56_blue_xloc, color=color.blue, transp=40, show_last=1)
plot(pred6, style=plot.style_columns, offset=-p56_red_xloc, color=color.red, transp=40, show_last=1)
// label_pred_56=label.new(bar_index[p56_red_xloc],pred6,style=label.style_none,text=tostring(truncate(pred6,2))+"%")
// label.delete(label_pred_56[1])
// //label_5dn=label.new(bar_index[p56_red_xloc],red5,style=label.style_none,text="5 bars downward: "+tostring(red5))
// //label.delete(label_5dn[1])
// label_pblue_56=label.new(bar_index[p56_blue_xloc],pblue6,style=label.style_none,text=tostring(truncate(pblue6,2))+"%")
// label.delete(label_pblue_56[1])
// //label_5up=label.new(bar_index[p56_blue_xloc],blue5,style=label.style_none,text="5 bars upward: "+tostring(blue5))
// //label.delete(label_5up[1])
// label_56=label.new(bar_index[p56_lable_xloc],p56_label_yloc,style=label.style_labeldown,text="6 bars same direction", color=color.orange)
// label.delete(label_56[1])
//Percent 7th bar has same direction
pred7=(red7/red6)*100
pblue7=(blue7/blue6)*100
//6->7
p67_blue_xloc=16
p67_red_xloc=18
p67_lable_xloc=round((p67_blue_xloc+p67_red_xloc)/2)
p67_label_yloc=1.0*100
blue6_100=100
red6_100=100
plot(blue6_100, style=plot.style_columns, offset=-p67_blue_xloc, color=color.blue, transp=60, show_last=1)
plot(red6_100, style=plot.style_columns, offset=-p67_red_xloc, color=color.red, transp=60, show_last=1)
plot(pblue7, style=plot.style_columns, offset=-p67_blue_xloc, color=color.blue, transp=40, show_last=1)
plot(pred7, style=plot.style_columns, offset=-p67_red_xloc, color=color.red, transp=40, show_last=1)
// label_pred_67=label.new(bar_index[p67_red_xloc],pred7,style=label.style_none,text=tostring(truncate(pred7,2))+"%")
// label.delete(label_pred_67[1])
// //label_6dn=label.new(bar_index[p67_red_xloc],red6,style=label.style_none,text="6 bars downward: "+tostring(red6))
// //label.delete(label_6dn[1])
// label_pblue_67=label.new(bar_index[p67_blue_xloc],pblue7,style=label.style_none,text=tostring(truncate(pblue7,2))+"%")
// label.delete(label_pblue_67[1])
// //label_6up=label.new(bar_index[p67_blue_xloc],blue6,style=label.style_none,text="6 bars upward: "+tostring(blue6))
// //label.delete(label_6up[1])
// label_67=label.new(bar_index[p67_lable_xloc],p67_label_yloc,style=label.style_labeldown,text="7 bars same direction", color=color.orange)
// label.delete(label_67[1])
//Plot Time Label
time_label_yloc=1.4*100
time_lable_xloc=round((p67_red_xloc+p23_blue_xloc)/2)
time_label_text="Bar's Direction Info From: "+tostring(FromDay)+"/"+tostring(FromMonth)+"/"+tostring(FromYear)+" To: "+tostring(ToDay)+"/"+tostring(ToMonth)+"/"+tostring(ToYear)
// label_time=label.new(bar_index[time_lable_xloc],time_label_yloc,style=label.style_none,text=time_label_text, color=color.aqua)
// label.delete(label_time[1])
//Signal
//Put signal
x1=
pblue3<50?blue2[0]>blue2[1] and blue3[0]==blue3[1]:false
x2=
pblue4<50?blue3[0]>blue3[1] and blue4[0]==blue4[1]:false
x3=
pblue5<50?blue4[0]>blue4[1] and blue5[0]==blue5[1]:false
x4=
pblue6<50?blue5[0]>blue5[1] and blue6[0]==blue6[1]:false
x5=
pblue7<50?blue6[0]>blue6[1] and blue7[0]==blue7[1]:false
//Call signal
y1=
pred3<50?red2[0]>red2[1] and red3[0]==red3[1]:false
y2=
pred4<50?red3[0]>red3[1] and red4[0]==red4[1]:false
y3=
pred5<50?red4[0]>red4[1] and red5[0]==red5[1]:false
y4=
pred6<50?red5[0]>red5[1] and red6[0]==red6[1]:false
y5=
pred7<50?red6[0]>red6[1] and red7[0]==red7[1]:false
//Function
xTech=
set1?x1:false
or set2?x2:false
or set3?x3:false
or set4?x4:false
or set5?x5:false
yTech=
set1?y1:false
or set2?y2:false
or set3?y3:false
or set4?y4:false
or set5?y5:false
//Plot Analyzing Signals
hline1=hline(-100)
hline2=hline(-1.6*100)
hline0=hline(0)
sigtext=xTech?"Put signal":yTech?"Call signal":"Analyzing Signals - Bar's Time left:"+tostring(minutesLeft)+":"+tostring(secondsLeft)
sig_col=xTech?color.new(color.red,0):yTech?color.new(color.blue,0):color.new(color.navy,0)
// label_sig_text = label.new(bar_index[0], -1.5*100, text=sigtext, style=label.style_none, textcolor=sig_col, size=size.large)
// label.delete(label_sig_text[1])
//plot Signal
putcol = xTech? color.red : na
callcol = yTech? color.blue : na
PutSignal= xTech and window1() and t0_DvM?-100:na
CallSignal= yTech and window1() and t0_DvM?-100:na
plot(PutSignal, title='Put Signal', style=plot.style_columns, color=color.red, offset=1, transp=0)
plot(CallSignal, title='Call Signal', style=plot.style_columns, color=color.blue, offset=1, transp=0)
plotshape(PutSignal, title='Put', text="Put", style=shape.labeldown, location=location.bottom, color=color.orange, textcolor=color.black, offset=1, transp=0)
plotshape(CallSignal, title='Call', text="Call", style=shape.labelup, location=location.bottom, color=color.orange, textcolor=color.black, offset=1, transp=0)
//Backtesting
strategy.entry("Call", strategy.long, when=yTech and window1() and t0_DvM)
strategy.entry("Put", strategy.short, when=xTech and window1() and t0_DvM)
strategy.close_all(when=barstate.isnew)
//EOF