C/C++ Streaming API
The streaming API is built for live feeds: open a stream once, then feed it one bar at a time. The stream carries its state from bar to bar, so each new bar costs O(1) — and every value is bit-identical to what the batch function (TA_SMA, TA_RSI, …) would return by recomputing over the whole array.
Every TA function gets these calls:
| Call | When | Does |
|---|---|---|
TA_<NAME>_Open | once | validate params, consume warm-up history, return a stream + current value |
TA_<NAME>_Update | once per closed bar | commit one bar, return the new value |
TA_<NAME>_Peek | any time on the forming bar | evaluate a provisional bar without committing state |
TA_<NAME>_Close | once | free the stream |
One more call, OpenAndFill, writes array output instead of a single value — see Array-Fill Open below.
Additional utility functions are available.
Example (SMA)
TA_SMA_Stream *s;
double sma;
int period = 30;
int historyLen = 30; /* must be >= TA_SMA_Lookback(period) + 1 */
/* Seed with warm-up history. */
double history[30] = { /* ...your closing prices... */ };
if( TA_SMA_Open( &s, history, historyLen, period, &sma ) != TA_SUCCESS )
return; /* s is NULL on failure */
/* Each time a bar closes: */
TA_SMA_Update( s, newClose, &sma );
printf( "SMA = %f\n", sma );
/* Intra-bar, on the not-yet-closed bar (repeat as the price ticks): */
TA_SMA_Peek( s, formingClose, &sma ); /* state left unchanged */
TA_SMA_Close( s );Rules
- Warm-up.
Opensucceeds only ifhistoryLen >= TA_<NAME>_Lookback(params) + 1— with fewer bars there is no defined value yet. AfterOpen, the history buffer can be freed — the stream keeps everything it needs. - Closed vs forming bar.
Updatecommits state irreversibly, so use it only for closed bars.Peekreturns the exact valueUpdatewould, but without committing — call it as often as the forming bar ticks. - Parameters are fixed at
Open. Changing a parameter means a new stream. Unstable period and candle settings are first read atOpenand must not change during the stream's life. - Threads. A stream is single-writer: an
UpdateorTA_<NAME>_Advancemust not race with any other call on the same stream. Processing forks are possible by cloning the stream, and each clone becomes fully independent and can be updated concurrently.
Multi-input / multi-output
Inputs and outputs mirror the batch function — OHLCV in, one out-pointer per output:
/* Candlestick: OHLC in, one int out */
TA_CDLDOJI_Update( s, open, high, low, close, &outInteger );
/* MACD: one in, three out */
TA_MACD_Update( s, close, &macd, &signal, &hist );Array-Fill Open
Open and Update each write a single value per output. One more call writes a full array instead — the same shape the batch function would produce — while still opening the stream:
| Call | When | Does |
|---|---|---|
TA_<NAME>_OpenAndFill | once, instead of Open | like Open, but returns the output for every history bar |
double out[300]; /* one array per output */
int begIdx, nbElement;
TA_SMA_OpenAndFill( &s, history, historyLen, period,
&begIdx, &nbElement, out );
/* out[0 .. nbElement-1] is the SMA over all of history; then stream on: */
TA_SMA_Update( s, newClose, &sma );Utility Calls
| Call | When | Does |
|---|---|---|
TA_<NAME>_Value | any time | the value(s) at the last bar the stream counted, without recomputing |
TA_<NAME>_Clone | any time | an independent fork of the stream, at the same bar |
TA_<NAME>_OutRange | any time | the bars the stream has an output for — the batch range over the same bars |
TA_<NAME>_Advance | after a bar you will not feed | advances the OutRange without affecting any other internal state of the stream |
double v;
int begIdx, nbElement;
TA_SMA_Stream *fork = NULL;
TA_SMA_Value( s, &v ); /* the value at the last bar s counted */
TA_SMA_Clone( s, &fork ); /* independent from here on */
TA_SMA_OutRange( s, &begIdx, &nbElement ); /* the bars s has an output for */
TA_SMA_Advance( s ); /* a bar you skipped, counted */See Rules for when concurrent reads of these are safe.
Error model
| Call | Returns |
|---|---|
TA_<NAME>_Open / TA_<NAME>_OpenAndFill |
*stream is NULL. |
TA_<NAME>_Update / TA_<NAME>_Peek |
|
TA_<NAME>_Close | TA_SUCCESS; TA_<NAME>_Close(NULL) is a no-op |
TA_<NAME>_Value | TA_BAD_PARAM on a NULL stream or a NULL out-pointer for a required output. A declinable output may be NULL, and is then simply not written. |
TA_<NAME>_Clone | TA_BAD_PARAM on a NULL stream or a NULL clone; TA_ALLOC_ERR if any allocation fails. On either, *clone is NULL and the original is untouched. |
TA_<NAME>_OutRange | TA_BAD_PARAM on a NULL argument |
TA_<NAME>_Advance | TA_BAD_PARAM on a NULL argument; TA_OUT_OF_RANGE_END_INDEX once the range has reached bar TA_MAX_INDEX |
Discovering streamable functions
When driving TA-Lib through the abstraction layer, streamable functions carry the TA_FUNC_FLG_STREAM flag in their function info.