Event Operators
All functions · nseries package
BarsSince
func (s Series) BarsSince(back ...int) Series
BarsSince returns, for each bar, the number of bars since the most recent event in the receiver, which is itself the event series: bar j is an event bar when s[j] is non-zero and not NaN, so +Inf and -Inf are events while 0, -0 and NaN are not. The current bar counts as an event bar, so with the default back the result is 0 on an event bar, 1 on the next bar, and so on. With back 1 it is the number of bars since the event before the most recent one. The values are exact non-negative integers (as float64) or NaN.
back is an nseries extension: neither TradingView’s ta.barssince nor AmiBroker’s BarsSince takes one. It selects the occurrence and is numbered as ValueWhen’s back: from 0, as TradingView’s ta.valuewhen occurrence, so 0 (the default) is the most recent event and 1 the one before it, one less than AmiBroker ValueWhen’s 1-based n. Only the first value of back is read; any further values are ignored. A back below zero is invalid and returns aligned zeros. Any non-negative back is valid, and one at or beyond the length of the receiver gives all NaN.
The result is NaN until the first event (until the (k+1)-th event when back is k), and NaN rather than 0 because the start depends on the data. The age is latched at events, so under a sliding slice of history the output depends on the first event inside the slice: bars before it read NaN, even where an earlier event lies outside the slice.
Sources: TradingView Pine Script v6 ta.barssince; AmiBroker AFL BarsSince; and, for the confirmed pivots the latch is often applied to, the rolling-window rule of Tsinaslanidis and Zapranis, Technical Analysis for Algorithmic Pattern Recognition (Springer, 2016), ch. 2 (their pattern rules on the most recent pivots are in chs 5 and 6).
ChangeSince
func (s Series) ChangeSince(cond Series) Series
ChangeSince returns, for each bar, the change of the receiver since the most recent bar on which cond is an event: the receiver’s value minus its value at that event bar. It equals s.Sub(s.ValueWhen(cond)) bit for bit, apart from the payload of a NaN, in one pass and one allocation. A value of cond is an event when it is non-zero and not NaN, so +Inf and -Inf are events while 0, -0 and NaN are not. The current bar counts as an event bar, so the result is 0 on an event bar where the receiver is finite. ChangeSince has no back argument; ValueWhen takes one.
The result is NaN wherever either operand is NaN, and an infinity minus the same infinity is NaN. A NaN held from an event bar therefore gives NaN until the next event.
The result is NaN until the first event, and NaN rather than 0 because the start depends on the data. The reference value is latched, so under a sliding slice of history the output depends on the first event inside the slice: bars before it read NaN, even where an earlier event lies outside the slice.
ChangeSince is an nseries composition of ValueWhen, and its sources are ValueWhen’s: TradingView Pine Script v6 ta.valuewhen; AmiBroker AFL ValueWhen; and, for the confirmed pivots the latch is often applied to, the rolling-window rule of Tsinaslanidis and Zapranis, Technical Analysis for Algorithmic Pattern Recognition (Springer, 2016), ch. 2 (their pattern rules on the most recent pivots are in chs 5 and 6).
cond is right-aligned with the receiver at the most recent bar: the last values are paired, then the second-last, and so on. A cond longer than the receiver contributes only its last len(receiver) values, and a shorter cond gives the same result as cond with zeros prepended. Receiver bars before the overlap (and every bar, for an empty cond) see no event and so read NaN until the first paired event. Series are paired by position only; see “Time alignment” in the manual.
HighestSince
func (s Series) HighestSince(cond Series) Series
HighestSince returns, for each bar, the highest value of the receiver from the most recent bar on which cond is an event up to the current bar. A value of cond is an event when it is non-zero and not NaN, so +Inf and -Inf are events while 0, -0 and NaN are not. The current bar counts as an event bar, the event bar is included in the span (on an event bar the result is the receiver’s own value, verbatim), and each event restarts the span.
The result is defined bit for bit by a recursion: on an event bar it is the receiver’s value; on a later bar of the span it is max(previous result, receiver’s value) with Go’s builtin max; before the first event it is NaN. So a NaN in the span gives NaN from that bar until the next event restarts the span, as Highest gives NaN while a NaN is in its window; max prefers +0 over -0, the same ordering as Highest; and infinities are ordinary values.
The result is NaN until the first event, and NaN rather than 0 because the start depends on the data. The span is latched at events, so under a sliding slice of history the output depends on the first event inside the slice: bars before it read NaN, even where an earlier event lies outside the slice.
Sources: AmiBroker AFL HighestSince; and, for the confirmed pivots the latch is often applied to, the rolling-window rule of Tsinaslanidis and Zapranis, Technical Analysis for Algorithmic Pattern Recognition (Springer, 2016), ch. 2 (their pattern rules on the most recent pivots are in chs 5 and 6).
cond is right-aligned with the receiver at the most recent bar: the last values are paired, then the second-last, and so on. A cond longer than the receiver contributes only its last len(receiver) values, and a shorter cond gives the same result as cond with zeros prepended. Receiver bars before the overlap (and every bar, for an empty cond) see no event and so read NaN until the first paired event. Series are paired by position only; see “Time alignment” in the manual.
LowestSince
func (s Series) LowestSince(cond Series) Series
LowestSince returns, for each bar, the lowest value of the receiver from the most recent bar on which cond is an event up to the current bar. A value of cond is an event when it is non-zero and not NaN, so +Inf and -Inf are events while 0, -0 and NaN are not. The current bar counts as an event bar, the event bar is included in the span (on an event bar the result is the receiver’s own value, verbatim), and each event restarts the span.
The result is defined bit for bit by a recursion: on an event bar it is the receiver’s value; on a later bar of the span it is min(previous result, receiver’s value) with Go’s builtin min; before the first event it is NaN. So a NaN in the span gives NaN from that bar until the next event restarts the span, as Lowest gives NaN while a NaN is in its window; min prefers -0 over +0, the same ordering as Lowest; and infinities are ordinary values.
The result is NaN until the first event, and NaN rather than 0 because the start depends on the data. The span is latched at events, so under a sliding slice of history the output depends on the first event inside the slice: bars before it read NaN, even where an earlier event lies outside the slice.
Sources: AmiBroker AFL LowestSince; and, for the confirmed pivots the latch is often applied to, the rolling-window rule of Tsinaslanidis and Zapranis, Technical Analysis for Algorithmic Pattern Recognition (Springer, 2016), ch. 2 (their pattern rules on the most recent pivots are in chs 5 and 6).
cond is right-aligned with the receiver at the most recent bar: the last values are paired, then the second-last, and so on. A cond longer than the receiver contributes only its last len(receiver) values, and a shorter cond gives the same result as cond with zeros prepended. Receiver bars before the overlap (and every bar, for an empty cond) see no event and so read NaN until the first paired event. Series are paired by position only; see “Time alignment” in the manual.
SumSince
func (s Series) SumSince(cond Series) Series
SumSince returns, for each bar, the sum of the receiver from the most recent bar on which cond is an event up to the current bar. A value of cond is an event when it is non-zero and not NaN, so +Inf and -Inf are events while 0, -0 and NaN are not. The current bar counts as an event bar, the event bar is included in the span (on an event bar the result is the one-term sum of the receiver’s value, so -0 gives +0 as Sum(1) does), and each event restarts the sum.
The summation is compensated and uses the accumulator behind Sum, so at bar i, with e the latest event bar and L = i-e+1, the result equals Series(s[e:i+1]).Sum(L)[L-1], Sum over the span alone, bit for bit. A NaN in the span, or both +Inf and -Inf, gives NaN; otherwise any +Inf gives +Inf and any -Inf gives -Inf, until the next event restarts the sum.
The event bar is included, as in AmiBroker’s SumSince with incFirst = True. AmiBroker’s default is incFirst = False, which leaves the event bar out and gives 0 on it, so this method differs from AmiBroker’s default.
The result is NaN until the first event, and NaN rather than 0 because the start depends on the data. The sum is latched at events, so under a sliding slice of history the output depends on the first event inside the slice: bars before it read NaN, even where an earlier event lies outside the slice.
Sources: AmiBroker AFL SumSince; TradingView’s anchored ta.vwap for the inclusive event bar; and, for the confirmed pivots the latch is often applied to, the rolling-window rule of Tsinaslanidis and Zapranis, Technical Analysis for Algorithmic Pattern Recognition (Springer, 2016), ch. 2 (their pattern rules on the most recent pivots are in chs 5 and 6).
cond is right-aligned with the receiver at the most recent bar: the last values are paired, then the second-last, and so on. A cond longer than the receiver contributes only its last len(receiver) values, and a shorter cond gives the same result as cond with zeros prepended. Receiver bars before the overlap (and every bar, for an empty cond) see no event and so read NaN until the first paired event. Series are paired by position only; see “Time alignment” in the manual.
ValueWhen
func (s Series) ValueWhen(cond Series, back ...int) Series
ValueWhen returns the value of the receiver at the most recent bar on which cond is an event, held until the next event; with back it returns the value at an earlier event instead. A value of cond is an event when it is non-zero and not NaN, so +Inf and -Inf are events while 0, -0 and NaN are not. The current bar counts as an event bar: on an event bar the most recent event is that bar itself, so the result there is the receiver’s own value.
The value is sampled verbatim, including NaN, +Inf, -Inf and -0. A NaN in the receiver on an event bar is held like any other value and still counts as an occurrence, as measured on TradingView by the PyneCore runtime; values on non-event bars do not matter.
back selects the occurrence and is numbered from 0, as TradingView’s occurrence argument: 0 (the default) is the most recent event, 1 the one before it. AmiBroker’s n is 1-based, so the nseries back equals AmiBroker’s n minus 1. Only the first value of back is read; any further values are ignored. A back below zero is invalid and returns aligned zeros. Any non-negative back is valid, and one at or beyond the length of the receiver gives all NaN.
The result is NaN until the first event (until the (k+1)-th event when back is k), and NaN rather than 0 because the start depends on the data. The value is latched, so under a sliding slice of history the output depends on the first event inside the slice: bars before it read NaN, even where an earlier event lies outside the slice.
Sources: TradingView Pine Script v6 ta.valuewhen; AmiBroker AFL ValueWhen; and, for the confirmed pivots the latch is often applied to, the rolling-window rule of Tsinaslanidis and Zapranis, Technical Analysis for Algorithmic Pattern Recognition (Springer, 2016), ch. 2 (their pattern rules on the most recent pivots are in chs 5 and 6).
cond is right-aligned with the receiver at the most recent bar: the last values are paired, then the second-last, and so on. A cond longer than the receiver contributes only its last len(receiver) values, and a shorter cond gives the same result as cond with zeros prepended. Receiver bars before the overlap (and every bar, for an empty cond) see no event and so read NaN until the first paired event. Series are paired by position only; see “Time alignment” in the manual.