TWAP Engine
An exchange-agnostic Time-Weighted Average Price (TWAP) order distribution engine, plus an optional ATR-based stop-loss calculator. Works on any ccxt-supported exchange (Binance, Bybit, Kraken, …). It depends on no particular project or infrastructure.
pip install twap-engine
Why
A large order placed in one go moves its own price: it eats the depth of the order book and the last fills land measurably worse than the first. TWAP splits that order into slices and spreads them over time.
The engine's job is to do that split and to notice when things are going wrong mid-execution and stop.
| Feature | Behaviour |
|---|---|
| Slicing | Splits a total amount into N slices over a time window |
| Slippage abort | Cancels the remaining slices if price drifts past a limit |
| Min-notional guard | Rejects up front if a slice would fall below the exchange minimum |
| Smart stop (optional) | ATR-based stop-loss suggestion that widens with volatility |
| Exchange agnostic | Anything ccxt speaks |
Design decision: it calculates, it never orders
The smart-stop layer computes a stop level. It never places an order.
That boundary is not documented — it is enforced by two tests. One checks the behaviour, the other scans the source for order-placing calls and fails if it finds any.
A calculation layer that can quietly place orders would be making decisions inside someone else's system on my behalf. I don't know who uses this library; how much authority I hand it is my responsibility, not theirs.
The same principle covers failure: if the stop calculator crashes, the TWAP flow is unaffected. An optional helper must never take down the main job. There is a test for that too.
Tests
test_engine.py 3/3
test_smart_stop.py 11/11
─────────
14/14
Four of them are boundary tests rather than unit tests:
| Test | Guarantees |
|---|---|
test_broken_calculator_never_blocks_twap |
A broken helper cannot stop the main flow |
test_smart_stop_never_orders |
The calculator does not place orders — behaviourally |
test_no_order_calls_in_smart_stop_source |
No order call exists in the source at all |
test_no_proprietary_guardian_references |
No reference to my private risk stack leaked into this package |
The last one is why this package can exist. The engine was originally written inside my own trading system, wired to proprietary risk layers. Publishing it meant cutting it out — and "I removed it" is not a verifiable claim. A single import, a comment, or a variable name can carry information out.
So the separation is a test. Documentation goes stale; a test re-proves itself on every run.
Usage
import asyncio
import ccxt.async_support as ccxt
from twap_engine import TWAPEngine
async def main():
exchange = ccxt.binance({
"apiKey": "...",
"secret": "...",
"enableRateLimit": True,
})
engine = TWAPEngine(exchange)
result = await engine.execute(
symbol="BTC/USDT",
side="buy",
total_amount=1000.0, # quote currency
slices=5,
interval_seconds=60,
max_slippage_pct=0.3, # abort the rest beyond this drift
)
print(result)
await exchange.close()
asyncio.run(main())
Run python demo_smart_stop.py to compare a fixed 1.5% stop against the
ATR-based one on live market data.
Scope
Deliberately narrow: it distributes an order, watches slippage, suggests a stop. It does not forecast the market and does not manage a portfolio. The prediction and risk layers of my own system are intentionally absent — that is a scope decision, not a missing feature.
License
MIT — commercial use included. See LICENSE.
Metadata
Release files for twap-engine 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| twap_engine-0.2.0.tar.gz | 14.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| twap_engine-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 27.5 kB
Release files / twap_engine-0.2.0.tar.gz
| Download URL | twap_engine-0.2.0.tar.gz |
|---|---|
| Size | 14.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
251e00861e5e16f0387ba3b43cb534ca7ac3ed69d4936f8fa1ed9b1885df966f
|
|
BLAKE2b-256 checksum How to use checksums |
92fec76825d2acedb5778841533a23741d76bdd10fb15b46bc8a1f0dafc53949
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.13
|
Release files / twap_engine-0.2.0-py3-none-any.whl
| Download URL | twap_engine-0.2.0-py3-none-any.whl |
|---|---|
| Size | 13.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
73f2e49fc57d1854b1886218ef7cfceb73f134b4cf313f8a9a01cb7f689a7228
|
|
BLAKE2b-256 checksum How to use checksums |
bdbc73d23c4cb384e643332081a5977211e30d6aab2750068073a515ffab6639
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.13
|