//@version=5 // PipAtlas - Session Range (MIT License) - education only, test on demo. // Draws Asia / London / New York session high-low boxes, with optional // 1:RR projection lines when a closed box breaks (risk = box height). indicator("PipAtlas - Session Range", overlay=true, max_boxes_count=90, max_lines_count=200) asiaClr = input.color(color.new(color.gray, 80), "Asia") londonClr = input.color(color.new(color.teal, 80), "London") nyClr = input.color(color.new(color.orange,80), "New York") showAsia = input.bool(true, "Show Asia") showLon = input.bool(true, "Show London") showNY = input.bool(true, "Show New York") showRR = input.bool(true, "Project 1:RR on box break") useHTF = input.bool(false, "Require 4H trend confluence (EMA50)") rrMult = input.float(2.0, "RR multiple", minval=0.5, step=0.5) tz = "UTC" inWin(h, a, b) => a <= b ? (h >= a and h < b) : (h >= a or h < b) hUTC = hour(time, tz) dOW = dayofweek(time, tz) weekend = (dOW == dayofweek.saturday) or (dOW == dayofweek.sunday and hUTC < 22) or (dOW == dayofweek.friday and hUTC >= 22) active = not weekend // ---- session boxes: each window draws one high-low box per session ---- f_box(cond, clr) => var float hi = na var float lo = na var int st = na if cond and not cond[1] hi := high lo := low st := time if cond hi := math.max(hi, high) lo := math.min(lo, low) if not cond and cond[1] and not na(st) box.new(st, hi, time, lo, bgcolor=clr, border_color=color.new(clr, 40)) hi := na lo := na st := na f_box(showAsia and active and inWin(hUTC, 0, 9), asiaClr) f_box(showLon and active and inWin(hUTC, 8, 17), londonClr) f_box(showNY and active and inWin(hUTC, 13, 21), nyClr) // ---- RR projection: track the latest session range; project on first break after close ---- anySess = (showAsia and active and inWin(hUTC, 0, 9)) or (showLon and active and inWin(hUTC, 8, 17)) or (showNY and active and inWin(hUTC, 13, 21)) var float sHi = na var float sLo = na var bool sDone = false if anySess and not anySess[1] sHi := high sLo := low sDone := false if anySess sHi := math.max(sHi, high) sLo := math.min(sLo, low) if not anySess and anySess[1] sDone := true htfEma = request.security(syminfo.tickerid, "240", ta.ema(close, 50), lookahead=barmerge.lookahead_off) longConf = not useHTF or close > htfEma shortConf = not useHTF or close < htfEma riskH = sHi - sLo longBrk = showRR and sDone and not na(sHi) and ta.crossover(close, sHi) and longConf shortBrk = showRR and sDone and not na(sHi) and ta.crossunder(close, sLo) and shortConf if longBrk line.new(bar_index, sHi, bar_index + 20, sHi + riskH * rrMult, color=color.new(color.teal, 0), width=2) // target line.new(bar_index, sHi, bar_index + 20, sHi - riskH, color=color.new(color.red, 30)) // stop (box low) sDone := false if shortBrk line.new(bar_index, sLo, bar_index + 20, sLo - riskH * rrMult, color=color.new(color.red, 0), width=2) // target line.new(bar_index, sLo, bar_index + 20, sLo + riskH, color=color.new(color.teal, 30)) // stop (box high) sDone := false alertcondition(longBrk, "Session box broke UP", "PipAtlas: latest session range broken upward - 1:RR projection drawn") alertcondition(shortBrk, "Session box broke DOWN", "PipAtlas: latest session range broken downward - 1:RR projection drawn")