Changelog#
All notable changes to this project are documented in this file.
[Unreleased]#
0.12.0 - 2026-07-23#
Added#
BayesianRegression: online Bayesian univariate regression that emits a causal one-step-ahead predictive mean and standard deviation plus the current slope and intercept. Normal-Inverse-Gamma posterior (noise learned online, Student-t predictive) with exponential forgetting (com/span/halflife/alpha) and a weak prior, so estimates and intervals are defined from the first sample.Example notebook 16, "Supervised forecasting with
forecast_pairs": build a leak-safe training set, fit a least-squares model, check it out of sample, and tie the prediction into a backtest.
Fixed#
forecast_pairs(count=..., dropna=True)now also drops rows whose target is NaN (not only feature-warmup rows), matchingduration=mode, so it returns a clean training set.
Docs#
Documentation rewritten to the NumPy and scikit-learn voice. Removed the repeated batch-vs-live-stream property from per-operator docs and notebook closers (it is stated once, where streaming is the subject), the verification cells that only demonstrated equivalence, and the closing summary sections.
0.11.0 - 2026-07-22#
Added#
Backtesting: engines are renamed and reorganised into a
Backtest<DataModel><OrderDef>grid. The data model (Price, OHLC, Trades, L1, L1Trades) names the market feed; the order definition (Target, Orders) names the strategy's output contract. Eight engines fill eight of the ten cells of the 5x2 matrix;BacktestPriceOrdersandBacktestL1TradesTargetare intentionally not provided (seechoosing_a_backtest_engine).Target engines (
BacktestPriceTarget,BacktestOHLCTarget,BacktestTradesTarget,BacktestL1Target): receive a scalar target position each event, compute the delta to the current position, and take liquidity to reach it. The target is clamped to the static[min_position, max_position]cap before sizing the order.BacktestOHLCTargetdefers execution to the next bar's open (causal; no manual lag needed).BacktestTradesTargetandBacktestL1Targetexecute immediately against the current event.Orders engines (
BacktestOHLCOrders,BacktestTradesOrders,BacktestL1Orders,BacktestL1TradesOrders): receive a two-sided resting quote(bid_price, bid_size, ask_price, ask_size)each event plus the market data columns. Either or both sides can fill on the same event. A quote submitted already crossing the spread is a taker.New engines completing the useful grid cells:
BacktestOHLCTargetandBacktestOHLCOrders(replacingBacktestOHLC/BacktestOHLCMaker),BacktestTradesTargetandBacktestTradesOrders(replacingBacktestTrades/BacktestTradesMaker),BacktestL1TargetandBacktestL1Orders(replacingBacktestL1),BacktestL1TradesOrders(replacingBacktestL1Trades), andBacktestPriceTarget(replacingBacktestSignal).All engines accept
min_positionandmax_position(default unbounded). Fills are capped by a three-way minimum: order size, participation limit (where applicable), and remaining room to the position bound.MARKET/NaN/inf encoding shared across all engines: a finite price is a resting limit (maker);
NaNis a side-agnostic market order (taker);+inf/screamer.MARKETis a market buy (never-fill sell);-infis a market sell (never-fill buy).Docs:
choosing_a_backtest_enginegrid overview page with the 5x2 matrix, order-definition interfaces, MARKET encoding table, and fill-cap rule.SchmittTriggergains aninitiallatch seed (0.0,1.0, orNaN).Delay(duration)stream op: re-stamp each event's index by a time offset (the time-based counterpart ofLag). Requires an explicit index; lossless, 1:1, no warmup.screamer.supervised.forecast_pairs(X, y, count=|duration=): build a forecasting training set by lagging features to align with a future causal target. Returns(X_shifted, y, as_of);count=is event-based,duration=is time-based (usesDelay, needs an index). Fully causal (lags X, never leads y).
Changed (breaking)#
SchmittTriggernow seeds its latch withinitial(default0.0, low) instead ofNaN, so a signal that starts inside the dead band reads low during warmup rather thanNaN. Passinitial=nanto restore the previous undefined-until-first-crossing behavior; passinitial=1.0to start high.
0.10.0 - 2026-07-18#
Added#
Risk statistics:
RollingDownsideDeviation(downside semideviation, the Sortino denominator),RollingOmega(Omega ratio of gains to losses about a threshold), andRollingCVaR(historical Conditional Value-at-Risk / Expected Shortfall, the mean loss in the worst alpha tail; VaR is-RollingQuantile). Each with a reference page, a plotted example, and tests.Backtesting: a suite of five causal C++ engines named by the market data they consume, all sharing one accounting core (
detail::PnLAccount) and the[equity, pnl, position, cost]output schema. Fills follow one rule set: a trade or quote through your price fills the full remaining, a fill at your price ismin(remaining, participation_ratio * available_size), and a marketable order fills fully withtick_sizeslippage. Resting orders fill at their limit price (maker); an order submitted already crossing is a taker.BacktestSignal(2 inputs): marks a position signal to a price, with a fractionalspread(crossing cost) andfee.BacktestOHLC(6 inputs): a directional target-position strategy on OHLC bars, with market orders (fill at the open, crossing half thespread, payingtaker_fee) and limit orders ("touch"/"breach"of the bar range, payingmaker_fee); bars fill in full. Causal by design: the target decided on a bar's close is deferred and traded on the next bar, so no manual lag is needed.BacktestTrades(4 inputs): a resting limit order against the trade tape; a through-print sweeps the full order, an at-print fills aparticipation_ratioshare.BacktestL1(8 inputs): a two-sided maker against top-of-book quotes only. Fills are a documented heuristic:"breach"(default) fills on a through,"touch"adds a participation partial once per lock episode. Inventory cap,taker_fee, andtick_sizefor marketable orders.BacktestL1Trades(10 inputs): the preferred maker engine. Quotes mark the position, the trade tape drives fills (each trade on its own event row, so no fill-versus-cancel ambiguity), a quote cross with no explaining trade is the run-over fallback.BacktestReport(4 inputs, 6 outputs): the C++ node that turns an engine's[equity, pnl, position, cost]into the running report columns (dollar drawdown, cumulative cost, turnover, trade count, running max drawdown, and running Sharpe), so pure-C++ callers get the statistics too. Thebacktest_reporthelper wrapsBacktestReport, labeling its columns and reading the last row into a summary (total PnL, max drawdown, cost, turnover, trades, Sharpe). It returns plain dicts of numpy arrays and needs no pandas. Reference pages with plotted examples, tests, and two demo notebooks (a signal on bars, and the event-driven engines on a real tape).
[0.9.0] - 2026-07-17#
More microstructure: order-flow toxicity, book pressure, and spread decomposition, plus a re-classified docs taxonomy.
Added#
Microstructure tranche 2, order-flow toxicity and book features:
VPIN(Easley-Lopez de Prado-O'Hara 2012): order-flow toxicity over a self-contained volume clock (equal-volume buckets, boundary-splitting).MicroPrice(Stoikov 2018, first-order): the imbalance-weighted mid, a fair value that leans toward the thinner side of the book.QueueImbalance: L1 book (queue) imbalance, a documented synonym ofOFIapplied to resting bid/ask sizes.
Microstructure tranche 3, order-book flow and spread decomposition:
ContOFI(Cont-Kukanov-Stoikov 2014): the canonical order-flow imbalance from L1 book events, distinct from the trade-flowOFI.EffectiveSpread(2*|price - mid|) andRealizedSpread(the liquidity part kept after the price moves); their difference is the price-impact / adverse-selection component.
Each ships with a reference page, a plotted usage example, and tests.
Docs: the flat "Microstructure" function topic is split into four groups - Trade signing, Order-flow imbalance, Price impact & liquidity, and Order-flow arrivals - with "microstructure" kept as a search tag.
Docs: a third microstructure notebook (toxicity, book pressure, and spreads) covering VPIN, QueueImbalance, MicroPrice, ContOFI, and the effective/realized spread decomposition.
[0.8.0] - 2026-07-16#
Microstructure and order-flow operators, and the lazy Pipeline path moved into the C++ core.
Added#
Microstructure and order-flow operators, all implemented as C++ core nodes:
Trade signing:
TickRuleSign,LeeReadySign,SignedVolume, and the bar-levelBulkVolumeClassifier(BVC).Order flow:
OFI(order-flow imbalance) andRollingOrderImbalance.Price impact and liquidity:
RollingKyleLambda,EwKyleLambda,AmihudIlliquidity,RollSpread(Roll effective spread), and the BouchaudPropagator.Event intensity:
HawkesIntensity, a self-exciting arrival-rate model.
Two demo notebooks driven by a small committed real-data slice (six hours of Deribit BTC- and ETH-perpetual trades): order flow and trade signing, and price impact and liquidity.
Internal#
The lazy (Python-iterator)
Pipelinepath now runs in the C++ core. A C++ driver merges the input feeds, drives the compiled graph, and runs the multi-output watermark as-of join, replacing the previous Python driver. Thebatch == lazy == graphinvariant is now enforced by one implementation rather than by parallel ones agreeing. The k-way merge refills lazily, so it never reads further ahead than requested (safe for endless streams).Eager
combine_latestcoalesces per index in C++ (the Python dedup is gone), andsplitruns in C++.
[0.7.0] - 2026-07-12#
The v2 API: one consistent call shape, streams as plain tuples, and pipelines.
Changed (breaking)#
Stream operators are now CamelCase config-first classes, called like the functors as
Op(config)(data):Resample,Dropna,Select,Filter,CombineLatest,Merge. The lowercase function forms are removed from the public API.The
Streamclass is removed. A stream is a plain(values, index)tuple;to_pandas/from_pandasconvert to and from pandas.Dagis renamed toPipeline(from screamer import Pipeline).Resampletakesfreq=(a time window) orcount=(a number of arrivals), andagg=a functor or string. Theevery=,func=, andagg={dict}forms are gone; compose several reducers withCombineLatestinstead.replayandmulti_resampleare removed; compose the existing operators.
Added#
Comparison and logic operators:
GreaterThan,LessThan,GreaterEqual,LessEqual,Equal,NotEqual,And,Or,Not,Where,IsNan,IsFinite. These build the masks the newFiltergate consumes.Expanding whole-history statistics:
ExpandingMean,ExpandingVar,ExpandingStd,ExpandingSkew,ExpandingKurt,ExpandingSlope, and the runningExpandingSum/ExpandingMax/ExpandingMin/ExpandingProd.PosPart(max(x, 0)) andNegPart(max(-x, 0)).OHLC bar aggregations for
Resample:agg="ohlc","ohlcv","ohlcv2".
Internal#
All stream-operator compute moved into C++ (dropna, select, filter, and merge as graph nodes), so the Python bindings stay thin.
Fixed#
Clipvectorizes to SIMD min/max, about 2x faster; it had regressed to 2x slower thannp.clip.
[0.6.0] - 2026-07-06#
Multi-stream and pipeline infrastructure.
Added#
The streams layer, for aligning and reshaping feeds that do not tick together:
CombineLatest,Merge,Dropna,Filter,Select,split, and time- or count-basedResample.Pipelines (then named
Dag): wire operators into a reusable graph, run it in batch or live with identical results, serialize it to JSON, and visualize it as a text tree or Graphviz.Despiking functors:
RollingMedianAD,Hampel,ImpulseClip.A topic taxonomy and unified frontmatter across all function reference pages.
[0.5.0] - 2026-05-21#
Added#
SchmittTrigger, a hysteresis comparator.
Changed#
The
ignoreNaN policy is applied consistently across the library: aNaNinput is skipped and never corrupts a function's internal state.
[0.4.0] - 2026-05-20#
Changed (breaking - JSON consumers)#
screamer/data/help.jsonschema: the freeformbody_markdownfield has been removed and replaced with two structured fields:details(string) - markdown prose, guaranteed to contain no fenced code blocks. Use this when rendering the description / math / notes.examples(list of{language, caption, code}) - extracted code examples, one entry per### Captionheading in the source markdown.{eval-rst} .. plotly::directives are unwrapped to plain python.
Consumers that read
body_markdownmust switch todetails(and optionally renderexamplesseparately). No backwards-compatibility shim is provided.
Changed#
Function reference docs (
docs/functions_*/<Name>.md) now follow a canonical layout: prose lives under H2 sub-headings (Description, Formula, …), examples live under a single## ExamplesH2 with one### Captionper example. The sphinx-rendered pages adopt the same structure.
[0.3.0] - 2026-05-11#
This release more than doubles the indicator surface (67 → 153 exposed classes) and closes six of the seven roadmap sections. Almost every new class is cross-validated against TA-Lib, pandas, scipy, or pandas-ta-classic to floating-point precision; documented divergences (EMA convention, Cutler vs Wilder RSI) are pinned by tests so future drift fires. Full test suite: 2126 passing.
Added#
Dispatcher infrastructure#
Plan E (
N→Mdispatch) completed.FunctorBasenow supports any combination of multi-input + multi-output classes (1→1, N→1, 1→M, N→M). First consumers:Cart2Polar/Polar2Cart(2→2),KeltnerChannels(3→3),RollingLinearRegression(2→4).New shared primitives:
detail::MonotonicDeque<bool IsMax>(six+ classes share it),detail::WilderSmoother.Documented multi-output shape rule
output.shape == single_input.shape + (M,)with column-by-column pairing indocs/polymorphic_api.md.
Math#
Element-wise:
Floor,Ceil,Round(banker's rounding),Square,Cube,Sin,Cos,Atan,Asin,Acos,Identity,Hypot(2→1),Atan2(2→1).Linear2(a, b, c)- two-input affine combinationa*x + b*y + c, pairs withSign/Relu/Sigmoidfor compact composed expressions.Cart2Polar/Polar2Cart- 2→2 coordinate conversions; first consumers of the N→M dispatcher.
Misc / data transforms#
CumSum,CumProd,CumMax,CumMin-O(1)running reductions matching numpy.Diff2- second-order finite difference (discrete second derivative).Detrend(window)-x − rolling_mean(x).Momentum(k)- alias ofDiff(k)(TA-Lib'sMOM).
Rolling-window statistics#
RollingMad,RollingIqr,RollingRange- composition of existing primitives or sharper variants.RollingArgmin,RollingArgmax- window-offset of the rolling extremum (TA-Lib'sMININDEX/MAXINDEX).RollingRank,RollingPercentile- pandas-style position metrics with average tie rule.
Exponentially-weighted statistics#
EwCov,EwCorr,EwBeta- 2-input pair statistics. Matches pandasewm(adjust=True).cov / .corrbit-exactly. EwBeta follows the CAPM(target, regressor)convention.
Moving averages#
WMA- linearly-weighted moving average, O(1) per step via the identityW[t] − W[t−1] = w·x[t] − S[t−1].DEMA,TEMA- Mulloy's double/triple EMA compositions.TRIMA- triangular MA (SMA(SMA(x))).HullMA-WMA(2·WMA(n/2) − WMA(n), √n).KAMA- Kaufman Adaptive MA with O(1) per step; matches TA-Lib bit-exactly.
Momentum / oscillators#
MACD(1→3),WilliamsR(3→1),Stoch(3→2, fast and slow viasmooth_k),StochRSI(1→2),TRIX,BOP(4→1),CCI(3→1),UltimateOscillator(3→1),ADX(3→3 returning+DI/-DI/ADX).ROC,ROCP,ROCR- TA-Lib rate-of-change family.RollingRSIdefault changed to Wilder's smoothing (matches TA-Lib and pandas-ta);method="cutler"preserves the old Cutler form. Earlier versions diverged from TA-Lib'sRSIby ~11 RSI points -- now bit-exact.
Volatility / range#
Range-based volatility quartet: Parkinson, Garman-Klass, Rogers-Satchell, Yang-Zhang. Each ships in
VarandVolvariants, with rolling and EW smoothing (for the first three) -- 14 classes total.TrueRange,ATR(window),NATR(window)- Wilder's bar-aware volatility family.DonchianChannels(2→3),KeltnerChannels(3→3) - channel indicators.
Volume-aware#
RollingVWAP,OBV,AD,ADOSC,MFI- first volume-aware primitives in screamer; all bit-exact to TA-Lib counterparts (exceptADOSC, which inherits the documented EMA-convention divergence).
Performance / risk#
Drawdown,MaxDrawdown,RollingMaxDrawdown,RollingSharpe(window, periods_per_year),RollingSortino(window, ppy, target),RollingInfoRatio(window, ppy),RollingCalmar(window, ppy),RollingHitRate(window)- backtest-evaluation metrics. None of these are in TA-Lib; they're a real differentiator for screamer in trading pipelines.
Statistical / regression#
RollingAlpha- companion intercept toRollingBeta.RollingResidualStd- std of the per-barRollingSpread.RollingLinearRegression(2→4) - full OLS fit returning(slope, intercept, r², stderr). First 2→4 consumer of the N→M dispatcher.stderris the RMSE of residuals (standard error of estimate, not slope-stderr).RollingTSF- TA-Lib's Time-Series Forecast (regression vs time projected one step ahead), bit-exact totalib.TSF.RollingHurst(window, min_scale=4, method='rs')- rolling Hurst exponent via Anis-Lloyd corrected rescaled-range analysis at dyadic scales. Bit-exact to the reference Python implementation; ~0.5 on white noise, >0.5 on integrated processes.
Signal processing#
ButterHighpass,ButterBandpass,ButterBandstop- high-pass, band-pass, band-stop Butterworth IIR filters. Added the underlyinglp2hp_zpk/lp2bp_zpk/lp2bs_zpkZPK transformations so future Bessel/Cheby/Elliptic families also get all four btypes once their prototypes are written.MovingAverage(taps)- FIR with arbitrary user-supplied taps (pair withnp.hamming/np.kaiser/scipy.signal.firwin).KalmanFilter(process_var, observation_var)- scalar 1-D Kalman, O(1) per step.
Validation#
New
tests/test_third_party_alignment.pyruns against TA-Lib and pandas-ta-classic under the new optionalvalidationinstall group. Tests are skipped gracefully when the libraries are unavailable.New
docs/conventions.mddocuments the few deliberate divergences (EMAadjust=Truevs TA-Lib's adjust=False + SMA seed;ddof=1vs ddof=0 inRollingStd; Wilder vs Cutler RSI). Each divergence is asserted in the expected direction so future drift in either screamer or the third-party library trips the test.
Changed#
RollingRSIdefault is now Wilder smoothing (was Cutler);method="cutler"preserves the previous behaviour.Pre-existing pending items now part of this release: general- order Butterworth filter,
RollingOU, refactored devtools.
Version v0.1.46 (2024-11-02)#
Added#
RollingSigmaClip
Relu
Elu
Selu
Sigmoid
Tanh
Softsign
Linear
Power
Version v0.1.35 (2024-11-01)#
Improved documentation
Version v0.1.34 (2024-10-31)#
Version v0.1.33 (2024-10-31)#
Added#
Data handeling#
fillna
ffill
clip
Math#
Abs
Sign
Exp
Log
Sqrt
Erf
Erfc
Simple transforms#
Diff
Lag
Return
LogReturn
Rolling window functions#
rolling std
rolling skew
rolling kurtosis
rolling zscore
rolling min
rolling max
rolling median
rolling quantile
rolling rms
rolling poly1, 1rst order polynomial fit
rolling poly2, 2nd order polynomial fit
Exponentiually weighted functions#
EwMean
EwStd
EwVar
EwSkew
EwKurt
EwRms
Filters#
2nd order Butterworth
Interface#
support for iterator / generator processing
Fixed#
Fixed incorrect results when applying transforms to a view on a numpy array.
Changed#
removed the transform member functions
Version v0.1.32 (2024-10-20)#
Added#
Differences, Simple Return, Log Return, Rolling Sum, Simple Moving Average
Changed#
removed initial_value from the constructor, we (for now) return NaN values when we cant resolve indicators.
Version v0.1.31 (2024-10-20)#
Added#
The indicator.transform() member functions can now transform multi-dimensional numpy arrays.
Added documentation.