Tradingview 价量分布
//@version=5
// ══════════════════════════════════════════════════════════════════════════════════════════════════ //
//
//
//
//
//
//
//
//
//
// ══════════════════════════════════════════════════════════════════════════════════════════════════ //
indicator("Volume Profile by DGT", "VPFR ʙʏ DGT ☼☾", true, max_bars_back = 5000, max_lines_count = 500, max_boxes_count = 500)
// ---------------------------------------------------------------------------------------------- //
// Volume Profile (Price by Volume) ------------------------------------------------------------ //
group_volume_profile = 'Volume Profile / Price by Volume'
tooltip_volume_profile = 'Volume Profile (also known as Price by Volume) is an charting study that displays trading activity over a specified time period at specific price levels'
volumeProfile = input.bool(true, group = group_volume_profile, tooltip = tooltip_volume_profile)
lookbackLength = input.int(360, 'Lookback Length', minval = 10, maxval = 5000, step = 10, group = group_volume_profile)
profileLevels = input.int(100, 'Number of Rows' , minval = 10, maxval = 150, step = 1, group = group_volume_profile)
profileDisplay = input.string('Up/Down', 'Volume', options = ['Up/Down', 'Total'], group = group_volume_profile)
upVolumeColor = input.color(color.new(
downVolumeColor = input.color(color.new(
totalVolumeColor = input.color(color.new(
pointOfControl = input.bool(true, 'Show Point of Control (POC)', group = group_volume_profile)
profilePlacement = input.string('Right', 'Placment', options = ['Right', 'Left'], group = group_volume_profile)
profileWidth = input.int(145, 'Profile Width' , minval = 41, maxval = 300, group = group_volume_profile)
volumeStorageT = array.new_float(profileLevels + 1, 0.)
volumeStorageB = array.new_float(profileLevels + 1, 0.)
var a_box = array.new_box()
priceHighest = ta.highest(high, lookbackLength)
priceLowest = ta.lowest (low , lookbackLength)
priceStep = (priceHighest - priceLowest) / profileLevels
barPriceLow = low
barPriceHigh = high
nzVolume = nz(volume)
bullCandle = close > open
if barstate.islast and nzVolume and volumeProfile
if array.size(a_box) > 0
for i = 1 to array.size(a_box)
box.delete(array.shift(a_box))
for barIndex = 0 to lookbackLength - 1
level = 0
for priceLevel = priceLowest to priceHighest by priceStep
if barPriceHigh[barIndex] >= priceLevel and barPriceLow[barIndex] < priceLevel + priceStep
array.set(volumeStorageT, level, array.get(volumeStorageT, level) + nzVolume[barIndex] * ((barPriceHigh[barIndex] - barPriceLow[barIndex]) == 0 ? 1 : priceStep / (barPriceHigh[barIndex] - barPriceLow[barIndex])) )
if bullCandle[barIndex] and profileDisplay == 'Up/Down'
array.set(volumeStorageB, level, array.get(volumeStorageB, level) + nzVolume[barIndex] * ((barPriceHigh[barIndex] - barPriceLow[barIndex]) == 0 ? 1 : priceStep / (barPriceHigh[barIndex] - barPriceLow[barIndex])) )
level += 1
array.push(a_box, box.new(bar_index - lookbackLength + 1, priceLowest, bar_index + (profilePlacement == 'Right' ? profileWidth : 0), priceHighest, color.new(color.blue, 37), 1, line.style_dotted, bgcolor = color.new(color.blue, 95) ))
if pointOfControl
array.push(a_box, box.new(bar_index - lookbackLength + 1, priceLowest + (array.indexof(volumeStorageT, array.max(volumeStorageT)) + .40) * priceStep, bar_index + (profilePlacement == 'Right' ? profileWidth : 0), priceLowest + (array.indexof(volumeStorageT, array.max(volumeStorageT)) + .60) * priceStep, color.new(
for level = 0 to profileLevels - 1
levelColor = profileDisplay == 'Up/Down' ? downVolumeColor : totalVolumeColor
startBoxIndex = profilePlacement == 'Right' ? bar_index + profileWidth - int(array.get(volumeStorageT, level) / array.max(volumeStorageT) * (profileWidth - 9)) : bar_index - lookbackLength + 1
endBoxIndex = profilePlacement == 'Right' ? bar_index + profileWidth : startBoxIndex + int( array.get(volumeStorageT, level) / array.max(volumeStorageT) * (profileWidth - 9))
array.push(a_box, box.new(startBoxIndex, priceLowest + (level + 0.1) * priceStep, endBoxIndex, priceLowest + (level + 0.9) * priceStep, levelColor, bgcolor = levelColor ))
if profileDisplay == 'Up/Down'
startBoxIndex := profilePlacement == 'Right' ? bar_index + profileWidth - int(array.get(volumeStorageB, level) / array.max(volumeStorageB) * (profileWidth - 9)/2) : bar_index - lookbackLength + 1
endBoxIndex := profilePlacement == 'Right' ? bar_index + profileWidth : startBoxIndex + int( array.get(volumeStorageB, level) / array.max(volumeStorageB) * (profileWidth - 9)/2)
array.push(a_box, box.new(startBoxIndex, priceLowest + (level + 0.1) * priceStep, endBoxIndex, priceLowest + (level + 0.9) * priceStep, upVolumeColor, bgcolor = upVolumeColor ))
// Volume Profile (Price by Volume) ------------------------------------------------------------ //
// ---------------------------------------------------------------------------------------------- //
// Volume Weighted Colored Bars ----------------------------------------------------------------- //
group_volume_weighted_colored_bars = 'Volume Weighted Colored Bars'
vwcb = input.bool(true, 'Volume Weighted Colored Bars', group=group_volume_weighted_colored_bars, tooltip='Colors bars based on the bar\'s volume relative to volume moving average')
vSMA = ta.sma(nzVolume, input.int(89, 'Volume Moving Average Length', group=group_volume_weighted_colored_bars))
barcolor(vwcb and nzVolume ? nzVolume > vSMA * input.float(1.618, 'Higher Theshold', minval=1., step=.1, group=group_volume_weighted_colored_bars) ? bullCandle ?
// Volume Weighted Colored Bars ----------------------------------------------------------------- //
// ---------------------------------------------------------------------------------------------- //
var table logo = table.new(position.bottom_right, 1, 1)
if barstate.islast
table.cell(logo, 0, 0, '☼☾ ', text_size=size.normal, text_color=color.teal)
评论
发表评论