Strategi Multi-Bar Direction mengenal pasti isyarat pembalikan trend dengan mengira kebarangkalian beberapa bar bergerak ke arah yang sama.
Strategi ini mula-mula menetapkan waktu permulaan dan akhir untuk pengekstrakan data sejarah. Jam dagangan dikonfigurasi untuk mengenal pasti lilin yang layak. Ia mengira kebarangkalian kenaikan atau penurunan berturut-turut dalam 2 hingga 7 lilin. Isyarat dagangan dihasilkan apabila nisbah naik atau turun melebihi ambang.
Sebagai contoh, jika kebarangkalian trend menurun dalam 3 lilin adalah lebih rendah daripada 50%, 3 lilin semasa memenuhi syarat dan isyarat beli dihasilkan. Parameter dari 2 hingga 7 bar boleh dikonfigurasi.
Logika khusus adalah seperti berikut:
Tetapkan julat masa backtest, termasuk tarikh permulaan, tarikh akhir, jam dagangan.
Hitung jumlah arah yang sama naik atau turun dalam 2 hingga 7 lilin.
Mengira kebarangkalian kelanjutan ke atas atau ke bawah di antara candelabres bersebelahan.
Jika kebarangkalian adalah kurang daripada 50%, lilin semasa sesuai dengan corak pembalikan.
Menghasilkan isyarat beli atau jual dalam waktu perdagangan.
Uji balik untuk mengesahkan strategi.
Elakkan isyarat palsu dengan mempertimbangkan kemungkinan pelbagai candlestick.
Bilangan bar yang boleh disesuaikan untuk mengenal pasti isyarat pembalikan dalam jangka masa yang berbeza.
Waktu perdagangan yang jelas mengelakkan isyarat yang tidak tepat pada masanya.
Paparan statistik intuitif untuk penilaian prestasi.
Banyak parameter yang boleh dioptimumkan yang sesuai untuk pasaran yang berbeza.
Pengiraan bar tidak dapat menentukan titik pembalikan trend.
Tempoh statistik yang panjang mungkin kehilangan peluang perdagangan jangka pendek.
Sempadan statik dipengaruhi oleh turun naik pasaran. penyesuaian dinamik diperlukan.
Pemilihan tempoh ujian belakang boleh menyebabkan pemasangan berlebihan.
Penyelesaian yang mungkin:
Mengoptimumkan bilangan bar untuk jangka masa yang berbeza.
Sertakan penunjuk lain.
Mengambil ambang dinamik berdasarkan turun naik pasaran.
Memperluaskan tempoh backtest dan menjalankan pelbagai backtest.
Strategi ini boleh dioptimumkan dalam aspek berikut:
Mengoptimumkan bilangan bar dari 2 hingga 10 dan pilih parameter yang optimum.
Sempadan pembalikan ujian dari 40% hingga 60% memandangkan perubahan pasaran.
Tambah stop loss selepas penjanaan isyarat untuk mengehadkan risiko.
Masukkan penunjuk lain seperti RSI untuk mengesahkan isyarat.
Tambah lebih banyak produk seperti niaga hadapan dan forex untuk ujian parameter.
Penyesuaian parameter tambahan untuk mencari kombinasi yang optimum.
Gunakan model pembelajaran mesin untuk mencari parameter optimum secara automatik.
Strategi Multi-Bar Direction mengenal pasti isyarat pembalikan yang berpotensi dengan menganalisis kebarangkalian candlestick secara statistik. Tetapi prestasi bergantung pada penyesuaian parameter berdasarkan pengoptimuman yang mencukupi. Di samping itu, isyarat pembalikan mempunyai risiko salah menilai dan memerlukan pengesahan. Secara keseluruhan, ini adalah strategi statistik yang mudah dan berkesan yang bernilai untuk penyelidikan dan pengoptimuman lanjut.
/*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