Created
November 28, 2023 12:48
-
-
Save klobi1987/602afb85911e00ff89a3641d9e5cfca7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Define your strategy's name, type, and other properties | |
strategy("orderblocks", initial_capital = 100, currency = currency.USD, default_qty_type = strategy.percent_of_equity, default_qty_value = 1, commission_value = 0.04) | |
// Your existing code to calculate indicators and signals... | |
//@version=5 | |
indicator("after+ peak market + open bars + avg bars+luxalgo+Support resistance", shorttitle = "allin1" , overlay=true, max_labels_count = 500, max_lines_count = 500, max_boxes_count = 500, max_bars_back = 500) | |
devUp1 = input.float(1.28, "Stdev above (1)") | |
devDn1 = input.float(1.28, "Stdev below (1)") | |
devUp2 = input.float(2.01, "Stdev above (2)") | |
devDn2 = input.float(2.01, "Stdev below (2)") | |
devUp3 = input.float(2.51, "Stdev above (3)") | |
devDn3 = input.float(2.51, "Stdev below (3)") | |
devUp4 = input.float(3.09, "Stdev above (4)") | |
devDn4 = input.float(3.09, "Stdev below (4)") | |
devUp5 = input.float(4.01, "Stdev above (5)") | |
devDn5 = input.float(4.01, "Stdev below (5)") | |
showDv2 = input.bool(true, "Show second group of bands?") | |
showDv3 = input.bool(true, "Show third group of bands?") | |
showDv4 = input.bool(true, "Show fourth group of bands?") | |
showDv5 = input.bool(true, "Show fifth group of bands?") | |
showPrevVWAP = input.bool(true, title="Show previous VWAP close") | |
var float vwapsum = 0.0 | |
var float volumesum = 0.0 | |
var float v2sum = 0.0 | |
var float myvwap = 0.0 | |
var float prevwap = 0.0 | |
var bool newSession = false | |
start = request.security(syminfo.tickerid, "D", time) | |
vwapsum := newSession ? hl2*volume : vwapsum[1]+hl2*volume | |
volumesum := newSession ? volume : volumesum[1]+volume | |
v2sum := newSession ? volume*hl2*hl2 : v2sum[1]+volume*hl2*hl2 | |
vwap1 = vwapsum / volumesum | |
prevwap := newSession ? myvwap[1] : prevwap[1] | |
stdev = math.sqrt(v2sum / volumesum - vwap1 * vwap1) | |
myvwap := vwap1 | |
myvwap := vwap1 | |
deviation1 = devUp1 * stdev | |
deviation2 = devDn1 * stdev | |
plot(myvwap, title="VWAP", color=color.black, style=plot.style_circles) | |
// Plotting VWAP Upper and Lower Bands | |
U1 = plot(myvwap + deviation1, title="VWAP Upper", color=color.gray, style=plot.style_circles) | |
D1 = plot(myvwap - deviation1, title="VWAP Lower", color=color.gray, style=plot.style_circles) | |
U2 = plot(showDv2 ? myvwap + devUp2 * stdev : na, title="VWAP Upper (2)", color=color.red) | |
D2 = plot(showDv2 ? myvwap - devDn2 * stdev : na, title="VWAP Lower (2)", color=color.green) | |
U3 = plot(showDv3 ? myvwap + devUp3 * stdev : na, title="VWAP Upper (3)", color=color.red) | |
D3 = plot(showDv3 ? myvwap - devDn3 * stdev : na, title="VWAP Lower (3)", color=color.green) | |
U4 = plot(showDv4 ? myvwap + devUp4 * stdev : na, title="VWAP Upper (4)", color=color.red) | |
D4 = plot(showDv4 ? myvwap - devDn4 * stdev : na, title="VWAP Lower (4)", color=color.green) | |
U5 = plot(showDv5 ? myvwap + devUp5 * stdev : na, title="VWAP Upper (5)", color=color.red) | |
D5 = plot(showDv5 ? myvwap - devDn5 * stdev : na, title="VWAP Lower (5)", color=color.green) | |
prevwap := newSession ? vwap1[1] : prevwap[1] | |
prevVWAPColor = close > prevwap ? color.green : color.red | |
plot(showPrevVWAP ? prevwap : na, title="Previous VWAP", color=prevVWAPColor, style=plot.style_circles) | |
fill(U1, U2, color=color.new(color.red, 90), title="Over Bought Fill 1") | |
fill(D1, D2, color=color.new(color.green, 90), title="Over Sold Fill 1") | |
fill(U2, U3, color=color.new(color.red, 90), title="Over Bought Fill 2") | |
fill(D2, D3, color=color.new(color.green, 90), title="Over Sold Fill 2") | |
fill(U3, U4, color=color.new(color.red, 90), title="Over Bought Fill 3") | |
fill(D3, D4, color=color.new(color.green, 90), title="Over Sold Fill 3") | |
fill(U4, U5, color=color.new(color.red, 90), title="Over Bought Fill 4") | |
fill(D4, D5, color=color.new(color.green, 90), title="Over Sold Fill 4") | |
// Recording previous session's VWAP | |
// Define extended hours time range | |
hs = input.int(title="Hour start", defval=16) | |
hso = input.int(title="Hour start or", defval=17) | |
ms = input.int(title="Minute start", defval=15) | |
he = input.int(title="Hour end", defval=9) | |
heo = input.int(title="Hour end or", defval=8) | |
me = input.int(title="Minute end", defval=30) | |
op = input.int(title="opac", defval=94) | |
var int intervalops = op | |
var int intervalhs = hs | |
var int intervalhso = hso | |
var int intervalms = ms | |
var int intervalhe = he | |
var int intervalheo = heo | |
var int intervalme = me | |
// Define holidays as date ranges | |
newYearsDay = (month == 1 and dayofmonth == 1) or (month == 1 and dayofweek == 1 and dayofmonth == 2) | |
mlkDay = (month == 1 and dayofweek == 1 and dayofmonth >= 15 and dayofmonth <= 21) | |
washingtonsBday = (month == 2 and dayofweek == 1 and dayofmonth >= 15 and dayofmonth <= 21) | |
goodFriday = year >= 2022 and month == 4 and dayofmonth == 15 or year < 2022 and month == 4 and dayofmonth == 7 | |
memorialDay = (month == 5 and dayofweek == 1 and dayofmonth >= 25 and dayofmonth <= 31) | |
juneteenth = year >= 2022 and month == 6 and dayofmonth == 19 or year < 2022 and month == 6 and dayofmonth == 19 and dayofweek != 1 | |
independenceDay = (month == 7 and dayofmonth == 4) | |
laborDay = (month == 9 and dayofweek == 1 and dayofmonth >= 1 and dayofmonth <= 7) | |
thanksgivingDay = (month == 11 and dayofweek == 5 and dayofmonth >= 22 and dayofmonth <= 28) | |
christmasDay = (month == 12 and dayofmonth == 25) | |
// Check if current time falls within extended hours | |
isExtendedHours = (hour >= intervalhs and minute >= intervalms or hour >= intervalhso) or (hour <= intervalhe and minute <= intervalme or hour <= intervalheo) | |
isExtendeddays = month and dayofmonth and dayofweek == newYearsDay or mlkDay or washingtonsBday or goodFriday or memorialDay or juneteenth or independenceDay or laborDay or thanksgivingDay or christmasDay | |
// Set colors for extended hours and regular hours | |
bgcolor(isExtendedHours or isExtendeddays ? color.rgb(231, 74, 74, op) : na) | |
// Input params | |
var float openingRangeLengthInMinutes = input.float(4.98, title="Opening Range Length (minutes)") | |
var timezone_offset = input(title="Timezone Offset", defval=0) | |
// Calculate opening range high and low prices | |
var float openingRangeHighPrice = na | |
var float openingRangeLowPrice = na | |
var startUnixTime = timestamp("2023-03-22 09:30:00") + timezone_offset * 60 // add timezone offset in seconds | |
var startUnixTimeSeconds = startUnixTime % 86400 | |
var secondsPerMinute = 60 | |
var startBarTimeSecondsFromOpen = timenow % 86400 - startUnixTimeSeconds | |
// Check if we are inside Opening Range period. | |
condInsideORPd = (startBarTimeSecondsFromOpen <= openingRangeLengthInMinutes*secondsPerMinute ) | |
interval = input.int(title="fast", defval=10) | |
var int intt = interval | |
// Get Opening Bar Details | |
OR_bar_high = ta.valuewhen(condInsideORPd and high>high[1], high, occurrence=0) | |
OR_bar_low = ta.valuewhen(condInsideORPd and low<low[1], low, occurrence=0) | |
// Filter-Out Stocks that cross Opening High/Low | |
cond_crossing_OR = high > OR_bar_high or low < OR_bar_low | |
if condInsideORPd and cond_crossing_OR | |
alert('Stock Crossing High/Low: {syminfo.tickerid} {close} {datetime}') | |
plot(OR_bar_high, style=plot.style_linebr, color=color.green, linewidth=2) | |
plot(OR_bar_low, style=plot.style_linebr, color=color.red, linewidth=2) | |
lookbackStart1 = input.int(title="lookbackStart1", defval=13) | |
lookbackEnd1 = input.int(title="lookbackEnd1", defval=12) | |
var int le1 = lookbackStart1 | |
var int lh1 = lookbackEnd1 | |
highestHigh1 = ta.highest(high[le1], le1 - le1 + 1) | |
lowestLow1 = ta.lowest(low[le1], le1 - le1 + 1) | |
plot(le1, title="Highest High", color=color.green, linewidth=2) | |
plot(lowestLow1, title="Lowest Low", color=color.red, linewidth=2) | |
// Define extended hours time range | |
hs1 = input.int(title="First Hour start", defval=9) | |
ms1 = input.int(title="First Minute start", defval=30) | |
hso1 = input.int(title="First Hour end", defval=10) | |
mso = input.int(title="First Minute end", defval=30) | |
he1 = input.int(title="Second Hour start", defval=16) | |
me1 = input.int(title="Second start", defval=00) | |
he2 = input.int(title="Second end", defval=16) | |
me2 = input.int(title="Second end", defval=30) | |
op1 = input.int(title="Opacity", defval=94) | |
var int intervalhs1 = hs1 | |
var int intervalms1 = ms1 | |
var int intervalhso1 = hso1 | |
var int intervalmso = mso | |
var int intervalhe1 = he1 | |
var int intervalme1 = me1 | |
var int intervalhe11 = he2 | |
var int intervalme2 = me2 | |
var int intervalops1 = op1 | |
// Check if current time should be highlighted based on inputs | |
is_range1 = (hour == intervalhs1 and minute >= intervalms1) or (hour == intervalhso1 and minute <= intervalmso) | |
is_range2 = (hour == intervalhe1 and minute >= intervalme1) or (hour == intervalhe11 and minute <= intervalme2) | |
// Set colors for extended hours and regular hours | |
bgcolor(is_range1 or is_range2 ? color.rgb(81, 207, 85, op1) : na) | |
// 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/ | |
// © LuxAlgo | |
//-----------------------------------------------------------------------------{ | |
//Constants | |
//-----------------------------------------------------------------------------{ | |
color TRANSP_CSS = #ffffff00 | |
//Tooltips | |
string MODE_TOOLTIP = 'Allows to display historical Structure or only the recent ones' | |
string STYLE_TOOLTIP = 'Indicator color theme' | |
string COLOR_CANDLES_TOOLTIP = 'Display additional candles with a color reflecting the current trend detected by structure' | |
string SHOW_INTERNAL = 'Display internal market structure' | |
string CONFLUENCE_FILTER = 'Filter non significant internal structure breakouts' | |
string SHOW_SWING = 'Display swing market Structure' | |
string SHOW_SWING_POINTS = 'Display swing point as labels on the chart' | |
string SHOW_SWHL_POINTS = 'Highlight most recent strong and weak high/low points on the chart' | |
string INTERNAL_OB = 'Display internal order blocks on the chart\n\nNumber of internal order blocks to display on the chart' | |
string SWING_OB = 'Display swing order blocks on the chart\n\nNumber of internal swing blocks to display on the chart' | |
string FILTER_OB = 'Method used to filter out volatile order blocks \n\nIt is recommended to use the cumulative mean range method when a low amount of data is available' | |
string SHOW_EQHL = 'Display equal highs and equal lows on the chart' | |
string EQHL_BARS = 'Number of bars used to confirm equal highs and equal lows' | |
string EQHL_THRESHOLD = 'Sensitivity threshold in a range (0, 1) used for the detection of equal highs & lows\n\nLower values will return fewer but more pertinent results' | |
string SHOW_FVG = 'Display fair values gaps on the chart' | |
string AUTO_FVG = 'Filter out non significant fair value gaps' | |
string FVG_TF = 'Fair value gaps timeframe' | |
string EXTEND_FVG = 'Determine how many bars to extend the Fair Value Gap boxes on chart' | |
string PED_ZONES = 'Display premium, discount, and equilibrium zones on chart' | |
//-----------------------------------------------------------------------------{ | |
//Settings | |
//-----------------------------------------------------------------------------{ | |
//General | |
//----------------------------------------{ | |
mode = input.string('Historical' | |
, options = ['Historical', 'Present'] | |
, group = 'Smart Money Concepts' | |
, tooltip = MODE_TOOLTIP) | |
style = input.string('Colored' | |
, options = ['Colored', 'Monochrome'] | |
, group = 'Smart Money Concepts' | |
, tooltip = STYLE_TOOLTIP) | |
show_trend = input(false, 'Color Candles' | |
, group = 'Smart Money Concepts' | |
, tooltip = COLOR_CANDLES_TOOLTIP) | |
//----------------------------------------} | |
//Internal Structure | |
//----------------------------------------{ | |
show_internals = input(true, 'Show Internal Structure' | |
, group = 'Real Time Internal Structure' | |
, tooltip = SHOW_INTERNAL) | |
show_ibull = input.string('All', 'Bullish Structure' | |
, options = ['All', 'BOS', 'CHoCH'] | |
, inline = 'ibull' | |
, group = 'Real Time Internal Structure') | |
swing_ibull_css = input(#089981, '' | |
, inline = 'ibull' | |
, group = 'Real Time Internal Structure') | |
//Bear Structure | |
show_ibear = input.string('All', 'Bearish Structure' | |
, options = ['All', 'BOS', 'CHoCH'] | |
, inline = 'ibear' | |
, group = 'Real Time Internal Structure') | |
swing_ibear_css = input(#f23645, '' | |
, inline = 'ibear' | |
, group = 'Real Time Internal Structure') | |
ifilter_confluence = input(false, 'Confluence Filter' | |
, group = 'Real Time Internal Structure' | |
, tooltip = CONFLUENCE_FILTER) | |
internal_structure_size = input.string('Tiny', 'Internal Label Size' | |
, options = ['Tiny', 'Small', 'Normal'] | |
, group = 'Real Time Internal Structure') | |
//----------------------------------------} | |
//Swing Structure | |
//----------------------------------------{ | |
show_Structure = input(true, 'Show Swing Structure' | |
, group = 'Real Time Swing Structure' | |
, tooltip = SHOW_SWING) | |
//Bull Structure | |
show_bull = input.string('All', 'Bullish Structure' | |
, options = ['All', 'BOS', 'CHoCH'] | |
, inline = 'bull' | |
, group = 'Real Time Swing Structure') | |
swing_bull_css = input(#089981, '' | |
, inline = 'bull' | |
, group = 'Real Time Swing Structure') | |
//Bear Structure | |
show_bear = input.string('All', 'Bearish Structure' | |
, options = ['All', 'BOS', 'CHoCH'] | |
, inline = 'bear' | |
, group = 'Real Time Swing Structure') | |
swing_bear_css = input(#f23645, '' | |
, inline = 'bear' | |
, group = 'Real Time Swing Structure') | |
swing_structure_size = input.string('Small', 'Swing Label Size' | |
, options = ['Tiny', 'Small', 'Normal'] | |
, group = 'Real Time Swing Structure') | |
//Swings | |
show_swings = input(false, 'Show Swings Points' | |
, inline = 'swings' | |
, group = 'Real Time Swing Structure' | |
, tooltip = SHOW_SWING_POINTS) | |
length = input.int(50, '' | |
, minval = 10 | |
, inline = 'swings' | |
, group = 'Real Time Swing Structure') | |
show_hl_swings = input(true, 'Show Strong/Weak High/Low' | |
, group = 'Real Time Swing Structure' | |
, tooltip = SHOW_SWHL_POINTS) | |
//----------------------------------------} | |
//Order Blocks | |
//----------------------------------------{ | |
show_iob = input(true, 'Internal Order Blocks' | |
, inline = 'iob' | |
, group = 'Order Blocks' | |
, tooltip = INTERNAL_OB) | |
iob_showlast = input.int(5, '' | |
, minval = 1 | |
, inline = 'iob' | |
, group = 'Order Blocks') | |
show_ob = input(false, 'Swing Order Blocks' | |
, inline = 'ob' | |
, group = 'Order Blocks' | |
, tooltip = SWING_OB) | |
ob_showlast = input.int(5, '' | |
, minval = 1 | |
, inline = 'ob' | |
, group = 'Order Blocks') | |
ob_filter = input.string('Atr', 'Order Block Filter' | |
, options = ['Atr', 'Cumulative Mean Range'] | |
, group = 'Order Blocks' | |
, tooltip = FILTER_OB) | |
ibull_ob_css = input.color(color.new(#3179f5, 80), 'Internal Bullish OB' | |
, group = 'Order Blocks') | |
ibear_ob_css = input.color(color.new(#f77c80, 80), 'Internal Bearish OB' | |
, group = 'Order Blocks') | |
bull_ob_css = input.color(color.new(#1848cc, 80), 'Bullish OB' | |
, group = 'Order Blocks') | |
bear_ob_css = input.color(color.new(#b22833, 80), 'Bearish OB' | |
, group = 'Order Blocks') | |
//----------------------------------------} | |
//EQH/EQL | |
//----------------------------------------{ | |
show_eq = input(true, 'Equal High/Low' | |
, group = 'EQH/EQL' | |
, tooltip = SHOW_EQHL) | |
eq_len = input.int(3, 'Bars Confirmation' | |
, minval = 1 | |
, group = 'EQH/EQL' | |
, tooltip = EQHL_BARS) | |
eq_threshold = input.float(0.1, 'Threshold' | |
, minval = 0 | |
, maxval = 0.5 | |
, step = 0.1 | |
, group = 'EQH/EQL' | |
, tooltip = EQHL_THRESHOLD) | |
eq_size = input.string('Tiny', 'Label Size' | |
, options = ['Tiny', 'Small', 'Normal'] | |
, group = 'EQH/EQL') | |
//----------------------------------------} | |
//Fair Value Gaps | |
//----------------------------------------{ | |
show_fvg = input(false, 'Fair Value Gaps' | |
, group = 'Fair Value Gaps' | |
, tooltip = SHOW_FVG) | |
fvg_auto = input(true, "Auto Threshold" | |
, group = 'Fair Value Gaps' | |
, tooltip = AUTO_FVG) | |
fvg_tf = input.timeframe('', "Timeframe" | |
, group = 'Fair Value Gaps' | |
, tooltip = FVG_TF) | |
bull_fvg_css = input.color(color.new(#00ff68, 70), 'Bullish FVG' | |
, group = 'Fair Value Gaps') | |
bear_fvg_css = input.color(color.new(#ff0008, 70), 'Bearish FVG' | |
, group = 'Fair Value Gaps') | |
fvg_extend = input.int(1, "Extend FVG" | |
, minval = 0 | |
, group = 'Fair Value Gaps' | |
, tooltip = EXTEND_FVG) | |
//----------------------------------------} | |
//Previous day/week high/low | |
//----------------------------------------{ | |
//Daily | |
show_pdhl = input(false, 'Daily' | |
, inline = 'daily' | |
, group = 'Highs & Lows MTF') | |
pdhl_style = input.string('⎯⎯⎯', '' | |
, options = ['⎯⎯⎯', '----', '····'] | |
, inline = 'daily' | |
, group = 'Highs & Lows MTF') | |
pdhl_css = input(#2157f3, '' | |
, inline = 'daily' | |
, group = 'Highs & Lows MTF') | |
//Weekly | |
show_pwhl = input(false, 'Weekly' | |
, inline = 'weekly' | |
, group = 'Highs & Lows MTF') | |
pwhl_style = input.string('⎯⎯⎯', '' | |
, options = ['⎯⎯⎯', '----', '····'] | |
, inline = 'weekly' | |
, group = 'Highs & Lows MTF') | |
pwhl_css = input(#2157f3, '' | |
, inline = 'weekly' | |
, group = 'Highs & Lows MTF') | |
//Monthly | |
show_pmhl = input(false, 'Monthly' | |
, inline = 'monthly' | |
, group = 'Highs & Lows MTF') | |
pmhl_style = input.string('⎯⎯⎯', '' | |
, options = ['⎯⎯⎯', '----', '····'] | |
, inline = 'monthly' | |
, group = 'Highs & Lows MTF') | |
pmhl_css = input(#2157f3, '' | |
, inline = 'monthly' | |
, group = 'Highs & Lows MTF') | |
//----------------------------------------} | |
//Premium/Discount zones | |
//----------------------------------------{ | |
show_sd = input(false, 'Premium/Discount Zones' | |
, group = 'Premium & Discount Zones' | |
, tooltip = PED_ZONES) | |
premium_css = input.color(#f23645, 'Premium Zone' | |
, group = 'Premium & Discount Zones') | |
eq_css = input.color(#b2b5be, 'Equilibrium Zone' | |
, group = 'Premium & Discount Zones') | |
discount_css = input.color(#089981, 'Discount Zone' | |
, group = 'Premium & Discount Zones') | |
//-----------------------------------------------------------------------------} | |
//Functions | |
//-----------------------------------------------------------------------------{ | |
n = bar_index | |
atr = ta.atr(200) | |
cmean_range = ta.cum(high - low) / n | |
//HL Output function | |
hl() => [high, low] | |
//Get ohlc values function | |
get_ohlc()=> [close[1], open[1], high, low, high[2], low[2]] | |
//Display Structure function | |
display_Structure(x, y, txt, css, dashed, down, lbl_size)=> | |
structure_line = line.new(x, y, n, y | |
, color = css | |
, style = dashed ? line.style_dashed : line.style_solid) | |
structure_lbl = label.new(int(math.avg(x, n)), y, txt | |
, color = TRANSP_CSS | |
, textcolor = css | |
, style = down ? label.style_label_down : label.style_label_up | |
, size = lbl_size) | |
if mode == 'Present' | |
line.delete(structure_line[1]) | |
label.delete(structure_lbl[1]) | |
//Swings detection/measurements | |
swings(len)=> | |
var os = 0 | |
upper = ta.highest(len) | |
lower = ta.lowest(len) | |
os := high[len] > upper ? 0 : low[len] < lower ? 1 : os[1] | |
top = os == 0 and os[1] != 0 ? high[len] : 0 | |
btm = os == 1 and os[1] != 1 ? low[len] : 0 | |
[top, btm] | |
//Order block coordinates function | |
ob_coord(use_max, loc, target_top, target_btm, target_left, target_type)=> | |
min = 99999999. | |
max = 0. | |
idx = 1 | |
ob_threshold = ob_filter == 'Atr' ? atr : cmean_range | |
//Search for highest/lowest high within the structure interval and get range | |
if use_max | |
for i = 1 to (n - loc)-1 | |
if (high[i] - low[i]) < ob_threshold[i] * 2 | |
max := math.max(high[i], max) | |
min := max == high[i] ? low[i] : min | |
idx := max == high[i] ? i : idx | |
else | |
for i = 1 to (n - loc)-1 | |
if (high[i] - low[i]) < ob_threshold[i] * 2 | |
min := math.min(low[i], min) | |
max := min == low[i] ? high[i] : max | |
idx := min == low[i] ? i : idx | |
array.unshift(target_top, max) | |
array.unshift(target_btm, min) | |
array.unshift(target_left, time[idx]) | |
array.unshift(target_type, use_max ? -1 : 1) | |
//Set order blocks | |
display_ob(boxes, target_top, target_btm, target_left, target_type, show_last, swing, size)=> | |
for i = 0 to math.min(show_last-1, size-1) | |
get_box = array.get(boxes, i) | |
box.set_lefttop(get_box, array.get(target_left, i), array.get(target_top, i)) | |
box.set_rightbottom(get_box, array.get(target_left, i), array.get(target_btm, i)) | |
box.set_extend(get_box, extend.right) | |
color css = na | |
if swing | |
if style == 'Monochrome' | |
css := array.get(target_type, i) == 1 ? color.new(#b2b5be, 80) : color.new(#5d606b, 80) | |
border_css = array.get(target_type, i) == 1 ? #b2b5be : #5d606b | |
box.set_border_color(get_box, border_css) | |
else | |
css := array.get(target_type, i) == 1 ? bull_ob_css : bear_ob_css | |
box.set_border_color(get_box, css) | |
box.set_bgcolor(get_box, css) | |
else | |
if style == 'Monochrome' | |
css := array.get(target_type, i) == 1 ? color.new(#b2b5be, 80) : color.new(#5d606b, 80) | |
else | |
css := array.get(target_type, i) == 1 ? ibull_ob_css : ibear_ob_css | |
box.set_border_color(get_box, css) | |
box.set_bgcolor(get_box, css) | |
//Line Style function | |
get_line_style(style) => | |
out = switch style | |
'⎯⎯⎯' => line.style_solid | |
'----' => line.style_dashed | |
'····' => line.style_dotted | |
//Set line/labels function for previous high/lows | |
phl(h, l, tf, css)=> | |
var line high_line = line.new(na,na,na,na | |
, xloc = xloc.bar_time | |
, color = css | |
, style = get_line_style(pdhl_style)) | |
var label high_lbl = label.new(na,na | |
, xloc = xloc.bar_time | |
, text = str.format('P{0}H', tf) | |
, color = TRANSP_CSS | |
, textcolor = css | |
, size = size.small | |
, style = label.style_label_left) | |
var line low_line = line.new(na,na,na,na | |
, xloc = xloc.bar_time | |
, color = css | |
, style = get_line_style(pdhl_style)) | |
var label low_lbl = label.new(na,na | |
, xloc = xloc.bar_time | |
, text = str.format('P{0}L', tf) | |
, color = TRANSP_CSS | |
, textcolor = css | |
, size = size.small | |
, style = label.style_label_left) | |
hy = ta.valuewhen(h != h[1], h, 1) | |
hx = ta.valuewhen(h == high, time, 1) | |
ly = ta.valuewhen(l != l[1], l, 1) | |
lx = ta.valuewhen(l == low, time, 1) | |
if barstate.islast | |
ext = time + (time - time[1])*20 | |
//High | |
line.set_xy1(high_line, hx, hy) | |
line.set_xy2(high_line, ext, hy) | |
label.set_xy(high_lbl, ext, hy) | |
//Low | |
line.set_xy1(low_line, lx, ly) | |
line.set_xy2(low_line, ext, ly) | |
label.set_xy(low_lbl, ext, ly) | |
//-----------------------------------------------------------------------------} | |
//Global variables | |
//-----------------------------------------------------------------------------{ | |
var trend = 0, var itrend = 0 | |
var top_y = 0., var top_x = 0 | |
var btm_y = 0., var btm_x = 0 | |
var itop_y = 0., var itop_x = 0 | |
var ibtm_y = 0., var ibtm_x = 0 | |
var trail_up = high, var trail_dn = low | |
var trail_up_x = 0, var trail_dn_x = 0 | |
var top_cross = true, var btm_cross = true | |
var itop_cross = true, var ibtm_cross = true | |
var txt_top = '', var txt_btm = '' | |
//Alerts | |
bull_choch_alert = false | |
bull_bos_alert = false | |
bear_choch_alert = false | |
bear_bos_alert = false | |
bull_ichoch_alert = false | |
bull_ibos_alert = false | |
bear_ichoch_alert = false | |
bear_ibos_alert = false | |
bull_iob_break = false | |
bear_iob_break = false | |
bull_ob_break = false | |
bear_ob_break = false | |
eqh_alert = false | |
eql_alert = false | |
//Structure colors | |
var bull_css = style == 'Monochrome' ? #b2b5be | |
: swing_bull_css | |
var bear_css = style == 'Monochrome' ? #b2b5be | |
: swing_bear_css | |
var ibull_css = style == 'Monochrome' ? #b2b5be | |
: swing_ibull_css | |
var ibear_css = style == 'Monochrome' ? #b2b5be | |
: swing_ibear_css | |
//Labels size | |
var internal_structure_lbl_size = internal_structure_size == 'Tiny' | |
? size.tiny | |
: internal_structure_size == 'Small' | |
? size.small | |
: size.normal | |
var swing_structure_lbl_size = swing_structure_size == 'Tiny' | |
? size.tiny | |
: swing_structure_size == 'Small' | |
? size.small | |
: size.normal | |
var eqhl_lbl_size = eq_size == 'Tiny' | |
? size.tiny | |
: eq_size == 'Small' | |
? size.small | |
: size.normal | |
//Swings | |
[top, btm] = swings(length) | |
[itop, ibtm] = swings(5) | |
//-----------------------------------------------------------------------------} | |
//Pivot High | |
//-----------------------------------------------------------------------------{ | |
var line extend_top = na | |
var label extend_top_lbl = label.new(na, na | |
, color = TRANSP_CSS | |
, textcolor = bear_css | |
, style = label.style_label_down | |
, size = size.tiny) | |
if top | |
top_cross := true | |
txt_top := top > top_y ? 'HH' : 'LH' | |
if show_swings | |
top_lbl = label.new(n-length, top, txt_top | |
, color = TRANSP_CSS | |
, textcolor = bear_css | |
, style = label.style_label_down | |
, size = swing_structure_lbl_size) | |
if mode == 'Present' | |
label.delete(top_lbl[1]) | |
//Extend recent top to last bar | |
line.delete(extend_top[1]) | |
extend_top := line.new(n-length, top, n, top | |
, color = bear_css) | |
top_y := top | |
top_x := n - length | |
trail_up := top | |
trail_up_x := n - length | |
if itop | |
itop_cross := true | |
itop_y := itop | |
itop_x := n - 5 | |
//Trailing maximum | |
trail_up := math.max(high, trail_up) | |
trail_up_x := trail_up == high ? n : trail_up_x | |
//Set top extension label/line | |
if barstate.islast and show_hl_swings | |
line.set_xy1(extend_top, trail_up_x, trail_up) | |
line.set_xy2(extend_top, n + 20, trail_up) | |
label.set_x(extend_top_lbl, n + 20) | |
label.set_y(extend_top_lbl, trail_up) | |
label.set_text(extend_top_lbl, trend < 0 ? 'Strong High' : 'Weak High') | |
//-----------------------------------------------------------------------------} | |
//Pivot Low | |
//-----------------------------------------------------------------------------{ | |
var line extend_btm = na | |
var label extend_btm_lbl = label.new(na, na | |
, color = TRANSP_CSS | |
, textcolor = bull_css | |
, style = label.style_label_up | |
, size = size.tiny) | |
if btm | |
btm_cross := true | |
txt_btm := btm < btm_y ? 'LL' : 'HL' | |
if show_swings | |
btm_lbl = label.new(n - length, btm, txt_btm | |
, color = TRANSP_CSS | |
, textcolor = bull_css | |
, style = label.style_label_up | |
, size = swing_structure_lbl_size) | |
if mode == 'Present' | |
label.delete(btm_lbl[1]) | |
//Extend recent btm to last bar | |
line.delete(extend_btm[1]) | |
extend_btm := line.new(n - length, btm, n, btm | |
, color = bull_css) | |
btm_y := btm | |
btm_x := n-length | |
trail_dn := btm | |
trail_dn_x := n-length | |
if ibtm | |
ibtm_cross := true | |
ibtm_y := ibtm | |
ibtm_x := n - 5 | |
//Trailing minimum | |
trail_dn := math.min(low, trail_dn) | |
trail_dn_x := trail_dn == low ? n : trail_dn_x | |
//Set btm extension label/line | |
if barstate.islast and show_hl_swings | |
line.set_xy1(extend_btm, trail_dn_x, trail_dn) | |
line.set_xy2(extend_btm, n + 20, trail_dn) | |
label.set_x(extend_btm_lbl, n + 20) | |
label.set_y(extend_btm_lbl, trail_dn) | |
label.set_text(extend_btm_lbl, trend > 0 ? 'Strong Low' : 'Weak Low') | |
//-----------------------------------------------------------------------------} | |
//Order Blocks Arrays | |
//-----------------------------------------------------------------------------{ | |
var iob_top = array.new_float(0) | |
var iob_btm = array.new_float(0) | |
var iob_left = array.new_int(0) | |
var iob_type = array.new_int(0) | |
var ob_top = array.new_float(0) | |
var ob_btm = array.new_float(0) | |
var ob_left = array.new_int(0) | |
var ob_type = array.new_int(0) | |
//-----------------------------------------------------------------------------} | |
//Pivot High BOS/CHoCH | |
//-----------------------------------------------------------------------------{ | |
//Filtering | |
var bull_concordant = true | |
if ifilter_confluence | |
bull_concordant := high - math.max(close, open) > math.min(close, open - low) | |
//Detect internal bullish Structure | |
if ta.crossover(close, itop_y) and itop_cross and top_y != itop_y and bull_concordant | |
bool choch = na | |
if itrend < 0 | |
choch := true | |
bull_ichoch_alert := true | |
else | |
bull_ibos_alert := true | |
txt = choch ? 'CHoCH' : 'BOS' | |
if show_internals | |
if show_ibull == 'All' or (show_ibull == 'BOS' and not choch) or (show_ibull == 'CHoCH' and choch) | |
display_Structure(itop_x, itop_y, txt, ibull_css, true, true, internal_structure_lbl_size) | |
itop_cross := false | |
itrend := 1 | |
//Internal Order Block | |
if show_iob | |
ob_coord(false, itop_x, iob_top, iob_btm, iob_left, iob_type) | |
//Detect bullish Structure | |
if ta.crossover(close, top_y) and top_cross | |
bool choch = na | |
if trend < 0 | |
choch := true | |
bull_choch_alert := true | |
else | |
bull_bos_alert := true | |
txt = choch ? 'CHoCH' : 'BOS' | |
if show_Structure | |
if show_bull == 'All' or (show_bull == 'BOS' and not choch) or (show_bull == 'CHoCH' and choch) | |
display_Structure(top_x, top_y, txt, bull_css, false, true, swing_structure_lbl_size) | |
//Order Block | |
if show_ob | |
ob_coord(false, top_x, ob_top, ob_btm, ob_left, ob_type) | |
top_cross := false | |
trend := 1 | |
//-----------------------------------------------------------------------------} | |
//Pivot Low BOS/CHoCH | |
//-----------------------------------------------------------------------------{ | |
var bear_concordant = true | |
if ifilter_confluence | |
bear_concordant := high - math.max(close, open) < math.min(close, open - low) | |
//Detect internal bearish Structure | |
if ta.crossunder(close, ibtm_y) and ibtm_cross and btm_y != ibtm_y and bear_concordant | |
bool choch = false | |
if itrend > 0 | |
choch := true | |
bear_ichoch_alert := true | |
else | |
bear_ibos_alert := true | |
txt = choch ? 'CHoCH' : 'BOS' | |
if show_internals | |
if show_ibear == 'All' or (show_ibear == 'BOS' and not choch) or (show_ibear == 'CHoCH' and choch) | |
display_Structure(ibtm_x, ibtm_y, txt, ibear_css, true, false, internal_structure_lbl_size) | |
ibtm_cross := false | |
itrend := -1 | |
//Internal Order Block | |
if show_iob | |
ob_coord(true, ibtm_x, iob_top, iob_btm, iob_left, iob_type) | |
//Detect bearish Structure | |
if ta.crossunder(close, btm_y) and btm_cross | |
bool choch = na | |
if trend > 0 | |
choch := true | |
bear_choch_alert := true | |
else | |
bear_bos_alert := true | |
txt = choch ? 'CHoCH' : 'BOS' | |
if show_Structure | |
if show_bear == 'All' or (show_bear == 'BOS' and not choch) or (show_bear == 'CHoCH' and choch) | |
display_Structure(btm_x, btm_y, txt, bear_css, false, false, swing_structure_lbl_size) | |
//Order Block | |
if show_ob | |
ob_coord(true, btm_x, ob_top, ob_btm, ob_left, ob_type) | |
btm_cross := false | |
trend := -1 | |
//-----------------------------------------------------------------------------} | |
//Order Blocks | |
//-----------------------------------------------------------------------------{ | |
//Set order blocks | |
var iob_boxes = array.new_box(0) | |
var ob_boxes = array.new_box(0) | |
//Delete internal order blocks box coordinates if top/bottom is broken | |
for element in iob_type | |
index = array.indexof(iob_type, element) | |
if close < array.get(iob_btm, index) and element == 1 | |
array.remove(iob_top, index) | |
array.remove(iob_btm, index) | |
array.remove(iob_left, index) | |
array.remove(iob_type, index) | |
bull_iob_break := true | |
else if close > array.get(iob_top, index) and element == -1 | |
array.remove(iob_top, index) | |
array.remove(iob_btm, index) | |
array.remove(iob_left, index) | |
array.remove(iob_type, index) | |
bear_iob_break := true | |
//Delete internal order blocks box coordinates if top/bottom is broken | |
for element in ob_type | |
index = array.indexof(ob_type, element) | |
if close < array.get(ob_btm, index) and element == 1 | |
array.remove(ob_top, index) | |
array.remove(ob_btm, index) | |
array.remove(ob_left, index) | |
array.remove(ob_type, index) | |
bull_ob_break := true | |
else if close > array.get(ob_top, index) and element == -1 | |
array.remove(ob_top, index) | |
array.remove(ob_btm, index) | |
array.remove(ob_left, index) | |
array.remove(ob_type, index) | |
bear_ob_break := true | |
iob_size = array.size(iob_type) | |
ob_size = array.size(ob_type) | |
if barstate.isfirst | |
if show_iob | |
for i = 0 to iob_showlast-1 | |
array.push(iob_boxes, box.new(na,na,na,na, xloc = xloc.bar_time)) | |
if show_ob | |
for i = 0 to ob_showlast-1 | |
array.push(ob_boxes, box.new(na,na,na,na, xloc = xloc.bar_time)) | |
if iob_size > 0 | |
if barstate.islast | |
display_ob(iob_boxes, iob_top, iob_btm, iob_left, iob_type, iob_showlast, false, iob_size) | |
if ob_size > 0 | |
if barstate.islast | |
display_ob(ob_boxes, ob_top, ob_btm, ob_left, ob_type, ob_showlast, true, ob_size) | |
//-----------------------------------------------------------------------------} | |
//EQH/EQL | |
//-----------------------------------------------------------------------------{ | |
var eq_prev_top = 0. | |
var eq_top_x = 0 | |
var eq_prev_btm = 0. | |
var eq_btm_x = 0 | |
if show_eq | |
eq_top = ta.pivothigh(eq_len, eq_len) | |
eq_btm = ta.pivotlow(eq_len, eq_len) | |
if eq_top | |
max = math.max(eq_top, eq_prev_top) | |
min = math.min(eq_top, eq_prev_top) | |
if max < min + atr * eq_threshold | |
eqh_line = line.new(eq_top_x, eq_prev_top, n-eq_len, eq_top | |
, color = bear_css | |
, style = line.style_dotted) | |
eqh_lbl = label.new(int(math.avg(n-eq_len, eq_top_x)), eq_top, 'EQH' | |
, color = #00000000 | |
, textcolor = bear_css | |
, style = label.style_label_down | |
, size = eqhl_lbl_size) | |
if mode == 'Present' | |
line.delete(eqh_line[1]) | |
label.delete(eqh_lbl[1]) | |
eqh_alert := true | |
eq_prev_top := eq_top | |
eq_top_x := n-eq_len | |
if eq_btm | |
max = math.max(eq_btm, eq_prev_btm) | |
min = math.min(eq_btm, eq_prev_btm) | |
if min > max - atr * eq_threshold | |
eql_line = line.new(eq_btm_x, eq_prev_btm, n-eq_len, eq_btm | |
, color = bull_css | |
, style = line.style_dotted) | |
eql_lbl = label.new(int(math.avg(n-eq_len, eq_btm_x)), eq_btm, 'EQL' | |
, color = #00000000 | |
, textcolor = bull_css | |
, style = label.style_label_up | |
, size = eqhl_lbl_size) | |
eql_alert := true | |
if mode == 'Present' | |
line.delete(eql_line[1]) | |
label.delete(eql_lbl[1]) | |
eq_prev_btm := eq_btm | |
eq_btm_x := n-eq_len | |
//-----------------------------------------------------------------------------} | |
//Fair Value Gaps | |
//-----------------------------------------------------------------------------{ | |
var bullish_fvg_max = array.new_box(0) | |
var bullish_fvg_min = array.new_box(0) | |
var bearish_fvg_max = array.new_box(0) | |
var bearish_fvg_min = array.new_box(0) | |
float bullish_fvg_avg = na | |
float bearish_fvg_avg = na | |
bullish_fvg_cnd = false | |
bearish_fvg_cnd = false | |
[src_c1, src_o1, src_h, src_l, src_h2, src_l2] = | |
request.security(syminfo.tickerid, fvg_tf, get_ohlc()) | |
if show_fvg | |
delta_per = (src_c1 - src_o1) / src_o1 * 100 | |
change_tf = timeframe.change(fvg_tf) | |
threshold = fvg_auto ? ta.cum(math.abs(change_tf ? delta_per : 0)) / n * 2 | |
: 0 | |
//FVG conditions | |
bullish_fvg_cnd := src_l > src_h2 | |
and src_c1 > src_h2 | |
and delta_per > threshold | |
and change_tf | |
bearish_fvg_cnd := src_h < src_l2 | |
and src_c1 < src_l2 | |
and -delta_per > threshold | |
and change_tf | |
//FVG Areas | |
if bullish_fvg_cnd | |
array.unshift(bullish_fvg_max, box.new(n-1, src_l, n + fvg_extend, math.avg(src_l, src_h2) | |
, border_color = bull_fvg_css | |
, bgcolor = bull_fvg_css)) | |
array.unshift(bullish_fvg_min, box.new(n-1, math.avg(src_l, src_h2), n + fvg_extend, src_h2 | |
, border_color = bull_fvg_css | |
, bgcolor = bull_fvg_css)) | |
if bearish_fvg_cnd | |
array.unshift(bearish_fvg_max, box.new(n-1, src_h, n + fvg_extend, math.avg(src_h, src_l2) | |
, border_color = bear_fvg_css | |
, bgcolor = bear_fvg_css)) | |
array.unshift(bearish_fvg_min, box.new(n-1, math.avg(src_h, src_l2), n + fvg_extend, src_l2 | |
, border_color = bear_fvg_css | |
, bgcolor = bear_fvg_css)) | |
for bx in bullish_fvg_min | |
if low < box.get_bottom(bx) | |
box.delete(bx) | |
box.delete(array.get(bullish_fvg_max, array.indexof(bullish_fvg_min, bx))) | |
for bx in bearish_fvg_max | |
if high > box.get_top(bx) | |
box.delete(bx) | |
box.delete(array.get(bearish_fvg_min, array.indexof(bearish_fvg_max, bx))) | |
//-----------------------------------------------------------------------------} | |
//Previous day/week high/lows | |
//-----------------------------------------------------------------------------{ | |
//Daily high/low | |
[pdh, pdl] = request.security(syminfo.tickerid, 'D', hl() | |
, lookahead = barmerge.lookahead_on) | |
//Weekly high/low | |
[pwh, pwl] = request.security(syminfo.tickerid, 'W', hl() | |
, lookahead = barmerge.lookahead_on) | |
//Monthly high/low | |
[pmh, pml] = request.security(syminfo.tickerid, 'M', hl() | |
, lookahead = barmerge.lookahead_on) | |
//Display Daily | |
if show_pdhl | |
phl(pdh, pdl, 'D', pdhl_css) | |
//Display Weekly | |
if show_pwhl | |
phl(pwh, pwl, 'W', pwhl_css) | |
//Display Monthly | |
if show_pmhl | |
phl(pmh, pml, 'M', pmhl_css) | |
//-----------------------------------------------------------------------------} | |
//Premium/Discount/Equilibrium zones | |
//-----------------------------------------------------------------------------{ | |
var premium = box.new(na, na, na, na | |
, bgcolor = color.new(premium_css, 80) | |
, border_color = na) | |
var premium_lbl = label.new(na, na | |
, text = 'Premium' | |
, color = TRANSP_CSS | |
, textcolor = premium_css | |
, style = label.style_label_down | |
, size = size.small) | |
var eq = box.new(na, na, na, na | |
, bgcolor = color.rgb(120, 123, 134, 80) | |
, border_color = na) | |
var eq_lbl = label.new(na, na | |
, text = 'Equilibrium' | |
, color = TRANSP_CSS | |
, textcolor = eq_css | |
, style = label.style_label_left | |
, size = size.small) | |
var discount = box.new(na, na, na, na | |
, bgcolor = color.new(discount_css, 80) | |
, border_color = na) | |
var discount_lbl = label.new(na, na | |
, text = 'Discount' | |
, color = TRANSP_CSS | |
, textcolor = discount_css | |
, style = label.style_label_up | |
, size = size.small) | |
//Show Premium/Discount Areas | |
if barstate.islast and show_sd | |
avg = math.avg(trail_up, trail_dn) | |
box.set_lefttop(premium, math.max(top_x, btm_x), trail_up) | |
box.set_rightbottom(premium, n, .95 * trail_up + .05 * trail_dn) | |
label.set_xy(premium_lbl, int(math.avg(math.max(top_x, btm_x), n)), trail_up) | |
box.set_lefttop(eq, math.max(top_x, btm_x), .525 * trail_up + .475*trail_dn) | |
box.set_rightbottom(eq, n, .525 * trail_dn + .475 * trail_up) | |
label.set_xy(eq_lbl, n, avg) | |
box.set_lefttop(discount, math.max(top_x, btm_x), .95 * trail_dn + .05 * trail_up) | |
box.set_rightbottom(discount, n, trail_dn) | |
label.set_xy(discount_lbl, int(math.avg(math.max(top_x, btm_x), n)), trail_dn) | |
//-----------------------------------------------------------------------------} | |
//Trend | |
//-----------------------------------------------------------------------------{ | |
var color trend_css = na | |
if show_trend | |
if style == 'Colored' | |
trend_css := itrend == 1 ? bull_css : bear_css | |
else if style == 'Monochrome' | |
trend_css := itrend == 1 ? #b2b5be : #5d606b | |
plotcandle(open, high, low, close | |
, color = trend_css | |
, wickcolor = trend_css | |
, bordercolor = trend_css | |
, editable = false) | |
//-----------------------------------------------------------------------------} | |
//Alerts | |
//-----------------------------------------------------------------------------{ | |
//Internal Structure | |
alertcondition(bull_ibos_alert, 'Internal Bullish BOS', 'Internal Bullish BOS formed') | |
alertcondition(bull_ichoch_alert, 'Internal Bullish CHoCH', 'Internal Bullish CHoCH formed') | |
alertcondition(bear_ibos_alert, 'Internal Bearish BOS', 'Internal Bearish BOS formed') | |
alertcondition(bear_ichoch_alert, 'Internal Bearish CHoCH', 'Internal Bearish CHoCH formed') | |
//Swing Structure | |
alertcondition(bull_bos_alert, 'Bullish BOS', 'Internal Bullish BOS formed') | |
alertcondition(bull_choch_alert, 'Bullish CHoCH', 'Internal Bullish CHoCH formed') | |
alertcondition(bear_bos_alert, 'Bearish BOS', 'Bearish BOS formed') | |
alertcondition(bear_choch_alert, 'Bearish CHoCH', 'Bearish CHoCH formed') | |
//order Blocks | |
alertcondition(bull_iob_break, 'Bullish Internal OB Breakout', 'Price broke bullish internal OB') | |
alertcondition(bear_iob_break, 'Bearish Internal OB Breakout', 'Price broke bearish internal OB') | |
alertcondition(bull_ob_break, 'Bullish Swing OB Breakout', 'Price broke bullish swing OB') | |
alertcondition(bear_ob_break, 'Bearish Swing OB Breakout', 'Price broke bearish swing OB') | |
//EQH/EQL | |
alertcondition(eqh_alert, 'Equal Highs', 'Equal highs detected') | |
alertcondition(eql_alert, 'Equal Lows', 'Equal lows detected') | |
//FVG | |
alertcondition(bullish_fvg_cnd, 'Bullish FVG', 'Bullish FVG formed') | |
alertcondition(bearish_fvg_cnd, 'Bearish FVG', 'Bearish FVG formed') | |
//-----------------------------------------------------------------------------} | |
prd = input.int(10) | |
ppsrc = input.string('High/Low') | |
maxnumpp = input.int(20) | |
ChannelW = input.int(10) | |
maxnumsr = input.int(5) | |
min_strength = input.int(2) | |
labelloc = input.int(20) | |
linestyle = input.string('Dashed') | |
linewidth = input.int(2) | |
showpp = input.bool(false, "Show Pivot Points") | |
tplevels = input.bool(false, "Automatic S/R Levels") | |
opacityred = input.int(title="opacityred", defval=94) | |
opacitylime = input.int(title="opacitylime", defval=94) | |
var int opr = opacityred | |
var int opl = opacitylime | |
resistancecolor = color.rgb(235, 63, 63,opr) | |
supportcolor = color.rgb(77, 211, 146,opl) | |
float src1 = ppsrc == 'High/Low' ? high : math.max(close, open) | |
float src2 = ppsrc == 'High/Low' ? low : math.min(close, open) | |
float ph = ta.pivothigh(src1, prd, prd) | |
float pl = ta.pivotlow(src2, prd, prd) | |
Lstyle = linestyle == 'Dashed' ? line.style_solid : linestyle == 'Solid' ? line.style_solid : line.style_solid | |
//calculate maximum S/R channel zone width | |
prdhighest = ta.highest(300) | |
prdlowest = ta.lowest(300) | |
cwidth = (prdhighest - prdlowest) * ChannelW / 100 | |
var pivotvals = array.new_float(0) | |
if ph or pl | |
array.unshift(pivotvals, ph ? ph : pl) | |
if array.size(pivotvals) > maxnumpp // limit the array size | |
array.pop(pivotvals) | |
get_sr_vals(ind) => | |
float lo = array.get(pivotvals, ind) | |
float hi = lo | |
int numpp = 0 | |
for y = 0 to array.size(pivotvals) - 1 by 1 | |
float cpp = array.get(pivotvals, y) | |
float wdth = cpp <= lo ? hi - cpp : cpp - lo | |
if wdth <= cwidth // fits the max channel width? | |
if cpp <= hi | |
lo := math.min(lo, cpp) | |
else | |
hi := math.max(hi, cpp) | |
numpp += 1 | |
numpp | |
[hi, lo, numpp] | |
var sr_up_level = array.new_float(0) | |
var sr_dn_level = array.new_float(0) | |
sr_strength = array.new_float(0) | |
find_loc(strength) => | |
ret = array.size(sr_strength) | |
for i = ret > 0 ? array.size(sr_strength) - 1 : na to 0 by 1 | |
if strength <= array.get(sr_strength, i) | |
break | |
ret := i | |
ret | |
ret | |
check_sr(hi, lo, strength) => | |
ret = true | |
for i = 0 to array.size(sr_up_level) > 0 ? array.size(sr_up_level) - 1 : na by 1 | |
//included? | |
if array.get(sr_up_level, i) >= lo and array.get(sr_up_level, i) <= hi or array.get(sr_dn_level, i) >= lo and array.get(sr_dn_level, i) <= hi | |
if strength >= array.get(sr_strength, i) | |
array.remove(sr_strength, i) | |
array.remove(sr_up_level, i) | |
array.remove(sr_dn_level, i) | |
ret | |
else | |
ret := false | |
ret | |
break | |
ret | |
var sr_lines = array.new_line(11, na) | |
var sr_labels = array.new_label(11, na) | |
for x = 1 to 10 by 1 | |
rate = 100 * (label.get_y(array.get(sr_labels, x)) - close) / close | |
label.set_text(array.get(sr_labels, x), text=str.tostring(label.get_y(array.get(sr_labels, x))) + '(' + str.tostring(rate, '#.##') + '%)') | |
label.set_x(array.get(sr_labels, x), x=bar_index + labelloc) | |
label.set_color(array.get(sr_labels, x), color=label.get_y(array.get(sr_labels, x)) >= close ? color.rgb(207, 30, 30, opr) : color.rgb(84, 175, 131, opr)) | |
label.set_textcolor(array.get(sr_labels, x), textcolor=label.get_y(array.get(sr_labels, x)) >= close ? color.rgb(235, 229, 229,opr) : color.rgb(30, 34, 43,opr)) | |
label.set_style(array.get(sr_labels, x), style=label.get_y(array.get(sr_labels, x)) >= close ? label.style_label_down : label.style_label_up) | |
line.set_color(array.get(sr_lines, x), color=line.get_y1(array.get(sr_lines, x)) >= close ? color.rgb(207, 30, 30, opr) : color.rgb(84, 175, 131, opr)) | |
if ph or pl | |
//because of new calculation, remove old S/R levels | |
array.clear(sr_up_level) | |
array.clear(sr_dn_level) | |
array.clear(sr_strength) | |
//find S/R zones | |
for x = 0 to array.size(pivotvals) - 1 by 1 | |
[hi, lo, strength] = get_sr_vals(x) | |
if check_sr(hi, lo, strength) | |
loc = find_loc(strength) | |
// if strength is in first maxnumsr sr then insert it to the arrays | |
if loc < maxnumsr and strength >= min_strength | |
array.insert(sr_strength, loc, strength) | |
array.insert(sr_up_level, loc, hi) | |
array.insert(sr_dn_level, loc, lo) | |
// keep size of the arrays = 5 | |
if array.size(sr_strength) > maxnumsr | |
array.pop(sr_strength) | |
array.pop(sr_up_level) | |
array.pop(sr_dn_level) | |
for x = 1 to 10 by 1 | |
line.delete(array.get(sr_lines, x)) | |
label.delete(array.get(sr_labels, x)) | |
for x = 0 to array.size(sr_up_level) > 0 ? array.size(sr_up_level) - 1 : na by 1 | |
float mid = math.round_to_mintick((array.get(sr_up_level, x) + array.get(sr_dn_level, x)) / 2) | |
rate = 100 * (mid - close) / close | |
array.set(sr_labels, x + 1, label.new(x=bar_index + labelloc, y=mid, text=str.tostring(mid) + '(' + str.tostring(rate, '#.##') + '%)', color=mid >= close ? color.rgb(250, 89, 89,opr) : color.rgb(25, 231, 132), textcolor=mid >= close ? color.rgb(247, 230, 230,opr) : color.rgb(63, 67, 80,opr), style=mid >= close ? label.style_label_down : label.style_label_up)) | |
array.set(sr_lines, x + 1, line.new(x1=bar_index, y1=mid, x2=bar_index - 1, y2=mid, extend=extend.both, color=mid >= close ? resistancecolor : supportcolor, style=Lstyle, width=linewidth)) | |
// Entry conditions | |
if (buy_condition) | |
strategy.entry("Buy", strategy.long) | |
if (sell_condition) | |
strategy.entry("Sell", strategy.short) | |
// Exit conditions | |
if (exit_buy_condition) | |
strategy.close("Buy") | |
if (exit_sell_condition) | |
strategy.close("Sell") | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment