orderflow-metrics 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- orderflow_metrics-0.1.0/.gitignore +19 -0
- orderflow_metrics-0.1.0/CHANGELOG.md +31 -0
- orderflow_metrics-0.1.0/LICENSE +21 -0
- orderflow_metrics-0.1.0/PKG-INFO +209 -0
- orderflow_metrics-0.1.0/README.md +180 -0
- orderflow_metrics-0.1.0/pyproject.toml +53 -0
- orderflow_metrics-0.1.0/src/orderflow_metrics/__init__.py +105 -0
- orderflow_metrics-0.1.0/src/orderflow_metrics/bars.py +122 -0
- orderflow_metrics-0.1.0/src/orderflow_metrics/classify.py +64 -0
- orderflow_metrics-0.1.0/src/orderflow_metrics/efficiency.py +64 -0
- orderflow_metrics-0.1.0/src/orderflow_metrics/execution.py +92 -0
- orderflow_metrics-0.1.0/src/orderflow_metrics/fairvalue.py +30 -0
- orderflow_metrics-0.1.0/src/orderflow_metrics/imbalance.py +24 -0
- orderflow_metrics-0.1.0/src/orderflow_metrics/liquidity.py +29 -0
- orderflow_metrics-0.1.0/src/orderflow_metrics/ofi.py +40 -0
- orderflow_metrics-0.1.0/src/orderflow_metrics/orderbook.py +79 -0
- orderflow_metrics-0.1.0/src/orderflow_metrics/py.typed +0 -0
- orderflow_metrics-0.1.0/src/orderflow_metrics/scheduling.py +45 -0
- orderflow_metrics-0.1.0/src/orderflow_metrics/simulate.py +73 -0
- orderflow_metrics-0.1.0/src/orderflow_metrics/types.py +38 -0
- orderflow_metrics-0.1.0/src/orderflow_metrics/volatility.py +34 -0
- orderflow_metrics-0.1.0/src/orderflow_metrics/vpin.py +108 -0
- orderflow_metrics-0.1.0/tests/test_book_execution.py +114 -0
- orderflow_metrics-0.1.0/tests/test_core_metrics.py +145 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/).
|
|
4
|
+
This project follows [Semantic Versioning](https://semver.org/); pre-1.0 the
|
|
5
|
+
public API may still change between minor versions.
|
|
6
|
+
|
|
7
|
+
## [0.1.0] - 2026-08-10
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
- Initial release — a dependency-free Python port of the TypeScript
|
|
11
|
+
`orderflow-metrics` library, with full feature parity:
|
|
12
|
+
- **Order Flow Imbalance** (Cont–Kukanov–Stoikov 2014): `ofi`, `ofi_series`,
|
|
13
|
+
`ofi_contribution`.
|
|
14
|
+
- **Imbalance**: `depth_imbalance`, `trade_imbalance`.
|
|
15
|
+
- **VPIN** (Easley–López de Prado–O'Hara 2012): `vpin`, `bucket_by_volume`,
|
|
16
|
+
`bvc_buy_fraction`, `standard_normal_cdf`.
|
|
17
|
+
- **Execution / TCA**: `effective_spread`, `effective_half_spread`,
|
|
18
|
+
`realized_spread`, `price_impact`, `kyle_lambda`, `roll_spread`.
|
|
19
|
+
- **Fair value**: `mid`, `weighted_mid`, `relative_spread_bps`.
|
|
20
|
+
- **Trade-sign classification**: `tick_rule`, `lee_ready`.
|
|
21
|
+
- **Liquidity**: `amihud_illiquidity`.
|
|
22
|
+
- **Volatility**: `realized_variance`, `realized_volatility`,
|
|
23
|
+
`annualized_volatility`.
|
|
24
|
+
- **Market efficiency**: `autocorrelation`, `variance_ratio`.
|
|
25
|
+
- **Order book**: `OrderBook` reconstruction from incremental level updates.
|
|
26
|
+
- **Market-order simulation**: `simulate_market_order`.
|
|
27
|
+
- **Execution scheduling**: `twap`, `pov`.
|
|
28
|
+
- **Information-driven bars** (López de Prado 2018): `tick_bars`,
|
|
29
|
+
`volume_bars`, `dollar_bars`.
|
|
30
|
+
- pytest test suite, PEP 561 typing marker (`py.typed`), zero runtime
|
|
31
|
+
dependencies.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 RATE LTD (TwoWayMind)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: orderflow-metrics
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Dependency-free market-microstructure metrics in Python — OFI, VPIN, information-driven bars, price impact, Kyle's lambda, trade-sign classification, order-book reconstruction.
|
|
5
|
+
Project-URL: Homepage, https://twowaymind.com
|
|
6
|
+
Project-URL: Repository, https://github.com/twowaymind/orderflow-metrics
|
|
7
|
+
Project-URL: Issues, https://github.com/twowaymind/orderflow-metrics/issues
|
|
8
|
+
Author: TwoWayMind (RATE LTD)
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: dollar-bars,information-driven-bars,market-microstructure,ofi,order-book,order-flow-imbalance,quantitative-finance,trading,vpin
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Financial and Insurance Industry
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Topic :: Office/Business :: Financial :: Investment
|
|
24
|
+
Classifier: Typing :: Typed
|
|
25
|
+
Requires-Python: >=3.9
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
|
|
30
|
+
# orderflow-metrics (Python)
|
|
31
|
+
|
|
32
|
+
[](https://github.com/twowaymind/orderflow-metrics-py/actions/workflows/ci.yml)
|
|
33
|
+
[](https://pypi.org/project/orderflow-metrics/)
|
|
34
|
+
[](https://pypi.org/project/orderflow-metrics/)
|
|
35
|
+
[](LICENSE)
|
|
36
|
+
|
|
37
|
+
Dependency-free **market-microstructure metrics** in pure Python: Order Flow
|
|
38
|
+
Imbalance (OFI), VPIN, information-driven bars, transaction-cost / price-impact
|
|
39
|
+
metrics, trade-sign classification, limit-order-book reconstruction and
|
|
40
|
+
execution scheduling. No NumPy, no pandas — just the standard library.
|
|
41
|
+
|
|
42
|
+
This is the Python port of the TypeScript
|
|
43
|
+
[`orderflow-metrics`](https://github.com/twowaymind/orderflow-metrics) library,
|
|
44
|
+
with the same API surface in `snake_case`.
|
|
45
|
+
|
|
46
|
+
## Install
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install orderflow-metrics
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Usage
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
from orderflow_metrics import ofi, depth_imbalance, trade_imbalance, L1Quote, Trade
|
|
56
|
+
|
|
57
|
+
quotes = [
|
|
58
|
+
L1Quote(bid_price=100, bid_size=5, ask_price=101, ask_size=4),
|
|
59
|
+
L1Quote(bid_price=100, bid_size=8, ask_price=101, ask_size=1),
|
|
60
|
+
L1Quote(bid_price=100.5, bid_size=2, ask_price=101, ask_size=1),
|
|
61
|
+
]
|
|
62
|
+
ofi(quotes) # 8 (net buy-side pressure)
|
|
63
|
+
|
|
64
|
+
depth_imbalance(quotes[0]) # (5 - 4) / (5 + 4) ~ 0.111
|
|
65
|
+
|
|
66
|
+
trade_imbalance([Trade(100, 2, "buy"), Trade(100, 1, "sell")]) # 0.333
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Order Flow Imbalance
|
|
70
|
+
|
|
71
|
+
`ofi` implements the level-1 OFI of Cont, Kukanov & Stoikov (2014). OFI over a
|
|
72
|
+
window is the sum of per-event contributions; it counts size added to the bid
|
|
73
|
+
and removed from the ask (buy pressure) against the reverse, and is a strong
|
|
74
|
+
linear predictor of short-horizon price changes.
|
|
75
|
+
|
|
76
|
+
- `ofi_contribution(prev, curr)` — one transition
|
|
77
|
+
- `ofi_series(quotes)` — per-step contributions
|
|
78
|
+
- `ofi(quotes)` — cumulative
|
|
79
|
+
|
|
80
|
+
## VPIN
|
|
81
|
+
|
|
82
|
+
Volume-Synchronized Probability of Informed Trading (Easley, López de Prado &
|
|
83
|
+
O'Hara, 2012). Trades are grouped into equal-volume buckets; each bucket is
|
|
84
|
+
split into buy/sell volume by Bulk Volume Classification, and VPIN is the
|
|
85
|
+
average absolute imbalance over a rolling window.
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
from orderflow_metrics import bucket_by_volume, vpin
|
|
89
|
+
|
|
90
|
+
buckets = bucket_by_volume(trades, 1_000)
|
|
91
|
+
vpin(buckets, window=50) # flow toxicity in [0, 1]
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Execution cost & price impact
|
|
95
|
+
|
|
96
|
+
Transaction-cost analysis building blocks (buys `+1`, sells `-1`):
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
from orderflow_metrics import effective_spread, realized_spread, price_impact, kyle_lambda, FlowObservation
|
|
100
|
+
|
|
101
|
+
effective_spread(101, 100, "buy") # 2 — cost vs the midpoint
|
|
102
|
+
realized_spread(101, 100.5, "buy") # 1 — LP revenue after reversion
|
|
103
|
+
price_impact(100, 100.5, "buy") # 1 — permanent impact
|
|
104
|
+
|
|
105
|
+
kyle_lambda([
|
|
106
|
+
FlowObservation(price_change=1, signed_volume=2),
|
|
107
|
+
FlowObservation(price_change=-1, signed_volume=-2),
|
|
108
|
+
]) # 0.5 — price impact per unit signed flow
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Also: `effective_half_spread`, `roll_spread` (Roll 1984).
|
|
112
|
+
|
|
113
|
+
## Fair value
|
|
114
|
+
|
|
115
|
+
```python
|
|
116
|
+
from orderflow_metrics import weighted_mid, relative_spread_bps, L1Quote
|
|
117
|
+
|
|
118
|
+
weighted_mid(L1Quote(100, 9, 101, 1)) # ~100.9 — heavy bid pulls toward ask
|
|
119
|
+
relative_spread_bps(L1Quote(99.99, 1, 100.01, 1)) # 2 (bps)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Trade-sign classification
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
from orderflow_metrics import tick_rule, lee_ready, PriceVsMid
|
|
126
|
+
|
|
127
|
+
tick_rule([100, 101, 101, 100]) # [0, 1, 1, -1]
|
|
128
|
+
lee_ready([PriceVsMid(101, 100), PriceVsMid(99, 100)]) # [1, -1]
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Liquidity, volatility, efficiency
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
from orderflow_metrics import (
|
|
135
|
+
amihud_illiquidity, ReturnVolume,
|
|
136
|
+
realized_volatility, annualized_volatility,
|
|
137
|
+
variance_ratio, autocorrelation,
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
amihud_illiquidity([ReturnVolume(0.02, 100), ReturnVolume(-0.01, 50)]) # 0.0002
|
|
141
|
+
realized_volatility([0.03, 0.04]) # 0.05
|
|
142
|
+
variance_ratio(returns, 2) # <1 mean-reverting · ~1 random walk · >1 trending
|
|
143
|
+
autocorrelation(returns, 1) # lag-1 autocorrelation
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Order book & market-order simulation
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
from orderflow_metrics import OrderBook, simulate_market_order
|
|
150
|
+
|
|
151
|
+
ob = OrderBook()
|
|
152
|
+
ob.update("bid", 100, 5)
|
|
153
|
+
ob.update("ask", 101, 3)
|
|
154
|
+
ob.mid() # 100.5
|
|
155
|
+
ob.imbalance(1) # 0.25 — top-of-book size imbalance
|
|
156
|
+
ob.update("bid", 100, 0) # size 0 removes the level
|
|
157
|
+
|
|
158
|
+
r = simulate_market_order(ob, "buy", 4)
|
|
159
|
+
r.avg_price # volume-weighted fill price
|
|
160
|
+
r.slippage_bps # cost vs mid, in basis points
|
|
161
|
+
r.remaining_size # > 0 if the book was too thin
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
`OrderBook.mid()`, `spread()`, `best_bid()`, `best_ask()` return `None` on an
|
|
165
|
+
empty side.
|
|
166
|
+
|
|
167
|
+
## Information-driven bars
|
|
168
|
+
|
|
169
|
+
Sampling on **activity** rather than the clock — a bar every N ticks, N units of
|
|
170
|
+
volume, or N units of traded value — gives returns with far better statistical
|
|
171
|
+
properties (López de Prado, *Advances in Financial ML*, ch. 2). Build them
|
|
172
|
+
first, then run the other metrics on the resulting series.
|
|
173
|
+
|
|
174
|
+
```python
|
|
175
|
+
from orderflow_metrics import tick_bars, volume_bars, dollar_bars
|
|
176
|
+
|
|
177
|
+
tick_bars(trades, 100) # a bar per 100 trades
|
|
178
|
+
volume_bars(trades, 5_000) # a bar per 5,000 units of volume
|
|
179
|
+
dollar_bars(trades, 250_000) # a bar per $250k of traded value
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Each `Bar` carries `open`/`high`/`low`/`close`, `volume`, `dollar`, `vwap`,
|
|
183
|
+
`ticks`, and signed `buy_volume` / `sell_volume` (plus `start` / `end`
|
|
184
|
+
timestamps when the feed provides them). Dollar bars are usually preferred.
|
|
185
|
+
|
|
186
|
+
## Execution scheduling
|
|
187
|
+
|
|
188
|
+
```python
|
|
189
|
+
from orderflow_metrics import twap, pov
|
|
190
|
+
|
|
191
|
+
twap(100, 4) # [25, 25, 25, 25] — even time slices
|
|
192
|
+
pov(30, [100, 100, 100], 0.1) # [10, 10, 10] — 10% of each interval's volume
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## Tests
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
pip install -e ".[dev]"
|
|
199
|
+
pytest
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## License
|
|
203
|
+
|
|
204
|
+
MIT © RATE LTD (TwoWayMind). See [LICENSE](LICENSE).
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
Part of [TwoWayMind](https://twowaymind.com)'s open microstructure tooling.
|
|
209
|
+
Educational and technical material only — not investment advice.
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# orderflow-metrics (Python)
|
|
2
|
+
|
|
3
|
+
[](https://github.com/twowaymind/orderflow-metrics-py/actions/workflows/ci.yml)
|
|
4
|
+
[](https://pypi.org/project/orderflow-metrics/)
|
|
5
|
+
[](https://pypi.org/project/orderflow-metrics/)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
|
|
8
|
+
Dependency-free **market-microstructure metrics** in pure Python: Order Flow
|
|
9
|
+
Imbalance (OFI), VPIN, information-driven bars, transaction-cost / price-impact
|
|
10
|
+
metrics, trade-sign classification, limit-order-book reconstruction and
|
|
11
|
+
execution scheduling. No NumPy, no pandas — just the standard library.
|
|
12
|
+
|
|
13
|
+
This is the Python port of the TypeScript
|
|
14
|
+
[`orderflow-metrics`](https://github.com/twowaymind/orderflow-metrics) library,
|
|
15
|
+
with the same API surface in `snake_case`.
|
|
16
|
+
|
|
17
|
+
## Install
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pip install orderflow-metrics
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
from orderflow_metrics import ofi, depth_imbalance, trade_imbalance, L1Quote, Trade
|
|
27
|
+
|
|
28
|
+
quotes = [
|
|
29
|
+
L1Quote(bid_price=100, bid_size=5, ask_price=101, ask_size=4),
|
|
30
|
+
L1Quote(bid_price=100, bid_size=8, ask_price=101, ask_size=1),
|
|
31
|
+
L1Quote(bid_price=100.5, bid_size=2, ask_price=101, ask_size=1),
|
|
32
|
+
]
|
|
33
|
+
ofi(quotes) # 8 (net buy-side pressure)
|
|
34
|
+
|
|
35
|
+
depth_imbalance(quotes[0]) # (5 - 4) / (5 + 4) ~ 0.111
|
|
36
|
+
|
|
37
|
+
trade_imbalance([Trade(100, 2, "buy"), Trade(100, 1, "sell")]) # 0.333
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Order Flow Imbalance
|
|
41
|
+
|
|
42
|
+
`ofi` implements the level-1 OFI of Cont, Kukanov & Stoikov (2014). OFI over a
|
|
43
|
+
window is the sum of per-event contributions; it counts size added to the bid
|
|
44
|
+
and removed from the ask (buy pressure) against the reverse, and is a strong
|
|
45
|
+
linear predictor of short-horizon price changes.
|
|
46
|
+
|
|
47
|
+
- `ofi_contribution(prev, curr)` — one transition
|
|
48
|
+
- `ofi_series(quotes)` — per-step contributions
|
|
49
|
+
- `ofi(quotes)` — cumulative
|
|
50
|
+
|
|
51
|
+
## VPIN
|
|
52
|
+
|
|
53
|
+
Volume-Synchronized Probability of Informed Trading (Easley, López de Prado &
|
|
54
|
+
O'Hara, 2012). Trades are grouped into equal-volume buckets; each bucket is
|
|
55
|
+
split into buy/sell volume by Bulk Volume Classification, and VPIN is the
|
|
56
|
+
average absolute imbalance over a rolling window.
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
from orderflow_metrics import bucket_by_volume, vpin
|
|
60
|
+
|
|
61
|
+
buckets = bucket_by_volume(trades, 1_000)
|
|
62
|
+
vpin(buckets, window=50) # flow toxicity in [0, 1]
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Execution cost & price impact
|
|
66
|
+
|
|
67
|
+
Transaction-cost analysis building blocks (buys `+1`, sells `-1`):
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
from orderflow_metrics import effective_spread, realized_spread, price_impact, kyle_lambda, FlowObservation
|
|
71
|
+
|
|
72
|
+
effective_spread(101, 100, "buy") # 2 — cost vs the midpoint
|
|
73
|
+
realized_spread(101, 100.5, "buy") # 1 — LP revenue after reversion
|
|
74
|
+
price_impact(100, 100.5, "buy") # 1 — permanent impact
|
|
75
|
+
|
|
76
|
+
kyle_lambda([
|
|
77
|
+
FlowObservation(price_change=1, signed_volume=2),
|
|
78
|
+
FlowObservation(price_change=-1, signed_volume=-2),
|
|
79
|
+
]) # 0.5 — price impact per unit signed flow
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Also: `effective_half_spread`, `roll_spread` (Roll 1984).
|
|
83
|
+
|
|
84
|
+
## Fair value
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
from orderflow_metrics import weighted_mid, relative_spread_bps, L1Quote
|
|
88
|
+
|
|
89
|
+
weighted_mid(L1Quote(100, 9, 101, 1)) # ~100.9 — heavy bid pulls toward ask
|
|
90
|
+
relative_spread_bps(L1Quote(99.99, 1, 100.01, 1)) # 2 (bps)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Trade-sign classification
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
from orderflow_metrics import tick_rule, lee_ready, PriceVsMid
|
|
97
|
+
|
|
98
|
+
tick_rule([100, 101, 101, 100]) # [0, 1, 1, -1]
|
|
99
|
+
lee_ready([PriceVsMid(101, 100), PriceVsMid(99, 100)]) # [1, -1]
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Liquidity, volatility, efficiency
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
from orderflow_metrics import (
|
|
106
|
+
amihud_illiquidity, ReturnVolume,
|
|
107
|
+
realized_volatility, annualized_volatility,
|
|
108
|
+
variance_ratio, autocorrelation,
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
amihud_illiquidity([ReturnVolume(0.02, 100), ReturnVolume(-0.01, 50)]) # 0.0002
|
|
112
|
+
realized_volatility([0.03, 0.04]) # 0.05
|
|
113
|
+
variance_ratio(returns, 2) # <1 mean-reverting · ~1 random walk · >1 trending
|
|
114
|
+
autocorrelation(returns, 1) # lag-1 autocorrelation
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Order book & market-order simulation
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
from orderflow_metrics import OrderBook, simulate_market_order
|
|
121
|
+
|
|
122
|
+
ob = OrderBook()
|
|
123
|
+
ob.update("bid", 100, 5)
|
|
124
|
+
ob.update("ask", 101, 3)
|
|
125
|
+
ob.mid() # 100.5
|
|
126
|
+
ob.imbalance(1) # 0.25 — top-of-book size imbalance
|
|
127
|
+
ob.update("bid", 100, 0) # size 0 removes the level
|
|
128
|
+
|
|
129
|
+
r = simulate_market_order(ob, "buy", 4)
|
|
130
|
+
r.avg_price # volume-weighted fill price
|
|
131
|
+
r.slippage_bps # cost vs mid, in basis points
|
|
132
|
+
r.remaining_size # > 0 if the book was too thin
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
`OrderBook.mid()`, `spread()`, `best_bid()`, `best_ask()` return `None` on an
|
|
136
|
+
empty side.
|
|
137
|
+
|
|
138
|
+
## Information-driven bars
|
|
139
|
+
|
|
140
|
+
Sampling on **activity** rather than the clock — a bar every N ticks, N units of
|
|
141
|
+
volume, or N units of traded value — gives returns with far better statistical
|
|
142
|
+
properties (López de Prado, *Advances in Financial ML*, ch. 2). Build them
|
|
143
|
+
first, then run the other metrics on the resulting series.
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
from orderflow_metrics import tick_bars, volume_bars, dollar_bars
|
|
147
|
+
|
|
148
|
+
tick_bars(trades, 100) # a bar per 100 trades
|
|
149
|
+
volume_bars(trades, 5_000) # a bar per 5,000 units of volume
|
|
150
|
+
dollar_bars(trades, 250_000) # a bar per $250k of traded value
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Each `Bar` carries `open`/`high`/`low`/`close`, `volume`, `dollar`, `vwap`,
|
|
154
|
+
`ticks`, and signed `buy_volume` / `sell_volume` (plus `start` / `end`
|
|
155
|
+
timestamps when the feed provides them). Dollar bars are usually preferred.
|
|
156
|
+
|
|
157
|
+
## Execution scheduling
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
from orderflow_metrics import twap, pov
|
|
161
|
+
|
|
162
|
+
twap(100, 4) # [25, 25, 25, 25] — even time slices
|
|
163
|
+
pov(30, [100, 100, 100], 0.1) # [10, 10, 10] — 10% of each interval's volume
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Tests
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
pip install -e ".[dev]"
|
|
170
|
+
pytest
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## License
|
|
174
|
+
|
|
175
|
+
MIT © RATE LTD (TwoWayMind). See [LICENSE](LICENSE).
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
Part of [TwoWayMind](https://twowaymind.com)'s open microstructure tooling.
|
|
180
|
+
Educational and technical material only — not investment advice.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "orderflow-metrics"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Dependency-free market-microstructure metrics in Python — OFI, VPIN, information-driven bars, price impact, Kyle's lambda, trade-sign classification, order-book reconstruction."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [{ name = "TwoWayMind (RATE LTD)" }]
|
|
13
|
+
keywords = [
|
|
14
|
+
"market-microstructure",
|
|
15
|
+
"order-flow-imbalance",
|
|
16
|
+
"ofi",
|
|
17
|
+
"vpin",
|
|
18
|
+
"order-book",
|
|
19
|
+
"information-driven-bars",
|
|
20
|
+
"dollar-bars",
|
|
21
|
+
"quantitative-finance",
|
|
22
|
+
"trading",
|
|
23
|
+
]
|
|
24
|
+
classifiers = [
|
|
25
|
+
"Development Status :: 4 - Beta",
|
|
26
|
+
"Intended Audience :: Financial and Insurance Industry",
|
|
27
|
+
"Intended Audience :: Science/Research",
|
|
28
|
+
"License :: OSI Approved :: MIT License",
|
|
29
|
+
"Operating System :: OS Independent",
|
|
30
|
+
"Programming Language :: Python :: 3",
|
|
31
|
+
"Programming Language :: Python :: 3.9",
|
|
32
|
+
"Programming Language :: Python :: 3.10",
|
|
33
|
+
"Programming Language :: Python :: 3.11",
|
|
34
|
+
"Programming Language :: Python :: 3.12",
|
|
35
|
+
"Programming Language :: Python :: 3.13",
|
|
36
|
+
"Topic :: Office/Business :: Financial :: Investment",
|
|
37
|
+
"Typing :: Typed",
|
|
38
|
+
]
|
|
39
|
+
dependencies = []
|
|
40
|
+
|
|
41
|
+
[project.optional-dependencies]
|
|
42
|
+
dev = ["pytest>=8"]
|
|
43
|
+
|
|
44
|
+
[project.urls]
|
|
45
|
+
Homepage = "https://twowaymind.com"
|
|
46
|
+
Repository = "https://github.com/twowaymind/orderflow-metrics"
|
|
47
|
+
Issues = "https://github.com/twowaymind/orderflow-metrics/issues"
|
|
48
|
+
|
|
49
|
+
[tool.hatch.build.targets.wheel]
|
|
50
|
+
packages = ["src/orderflow_metrics"]
|
|
51
|
+
|
|
52
|
+
[tool.pytest.ini_options]
|
|
53
|
+
testpaths = ["tests"]
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"""orderflow-metrics — dependency-free market-microstructure metrics in Python.
|
|
2
|
+
|
|
3
|
+
OFI, VPIN, information-driven bars, transaction-cost / price-impact metrics,
|
|
4
|
+
trade-sign classification, limit-order-book reconstruction, and execution
|
|
5
|
+
scheduling. Python port of the TypeScript library of the same name.
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from .bars import Bar, dollar_bars, tick_bars, volume_bars
|
|
10
|
+
from .classify import PriceVsMid, lee_ready, tick_rule
|
|
11
|
+
from .efficiency import autocorrelation, variance_ratio
|
|
12
|
+
from .execution import (
|
|
13
|
+
FlowObservation,
|
|
14
|
+
effective_half_spread,
|
|
15
|
+
effective_spread,
|
|
16
|
+
kyle_lambda,
|
|
17
|
+
price_impact,
|
|
18
|
+
realized_spread,
|
|
19
|
+
roll_spread,
|
|
20
|
+
)
|
|
21
|
+
from .fairvalue import mid, relative_spread_bps, weighted_mid
|
|
22
|
+
from .imbalance import depth_imbalance, trade_imbalance
|
|
23
|
+
from .liquidity import ReturnVolume, amihud_illiquidity
|
|
24
|
+
from .ofi import ofi, ofi_contribution, ofi_series
|
|
25
|
+
from .orderbook import BookSide, Level, OrderBook
|
|
26
|
+
from .scheduling import pov, twap
|
|
27
|
+
from .simulate import Fill, MarketOrderResult, simulate_market_order
|
|
28
|
+
from .types import L1Quote, Side, Trade
|
|
29
|
+
from .volatility import (
|
|
30
|
+
annualized_volatility,
|
|
31
|
+
realized_variance,
|
|
32
|
+
realized_volatility,
|
|
33
|
+
)
|
|
34
|
+
from .vpin import (
|
|
35
|
+
VolumeBucket,
|
|
36
|
+
bucket_by_volume,
|
|
37
|
+
bvc_buy_fraction,
|
|
38
|
+
standard_normal_cdf,
|
|
39
|
+
vpin,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
__version__ = "0.1.0"
|
|
43
|
+
|
|
44
|
+
__all__ = [
|
|
45
|
+
# types
|
|
46
|
+
"L1Quote",
|
|
47
|
+
"Trade",
|
|
48
|
+
"Side",
|
|
49
|
+
# ofi
|
|
50
|
+
"ofi",
|
|
51
|
+
"ofi_series",
|
|
52
|
+
"ofi_contribution",
|
|
53
|
+
# imbalance
|
|
54
|
+
"depth_imbalance",
|
|
55
|
+
"trade_imbalance",
|
|
56
|
+
# vpin
|
|
57
|
+
"vpin",
|
|
58
|
+
"bucket_by_volume",
|
|
59
|
+
"bvc_buy_fraction",
|
|
60
|
+
"standard_normal_cdf",
|
|
61
|
+
"VolumeBucket",
|
|
62
|
+
# execution
|
|
63
|
+
"effective_spread",
|
|
64
|
+
"effective_half_spread",
|
|
65
|
+
"realized_spread",
|
|
66
|
+
"price_impact",
|
|
67
|
+
"kyle_lambda",
|
|
68
|
+
"roll_spread",
|
|
69
|
+
"FlowObservation",
|
|
70
|
+
# fairvalue
|
|
71
|
+
"mid",
|
|
72
|
+
"weighted_mid",
|
|
73
|
+
"relative_spread_bps",
|
|
74
|
+
# classify
|
|
75
|
+
"tick_rule",
|
|
76
|
+
"lee_ready",
|
|
77
|
+
"PriceVsMid",
|
|
78
|
+
# liquidity
|
|
79
|
+
"amihud_illiquidity",
|
|
80
|
+
"ReturnVolume",
|
|
81
|
+
# volatility
|
|
82
|
+
"realized_variance",
|
|
83
|
+
"realized_volatility",
|
|
84
|
+
"annualized_volatility",
|
|
85
|
+
# efficiency
|
|
86
|
+
"autocorrelation",
|
|
87
|
+
"variance_ratio",
|
|
88
|
+
# orderbook
|
|
89
|
+
"OrderBook",
|
|
90
|
+
"Level",
|
|
91
|
+
"BookSide",
|
|
92
|
+
# simulate
|
|
93
|
+
"simulate_market_order",
|
|
94
|
+
"Fill",
|
|
95
|
+
"MarketOrderResult",
|
|
96
|
+
# scheduling
|
|
97
|
+
"twap",
|
|
98
|
+
"pov",
|
|
99
|
+
# bars
|
|
100
|
+
"tick_bars",
|
|
101
|
+
"volume_bars",
|
|
102
|
+
"dollar_bars",
|
|
103
|
+
"Bar",
|
|
104
|
+
"__version__",
|
|
105
|
+
]
|