Skip to main content

Trading engine — gateway, task manager, and process SDK

Project description

Trading Engine

Run algorithmic trading strategies as managed tasks — with a live dashboard, per-task logs, restart policies, and a market SDK that abstracts across venues.


Quickstart

1 — Install

pip install tribulnation-engine

2 — Initialize

Initialize the engine in a new directory:

engine init
# creates engine.toml, .env, and strats/ directory

Edit engine.toml and .env to configure accounts and strategies.

3 — Write a strategy

# strats/my_strat.py
from tribulnation.engine import Process, RestartPolicy

class MyStrat(Process):
  name = 'my-strat'
  restart = RestartPolicy(on='error', delay=5.0)

  async def run(self, market: str):
    mkt  = await self.sdk.market(market)
    book = await mkt.depth()
    self.log.info('mark price: %s', book.mark_price)

run() parameters become the task's argument schema — they appear as a form in the dashboard and are coerced to the declared types when a task is started.

4 — Start the engine

engine start          # foreground, logs to stdout
engine start -d       # background — writes .engine.pid and engine.log

For longer-running deployments on a systemd host, you can also install it as a user service:

engine service install --cwd . --memory 2G -v
engine service status
engine service logs -f

The generated service runs engine start, restarts automatically, and uses systemd MemoryMax when --memory is provided. It also uses a bounded stop timeout so stuck shutdowns are force-killed by systemd:

engine service install --cwd . --memory 2G --timeout-stop-sec 20

Manage it with:

engine service restart
engine service stop
engine service uninstall

5 — Run a strategy

From the dashboard at http://localhost:3121 or via the CLI:

engine task start my-strat bitcoin -a market=mexc:spot:BTCUSDT
# engine task start <process_name> <run_id> -a <arg_name>=<arg_value> ...

6 — Stop a strategy

From the dashboard or:

engine task stop my-strat bitcoin
# engine task stop <process_name> <run_id>

Strategies

The Process base

from tribulnation.engine import Process, RestartPolicy

Implement async def run(self, ...). Anything run() needs is injected via self:

Attribute What it is
self.sdk Market SDK — call await self.sdk.market('venue::symbol')
self.log Logger scoped to this task
self.run_id The run ID this task was started with
self.set_state(s) Publish a named state ('connected', 'quoting', …)
self.require(cls, id) Declare a dependency on another running task
self.ipc Call methods on Service processes

Restart policy

class Hedger(Process):
  restart = RestartPolicy(on='error', delay=5.0)
on= Behaviour
'never' Stop on exit or error
'error' Restart after an unhandled exception, with delay seconds between attempts
'always' Restart after any exit

max_attempts=N caps the number of consecutive restarts.

Dependencies

Use require() to gate a task on another reaching a named state:

class DydxMaker(Process):
  async def run(self, maker: str, hedge: str) -> None:
    async with self.require(Hedger, self.run_id, state='connected')(
      listen=maker, hedge=hedge
    ):
      # runs only while Hedger/{self.run_id} is alive and in state 'connected'
      ...

require() also auto-starts the dependency if it isn't running, and cancels the dependent if the dependency stops or errors.

Logging

Standard logging calls are automatically captured and streamed to the dashboard. No setup needed:

log = logging.getLogger(__name__)

class Hedger(Process):
  async def run(self, ...):
    log.info('listener live: %s%s', listen, hedge)
    # or use the process logger:
    self.log.info('works the same way')

INFO and above are always captured. DEBUG records are captured only from loggers whose name starts with a prefix listed in [daemon] debug_loggers:

[daemon]
debug_loggers = ["strats"]

Config reference (engine.toml)

[engine]
processes = [
  "strats.hedger:Hedger",
  "strats.dydx_maker:DydxMaker",
]

[daemon]
host     = "localhost"
port     = 3121
db       = "engine.db"    # SQLite path; default "engine.db"
max_logs = 500            # in-memory log lines per task; default unlimited

[accounts.dydx-main]
venue    = "dydx"
mnemonic = "$DYDX_MNEMONIC"

[accounts.hyperliquid-main]
venue       = "hyperliquid"
address     = "$HYPERLIQUID_ADDRESS"
private_key = "$HYPERLIQUID_PRIVATE_KEY"

[[tasks]]
process = "hedger"
id      = "btc"
args    = { listen = "dydx:perp:BTC-USD", hedge = "hl::BTC" }

Account credentials are resolved from environment variables when the value starts with $. engine start automatically loads .env from the same directory as engine.toml.

[[tasks]] entries are started automatically when the engine starts. Each entry needs process (the registered process name), id (the run ID), and optionally args (a table of keyword arguments matching the process signature).


CLI

engine start                                          # launch gateway + manager (foreground)
engine start -d                                       # background — writes .engine.pid + engine.log
engine service install --cwd . --memory 2G -v          # install as a user systemd service
engine service logs -f                                 # follow service logs
engine stop                                           # stop a background engine
engine task start hedger btc -a listen=dydx:perp:BTC-USD -a hedge=hyperliquid::BTC
engine task stop  hedger btc
engine register strats.new_strat:NewStrat             # hot-load a process class

HTTP API

Method Path Description
GET /api/tasks Running tasks
GET /api/tasks/history Completed tasks (SQLite)
GET /api/task/{process}/{id} Single task
GET /api/task/{process}/{id}/logs Task logs
GET /api/task/{process}/{id}/attempts Restart attempts
POST /api/task/{process}/{id} Start a task — body: {"args": {...}}
DELETE /api/task/{process}/{id} Stop a task
DELETE /api/task/{process}/{id}?purge=true Stop and remove from history
DELETE /api/task/{process}/{id}/logs Clear logs and attempt history
GET /api/processes Registered process classes
POST /api/processes Register a process at runtime
GET /api/health Health check
GET /api/ws WebSocket event feed

Architecture

engine start
├── engine gateway    owns real venue SDK connections, serves the market RPC protocol
└── engine manager    task control plane
  ├── in-process runtime — strategies run as asyncio tasks
  ├── REST + WebSocket API (FastAPI / uvicorn)
  └── SQLite store — task history, logs, restart attempts

Strategies never hold venue connections directly. self.sdk inside a task is a ProxySDK that routes market calls to the gateway over a local Unix socket. The gateway owns the real credentials and connections; the manager owns task lifecycle and the dashboard.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tribulnation_engine-0.1.12.tar.gz (108.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tribulnation_engine-0.1.12-py3-none-any.whl (122.2 kB view details)

Uploaded Python 3

File details

Details for the file tribulnation_engine-0.1.12.tar.gz.

File metadata

  • Download URL: tribulnation_engine-0.1.12.tar.gz
  • Upload date:
  • Size: 108.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for tribulnation_engine-0.1.12.tar.gz
Algorithm Hash digest
SHA256 1a6928a7fce6c12a93b198f9b7e0373bf9042b20e13813ca072425529b896cb2
MD5 d83d7d8206a40895de672e9c0a70e1ca
BLAKE2b-256 dd2b82602073951c6ba4c5a6da9c7da24fc6972c45c84bf6078d9e44579a447c

See more details on using hashes here.

File details

Details for the file tribulnation_engine-0.1.12-py3-none-any.whl.

File metadata

File hashes

Hashes for tribulnation_engine-0.1.12-py3-none-any.whl
Algorithm Hash digest
SHA256 dcd4316f4335419277a9095da804be295f31ff2023bf70b0bf8e4d459ed4b33f
MD5 b3a7fd93727d9b975fd6bf2e745f33ef
BLAKE2b-256 37c2aa7bd56f37be4c275afa3dbfde382674378dbc148d00e0c19a2e5ddfc8f9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page