本页源码来自 TradingView 公开发布的开源脚本,版权归原作者所有, 请遵循其原始许可(Pine 脚本常见 CC BY-NC-SA / MPL-2.0 / MIT)。 本项目仅用于研究检索与许可范围内的移植。
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Mxwll Mxwll Capital
//@version=5
indicator("Mxwll Sessions" , overlay = true , max_bars_back = 500, max_lines_count = 500, max_boxes_count = 500, max_labels_count = 500)
proj = input.string(defval = "Bars", title = "Show Projection", options = ["Bars", "Line", "None"])
profileType = input.string(defval = "Bars", options = ["Letters", "Bars", "None"], title = "Profile Type")
mult = input.int (defval = 1, title = "Profile Bar Multiplier", minval = 1)
use = input.bool (defval = true, title = "Use ATR in Projection")
removeBor = input.bool (defval = false, title = "Remove Box Border Color")
prep = input.bool (defval = true, title = "Show Pre-Market")
posp = input.bool (defval = true, title = "Show Post-Market")
poc = input.bool (defval = true, title = "Show Naked POCs")
showNY = input (true, title = '', inline = 'NY', group = 'New York')
NYcol = input.color (#6929F2, title = '', inline = 'NY', group = 'New York')
showLONDON = input (true, title = '', inline = 'LONDON', group = 'LONDON')
LONDONcol = input.color (#F24968, title = '', inline = 'LONDON', group = 'LONDON')
showAS = input (true, title = '', inline = 'ASIA', group = 'ASIA')
AScol = input.color (#39FF14, title = '', inline = 'ASIA', group = 'ASIA')
req() =>
cont = switch str.contains(syminfo.ticker, "T.P")
true => syminfo.ticker + "_OI"
=> str.endswith(syminfo.ticker, "USDT") ? syminfo.ticker + ".P_OI" : syminfo.ticker + "T.P_OI"
switch syminfo.type
"crypto" => cont
=> string(na)
oi = request.security(req(), timeframe.period, close - close[1]), var timeLevels = matrix.new<float>(2, 0)
method conditional_add(matrix <float> id) =>
if timeframe.multiplier >= 30
timeLevels.add_col(timeLevels.columns(), array.from(high, low))
else
max = 0., min = 1e8
if timeframe.change("30")
for i = 0 to math.floor(30 / timeframe.multiplier)
max := math.max(high[i], max)
min := math.min(low [i], min)
id.add_col(timeLevels.columns(), array.from(max, min))
timeLevels.conditional_add()
type objects
box sessionBox
label sessionLabel
box preSessionBox
label preSessionLabel
box postSessionBox
label postSessionLabel
var objNY = matrix.new<objects>(0, 6), var objLON = matrix.new<objects>(0, 6),
var objAS = matrix.new<objects>(0, 6)
method newObject(matrix <objects> id, titleTime, title, color col, bool condition)=>
if condition and last_bar_index - bar_index <= 7000
var timE = 0, var HIGH = high, var LOW = low, var vol = 0., var delta = 0., var oiD = 0.
if titleTime > titleTime[1]
timE := bar_index, HIGH := high, LOW := low, vol := volume, oiD := oi
calc = math.sign(close - open)
delta := switch calc
-1 => -volume
=> volume
id.add_row(id.rows(),
array.from(
objects.new(sessionBox = box.new(bar_index, HIGH, bar_index, LOW,
bgcolor = color.new(col, 90),
border_color = removeBor ? na : col
)),
objects.new(sessionLabel = label.new(timE, HIGH, title,
textcolor = col,
color = #ffffff00,
size = size.tiny)),
objects.new(preSessionBox = box (na)),
objects.new(preSessionLabel = label(na)),
objects.new(postSessionBox = box (na)),
objects.new(postSessionLabel= label(na))
))
if titleTime and titleTime == titleTime[1]
HIGH := math.max(high, HIGH), vol += volume, oiD += oi
LOW := math.min(low , LOW) , calc = math.sign(close - open)
switch calc
-1 => delta -= volume
=> delta += volume
if id.rows() > 0
if not na(id.get(id.rows() - 1, 0))
id.get(id.rows() - 1, 0).sessionBox.set_top(HIGH)
id.get(id.rows() - 1, 0).sessionBox.set_rightbottom(bar_index, LOW)
rang1 = id.get(id.rows() - 1, 0).sessionBox.get_top() - id.get(id.rows() - 1, 0) .sessionBox.get_bottom()
rang2 = (id.get(id.rows() - 1, 0).sessionBox.get_top() + id.get(id.rows() - 1, 0).sessionBox.get_bottom()) / 2
finrang = rang1 / rang2 * 100
if not na(id.get(id.rows() - 1, 1))
id.get(id.rows() - 1, 1).sessionLabel.set_xy(int(math.avg(timE, bar_index)), HIGH)
id.get(id.rows() - 1, 1).sessionLabel.set_text(title + "\nRange: " +
str.tostring(finrang, format.percent) + "\nVol: " +
str.tostring(vol , format.volume ) + "\n∆: " +
str.tostring(delta , format.volume ) + "\nOI: " +
str.tostring(oiD , format.mintick))
signTime(TIME) =>
int(math.sign(nz(time(timeframe.period, TIME, "America/New_York"))))
[preny, prel, pres] = switch
timeframe.multiplier <= 5 => ["0630-0931", "0005-0301", "1900-2001"]
timeframe.multiplier <= 30 => ["0630-0931", "0000-0301", "1900-2001"]
=> ["0600-1000", "0000-0301", "1900-2001"]
[nyT, lonT] = switch
timeframe.multiplier <= 30 => ['0930-1601', '0300-1131']
timeframe.multiplier => ['0900-1601', '0300-1101']
nytrue = signTime(nyT ), prenytrue = signTime(preny)
lontrue = signTime(lonT ), prelontrue = signTime(prel )
astrue = signTime('2000-0501' ), preaustrue = signTime(pres )
objNY .newObject(nytrue ,"New York" , NYcol, showNY), objLON.newObject(lontrue , "London", LONDONcol, showLONDON),
objAS .newObject(astrue ,"Asia", AScol, showAS)
method preSessionDraw(matrix <objects> id, int time1, int time2, int time3, color col, bool condition, bool activate) =>
if prep
if last_bar_index - bar_index <= 5000
and condition
and activate
if not na(id.get(id.rows() - 1, 0))
var preBar = 0
preBar := switch not time2[1] and time2
true => bar_index
=> preBar == 0 ? bar_index : preBar
if not time1[1] and time1
id.set(id.rows() - 1, 2,
objects.new(preSessionBox =
box.new(preBar, high, bar_index, low, border_style = line.style_dashed,
border_color = removeBor ? na : col,
bgcolor = color.new(col, 90)
)))
id.set(id.rows() - 1, 3,
objects.new(preSessionLabel =
label.new(bar_index, high, color = #00000000, text = "OPEN",
textcolor = color.white,
size = size.tiny,
style = label.style_label_down
)))
if id.rows() > 0 and time3 == 1
if not na(id.get(id.rows() - 1, 0))
id.get(id.rows() - 1, 2).preSessionBox .set_top (id.get(id.rows() - 1, 0).sessionBox.get_top())
id.get(id.rows() - 1, 2).preSessionBox .set_bottom(id.get(id.rows() - 1, 0).sessionBox.get_bottom())
id.get(id.rows() - 1, 3).preSessionLabel.set_y (id.get(id.rows() - 1, 0).sessionBox.get_top())
[nyP, lonP, nyP1, lonP1] = switch
timeframe.multiplier <= 30 => ['0930-0931', '0300-0301', "0931-1601", "0301-1130"]
timeframe.multiplier => ['0900-0901', '0300-0301', "0901-1601", "0301-1100"]
objNY .preSessionDraw(signTime(nyP), signTime(preny), signTime(nyP1), NYcol, showNY, true)
objLON.preSessionDraw(signTime(lonP), signTime(prel ), signTime(lonP1), LONDONcol, showLONDON, true)
objAS .preSessionDraw(signTime("2000-2001"), signTime(pres ), signTime("2001-0501"), AScol, showAS, false)
var string [] strx = array.from(
" A",
" B",
" C",
" D",
" E",
" F",
" G",
" H",
" I",
" J",
" K",
" L",
" M",
" N",
" O",
" P",
" Q",
" R",
" S",
" T",
" U",
" V",
" W",
" X",
" Y",
" Z",
" a",
" b",
" c",
" d",
" e",
" f",
" g",
" h",
" i",
" j",
" k",
" l",
" m",
" n",
" o",
" p",
" q",
" r",
" s",
" t",
" u",
" v",
" w",
" x",
" y",
" z"
)
if barstate.isfirst and profileType == "Letters"
sX = ""
for i = 0 to 1275
index = i % 52
sX := strx.get(index)
strx.push(sX)
var POCLINES = array.new_line(), earliest = array.new_int(), calcTime = 600 / timeframe.multiplier + 5
method postSessionDraw(matrix <objects> id, int time1, int time2, color col, bool condition, bool activate) =>
level = array.new_float(), lab = array.new_string(), bsize = array.new_int()
if last_bar_index - bar_index <= 5000
and condition
if not na(id.get(id.rows() - 1, 0))
if not time1[1] and time1
if profileType != "None"
calc = (id.get(id.rows() - 1, 0).sessionBox.get_top() - id.get(id.rows() - 1, 0).sessionBox.get_bottom()) / 20
index = 0,
for i = 0 to 20
level.push(id.get(id.rows() - 1, 0).sessionBox.get_bottom() + (calc * i))
switch profileType
"Letters" => lab.push("") , bsize.push(0)
"Bars" => bsize.push(0), index := 1
increment = switch
timeframe.multiplier >= 30 => 1
=> 30 / timeframe.multiplier
for i = math.ceil(id.get(id.rows() - 1, 0).sessionBox.get_left() / increment) to timeLevels.columns() - 1
highest = level.binary_search_leftmost (timeLevels.row(0).get(i))
lowest = level.binary_search_rightmost(timeLevels.row(1).get(i))
for x = lowest to highest
switch profileType
"Letters" => lab .set(x, lab.get(x) + strx.get(i - math.ceil(id.get(id.rows() - 1, 0).sessionBox.get_left() / increment)))
"Bars" => bsize.set(x, bsize.get(x) + 1)
nearest = 1000.
if profileType == "Letters"
for i = 0 to 20
split = str.split(lab.get(i), " ")
bsize.set(i, split.size())
if bsize.indexof(bsize.max()) != bsize.lastindexof(bsize.max())
mid = math.round(bsize.size() / 2)
for i = 0 to 20
if math.abs(mid - bsize.get(i)) < nearest and bsize.get(i) == bsize.max()
nearest := i
for i = index to 20
colorCond = switch
nearest == 1000 => bsize.get(i) == bsize.max()
=> i == nearest
COL = switch
colorCond => #6929F2
bsize.get(i) == 1 => #F24968
=> profileType == "Bars" ? col : color.white
if colorCond and poc
mid = switch profileType
"Letters" => level.get(i)
=> math.avg(level.get(i), level.get(i - 1))
POCLINES.push(line.new(id.get(id.rows() - 1, 0).sessionBox.get_left(), mid,
bar_index, mid,
color = color.new(color.red, 60),
width = 2
))
switch profileType
"Letters" =>
label.new(id.get(id.rows() - 1, 0).sessionBox.get_left(), level.get(i), lab.get(i),
style = label.style_label_left,
textcolor = COL,
text_font_family = font.family_monospace,
size = size.tiny,
color = #00000000)
"Bars" =>
box.new(
id.get(id.rows() - 1, 0).sessionBox.get_left(),
level.get(i),
id.get(id.rows() - 1, 0).sessionBox.get_left() + (bsize.get(i) * mult),
level.get(i - 1),
bgcolor = color.new(COL, 80),
border_color = removeBor ? na : color.new(COL, 80)
)
if activate and posp
id.set(id.rows() - 1, 4,
objects.new(
postSessionBox = box.new(bar_index, high, bar_index, low,
border_style = line.style_dashed,
border_color = removeBor ? na : col,
bgcolor = color.new(col, 90)
)))
id.set(id.rows() - 1, 5,
objects.new(postSessionLabel = label.new(bar_index, high, color = #00000000,
text = "CLOSE",
textcolor = color.white,
size = size.tiny,
style = label.style_label_down
)))
if activate
if time2 and id.rows() > 0
if not na(id.get(id.rows() - 1, 0)) and not na(id.get(id.rows() - 1, 2))
max = math.max(high, id.get(id.rows() - 1, 0).sessionBox.get_top ())
min = math.min(low, id.get(id.rows() - 1, 0).sessionBox.get_bottom())
id.get(id.rows() - 1, 5).postSessionLabel.set_y (max), id.get(id.rows() - 1, 4).postSessionBox .set_top (max)
id.get(id.rows() - 1, 4).postSessionBox .set_right (bar_index), id.get(id.rows() - 1, 4).postSessionBox .set_bottom(min)
id.get(id.rows() - 1, 2).preSessionBox .set_top (max), id.get(id.rows() - 1, 2).preSessionBox .set_bottom(min)
id.get(id.rows() - 1, 0).sessionBox .set_bottom(min), id.get(id.rows() - 1, 0).sessionBox .set_top (max)
id.get(id.rows() - 1, 1).sessionLabel .set_y (max), id.get(id.rows() - 1, 3).preSessionLabel .set_y (max)
lonAf = switch
timeframe.multiplier <= 30 => "1130-1131"
=> "1100-1101"
[aftny, aftl, afts] = switch
timeframe.multiplier <= 15 => ["1600-2001", "1130-1245", "0200-0500"]
timeframe.multiplier <= 30 => ["1600-2001", "1130-1300", "0200-0500"]
=> ["1600-2001", "1100-1300", "0200-0500"]
objNY .postSessionDraw(signTime("1600-1601"), signTime(aftny), NYcol, showNY , true)
objLON.postSessionDraw(signTime(lonAf), signTime(aftl ), LONDONcol, showLONDON, true)
objAS .postSessionDraw(signTime("0500-0501"), signTime(afts ), AScol, showAS ,false),
var cloMat = matrix.new<float>(0, calcTime), var hiMat = matrix.new<float>(0, calcTime), var loMat = matrix.new<float>(0, calcTime)
var cloMatl = matrix.new<float>(0, calcTime), var hiMatl = matrix.new<float>(0, calcTime), var loMatl = matrix.new<float>(0, calcTime)
var cloMata = matrix.new<float>(0, calcTime), var hiMata = matrix.new<float>(0, calcTime), var loMata = matrix.new<float>(0, calcTime)
method collectData(matrix<float> id, TIME, matrix<float> id2, matrix<float> id3, color col, bool condition) =>
if proj != "None"
var int columnPlace = -1, var maxPlace = 0 , atr = ta.atr(14)
cond1 = signTime(TIME), cond2 = cond1[1], var index = 0
var project = array.new_line(), var projectBox = array.new_box(),
var hlMat = matrix.new<line>(2, 0)
if cond1 == 1
columnPlace += 1
maxPlace := math.max(columnPlace, maxPlace)
if cond2 == 0
id.add_row(id.rows()), id2.add_row(id2.rows()), id3.add_row(id3.rows()), index := bar_index
id.set (id.rows() - 1, columnPlace, ((close - close[1]) / close[1]))
id2.set(id2.rows() - 1, columnPlace, (high - math.max(open, close)) / math.max(open, close))
id3.set(id3.rows() - 1, columnPlace, (low - math.min(open, close)) / math.min(open, close))
if cond1 != 1
columnPlace := 0
if project.size() > 0
for i = 0 to project.size() - 1
project.shift().delete()
if projectBox.size() > 0
for i = 0 to projectBox.size() - 1
projectBox.shift().delete()
if hlMat.columns() > 0
for i = 0 to hlMat.columns() - 1
hlMat.get(0, i).delete()
hlMat.get(1, i).delete()
hlMat .remove_col()
if barstate.islast
if not condition or condition and signTime("0300-0501") != 1
finClo = id .submatrix(0, id.rows (), 0, maxPlace + 1)
finHi = id2.submatrix(0, id2.rows(), 0, maxPlace + 1)
finLo = id3.submatrix(0, id3.rows(), 0, maxPlace + 1)
if cond1 == 1
start = bar_index - index
if proj == "Line"
if project.size() > 0
for i = 0 to project.size() - 1
project.shift().delete()
project.push(line.new(last_bar_index, close, last_bar_index + 1, close[1] * (1 + finClo.col(start).median()), style = line.style_dotted, color = col))
for i = start + 1 to finClo.columns() - 1
x = project.last().get_x2()
y = project.last().get_y2()
project.push(line.new(x, y, x + 1, y * (1 + finClo.col(i).median()), style = line.style_dotted, color = col))
if proj == "Bars"
if projectBox.size() > 0
for i = 0 to projectBox.size() - 1
projectBox.shift().delete()
if hlMat.columns() > 0
for i = 0 to hlMat.columns() - 1
hlMat.get(0, i).delete()
hlMat.get(1, i).delete()
for i = 0 to hlMat.columns() - 1
hlMat.remove_col()
projectBox.push(box.new(last_bar_index, close[1], last_bar_index + 2, close[1] * (1 + finClo.col(start).median()),
bgcolor = color.new(col, 80),
border_color = col
))
if use
switch math.sign(projectBox.last().get_bottom() - projectBox.last().get_top())
1 => projectBox.last().set_bottom(projectBox.last().get_bottom() + atr)
-1 => projectBox.last().set_bottom(projectBox.last().get_bottom() - atr)
hlMat.add_col(hlMat.columns(),
array.from(
line.new(
last_bar_index + 1,
math.max(projectBox.last().get_top(), projectBox.last().get_bottom()),
last_bar_index + 1,
math.max(projectBox.last().get_top(), projectBox.last().get_bottom()) * (1 + finHi.col(start).median()),
color = col
),
line.new(
last_bar_index + 1,
math.min(projectBox.last().get_top(), projectBox.last().get_bottom()),
last_bar_index + 1,
math.min(projectBox.last().get_top(), projectBox.last().get_bottom()) * (1 + finLo.col(start).median()),
color = col
)))
if start + 1 < finClo.columns() - 2
for i = start + 1 to math.min(start + 26, finClo.columns() - 1)
x = projectBox.last().get_right ()
y = projectBox.last().get_bottom()
projectBox.push(box.new(x, y, x + 2, y * (1 + finClo.col(i).median()), bgcolor = color.new(col, 80), border_color = col))
switch math.sign(projectBox.last().get_bottom() - projectBox.last().get_top())
1 => projectBox.last().set_bottom(projectBox.last().get_bottom() + atr)
-1 => projectBox.last().set_bottom(projectBox.last().get_bottom() - atr)
hlMat.add_col(hlMat.columns(),
array.from(
line.new(
x + 1,
math.max(projectBox.last().get_top(), projectBox.last().get_bottom()),
x + 1,
math.max(projectBox.last().get_top(), projectBox.last().get_bottom()) * (1 + finHi.col(i).median()),
color = col
),
line.new(
x + 1,
math.min(projectBox.last().get_top(), projectBox.last().get_bottom()),
x + 1,
math.min(projectBox.last().get_top(), projectBox.last().get_bottom()) * (1 + finLo.col(i).median()),
color = col
)))
cloMat .collectData(nyP1, hiMat, loMat, NYcol, false), cloMatl.collectData(lonP1, hiMatl, loMatl, LONDONcol, false),
cloMata.collectData("2001-0501", hiMata, loMata, AScol, true)
method lineDelete (array <line> id) =>
if id.size() > 0
for i = 0 to id.size() - 1
if id.get(i).get_y1() == id.get(i).get_y2()
if high >= id.get(i).get_y1() and low <= id.get(i).get_y1()
id.get(i).set_y2(id.get(i).get_y2() + syminfo.mintick)
if id.get(i).get_y1() == id.get(i).get_y2()
id.get(i).set_x2(bar_index)
method leftCheck(matrix <objects> id) =>
if id.rows() > 0
for i = 0 to id.rows() - 1
if not na(id.get(i, 2))
earliest.push(id.get(i, 2).preSessionBox.get_left())
POCLINES.lineDelete()
if barstate.islast
objNY .leftCheck(), objLON.leftCheck(),
objAS .leftCheck()
lin = line.all, bo = box.all, lab = label.all
if lin.size() > 0
for i = 0 to lin.size() - 1
if lin.get(i).get_x1() < earliest.min()
lin.get(i).delete()
if bo.size() > 0
for i = 0 to bo.size() - 1
if bo.get(i).get_left() < earliest.min()
bo.get(i).delete()
if lab.size() > 0
for i = 0 to lab.size() - 1
if lab.get(i).get_x() < earliest.min()
lab.get(i).delete()