From 955c0ed57746c97830c3ed864fbff6d1bb83c8f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Wed, 20 May 2026 15:06:37 +0800 Subject: [PATCH 1/5] docs: add sdk docs for shareholders/screener/short-trades/rank + CLI v0.22.0 release notes Co-Authored-By: Claude Sonnet 4.6 (1M context) --- docs/en/docs/cli/release-notes.md | 10 + .../fundamental/shareholder_detail.md | 252 ++++++++++++++++ .../fundamental/shareholder_top.md | 253 +++++++++++++++++ .../fundamental/valuation_comparison.md | 262 +++++++++++++++++ docs/en/docs/market/status/rank_categories.md | 239 ++++++++++++++++ docs/en/docs/market/status/rank_list.md | 248 ++++++++++++++++ docs/en/docs/market/status/stock_events.md | 265 +++++++++++++++++ .../quote/analytics/hk_short_positions.md | 236 +++++++++++++++ docs/en/docs/quote/analytics/short_trades.md | 239 ++++++++++++++++ docs/en/docs/screener/screener_indicators.md | 268 ++++++++++++++++++ .../screener/screener_recommend_strategies.md | 249 ++++++++++++++++ docs/en/docs/screener/screener_search.md | 260 +++++++++++++++++ docs/en/docs/screener/screener_strategy.md | 264 +++++++++++++++++ .../docs/screener/screener_user_strategies.md | 228 +++++++++++++++ docs/zh-CN/docs/cli/release-notes.md | 10 + .../fundamental/shareholder_detail.md | 264 +++++++++++++++++ .../fundamental/shareholder_top.md | 253 +++++++++++++++++ .../fundamental/valuation_comparison.md | 263 +++++++++++++++++ .../docs/market/status/rank_categories.md | 239 ++++++++++++++++ docs/zh-CN/docs/market/status/rank_list.md | 248 ++++++++++++++++ docs/zh-CN/docs/market/status/stock_events.md | 265 +++++++++++++++++ .../quote/analytics/hk_short_positions.md | 236 +++++++++++++++ .../docs/quote/analytics/short_trades.md | 239 ++++++++++++++++ docs/zh-CN/docs/screener/_category_.json | 7 + .../docs/screener/screener_indicators.md | 268 ++++++++++++++++++ .../screener/screener_recommend_strategies.md | 249 ++++++++++++++++ docs/zh-CN/docs/screener/screener_search.md | 260 +++++++++++++++++ docs/zh-CN/docs/screener/screener_strategy.md | 264 +++++++++++++++++ .../docs/screener/screener_user_strategies.md | 228 +++++++++++++++ docs/zh-HK/docs/cli/release-notes.md | 10 + .../fundamental/shareholder_detail.md | 264 +++++++++++++++++ .../fundamental/shareholder_top.md | 253 +++++++++++++++++ .../fundamental/valuation_comparison.md | 263 +++++++++++++++++ .../docs/market/status/rank_categories.md | 239 ++++++++++++++++ docs/zh-HK/docs/market/status/rank_list.md | 248 ++++++++++++++++ docs/zh-HK/docs/market/status/stock_events.md | 265 +++++++++++++++++ .../quote/analytics/hk_short_positions.md | 236 +++++++++++++++ .../docs/quote/analytics/short_trades.md | 239 ++++++++++++++++ .../docs/screener/screener_indicators.md | 268 ++++++++++++++++++ .../screener/screener_recommend_strategies.md | 249 ++++++++++++++++ docs/zh-HK/docs/screener/screener_search.md | 260 +++++++++++++++++ docs/zh-HK/docs/screener/screener_strategy.md | 264 +++++++++++++++++ .../docs/screener/screener_user_strategies.md | 228 +++++++++++++++ 43 files changed, 9852 insertions(+) create mode 100644 docs/en/docs/fundamental/fundamental/shareholder_detail.md create mode 100644 docs/en/docs/fundamental/fundamental/shareholder_top.md create mode 100644 docs/en/docs/fundamental/fundamental/valuation_comparison.md create mode 100644 docs/en/docs/market/status/rank_categories.md create mode 100644 docs/en/docs/market/status/rank_list.md create mode 100644 docs/en/docs/market/status/stock_events.md create mode 100644 docs/en/docs/quote/analytics/hk_short_positions.md create mode 100644 docs/en/docs/quote/analytics/short_trades.md create mode 100644 docs/en/docs/screener/screener_indicators.md create mode 100644 docs/en/docs/screener/screener_recommend_strategies.md create mode 100644 docs/en/docs/screener/screener_search.md create mode 100644 docs/en/docs/screener/screener_strategy.md create mode 100644 docs/en/docs/screener/screener_user_strategies.md create mode 100644 docs/zh-CN/docs/fundamental/fundamental/shareholder_detail.md create mode 100644 docs/zh-CN/docs/fundamental/fundamental/shareholder_top.md create mode 100644 docs/zh-CN/docs/fundamental/fundamental/valuation_comparison.md create mode 100644 docs/zh-CN/docs/market/status/rank_categories.md create mode 100644 docs/zh-CN/docs/market/status/rank_list.md create mode 100644 docs/zh-CN/docs/market/status/stock_events.md create mode 100644 docs/zh-CN/docs/quote/analytics/hk_short_positions.md create mode 100644 docs/zh-CN/docs/quote/analytics/short_trades.md create mode 100644 docs/zh-CN/docs/screener/_category_.json create mode 100644 docs/zh-CN/docs/screener/screener_indicators.md create mode 100644 docs/zh-CN/docs/screener/screener_recommend_strategies.md create mode 100644 docs/zh-CN/docs/screener/screener_search.md create mode 100644 docs/zh-CN/docs/screener/screener_strategy.md create mode 100644 docs/zh-CN/docs/screener/screener_user_strategies.md create mode 100644 docs/zh-HK/docs/fundamental/fundamental/shareholder_detail.md create mode 100644 docs/zh-HK/docs/fundamental/fundamental/shareholder_top.md create mode 100644 docs/zh-HK/docs/fundamental/fundamental/valuation_comparison.md create mode 100644 docs/zh-HK/docs/market/status/rank_categories.md create mode 100644 docs/zh-HK/docs/market/status/rank_list.md create mode 100644 docs/zh-HK/docs/market/status/stock_events.md create mode 100644 docs/zh-HK/docs/quote/analytics/hk_short_positions.md create mode 100644 docs/zh-HK/docs/quote/analytics/short_trades.md create mode 100644 docs/zh-HK/docs/screener/screener_indicators.md create mode 100644 docs/zh-HK/docs/screener/screener_recommend_strategies.md create mode 100644 docs/zh-HK/docs/screener/screener_search.md create mode 100644 docs/zh-HK/docs/screener/screener_strategy.md create mode 100644 docs/zh-HK/docs/screener/screener_user_strategies.md diff --git a/docs/en/docs/cli/release-notes.md b/docs/en/docs/cli/release-notes.md index e6e16189..9754ecfd 100644 --- a/docs/en/docs/cli/release-notes.md +++ b/docs/en/docs/cli/release-notes.md @@ -7,6 +7,16 @@ sidebar_icon: newspaper # Release Notes +### [v0.22.0](https://github.com/longbridge/longbridge-terminal/releases/tag/v0.22.0) + +- **New `shareholder --top`** — Top-20 major shareholders (institutions, individuals, insiders) with multi-period comparison; `--object-id ` for single shareholder holding history and trade details +- **Extended `short-positions`** — Added HK market support (`.HK` suffix auto-routes to HKEX short-position data) +- **New `short-trades`** — Daily short sale volume (US: FINRA/NASDAQ; HK: HKEX disclosure data) +- **New `compare`** — Multi-stock valuation comparison (PE/PB/PS/market-cap/close); server auto-selects peers when no comparison symbols given +- **New `top-movers`** — Stocks whose price movement exceeds the 20-day standard deviation, with correlated news; supports `--market`, `--sort time|change|hot` +- **New `screener` command group** — Stock screener: `strategies` (recommended/saved), `search --strategy-id ` or `--filter key:min:max`, `indicators` to list available filters +- **New `rank`** — Popularity leaderboard; list all categories without `--key`, or pass `--key ` for a specific ranking (e.g. `ib_hot_all-us`) + ### [v0.21.0](https://github.com/longbridge/longbridge-terminal/releases/tag/v0.21.0) - **New: `business-segments`** — revenue breakdown by business segment, current period or historical trend diff --git a/docs/en/docs/fundamental/fundamental/shareholder_detail.md b/docs/en/docs/fundamental/fundamental/shareholder_detail.md new file mode 100644 index 00000000..6dd3f34b --- /dev/null +++ b/docs/en/docs/fundamental/fundamental/shareholder_detail.md @@ -0,0 +1,252 @@ +--- +slug: shareholder-detail +title: Shareholder Detail +sidebar_position: 28 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +Get holding history and trade details for a specific shareholder. The `object_id` comes from the `shareholder_top` response. + + +longbridge shareholder AAPL.US --object-id 19463 +longbridge shareholder 700.HK --object-id 20181 + + + + + +## Parameters + +> **SDK method parameters.** + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| symbol | string | YES | Security symbol, e.g. `AAPL.US` | +| object_id | integer | YES | Shareholder ID from `shareholder_top` `object_id` field | + +## Request Example + + + + +```python +from longbridge.openapi import FundamentalContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = FundamentalContext(config) + +resp = ctx.shareholder_detail("AAPL.US", 19463) +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncFundamentalContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncFundamentalContext.create(config) + + resp = await ctx.shareholder_detail("AAPL.US", 19463) + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, FundamentalContext, OAuth } = require('longbridge') + +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 = FundamentalContext.new(config) + const resp = await ctx.shareholderDetail('AAPL.US', 19463) + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.fundamental.*; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + FundamentalContext ctx = FundamentalContext.create(config)) { + var resp = ctx.getShareholderDetail("AAPL.US", 19463L).get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, fundamental::FundamentalContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = FundamentalContext::new(config); + let resp = ctx.shareholder_detail("AAPL.US", 19463).await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::fundamental; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + FundamentalContext ctx = FundamentalContext::create(config); + ctx.shareholder_detail("AAPL.US", 19463, [](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/fundamental" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := fundamental.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.ShareholderDetail(context.Background(), "AAPL.US", 19463) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "owner_source": "Institution", + "holding_summary": [ + { + "period": "2025-12-31", + "accum_buy": "8500000", + "accum_sell": "2687264", + "stock_price": "243.08" + } + ], + "tradings": [ + { + "period": "2025-12-31", + "trading_details": [ + { + "trading_date": "2025-12-18", + "trading_shares": "5200000", + "trading_price": "248.12", + "trading_type": "Buy" + } + ] + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | Success | [ShareholderDetailResponse](#ShareholderDetailResponse) | +| 400 | Bad request | None | + +## Schemas + +### ShareholderDetailResponse + + + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| owner_source | string | false | Shareholder type: `Company`, `Institution`, `Person`, `Insider` | +| holding_summary | object[] | false | Holding summary per reporting period | +| ∟ period | string | false | Reporting period in `YYYY-MM-DD` format | +| ∟ accum_buy | string | false | Cumulative shares bought this period | +| ∟ accum_sell | string | false | Cumulative shares sold this period | +| ∟ stock_price | string | false | Closing price at end of period | +| tradings | object[] | false | Trade details per reporting period | +| ∟ period | string | false | Reporting period in `YYYY-MM-DD` format | +| ∟ trading_details | object[] | false | Individual transactions within the period | +| ∟ ∟ trading_date | string | false | Trade date in `YYYY-MM-DD` format | +| ∟ ∟ trading_shares | string | false | Number of shares traded | +| ∟ ∟ trading_price | string | false | Trade price | +| ∟ ∟ trading_type | string | false | Trade direction: `Buy` or `Sell` | diff --git a/docs/en/docs/fundamental/fundamental/shareholder_top.md b/docs/en/docs/fundamental/fundamental/shareholder_top.md new file mode 100644 index 00000000..9d0ff8af --- /dev/null +++ b/docs/en/docs/fundamental/fundamental/shareholder_top.md @@ -0,0 +1,253 @@ +--- +slug: shareholder-top +title: Top Shareholders +sidebar_position: 27 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +Get the top 20 major shareholders (institutional, individual, and insider) for a listed company, with support for multi-period comparison. `object_id` can be passed to `shareholder_detail` to retrieve full holding history. + + +longbridge shareholder AAPL.US --top +longbridge shareholder 700.HK --top + + + + + +## Parameters + +> **SDK method parameters.** + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| symbol | string | YES | Security symbol, e.g. `AAPL.US` | + +## Request Example + + + + +```python +from longbridge.openapi import FundamentalContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = FundamentalContext(config) + +resp = ctx.shareholder_top("AAPL.US") +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncFundamentalContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncFundamentalContext.create(config) + + resp = await ctx.shareholder_top("AAPL.US") + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, FundamentalContext, OAuth } = require('longbridge') + +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 = FundamentalContext.new(config) + const resp = await ctx.shareholderTop('AAPL.US') + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.fundamental.*; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + FundamentalContext ctx = FundamentalContext.create(config)) { + var resp = ctx.getShareholderTop("AAPL.US").get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, fundamental::FundamentalContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = FundamentalContext::new(config); + let resp = ctx.shareholder_top("AAPL.US").await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::fundamental; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + FundamentalContext ctx = FundamentalContext::create(config); + ctx.shareholder_top("AAPL.US", [](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/fundamental" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := fundamental.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.ShareholderTop(context.Background(), "AAPL.US") + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "periods": ["2025-12-31", "2025-09-30"], + "info": [ + { + "period": "2025-12-31", + "share_holders": [ + { + "object_id": 19463, + "name": "The Vanguard Group, Inc.", + "title": "Institution", + "shares_held": "1285506048", + "percent_shares_held": "8.46", + "shares_changed": "5812736", + "filing_date": "2026-02-14" + }, + { + "object_id": 20181, + "name": "BlackRock, Inc.", + "title": "Institution", + "shares_held": "1071234816", + "percent_shares_held": "7.05", + "shares_changed": "-3104128", + "filing_date": "2026-02-05" + } + ] + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | Success | [ShareholderTopResponse](#ShareholderTopResponse) | +| 400 | Bad request | None | + +## Schemas + +### ShareholderTopResponse + + + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| periods | string[] | false | Available reporting periods in `YYYY-MM-DD` format | +| info | object[] | false | Shareholder data per reporting period | +| ∟ period | string | false | Reporting period in `YYYY-MM-DD` format | +| ∟ share_holders | object[] | false | List of shareholders (up to 20) | +| ∟ ∟ object_id | integer | false | Unique shareholder ID; pass to `shareholder_detail` | +| ∟ ∟ name | string | false | Shareholder name | +| ∟ ∟ title | string | false | Shareholder type (Institution / Individual / Insider) | +| ∟ ∟ shares_held | string | false | Number of shares held | +| ∟ ∟ percent_shares_held | string | false | Ownership percentage | +| ∟ ∟ shares_changed | string | false | Net share count change (positive = bought, negative = sold) | +| ∟ ∟ filing_date | string | false | Filing date in `YYYY-MM-DD` format | diff --git a/docs/en/docs/fundamental/fundamental/valuation_comparison.md b/docs/en/docs/fundamental/fundamental/valuation_comparison.md new file mode 100644 index 00000000..92725d61 --- /dev/null +++ b/docs/en/docs/fundamental/fundamental/valuation_comparison.md @@ -0,0 +1,262 @@ +--- +slug: valuation-comparison +title: Valuation Comparison +sidebar_position: 29 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +Compare valuation metrics (PE/PB/PS/market cap/close price) across multiple stocks. When no comparison symbols are provided, the server automatically selects peers from the same industry. + + +longbridge compare AAPL.US +longbridge compare AAPL.US MSFT.US GOOGL.US + + + + + +## Parameters + +> **SDK method parameters.** + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| symbol | string | YES | Primary security symbol, e.g. `AAPL.US` | +| currency | string | YES | Result currency: `USD`, `HKD`, or `CNY` | +| comparison_symbols | string[] | NO | Symbols to compare against; if omitted, the server auto-selects industry peers | + +## Request Example + + + + +```python +from longbridge.openapi import FundamentalContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = FundamentalContext(config) + +# Auto-select peers +resp = ctx.valuation_comparison("AAPL.US", "USD") +# Specify comparison symbols +resp = ctx.valuation_comparison("AAPL.US", "USD", ["MSFT.US", "GOOGL.US"]) +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncFundamentalContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncFundamentalContext.create(config) + + resp = await ctx.valuation_comparison("AAPL.US", "USD", ["MSFT.US", "GOOGL.US"]) + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, FundamentalContext, OAuth } = require('longbridge') + +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 = FundamentalContext.new(config) + const resp = await ctx.valuationComparison('AAPL.US', 'USD', ['MSFT.US', 'GOOGL.US']) + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.fundamental.*; +import java.util.Arrays; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + FundamentalContext ctx = FundamentalContext.create(config)) { + var resp = ctx.getValuationComparison("AAPL.US", "USD", Arrays.asList("MSFT.US", "GOOGL.US")).get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, fundamental::FundamentalContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = FundamentalContext::new(config); + let resp = ctx.valuation_comparison("AAPL.US", "USD", Some(vec!["MSFT.US", "GOOGL.US"])).await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::fundamental; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + FundamentalContext ctx = FundamentalContext::create(config); + ctx.valuation_comparison("AAPL.US", "USD", {"MSFT.US", "GOOGL.US"}, [](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/fundamental" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := fundamental.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.ValuationComparison(context.Background(), "AAPL.US", "USD", []string{"MSFT.US", "GOOGL.US"}) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "list": [ + { + "symbol": "AAPL.US", + "name": "Apple Inc.", + "market_value": "3241500000000", + "price_close": "213.49", + "pe": "32.15", + "pb": "50.21", + "ps": "8.04", + "history": [ + { "date": "2026-05-01", "pe": "32.15", "pb": "50.21", "ps": "8.04" }, + { "date": "2026-04-01", "pe": "28.73", "pb": "46.88", "ps": "7.52" } + ] + }, + { + "symbol": "MSFT.US", + "name": "Microsoft", + "market_value": "3085000000000", + "price_close": "415.32", + "pe": "35.42", + "pb": "12.87", + "ps": "12.61", + "history": [ + { "date": "2026-05-01", "pe": "35.42", "pb": "12.87", "ps": "12.61" } + ] + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | Success | [ValuationComparisonResponse](#ValuationComparisonResponse) | +| 400 | Bad request | None | + +## Schemas + +### ValuationComparisonResponse + + + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| list | object[] | false | Valuation comparison list | +| ∟ symbol | string | false | Security symbol | +| ∟ name | string | false | Security name | +| ∟ market_value | string | false | Market cap in result currency | +| ∟ price_close | string | false | Latest closing price | +| ∟ pe | string | false | P/E ratio (TTM) | +| ∟ pb | string | false | P/B ratio | +| ∟ ps | string | false | P/S ratio (TTM) | +| ∟ history | object[] | false | Historical valuation time series | +| ∟ ∟ date | string | false | Date in `YYYY-MM-DD` format | +| ∟ ∟ pe | string | false | Historical PE | +| ∟ ∟ pb | string | false | Historical PB | +| ∟ ∟ ps | string | false | Historical PS | diff --git a/docs/en/docs/market/status/rank_categories.md b/docs/en/docs/market/status/rank_categories.md new file mode 100644 index 00000000..796cdac7 --- /dev/null +++ b/docs/en/docs/market/status/rank_categories.md @@ -0,0 +1,239 @@ +--- +slug: /market/rank-categories +title: Rank Categories +sidebar_position: 8 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +Get the tag category configuration for the popularity leaderboard. `second_tags[].key` can be passed to `rank_list`. + + +longbridge rank + + + + + +## Parameters + +> **SDK method parameters.** + +This method takes no parameters. + +## Request Example + + + + +```python +from longbridge.openapi import MarketContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = MarketContext(config) + +resp = ctx.rank_categories() +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncMarketContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncMarketContext.create(config) + + resp = await ctx.rank_categories() + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, MarketContext, OAuth } = require('longbridge') + +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 = MarketContext.new(config) + const resp = await ctx.rankCategories() + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.market.*; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + MarketContext ctx = MarketContext.create(config)) { + var resp = ctx.getRankCategories().get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, market::MarketContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = MarketContext::new(config); + let resp = ctx.rank_categories().await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::market; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + MarketContext ctx = MarketContext::create(config); + ctx.rank_categories([](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/market" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := market.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.RankCategories(context.Background()) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "first_tags": [ + { + "key": "ib_hot", + "name": "Hotness Rank", + "second_tags": [ + { "key": "ib_hot_all-us", "name": "US Total Hotness", "market": "US" }, + { "key": "ib_hot_all-hk", "name": "HK Total Hotness", "market": "HK" }, + { "key": "ib_hot_all-cn", "name": "A-share Total Hotness", "market": "CN" } + ] + }, + { + "key": "ib_change", + "name": "Price Change Rank", + "second_tags": [ + { "key": "ib_change_top-us", "name": "US Top Gainers", "market": "US" }, + { "key": "ib_change_top-hk", "name": "HK Top Gainers", "market": "HK" } + ] + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | Success | [RankCategoriesResponse](#RankCategoriesResponse) | +| 400 | Bad request | None | + +## Schemas + +### RankCategoriesResponse + + + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| first_tags | object[] | false | Top-level category list | +| ∟ key | string | false | Top-level category key | +| ∟ name | string | false | Top-level category name | +| ∟ second_tags | object[] | false | Second-level category list | +| ∟ ∟ key | string | false | Second-level category key; pass to `rank_list` as the `key` parameter | +| ∟ ∟ name | string | false | Second-level category name | +| ∟ ∟ market | string | false | Associated market: `US`, `HK`, `CN`, `SG` | diff --git a/docs/en/docs/market/status/rank_list.md b/docs/en/docs/market/status/rank_list.md new file mode 100644 index 00000000..03839b5d --- /dev/null +++ b/docs/en/docs/market/status/rank_list.md @@ -0,0 +1,248 @@ +--- +slug: /market/rank-list +title: Popularity Leaderboard +sidebar_position: 9 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +Get the stock ranking for a given leaderboard tag key. The key comes from `rank_categories` `second_tags[].key`, e.g. `ib_hot_all-us` (US total hotness). + + +longbridge rank --key ib_hot_all-us +longbridge rank --key ib_hot_all-hk + + + + + +## Parameters + +> **SDK method parameters.** + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| key | string | YES | Leaderboard tag key from `rank_categories` `second_tags[].key` | +| need_article | boolean | NO | Whether to return associated articles, default `false` | + +## Request Example + + + + +```python +from longbridge.openapi import MarketContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = MarketContext(config) + +resp = ctx.rank_list("ib_hot_all-us") +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncMarketContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncMarketContext.create(config) + + resp = await ctx.rank_list("ib_hot_all-us", need_article=False) + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, MarketContext, OAuth } = require('longbridge') + +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 = MarketContext.new(config) + const resp = await ctx.rankList('ib_hot_all-us', false) + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.market.*; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + MarketContext ctx = MarketContext.create(config)) { + var resp = ctx.getRankList("ib_hot_all-us", false).get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, market::MarketContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = MarketContext::new(config); + let resp = ctx.rank_list("ib_hot_all-us", false).await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::market; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + MarketContext ctx = MarketContext::create(config); + ctx.rank_list("ib_hot_all-us", false, [](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/market" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := market.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.RankList(context.Background(), "ib_hot_all-us", false) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "lists": [ + { + "symbol": "NVDA.US", + "name": "NVIDIA", + "last_done": "135.62", + "chg": "+2.84%", + "inflow": "1250000000", + "market_cap": "3312000000000", + "pre_post_price": "136.10", + "pre_post_chg": "+0.35%" + }, + { + "symbol": "TSLA.US", + "name": "Tesla", + "last_done": "342.15", + "chg": "-1.23%", + "inflow": "875000000", + "market_cap": "1098000000000", + "pre_post_price": "341.00", + "pre_post_chg": "-0.34%" + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | Success | [RankListResponse](#RankListResponse) | +| 400 | Bad request | None | + +## Schemas + +### RankListResponse + + + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| lists | object[] | false | Leaderboard stock list | +| ∟ symbol | string | false | Security symbol | +| ∟ name | string | false | Security name | +| ∟ last_done | string | false | Latest trade price | +| ∟ chg | string | false | Price change with sign, e.g. `+2.84%` | +| ∟ inflow | string | false | Net capital inflow (in the market's currency) | +| ∟ market_cap | string | false | Market capitalisation | +| ∟ pre_post_price | string | false | Pre/post-market price | +| ∟ pre_post_chg | string | false | Pre/post-market price change | diff --git a/docs/en/docs/market/status/stock_events.md b/docs/en/docs/market/status/stock_events.md new file mode 100644 index 00000000..d9e0f8f7 --- /dev/null +++ b/docs/en/docs/market/status/stock_events.md @@ -0,0 +1,265 @@ +--- +slug: /market/stock-events +title: Top Movers +sidebar_position: 7 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +Get stocks whose price movement exceeds the 20-trading-day standard deviation, with automatically correlated news to explain the move. + + +longbridge top-movers +longbridge top-movers --market HK --sort time + + + + + +## Parameters + +> **SDK method parameters.** + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| markets | string[] | NO | Market list: `HK`, `US`, `CN`, `SG`; returns all markets if omitted | +| sort | integer | NO | Sort order: `0`=time (newest first), `1`=price change, `2`=hotness (default) | +| date | string | NO | Target date in `YYYY-MM-DD` format; returns latest data if omitted | +| limit | integer | NO | Number of results to return, default 20 | + +## Request Example + + + + +```python +from longbridge.openapi import MarketContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = MarketContext(config) + +resp = ctx.stock_events(markets=["HK", "US"], sort=2, limit=20) +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncMarketContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncMarketContext.create(config) + + resp = await ctx.stock_events(markets=["HK", "US"], sort=2, limit=20) + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, MarketContext, OAuth } = require('longbridge') + +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 = MarketContext.new(config) + const resp = await ctx.stockEvents({ markets: ['HK', 'US'], sort: 2, limit: 20 }) + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.market.*; +import java.util.Arrays; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + MarketContext ctx = MarketContext.create(config)) { + var resp = ctx.getStockEvents(Arrays.asList("HK", "US"), 2, null, 20).get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, market::MarketContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = MarketContext::new(config); + let resp = ctx.stock_events(Some(vec!["HK", "US"]), Some(2), None, Some(20)).await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::market; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + MarketContext ctx = MarketContext::create(config); + ctx.stock_events({"HK", "US"}, 2, "", 20, [](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/market" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := market.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.StockEvents(context.Background(), []string{"HK", "US"}, 2, "", 20) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "events": [ + { + "stock": { + "symbol": "9988.HK", + "name": "Alibaba", + "change": "+4.82%", + "labels": ["HK", "Technology"] + }, + "timestamp": 1747728600000, + "alert_reason": "Earnings beat: revenue up 8%", + "alert_type": "earnings_beat", + "post": { + "id": "post_abc123", + "title": "Alibaba Q4 Earnings: Cloud Business Surges", + "url": "https://longbridge.com/news/post_abc123" + } + }, + { + "stock": { + "symbol": "NVDA.US", + "name": "NVIDIA", + "change": "+3.21%", + "labels": ["US", "Semiconductor"] + }, + "timestamp": 1747725000000, + "alert_reason": "Block buy: volume up 3x", + "alert_type": "volume_spike", + "post": null + } + ], + "next_params": "eyJvZmZzZXQiOjIwfQ==" + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | Success | [StockEventsResponse](#StockEventsResponse) | +| 400 | Bad request | None | + +## Schemas + +### StockEventsResponse + + + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| events | object[] | false | List of moving stocks | +| ∟ stock | object | false | Basic stock information | +| ∟ ∟ symbol | string | false | Security symbol | +| ∟ ∟ name | string | false | Security name | +| ∟ ∟ change | string | false | Price change with sign, e.g. `+4.82%` | +| ∟ ∟ labels | string[] | false | Tags (market, industry, etc.) | +| ∟ timestamp | integer | false | Event time (Unix milliseconds) | +| ∟ alert_reason | string | false | Description of the move reason | +| ∟ alert_type | string | false | Move type identifier | +| ∟ post | object | false | Associated news/article; `null` if none | +| ∟ ∟ id | string | false | Article ID | +| ∟ ∟ title | string | false | Article title | +| ∟ ∟ url | string | false | Article URL | +| next_params | string | false | Pagination cursor (Base64 encoded); pass to the next request to get the next page | diff --git a/docs/en/docs/quote/analytics/hk_short_positions.md b/docs/en/docs/quote/analytics/hk_short_positions.md new file mode 100644 index 00000000..172e070b --- /dev/null +++ b/docs/en/docs/quote/analytics/hk_short_positions.md @@ -0,0 +1,236 @@ +--- +slug: /quote/pull/hk-short-positions +title: HK Short Positions +sidebar_position: 26 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +Get HK short position data including short amount and short ratio. Data is provided by the Hong Kong Exchange (HKEX) and updated each trading day. Only HK-listed stocks are supported. + + +longbridge short-positions 700.HK +longbridge short-positions 9988.HK --count 50 + + + + + +## Parameters + +> **SDK method parameters.** + +| Name | Type | Required | Description | +| ------ | ------- | -------- | ---------------------------------------------- | +| symbol | string | YES | HK security symbol, e.g. `700.HK`, `9988.HK` | +| count | integer | NO | Number of records to return (1–100, default 20) | + +## Request Example + + + + +```python +from longbridge.openapi import QuoteContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = QuoteContext(config) + +resp = ctx.hk_short_positions("700.HK") +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncQuoteContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncQuoteContext.create(config) + + resp = await ctx.hk_short_positions("700.HK") + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, QuoteContext, OAuth } = require('longbridge') + +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.hkShortPositions('700.HK') + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.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 to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + QuoteContext ctx = QuoteContext.create(config)) { + var resp = ctx.getHkShortPositions("700.HK").get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, quote::QuoteContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let (ctx, _) = QuoteContext::new(config); + let resp = ctx.hk_short_positions("700.HK").await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::quote; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + QuoteContext ctx = QuoteContext::create(config); + ctx.hk_short_positions("700.HK", [](auto resp) { + if (resp) std::cout << resp->size() << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/quote" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + qctx, err := quote.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer qctx.Close() + resp, err := qctx.HkShortPositions(context.Background(), "700.HK") + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "list": [ + { + "date": "2026-05-16", + "short_amount": "2148600000", + "short_ratio": "0.0182", + "close": "418.20" + }, + { + "date": "2026-05-15", + "short_amount": "1935200000", + "short_ratio": "0.0163", + "close": "412.80" + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | Success | [hk_short_positions_rsp](#hk_short_positions_rsp) | +| 400 | Bad request | None | + +## Schemas + +### hk_short_positions_rsp + + + +| Name | Type | Required | Description | +| ------------- | -------- | -------- | ------------------------------------------------ | +| list | object[] | true | HK short position records | +| ∟ date | string | true | Trading date in `YYYY-MM-DD` format | +| ∟ short_amount | string | true | Short amount (HKD) | +| ∟ short_ratio | string | true | Short ratio (short amount ÷ total turnover) | +| ∟ close | string | true | Closing price on that day | diff --git a/docs/en/docs/quote/analytics/short_trades.md b/docs/en/docs/quote/analytics/short_trades.md new file mode 100644 index 00000000..f6d0fe75 --- /dev/null +++ b/docs/en/docs/quote/analytics/short_trades.md @@ -0,0 +1,239 @@ +--- +slug: /quote/pull/short-trades +title: Daily Short Sale Volume +sidebar_position: 27 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +Get daily short sale volume data for a security. Supports US stocks (FINRA/NASDAQ) and HK stocks (HKEX). US data is updated bi-weekly; HK data is updated each trading day. + + +longbridge short-trades TSLA.US +longbridge short-trades 700.HK --count 30 + + + + + +## Parameters + +> **SDK method parameters.** + +| Name | Type | Required | Description | +| ------ | ------- | -------- | --------------------------------------------------------------- | +| symbol | string | YES | Security symbol; supports US (e.g. `TSLA.US`) and HK (e.g. `700.HK`) | +| count | integer | NO | Number of records to return (1–100, default 20) | + +## Request Example + + + + +```python +from longbridge.openapi import QuoteContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = QuoteContext(config) + +resp = ctx.short_trades("TSLA.US") +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncQuoteContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncQuoteContext.create(config) + + resp = await ctx.short_trades("TSLA.US") + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, QuoteContext, OAuth } = require('longbridge') + +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.shortTrades('TSLA.US') + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.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 to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + QuoteContext ctx = QuoteContext.create(config)) { + var resp = ctx.getShortTrades("TSLA.US").get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, quote::QuoteContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let (ctx, _) = QuoteContext::new(config); + let resp = ctx.short_trades("TSLA.US").await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::quote; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + QuoteContext ctx = QuoteContext::create(config); + ctx.short_trades("TSLA.US", [](auto resp) { + if (resp) std::cout << resp->size() << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/quote" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + qctx, err := quote.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer qctx.Close() + resp, err := qctx.ShortTrades(context.Background(), "TSLA.US") + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "list": [ + { + "date": "2026-05-15", + "short_vol": "8452310", + "total_vol": "62345200", + "short_ratio": "0.1356", + "close": "342.15" + }, + { + "date": "2026-05-14", + "short_vol": "7831040", + "total_vol": "58921000", + "short_ratio": "0.1329", + "close": "338.72" + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | Success | [short_trades_rsp](#short_trades_rsp) | +| 400 | Bad request | None | + +## Schemas + +### short_trades_rsp + + + +| Name | Type | Required | Description | +| ------------ | -------- | -------- | --------------------------------------------- | +| list | object[] | true | Daily short sale volume records | +| ∟ date | string | true | Trading date in `YYYY-MM-DD` format | +| ∟ short_vol | string | true | Short sale volume for the day (shares) | +| ∟ total_vol | string | true | Total volume for the day (shares) | +| ∟ short_ratio | string | true | Short ratio (short volume ÷ total volume) | +| ∟ close | string | true | Closing price on that day | diff --git a/docs/en/docs/screener/screener_indicators.md b/docs/en/docs/screener/screener_indicators.md new file mode 100644 index 00000000..2c23b475 --- /dev/null +++ b/docs/en/docs/screener/screener_indicators.md @@ -0,0 +1,268 @@ +--- +slug: screener-indicators +title: Screener Indicators +sidebar_position: 5 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +Get all indicator definitions supported by the stock screener, including keys, names, units, and available ranges. Use these to build custom filter conditions. + + +longbridge screener indicators + + + + + +## Parameters + +> **SDK method parameters.** + +This method takes no parameters. + +## Request Example + + + + +```python +from longbridge.openapi import ScreenerContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = ScreenerContext(config) + +resp = ctx.screener_indicators() +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncScreenerContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncScreenerContext.create(config) + + resp = await ctx.screener_indicators() + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, ScreenerContext, OAuth } = require('longbridge') + +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 = ScreenerContext.new(config) + const resp = await ctx.screenerIndicators() + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.screener.*; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + ScreenerContext ctx = ScreenerContext.create(config)) { + var resp = ctx.getScreenerIndicators().get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, screener::ScreenerContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = ScreenerContext::new(config); + let resp = ctx.screener_indicators().await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::screener; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + ScreenerContext ctx = ScreenerContext::create(config); + ctx.screener_indicators([](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/screener" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := screener.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.ScreenerIndicators(context.Background()) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "indicators": [ + { + "id": 10, + "key": "filter_pe", + "name": "P/E Ratio", + "unit": "x", + "value_min": 0, + "value_max": 1000, + "step": 1 + }, + { + "id": 11, + "key": "filter_pb", + "name": "P/B Ratio", + "unit": "x", + "value_min": 0, + "value_max": 100, + "step": 0.1 + }, + { + "id": 20, + "key": "filter_marketcap", + "name": "Market Cap", + "unit": "bn", + "value_min": 0, + "value_max": 100000, + "step": 10 + }, + { + "id": 25, + "key": "filter_roe", + "name": "Return on Equity", + "unit": "%", + "value_min": -100, + "value_max": 200, + "step": 1 + }, + { + "id": 30, + "key": "filter_revenue_growth", + "name": "Revenue Growth", + "unit": "%", + "value_min": -100, + "value_max": 500, + "step": 1 + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | Success | [ScreenerIndicatorsResponse](#ScreenerIndicatorsResponse) | +| 400 | Bad request | None | + +## Schemas + +### ScreenerIndicatorsResponse + + + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| indicators | object[] | false | List of available indicators | +| ∟ id | integer | false | Indicator ID | +| ∟ key | string | false | Indicator key for building filter conditions (format: `filter_::`) | +| ∟ name | string | false | Indicator display name | +| ∟ unit | string | false | Unit (e.g. `x`, `%`, `bn`) | +| ∟ value_min | number | false | Minimum allowed value for this indicator | +| ∟ value_max | number | false | Maximum allowed value for this indicator | +| ∟ step | number | false | Suggested step size | diff --git a/docs/en/docs/screener/screener_recommend_strategies.md b/docs/en/docs/screener/screener_recommend_strategies.md new file mode 100644 index 00000000..365ace65 --- /dev/null +++ b/docs/en/docs/screener/screener_recommend_strategies.md @@ -0,0 +1,249 @@ +--- +slug: screener-recommend-strategies +title: Recommended Screener Strategies +sidebar_position: 1 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +Get the list of platform-recommended stock screener strategies, including recent average daily change and constituent stocks. + + +longbridge screener strategies + + + + + +## Parameters + +> **SDK method parameters.** + +This method takes no parameters. + +## Request Example + + + + +```python +from longbridge.openapi import ScreenerContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = ScreenerContext(config) + +resp = ctx.screener_recommend_strategies() +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncScreenerContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncScreenerContext.create(config) + + resp = await ctx.screener_recommend_strategies() + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, ScreenerContext, OAuth } = require('longbridge') + +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 = ScreenerContext.new(config) + const resp = await ctx.screenerRecommendStrategies() + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.screener.*; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + ScreenerContext ctx = ScreenerContext.create(config)) { + var resp = ctx.getScreenerRecommendStrategies().get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, screener::ScreenerContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = ScreenerContext::new(config); + let resp = ctx.screener_recommend_strategies().await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::screener; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + ScreenerContext ctx = ScreenerContext::create(config); + ctx.screener_recommend_strategies([](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/screener" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := screener.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.ScreenerRecommendStrategies(context.Background()) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "screeners": [ + { + "id": 1, + "name": "High Profit Low Valuation", + "average_day_chg": "+0.82%", + "stocks": ["AAPL.US", "MSFT.US", "GOOGL.US"], + "groups": [ + { + "group_name": "Valuation", + "indicators": [ + { "id": 10, "key": "filter_pe", "name": "P/E Ratio", "unit": "x", "min": 0, "max": 30 } + ] + }, + { + "group_name": "Profitability", + "indicators": [ + { "id": 25, "key": "filter_roe", "name": "Return on Equity", "unit": "%", "min": 15, "max": null } + ] + } + ] + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | Success | [ScreenerStrategiesResponse](#ScreenerStrategiesResponse) | +| 400 | Bad request | None | + +## Schemas + +### ScreenerStrategiesResponse + + + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| screeners | object[] | false | Strategy list | +| ∟ id | integer | false | Strategy ID | +| ∟ name | string | false | Strategy name | +| ∟ average_day_chg | string | false | Recent average daily change of strategy constituents | +| ∟ stocks | string[] | false | Current list of stock symbols from this strategy | +| ∟ groups | object[] | false | Filter condition groups | +| ∟ ∟ group_name | string | false | Group name | +| ∟ ∟ indicators | object[] | false | Indicator conditions in this group | +| ∟ ∟ ∟ id | integer | false | Indicator ID | +| ∟ ∟ ∟ key | string | false | Indicator key; usable in `screener_search` | +| ∟ ∟ ∟ name | string | false | Indicator name | +| ∟ ∟ ∟ unit | string | false | Indicator unit | +| ∟ ∟ ∟ min | number | false | Minimum value set by the strategy | +| ∟ ∟ ∟ max | number | false | Maximum value set by the strategy; `null` means no upper bound | diff --git a/docs/en/docs/screener/screener_search.md b/docs/en/docs/screener/screener_search.md new file mode 100644 index 00000000..0d0fb73f --- /dev/null +++ b/docs/en/docs/screener/screener_search.md @@ -0,0 +1,260 @@ +--- +slug: screener-search +title: Screener Search +sidebar_position: 4 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +Filter stocks by strategy ID or custom indicator conditions, with pagination support. + + +longbridge screener search --strategy-id 42 +longbridge screener search --market HK --filter filter_marketcap:100:1000 + + + + + +## Parameters + +> **SDK method parameters.** + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| market | string | YES | Market: `US`, `HK`, `CN`, `SG` | +| strategy_id | integer | NO | Strategy ID; use alone or combined with custom filters | +| page | integer | NO | Page number starting from 1, default 1 | +| size | integer | NO | Page size, default 20 | + +## Request Example + + + + +```python +from longbridge.openapi import ScreenerContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = ScreenerContext(config) + +# Filter by strategy ID +resp = ctx.screener_search("US", strategy_id=42) +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncScreenerContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncScreenerContext.create(config) + + resp = await ctx.screener_search("US", strategy_id=42, page=1, size=20) + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, ScreenerContext, OAuth } = require('longbridge') + +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 = ScreenerContext.new(config) + const resp = await ctx.screenerSearch('US', { strategyId: 42, page: 1, size: 20 }) + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.screener.*; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + ScreenerContext ctx = ScreenerContext.create(config)) { + var resp = ctx.screenerSearch("US", 42L, 1, 20).get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, screener::ScreenerContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = ScreenerContext::new(config); + let resp = ctx.screener_search("US", Some(42), 1, 20).await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::screener; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + ScreenerContext ctx = ScreenerContext::create(config); + ctx.screener_search("US", 42, 1, 20, [](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/screener" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := screener.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.ScreenerSearch(context.Background(), "US", 42, 1, 20) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "total": 87, + "page": 1, + "size": 20, + "stocks": [ + { + "symbol": "AAPL.US", + "name": "Apple Inc.", + "last_done": "213.49", + "chg": "+0.62%", + "market_cap": "3241500000000", + "pe": "32.15", + "pb": "50.21", + "ps": "8.04", + "roe": "147.25" + }, + { + "symbol": "MSFT.US", + "name": "Microsoft", + "last_done": "415.32", + "chg": "+1.05%", + "market_cap": "3085000000000", + "pe": "35.42", + "pb": "12.87", + "ps": "12.61", + "roe": "36.52" + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | Success | [ScreenerSearchResponse](#ScreenerSearchResponse) | +| 400 | Bad request | None | + +## Schemas + +### ScreenerSearchResponse + + + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| total | integer | false | Total number of matching stocks | +| page | integer | false | Current page number | +| size | integer | false | Number of results on the current page | +| stocks | object[] | false | Filtered stock list | +| ∟ symbol | string | false | Security symbol | +| ∟ name | string | false | Security name | +| ∟ last_done | string | false | Latest trade price | +| ∟ chg | string | false | Price change | +| ∟ market_cap | string | false | Market capitalisation | +| ∟ pe | string | false | P/E ratio | +| ∟ pb | string | false | P/B ratio | +| ∟ ps | string | false | P/S ratio | +| ∟ roe | string | false | Return on equity (%) | diff --git a/docs/en/docs/screener/screener_strategy.md b/docs/en/docs/screener/screener_strategy.md new file mode 100644 index 00000000..2d033053 --- /dev/null +++ b/docs/en/docs/screener/screener_strategy.md @@ -0,0 +1,264 @@ +--- +slug: screener-strategy +title: Screener Strategy Detail +sidebar_position: 3 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +Get the full configuration of a single stock screener strategy by strategy ID, including all indicator groups and the filter range for each indicator. + + +longbridge screener strategies --id 42 + + + + + +## Parameters + +> **SDK method parameters.** + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| id | integer | YES | Strategy ID from `screener_recommend_strategies` or `screener_user_strategies` | + +## Request Example + + + + +```python +from longbridge.openapi import ScreenerContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = ScreenerContext(config) + +resp = ctx.screener_strategy(42) +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncScreenerContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncScreenerContext.create(config) + + resp = await ctx.screener_strategy(42) + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, ScreenerContext, OAuth } = require('longbridge') + +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 = ScreenerContext.new(config) + const resp = await ctx.screenerStrategy(42) + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.screener.*; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + ScreenerContext ctx = ScreenerContext.create(config)) { + var resp = ctx.getScreenerStrategy(42L).get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, screener::ScreenerContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = ScreenerContext::new(config); + let resp = ctx.screener_strategy(42).await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::screener; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + ScreenerContext ctx = ScreenerContext::create(config); + ctx.screener_strategy(42, [](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/screener" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := screener.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.ScreenerStrategy(context.Background(), 42) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "id": 42, + "name": "My Growth Strategy", + "groups": [ + { + "group_name": "Valuation", + "indicators": [ + { + "id": 10, + "key": "filter_pe", + "name": "P/E Ratio", + "unit": "x", + "min": 5, + "max": 30 + }, + { + "id": 11, + "key": "filter_pb", + "name": "P/B Ratio", + "unit": "x", + "min": 1, + "max": 10 + } + ] + }, + { + "group_name": "Growth", + "indicators": [ + { + "id": 30, + "key": "filter_revenue_growth", + "name": "Revenue Growth", + "unit": "%", + "min": 20, + "max": null + } + ] + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | Success | [ScreenerStrategyDetail](#ScreenerStrategyDetail) | +| 400 | Bad request | None | + +## Schemas + +### ScreenerStrategyDetail + + + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| id | integer | false | Strategy ID | +| name | string | false | Strategy name | +| groups | object[] | false | Indicator group list | +| ∟ group_name | string | false | Group name | +| ∟ indicators | object[] | false | Indicator conditions in this group | +| ∟ ∟ id | integer | false | Indicator ID | +| ∟ ∟ key | string | false | Indicator key | +| ∟ ∟ name | string | false | Indicator display name | +| ∟ ∟ unit | string | false | Indicator unit (e.g. `x`, `%`, `bn`) | +| ∟ ∟ min | number | false | Minimum value; `null` means no lower bound | +| ∟ ∟ max | number | false | Maximum value; `null` means no upper bound | diff --git a/docs/en/docs/screener/screener_user_strategies.md b/docs/en/docs/screener/screener_user_strategies.md new file mode 100644 index 00000000..ed9da1dd --- /dev/null +++ b/docs/en/docs/screener/screener_user_strategies.md @@ -0,0 +1,228 @@ +--- +slug: screener-user-strategies +title: My Screener Strategies +sidebar_position: 2 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +Get the list of custom stock screener strategies created by the currently logged-in user. + + +longbridge screener strategies --mine + + + + + +## Parameters + +> **SDK method parameters.** + +This method takes no parameters (login required). + +## Request Example + + + + +```python +from longbridge.openapi import ScreenerContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = ScreenerContext(config) + +resp = ctx.screener_user_strategies() +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncScreenerContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncScreenerContext.create(config) + + resp = await ctx.screener_user_strategies() + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, ScreenerContext, OAuth } = require('longbridge') + +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 = ScreenerContext.new(config) + const resp = await ctx.screenerUserStrategies() + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.screener.*; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + ScreenerContext ctx = ScreenerContext.create(config)) { + var resp = ctx.getScreenerUserStrategies().get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, screener::ScreenerContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = ScreenerContext::new(config); + let resp = ctx.screener_user_strategies().await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::screener; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + ScreenerContext ctx = ScreenerContext::create(config); + ctx.screener_user_strategies([](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/screener" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := screener.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.ScreenerUserStrategies(context.Background()) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "screeners": [ + { + "id": 42, + "name": "My Growth Strategy", + "average_day_chg": "+1.24%", + "stocks": ["NVDA.US", "AMD.US"], + "groups": [ + { + "group_name": "Growth", + "indicators": [ + { "id": 30, "key": "filter_revenue_growth", "name": "Revenue Growth", "unit": "%", "min": 20, "max": null } + ] + } + ] + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | Success | [ScreenerStrategiesResponse](#ScreenerStrategiesResponse) | +| 400 | Bad request | None | + +## Schemas + +### ScreenerStrategiesResponse + + + +The response structure is identical to [screener_recommend_strategies](./screener_recommend_strategies). Please refer to that document for the Schema definition. diff --git a/docs/zh-CN/docs/cli/release-notes.md b/docs/zh-CN/docs/cli/release-notes.md index b415da08..b943f40a 100644 --- a/docs/zh-CN/docs/cli/release-notes.md +++ b/docs/zh-CN/docs/cli/release-notes.md @@ -7,6 +7,16 @@ sidebar_icon: newspaper # Release Notes +### [v0.22.0](https://github.com/longbridge/longbridge-terminal/releases/tag/v0.22.0) + +- **新增 `shareholder --top`** — 前20大股东(机构、个人、内部人)多报告期持股对比;`--object-id ` 查看单一股东持仓历史及交易明细 +- **扩展 `short-positions`** — 新增港股支持(`.HK` 自动路由至港交所沽空持仓数据) +- **新增 `short-trades`** — 每日沽空成交量(美股:FINRA/纳斯达克;港股:港交所披露数据) +- **新增 `compare`** — 多股估值对比(PE/PB/PS/市值/收盘价),不传对比股票时服务端自动选取同行业标的 +- **新增 `top-movers`** — 价格波动超近20日标准差的异动股票,附关联新闻解读;支持 `--market`、`--sort time|change|hot` 筛选 +- **新增 `screener` 命令组** — 股票筛选工具:`strategies`(推荐/我的策略)、`search --strategy-id ` 或 `--filter key:min:max` 执行筛选、`indicators` 查看可用指标 +- **新增 `rank`** — 人气排行榜;不带 `--key` 列出所有分类,`--key ` 获取对应排行(如 `ib_hot_all-us`) + ### [v0.21.0](https://github.com/longbridge/longbridge-terminal/releases/tag/v0.21.0) - **新增 `business-segments`** — 按业务分部拆解营收,支持当期数据或历史趋势对比 diff --git a/docs/zh-CN/docs/fundamental/fundamental/shareholder_detail.md b/docs/zh-CN/docs/fundamental/fundamental/shareholder_detail.md new file mode 100644 index 00000000..4202696a --- /dev/null +++ b/docs/zh-CN/docs/fundamental/fundamental/shareholder_detail.md @@ -0,0 +1,264 @@ +--- +slug: shareholder-detail +title: 股东持仓详情 +sidebar_position: 28 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +获取单个股东的持仓历史及交易明细。`object_id` 来自 `shareholder_top` 返回结果。 + + +longbridge shareholder AAPL.US --object-id 19463 +longbridge shareholder 700.HK --object-id 20181 + + + + + +## Parameters + +> **SDK 方法参数。** + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| symbol | string | 是 | 证券代码,例如 `AAPL.US` | +| object_id | integer | 是 | 股东 ID,来自 `shareholder_top` 的 `object_id` 字段 | + +## Request Example + + + + +```python +from longbridge.openapi import FundamentalContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = FundamentalContext(config) + +resp = ctx.shareholder_detail("AAPL.US", 19463) +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncFundamentalContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncFundamentalContext.create(config) + + resp = await ctx.shareholder_detail("AAPL.US", 19463) + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, FundamentalContext, OAuth } = require('longbridge') + +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 = FundamentalContext.new(config) + const resp = await ctx.shareholderDetail('AAPL.US', 19463) + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.fundamental.*; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + FundamentalContext ctx = FundamentalContext.create(config)) { + var resp = ctx.getShareholderDetail("AAPL.US", 19463L).get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, fundamental::FundamentalContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = FundamentalContext::new(config); + let resp = ctx.shareholder_detail("AAPL.US", 19463).await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::fundamental; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + FundamentalContext ctx = FundamentalContext::create(config); + ctx.shareholder_detail("AAPL.US", 19463, [](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/fundamental" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := fundamental.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.ShareholderDetail(context.Background(), "AAPL.US", 19463) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "owner_source": "Institution", + "holding_summary": [ + { + "period": "2025-12-31", + "accum_buy": "8500000", + "accum_sell": "2687264", + "stock_price": "243.08" + }, + { + "period": "2025-09-30", + "accum_buy": "3200000", + "accum_sell": "1500000", + "stock_price": "226.51" + } + ], + "tradings": [ + { + "period": "2025-12-31", + "trading_details": [ + { + "trading_date": "2025-12-18", + "trading_shares": "5200000", + "trading_price": "248.12", + "trading_type": "Buy" + }, + { + "trading_date": "2025-11-05", + "trading_shares": "2687264", + "trading_price": "222.91", + "trading_type": "Sell" + } + ] + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | 成功 | [ShareholderDetailResponse](#ShareholderDetailResponse) | +| 400 | 请求错误 | None | + +## Schemas + +### ShareholderDetailResponse + + + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| owner_source | string | false | 股东类型:`Company`、`Institution`、`Person`、`Insider` | +| holding_summary | object[] | false | 各报告期持仓汇总 | +| ∟ period | string | false | 报告期,格式 `YYYY-MM-DD` | +| ∟ accum_buy | string | false | 该期累计买入股数 | +| ∟ accum_sell | string | false | 该期累计卖出股数 | +| ∟ stock_price | string | false | 报告期末股价 | +| tradings | object[] | false | 各报告期交易明细 | +| ∟ period | string | false | 报告期,格式 `YYYY-MM-DD` | +| ∟ trading_details | object[] | false | 该报告期内的交易记录 | +| ∟ ∟ trading_date | string | false | 交易日期,格式 `YYYY-MM-DD` | +| ∟ ∟ trading_shares | string | false | 交易股数 | +| ∟ ∟ trading_price | string | false | 交易价格 | +| ∟ ∟ trading_type | string | false | 交易方向:`Buy` 或 `Sell` | diff --git a/docs/zh-CN/docs/fundamental/fundamental/shareholder_top.md b/docs/zh-CN/docs/fundamental/fundamental/shareholder_top.md new file mode 100644 index 00000000..ae60ece2 --- /dev/null +++ b/docs/zh-CN/docs/fundamental/fundamental/shareholder_top.md @@ -0,0 +1,253 @@ +--- +slug: shareholder-top +title: 大股东排行 +sidebar_position: 27 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +获取上市公司前20大股东(机构、个人、内部人)的持股数据,支持多报告期对比。`object_id` 可传入 `shareholder_detail` 查看详情。 + + +longbridge shareholder AAPL.US --top +longbridge shareholder 700.HK --top + + + + + +## Parameters + +> **SDK 方法参数。** + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| symbol | string | 是 | 证券代码,例如 `AAPL.US` | + +## Request Example + + + + +```python +from longbridge.openapi import FundamentalContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = FundamentalContext(config) + +resp = ctx.shareholder_top("AAPL.US") +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncFundamentalContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncFundamentalContext.create(config) + + resp = await ctx.shareholder_top("AAPL.US") + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, FundamentalContext, OAuth } = require('longbridge') + +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 = FundamentalContext.new(config) + const resp = await ctx.shareholderTop('AAPL.US') + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.fundamental.*; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + FundamentalContext ctx = FundamentalContext.create(config)) { + var resp = ctx.getShareholderTop("AAPL.US").get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, fundamental::FundamentalContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = FundamentalContext::new(config); + let resp = ctx.shareholder_top("AAPL.US").await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::fundamental; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + FundamentalContext ctx = FundamentalContext::create(config); + ctx.shareholder_top("AAPL.US", [](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/fundamental" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := fundamental.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.ShareholderTop(context.Background(), "AAPL.US") + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "periods": ["2025-12-31", "2025-09-30"], + "info": [ + { + "period": "2025-12-31", + "share_holders": [ + { + "object_id": 19463, + "name": "The Vanguard Group, Inc.", + "title": "机构", + "shares_held": "1285506048", + "percent_shares_held": "8.46", + "shares_changed": "5812736", + "filing_date": "2026-02-14" + }, + { + "object_id": 20181, + "name": "BlackRock, Inc.", + "title": "机构", + "shares_held": "1071234816", + "percent_shares_held": "7.05", + "shares_changed": "-3104128", + "filing_date": "2026-02-05" + } + ] + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | 成功 | [ShareholderTopResponse](#ShareholderTopResponse) | +| 400 | 请求错误 | None | + +## Schemas + +### ShareholderTopResponse + + + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| periods | string[] | false | 可用的报告期列表,格式 `YYYY-MM-DD` | +| info | object[] | false | 各报告期的股东数据 | +| ∟ period | string | false | 报告期,格式 `YYYY-MM-DD` | +| ∟ share_holders | object[] | false | 股东列表(最多 20 条) | +| ∟ ∟ object_id | integer | false | 股东唯一 ID,可传入 `shareholder_detail` | +| ∟ ∟ name | string | false | 股东名称 | +| ∟ ∟ title | string | false | 股东类型(机构 / 个人 / 内部人) | +| ∟ ∟ shares_held | string | false | 持股数量 | +| ∟ ∟ percent_shares_held | string | false | 持股比例(百分比) | +| ∟ ∟ shares_changed | string | false | 持股变动数量(正增负减) | +| ∟ ∟ filing_date | string | false | 申报日期,格式 `YYYY-MM-DD` | diff --git a/docs/zh-CN/docs/fundamental/fundamental/valuation_comparison.md b/docs/zh-CN/docs/fundamental/fundamental/valuation_comparison.md new file mode 100644 index 00000000..ba296f86 --- /dev/null +++ b/docs/zh-CN/docs/fundamental/fundamental/valuation_comparison.md @@ -0,0 +1,263 @@ +--- +slug: valuation-comparison +title: 多股估值对比 +sidebar_position: 29 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +对比多只股票的估值指标(PE/PB/PS/市值/收盘价)。不传对比股票时,服务端自动选取同行业标的。 + + +longbridge compare AAPL.US +longbridge compare AAPL.US MSFT.US GOOGL.US + + + + + +## Parameters + +> **SDK 方法参数。** + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| symbol | string | 是 | 主标的证券代码,例如 `AAPL.US` | +| currency | string | 是 | 结果货币:`USD`、`HKD`、`CNY` | +| comparison_symbols | string[] | 否 | 对比股票代码列表;不传时服务端自动选取同行业标的 | + +## Request Example + + + + +```python +from longbridge.openapi import FundamentalContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = FundamentalContext(config) + +# 自动选取同行业对比 +resp = ctx.valuation_comparison("AAPL.US", "USD") +# 指定对比标的 +resp = ctx.valuation_comparison("AAPL.US", "USD", ["MSFT.US", "GOOGL.US"]) +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncFundamentalContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncFundamentalContext.create(config) + + resp = await ctx.valuation_comparison("AAPL.US", "USD", ["MSFT.US", "GOOGL.US"]) + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, FundamentalContext, OAuth } = require('longbridge') + +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 = FundamentalContext.new(config) + const resp = await ctx.valuationComparison('AAPL.US', 'USD', ['MSFT.US', 'GOOGL.US']) + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.fundamental.*; +import java.util.Arrays; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + FundamentalContext ctx = FundamentalContext.create(config)) { + var resp = ctx.getValuationComparison("AAPL.US", "USD", Arrays.asList("MSFT.US", "GOOGL.US")).get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, fundamental::FundamentalContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = FundamentalContext::new(config); + let resp = ctx.valuation_comparison("AAPL.US", "USD", Some(vec!["MSFT.US", "GOOGL.US"])).await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::fundamental; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + FundamentalContext ctx = FundamentalContext::create(config); + ctx.valuation_comparison("AAPL.US", "USD", {"MSFT.US", "GOOGL.US"}, [](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/fundamental" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := fundamental.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.ValuationComparison(context.Background(), "AAPL.US", "USD", []string{"MSFT.US", "GOOGL.US"}) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "list": [ + { + "symbol": "AAPL.US", + "name": "苹果公司", + "market_value": "3241500000000", + "price_close": "213.49", + "pe": "32.15", + "pb": "50.21", + "ps": "8.04", + "history": [ + { "date": "2026-05-01", "pe": "32.15", "pb": "50.21", "ps": "8.04" }, + { "date": "2026-04-01", "pe": "28.73", "pb": "46.88", "ps": "7.52" } + ] + }, + { + "symbol": "MSFT.US", + "name": "微软", + "market_value": "3085000000000", + "price_close": "415.32", + "pe": "35.42", + "pb": "12.87", + "ps": "12.61", + "history": [ + { "date": "2026-05-01", "pe": "35.42", "pb": "12.87", "ps": "12.61" }, + { "date": "2026-04-01", "pe": "33.10", "pb": "12.01", "ps": "11.94" } + ] + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | 成功 | [ValuationComparisonResponse](#ValuationComparisonResponse) | +| 400 | 请求错误 | None | + +## Schemas + +### ValuationComparisonResponse + + + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| list | object[] | false | 股票估值对比列表 | +| ∟ symbol | string | false | 证券代码 | +| ∟ name | string | false | 证券名称 | +| ∟ market_value | string | false | 市值(结果货币) | +| ∟ price_close | string | false | 最新收盘价 | +| ∟ pe | string | false | 市盈率(TTM) | +| ∟ pb | string | false | 市净率 | +| ∟ ps | string | false | 市销率(TTM) | +| ∟ history | object[] | false | 历史估值时间序列 | +| ∟ ∟ date | string | false | 日期,格式 `YYYY-MM-DD` | +| ∟ ∟ pe | string | false | 历史 PE | +| ∟ ∟ pb | string | false | 历史 PB | +| ∟ ∟ ps | string | false | 历史 PS | diff --git a/docs/zh-CN/docs/market/status/rank_categories.md b/docs/zh-CN/docs/market/status/rank_categories.md new file mode 100644 index 00000000..c9cbcb72 --- /dev/null +++ b/docs/zh-CN/docs/market/status/rank_categories.md @@ -0,0 +1,239 @@ +--- +slug: /market/rank-categories +title: 人气排行分类 +sidebar_position: 8 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +获取人气排行榜的标签分类配置,`second_tags[].key` 可传入 `rank_list`。 + + +longbridge rank + + + + + +## Parameters + +> **SDK 方法参数。** + +此方法无参数。 + +## Request Example + + + + +```python +from longbridge.openapi import MarketContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = MarketContext(config) + +resp = ctx.rank_categories() +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncMarketContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncMarketContext.create(config) + + resp = await ctx.rank_categories() + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, MarketContext, OAuth } = require('longbridge') + +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 = MarketContext.new(config) + const resp = await ctx.rankCategories() + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.market.*; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + MarketContext ctx = MarketContext.create(config)) { + var resp = ctx.getRankCategories().get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, market::MarketContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = MarketContext::new(config); + let resp = ctx.rank_categories().await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::market; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + MarketContext ctx = MarketContext::create(config); + ctx.rank_categories([](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/market" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := market.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.RankCategories(context.Background()) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "first_tags": [ + { + "key": "ib_hot", + "name": "热度排行", + "second_tags": [ + { "key": "ib_hot_all-us", "name": "美股总热度", "market": "US" }, + { "key": "ib_hot_all-hk", "name": "港股总热度", "market": "HK" }, + { "key": "ib_hot_all-cn", "name": "A股总热度", "market": "CN" } + ] + }, + { + "key": "ib_change", + "name": "涨跌排行", + "second_tags": [ + { "key": "ib_change_top-us", "name": "美股涨幅榜", "market": "US" }, + { "key": "ib_change_top-hk", "name": "港股涨幅榜", "market": "HK" } + ] + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | 成功 | [RankCategoriesResponse](#RankCategoriesResponse) | +| 400 | 请求错误 | None | + +## Schemas + +### RankCategoriesResponse + + + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| first_tags | object[] | false | 一级分类列表 | +| ∟ key | string | false | 一级分类键值 | +| ∟ name | string | false | 一级分类名称 | +| ∟ second_tags | object[] | false | 二级分类列表 | +| ∟ ∟ key | string | false | 二级分类键值,可传入 `rank_list` 的 `key` 参数 | +| ∟ ∟ name | string | false | 二级分类名称 | +| ∟ ∟ market | string | false | 所属市场:`US`、`HK`、`CN`、`SG` | diff --git a/docs/zh-CN/docs/market/status/rank_list.md b/docs/zh-CN/docs/market/status/rank_list.md new file mode 100644 index 00000000..873ece0e --- /dev/null +++ b/docs/zh-CN/docs/market/status/rank_list.md @@ -0,0 +1,248 @@ +--- +slug: /market/rank-list +title: 人气排行榜 +sidebar_position: 9 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +根据排行榜标签 key 获取股票排行。key 来自 `rank_categories` 的 `second_tags[].key`,例如 `ib_hot_all-us`(美股总热度)。 + + +longbridge rank --key ib_hot_all-us +longbridge rank --key ib_hot_all-hk + + + + + +## Parameters + +> **SDK 方法参数。** + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| key | string | 是 | 排行榜标签键值,来自 `rank_categories` 的 `second_tags[].key` | +| need_article | boolean | 否 | 是否返回关联文章,默认 `false` | + +## Request Example + + + + +```python +from longbridge.openapi import MarketContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = MarketContext(config) + +resp = ctx.rank_list("ib_hot_all-us") +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncMarketContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncMarketContext.create(config) + + resp = await ctx.rank_list("ib_hot_all-us", need_article=False) + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, MarketContext, OAuth } = require('longbridge') + +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 = MarketContext.new(config) + const resp = await ctx.rankList('ib_hot_all-us', false) + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.market.*; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + MarketContext ctx = MarketContext.create(config)) { + var resp = ctx.getRankList("ib_hot_all-us", false).get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, market::MarketContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = MarketContext::new(config); + let resp = ctx.rank_list("ib_hot_all-us", false).await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::market; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + MarketContext ctx = MarketContext::create(config); + ctx.rank_list("ib_hot_all-us", false, [](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/market" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := market.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.RankList(context.Background(), "ib_hot_all-us", false) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "lists": [ + { + "symbol": "NVDA.US", + "name": "英伟达", + "last_done": "135.62", + "chg": "+2.84%", + "inflow": "1250000000", + "market_cap": "3312000000000", + "pre_post_price": "136.10", + "pre_post_chg": "+0.35%" + }, + { + "symbol": "TSLA.US", + "name": "特斯拉", + "last_done": "342.15", + "chg": "-1.23%", + "inflow": "875000000", + "market_cap": "1098000000000", + "pre_post_price": "341.00", + "pre_post_chg": "-0.34%" + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | 成功 | [RankListResponse](#RankListResponse) | +| 400 | 请求错误 | None | + +## Schemas + +### RankListResponse + + + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| lists | object[] | false | 排行榜股票列表 | +| ∟ symbol | string | false | 证券代码 | +| ∟ name | string | false | 证券名称 | +| ∟ last_done | string | false | 最新成交价 | +| ∟ chg | string | false | 涨跌幅(含符号,如 `+2.84%`) | +| ∟ inflow | string | false | 净流入资金(单位:所属市场货币) | +| ∟ market_cap | string | false | 市值 | +| ∟ pre_post_price | string | false | 盘前/盘后价格 | +| ∟ pre_post_chg | string | false | 盘前/盘后涨跌幅 | diff --git a/docs/zh-CN/docs/market/status/stock_events.md b/docs/zh-CN/docs/market/status/stock_events.md new file mode 100644 index 00000000..b87ef04e --- /dev/null +++ b/docs/zh-CN/docs/market/status/stock_events.md @@ -0,0 +1,265 @@ +--- +slug: /market/stock-events +title: 异动股票 +sidebar_position: 7 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +获取价格波动超过近20个交易日标准差的异动股票,系统自动关联相关新闻解读异动原因。 + + +longbridge top-movers +longbridge top-movers --market HK --sort time + + + + + +## Parameters + +> **SDK 方法参数。** + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| markets | string[] | 否 | 市场列表:`HK`、`US`、`CN`、`SG`;不传返回所有市场 | +| sort | integer | 否 | 排序方式:`0`=时间(最新优先),`1`=涨跌幅,`2`=热度(默认) | +| date | string | 否 | 指定日期,格式 `YYYY-MM-DD`;不传返回最新数据 | +| limit | integer | 否 | 返回条数,默认 20 | + +## Request Example + + + + +```python +from longbridge.openapi import MarketContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = MarketContext(config) + +resp = ctx.stock_events(markets=["HK", "US"], sort=2, limit=20) +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncMarketContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncMarketContext.create(config) + + resp = await ctx.stock_events(markets=["HK", "US"], sort=2, limit=20) + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, MarketContext, OAuth } = require('longbridge') + +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 = MarketContext.new(config) + const resp = await ctx.stockEvents({ markets: ['HK', 'US'], sort: 2, limit: 20 }) + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.market.*; +import java.util.Arrays; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + MarketContext ctx = MarketContext.create(config)) { + var resp = ctx.getStockEvents(Arrays.asList("HK", "US"), 2, null, 20).get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, market::MarketContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = MarketContext::new(config); + let resp = ctx.stock_events(Some(vec!["HK", "US"]), Some(2), None, Some(20)).await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::market; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + MarketContext ctx = MarketContext::create(config); + ctx.stock_events({"HK", "US"}, 2, "", 20, [](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/market" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := market.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.StockEvents(context.Background(), []string{"HK", "US"}, 2, "", 20) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "events": [ + { + "stock": { + "symbol": "9988.HK", + "name": "阿里巴巴", + "change": "+4.82%", + "labels": ["港股", "科技"] + }, + "timestamp": 1747728600000, + "alert_reason": "财报超预期,营收增长 8%", + "alert_type": "earnings_beat", + "post": { + "id": "post_abc123", + "title": "阿里巴巴Q4财报解读:云业务强劲增长", + "url": "https://longbridge.com/news/post_abc123" + } + }, + { + "stock": { + "symbol": "NVDA.US", + "name": "英伟达", + "change": "+3.21%", + "labels": ["美股", "半导体"] + }, + "timestamp": 1747725000000, + "alert_reason": "大宗买入,成交量放大 3 倍", + "alert_type": "volume_spike", + "post": null + } + ], + "next_params": "eyJvZmZzZXQiOjIwfQ==" + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | 成功 | [StockEventsResponse](#StockEventsResponse) | +| 400 | 请求错误 | None | + +## Schemas + +### StockEventsResponse + + + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| events | object[] | false | 异动股票列表 | +| ∟ stock | object | false | 股票基本信息 | +| ∟ ∟ symbol | string | false | 证券代码 | +| ∟ ∟ name | string | false | 证券名称 | +| ∟ ∟ change | string | false | 涨跌幅(含符号,如 `+4.82%`) | +| ∟ ∟ labels | string[] | false | 标签列表(市场、行业等) | +| ∟ timestamp | integer | false | 异动时间(Unix 毫秒时间戳) | +| ∟ alert_reason | string | false | 异动原因描述 | +| ∟ alert_type | string | false | 异动类型标识符 | +| ∟ post | object | false | 关联新闻/文章;无关联时为 `null` | +| ∟ ∟ id | string | false | 文章 ID | +| ∟ ∟ title | string | false | 文章标题 | +| ∟ ∟ url | string | false | 文章链接 | +| next_params | string | false | 翻页参数(Base64 编码),传入下次请求以获取下一页 | diff --git a/docs/zh-CN/docs/quote/analytics/hk_short_positions.md b/docs/zh-CN/docs/quote/analytics/hk_short_positions.md new file mode 100644 index 00000000..e04e024a --- /dev/null +++ b/docs/zh-CN/docs/quote/analytics/hk_short_positions.md @@ -0,0 +1,236 @@ +--- +slug: /quote/pull/hk-short-positions +title: 港股沽空数据 +sidebar_position: 26 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +获取港股沽空持仓数据,包括沽空金额、沽空比率等。数据由香港交易所(HKEX)提供,每个交易日更新。仅支持港股上市股票。 + + +longbridge short-positions 700.HK +longbridge short-positions 9988.HK --count 50 + + + + + +## Parameters + +> **SDK 方法参数。** + +| Name | Type | Required | Description | +| ------ | ------- | -------- | ---------------------------------------------- | +| symbol | string | YES | 港股证券代码,例如 `700.HK`、`9988.HK` | +| count | integer | NO | 返回记录数(1–100,默认 20) | + +## Request Example + + + + +```python +from longbridge.openapi import QuoteContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = QuoteContext(config) + +resp = ctx.hk_short_positions("700.HK") +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncQuoteContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncQuoteContext.create(config) + + resp = await ctx.hk_short_positions("700.HK") + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, QuoteContext, OAuth } = require('longbridge') + +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.hkShortPositions('700.HK') + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.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 to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + QuoteContext ctx = QuoteContext.create(config)) { + var resp = ctx.getHkShortPositions("700.HK").get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, quote::QuoteContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let (ctx, _) = QuoteContext::new(config); + let resp = ctx.hk_short_positions("700.HK").await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::quote; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + QuoteContext ctx = QuoteContext::create(config); + ctx.hk_short_positions("700.HK", [](auto resp) { + if (resp) std::cout << resp->size() << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/quote" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + qctx, err := quote.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer qctx.Close() + resp, err := qctx.HkShortPositions(context.Background(), "700.HK") + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "list": [ + { + "date": "2026-05-16", + "short_amount": "2148600000", + "short_ratio": "0.0182", + "close": "418.20" + }, + { + "date": "2026-05-15", + "short_amount": "1935200000", + "short_ratio": "0.0163", + "close": "412.80" + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | 成功 | [hk_short_positions_rsp](#hk_short_positions_rsp) | +| 400 | 请求错误 | None | + +## Schemas + +### hk_short_positions_rsp + + + +| Name | Type | Required | Description | +| ------------- | -------- | -------- | ---------------------------------------- | +| list | object[] | true | 港股沽空持仓记录 | +| ∟ date | string | true | 交易日期,格式 `YYYY-MM-DD` | +| ∟ short_amount | string | true | 沽空金额(港元) | +| ∟ short_ratio | string | true | 沽空比率(沽空金额 ÷ 总成交金额) | +| ∟ close | string | true | 当日收盘价 | diff --git a/docs/zh-CN/docs/quote/analytics/short_trades.md b/docs/zh-CN/docs/quote/analytics/short_trades.md new file mode 100644 index 00000000..01b510e1 --- /dev/null +++ b/docs/zh-CN/docs/quote/analytics/short_trades.md @@ -0,0 +1,239 @@ +--- +slug: /quote/pull/short-trades +title: 每日沽空成交量 +sidebar_position: 27 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +获取个股每日沽空成交量数据,支持美股(FINRA)和港股(HKEX)。美股数据每两周更新一次,港股数据每个交易日更新。 + + +longbridge short-trades TSLA.US +longbridge short-trades 700.HK --count 30 + + + + + +## Parameters + +> **SDK 方法参数。** + +| Name | Type | Required | Description | +| ------ | ------- | -------- | --------------------------------------------------------- | +| symbol | string | YES | 证券代码,支持美股(如 `TSLA.US`)和港股(如 `700.HK`) | +| count | integer | NO | 返回记录数(1–100,默认 20) | + +## Request Example + + + + +```python +from longbridge.openapi import QuoteContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = QuoteContext(config) + +resp = ctx.short_trades("TSLA.US") +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncQuoteContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncQuoteContext.create(config) + + resp = await ctx.short_trades("TSLA.US") + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, QuoteContext, OAuth } = require('longbridge') + +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.shortTrades('TSLA.US') + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.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 to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + QuoteContext ctx = QuoteContext.create(config)) { + var resp = ctx.getShortTrades("TSLA.US").get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, quote::QuoteContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let (ctx, _) = QuoteContext::new(config); + let resp = ctx.short_trades("TSLA.US").await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::quote; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + QuoteContext ctx = QuoteContext::create(config); + ctx.short_trades("TSLA.US", [](auto resp) { + if (resp) std::cout << resp->size() << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/quote" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + qctx, err := quote.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer qctx.Close() + resp, err := qctx.ShortTrades(context.Background(), "TSLA.US") + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "list": [ + { + "date": "2026-05-15", + "short_vol": "8452310", + "total_vol": "62345200", + "short_ratio": "0.1356", + "close": "342.15" + }, + { + "date": "2026-05-14", + "short_vol": "7831040", + "total_vol": "58921000", + "short_ratio": "0.1329", + "close": "338.72" + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | 成功 | [short_trades_rsp](#short_trades_rsp) | +| 400 | 请求错误 | None | + +## Schemas + +### short_trades_rsp + + + +| Name | Type | Required | Description | +| ------------ | -------- | -------- | --------------------------------------------- | +| list | object[] | true | 每日沽空成交量记录 | +| ∟ date | string | true | 交易日期,格式 `YYYY-MM-DD` | +| ∟ short_vol | string | true | 当日沽空成交量(股数) | +| ∟ total_vol | string | true | 当日总成交量(股数) | +| ∟ short_ratio | string | true | 沽空比率(沽空量 ÷ 总成交量) | +| ∟ close | string | true | 当日收盘价 | diff --git a/docs/zh-CN/docs/screener/_category_.json b/docs/zh-CN/docs/screener/_category_.json new file mode 100644 index 00000000..f7a6310e --- /dev/null +++ b/docs/zh-CN/docs/screener/_category_.json @@ -0,0 +1,7 @@ +{ + "label": "选股", + "collapsible": true, + "collapsed": true, + "link": null, + "position": 4.5 +} diff --git a/docs/zh-CN/docs/screener/screener_indicators.md b/docs/zh-CN/docs/screener/screener_indicators.md new file mode 100644 index 00000000..c790a238 --- /dev/null +++ b/docs/zh-CN/docs/screener/screener_indicators.md @@ -0,0 +1,268 @@ +--- +slug: screener-indicators +title: 选股指标 +sidebar_position: 5 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +获取选股器支持的所有指标定义,包含键值、名称、单位和可用范围,可用于构建自定义筛选条件。 + + +longbridge screener indicators + + + + + +## Parameters + +> **SDK 方法参数。** + +此方法无参数。 + +## Request Example + + + + +```python +from longbridge.openapi import ScreenerContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = ScreenerContext(config) + +resp = ctx.screener_indicators() +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncScreenerContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncScreenerContext.create(config) + + resp = await ctx.screener_indicators() + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, ScreenerContext, OAuth } = require('longbridge') + +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 = ScreenerContext.new(config) + const resp = await ctx.screenerIndicators() + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.screener.*; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + ScreenerContext ctx = ScreenerContext.create(config)) { + var resp = ctx.getScreenerIndicators().get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, screener::ScreenerContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = ScreenerContext::new(config); + let resp = ctx.screener_indicators().await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::screener; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + ScreenerContext ctx = ScreenerContext::create(config); + ctx.screener_indicators([](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/screener" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := screener.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.ScreenerIndicators(context.Background()) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "indicators": [ + { + "id": 10, + "key": "filter_pe", + "name": "市盈率", + "unit": "x", + "value_min": 0, + "value_max": 1000, + "step": 1 + }, + { + "id": 11, + "key": "filter_pb", + "name": "市净率", + "unit": "x", + "value_min": 0, + "value_max": 100, + "step": 0.1 + }, + { + "id": 20, + "key": "filter_marketcap", + "name": "市值", + "unit": "亿", + "value_min": 0, + "value_max": 100000, + "step": 10 + }, + { + "id": 25, + "key": "filter_roe", + "name": "净资产收益率", + "unit": "%", + "value_min": -100, + "value_max": 200, + "step": 1 + }, + { + "id": 30, + "key": "filter_revenue_growth", + "name": "营收增速", + "unit": "%", + "value_min": -100, + "value_max": 500, + "step": 1 + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | 成功 | [ScreenerIndicatorsResponse](#ScreenerIndicatorsResponse) | +| 400 | 请求错误 | None | + +## Schemas + +### ScreenerIndicatorsResponse + + + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| indicators | object[] | false | 可用指标列表 | +| ∟ id | integer | false | 指标 ID | +| ∟ key | string | false | 指标键值,用于构建筛选条件(格式:`filter_::`) | +| ∟ name | string | false | 指标显示名称 | +| ∟ unit | string | false | 单位(如 `x`、`%`、`亿`) | +| ∟ value_min | number | false | 指标允许的最小值 | +| ∟ value_max | number | false | 指标允许的最大值 | +| ∟ step | number | false | 建议步长 | diff --git a/docs/zh-CN/docs/screener/screener_recommend_strategies.md b/docs/zh-CN/docs/screener/screener_recommend_strategies.md new file mode 100644 index 00000000..ab65cd36 --- /dev/null +++ b/docs/zh-CN/docs/screener/screener_recommend_strategies.md @@ -0,0 +1,249 @@ +--- +slug: screener-recommend-strategies +title: 推荐选股策略 +sidebar_position: 1 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +获取平台推荐的选股策略列表,含近期平均日涨跌幅和策略内股票。 + + +longbridge screener strategies + + + + + +## Parameters + +> **SDK 方法参数。** + +此方法无参数。 + +## Request Example + + + + +```python +from longbridge.openapi import ScreenerContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = ScreenerContext(config) + +resp = ctx.screener_recommend_strategies() +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncScreenerContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncScreenerContext.create(config) + + resp = await ctx.screener_recommend_strategies() + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, ScreenerContext, OAuth } = require('longbridge') + +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 = ScreenerContext.new(config) + const resp = await ctx.screenerRecommendStrategies() + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.screener.*; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + ScreenerContext ctx = ScreenerContext.create(config)) { + var resp = ctx.getScreenerRecommendStrategies().get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, screener::ScreenerContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = ScreenerContext::new(config); + let resp = ctx.screener_recommend_strategies().await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::screener; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + ScreenerContext ctx = ScreenerContext::create(config); + ctx.screener_recommend_strategies([](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/screener" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := screener.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.ScreenerRecommendStrategies(context.Background()) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "screeners": [ + { + "id": 1, + "name": "高盈利低估值", + "average_day_chg": "+0.82%", + "stocks": ["AAPL.US", "MSFT.US", "GOOGL.US"], + "groups": [ + { + "group_name": "估值", + "indicators": [ + { "id": 10, "key": "filter_pe", "name": "市盈率", "unit": "x", "min": 0, "max": 30 } + ] + }, + { + "group_name": "盈利能力", + "indicators": [ + { "id": 25, "key": "filter_roe", "name": "净资产收益率", "unit": "%", "min": 15, "max": null } + ] + } + ] + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | 成功 | [ScreenerStrategiesResponse](#ScreenerStrategiesResponse) | +| 400 | 请求错误 | None | + +## Schemas + +### ScreenerStrategiesResponse + + + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| screeners | object[] | false | 策略列表 | +| ∟ id | integer | false | 策略 ID | +| ∟ name | string | false | 策略名称 | +| ∟ average_day_chg | string | false | 策略标的近期平均日涨跌幅 | +| ∟ stocks | string[] | false | 策略当前筛选出的股票代码列表 | +| ∟ groups | object[] | false | 策略过滤条件分组 | +| ∟ ∟ group_name | string | false | 分组名称 | +| ∟ ∟ indicators | object[] | false | 该分组下的指标条件 | +| ∟ ∟ ∟ id | integer | false | 指标 ID | +| ∟ ∟ ∟ key | string | false | 指标键值,可用于 `screener_search` | +| ∟ ∟ ∟ name | string | false | 指标名称 | +| ∟ ∟ ∟ unit | string | false | 指标单位 | +| ∟ ∟ ∟ min | number | false | 策略设定的最小值 | +| ∟ ∟ ∟ max | number | false | 策略设定的最大值;`null` 表示无上限 | diff --git a/docs/zh-CN/docs/screener/screener_search.md b/docs/zh-CN/docs/screener/screener_search.md new file mode 100644 index 00000000..65b062a9 --- /dev/null +++ b/docs/zh-CN/docs/screener/screener_search.md @@ -0,0 +1,260 @@ +--- +slug: screener-search +title: 选股筛选 +sidebar_position: 4 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +按策略 ID 或自定义指标条件筛选股票,支持分页。 + + +longbridge screener search --strategy-id 42 +longbridge screener search --market HK --filter filter_marketcap:100:1000 + + + + + +## Parameters + +> **SDK 方法参数。** + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| market | string | 是 | 市场:`US`、`HK`、`CN`、`SG` | +| strategy_id | integer | 否 | 策略 ID;与自定义 filter 二选一,或同时使用 | +| page | integer | 否 | 页码,从 1 开始,默认 1 | +| size | integer | 否 | 每页条数,默认 20 | + +## Request Example + + + + +```python +from longbridge.openapi import ScreenerContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = ScreenerContext(config) + +# 按策略 ID 筛选 +resp = ctx.screener_search("US", strategy_id=42) +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncScreenerContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncScreenerContext.create(config) + + resp = await ctx.screener_search("US", strategy_id=42, page=1, size=20) + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, ScreenerContext, OAuth } = require('longbridge') + +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 = ScreenerContext.new(config) + const resp = await ctx.screenerSearch('US', { strategyId: 42, page: 1, size: 20 }) + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.screener.*; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + ScreenerContext ctx = ScreenerContext.create(config)) { + var resp = ctx.screenerSearch("US", 42L, 1, 20).get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, screener::ScreenerContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = ScreenerContext::new(config); + let resp = ctx.screener_search("US", Some(42), 1, 20).await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::screener; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + ScreenerContext ctx = ScreenerContext::create(config); + ctx.screener_search("US", 42, 1, 20, [](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/screener" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := screener.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.ScreenerSearch(context.Background(), "US", 42, 1, 20) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "total": 87, + "page": 1, + "size": 20, + "stocks": [ + { + "symbol": "AAPL.US", + "name": "苹果公司", + "last_done": "213.49", + "chg": "+0.62%", + "market_cap": "3241500000000", + "pe": "32.15", + "pb": "50.21", + "ps": "8.04", + "roe": "147.25" + }, + { + "symbol": "MSFT.US", + "name": "微软", + "last_done": "415.32", + "chg": "+1.05%", + "market_cap": "3085000000000", + "pe": "35.42", + "pb": "12.87", + "ps": "12.61", + "roe": "36.52" + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | 成功 | [ScreenerSearchResponse](#ScreenerSearchResponse) | +| 400 | 请求错误 | None | + +## Schemas + +### ScreenerSearchResponse + + + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| total | integer | false | 满足条件的股票总数 | +| page | integer | false | 当前页码 | +| size | integer | false | 当前页条数 | +| stocks | object[] | false | 筛选结果股票列表 | +| ∟ symbol | string | false | 证券代码 | +| ∟ name | string | false | 证券名称 | +| ∟ last_done | string | false | 最新成交价 | +| ∟ chg | string | false | 涨跌幅 | +| ∟ market_cap | string | false | 市值 | +| ∟ pe | string | false | 市盈率 | +| ∟ pb | string | false | 市净率 | +| ∟ ps | string | false | 市销率 | +| ∟ roe | string | false | 净资产收益率(%) | diff --git a/docs/zh-CN/docs/screener/screener_strategy.md b/docs/zh-CN/docs/screener/screener_strategy.md new file mode 100644 index 00000000..19081c85 --- /dev/null +++ b/docs/zh-CN/docs/screener/screener_strategy.md @@ -0,0 +1,264 @@ +--- +slug: screener-strategy +title: 选股策略详情 +sidebar_position: 3 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +根据策略 ID 获取单个选股策略的完整配置,包含所有指标分组和各指标的筛选范围。 + + +longbridge screener strategies --id 42 + + + + + +## Parameters + +> **SDK 方法参数。** + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| id | integer | 是 | 策略 ID,来自 `screener_recommend_strategies` 或 `screener_user_strategies` | + +## Request Example + + + + +```python +from longbridge.openapi import ScreenerContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = ScreenerContext(config) + +resp = ctx.screener_strategy(42) +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncScreenerContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncScreenerContext.create(config) + + resp = await ctx.screener_strategy(42) + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, ScreenerContext, OAuth } = require('longbridge') + +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 = ScreenerContext.new(config) + const resp = await ctx.screenerStrategy(42) + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.screener.*; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + ScreenerContext ctx = ScreenerContext.create(config)) { + var resp = ctx.getScreenerStrategy(42L).get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, screener::ScreenerContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = ScreenerContext::new(config); + let resp = ctx.screener_strategy(42).await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::screener; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + ScreenerContext ctx = ScreenerContext::create(config); + ctx.screener_strategy(42, [](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/screener" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := screener.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.ScreenerStrategy(context.Background(), 42) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "id": 42, + "name": "我的成长股策略", + "groups": [ + { + "group_name": "估值", + "indicators": [ + { + "id": 10, + "key": "filter_pe", + "name": "市盈率", + "unit": "x", + "min": 5, + "max": 30 + }, + { + "id": 11, + "key": "filter_pb", + "name": "市净率", + "unit": "x", + "min": 1, + "max": 10 + } + ] + }, + { + "group_name": "成长性", + "indicators": [ + { + "id": 30, + "key": "filter_revenue_growth", + "name": "营收增速", + "unit": "%", + "min": 20, + "max": null + } + ] + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | 成功 | [ScreenerStrategyDetail](#ScreenerStrategyDetail) | +| 400 | 请求错误 | None | + +## Schemas + +### ScreenerStrategyDetail + + + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| id | integer | false | 策略 ID | +| name | string | false | 策略名称 | +| groups | object[] | false | 指标分组列表 | +| ∟ group_name | string | false | 分组名称 | +| ∟ indicators | object[] | false | 该分组下的指标条件 | +| ∟ ∟ id | integer | false | 指标 ID | +| ∟ ∟ key | string | false | 指标键值 | +| ∟ ∟ name | string | false | 指标显示名称 | +| ∟ ∟ unit | string | false | 指标单位(如 `x`、`%`、`亿` 等) | +| ∟ ∟ min | number | false | 最小值;`null` 表示无下限 | +| ∟ ∟ max | number | false | 最大值;`null` 表示无上限 | diff --git a/docs/zh-CN/docs/screener/screener_user_strategies.md b/docs/zh-CN/docs/screener/screener_user_strategies.md new file mode 100644 index 00000000..7c4c0295 --- /dev/null +++ b/docs/zh-CN/docs/screener/screener_user_strategies.md @@ -0,0 +1,228 @@ +--- +slug: screener-user-strategies +title: 我的选股策略 +sidebar_position: 2 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +获取当前登录用户创建的自定义选股策略列表。 + + +longbridge screener strategies --mine + + + + + +## Parameters + +> **SDK 方法参数。** + +此方法无参数(需登录)。 + +## Request Example + + + + +```python +from longbridge.openapi import ScreenerContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = ScreenerContext(config) + +resp = ctx.screener_user_strategies() +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncScreenerContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncScreenerContext.create(config) + + resp = await ctx.screener_user_strategies() + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, ScreenerContext, OAuth } = require('longbridge') + +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 = ScreenerContext.new(config) + const resp = await ctx.screenerUserStrategies() + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.screener.*; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + ScreenerContext ctx = ScreenerContext.create(config)) { + var resp = ctx.getScreenerUserStrategies().get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, screener::ScreenerContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = ScreenerContext::new(config); + let resp = ctx.screener_user_strategies().await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::screener; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + ScreenerContext ctx = ScreenerContext::create(config); + ctx.screener_user_strategies([](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/screener" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := screener.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.ScreenerUserStrategies(context.Background()) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "screeners": [ + { + "id": 42, + "name": "我的成长股策略", + "average_day_chg": "+1.24%", + "stocks": ["NVDA.US", "AMD.US"], + "groups": [ + { + "group_name": "成长性", + "indicators": [ + { "id": 30, "key": "filter_revenue_growth", "name": "营收增速", "unit": "%", "min": 20, "max": null } + ] + } + ] + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | 成功 | [ScreenerStrategiesResponse](#ScreenerStrategiesResponse) | +| 400 | 请求错误 | None | + +## Schemas + +### ScreenerStrategiesResponse + + + +响应结构与 [screener_recommend_strategies](./screener_recommend_strategies) 相同,请参阅该文档中的 Schema 定义。 diff --git a/docs/zh-HK/docs/cli/release-notes.md b/docs/zh-HK/docs/cli/release-notes.md index 4802786a..84127fd3 100644 --- a/docs/zh-HK/docs/cli/release-notes.md +++ b/docs/zh-HK/docs/cli/release-notes.md @@ -7,6 +7,16 @@ sidebar_icon: newspaper # Release Notes +### [v0.22.0](https://github.com/longbridge/longbridge-terminal/releases/tag/v0.22.0) + +- **新增 `shareholder --top`** — 前20大股東(機構、個人、內部人)多報告期持股對比;`--object-id ` 查看單一股東持倉歷史及交易明細 +- **擴展 `short-positions`** — 新增港股支持(`.HK` 自動路由至港交所沽空持倉數據) +- **新增 `short-trades`** — 每日沽空成交量(美股:FINRA/納斯達克;港股:港交所披露數據) +- **新增 `compare`** — 多股估值對比(PE/PB/PS/市值/收盤價),不傳對比股票時服務端自動選取同行業標的 +- **新增 `top-movers`** — 價格波動超近20日標準差的異動股票,附關聯新聞解讀;支持 `--market`、`--sort time|change|hot` 篩選 +- **新增 `screener` 命令組** — 股票篩選工具:`strategies`(推薦/我的策略)、`search --strategy-id ` 或 `--filter key:min:max` 執行篩選、`indicators` 查看可用指標 +- **新增 `rank`** — 人氣排行榜;不帶 `--key` 列出所有分類,`--key ` 獲取對應排行(如 `ib_hot_all-us`) + ### [v0.21.0](https://github.com/longbridge/longbridge-terminal/releases/tag/v0.21.0) - **新增 `business-segments`** — 按业务分部拆解营收,支持当期数据或历史趋势对比 diff --git a/docs/zh-HK/docs/fundamental/fundamental/shareholder_detail.md b/docs/zh-HK/docs/fundamental/fundamental/shareholder_detail.md new file mode 100644 index 00000000..f670fcfc --- /dev/null +++ b/docs/zh-HK/docs/fundamental/fundamental/shareholder_detail.md @@ -0,0 +1,264 @@ +--- +slug: shareholder-detail +title: 股東持倉詳情 +sidebar_position: 28 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +獲取單個股東的持倉歷史及交易明細。`object_id` 來自 `shareholder_top` 返回結果。 + + +longbridge shareholder AAPL.US --object-id 19463 +longbridge shareholder 700.HK --object-id 20181 + + + + + +## Parameters + +> **SDK 方法參數。** + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| symbol | string | 是 | 證券代碼,例如 `AAPL.US` | +| object_id | integer | 是 | 股東 ID,來自 `shareholder_top` 的 `object_id` 字段 | + +## Request Example + + + + +```python +from longbridge.openapi import FundamentalContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = FundamentalContext(config) + +resp = ctx.shareholder_detail("AAPL.US", 19463) +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncFundamentalContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncFundamentalContext.create(config) + + resp = await ctx.shareholder_detail("AAPL.US", 19463) + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, FundamentalContext, OAuth } = require('longbridge') + +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 = FundamentalContext.new(config) + const resp = await ctx.shareholderDetail('AAPL.US', 19463) + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.fundamental.*; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + FundamentalContext ctx = FundamentalContext.create(config)) { + var resp = ctx.getShareholderDetail("AAPL.US", 19463L).get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, fundamental::FundamentalContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = FundamentalContext::new(config); + let resp = ctx.shareholder_detail("AAPL.US", 19463).await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::fundamental; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + FundamentalContext ctx = FundamentalContext::create(config); + ctx.shareholder_detail("AAPL.US", 19463, [](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/fundamental" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := fundamental.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.ShareholderDetail(context.Background(), "AAPL.US", 19463) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "owner_source": "Institution", + "holding_summary": [ + { + "period": "2025-12-31", + "accum_buy": "8500000", + "accum_sell": "2687264", + "stock_price": "243.08" + }, + { + "period": "2025-09-30", + "accum_buy": "3200000", + "accum_sell": "1500000", + "stock_price": "226.51" + } + ], + "tradings": [ + { + "period": "2025-12-31", + "trading_details": [ + { + "trading_date": "2025-12-18", + "trading_shares": "5200000", + "trading_price": "248.12", + "trading_type": "Buy" + }, + { + "trading_date": "2025-11-05", + "trading_shares": "2687264", + "trading_price": "222.91", + "trading_type": "Sell" + } + ] + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | 成功 | [ShareholderDetailResponse](#ShareholderDetailResponse) | +| 400 | 請求錯誤 | None | + +## Schemas + +### ShareholderDetailResponse + + + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| owner_source | string | false | 股東類型:`Company`、`Institution`、`Person`、`Insider` | +| holding_summary | object[] | false | 各報告期持倉匯總 | +| ∟ period | string | false | 報告期,格式 `YYYY-MM-DD` | +| ∟ accum_buy | string | false | 該期累計買入股數 | +| ∟ accum_sell | string | false | 該期累計賣出股數 | +| ∟ stock_price | string | false | 報告期末股價 | +| tradings | object[] | false | 各報告期交易明細 | +| ∟ period | string | false | 報告期,格式 `YYYY-MM-DD` | +| ∟ trading_details | object[] | false | 該報告期內的交易記錄 | +| ∟ ∟ trading_date | string | false | 交易日期,格式 `YYYY-MM-DD` | +| ∟ ∟ trading_shares | string | false | 交易股數 | +| ∟ ∟ trading_price | string | false | 交易價格 | +| ∟ ∟ trading_type | string | false | 交易方向:`Buy` 或 `Sell` | diff --git a/docs/zh-HK/docs/fundamental/fundamental/shareholder_top.md b/docs/zh-HK/docs/fundamental/fundamental/shareholder_top.md new file mode 100644 index 00000000..5a57b423 --- /dev/null +++ b/docs/zh-HK/docs/fundamental/fundamental/shareholder_top.md @@ -0,0 +1,253 @@ +--- +slug: shareholder-top +title: 大股東排行 +sidebar_position: 27 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +獲取上市公司前20大股東(機構、個人、內部人)的持股數據,支持多報告期對比。`object_id` 可傳入 `shareholder_detail` 查看詳情。 + + +longbridge shareholder AAPL.US --top +longbridge shareholder 700.HK --top + + + + + +## Parameters + +> **SDK 方法參數。** + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| symbol | string | 是 | 證券代碼,例如 `AAPL.US` | + +## Request Example + + + + +```python +from longbridge.openapi import FundamentalContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = FundamentalContext(config) + +resp = ctx.shareholder_top("AAPL.US") +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncFundamentalContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncFundamentalContext.create(config) + + resp = await ctx.shareholder_top("AAPL.US") + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, FundamentalContext, OAuth } = require('longbridge') + +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 = FundamentalContext.new(config) + const resp = await ctx.shareholderTop('AAPL.US') + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.fundamental.*; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + FundamentalContext ctx = FundamentalContext.create(config)) { + var resp = ctx.getShareholderTop("AAPL.US").get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, fundamental::FundamentalContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = FundamentalContext::new(config); + let resp = ctx.shareholder_top("AAPL.US").await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::fundamental; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + FundamentalContext ctx = FundamentalContext::create(config); + ctx.shareholder_top("AAPL.US", [](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/fundamental" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := fundamental.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.ShareholderTop(context.Background(), "AAPL.US") + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "periods": ["2025-12-31", "2025-09-30"], + "info": [ + { + "period": "2025-12-31", + "share_holders": [ + { + "object_id": 19463, + "name": "The Vanguard Group, Inc.", + "title": "機構", + "shares_held": "1285506048", + "percent_shares_held": "8.46", + "shares_changed": "5812736", + "filing_date": "2026-02-14" + }, + { + "object_id": 20181, + "name": "BlackRock, Inc.", + "title": "機構", + "shares_held": "1071234816", + "percent_shares_held": "7.05", + "shares_changed": "-3104128", + "filing_date": "2026-02-05" + } + ] + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | 成功 | [ShareholderTopResponse](#ShareholderTopResponse) | +| 400 | 請求錯誤 | None | + +## Schemas + +### ShareholderTopResponse + + + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| periods | string[] | false | 可用的報告期列表,格式 `YYYY-MM-DD` | +| info | object[] | false | 各報告期的股東數據 | +| ∟ period | string | false | 報告期,格式 `YYYY-MM-DD` | +| ∟ share_holders | object[] | false | 股東列表(最多 20 條) | +| ∟ ∟ object_id | integer | false | 股東唯一 ID,可傳入 `shareholder_detail` | +| ∟ ∟ name | string | false | 股東名稱 | +| ∟ ∟ title | string | false | 股東類型(機構 / 個人 / 內部人) | +| ∟ ∟ shares_held | string | false | 持股數量 | +| ∟ ∟ percent_shares_held | string | false | 持股比例(百分比) | +| ∟ ∟ shares_changed | string | false | 持股變動數量(正增負減) | +| ∟ ∟ filing_date | string | false | 申報日期,格式 `YYYY-MM-DD` | diff --git a/docs/zh-HK/docs/fundamental/fundamental/valuation_comparison.md b/docs/zh-HK/docs/fundamental/fundamental/valuation_comparison.md new file mode 100644 index 00000000..03402eee --- /dev/null +++ b/docs/zh-HK/docs/fundamental/fundamental/valuation_comparison.md @@ -0,0 +1,263 @@ +--- +slug: valuation-comparison +title: 多股估值對比 +sidebar_position: 29 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +對比多隻股票的估值指標(PE/PB/PS/市值/收盤價)。不傳對比股票時,服務端自動選取同行業標的。 + + +longbridge compare AAPL.US +longbridge compare AAPL.US MSFT.US GOOGL.US + + + + + +## Parameters + +> **SDK 方法參數。** + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| symbol | string | 是 | 主標的證券代碼,例如 `AAPL.US` | +| currency | string | 是 | 結果貨幣:`USD`、`HKD`、`CNY` | +| comparison_symbols | string[] | 否 | 對比股票代碼列表;不傳時服務端自動選取同行業標的 | + +## Request Example + + + + +```python +from longbridge.openapi import FundamentalContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = FundamentalContext(config) + +# 自動選取同行業對比 +resp = ctx.valuation_comparison("AAPL.US", "USD") +# 指定對比標的 +resp = ctx.valuation_comparison("AAPL.US", "USD", ["MSFT.US", "GOOGL.US"]) +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncFundamentalContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncFundamentalContext.create(config) + + resp = await ctx.valuation_comparison("AAPL.US", "USD", ["MSFT.US", "GOOGL.US"]) + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, FundamentalContext, OAuth } = require('longbridge') + +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 = FundamentalContext.new(config) + const resp = await ctx.valuationComparison('AAPL.US', 'USD', ['MSFT.US', 'GOOGL.US']) + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.fundamental.*; +import java.util.Arrays; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + FundamentalContext ctx = FundamentalContext.create(config)) { + var resp = ctx.getValuationComparison("AAPL.US", "USD", Arrays.asList("MSFT.US", "GOOGL.US")).get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, fundamental::FundamentalContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = FundamentalContext::new(config); + let resp = ctx.valuation_comparison("AAPL.US", "USD", Some(vec!["MSFT.US", "GOOGL.US"])).await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::fundamental; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + FundamentalContext ctx = FundamentalContext::create(config); + ctx.valuation_comparison("AAPL.US", "USD", {"MSFT.US", "GOOGL.US"}, [](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/fundamental" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := fundamental.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.ValuationComparison(context.Background(), "AAPL.US", "USD", []string{"MSFT.US", "GOOGL.US"}) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "list": [ + { + "symbol": "AAPL.US", + "name": "蘋果公司", + "market_value": "3241500000000", + "price_close": "213.49", + "pe": "32.15", + "pb": "50.21", + "ps": "8.04", + "history": [ + { "date": "2026-05-01", "pe": "32.15", "pb": "50.21", "ps": "8.04" }, + { "date": "2026-04-01", "pe": "28.73", "pb": "46.88", "ps": "7.52" } + ] + }, + { + "symbol": "MSFT.US", + "name": "微軟", + "market_value": "3085000000000", + "price_close": "415.32", + "pe": "35.42", + "pb": "12.87", + "ps": "12.61", + "history": [ + { "date": "2026-05-01", "pe": "35.42", "pb": "12.87", "ps": "12.61" }, + { "date": "2026-04-01", "pe": "33.10", "pb": "12.01", "ps": "11.94" } + ] + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | 成功 | [ValuationComparisonResponse](#ValuationComparisonResponse) | +| 400 | 請求錯誤 | None | + +## Schemas + +### ValuationComparisonResponse + + + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| list | object[] | false | 股票估值對比列表 | +| ∟ symbol | string | false | 證券代碼 | +| ∟ name | string | false | 證券名稱 | +| ∟ market_value | string | false | 市值(結果貨幣) | +| ∟ price_close | string | false | 最新收盤價 | +| ∟ pe | string | false | 市盈率(TTM) | +| ∟ pb | string | false | 市淨率 | +| ∟ ps | string | false | 市銷率(TTM) | +| ∟ history | object[] | false | 歷史估值時間序列 | +| ∟ ∟ date | string | false | 日期,格式 `YYYY-MM-DD` | +| ∟ ∟ pe | string | false | 歷史 PE | +| ∟ ∟ pb | string | false | 歷史 PB | +| ∟ ∟ ps | string | false | 歷史 PS | diff --git a/docs/zh-HK/docs/market/status/rank_categories.md b/docs/zh-HK/docs/market/status/rank_categories.md new file mode 100644 index 00000000..746a82a8 --- /dev/null +++ b/docs/zh-HK/docs/market/status/rank_categories.md @@ -0,0 +1,239 @@ +--- +slug: /market/rank-categories +title: 人氣排行分類 +sidebar_position: 8 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +獲取人氣排行榜的標籤分類配置,`second_tags[].key` 可傳入 `rank_list`。 + + +longbridge rank + + + + + +## Parameters + +> **SDK 方法參數。** + +此方法無參數。 + +## Request Example + + + + +```python +from longbridge.openapi import MarketContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = MarketContext(config) + +resp = ctx.rank_categories() +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncMarketContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncMarketContext.create(config) + + resp = await ctx.rank_categories() + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, MarketContext, OAuth } = require('longbridge') + +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 = MarketContext.new(config) + const resp = await ctx.rankCategories() + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.market.*; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + MarketContext ctx = MarketContext.create(config)) { + var resp = ctx.getRankCategories().get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, market::MarketContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = MarketContext::new(config); + let resp = ctx.rank_categories().await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::market; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + MarketContext ctx = MarketContext::create(config); + ctx.rank_categories([](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/market" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := market.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.RankCategories(context.Background()) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "first_tags": [ + { + "key": "ib_hot", + "name": "熱度排行", + "second_tags": [ + { "key": "ib_hot_all-us", "name": "美股總熱度", "market": "US" }, + { "key": "ib_hot_all-hk", "name": "港股總熱度", "market": "HK" }, + { "key": "ib_hot_all-cn", "name": "A股總熱度", "market": "CN" } + ] + }, + { + "key": "ib_change", + "name": "漲跌排行", + "second_tags": [ + { "key": "ib_change_top-us", "name": "美股漲幅榜", "market": "US" }, + { "key": "ib_change_top-hk", "name": "港股漲幅榜", "market": "HK" } + ] + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | 成功 | [RankCategoriesResponse](#RankCategoriesResponse) | +| 400 | 請求錯誤 | None | + +## Schemas + +### RankCategoriesResponse + + + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| first_tags | object[] | false | 一級分類列表 | +| ∟ key | string | false | 一級分類鍵值 | +| ∟ name | string | false | 一級分類名稱 | +| ∟ second_tags | object[] | false | 二級分類列表 | +| ∟ ∟ key | string | false | 二級分類鍵值,可傳入 `rank_list` 的 `key` 參數 | +| ∟ ∟ name | string | false | 二級分類名稱 | +| ∟ ∟ market | string | false | 所屬市場:`US`、`HK`、`CN`、`SG` | diff --git a/docs/zh-HK/docs/market/status/rank_list.md b/docs/zh-HK/docs/market/status/rank_list.md new file mode 100644 index 00000000..9bc44c0b --- /dev/null +++ b/docs/zh-HK/docs/market/status/rank_list.md @@ -0,0 +1,248 @@ +--- +slug: /market/rank-list +title: 人氣排行榜 +sidebar_position: 9 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +根據排行榜標籤 key 獲取股票排行。key 來自 `rank_categories` 的 `second_tags[].key`,例如 `ib_hot_all-us`(美股總熱度)。 + + +longbridge rank --key ib_hot_all-us +longbridge rank --key ib_hot_all-hk + + + + + +## Parameters + +> **SDK 方法參數。** + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| key | string | 是 | 排行榜標籤鍵值,來自 `rank_categories` 的 `second_tags[].key` | +| need_article | boolean | 否 | 是否返回關聯文章,默認 `false` | + +## Request Example + + + + +```python +from longbridge.openapi import MarketContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = MarketContext(config) + +resp = ctx.rank_list("ib_hot_all-us") +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncMarketContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncMarketContext.create(config) + + resp = await ctx.rank_list("ib_hot_all-us", need_article=False) + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, MarketContext, OAuth } = require('longbridge') + +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 = MarketContext.new(config) + const resp = await ctx.rankList('ib_hot_all-us', false) + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.market.*; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + MarketContext ctx = MarketContext.create(config)) { + var resp = ctx.getRankList("ib_hot_all-us", false).get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, market::MarketContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = MarketContext::new(config); + let resp = ctx.rank_list("ib_hot_all-us", false).await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::market; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + MarketContext ctx = MarketContext::create(config); + ctx.rank_list("ib_hot_all-us", false, [](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/market" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := market.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.RankList(context.Background(), "ib_hot_all-us", false) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "lists": [ + { + "symbol": "NVDA.US", + "name": "英偉達", + "last_done": "135.62", + "chg": "+2.84%", + "inflow": "1250000000", + "market_cap": "3312000000000", + "pre_post_price": "136.10", + "pre_post_chg": "+0.35%" + }, + { + "symbol": "TSLA.US", + "name": "特斯拉", + "last_done": "342.15", + "chg": "-1.23%", + "inflow": "875000000", + "market_cap": "1098000000000", + "pre_post_price": "341.00", + "pre_post_chg": "-0.34%" + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | 成功 | [RankListResponse](#RankListResponse) | +| 400 | 請求錯誤 | None | + +## Schemas + +### RankListResponse + + + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| lists | object[] | false | 排行榜股票列表 | +| ∟ symbol | string | false | 證券代碼 | +| ∟ name | string | false | 證券名稱 | +| ∟ last_done | string | false | 最新成交價 | +| ∟ chg | string | false | 漲跌幅(含符號,如 `+2.84%`) | +| ∟ inflow | string | false | 淨流入資金(單位:所屬市場貨幣) | +| ∟ market_cap | string | false | 市值 | +| ∟ pre_post_price | string | false | 盤前/盤後價格 | +| ∟ pre_post_chg | string | false | 盤前/盤後漲跌幅 | diff --git a/docs/zh-HK/docs/market/status/stock_events.md b/docs/zh-HK/docs/market/status/stock_events.md new file mode 100644 index 00000000..d3576cbc --- /dev/null +++ b/docs/zh-HK/docs/market/status/stock_events.md @@ -0,0 +1,265 @@ +--- +slug: /market/stock-events +title: 異動股票 +sidebar_position: 7 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +獲取價格波動超過近20個交易日標準差的異動股票,系統自動關聯相關新聞解讀異動原因。 + + +longbridge top-movers +longbridge top-movers --market HK --sort time + + + + + +## Parameters + +> **SDK 方法參數。** + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| markets | string[] | 否 | 市場列表:`HK`、`US`、`CN`、`SG`;不傳返回所有市場 | +| sort | integer | 否 | 排序方式:`0`=時間(最新優先),`1`=漲跌幅,`2`=熱度(默認) | +| date | string | 否 | 指定日期,格式 `YYYY-MM-DD`;不傳返回最新數據 | +| limit | integer | 否 | 返回條數,默認 20 | + +## Request Example + + + + +```python +from longbridge.openapi import MarketContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = MarketContext(config) + +resp = ctx.stock_events(markets=["HK", "US"], sort=2, limit=20) +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncMarketContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncMarketContext.create(config) + + resp = await ctx.stock_events(markets=["HK", "US"], sort=2, limit=20) + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, MarketContext, OAuth } = require('longbridge') + +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 = MarketContext.new(config) + const resp = await ctx.stockEvents({ markets: ['HK', 'US'], sort: 2, limit: 20 }) + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.market.*; +import java.util.Arrays; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + MarketContext ctx = MarketContext.create(config)) { + var resp = ctx.getStockEvents(Arrays.asList("HK", "US"), 2, null, 20).get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, market::MarketContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = MarketContext::new(config); + let resp = ctx.stock_events(Some(vec!["HK", "US"]), Some(2), None, Some(20)).await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::market; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + MarketContext ctx = MarketContext::create(config); + ctx.stock_events({"HK", "US"}, 2, "", 20, [](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/market" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := market.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.StockEvents(context.Background(), []string{"HK", "US"}, 2, "", 20) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "events": [ + { + "stock": { + "symbol": "9988.HK", + "name": "阿里巴巴", + "change": "+4.82%", + "labels": ["港股", "科技"] + }, + "timestamp": 1747728600000, + "alert_reason": "財報超預期,營收增長 8%", + "alert_type": "earnings_beat", + "post": { + "id": "post_abc123", + "title": "阿里巴巴Q4財報解讀:雲業務強勁增長", + "url": "https://longbridge.com/news/post_abc123" + } + }, + { + "stock": { + "symbol": "NVDA.US", + "name": "英偉達", + "change": "+3.21%", + "labels": ["美股", "半導體"] + }, + "timestamp": 1747725000000, + "alert_reason": "大宗買入,成交量放大 3 倍", + "alert_type": "volume_spike", + "post": null + } + ], + "next_params": "eyJvZmZzZXQiOjIwfQ==" + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | 成功 | [StockEventsResponse](#StockEventsResponse) | +| 400 | 請求錯誤 | None | + +## Schemas + +### StockEventsResponse + + + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| events | object[] | false | 異動股票列表 | +| ∟ stock | object | false | 股票基本信息 | +| ∟ ∟ symbol | string | false | 證券代碼 | +| ∟ ∟ name | string | false | 證券名稱 | +| ∟ ∟ change | string | false | 漲跌幅(含符號,如 `+4.82%`) | +| ∟ ∟ labels | string[] | false | 標籤列表(市場、行業等) | +| ∟ timestamp | integer | false | 異動時間(Unix 毫秒時間戳) | +| ∟ alert_reason | string | false | 異動原因描述 | +| ∟ alert_type | string | false | 異動類型標識符 | +| ∟ post | object | false | 關聯新聞/文章;無關聯時為 `null` | +| ∟ ∟ id | string | false | 文章 ID | +| ∟ ∟ title | string | false | 文章標題 | +| ∟ ∟ url | string | false | 文章鏈接 | +| next_params | string | false | 翻頁參數(Base64 編碼),傳入下次請求以獲取下一頁 | diff --git a/docs/zh-HK/docs/quote/analytics/hk_short_positions.md b/docs/zh-HK/docs/quote/analytics/hk_short_positions.md new file mode 100644 index 00000000..32820bd0 --- /dev/null +++ b/docs/zh-HK/docs/quote/analytics/hk_short_positions.md @@ -0,0 +1,236 @@ +--- +slug: /quote/pull/hk-short-positions +title: 港股沽空數據 +sidebar_position: 26 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +獲取港股沽空持倉數據,包括沽空金額、沽空比率等。數據由香港交易所(HKEX)提供,每個交易日更新。僅支持港股上市股票。 + + +longbridge short-positions 700.HK +longbridge short-positions 9988.HK --count 50 + + + + + +## Parameters + +> **SDK 方法參數。** + +| Name | Type | Required | Description | +| ------ | ------- | -------- | ---------------------------------------------- | +| symbol | string | YES | 港股證券代碼,例如 `700.HK`、`9988.HK` | +| count | integer | NO | 返回記錄數(1–100,默認 20) | + +## Request Example + + + + +```python +from longbridge.openapi import QuoteContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = QuoteContext(config) + +resp = ctx.hk_short_positions("700.HK") +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncQuoteContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncQuoteContext.create(config) + + resp = await ctx.hk_short_positions("700.HK") + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, QuoteContext, OAuth } = require('longbridge') + +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.hkShortPositions('700.HK') + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.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 to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + QuoteContext ctx = QuoteContext.create(config)) { + var resp = ctx.getHkShortPositions("700.HK").get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, quote::QuoteContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let (ctx, _) = QuoteContext::new(config); + let resp = ctx.hk_short_positions("700.HK").await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::quote; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + QuoteContext ctx = QuoteContext::create(config); + ctx.hk_short_positions("700.HK", [](auto resp) { + if (resp) std::cout << resp->size() << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/quote" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + qctx, err := quote.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer qctx.Close() + resp, err := qctx.HkShortPositions(context.Background(), "700.HK") + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "list": [ + { + "date": "2026-05-16", + "short_amount": "2148600000", + "short_ratio": "0.0182", + "close": "418.20" + }, + { + "date": "2026-05-15", + "short_amount": "1935200000", + "short_ratio": "0.0163", + "close": "412.80" + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | 成功 | [hk_short_positions_rsp](#hk_short_positions_rsp) | +| 400 | 請求錯誤 | None | + +## Schemas + +### hk_short_positions_rsp + + + +| Name | Type | Required | Description | +| ------------- | -------- | -------- | ---------------------------------------- | +| list | object[] | true | 港股沽空持倉記錄 | +| ∟ date | string | true | 交易日期,格式 `YYYY-MM-DD` | +| ∟ short_amount | string | true | 沽空金額(港元) | +| ∟ short_ratio | string | true | 沽空比率(沽空金額 ÷ 總成交金額) | +| ∟ close | string | true | 當日收盤價 | diff --git a/docs/zh-HK/docs/quote/analytics/short_trades.md b/docs/zh-HK/docs/quote/analytics/short_trades.md new file mode 100644 index 00000000..d46ae134 --- /dev/null +++ b/docs/zh-HK/docs/quote/analytics/short_trades.md @@ -0,0 +1,239 @@ +--- +slug: /quote/pull/short-trades +title: 每日沽空成交量 +sidebar_position: 27 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +獲取個股每日沽空成交量數據,支持美股(FINRA)和港股(HKEX)。美股數據每兩週更新一次,港股數據每個交易日更新。 + + +longbridge short-trades TSLA.US +longbridge short-trades 700.HK --count 30 + + + + + +## Parameters + +> **SDK 方法參數。** + +| Name | Type | Required | Description | +| ------ | ------- | -------- | --------------------------------------------------------- | +| symbol | string | YES | 證券代碼,支持美股(如 `TSLA.US`)和港股(如 `700.HK`) | +| count | integer | NO | 返回記錄數(1–100,默認 20) | + +## Request Example + + + + +```python +from longbridge.openapi import QuoteContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = QuoteContext(config) + +resp = ctx.short_trades("TSLA.US") +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncQuoteContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncQuoteContext.create(config) + + resp = await ctx.short_trades("TSLA.US") + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, QuoteContext, OAuth } = require('longbridge') + +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.shortTrades('TSLA.US') + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.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 to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + QuoteContext ctx = QuoteContext.create(config)) { + var resp = ctx.getShortTrades("TSLA.US").get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, quote::QuoteContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let (ctx, _) = QuoteContext::new(config); + let resp = ctx.short_trades("TSLA.US").await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::quote; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + QuoteContext ctx = QuoteContext::create(config); + ctx.short_trades("TSLA.US", [](auto resp) { + if (resp) std::cout << resp->size() << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/quote" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + qctx, err := quote.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer qctx.Close() + resp, err := qctx.ShortTrades(context.Background(), "TSLA.US") + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "list": [ + { + "date": "2026-05-15", + "short_vol": "8452310", + "total_vol": "62345200", + "short_ratio": "0.1356", + "close": "342.15" + }, + { + "date": "2026-05-14", + "short_vol": "7831040", + "total_vol": "58921000", + "short_ratio": "0.1329", + "close": "338.72" + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | 成功 | [short_trades_rsp](#short_trades_rsp) | +| 400 | 請求錯誤 | None | + +## Schemas + +### short_trades_rsp + + + +| Name | Type | Required | Description | +| ------------ | -------- | -------- | --------------------------------------------- | +| list | object[] | true | 每日沽空成交量記錄 | +| ∟ date | string | true | 交易日期,格式 `YYYY-MM-DD` | +| ∟ short_vol | string | true | 當日沽空成交量(股數) | +| ∟ total_vol | string | true | 當日總成交量(股數) | +| ∟ short_ratio | string | true | 沽空比率(沽空量 ÷ 總成交量) | +| ∟ close | string | true | 當日收盤價 | diff --git a/docs/zh-HK/docs/screener/screener_indicators.md b/docs/zh-HK/docs/screener/screener_indicators.md new file mode 100644 index 00000000..d74e0240 --- /dev/null +++ b/docs/zh-HK/docs/screener/screener_indicators.md @@ -0,0 +1,268 @@ +--- +slug: screener-indicators +title: 選股指標 +sidebar_position: 5 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +獲取選股器支持的所有指標定義,包含鍵值、名稱、單位和可用範圍,可用於構建自定義篩選條件。 + + +longbridge screener indicators + + + + + +## Parameters + +> **SDK 方法參數。** + +此方法無參數。 + +## Request Example + + + + +```python +from longbridge.openapi import ScreenerContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = ScreenerContext(config) + +resp = ctx.screener_indicators() +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncScreenerContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncScreenerContext.create(config) + + resp = await ctx.screener_indicators() + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, ScreenerContext, OAuth } = require('longbridge') + +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 = ScreenerContext.new(config) + const resp = await ctx.screenerIndicators() + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.screener.*; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + ScreenerContext ctx = ScreenerContext.create(config)) { + var resp = ctx.getScreenerIndicators().get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, screener::ScreenerContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = ScreenerContext::new(config); + let resp = ctx.screener_indicators().await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::screener; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + ScreenerContext ctx = ScreenerContext::create(config); + ctx.screener_indicators([](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/screener" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := screener.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.ScreenerIndicators(context.Background()) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "indicators": [ + { + "id": 10, + "key": "filter_pe", + "name": "市盈率", + "unit": "x", + "value_min": 0, + "value_max": 1000, + "step": 1 + }, + { + "id": 11, + "key": "filter_pb", + "name": "市淨率", + "unit": "x", + "value_min": 0, + "value_max": 100, + "step": 0.1 + }, + { + "id": 20, + "key": "filter_marketcap", + "name": "市值", + "unit": "億", + "value_min": 0, + "value_max": 100000, + "step": 10 + }, + { + "id": 25, + "key": "filter_roe", + "name": "淨資產收益率", + "unit": "%", + "value_min": -100, + "value_max": 200, + "step": 1 + }, + { + "id": 30, + "key": "filter_revenue_growth", + "name": "營收增速", + "unit": "%", + "value_min": -100, + "value_max": 500, + "step": 1 + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | 成功 | [ScreenerIndicatorsResponse](#ScreenerIndicatorsResponse) | +| 400 | 請求錯誤 | None | + +## Schemas + +### ScreenerIndicatorsResponse + + + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| indicators | object[] | false | 可用指標列表 | +| ∟ id | integer | false | 指標 ID | +| ∟ key | string | false | 指標鍵值,用於構建篩選條件(格式:`filter_::`) | +| ∟ name | string | false | 指標顯示名稱 | +| ∟ unit | string | false | 單位(如 `x`、`%`、`億`) | +| ∟ value_min | number | false | 指標允許的最小值 | +| ∟ value_max | number | false | 指標允許的最大值 | +| ∟ step | number | false | 建議步長 | diff --git a/docs/zh-HK/docs/screener/screener_recommend_strategies.md b/docs/zh-HK/docs/screener/screener_recommend_strategies.md new file mode 100644 index 00000000..836223f8 --- /dev/null +++ b/docs/zh-HK/docs/screener/screener_recommend_strategies.md @@ -0,0 +1,249 @@ +--- +slug: screener-recommend-strategies +title: 推薦選股策略 +sidebar_position: 1 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +獲取平台推薦的選股策略列表,含近期平均日漲跌幅和策略內股票。 + + +longbridge screener strategies + + + + + +## Parameters + +> **SDK 方法參數。** + +此方法無參數。 + +## Request Example + + + + +```python +from longbridge.openapi import ScreenerContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = ScreenerContext(config) + +resp = ctx.screener_recommend_strategies() +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncScreenerContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncScreenerContext.create(config) + + resp = await ctx.screener_recommend_strategies() + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, ScreenerContext, OAuth } = require('longbridge') + +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 = ScreenerContext.new(config) + const resp = await ctx.screenerRecommendStrategies() + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.screener.*; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + ScreenerContext ctx = ScreenerContext.create(config)) { + var resp = ctx.getScreenerRecommendStrategies().get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, screener::ScreenerContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = ScreenerContext::new(config); + let resp = ctx.screener_recommend_strategies().await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::screener; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + ScreenerContext ctx = ScreenerContext::create(config); + ctx.screener_recommend_strategies([](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/screener" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := screener.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.ScreenerRecommendStrategies(context.Background()) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "screeners": [ + { + "id": 1, + "name": "高盈利低估值", + "average_day_chg": "+0.82%", + "stocks": ["AAPL.US", "MSFT.US", "GOOGL.US"], + "groups": [ + { + "group_name": "估值", + "indicators": [ + { "id": 10, "key": "filter_pe", "name": "市盈率", "unit": "x", "min": 0, "max": 30 } + ] + }, + { + "group_name": "盈利能力", + "indicators": [ + { "id": 25, "key": "filter_roe", "name": "淨資產收益率", "unit": "%", "min": 15, "max": null } + ] + } + ] + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | 成功 | [ScreenerStrategiesResponse](#ScreenerStrategiesResponse) | +| 400 | 請求錯誤 | None | + +## Schemas + +### ScreenerStrategiesResponse + + + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| screeners | object[] | false | 策略列表 | +| ∟ id | integer | false | 策略 ID | +| ∟ name | string | false | 策略名稱 | +| ∟ average_day_chg | string | false | 策略標的近期平均日漲跌幅 | +| ∟ stocks | string[] | false | 策略當前篩選出的股票代碼列表 | +| ∟ groups | object[] | false | 策略過濾條件分組 | +| ∟ ∟ group_name | string | false | 分組名稱 | +| ∟ ∟ indicators | object[] | false | 該分組下的指標條件 | +| ∟ ∟ ∟ id | integer | false | 指標 ID | +| ∟ ∟ ∟ key | string | false | 指標鍵值,可用於 `screener_search` | +| ∟ ∟ ∟ name | string | false | 指標名稱 | +| ∟ ∟ ∟ unit | string | false | 指標單位 | +| ∟ ∟ ∟ min | number | false | 策略設定的最小值 | +| ∟ ∟ ∟ max | number | false | 策略設定的最大值;`null` 表示無上限 | diff --git a/docs/zh-HK/docs/screener/screener_search.md b/docs/zh-HK/docs/screener/screener_search.md new file mode 100644 index 00000000..9bfc57d6 --- /dev/null +++ b/docs/zh-HK/docs/screener/screener_search.md @@ -0,0 +1,260 @@ +--- +slug: screener-search +title: 選股篩選 +sidebar_position: 4 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +按策略 ID 或自定義指標條件篩選股票,支持分頁。 + + +longbridge screener search --strategy-id 42 +longbridge screener search --market HK --filter filter_marketcap:100:1000 + + + + + +## Parameters + +> **SDK 方法參數。** + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| market | string | 是 | 市場:`US`、`HK`、`CN`、`SG` | +| strategy_id | integer | 否 | 策略 ID;與自定義 filter 二選一,或同時使用 | +| page | integer | 否 | 頁碼,從 1 開始,默認 1 | +| size | integer | 否 | 每頁條數,默認 20 | + +## Request Example + + + + +```python +from longbridge.openapi import ScreenerContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = ScreenerContext(config) + +# 按策略 ID 篩選 +resp = ctx.screener_search("US", strategy_id=42) +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncScreenerContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncScreenerContext.create(config) + + resp = await ctx.screener_search("US", strategy_id=42, page=1, size=20) + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, ScreenerContext, OAuth } = require('longbridge') + +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 = ScreenerContext.new(config) + const resp = await ctx.screenerSearch('US', { strategyId: 42, page: 1, size: 20 }) + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.screener.*; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + ScreenerContext ctx = ScreenerContext.create(config)) { + var resp = ctx.screenerSearch("US", 42L, 1, 20).get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, screener::ScreenerContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = ScreenerContext::new(config); + let resp = ctx.screener_search("US", Some(42), 1, 20).await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::screener; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + ScreenerContext ctx = ScreenerContext::create(config); + ctx.screener_search("US", 42, 1, 20, [](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/screener" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := screener.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.ScreenerSearch(context.Background(), "US", 42, 1, 20) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "total": 87, + "page": 1, + "size": 20, + "stocks": [ + { + "symbol": "AAPL.US", + "name": "蘋果公司", + "last_done": "213.49", + "chg": "+0.62%", + "market_cap": "3241500000000", + "pe": "32.15", + "pb": "50.21", + "ps": "8.04", + "roe": "147.25" + }, + { + "symbol": "MSFT.US", + "name": "微軟", + "last_done": "415.32", + "chg": "+1.05%", + "market_cap": "3085000000000", + "pe": "35.42", + "pb": "12.87", + "ps": "12.61", + "roe": "36.52" + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | 成功 | [ScreenerSearchResponse](#ScreenerSearchResponse) | +| 400 | 請求錯誤 | None | + +## Schemas + +### ScreenerSearchResponse + + + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| total | integer | false | 滿足條件的股票總數 | +| page | integer | false | 當前頁碼 | +| size | integer | false | 當前頁條數 | +| stocks | object[] | false | 篩選結果股票列表 | +| ∟ symbol | string | false | 證券代碼 | +| ∟ name | string | false | 證券名稱 | +| ∟ last_done | string | false | 最新成交價 | +| ∟ chg | string | false | 漲跌幅 | +| ∟ market_cap | string | false | 市值 | +| ∟ pe | string | false | 市盈率 | +| ∟ pb | string | false | 市淨率 | +| ∟ ps | string | false | 市銷率 | +| ∟ roe | string | false | 淨資產收益率(%) | diff --git a/docs/zh-HK/docs/screener/screener_strategy.md b/docs/zh-HK/docs/screener/screener_strategy.md new file mode 100644 index 00000000..da8489b8 --- /dev/null +++ b/docs/zh-HK/docs/screener/screener_strategy.md @@ -0,0 +1,264 @@ +--- +slug: screener-strategy +title: 選股策略詳情 +sidebar_position: 3 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +根據策略 ID 獲取單個選股策略的完整配置,包含所有指標分組和各指標的篩選範圍。 + + +longbridge screener strategies --id 42 + + + + + +## Parameters + +> **SDK 方法參數。** + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| id | integer | 是 | 策略 ID,來自 `screener_recommend_strategies` 或 `screener_user_strategies` | + +## Request Example + + + + +```python +from longbridge.openapi import ScreenerContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = ScreenerContext(config) + +resp = ctx.screener_strategy(42) +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncScreenerContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncScreenerContext.create(config) + + resp = await ctx.screener_strategy(42) + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, ScreenerContext, OAuth } = require('longbridge') + +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 = ScreenerContext.new(config) + const resp = await ctx.screenerStrategy(42) + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.screener.*; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + ScreenerContext ctx = ScreenerContext.create(config)) { + var resp = ctx.getScreenerStrategy(42L).get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, screener::ScreenerContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = ScreenerContext::new(config); + let resp = ctx.screener_strategy(42).await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::screener; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + ScreenerContext ctx = ScreenerContext::create(config); + ctx.screener_strategy(42, [](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/screener" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := screener.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.ScreenerStrategy(context.Background(), 42) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "id": 42, + "name": "我的成長股策略", + "groups": [ + { + "group_name": "估值", + "indicators": [ + { + "id": 10, + "key": "filter_pe", + "name": "市盈率", + "unit": "x", + "min": 5, + "max": 30 + }, + { + "id": 11, + "key": "filter_pb", + "name": "市淨率", + "unit": "x", + "min": 1, + "max": 10 + } + ] + }, + { + "group_name": "成長性", + "indicators": [ + { + "id": 30, + "key": "filter_revenue_growth", + "name": "營收增速", + "unit": "%", + "min": 20, + "max": null + } + ] + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | 成功 | [ScreenerStrategyDetail](#ScreenerStrategyDetail) | +| 400 | 請求錯誤 | None | + +## Schemas + +### ScreenerStrategyDetail + + + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| id | integer | false | 策略 ID | +| name | string | false | 策略名稱 | +| groups | object[] | false | 指標分組列表 | +| ∟ group_name | string | false | 分組名稱 | +| ∟ indicators | object[] | false | 該分組下的指標條件 | +| ∟ ∟ id | integer | false | 指標 ID | +| ∟ ∟ key | string | false | 指標鍵值 | +| ∟ ∟ name | string | false | 指標顯示名稱 | +| ∟ ∟ unit | string | false | 指標單位(如 `x`、`%`、`億` 等) | +| ∟ ∟ min | number | false | 最小值;`null` 表示無下限 | +| ∟ ∟ max | number | false | 最大值;`null` 表示無上限 | diff --git a/docs/zh-HK/docs/screener/screener_user_strategies.md b/docs/zh-HK/docs/screener/screener_user_strategies.md new file mode 100644 index 00000000..aa635bd6 --- /dev/null +++ b/docs/zh-HK/docs/screener/screener_user_strategies.md @@ -0,0 +1,228 @@ +--- +slug: screener-user-strategies +title: 我的選股策略 +sidebar_position: 2 +language_tabs: false +toc_footers: [] +includes: [] +search: true +highlight_theme: '' +headingLevel: 2 +--- + +獲取當前登錄用戶創建的自定義選股策略列表。 + + +longbridge screener strategies --mine + + + + + +## Parameters + +> **SDK 方法參數。** + +此方法無參數(需登錄)。 + +## Request Example + + + + +```python +from longbridge.openapi import ScreenerContext, Config, OAuthBuilder + +oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) +config = Config.from_oauth(oauth) +ctx = ScreenerContext(config) + +resp = ctx.screener_user_strategies() +print(resp) +``` + + + + +```python +import asyncio +from longbridge.openapi import AsyncScreenerContext, Config, OAuthBuilder + +async def main() -> None: + oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) + config = Config.from_oauth(oauth) + ctx = AsyncScreenerContext.create(config) + + resp = await ctx.screener_user_strategies() + print(resp) + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + +```javascript +const { Config, ScreenerContext, OAuth } = require('longbridge') + +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 = ScreenerContext.new(config) + const resp = await ctx.screenerUserStrategies() + console.log(resp) +} +main().catch(console.error) +``` + + + + +```java +import com.longbridge.*; +import com.longbridge.screener.*; + +class Main { + public static void main(String[] args) throws Exception { + try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); + Config config = Config.fromOAuth(oauth); + ScreenerContext ctx = ScreenerContext.create(config)) { + var resp = ctx.getScreenerUserStrategies().get(); + System.out.println(resp); + } + } +} +``` + + + + +```rust +use std::sync::Arc; +use longbridge::{oauth::OAuthBuilder, screener::ScreenerContext, Config}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; + let config = Arc::new(Config::from_oauth(oauth)); + let ctx = ScreenerContext::new(config); + let resp = ctx.screener_user_strategies().await?; + println!("{:?}", resp); + Ok(()) +} +``` + + + + +```cpp +#include +#include + +using namespace longbridge; +using namespace longbridge::screener; + +int main() { + OAuthBuilder("your-client-id").build( + [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, + [](auto res) { + if (!res) return; + Config config = Config::from_oauth(*res); + ScreenerContext ctx = ScreenerContext::create(config); + ctx.screener_user_strategies([](auto resp) { + if (resp) std::cout << "OK" << std::endl; + }); + }); + std::cin.get(); +} +``` + + + + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/longbridge/openapi-go/config" + "github.com/longbridge/openapi-go/oauth" + "github.com/longbridge/openapi-go/screener" +) + +func main() { + o := oauth.New("your-client-id"). + OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) + if err := o.Build(context.Background()); err != nil { + log.Fatal(err) + } + conf, err := config.New(config.WithOAuthClient(o)) + if err != nil { + log.Fatal(err) + } + c, err := screener.NewFromCfg(conf) + if err != nil { + log.Fatal(err) + } + defer c.Close() + resp, err := c.ScreenerUserStrategies(context.Background()) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%+v\n", resp) +} +``` + + + + +## Response + + +### Response Example + +```json +{ + "code": 0, + "message": "success", + "data": { + "screeners": [ + { + "id": 42, + "name": "我的成長股策略", + "average_day_chg": "+1.24%", + "stocks": ["NVDA.US", "AMD.US"], + "groups": [ + { + "group_name": "成長性", + "indicators": [ + { "id": 30, "key": "filter_revenue_growth", "name": "營收增速", "unit": "%", "min": 20, "max": null } + ] + } + ] + } + ] + } +} +``` + +### Response Status + +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | 成功 | [ScreenerStrategiesResponse](#ScreenerStrategiesResponse) | +| 400 | 請求錯誤 | None | + +## Schemas + +### ScreenerStrategiesResponse + + + +響應結構與 [screener_recommend_strategies](./screener_recommend_strategies) 相同,請參閱該文檔中的 Schema 定義。 From fe50eb62f0ff8b971f32a3052b60291276f632ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Wed, 20 May 2026 15:07:54 +0800 Subject: [PATCH 2/5] docs: add screener _category_.json for en and zh-HK --- docs/en/docs/screener/_category_.json | 7 +++++++ docs/zh-HK/docs/screener/_category_.json | 7 +++++++ 2 files changed, 14 insertions(+) create mode 100644 docs/en/docs/screener/_category_.json create mode 100644 docs/zh-HK/docs/screener/_category_.json diff --git a/docs/en/docs/screener/_category_.json b/docs/en/docs/screener/_category_.json new file mode 100644 index 00000000..bfe81409 --- /dev/null +++ b/docs/en/docs/screener/_category_.json @@ -0,0 +1,7 @@ +{ + "label": "Screener", + "collapsible": true, + "collapsed": true, + "link": null, + "position": 4.5 +} diff --git a/docs/zh-HK/docs/screener/_category_.json b/docs/zh-HK/docs/screener/_category_.json new file mode 100644 index 00000000..fa271fd3 --- /dev/null +++ b/docs/zh-HK/docs/screener/_category_.json @@ -0,0 +1,7 @@ +{ + "label": "選股", + "collapsible": true, + "collapsed": true, + "link": null, + "position": 4.5 +} From 240facf6741c8ea7472bf1434a995f9daf5b1a1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Wed, 20 May 2026 15:56:09 +0800 Subject: [PATCH 3/5] docs: merge hk_short_positions into short_positions (US+HK unified) Co-Authored-By: Claude Sonnet 4.6 (1M context) --- .../quote/analytics/hk_short_positions.md | 236 ------------------ .../docs/quote/analytics/short_positions.md | 118 ++++++--- .../quote/analytics/hk_short_positions.md | 236 ------------------ .../docs/quote/analytics/short_positions.md | 113 ++++++--- .../quote/analytics/hk_short_positions.md | 236 ------------------ .../docs/quote/analytics/short_positions.md | 113 ++++++--- 6 files changed, 243 insertions(+), 809 deletions(-) delete mode 100644 docs/en/docs/quote/analytics/hk_short_positions.md delete mode 100644 docs/zh-CN/docs/quote/analytics/hk_short_positions.md delete mode 100644 docs/zh-HK/docs/quote/analytics/hk_short_positions.md diff --git a/docs/en/docs/quote/analytics/hk_short_positions.md b/docs/en/docs/quote/analytics/hk_short_positions.md deleted file mode 100644 index 172e070b..00000000 --- a/docs/en/docs/quote/analytics/hk_short_positions.md +++ /dev/null @@ -1,236 +0,0 @@ ---- -slug: /quote/pull/hk-short-positions -title: HK Short Positions -sidebar_position: 26 -language_tabs: false -toc_footers: [] -includes: [] -search: true -highlight_theme: '' -headingLevel: 2 ---- - -Get HK short position data including short amount and short ratio. Data is provided by the Hong Kong Exchange (HKEX) and updated each trading day. Only HK-listed stocks are supported. - - -longbridge short-positions 700.HK -longbridge short-positions 9988.HK --count 50 - - - - - -## Parameters - -> **SDK method parameters.** - -| Name | Type | Required | Description | -| ------ | ------- | -------- | ---------------------------------------------- | -| symbol | string | YES | HK security symbol, e.g. `700.HK`, `9988.HK` | -| count | integer | NO | Number of records to return (1–100, default 20) | - -## Request Example - - - - -```python -from longbridge.openapi import QuoteContext, Config, OAuthBuilder - -oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) -config = Config.from_oauth(oauth) -ctx = QuoteContext(config) - -resp = ctx.hk_short_positions("700.HK") -print(resp) -``` - - - - -```python -import asyncio -from longbridge.openapi import AsyncQuoteContext, Config, OAuthBuilder - -async def main() -> None: - oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) - config = Config.from_oauth(oauth) - ctx = AsyncQuoteContext.create(config) - - resp = await ctx.hk_short_positions("700.HK") - print(resp) - -if __name__ == "__main__": - asyncio.run(main()) -``` - - - - -```javascript -const { Config, QuoteContext, OAuth } = require('longbridge') - -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.hkShortPositions('700.HK') - console.log(resp) -} -main().catch(console.error) -``` - - - - -```java -import com.longbridge.*; -import com.longbridge.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 to authorize: " + url)).get(); - Config config = Config.fromOAuth(oauth); - QuoteContext ctx = QuoteContext.create(config)) { - var resp = ctx.getHkShortPositions("700.HK").get(); - System.out.println(resp); - } - } -} -``` - - - - -```rust -use std::sync::Arc; -use longbridge::{oauth::OAuthBuilder, quote::QuoteContext, Config}; - -#[tokio::main] -async fn main() -> Result<(), Box> { - let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; - let config = Arc::new(Config::from_oauth(oauth)); - let (ctx, _) = QuoteContext::new(config); - let resp = ctx.hk_short_positions("700.HK").await?; - println!("{:?}", resp); - Ok(()) -} -``` - - - - -```cpp -#include -#include - -using namespace longbridge; -using namespace longbridge::quote; - -int main() { - OAuthBuilder("your-client-id").build( - [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, - [](auto res) { - if (!res) return; - Config config = Config::from_oauth(*res); - QuoteContext ctx = QuoteContext::create(config); - ctx.hk_short_positions("700.HK", [](auto resp) { - if (resp) std::cout << resp->size() << std::endl; - }); - }); - std::cin.get(); -} -``` - - - - -```go -package main - -import ( - "context" - "fmt" - "log" - - "github.com/longbridge/openapi-go/config" - "github.com/longbridge/openapi-go/oauth" - "github.com/longbridge/openapi-go/quote" -) - -func main() { - o := oauth.New("your-client-id"). - OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) - if err := o.Build(context.Background()); err != nil { - log.Fatal(err) - } - conf, err := config.New(config.WithOAuthClient(o)) - if err != nil { - log.Fatal(err) - } - qctx, err := quote.NewFromCfg(conf) - if err != nil { - log.Fatal(err) - } - defer qctx.Close() - resp, err := qctx.HkShortPositions(context.Background(), "700.HK") - if err != nil { - log.Fatal(err) - } - fmt.Printf("%+v\n", resp) -} -``` - - - - -## Response - - -### Response Example - -```json -{ - "code": 0, - "message": "success", - "data": { - "list": [ - { - "date": "2026-05-16", - "short_amount": "2148600000", - "short_ratio": "0.0182", - "close": "418.20" - }, - { - "date": "2026-05-15", - "short_amount": "1935200000", - "short_ratio": "0.0163", - "close": "412.80" - } - ] - } -} -``` - -### Response Status - -| Status | Description | Schema | -| ------ | ----------- | ------ | -| 200 | Success | [hk_short_positions_rsp](#hk_short_positions_rsp) | -| 400 | Bad request | None | - -## Schemas - -### hk_short_positions_rsp - - - -| Name | Type | Required | Description | -| ------------- | -------- | -------- | ------------------------------------------------ | -| list | object[] | true | HK short position records | -| ∟ date | string | true | Trading date in `YYYY-MM-DD` format | -| ∟ short_amount | string | true | Short amount (HKD) | -| ∟ short_ratio | string | true | Short ratio (short amount ÷ total turnover) | -| ∟ close | string | true | Closing price on that day | diff --git a/docs/en/docs/quote/analytics/short_positions.md b/docs/en/docs/quote/analytics/short_positions.md index 90986091..20455a18 100644 --- a/docs/en/docs/quote/analytics/short_positions.md +++ b/docs/en/docs/quote/analytics/short_positions.md @@ -1,6 +1,6 @@ --- slug: /quote/pull/short-positions -title: Short Positions +title: Short Positions (US & HK) sidebar_position: 25 language_tabs: false toc_footers: [] @@ -10,12 +10,13 @@ highlight_theme: '' headingLevel: 2 --- -# Short Positions +# Short Positions (US & HK) -Get US stock short selling data — short interest, short ratio, days to cover, and average daily volume. Records are updated bi-monthly by FINRA. Only US-listed stocks and ETFs are supported. +Get short interest data for US or HK securities. Market is auto-detected from the symbol suffix: `.HK` → HKEX short position data (daily); others → US FINRA short interest data (bi-monthly). longbridge short-positions TSLA.US +longbridge short-positions 700.HK longbridge short-positions AAPL.US --count 50 @@ -25,10 +26,10 @@ longbridge short-positions AAPL.US --count 50 > **SDK method parameters.** -| Name | Type | Required | Description | -| ------ | ------- | -------- | ------------------------------------------------ | -| symbol | string | YES | US security symbol, e.g. `TSLA.US`, `AAPL.US` | -| count | integer | NO | Number of records to return (1–100, default: 20) | +| Name | Type | Required | Description | +| ------ | ------- | -------- | ----------------------------------------------------------------- | +| symbol | string | YES | Security symbol, e.g. `TSLA.US` or `700.HK` | +| count | integer | NO | Number of records to return (1–100, default: 20) | ## Request Example @@ -37,6 +38,7 @@ longbridge short-positions AAPL.US --count 50 longbridge short-positions TSLA.US +longbridge short-positions 700.HK longbridge short-positions AAPL.US --count 50 @@ -50,7 +52,12 @@ oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) config = Config.from_oauth(oauth) ctx = QuoteContext(config) -resp = ctx.short_positions("TSLA.US") +# US example +resp = ctx.short_positions("TSLA.US", 20) +print(resp) + +# HK example +resp = ctx.short_positions("700.HK", 20) print(resp) ``` @@ -66,7 +73,12 @@ async def main() -> None: config = Config.from_oauth(oauth) ctx = AsyncQuoteContext.create(config) - resp = await ctx.short_positions("TSLA.US") + # US example + resp = await ctx.short_positions("TSLA.US", 20) + print(resp) + + # HK example + resp = await ctx.short_positions("700.HK", 20) print(resp) if __name__ == "__main__": @@ -85,7 +97,7 @@ async function main() { }) const config = Config.fromOAuth(oauth) const ctx = QuoteContext.new(config) - const resp = await ctx.shortPositions('TSLA.US') + const resp = await ctx.shortPositions('TSLA.US', 20) console.log(resp) } main().catch(console.error) @@ -103,7 +115,7 @@ class Main { try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); Config config = Config.fromOAuth(oauth); QuoteContext ctx = QuoteContext.create(config)) { - var resp = ctx.getShortPositions("TSLA.US").get(); + var resp = ctx.getShortPositions("TSLA.US", 20).get(); System.out.println(resp); } } @@ -122,7 +134,7 @@ async fn main() -> Result<(), Box> { let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; let config = Arc::new(Config::from_oauth(oauth)); let (ctx, _) = QuoteContext::new(config); - let resp = ctx.short_positions("TSLA.US").await?; + let resp = ctx.short_positions("TSLA.US", 20).await?; println!("{:?}", resp); Ok(()) } @@ -145,7 +157,7 @@ int main() { if (!res) return; Config config = Config::from_oauth(*res); QuoteContext ctx = QuoteContext::create(config); - ctx.short_positions("TSLA.US", [](auto resp) { + ctx.short_positions("TSLA.US", 20, [](auto resp) { if (resp) std::cout << resp->size() << std::endl; }); }); @@ -184,7 +196,7 @@ func main() { log.Fatal(err) } defer qctx.Close() - resp, err := qctx.ShortPositions(context.Background(), "TSLA.US") + resp, err := qctx.ShortPositions(context.Background(), "TSLA.US", 20) if err != nil { log.Fatal(err) } @@ -199,6 +211,9 @@ func main() { ### Response Example + + + ```json { "code": 0, @@ -206,11 +221,11 @@ func main() { "data": { "list": [ { - "date": "2026-03-31", + "timestamp": 1743379200, + "current_shares_short": "65598603", "rate": "0.0175", - "short_shares": "65598603", - "avg_daily_vol": "62121644", - "days_cover": "1.06", + "avg_daily_share_volume": "62121644", + "days_to_cover": "1.06", "close": "371.750" } ] @@ -218,25 +233,58 @@ func main() { } ``` -### Response Status + + + +```json +{ + "code": 0, + "message": "success", + "data": [ + { + "timestamp": 1747353600, + "amount": "2148600000", + "balance": "6200000", + "close": "418.20", + "rate": "0.0182", + "total_amount": "118120000000" + } + ] +} +``` -| Status | Description | Schema | -| ------ | ----------- | ------------------------------------------- | -| 200 | Success | [short_positions_rsp](#short_positions_rsp) | -| 400 | Bad request | None | + + -## Schemas +### Response Status -### short_positions_rsp +| Status | Description | Schema | +| ------ | ----------- | ------ | +| 200 | Success | See schemas below | +| 400 | Bad request | None | - +## Schemas -| Name | Type | Required | Description | -| --------------- | -------- | -------- | -------------------------------------------------- | -| list | object[] | true | Short position records | -| ∟ date | string | true | Settlement date in `YYYY-MM-DD` format | -| ∟ rate | string | true | Short ratio (short shares ÷ float) | -| ∟ short_shares | string | true | Number of short shares | -| ∟ avg_daily_vol | string | true | Average daily volume | -| ∟ days_cover | string | true | Days-to-cover ratio (short shares ÷ avg daily vol) | -| ∟ close | string | true | Closing price on that date | +### US Response (`.US` symbols) + +| Name | Type | Required | Description | +| ----------------------- | -------- | -------- | -------------------------------------------------- | +| list | object[] | false | Short position records | +| ∟ timestamp | integer | false | Settlement date (Unix timestamp) | +| ∟ current_shares_short | string | false | Number of short shares | +| ∟ rate | string | false | Short ratio | +| ∟ avg_daily_share_volume | string | false | Average daily volume | +| ∟ days_to_cover | string | false | Days-to-cover ratio | +| ∟ close | string | false | Closing price | + +### HK Response (`.HK` symbols) + +| Name | Type | Required | Description | +| ------------- | -------- | -------- | ------------------------------------------------ | +| data | object[] | false | Short position records | +| ∟ timestamp | integer | false | Date (Unix timestamp) | +| ∟ amount | string | false | Short selling amount (HKD) | +| ∟ balance | string | false | Net short position balance | +| ∟ close | string | false | Closing price | +| ∟ rate | string | false | Short ratio (short amount ÷ total turnover) | +| ∟ total_amount | string | false | Total turnover | diff --git a/docs/zh-CN/docs/quote/analytics/hk_short_positions.md b/docs/zh-CN/docs/quote/analytics/hk_short_positions.md deleted file mode 100644 index e04e024a..00000000 --- a/docs/zh-CN/docs/quote/analytics/hk_short_positions.md +++ /dev/null @@ -1,236 +0,0 @@ ---- -slug: /quote/pull/hk-short-positions -title: 港股沽空数据 -sidebar_position: 26 -language_tabs: false -toc_footers: [] -includes: [] -search: true -highlight_theme: '' -headingLevel: 2 ---- - -获取港股沽空持仓数据,包括沽空金额、沽空比率等。数据由香港交易所(HKEX)提供,每个交易日更新。仅支持港股上市股票。 - - -longbridge short-positions 700.HK -longbridge short-positions 9988.HK --count 50 - - - - - -## Parameters - -> **SDK 方法参数。** - -| Name | Type | Required | Description | -| ------ | ------- | -------- | ---------------------------------------------- | -| symbol | string | YES | 港股证券代码,例如 `700.HK`、`9988.HK` | -| count | integer | NO | 返回记录数(1–100,默认 20) | - -## Request Example - - - - -```python -from longbridge.openapi import QuoteContext, Config, OAuthBuilder - -oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) -config = Config.from_oauth(oauth) -ctx = QuoteContext(config) - -resp = ctx.hk_short_positions("700.HK") -print(resp) -``` - - - - -```python -import asyncio -from longbridge.openapi import AsyncQuoteContext, Config, OAuthBuilder - -async def main() -> None: - oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) - config = Config.from_oauth(oauth) - ctx = AsyncQuoteContext.create(config) - - resp = await ctx.hk_short_positions("700.HK") - print(resp) - -if __name__ == "__main__": - asyncio.run(main()) -``` - - - - -```javascript -const { Config, QuoteContext, OAuth } = require('longbridge') - -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.hkShortPositions('700.HK') - console.log(resp) -} -main().catch(console.error) -``` - - - - -```java -import com.longbridge.*; -import com.longbridge.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 to authorize: " + url)).get(); - Config config = Config.fromOAuth(oauth); - QuoteContext ctx = QuoteContext.create(config)) { - var resp = ctx.getHkShortPositions("700.HK").get(); - System.out.println(resp); - } - } -} -``` - - - - -```rust -use std::sync::Arc; -use longbridge::{oauth::OAuthBuilder, quote::QuoteContext, Config}; - -#[tokio::main] -async fn main() -> Result<(), Box> { - let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; - let config = Arc::new(Config::from_oauth(oauth)); - let (ctx, _) = QuoteContext::new(config); - let resp = ctx.hk_short_positions("700.HK").await?; - println!("{:?}", resp); - Ok(()) -} -``` - - - - -```cpp -#include -#include - -using namespace longbridge; -using namespace longbridge::quote; - -int main() { - OAuthBuilder("your-client-id").build( - [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, - [](auto res) { - if (!res) return; - Config config = Config::from_oauth(*res); - QuoteContext ctx = QuoteContext::create(config); - ctx.hk_short_positions("700.HK", [](auto resp) { - if (resp) std::cout << resp->size() << std::endl; - }); - }); - std::cin.get(); -} -``` - - - - -```go -package main - -import ( - "context" - "fmt" - "log" - - "github.com/longbridge/openapi-go/config" - "github.com/longbridge/openapi-go/oauth" - "github.com/longbridge/openapi-go/quote" -) - -func main() { - o := oauth.New("your-client-id"). - OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) - if err := o.Build(context.Background()); err != nil { - log.Fatal(err) - } - conf, err := config.New(config.WithOAuthClient(o)) - if err != nil { - log.Fatal(err) - } - qctx, err := quote.NewFromCfg(conf) - if err != nil { - log.Fatal(err) - } - defer qctx.Close() - resp, err := qctx.HkShortPositions(context.Background(), "700.HK") - if err != nil { - log.Fatal(err) - } - fmt.Printf("%+v\n", resp) -} -``` - - - - -## Response - - -### Response Example - -```json -{ - "code": 0, - "message": "success", - "data": { - "list": [ - { - "date": "2026-05-16", - "short_amount": "2148600000", - "short_ratio": "0.0182", - "close": "418.20" - }, - { - "date": "2026-05-15", - "short_amount": "1935200000", - "short_ratio": "0.0163", - "close": "412.80" - } - ] - } -} -``` - -### Response Status - -| Status | Description | Schema | -| ------ | ----------- | ------ | -| 200 | 成功 | [hk_short_positions_rsp](#hk_short_positions_rsp) | -| 400 | 请求错误 | None | - -## Schemas - -### hk_short_positions_rsp - - - -| Name | Type | Required | Description | -| ------------- | -------- | -------- | ---------------------------------------- | -| list | object[] | true | 港股沽空持仓记录 | -| ∟ date | string | true | 交易日期,格式 `YYYY-MM-DD` | -| ∟ short_amount | string | true | 沽空金额(港元) | -| ∟ short_ratio | string | true | 沽空比率(沽空金额 ÷ 总成交金额) | -| ∟ close | string | true | 当日收盘价 | diff --git a/docs/zh-CN/docs/quote/analytics/short_positions.md b/docs/zh-CN/docs/quote/analytics/short_positions.md index a3ed3ccf..f8bdb94f 100644 --- a/docs/zh-CN/docs/quote/analytics/short_positions.md +++ b/docs/zh-CN/docs/quote/analytics/short_positions.md @@ -1,6 +1,6 @@ --- slug: /quote/pull/short-positions -title: 沽空数据 +title: 沽空数据(美股 / 港股) sidebar_position: 25 language_tabs: false toc_footers: [] @@ -10,10 +10,11 @@ highlight_theme: '' headingLevel: 2 --- -Get US stock short selling data — short interest, short ratio, days to cover, and average daily volume. Records are updated bi-monthly by FINRA. Only US-listed stocks and ETFs are supported. +获取美股或港股沽空持仓数据。市场根据代码后缀自动识别:`.HK` → 港交所沽空数据(每日更新);其他 → 美股 FINRA 沽空数据(双月更新)。 longbridge short-positions TSLA.US +longbridge short-positions 700.HK longbridge short-positions AAPL.US --count 50 @@ -24,10 +25,10 @@ longbridge short-positions AAPL.US --count 50 > **SDK 方法参数。** -| Name | Type | Required | Description | -| ------ | ------ | -------- | --------------------------------------------------- | -| symbol | string | YES | US security symbol, e.g. `TSLA.US`, `AAPL.US` | -| count | integer | NO | Number of records to return (1–100, default: 20) | +| Name | Type | Required | Description | +| ------ | ------- | -------- | ---------------------------------------------------------------- | +| symbol | string | YES | 证券代码,例如 `TSLA.US` 或 `700.HK` | +| count | integer | NO | 返回记录数(1–100,默认 20) | ## Request Example @@ -36,6 +37,7 @@ longbridge short-positions AAPL.US --count 50 longbridge short-positions TSLA.US +longbridge short-positions 700.HK longbridge short-positions AAPL.US --count 50 @@ -49,7 +51,12 @@ oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) config = Config.from_oauth(oauth) ctx = QuoteContext(config) -resp = ctx.short_positions("TSLA.US") +# 美股示例 +resp = ctx.short_positions("TSLA.US", 20) +print(resp) + +# 港股示例 +resp = ctx.short_positions("700.HK", 20) print(resp) ``` @@ -65,7 +72,12 @@ async def main() -> None: config = Config.from_oauth(oauth) ctx = AsyncQuoteContext.create(config) - resp = await ctx.short_positions("TSLA.US") + # 美股示例 + resp = await ctx.short_positions("TSLA.US", 20) + print(resp) + + # 港股示例 + resp = await ctx.short_positions("700.HK", 20) print(resp) if __name__ == "__main__": @@ -84,7 +96,7 @@ async function main() { }) const config = Config.fromOAuth(oauth) const ctx = QuoteContext.new(config) - const resp = await ctx.shortPositions('TSLA.US') + const resp = await ctx.shortPositions('TSLA.US', 20) console.log(resp) } main().catch(console.error) @@ -102,7 +114,7 @@ class Main { try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); Config config = Config.fromOAuth(oauth); QuoteContext ctx = QuoteContext.create(config)) { - var resp = ctx.getShortPositions("TSLA.US").get(); + var resp = ctx.getShortPositions("TSLA.US", 20).get(); System.out.println(resp); } } @@ -121,7 +133,7 @@ async fn main() -> Result<(), Box> { let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; let config = Arc::new(Config::from_oauth(oauth)); let (ctx, _) = QuoteContext::new(config); - let resp = ctx.short_positions("TSLA.US").await?; + let resp = ctx.short_positions("TSLA.US", 20).await?; println!("{:?}", resp); Ok(()) } @@ -144,7 +156,7 @@ int main() { if (!res) return; Config config = Config::from_oauth(*res); QuoteContext ctx = QuoteContext::create(config); - ctx.short_positions("TSLA.US", [](auto resp) { + ctx.short_positions("TSLA.US", 20, [](auto resp) { if (resp) std::cout << resp->size() << std::endl; }); }); @@ -183,7 +195,7 @@ func main() { log.Fatal(err) } defer qctx.Close() - resp, err := qctx.ShortPositions(context.Background(), "TSLA.US") + resp, err := qctx.ShortPositions(context.Background(), "TSLA.US", 20) if err != nil { log.Fatal(err) } @@ -196,9 +208,11 @@ func main() { ## Response - ### Response Example + + + ```json { "code": 0, @@ -206,11 +220,11 @@ func main() { "data": { "list": [ { - "date": "2026-03-31", + "timestamp": 1743379200, + "current_shares_short": "65598603", "rate": "0.0175", - "short_shares": "65598603", - "avg_daily_vol": "62121644", - "days_cover": "1.06", + "avg_daily_share_volume": "62121644", + "days_to_cover": "1.06", "close": "371.750" } ] @@ -218,25 +232,58 @@ func main() { } ``` + + + +```json +{ + "code": 0, + "message": "success", + "data": [ + { + "timestamp": 1747353600, + "amount": "2148600000", + "balance": "6200000", + "close": "418.20", + "rate": "0.0182", + "total_amount": "118120000000" + } + ] +} +``` + + + + ### Response Status | Status | Description | Schema | | ------ | ----------- | ------ | -| 200 | Success | [short_positions_rsp](#short_positions_rsp) | -| 400 | Bad request | None | +| 200 | 成功 | 见下方 Schema | +| 400 | 请求错误 | None | ## Schemas -### short_positions_rsp - - - -| Name | Type | Required | Description | -| ------------- | -------- | -------- | ------------------------------------------------ | -| list | object[] | true | Short position records | -| ∟ date | string | true | Settlement date in `YYYY-MM-DD` format | -| ∟ rate | string | true | Short ratio (short shares ÷ float) | -| ∟ short_shares | string | true | Number of short shares | -| ∟ avg_daily_vol | string | true | Average daily volume | -| ∟ days_cover | string | true | Days-to-cover ratio (short shares ÷ avg daily vol) | -| ∟ close | string | true | Closing price on that date | +### 美股响应(`.US` 代码) + +| Name | Type | Required | Description | +| ----------------------- | -------- | -------- | ---------------------------------- | +| list | object[] | false | 沽空持仓记录 | +| ∟ timestamp | integer | false | 结算日期(Unix 时间戳) | +| ∟ current_shares_short | string | false | 沽空股数 | +| ∟ rate | string | false | 沽空比率 | +| ∟ avg_daily_share_volume | string | false | 日均成交量 | +| ∟ days_to_cover | string | false | 回补天数(沽空股数 ÷ 日均成交量) | +| ∟ close | string | false | 收盘价 | + +### 港股响应(`.HK` 代码) + +| Name | Type | Required | Description | +| ------------- | -------- | -------- | ---------------------------------------- | +| data | object[] | false | 沽空持仓记录 | +| ∟ timestamp | integer | false | 日期(Unix 时间戳) | +| ∟ amount | string | false | 沽空金额(港元) | +| ∟ balance | string | false | 净沽空持仓余额 | +| ∟ close | string | false | 收盘价 | +| ∟ rate | string | false | 沽空比率(沽空金额 ÷ 总成交金额) | +| ∟ total_amount | string | false | 总成交金额 | diff --git a/docs/zh-HK/docs/quote/analytics/hk_short_positions.md b/docs/zh-HK/docs/quote/analytics/hk_short_positions.md deleted file mode 100644 index 32820bd0..00000000 --- a/docs/zh-HK/docs/quote/analytics/hk_short_positions.md +++ /dev/null @@ -1,236 +0,0 @@ ---- -slug: /quote/pull/hk-short-positions -title: 港股沽空數據 -sidebar_position: 26 -language_tabs: false -toc_footers: [] -includes: [] -search: true -highlight_theme: '' -headingLevel: 2 ---- - -獲取港股沽空持倉數據,包括沽空金額、沽空比率等。數據由香港交易所(HKEX)提供,每個交易日更新。僅支持港股上市股票。 - - -longbridge short-positions 700.HK -longbridge short-positions 9988.HK --count 50 - - - - - -## Parameters - -> **SDK 方法參數。** - -| Name | Type | Required | Description | -| ------ | ------- | -------- | ---------------------------------------------- | -| symbol | string | YES | 港股證券代碼,例如 `700.HK`、`9988.HK` | -| count | integer | NO | 返回記錄數(1–100,默認 20) | - -## Request Example - - - - -```python -from longbridge.openapi import QuoteContext, Config, OAuthBuilder - -oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) -config = Config.from_oauth(oauth) -ctx = QuoteContext(config) - -resp = ctx.hk_short_positions("700.HK") -print(resp) -``` - - - - -```python -import asyncio -from longbridge.openapi import AsyncQuoteContext, Config, OAuthBuilder - -async def main() -> None: - oauth = await OAuthBuilder("your-client-id").build_async(lambda url: print("Visit:", url)) - config = Config.from_oauth(oauth) - ctx = AsyncQuoteContext.create(config) - - resp = await ctx.hk_short_positions("700.HK") - print(resp) - -if __name__ == "__main__": - asyncio.run(main()) -``` - - - - -```javascript -const { Config, QuoteContext, OAuth } = require('longbridge') - -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.hkShortPositions('700.HK') - console.log(resp) -} -main().catch(console.error) -``` - - - - -```java -import com.longbridge.*; -import com.longbridge.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 to authorize: " + url)).get(); - Config config = Config.fromOAuth(oauth); - QuoteContext ctx = QuoteContext.create(config)) { - var resp = ctx.getHkShortPositions("700.HK").get(); - System.out.println(resp); - } - } -} -``` - - - - -```rust -use std::sync::Arc; -use longbridge::{oauth::OAuthBuilder, quote::QuoteContext, Config}; - -#[tokio::main] -async fn main() -> Result<(), Box> { - let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; - let config = Arc::new(Config::from_oauth(oauth)); - let (ctx, _) = QuoteContext::new(config); - let resp = ctx.hk_short_positions("700.HK").await?; - println!("{:?}", resp); - Ok(()) -} -``` - - - - -```cpp -#include -#include - -using namespace longbridge; -using namespace longbridge::quote; - -int main() { - OAuthBuilder("your-client-id").build( - [](const std::string& url) { std::cout << "Open: " << url << std::endl; }, - [](auto res) { - if (!res) return; - Config config = Config::from_oauth(*res); - QuoteContext ctx = QuoteContext::create(config); - ctx.hk_short_positions("700.HK", [](auto resp) { - if (resp) std::cout << resp->size() << std::endl; - }); - }); - std::cin.get(); -} -``` - - - - -```go -package main - -import ( - "context" - "fmt" - "log" - - "github.com/longbridge/openapi-go/config" - "github.com/longbridge/openapi-go/oauth" - "github.com/longbridge/openapi-go/quote" -) - -func main() { - o := oauth.New("your-client-id"). - OnOpenURL(func(url string) { fmt.Println("Open this URL to authorize:", url) }) - if err := o.Build(context.Background()); err != nil { - log.Fatal(err) - } - conf, err := config.New(config.WithOAuthClient(o)) - if err != nil { - log.Fatal(err) - } - qctx, err := quote.NewFromCfg(conf) - if err != nil { - log.Fatal(err) - } - defer qctx.Close() - resp, err := qctx.HkShortPositions(context.Background(), "700.HK") - if err != nil { - log.Fatal(err) - } - fmt.Printf("%+v\n", resp) -} -``` - - - - -## Response - - -### Response Example - -```json -{ - "code": 0, - "message": "success", - "data": { - "list": [ - { - "date": "2026-05-16", - "short_amount": "2148600000", - "short_ratio": "0.0182", - "close": "418.20" - }, - { - "date": "2026-05-15", - "short_amount": "1935200000", - "short_ratio": "0.0163", - "close": "412.80" - } - ] - } -} -``` - -### Response Status - -| Status | Description | Schema | -| ------ | ----------- | ------ | -| 200 | 成功 | [hk_short_positions_rsp](#hk_short_positions_rsp) | -| 400 | 請求錯誤 | None | - -## Schemas - -### hk_short_positions_rsp - - - -| Name | Type | Required | Description | -| ------------- | -------- | -------- | ---------------------------------------- | -| list | object[] | true | 港股沽空持倉記錄 | -| ∟ date | string | true | 交易日期,格式 `YYYY-MM-DD` | -| ∟ short_amount | string | true | 沽空金額(港元) | -| ∟ short_ratio | string | true | 沽空比率(沽空金額 ÷ 總成交金額) | -| ∟ close | string | true | 當日收盤價 | diff --git a/docs/zh-HK/docs/quote/analytics/short_positions.md b/docs/zh-HK/docs/quote/analytics/short_positions.md index 95ca49cd..ae9b314e 100644 --- a/docs/zh-HK/docs/quote/analytics/short_positions.md +++ b/docs/zh-HK/docs/quote/analytics/short_positions.md @@ -1,6 +1,6 @@ --- slug: /quote/pull/short-positions -title: 沽空數據 +title: 沽空數據(美股 / 港股) sidebar_position: 25 language_tabs: false toc_footers: [] @@ -10,10 +10,11 @@ highlight_theme: '' headingLevel: 2 --- -Get US stock short selling data — short interest, short ratio, days to cover, and average daily volume. Records are updated bi-monthly by FINRA. Only US-listed stocks and ETFs are supported. +獲取美股或港股沽空持倉數據。市場根據代碼後綴自動識別:`.HK` → 港交所沽空數據(每日更新);其他 → 美股 FINRA 沽空數據(雙月更新)。 longbridge short-positions TSLA.US +longbridge short-positions 700.HK longbridge short-positions AAPL.US --count 50 @@ -24,10 +25,10 @@ longbridge short-positions AAPL.US --count 50 > **SDK 方法參數。** -| Name | Type | Required | Description | -| ------ | ------ | -------- | --------------------------------------------------- | -| symbol | string | YES | US security symbol, e.g. `TSLA.US`, `AAPL.US` | -| count | integer | NO | Number of records to return (1–100, default: 20) | +| Name | Type | Required | Description | +| ------ | ------- | -------- | ---------------------------------------------------------------- | +| symbol | string | YES | 證券代碼,例如 `TSLA.US` 或 `700.HK` | +| count | integer | NO | 返回記錄數(1–100,默認 20) | ## Request Example @@ -36,6 +37,7 @@ longbridge short-positions AAPL.US --count 50 longbridge short-positions TSLA.US +longbridge short-positions 700.HK longbridge short-positions AAPL.US --count 50 @@ -49,7 +51,12 @@ oauth = OAuthBuilder("your-client-id").build(lambda url: print("Visit:", url)) config = Config.from_oauth(oauth) ctx = QuoteContext(config) -resp = ctx.short_positions("TSLA.US") +# 美股示例 +resp = ctx.short_positions("TSLA.US", 20) +print(resp) + +# 港股示例 +resp = ctx.short_positions("700.HK", 20) print(resp) ``` @@ -65,7 +72,12 @@ async def main() -> None: config = Config.from_oauth(oauth) ctx = AsyncQuoteContext.create(config) - resp = await ctx.short_positions("TSLA.US") + # 美股示例 + resp = await ctx.short_positions("TSLA.US", 20) + print(resp) + + # 港股示例 + resp = await ctx.short_positions("700.HK", 20) print(resp) if __name__ == "__main__": @@ -84,7 +96,7 @@ async function main() { }) const config = Config.fromOAuth(oauth) const ctx = QuoteContext.new(config) - const resp = await ctx.shortPositions('TSLA.US') + const resp = await ctx.shortPositions('TSLA.US', 20) console.log(resp) } main().catch(console.error) @@ -102,7 +114,7 @@ class Main { try (OAuth oauth = new OAuthBuilder("your-client-id").build(url -> System.out.println("Open to authorize: " + url)).get(); Config config = Config.fromOAuth(oauth); QuoteContext ctx = QuoteContext.create(config)) { - var resp = ctx.getShortPositions("TSLA.US").get(); + var resp = ctx.getShortPositions("TSLA.US", 20).get(); System.out.println(resp); } } @@ -121,7 +133,7 @@ async fn main() -> Result<(), Box> { let oauth = OAuthBuilder::new("your-client-id").build(|url| println!("Open: {url}")).await?; let config = Arc::new(Config::from_oauth(oauth)); let (ctx, _) = QuoteContext::new(config); - let resp = ctx.short_positions("TSLA.US").await?; + let resp = ctx.short_positions("TSLA.US", 20).await?; println!("{:?}", resp); Ok(()) } @@ -144,7 +156,7 @@ int main() { if (!res) return; Config config = Config::from_oauth(*res); QuoteContext ctx = QuoteContext::create(config); - ctx.short_positions("TSLA.US", [](auto resp) { + ctx.short_positions("TSLA.US", 20, [](auto resp) { if (resp) std::cout << resp->size() << std::endl; }); }); @@ -183,7 +195,7 @@ func main() { log.Fatal(err) } defer qctx.Close() - resp, err := qctx.ShortPositions(context.Background(), "TSLA.US") + resp, err := qctx.ShortPositions(context.Background(), "TSLA.US", 20) if err != nil { log.Fatal(err) } @@ -196,9 +208,11 @@ func main() { ## Response - ### Response Example + + + ```json { "code": 0, @@ -206,11 +220,11 @@ func main() { "data": { "list": [ { - "date": "2026-03-31", + "timestamp": 1743379200, + "current_shares_short": "65598603", "rate": "0.0175", - "short_shares": "65598603", - "avg_daily_vol": "62121644", - "days_cover": "1.06", + "avg_daily_share_volume": "62121644", + "days_to_cover": "1.06", "close": "371.750" } ] @@ -218,25 +232,58 @@ func main() { } ``` + + + +```json +{ + "code": 0, + "message": "success", + "data": [ + { + "timestamp": 1747353600, + "amount": "2148600000", + "balance": "6200000", + "close": "418.20", + "rate": "0.0182", + "total_amount": "118120000000" + } + ] +} +``` + + + + ### Response Status | Status | Description | Schema | | ------ | ----------- | ------ | -| 200 | Success | [short_positions_rsp](#short_positions_rsp) | -| 400 | Bad request | None | +| 200 | 成功 | 見下方 Schema | +| 400 | 請求錯誤 | None | ## Schemas -### short_positions_rsp - - - -| Name | Type | Required | Description | -| ------------- | -------- | -------- | ------------------------------------------------ | -| list | object[] | true | Short position records | -| ∟ date | string | true | Settlement date in `YYYY-MM-DD` format | -| ∟ rate | string | true | Short ratio (short shares ÷ float) | -| ∟ short_shares | string | true | Number of short shares | -| ∟ avg_daily_vol | string | true | Average daily volume | -| ∟ days_cover | string | true | Days-to-cover ratio (short shares ÷ avg daily vol) | -| ∟ close | string | true | Closing price on that date | +### 美股響應(`.US` 代碼) + +| Name | Type | Required | Description | +| ----------------------- | -------- | -------- | ---------------------------------- | +| list | object[] | false | 沽空持倉記錄 | +| ∟ timestamp | integer | false | 結算日期(Unix 時間戳) | +| ∟ current_shares_short | string | false | 沽空股數 | +| ∟ rate | string | false | 沽空比率 | +| ∟ avg_daily_share_volume | string | false | 日均成交量 | +| ∟ days_to_cover | string | false | 回補天數(沽空股數 ÷ 日均成交量) | +| ∟ close | string | false | 收盤價 | + +### 港股響應(`.HK` 代碼) + +| Name | Type | Required | Description | +| ------------- | -------- | -------- | ---------------------------------------- | +| data | object[] | false | 沽空持倉記錄 | +| ∟ timestamp | integer | false | 日期(Unix 時間戳) | +| ∟ amount | string | false | 沽空金額(港元) | +| ∟ balance | string | false | 淨沽空持倉餘額 | +| ∟ close | string | false | 收盤價 | +| ∟ rate | string | false | 沽空比率(沽空金額 ÷ 總成交金額) | +| ∟ total_amount | string | false | 總成交金額 | From 915d0a695db1d269409d8b14cef6ad055912f0f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Wed, 20 May 2026 16:08:06 +0800 Subject: [PATCH 4/5] fix(docs): add spaces between Chinese and numbers per autocorrect rules --- docs/zh-CN/docs/cli/release-notes.md | 4 ++-- docs/zh-CN/docs/fundamental/fundamental/shareholder_top.md | 2 +- docs/zh-CN/docs/market/status/rank_categories.md | 2 +- docs/zh-CN/docs/market/status/stock_events.md | 4 ++-- docs/zh-HK/docs/cli/release-notes.md | 4 ++-- docs/zh-HK/docs/fundamental/fundamental/shareholder_top.md | 2 +- docs/zh-HK/docs/market/status/rank_categories.md | 2 +- docs/zh-HK/docs/market/status/stock_events.md | 4 ++-- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/zh-CN/docs/cli/release-notes.md b/docs/zh-CN/docs/cli/release-notes.md index b943f40a..1ca00282 100644 --- a/docs/zh-CN/docs/cli/release-notes.md +++ b/docs/zh-CN/docs/cli/release-notes.md @@ -9,11 +9,11 @@ sidebar_icon: newspaper ### [v0.22.0](https://github.com/longbridge/longbridge-terminal/releases/tag/v0.22.0) -- **新增 `shareholder --top`** — 前20大股东(机构、个人、内部人)多报告期持股对比;`--object-id ` 查看单一股东持仓历史及交易明细 +- **新增 `shareholder --top`** — 前 20 大股东(机构、个人、内部人)多报告期持股对比;`--object-id ` 查看单一股东持仓历史及交易明细 - **扩展 `short-positions`** — 新增港股支持(`.HK` 自动路由至港交所沽空持仓数据) - **新增 `short-trades`** — 每日沽空成交量(美股:FINRA/纳斯达克;港股:港交所披露数据) - **新增 `compare`** — 多股估值对比(PE/PB/PS/市值/收盘价),不传对比股票时服务端自动选取同行业标的 -- **新增 `top-movers`** — 价格波动超近20日标准差的异动股票,附关联新闻解读;支持 `--market`、`--sort time|change|hot` 筛选 +- **新增 `top-movers`** — 价格波动超近 20 日标准差的异动股票,附关联新闻解读;支持 `--market`、`--sort time|change|hot` 筛选 - **新增 `screener` 命令组** — 股票筛选工具:`strategies`(推荐/我的策略)、`search --strategy-id ` 或 `--filter key:min:max` 执行筛选、`indicators` 查看可用指标 - **新增 `rank`** — 人气排行榜;不带 `--key` 列出所有分类,`--key ` 获取对应排行(如 `ib_hot_all-us`) diff --git a/docs/zh-CN/docs/fundamental/fundamental/shareholder_top.md b/docs/zh-CN/docs/fundamental/fundamental/shareholder_top.md index ae60ece2..1ddd1245 100644 --- a/docs/zh-CN/docs/fundamental/fundamental/shareholder_top.md +++ b/docs/zh-CN/docs/fundamental/fundamental/shareholder_top.md @@ -10,7 +10,7 @@ highlight_theme: '' headingLevel: 2 --- -获取上市公司前20大股东(机构、个人、内部人)的持股数据,支持多报告期对比。`object_id` 可传入 `shareholder_detail` 查看详情。 +获取上市公司前 20 大股东(机构、个人、内部人)的持股数据,支持多报告期对比。`object_id` 可传入 `shareholder_detail` 查看详情。 longbridge shareholder AAPL.US --top diff --git a/docs/zh-CN/docs/market/status/rank_categories.md b/docs/zh-CN/docs/market/status/rank_categories.md index c9cbcb72..bd4a0d65 100644 --- a/docs/zh-CN/docs/market/status/rank_categories.md +++ b/docs/zh-CN/docs/market/status/rank_categories.md @@ -199,7 +199,7 @@ func main() { "second_tags": [ { "key": "ib_hot_all-us", "name": "美股总热度", "market": "US" }, { "key": "ib_hot_all-hk", "name": "港股总热度", "market": "HK" }, - { "key": "ib_hot_all-cn", "name": "A股总热度", "market": "CN" } + { "key": "ib_hot_all-cn", "name": "A 股总热度", "market": "CN" } ] }, { diff --git a/docs/zh-CN/docs/market/status/stock_events.md b/docs/zh-CN/docs/market/status/stock_events.md index b87ef04e..f00821b7 100644 --- a/docs/zh-CN/docs/market/status/stock_events.md +++ b/docs/zh-CN/docs/market/status/stock_events.md @@ -10,7 +10,7 @@ highlight_theme: '' headingLevel: 2 --- -获取价格波动超过近20个交易日标准差的异动股票,系统自动关联相关新闻解读异动原因。 +获取价格波动超过近 20 个交易日标准差的异动股票,系统自动关联相关新闻解读异动原因。 longbridge top-movers @@ -212,7 +212,7 @@ func main() { "alert_type": "earnings_beat", "post": { "id": "post_abc123", - "title": "阿里巴巴Q4财报解读:云业务强劲增长", + "title": "阿里巴巴 Q4 财报解读:云业务强劲增长", "url": "https://longbridge.com/news/post_abc123" } }, diff --git a/docs/zh-HK/docs/cli/release-notes.md b/docs/zh-HK/docs/cli/release-notes.md index 84127fd3..6b6a043a 100644 --- a/docs/zh-HK/docs/cli/release-notes.md +++ b/docs/zh-HK/docs/cli/release-notes.md @@ -9,11 +9,11 @@ sidebar_icon: newspaper ### [v0.22.0](https://github.com/longbridge/longbridge-terminal/releases/tag/v0.22.0) -- **新增 `shareholder --top`** — 前20大股東(機構、個人、內部人)多報告期持股對比;`--object-id ` 查看單一股東持倉歷史及交易明細 +- **新增 `shareholder --top`** — 前 20 大股東(機構、個人、內部人)多報告期持股對比;`--object-id ` 查看單一股東持倉歷史及交易明細 - **擴展 `short-positions`** — 新增港股支持(`.HK` 自動路由至港交所沽空持倉數據) - **新增 `short-trades`** — 每日沽空成交量(美股:FINRA/納斯達克;港股:港交所披露數據) - **新增 `compare`** — 多股估值對比(PE/PB/PS/市值/收盤價),不傳對比股票時服務端自動選取同行業標的 -- **新增 `top-movers`** — 價格波動超近20日標準差的異動股票,附關聯新聞解讀;支持 `--market`、`--sort time|change|hot` 篩選 +- **新增 `top-movers`** — 價格波動超近 20 日標準差的異動股票,附關聯新聞解讀;支持 `--market`、`--sort time|change|hot` 篩選 - **新增 `screener` 命令組** — 股票篩選工具:`strategies`(推薦/我的策略)、`search --strategy-id ` 或 `--filter key:min:max` 執行篩選、`indicators` 查看可用指標 - **新增 `rank`** — 人氣排行榜;不帶 `--key` 列出所有分類,`--key ` 獲取對應排行(如 `ib_hot_all-us`) diff --git a/docs/zh-HK/docs/fundamental/fundamental/shareholder_top.md b/docs/zh-HK/docs/fundamental/fundamental/shareholder_top.md index 5a57b423..adb81279 100644 --- a/docs/zh-HK/docs/fundamental/fundamental/shareholder_top.md +++ b/docs/zh-HK/docs/fundamental/fundamental/shareholder_top.md @@ -10,7 +10,7 @@ highlight_theme: '' headingLevel: 2 --- -獲取上市公司前20大股東(機構、個人、內部人)的持股數據,支持多報告期對比。`object_id` 可傳入 `shareholder_detail` 查看詳情。 +獲取上市公司前 20 大股東(機構、個人、內部人)的持股數據,支持多報告期對比。`object_id` 可傳入 `shareholder_detail` 查看詳情。 longbridge shareholder AAPL.US --top diff --git a/docs/zh-HK/docs/market/status/rank_categories.md b/docs/zh-HK/docs/market/status/rank_categories.md index 746a82a8..e38f2714 100644 --- a/docs/zh-HK/docs/market/status/rank_categories.md +++ b/docs/zh-HK/docs/market/status/rank_categories.md @@ -199,7 +199,7 @@ func main() { "second_tags": [ { "key": "ib_hot_all-us", "name": "美股總熱度", "market": "US" }, { "key": "ib_hot_all-hk", "name": "港股總熱度", "market": "HK" }, - { "key": "ib_hot_all-cn", "name": "A股總熱度", "market": "CN" } + { "key": "ib_hot_all-cn", "name": "A 股總熱度", "market": "CN" } ] }, { diff --git a/docs/zh-HK/docs/market/status/stock_events.md b/docs/zh-HK/docs/market/status/stock_events.md index d3576cbc..8fc2d64d 100644 --- a/docs/zh-HK/docs/market/status/stock_events.md +++ b/docs/zh-HK/docs/market/status/stock_events.md @@ -10,7 +10,7 @@ highlight_theme: '' headingLevel: 2 --- -獲取價格波動超過近20個交易日標準差的異動股票,系統自動關聯相關新聞解讀異動原因。 +獲取價格波動超過近 20 個交易日標準差的異動股票,系統自動關聯相關新聞解讀異動原因。 longbridge top-movers @@ -212,7 +212,7 @@ func main() { "alert_type": "earnings_beat", "post": { "id": "post_abc123", - "title": "阿里巴巴Q4財報解讀:雲業務強勁增長", + "title": "阿里巴巴 Q4 財報解讀:雲業務強勁增長", "url": "https://longbridge.com/news/post_abc123" } }, From eab6c5d54659a2d0f90b17bc2374ab32e8cae117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Wed, 20 May 2026 17:32:23 +0800 Subject: [PATCH 5/5] fix(docs): align response schemas with real API output Corrects response examples and schema tables for 8 API endpoints across en, zh-CN, and zh-HK locales to match live API responses: - shareholder_top: object_id is string; percent_shares_held includes % sign; add percent_shares_changed field; remove non-existent top-level periods array - shareholder_detail: add name/title/avatar/holding_periods/holding_details/ trading_periods fields; tradings[] has accum_buy/sell/net_buy at period level - valuation_comparison: symbol -> counter_id; add currency/roe/eps/bps/dps/ div_yld/assets fields; history.date is Unix timestamp - stock_events: stock.symbol -> stock.code; add counter_id/last_done/market/ logo/trade_status fields; alert_type is integer; next_params is object - rank_list: add bmp boolean field; symbol -> code; add counter_id/market/ industry fields; chg is ratio not percentage string - screener_recommend_strategies: id is string; remove average_day_chg/stocks; add group_type; min/max/value are strings; add tech_data field - screener_strategy: remove top-level id/name (response is groups only); add group_type; min/max/value are strings; add tech_data field - screener_indicators: response is {groups:[]} not {indicators:[]}; replace value_min/value_max/step with value_ranges/default_range/default_selected/ category/description/places/sub_indicators/tech_indicators Co-Authored-By: Claude Sonnet 4.6 (1M context) --- .../fundamental/shareholder_detail.md | 41 ++++--- .../fundamental/shareholder_top.md | 42 +++---- .../fundamental/valuation_comparison.md | 37 +++++-- docs/en/docs/market/status/rank_list.md | 40 ++++--- docs/en/docs/market/status/stock_events.md | 59 +++++----- docs/en/docs/screener/screener_indicators.md | 103 +++++++++--------- .../screener/screener_recommend_strategies.md | 27 ++--- docs/en/docs/screener/screener_strategy.md | 55 +++++----- .../fundamental/shareholder_detail.md | 55 +++++----- .../fundamental/shareholder_top.md | 42 +++---- .../fundamental/valuation_comparison.md | 38 +++++-- docs/zh-CN/docs/market/status/rank_list.md | 38 +++---- docs/zh-CN/docs/market/status/stock_events.md | 59 +++++----- .../docs/screener/screener_indicators.md | 103 +++++++++--------- .../screener/screener_recommend_strategies.md | 27 ++--- docs/zh-CN/docs/screener/screener_strategy.md | 55 +++++----- .../fundamental/shareholder_detail.md | 55 +++++----- .../fundamental/shareholder_top.md | 42 +++---- .../fundamental/valuation_comparison.md | 38 +++++-- docs/zh-HK/docs/market/status/rank_list.md | 38 +++---- docs/zh-HK/docs/market/status/stock_events.md | 59 +++++----- .../docs/screener/screener_indicators.md | 103 +++++++++--------- .../screener/screener_recommend_strategies.md | 27 ++--- docs/zh-HK/docs/screener/screener_strategy.md | 55 +++++----- 24 files changed, 642 insertions(+), 596 deletions(-) diff --git a/docs/en/docs/fundamental/fundamental/shareholder_detail.md b/docs/en/docs/fundamental/fundamental/shareholder_detail.md index 6dd3f34b..0b93a122 100644 --- a/docs/en/docs/fundamental/fundamental/shareholder_detail.md +++ b/docs/en/docs/fundamental/fundamental/shareholder_detail.md @@ -196,18 +196,20 @@ func main() { "code": 0, "message": "success", "data": { + "name": "The Vanguard Group, Inc.", + "title": "", + "avatar": "", "owner_source": "Institution", - "holding_summary": [ - { - "period": "2025-12-31", - "accum_buy": "8500000", - "accum_sell": "2687264", - "stock_price": "243.08" - } - ], + "holding_periods": [], + "holding_details": [], + "holding_summary": [], + "trading_periods": ["Past 1 Month", "Past 3 Months", "Past 1 Year", "Past 3 Years"], "tradings": [ { - "period": "2025-12-31", + "period": "Past 1 Month", + "accum_buy": "8500000.00", + "accum_sell": "2687264.00", + "net_buy": "5812736.00", "trading_details": [ { "trading_date": "2025-12-18", @@ -237,16 +239,21 @@ func main() { | Name | Type | Required | Description | | ---- | ---- | -------- | ----------- | +| name | string | false | Shareholder name | +| title | string | false | Shareholder title / type | +| avatar | string | false | Avatar URL | | owner_source | string | false | Shareholder type: `Company`, `Institution`, `Person`, `Insider` | -| holding_summary | object[] | false | Holding summary per reporting period | -| ∟ period | string | false | Reporting period in `YYYY-MM-DD` format | -| ∟ accum_buy | string | false | Cumulative shares bought this period | -| ∟ accum_sell | string | false | Cumulative shares sold this period | -| ∟ stock_price | string | false | Closing price at end of period | -| tradings | object[] | false | Trade details per reporting period | -| ∟ period | string | false | Reporting period in `YYYY-MM-DD` format | +| holding_periods | string[] | false | Available holding periods | +| holding_details | object[] | false | Holding detail records | +| holding_summary | object[] | false | Holding summary records | +| trading_periods | string[] | false | Available trading periods (e.g. `Past 1 Month`, `Past 3 Months`) | +| tradings | object[] | false | Trade aggregates per period | +| ∟ period | string | false | Period label (e.g. `Past 1 Month`) | +| ∟ accum_buy | string | false | Cumulative shares bought in this period | +| ∟ accum_sell | string | false | Cumulative shares sold in this period | +| ∟ net_buy | string | false | Net shares bought (buy minus sell) in this period | | ∟ trading_details | object[] | false | Individual transactions within the period | -| ∟ ∟ trading_date | string | false | Trade date in `YYYY-MM-DD` format | +| ∟ ∟ trading_date | string | false | Trade date | | ∟ ∟ trading_shares | string | false | Number of shares traded | | ∟ ∟ trading_price | string | false | Trade price | | ∟ ∟ trading_type | string | false | Trade direction: `Buy` or `Sell` | diff --git a/docs/en/docs/fundamental/fundamental/shareholder_top.md b/docs/en/docs/fundamental/fundamental/shareholder_top.md index 9d0ff8af..ba4025f6 100644 --- a/docs/en/docs/fundamental/fundamental/shareholder_top.md +++ b/docs/en/docs/fundamental/fundamental/shareholder_top.md @@ -195,28 +195,31 @@ func main() { "code": 0, "message": "success", "data": { - "periods": ["2025-12-31", "2025-09-30"], "info": [ { - "period": "2025-12-31", + "period": "Latest", "share_holders": [ { - "object_id": 19463, + "object_id": "148057", "name": "The Vanguard Group, Inc.", - "title": "Institution", - "shares_held": "1285506048", - "percent_shares_held": "8.46", - "shares_changed": "5812736", - "filing_date": "2026-02-14" + "title": "", + "shares_held": "1426283914.00", + "percent_shares_held": "9.71%", + "percent_shares_changed": "0.01%", + "shares_changed": "0.00", + "period": "Latest", + "filing_date": "2025/12/31" }, { - "object_id": 20181, + "object_id": "452583", "name": "BlackRock, Inc.", - "title": "Institution", - "shares_held": "1071234816", - "percent_shares_held": "7.05", - "shares_changed": "-3104128", - "filing_date": "2026-02-05" + "title": "", + "shares_held": "1138572603.00", + "percent_shares_held": "7.75%", + "percent_shares_changed": "-0.06%", + "shares_changed": "-10565359.00", + "period": "Latest", + "filing_date": "2026/03/31" } ] } @@ -240,14 +243,15 @@ func main() { | Name | Type | Required | Description | | ---- | ---- | -------- | ----------- | -| periods | string[] | false | Available reporting periods in `YYYY-MM-DD` format | | info | object[] | false | Shareholder data per reporting period | -| ∟ period | string | false | Reporting period in `YYYY-MM-DD` format | +| ∟ period | string | false | Reporting period label (e.g. `Latest`) | | ∟ share_holders | object[] | false | List of shareholders (up to 20) | -| ∟ ∟ object_id | integer | false | Unique shareholder ID; pass to `shareholder_detail` | +| ∟ ∟ object_id | string | false | Unique shareholder ID; pass to `shareholder_detail` | | ∟ ∟ name | string | false | Shareholder name | | ∟ ∟ title | string | false | Shareholder type (Institution / Individual / Insider) | | ∟ ∟ shares_held | string | false | Number of shares held | -| ∟ ∟ percent_shares_held | string | false | Ownership percentage | +| ∟ ∟ percent_shares_held | string | false | Ownership percentage, including `%` sign (e.g. `9.71%`) | +| ∟ ∟ percent_shares_changed | string | false | Change in ownership percentage, including `%` sign | | ∟ ∟ shares_changed | string | false | Net share count change (positive = bought, negative = sold) | -| ∟ ∟ filing_date | string | false | Filing date in `YYYY-MM-DD` format | +| ∟ ∟ period | string | false | Period label for this entry | +| ∟ ∟ filing_date | string | false | Filing date | diff --git a/docs/en/docs/fundamental/fundamental/valuation_comparison.md b/docs/en/docs/fundamental/fundamental/valuation_comparison.md index 92725d61..f046aa16 100644 --- a/docs/en/docs/fundamental/fundamental/valuation_comparison.md +++ b/docs/en/docs/fundamental/fundamental/valuation_comparison.md @@ -203,28 +203,42 @@ func main() { "data": { "list": [ { - "symbol": "AAPL.US", + "counter_id": "ST/US/AAPL", "name": "Apple Inc.", + "currency": "USD", "market_value": "3241500000000", "price_close": "213.49", "pe": "32.15", "pb": "50.21", "ps": "8.04", + "roe": "136.45", + "eps": "6.43", + "bps": "4.38", + "dps": "0.99", + "div_yld": "0.46", + "assets": "371082000000", "history": [ - { "date": "2026-05-01", "pe": "32.15", "pb": "50.21", "ps": "8.04" }, - { "date": "2026-04-01", "pe": "28.73", "pb": "46.88", "ps": "7.52" } + { "date": "1622520000", "pe": "37.56", "pb": "30.16", "ps": "6.41" }, + { "date": "1625112000", "pe": "41.49", "pb": "35.64", "ps": "6.60" } ] }, { - "symbol": "MSFT.US", + "counter_id": "ST/US/MSFT", "name": "Microsoft", + "currency": "USD", "market_value": "3085000000000", "price_close": "415.32", "pe": "35.42", "pb": "12.87", "ps": "12.61", + "roe": "38.21", + "eps": "11.72", + "bps": "32.28", + "dps": "3.32", + "div_yld": "0.80", + "assets": "512163000000", "history": [ - { "date": "2026-05-01", "pe": "35.42", "pb": "12.87", "ps": "12.61" } + { "date": "1622520000", "pe": "33.12", "pb": "11.94", "ps": "11.84" } ] } ] @@ -248,15 +262,22 @@ func main() { | Name | Type | Required | Description | | ---- | ---- | -------- | ----------- | | list | object[] | false | Valuation comparison list | -| ∟ symbol | string | false | Security symbol | +| ∟ counter_id | string | false | Counter ID (e.g. `ST/US/AAPL`) | | ∟ name | string | false | Security name | -| ∟ market_value | string | false | Market cap in result currency | +| ∟ currency | string | false | Currency of the values | +| ∟ market_value | string | false | Market capitalisation | | ∟ price_close | string | false | Latest closing price | | ∟ pe | string | false | P/E ratio (TTM) | | ∟ pb | string | false | P/B ratio | | ∟ ps | string | false | P/S ratio (TTM) | +| ∟ roe | string | false | Return on equity (%) | +| ∟ eps | string | false | Earnings per share (TTM) | +| ∟ bps | string | false | Book value per share | +| ∟ dps | string | false | Dividends per share (TTM) | +| ∟ div_yld | string | false | Dividend yield (%) | +| ∟ assets | string | false | Total assets | | ∟ history | object[] | false | Historical valuation time series | -| ∟ ∟ date | string | false | Date in `YYYY-MM-DD` format | +| ∟ ∟ date | string | false | Date as Unix timestamp (seconds) | | ∟ ∟ pe | string | false | Historical PE | | ∟ ∟ pb | string | false | Historical PB | | ∟ ∟ ps | string | false | Historical PS | diff --git a/docs/en/docs/market/status/rank_list.md b/docs/en/docs/market/status/rank_list.md index 03839b5d..832880ff 100644 --- a/docs/en/docs/market/status/rank_list.md +++ b/docs/en/docs/market/status/rank_list.md @@ -196,26 +196,20 @@ func main() { "code": 0, "message": "success", "data": { + "bmp": false, "lists": [ { - "symbol": "NVDA.US", - "name": "NVIDIA", - "last_done": "135.62", - "chg": "+2.84%", - "inflow": "1250000000", - "market_cap": "3312000000000", - "pre_post_price": "136.10", - "pre_post_chg": "+0.35%" - }, - { - "symbol": "TSLA.US", - "name": "Tesla", - "last_done": "342.15", - "chg": "-1.23%", - "inflow": "875000000", - "market_cap": "1098000000000", - "pre_post_price": "341.00", - "pre_post_chg": "-0.34%" + "code": "MU", + "counter_id": "ST/US/MU", + "name": "Micron Technology", + "market": "US", + "last_done": "698.740", + "chg": "0.0252", + "inflow": "-347041642", + "market_cap": "787992890796", + "industry": "Semiconductor Manufacturers", + "pre_post_price": "700.10", + "pre_post_chg": "0.0020" } ] } @@ -237,12 +231,16 @@ func main() { | Name | Type | Required | Description | | ---- | ---- | -------- | ----------- | +| bmp | boolean | false | Whether the response is a market preview (before open) | | lists | object[] | false | Leaderboard stock list | -| ∟ symbol | string | false | Security symbol | +| ∟ code | string | false | Ticker code (e.g. `MU`) | +| ∟ counter_id | string | false | Counter ID (e.g. `ST/US/MU`) | | ∟ name | string | false | Security name | +| ∟ market | string | false | Market: `US`, `HK`, `CN`, `SG` | | ∟ last_done | string | false | Latest trade price | -| ∟ chg | string | false | Price change with sign, e.g. `+2.84%` | +| ∟ chg | string | false | Price change ratio (e.g. `0.0252`) | | ∟ inflow | string | false | Net capital inflow (in the market's currency) | | ∟ market_cap | string | false | Market capitalisation | +| ∟ industry | string | false | Industry classification | | ∟ pre_post_price | string | false | Pre/post-market price | -| ∟ pre_post_chg | string | false | Pre/post-market price change | +| ∟ pre_post_chg | string | false | Pre/post-market price change ratio | diff --git a/docs/en/docs/market/status/stock_events.md b/docs/en/docs/market/status/stock_events.md index d9e0f8f7..15505d85 100644 --- a/docs/en/docs/market/status/stock_events.md +++ b/docs/en/docs/market/status/stock_events.md @@ -202,34 +202,25 @@ func main() { "events": [ { "stock": { - "symbol": "9988.HK", - "name": "Alibaba", - "change": "+4.82%", - "labels": ["HK", "Technology"] + "code": "TSLA", + "counter_id": "ST/US/TSLA", + "name": "特斯拉", + "change": "-0.0388", + "last_done": "404.110", + "market": "US", + "labels": ["汽车制造商"], + "logo": "https://assets.lbkrs.com/ticker/ST/US/TSLA.png", + "trade_status": 0 }, - "timestamp": 1747728600000, - "alert_reason": "Earnings beat: revenue up 8%", - "alert_type": "earnings_beat", - "post": { - "id": "post_abc123", - "title": "Alibaba Q4 Earnings: Cloud Business Surges", - "url": "https://longbridge.com/news/post_abc123" - } - }, - { - "stock": { - "symbol": "NVDA.US", - "name": "NVIDIA", - "change": "+3.21%", - "labels": ["US", "Semiconductor"] - }, - "timestamp": 1747725000000, - "alert_reason": "Block buy: volume up 3x", - "alert_type": "volume_spike", + "timestamp": "1779202097", + "alert_reason": "波动超 20 日均值", + "alert_type": 11, "post": null } ], - "next_params": "eyJvZmZzZXQiOjIwfQ==" + "next_params": { + "visited": ["11098290", "11098478", "11099705"] + } } } ``` @@ -251,15 +242,17 @@ func main() { | ---- | ---- | -------- | ----------- | | events | object[] | false | List of moving stocks | | ∟ stock | object | false | Basic stock information | -| ∟ ∟ symbol | string | false | Security symbol | +| ∟ ∟ code | string | false | Ticker code (e.g. `TSLA`) | +| ∟ ∟ counter_id | string | false | Counter ID (e.g. `ST/US/TSLA`) | | ∟ ∟ name | string | false | Security name | -| ∟ ∟ change | string | false | Price change with sign, e.g. `+4.82%` | -| ∟ ∟ labels | string[] | false | Tags (market, industry, etc.) | -| ∟ timestamp | integer | false | Event time (Unix milliseconds) | +| ∟ ∟ change | string | false | Price change ratio (e.g. `-0.0388`) | +| ∟ ∟ last_done | string | false | Latest trade price | +| ∟ ∟ market | string | false | Market: `US`, `HK`, `CN`, `SG` | +| ∟ ∟ labels | string[] | false | Industry / theme tags | +| ∟ ∟ logo | string | false | Logo image URL | +| ∟ ∟ trade_status | integer | false | Trading status code | +| ∟ timestamp | string | false | Event time (Unix seconds as string) | | ∟ alert_reason | string | false | Description of the move reason | -| ∟ alert_type | string | false | Move type identifier | +| ∟ alert_type | integer | false | Move type code | | ∟ post | object | false | Associated news/article; `null` if none | -| ∟ ∟ id | string | false | Article ID | -| ∟ ∟ title | string | false | Article title | -| ∟ ∟ url | string | false | Article URL | -| next_params | string | false | Pagination cursor (Base64 encoded); pass to the next request to get the next page | +| next_params | object | false | Pagination cursor object; pass to the next request to get the next page | diff --git a/docs/en/docs/screener/screener_indicators.md b/docs/en/docs/screener/screener_indicators.md index 2c23b475..0ac9f62d 100644 --- a/docs/en/docs/screener/screener_indicators.md +++ b/docs/en/docs/screener/screener_indicators.md @@ -192,51 +192,46 @@ func main() { "code": 0, "message": "success", "data": { - "indicators": [ + "groups": [ { - "id": 10, - "key": "filter_pe", - "name": "P/E Ratio", - "unit": "x", - "value_min": 0, - "value_max": 1000, - "step": 1 + "group_name": "Market", + "group_type": "range", + "indicators": [ + { + "id": -1, + "key": "filter_market", + "name": "Market", + "unit": "", + "category": 0, + "description": "", + "default_range": [], + "default_selected": false, + "places": 0, + "sub_indicators": [], + "tech_indicators": [], + "value_ranges": [] + } + ] }, { - "id": 11, - "key": "filter_pb", - "name": "P/B Ratio", - "unit": "x", - "value_min": 0, - "value_max": 100, - "step": 0.1 - }, - { - "id": 20, - "key": "filter_marketcap", - "name": "Market Cap", - "unit": "bn", - "value_min": 0, - "value_max": 100000, - "step": 10 - }, - { - "id": 25, - "key": "filter_roe", - "name": "Return on Equity", - "unit": "%", - "value_min": -100, - "value_max": 200, - "step": 1 - }, - { - "id": 30, - "key": "filter_revenue_growth", - "name": "Revenue Growth", - "unit": "%", - "value_min": -100, - "value_max": 500, - "step": 1 + "group_name": "Quote Indicators", + "group_type": "Quotes", + "indicators": [ + { + "id": 1, + "key": "filter_marketcap", + "name": "Market Cap", + "unit": "bn", + "category": 0, + "description": "", + "default_range": [], + "default_selected": false, + "places": 0, + "sub_indicators": [], + "tech_indicators": [], + "value_ranges": [] + } + ] } ] } @@ -258,11 +253,19 @@ func main() { | Name | Type | Required | Description | | ---- | ---- | -------- | ----------- | -| indicators | object[] | false | List of available indicators | -| ∟ id | integer | false | Indicator ID | -| ∟ key | string | false | Indicator key for building filter conditions (format: `filter_::`) | -| ∟ name | string | false | Indicator display name | -| ∟ unit | string | false | Unit (e.g. `x`, `%`, `bn`) | -| ∟ value_min | number | false | Minimum allowed value for this indicator | -| ∟ value_max | number | false | Maximum allowed value for this indicator | -| ∟ step | number | false | Suggested step size | +| groups | object[] | false | Indicator groups | +| ∟ group_name | string | false | Group name | +| ∟ group_type | string | false | Group type (e.g. `range`, `Quotes`, `DividendIndex`) | +| ∟ indicators | object[] | false | List of indicators in this group | +| ∟ ∟ id | integer | false | Indicator ID | +| ∟ ∟ key | string | false | Indicator key for building filter conditions | +| ∟ ∟ name | string | false | Indicator display name | +| ∟ ∟ unit | string | false | Unit (e.g. `%`, `bn`) | +| ∟ ∟ category | integer | false | Indicator category code | +| ∟ ∟ description | string | false | Indicator description | +| ∟ ∟ default_range | array | false | Default filter range | +| ∟ ∟ default_selected | boolean | false | Whether this indicator is selected by default | +| ∟ ∟ places | integer | false | Decimal places for display | +| ∟ ∟ sub_indicators | array | false | Sub-indicator definitions | +| ∟ ∟ tech_indicators | array | false | Technical indicator definitions | +| ∟ ∟ value_ranges | array | false | Available value ranges for this indicator | diff --git a/docs/en/docs/screener/screener_recommend_strategies.md b/docs/en/docs/screener/screener_recommend_strategies.md index 365ace65..fb22e56d 100644 --- a/docs/en/docs/screener/screener_recommend_strategies.md +++ b/docs/en/docs/screener/screener_recommend_strategies.md @@ -194,21 +194,21 @@ func main() { "data": { "screeners": [ { - "id": 1, - "name": "High Profit Low Valuation", - "average_day_chg": "+0.82%", - "stocks": ["AAPL.US", "MSFT.US", "GOOGL.US"], + "id": "1", + "name": "High Dividend Blue Chips", "groups": [ { - "group_name": "Valuation", + "group_name": "Range", + "group_type": "range", "indicators": [ - { "id": 10, "key": "filter_pe", "name": "P/E Ratio", "unit": "x", "min": 0, "max": 30 } + { "id": -1, "key": "filter_market", "name": "HK", "unit": "", "min": "", "max": "", "value": "HK", "tech_data": [] } ] }, { - "group_name": "Profitability", + "group_name": "Dividend Indicators", + "group_type": "DividendIndex", "indicators": [ - { "id": 25, "key": "filter_roe", "name": "Return on Equity", "unit": "%", "min": 15, "max": null } + { "id": 29, "key": "filter_divyld", "name": "Dividend Yield (TTM)", "unit": "%", "min": "4", "max": "", "value": "", "tech_data": [] } ] } ] @@ -234,16 +234,17 @@ func main() { | Name | Type | Required | Description | | ---- | ---- | -------- | ----------- | | screeners | object[] | false | Strategy list | -| ∟ id | integer | false | Strategy ID | +| ∟ id | string | false | Strategy ID | | ∟ name | string | false | Strategy name | -| ∟ average_day_chg | string | false | Recent average daily change of strategy constituents | -| ∟ stocks | string[] | false | Current list of stock symbols from this strategy | | ∟ groups | object[] | false | Filter condition groups | | ∟ ∟ group_name | string | false | Group name | +| ∟ ∟ group_type | string | false | Group type (e.g. `range`, `Quotes`, `DividendIndex`) | | ∟ ∟ indicators | object[] | false | Indicator conditions in this group | | ∟ ∟ ∟ id | integer | false | Indicator ID | | ∟ ∟ ∟ key | string | false | Indicator key; usable in `screener_search` | | ∟ ∟ ∟ name | string | false | Indicator name | | ∟ ∟ ∟ unit | string | false | Indicator unit | -| ∟ ∟ ∟ min | number | false | Minimum value set by the strategy | -| ∟ ∟ ∟ max | number | false | Maximum value set by the strategy; `null` means no upper bound | +| ∟ ∟ ∟ min | string | false | Minimum value set by the strategy; empty string means no lower bound | +| ∟ ∟ ∟ max | string | false | Maximum value set by the strategy; empty string means no upper bound | +| ∟ ∟ ∟ value | string | false | Fixed value (used for non-range indicators such as market selector) | +| ∟ ∟ ∟ tech_data | array | false | Technical indicator data array | diff --git a/docs/en/docs/screener/screener_strategy.md b/docs/en/docs/screener/screener_strategy.md index 2d033053..d8a41934 100644 --- a/docs/en/docs/screener/screener_strategy.md +++ b/docs/en/docs/screener/screener_strategy.md @@ -194,40 +194,36 @@ func main() { "code": 0, "message": "success", "data": { - "id": 42, - "name": "My Growth Strategy", "groups": [ { - "group_name": "Valuation", + "group_name": "Range", + "group_type": "range", "indicators": [ { - "id": 10, - "key": "filter_pe", - "name": "P/E Ratio", - "unit": "x", - "min": 5, - "max": 30 - }, - { - "id": 11, - "key": "filter_pb", - "name": "P/B Ratio", - "unit": "x", - "min": 1, - "max": 10 + "id": -1, + "key": "filter_market", + "name": "HK", + "unit": "", + "min": "", + "max": "", + "value": "HK", + "tech_data": [] } ] }, { - "group_name": "Growth", + "group_name": "Quote Indicators", + "group_type": "Quotes", "indicators": [ { - "id": 30, - "key": "filter_revenue_growth", - "name": "Revenue Growth", - "unit": "%", - "min": 20, - "max": null + "id": 1, + "key": "filter_marketcap", + "name": "Market Cap", + "unit": "bn", + "min": "100", + "max": "", + "value": "", + "tech_data": [] } ] } @@ -251,14 +247,15 @@ func main() { | Name | Type | Required | Description | | ---- | ---- | -------- | ----------- | -| id | integer | false | Strategy ID | -| name | string | false | Strategy name | | groups | object[] | false | Indicator group list | | ∟ group_name | string | false | Group name | +| ∟ group_type | string | false | Group type (e.g. `range`, `Quotes`, `DividendIndex`) | | ∟ indicators | object[] | false | Indicator conditions in this group | | ∟ ∟ id | integer | false | Indicator ID | | ∟ ∟ key | string | false | Indicator key | | ∟ ∟ name | string | false | Indicator display name | -| ∟ ∟ unit | string | false | Indicator unit (e.g. `x`, `%`, `bn`) | -| ∟ ∟ min | number | false | Minimum value; `null` means no lower bound | -| ∟ ∟ max | number | false | Maximum value; `null` means no upper bound | +| ∟ ∟ unit | string | false | Indicator unit (e.g. `%`, `bn`) | +| ∟ ∟ min | string | false | Minimum value; empty string means no lower bound | +| ∟ ∟ max | string | false | Maximum value; empty string means no upper bound | +| ∟ ∟ value | string | false | Fixed value (used for non-range indicators such as market selector) | +| ∟ ∟ tech_data | array | false | Technical indicator data array | diff --git a/docs/zh-CN/docs/fundamental/fundamental/shareholder_detail.md b/docs/zh-CN/docs/fundamental/fundamental/shareholder_detail.md index 4202696a..b4462610 100644 --- a/docs/zh-CN/docs/fundamental/fundamental/shareholder_detail.md +++ b/docs/zh-CN/docs/fundamental/fundamental/shareholder_detail.md @@ -196,36 +196,26 @@ func main() { "code": 0, "message": "success", "data": { + "name": "The Vanguard Group, Inc.", + "title": "", + "avatar": "", "owner_source": "Institution", - "holding_summary": [ - { - "period": "2025-12-31", - "accum_buy": "8500000", - "accum_sell": "2687264", - "stock_price": "243.08" - }, - { - "period": "2025-09-30", - "accum_buy": "3200000", - "accum_sell": "1500000", - "stock_price": "226.51" - } - ], + "holding_periods": [], + "holding_details": [], + "holding_summary": [], + "trading_periods": ["Past 1 Month", "Past 3 Months", "Past 1 Year", "Past 3 Years"], "tradings": [ { - "period": "2025-12-31", + "period": "Past 1 Month", + "accum_buy": "8500000.00", + "accum_sell": "2687264.00", + "net_buy": "5812736.00", "trading_details": [ { "trading_date": "2025-12-18", "trading_shares": "5200000", "trading_price": "248.12", "trading_type": "Buy" - }, - { - "trading_date": "2025-11-05", - "trading_shares": "2687264", - "trading_price": "222.91", - "trading_type": "Sell" } ] } @@ -249,16 +239,21 @@ func main() { | Name | Type | Required | Description | | ---- | ---- | -------- | ----------- | +| name | string | false | 股东名称 | +| title | string | false | 股东头衔 / 类型 | +| avatar | string | false | 头像 URL | | owner_source | string | false | 股东类型:`Company`、`Institution`、`Person`、`Insider` | -| holding_summary | object[] | false | 各报告期持仓汇总 | -| ∟ period | string | false | 报告期,格式 `YYYY-MM-DD` | -| ∟ accum_buy | string | false | 该期累计买入股数 | -| ∟ accum_sell | string | false | 该期累计卖出股数 | -| ∟ stock_price | string | false | 报告期末股价 | -| tradings | object[] | false | 各报告期交易明细 | -| ∟ period | string | false | 报告期,格式 `YYYY-MM-DD` | -| ∟ trading_details | object[] | false | 该报告期内的交易记录 | -| ∟ ∟ trading_date | string | false | 交易日期,格式 `YYYY-MM-DD` | +| holding_periods | string[] | false | 可用的持仓报告期列表 | +| holding_details | object[] | false | 持仓明细记录 | +| holding_summary | object[] | false | 持仓汇总记录 | +| trading_periods | string[] | false | 可用的交易统计区间(如 `Past 1 Month`、`Past 3 Months`) | +| tradings | object[] | false | 各区间交易汇总 | +| ∟ period | string | false | 区间标签(如 `Past 1 Month`) | +| ∟ accum_buy | string | false | 该区间累计买入股数 | +| ∟ accum_sell | string | false | 该区间累计卖出股数 | +| ∟ net_buy | string | false | 该区间净买入股数(买入减卖出) | +| ∟ trading_details | object[] | false | 该区间内的具体交易记录 | +| ∟ ∟ trading_date | string | false | 交易日期 | | ∟ ∟ trading_shares | string | false | 交易股数 | | ∟ ∟ trading_price | string | false | 交易价格 | | ∟ ∟ trading_type | string | false | 交易方向:`Buy` 或 `Sell` | diff --git a/docs/zh-CN/docs/fundamental/fundamental/shareholder_top.md b/docs/zh-CN/docs/fundamental/fundamental/shareholder_top.md index 1ddd1245..4eece3cd 100644 --- a/docs/zh-CN/docs/fundamental/fundamental/shareholder_top.md +++ b/docs/zh-CN/docs/fundamental/fundamental/shareholder_top.md @@ -195,28 +195,31 @@ func main() { "code": 0, "message": "success", "data": { - "periods": ["2025-12-31", "2025-09-30"], "info": [ { - "period": "2025-12-31", + "period": "Latest", "share_holders": [ { - "object_id": 19463, + "object_id": "148057", "name": "The Vanguard Group, Inc.", - "title": "机构", - "shares_held": "1285506048", - "percent_shares_held": "8.46", - "shares_changed": "5812736", - "filing_date": "2026-02-14" + "title": "", + "shares_held": "1426283914.00", + "percent_shares_held": "9.71%", + "percent_shares_changed": "0.01%", + "shares_changed": "0.00", + "period": "Latest", + "filing_date": "2025/12/31" }, { - "object_id": 20181, + "object_id": "452583", "name": "BlackRock, Inc.", - "title": "机构", - "shares_held": "1071234816", - "percent_shares_held": "7.05", - "shares_changed": "-3104128", - "filing_date": "2026-02-05" + "title": "", + "shares_held": "1138572603.00", + "percent_shares_held": "7.75%", + "percent_shares_changed": "-0.06%", + "shares_changed": "-10565359.00", + "period": "Latest", + "filing_date": "2026/03/31" } ] } @@ -240,14 +243,15 @@ func main() { | Name | Type | Required | Description | | ---- | ---- | -------- | ----------- | -| periods | string[] | false | 可用的报告期列表,格式 `YYYY-MM-DD` | | info | object[] | false | 各报告期的股东数据 | -| ∟ period | string | false | 报告期,格式 `YYYY-MM-DD` | +| ∟ period | string | false | 报告期标签(如 `Latest`) | | ∟ share_holders | object[] | false | 股东列表(最多 20 条) | -| ∟ ∟ object_id | integer | false | 股东唯一 ID,可传入 `shareholder_detail` | +| ∟ ∟ object_id | string | false | 股东唯一 ID,可传入 `shareholder_detail` | | ∟ ∟ name | string | false | 股东名称 | | ∟ ∟ title | string | false | 股东类型(机构 / 个人 / 内部人) | | ∟ ∟ shares_held | string | false | 持股数量 | -| ∟ ∟ percent_shares_held | string | false | 持股比例(百分比) | +| ∟ ∟ percent_shares_held | string | false | 持股比例,含 `%` 符号(如 `9.71%`) | +| ∟ ∟ percent_shares_changed | string | false | 持股比例变动,含 `%` 符号 | | ∟ ∟ shares_changed | string | false | 持股变动数量(正增负减) | -| ∟ ∟ filing_date | string | false | 申报日期,格式 `YYYY-MM-DD` | +| ∟ ∟ period | string | false | 该条目的报告期标签 | +| ∟ ∟ filing_date | string | false | 申报日期 | diff --git a/docs/zh-CN/docs/fundamental/fundamental/valuation_comparison.md b/docs/zh-CN/docs/fundamental/fundamental/valuation_comparison.md index ba296f86..0a9eef41 100644 --- a/docs/zh-CN/docs/fundamental/fundamental/valuation_comparison.md +++ b/docs/zh-CN/docs/fundamental/fundamental/valuation_comparison.md @@ -203,29 +203,42 @@ func main() { "data": { "list": [ { - "symbol": "AAPL.US", + "counter_id": "ST/US/AAPL", "name": "苹果公司", + "currency": "USD", "market_value": "3241500000000", "price_close": "213.49", "pe": "32.15", "pb": "50.21", "ps": "8.04", + "roe": "136.45", + "eps": "6.43", + "bps": "4.38", + "dps": "0.99", + "div_yld": "0.46", + "assets": "371082000000", "history": [ - { "date": "2026-05-01", "pe": "32.15", "pb": "50.21", "ps": "8.04" }, - { "date": "2026-04-01", "pe": "28.73", "pb": "46.88", "ps": "7.52" } + { "date": "1622520000", "pe": "37.56", "pb": "30.16", "ps": "6.41" }, + { "date": "1625112000", "pe": "41.49", "pb": "35.64", "ps": "6.60" } ] }, { - "symbol": "MSFT.US", + "counter_id": "ST/US/MSFT", "name": "微软", + "currency": "USD", "market_value": "3085000000000", "price_close": "415.32", "pe": "35.42", "pb": "12.87", "ps": "12.61", + "roe": "38.21", + "eps": "11.72", + "bps": "32.28", + "dps": "3.32", + "div_yld": "0.80", + "assets": "512163000000", "history": [ - { "date": "2026-05-01", "pe": "35.42", "pb": "12.87", "ps": "12.61" }, - { "date": "2026-04-01", "pe": "33.10", "pb": "12.01", "ps": "11.94" } + { "date": "1622520000", "pe": "33.12", "pb": "11.94", "ps": "11.84" } ] } ] @@ -249,15 +262,22 @@ func main() { | Name | Type | Required | Description | | ---- | ---- | -------- | ----------- | | list | object[] | false | 股票估值对比列表 | -| ∟ symbol | string | false | 证券代码 | +| ∟ counter_id | string | false | Counter ID(如 `ST/US/AAPL`) | | ∟ name | string | false | 证券名称 | -| ∟ market_value | string | false | 市值(结果货币) | +| ∟ currency | string | false | 数值所用货币 | +| ∟ market_value | string | false | 市值 | | ∟ price_close | string | false | 最新收盘价 | | ∟ pe | string | false | 市盈率(TTM) | | ∟ pb | string | false | 市净率 | | ∟ ps | string | false | 市销率(TTM) | +| ∟ roe | string | false | 净资产收益率(%) | +| ∟ eps | string | false | 每股收益(TTM) | +| ∟ bps | string | false | 每股净资产 | +| ∟ dps | string | false | 每股派息(TTM) | +| ∟ div_yld | string | false | 股息率(%) | +| ∟ assets | string | false | 总资产 | | ∟ history | object[] | false | 历史估值时间序列 | -| ∟ ∟ date | string | false | 日期,格式 `YYYY-MM-DD` | +| ∟ ∟ date | string | false | 日期(Unix 时间戳,秒) | | ∟ ∟ pe | string | false | 历史 PE | | ∟ ∟ pb | string | false | 历史 PB | | ∟ ∟ ps | string | false | 历史 PS | diff --git a/docs/zh-CN/docs/market/status/rank_list.md b/docs/zh-CN/docs/market/status/rank_list.md index 873ece0e..44eb32b8 100644 --- a/docs/zh-CN/docs/market/status/rank_list.md +++ b/docs/zh-CN/docs/market/status/rank_list.md @@ -196,26 +196,20 @@ func main() { "code": 0, "message": "success", "data": { + "bmp": false, "lists": [ { - "symbol": "NVDA.US", - "name": "英伟达", - "last_done": "135.62", - "chg": "+2.84%", - "inflow": "1250000000", - "market_cap": "3312000000000", - "pre_post_price": "136.10", - "pre_post_chg": "+0.35%" - }, - { - "symbol": "TSLA.US", - "name": "特斯拉", - "last_done": "342.15", - "chg": "-1.23%", - "inflow": "875000000", - "market_cap": "1098000000000", - "pre_post_price": "341.00", - "pre_post_chg": "-0.34%" + "code": "MU", + "counter_id": "ST/US/MU", + "name": "美光科技", + "market": "US", + "last_done": "698.740", + "chg": "0.0252", + "inflow": "-347041642", + "market_cap": "787992890796", + "industry": "半导体厂商", + "pre_post_price": "700.10", + "pre_post_chg": "0.0020" } ] } @@ -237,12 +231,16 @@ func main() { | Name | Type | Required | Description | | ---- | ---- | -------- | ----------- | +| bmp | boolean | false | 是否为盘前预览数据 | | lists | object[] | false | 排行榜股票列表 | -| ∟ symbol | string | false | 证券代码 | +| ∟ code | string | false | 股票代码(如 `MU`) | +| ∟ counter_id | string | false | Counter ID(如 `ST/US/MU`) | | ∟ name | string | false | 证券名称 | +| ∟ market | string | false | 市场:`US`、`HK`、`CN`、`SG` | | ∟ last_done | string | false | 最新成交价 | -| ∟ chg | string | false | 涨跌幅(含符号,如 `+2.84%`) | +| ∟ chg | string | false | 涨跌幅(如 `0.0252`) | | ∟ inflow | string | false | 净流入资金(单位:所属市场货币) | | ∟ market_cap | string | false | 市值 | +| ∟ industry | string | false | 行业分类 | | ∟ pre_post_price | string | false | 盘前/盘后价格 | | ∟ pre_post_chg | string | false | 盘前/盘后涨跌幅 | diff --git a/docs/zh-CN/docs/market/status/stock_events.md b/docs/zh-CN/docs/market/status/stock_events.md index f00821b7..e4eb9596 100644 --- a/docs/zh-CN/docs/market/status/stock_events.md +++ b/docs/zh-CN/docs/market/status/stock_events.md @@ -202,34 +202,25 @@ func main() { "events": [ { "stock": { - "symbol": "9988.HK", - "name": "阿里巴巴", - "change": "+4.82%", - "labels": ["港股", "科技"] + "code": "TSLA", + "counter_id": "ST/US/TSLA", + "name": "特斯拉", + "change": "-0.0388", + "last_done": "404.110", + "market": "US", + "labels": ["汽车制造商"], + "logo": "https://assets.lbkrs.com/ticker/ST/US/TSLA.png", + "trade_status": 0 }, - "timestamp": 1747728600000, - "alert_reason": "财报超预期,营收增长 8%", - "alert_type": "earnings_beat", - "post": { - "id": "post_abc123", - "title": "阿里巴巴 Q4 财报解读:云业务强劲增长", - "url": "https://longbridge.com/news/post_abc123" - } - }, - { - "stock": { - "symbol": "NVDA.US", - "name": "英伟达", - "change": "+3.21%", - "labels": ["美股", "半导体"] - }, - "timestamp": 1747725000000, - "alert_reason": "大宗买入,成交量放大 3 倍", - "alert_type": "volume_spike", + "timestamp": "1779202097", + "alert_reason": "波动超 20 日均值", + "alert_type": 11, "post": null } ], - "next_params": "eyJvZmZzZXQiOjIwfQ==" + "next_params": { + "visited": ["11098290", "11098478", "11099705"] + } } } ``` @@ -251,15 +242,17 @@ func main() { | ---- | ---- | -------- | ----------- | | events | object[] | false | 异动股票列表 | | ∟ stock | object | false | 股票基本信息 | -| ∟ ∟ symbol | string | false | 证券代码 | +| ∟ ∟ code | string | false | 股票代码(如 `TSLA`) | +| ∟ ∟ counter_id | string | false | Counter ID(如 `ST/US/TSLA`) | | ∟ ∟ name | string | false | 证券名称 | -| ∟ ∟ change | string | false | 涨跌幅(含符号,如 `+4.82%`) | -| ∟ ∟ labels | string[] | false | 标签列表(市场、行业等) | -| ∟ timestamp | integer | false | 异动时间(Unix 毫秒时间戳) | +| ∟ ∟ change | string | false | 涨跌幅(如 `-0.0388`) | +| ∟ ∟ last_done | string | false | 最新成交价 | +| ∟ ∟ market | string | false | 市场:`US`、`HK`、`CN`、`SG` | +| ∟ ∟ labels | string[] | false | 行业 / 主题标签 | +| ∟ ∟ logo | string | false | Logo 图片 URL | +| ∟ ∟ trade_status | integer | false | 交易状态码 | +| ∟ timestamp | string | false | 异动时间(Unix 秒,字符串格式) | | ∟ alert_reason | string | false | 异动原因描述 | -| ∟ alert_type | string | false | 异动类型标识符 | +| ∟ alert_type | integer | false | 异动类型代码 | | ∟ post | object | false | 关联新闻/文章;无关联时为 `null` | -| ∟ ∟ id | string | false | 文章 ID | -| ∟ ∟ title | string | false | 文章标题 | -| ∟ ∟ url | string | false | 文章链接 | -| next_params | string | false | 翻页参数(Base64 编码),传入下次请求以获取下一页 | +| next_params | object | false | 翻页参数对象,传入下次请求以获取下一页 | diff --git a/docs/zh-CN/docs/screener/screener_indicators.md b/docs/zh-CN/docs/screener/screener_indicators.md index c790a238..8ffb70de 100644 --- a/docs/zh-CN/docs/screener/screener_indicators.md +++ b/docs/zh-CN/docs/screener/screener_indicators.md @@ -192,51 +192,46 @@ func main() { "code": 0, "message": "success", "data": { - "indicators": [ + "groups": [ { - "id": 10, - "key": "filter_pe", - "name": "市盈率", - "unit": "x", - "value_min": 0, - "value_max": 1000, - "step": 1 + "group_name": "市场", + "group_type": "range", + "indicators": [ + { + "id": -1, + "key": "filter_market", + "name": "市场", + "unit": "", + "category": 0, + "description": "", + "default_range": [], + "default_selected": false, + "places": 0, + "sub_indicators": [], + "tech_indicators": [], + "value_ranges": [] + } + ] }, { - "id": 11, - "key": "filter_pb", - "name": "市净率", - "unit": "x", - "value_min": 0, - "value_max": 100, - "step": 0.1 - }, - { - "id": 20, - "key": "filter_marketcap", - "name": "市值", - "unit": "亿", - "value_min": 0, - "value_max": 100000, - "step": 10 - }, - { - "id": 25, - "key": "filter_roe", - "name": "净资产收益率", - "unit": "%", - "value_min": -100, - "value_max": 200, - "step": 1 - }, - { - "id": 30, - "key": "filter_revenue_growth", - "name": "营收增速", - "unit": "%", - "value_min": -100, - "value_max": 500, - "step": 1 + "group_name": "行情类指标", + "group_type": "Quotes", + "indicators": [ + { + "id": 1, + "key": "filter_marketcap", + "name": "市值", + "unit": "亿", + "category": 0, + "description": "", + "default_range": [], + "default_selected": false, + "places": 0, + "sub_indicators": [], + "tech_indicators": [], + "value_ranges": [] + } + ] } ] } @@ -258,11 +253,19 @@ func main() { | Name | Type | Required | Description | | ---- | ---- | -------- | ----------- | -| indicators | object[] | false | 可用指标列表 | -| ∟ id | integer | false | 指标 ID | -| ∟ key | string | false | 指标键值,用于构建筛选条件(格式:`filter_::`) | -| ∟ name | string | false | 指标显示名称 | -| ∟ unit | string | false | 单位(如 `x`、`%`、`亿`) | -| ∟ value_min | number | false | 指标允许的最小值 | -| ∟ value_max | number | false | 指标允许的最大值 | -| ∟ step | number | false | 建议步长 | +| groups | object[] | false | 指标分组 | +| ∟ group_name | string | false | 分组名称 | +| ∟ group_type | string | false | 分组类型(如 `range`、`Quotes`、`DividendIndex`) | +| ∟ indicators | object[] | false | 该分组下的指标列表 | +| ∟ ∟ id | integer | false | 指标 ID | +| ∟ ∟ key | string | false | 指标键值,用于构建筛选条件 | +| ∟ ∟ name | string | false | 指标显示名称 | +| ∟ ∟ unit | string | false | 单位(如 `%`、`亿`) | +| ∟ ∟ category | integer | false | 指标分类代码 | +| ∟ ∟ description | string | false | 指标描述 | +| ∟ ∟ default_range | array | false | 默认筛选范围 | +| ∟ ∟ default_selected | boolean | false | 是否默认选中 | +| ∟ ∟ places | integer | false | 显示小数位数 | +| ∟ ∟ sub_indicators | array | false | 子指标定义 | +| ∟ ∟ tech_indicators | array | false | 技术指标定义 | +| ∟ ∟ value_ranges | array | false | 指标可选值范围 | diff --git a/docs/zh-CN/docs/screener/screener_recommend_strategies.md b/docs/zh-CN/docs/screener/screener_recommend_strategies.md index ab65cd36..4ca32915 100644 --- a/docs/zh-CN/docs/screener/screener_recommend_strategies.md +++ b/docs/zh-CN/docs/screener/screener_recommend_strategies.md @@ -194,21 +194,21 @@ func main() { "data": { "screeners": [ { - "id": 1, - "name": "高盈利低估值", - "average_day_chg": "+0.82%", - "stocks": ["AAPL.US", "MSFT.US", "GOOGL.US"], + "id": "1", + "name": "高股息蓝筹股", "groups": [ { - "group_name": "估值", + "group_name": "范围", + "group_type": "range", "indicators": [ - { "id": 10, "key": "filter_pe", "name": "市盈率", "unit": "x", "min": 0, "max": 30 } + { "id": -1, "key": "filter_market", "name": "港股", "unit": "", "min": "", "max": "", "value": "HK", "tech_data": [] } ] }, { - "group_name": "盈利能力", + "group_name": "分红指标", + "group_type": "DividendIndex", "indicators": [ - { "id": 25, "key": "filter_roe", "name": "净资产收益率", "unit": "%", "min": 15, "max": null } + { "id": 29, "key": "filter_divyld", "name": "股息率 (TTM)", "unit": "%", "min": "4", "max": "", "value": "", "tech_data": [] } ] } ] @@ -234,16 +234,17 @@ func main() { | Name | Type | Required | Description | | ---- | ---- | -------- | ----------- | | screeners | object[] | false | 策略列表 | -| ∟ id | integer | false | 策略 ID | +| ∟ id | string | false | 策略 ID | | ∟ name | string | false | 策略名称 | -| ∟ average_day_chg | string | false | 策略标的近期平均日涨跌幅 | -| ∟ stocks | string[] | false | 策略当前筛选出的股票代码列表 | | ∟ groups | object[] | false | 策略过滤条件分组 | | ∟ ∟ group_name | string | false | 分组名称 | +| ∟ ∟ group_type | string | false | 分组类型(如 `range`、`Quotes`、`DividendIndex`) | | ∟ ∟ indicators | object[] | false | 该分组下的指标条件 | | ∟ ∟ ∟ id | integer | false | 指标 ID | | ∟ ∟ ∟ key | string | false | 指标键值,可用于 `screener_search` | | ∟ ∟ ∟ name | string | false | 指标名称 | | ∟ ∟ ∟ unit | string | false | 指标单位 | -| ∟ ∟ ∟ min | number | false | 策略设定的最小值 | -| ∟ ∟ ∟ max | number | false | 策略设定的最大值;`null` 表示无上限 | +| ∟ ∟ ∟ min | string | false | 策略设定的最小值;空字符串表示无下限 | +| ∟ ∟ ∟ max | string | false | 策略设定的最大值;空字符串表示无上限 | +| ∟ ∟ ∟ value | string | false | 固定值(用于非范围型指标,如市场选择器) | +| ∟ ∟ ∟ tech_data | array | false | 技术指标数据数组 | diff --git a/docs/zh-CN/docs/screener/screener_strategy.md b/docs/zh-CN/docs/screener/screener_strategy.md index 19081c85..91e2e6ab 100644 --- a/docs/zh-CN/docs/screener/screener_strategy.md +++ b/docs/zh-CN/docs/screener/screener_strategy.md @@ -194,40 +194,36 @@ func main() { "code": 0, "message": "success", "data": { - "id": 42, - "name": "我的成长股策略", "groups": [ { - "group_name": "估值", + "group_name": "范围", + "group_type": "range", "indicators": [ { - "id": 10, - "key": "filter_pe", - "name": "市盈率", - "unit": "x", - "min": 5, - "max": 30 - }, - { - "id": 11, - "key": "filter_pb", - "name": "市净率", - "unit": "x", - "min": 1, - "max": 10 + "id": -1, + "key": "filter_market", + "name": "港股", + "unit": "", + "min": "", + "max": "", + "value": "HK", + "tech_data": [] } ] }, { - "group_name": "成长性", + "group_name": "行情类指标", + "group_type": "Quotes", "indicators": [ { - "id": 30, - "key": "filter_revenue_growth", - "name": "营收增速", - "unit": "%", - "min": 20, - "max": null + "id": 1, + "key": "filter_marketcap", + "name": "市值", + "unit": "亿", + "min": "100", + "max": "", + "value": "", + "tech_data": [] } ] } @@ -251,14 +247,15 @@ func main() { | Name | Type | Required | Description | | ---- | ---- | -------- | ----------- | -| id | integer | false | 策略 ID | -| name | string | false | 策略名称 | | groups | object[] | false | 指标分组列表 | | ∟ group_name | string | false | 分组名称 | +| ∟ group_type | string | false | 分组类型(如 `range`、`Quotes`、`DividendIndex`) | | ∟ indicators | object[] | false | 该分组下的指标条件 | | ∟ ∟ id | integer | false | 指标 ID | | ∟ ∟ key | string | false | 指标键值 | | ∟ ∟ name | string | false | 指标显示名称 | -| ∟ ∟ unit | string | false | 指标单位(如 `x`、`%`、`亿` 等) | -| ∟ ∟ min | number | false | 最小值;`null` 表示无下限 | -| ∟ ∟ max | number | false | 最大值;`null` 表示无上限 | +| ∟ ∟ unit | string | false | 指标单位(如 `%`、`亿` 等) | +| ∟ ∟ min | string | false | 最小值;空字符串表示无下限 | +| ∟ ∟ max | string | false | 最大值;空字符串表示无上限 | +| ∟ ∟ value | string | false | 固定值(用于非范围型指标,如市场选择器) | +| ∟ ∟ tech_data | array | false | 技术指标数据数组 | diff --git a/docs/zh-HK/docs/fundamental/fundamental/shareholder_detail.md b/docs/zh-HK/docs/fundamental/fundamental/shareholder_detail.md index f670fcfc..af7b1478 100644 --- a/docs/zh-HK/docs/fundamental/fundamental/shareholder_detail.md +++ b/docs/zh-HK/docs/fundamental/fundamental/shareholder_detail.md @@ -196,36 +196,26 @@ func main() { "code": 0, "message": "success", "data": { + "name": "The Vanguard Group, Inc.", + "title": "", + "avatar": "", "owner_source": "Institution", - "holding_summary": [ - { - "period": "2025-12-31", - "accum_buy": "8500000", - "accum_sell": "2687264", - "stock_price": "243.08" - }, - { - "period": "2025-09-30", - "accum_buy": "3200000", - "accum_sell": "1500000", - "stock_price": "226.51" - } - ], + "holding_periods": [], + "holding_details": [], + "holding_summary": [], + "trading_periods": ["Past 1 Month", "Past 3 Months", "Past 1 Year", "Past 3 Years"], "tradings": [ { - "period": "2025-12-31", + "period": "Past 1 Month", + "accum_buy": "8500000.00", + "accum_sell": "2687264.00", + "net_buy": "5812736.00", "trading_details": [ { "trading_date": "2025-12-18", "trading_shares": "5200000", "trading_price": "248.12", "trading_type": "Buy" - }, - { - "trading_date": "2025-11-05", - "trading_shares": "2687264", - "trading_price": "222.91", - "trading_type": "Sell" } ] } @@ -249,16 +239,21 @@ func main() { | Name | Type | Required | Description | | ---- | ---- | -------- | ----------- | +| name | string | false | 股東名稱 | +| title | string | false | 股東頭銜 / 類型 | +| avatar | string | false | 頭像 URL | | owner_source | string | false | 股東類型:`Company`、`Institution`、`Person`、`Insider` | -| holding_summary | object[] | false | 各報告期持倉匯總 | -| ∟ period | string | false | 報告期,格式 `YYYY-MM-DD` | -| ∟ accum_buy | string | false | 該期累計買入股數 | -| ∟ accum_sell | string | false | 該期累計賣出股數 | -| ∟ stock_price | string | false | 報告期末股價 | -| tradings | object[] | false | 各報告期交易明細 | -| ∟ period | string | false | 報告期,格式 `YYYY-MM-DD` | -| ∟ trading_details | object[] | false | 該報告期內的交易記錄 | -| ∟ ∟ trading_date | string | false | 交易日期,格式 `YYYY-MM-DD` | +| holding_periods | string[] | false | 可用的持倉報告期列表 | +| holding_details | object[] | false | 持倉明細記錄 | +| holding_summary | object[] | false | 持倉匯總記錄 | +| trading_periods | string[] | false | 可用的交易統計區間(如 `Past 1 Month`、`Past 3 Months`) | +| tradings | object[] | false | 各區間交易匯總 | +| ∟ period | string | false | 區間標籤(如 `Past 1 Month`) | +| ∟ accum_buy | string | false | 該區間累計買入股數 | +| ∟ accum_sell | string | false | 該區間累計賣出股數 | +| ∟ net_buy | string | false | 該區間淨買入股數(買入減賣出) | +| ∟ trading_details | object[] | false | 該區間內的具體交易記錄 | +| ∟ ∟ trading_date | string | false | 交易日期 | | ∟ ∟ trading_shares | string | false | 交易股數 | | ∟ ∟ trading_price | string | false | 交易價格 | | ∟ ∟ trading_type | string | false | 交易方向:`Buy` 或 `Sell` | diff --git a/docs/zh-HK/docs/fundamental/fundamental/shareholder_top.md b/docs/zh-HK/docs/fundamental/fundamental/shareholder_top.md index adb81279..d5e7cf7e 100644 --- a/docs/zh-HK/docs/fundamental/fundamental/shareholder_top.md +++ b/docs/zh-HK/docs/fundamental/fundamental/shareholder_top.md @@ -195,28 +195,31 @@ func main() { "code": 0, "message": "success", "data": { - "periods": ["2025-12-31", "2025-09-30"], "info": [ { - "period": "2025-12-31", + "period": "Latest", "share_holders": [ { - "object_id": 19463, + "object_id": "148057", "name": "The Vanguard Group, Inc.", - "title": "機構", - "shares_held": "1285506048", - "percent_shares_held": "8.46", - "shares_changed": "5812736", - "filing_date": "2026-02-14" + "title": "", + "shares_held": "1426283914.00", + "percent_shares_held": "9.71%", + "percent_shares_changed": "0.01%", + "shares_changed": "0.00", + "period": "Latest", + "filing_date": "2025/12/31" }, { - "object_id": 20181, + "object_id": "452583", "name": "BlackRock, Inc.", - "title": "機構", - "shares_held": "1071234816", - "percent_shares_held": "7.05", - "shares_changed": "-3104128", - "filing_date": "2026-02-05" + "title": "", + "shares_held": "1138572603.00", + "percent_shares_held": "7.75%", + "percent_shares_changed": "-0.06%", + "shares_changed": "-10565359.00", + "period": "Latest", + "filing_date": "2026/03/31" } ] } @@ -240,14 +243,15 @@ func main() { | Name | Type | Required | Description | | ---- | ---- | -------- | ----------- | -| periods | string[] | false | 可用的報告期列表,格式 `YYYY-MM-DD` | | info | object[] | false | 各報告期的股東數據 | -| ∟ period | string | false | 報告期,格式 `YYYY-MM-DD` | +| ∟ period | string | false | 報告期標籤(如 `Latest`) | | ∟ share_holders | object[] | false | 股東列表(最多 20 條) | -| ∟ ∟ object_id | integer | false | 股東唯一 ID,可傳入 `shareholder_detail` | +| ∟ ∟ object_id | string | false | 股東唯一 ID,可傳入 `shareholder_detail` | | ∟ ∟ name | string | false | 股東名稱 | | ∟ ∟ title | string | false | 股東類型(機構 / 個人 / 內部人) | | ∟ ∟ shares_held | string | false | 持股數量 | -| ∟ ∟ percent_shares_held | string | false | 持股比例(百分比) | +| ∟ ∟ percent_shares_held | string | false | 持股比例,含 `%` 符號(如 `9.71%`) | +| ∟ ∟ percent_shares_changed | string | false | 持股比例變動,含 `%` 符號 | | ∟ ∟ shares_changed | string | false | 持股變動數量(正增負減) | -| ∟ ∟ filing_date | string | false | 申報日期,格式 `YYYY-MM-DD` | +| ∟ ∟ period | string | false | 該條目的報告期標籤 | +| ∟ ∟ filing_date | string | false | 申報日期 | diff --git a/docs/zh-HK/docs/fundamental/fundamental/valuation_comparison.md b/docs/zh-HK/docs/fundamental/fundamental/valuation_comparison.md index 03402eee..63a8252e 100644 --- a/docs/zh-HK/docs/fundamental/fundamental/valuation_comparison.md +++ b/docs/zh-HK/docs/fundamental/fundamental/valuation_comparison.md @@ -203,29 +203,42 @@ func main() { "data": { "list": [ { - "symbol": "AAPL.US", + "counter_id": "ST/US/AAPL", "name": "蘋果公司", + "currency": "USD", "market_value": "3241500000000", "price_close": "213.49", "pe": "32.15", "pb": "50.21", "ps": "8.04", + "roe": "136.45", + "eps": "6.43", + "bps": "4.38", + "dps": "0.99", + "div_yld": "0.46", + "assets": "371082000000", "history": [ - { "date": "2026-05-01", "pe": "32.15", "pb": "50.21", "ps": "8.04" }, - { "date": "2026-04-01", "pe": "28.73", "pb": "46.88", "ps": "7.52" } + { "date": "1622520000", "pe": "37.56", "pb": "30.16", "ps": "6.41" }, + { "date": "1625112000", "pe": "41.49", "pb": "35.64", "ps": "6.60" } ] }, { - "symbol": "MSFT.US", + "counter_id": "ST/US/MSFT", "name": "微軟", + "currency": "USD", "market_value": "3085000000000", "price_close": "415.32", "pe": "35.42", "pb": "12.87", "ps": "12.61", + "roe": "38.21", + "eps": "11.72", + "bps": "32.28", + "dps": "3.32", + "div_yld": "0.80", + "assets": "512163000000", "history": [ - { "date": "2026-05-01", "pe": "35.42", "pb": "12.87", "ps": "12.61" }, - { "date": "2026-04-01", "pe": "33.10", "pb": "12.01", "ps": "11.94" } + { "date": "1622520000", "pe": "33.12", "pb": "11.94", "ps": "11.84" } ] } ] @@ -249,15 +262,22 @@ func main() { | Name | Type | Required | Description | | ---- | ---- | -------- | ----------- | | list | object[] | false | 股票估值對比列表 | -| ∟ symbol | string | false | 證券代碼 | +| ∟ counter_id | string | false | Counter ID(如 `ST/US/AAPL`) | | ∟ name | string | false | 證券名稱 | -| ∟ market_value | string | false | 市值(結果貨幣) | +| ∟ currency | string | false | 數值所用貨幣 | +| ∟ market_value | string | false | 市值 | | ∟ price_close | string | false | 最新收盤價 | | ∟ pe | string | false | 市盈率(TTM) | | ∟ pb | string | false | 市淨率 | | ∟ ps | string | false | 市銷率(TTM) | +| ∟ roe | string | false | 淨資產收益率(%) | +| ∟ eps | string | false | 每股收益(TTM) | +| ∟ bps | string | false | 每股淨資產 | +| ∟ dps | string | false | 每股派息(TTM) | +| ∟ div_yld | string | false | 股息率(%) | +| ∟ assets | string | false | 總資產 | | ∟ history | object[] | false | 歷史估值時間序列 | -| ∟ ∟ date | string | false | 日期,格式 `YYYY-MM-DD` | +| ∟ ∟ date | string | false | 日期(Unix 時間戳,秒) | | ∟ ∟ pe | string | false | 歷史 PE | | ∟ ∟ pb | string | false | 歷史 PB | | ∟ ∟ ps | string | false | 歷史 PS | diff --git a/docs/zh-HK/docs/market/status/rank_list.md b/docs/zh-HK/docs/market/status/rank_list.md index 9bc44c0b..e6813a4d 100644 --- a/docs/zh-HK/docs/market/status/rank_list.md +++ b/docs/zh-HK/docs/market/status/rank_list.md @@ -196,26 +196,20 @@ func main() { "code": 0, "message": "success", "data": { + "bmp": false, "lists": [ { - "symbol": "NVDA.US", - "name": "英偉達", - "last_done": "135.62", - "chg": "+2.84%", - "inflow": "1250000000", - "market_cap": "3312000000000", - "pre_post_price": "136.10", - "pre_post_chg": "+0.35%" - }, - { - "symbol": "TSLA.US", - "name": "特斯拉", - "last_done": "342.15", - "chg": "-1.23%", - "inflow": "875000000", - "market_cap": "1098000000000", - "pre_post_price": "341.00", - "pre_post_chg": "-0.34%" + "code": "MU", + "counter_id": "ST/US/MU", + "name": "美光科技", + "market": "US", + "last_done": "698.740", + "chg": "0.0252", + "inflow": "-347041642", + "market_cap": "787992890796", + "industry": "半導體廠商", + "pre_post_price": "700.10", + "pre_post_chg": "0.0020" } ] } @@ -237,12 +231,16 @@ func main() { | Name | Type | Required | Description | | ---- | ---- | -------- | ----------- | +| bmp | boolean | false | 是否為盤前預覽數據 | | lists | object[] | false | 排行榜股票列表 | -| ∟ symbol | string | false | 證券代碼 | +| ∟ code | string | false | 股票代碼(如 `MU`) | +| ∟ counter_id | string | false | Counter ID(如 `ST/US/MU`) | | ∟ name | string | false | 證券名稱 | +| ∟ market | string | false | 市場:`US`、`HK`、`CN`、`SG` | | ∟ last_done | string | false | 最新成交價 | -| ∟ chg | string | false | 漲跌幅(含符號,如 `+2.84%`) | +| ∟ chg | string | false | 漲跌幅(如 `0.0252`) | | ∟ inflow | string | false | 淨流入資金(單位:所屬市場貨幣) | | ∟ market_cap | string | false | 市值 | +| ∟ industry | string | false | 行業分類 | | ∟ pre_post_price | string | false | 盤前/盤後價格 | | ∟ pre_post_chg | string | false | 盤前/盤後漲跌幅 | diff --git a/docs/zh-HK/docs/market/status/stock_events.md b/docs/zh-HK/docs/market/status/stock_events.md index 8fc2d64d..234d6a3f 100644 --- a/docs/zh-HK/docs/market/status/stock_events.md +++ b/docs/zh-HK/docs/market/status/stock_events.md @@ -202,34 +202,25 @@ func main() { "events": [ { "stock": { - "symbol": "9988.HK", - "name": "阿里巴巴", - "change": "+4.82%", - "labels": ["港股", "科技"] + "code": "TSLA", + "counter_id": "ST/US/TSLA", + "name": "特斯拉", + "change": "-0.0388", + "last_done": "404.110", + "market": "US", + "labels": ["汽車製造商"], + "logo": "https://assets.lbkrs.com/ticker/ST/US/TSLA.png", + "trade_status": 0 }, - "timestamp": 1747728600000, - "alert_reason": "財報超預期,營收增長 8%", - "alert_type": "earnings_beat", - "post": { - "id": "post_abc123", - "title": "阿里巴巴 Q4 財報解讀:雲業務強勁增長", - "url": "https://longbridge.com/news/post_abc123" - } - }, - { - "stock": { - "symbol": "NVDA.US", - "name": "英偉達", - "change": "+3.21%", - "labels": ["美股", "半導體"] - }, - "timestamp": 1747725000000, - "alert_reason": "大宗買入,成交量放大 3 倍", - "alert_type": "volume_spike", + "timestamp": "1779202097", + "alert_reason": "波動超 20 日均值", + "alert_type": 11, "post": null } ], - "next_params": "eyJvZmZzZXQiOjIwfQ==" + "next_params": { + "visited": ["11098290", "11098478", "11099705"] + } } } ``` @@ -251,15 +242,17 @@ func main() { | ---- | ---- | -------- | ----------- | | events | object[] | false | 異動股票列表 | | ∟ stock | object | false | 股票基本信息 | -| ∟ ∟ symbol | string | false | 證券代碼 | +| ∟ ∟ code | string | false | 股票代碼(如 `TSLA`) | +| ∟ ∟ counter_id | string | false | Counter ID(如 `ST/US/TSLA`) | | ∟ ∟ name | string | false | 證券名稱 | -| ∟ ∟ change | string | false | 漲跌幅(含符號,如 `+4.82%`) | -| ∟ ∟ labels | string[] | false | 標籤列表(市場、行業等) | -| ∟ timestamp | integer | false | 異動時間(Unix 毫秒時間戳) | +| ∟ ∟ change | string | false | 漲跌幅(如 `-0.0388`) | +| ∟ ∟ last_done | string | false | 最新成交價 | +| ∟ ∟ market | string | false | 市場:`US`、`HK`、`CN`、`SG` | +| ∟ ∟ labels | string[] | false | 行業 / 主題標籤 | +| ∟ ∟ logo | string | false | Logo 圖片 URL | +| ∟ ∟ trade_status | integer | false | 交易狀態碼 | +| ∟ timestamp | string | false | 異動時間(Unix 秒,字符串格式) | | ∟ alert_reason | string | false | 異動原因描述 | -| ∟ alert_type | string | false | 異動類型標識符 | +| ∟ alert_type | integer | false | 異動類型代碼 | | ∟ post | object | false | 關聯新聞/文章;無關聯時為 `null` | -| ∟ ∟ id | string | false | 文章 ID | -| ∟ ∟ title | string | false | 文章標題 | -| ∟ ∟ url | string | false | 文章鏈接 | -| next_params | string | false | 翻頁參數(Base64 編碼),傳入下次請求以獲取下一頁 | +| next_params | object | false | 翻頁參數對象,傳入下次請求以獲取下一頁 | diff --git a/docs/zh-HK/docs/screener/screener_indicators.md b/docs/zh-HK/docs/screener/screener_indicators.md index d74e0240..d7ef5132 100644 --- a/docs/zh-HK/docs/screener/screener_indicators.md +++ b/docs/zh-HK/docs/screener/screener_indicators.md @@ -192,51 +192,46 @@ func main() { "code": 0, "message": "success", "data": { - "indicators": [ + "groups": [ { - "id": 10, - "key": "filter_pe", - "name": "市盈率", - "unit": "x", - "value_min": 0, - "value_max": 1000, - "step": 1 + "group_name": "市場", + "group_type": "range", + "indicators": [ + { + "id": -1, + "key": "filter_market", + "name": "市場", + "unit": "", + "category": 0, + "description": "", + "default_range": [], + "default_selected": false, + "places": 0, + "sub_indicators": [], + "tech_indicators": [], + "value_ranges": [] + } + ] }, { - "id": 11, - "key": "filter_pb", - "name": "市淨率", - "unit": "x", - "value_min": 0, - "value_max": 100, - "step": 0.1 - }, - { - "id": 20, - "key": "filter_marketcap", - "name": "市值", - "unit": "億", - "value_min": 0, - "value_max": 100000, - "step": 10 - }, - { - "id": 25, - "key": "filter_roe", - "name": "淨資產收益率", - "unit": "%", - "value_min": -100, - "value_max": 200, - "step": 1 - }, - { - "id": 30, - "key": "filter_revenue_growth", - "name": "營收增速", - "unit": "%", - "value_min": -100, - "value_max": 500, - "step": 1 + "group_name": "行情類指標", + "group_type": "Quotes", + "indicators": [ + { + "id": 1, + "key": "filter_marketcap", + "name": "市值", + "unit": "億", + "category": 0, + "description": "", + "default_range": [], + "default_selected": false, + "places": 0, + "sub_indicators": [], + "tech_indicators": [], + "value_ranges": [] + } + ] } ] } @@ -258,11 +253,19 @@ func main() { | Name | Type | Required | Description | | ---- | ---- | -------- | ----------- | -| indicators | object[] | false | 可用指標列表 | -| ∟ id | integer | false | 指標 ID | -| ∟ key | string | false | 指標鍵值,用於構建篩選條件(格式:`filter_::`) | -| ∟ name | string | false | 指標顯示名稱 | -| ∟ unit | string | false | 單位(如 `x`、`%`、`億`) | -| ∟ value_min | number | false | 指標允許的最小值 | -| ∟ value_max | number | false | 指標允許的最大值 | -| ∟ step | number | false | 建議步長 | +| groups | object[] | false | 指標分組 | +| ∟ group_name | string | false | 分組名稱 | +| ∟ group_type | string | false | 分組類型(如 `range`、`Quotes`、`DividendIndex`) | +| ∟ indicators | object[] | false | 該分組下的指標列表 | +| ∟ ∟ id | integer | false | 指標 ID | +| ∟ ∟ key | string | false | 指標鍵值,用於構建篩選條件 | +| ∟ ∟ name | string | false | 指標顯示名稱 | +| ∟ ∟ unit | string | false | 單位(如 `%`、`億`) | +| ∟ ∟ category | integer | false | 指標分類代碼 | +| ∟ ∟ description | string | false | 指標描述 | +| ∟ ∟ default_range | array | false | 默認篩選範圍 | +| ∟ ∟ default_selected | boolean | false | 是否默認選中 | +| ∟ ∟ places | integer | false | 顯示小數位數 | +| ∟ ∟ sub_indicators | array | false | 子指標定義 | +| ∟ ∟ tech_indicators | array | false | 技術指標定義 | +| ∟ ∟ value_ranges | array | false | 指標可選值範圍 | diff --git a/docs/zh-HK/docs/screener/screener_recommend_strategies.md b/docs/zh-HK/docs/screener/screener_recommend_strategies.md index 836223f8..4bdf581d 100644 --- a/docs/zh-HK/docs/screener/screener_recommend_strategies.md +++ b/docs/zh-HK/docs/screener/screener_recommend_strategies.md @@ -194,21 +194,21 @@ func main() { "data": { "screeners": [ { - "id": 1, - "name": "高盈利低估值", - "average_day_chg": "+0.82%", - "stocks": ["AAPL.US", "MSFT.US", "GOOGL.US"], + "id": "1", + "name": "高股息藍籌股", "groups": [ { - "group_name": "估值", + "group_name": "範圍", + "group_type": "range", "indicators": [ - { "id": 10, "key": "filter_pe", "name": "市盈率", "unit": "x", "min": 0, "max": 30 } + { "id": -1, "key": "filter_market", "name": "港股", "unit": "", "min": "", "max": "", "value": "HK", "tech_data": [] } ] }, { - "group_name": "盈利能力", + "group_name": "分紅指標", + "group_type": "DividendIndex", "indicators": [ - { "id": 25, "key": "filter_roe", "name": "淨資產收益率", "unit": "%", "min": 15, "max": null } + { "id": 29, "key": "filter_divyld", "name": "股息率 (TTM)", "unit": "%", "min": "4", "max": "", "value": "", "tech_data": [] } ] } ] @@ -234,16 +234,17 @@ func main() { | Name | Type | Required | Description | | ---- | ---- | -------- | ----------- | | screeners | object[] | false | 策略列表 | -| ∟ id | integer | false | 策略 ID | +| ∟ id | string | false | 策略 ID | | ∟ name | string | false | 策略名稱 | -| ∟ average_day_chg | string | false | 策略標的近期平均日漲跌幅 | -| ∟ stocks | string[] | false | 策略當前篩選出的股票代碼列表 | | ∟ groups | object[] | false | 策略過濾條件分組 | | ∟ ∟ group_name | string | false | 分組名稱 | +| ∟ ∟ group_type | string | false | 分組類型(如 `range`、`Quotes`、`DividendIndex`) | | ∟ ∟ indicators | object[] | false | 該分組下的指標條件 | | ∟ ∟ ∟ id | integer | false | 指標 ID | | ∟ ∟ ∟ key | string | false | 指標鍵值,可用於 `screener_search` | | ∟ ∟ ∟ name | string | false | 指標名稱 | | ∟ ∟ ∟ unit | string | false | 指標單位 | -| ∟ ∟ ∟ min | number | false | 策略設定的最小值 | -| ∟ ∟ ∟ max | number | false | 策略設定的最大值;`null` 表示無上限 | +| ∟ ∟ ∟ min | string | false | 策略設定的最小值;空字符串表示無下限 | +| ∟ ∟ ∟ max | string | false | 策略設定的最大值;空字符串表示無上限 | +| ∟ ∟ ∟ value | string | false | 固定值(用於非範圍型指標,如市場選擇器) | +| ∟ ∟ ∟ tech_data | array | false | 技術指標數據數組 | diff --git a/docs/zh-HK/docs/screener/screener_strategy.md b/docs/zh-HK/docs/screener/screener_strategy.md index da8489b8..b06d78bf 100644 --- a/docs/zh-HK/docs/screener/screener_strategy.md +++ b/docs/zh-HK/docs/screener/screener_strategy.md @@ -194,40 +194,36 @@ func main() { "code": 0, "message": "success", "data": { - "id": 42, - "name": "我的成長股策略", "groups": [ { - "group_name": "估值", + "group_name": "範圍", + "group_type": "range", "indicators": [ { - "id": 10, - "key": "filter_pe", - "name": "市盈率", - "unit": "x", - "min": 5, - "max": 30 - }, - { - "id": 11, - "key": "filter_pb", - "name": "市淨率", - "unit": "x", - "min": 1, - "max": 10 + "id": -1, + "key": "filter_market", + "name": "港股", + "unit": "", + "min": "", + "max": "", + "value": "HK", + "tech_data": [] } ] }, { - "group_name": "成長性", + "group_name": "行情類指標", + "group_type": "Quotes", "indicators": [ { - "id": 30, - "key": "filter_revenue_growth", - "name": "營收增速", - "unit": "%", - "min": 20, - "max": null + "id": 1, + "key": "filter_marketcap", + "name": "市值", + "unit": "億", + "min": "100", + "max": "", + "value": "", + "tech_data": [] } ] } @@ -251,14 +247,15 @@ func main() { | Name | Type | Required | Description | | ---- | ---- | -------- | ----------- | -| id | integer | false | 策略 ID | -| name | string | false | 策略名稱 | | groups | object[] | false | 指標分組列表 | | ∟ group_name | string | false | 分組名稱 | +| ∟ group_type | string | false | 分組類型(如 `range`、`Quotes`、`DividendIndex`) | | ∟ indicators | object[] | false | 該分組下的指標條件 | | ∟ ∟ id | integer | false | 指標 ID | | ∟ ∟ key | string | false | 指標鍵值 | | ∟ ∟ name | string | false | 指標顯示名稱 | -| ∟ ∟ unit | string | false | 指標單位(如 `x`、`%`、`億` 等) | -| ∟ ∟ min | number | false | 最小值;`null` 表示無下限 | -| ∟ ∟ max | number | false | 最大值;`null` 表示無上限 | +| ∟ ∟ unit | string | false | 指標單位(如 `%`、`億` 等) | +| ∟ ∟ min | string | false | 最小值;空字符串表示無下限 | +| ∟ ∟ max | string | false | 最大值;空字符串表示無上限 | +| ∟ ∟ value | string | false | 固定值(用於非範圍型指標,如市場選擇器) | +| ∟ ∟ tech_data | array | false | 技術指標數據數組 |