Base Adapter¶
Abstract interface that all broker adapters implement.
base
¶
Base adapter interface for broker integrations.
All broker adapters must inherit from BaseAdapter and implement the required abstract methods. The executor loop calls these methods at specific points during its tick cycle — adapters never drive the flow themselves, they only respond when the executor invokes them.
The typical lifecycle is:
- User clicks Start in the web UI.
- The executor calls
connect()once to establish a broker session. - On every tick, the executor calls
fetch_quote()for each tracked symbol, then sends prices and pending transactions to TradeTracer. - TradeTracer responds with orders. The executor calls
execute_order(), which dispatches toexecute_buy()orexecute_sell(). - When the user clicks Stop, the executor calls
disconnect().
Example
from adapters.base import BaseAdapter
class MyBrokerAdapter(BaseAdapter):
@classmethod
def get_config_fields(cls):
return [{"name": "api_key", "type": "password", "required": True}]
def connect(self) -> bool:
self.client = MyBrokerClient(self.api_key)
return self.client.is_connected()
def disconnect(self) -> None:
self.client.close()
def execute_buy(self, symbol, shares, price):
result = self.client.buy(symbol, shares)
return {"success": True, "fill_price": result.price, ...}
def execute_sell(self, symbol, shares, price):
result = self.client.sell(symbol, shares)
return {"success": True, "fill_price": result.price, ...}
ConfigField
¶
Bases: TypedDict
Configuration field for the web UI form.
Displayed as a form input in the executor's web interface.
The name must match an __init__ parameter on the adapter.
Source code in adapters/base.py
Bar
¶
Bases: TypedDict
Single OHLCV bar with a timestamp.
Used in the bars array sent to TradeTracer.
Source code in adapters/base.py
Quote
¶
Bases: TypedDict
Price quote for a symbol.
Returned by fetch_quote(). The executor maps this into the
TradeTracer bars format (with bid/ask) before sending.
All fields are optional — return whatever the broker provides.
Source code in adapters/base.py
FillResult
¶
Bases: TypedDict
Result of executing a buy or sell order.
On success, success is True and fill_price, fill_shares,
and commission are set. On failure, success is False and
error describes what went wrong.
Source code in adapters/base.py
Order
¶
Bases: TypedDict
Order from the TradeTracer API.
Passed to execute_order(), which dispatches to
execute_buy() or execute_sell().
Source code in adapters/base.py
BaseAdapter
¶
Bases: ABC
Abstract base class for broker adapters.
An adapter is the bridge between the executor and a specific broker.
It knows how to connect to the broker, execute buy/sell orders, and
optionally fetch real-time quotes. The executor owns the lifecycle —
it calls connect() on start, fetch_quote() and execute_buy()/
execute_sell() during each tick, and disconnect() on stop.
Adapters should never raise exceptions for expected failures like
insufficient funds or rejected orders. Instead, return a result dict
with "success": False and an "error" message. The executor logs
these and continues to the next order.
Source code in adapters/base.py
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 | |
get_config_fields()
abstractmethod
classmethod
¶
Return configuration fields for the web UI.
Called by the web UI when rendering the adapter configuration form. Each field describes one input the user needs to fill in to connect to this broker — for example, an API key, a hostname, or a port number.
The web UI dynamically renders form inputs based on these field
definitions. When the user saves, the values are stored in
config.json under adapter_config and passed as keyword arguments
to the adapter's __init__(). The name of each field must match
an __init__ parameter name so the value gets passed through.
Returns:
| Type | Description |
|---|---|
list[ConfigField]
|
List of field configuration dicts. Each dict has |
Example
Source code in adapters/base.py
connect()
abstractmethod
¶
Connect to the broker and verify the session is usable.
Called exactly once when the user starts the executor. This is where the adapter should establish a network connection, authenticate with credentials, and verify that the session is ready to accept orders.
If the connection fails — wrong credentials, broker offline, network error — return False. The executor will log the failure, stay in the stopped state, and the user can fix their config and try again.
For adapters that don't need a persistent connection (like the sandbox adapter), this can simply return True.
Returns:
| Type | Description |
|---|---|
bool
|
True if the connection was established and the adapter is ready to execute orders. False if something went wrong. |
Source code in adapters/base.py
disconnect()
abstractmethod
¶
Disconnect from the broker and clean up resources.
Called once when the user stops the executor, or when the container shuts down (via SIGTERM/SIGINT). This is where the adapter should close network connections, cancel any pending requests, and release resources.
This method should never raise exceptions. If the connection is already closed or was never established, it should silently do nothing. The executor calls this unconditionally during shutdown regardless of the adapter's current state.
Source code in adapters/base.py
execute_buy(symbol, shares, price)
abstractmethod
¶
Execute a buy order on the broker.
Called by the executor when TradeTracer issues a buy order during a tick. The executor receives orders from the TradeTracer API response, then calls this method for each buy order. The adapter should submit the order to the broker and return the fill details.
The price parameter is the ask price that TradeTracer used to size
the order. Depending on your broker integration, you can use it as a
limit price, a sanity check against slippage, or ignore it entirely
and use a market order. The fill price you report back is what
TradeTracer records as the actual execution price.
On success, you must return all four fields: success, fill_price,
fill_shares, and commission. The executor builds a transaction
from these and reports it to TradeTracer on the next tick.
On failure (insufficient funds, symbol not found, broker rejected the
order), return "success": False with an "error" message. Do not
raise exceptions — the executor logs the error and moves on to the
next order.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
symbol
|
str
|
Stock ticker symbol (e.g., |
required |
shares
|
int
|
Number of shares to buy. Always a positive integer.
This is the net consolidated volume from TradeTracer — if
a strategy called |
required |
price
|
float
|
The ask price TradeTracer used when generating this order. Use as a limit price or for slippage validation. |
required |
Returns:
| Type | Description |
|---|---|
FillResult
|
A dict with |
Example
Source code in adapters/base.py
execute_sell(symbol, shares, price)
abstractmethod
¶
Execute a sell order on the broker.
Called by the executor when TradeTracer issues a sell order during a
tick. Behaves identically to execute_buy() but for the sell side.
The price parameter is the bid price that TradeTracer used to
calculate expected proceeds. As with buys, you can use it as a limit,
a sanity check, or ignore it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
symbol
|
str
|
Stock ticker symbol (e.g., |
required |
shares
|
int
|
Number of shares to sell. Always a positive integer. The executor only sends sell orders for positions the strategy holds, but the adapter should still validate against its own position tracking in case of desync. |
required |
price
|
float
|
The bid price TradeTracer used when generating this order. Use as a limit price or for slippage validation. |
required |
Returns:
| Type | Description |
|---|---|
FillResult
|
Same format as |
Source code in adapters/base.py
fetch_quote(symbol, eod_last_price)
abstractmethod
¶
Fetch a price quote for a symbol.
Called by the executor at the start of every tick, once per tracked symbol. The executor sends the returned quotes to TradeTracer, which uses them for intraday strategy evaluation and order pricing.
The eod_last_price is the most recent end-of-day close price from
TradeTracer's data. Adapters can use it however they need — for
example, the sandbox adapter uses it to simulate intraday price
movement via random walk. Broker adapters like IBKR can ignore it
and fetch real-time data from the broker instead.
The EOD price also serves as a sanity check — users can compare their broker's price against TradeTracer's data to verify accuracy. TradeTracer's data is not always correct, and this transparency helps users catch discrepancies.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
symbol
|
str
|
Stock ticker symbol (e.g., |
required |
eod_last_price
|
float | None
|
Last known EOD close price from TradeTracer, or None if not yet available (first tick). |
required |
Returns:
| Type | Description |
|---|---|
Quote | None
|
A Quote dict with price fields, or None if unavailable. |
Example
# Broker adapter — fetch real data, ignore EOD
def fetch_quote(self, symbol, eod_last_price):
ticker = self.client.get_ticker(symbol)
return {"close": ticker.last, "bid": ticker.bid, "ask": ticker.ask}
# Sandbox adapter — simulate from EOD
def fetch_quote(self, symbol, eod_last_price):
if not eod_last_price:
return None
price = eod_last_price * (1 + random.uniform(-0.005, 0.005))
return {"close": price, "bid": price - 0.01, "ask": price + 0.01}
Source code in adapters/base.py
fetch_bars(symbol, count)
¶
Fetch historical OHLCV bars for warmup.
Called by the executor when the strategy-runner requests warmup
data for a symbol. The executor sends the returned bars in the
bars array instead of a single bar derived from fetch_quote.
Override this method if your adapter can provide historical bars.
The default implementation returns an empty list, which causes the
executor to fall back to a single bar from fetch_quote.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
symbol
|
str
|
Stock ticker symbol (e.g., |
required |
count
|
int
|
Maximum number of bars to return (up to 1000). |
required |
Returns:
| Type | Description |
|---|---|
list[Bar]
|
List of Bar dicts with keys |
Source code in adapters/base.py
execute_order(order)
¶
Dispatch an order from TradeTracer to the appropriate handler.
This is the method the executor loop actually calls. It reads the
action field from the order dict and routes to execute_buy() or
execute_sell(). You do not need to override this method — it
exists as a convenience so the executor doesn't need to branch on
order type itself.
The order dict comes directly from the TradeTracer API response.
Each order represents a consolidated net trade for one symbol from
one worker during one tick. TradeTracer handles consolidation — if
a strategy called buy(50) then sell(20), you receive a single
order with action: "buy" and volume: 30.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
order
|
Order
|
Order dict from the TradeTracer API response with keys:
|
required |
Returns:
| Type | Description |
|---|---|
FillResult
|
The result dict from |