Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Independent TradingView port of Distilled Desk's New York and London Time Ranges.
- // © DistilledTrades. Private research display; no orders or trade signals.
- //@version=6
- indicator("Time Ranges",overlay=true,dynamic_requests=true,max_boxes_count=300,max_lines_count=500,max_labels_count=500)
- const string NY="America/New_York"
- const string LONDON="Europe/London"
- a0=input.bool(true,"08:50–09:10 → 10:55",group="New York windows")
- a1=input.bool(true,"10:50–11:10 → 12:10",group="New York windows")
- a2=input.bool(false,"Bell · 09:00–09:30 → 10:30",group="New York windows")
- a3=input.bool(false,"Pre-news · 07:30–08:30 → 12:30",group="New York windows")
- a4=input.bool(true,"Opening hour · 09:30–10:30 → 12:30",group="New York windows")
- a5=input.bool(false,"09:50–10:10 → 12:10",group="New York windows")
- a6=input.bool(false,"Pre-open · 07:00–08:00 → 10:00 UK",group="London windows")
- a7=input.bool(true,"Opening hour · 08:00–09:00 → 12:00 UK",group="London windows")
- showBands=input.bool(true,"Historical P30–P70 zones",group="Display",tooltip="Earlier complete same-symbol/feed sessions only, separately grouped by first edge and final outcome. 30+ observations for qualified bands; optional dashed previews use3–29. Conditional historical excursions, not targets or forecast probabilities.")
- previewBands=input.bool(true,"Show low-sample P-box previews",group="Display",tooltip="Exploratory preview with 3–29 earlier complete sessions in that exact side/outcome cohort. Dashed outline, LOW SAMPLE label and n. Does not relax the 30-session percentage threshold or mark a preview as qualified.")
- showLabels=input.bool(true,"Chart labels",group="Display")
- showPanel=input.bool(true,"Range status table",group="Display")
- keepDays=input.int(3,"Recent chart days",minval=1,maxval=5,group="Display")
- rangeInk=input.color(#4CAF50,"Range",group="Display")
- contInk=input.color(#29946e,"Continuation",group="Display")
- revInk=input.color(#ce6570,"Reversal",group="Display")
- header=input.color(#283238,"Table header",group="Display")
- rowsInk=input.color(#f0f0f0,"Table rows",group="Display")
- textInk=input.color(#20252b,"Table text",group="Display")
- where=input.string("Bottom right","Table position",options=["Top right","Top left","Bottom right","Bottom left"],group="Display")
- textSize=input.string(size.small,"Table text size",options=[size.tiny,size.small,size.normal],group="Display")
- weekdayFilter=input.string("All weekdays","Historical weekday filter",options=["All weekdays","Current range weekday"],group="Historical tendency")
- firstFilter=input.string("Auto · observed first edge","Historical first-break filter",options=["Auto · observed first edge","Both","High first","Low first"],group="Historical tendency",tooltip="Auto uses both sides before the first break, then the actual observed first edge. Fixed High/Low selections are labelled explicitly and are not today's detected direction.")
- cohortMax=input.int(250,"Earlier sessions retained per window",minval=60,maxval=500,group="History")
- sharedHistory=input.bool(true,"Use deeper shared minute history",group="History",tooltip="Loads actual native minutes through a background 1H context. The same symbol, range, first-side and outcome definitions are preserved. Only earlier complete sessions qualify. Each statistic uses the source with more samples; never adds overlapping source counts.")
- fineHistory=input.int(200000,"Native minute lookback",minval=5000,maxval=200000,step=5000,group="History",tooltip="Actual history depends on TradingView's plan, symbol and intrabar availability. Missing minutes are not filled. Low sample cohorts remain withheld.")
- int sec=int(timeframe.in_seconds(timeframe.main_period))
- bool supported=chart.is_standard and sec>=30 and sec<=3600
- // One exact closed minute is the atomic observation, including on a 30s chart.
- type Minute
- int t
- int e
- float o
- float h
- float l
- float c
- f_minute()=>
- Minute.new(time,time_close,open,high,low,close)
- type Sample
- int deadline
- int side
- int outcome
- float excursion
- float opposing
- type Range
- int id
- int start
- int finish
- int deadline
- string name
- bool enabled
- int last=na
- bool valid=true
- float hi=na
- float lo=na
- float postHi=na
- float postLo=na
- int side=0
- int firstAt=na
- int reversalAt=na
- int state=0 // building 0, waiting 1, pending 2, reversal 3, continuation 4, ambiguous 5, unavailable 6, no break 7
- bool archived=false
- array<float> bands=na // high continuation P30/50/70, high reversal, low continuation, low reversal
- array<int> counts=na
- array<int> tendency=na // high C/R, low C/R; frozen at this range close
- string historySource="Chart"
- f_name(int i)=>
- i==0?"08:50–09:10":i==1?"10:50–11:10":i==2?"09:00–09:30":i==3?"07:30–08:30":i==4?"09:30–10:30":i==5?"09:50–10:10":i==6?"London 07:00–08:00":"London 08:00–09:00"
- f_zone(int i)=>
- i>=6?LONDON:NY
- f_zoneLabel(int i)=>
- i>=6?"UK":"NY"
- f_clocks(int t,int i)=>
- int startM=i==0?530:i==1?650:i==2?540:i==3?450:i==4?570:i==5?590:i==6?420:480
- int endM=i==0?550:i==1?670:i==2?570:i==3?510:i==4?630:i==5?610:i==6?480:540
- int stopM=i==0?655:i==1?730:i==2?630:i==3?750:i==4?750:i==5?730:i==6?600:720
- string zone=f_zone(i)
- int y=year(t,zone),m=month(t,zone),d=dayofmonth(t,zone)
- [timestamp(zone,y,m,d,int(startM/60),startM%60),timestamp(zone,y,m,d,int(endM/60),endM%60),timestamp(zone,y,m,d,int(stopM/60),stopM%60)]
- // NumPy method="linear" parity: percentile position is (n-1)*q.
- f_linear(array<float> values,float q)=>
- float at=(values.size()-1)*q
- int left=int(math.floor(at))
- int right=int(math.ceil(at))
- values.get(left)+(values.get(right)-values.get(left))*(at-left)
- f_quantiles(array<Sample> history,Range r)=>
- r.bands:=array.new_float(12,na)
- r.counts:=array.new_int(4,0)
- r.tendency:=array.new_int(4,0)
- for sample in history
- if sample.deadline<r.start and (weekdayFilter=="All weekdays" or dayofweek(sample.deadline,f_zone(r.id))==dayofweek(r.start,f_zone(r.id)))
- int slot=(sample.side==1?0:2)+(sample.outcome==3?1:0)
- r.tendency.set(slot,r.tendency.get(slot)+1)
- for cohort=0 to 3
- array<float> values=array.new_float()
- int side=cohort<2?1:-1
- int outcome=cohort%2==0?4:3
- for sample in history
- if sample.deadline<r.start and sample.side==side and sample.outcome==outcome
- values.push(outcome==4?sample.excursion:sample.opposing)
- r.counts.set(cohort,values.size())
- if values.size()>=30 or previewBands and values.size()>=3
- values.sort()
- r.bands.set(cohort*3,f_linear(values,.3))
- r.bands.set(cohort*3+1,f_linear(values,.5))
- r.bands.set(cohort*3+2,f_linear(values,.7))
- 0
- method step(Range r,Minute b,array<Sample> history)=>
- if b.t>=r.start and b.t<r.deadline and not r.archived
- bool prices=not na(b.o) and not na(b.h) and not na(b.l) and not na(b.c) and b.h>=math.max(b.o,b.c) and b.l<=math.min(b.o,b.c)
- if b.e-b.t!=60000 or (na(r.last)?b.t!=r.start:b.t!=r.last) or not prices
- r.valid:=false
- r.last:=b.e
- if b.t<r.finish
- r.hi:=na(r.hi)?b.h:math.max(r.hi,b.h)
- r.lo:=na(r.lo)?b.l:math.min(r.lo,b.l)
- if b.e==r.finish
- r.valid:=r.valid and r.hi>r.lo
- r.state:=r.valid?1:6
- if r.valid
- f_quantiles(history,r)
- else if r.valid
- bool up=b.h>r.hi
- bool down=b.l<r.lo
- if r.side==0 and r.state!=5
- if up and down
- r.state:=5
- r.firstAt:=b.e
- else if up or down
- r.side:=up?1:-1
- r.firstAt:=b.e
- r.state:=2
- if r.side!=0
- r.postHi:=na(r.postHi)?b.h:math.max(r.postHi,b.h)
- r.postLo:=na(r.postLo)?b.l:math.min(r.postLo,b.l)
- if na(r.reversalAt) and (r.side==1?down:up)
- r.reversalAt:=b.e
- r.state:=3
- if not r.valid
- r.state:=6
- if b.e==r.deadline
- if r.valid and r.state!=5
- r.state:=r.side==0?7:not na(r.reversalAt)?3:4
- if r.state==3 or r.state==4
- float width=r.hi-r.lo
- float excursion=r.side==1?(r.postHi-r.hi)/width:(r.lo-r.postLo)/width
- float opposing=math.max(0,r.side==1?(r.lo-r.postLo)/width:(r.postHi-r.hi)/width)
- history.push(Sample.new(r.deadline,r.side,r.state,excursion,opposing))
- if history.size()>cohortMax
- history.shift()
- r.archived:=true
- else if b.t>=r.deadline and not r.archived
- // Even one absent minute through the deadline invalidates the whole cohort.
- r.valid:=false
- r.state:=6
- r.archived:=true
- 0
- var h0=array.new<Sample>()
- var h1=array.new<Sample>()
- var h2=array.new<Sample>()
- var h3=array.new<Sample>()
- var h4=array.new<Sample>()
- var h5=array.new<Sample>()
- var h6=array.new<Sample>()
- var h7=array.new<Sample>()
- f_history(int i)=>
- i==0?h0:i==1?h1:i==2?h2:i==3?h3:i==4?h4:i==5?h5:i==6?h6:h7
- var ranges=array.new<Range>()
- var int dateKey=na
- var int lastEnd=na
- var int gaps=0
- f_dayKey(int t,string zone)=>
- year(t,zone)*10000+month(t,zone)*100+dayofmonth(t,zone)
- f_enabled(int i)=>
- i==0?a0:i==1?a1:i==2?a2:i==3?a3:i==4?a4:i==5?a5:i==6?a6:a7
- // Each profile rolls on its own local date. London must not be reset at NY midnight.
- var profileDays=array.new_int(8,na)
- f_dispatch(Minute b,int key)=>
- for i=0 to 7
- string zone=f_zone(i)
- int today=f_dayKey(b.t,zone)
- if na(profileDays.get(i)) or today!=profileDays.get(i)
- for r in ranges
- if r.id==i and not r.archived
- r.state:=6
- r.valid:=false
- r.archived:=true
- if dayofweek(b.t,zone)>=dayofweek.monday and dayofweek(b.t,zone)<=dayofweek.friday
- [s,e,d]=f_clocks(b.t,i)
- ranges.push(Range.new(i,s,e,d,f_name(i),f_enabled(i)))
- profileDays.set(i,today)
- while ranges.size()>keepDays*8
- ranges.shift()
- for r in ranges
- if not r.archived
- r.step(b,f_history(r.id))
- f_dayKey(b.t,NY)
- // Native 1m requests on charts >=1m; native 30s pairs on the seconds chart.
- var int halfStart=na
- var Minute half=na
- if supported
- int cutoff=barstate.isrealtime?int(math.floor(timenow/60000)*60000):time_close
- array<Minute> incoming=array.new<Minute>()
- if sec>60
- incoming:=request.security_lower_tf(syminfo.tickerid,"1",f_minute(),calc_bars_count=fineHistory)
- else if sec==60
- incoming.push(f_minute())
- else
- int minuteStart=time("1")
- if barstate.isconfirmed
- if time==minuteStart and time_close-time==30000
- halfStart:=minuteStart
- half:=f_minute()
- else if not na(half) and halfStart==minuteStart and time==half.e and time_close-time==30000 and time_close==time_close("1")
- incoming.push(Minute.new(half.t,time_close,half.o,math.max(half.h,high),math.min(half.l,low),close))
- half:=na
- for b in incoming
- if b.e<=cutoff and (na(lastEnd) or b.e>lastEnd)
- if not na(lastEnd) and b.t!=lastEnd
- gaps+=1
- dateKey:=f_dispatch(b,dateKey)
- lastEnd:=b.e
- // Shared calibration runs in a deeper 1H context using complete native minute arrays.
- // It never returns or imports an event state into the chart's live detector.
- type HistoryBook
- array<Range> views
- array<int> days
- array<Sample> h0
- array<Sample> h1
- array<Sample> h2
- array<Sample> h3
- array<Sample> h4
- array<Sample> h5
- array<Sample> h6
- array<Sample> h7
- int last=na
- int first=na
- int minutes=0
- type HistoryBundle
- array<Range> views
- int last
- int first
- int minutes
- f_sharedBook()=>
- HistoryBook.new(array.new<Range>(),array.new_int(8,na),array.new<Sample>(),array.new<Sample>(),array.new<Sample>(),array.new<Sample>(),array.new<Sample>(),array.new<Sample>(),array.new<Sample>(),array.new<Sample>())
- f_sharedSamples(HistoryBook book,int i)=>
- i==0?book.h0:i==1?book.h1:i==2?book.h2:i==3?book.h3:i==4?book.h4:i==5?book.h5:i==6?book.h6:book.h7
- method ingestShared(HistoryBook book,Minute b)=>
- if na(book.last) or b.e>book.last
- if na(book.first)
- book.first:=b.t
- book.minutes+=1
- for i=0 to 7
- string zone=f_zone(i)
- int today=f_dayKey(b.t,zone)
- if na(book.days.get(i)) or today!=book.days.get(i)
- for view in book.views
- if view.id==i and not view.archived
- view.state:=6
- view.valid:=false
- view.archived:=true
- if dayofweek(b.t,zone)>=dayofweek.monday and dayofweek(b.t,zone)<=dayofweek.friday
- [s,e,d]=f_clocks(b.t,i)
- Range view=Range.new(i,s,e,d,f_name(i),true)
- f_quantiles(f_sharedSamples(book,i),view)
- book.views.push(view)
- book.days.set(i,today)
- while book.views.size()>keepDays*8
- book.views.shift()
- for view in book.views
- if not view.archived
- view.step(b,f_sharedSamples(book,view.id))
- book.last:=b.e
- 0
- f_sharedCalibration()=>
- var HistoryBook book=f_sharedBook()
- string historyTicker=ticker.modify(syminfo.tickerid,session=syminfo.session)
- array<Minute> native=request.security_lower_tf(historyTicker,"1",f_minute(),currency=syminfo.currency,calc_bars_count=fineHistory)
- int cutoff=barstate.isrealtime?int(math.floor(timenow/60000)*60000):time_close
- for b in native
- if b.e<=cutoff
- book.ingestShared(b)
- // Returning collections on every requested bar would duplicate large buffers.
- HistoryBundle result=na
- if barstate.islast or barstate.islastconfirmedhistory
- result:=HistoryBundle.new(book.views,book.last,book.first,book.minutes)
- result
- // Direct minute context avoids reusing a short chart-minute dataset when available.
- f_sharedMinuteCalibration()=>
- var HistoryBook book=f_sharedBook()
- int cutoff=barstate.isrealtime?int(math.floor(timenow/60000)*60000):time_close
- if time_close<=cutoff
- book.ingestShared(f_minute())
- HistoryBundle result=na
- if barstate.islast or barstate.islastconfirmedhistory
- result:=HistoryBundle.new(book.views,book.last,book.first,book.minutes)
- result
- f_applyShared(Range local,Range remote)=>
- bool used=false
- // Exact window/session key; frozen remote facts contain only deadlines before start.
- if local.id==remote.id and local.start==remote.start and not na(remote.tendency)
- if na(local.tendency)
- local.tendency:=array.new_int(4,0)
- if na(local.counts)
- local.counts:=array.new_int(4,0)
- if na(local.bands)
- local.bands:=array.new_float(12,na)
- if remote.tendency.sum()>local.tendency.sum()
- local.tendency:=remote.tendency.copy()
- used:=true
- for cohort=0 to 3
- if remote.counts.get(cohort)>local.counts.get(cohort)
- local.counts.set(cohort,remote.counts.get(cohort))
- for q=0 to 2
- local.bands.set(cohort*3+q,remote.bands.get(cohort*3+q))
- used:=true
- if used
- local.historySource:="Shared 1m"
- used
- HistoryBundle shared=na
- HistoryBundle sharedMinute=na
- if sharedHistory and supported
- shared:=request.security(syminfo.tickerid,"60",f_sharedCalibration(),gaps=barmerge.gaps_off,lookahead=barmerge.lookahead_off,calc_bars_count=int(math.ceil(fineHistory/60.0))+48)
- if sec<=60
- sharedMinute:=request.security(ticker.modify(syminfo.tickerid,session=syminfo.session),"1",f_sharedMinuteCalibration(),gaps=barmerge.gaps_off,lookahead=barmerge.lookahead_off,calc_bars_count=fineHistory)
- if barstate.islast
- for source=0 to 1
- HistoryBundle bundle=source==0?shared:sharedMinute
- if not na(bundle) and not na(bundle.views)
- for local in ranges
- for remote in bundle.views
- if local.id==remote.id and local.start==remote.start
- f_applyShared(local,remote)
- if not na(sharedMinute) and (na(shared) or sharedMinute.minutes>shared.minutes)
- shared:=sharedMinute
- // Render only after a new closed minute. State and calibration never use a forming minute.
- var boxes=array.new<box>()
- var lines=array.new<line>()
- var labels=array.new<label>()
- f_line(int a,int z,float p,color ink,string caption="",float offset=0)=>
- lines.push(line.new(a,p,z,p,xloc=xloc.bar_time,color=ink,width=1))
- if showLabels and caption!=""
- labels.push(label.new(z,p+offset,caption,xloc=xloc.bar_time,style=label.style_label_left,color=color.new(ink,100),textcolor=ink,size=size.tiny))
- 0
- f_draw(Range r)=>
- int cursor=math.min(nz(lastEnd,r.start),r.deadline)
- if r.enabled and cursor>r.start and not na(r.hi) and r.state!=6
- float width=r.hi-r.lo
- float pad=width*.04
- int right=math.min(r.deadline,cursor+600000)
- boxes.push(box.new(r.start,r.hi,math.min(r.finish,cursor),r.lo,xloc=xloc.bar_time,bgcolor=color.new(rangeInk,91),border_color=rangeInk))
- f_line(r.start,right,r.hi,rangeInk,showLabels?r.name+" "+f_zoneLabel(r.id)+" · High "+str.tostring(r.hi,format.mintick)+(r.side==1 or not na(r.reversalAt)?" · BSL taken":" · BSL"):"",pad)
- f_line(r.start,right,r.lo,rangeInk,showLabels?r.name+" "+f_zoneLabel(r.id)+" · Low "+str.tostring(r.lo,format.mintick)+(r.side==-1 or not na(r.reversalAt)?" · SSL taken":" · SSL"):"",-pad)
- if cursor>=r.finish
- lines.push(line.new(r.finish,r.hi,r.finish,r.lo,xloc=xloc.bar_time,color=rangeInk,style=line.style_dashed))
- if not na(r.firstAt) and r.side!=0 and showLabels
- labels.push(label.new(r.firstAt-60000,r.side==1?r.hi:r.lo,r.side==1?"▲":"▼",xloc=xloc.bar_time,style=label.style_label_center,color=color.new(color.black,100),textcolor=color.black,size=size.tiny))
- if not na(r.reversalAt)
- lines.push(line.new(r.reversalAt-60000,r.hi,r.reversalAt-60000,r.lo,xloc=xloc.bar_time,color=revInk,style=line.style_dashed))
- if showBands and cursor>=r.finish and r.state!=5 and not na(r.bands)
- for cohort=0 to 3
- int side=cohort<2?1:-1
- bool reversal=cohort%2==1
- if not na(r.bands.get(cohort*3)) and (r.side==0?not reversal:r.side==side)
- float anchor=reversal?(side==1?r.lo:r.hi):(side==1?r.hi:r.lo)
- int sign=reversal?-side:side
- float p30=anchor+sign*width*r.bands.get(cohort*3)
- float p50=anchor+sign*width*r.bands.get(cohort*3+1)
- float p70=anchor+sign*width*r.bands.get(cohort*3+2)
- int left=na(r.firstAt)?r.finish:math.max(r.finish,r.firstAt-60000)
- color ink=reversal?revInk:contInk
- int direction=reversal?-side:side
- string title=(r.side==0?"If "+(side==1?"high":"low")+" breaks · ":"")+(direction==1?"▲ Bullish ":"▼ Bearish ")+(reversal?"reversal":"continuation")+" P30–P70 · n="+str.tostring(r.counts.get(cohort))+(r.counts.get(cohort)<30?" · LOW SAMPLE PREVIEW":"")
- if right>left
- boxes.push(box.new(left,math.max(p30,p70),right,math.min(p30,p70),xloc=xloc.bar_time,bgcolor=color.new(ink,86),border_color=r.counts.get(cohort)<30?#c08a25:ink,border_style=r.counts.get(cohort)<30?line.style_dashed:line.style_solid))
- f_line(left,right,p50,ink,title+" · P50",pad)
- 0
- f_state(Range r)=>
- int direction=r.state==3?-r.side:r.side
- string side=direction==1?"▲ BULL ":direction==-1?"▼ BEAR ":""
- r.state==6?"UNAVAILABLE":lastEnd<r.start?"SCHEDULED":r.state==0?"BUILDING":r.state==1?"WAIT BREAK":r.state==2?side+"BREAK · PENDING":r.state==3?side+"REVERSAL":r.state==4?side+"CONTINUATION":r.state==5?"AMBIGUOUS":"NO BREAK"
- var table panel=table.new(where=="Top right"?position.top_right:where=="Top left"?position.top_left:where=="Bottom left"?position.bottom_left:position.bottom_right,4,10,border_width=0,frame_color=header,frame_width=1)
- var int rendered=na
- if barstate.islast
- if na(rendered) or rendered!=lastEnd or sharedHistory and not na(shared)
- for b in boxes
- box.delete(b)
- for l in lines
- line.delete(l)
- for l in labels
- label.delete(l)
- boxes.clear()
- lines.clear()
- labels.clear()
- for r in ranges
- f_draw(r)
- rendered:=lastEnd
- table.clear(panel,0,0,3,9)
- if showPanel
- table.cell(panel,0,0,"DSTL TIME RANGES",text_color=color.white,bgcolor=header,text_size=textSize,text_halign=text.align_left)
- table.cell(panel,1,0,"STATE",text_color=color.white,bgcolor=header,text_size=textSize)
- table.cell(panel,2,0,"CONT / REV · n",text_color=color.white,bgcolor=header,text_size=textSize)
- table.cell(panel,3,0,"P BOXES · C / R",text_color=color.white,bgcolor=header,text_size=textSize)
- int row=1
- for r in ranges
- if not na(lastEnd) and f_dayKey(r.start,f_zone(r.id))==f_dayKey(lastEnd-1,f_zone(r.id)) and r.enabled
- int filterSide=firstFilter=="High first"?1:firstFilter=="Low first"?-1:firstFilter=="Both"?0:r.side
- string filterName=filterSide==1?"High first":filterSide==-1?"Low first":"Both first edges"
- int c=0
- int v=0
- if not na(r.tendency)
- c:=filterSide==0?r.tendency.get(0)+r.tendency.get(2):r.tendency.get(filterSide==1?0:2)
- v:=filterSide==0?r.tendency.get(1)+r.tendency.get(3):r.tendency.get(filterSide==1?1:3)
- int n=c+v
- float rate=n>0?float(c)/n:na
- string counts=n>=30?str.tostring(rate*100,"#.#")+"% / "+str.tostring((1-rate)*100,"#.#")+"% · "+str.tostring(n):"n="+str.tostring(n)+" · NEED 30"
- color tendencyInk=n<30?color.gray:c>v?contInk:v>c?revInk:textInk
- float centre=n>0?(rate+3.8416/(2*n))/(1+3.8416/n):na
- float margin=n>0?1.96*math.sqrt(rate*(1-rate)/n+3.8416/(4*n*n))/(1+3.8416/n):na
- string confidence=n>=30?" Continuation 95% Wilson interval "+str.tostring((centre-margin)*100,"#.#")+"–"+str.tostring((centre+margin)*100,"#.#")+"%.":" At least 30 earlier complete breakout sessions required."
- int direction=r.state==3?-r.side:r.side
- color ink=r.state==6?color.gray:direction==1?#138c52:direction==-1?#a43b45:textInk
- table.cell(panel,0,row,r.name+" "+f_zoneLabel(r.id),text_color=textInk,bgcolor=rowsInk,text_size=textSize,text_halign=text.align_left)
- table.cell(panel,1,row,f_state(r),text_color=ink,bgcolor=rowsInk,text_size=textSize,tooltip="Range "+str.format_time(r.start,"HH:mm",f_zone(r.id))+"–"+str.format_time(r.finish,"HH:mm",f_zone(r.id))+"; deadline "+str.format_time(r.deadline,"HH:mm",f_zone(r.id))+" "+f_zoneLabel(r.id)+". Strict wick break; equality is a touch. Both edges first broken within one minute = ambiguous. Continuation is confirmed only at the deadline. Missing minutes invalidate the session.")
- table.cell(panel,2,row,counts,text_color=tendencyInk,bgcolor=rowsInk,text_size=textSize,tooltip=r.historySource+" history · "+filterName+" · "+weekdayFilter+". "+str.tostring(c)+" continuation / "+str.tostring(v)+" reversal. Historical event frequency frozen before this range's first break; not a validated current-day probability or a trade win rate."+confidence+" Today's outcome never enters today's sample. Ambiguous/no-break/missing sessions excluded. Bands separately require 30 per outcome cohort.")
- string bandRead="WAIT RANGE"
- if not showBands
- bandRead:="OFF"
- else if r.state==6
- bandRead:="DATA GAP"
- else if r.state==5
- bandRead:="AMBIGUOUS"
- else if not na(r.counts)
- int cN=r.counts.get(r.side==-1?2:0)
- int rN=r.counts.get(r.side==-1?3:1)
- bandRead:=r.side==0?"↑ "+str.tostring(cN)+"/"+str.tostring(rN)+" · ↓ "+str.tostring(r.counts.get(2))+"/"+str.tostring(r.counts.get(3)):"C "+str.tostring(cN)+(cN>=30?" OK":previewBands and cN>=3?" LOW":" WAIT")+" / R "+str.tostring(rN)+(rN>=30?" OK":previewBands and rN>=3?" LOW":" WAIT")
- table.cell(panel,3,row,bandRead,text_color=color.gray,bgcolor=rowsInk,text_size=textSize,tooltip=r.historySource+" history · best available samples per cohort; overlapping sources are not added. Each P box has its own first-side/outcome cohort; percentages use combined outcome counts. Before an edge breaks, each first side is assessed separately. OK = at least30; LOW = exploratory3–29 when previews enabled; WAIT = insufficient sample. Before a break only continuation boxes are drawn, for each possible first side. Missing data and ambiguous first breaks always withhold boxes.")
- row+=1
- string status=not supported?"USE STANDARD 30s–1H":na(lastEnd)?"WAIT NATIVE MINUTES":"NY "+str.format_time(lastEnd,"HH:mm",NY)+" · UK "+str.format_time(lastEnd,"HH:mm",LONDON)+(sharedHistory?(not na(shared)?" · shared 1m · "+str.tostring(shared.minutes)+" bars":" · shared waiting"):" · chart history")
- table.cell(panel,0,9,status,text_color=color.gray,bgcolor=rowsInk,text_size=size.tiny,tooltip=(not na(shared)?"Shared native-minute coverage: "+str.format_time(shared.first,"yyyy-MM-dd HH:mm",NY)+" to "+str.format_time(shared.last,"yyyy-MM-dd HH:mm",NY)+" NY; "+str.tostring(shared.minutes)+" actual minutes. History is limited by TradingView and the feed; a larger request cannot create unavailable bars. ":"")+"Conditional historical bands are not entries or targets. TradingView's symbol/feed/history may differ from Desk. No synthesized missing candles.")
Advertisement
Add Comment
Please, Sign In to add comment