LibVPrfLibrary   "LibVPrf" 
This library provides an object-oriented framework for volume
profile analysis in Pine Script®. It is built around the `VProf`
User-Defined Type (UDT), which encapsulates all data, settings,
and statistical metrics for a single profile, enabling stateful
analysis with on-demand calculations.
Key Features:
1.  **Object-Oriented Design (UDT):** The library is built around
the `VProf` UDT. This object encapsulates all profile data
and provides methods for its full lifecycle management,
including creation, cloning, clearing, and merging of profiles.
2.  **Volume Allocation (`AllotMode`):** Offers two methods for
allocating a bar's volume:
- **Classic:** Assigns the entire bar's volume to the close
price bucket.
- **PDF:** Distributes volume across the bar's range using a
statistical price distribution model from the `LibBrSt` library.
3.  **Buy/Sell Volume Splitting (`SplitMode`):** Provides methods
for classifying volume into buying and selling pressure:
- **Classic:** Classifies volume based on the bar's color (Close vs. Open).
- **Dynamic:** A specific model that analyzes candle structure
(body vs. wicks) and a short-term trend factor to
estimate the buy/sell share at each price level.
4.  **Statistical Analysis (On-Demand):** Offers a suite of
statistical metrics calculated using a "Lazy Evaluation"
pattern (computed only when requested via `get...` methods):
- **Central Tendency:** Point of Control (POC), VWAP, and Median.
- **Dispersion:** Value Area (VA) and Population Standard Deviation.
- **Shape:** Skewness and Excess Kurtosis.
- **Delta:** Cumulative Volume Delta, including its
historical high/low watermarks.
5.  **Structural Analysis:** Includes a parameter-free method
(`getSegments`) to decompose a profile into its fundamental
unimodal segments, allowing for modality detection (e.g.,
identifying bimodal profiles).
6.  **Dynamic Profile Management:**
- **Auto-Fitting:** Profiles set to `dynamic = true` will
automatically expand their price range to fit new data.
- **Manipulation:** The resolution, price range, and Value Area
of a dynamic profile can be changed at any time. This
triggers a resampling process that uses a **linear
interpolation model** to re-bucket existing volume.
- **Assumption:** Non-dynamic profiles are fixed and will throw
a `runtime.error` if `addBar` is called with data
outside their initial range.
7.  **Bucket-Level Access:** Provides getter methods for direct
iteration and analysis of the raw buy/sell volume and price
boundaries of each individual price bucket.
---
**DISCLAIMER**
This library is provided "AS IS" and for informational and
educational purposes only. It does not constitute financial,
investment, or trading advice.
The author assumes no liability for any errors, inaccuracies,
or omissions in the code. Using this library to build
trading indicators or strategies is entirely at your own risk.
As a developer using this library, you are solely responsible
for the rigorous testing, validation, and performance of any
scripts you create based on these functions. The author shall
not be held liable for any financial losses incurred directly
or indirectly from the use of this library or any scripts
derived from it.
 create(buckets, rangeUp, rangeLo, dynamic, valueArea, allot, estimator, cdfSteps, split, trendLen) 
  Construct a new `VProf` object with fixed bucket count & range.
  Parameters:
     buckets (int) : series int        number of price buckets ≥ 1
     rangeUp (float) : series float      upper price bound (absolute)
     rangeLo (float) : series float      lower price bound (absolute)
     dynamic (bool) : series bool       Flag for dynamic adaption of profile ranges
     valueArea (int) : series int        Percentage of total volume to include in the Value Area (1..100)
     allot (series AllotMode) : series AllotMode  Allocation mode `classic` or `pdf`  (default `classic`)
     estimator (series PriceEst enum from AustrianTradingMachine/LibBrSt/1) : series LibBrSt.PriceEst PDF model when `model == PDF`. (deflault = 'uniform')
     cdfSteps (int) : series int        even #sub-intervals for Simpson rule (default 20)
     split (series SplitMode) : series SplitMode  Buy/Sell determination (default `classic`)
     trendLen (int) : series int        Look‑back bars for trend factor (default 3)
  Returns: VProf             freshly initialised profile
 method clone(self) 
  Create a deep copy of the volume profile.
  Namespace types: VProf
  Parameters:
     self (VProf) : VProf  Profile object to copy
  Returns: VProf  A new, independent copy of the profile
 method clear(self) 
  Reset all bucket tallies while keeping configuration intact.
  Namespace types: VProf
  Parameters:
     self (VProf) : VProf  profile object
  Returns: VProf  cleared profile (chaining)
 method merge(self, srcABuy, srcASell, srcRangeUp, srcRangeLo, srcCvd, srcCvdHi, srcCvdLo) 
  Merges volume data from a source profile into the current profile.
If resizing is needed, it performs a high-fidelity re-bucketing of existing
volume using a linear interpolation model inferred from neighboring buckets,
preventing aliasing artifacts and ensuring accurate volume preservation.
  Namespace types: VProf
  Parameters:
     self (VProf) : VProf         The target profile object to merge into.
     srcABuy (array) : array  The source profile's buy volume bucket array.
     srcASell (array) : array  The source profile's sell volume bucket array.
     srcRangeUp (float) : series float  The upper price bound of the source profile.
     srcRangeLo (float) : series float  The lower price bound of the source profile.
     srcCvd (float) : series float  The final Cumulative Volume Delta (CVD) value of the source profile.
     srcCvdHi (float) : series float  The historical high-water mark of the CVD from the source profile.
     srcCvdLo (float) : series float  The historical low-water mark of the CVD from the source profile.
  Returns: VProf         `self` (chaining), now containing the merged data.
 method addBar(self, offset) 
  Add current bar’s volume to the profile (call once per realtime bar).
classic mode: allocates all volume to the close bucket and classifies
by `close >= open`. PDF mode: distributes volume across buckets by the
estimator’s CDF mass. For `split = dynamic`, the buy/sell share per
price is computed via context-driven piecewise s(u).
  Namespace types: VProf
  Parameters:
     self (VProf) : VProf       Profile object
     offset (int) : series int  To offset the calculated bar
  Returns: VProf       `self` (method chaining)
 method setBuckets(self, buckets) 
  Sets the number of buckets for the volume profile.
Behavior depends on the `isDynamic` flag.
- If `dynamic = true`: Works on filled profiles by re-bucketing to a new resolution.
- If `dynamic = false`: Only works on empty profiles to prevent accidental changes.
  Namespace types: VProf
  Parameters:
     self (VProf) : VProf       Profile object
     buckets (int) : series int  The new number of buckets
  Returns: VProf       `self` (chaining)
 method setRanges(self, rangeUp, rangeLo) 
  Sets the price range for the volume profile.
Behavior depends on the `dynamic` flag.
- If `dynamic = true`: Works on filled profiles by re-bucketing existing volume.
- If `dynamic = false`: Only works on empty profiles to prevent accidental changes.
  Namespace types: VProf
  Parameters:
     self (VProf) : VProf         Profile object
     rangeUp (float) : series float  The new upper price bound
     rangeLo (float) : series float  The new lower price bound
  Returns: VProf         `self` (chaining)
 method setValueArea(self, valueArea) 
  Set the percentage of volume for the Value Area. If the value
changes, the profile is finalized again.
  Namespace types: VProf
  Parameters:
     self (VProf) : VProf       Profile object
     valueArea (int) : series int  The new Value Area percentage (0..100)
  Returns: VProf       `self` (chaining)
 method getBktBuyVol(self, idx) 
  Get Buy volume of a bucket.
  Namespace types: VProf
  Parameters:
     self (VProf) : VProf         Profile object
     idx (int) : series int    Bucket index
  Returns: series float  Buy volume ≥ 0
 method getBktSellVol(self, idx) 
  Get Sell volume of a bucket.
  Namespace types: VProf
  Parameters:
     self (VProf) : VProf         Profile object
     idx (int) : series int    Bucket index
  Returns: series float  Sell volume ≥ 0
 method getBktBnds(self, idx) 
  Get Bounds of a bucket.
  Namespace types: VProf
  Parameters:
     self (VProf) : VProf       Profile object
     idx (int) : series int  Bucket index
  Returns:  
up  series float  The upper price bound of the bucket.
lo  series float  The lower price bound of the bucket.
 method getPoc(self) 
  Get POC information.
  Namespace types: VProf
  Parameters:
     self (VProf) : VProf  Profile object
  Returns:  
pocIndex  series int    The index of the Point of Control (POC) bucket.
pocPrice. series float  The mid-price of the Point of Control (POC) bucket.
 method getVA(self) 
  Get Value Area (VA) information.
  Namespace types: VProf
  Parameters:
     self (VProf) : VProf  Profile object
  Returns:  
vaUpIndex  series int    The index of the upper bound bucket of the Value Area.
vaUpPrice  series float  The upper price bound of the Value Area.
vaLoIndex  series int    The index of the lower bound bucket of the Value Area.
vaLoPrice  series float  The lower price bound of the Value Area.
 method getMedian(self) 
  Get the profile's median price and its bucket index. Calculates the value on-demand if stale.
  Namespace types: VProf
  Parameters:
     self (VProf) : VProf         Profile object.
  Returns:     
medianIndex  series int    The index of the bucket containing the Median.
medianPrice  series float  The Median price of the profile.
 method getVwap(self) 
  Get the profile's VWAP and its bucket index. Calculates the value on-demand if stale.
  Namespace types: VProf
  Parameters:
     self (VProf) : VProf         Profile object.
  Returns:     
vwapIndex    series int    The index of the bucket containing the VWAP.
vwapPrice    series float  The Volume Weighted Average Price of the profile.
 method getStdDev(self) 
  Get the profile's volume-weighted standard deviation. Calculates the value on-demand if stale.
  Namespace types: VProf
  Parameters:
     self (VProf) : VProf         Profile object.
  Returns: series float  The Standard deviation of the profile.
 method getSkewness(self) 
  Get the profile's skewness. Calculates the value on-demand if stale.
  Namespace types: VProf
  Parameters:
     self (VProf) : VProf         Profile object.
  Returns: series float  The Skewness of the profile.
 method getKurtosis(self) 
  Get the profile's excess kurtosis. Calculates the value on-demand if stale.
  Namespace types: VProf
  Parameters:
     self (VProf) : VProf         Profile object.
  Returns: series float  The Kurtosis of the profile.
 method getSegments(self) 
  Get the profile's fundamental unimodal segments. Calculates on-demand if stale.
Uses a parameter-free, pivot-based recursive algorithm.
  Namespace types: VProf
  Parameters:
     self (VProf) : VProf        The profile object.
  Returns: matrix  A 2-column matrix where each row is an   pair.
 method getCvd(self) 
  Cumulative Volume Delta (CVD) like metric over all buckets.
  Namespace types: VProf
  Parameters:
     self (VProf) : VProf      Profile object.
  Returns:  
cvd    series float  The final Cumulative Volume Delta (Total Buy Vol - Total Sell Vol).
cvdHi  series float  The running high-water mark of the CVD as volume was added.
cvdLo  series float  The running low-water mark of the CVD as volume was added.
 VProf 
  VProf  Bucketed Buy/Sell volume profile plus meta information.
  Fields:
     buckets (series int) : int              Number of price buckets (granularity ≥1)
     rangeUp (series float) : float            Upper price range (absolute)
     rangeLo (series float) : float            Lower price range (absolute)
     dynamic (series bool) : bool             Flag for dynamic adaption of profile ranges
     valueArea (series int) : int              Percentage of total volume to include in the Value Area (1..100)
     allot (series AllotMode) : AllotMode        Allocation mode `classic` or `pdf`
     estimator (series PriceEst enum from AustrianTradingMachine/LibBrSt/1) : LibBrSt.PriceEst Price density model when  `model == PDF`
     cdfSteps (series int) : int              Simpson integration resolution (even ≥2)
     split (series SplitMode) : SplitMode        Buy/Sell split strategy per bar
     trendLen (series int) : int              Look‑back length for trend factor (≥1)
     maxBkt (series int) : int              User-defined number of buckets (unclamped)
     aBuy (array) : array     Buy volume per bucket
     aSell (array) : array     Sell volume per bucket
     cvd (series float) : float            Final Cumulative Volume Delta (Total Buy Vol - Total Sell Vol).
     cvdHi (series float) : float            Running high-water mark of the CVD as volume was added.
     cvdLo (series float) : float            Running low-water mark of the CVD as volume was added.
     poc (series int) : int              Index of max‑volume bucket (POC). Is `na` until calculated.
     vaUp (series int) : int              Index of upper Value‑Area bound. Is `na` until calculated.
     vaLo (series int) : int              Index of lower value‑Area bound. Is `na` until calculated.
     median (series float) : float            Median price of the volume distribution. Is `na` until calculated.
     vwap (series float) : float            Profile VWAP (Volume Weighted Average Price). Is `na` until calculated.
     stdDev (series float) : float            Standard Deviation of volume around the VWAP. Is `na` until calculated.
     skewness (series float) : float            Skewness of the volume distribution. Is `na` until calculated.
     kurtosis (series float) : float            Excess Kurtosis of the volume distribution. Is `na` until calculated.
     segments (matrix) : matrix      A 2-column matrix where each row is an   pair. Is `na` until calculated.
