# Longport OpenAPI SDK for Java
`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/java/index.html
- Longport OpenAPI: https://open.longportapp.com/en/
## Examples
Runnable examples live in `examples/java/`:
- `examples/java/account_asset/src/main/java/main.java`
- `examples/java/history_candlesticks/src/main/java/Main.java`
- `examples/java/subscribe_quote/src/main/java/Main.java`
- `examples/java/submit_order/src/main/java/Main.java`
- `examples/java/today_orders/src/main/java/main.java`
## Quickstart
_Install Longport OpenAPI SDK_
Add `io.github.longport:openapi-sdk` to `pom.xml`
```xml
io.github.longport
openapi-sdk
LATEST
```
### 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 OAuth client and create a Config**
`OAuthBuilder.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. The resulting `OAuth` handle is passed directly to
`Config.fromOAuth`.
```java
import com.longport.*;
class Main {
public static void main(String[] args) throws Exception {
try (OAuth oauth = new OAuthBuilder("your-client-id")
.build(url -> System.out.println("Open this URL to authorize: " + url))
.get();
Config config = Config.fromOAuth(oauth)) {
// Use config to create contexts...
}
}
}
```
#### 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)_
```powershell
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`) |
## Quote API _(Get basic information of securities)_
```java
import com.longport.*;
import com.longport.quote.*;
class Main {
public static void main(String[] args) throws Exception {
try (OAuth oauth = new OAuthBuilder("your-client-id")
.build(url -> System.out.println("Open this URL to authorize: " + url))
.get();
Config config = Config.fromOAuth(oauth);
QuoteContext ctx = QuoteContext.create(config)) {
SecurityQuote[] resp = ctx.getQuote(
new String[] { "700.HK", "AAPL.US", "TSLA.US", "NFLX.US" }).get();
for (SecurityQuote obj : resp) {
System.out.println(obj);
}
}
}
}
```
## Quote API _(Subscribe quotes)_
```java
import com.longport.*;
import com.longport.quote.*;
class Main {
public static void main(String[] args) throws Exception {
try (OAuth oauth = new OAuthBuilder("your-client-id")
.build(url -> System.out.println("Open this URL to authorize: " + url))
.get();
Config config = Config.fromOAuth(oauth);
QuoteContext ctx = QuoteContext.create(config)) {
ctx.setOnQuote((symbol, quote) -> System.out.printf("%s\t%s\n", symbol, quote));
ctx.subscribe(
new String[] { "700.HK", "AAPL.US", "TSLA.US", "NFLX.US" },
SubFlags.Quote).get();
Thread.sleep(30000);
}
}
}
```
## Trade API _(Submit order)_
```java
import com.longport.*;
import com.longport.trade.*;
import java.math.BigDecimal;
class Main {
public static void main(String[] args) throws Exception {
try (OAuth oauth = new OAuthBuilder("your-client-id")
.build(url -> System.out.println("Open this URL to authorize: " + url))
.get();
Config config = Config.fromOAuth(oauth);
TradeContext ctx = TradeContext.create(config)) {
SubmitOrderOptions opts = new SubmitOrderOptions("700.HK",
OrderType.LO,
OrderSide.Buy,
200,
TimeInForceType.Day).setSubmittedPrice(new BigDecimal(50));
SubmitOrderResponse resp = ctx.submitOrder(opts).get();
System.out.println(resp);
}
}
}
```
## Troubleshooting
- Windows `setx` requires a new terminal; use `set` for the current `cmd.exe` session.
- If you don't see push events, ensure the program keeps running (e.g. `Thread.sleep(...)`).
- 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.