# Longport OpenAPI SDK for Node.js `longport` provides an easy-to-use interface for invoking [`Longport OpenAPI`](https://open.longportapp.com/en/). ## Context Types | Context | Description | |---------|-------------| | `QuoteContext` | Real-time quotes, candlesticks, options, warrants, watchlists, push subscriptions | | `TradeContext` | Orders, positions, account balance, executions, cash flow | | `AssetContext` | Account statement download | | `ContentContext` | News, community topics | | `FundamentalContext` | Financial reports, analyst ratings, dividends, valuation, company overview, shareholders | | `MarketContext` | Market status, broker holdings, A/H premium, trade statistics, anomaly alerts, index constituents | | `CalendarContext` | Financial calendar (earnings, dividends, splits, IPOs, macro data, market closures) | | `PortfolioContext` | Exchange rates, portfolio P&L analysis | | `AlertContext` | Price alert management (add/enable/disable/delete) | | `DCAContext` | Dollar-cost averaging plan management | | `SharelistContext` | Community sharelist management | ## Documentation - SDK docs: https://longportapp.github.io/openapi/nodejs/index.html - Longport OpenAPI: https://open.longportapp.com/en/ ## Examples Runnable examples live in `examples/nodejs/`: - `examples/nodejs/account_asset.js` - `examples/nodejs/http_client.js` - `examples/nodejs/subscribe_candlesticks.js` - `examples/nodejs/subscribe_quote.js` - `examples/nodejs/submit_order.js` - `examples/nodejs/today_orders.js` ## Quickstart _Install Longport OpenAPI SDK_ ```bash npm install longport ``` ### Authentication Longport OpenAPI supports two authentication methods: #### 1. OAuth 2.0 (Recommended) 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_ ```bash curl -X POST https://openapi.longportapp.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)_ ```powershell Invoke-RestMethod -Method Post -Uri https://openapi.longportapp.com/oauth2/register ` -ContentType "application/json" ` -Body '{ "client_name": "My Application", "redirect_uris": ["http://localhost:60355/callback"], "grant_types": ["authorization_code", "refresh_token"] }' ``` Response: ```json { "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 an OAuth client and create Config** `OAuth.build()` loads a cached token from `~/.longport/openapi/tokens/` (`%USERPROFILE%\.longport\openapi\tokens\` 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. ```javascript const { OAuth, Config } = require('longport'); async function main() { const oauth = await OAuth.build( "your-client-id", (_, url) => console.log("Open this URL to authorize: " + url) ); const config = Config.fromOAuth(oauth); // Use config to create contexts... } main(); ``` #### 2. Legacy API Key (Environment Variables) _Setting environment variables (macOS/Linux)_ ```bash export LONGPORT_APP_KEY="App Key get from user center" export LONGPORT_APP_SECRET="App Secret get from user center" export LONGPORT_ACCESS_TOKEN="Access Token get from user center" ``` _Setting environment variables (Windows)_ ```bash setx LONGPORT_APP_KEY "App Key get from user center" setx LONGPORT_APP_SECRET "App Secret get from user center" setx LONGPORT_ACCESS_TOKEN "Access Token get from user center" ``` ### Other environment variables | Name | Description | |----------------------------------|---------------------------------------------------------------------------------| | LONGPORT_LANGUAGE | Language identifier, `zh-CN`, `zh-HK` or `en` (Default: `en`) | | LONGPORT_HTTP_URL | HTTP endpoint url (Default: `https://openapi.longportapp.com`) | | LONGPORT_QUOTE_WS_URL | Quote websocket endpoint url (Default: `wss://openapi-quote.longportapp.com/v2`) | | LONGPORT_TRADE_WS_URL | Trade websocket endpoint url (Default: `wss://openapi-trade.longportapp.com/v2`) | | LONGPORT_ENABLE_OVERNIGHT | Enable overnight quote, `true` or `false` (Default: `false`) | | LONGPORT_PUSH_CANDLESTICK_MODE | `realtime` or `confirmed` (Default: `realtime`) | | LONGPORT_PRINT_QUOTE_PACKAGES | Print quote packages when connected, `true` or `false` (Default: `true`) | | LONGPORT_LOG_PATH | Set the path of the log files (Default: `no logs`) | Then create a config from the environment: ```javascript const { Config } = require('longport'); const config = Config.fromApikeyEnv(); ``` ## Quote API _(Get basic information of securities)_ ```javascript const { OAuth, Config, QuoteContext } = require('longport'); async function main() { const oauth = await OAuth.build( "your-client-id", (_, url) => console.log("Open this URL to authorize: " + url) ); const config = Config.fromOAuth(oauth); const ctx = QuoteContext.new(config); const resp = await ctx.quote(["700.HK", "AAPL.US", "TSLA.US", "NFLX.US"]); for (let obj of resp) { console.log(obj.toString()); } } main(); ``` ## Quote API _(Subscribe quotes)_ ```javascript const { OAuth, Config, QuoteContext, SubType } = require('longport'); async function main() { const oauth = await OAuth.build( "your-client-id", (_, url) => console.log("Open this URL to authorize: " + url) ); const config = Config.fromOAuth(oauth); const ctx = QuoteContext.new(config); ctx.setOnQuote((_, event) => console.log(event.toString())); await ctx.subscribe( ["700.HK", "AAPL.US", "TSLA.US", "NFLX.US"], [SubType.Quote], ); } main(); ``` ## Trade API _(Submit order)_ ```javascript const { OAuth, Config, TradeContext, Decimal, OrderSide, TimeInForceType, OrderType, } = require('longport'); async function main() { const oauth = await OAuth.build( "your-client-id", (_, url) => console.log("Open this URL to authorize: " + url) ); const config = Config.fromOAuth(oauth); const ctx = TradeContext.new(config); const resp = await ctx.submitOrder({ symbol: "700.HK", orderType: OrderType.LO, side: OrderSide.Buy, timeInForce: TimeInForceType.Day, submittedPrice: new Decimal("50"), submittedQuantity: new Decimal(200), }); console.log(resp.toString()); } main(); ``` ## Troubleshooting - Windows `setx` requires a new terminal; use `set` for the current `cmd.exe` session. - If the script exits, you won't receive push events; keep Node running. - For debugging, set `LONGPORT_LOG_PATH` to enable SDK logs. ## License Licensed under either of * Apache License, Version 2.0,([LICENSE-APACHE](../LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) * MIT license ([LICENSE-MIT](../LICENSE-MIT) or http://opensource.org/licenses/MIT) at your option.