QL-Dash Developer Guide

Connect, trade, and run live alphas on QL-Dash from Python. Read this page top to bottom and you'll go from "what is FIX?" to a running strategy with real market data.

Your Python code paperbroker-client FIX 4.4 QL-Dash engine
Market data Redis / Kafka feed

Step 1 What is FIX?

QL-Dash speaks FIX 4.4 (Financial Information eXchange) over QuickFIX — the same industry-standard messaging protocol banks and brokers use worldwide for order entry and execution. Before you write any code, it helps to know what FIX gives you:

  • Standardized messages for orders, execution reports, and market data
  • Session management — logon, logout, and heartbeats keep the connection alive
  • Reliability — message sequencing and recovery so nothing is silently lost
  • Two key IDs you'll see everywhere: ClOrdID (you generate it) vs OrderID (the server assigns it)
Go deeper

The full connection sequence, how to read raw FIX messages, debug fields, and common pitfalls live in the dedicated guide. Read it once and FIX stops feeling like a black box.

You now know what FIX is and why QL-Dash uses it.

Step 2 Why you need the package

You could speak FIX by hand — but you'd spend your time on plumbing instead of strategy. The paperbroker-client package wraps all of it behind a few Python calls.

TaskRaw FIX, by handWith paperbroker-client
Connect & stay aliveBuild logon, manage heartbeats & sequence numbers, handle resend requestsclient.connect()
Place an orderAssemble tag/value message 35=D|11=...|55=...|54=1|38=1|44=...client.place_order(...)
Track a fillParse execution reports, match ClOrdID/OrderID, decode status enumsSubscribe to events, get typed callbacks
Reconnect after dropRe-logon, recover sequence, re-query open ordersHandled + optional SQLite persistence

Download & install

paperbroker_client-0.2.7 Latest Preview
Alpha framework + TIF default DAY. Preview track — production should pin v0.2.4.
paperbroker_client-0.2.4 Stable
SQLite order persistence & recover_pending_orders(). Recommended for production.

First, create a virtual environment

Install the package inside a virtual environment (venv), never into your system Python. A venv gives this project its own isolated set of dependencies, so paperbroker-client (and its pinned version of quickfix) can't clash with other projects or with packages your OS relies on. It also means you can wipe and rebuild the environment cleanly if anything breaks — without touching the rest of your machine.

# Create & activate a virtual environment (Python 3.10+)
python -m venv .venv

# macOS / Linux
source .venv/bin/activate
# Windows (PowerShell)
# .venv\Scripts\Activate.ps1

# Upgrade pip inside the fresh venv
python -m pip install --upgrade pip
# Install from the downloaded wheel (with the venv activated)
pip install paperbroker_client-0.2.7-py3-none-any.whl

# Optional: enable the YAML-driven alpha CLI
pip install 'paperbroker_client[cli]'

# For production, pin the stable track instead:
# pip install paperbroker_client-0.2.4-py3-none-any.whl
Heads up — building on macOS

paperbroker-client depends on quickfix, which is a C++ extension that has to be compiled at install time. On macOS this build can fail (toolchain / Xcode CLT mismatches, Apple-Silicon vs. Intel, missing headers), and you may need to compile a quickfix build specifically for your Mac instead of relying on a prebuilt wheel.

If the build fails or you're not sure how to produce a Mac-compatible quickfix, contact an admin for support — don't fight the toolchain alone. (Internal — your team knows who to reach.)

Changelog & release notes

You understand why the package exists and have it installed.

Step 3 How the API works

The PaperBrokerClient is event-based. You connect once, wait for logon, then place orders and react to fills through callbacks. Here is the whole loop in one snippet:

from paperbroker.client import PaperBrokerClient

client = PaperBrokerClient(
    default_sub_account="D1",
    username="your_username",
    password="your_password",
    rest_base_url="http://localhost:9090",
    socket_connect_host="localhost",
    socket_connect_port=5001,
    sender_comp_id="your-FIX",
    target_comp_id="SERVER",
)

# React to session + execution events
client.on("fix:logon", lambda session_id, **kw: print(f"✅ Logged in: {session_id}"))

client.connect()                       # opens the FIX session
if client.wait_until_logged_on(timeout=10):
    cash = client.get_cash_balance()   # account query
    cl_ord_id = client.place_order(    # new order single (35=D)
        full_symbol="HNXDS:VN30F2606", side="BUY", qty=1, price=1200.0,
    )                                  # tif defaults to "DAY" in v0.2.7
    is_terminal, status = client.cancel_order(cl_ord_id, timeout=5.0)

The mental model

  • Order lifecycle: connect → logon → place_order → execution reports (new → fill / partial / cancelled).
  • Sub-accounts: D1, D2, … let one login trade multiple books (see example 03, cross-matching).
  • Market data arrives separately from order flow — via Redis (one-shot query & pub/sub) or Kafka (recommended for multi-instrument).
  • Alpha framework: subclass SignalDrivenAlpha, override a few hooks, and bar aggregation, order placement, fill tracking, and state persistence are handled for you.
Full API reference

Configuration, Connection, Order Management, Account Queries, Events, Market Data, Alpha Framework, and CLI — every method and option.

You can picture how data and orders flow between your code and the engine.

Step 4 Learn from examples

Work through these in order — each builds on the last. Every file is runnable and downloadable.

Paper basics (01–08)

Alpha framework (09–15) v0.2.7

Full example tutorials with explanations & expected output

You can run the first example and know where the advanced ones live.

Step 5 Get & use an account

Accounts on QL-Dash are provisioned by an admin — there is no self-service signup. The admin sets up your login, your FIX trading account, and one or more sub-accounts, then hands you the credentials. Your job is to drop those credentials into the client and start trading.

The account model

  • Trader account (login) — your main identity and QL-Dash dashboard login (e.g. the name shown after Hello, in the top bar).
  • Environment — an isolated context such as REAL or PLAYBACK. One trader account can have several; each has its own configuration for testing vs production.
  • FIX account — the login gateway: the username / password and connection details your Python client authenticates with over FIX.
  • Sub-account — an independent trading book under a FIX account (e.g. main, D1, D2), each linked to one environment with its own balance, portfolio, and transactions. Cross-matching examples use D1 vs D2.
  • Alias — an optional friendly display name for an account/sub-account on the dashboard and arena leaderboard.

How they fit together

1 Trader account → has many environments
2 Environment REAL / PLAYBACK — isolated config
3 FIX account → connects to many sub-accounts
4 Sub-account links to one environment; own balance & portfolio

The admin sets up this whole hierarchy for you — you just receive the credentials at the FIX-account / sub-account level.

What the admin gives you

When your account is ready you'll receive everything needed to connect:

  • username and password (your FIX account)
  • sender_comp_id (your FIX session ID) — target_comp_id is always SERVER
  • Host & port for the FIX gateway and the REST base URL
  • Your sub-account id(s) and their starting balance

Fast path: copy your .env from the dashboard

You don't have to wire the values by hand. On the QL-Dash home page, every paper account row has a .env button in the Actions column (between the rename and the PDF buttons). Click it and a ready-to-use .env — already using the SDK v0.2.7 variable names — is copied to your clipboard.

It pre-fills everything that's known for that account; only the password is left for you to paste in:

# PaperBroker .env — sub account: main
# PAPER_PASSWORD is not filled in: contact the admin for this account's FIX password.

PAPER_ACCOUNT_ID=main                 # your sub-account id
PAPER_USERNAME=fix_yourname           # your FIX account username
PAPER_PASSWORD=<contact_admin>        # ← paste the password the admin gave you
SENDER_COMP_ID=<your FIX account id>   # your FIX session id
PAPERBROKER_ENV_ID=main               # environment id

PAPER_REST_BASE_URL=https://papertrade.algotrade.vn/accounting
SOCKET_HOST=papertrade.algotrade.vn
SOCKET_PORT=5001
TARGET_COMP_ID=SERVER
Three steps:

1. Click .env on your account row → it's copied.   2. Paste into your project's .env file.   3. Replace <contact_admin> in PAPER_PASSWORD with the password from your admin.

Need the market-data values too (MARKET_REDIS_*, PAPERBROKER_KAFKA_*)? Those aren't in the copied .env — see Step 6 below.

Map credentials into the client

Prefer to wire it by hand? Each value the admin gives you maps to one PaperBrokerClient(...) argument from Step 3:

What the admin gives youPaperBrokerClient argument
FIX account usernameusername
FIX account passwordpassword
FIX session IDsender_comp_id
(fixed)target_comp_id="SERVER"
Sub-account id (e.g. D1)default_sub_account
Gateway host / portsocket_connect_host / socket_connect_port
REST base URLrest_base_url

View your account state

Once connected you can read your portfolio, open orders, and transactions both on the QL-Dash dashboard and from code — see example 06 (account_state.py) for portfolio + orders + transactions in one call.

Don't have an account yet?

Contact an admin to get a login, a FIX account, and your sub-account(s) provisioned.

You have credentials, they're wired into the client, and you can see your account state.

Step 6 Get the market data feed

The live market data feed (Redis / Kafka) isn't public — access is granted per user. This is the last step before you can run a strategy against real data.

What the feed provides

  • Redis — one-shot quote queries and a pub/sub stream of live prices (examples 04 & 05).
  • Kafka — a real-time market-data stream, recommended when you subscribe to many instruments at once (example 08).

The feed is independent of the FIX order flow: orders go out over FIX, while prices come in over Redis/Kafka. Your alpha and any market-data example read from it.

What you'll receive

Endpoints and credentials are environment-specific and not public. The admin will give you the host, port, and password for the data Redis (and Kafka brokers if you use Kafka).

Plug it into your code

Pass the values you receive into the market-data helpers — the same parameters used in examples 04 / 05 / 08 and by the alpha framework:

from paperbroker.market_data import RedisMarketDataClient, QuoteSnapshot

# host / port / password come from the admin
client = RedisMarketDataClient(
    host="REDIS_HOST_FROM_ADMIN",
    port=6380,
    password="REDIS_PASSWORD_FROM_ADMIN",
)

# one-shot query (example 04)
quote = await client.query("HNXDS:VN30F2606")

# pub/sub stream (example 05)
async def on_quote(instrument: str, quote: QuoteSnapshot):
    print(instrument, quote)

await client.subscribe("HNXDS:VN30F2606", on_quote)
Need data feed access?

Contact an admin to be granted access to the market data feed. (Internal — your team knows who to reach.)

You have the feed and you're ready to run a live alpha.