Screamer
Screamer is a high-performance Python library for time series analysis, designed for speed, accuracy, and versatility in handling both NumPy arrays and streaming data.
pip install screamer
Easy to use, and powerfull
The 3-lines-of-code example below shows a stream processor that fits a trendline to a sliding window of the last 50 values. It then returns the slope of this fitted line. This slope is fed into a second stream processor, which outputs the sign of the slope, indicating the trend direction (upward or downward).
from screamer import RollingPoly2, Sign
slope = RollingPoly2(window_size=50, derivative_order=1)
sign = Sign()
result = sign(slope(data))
The plot below shows the input data (top, blue), the slope calculated over the previous 50 samples (middle, orange), and the sign of the slope (bottom, red).
Build for speed
Engineered in C++ with state-of-the-art numerical algorithms, Screamer delivers exceptional computational efficiency, consistently outperforming traditional libraries like NumPy and Pandas—often by factors of two or more, and in some cases by orders of magnitude.
Streaming- or batch- processing
Screamer seamlessly handles both batch and streaming data with the same code, producing identical results regardless of the data source. This design means that models tested offline on batch datasets will perform exactly the same when deployed with live streaming data, providing confidence in the consistency and reliability of your results.
Screamer’s streaming design ensures that all transformations are naturally free from look-ahead bias, guaranteeing accurate and reliable results
Mini Tutorial
Using screamer Functions
screamer functions share a common structure with function-specific settings.
First, create a
screamerfunction object by specifying the parameters for data transformation. For example,obj = RollingMean(30)creates an object to apply a 30-step moving average to the input data.Next, pass either streaming data (
obj(datafeed)) or batch data (obj(dataset)) to this object. It will then process each data element as specified.screamerfunctions return data in the same format as the input. A NumPy array input returns a NumPy array of the same size, while a Python generator input returns a generator that yields transformed elements.
The screamer library’s unified interface supports both batch and streaming data, making it easy to transition from backtesting on historical datasets to live streaming deployment without modifying your code.
Example 1: Batch Processing with NumPy Arrays
This example shows the simplest use of screamer for batch processing a NumPy array with RollingMax. Given a one-dimensional array, RollingMax computes the rolling maximum over a specified window size, here set to 4. You can initialize the object once and apply it, or perform this in a single line with RollingMax(window_size=4)(data). This approach efficiently processes pre-loaded data with results returned as a new array.
# Sample data
data = np.random.normal(size=10)
print("Data:")
print(data)
Data:
[ 0.49671415 -0.1382643 0.64768854 1.52302986 -0.23415337 -0.23413696
1.57921282 0.76743473 -0.46947439 0.54256004]
The following code creates a screamer object to computes the rolling maximum over a sliding window of size 4.
# Create a screamer object
obj = RollingMax(window_size=4)
# Transform the data
result = obj(data)
or alternatively in a one-liner
# Create a screamer object and transform the data
result = RollingMax(window_size=4)(data)
The result is a numpy array with the same size as the input data. This is in general the case with all screamer transformations.
print("Result:")
print(result)
Result:
[0.49671415 0.49671415 0.64768854 1.52302986 1.52302986 1.52302986
1.57921282 1.57921282 1.57921282 1.57921282]
Example 2: Batch Processing Multi-Dimensional Arrays
For multi-dimensional arrays like matrices, screamer applies rolling operations column-by-column
as if they were independent vectors.

Using RollingMax of the following two column data will give the exact same result as applying it to
each column separately.
This method is particularly useful for time series data with multiple features, where each column (representing a feature) is transformed independently but remains synchronized across rows.
1# Sample data
2data = np.random.normal(size=(10, 2))
3
4# Process the multi-dimensional array with RollingMax
5result = RollingMax(window_size=4)(data)
Result:
[[ 0.49671415 -0.1382643 ]
[ 0.64768854 1.52302986]
[ 0.64768854 1.52302986]
[ 1.57921282 1.52302986]
[ 1.57921282 1.52302986]
[ 1.57921282 0.76743473]
[ 1.57921282 0.76743473]
[ 0.24196227 0.54256004]
[ 0.24196227 0.31424733]
[ 0.24196227 0.31424733]]
Example 3: Element-Wise Stream Processing
screamer functions support element-by-element processing for streaming applications. In this example, RollingMax calculates the rolling maximum for each new element as it arrives, using a window size of 4. Processing data sequentially enables real-time transformation without loading the entire dataset into memory, ideal for streaming use cases.
# Sample data
data = np.random.normal(size=10)
# Element-by-element processing
rolling_max = RollingMax(window_size=4)
for x in data:
y = rolling_max(x)
print(f'input: {x:.4f}, output: {y:.4f}')
input: 0.4967, output: 0.4967
input: -0.1383, output: 0.4967
input: 0.6477, output: 0.6477
input: 1.5230, output: 1.5230
input: -0.2342, output: 1.5230
input: -0.2341, output: 1.5230
input: 1.5792, output: 1.5792
input: 0.7674, output: 1.5792
input: -0.4695, output: 1.5792
input: 0.5426, output: 1.5792
Example 4: Using screamer Objects as Generators
screamer objects can act as generators for real-time data transformation. This example sets up RollingMax as a generator with a 4-element window, allowing it to compute the rolling maximum as elements arrive. This approach processes data as an iterable, suitable for large or streaming datasets where loading everything at once is impractical.
# Sample data
data = np.random.normal(size=10)
data_generator = iter(data)
# RollingMax as a generator
obj = RollingMax(window_size=4)
rolling_max_generator = obj(data_generator)
for x in rolling_max_generator:
print(f'{x:.4f}')
0.4967
0.4967
0.6477
1.5230
1.5230
1.5230
1.5792
1.5792
1.5792
1.5792
Example 5: Composing Generators
screamer supports chaining multiple generators for complex transformations. Here, Diff first applies a 3-point difference operation, and RollingMax then computes the rolling maximum on the results with a window size of 4. This composition processes each data element sequentially, making it efficient for streaming applications where memory conservation is key.
# Sample data
data = np.random.normal(size=10)
data_generator = iter(data)
# Compose Diff and RollingMax as chained generators
diff = Diff(3)
rmax = RollingMax(window_size=4)
chained_generator = rmax(diff(data_generator))
for x in chained_generator:
print(f'{x:.4f}')
nan
nan
nan
nan
nan
nan
1.0263
1.0016
1.0016
1.0016