longbridge provides an easy-to-use interface for invoking Longbridge OpenAPI.
- SDK docs: https://longbridge.github.io/openapi/c/index.html
- Longbridge OpenAPI: https://open.longbridge.com/en/
Runnable examples live in examples/c/:
examples/c/account_asset/main.cexamples/c/get_quote/main.cexamples/c/http_client/main.cexamples/c/subscribe_quote/main.cexamples/c/submit_order/main.cexamples/c/today_orders/main.c
Install Longbridge OpenAPI SDK
Longbridge OpenAPI supports two authentication methods:
OAuth 2.0 is the modern authentication method that uses Bearer tokens without requiring HMAC signatures.
Step 1: Register OAuth Client
First, register an OAuth client to get your client_id:
bash / macOS / Linux
curl -X POST https://openapi.longbridge.com/oauth2/register \
-H "Content-Type: application/json" \
-d '{
"client_name": "My Application",
"redirect_uris": ["http://localhost:60355/callback"],
"grant_types": ["authorization_code", "refresh_token"]
}'PowerShell (Windows)
Invoke-RestMethod -Method Post -Uri https://openapi.longbridge.com/oauth2/register `
-ContentType "application/json" `
-Body '{
"client_name": "My Application",
"redirect_uris": ["http://localhost:60355/callback"],
"grant_types": ["authorization_code", "refresh_token"]
}'Response:
{
"client_id": "your-client-id-here",
"client_secret": null,
"client_name": "My Application",
"redirect_uris": ["http://localhost:60355/callback"]
}Save the client_id for use in your application.
Step 2: Build OAuth client and create a Config
lb_oauth_new loads a cached token from
~/.longbridge/openapi/tokens/<client_id> (%USERPROFILE%\.longbridge\openapi\tokens\<client_id> on Windows)
if one exists and is still valid, or starts the browser authorization flow
automatically. The token is persisted to the same path after a successful
authorization or refresh. The resulting lb_oauth_t* handle is passed
directly to lb_config_from_oauth.
#include <longbridge.h>
#include <stdio.h>
static void
on_open_url(const char* url, void* userdata)
{
printf("Open this URL to authorize: %s\n", url);
}
static void
on_oauth_ready(const struct lb_async_result_t* res)
{
if (res->error) {
printf("OAuth failed: %s\n", lb_error_message(res->error));
return;
}
lb_oauth_t* oauth = (lb_oauth_t*)res->data;
lb_config_t* config = lb_config_from_oauth(oauth);
// Use config to create contexts...
lb_config_free(config);
lb_oauth_free(oauth);
}
int
main(int argc, char const* argv[])
{
lb_oauth_new("your-client-id", 0, on_open_url, NULL, on_oauth_ready, NULL);
getchar();
return 0;
}Setting environment variables(MacOS/Linux)
export LONGBRIDGE_APP_KEY="App Key get from user center"
export LONGBRIDGE_APP_SECRET="App Secret get from user center"
export LONGBRIDGE_ACCESS_TOKEN="Access Token get from user center"Setting environment variables(Windows)
setx LONGBRIDGE_APP_KEY "App Key get from user center"
setx LONGBRIDGE_APP_SECRET "App Secret get from user center"
setx LONGBRIDGE_ACCESS_TOKEN "Access Token get from user center"| Name | Description |
|---|---|
| LONGBRIDGE_LANGUAGE | Language identifier, zh-CN, zh-HK or en (Default: en) |
| LONGBRIDGE_HTTP_URL | HTTP endpoint url (Default: https://openapi.longbridge.com) |
| LONGBRIDGE_QUOTE_WS_URL | Quote websocket endpoint url (Default: wss://openapi-quote.longbridge.com/v2) |
| LONGBRIDGE_TRADE_WS_URL | Trade websocket endpoint url (Default: wss://openapi-trade.longbridge.com/v2) |
| LONGBRIDGE_ENABLE_OVERNIGHT | Enable overnight quote, true or false (Default: false) |
| LONGBRIDGE_PUSH_CANDLESTICK_MODE | realtime or confirmed (Default: realtime) |
| LONGBRIDGE_PRINT_QUOTE_PACKAGES | Print quote packages when connected, true or false (Default: true) |
| LONGBRIDGE_LOG_PATH | Set the path of the log files (Default: no logs) |
#include <longbridge.h>
#include <stdio.h>
#ifdef WIN32
#include <windows.h>
#endif
static void
on_quote(const struct lb_async_result_t* res)
{
if (res->error) {
printf("failed to get quote: %s\n", lb_error_message(res->error));
return;
}
lb_security_quote_t* data = (lb_security_quote_t*)res->data;
for (int i = 0; i < res->length; i++) {
const lb_security_quote_t* quote = &data[i];
printf("%s timestamp=%lld last_done=%f open=%f high=%f low=%f volume=%lld "
"turnover=%f\n",
quote->symbol,
quote->timestamp,
lb_decimal_to_double(quote->last_done),
lb_decimal_to_double(quote->open),
lb_decimal_to_double(quote->high),
lb_decimal_to_double(quote->low),
quote->volume,
lb_decimal_to_double(quote->turnover));
}
}
static void
on_oauth_ready(const struct lb_async_result_t* res)
{
if (res->error) {
printf("OAuth failed: %s\n", lb_error_message(res->error));
return;
}
lb_oauth_t* oauth = (lb_oauth_t*)res->data;
lb_config_t* config = lb_config_from_oauth(oauth);
const lb_quote_context_t* ctx = lb_quote_context_new(config);
lb_config_free(config);
lb_oauth_free(oauth);
const char* symbols[] = { "700.HK", "AAPL.US", "TSLA.US", "NFLX.US" };
lb_quote_context_quote(ctx, symbols, 4, on_quote, NULL);
}
static void
on_open_url(const char* url, void* userdata)
{
printf("Open this URL to authorize: %s\n", url);
}
int
main(int argc, char const* argv[])
{
#ifdef WIN32
SetConsoleOutputCP(CP_UTF8);
#endif
lb_oauth_new("your-client-id", 0, on_open_url, NULL, on_oauth_ready, NULL);
getchar();
return 0;
}#include <longbridge.h>
#include <stdio.h>
#ifdef WIN32
#include <windows.h>
#endif
static void
on_quote(const struct lb_quote_context_t* ctx,
const struct lb_push_quote_t* quote,
void* userdata)
{
printf("%s timestamp=%lld last_done=%f open=%f high=%f low=%f volume=%lld "
"turnover=%f\n",
quote->symbol,
quote->timestamp,
lb_decimal_to_double(quote->last_done),
lb_decimal_to_double(quote->open),
lb_decimal_to_double(quote->high),
lb_decimal_to_double(quote->low),
quote->volume,
lb_decimal_to_double(quote->turnover));
}
static void
on_subscribe(const struct lb_async_result_t* res)
{
if (res->error) {
printf("failed to subscribe: %s\n", lb_error_message(res->error));
}
}
static void
on_oauth_ready(const struct lb_async_result_t* res)
{
if (res->error) {
printf("OAuth failed: %s\n", lb_error_message(res->error));
return;
}
lb_oauth_t* oauth = (lb_oauth_t*)res->data;
lb_config_t* config = lb_config_from_oauth(oauth);
const lb_quote_context_t* ctx = lb_quote_context_new(config);
lb_config_free(config);
lb_oauth_free(oauth);
lb_quote_context_set_on_quote(ctx, on_quote, NULL, NULL);
const char* symbols[] = { "700.HK", "AAPL.US", "TSLA.US", "NFLX.US" };
lb_quote_context_subscribe(ctx, symbols, 4, LB_SUBFLAGS_QUOTE, on_subscribe, NULL);
}
static void
on_open_url(const char* url, void* userdata)
{
printf("Open this URL to authorize: %s\n", url);
}
int
main(int argc, char const* argv[])
{
#ifdef WIN32
SetConsoleOutputCP(CP_UTF8);
#endif
lb_oauth_new("your-client-id", 0, on_open_url, NULL, on_oauth_ready, NULL);
getchar();
return 0;
}#include <longbridge.h>
#include <stdio.h>
#ifdef WIN32
#include <windows.h>
#endif
static void
on_submit_order(const struct lb_async_result_t* res)
{
if (res->error) {
printf("failed to submit order: %s\n", lb_error_message(res->error));
return;
}
const lb_submit_order_response_t* resp = res->data;
printf("order id: %s\n", resp->order_id);
}
static void
on_oauth_ready(const struct lb_async_result_t* res)
{
if (res->error) {
printf("OAuth failed: %s\n", lb_error_message(res->error));
return;
}
lb_oauth_t* oauth = (lb_oauth_t*)res->data;
lb_config_t* config = lb_config_from_oauth(oauth);
const lb_trade_context_t* ctx = lb_trade_context_new(config);
lb_config_free(config);
lb_oauth_free(oauth);
lb_decimal_t* submitted_price = lb_decimal_from_double(50.0);
lb_decimal_t* submitted_quantity = lb_decimal_from_double(200.0);
lb_submit_order_options_t opts = {
"700.HK", OrderTypeLO,
OrderSideBuy, submitted_quantity,
TimeInForceDay, submitted_price,
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL,
};
lb_decimal_free(submitted_price);
lb_decimal_free(submitted_quantity);
lb_trade_context_submit_order(ctx, &opts, on_submit_order, NULL);
}
static void
on_open_url(const char* url, void* userdata)
{
printf("Open this URL to authorize: %s\n", url);
}
int
main(int argc, char const* argv[])
{
#ifdef WIN32
SetConsoleOutputCP(CP_UTF8);
#endif
lb_oauth_new("your-client-id", 0, on_open_url, NULL, on_oauth_ready, NULL);
getchar();
return 0;
}- Windows
setxrequires a new terminal; usesetfor the currentcmd.exesession. - If you don't see callbacks, keep the process alive (examples use
getchar()). - If building on Linux/macOS, ensure
ncursesis installed (examples link it on non-Windows). - For debugging, set
LONGBRIDGE_LOG_PATHto enable SDK logs.
Licensed under either of
- Apache License, Version 2.0,(LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT) at your option.