C++ SDK Reference

The Aurum SDK is a C++23 application library. Public strategy types are under namespace aurum; application configuration types are under aurum::sdk. Include the umbrella header and any venue package used by the project:

#include <aurum/sdk.hpp>
#include <aurum/venue/okx.hpp>

using namespace aurum;

Application

Derive one type from sdk::Application and export it with AURUM_EXPORT:

class SignalWatch final : public sdk::Application {
public:
  SignalWatch()
    : sdk::Application({.mode = sdk::RuntimeMode::LIVE}) {
    // Bind devices and handlers here.
  }
};

AURUM_EXPORT(SignalWatch)

AURUM_EXPORT(Type) supplies main(), initializes logging, constructs the application, and returns its run result. A project exports exactly one application type.

Application configuration

Field

Type

Meaning

mode

sdk::RuntimeMode

LIVE or REPLAY. Defaults to LIVE.

replay

sdk::ReplayConfig

Replay speed and optional start/end bounds.

live

sdk::LiveTimeConfig

Late-event, watermark, and source-staleness policy.

accounts

std::vector<venue::Account>

Venue accounts verified during startup.

host

std::string

Runtime HTTP/WebSocket bind host. Defaults to 127.0.0.1.

port

std::uint16_t

Runtime HTTP/WebSocket port. Defaults to 9441.

ws_enabled

bool

Enables the runtime server. Defaults to true.

sdk::ReplayConfig has start_ns, end_ns, speed, has_start, and has_end fields. speed = 0 processes eligible events without wall-clock pacing.

Data sources

Bind a released venue factory with bind<Datafeed>:

bind<Datafeed>(venue::okx::Bar("BTCUSDT", "1m"));
bind<Datafeed>(venue::okx::Orderbook("BTCUSDT"));
bind<Datafeed>(venue::okx::Trades("BTCUSDT"));

The current factories are:

Package

Factory

Canonical resource

OKX

Bar(symbol, interval)

bar://okx/{symbol}@{interval}

OKX

Orderbook / Books / Books5 / BboTbt

book://okx/{symbol}@{full|5|bbo-tbt}

OKX

Trades(symbol)

order://okx/{symbol}/trade

Binance

Bar(symbol, interval)

bar://binance/{symbol}@{interval}

Binance

Orderbook / Depth5 / Depth10 / Depth20 / BookTicker

book://binance/{symbol}@{full|5|10|20|ticker}

Binance

AggTrades / Trades

order://binance/{symbol}/trade

Factories normalize symbols into the resource catalog. Subscribe to the catalog key rather than reproducing venue channel naming rules.

Topic handlers

on(TOPIC<key>, handler) registers a typed handler on the engine thread:

on(TOPIC<"bar://okx/BTCUSDT@1m">,
   [](const Tick<schema::BarRow>& tick) {
  if (tick.payload.close_timestamp == 0) return;
  log::info("close={}", tick.payload.close.to_string());
});

A handler may accept (sdk::Context&, const T&), (const T&), (sdk::Context&), or no arguments. The topic literal selects T at compile time; an incompatible payload does not compile.

Latest values

ref(TOPIC<key>) reads the current cached value:

auto bar = ref(TOPIC<"bar://okx/BTCUSDT@1m">);
if (bar) {
  log::info("high={}", bar->payload.high.to_string());
}

For a factor or scalar topic, ref returns std::optional<double>. For other snapshotable topics it returns std::optional<T>. An empty optional means that the resource has no current value; it is not an error result.

Application-owned topics

emit publishes the payload type selected by an application-owned topic:

emit(TOPIC<"scalar://signal-watch/confidence">,
     Tick<double>{timestamp_ns, 0.82});

Prefer wire for generated factor resources. External clients discover both kinds through the runtime catalog.

Startup readiness

Use require when the application must not become ready until a topic is initialized or warm:

require(TOPIC<"bar://okx/BTCUSDT@1m">);

The default topic requirement is sdk::TopicStartupRequirement::Warm with sdk::StartupFailurePolicy::FailFast. Overloads accept an explicit readiness level, failure policy, and timeout in nanoseconds.

Schedules

set creates a cron or one-shot timer. Bind it with on:

auto& heartbeat = set(cron("*/30 * * * * *"));
on(heartbeat) = [](sdk::Context& context) {
  log::info("engine_time={}", context.engine_time_ns);
};

auto& once = set(timer(time::seconds(5)));
on(once) = [] { log::info("timer fired"); };

cancel(once);

Cron expressions contain six fields, beginning with seconds. User schedules run after startup readiness by default. Pass sdk::during_warmup() to the schedule on overload only for work that is valid before the application is ready.

Paper execution

Bind paper::Account to obtain a device::BoundExecutor:

auto executor = bind<device::BoundExecutor>(paper::Account{
    .id = "paper",
    .balances = {
        {.asset = "USDT", .amount = Notional{100'000}},
        {.asset = "BTC", .amount = Notional{0}},
    },
    .instruments = {
        Instrument::Spot("BTCUSDT", "BTC", "USDT"),
    },
    .simulation = paper::fromBar{
        .topic = "bar://okx/BTCUSDT@1m",
        .latency = time::milliseconds(100),
    },
});

paper::fromBar uses the configured bar resource as fill evidence. paper::BBO uses best-bid/offer evidence for a named venue. Both accept a simulated latency.

Live accounts

Released venue packages expose Account and Executor factories:

auto account = venue::okx::Account("trading", TRADE);
auto executor =
    bind<device::BoundExecutor>(venue::okx::Executor(account));

PUBLIC requests public data access. TRADE, DEPOSIT, and WITHDRAW add private permissions. Private accounts need a matching credential document supplied with aurum run --auth. See Configuration.

Orders and receipts

Submit an Order through a bound executor:

auto receipt = executor.submit(Order{
    .instrument_id = "BTCUSDT",
    .type = OrderType::Market,
    .side = OrderSide::Buy,
    .tif = TimeInForce::Ioc,
    .quantity = Quantity{0.01},
});

on(receipt.accepted) = [](const trading::OrderAccepted& accepted) {
  log::info("accepted {}", accepted.order.client_order_id);
};
on(receipt.rejected) = [](const trading::OrderDenied& denied) {
  log::warn("rejected: {}", denied.reason);
};
on(receipt.filled) = [](const trading::OrderFilled& filled) {
  log::info("filled {}", filled.order.client_order_id);
};
on(receipt.err) = [](const core::QueryErrorInfo& error) {
  log::error("submit failed: {}", error.message);
};

An OrderSubmitReceipt exposes submitted, accepted, rejected, partial_filled, filled, canceled, events, timeout, err, cancel, and eof branches. Local submission does not mean exchange acceptance or fill; handle all outcomes required by the strategy’s risk model.

Cancel by client order ID:

auto cancel_receipt = executor.cancel(client_order_id);
on(cancel_receipt.canceled) = [](const trading::OrderCanceled&) {};
on(cancel_receipt.rejected) =
    [](const trading::OrderCancelRejected& rejected) {
  log::warn("cancel rejected: {}", rejected.reason);
};

The cancellation receipt also exposes requested, already_terminal, timeout, err, cancel, and eof.

Generated factors

wire<source, Plugins...>() attaches Athanor-generated plugins to one explicit bar or book resource:

(void)wire<"bar://okx/BTCUSDT@1m",
    aurum::alpha::spread,
    aurum::alpha::spread_mean>();

The source must include an explicit @ parameter. Do not mix bar-sourced and book-sourced plugins in one call. Ready values are published under factor:// keys and returned as std::optional<double> by ref.

Logging and time

Use log::trace, debug, info, warn, error, and fatal for structured runtime logging. Duration helpers include time::nanoseconds, milliseconds, seconds, and minutes.

See Project Contract for the project contract, Simulation and Replay for the paper workflow, and Resource Contracts for topic payloads and delivery semantics.