Skip to content

amihud_illiquidity nulls a whole window for one untraded bar #31

Closed

Description

@stefan-jansen

features/microstructure/amihud_illiquidity.py:198-199 nulls the bar where dollar volume is zero
and then takes rolling_mean(period) over that series:

    .otherwise(None)
    .rolling_mean(period)

Polars' rolling_mean propagates nulls, so one untraded bar nulls the whole following window,
not just itself.

Measured

Called with period=30 on a NASDAQ-100 minute panel, 2020-01-02 to 2020-03-31, 2,074,372 rows:

Column Null share
illiq 9.08%
dollar_vol (the underlying, null only on the bar itself) 0.64%

0.64% of bars are untraded and 9.08% of rows carry no Amihud value: a ~14x amplification, which is
period acting on isolated gaps.

Why this is a defect and not a convention choice

Amihud (2002) defines ILLIQ as the average of |R_d| / DVOL_d over the D days the stock traded in
the period
- the sum is over traded days and the denominator is their count. The implementation
instead requires every bar in the window to have traded.

On daily equity data the two agree, because a listed name trades every day. On intraday data they do
not, which is where the 14x appears.

Suggested direction

Give the rolling mean min_periods (or skip nulls) so the average is taken over the bars in the
window that traded, matching the definition. That is a behaviour change for any caller with gaps, so
the docstring should state which convention is used.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions