v1.0 — API Reference

Developer API Reference

Complete technical documentation for integrating HFThot Research Lab into your systems. Covers REST, WebSocket, gRPC, and Lakehouse APIs with Python and Rust examples.

🏔️ Polarway

Hybrid lakehouse engine powering all data storage, streaming, and ACID-compliant writes.

ReadTheDocs →
⚙️ optimiz-rs

Rust optimization library — DE/SHADE solvers, MFG equations, PyO3 bindings.

GitHub →
🔥 HFThot Core

Rust HFT core — gRPC server (Tonic), WebSocket feed, strategy engine.

GitHub →

🔑 Authentication

All API calls require an HFThot API key. Pass it as a header on every request.

X-HFThot-API-Key: hft_abc123_your-key-here
API keys are generated by the Polarway Lakehouse during user registration. Keys are tied to your subscription tier and rate limits. Obtain yours at hfthot-lab.eu/app/

Key Tiers

TierKey prefixRate limitFeatures
Free Betahft_free_60 req/minMarket data, Regime stream
Hobbyisthft_hob_300 req/min+ Portfolio optimization, Backtest
Professionalhft_pro_2000 req/min+ gRPC, Lakehouse, Websocket
Enterprisehft_ent_UnlimitedAll features + SLA + dedicated infra

⚡ Rate Limits

Rate limits are enforced per API key using a sliding window algorithm. Exceeding the limit returns HTTP 429.

60
req/min · Free
300
req/min · Hobbyist
2000
req/min · Pro
req/min · Enterprise

Response headers include current limit data:

X-RateLimit-Limit: 300
X-RateLimit-Remaining: 247
X-RateLimit-Reset: 1706785200

⚠️ Error Codes

HTTP StatusCodeDescription
200 OKSuccess
400INVALID_PARAMSMissing or invalid request parameters
401UNAUTHORIZEDMissing or invalid API key
403TIER_REQUIREDEndpoint requires higher subscription tier
429RATE_LIMITEDToo many requests — see X-RateLimit-Reset
500INTERNAL_ERRORUnexpected server error — retry with exponential backoff

GET Market Data

Base URL: https://api.hfthot-lab.eu/v1
GET /market/ohlcv Fetch OHLCV bars from Polarway lakehouse

Query Parameters

ParameterTypeRequiredDescription
symbolstringrequiredTrading pair, e.g. BTC-USDT
intervalstringrequired1m, 5m, 15m, 1h, 1d
start_timeint64optionalUnix ms timestamp (default: 1000 bars ago)
end_timeint64optionalUnix ms timestamp (default: now)
limitintoptionalMax bars returned (default: 500, max: 5000)
import requests

resp = requests.get(
    "https://api.hfthot-lab.eu/v1/market/ohlcv",
    headers={"X-HFThot-API-Key": "hft_pro_your_key"},
    params={"symbol": "BTC-USDT", "interval": "5m", "limit": 100}
)
data = resp.json()
# data["bars"] → list of {time, open, high, low, close, volume}
curl -G https://api.hfthot-lab.eu/v1/market/ohlcv \
  -H "X-HFThot-API-Key: hft_pro_your_key" \
  -d symbol=BTC-USDT \
  -d interval=5m \
  -d limit=100
200 Response
{
  "symbol": "BTC-USDT",
  "interval": "5m",
  "bars": [
    {"time": 1706784000000, "open": 42150.5, "high": 42280.0,
     "low": 42100.3, "close": 42250.8, "volume": 183.42},
    ...
  ],
  "source": "polarway-lakehouse",
  "latency_ms": 18
}
GET /market/orderbook Top-N L2 order book snapshot
ParameterTypeRequiredDescription
symbolstringrequiredTrading pair
depthintoptionalLevels per side (default: 20, max: 100)

GET Trading Signals

GET /signals/regime Current HMM regime classification

Returns the current market regime detected by the 3-state Hidden Markov Model (HMM) and the strategy recommendation.

ParameterTypeRequiredDescription
symbolstringrequiredTrading pair
lookbackintoptionalBars used for HMM inference (default: 200)
{
  "symbol": "BTC-USDT",
  "regime": "mean_reverting",
  "confidence": 0.87,
  "strategy": "stat_arb",
  "state_probs": {
    "trending": 0.06,
    "mean_reverting": 0.87,
    "volatile": 0.07
  },
  "latency_us": 94
}
GET /signals/mfg-price Mean Field Game price prediction (optimiz-rs)

Runs the HJB-FP equation system via optimiz-rs to predict equilibrium price trajectory over a finite horizon.

ParameterTypeRequiredDescription
symbolstringrequiredTrading pair
horizon_minintoptionalPrediction horizon in minutes (default: 5)
n_agentsintoptionalNumber of agents in simulation (default: 1000)
Requires Professional tier or above. Returns 403 TIER_REQUIRED for lower tiers.

POST Portfolio Optimization

POST /portfolio/optimize Compute optimal weights via CARA, Risk Parity, or Sparse L1

Request Body (JSON)

FieldTypeRequiredDescription
methodstringrequired"cara", "risk_parity", or "sparse_l1"
symbolsstring[]requiredArray of trading pairs
lookback_daysintoptionalDays of history for covariance (default: 60)
gammafloatoptionalRisk aversion (CARA only, default: 2.0)
rhofloatoptionalL1 sparsity penalty (sparse_l1 only, default: 0.05)
import requests

resp = requests.post(
    "https://api.hfthot-lab.eu/v1/portfolio/optimize",
    headers={"X-HFThot-API-Key": "hft_pro_your_key"},
    json={
        "method": "risk_parity",
        "symbols": ["BTC-USDT", "ETH-USDT", "SOL-USDT"],
        "lookback_days": 30
    }
)
result = resp.json()
print(result["weights"])
# → {"BTC-USDT": 0.35, "ETH-USDT": 0.42, "SOL-USDT": 0.23}
// Using hfthot-rs client (see SDK section)
let client = HfthotClient::new("hft_pro_your_key");
let weights = client
    .portfolio()
    .optimize(OptimizeRequest {
        method: Method::RiskParity,
        symbols: vec!["BTC-USDT", "ETH-USDT", "SOL-USDT"],
        lookback_days: 30,
        ..Default::default()
    })
    .await?;
println!("{:?}", weights); 
// Weights { btc_usdt: 0.35, eth_usdt: 0.42, sol_usdt: 0.23 }

GET Lakehouse Queries

GET /lakehouse/query Execute a DuckDB SQL query on Polarway data
SQL queries are sandboxed (read-only). DROP, INSERT, UPDATE are not allowed.
ParameterTypeRequiredDescription
sqlstringrequiredURL-encoded DuckDB SQL SELECT statement
formatstringoptional"json" (default) or "arrow" (for zero-copy PyArrow)
import requests, urllib.parse

sql = """
  SELECT date_trunc('hour', ts) as hour,
         avg(close) as avg_close,
         sum(volume) as total_vol
  FROM   market.ohlcv
  WHERE  symbol = 'BTC-USDT'
    AND  ts >= now() - INTERVAL '24 hours'
  GROUP BY 1 ORDER BY 1
"""
resp = requests.get(
    "https://api.hfthot-lab.eu/v1/lakehouse/query",
    headers={"X-HFThot-API-Key": "hft_pro_your_key"},
    params={"sql": sql, "format": "json"}
)
print(resp.json()["rows"])

🔌 WebSocket API

Real-time streaming over WebSocket. Authenticate by passing the API key as a query parameter during handshake.

WS URL: wss://api.hfthot-lab.eu/v1/stream
WebSocket connections auto-heartbeat every 30 s. Send {"type":"ping"} and expect {"type":"pong"}. Connections idle for 60 s are closed.

Connection

import websockets, asyncio, json

async def stream():
    url = "wss://api.hfthot-lab.eu/v1/stream?api_key=hft_pro_your_key"
    async with websockets.connect(url) as ws:
        # Subscribe to price feed
        await ws.send(json.dumps({
            "type": "subscribe",
            "stream": "price_feed",
            "symbol": "BTC-USDT"
        }))
        async for msg in ws:
            data = json.loads(msg)
            print(data)

asyncio.run(stream())

📡 Price Feed Stream

Subscribe to live tick-by-tick price updates sourced from exchange WebSockets, normalized and forwarded through the Polarway streaming layer.

Subscribe message

{"type": "subscribe", "stream": "price_feed", "symbol": "BTC-USDT"}

Incoming messages

{
  "type": "tick",
  "symbol": "BTC-USDT",
  "price": 42315.50,
  "qty": 0.024,
  "side": "buy",
  "ts_ms": 1706785201423,
  "latency_us": 320
}

🌊 Regime Stream

Subscribe to HMM regime state changes. The server pushes an update whenever the Viterbi algorithm detects a state transition with confidence > 0.75.

{"type": "subscribe", "stream": "regime", "symbol": "BTC-USDT"}

// Incoming regime change:
{
  "type": "regime_change",
  "symbol": "BTC-USDT",
  "from": "trending",
  "to": "mean_reverting",
  "confidence": 0.89,
  "recommended_strategy": "stat_arb",
  "ts_ms": 1706785260000
}

⚡ gRPC / RPC API

The HFThot Core exposes a Tonic gRPC server on port 50053 for ultra-low-latency access. Recommended for algorithmic trading bots requiring sub-millisecond round-trips.

50053
gRPC port
<1ms
Round-trip latency
TLS
Transport security
Proto3
Schema definition
Use gRPC for latency-critical paths (order submission, tick processing). Use REST for everything else (analytics, backtesting).

📄 Proto Definition

syntax = "proto3"; package hfthot.v1; // Market data service — real-time ticks and OHLCV service MarketService { rpc GetTicker (TickerRequest) returns (TickerResponse); rpc StreamTicks (SubscribeRequest) returns (stream Tick); rpc GetOHLCV (OHLCVRequest) returns (OHLCVResponse); } // Signals service — regime detection, MFG pricing service SignalService { rpc GetRegime (RegimeRequest) returns (RegimeResponse); rpc GetMFGPrice (MFGRequest) returns (MFGResponse); rpc StreamRegime (SubscribeRequest) returns (stream RegimeEvent); } // Portfolio optimization — calls optimiz-rs via FFI service PortfolioService { rpc Optimize (OptimizeRequest) returns (OptimizeResponse); rpc Backtest (BacktestRequest) returns (BacktestResponse); } // Message types message TickerRequest { string symbol = 1; } message TickerResponse { string symbol = 1; double bid = 2; double ask = 3; double last = 4; int64 ts_ms = 5; } message RegimeRequest { string symbol = 1; int32 lookback = 2; } message RegimeResponse { string regime = 1; // "trending" | "mean_reverting" | "volatile" double confidence = 2; string strategy = 3; int64 latency_us = 4; }

💻 gRPC Code Examples

import grpc
import hfthot_pb2 as pb
import hfthot_pb2_grpc as stub

# Authenticated channel with TLS
credentials = grpc.ssl_channel_credentials()
channel = grpc.secure_channel("api.hfthot-lab.eu:50053", credentials)
metadata = [("x-hfthot-api-key", "hft_pro_your_key")]

client = stub.SignalServiceStub(channel)
resp = client.GetRegime(
    pb.RegimeRequest(symbol="BTC-USDT", lookback=200),
    metadata=metadata
)
print(f"Regime: {resp.regime} ({resp.confidence:.0%}) → {resp.strategy}")
# Regime: mean_reverting (87%) → stat_arb

# Streaming ticks
market = stub.MarketServiceStub(channel)
for tick in market.StreamTicks(pb.SubscribeRequest(symbol="BTC-USDT"), metadata=metadata):
    print(f"{tick.ts_ms}: {tick.price} ({tick.side})")
use hfthot::v1::{signal_service_client::SignalServiceClient, RegimeRequest};
use tonic::{Request, transport::Channel, metadata::MetadataValue};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let channel = Channel::from_static("https://api.hfthot-lab.eu:50053")
        .connect()
        .await?;

    let token: MetadataValue<_> = "hft_pro_your_key".parse()?;
    let mut client = SignalServiceClient::with_interceptor(channel, move |mut req: Request<()>| {
        req.metadata_mut().insert("x-hfthot-api-key", token.clone());
        Ok(req)
    });

    let resp = client.get_regime(RegimeRequest {
        symbol: "BTC-USDT".into(),
        lookback: 200,
    }).await?.into_inner();

    println!("Regime: {} ({:.0}%) → {}",
        resp.regime,
        resp.confidence * 100.0,
        resp.strategy
    );
    Ok(())
}

🗄️ Lakehouse API

The Polarway Lakehouse is the data storage backbone of HFThot — a Delta Lake-backed system providing ACID transactions, time-travel queries, and RGPD compliance. It serves both the user auth system and the market data store.

🔒
ACID
Delta Lake
⏱️
Time-Travel
Any version
Polars
Lazy eval
🛡️
RGPD
Art. 15/17/20

Full Lakehouse documentation: polarway.readthedocs.io → Lakehouse

🐍 Python Client

from python.lakehouse.client import LakehouseClient

client = LakehouseClient(
    base_path="/app/data/lakehouse",
    api_key="hft_pro_your_key"
)

# Read latest 1000 BTC bars with Polars lazy frame
df = (
    client.market("BTC-USDT")
          .ohlcv(interval="5m")
          .tail(1000)
          .collect()           # Polars LazyFrame → DataFrame
)
print(df.head())

# Read API key quota status
keys = client.get_api_keys(user_id="user-123")
print(f"Finnhub remaining: {keys['provider_keys']['finnhub']['queries_remaining']}")

⏱️ Time-Travel Queries

Access historical versions of any Delta table — for auditing, regulatory compliance, or debugging.

from datetime import datetime

# By version number
df_v5 = client.read_version("users", version=5)

# By timestamp (e.g. MiFID II audit)
audit_ts = datetime(2026, 1, 15, 14, 0, 0)
df_jan15 = client.read_at_timestamp("api_keys", audit_ts)

# List all available versions
versions = client.list_versions("market/BTC-USDT")
# [{"version": 0, "ts": "2026-01-01T00:00:00Z", "operation": "WRITE"},
#  {"version": 1, "ts": "2026-01-01T01:00:00Z", "operation": "WRITE"}, ...]
Time-travel is also available via REST: GET /lakehouse/query?sql=SELECT * FROM market.ohlcv VERSION AS OF 5

📦 SDKs & Client Libraries

Python SDK

Full-featured client: REST, WebSocket, Lakehouse. Built on httpx + websockets.

pip install hfthot-sdk
GitHub →

Rust Client

Async Tonic gRPC client + REST. Zero-cost abstractions. Ideal for bots and HFT engines.

hfthot-client = "0.1"
GitHub →

JavaScript / WASM

Browser-ready client via optimiz-rs WASM bindings. Portfolio optimization in the browser.

npm install @hfthot/sdk
GitHub →

🔑 Generate API Key

Create a quota-aware API key tied to your subscription tier. Keys grant access to REST, WebSocket, and gRPC endpoints.

New API Key

2000
req/min
10
WS streams
gRPC access
Lakehouse SQL

📊 Quotas & Billing

Each API key has tier-specific quotas enforced by the Polarway Lakehouse. Monitor usage via response headers or the dashboard.

FeatureFree BetaHobbyistProfessionalEnterprise
REST requests60/min300/min2,000/minUnlimited
WebSocket streams1310Unlimited
gRPC access
Lakehouse SQL queries10/hr100/hrUnlimited
Portfolio optimization5/day50/dayUnlimitedUnlimited
MFG price signals
Historical data depth30 days1 year5 years10+ years
Data export (Parquet)
SLA guarantee99.5%99.95%
Price€0€9/mo€199/moCustom

Usage Dashboard

Track your API usage in real-time via the Streamlit dashboard or programmatically:

import requests

resp = requests.get(
    "https://api.hfthot-lab.eu/v1/account/usage",
    headers={"X-HFThot-API-Key": "hft_pro_your_key"}
)
usage = resp.json()
print(f"Requests today: {usage['requests_today']}/{usage['daily_limit']}")
print(f"WS connections: {usage['ws_active']}/{usage['ws_max']}")
print(f"Tier: {usage['tier']} — renews {usage['billing_cycle_end']}")
Approaching your limit? Upgrade anytime from the Streamlit dashboardAccount SettingsSubscription.