Specification
TA-Lib's calling contract, stated rule by rule for a robust integration. Every rule is enforced by the test suite, so your code can rely on it.
Written as a reference for AI agents integrating TA-Lib. For a lighter introduction written for people, start with the API pages for C/C++, Rust, Java or C#.
The rules use C's spelling. This page maps that shared vocabulary onto the other languages.
An AI agent is expected to read the code for exact signatures and names. The specification states the invariants: behaviour an integrator can rely on across languages and releases.
Scope
- The native APIs (C, Rust, Java, C#): batch, lookback, display shift, streams, settings, and the Abstract API.
- A wrapper keeps its own conventions. ta-lib-python aligns outputs to the input and fills the warm-up with NaN; the native APIs do not (rW3).
- Owned by other pages: Install (packages and versions), Unstable Period, Candlestick Settings (model and defaults), streaming in C, Rust, Java and C#, Numerical Stability, and the function pages: inputs, outputs in order, parameters (type, default, accepted values), stability category, flags.
- The pages other than the per-function pages are in /llms-full.txt; its function index links each function page. /llms.txt indexes every page. Each page has a Markdown twin; this page's is
/spec/index.md.
Rule pages
In the order a caller meets them:
| Page | Covers | Rule families |
|---|---|---|
| Batch Inputs and Outputs | what a call takes, what a successful call writes, pattern outputs, computing in place | rP parameters, rW writes |
| Lookback and Shift | lookback call, what enters it, display shift, stability from metadata | rL lookback |
| Auto-Stabilization | the bars an Auto level adds for each id, what a level targets, the known exceptions | rZ Auto-Stabilization |
| Streaming | bit-identity with batch, opening, advancing, accessors | rH handle behaviour, rS stream opening, rU update |
| Abstract API and Metadata | what the Abstract API provides, its rules and return codes, run-time information, the catalog of metadata flags | rA Abstract API |
| Settings and Threads | C lifecycle and settings, Core, setting validation, threads | rT settings and threads |
| Errors | return codes, batch conditions | rE errors, rB batch conditions |
| Versions and Determinism | bit-identity across languages and equivalent calls; releases | rD determinism, rV versions |
Each page has two kinds of statement:
- The caller must: what the calling code has to ensure. Most of it is not checked by the library, so it comes first on every page, and the next section lists what the library never reports.
- A rule: what TA-Lib does. Every rule is enforced by the test suite. Its id is
r, the letter of its family and a number, such asrB5, and its anchor is the id in lower case: /spec/errors/#rb5. An id's meaning can change from one release to the next.
<N> stands for a function's canonical name: TA_<N>_Open is TA_SMA_Open.
What is not detected
None of these is reported. The caller avoids them, or treats what follows as undefined.
- A buffer too short, in C: read or written past its end. Rust, Java and C# reject it.
- A buffer bound to a C parameter holder that is no longer valid when the holder is called.
- A C parameter holder or table never released, or released twice.
- NaN or infinity inside an input series, or inside the history a stream opens on.
- A real input outside ±3e37.
- Intermediate overflow on finite input.
- Buffers that partially overlap, in C.
- C used before
TA_Initializeor afterTA_Shutdown, orTA_Initializecalled twice. - A C setting changed while a TA function is running or a stream is open.
- A writer and any other call at once on one stream handle, or two threads on one parameter holder or builder (in Rust, the compiler rejects it).
- C's unstable-period getter given the set-all wildcard or an out-of-range id: it returns 0.
- The state after an allocation failure.
Names in each language
A function's canonical name is its name on /functions/. A fold changes only case and _; it adds no word boundary inside a segment:
| Fold | Rule | SMA | HT_TRENDLINE | CDL3BLACKCROWS |
|---|---|---|---|---|
| C | TA_ + canonical | TA_SMA | TA_HT_TRENDLINE | TA_CDL3BLACKCROWS |
| snake | lower case | sma | ht_trendline | cdl3blackcrows |
| UpperCamel | lower case, upper-case each _ segment's first letter, drop _ | Sma | HtTrendline | Cdl3blackcrows |
| lowerCamel | UpperCamel, first letter lower case | sma | htTrendline | cdl3blackcrows |
Rust uses snake for functions, UpperCamel for types; Java lowerCamel for methods, UpperCamel for types; C# UpperCamel. Messages and the Abstract API use the canonical name. Indicator parameters keep C's names everywhere (startIdx, inReal, optInTimePeriod, outReal).
Every function has this surface; in Rust, Java and C# the calls are methods of a Core:
| Surface | C | Rust | Java | C# |
|---|---|---|---|---|
| batch | TA_SMA | sma | sma | Sma |
| lookback | int TA_SMA_Lookback | sma_lookback returns Result<usize, RetCode> | int smaLookback | int SmaLookback |
| display shift of one output | int TA_SMA_DisplayShift | sma_display_shift returns Result<i32, RetCode> | int smaDisplayShift | int SmaDisplayShift |
| open, open and fill | TA_SMA_Open, TA_SMA_OpenAndFill | sma_open, sma_open_and_fill | smaOpen, smaOpenAndFill | SmaOpen, SmaOpenAndFill |
| handle | TA_SMA_Stream * | SmaStream | Core.SmaStream | Core.SmaStream |
| handle calls | TA_SMA_Update, _Peek, _Value, _OutRange, _Advance, _Clone, _Close | update, peek, value, out_range, advance, clone; drop to release | update, peek, value, outRange, advance, clone | Update, Peek, Advance, Clone; properties Value, OutRange |
| one bar of MACD | three out-pointers | (f64, f64, f64) | caller-owned Core.MacdOut sink | returned Core.MacdValue |
| Argument | C | Rust | Java | C# |
|---|---|---|---|---|
| index | int | usize | int | int |
| real input, output | const double[], double[] | &[f64], &mut [f64] | double[] | ReadOnlySpan<double>, Span<double> |
| integer output | int[] | &mut [i32] | int[] | Span<int> |
| integer, real parameter | int, double | i32, f64 | int, double | int, double |
| MA-type parameter | TA_MAType | MAType | MAType | MAType |
| absent (rB4) | NULL | an empty slice | null or an empty array | an empty span, which a null array becomes |
| Type | C | Rust | Java | C# |
|---|---|---|---|---|
| import | ta_libc.h | crate ta_lib | io.github.talib | TALib |
| settings: default, builder | process-wide (settings) | Core::new(), Core::builder() | Core.DEFAULT, Core.builder() | Core.Default, Core.Builder() |
| output range | outBegIdx, outNBElement | OutRange { beg_idx, count }, EMPTY, is_empty() | OutRange(begIdx, count), EMPTY, isEmpty() | OutRange(BegIdx, Count), Empty, IsEmpty |
Setters per language: Unstable Period, Candlestick Settings. C has no public candle-setting type: a setting is the arguments of TA_SetCandleSettings.
Enum types drop C's TA_. Members:
| Enum | C | Rust, C# | Java |
|---|---|---|---|
RetCode | TA_BAD_PARAM | BadParam | BAD_PARAM |
CandleSettingType | TA_BodyLong | BodyLong | BODY_LONG |
RangeType | TA_RangeType_RealBody | RealBody | REAL_BODY |
MAType | TA_MAType_SMA | SMA | SMA |
FuncUnstId | TA_FUNC_UNST_HT_DCPERIOD | HT_DCPERIOD | HT_DCPERIOD |
Constants: C prefixes TA_ (TA_INDEX_MAX); Rust, Java and C# hold them on Core, C# in UpperCamel (Core.IndexMax).
| Constant | Value |
|---|---|
INDEX_MAX | 100000000, the largest index |
UNSTABLE_AUTO_PREC_4 | INDEX_MAX + 4, an Auto level of the unstable period (rT3, rZ1) |
UNSTABLE_AUTO_PREC_8 | INDEX_MAX + 8, an Auto level of the unstable period |
REAL_DEFAULT | -4e37, selects a real parameter's default (rP3) |
INTEGER_DEFAULT | INT_MIN, selects an integer parameter's default |
REAL_MIN, REAL_MAX | -3e37, 3e37 (input domain) |
Metadata flags
One type holds the flags of each word. What each flag means: flags.
| Flags of | C prefix | Rust, Java | C# |
|---|---|---|---|
| a function | TA_FUNC_FLG_ | FuncFlags | FuncFlags |
| a price input | TA_IN_PRICE_ | InputFlags | PriceComponents |
| an optional parameter | TA_OPTIN_ | OptInputFlags | OptInputFlags |
| an output | TA_OUT_ | OutputFlags | OutputFlags |
Members are upper case in Rust and Java and UpperCamel in C#, and can use other words than C's: read them from the type. Each C# flag enum also has None, the empty word.
How a failure reaches the caller
| Success | C, returning TA_SUCCESS | Rust | Java | C# |
|---|---|---|---|---|
| batch | range in *outBegIdx, *outNBElement | Ok(OutRange) | OutRange | OutRange |
| open | handle in *stream, last value in the out-pointers | Ok((handle, value)) | handle | handle |
| open and fill | handle and range in out-pointers | Ok((handle, OutRange)) | handle; range from outRange() | handle; range from OutRange |
| update, peek | value in the out-pointers | Ok(value) | value, or written into the sink | value |
| Failure | C | Rust | Java | C# |
|---|---|---|---|---|
| carrier, code | returned TA_RetCode | Err(RetCode) | an exception implementing TALibFailure; retCode() | an exception implementing ITALibFailure; RetCode |
| C's number | the value | as_c_int() | asCInt() | (int) cast |
| lookback (rL2) | -1 | Err(RetCode::BadParam) | -1 | -1 |
| display shift (rL11) | INT_MIN | Err(RetCode::BadParam) | Integer.MIN_VALUE | int.MinValue |
One row per code a function call can report; the number in parentheses is C's, and it never changes (rV2). A : B means A extends the platform type B, so a catch of B works.
| Code | Rust | Java | C# |
|---|---|---|---|
TA_BAD_PARAM (2) | BadParam | TALibArgumentException : IllegalArgumentException | TALibArgumentException : ArgumentException |
TA_OUT_OF_RANGE_START_INDEX (12) | OutOfRangeStartIndex | TALibIndexException : IndexOutOfBoundsException | TALibArgumentOutOfRangeException : ArgumentOutOfRangeException |
TA_OUT_OF_RANGE_END_INDEX (13) | OutOfRangeEndIndex | TALibIndexException | TALibArgumentOutOfRangeException; TALibArgumentException from Update, Advance (rU4) |
TA_INSUFFICIENT_HISTORY (17) | InsufficientHistory | InsufficientHistoryException : TALibArgumentException | InsufficientHistoryException : TALibArgumentException |
TA_INTERNAL_ERROR (5000, rB9) | InternalError | TALibStateException : IllegalStateException | TALibInvalidOperationException : InvalidOperationException |
TA_ALLOC_ERR (3) | AllocErr, never returned (rB8) | never thrown | never thrown |
Failed settings:
| Failure | C | Rust | Java | C# |
|---|---|---|---|---|
| setter (rT2) | returns TA_BAD_PARAM | build() returns Err(RetCode::BadParam) (rT8) | throws IllegalArgumentException (NullPointerException on null), no code | throws ArgumentOutOfRangeException, no code |
| getter (rT4) | cannot fail | returns Err(RetCode::BadParam) | as the setter | as the setter |