Connect Trade API Cookbook

The Connect Trade API Cookbook provides ready-to-run code samples in Python, JavaScript, Go, and Rust for the most common integration tasks. All samples use the base URL https://api.connecttrade.com and authenticate via client-id, client-secret, user-id, and user-secret headers.

Setup

Configure credentials and create reusable HTTP helpers for GET, POST, PATCH, and DELETE requests.

import requests

BASE_URL = "https://api.connecttrade.com"

HEADERS = {
    "client-id": "YOUR_CLIENT_ID",
    "client-secret": "YOUR_CLIENT_SECRET",
    "user-id": "YOUR_USER_ID",
    "user-secret": "YOUR_USER_SECRET",
}

def get(path, params=None):
    r = requests.get(f"{BASE_URL}{path}", headers=HEADERS, params=params)
    r.raise_for_status()
    return r.json()

def post(path, body):
    r = requests.post(f"{BASE_URL}{path}", headers={**HEADERS, "Content-Type": "application/json"}, json=body)
    r.raise_for_status()
    return r.json()

def delete(path):
    r = requests.delete(f"{BASE_URL}{path}", headers=HEADERS)
    r.raise_for_status()
    return r.json()

def patch(path, body):
    r = requests.patch(f"{BASE_URL}{path}", headers={**HEADERS, "Content-Type": "application/json"}, json=body)
    r.raise_for_status()
    return r.json()

Get Account Balances

Retrieve cash, buying power, and margin information across all connected brokerage accounts using GET /balances.

balances = get("/balances")
for bal in balances:
    print(f"Account {bal['account_number']}: "
          f"cash={bal['cash']}, buying_power={bal['buying_power']}")

Get Positions

Retrieve current holdings including quantity, last price, and unrealized P&L for each position using GET /positions.

positions = get("/positions")
for pos in positions:
    print(f"{pos['symbol']}: {pos['quantity']} shares @ {pos['last_price']}, "
          f"unrealized P&L: {pos['unrealized_pl']}")

Get Open Orders

List all working orders filtered by status using GET /orders?status=open. Each order includes symbol, side, quantity, order type, and normalized status.

orders = get("/orders", params={"status": "open"})
for order in orders:
    print(f"{order['symbol']} {order['side']} {order['order_qty']} "
          f"({order['order_type']}) — {order['normalized_status']}")

Get Filled Orders

Retrieve recently filled orders sorted by execution time. Each order includes a fills array with per-execution quantity and price.

orders = get("/orders", params={"status": "filled", "sort": "last_exec_time:desc", "limit": "20"})
for order in orders:
    fills = order.get("fills", [])
    total_filled = sum(float(f["quantity"]) for f in fills)
    print(f"{order['symbol']} {order['side']} filled {total_filled} shares")

List Connected Accounts

List all brokerage accounts linked to the user, including institution name, account number, and account ID using GET /accounts.

accounts = get("/accounts")
for acct in accounts:
    print(f"{acct['institution_name']} — {acct['account_number']} (id: {acct['account_id']})")

Get Recent Transactions

Retrieve historical transaction activity filtered by date range using GET /transactions.

txns = get("/transactions", params={
    "start_date": "2025-06-01",
    "end_date": "2025-06-30"
})
for txn in txns:
    print(f"{txn['transaction_type']}: {txn.get('symbol', 'N/A')} — {txn.get('amount', 'N/A')}")

Place a Market Order

Submit a market order using POST /orders. Required fields include account_id, a unique cl_order_id, broker code, side, quantity, order type, time in force, instrument, and symbol.

import uuid

order = post("/orders", {
    "account_id": "YOUR_ACCOUNT_ID",
    "cl_order_id": str(uuid.uuid4())[:30],
    "broker": "ALPACA",
    "side": "BUY",
    "order_qty": "10",
    "order_type": "MKT",
    "order_tif": "DAY",
    "instrument": "STK",
    "symbol": "AAPL"
})
print(f"Order {order['order_id']} — status: {order['normalized_status']}")

Cancel All Open Orders

Fetch all open orders and cancel each one using DELETE /accounts/{account_id}/orders/{order_id}.

orders = get("/orders", params={"status": "open"})
for order in orders:
    result = delete(f"/accounts/{order['account_id']}/orders/{order['order_id']}")
    print(f"Cancelled {order['symbol']} {order['side']} — {result['message']}")

Sum Unrealized P&L

Calculate total unrealized profit and loss across all positions by summing the unrealized_pl field from GET /positions.

positions = get("/positions")
total_pl = sum(
    float(p["unrealized_pl"])
    for p in positions
    if p.get("unrealized_pl") is not None
)
print(f"Total unrealized P&L: ${total_pl:,.2f}")

Fills from Today

Retrieve all order fills from the current trading day by filtering orders by start time and flattening the fills array from each order.

from datetime import datetime, timezone

today = datetime.now(timezone.utc).strftime("%Y-%m-%dT00:00:00Z")
orders = get("/orders", params={
    "status": "all",
    "start_time": today,
    "sort": "last_exec_time:desc",
    "limit": "500"
})

fills = []
for order in orders:
    for fill in order.get("fills", []):
        fills.append({
            "symbol": order["symbol"],
            "side": order["side"],
            "price": fill["price"],
            "quantity": fill["quantity"],
            "time": fill["time"],
        })

print(f"Total fills today: {len(fills)}")
for f in fills[:10]:
    print(f"  {f['time']} {f['symbol']} {f['side']} {f['quantity']} @ {f['price']}")

Momentum Signal

Calculate a 20-day price momentum signal for a symbol using the Streaming Market Data API. Connect to wss://mdstream.connecttrade.com, authenticate with a short-lived access token, and subscribe to daily bars with historical backfill.

import asyncio, json, uuid
import websockets

async def spy_momentum():
    token_resp = get("/connections/YOUR_CONNECTION_ID/token")
    access_token = token_resp["access_token"]

    async with websockets.connect("wss://mdstream.connecttrade.com") as ws:
        await ws.send(json.dumps({
            "action": "authenticate",
            "access_token": access_token,
            "request_id": str(uuid.uuid4()),
            "version": "v1.0"
        }))
        auth = json.loads(await ws.recv())
        assert auth["type"] == "auth_success"

        await ws.send(json.dumps({
            "action": "subscribe",
            "channel": "bars",
            "symbol": "SPY",
            "interval": "1d",
            "session": "USEqCore",
            "request_id": str(uuid.uuid4()),
            "backfill_nbars": 20
        }))

        bars = []
        async for raw in ws:
            msg = json.loads(raw)
            if msg.get("type") == "subscribed":
                continue
            if "c" in msg:
                bars.append(float(msg["c"]))
                if len(bars) >= 20:
                    momentum = (bars[-1] / bars[0]) - 1
                    print(f"SPY 20-day momentum: {momentum:+.2%}")
                    return

asyncio.run(spy_momentum())

Calculate VWAP

Compute the volume-weighted average price (VWAP) for a symbol's fills from the current day. Fetches filled orders for a symbol and calculates the weighted average across all executions.

from datetime import datetime, timezone

orders = get("/orders", params={
    "status": "filled",
    "symbols": "AAPL",
    "start_time": datetime.now(timezone.utc).strftime("%Y-%m-%dT00:00:00Z"),
    "limit": "500"
})

total_qty = 0
total_cost = 0
for order in orders:
    for fill in order.get("fills", []):
        qty = float(fill["quantity"])
        px = float(fill["price"])
        total_qty += qty
        total_cost += qty * px

if total_qty > 0:
    vwap = total_cost / total_qty
    print(f"AAPL execution VWAP: ${vwap:.4f} ({total_qty:.0f} shares)")

Portfolio Concentration

Calculate each position's share of total portfolio market value, sorted from largest to smallest. Uses last_price and quantity from GET /positions.

positions = get("/positions")
values = []
for pos in positions:
    if pos.get("last_price") and pos.get("quantity"):
        mv = float(pos["last_price"]) * float(pos["quantity"])
        values.append((pos["symbol"], mv))

total = sum(v for _, v in values)
values.sort(key=lambda x: -x[1])
print("Portfolio concentration:")
for sym, mv in values:
    pct = mv / total * 100 if total else 0
    print(f"  {sym}: ${mv:,.0f} ({pct:.1f}%)")

All Recipes in JavaScript, Go, and Rust

Setup (JavaScript)

const BASE_URL = "https://api.connecttrade.com";

const HEADERS = {
  "client-id": "YOUR_CLIENT_ID",
  "client-secret": "YOUR_CLIENT_SECRET",
  "user-id": "YOUR_USER_ID",
  "user-secret": "YOUR_USER_SECRET",
};

async function get(path, params = {}) {
  const url = new URL(`${BASE_URL}${path}`);
  Object.entries(params).forEach(([k, v]) => url.searchParams.set(k, v));
  const res = await fetch(url, { headers: HEADERS });
  if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);
  return res.json();
}

async function post(path, body) {
  const res = await fetch(`${BASE_URL}${path}`, {
    method: "POST",
    headers: { ...HEADERS, "Content-Type": "application/json" },
    body: JSON.stringify(body),
  });
  if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);
  return res.json();
}

async function del(path) {
  const res = await fetch(`${BASE_URL}${path}`, {
    method: "DELETE",
    headers: HEADERS,
  });
  if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);
  return res.json();
}

async function patch(path, body) {
  const res = await fetch(`${BASE_URL}${path}`, {
    method: "PATCH",
    headers: { ...HEADERS, "Content-Type": "application/json" },
    body: JSON.stringify(body),
  });
  if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);
  return res.json();
}

Setup (Go)

package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/url"
)

const baseURL = "https://api.connecttrade.com"

var headers = map[string]string{
	"client-id":     "YOUR_CLIENT_ID",
	"client-secret": "YOUR_CLIENT_SECRET",
	"user-id":       "YOUR_USER_ID",
	"user-secret":   "YOUR_USER_SECRET",
}

func doRequest(method, path string, params map[string]string, body any) ([]byte, error) {
	u, _ := url.Parse(baseURL + path)
	if params != nil {
		q := u.Query()
		for k, v := range params {
			q.Set(k, v)
		}
		u.RawQuery = q.Encode()
	}
	var reqBody io.Reader
	if body != nil {
		b, _ := json.Marshal(body)
		reqBody = bytes.NewReader(b)
	}
	req, _ := http.NewRequest(method, u.String(), reqBody)
	for k, v := range headers {
		req.Header.Set(k, v)
	}
	if body != nil {
		req.Header.Set("Content-Type", "application/json")
	}
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	return io.ReadAll(resp.Body)
}

Setup (Rust)

use reqwest::header::{HeaderMap, HeaderValue};
use serde_json::Value;

fn build_headers() -> HeaderMap {
    let mut h = HeaderMap::new();
    h.insert("client-id",     HeaderValue::from_static("YOUR_CLIENT_ID"));
    h.insert("client-secret", HeaderValue::from_static("YOUR_CLIENT_SECRET"));
    h.insert("user-id",       HeaderValue::from_static("YOUR_USER_ID"));
    h.insert("user-secret",   HeaderValue::from_static("YOUR_USER_SECRET"));
    h
}

fn client() -> reqwest::Client {
    reqwest::Client::builder()
        .default_headers(build_headers())
        .build()
        .unwrap()
}

async fn get(path: &str, params: &[(&str, &str)]) -> Value {
    let url = format!("https://api.connecttrade.com{}", path);
    client().get(&url).query(params)
        .send().await.unwrap()
        .json().await.unwrap()
}

async fn post(path: &str, body: &Value) -> Value {
    let url = format!("https://api.connecttrade.com{}", path);
    client().post(&url).json(body)
        .send().await.unwrap()
        .json().await.unwrap()
}

async fn delete(path: &str) -> Value {
    let url = format!("https://api.connecttrade.com{}", path);
    client().delete(&url)
        .send().await.unwrap()
        .json().await.unwrap()
}

Get Account Balances (JavaScript)

const balances = await get("/balances");
for (const bal of balances) {
  console.log(`Account ${bal.account_number}: cash=${bal.cash}, buying_power=${bal.buying_power}`);
}

Get Account Balances (Go)

data, _ := doRequest("GET", "/balances", nil, nil)
var balances []map[string]any
json.Unmarshal(data, &balances)
for _, bal := range balances {
    fmt.Printf("Account %s: cash=%s, buying_power=%s
",
        bal["account_number"], bal["cash"], bal["buying_power"])
}

Get Account Balances (Rust)

let balances = get("/balances", &[]).await;
for bal in balances.as_array().unwrap() {
    println!("Account {}: cash={}, buying_power={}",
        bal["account_number"], bal["cash"], bal["buying_power"]);
}

Get Positions (JavaScript)

const positions = await get("/positions");
for (const pos of positions) {
  console.log(`${pos.symbol}: ${pos.quantity} shares @ ${pos.last_price}, unrealized P&L: ${pos.unrealized_pl}`);
}

Get Positions (Go)

data, _ := doRequest("GET", "/positions", nil, nil)
var positions []map[string]any
json.Unmarshal(data, &positions)
for _, pos := range positions {
    fmt.Printf("%s: %s shares @ %s, unrealized P&L: %s
",
        pos["symbol"], pos["quantity"], pos["last_price"], pos["unrealized_pl"])
}

Get Positions (Rust)

let positions = get("/positions", &[]).await;
for pos in positions.as_array().unwrap() {
    println!("{}: {} shares @ {}, unrealized P&L: {}",
        pos["symbol"], pos["quantity"], pos["last_price"], pos["unrealized_pl"]);
}

Get Open Orders (JavaScript)

const orders = await get("/orders", { status: "open" });
for (const order of orders) {
  console.log(`${order.symbol} ${order.side} ${order.order_qty} (${order.order_type}) — ${order.normalized_status}`);
}

Get Open Orders (Go)

data, _ := doRequest("GET", "/orders", map[string]string{"status": "open"}, nil)
var orders []map[string]any
json.Unmarshal(data, &orders)
for _, o := range orders {
    fmt.Printf("%s %s %s (%s) — %s
",
        o["symbol"], o["side"], o["order_qty"], o["order_type"], o["normalized_status"])
}

Get Open Orders (Rust)

let orders = get("/orders", &[("status", "open")]).await;
for o in orders.as_array().unwrap() {
    println!("{} {} {} ({}) — {}",
        o["symbol"], o["side"], o["order_qty"], o["order_type"], o["normalized_status"]);
}

Get Filled Orders (JavaScript)

const orders = await get("/orders", { status: "filled", sort: "last_exec_time:desc", limit: "20" });
for (const order of orders) {
  const totalFilled = (order.fills || []).reduce((s, f) => s + parseFloat(f.quantity), 0);
  console.log(`${order.symbol} ${order.side} filled ${totalFilled} shares`);
}

Get Filled Orders (Go)

data, _ := doRequest("GET", "/orders", map[string]string{
    "status": "filled", "sort": "last_exec_time:desc", "limit": "20",
}, nil)
var orders []map[string]any
json.Unmarshal(data, &orders)
for _, o := range orders {
    total := 0.0
    if fills, ok := o["fills"].([]any); ok {
        for _, f := range fills {
            fill := f.(map[string]any)
            qty := 0.0
            fmt.Sscanf(fill["quantity"].(string), "%f", &qty)
            total += qty
        }
    }
    fmt.Printf("%s %s filled %.0f shares
", o["symbol"], o["side"], total)
}

Get Filled Orders (Rust)

let orders = get("/orders", &[
    ("status", "filled"), ("sort", "last_exec_time:desc"), ("limit", "20"),
]).await;
for o in orders.as_array().unwrap() {
    let total: f64 = o["fills"].as_array().unwrap_or(&vec![])
        .iter()
        .map(|f| f["quantity"].as_str().unwrap().parse::<f64>().unwrap())
        .sum();
    println!("{} {} filled {} shares", o["symbol"], o["side"], total);
}

List Connected Accounts (JavaScript)

const accounts = await get("/accounts");
for (const acct of accounts) {
  console.log(`${acct.institution_name} — ${acct.account_number} (id: ${acct.account_id})`);
}

List Connected Accounts (Go)

data, _ := doRequest("GET", "/accounts", nil, nil)
var accounts []map[string]any
json.Unmarshal(data, &accounts)
for _, acct := range accounts {
    fmt.Printf("%s — %s (id: %s)
",
        acct["institution_name"], acct["account_number"], acct["account_id"])
}

List Connected Accounts (Rust)

let accounts = get("/accounts", &[]).await;
for acct in accounts.as_array().unwrap() {
    println!("{} — {} (id: {})",
        acct["institution_name"], acct["account_number"], acct["account_id"]);
}

Get Recent Transactions (JavaScript)

const txns = await get("/transactions", { start_date: "2025-06-01", end_date: "2025-06-30" });
for (const txn of txns) {
  console.log(`${txn.transaction_type}: ${txn.symbol ?? "N/A"} — ${txn.amount ?? "N/A"}`);
}

Get Recent Transactions (Go)

data, _ := doRequest("GET", "/transactions", map[string]string{
    "start_date": "2025-06-01", "end_date": "2025-06-30",
}, nil)
var txns []map[string]any
json.Unmarshal(data, &txns)
for _, txn := range txns {
    sym, _ := txn["symbol"].(string)
    amt, _ := txn["amount"].(string)
    if sym == "" { sym = "N/A" }
    if amt == "" { amt = "N/A" }
    fmt.Printf("%s: %s — %s
", txn["transaction_type"], sym, amt)
}

Get Recent Transactions (Rust)

let txns = get("/transactions", &[
    ("start_date", "2025-06-01"), ("end_date", "2025-06-30"),
]).await;
for txn in txns.as_array().unwrap() {
    let sym = txn["symbol"].as_str().unwrap_or("N/A");
    let amt = txn["amount"].as_str().unwrap_or("N/A");
    println!("{}: {} — {}", txn["transaction_type"], sym, amt);
}

Place a Market Order (JavaScript)

const order = await post("/orders", {
  account_id: "YOUR_ACCOUNT_ID",
  cl_order_id: crypto.randomUUID().slice(0, 30),
  broker: "ALPACA",
  side: "BUY",
  order_qty: "10",
  order_type: "MKT",
  order_tif: "DAY",
  instrument: "STK",
  symbol: "AAPL",
});
console.log(`Order ${order.order_id} — status: ${order.normalized_status}`);

Place a Market Order (Go)

body := map[string]any{
    "account_id":  "YOUR_ACCOUNT_ID",
    "cl_order_id": fmt.Sprintf("%d", time.Now().UnixNano())[:30],
    "broker": "ALPACA", "side": "BUY", "order_qty": "10",
    "order_type": "MKT", "order_tif": "DAY",
    "instrument": "STK", "symbol": "AAPL",
}
data, _ := doRequest("POST", "/orders", nil, body)
var order map[string]any
json.Unmarshal(data, &order)
fmt.Printf("Order %s — status: %s
", order["order_id"], order["normalized_status"])

Place a Market Order (Rust)

let order = post("/orders", &serde_json::json!({
    "account_id": "YOUR_ACCOUNT_ID",
    "cl_order_id": &uuid::Uuid::new_v4().to_string()[..30],
    "broker": "ALPACA", "side": "BUY", "order_qty": "10",
    "order_type": "MKT", "order_tif": "DAY",
    "instrument": "STK", "symbol": "AAPL"
})).await;
println!("Order {} — status: {}", order["order_id"], order["normalized_status"]);

Cancel All Open Orders (JavaScript)

const orders = await get("/orders", { status: "open" });
for (const order of orders) {
  const result = await del(`/accounts/${order.account_id}/orders/${order.order_id}`);
  console.log(`Cancelled ${order.symbol} ${order.side} — ${result.message}`);
}

Cancel All Open Orders (Go)

data, _ := doRequest("GET", "/orders", map[string]string{"status": "open"}, nil)
var orders []map[string]any
json.Unmarshal(data, &orders)
for _, o := range orders {
    path := fmt.Sprintf("/accounts/%s/orders/%s", o["account_id"], o["order_id"])
    res, _ := doRequest("DELETE", path, nil, nil)
    var result map[string]any
    json.Unmarshal(res, &result)
    fmt.Printf("Cancelled %s %s — %s
", o["symbol"], o["side"], result["message"])
}

Cancel All Open Orders (Rust)

let orders = get("/orders", &[("status", "open")]).await;
for o in orders.as_array().unwrap() {
    let path = format!("/accounts/{}/orders/{}",
        o["account_id"].as_str().unwrap(),
        o["order_id"].as_str().unwrap());
    let result = delete(&path).await;
    println!("Cancelled {} {} — {}", o["symbol"], o["side"], result["message"]);
}

Sum Unrealized P&L (JavaScript)

const positions = await get("/positions");
const totalPl = positions
  .filter((p) => p.unrealized_pl != null)
  .reduce((sum, p) => sum + parseFloat(p.unrealized_pl), 0);
console.log(`Total unrealized P&L: ${totalPl.toFixed(2)}`);

Sum Unrealized P&L (Go)

data, _ := doRequest("GET", "/positions", nil, nil)
var positions []map[string]any
json.Unmarshal(data, &positions)
total := 0.0
for _, p := range positions {
    if pl, ok := p["unrealized_pl"].(string); ok {
        v := 0.0
        fmt.Sscanf(pl, "%f", &v)
        total += v
    }
}
fmt.Printf("Total unrealized P&L: $%.2f
", total)

Sum Unrealized P&L (Rust)

let positions = get("/positions", &[]).await;
let total: f64 = positions.as_array().unwrap()
    .iter()
    .filter_map(|p| p["unrealized_pl"].as_str()?.parse::<f64>().ok())
    .sum();
println!("Total unrealized P&L: ${:.2}", total);

Fills from Today (JavaScript)

const today = new Date().toISOString().split("T")[0] + "T00:00:00Z";
const orders = await get("/orders", {
  status: "all", start_time: today, sort: "last_exec_time:desc", limit: "500",
});

const fills = orders.flatMap((order) =>
  (order.fills || []).map((fill) => ({
    symbol: order.symbol, side: order.side,
    price: fill.price, quantity: fill.quantity, time: fill.time,
  }))
);

console.log(`Total fills today: ${fills.length}`);
fills.slice(0, 10).forEach((f) => {
  console.log(`  ${f.time} ${f.symbol} ${f.side} ${f.quantity} @ ${f.price}`);
});

Fills from Today (Go)

today := time.Now().UTC().Format("2006-01-02") + "T00:00:00Z"
data, _ := doRequest("GET", "/orders", map[string]string{
    "status": "all", "start_time": today,
    "sort": "last_exec_time:desc", "limit": "500",
}, nil)
var orders []map[string]any
json.Unmarshal(data, &orders)

type Fill struct{ Symbol, Side, Price, Qty, Time string }
var fills []Fill
for _, o := range orders {
    if fs, ok := o["fills"].([]any); ok {
        for _, f := range fs {
            fm := f.(map[string]any)
            fills = append(fills, Fill{
                o["symbol"].(string), o["side"].(string),
                fm["price"].(string), fm["quantity"].(string), fm["time"].(string),
            })
        }
    }
}
fmt.Printf("Total fills today: %d
", len(fills))
for i, f := range fills {
    if i >= 10 { break }
    fmt.Printf("  %s %s %s %s @ %s
", f.Time, f.Symbol, f.Side, f.Qty, f.Price)
}

Fills from Today (Rust)

let today = chrono::Utc::now().format("%Y-%m-%dT00:00:00Z").to_string();
let orders = get("/orders", &[
    ("status", "all"), ("start_time", &today),
    ("sort", "last_exec_time:desc"), ("limit", "500"),
]).await;

let mut fills = vec![];
for o in orders.as_array().unwrap() {
    for f in o["fills"].as_array().unwrap_or(&vec![]) {
        fills.push((
            o["symbol"].as_str().unwrap(), o["side"].as_str().unwrap(),
            f["quantity"].as_str().unwrap(), f["price"].as_str().unwrap(),
            f["time"].as_str().unwrap(),
        ));
    }
}
println!("Total fills today: {}", fills.len());
for (sym, side, qty, px, time) in fills.iter().take(10) {
    println!("  {} {} {} {} @ {}", time, sym, side, qty, px);
}

Momentum Signal (JavaScript)

import WebSocket from "ws";

const tokenResp = await get("/connections/YOUR_CONNECTION_ID/token");
const ws = new WebSocket("wss://mdstream.connecttrade.com");

ws.on("open", () => {
  ws.send(JSON.stringify({
    action: "authenticate", access_token: tokenResp.access_token,
    request_id: crypto.randomUUID(), version: "v1.0",
  }));
});

const bars = [];
ws.on("message", (raw) => {
  const msg = JSON.parse(raw);
  if (msg.type === "auth_success") {
    ws.send(JSON.stringify({
      action: "subscribe", channel: "bars", symbol: "SPY",
      interval: "1d", session: "USEqCore",
      request_id: crypto.randomUUID(), backfill_nbars: 20,
    }));
  }
  if (msg.c) {
    bars.push(parseFloat(msg.c));
    if (bars.length >= 20) {
      const momentum = bars[bars.length - 1] / bars[0] - 1;
      console.log(`SPY 20-day momentum: ${(momentum * 100).toFixed(2)}%`);
      ws.close();
    }
  }
});

Momentum Signal (Go)

// Uses gorilla/websocket
import "github.com/gorilla/websocket"

data, _ := doRequest("GET", "/connections/YOUR_CONNECTION_ID/token", nil, nil)
var tokenResp map[string]any
json.Unmarshal(data, &tokenResp)

conn, _, _ := websocket.DefaultDialer.Dial("wss://mdstream.connecttrade.com", nil)
defer conn.Close()

conn.WriteJSON(map[string]any{
    "action": "authenticate", "access_token": tokenResp["access_token"],
    "request_id": fmt.Sprintf("%d", time.Now().UnixNano()), "version": "v1.0",
})
var authResp map[string]any
conn.ReadJSON(&authResp)

conn.WriteJSON(map[string]any{
    "action": "subscribe", "channel": "bars", "symbol": "SPY",
    "interval": "1d", "session": "USEqCore",
    "request_id": fmt.Sprintf("%d", time.Now().UnixNano()), "backfill_nbars": 20,
})

var bars []float64
for {
    var msg map[string]any
    conn.ReadJSON(&msg)
    if c, ok := msg["c"].(string); ok {
        v := 0.0
        fmt.Sscanf(c, "%f", &v)
        bars = append(bars, v)
        if len(bars) >= 20 {
            momentum := (bars[len(bars)-1] / bars[0]) - 1
            fmt.Printf("SPY 20-day momentum: %+.2f%%
", momentum*100)
            break
        }
    }
}

Momentum Signal (Rust)

// Uses tokio-tungstenite
use tokio_tungstenite::connect_async;
use futures_util::{SinkExt, StreamExt};

let token: Value = get("/connections/YOUR_CONNECTION_ID/token", &[]).await;
let (mut ws, _) = connect_async("wss://mdstream.connecttrade.com").await.unwrap();

ws.send(serde_json::json!({
    "action": "authenticate",
    "access_token": token["access_token"].as_str().unwrap(),
    "request_id": uuid::Uuid::new_v4().to_string(),
    "version": "v1.0"
}).to_string().into()).await.unwrap();
let _ = ws.next().await;

ws.send(serde_json::json!({
    "action": "subscribe", "channel": "bars", "symbol": "SPY",
    "interval": "1d", "session": "USEqCore",
    "request_id": uuid::Uuid::new_v4().to_string(), "backfill_nbars": 20
}).to_string().into()).await.unwrap();

let mut bars: Vec<f64> = vec![];
while let Some(Ok(msg)) = ws.next().await {
    let data: Value = serde_json::from_str(&msg.to_string()).unwrap_or_default();
    if let Some(c) = data["c"].as_str() {
        bars.push(c.parse().unwrap());
        if bars.len() >= 20 {
            let momentum = bars.last().unwrap() / bars[0] - 1.0;
            println!("SPY 20-day momentum: {:.2}%", momentum * 100.0);
            break;
        }
    }
}

Calculate VWAP (JavaScript)

const today = new Date().toISOString().split("T")[0] + "T00:00:00Z";
const orders = await get("/orders", {
  status: "filled", symbols: "AAPL", start_time: today, limit: "500",
});

let totalQty = 0, totalCost = 0;
for (const order of orders) {
  for (const fill of order.fills || []) {
    const qty = parseFloat(fill.quantity), px = parseFloat(fill.price);
    totalQty += qty;
    totalCost += qty * px;
  }
}
if (totalQty > 0) {
  console.log(`AAPL execution VWAP: ${(totalCost / totalQty).toFixed(4)} (${totalQty} shares)`);
}

Calculate VWAP (Go)

today := time.Now().UTC().Format("2006-01-02") + "T00:00:00Z"
data, _ := doRequest("GET", "/orders", map[string]string{
    "status": "filled", "symbols": "AAPL", "start_time": today, "limit": "500",
}, nil)
var orders []map[string]any
json.Unmarshal(data, &orders)

totalQty, totalCost := 0.0, 0.0
for _, o := range orders {
    if fills, ok := o["fills"].([]any); ok {
        for _, f := range fills {
            fm := f.(map[string]any)
            qty, px := 0.0, 0.0
            fmt.Sscanf(fm["quantity"].(string), "%f", &qty)
            fmt.Sscanf(fm["price"].(string), "%f", &px)
            totalQty += qty
            totalCost += qty * px
        }
    }
}
if totalQty > 0 {
    fmt.Printf("AAPL execution VWAP: $%.4f (%.0f shares)
", totalCost/totalQty, totalQty)
}

Calculate VWAP (Rust)

let today = chrono::Utc::now().format("%Y-%m-%dT00:00:00Z").to_string();
let orders = get("/orders", &[
    ("status", "filled"), ("symbols", "AAPL"),
    ("start_time", &today), ("limit", "500"),
]).await;

let (mut total_qty, mut total_cost) = (0.0_f64, 0.0_f64);
for o in orders.as_array().unwrap() {
    for f in o["fills"].as_array().unwrap_or(&vec![]) {
        let qty: f64 = f["quantity"].as_str().unwrap().parse().unwrap();
        let px:  f64 = f["price"].as_str().unwrap().parse().unwrap();
        total_qty  += qty;
        total_cost += qty * px;
    }
}
if total_qty > 0.0 {
    println!("AAPL execution VWAP: ${:.4} ({:.0} shares)", total_cost / total_qty, total_qty);
}

Portfolio Concentration (JavaScript)

const positions = await get("/positions");
const values = positions
  .filter((p) => p.last_price && p.quantity)
  .map((p) => ({ symbol: p.symbol, mv: parseFloat(p.last_price) * parseFloat(p.quantity) }))
  .sort((a, b) => b.mv - a.mv);

const total = values.reduce((s, v) => s + v.mv, 0);
console.log("Portfolio concentration:");
for (const { symbol, mv } of values) {
  console.log(`  ${symbol}: ${mv.toFixed(0)} (${((mv / total) * 100).toFixed(1)}%)`);
}

Portfolio Concentration (Go)

data, _ := doRequest("GET", "/positions", nil, nil)
var positions []map[string]any
json.Unmarshal(data, &positions)

type Holding struct { Symbol string; MV float64 }
var holdings []Holding
total := 0.0
for _, p := range positions {
    px, qty := 0.0, 0.0
    if s, ok := p["last_price"].(string); ok { fmt.Sscanf(s, "%f", &px) }
    if s, ok := p["quantity"].(string);   ok { fmt.Sscanf(s, "%f", &qty) }
    if px > 0 && qty > 0 {
        mv := px * qty
        holdings = append(holdings, Holding{p["symbol"].(string), mv})
        total += mv
    }
}
sort.Slice(holdings, func(i, j int) bool { return holdings[i].MV > holdings[j].MV })
fmt.Println("Portfolio concentration:")
for _, h := range holdings {
    fmt.Printf("  %s: $%.0f (%.1f%%)
", h.Symbol, h.MV, h.MV/total*100)
}

Portfolio Concentration (Rust)

let positions = get("/positions", &[]).await;
let mut values: Vec<(&str, f64)> = positions.as_array().unwrap()
    .iter()
    .filter_map(|p| {
        let px:  f64 = p["last_price"].as_str()?.parse().ok()?;
        let qty: f64 = p["quantity"].as_str()?.parse().ok()?;
        Some((p["symbol"].as_str()?, px * qty))
    })
    .collect();
values.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap());
let total: f64 = values.iter().map(|v| v.1).sum();
println!("Portfolio concentration:");
for (sym, mv) in &values {
    println!("  {}: ${:.0} ({:.1}%)", sym, mv, mv / total * 100.0);
}

Full API documentation | Interactive API reference (Redoc) | API documentation overview