zeroledger
The official Python SDK for the ZeroLedger programmatic trading API. Access your accounts, market and historical data, order-book depth, place and manage orders through the risk gate, set server-side trailing-stop rules, and stream live updates — all over a clean, broker-neutral interface.
Install
pip install zeroledger # REST
pip install "zeroledger[stream]" # + WebSocket streaming
Authenticate
Create an API key in the dashboard under Configuration → API Keys, grant it scopes, then:
from zeroledger import ZeroLedger
zl = ZeroLedger(api_key="zl_xxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
print(zl.me()) # {key_id, scopes, account_scope, rate_limit_per_minute}
Everything you touch is broker-blind: symbols are standardized (GOLD, EURUSD) and every id is opaque
(acct_…, pos_…, ord_…, rule_…). No upstream broker is ever exposed.
Accounts & positions (scopes: accounts:read, trades:read)
for a in zl.accounts():
print(a["account_number"], a["type"], a["balance"], a["can_trade"])
acct = zl.accounts()[0]["id"]
zl.positions(acct)
zl.orders(acct)
zl.trades(acct, days=30)
Market data (scope: market:read, depth: depth:read)
zl.symbols()
zl.symbol("GOLD")
zl.candles("GOLD", "1m", limit=100) # recent OHLCV
zl.quotes(["GOLD", "EURUSD"])
zl.depth("GOLD") # live order-book snapshot
Deep historical data (Swiss) (scope: swiss:read)
import time
end = int(time.time() * 1000)
start = end - 7 * 86400 * 1000
hist = zl.history("GOLD", "1h", start=start, end=end) # columnar t/o/h/l/c/v + page_info
bars = zl.history("GOLD", "1h", start=start, end=end, as_object=True)["candles"]
zl.coverage("GOLD") # earliest/latest per timeframe
Follow hist["page_info"]["next_from"] to page forward; a fully-closed range is immutable.
Trading (scope: trades:write — every placement passes the risk gate)
order = zl.place_order(acct, symbol="GOLD", side="buy", type="market", volume=0.10,
sl=4100.0, tp=4200.0) # Idempotency-Key auto-generated
limit = zl.place_order(acct, symbol="EURUSD", side="sell", type="limit",
price=1.1200, volume=0.50)
zl.modify_position(order["id"], sl=4120.0) # safe partial — only the fields you send
zl.close_position(order["id"]) # or volume=0.05 for partial
zl.cancel_order(limit["id"])
Placements are idempotent: retrying with the same idempotency_key= returns the original result instead of
executing twice.
Server-side trailing stops (scopes: rules:read, rules:write)
Rules run on ZeroLedger's servers and ratchet your stop even while your client is offline. Distances are in price units.
# trail a position's stop 5.0 behind price once it is 3.0 in profit
zl.trailing_stop(acct, order["id"], distance=5.0, activation=3.0)
# or any rule type: trailing_sl | move_to_breakeven | step_trail
zl.create_rule(acct, type="move_to_breakeven",
target={"kind": "position", "position": order["id"]},
params={"activation": 10.0, "offset": 0.5})
zl.rules(acct)
zl.delete_rule(acct, rule_id)
Streaming (scope: stream, needs zeroledger[stream])
for frame in zl.stream(["depth:GOLD", "quotes:EURUSD", "account:" + acct, "positions:" + acct]):
if frame["type"] == "data":
print(frame["channel"], frame["key"], frame["data"])
Channels: quotes, depth (market), account, positions, orders (your accounts). Frames arrive on
change.
Errors
All failures raise a typed ZeroLedgerError subclass: AuthError, ForbiddenError, NotFoundError,
ValidationError, OrderRejected (carries .code/.retcode), IdempotencyConflict, RateLimited,
UpstreamUnavailable.
from zeroledger import OrderRejected
try:
zl.place_order(acct, symbol="GOLD", side="buy", type="market", volume=99.0)
except OrderRejected as e:
print(e.code, e.message, e.retcode)
Metadata
Release files for zeroledger 0.1.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 | Provenance | Actions |
|---|---|---|---|---|
| zeroledger-0.1.0.tar.gz | 7.9 kB | Without provenance | Details for zeroledger-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| zeroledger-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for zeroledger-0.1.0-py3-none-any.whl |
Total release size: 16.9 kB
Release files / zeroledger-0.1.0.tar.gz
| Download URL | zeroledger-0.1.0.tar.gz |
|---|---|
| Size | 7.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ed2bc9968a9adc674fe92a4fc3a158980da5644917344a99dfd8540fc5357f3e
|
|
BLAKE2b-256 checksum How to use checksums |
7ae8cc9cce9b72963c42d5af8af2edf0560afb1d5745590c80bbb25d7aaae3c0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.4
|
Release files / zeroledger-0.1.0-py3-none-any.whl
| Download URL | zeroledger-0.1.0-py3-none-any.whl |
|---|---|
| Size | 9.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ca141196010b1de1bafe5e55e97fbbf0b6467e7e9235bf31114e5105d03dcdd1
|
|
BLAKE2b-256 checksum How to use checksums |
417e63a0a91aed0f6400f1716130913e6926e413031d2e4ddb325d22a96ba026
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.4
|
Security for zeroledger 0.1.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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
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.