Error Handling and Validation
ferro-ta uses a consistent error model so you can catch and handle failures in a predictable way.
Exception hierarchy
All ferro-ta–specific exceptions inherit from ferro_ta.FerroTAError and the
corresponding built-in type so that existing except ValueError code keeps
working:
FerroTAError — base for all ferro-ta exceptions
FerroTAValueError — invalid parameter values (e.g.
timeperiod < 1,fastperiod >= slowperiodfor MACD). Inherits fromValueError.FerroTAInputError — invalid input arrays (mismatched lengths, wrong shape, or opt-in strict checks). Inherits from
ValueError.
Example:
from ferro_ta import SMA, FerroTAValueError, FerroTAInputError
try:
SMA(close, timeperiod=0)
except FerroTAValueError as e:
print(e) # "timeperiod must be >= 1, got 0"
try:
SMA(open_arr, timeperiod=5) # if open_arr has different length
except FerroTAInputError as e:
print(e)
Validation in wrappers
Every indicator wrapper validates parameters and inputs before calling the Rust engine:
Period parameters (e.g.
timeperiod,fastperiod,slowperiod) are checked withferro_ta.exceptions.check_timeperiod()and must be >= 1 (or >= 2 where the algorithm requires it, e.g. MAVPminperiod).Multiple arrays (e.g. open, high, low, close, volume) are checked with
ferro_ta.exceptions.check_equal_length()so all have the same length.
Any error raised by the Rust extension (e.g. invalid value or bad array) is
re-raised as FerroTAValueError or FerroTAInputError with the same
message, so you can rely on the ferro-ta exception hierarchy.
NaN and Inf
By default, ferro-ta propagates NaN and Inf in input arrays: output values that depend on a NaN/Inf input will themselves be NaN/Inf. No exception is raised for NaN or Inf in the input.
For running sums and recursions this is permanent, exactly as in TA-Lib: one
NaN in the middle of a series turns every later value of SMA, EMA,
RSI, MACD, STOCH (and the other moving averages) into NaN, because
sum - NaN and alpha * NaN never recover.
nan_policy="skip"
The moving averages (SMA, EMA, WMA, DEMA, TEMA,
TRIMA, KAMA, T3), BBANDS, MACD, RSI, STOCH and
ATR take nan_policy="skip": rows with a non-finite value in any input
are dropped, the indicator runs on the remaining rows, and NaN is written back
at the dropped rows. Output stays the input’s length and recovers right after
the bad bar.
import numpy as np
import ferro_ta as ft
close = np.arange(1.0, 21.0)
close[5] = np.nan
ft.SMA(close, 3) # NaN from index 5 onward (TA-Lib)
ft.SMA(close, 3, nan_policy="skip") # NaN only at index 5; recovers
"skip" is the same rule the streaming classes apply to a bad tick, so a
batch result with nan_policy="skip" matches feeding the same data through
StreamingSMA etc. bar by bar. The default stays "propagate" for TA-Lib
parity.
If you need strict behaviour (no NaN/Inf), call
ferro_ta.exceptions.check_finite() on your arrays before passing them to
an indicator.
Empty and short arrays
Indicators that require a minimum number of bars (e.g. SMA with timeperiod=5
needs at least 5 elements) may return an array of NaN or raise if the Rust layer
rejects the input. You can use ferro_ta.exceptions.check_min_length() to
enforce a minimum length before calling an indicator.
Helper reference
ferro_ta.exceptions.check_timeperiod()— raise if a period parameter is below minimumferro_ta.exceptions.check_equal_length()— raise if supplied arrays have different lengthsferro_ta.exceptions.check_finite()— raise if an array contains NaN or Inf (opt-in strict)ferro_ta.exceptions.check_min_length()— raise if an array is shorter than required
See the ferro_ta.exceptions API for full signatures and examples.