0% found this document useful (0 votes)
4 views

Dashboard and Signals Table

This document contains Pine Script code for a trading strategy that utilizes moving averages and ATR for entry and exit signals. It includes user inputs for customizing the strategy parameters, as well as visual signals for buy and sell conditions. The script also features a table displaying take profit, stop loss, and strength levels for buyers and sellers.

Uploaded by

Aj Deshmukh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views

Dashboard and Signals Table

This document contains Pine Script code for a trading strategy that utilizes moving averages and ATR for entry and exit signals. It includes user inputs for customizing the strategy parameters, as well as visual signals for buy and sell conditions. The script also features a table displaying take profit, stop loss, and strength levels for buyers and sellers.

Uploaded by

Aj Deshmukh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 22

// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.

0
at https://mozilla.org/MPL/2.0/

// © bcracker82

//@version=6

plot(close)

// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0
at https://mozilla.org/MPL/2.0/

// © bcracker82

//@version=6

plot(close)

// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0
at https://mozilla.org/MPL/2.0/

// © bcracker82

//@version=6

plot(close)

//@version=6

strategy("premium HFT ", overlay=true)

// User Inputs

fastMA = input(10, title="Fast MA")

slowMA = input(30, title="Slow MA")

atrLength = input(14, title="ATR Length")

atrMultiplierSL = input.float(1.5, title="ATR Stop Multiplier")

tp1Multiplier = input.float(0.5, title="TP1 Multiplier")

tp2Multiplier = input.float(1.0, title="TP2 Multiplier")

tp3Multiplier = input.float(1.5, title="TP3 Multiplier")

// Indicators
fastMA_val = ta.ema(close, fastMA)

slowMA_val = ta.ema(close, slowMA)

atr_val = ta.atr(atrLength)

// Entry Conditions

longCondition = ta.crossover(fastMA_val, slowMA_val)

shortCondition = ta.crossunder(fastMA_val, slowMA_val)

// Stop Loss and Take Profit Levels

longStopLoss = close - (atr_val * atrMultiplierSL)

shortStopLoss = close + (atr_val * atrMultiplierSL)

longTP1 = close + (atr_val * tp1Multiplier)

longTP2 = close + (atr_val * tp2Multiplier)

longTP3 = close + (atr_val * tp3Multiplier)

shortTP1 = close - (atr_val * tp1Multiplier)

shortTP2 = close - (atr_val * tp2Multiplier)

shortTP3 = close - (atr_val * tp3Multiplier)

// Define explicit colors for each column with green and black

signalColor = #32CD32 // Lime Green (for Signal)

tpColor = #008000 // Green (for TP columns)

strengthColor = #000000 // Black (for Strength columns)

slColor = #008000 // Green (for Stop Loss)

transparentColor = color.rgb(0, 0, 0, 0) // Fully transparent color

// Create Table for displaying TP, SL, and Strength levels (Vertical Table)

var table myTable = table.new(position.top_right, 2, 7, border_width=1,


frame_color=color.black, bgcolor=transparentColor)
// Buyers and Sellers Strength Calculation

buyerStrength = (close > open) ? volume : 0

sellerStrength = (close < open) ? volume : 0

// Update table when a new trade is triggered

if (longCondition)

table.cell(myTable, 0, 0, "Signal", bgcolor=signalColor,


text_color=color.white, text_size=size.tiny)

table.cell(myTable, 1, 0, "Long", bgcolor=signalColor, text_color=color.white,


text_size=size.tiny)

table.cell(myTable, 0, 1, "TP1", bgcolor=tpColor, text_color=color.white,


text_size=size.tiny)

table.cell(myTable, 1, 1, str.tostring(longTP1), bgcolor=tpColor,


text_color=color.white, text_size=size.tiny)

table.cell(myTable, 0, 2, "TP2", bgcolor=tpColor, text_color=color.white,


text_size=size.tiny)

table.cell(myTable, 1, 2, str.tostring(longTP2), bgcolor=tpColor,


text_color=color.white, text_size=size.tiny)

table.cell(myTable, 0, 3, "TP3", bgcolor=tpColor, text_color=color.white,


text_size=size.tiny)

table.cell(myTable, 1, 3, str.tostring(longTP3), bgcolor=tpColor,


text_color=color.white, text_size=size.tiny)

table.cell(myTable, 0, 4, "Buyers Strength", bgcolor=strengthColor,


text_color=color.white, text_size=size.tiny)

table.cell(myTable, 1, 4, str.tostring(buyerStrength), bgcolor=strengthColor,


text_color=color.white, text_size=size.tiny)

table.cell(myTable, 0, 5, "Sellers Strength", bgcolor=strengthColor,


text_color=color.white, text_size=size.tiny)

table.cell(myTable, 1, 5, str.tostring(sellerStrength), bgcolor=strengthColor,


text_color=color.white, text_size=size.tiny)
table.cell(myTable, 0, 6, "Stop Loss", bgcolor=slColor, text_color=color.white,
text_size=size.tiny)

table.cell(myTable, 1, 6, str.tostring(longStopLoss), bgcolor=slColor,


text_color=color.white, text_size=size.tiny)

if (shortCondition)

table.cell(myTable, 0, 0, "Signal", bgcolor=signalColor,


text_color=color.white, text_size=size.tiny)

table.cell(myTable, 1, 0, "Short", bgcolor=signalColor, text_color=color.white,


text_size=size.tiny)

table.cell(myTable, 0, 1, "TP1", bgcolor=tpColor, text_color=color.white,


text_size=size.tiny)

table.cell(myTable, 1, 1, str.tostring(shortTP1), bgcolor=tpColor,


text_color=color.white, text_size=size.tiny)

table.cell(myTable, 0, 2, "TP2", bgcolor=tpColor, text_color=color.white,


text_size=size.tiny)

table.cell(myTable, 1, 2, str.tostring(shortTP2), bgcolor=tpColor,


text_color=color.white, text_size=size.tiny)

table.cell(myTable, 0, 3, "TP3", bgcolor=tpColor, text_color=color.white,


text_size=size.tiny)

table.cell(myTable, 1, 3, str.tostring(shortTP3), bgcolor=tpColor,


text_color=color.white, text_size=size.tiny)

table.cell(myTable, 0, 4, "Buyers Strength", bgcolor=strengthColor,


text_color=color.white, text_size=size.tiny)

table.cell(myTable, 1, 4, str.tostring(buyerStrength), bgcolor=strengthColor,


text_color=color.white, text_size=size.tiny)

table.cell(myTable, 0, 5, "Sellers Strength", bgcolor=strengthColor,


text_color=color.white, text_size=size.tiny)

table.cell(myTable, 1, 5, str.tostring(sellerStrength), bgcolor=strengthColor,


text_color=color.white, text_size=size.tiny)
table.cell(myTable, 0, 6, "Stop Loss", bgcolor=slColor, text_color=color.white,
text_size=size.tiny)

table.cell(myTable, 1, 6, str.tostring(shortStopLoss), bgcolor=slColor,


text_color=color.white, text_size=size.tiny)

// Visual Signals

plotshape(series=longCondition, title="Buy Signal", location=location.belowbar,


color=color.green, style=shape.labelup, text="BUY")

plotshape(series=shortCondition, title="Sell Signal", location=location.abovebar,


color=color.red, style=shape.labeldown, text="SELL")

// Plot MAs

plot(fastMA_val, color=color.green, title="Fast MA")

plot(slowMA_val, color=color.red, title="Slow MA")

// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0
at https://mozilla.org/MPL/2.0/

// © fluxchart

//@version=5

const bool DEBUG = false

const int maxBoxesCount = 500

const float overlapThresholdPercentage = 0

const int maxDistanceToLastBar = 1750 // Affects Running Time

const int maxOrderBlocks = 30

showInvalidated = input.bool(true, "Show Historic Zones", group = "General


Configuration", display = display.none)

OBsEnabled = true

orderBlockVolumetricInfo = input.bool(true, "Volumetric Info", group = "General


Configuration", inline="EV", display = display.none)
obEndMethod = input.string("Wick", "Zone Invalidation", options = ["Wick",
"Close"], group = "General Configuration", display = display.none)

combineOBs = DEBUG ? input.bool(true, "Combine Zones", group = "General


Configuration", display = display.none) : true

maxATRMult = DEBUG ? input.float(3.5,"Max Atr Multiplier", group = "General


Configuration") : 3.5

swingLength = input.int(10, 'Swing Length', minval = 3, tooltip="Swing length is


used when finding order block formations. Smaller values will result in finding
smaller order blocks.",group = "General Configuration", display = display.none)

zoneCount = input.string("Low", 'Zone Count', options = ["High", "Medium", "Low",


"One"], tooltip = "Number of Order Block Zones to be rendered. Higher options will
result in older Order Blocks shown.", group = "General Configuration", display =
display.none)

bullOrderBlockColor = input(#08998180, 'Bullish', inline = 'obColor', group =


'General Configuration', display = display.none)

bearOrderBlockColor = input(#f2364680, 'Bearish', inline = 'obColor', group =


'General Configuration', display = display.none)

bullishOrderBlocks = zoneCount == "One" ? 1 : zoneCount == "Low" ? 3 : zoneCount ==


"Medium" ? 5 : 10

bearishOrderBlocks = zoneCount == "One" ? 1 : zoneCount == "Low" ? 3 : zoneCount ==


"Medium" ? 5 : 10

timeframe1Enabled = true

timeframe1 = ""

textColor = input.color(#ffffff80, "Text Color", group = "Style")

extendZonesBy = DEBUG ? input.int(15, "Extend Zones", group = "Style", minval = 1,


maxval = 30, inline = "ExtendZones") : 15

extendZonesDynamic = DEBUG ? input.bool(true, "Dynamic", group = "Style", inline =


"ExtendZones") : true

combinedText = DEBUG ? input.bool(false, "Combined Text", group = "Style", inline =


"CombinedColor") : false

volumeBarsPlace = DEBUG ? input.string("Left", "Show Volume Bars At", options =


["Left", "Right"], group = "Style", inline = "volumebars") : "Left"

mirrorVolumeBars = DEBUG ? input.bool(true, "Mirror Volume Bars", group = "Style",


inline = "volumebars") : true
volumeBarsLeftSide = (volumeBarsPlace == "Left")

extendZonesByTime = extendZonesBy * timeframe.in_seconds(timeframe.period) * 1000

atr = ta.atr(10)

type orderBlockInfo

float top

float bottom

float obVolume

string obType

int startTime

float bbVolume

float obLowVolume

float obHighVolume

bool breaker

int breakTime

string timeframeStr

bool disabled = false

string combinedTimeframesStr = na

bool combined = false

type orderBlock

orderBlockInfo info

bool isRendered = false

box orderBox = na

box breakerBox = na

line orderBoxLineTop = na

line orderBoxLineBottom = na
line breakerBoxLineTop = na

line breakerBoxLineBottom = na

//

box orderBoxText = na

box orderBoxPositive = na

box orderBoxNegative = na

line orderSeperator = na

line orderTextSeperator = na

createOrderBlock (orderBlockInfo orderBlockInfoF) =>

orderBlock newOrderBlock = orderBlock.new(orderBlockInfoF)

newOrderBlock

safeDeleteOrderBlock (orderBlock orderBlockF) =>

orderBlockF.isRendered := false

box.delete(orderBlockF.orderBox)

box.delete(orderBlockF.breakerBox)

box.delete(orderBlockF.orderBoxText)

box.delete(orderBlockF.orderBoxPositive)

box.delete(orderBlockF.orderBoxNegative)

line.delete(orderBlockF.orderBoxLineTop)

line.delete(orderBlockF.orderBoxLineBottom)

line.delete(orderBlockF.breakerBoxLineTop)

line.delete(orderBlockF.breakerBoxLineBottom)

line.delete(orderBlockF.orderSeperator)

line.delete(orderBlockF.orderTextSeperator)
type timeframeInfo

int index = na

string timeframeStr = na

bool isEnabled = false

orderBlockInfo[] bullishOrderBlocksList = na

orderBlockInfo[] bearishOrderBlocksList = na

newTimeframeInfo (index, timeframeStr, isEnabled) =>

newTFInfo = timeframeInfo.new()

newTFInfo.index := index

newTFInfo.isEnabled := isEnabled

newTFInfo.timeframeStr := timeframeStr

newTFInfo

type obSwing

int x = na

float y = na

float swingVolume = na

bool crossed = false

// ____ TYPES END ____

var timeframeInfo[] timeframeInfos = array.from(newTimeframeInfo(1, timeframe1,


timeframe1Enabled))

var bullishOrderBlocksList = array.new<orderBlockInfo>(0)

var bearishOrderBlocksList = array.new<orderBlockInfo>(0)


var allOrderBlocksList = array.new<orderBlock>(0)

moveLine(_line, _x, _y, _x2) =>

line.set_xy1(_line, _x, _y)

line.set_xy2(_line, _x2, _y)

moveBox (_box, _topLeftX, _topLeftY, _bottomRightX, _bottomRightY) =>

box.set_lefttop(_box, _topLeftX, _topLeftY)

box.set_rightbottom(_box, _bottomRightX, _bottomRightY)

isTimeframeLower (timeframe1F, timeframe2F) =>

timeframe.in_seconds(timeframe1F) < timeframe.in_seconds(timeframe2F)

getMinTimeframe (timeframe1F, timeframe2F) =>

if isTimeframeLower(timeframe1F, timeframe2F)

timeframe1F

else

timeframe2F

getMaxTimeframe (timeframe1F, timeframe2F) =>

if isTimeframeLower(timeframe1F, timeframe2F)

timeframe2F

else

timeframe1F

formatTimeframeString (formatTimeframe) =>

timeframeF = formatTimeframe == "" ? timeframe.period : formatTimeframe

if str.contains(timeframeF, "D") or str.contains(timeframeF, "W") or


str.contains(timeframeF, "S") or str.contains(timeframeF, "M")
timeframeF

else

seconds = timeframe.in_seconds(timeframeF)

if seconds >= 3600

hourCount = int(seconds / 3600)

str.tostring(hourCount) + " Hour" + (hourCount > 1 ? "s" : "")

else

timeframeF + " Min"

betterCross(s1, s2) =>

string ret = na

if s1 >= s2 and s1[1] < s2

ret := "Bull"

if s1 < s2 and s1[1] >= s2

ret := "Bear"

ret

colorWithTransparency (colorF, transparencyX) =>

color.new(colorF, color.t(colorF) * transparencyX)

createOBBox (boxColor, transparencyX = 1.0, xlocType = xloc.bar_time) =>

box.new(na, na, na, na, text_size = size.normal, xloc = xlocType, extend =


extend.none, bgcolor = colorWithTransparency(boxColor, transparencyX), text_color =
textColor, text_halign = text.align_center, border_color = #00000000)

renderOrderBlock (orderBlock ob) =>

orderBlockInfo info = ob.info

ob.isRendered := true

orderColor = ob.info.obType == "Bull" ? bullOrderBlockColor :


bearOrderBlockColor
if OBsEnabled and (not false or not (false and info.breaker)) and not (not
showInvalidated and info.breaker)

ob.orderBox := createOBBox(orderColor, 1.5)

if ob.info.combined

ob.orderBox.set_bgcolor(colorWithTransparency(orderColor, 1.1))

ob.orderBoxText := createOBBox(color.new(color.white, 100))

if orderBlockVolumetricInfo

ob.orderBoxPositive := createOBBox(bullOrderBlockColor)

ob.orderBoxNegative := createOBBox(bearOrderBlockColor)

ob.orderSeperator :=
line.new(na,na,na,na,xloc.bar_time,extend.none,textColor,line.style_dashed,1)

ob.orderTextSeperator :=
line.new(na,na,na,na,xloc.bar_time,extend.none,textColor,line.style_solid,1)

zoneSize = extendZonesDynamic ? na(info.breakTime) ? extendZonesByTime :


(info.breakTime - info.startTime) : extendZonesByTime

if na(info.breakTime)

zoneSize := (time + 1) - info.startTime

startX = volumeBarsLeftSide ? info.startTime : info.startTime + zoneSize -


zoneSize / 3

maxEndX = volumeBarsLeftSide ? info.startTime + zoneSize / 3 :


info.startTime + zoneSize

moveBox(ob.orderBox, info.startTime, info.top, info.startTime + zoneSize,


info.bottom)

moveBox(ob.orderBoxText, volumeBarsLeftSide ? maxEndX : info.startTime,


info.top, volumeBarsLeftSide ? info.startTime + zoneSize : startX, info.bottom)

percentage = int((math.min(info.obHighVolume, info.obLowVolume) /


math.max(info.obHighVolume, info.obLowVolume)) * 100.0)

OBText = (na(ob.info.combinedTimeframesStr) ?
formatTimeframeString(ob.info.timeframeStr) : ob.info.combinedTimeframesStr) + "
OB"

box.set_text(ob.orderBoxText, (orderBlockVolumetricInfo ?
str.tostring(ob.info.obVolume, format.volume) + " (" + str.tostring(percentage) +
"%)\n" : "") + (combinedText and ob.info.combined ? "[Combined]\n" : "") + OBText)

if orderBlockVolumetricInfo

showHighLowBoxText = false

curEndXHigh = int(math.ceil((info.obHighVolume / info.obVolume) *


(maxEndX - startX) + startX))

curEndXLow = int(math.ceil((info.obLowVolume / info.obVolume) *


(maxEndX - startX) + startX))

moveBox(ob.orderBoxPositive, mirrorVolumeBars ? startX : curEndXLow,


info.top, mirrorVolumeBars ? curEndXHigh : maxEndX, (info.bottom + info.top) / 2)

box.set_text(ob.orderBoxPositive, showHighLowBoxText ?
str.tostring(info.obHighVolume, format.volume) : "")

moveBox(ob.orderBoxNegative, mirrorVolumeBars ? startX : curEndXHigh,


info.bottom, mirrorVolumeBars ? curEndXLow : maxEndX, (info.bottom + info.top) / 2)

box.set_text(ob.orderBoxNegative, showHighLowBoxText ?
str.tostring(info.obLowVolume, format.volume) : "")

moveLine(ob.orderSeperator, volumeBarsLeftSide ? startX : maxEndX,


(info.bottom + info.top) / 2, volumeBarsLeftSide ? maxEndX : startX)

line.set_xy1(ob.orderTextSeperator, volumeBarsLeftSide ? maxEndX :


startX, info.top)

line.set_xy2(ob.orderTextSeperator, volumeBarsLeftSide ? maxEndX :


startX, info.bottom)

findOBSwings(len) =>

var swingType = 0

var obSwing top = obSwing.new(na, na)

var obSwing bottom = obSwing.new(na, na)

upper = ta.highest(len)
lower = ta.lowest(len)

swingType := high[len] > upper ? 0 : low[len] < lower ? 1 : swingType

if swingType == 0 and swingType[1] != 0

top := obSwing.new(bar_index[len], high[len], volume[len])

if swingType == 1 and swingType[1] != 1

bottom := obSwing.new(bar_index[len], low[len], volume[len])

[top, bottom]

findOrderBlocks () =>

if bar_index > last_bar_index - maxDistanceToLastBar

[top, btm] = findOBSwings(swingLength)

useBody = false

max = useBody ? math.max(close, open) : high

min = useBody ? math.min(close, open) : low

// Bullish Order Block

bullishBreaked = 0

if bullishOrderBlocksList.size() > 0

for i = bullishOrderBlocksList.size() - 1 to 0

currentOB = bullishOrderBlocksList.get(i)

if not currentOB.breaker

if (obEndMethod == "Wick" ? low : math.min(open, close)) <


currentOB.bottom

currentOB.breaker := true
currentOB.breakTime := time

currentOB.bbVolume := volume

else

if high > currentOB.top

bullishOrderBlocksList.remove(i)

else if i < bullishOrderBlocks and top.y < currentOB.top and


top.y > currentOB.bottom

bullishBreaked := 1

if close > top.y and not top.crossed

top.crossed := true

boxBtm = max[1]

boxTop = min[1]

boxLoc = time[1]

for i = 1 to (bar_index - top.x) - 1

boxBtm := math.min(min[i], boxBtm)

boxTop := boxBtm == min[i] ? max[i] : boxTop

boxLoc := boxBtm == min[i] ? time[i] : boxLoc

newOrderBlockInfo = orderBlockInfo.new(boxTop, boxBtm, volume +


volume[1] + volume[2], "Bull", boxLoc)

newOrderBlockInfo.obLowVolume := volume[2]

newOrderBlockInfo.obHighVolume := volume + volume[1]

obSize = math.abs(newOrderBlockInfo.top - newOrderBlockInfo.bottom)

if obSize <= atr * maxATRMult

bullishOrderBlocksList.unshift(newOrderBlockInfo)

if bullishOrderBlocksList.size() > maxOrderBlocks

bullishOrderBlocksList.pop()
// Bearish Order Block

bearishBreaked = 0

if bearishOrderBlocksList.size() > 0

for i = bearishOrderBlocksList.size() - 1 to 0

currentOB = bearishOrderBlocksList.get(i)

if not currentOB.breaker

if (obEndMethod == "Wick" ? high : math.max(open, close)) >


currentOB.top

currentOB.breaker := true

currentOB.breakTime := time

currentOB.bbVolume := volume

else

if low < currentOB.bottom

bearishOrderBlocksList.remove(i)

else if i < bearishOrderBlocks and btm.y > currentOB.bottom and


btm.y < currentOB.top

bearishBreaked := 1

if close < btm.y and not btm.crossed

btm.crossed := true

boxBtm = min[1]

boxTop = max[1]

boxLoc = time[1]

for i = 1 to (bar_index - btm.x) - 1


boxTop := math.max(max[i], boxTop)

boxBtm := boxTop == max[i] ? min[i] : boxBtm

boxLoc := boxTop == max[i] ? time[i] : boxLoc

newOrderBlockInfo = orderBlockInfo.new(boxTop, boxBtm, volume +


volume[1] + volume[2], "Bear", boxLoc)

newOrderBlockInfo.obLowVolume := volume + volume[1]

newOrderBlockInfo.obHighVolume := volume[2]

obSize = math.abs(newOrderBlockInfo.top - newOrderBlockInfo.bottom)

if obSize <= atr * maxATRMult

bearishOrderBlocksList.unshift(newOrderBlockInfo)

if bearishOrderBlocksList.size() > maxOrderBlocks

bearishOrderBlocksList.pop()

true

areaOfOB (orderBlockInfo OBInfoF) =>

float XA1 = OBInfoF.startTime

float XA2 = na(OBInfoF.breakTime) ? time + 1 : OBInfoF.breakTime

float YA1 = OBInfoF.top

float YA2 = OBInfoF.bottom

float edge1 = math.sqrt((XA2 - XA1) * (XA2 - XA1) + (YA2 - YA2) * (YA2 - YA2))

float edge2 = math.sqrt((XA2 - XA2) * (XA2 - XA2) + (YA2 - YA1) * (YA2 - YA1))

float totalArea = edge1 * edge2

totalArea

doOBsTouch (orderBlockInfo OBInfo1, orderBlockInfo OBInfo2) =>

float XA1 = OBInfo1.startTime

float XA2 = na(OBInfo1.breakTime) ? time + 1 : OBInfo1.breakTime

float YA1 = OBInfo1.top


float YA2 = OBInfo1.bottom

float XB1 = OBInfo2.startTime

float XB2 = na(OBInfo2.breakTime) ? time + 1 : OBInfo2.breakTime

float YB1 = OBInfo2.top

float YB2 = OBInfo2.bottom

float intersectionArea = math.max(0, math.min(XA2, XB2) - math.max(XA1, XB1)) *


math.max(0, math.min(YA1, YB1) - math.max(YA2, YB2))

float unionArea = areaOfOB(OBInfo1) + areaOfOB(OBInfo2) - intersectionArea

float overlapPercentage = (intersectionArea / unionArea) * 100.0

if overlapPercentage > overlapThresholdPercentage

true

else

false

isOBValid (orderBlockInfo OBInfo) =>

valid = true

if OBInfo.disabled

valid := false

valid

combineOBsFunc () =>

if allOrderBlocksList.size() > 0

lastCombinations = 999

while lastCombinations > 0

lastCombinations := 0

for i = 0 to allOrderBlocksList.size() - 1

curOB1 = allOrderBlocksList.get(i)
for j = 0 to allOrderBlocksList.size() - 1

curOB2 = allOrderBlocksList.get(j)

if i == j

continue

if not isOBValid(curOB1.info) or not isOBValid(curOB2.info)

continue

if curOB1.info.obType != curOB2.info.obType

continue

if doOBsTouch(curOB1.info, curOB2.info)

curOB1.info.disabled := true

curOB2.info.disabled := true

orderBlock newOB =
createOrderBlock(orderBlockInfo.new(math.max(curOB1.info.top, curOB2.info.top),
math.min(curOB1.info.bottom, curOB2.info.bottom), curOB1.info.obVolume +
curOB2.info.obVolume, curOB1.info.obType))

newOB.info.startTime := math.min(curOB1.info.startTime,
curOB2.info.startTime)

newOB.info.breakTime := math.max(nz(curOB1.info.breakTime),
nz(curOB2.info.breakTime))

newOB.info.breakTime := newOB.info.breakTime == 0 ? na :
newOB.info.breakTime

newOB.info.timeframeStr := curOB1.info.timeframeStr

newOB.info.obVolume := curOB1.info.obVolume +
curOB2.info.obVolume

newOB.info.obLowVolume := curOB1.info.obLowVolume +
curOB2.info.obLowVolume

newOB.info.obHighVolume := curOB1.info.obHighVolume +
curOB2.info.obHighVolume

newOB.info.bbVolume := nz(curOB1.info.bbVolume, 0) +
nz(curOB2.info.bbVolume, 0)

newOB.info.breaker := curOB1.info.breaker or
curOB2.info.breaker

newOB.info.combined := true
if timeframe.in_seconds(curOB1.info.timeframeStr) !=
timeframe.in_seconds(curOB2.info.timeframeStr)

newOB.info.combinedTimeframesStr :=
(na(curOB1.info.combinedTimeframesStr) ?
formatTimeframeString(curOB1.info.timeframeStr) :
curOB1.info.combinedTimeframesStr) + " & " + (na(curOB2.info.combinedTimeframesStr)
? formatTimeframeString(curOB2.info.timeframeStr) :
curOB2.info.combinedTimeframesStr)

allOrderBlocksList.unshift(newOB)

lastCombinations += 1

reqSeq (timeframeStr) =>

[bullishOrderBlocksListF, bearishOrderBlocksListF] =
request.security(syminfo.tickerid, timeframeStr, [bullishOrderBlocksList,
bearishOrderBlocksList])

[bullishOrderBlocksListF, bearishOrderBlocksListF]

getTFData (timeframeInfo timeframeInfoF, timeframeStr) =>

if not isTimeframeLower(timeframeInfoF.timeframeStr, timeframe.period) and


timeframeInfoF.isEnabled

[bullishOrderBlocksListF, bearishOrderBlocksListF] = reqSeq(timeframeStr)

[bullishOrderBlocksListF, bearishOrderBlocksListF]

else

[na, na]

handleTimeframeInfo (timeframeInfo timeframeInfoF, bullishOrderBlocksListF,


bearishOrderBlocksListF) =>

if not isTimeframeLower(timeframeInfoF.timeframeStr, timeframe.period) and


timeframeInfoF.isEnabled

timeframeInfoF.bullishOrderBlocksList := bullishOrderBlocksListF

timeframeInfoF.bearishOrderBlocksList := bearishOrderBlocksListF

handleOrderBlocksFinal () =>
if DEBUG

log.info("Bullish OB Count " + str.tostring(bullishOrderBlocksList.size()))

log.info("Bearish OB Count " + str.tostring(bearishOrderBlocksList.size()))

if allOrderBlocksList.size () > 0

for i = 0 to allOrderBlocksList.size() - 1

safeDeleteOrderBlock(allOrderBlocksList.get(i))

allOrderBlocksList.clear()

for i = 0 to timeframeInfos.size() - 1

curTimeframe = timeframeInfos.get(i)

if not curTimeframe.isEnabled

continue

if curTimeframe.bullishOrderBlocksList.size() > 0

for j = 0 to math.min(curTimeframe.bullishOrderBlocksList.size() - 1,
bullishOrderBlocks - 1)

orderBlockInfoF = curTimeframe.bullishOrderBlocksList.get(j)

orderBlockInfoF.timeframeStr := curTimeframe.timeframeStr

allOrderBlocksList.unshift(createOrderBlock(orderBlockInfo.copy(orderBlockInfoF)))

if curTimeframe.bearishOrderBlocksList.size() > 0

for j = 0 to math.min(curTimeframe.bearishOrderBlocksList.size() - 1,
bearishOrderBlocks - 1)

orderBlockInfoF = curTimeframe.bearishOrderBlocksList.get(j)

orderBlockInfoF.timeframeStr := curTimeframe.timeframeStr

allOrderBlocksList.unshift(createOrderBlock(orderBlockInfo.copy(orderBlockInfoF)))

if combineOBs

combineOBsFunc()
if allOrderBlocksList.size() > 0

for i = 0 to allOrderBlocksList.size() - 1

curOB = allOrderBlocksList.get(i)

if isOBValid(curOB.info)

renderOrderBlock(curOB)

findOrderBlocks()

[bullishOrderBlocksListTimeframe1, bearishOrderBlocksListTimeframe1] =
getTFData(timeframeInfos.get(0), timeframe1)

if barstate.isconfirmed

handleTimeframeInfo(timeframeInfos.get(0), bullishOrderBlocksListTimeframe1,
bearishOrderBlocksListTimeframe1)

handleOrderBlocksFinal()

You might also like