Ok, here's what I've come up with:
Code:
# 5-day Average Premarket Volume
declare upper;
########## Scripts
script BarsPerPeriod {
input barCount = 32; #hint barCount: the number of 30 minute candles in a full trading day
input length = 11; #hint length: the number of premarket candles to count
plot cumulativeVolume = (fold i = 0 to length with o = 0 do o + GetValue(volume, (barCount - i), 0));
}
script PremarketVolume {
# code for today's premarket volume
def st = 0400; # today's premarket start time
def et = 0929; # today's premarket end time
def Active = SecondsFromTime(st) >= 0 and SecondsTillTime(et) >= 0;
def tPV = if Active and !Active[1] then volume
else if Active then (tPV[1] + volume)
else tPV[1];
plot TodaysPremarketVolume = tPV;
# code for prior days' premarket volume
input barCount = 32; #hint barCount: the number of 30 minute candles in a full trading day
def pst = 0400; # prior days' premarket start time
def pet = 0429; # prior days' premarket end time
def pActive = SecondsFromTime(pst) >= 0 and SecondsTillTime(pet) >= 0;
def pPV = if pActive and !pActive[1] then BarsPerPeriod(barCount).cumulativeVolume
else if pActive Then pPV[1] + BarsPerPeriod(barCount).cumulativeVolume
else pPV[1];
plot PremarketVolume = pPV;
}
########## /Scripts
input showLabels = yes;
def day1 = PremarketVolume(32).PremarketVolume;
def day2 = PremarketVolume(64).PremarketVolume;
def day3 = PremarketVolume(96).PremarketVolume;
def day4 = PremarketVolume(128).PremarketVolume;
def day5 = PremarketVolume(160).PremarketVolume;
AddLabel(showLabels, "Day 1: " + day1, Color.Light_Gray);
AddLabel(showLabels, "Day 2: " + day2, Color.Light_Gray);
AddLabel(showLabels, "Day 3: " + day3, Color.Light_Gray);
AddLabel(showLabels, "Day 4: " + day4, Color.Light_Gray);
AddLabel(showLabels, "Day 5: " + day5, Color.Light_Gray);
def AvgPremarketVolume = Round((day1 + day2 + day3 + day4 + day5) / 5, 0); # tried to implement as a fold function but couldn't get it to work
def todaysPremarketVolume = PremarketVolume(0).TodaysPremarketVolume;
def Avg = Round((todaysPremarketVolume / AvgPremarketVolume) * 100, 0);
AddLabel(showLabels, "Avg PV: " + AvgPremarketVolume, Color.LIGHT_GRAY);
AddLabel(showLabels, "Today: " + todaysPremarketVolume + " | " + AsPercent(Avg / 100), Color.Orange);
Apply this on a 30min chart with extended hours on. It gets the premarket volume of the previous 5 days, averages that volume, and compares it with the current day's premarket volume. The labels for each of the 5 days are given just to show you what the numbers look like, but they can easily be commented out.
I used the 30min timeframe because it gives you the least amount of candles while accounting for the last 30 minutes of premarket volume (the hourly timeframes don't make it easy to get that data). This timeframe gives you a total of 32 candles from the start of premarket all the way to the end of after hours (11 premarket, 13 regular trading hours, 8 after hours). To get premarket data for the previous day:
1. Start with the first premarket candle of the current day
2. Count backwards 32 candles until you reach the first premarket candle of the previous day
3. Beginning with that first premarket candle, get the volume associated with it and move forward 1 candle until you've gone forward 11 candles, adding each candle's volume to the prior candle's volume. (Another way to look at it, you'll be counting down from 32 to 21.)
To get the same data for additional days, do the same steps listed above except in #2 multiply 32 by the number of days in the past you want. Of course, my code doesn't allow anything past 5 days, so you'll have to adjust it to suit your needs. Also, my code doesn't account for partial/short trading days or days in which a stock doesn't have 11 total premarket candles.
To ensure that the numbers are correct, you'll have to view a ticker and do some math by hand and compare the volume numbers you get with the numbers the labels show. My tests with TSLA show that I'm right, but take that with a half grain of salt.
My code is by no means perfect. Some of the code I don't fully understand as I reused code I've seen in other indicators to make this work. Hopefully someone can optimize it.
Hope this helps.