quantstrip
The module every strategy client imports. quantstrip.py is a
single top-level module, not a package. It defines ClientBase and instantiates
the application's DB, email, and settings singletons, shared by all client scripts.
Import surface
from quantstrip import (
ClientBase, # base class for your client
db_handler, # DBHandler singleton — see the database API
email_manager, # EmailManager singleton — see the email API
settings, # Settings singleton — see the settings API
send_email, # shorthand for email_manager's default-account send
)
Only ClientBase is documented on this page. db_handler,
email_manager, settings, and send_email are re-exports —
see database, email, and
settings for their full method surfaces.
class ClientBase
Base class for every client. Subclass it, do your setup in __init__ (after calling
super().__init__()), schedule jobs on self.scheduler
(a schedule.Scheduler), and call run_client() to start.
Sets the internal stop flag. The running main_loop thread exits on its next
iteration.
Resets lifecycle state — clears the stop flag, records the start timestamp, resets
job_count and last_job_error, and stamps the initial heartbeat.
Called automatically by run_client; you generally don't call this directly.
Returns None if the client hasn't been started yet. Otherwise returns a dict:
cpu_percent · thread_count · last_heartbeat ·
job_count · last_job_error
Starts main_loop on a background thread and sets is_running = True.
This is what you call from your client's entry point to actually go live.
Runs on the background thread started by run_client. Every 100ms: runs any
pending jobs on self.scheduler, increments job_count, and updates
the heartbeat. Continues until the stop flag is set.
A single job raising an exception is caught, logged, and recorded in
last_job_error — it does not stop the loop. An exception in the loop itself
(outside a job) is fatal: it's logged, exception is set to a
"FATAL: ..." string, and the client stops.
Minimal example
A client that logs a message once a second — the actual pattern used by the smallest example in the codebase:
from quantstrip import ClientBase
import logging
logger = logging.getLogger(__name__)
class Client(ClientBase):
def __init__(self, *args):
super().__init__()
self.display_name = "Default Client"
self.scheduler.every(1).seconds.do(self.job)
def job(self):
logger.info(f"Hello from {self.display_name}")
# Elsewhere, to go live:
client = Client()
client.run_client(client_id="default-client-1")
db_handler.