Skip to main content

Trade Classification With Python

GitHubActions codecov Quality Gate Status

Logo

Documentation ✒️: https://karelze.github.io/tclf/

Source Code 🐍: https://github.com/KarelZe/tclf

tclf is a scikit-learn-compatible implementation of trade classification algorithms to classify financial markets transactions into buyer- and seller-initiated trades.

The key features are:

  • Easy: Easy to use and learn.
  • Sklearn-compatible: Compatible to the sklearn API. Use sklearn metrics and visualizations.
  • Feature complete: Wide range of supported algorithms. Use the algorithms individually or stack them like LEGO blocks.
  • DataFrame-agnostic: Works with any narwhals-compatible DataFrame, including pandas, Polars, and cuDF.

Installation

pip

pip install tclf

uv⚡

uv add tclf

Supported Algorithms

  • (Rev.) CLNV rule1
  • (Rev.) EMO rule2
  • (Rev.) LR algorithm3
  • (Rev.) Tick test4
  • Depth rule5
  • Quote rule6
  • Tradesize rule5

For a primer on trade classification rules visit the rules section 🆕 in our docs.

Minimal Example

Let's start simple: classify all trades by the quote rule and all other trades, which cannot be classified by the quote rule, randomly.

tclf accepts any narwhals-compatible DataFrame — pandas, Polars, cuDF, and more — as well as plain numpy arrays.

Polars

import polars as pl

from tclf.classical_classifier import ClassicalClassifier

X = pl.DataFrame({
    "trade_price": [1.5, 2.5, 1.5, 2.5, 1.0, 3.0],
    "bid_ex": [1.0, 1.0, 3.0, 3.0, None, None],
    "ask_ex": [3.0, 3.0, 1.0, 1.0, 1.0, None],
})

clf = ClassicalClassifier(layers=[("quote", "ex")], strategy="random")
clf.fit(X)
probs = clf.predict_proba(X)

pandas

import numpy as np
import pandas as pd

from tclf.classical_classifier import ClassicalClassifier

X = pd.DataFrame(
    [
        [1.5, 1, 3],
        [2.5, 1, 3],
        [1.5, 3, 1],
        [2.5, 3, 1],
        [1, np.nan, 1],
        [3, np.nan, np.nan],
    ],
    columns=["trade_price", "bid_ex", "ask_ex"],
)

clf = ClassicalClassifier(layers=[("quote", "ex")], strategy="random")
clf.fit(X)
probs = clf.predict_proba(X)

Run your script with

$ python main.py

In this example, input data has columns conforming to our naming conventions.

The parameter layers=[("quote", "ex")] sets the quote rule at the exchange level and strategy="random" specifies the fallback strategy for unclassified trades.

Advanced Example

Often it is desirable to classify both on exchange level data and nbbo data. Also, data might only be available as a numpy array. So let's extend the previous example by classifying using the quote rule at exchange level, then at nbbo and all other trades randomly.

import numpy as np
from sklearn.metrics import accuracy_score

from tclf.classical_classifier import ClassicalClassifier

X = np.array([
    [1.5, 1, 3, 2, 2.5],
    [2.5, 1, 3, 1, 3],
    [1.5, 3, 1, 1, 3],
    [2.5, 3, 1, 1, 3],
    [1, np.nan, 1, 1, 3],
    [3, np.nan, np.nan, 1, 3],
])
y_true = np.array([-1, 1, 1, -1, -1, 1])
features = ["trade_price", "bid_ex", "ask_ex", "bid_best", "ask_best"]

clf = ClassicalClassifier(
    layers=[("quote", "ex"), ("quote", "best")], strategy="random", features=features
)
clf.fit(X)
acc = accuracy_score(y_true, clf.predict(X))

In this example, input data is available as np.arrays with both exchange ("ex") and nbbo data ("best"). We set the layers parameter to layers=[("quote", "ex"), ("quote", "best")] to classify trades first on subset "ex" and remaining trades on subset "best". Additionally, we have to set ClassicalClassifier(..., features=features) to pass column information to the classifier.

Like before, column/feature names must follow our naming conventions.

Other Examples

For more practical examples, see our examples section.

Development

We are using uv for development. uv sync creates a virtual environment with all development dependencies.

uv sync                                      # install package and dev dependencies
uv run pytest                                # run tests
uv run ruff check src tests                  # lint
uv run ruff format src tests                 # format
uv run ty check src                          # type check
uv run prek run --all-files                  # run prek hooks
uv run zensical serve                        # serve docs at http://localhost:8000
uv build                                     # build distribution

Citation

If you are using the package in publications, please cite as:

@software{bilz_tclf_2023,
    author = {Bilz, Markus},
    license = {BSD 3},
    month = nov,
    title = {{tclf} -- trade classification with python},
    url = {https://github.com/KarelZe/tclf},
    version = {0.4.0},
    year = {2023}
}

Footnotes

  1. Chakrabarty, B., Li, B., Nguyen, V., & Van Ness, R. A. (2007). Trade classification algorithms for electronic communications network trades. Journal of Banking & Finance, 31(12), 3806–3821. https://doi.org/10.1016/j.jbankfin.2007.03.003
    ↩
  2. Ellis, K., Michaely, R., & O’Hara, M. (2000). The accuracy of trade classification rules: Evidence from nasdaq. The Journal of Financial and Quantitative Analysis, 35(4), 529–551. https://doi.org/10.2307/2676254
    ↩
  3. Lee, C., & Ready, M. J. (1991). Inferring trade direction from intraday data. The Journal of Finance, 46(2), 733–746. https://doi.org/10.1111/j.1540-6261.1991.tb02683.x
    ↩
  4. Hasbrouck, J. (2009). Trading costs and returns for U.s. Equities: Estimating effective costs from daily data. The Journal of Finance, 64(3), 1445–1477. https://doi.org/10.1111/j.1540-6261.2009.01469.x
    ↩
  5. Grauer, C., Schuster, P., & Uhrig-Homburg, M. (2023). Option trade classification. https://doi.org/10.2139/ssrn.4098475
    ↩ ↩2
  6. Harris, L. (1989). A day-end transaction price anomaly. The Journal of Financial and Quantitative Analysis, 24(1), 29. https://doi.org/10.2307/2330746
    ↩

Metadata

Release files for tclf 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tclf 0.4.0
File Size Uploaded Provenance
tclf-0.4.0.tar.gz 12.7 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for tclf 0.4.0
File Interpreter ABI Platform
tclf-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 24.7 kB

Release files / tclf-0.4.0.tar.gz

Download URL tclf-0.4.0.tar.gz
Size 12.7 kB
Tags Source
SHA-256 checksum
How to use checksums
75d4681b99171d68913676418ea7ae4ec3263631143085789238e8e9ad05ea50
BLAKE2b-256 checksum
How to use checksums
ed23068c6dc05999ec3331e68f198b03f23cf6cbfc530fe8f8e07be211ef2571
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

Release files / tclf-0.4.0-py3-none-any.whl

Download URL tclf-0.4.0-py3-none-any.whl
Size 12.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5b04072839556aba1b2a766dcb2851dfef92f963c4e7d04d1b251863372fc694
BLAKE2b-256 checksum
How to use checksums
2944e6d4fb197af57152a91bdcef46aedc2ed9b98eedb2258dd4ff8f9f070156
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

Security for tclf 0.4.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for tclf-0.4.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page