LeeReadySign#
Description#
LeeReadySign classifies each trade as buyer-initiated (+1) or
seller-initiated (-1) using the Lee-Ready (1991) algorithm. The rule has
two steps.
Quote test: if the trade price is above the mid-quote, it is a buy (
+1); if it is below, it is a sell (-1).Tick-rule fallback: if the trade price equals the mid-quote exactly, the sign of the most recent price change is used instead (the tick rule). An up-tick is a buy; a down-tick is a sell; an unchanged tick carries the previous sign.
LeeReadySign()(price, mid) returns the signed series. The tick-rule fallback
state advances on every price (not only at-mid samples), so the classification
is consistent between whole-array and one-sample-at-a-time driving.
A missing price or mid (NaN) yields NaN
(nan_policy: ignore).
Return value: an array of +1.0 and -1.0 trade signs (or NaN where
input is missing). The first sample is NaN when the tick-rule fallback is
needed at index 0 (no prior price to compute a tick direction).
Reference: Lee, C. M. C., and Ready, M. J. (1991). "Inferring Trade Direction from Intraday Data." Journal of Finance, 46(2), 733-746.
Examples#
Usage plot#
import numpy as np
import plotly.graph_objects as go
from plotly.subplots import make_subplots
from screamer import LeeReadySign
rng = np.random.default_rng(1)
n = 200
mid = 100 + np.cumsum(rng.standard_normal(n) * 0.05)
price = mid + rng.choice([-0.5, 0.5], size=n) # trades at the bid or the offer
sign = LeeReadySign()(price, mid)
fig = make_subplots(rows=2, cols=1, shared_xaxes=True, row_heights=[0.7, 0.3],
vertical_spacing=0.08)
fig.add_trace(go.Scatter(y=price, mode='markers', name='trade price',
marker=dict(color='lightslategray', size=4)), row=1, col=1)
fig.add_trace(go.Scatter(y=mid, mode='lines', name='mid',
line=dict(color='steelblue')), row=1, col=1)
fig.add_trace(go.Scatter(y=sign, mode='lines', line_shape='hv', name='Lee-Ready sign',
line=dict(color='crimson')), row=2, col=1)
fig.update_layout(title='LeeReadySign: buy above the mid, sell below',
yaxis=dict(title='price'), yaxis2=dict(title='sign', dtick=1),
margin=dict(l=20, r=20, t=60, b=20), legend=dict(orientation='h', yanchor='bottom', y=1.02, xanchor='right', x=1))
fig.show()