J3 TV
J3 TV
2.0 at https://mozilla.org/MPL/2.0/
// ©Kioshi
// @version=5
indicator(title="Kioshi's Algorithm Toolkit", shorttitle="Kioshi's Algorithm
Toolkit", overlay=true, max_lines_count=500, max_boxes_count=500)
//{ Constants
var CBDR_SESSION = "1600-2000"
var FLOUT_SESSION = "1600-2430"
var ASIA_SESSION = "1800-0030"
var TRUEDAY_SESSION = "0000-0100"
var SUNDAY_SESSION = "1700-1701:1"
var DAILY_OPEN_SESSION = "1700-1704"
var GMT_OPEN_SESSION = "1900-1901"
var FOUR_OPEN_SESSION = "0400-0401"
var LONDON_OPEN_KILLZONE_SESSION = "0200-0500"
var NY_OPEN_KILLZONE_SESSION = "0700-0900"
var LONDON_CLOSE_KILLZONE_SESSION = "1030-1200"
var ASIAN_OPEN_KILLZONE_SESSION = "2000-2200"
var NY_LUNCH_SESSION = "1200-1300"
var CBDR_LABEL_NAME = "CBDR"
var FLOUT_LABEL_NAME = "Flout"
var ASIA_LABEL_NAME = "AR"
//}
//{ HTF Levels
pdhColorInput = input.color(color.new(#663cff, 5), "", "Note:
This is the previous true day high, not the actual chart's previous daily high",
group="HTF Levels", inline="pdh")
pdhToggleInput = input.bool(false,"PDH ", group="HTF Levels",
inline="pdh")
pdhHistoryToggleInput = input.bool(false, "History", group="HTF Levels",
inline="pdh")
pdhLabelToggleInput = input.bool(true, "Name", group="HTF Levels",
inline="pdh")
pdhWidthInput = input.int(2, "", 1, 3, group="HTF Levels",
inline="pdh2")
pdhLineStyleInput = input.string("Solid", "", options=['Solid',
'Dotted', 'Dashed'],group="HTF Levels", inline="pdh2")
var TT_PDL = "Note: This is the previous true day low, not the
actual chart's previous daily low"
pdlColorInput = input.color(color.new(#663cff, 5), "", TT_PDL,
group="HTF Levels", inline="pdl")
pdlToggleInput = input.bool(false,"PDL ", group="HTF Levels",
inline="pdl")
pdlHistoryToggleInput = input.bool(false, "History", group="HTF Levels",
inline="pdl")
pdlLabelToggleInput = input.bool(true, "Name", group="HTF Levels",
inline="pdl")
pdlWidthInput = input.int(2, "", 1, 3, group="HTF Levels",
inline="pdl2")
pdlLineStyleInput = input.string("Solid", "", options=['Solid',
'Dotted', 'Dashed'],group="HTF Levels", inline="pdl2")
//}
//{ Weekday input
weekdaysColorInput = input.color(color.gray, "", group="weekdays",
inline="weekdays")
weekdaysLocationInput = input.string("Bottom", "", ["Top", "Bottom"],
group="weekdays", inline="weekdays")
weekdaysToggleInput = input.bool(true, "Weekdays", group="weekdays",
inline="weekdays")
weekdaysShortFormatToggleInput = input.bool(false, "Short format",
group="weekdays", inline="weekdays")
weekdayOffsetInput = input.int(0, "Horizontal position offset",
tooltip=TT_WEEKDAY_OFFSET_INPUT)
//END Weekday input}
//{ Session Times input
cbdrSessionInput = input.session(CBDR_SESSION, "CBDR",
group="Session Times Customization")
floutSessionInput = input.session(FLOUT_SESSION, "Flout",
group="Session Times Customization")
asiaSessionInput = input.session(ASIA_SESSION, "Asian Range",
group="Session Times Customization")
stdvNumLinesInput = input.int(8, "Standard Deviations", 1, 10,
group="Session Times Customization")
//}
//END Inputs}
//{ Functions
hours(int h, int m=0) =>
//@function Returns UNIX time a certain number hours from now.
//@param h (int) number of hours
//@param m (int) (optional) number of minutes
time+(3600000*h)+(60000*m)
stringToHour(s) =>
//@function Converts session input strings to integers for using with the
hours() function
//@param s session string
//@return (int) hours part of the session string input parameter
math.round(str.tonumber(str.substring(s, 0, 2)))
stringToMinutes(s) =>
//@function Converts session input strings to integers for using with the
hours() function
//@param s session string
//@return (int) minutes part of the session string input parameter
math.round(str.tonumber(str.substring(s, 2, 4)))
averageRange(h, l, n) =>
//@function Calculate the average range in pips of a number of bars
//@param h = high, l = low, n = number of bars
r = 0.0
for i = 1 to n
r += h[i]-l[i]
PIP*r/n
delLines(a) =>
//@function Delete all lines in a line array
//@param a = line array
if array.size(a) > 0
for i=0 to array.size(a)-1
line.delete(array.get(a, i))
lineset_y(l, y) =>
//@function Makes a line horizontal at a location
//@param l = line id, y = y coordinate
line.set_y1(l, y)
line.set_y2(l, y)
getBrightness(color c) =>
//@function Calculates percieved brightness of a color
//@param c (color)
//@returns (float) brightness of c between 0 and 255
r = color.r(c)
g = color.g(c)
b = color.b(c)
math.sqrt(r*r*0.241 + g*g*0.691 + b*b*0.068)
blackOrWhiteText(c) =>
if getBrightness(c) > 130
color.black
else
color.white
getLineStyle(s) =>
switch(s)
"Solid" => line.style_solid
"Dotted" => line.style_dotted
"Dashed" => line.style_dashed
//END Functions}
if cbdrStart //are we at
the start of a CBDR?
if not cbdrHistoryInput //is CBDR
history off?
box.delete(cbdrBox) //
label.delete(cbdrLabel) //then
delete previous boxes and labels
array.clear(cbdrLinesHi) //
array.clear(cbdrLinesLo) //Clean up the CBDR
Line arrays
cbdrHighPrice := tfOpen //
cbdrLowPrice := tfOpen //Set
the initial high and low of the CBDR
cbdrRange := 0.0 //
asiaRange := 0.0 //Reset the
range of the CBDR and Asian Range
else if inCbdrSession //are we in
the CBDR session?
if useWicks
cbdrHighPrice := math.max(cbdrHighPrice, tfHigh)
cbdrLowPrice := math.min(cbdrLowPrice, tfLow)
else
cbdrHighPrice := math.max(cbdrHighPrice, math.max(tfOpen,tfClose))
//
cbdrLowPrice := math.min(cbdrLowPrice, math.min(tfOpen, tfClose))
//check for new high and low
cbdrRange := (PIP*(cbdrHighPrice-cbdrLowPrice)) //calculate
the CBDR and convert to pips
if floutStart
if not floutHistoryToggleInput //is flout
history off?
box.delete(floutBox) //
label.delete(floutLabel) //then
delete previous boxes and labels
array.clear(floutLinesHi) //
array.clear(floutLinesLo) //Clean up
the flout Line arrays
floutHighPrice := tfOpen //
floutLowPrice := tfOpen //reset
flout high and low
else if inFloutSession //are we
already in the flout?
if useWicks
floutHighPrice := math.max(floutHighPrice, tfHigh)
//check for new flout high
floutLowPrice := math.min(floutLowPrice, tfLow)
//check for new flout low
else
floutHighPrice := math.max(floutHighPrice, math.max(tfOpen,tfClose))
floutLowPrice := math.min(floutLowPrice, math.min(tfOpen, tfClose))
floutRange := PIP*(floutHighPrice-floutLowPrice) //calculate
current flout range and convert to pips
if asiaStart //are we at
the start of a new asian range?
if not asiaHistoryInput //is asian
range history off?
box.delete(asiaBox) //
label.delete(asiaLabel) //then
delete previous boxes and labels
array.clear(asiaLinesHi) //
array.clear(asiaLinesLo) //Clean up
the asian Line arrays
asiaHighPrice := tfOpen //
asiaLowPrice := tfOpen //reset
asian range high and low
else if inasiaSession //are we
already in the asian range?
if useWicks
asiaHighPrice := math.max(asiaHighPrice, tfHigh)
//check for new asian range high
asiaLowPrice := math.min(asiaLowPrice, tfLow)
//check for new asian range low
else
asiaHighPrice := math.max(asiaHighPrice, math.max(tfOpen, tfClose))
asiaLowPrice := math.min(asiaLowPrice, math.min(tfOpen, tfClose))
asiaRange := (PIP*(asiaHighPrice-asiaLowPrice)) //calculate
current asian range and convert to pips
if dailyOpenStart
label.delete(pmhLabel)
label.delete(pmlLabel)
if not pmhHistoryToggleInput
line.delete(pmhLine)
if pmhToggleInput
pmhLine := line.new(time, pmHigh, dayofweek(time) == 6 ? hours(72) :
hours(24), pmHigh, xloc=xloc.bar_time, color=pmhColorInput, style=pmhStyle,
width=pmhWidthInput)
if pmhLabelToggleInput
pmhLabel := label.new(dayofweek(time) == 6 ? hours(72) : hours(24),
pmHigh, levelLabelsShortFormatInput ? PMH_LABEL_SHORT : PMH_LABEL_TEXT,
xloc.bar_time, yloc.price, invisible, label.style_none, pmhLabelColor,
levelsLabelTextSize)
if not pmlHistoryToggleInput
line.delete(pmlLine)
if pmlToggleInput
pmlLine := line.new(time, pmLow, dayofweek(time) == 6 ? hours(72) :
hours(24), pmLow, xloc=xloc.bar_time, color=pmlColorInput, style=pmlStyle,
width=pmlWidthInput)
if pmlLabelToggleInput
pmlLabel := label.new(dayofweek(time) == 6 ? hours(72) : hours(24),
pmLow, levelLabelsShortFormatInput ? PML_LABEL_SHORT : PML_LABEL_TEXT,
xloc.bar_time, yloc.price, invisible, label.style_none, pmlLabelColor,
levelsLabelTextSize)
if not dailyOpenHistoryToggleInput
line.delete(dailyOpenLine)
label.delete(dailyOpenLabel)
if dailyOpenToggleInput
dailyOpenLine := line.new(time, open, dayofweek(time) == 6 ? hours(72) :
hours(24), open, xloc=xloc.bar_time, color=dailyOpenColorInput,
style=dailyOpenStyle, width=dailyOpenWidthInput)
if dailyOpenLabelToggleInput
dailyOpenLabel := label.new(dayofweek(time) == 6 ? hours(72) :
hours(24), open, levelLabelsShortFormatInput ? DAILY_OPEN_LABEL_SHORT :
DAILY_OPEN_LABEL_TEXT, xloc.bar_time, yloc.price, invisible, label.style_none,
dailyOpenLabelColor, levelsLabelTextSize)
if fourOpenStart
if not fourOpenHistoryToggleInput
line.delete(fourOpenLine)
label.delete(fourOpenLabel)
if fourOpenToggleInput
fourOpenLine := line.new(time, open, dayofweek(time) == 6 ? hours(72) :
hours(24), open, xloc=xloc.bar_time, color=fourOpenColorInput, style=fourOpenStyle,
width=fourOpenWidthInput)
if fourOpenLabelToggleInput
fourOpenLabel := label.new(dayofweek(time) == 6 ? hours(72) :
hours(24), open, levelLabelsShortFormatInput ? FOUR_OPEN_LABEL_SHORT :
FOUR_OPEN_LABEL_TEXT, xloc.bar_time, yloc.price, invisible, label.style_none,
fourOpenLabelColor, levelsLabelTextSize)
if gmtOpenStart
if not gmtOpenHistoryToggleInput
line.delete(gmtOpenLine)
label.delete(gmtOpenLabel)
if gmtOpenToggleInput
gmtOpenLine := line.new(time, open, dayofweek(time) == 6 ? hours(72) :
hours(24), open, xloc=xloc.bar_time, color=gmtOpenColorInput, style=gmtOpenStyle,
width=gmtOpenWidthInput)
if gmtOpenLabelToggleInput
gmtOpenLabel := label.new(dayofweek(time) == 6 ? hours(72) : hours(24),
open, levelLabelsShortFormatInput ? GMT_LABEL_SHORT : GMT_LABEL_TEXT,
xloc.bar_time, yloc.price, invisible, label.style_none, gmtOpenLabelColor,
levelsLabelTextSize)
if not pdhHistoryToggleInput
label.delete(pdhLabel)
line.delete(pdhLine)
if pdhToggleInput
pdhLine := line.new(ptdHighX, ptdHigh, _h, ptdHigh, xloc=xloc.bar_time,
color=pdhColorInput, style=pdhStyle, width=pdhWidthInput)
if pdhLabelToggleInput
pdhLabel := label.new(_h, ptdHigh, levelLabelsShortFormatInput ?
PDH_LABEL_SHORT : PDH_LABEL_TEXT, xloc.bar_time, yloc.price, invisible,
label.style_none, pdhLabelColor, levelsLabelTextSize)
if not pdlHistoryToggleInput
label.delete(pdlLabel)
line.delete(pdlLine)
if pdlToggleInput
pdlLine := line.new(ptdLowX, ptdLow, _h, ptdLow, xloc=xloc.bar_time,
color=pdlColorInput, style=pdlStyle, width=pdlWidthInput)
if pdlLabelToggleInput
pdlLabel := label.new(_h, ptdLow, levelLabelsShortFormatInput ?
PDL_LABEL_SHORT : PDL_LABEL_TEXT, xloc.bar_time, yloc.price, invisible,
label.style_none, pdlLabelColor, levelsLabelTextSize)
hours(stringToHour(LONDON_OPEN_KILLZONE_END),
stringToMinutes(LONDON_OPEN_KILLZONE_END)),
killzoneHighPrice, xloc=xloc.bar_time,
color=killzoneLondonOpenColorInput, style=line.style_solid,
width=math.round(killzoneLineWidthInput))
kzLoLine2 := line.copy(kzLoLine1) //draw
london open killzone lines from it's start to end
else
kzLoBox1 := box.new(hours(stringToHour(LONDON_OPEN_KILLZONE_START),
stringToMinutes(LONDON_OPEN_KILLZONE_START)),
killzoneHighPrice,
hours(stringToHour(LONDON_OPEN_KILLZONE_END),
stringToMinutes(LONDON_OPEN_KILLZONE_END)),
killzoneHighPrice, xloc=xloc.bar_time,
bgcolor=killzoneLondonOpenColorInput, border_width=0)
kzLoBox2 := box.copy(kzLoBox1)
hours(stringToHour(LONDON_CLOSE_KILLZONE_END),
stringToMinutes(LONDON_CLOSE_KILLZONE_END)),
killzoneHighPrice, xloc=xloc.bar_time,
color=killzoneLondonCloseColorInput, style=line.style_solid,
width=math.round(killzoneLineWidthInput))
kzLCLine2 := line.copy(kzLCLine1) //draw
london close killzone lines from it's start to end
else
kzLcBox1 :=
box.new(hours(stringToHour(LONDON_CLOSE_KILLZONE_START),
stringToMinutes(LONDON_CLOSE_KILLZONE_START)),
killzoneHighPrice,
hours(stringToHour(LONDON_CLOSE_KILLZONE_END),
stringToMinutes(LONDON_CLOSE_KILLZONE_END)),
killzoneHighPrice, xloc=xloc.bar_time,
bgcolor=killzoneLondonCloseColorInput, border_width=0)
kzLcBox2 := box.copy(kzLcBox1)
hours(stringToHour(ASIAN_OPEN_KILLZONE_END),
stringToMinutes(ASIAN_OPEN_KILLZONE_END)),
killzoneHighPrice, xloc=xloc.bar_time,
color=killzoneAsianOpenColorInput, style=line.style_solid,
width=math.round(killzoneLineWidthInput))
kzAOLine2 := line.copy(kzAOLine1) //draw
asian open killzone lines from it's start to end
else
kzAoBox1 := box.new(hours(stringToHour(ASIAN_OPEN_KILLZONE_START),
stringToMinutes(ASIAN_OPEN_KILLZONE_START)),
killzoneHighPrice,
hours(stringToHour(ASIAN_OPEN_KILLZONE_END),
stringToMinutes(ASIAN_OPEN_KILLZONE_END)),
killzoneHighPrice, xloc=xloc.bar_time,
bgcolor=killzoneAsianOpenColorInput, border_width=0,
text_color=blackOrWhiteText(killzoneAsianOpenColorInput))
kzAoBox2 := box.copy(kzAoBox1)
c := blackOrWhiteText(killzoneNyColorInput)
box.set_text(kzNyBox1, "NEW YORK KZ")
box.set_text(kzNyBox2, "NEW YORK KZ")
box.set_text_color(kzNyBox1, c)
box.set_text_color(kzNyBox2, c)
c := blackOrWhiteText(killzoneLondonCloseColorInput)
box.set_text(kzLcBox1, "LONDON CLOSE KZ")
box.set_text_color(kzLcBox1, c )
box.set_text(kzLcBox2, "LONDON CLOSE KZ")
box.set_text_color(kzLcBox2, c)
c := blackOrWhiteText(killzoneAsianOpenColorInput)
box.set_text(kzAoBox1, "ASIAN OPEN KZ")
box.set_text(kzAoBox2, "ASIAN OPEN KZ")
box.set_text_color(kzAoBox1, c)
box.set_text_color(kzAoBox2, c)
c := blackOrWhiteText(killzoneNyLunchColorInput)
box.set_text(kzNyLBox1, "NEW YORK LUNCH")
box.set_text(kzNyLBox2, "NEW YORK LUNCH")
box.set_text_color(kzNyLBox1, c)
box.set_text_color(kzNyLBox2, c)
lineset_y(kzNYLine1,
killzoneHighPrice+(killzoneHighPrice-killzoneLowPrice)/killzoneYoffsetInput)
lineset_y(kzNYLine2,
killzoneLowPrice-(killzoneHighPrice-killzoneLowPrice)/killzoneYoffsetInput)
lineset_y(kzLCLine1,
killzoneHighPrice+(killzoneHighPrice-killzoneLowPrice)/killzoneYoffsetInput)
lineset_y(kzLCLine2,
killzoneLowPrice-(killzoneHighPrice-killzoneLowPrice)/killzoneYoffsetInput)
lineset_y(kzAOLine1,
killzoneHighPrice+(killzoneHighPrice-killzoneLowPrice)/killzoneYoffsetInput)
lineset_y(kzAOLine2,
killzoneLowPrice-(killzoneHighPrice-killzoneLowPrice)/killzoneYoffsetInput)
lineset_y(kzNyLLine1,
killzoneHighPrice+(killzoneHighPrice-killzoneLowPrice)/killzoneYoffsetInput)
lineset_y(kzNyLLine2,
killzoneLowPrice-(killzoneHighPrice-killzoneLowPrice)/killzoneYoffsetInput)
else
box.set_top(kzLoBox1, kzUpperBoxTop)
box.set_bottom(kzLoBox1, kzUpperBoxBottom)
box.set_top(kzLoBox2, kzLowerBoxTop)
box.set_bottom(kzLoBox2, kzLowerBoxBottom)
box.set_top(kzNyBox1, kzUpperBoxTop)
box.set_bottom(kzNyBox1, kzUpperBoxBottom)
box.set_top(kzNyBox2, kzLowerBoxTop)
box.set_bottom(kzNyBox2, kzLowerBoxBottom)
box.set_top(kzLcBox1, kzUpperBoxTop)
box.set_bottom(kzLcBox1, kzUpperBoxBottom)
box.set_top(kzLcBox2, kzLowerBoxTop)
box.set_bottom(kzLcBox2, kzLowerBoxBottom)
box.set_top(kzAoBox1, kzUpperBoxTop)
box.set_bottom(kzAoBox1, kzUpperBoxBottom)
box.set_top(kzAoBox2, kzLowerBoxTop)
box.set_bottom(kzAoBox2, kzLowerBoxBottom)
box.set_top(kzNyLBox1, kzUpperBoxTop)
box.set_bottom(kzNyLBox1, kzUpperBoxBottom)
box.set_top(kzNyLBox2, kzLowerBoxTop)
box.set_bottom(kzNyLBox2, kzLowerBoxBottom)
if tableToggleInput
tablePosition = tableLocInput == "Top Left" ?
position.top_left : tableLocInput == "Bottom Left" ? position.bottom_left :
tableLocInput == "Top Right" ? position.top_right : tableLocInput == "Top Center" ?
position.top_center : tableLocInput == "Bottom Center" ? position.bottom_center :
position.bottom_right
adrTable = table.new(tablePosition,
tableOrientationInput == "Vertical" ? 2 : 4, tableOrientationInput == "Vertical" ?
4 : 1, tableBgInput, border_width = 1)
bgBrightness = getBrightness(tableBgInput)
//color staticTextColor = bgBrightness > 130 ? color.black :
color.white
color staticTextColor = blackOrWhiteText(tableBgInput)
color dynamicGreen = staticTextColor
color dynamicRed = staticTextColor
color dynamicOrange = staticTextColor
color currentDailyRangeColor = staticTextColor
if tableDynamicTextInputToggle
dynamicGreen := bgBrightness > 130 ? color.green :
color.rgb(0, 255, 0)
dynamicRed := bgBrightness > 130 ? color.rgb(155, 0, 0) :
color.rgb(255, 0, 0)
dynamicOrange := bgBrightness > 130 ? color.rgb(255, 152,
0) : color.rgb(255, 200, 0)
currentDailyRangeColor :=
currentDailyRangeRounded/averageDailyRangeRounded < 0.5 ? dynamicGreen :
currentDailyRangeRounded/averageDailyRangeRounded < 1.0 ? dynamicOrange :
dynamicRed
// This source code is subject to the terms of the Mozilla Public License 2.0 at
https://mozilla.org/MPL/2.0/
// © Kioshi
//@version=5
bgColor = input.bool(false, "Activate High/Low View")
InAndOutColor = input.color(color.olive)
AsiaPacificFundingCompletion = input.color(color.yellow)
EUAndNAFundingCompletion = input.color(color.purple)
///Sessions
//Bars
is_newbar(sess) =>
t = time(res, sess, "America/New_York")
na(t[1]) and not na(t) or t[1] < t
is_session(sess) =>
not na(time(timeframe.period, sess, "America/New_York"))
//New York
nyNewbar = is_newbar(ny)
nySession = is_session(ny)
float nyLow = na
nyLow := if nySession
if nyNewbar
low
else
math.min(nyLow[1],low)
else
nyLow
float nyHigh = na
nyHigh := if nySession
if nyNewbar
high
else
math.max(nyHigh[1],high)
else
nyHigh
tokyoNewbar = is_newbar(tokyo)
tokyoSession = is_session(tokyo)
float tokyoLow = na
tokyoLow := if tokyoSession
if tokyoNewbar
low
else
math.min(tokyoLow[1],low)
else
tokyoLow
float tokyoHigh = na
tokyoHigh := if tokyoSession
if tokyoNewbar
high
else
math.max(tokyoHigh[1],high)
else
tokyoHigh
//Sydney
sydneyNewbar = is_newbar(sydney)
sydneySession = is_session(sydney)
float sydneyLow = na
sydneyLow := if sydneySession
if sydneyNewbar
low
else
math.min(sydneyLow[1],low)
else
sydneyLow
float sydneyHigh = na
sydneyHigh := if sydneySession
if sydneyNewbar
high
else
math.max(sydneyHigh[1],high)
else
sydneyHigh