True Close – Institutional Trading Sessions (Zeiierman)

Zeiierman · study · 332 行 · 点赞 3,652 · TradingView 原页

本页源码来自 TradingView 公开发布的开源脚本,版权归原作者所有, 请遵循其原始许可(Pine 脚本常见 CC BY-NC-SA / MPL-2.0 / MIT)。 本项目仅用于研究检索与许可范围内的移植。

Pine Script

// This work is licensed under a Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) https://creativecommons.org/licenses/by-nc-sa/4.0/
 
// © Zeiierman {
//@version=6
indicator('True Close – Institutional Trading Sessions (Zeiierman)', overlay = true, max_boxes_count = 1000, max_lines_count = 500)
//~~}
 
// ~~ Tooltips {
var string t1   = "Defines the current time zone you want the session schedule to follow (e.g. UTC+2 for Central European Summer Time)."
var string t2   = "Toggle visibility of each session (Sydney, Tokyo, London, New York)."
var string t3   = "Defines the session time interval (e.g. 0900-1700). Must match the format 'HHMM-HHMM'."
var string t4   = "Background fill color for each session. Only applies when 'Show Session Background' is enabled."
var string t5   = "Border color for the first-hour true close line that appears after the first session hour completes."
var string t6   = "Color used to fill the first-hour box in each session."
var string t7   = "If checked, the background for each session box is drawn."
var string t8   = "Draws a dashed border around each session box if enabled."
var string t9   = "Draws a background highlight for the first hour of each session."
var string t10  = "Draws a border around the first-hour box when enabled."
var string t11  = "When enabled, plots a horizontal line at the true close of the first hour of the session."
var string t12  = "Adds a label at the end of each session showing the price where the true close line was formed."
var string t13  = "Shows a label under each session at its opening bar stating the execution hour."
var string t14  = "Controls the thickness of the outer border for the full session box."
var string t15  = "Controls the border width of the first-hour range box."
var string t16  = "Sets the width of the true close line plotted after the first hour."
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
 
// ~~ Inputs {
utc  = input.string('UTC+2', 'UTC', tooltip=t1)
show = array.from(
 input.bool(true, 'Sydney', group = 'Sydney', inline = 'sy', tooltip=t2), 
 input.bool(true, 'Tokyo', group = 'Tokyo', inline = 'to', tooltip=t2), 
 input.bool(true, 'London', group = 'London', inline = 'lo', tooltip=t2), 
 input.bool(true, 'New York', group = 'New York', inline = 'ny', tooltip=t2))
 
times = array.from(
 input.session('0100-0900', '', group = 'Sydney', inline = 'sy', tooltip=t3), 
 input.session('0000-0600', '', group = 'Tokyo', inline = 'to', tooltip=t3),
 input.session('0900-1730', '', group = 'London', inline = 'lo', tooltip=t3), 
 input.session('1530-2200', '', group = 'New York', inline = 'ny', tooltip=t3))
 
colors = array.from(
 input.color(color.red, '', group = 'Sydney', inline = 'sy', tooltip=t4), 
 input.color(color.yellow, '', group = 'Tokyo', inline = 'to', tooltip=t4), 
 input.color(#06e3ff, '', group = 'London', inline = 'lo', tooltip=t4), 
 input.color(color.lime, '', group = 'New York', inline = 'ny', tooltip=t4))
 
lineColors = array.from(
 input.color(color.new(color.red, 0), '', group = 'Sydney', inline = 'sy', tooltip=t5), 
 input.color(color.new(color.yellow, 0), '', group = 'Tokyo', inline = 'to', tooltip=t5), 
 input.color(color.new(#06e3ff, 0), '', group = 'London', inline = 'lo', tooltip=t5), 
 input.color(color.new(color.lime, 0), '', group = 'New York', inline = 'ny', tooltip=t5))
 
firstHourColors = array.from(
 input.color(color.new(color.white, 0), '', group = 'Sydney', inline = 'sy', tooltip=t6), 
 input.color(color.new(color.white, 0), '', group = 'Tokyo', inline = 'to', tooltip=t6), 
 input.color(color.new(color.white, 0), '', group = 'London', inline = 'lo', tooltip=t6), 
 input.color(color.new(color.white, 0), '', group = 'New York', inline = 'ny', tooltip=t6)) 
 
showSessionBg    = input.bool(false, 'Show Session Background', group = 'Display Options', tooltip=t7)
showSessionBrdr  = input.bool(true, 'Show Session Border', group = 'Display Options', tooltip=t8)
showFirstHourBg  = input.bool(true, 'Show First Hour Background', group = 'Display Options', tooltip=t9)
showFirstHourBrd = input.bool(true, 'Show First Hour Border', group = 'Display Options', tooltip=t10)
showLine         = input.bool(true, 'Show True Close Line', group = 'Display Options', tooltip=t11)
showTrueClose    = input.bool(true, 'Show True Close label', group = 'Display Options', tooltip=t12)
showExHour       = input.bool(true, 'Show Execution Hour label', group = 'Display Options', tooltip=t13)
sessionBorderWidth   = input.int(1, 'Session Border Width', minval = 0, maxval = 5, group = 'Display Options', tooltip=t14)
firstHourBorderWidth = input.int(2, 'First Hour Border Width', minval = 0, maxval = 5, group = 'Display Options', tooltip=t15)
lineWidth            = input.int(2, 'Line Width', minval = 1, maxval = 10, group = 'Display Options', tooltip=t16)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
 
// ~~ type {
type Sessions
    array<box>   bo
    array<box>   fbo
    array<line>  flo
    array<label> flabel
    array<label> endLabel
    string  str
    int     leftBar
    float   st
    float   o
    float   h
    float   l
    float   c
    int     lineStartBar
    float   linePrice
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
 
// ~~ session instances {
var a1 = Sessions.new(array.new<box>(), array.new<box>(), array.new<line>(), array.new<label>(), array.new<label>(), 'Sydney', na, 0.0, 0.0, 0.0, 0.0, na, na)
var a2 = Sessions.new(array.new<box>(), array.new<box>(), array.new<line>(), array.new<label>(), array.new<label>(), 'Tokyo', na, 0.0, 0.0, 0.0, 0.0, na, na)
var a3 = Sessions.new(array.new<box>(), array.new<box>(), array.new<line>(), array.new<label>(), array.new<label>(), 'London', na, 0.0, 0.0, 0.0, 0.0, na, na)
var a4 = Sessions.new(array.new<box>(), array.new<box>(), array.new<line>(), array.new<label>(), array.new<label>(), 'New York', na, 0.0, 0.0, 0.0, 0.0, na, na)
sessionNames = array.from('Sydney', 'Tokyo', 'London', 'New York')
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
 
// ~~ constants {
const int ONE_HOUR_MS = 60 * 60 * 1000
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
// ~~ helpers {
formatSession(rangeStr) =>
    start = str.substring(rangeStr, 0, 4)
    stop  = str.substring(rangeStr, 5, 9)
    str.format("{0}:{1}-{2}:{3}",
     str.substring(start, 0, 2), str.substring(start, 2, 4),
     str.substring(stop, 0, 2),  str.substring(stop, 2, 4))
 
inSession(sessStr) =>
    not na(time(timeframe.period, sessStr, utc))
 
inFirstHour(sessStart) =>
    bar_index - sessStart < math.round(60/timeframe.multiplier)
 
belowBox(_high, _low, percent) => _low - (_high - _low) * percent
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
 
// ~~ session logic {
method RunSessions(Sessions x, int i, bool session) =>
    if show.get(i)
        if session and not session[1]
            x.leftBar := bar_index
            x.st := time
            x.o := open
            x.h := high
            x.l := low
            x.c := close
 
            if array.size(x.flo) > 0
                line.delete(x.flo.get(0))
                x.flo.clear()
 
            fullBox = box.new(bar_index, high, bar_index, low, 
             border_color = showSessionBrdr ? colors.get(i) : color.new(color.black, 100), 
             border_style= line.style_dashed, 
             bgcolor = showSessionBg ? color.new(colors.get(i), 80) : color.new(color.black, 100), 
             border_width = sessionBorderWidth, 
             extend = extend.none)
 
            if array.size(x.bo) > 0
                box.delete(x.bo.get(0))
                x.bo.set(0, fullBox)
            else
                x.bo.unshift(fullBox)
 
            hourBox = box.new(bar_index, high, bar_index, low, 
             border_color = showFirstHourBrd ? color.new(firstHourColors.get(i), 0) : color.new(color.black, 100), 
             bgcolor = showFirstHourBg ? color.new(firstHourColors.get(i), 80) : color.new(color.black, 100), 
             border_width = firstHourBorderWidth, 
             extend = extend.none)
 
            if array.size(x.fbo) > 0
                box.delete(x.fbo.get(0))
                x.fbo.set(0, hourBox)
            else
                x.fbo.unshift(hourBox)
 
            midXx  = x.leftBar
            labelY = belowBox(x.h, x.l, 0.03)  
            infoText = array.get(sessionNames, i) + '\nExecution Hour'
 
            lbl = label.new(midXx, labelY,
                         text   = infoText,
                         style  = label.style_label_lower_left,
                         textcolor = showExHour ? chart.fg_color : na,
                         color  = na,
                         size   = size.small,
                         textalign = text.align_left,
                         tooltip = "Institutional view: True Close ≠ Official Close.\nMost funds treat the first hour of the next day as the real close — where final flows, rebalancing, and execution dust settles."
                         )
 
            if array.size(x.flabel) > 0
                label.delete(x.flabel.get(0))
                x.flabel.clear()
            x.flabel.unshift(lbl)
 
        if session
            x.h := math.max(high, x.h)
            x.l := math.min(low, x.l)
            x.c := close
 
            fb = x.bo.get(0)
            box.set_rightbottom(fb, bar_index, x.l)
            box.set_top(fb, x.h)
 
            if not na(x.st) and time - x.st < ONE_HOUR_MS
                fh = x.fbo.get(0)
                box.set_rightbottom(fh, bar_index, x.l)
                box.set_top(fh, x.h)
 
            if array.size(x.flabel) > 0
                newY = belowBox(x.h, x.l, 0.03)
                label.set_y(x.flabel.get(0), newY)
 
            if not na(x.st) and time - x.st >= ONE_HOUR_MS and array.size(x.flo) == 0 and showLine
                x.lineStartBar := bar_index
                x.linePrice := close
                l = line.new(
                 x1 = x.lineStartBar, y1 = x.linePrice,
                 x2 = bar_index,      y2 = x.linePrice,
                 xloc = xloc.bar_index,
                 extend = extend.none,
                 color = lineColors.get(i),
                 width = lineWidth,
                 style = line.style_solid)
                x.flo.unshift(l)
 
                if array.size(x.endLabel) > 0
                    label.delete(x.endLabel.get(0))
                    x.endLabel.clear()
 
                txt = str.format("{0} – {1}", array.get(sessionNames, i), str.tostring(x.linePrice))
                lb = label.new(
                 x = bar_index + 10,
                 y = x.linePrice,
                 text = txt,
                 xloc = xloc.bar_index,
                 style = label.style_label_left,
                 color = color.new(color.black, 100),
                 textcolor = showTrueClose?chart.fg_color:na,
                 size = size.small,
                 tooltip = "Institutions often treat this level — the close of the first hour — as the true close of the prior day.")
                x.endLabel.unshift(lb)
 
        if array.size(x.flo) > 0
            line.set_xy2(x.flo.get(0), bar_index + 10, x.linePrice)
            if array.size(x.endLabel) > 0
                label.set_x(x.endLabel.get(0), bar_index + 10)
                label.set_y(x.endLabel.get(0), x.linePrice)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
 
// ~~ session flags {
syd = not na(time(timeframe.period, times.get(0), utc))
tok = not na(time(timeframe.period, times.get(1), utc))
lon = not na(time(timeframe.period, times.get(2), utc))
nyc = not na(time(timeframe.period, times.get(3), utc))
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
 
// ~~ run sessions {
a1.RunSessions(0, syd)
a2.RunSessions(1, tok)
a3.RunSessions(2, lon)
a4.RunSessions(3, nyc)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
 
// ~~ dashboard table {
if barstate.islast
    var table dash = table.new(position.top_right, 6, 6,
     bgcolor = color.new(chart.bg_color, 0),
     border_color = chart.fg_color,
     frame_color = color.new(chart.fg_color, 0),
     frame_width = 2,
     border_width = 2)
 
    table.cell(dash, 0, 0, "Session",
               text_color = chart.fg_color,
               text_halign = text.align_left,
               tooltip = "Regional trading block (Sydney, Tokyo, London, NY). Each desk\nhas unique flow & news sensitivity.")
    table.cell(dash, 1, 0, "Time",
               text_color = chart.fg_color,
               tooltip = "Official exchange session in the UTC offset you set above.")
    table.cell(dash, 2, 0, "In Sess",
               text_color = chart.fg_color,
               tooltip = "Is the session **live right now**? Green •Yes means that desk\nis currently executing flow; red •— means it is closed.")
    table.cell(dash, 3, 0, "1st Hr",
               text_color = chart.fg_color,
               tooltip = "Are we inside the *first* 60 min of the session?\nInstitutions finish yesterday’s business here ➜ ‘true close’.")
    table.cell(dash, 4, 0, "True Close",
               text_color = chart.fg_color,
               tooltip = "First-hour closing price. Risk desks treat this as the real daily\nreference after all spill-over orders are cleared.")
 
    sessArr    = array.from(a1, a2, a3, a4)
    rangeArr   = times
    nameArr    = sessionNames
    visibleRow = 1
 
    for idx = 0 to 3
        if show.get(idx)                           
            s   = sessArr.get(idx)
            rng = rangeArr.get(idx)
            nm  = nameArr.get(idx)
            clr = colors.get(idx)
 
            sessNow = inSession(rng)
            hrNow   = sessNow and inFirstHour(s.leftBar)
 
            txtSess = sessNow ? "Yes" : "—"
            txtHr   = hrNow   ? "Yes" : "—"
            txtLvl  = showLine and not na(s.linePrice) ? str.tostring(s.linePrice) : "—"
 
            // Session name cell ➜ tooltip explains region-specific colour
            table.cell(dash, 0, visibleRow, nm,
                     text_color = chart.fg_color,
                     bgcolor    = color.new(clr, 90),
                     text_halign = text.align_left,
                     tooltip = str.format(
                         "{0} session. Coloured box & line use this hue\nso you can visually link dashboard ⇒ chart.", nm))
 
            // Time range cell ➜ show formatted range
            table.cell(dash, 1, visibleRow, formatSession(rng),
                      text_color = chart.fg_color,
                      bgcolor    = color.new(clr, 90),
                      tooltip = str.format(
                         "{0} official window (exchange clock).\nFlows tend to concentrate at open/close.", nm))
 
            // “In Sess” cell with live indicator
            table.cell(dash, 2, visibleRow, txtSess,
                     text_color = sessNow ? color.lime : color.red,
                     bgcolor    = color.new(clr, 95),
                     tooltip = sessNow
                         ? "Desk currently active → expect authentic\ninstitutional flow & liquidity."
                         : "Desk closed → any prints now are typically\npassive or cross-session arbitrage.")
 
            // “1st Hr” cell
            table.cell(dash, 3, visibleRow, txtHr,
                     text_color = hrNow ? color.lime : color.red,
                     bgcolor    = color.new(clr, 95),
                     tooltip = hrNow
                         ? "We are **inside** the first hour → ‘true close’ being\nfinalised (VWAP/TWAP spillovers, compliance lags)."
                         : "Outside first hour. Market has largely processed\nyesterday’s unfinished flows.")
 
            // True-close price cell
            table.cell(dash, 4, visibleRow, txtLvl,
                         text_color = chart.fg_color,
                         bgcolor    = color.new(clr, 90),
                         tooltip = na(txtLvl)
                         ? "True-close price appears once the first-hour bar\nhas completed."
                           : str.format(
                             "{0} ‘true close’ = {1}\nInstitutions anchor risk & overnight P/L to this level.",
                               nm, txtLvl))
 
            visibleRow += 1
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}

← 返回列表