Unstable Period
Some indicators need a warm-up before their output settles. The unstable period setting controls how many of those warm-up bars TA-Lib discards instead of reporting them.
Why it exists
Some indicators have "memory" — each output depends on the previous one, seeded from the start of the data. An Exponential Moving Average is the classic example: its value at a given bar depends on every bar before it. In practice the influence of the earliest bars decays quickly, so the result becomes stable after enough bars.
This is inherent to the algorithms, not something specific to TA-Lib — every implementation has to seed the recursion somewhere, and the earliest outputs are distorted by that seed. What TA-Lib adds is the ability to scrub those early values on every function call, so unstable data never gets injected into your application.
What to do
There are three distinct approaches, from the most common to the most rigorous:
Ignore the problem. This is what most users and most charting sites do, and it is relatively OK in practice: most people focus on the most recent bar, which by then has enough history behind it that the value has long since stabilized. The weakness is that nothing warns you when the assumption stops holding — a short series, or a back-test that acts on the earliest bars, will quietly use values that are off.
Provide extra history. Fetch more bars than you intend to use and treat the leading outputs as throwaway, so that even the first bar you actually act on has stabilized. This is application-level scrubbing: TA-Lib is left at its default (unstable period
0) and returns everything it can compute, while your code chooses what to drop.Have TA-Lib drop the unstable data. Set an unstable period and TA-Lib strips that many extra bars from the front of the output, on top of the function's normal lookback:
outBegIdxmoves forward and those unstable outputs never reach your code.
API
id selects which function to affect. The period sets how many warm-up bars that function discards — the larger the value, the later the first output. The default, 0, discards nothing: you get every value the function can compute.
The setting follows the function wherever it runs: whether you call it directly, or another indicator uses it internally. The EMA id therefore affects EMA itself and every indicator built on one, such as MACD and DEMA.
TA_RetCode TA_SetUnstablePeriod( TA_FuncUnstId id, unsigned int unstablePeriod );
unsigned int TA_GetUnstablePeriod( TA_FuncUnstId id );
/* Strip 30 extra bars from every EMA-based calculation: */
TA_SetUnstablePeriod( TA_FUNC_UNST_EMA, 30 );
/* Apply the same unstable period to ALL affected functions at once: */
TA_SetUnstablePeriod( TA_FUNC_UNST_ALL, 30 );use ta_lib::{Core, FuncUnstId};
// Strip 30 extra bars from every EMA-based calculation:
let core = Core::builder()
.unstable_period(FuncUnstId::Ema, 30)
.build();
// Apply the same unstable period to ALL affected functions at once:
let core = Core::builder()
.unstable_period(FuncUnstId::FuncUnstAll, 30)
.build();
let n = core.get_unstable_period(FuncUnstId::Ema); // read it backFunctions with an unstable period
These are the functions with an unstable period. Every binding covers the same set; only the spelling of the id differs (see the tabs above). Each language also has a wildcard that targets all of them at once.
ADX, ATR, CMO, DX, EMA, HT_DCPERIOD, HT_DCPHASE, HT_PHASOR, HT_SINE, HT_TRENDLINE, HT_TRENDMODE, KAMA, MAMA, MINUS_DI, MINUS_DM, NATR, PLUS_DI, PLUS_DM, RSI, T3.
The C enumeration is in ta_defs.h.