You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<Run>The "Bucket Size" represents a predefined quantity or volume of data points or trades. </Run>
30
+
<Run>The volume threshold that must accumulate before a bucket completes. Trades are split at bucket boundaries so each bucket contains exactly this volume.</Run>
31
31
<LineBreak />
32
-
<Run>When analyzing data, it's often grouped into "buckets" to make it more manageable and to identify patterns or trends over specific intervals.</Run>
<RunFontStyle="Italic">For example, if you're analyzing trade volumes and choose a bucket size of 100, the system will group trades in sets of 100 and then analyze each set as a single unit.</Run>
35
+
<Run>V = ADV / n, where ADV = Average Daily Volume and n = Number of Buckets.</Run>
36
36
<LineBreak />
37
+
<Run>This calibrates each bucket to represent 1/n of a trading day.</Run>
37
38
<LineBreak />
38
-
<RunFontWeight="Bold">How to Use it</Run>
39
39
<LineBreak />
40
-
<Run>1. Choose a smaller bucket size for more granular analysis. This can help in identifying short-term patterns.</Run>
40
+
<RunFontWeight="Bold">How to Estimate</Run>
41
41
<LineBreak />
42
-
<Run>2. Choose a larger bucket size for a broader overview, which can be useful for spotting long-term trends.</Run>
42
+
<Run>1. Observe your instrument's daily traded volume (in base units, e.g., BTC, shares, contracts).</Run>
43
+
<LineBreak />
44
+
<Run>2. Divide by Number of Buckets (default 50).</Run>
45
+
<LineBreak />
46
+
<RunFontStyle="Italic">Example: If BTC/USD trades ~10,000 BTC/day with 50 buckets, set V = 200.</Run>
47
+
<LineBreak />
48
+
<RunFontStyle="Italic">Example: If a stock trades ~5M shares/day with 50 buckets, set V = 100,000.</Run>
49
+
<LineBreak />
50
+
<LineBreak />
51
+
<RunFontWeight="Bold">Sizing Guidelines</Run>
52
+
<LineBreak />
53
+
<Run>- Too small: buckets fill in 1-2 trades, VPIN saturates at 1.0 (no mixing of buys/sells).</Run>
54
+
<LineBreak />
55
+
<Run>- Too large: buckets take too long to fill, VPIN updates infrequently.</Run>
56
+
<LineBreak />
57
+
<Run>- Aim for each bucket to contain at least 20-50 trades for meaningful buy/sell classification.</Run>
/// The VPIN (Volume-Synchronized Probability of Informed Trading) value is a measure of the imbalance between buy and sell volumes in a given bucket. It's calculated as the absolute difference between buy and sell volumes divided by the total volume (buy + sell) for that bucket.
19
-
///
20
-
/// Given this definition, the range of VPIN values is between 0 and 1:
21
-
/// 0: This indicates a perfect balance between buy and sell volumes in the bucket. In other words, the number of buy trades is equal to the number of sell trades.
22
-
/// 1: This indicates a complete imbalance, meaning all the trades in the bucket are either all buys or all sells.
23
-
/// Most of the time, the VPIN value will be somewhere between these two extremes, indicating some level of imbalance between buy and sell trades. The closer the VPIN value is to 1, the greater the imbalance, and vice versa.
18
+
/// VPIN (Volume-Synchronized Probability of Informed Trading) measures order flow toxicity
19
+
/// using volume-synchronized buckets per Easley, Lopez de Prado & O'Hara (2012).
20
+
///
21
+
/// Formula: VPIN = (1/n) * SUM |V_buy_i - V_sell_i| / V_bucket, over n completed buckets.
22
+
///
23
+
/// Range [0, 1]: 0 = balanced flow, 1 = fully toxic (all buys or all sells).
24
24
/// </summary>
25
25
publicclassVPINStudy:BasePluginStudy
26
26
{
27
-
privateconststringValueFormat="N1";
27
+
privateconststringValueFormat="N2";
28
28
privateconststringcolorGreen="Green";
29
29
privateconststringcolorWhite="White";
30
+
privateconstintDEFAULT_NUMBER_OF_BUCKETS=50;
30
31
31
32
privatebool_disposed=false;// to track whether the object has been disposed
32
33
privatePlugInSettings_settings;
34
+
privatereadonlyobject_lockBucket=newobject();
33
35
34
36
//variables for calculation
35
37
privatedecimal_bucketVolumeSize;// The volume size of each bucket
36
-
privatedecimal_currentBucketVolume;// The volume size of each bucket
38
+
privatedecimal_currentBucketVolume;// Running accumulated volume in current bucket
37
39
privatedecimal_lastMarketMidPrice=0;//keep track of market price
38
40
privatedecimal_currentBuyVolume=0;
39
41
privatedecimal_currentSellVolume=0;
40
42
43
+
// Rolling window of completed bucket imbalances: |V_buy - V_sell| / V_bucket
44
+
privatedecimal[]_bucketImbalances;
45
+
privateint_bufferIndex=0;
46
+
privateint_bufferCount=0;
47
+
privatedecimal_rollingSum=0;// Running sum for O(1) average calculation
0 commit comments