Session VWAP — the volume-weighted average price accumulated from each
session's open and reset at the next one:
${output}[i] =Σ typicalPrice·volume /Σ volume over this session's bars up to i typicalPrice = (high + low + close) /3
This is the VWAP an intraday desk actually watches — "we are above VWAP" on
a trading floor always means today's VWAP, from today's open, not a
rolling window and not a line running since the series began. It is the
third form vwap named and deliberately left open and
anchoredVwap could only half-provide: the reset needs session
boundaries, which is the corpus' G4 gate, and the trading calendar is
what closed it.
Appends one column, defined from each session's first bar (where it is
simply that bar's typical price) and undefined on any bar that falls in
closed time — a gap between sessions, an overnight print, a weekend bar
on a 24/7 feed. A bar with no session has no session VWAP; that is a fact
about the bar, not a hole to fill. A session's intraday breaks do not
split it: a lunch-halt session is one VWAP across both halves.
constcal= TradingCalendar.fromRules( { timeZone: 'America/New_York', open: '09:30', close: '16:00' }, { from: '2024-01-02', to: '2024-12-31' }, ); sessionVwap(bars, { sessions: cal }); // the primary door sessionVwap(cal.tagSessions(bars), { session: 'session' }); // already partitioned
Both are the same anchoring: tagSessions and the sessions door run the
same sessionIdValues walk, and a test pins the two routes equal under both
stamp conventions. sessions also accepts a raw Session[] — the schedule
table a feed hands you — which is validated (sorted, non-overlapping) before
it is used.
Composed, not new arithmetic
typicalPriceValues for the price and anchoredVwapValues for the
ratio of running sums — the same kernel anchoredVwap runs on. The
only difference between the two studies is what they pass as the anchor
group: anchoredVwap passes one group starting at the anchor bar, this
passes each bar's session id. Saying "session VWAP is anchored VWAP
re-anchored every session" is therefore a fact about the code, not a
comment.
Edges
An interior gap ends THIS SESSION's line, and the next session
re-seeds. Both sums are running sums, so after a missing term every
later level in that session is a known sum plus an unknown — obv's rule
and anchoredVwap's. The difference is that the reset recovers it
automatically at the next open, where anchoredVwap needs the caller to
re-anchor. A gap in any of the four inputs counts: the denominator is
blanked wherever the numerator is, so the two sums consume the same bars
and a bar with volume but a missing high cannot bias the average toward
zero (the #710 rule).
Zero accumulated volume → undefined. Reachable on a session that
opens on a run of zero-volume bars: there is nothing to weight by, so
there is no average price — not 0, not the plain mean of typical price.
The guard is live and at the output; without it the reading would be
±Infinity, which withColumn rejects outright.
A session the schedule has but the data doesn't simply contributes
nothing — the line is built from bars, not from the calendar.
Scales with price, not with volume — doubling every price doubles it,
doubling every volume leaves it unchanged, exactly as vwap and
anchoredVwap do. Both are pinned as property tests.
Session VWAP — the volume-weighted average price accumulated from each session's open and reset at the next one:
This is the VWAP an intraday desk actually watches — "we are above VWAP" on a trading floor always means today's VWAP, from today's open, not a rolling window and not a line running since the series began. It is the third form vwap named and deliberately left open and anchoredVwap could only half-provide: the reset needs session boundaries, which is the corpus' G4 gate, and the trading calendar is what closed it.
Appends one column, defined from each session's first bar (where it is simply that bar's typical price) and
undefinedon any bar that falls in closed time — a gap between sessions, an overnight print, a weekend bar on a 24/7 feed. A bar with no session has no session VWAP; that is a fact about the bar, not a hole to fill. A session's intradaybreaksdo not split it: a lunch-halt session is one VWAP across both halves.Where the sessions come from
Exactly one of two doors — see SessionAnchorOptions:
Both are the same anchoring:
tagSessionsand thesessionsdoor run the samesessionIdValueswalk, and a test pins the two routes equal under both stamp conventions.sessionsalso accepts a rawSession[]— the schedule table a feed hands you — which is validated (sorted, non-overlapping) before it is used.Composed, not new arithmetic
typicalPriceValues for the price and
anchoredVwapValuesfor the ratio of running sums — the same kernel anchoredVwap runs on. The only difference between the two studies is what they pass as the anchor group:anchoredVwappasses one group starting at the anchor bar, this passes each bar's session id. Saying "session VWAP is anchored VWAP re-anchored every session" is therefore a fact about the code, not a comment.Edges
obv's rule and anchoredVwap's. The difference is that the reset recovers it automatically at the next open, whereanchoredVwapneeds the caller to re-anchor. A gap in any of the four inputs counts: the denominator is blanked wherever the numerator is, so the two sums consume the same bars and a bar with volume but a missinghighcannot bias the average toward zero (the #710 rule).undefined. Reachable on a session that opens on a run of zero-volume bars: there is nothing to weight by, so there is no average price — not0, not the plain mean of typical price. The guard is live and at the output; without it the reading would be±Infinity, whichwithColumnrejects outright.vwapandanchoredVwapdo. Both are pinned as property tests.