From 46259e30b4e882cdc61f8d203e158b772c958762 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Tue, 9 Jun 2026 19:33:05 +0800 Subject: [PATCH 01/28] feat(fundamental): add economic_indicator_list and economic_indicator methods Two new methods on FundamentalContext across all language SDKs: - economic_indicator_list: GET /v1/quote/macrodata - economic_indicator: GET /v1/quote/macrodata/{indicator_code} New types: MultiLanguageText, EconomicIndicatorInfo, EconomicIndicatorData, EconomicIndicatorResponse. Co-Authored-By: Claude Sonnet 4.6 (1M context) --- .../main/java/com/longbridge/SdkNative.java | 8 ++ .../fundamental/EconomicIndicatorData.java | 15 +++ .../fundamental/EconomicIndicatorInfo.java | 19 ++++ .../EconomicIndicatorResponse.java | 7 ++ .../fundamental/FundamentalContext.java | 14 +++ .../fundamental/MultiLanguageText.java | 8 ++ java/src/fundamental_context.rs | 50 +++++++++ java/src/types/classes.rs | 49 +++++++++ nodejs/index.d.ts | 40 +++++++ nodejs/src/fundamental/context.rs | 34 ++++++ nodejs/src/fundamental/types.rs | 102 ++++++++++++++++++ python/pysrc/longbridge/openapi.pyi | 86 +++++++++++++++ python/src/fundamental/context.rs | 30 ++++++ python/src/fundamental/context_async.rs | 40 +++++++ python/src/fundamental/mod.rs | 4 + python/src/fundamental/types.rs | 102 ++++++++++++++++++ rust/src/fundamental/context.rs | 59 ++++++++++ rust/src/fundamental/types.rs | 100 +++++++++++++++++ 18 files changed, 767 insertions(+) create mode 100644 java/javasrc/src/main/java/com/longbridge/fundamental/EconomicIndicatorData.java create mode 100644 java/javasrc/src/main/java/com/longbridge/fundamental/EconomicIndicatorInfo.java create mode 100644 java/javasrc/src/main/java/com/longbridge/fundamental/EconomicIndicatorResponse.java create mode 100644 java/javasrc/src/main/java/com/longbridge/fundamental/MultiLanguageText.java diff --git a/java/javasrc/src/main/java/com/longbridge/SdkNative.java b/java/javasrc/src/main/java/com/longbridge/SdkNative.java index 4ed90791a..2e30f186b 100644 --- a/java/javasrc/src/main/java/com/longbridge/SdkNative.java +++ b/java/javasrc/src/main/java/com/longbridge/SdkNative.java @@ -451,6 +451,14 @@ public static native void fundamentalContextGetFinancialReportSnapshot(long cont Object opts, AsyncCallback callback); + public static native void fundamentalContextEconomicIndicatorList(long context, + Object offset, Object limit, + AsyncCallback callback); + + public static native void fundamentalContextEconomicIndicator(long context, + Object indicatorCode, Object startTime, Object endTime, Object limit, + AsyncCallback callback); + public static native void portfolioContextProfitAnalysisFlows(long context, Object opts, AsyncCallback callback); diff --git a/java/javasrc/src/main/java/com/longbridge/fundamental/EconomicIndicatorData.java b/java/javasrc/src/main/java/com/longbridge/fundamental/EconomicIndicatorData.java new file mode 100644 index 000000000..c81fa359c --- /dev/null +++ b/java/javasrc/src/main/java/com/longbridge/fundamental/EconomicIndicatorData.java @@ -0,0 +1,15 @@ +package com.longbridge.fundamental; + +/** One historical data point for a macroeconomic indicator. */ +public class EconomicIndicatorData { + /** Statistical period (e.g. 2024-Q1, 2024-03). */ + public String period; + public String releaseAt; + public String actualValue; + public String previousValue; + public String forecastValue; + public String revisedValue; + public String nextReleaseAt; + public MultiLanguageText unit; + public MultiLanguageText unitPrefix; +} diff --git a/java/javasrc/src/main/java/com/longbridge/fundamental/EconomicIndicatorInfo.java b/java/javasrc/src/main/java/com/longbridge/fundamental/EconomicIndicatorInfo.java new file mode 100644 index 000000000..b7ea08601 --- /dev/null +++ b/java/javasrc/src/main/java/com/longbridge/fundamental/EconomicIndicatorInfo.java @@ -0,0 +1,19 @@ +package com.longbridge.fundamental; + +/** Metadata for one macroeconomic indicator. */ +public class EconomicIndicatorInfo { + /** External vendor code (input to getEconomicIndicator). */ + public String indicatorCode; + public String sourceOrg; + public String country; + public MultiLanguageText name; + public String adjustmentFactor; + /** Release periodicity (e.g. monthly / quarterly). */ + public String periodicity; + public String category; + public MultiLanguageText describe; + /** Importance — higher is more important. */ + public int importance; + /** Start date of data coverage (unix timestamp string). */ + public String startDate; +} diff --git a/java/javasrc/src/main/java/com/longbridge/fundamental/EconomicIndicatorResponse.java b/java/javasrc/src/main/java/com/longbridge/fundamental/EconomicIndicatorResponse.java new file mode 100644 index 000000000..6a2740a91 --- /dev/null +++ b/java/javasrc/src/main/java/com/longbridge/fundamental/EconomicIndicatorResponse.java @@ -0,0 +1,7 @@ +package com.longbridge.fundamental; + +/** Response for {@link FundamentalContext#getEconomicIndicator}. */ +public class EconomicIndicatorResponse { + public EconomicIndicatorInfo info; + public EconomicIndicatorData[] data; +} diff --git a/java/javasrc/src/main/java/com/longbridge/fundamental/FundamentalContext.java b/java/javasrc/src/main/java/com/longbridge/fundamental/FundamentalContext.java index 8c0a7299a..f4e19c224 100644 --- a/java/javasrc/src/main/java/com/longbridge/fundamental/FundamentalContext.java +++ b/java/javasrc/src/main/java/com/longbridge/fundamental/FundamentalContext.java @@ -334,4 +334,18 @@ public CompletableFuture getValuationComparison(Val SdkNative.fundamentalContextValuationComparison(raw, opts, callback); }); } + + /** List macroeconomic indicators. */ + public CompletableFuture getEconomicIndicatorList(Integer offset, Integer limit) throws OpenApiException { + return AsyncCallback.executeTask((callback) -> { + SdkNative.fundamentalContextEconomicIndicatorList(raw, offset, limit, callback); + }); + } + + /** Get historical data for a macroeconomic indicator. */ + public CompletableFuture getEconomicIndicator(String indicatorCode, Long startTime, Long endTime, Integer limit) throws OpenApiException { + return AsyncCallback.executeTask((callback) -> { + SdkNative.fundamentalContextEconomicIndicator(raw, indicatorCode, startTime, endTime, limit, callback); + }); + } } diff --git a/java/javasrc/src/main/java/com/longbridge/fundamental/MultiLanguageText.java b/java/javasrc/src/main/java/com/longbridge/fundamental/MultiLanguageText.java new file mode 100644 index 000000000..2bb9bf361 --- /dev/null +++ b/java/javasrc/src/main/java/com/longbridge/fundamental/MultiLanguageText.java @@ -0,0 +1,8 @@ +package com.longbridge.fundamental; + +/** Localized text in simplified Chinese, traditional Chinese, and English. */ +public class MultiLanguageText { + public String english; + public String simplifiedChinese; + public String traditionalChinese; +} diff --git a/java/src/fundamental_context.rs b/java/src/fundamental_context.rs index 95c39a995..b0b770205 100644 --- a/java/src/fundamental_context.rs +++ b/java/src/fundamental_context.rs @@ -262,3 +262,53 @@ pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextVa Ok(()) }) } + +#[unsafe(no_mangle)] +pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextEconomicIndicatorList( + mut env: JNIEnv, + _class: JClass, + context: i64, + offset: JObject, + limit: JObject, + callback: JObject, +) { + jni_result(&mut env, (), |env| { + let context = &*(context as *const ContextObj); + let offset: Option = FromJValue::from_jvalue(env, offset.into())?; + let limit: Option = FromJValue::from_jvalue(env, limit.into())?; + async_util::execute(env, callback, async move { + Ok(context + .ctx + .economic_indicator_list(offset, limit) + .await?) + })?; + Ok(()) + }) +} + +#[unsafe(no_mangle)] +pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextEconomicIndicator( + mut env: JNIEnv, + _class: JClass, + context: i64, + indicator_code: JObject, + start_time: JObject, + end_time: JObject, + limit: JObject, + callback: JObject, +) { + jni_result(&mut env, (), |env| { + let context = &*(context as *const ContextObj); + let indicator_code: String = FromJValue::from_jvalue(env, indicator_code.into())?; + let start_time: Option = FromJValue::from_jvalue(env, start_time.into())?; + let end_time: Option = FromJValue::from_jvalue(env, end_time.into())?; + let limit: Option = FromJValue::from_jvalue(env, limit.into())?; + async_util::execute(env, callback, async move { + Ok(context + .ctx + .economic_indicator(indicator_code, start_time, end_time, limit) + .await?) + })?; + Ok(()) + }) +} diff --git a/java/src/types/classes.rs b/java/src/types/classes.rs index 141d5f839..4061f93c7 100644 --- a/java/src/types/classes.rs +++ b/java/src/types/classes.rs @@ -2698,6 +2698,55 @@ impl_java_class!( ] ); +impl_java_class!( + "com/longbridge/fundamental/MultiLanguageText", + longbridge::fundamental::MultiLanguageText, + [english, simplified_chinese, traditional_chinese] +); + +impl_java_class!( + "com/longbridge/fundamental/EconomicIndicatorInfo", + longbridge::fundamental::EconomicIndicatorInfo, + [ + indicator_code, + source_org, + country, + name, + adjustment_factor, + periodicity, + category, + describe, + importance, + start_date + ] +); + +impl_java_class!( + "com/longbridge/fundamental/EconomicIndicatorData", + longbridge::fundamental::EconomicIndicatorData, + [ + period, + release_at, + actual_value, + previous_value, + forecast_value, + revised_value, + next_release_at, + unit, + unit_prefix + ] +); + +impl_java_class!( + "com/longbridge/fundamental/EconomicIndicatorResponse", + longbridge::fundamental::EconomicIndicatorResponse, + [ + info, + #[java(objarray)] + data + ] +); + // ── MarketContext: top movers / rank ────────────────────────────── impl_java_class!( diff --git a/nodejs/index.d.ts b/nodejs/index.d.ts index c7f7b1eb4..ae7d753eb 100644 --- a/nodejs/index.d.ts +++ b/nodejs/index.d.ts @@ -618,6 +618,10 @@ export declare class FundamentalContext { * industry) */ etfAssetAllocation(symbol: string): Promise + /** List macroeconomic indicators */ + economicIndicatorList(offset?: number | null, limit?: number | null): Promise> + /** Get historical data for a macroeconomic indicator */ + economicIndicator(indicatorCode: string, startTime?: bigint | null, endTime?: bigint | null, limit?: number | null): Promise } /** Fund position */ @@ -3133,6 +3137,42 @@ export interface AssetAllocationResponse { /** Asset allocation groups */ info: Array } +/** Localized text in simplified Chinese, traditional Chinese, and English */ +export interface MultiLanguageText { + english: string + simplifiedChinese: string + traditionalChinese: string +} +/** Metadata for one macroeconomic indicator */ +export interface EconomicIndicatorInfo { + indicatorCode: string + sourceOrg: string + country: string + name: MultiLanguageText + adjustmentFactor: string + periodicity: string + category: string + describe: MultiLanguageText + importance: number + startDate: string +} +/** One historical data point for a macroeconomic indicator */ +export interface EconomicIndicatorData { + period: string + releaseAt: string + actualValue: string + previousValue: string + forecastValue: string + revisedValue: string + nextReleaseAt: string + unit: MultiLanguageText + unitPrefix: MultiLanguageText +} +/** Response for economicIndicator */ +export interface EconomicIndicatorResponse { + info: EconomicIndicatorInfo + data: Array +} export declare const enum AssetType { /** Unknown */ diff --git a/nodejs/src/fundamental/context.rs b/nodejs/src/fundamental/context.rs index ca1cc3528..c886e27d3 100644 --- a/nodejs/src/fundamental/context.rs +++ b/nodejs/src/fundamental/context.rs @@ -287,4 +287,38 @@ impl FundamentalContext { .map_err(ErrorNewType)? .into()) } + + /// List macroeconomic indicators + #[napi] + pub async fn economic_indicator_list( + &self, + offset: Option, + limit: Option, + ) -> Result> { + Ok(self + .ctx + .economic_indicator_list(offset, limit) + .await + .map_err(ErrorNewType)? + .into_iter() + .map(Into::into) + .collect()) + } + + /// Get historical data for a macroeconomic indicator + #[napi] + pub async fn economic_indicator( + &self, + indicator_code: String, + start_time: Option, + end_time: Option, + limit: Option, + ) -> Result { + Ok(self + .ctx + .economic_indicator(indicator_code, start_time, end_time, limit) + .await + .map_err(ErrorNewType)? + .into()) + } } diff --git a/nodejs/src/fundamental/types.rs b/nodejs/src/fundamental/types.rs index 37664aba5..863a6b81a 100644 --- a/nodejs/src/fundamental/types.rs +++ b/nodejs/src/fundamental/types.rs @@ -1902,3 +1902,105 @@ impl From for AssetAllocationResponse { } } } + +// ── economic_indicator ───────────────────────────────────────────────────── + +/// Localized text in simplified Chinese, traditional Chinese, and English +#[napi_derive::napi(object)] +#[derive(Debug, Clone, Default)] +pub struct MultiLanguageText { + pub english: String, + pub simplified_chinese: String, + pub traditional_chinese: String, +} + +impl From for MultiLanguageText { + fn from(v: lb::MultiLanguageText) -> Self { + Self { + english: v.english, + simplified_chinese: v.simplified_chinese, + traditional_chinese: v.traditional_chinese, + } + } +} + +/// Metadata for one macroeconomic indicator +#[napi_derive::napi(object)] +#[derive(Debug, Clone)] +pub struct EconomicIndicatorInfo { + pub indicator_code: String, + pub source_org: String, + pub country: String, + pub name: MultiLanguageText, + pub adjustment_factor: String, + pub periodicity: String, + pub category: String, + pub describe: MultiLanguageText, + pub importance: i32, + pub start_date: String, +} + +impl From for EconomicIndicatorInfo { + fn from(v: lb::EconomicIndicatorInfo) -> Self { + Self { + indicator_code: v.indicator_code, + source_org: v.source_org, + country: v.country, + name: v.name.into(), + adjustment_factor: v.adjustment_factor, + periodicity: v.periodicity, + category: v.category, + describe: v.describe.into(), + importance: v.importance, + start_date: v.start_date, + } + } +} + +/// One historical data point for a macroeconomic indicator +#[napi_derive::napi(object)] +#[derive(Debug, Clone)] +pub struct EconomicIndicatorData { + pub period: String, + pub release_at: String, + pub actual_value: String, + pub previous_value: String, + pub forecast_value: String, + pub revised_value: String, + pub next_release_at: String, + pub unit: MultiLanguageText, + pub unit_prefix: MultiLanguageText, +} + +impl From for EconomicIndicatorData { + fn from(v: lb::EconomicIndicatorData) -> Self { + Self { + period: v.period, + release_at: v.release_at, + actual_value: v.actual_value, + previous_value: v.previous_value, + forecast_value: v.forecast_value, + revised_value: v.revised_value, + next_release_at: v.next_release_at, + unit: v.unit.into(), + unit_prefix: v.unit_prefix.into(), + } + } +} + +/// Response for economic_indicator +#[napi_derive::napi(object)] +#[derive(Debug, Clone)] +pub struct EconomicIndicatorResponse { + pub info: EconomicIndicatorInfo, + pub data: Vec, +} + +impl From for EconomicIndicatorResponse { + fn from(v: lb::EconomicIndicatorResponse) -> Self { + Self { + info: v.info.into(), + data: v.data.into_iter().map(Into::into).collect(), + } + } +} diff --git a/python/pysrc/longbridge/openapi.pyi b/python/pysrc/longbridge/openapi.pyi index 90bc788e3..5953e2685 100644 --- a/python/pysrc/longbridge/openapi.pyi +++ b/python/pysrc/longbridge/openapi.pyi @@ -9922,6 +9922,44 @@ class FundamentalContext: """ ... + def economic_indicator_list( + self, + offset: int | None = None, + limit: int | None = None, + ) -> list["EconomicIndicatorInfo"]: + """ + List macroeconomic indicators. + + Args: + offset: Pagination offset (default 0) + limit: Page size (default 100, max 1000) + + Returns: + List of :class:`EconomicIndicatorInfo` + """ + ... + + def economic_indicator( + self, + indicator_code: str, + start_time: int | None = None, + end_time: int | None = None, + limit: int | None = None, + ) -> "EconomicIndicatorResponse": + """ + Get historical data for a macroeconomic indicator. + + Args: + indicator_code: External vendor code from ``economic_indicator_list`` + start_time: Data start Unix timestamp (optional) + end_time: Data end Unix timestamp (optional) + limit: Max records to return (default 100, max 100) + + Returns: + :class:`EconomicIndicatorResponse` + """ + ... + # ── FundamentalContext new response types ───────────────────────── @@ -10065,6 +10103,54 @@ class AssetAllocationResponse: """Asset allocation groups""" +class MultiLanguageText: + """Localized text in simplified Chinese, traditional Chinese, and English.""" + + english: str + simplified_chinese: str + traditional_chinese: str + + +class EconomicIndicatorInfo: + """Metadata for one macroeconomic indicator.""" + + indicator_code: str + """External vendor code (input to economic_indicator)""" + source_org: str + country: str + name: MultiLanguageText + adjustment_factor: str + periodicity: str + """Release periodicity (e.g. monthly / quarterly)""" + category: str + describe: MultiLanguageText + importance: int + start_date: str + """Start date of data coverage (unix timestamp string)""" + + +class EconomicIndicatorData: + """One historical data point for a macroeconomic indicator.""" + + period: str + """Statistical period (e.g. 2024-Q1, 2024-03)""" + release_at: str + actual_value: str + previous_value: str + forecast_value: str + revised_value: str + next_release_at: str + unit: MultiLanguageText + unit_prefix: MultiLanguageText + + +class EconomicIndicatorResponse: + """Response for economic_indicator.""" + + info: EconomicIndicatorInfo + data: list[EconomicIndicatorData] + + # ── MarketContext ───────────────────────────────────────────────── class MarketTimeItem: diff --git a/python/src/fundamental/context.rs b/python/src/fundamental/context.rs index e65d93fd2..099ee33f1 100644 --- a/python/src/fundamental/context.rs +++ b/python/src/fundamental/context.rs @@ -208,4 +208,34 @@ impl FundamentalContext { .map_err(ErrorNewType)? .into()) } + + /// List macroeconomic indicators. + fn economic_indicator_list( + &self, + offset: Option, + limit: Option, + ) -> PyResult> { + Ok(self + .ctx + .economic_indicator_list(offset, limit) + .map_err(ErrorNewType)? + .into_iter() + .map(Into::into) + .collect()) + } + + /// Get historical data for a macroeconomic indicator. + fn economic_indicator( + &self, + indicator_code: String, + start_time: Option, + end_time: Option, + limit: Option, + ) -> PyResult { + Ok(self + .ctx + .economic_indicator(indicator_code, start_time, end_time, limit) + .map_err(ErrorNewType)? + .into()) + } } diff --git a/python/src/fundamental/context_async.rs b/python/src/fundamental/context_async.rs index eed4d6142..e82b480ce 100644 --- a/python/src/fundamental/context_async.rs +++ b/python/src/fundamental/context_async.rs @@ -317,4 +317,44 @@ impl AsyncFundamentalContext { }) .map(|b| b.unbind()) } + + /// List macroeconomic indicators. Returns awaitable. + fn economic_indicator_list( + &self, + py: Python<'_>, + offset: Option, + limit: Option, + ) -> PyResult> { + let ctx = self.ctx.clone(); + pyo3_async_runtimes::tokio::future_into_py(py, async move { + Ok(ctx + .economic_indicator_list(offset, limit) + .await + .map_err(ErrorNewType)? + .into_iter() + .map(EconomicIndicatorInfo::from) + .collect::>()) + }) + .map(|b| b.unbind()) + } + + /// Get historical data for a macroeconomic indicator. Returns awaitable. + fn economic_indicator( + &self, + py: Python<'_>, + indicator_code: String, + start_time: Option, + end_time: Option, + limit: Option, + ) -> PyResult> { + let ctx = self.ctx.clone(); + pyo3_async_runtimes::tokio::future_into_py(py, async move { + Ok(EconomicIndicatorResponse::from( + ctx.economic_indicator(indicator_code, start_time, end_time, limit) + .await + .map_err(ErrorNewType)?, + )) + }) + .map(|b| b.unbind()) + } } diff --git a/python/src/fundamental/mod.rs b/python/src/fundamental/mod.rs index a788e712e..761de5d1e 100644 --- a/python/src/fundamental/mod.rs +++ b/python/src/fundamental/mod.rs @@ -74,6 +74,10 @@ pub(crate) fn register_types(parent: &Bound) -> PyResult<()> { parent.add_class::()?; parent.add_class::()?; parent.add_class::()?; + parent.add_class::()?; + parent.add_class::()?; + parent.add_class::()?; + parent.add_class::()?; parent.add_class::()?; parent.add_class::()?; Ok(()) diff --git a/python/src/fundamental/types.rs b/python/src/fundamental/types.rs index 3a8f6ed59..7d38b43eb 100644 --- a/python/src/fundamental/types.rs +++ b/python/src/fundamental/types.rs @@ -1965,3 +1965,105 @@ impl From for AssetAllocationResponse { } } } + +// ── economic_indicator ───────────────────────────────────────────────────── + +/// Localized text in simplified Chinese, traditional Chinese, and English +#[pyclass(get_all, skip_from_py_object)] +#[derive(Debug, Clone, Default)] +pub(crate) struct MultiLanguageText { + pub english: String, + pub simplified_chinese: String, + pub traditional_chinese: String, +} + +impl From for MultiLanguageText { + fn from(v: lb::MultiLanguageText) -> Self { + Self { + english: v.english, + simplified_chinese: v.simplified_chinese, + traditional_chinese: v.traditional_chinese, + } + } +} + +/// Metadata for one macroeconomic indicator +#[pyclass(get_all, skip_from_py_object)] +#[derive(Debug, Clone)] +pub(crate) struct EconomicIndicatorInfo { + pub indicator_code: String, + pub source_org: String, + pub country: String, + pub name: MultiLanguageText, + pub adjustment_factor: String, + pub periodicity: String, + pub category: String, + pub describe: MultiLanguageText, + pub importance: i32, + pub start_date: String, +} + +impl From for EconomicIndicatorInfo { + fn from(v: lb::EconomicIndicatorInfo) -> Self { + Self { + indicator_code: v.indicator_code, + source_org: v.source_org, + country: v.country, + name: v.name.into(), + adjustment_factor: v.adjustment_factor, + periodicity: v.periodicity, + category: v.category, + describe: v.describe.into(), + importance: v.importance, + start_date: v.start_date, + } + } +} + +/// One historical data point for a macroeconomic indicator +#[pyclass(get_all, skip_from_py_object)] +#[derive(Debug, Clone)] +pub(crate) struct EconomicIndicatorData { + pub period: String, + pub release_at: String, + pub actual_value: String, + pub previous_value: String, + pub forecast_value: String, + pub revised_value: String, + pub next_release_at: String, + pub unit: MultiLanguageText, + pub unit_prefix: MultiLanguageText, +} + +impl From for EconomicIndicatorData { + fn from(v: lb::EconomicIndicatorData) -> Self { + Self { + period: v.period, + release_at: v.release_at, + actual_value: v.actual_value, + previous_value: v.previous_value, + forecast_value: v.forecast_value, + revised_value: v.revised_value, + next_release_at: v.next_release_at, + unit: v.unit.into(), + unit_prefix: v.unit_prefix.into(), + } + } +} + +/// Response for economic_indicator +#[pyclass(get_all, skip_from_py_object)] +#[derive(Debug, Clone)] +pub(crate) struct EconomicIndicatorResponse { + pub info: EconomicIndicatorInfo, + pub data: Vec, +} + +impl From for EconomicIndicatorResponse { + fn from(v: lb::EconomicIndicatorResponse) -> Self { + Self { + info: v.info.into(), + data: v.data.into_iter().map(Into::into).collect(), + } + } +} diff --git a/rust/src/fundamental/context.rs b/rust/src/fundamental/context.rs index a5d9e64b5..1a83cedb4 100644 --- a/rust/src/fundamental/context.rs +++ b/rust/src/fundamental/context.rs @@ -829,4 +829,63 @@ impl FundamentalContext { ) .await } + + // ── economic_indicator ──────────────────────────────────────────────── + + /// List macroeconomic indicators. + /// + /// Path: `GET /v1/quote/macrodata` + pub async fn economic_indicator_list( + &self, + offset: Option, + limit: Option, + ) -> Result> { + #[derive(Serialize)] + struct Query { + #[serde(skip_serializing_if = "Option::is_none")] + offset: Option, + #[serde(skip_serializing_if = "Option::is_none")] + limit: Option, + } + let resp: EconomicIndicatorListResponse = self + .get("/v1/quote/macrodata", Query { offset, limit }) + .await?; + Ok(resp.data) + } + + /// Get historical data for a macroeconomic indicator. + /// + /// Path: `GET /v1/quote/macrodata/{indicator_code}` + pub async fn economic_indicator( + &self, + indicator_code: impl Into, + start_time: Option, + end_time: Option, + limit: Option, + ) -> Result { + #[derive(Serialize)] + struct Query { + #[serde(skip_serializing_if = "Option::is_none")] + start_time: Option, + #[serde(skip_serializing_if = "Option::is_none")] + end_time: Option, + #[serde(skip_serializing_if = "Option::is_none")] + limit: Option, + } + let path = format!("/v1/quote/macrodata/{}", indicator_code.into()); + Ok(self + .0 + .http_cli + .request(Method::GET, path) + .query_params(Query { + start_time, + end_time, + limit, + }) + .response::>() + .send() + .with_subscriber(self.0.log_subscriber.clone()) + .await? + .0) + } } diff --git a/rust/src/fundamental/types.rs b/rust/src/fundamental/types.rs index 929f8ce98..3bbb6a1f9 100644 --- a/rust/src/fundamental/types.rs +++ b/rust/src/fundamental/types.rs @@ -1562,3 +1562,103 @@ pub struct AssetAllocationResponse { #[serde(default)] pub info: Vec, } + +// ── economic_indicator ───────────────────────────────────────────────────── + +/// Localized text in simplified Chinese, traditional Chinese, and English +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +pub struct MultiLanguageText { + /// English + #[serde(default)] + pub english: String, + /// Simplified Chinese + #[serde(default)] + pub simplified_chinese: String, + /// Traditional Chinese + #[serde(default)] + pub traditional_chinese: String, +} + +/// Metadata for one macroeconomic indicator +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct EconomicIndicatorInfo { + /// External vendor code (used as input to `economic_indicator`) + pub indicator_code: String, + /// Publishing organisation + #[serde(default)] + pub source_org: String, + /// Country + #[serde(default)] + pub country: String, + /// Indicator name (multilingual) + #[serde(default)] + pub name: MultiLanguageText, + /// Adjustment factor + #[serde(default)] + pub adjustment_factor: String, + /// Release periodicity (e.g. `monthly` / `quarterly`) + #[serde(default)] + pub periodicity: String, + /// Indicator category + #[serde(default)] + pub category: String, + /// Description (multilingual) + #[serde(default)] + pub describe: MultiLanguageText, + /// Importance — higher is more important + #[serde(default)] + pub importance: i32, + /// Start date of data coverage (unix timestamp string) + #[serde(default)] + pub start_date: String, +} + +/// Response for [`crate::FundamentalContext::economic_indicator_list`] +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct EconomicIndicatorListResponse { + /// Indicator list + #[serde(default)] + pub data: Vec, +} + +/// One historical data point for a macroeconomic indicator +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct EconomicIndicatorData { + /// Statistical period (e.g. `2024-Q1`, `2024-03`) + #[serde(default)] + pub period: String, + /// Release timestamp (unix timestamp string) + #[serde(default)] + pub release_at: String, + /// Actual value + #[serde(default)] + pub actual_value: String, + /// Previous value + #[serde(default)] + pub previous_value: String, + /// Forecast value (market consensus) + #[serde(default)] + pub forecast_value: String, + /// Revised value + #[serde(default)] + pub revised_value: String, + /// Next release timestamp (unix timestamp string) + #[serde(default)] + pub next_release_at: String, + /// Unit (multilingual) + #[serde(default)] + pub unit: MultiLanguageText, + /// Unit prefix / data scale (multilingual, e.g. millions / billions) + #[serde(default)] + pub unit_prefix: MultiLanguageText, +} + +/// Response for [`crate::FundamentalContext::economic_indicator`] +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct EconomicIndicatorResponse { + /// Indicator metadata + pub info: EconomicIndicatorInfo, + /// Historical data points + #[serde(default)] + pub data: Vec, +} From 400acd05b85950409ddcd768600af975acd4e189 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Tue, 9 Jun 2026 19:40:39 +0800 Subject: [PATCH 02/28] fix: align timestamp types with other SDK methods - EconomicIndicatorInfo.start_date: String -> Option - EconomicIndicatorData.release_at/next_release_at: String -> Option Python: PyOffsetDateTimeWrapper (datetime), Node.js: Option (unix seconds). Co-Authored-By: Claude Sonnet 4.6 (1M context) --- nodejs/index.d.ts | 9 ++++++--- nodejs/src/fundamental/types.rs | 15 +++++++++------ python/pysrc/longbridge/openapi.pyi | 8 ++++---- python/src/fundamental/types.rs | 12 ++++++------ rust/src/fundamental/types.rs | 22 +++++++++++++--------- 5 files changed, 38 insertions(+), 28 deletions(-) diff --git a/nodejs/index.d.ts b/nodejs/index.d.ts index ae7d753eb..3aef4da95 100644 --- a/nodejs/index.d.ts +++ b/nodejs/index.d.ts @@ -3154,17 +3154,20 @@ export interface EconomicIndicatorInfo { category: string describe: MultiLanguageText importance: number - startDate: string + /** Start date of data coverage (unix timestamp in seconds; null if unset) */ + startDate: bigint | null } /** One historical data point for a macroeconomic indicator */ export interface EconomicIndicatorData { period: string - releaseAt: string + /** Release datetime (unix timestamp in seconds; null if unset) */ + releaseAt: bigint | null actualValue: string previousValue: string forecastValue: string revisedValue: string - nextReleaseAt: string + /** Next release datetime (unix timestamp in seconds; null if unset) */ + nextReleaseAt: bigint | null unit: MultiLanguageText unitPrefix: MultiLanguageText } diff --git a/nodejs/src/fundamental/types.rs b/nodejs/src/fundamental/types.rs index 863a6b81a..476d4fe3c 100644 --- a/nodejs/src/fundamental/types.rs +++ b/nodejs/src/fundamental/types.rs @@ -1937,7 +1937,8 @@ pub struct EconomicIndicatorInfo { pub category: String, pub describe: MultiLanguageText, pub importance: i32, - pub start_date: String, + /// Start date of data coverage (unix timestamp in seconds; null if unset) + pub start_date: Option, } impl From for EconomicIndicatorInfo { @@ -1952,7 +1953,7 @@ impl From for EconomicIndicatorInfo { category: v.category, describe: v.describe.into(), importance: v.importance, - start_date: v.start_date, + start_date: v.start_date.map(|dt| dt.unix_timestamp()), } } } @@ -1962,12 +1963,14 @@ impl From for EconomicIndicatorInfo { #[derive(Debug, Clone)] pub struct EconomicIndicatorData { pub period: String, - pub release_at: String, + /// Release datetime (unix timestamp in seconds; null if unset) + pub release_at: Option, pub actual_value: String, pub previous_value: String, pub forecast_value: String, pub revised_value: String, - pub next_release_at: String, + /// Next release datetime (unix timestamp in seconds; null if unset) + pub next_release_at: Option, pub unit: MultiLanguageText, pub unit_prefix: MultiLanguageText, } @@ -1976,12 +1979,12 @@ impl From for EconomicIndicatorData { fn from(v: lb::EconomicIndicatorData) -> Self { Self { period: v.period, - release_at: v.release_at, + release_at: v.release_at.map(|dt| dt.unix_timestamp()), actual_value: v.actual_value, previous_value: v.previous_value, forecast_value: v.forecast_value, revised_value: v.revised_value, - next_release_at: v.next_release_at, + next_release_at: v.next_release_at.map(|dt| dt.unix_timestamp()), unit: v.unit.into(), unit_prefix: v.unit_prefix.into(), } diff --git a/python/pysrc/longbridge/openapi.pyi b/python/pysrc/longbridge/openapi.pyi index 5953e2685..99f1bf54b 100644 --- a/python/pysrc/longbridge/openapi.pyi +++ b/python/pysrc/longbridge/openapi.pyi @@ -10125,8 +10125,8 @@ class EconomicIndicatorInfo: category: str describe: MultiLanguageText importance: int - start_date: str - """Start date of data coverage (unix timestamp string)""" + start_date: datetime | None + """Start date of data coverage""" class EconomicIndicatorData: @@ -10134,12 +10134,12 @@ class EconomicIndicatorData: period: str """Statistical period (e.g. 2024-Q1, 2024-03)""" - release_at: str + release_at: datetime | None actual_value: str previous_value: str forecast_value: str revised_value: str - next_release_at: str + next_release_at: datetime | None unit: MultiLanguageText unit_prefix: MultiLanguageText diff --git a/python/src/fundamental/types.rs b/python/src/fundamental/types.rs index 7d38b43eb..05376e9be 100644 --- a/python/src/fundamental/types.rs +++ b/python/src/fundamental/types.rs @@ -2000,7 +2000,7 @@ pub(crate) struct EconomicIndicatorInfo { pub category: String, pub describe: MultiLanguageText, pub importance: i32, - pub start_date: String, + pub start_date: Option, } impl From for EconomicIndicatorInfo { @@ -2015,7 +2015,7 @@ impl From for EconomicIndicatorInfo { category: v.category, describe: v.describe.into(), importance: v.importance, - start_date: v.start_date, + start_date: v.start_date.map(crate::time::PyOffsetDateTimeWrapper), } } } @@ -2025,12 +2025,12 @@ impl From for EconomicIndicatorInfo { #[derive(Debug, Clone)] pub(crate) struct EconomicIndicatorData { pub period: String, - pub release_at: String, + pub release_at: Option, pub actual_value: String, pub previous_value: String, pub forecast_value: String, pub revised_value: String, - pub next_release_at: String, + pub next_release_at: Option, pub unit: MultiLanguageText, pub unit_prefix: MultiLanguageText, } @@ -2039,12 +2039,12 @@ impl From for EconomicIndicatorData { fn from(v: lb::EconomicIndicatorData) -> Self { Self { period: v.period, - release_at: v.release_at, + release_at: v.release_at.map(crate::time::PyOffsetDateTimeWrapper), actual_value: v.actual_value, previous_value: v.previous_value, forecast_value: v.forecast_value, revised_value: v.revised_value, - next_release_at: v.next_release_at, + next_release_at: v.next_release_at.map(crate::time::PyOffsetDateTimeWrapper), unit: v.unit.into(), unit_prefix: v.unit_prefix.into(), } diff --git a/rust/src/fundamental/types.rs b/rust/src/fundamental/types.rs index 3bbb6a1f9..f2220ae1e 100644 --- a/rust/src/fundamental/types.rs +++ b/rust/src/fundamental/types.rs @@ -1608,9 +1608,13 @@ pub struct EconomicIndicatorInfo { /// Importance — higher is more important #[serde(default)] pub importance: i32, - /// Start date of data coverage (unix timestamp string) - #[serde(default)] - pub start_date: String, + /// Start date of data coverage + #[serde( + default, + with = "crate::serde_utils::timestamp_opt", + rename = "start_date" + )] + pub start_date: Option, } /// Response for [`crate::FundamentalContext::economic_indicator_list`] @@ -1627,9 +1631,9 @@ pub struct EconomicIndicatorData { /// Statistical period (e.g. `2024-Q1`, `2024-03`) #[serde(default)] pub period: String, - /// Release timestamp (unix timestamp string) - #[serde(default)] - pub release_at: String, + /// Release datetime + #[serde(default, with = "crate::serde_utils::timestamp_opt")] + pub release_at: Option, /// Actual value #[serde(default)] pub actual_value: String, @@ -1642,9 +1646,9 @@ pub struct EconomicIndicatorData { /// Revised value #[serde(default)] pub revised_value: String, - /// Next release timestamp (unix timestamp string) - #[serde(default)] - pub next_release_at: String, + /// Next release datetime + #[serde(default, with = "crate::serde_utils::timestamp_opt")] + pub next_release_at: Option, /// Unit (multilingual) #[serde(default)] pub unit: MultiLanguageText, From 6a63c8a60170bd8dc45907a9153e711f68eb2c33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Tue, 9 Jun 2026 19:50:43 +0800 Subject: [PATCH 03/28] refactor: rename macrodata_list to macrodata_indicators Co-Authored-By: Claude Sonnet 4.6 (1M context) --- .../main/java/com/longbridge/SdkNative.java | 4 ++-- .../fundamental/FundamentalContext.java | 8 +++---- java/src/fundamental_context.rs | 4 ++-- nodejs/index.d.ts | 6 ++--- nodejs/src/fundamental/context.rs | 8 +++---- python/pysrc/longbridge/openapi.pyi | 10 ++++---- python/src/fundamental/context.rs | 8 +++---- python/src/fundamental/context_async.rs | 8 +++---- rust/src/blocking/fundamental.rs | 24 +++++++++++++++++++ rust/src/fundamental/context.rs | 6 ++--- rust/src/fundamental/types.rs | 8 +++---- 11 files changed, 59 insertions(+), 35 deletions(-) diff --git a/java/javasrc/src/main/java/com/longbridge/SdkNative.java b/java/javasrc/src/main/java/com/longbridge/SdkNative.java index 2e30f186b..6f9f5927d 100644 --- a/java/javasrc/src/main/java/com/longbridge/SdkNative.java +++ b/java/javasrc/src/main/java/com/longbridge/SdkNative.java @@ -451,11 +451,11 @@ public static native void fundamentalContextGetFinancialReportSnapshot(long cont Object opts, AsyncCallback callback); - public static native void fundamentalContextEconomicIndicatorList(long context, + public static native void fundamentalContextMacrodataIndicators(long context, Object offset, Object limit, AsyncCallback callback); - public static native void fundamentalContextEconomicIndicator(long context, + public static native void fundamentalContextMacrodata(long context, Object indicatorCode, Object startTime, Object endTime, Object limit, AsyncCallback callback); diff --git a/java/javasrc/src/main/java/com/longbridge/fundamental/FundamentalContext.java b/java/javasrc/src/main/java/com/longbridge/fundamental/FundamentalContext.java index f4e19c224..db692ef20 100644 --- a/java/javasrc/src/main/java/com/longbridge/fundamental/FundamentalContext.java +++ b/java/javasrc/src/main/java/com/longbridge/fundamental/FundamentalContext.java @@ -336,16 +336,16 @@ public CompletableFuture getValuationComparison(Val } /** List macroeconomic indicators. */ - public CompletableFuture getEconomicIndicatorList(Integer offset, Integer limit) throws OpenApiException { + public CompletableFuture getMacrodataIndicators(Integer offset, Integer limit) throws OpenApiException { return AsyncCallback.executeTask((callback) -> { - SdkNative.fundamentalContextEconomicIndicatorList(raw, offset, limit, callback); + SdkNative.fundamentalContextMacrodataIndicators(raw, offset, limit, callback); }); } /** Get historical data for a macroeconomic indicator. */ - public CompletableFuture getEconomicIndicator(String indicatorCode, Long startTime, Long endTime, Integer limit) throws OpenApiException { + public CompletableFuture getMacrodata(String indicatorCode, Long startTime, Long endTime, Integer limit) throws OpenApiException { return AsyncCallback.executeTask((callback) -> { - SdkNative.fundamentalContextEconomicIndicator(raw, indicatorCode, startTime, endTime, limit, callback); + SdkNative.fundamentalContextMacrodata(raw, indicatorCode, startTime, endTime, limit, callback); }); } } diff --git a/java/src/fundamental_context.rs b/java/src/fundamental_context.rs index b0b770205..b5869ce1a 100644 --- a/java/src/fundamental_context.rs +++ b/java/src/fundamental_context.rs @@ -264,7 +264,7 @@ pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextVa } #[unsafe(no_mangle)] -pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextEconomicIndicatorList( +pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextMacrodataIndicators( mut env: JNIEnv, _class: JClass, context: i64, @@ -287,7 +287,7 @@ pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextEc } #[unsafe(no_mangle)] -pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextEconomicIndicator( +pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextMacrodata( mut env: JNIEnv, _class: JClass, context: i64, diff --git a/nodejs/index.d.ts b/nodejs/index.d.ts index 3aef4da95..08e99d698 100644 --- a/nodejs/index.d.ts +++ b/nodejs/index.d.ts @@ -619,9 +619,9 @@ export declare class FundamentalContext { */ etfAssetAllocation(symbol: string): Promise /** List macroeconomic indicators */ - economicIndicatorList(offset?: number | null, limit?: number | null): Promise> + macrodataIndicators(offset?: number | null, limit?: number | null): Promise> /** Get historical data for a macroeconomic indicator */ - economicIndicator(indicatorCode: string, startTime?: bigint | null, endTime?: bigint | null, limit?: number | null): Promise + macrodata(indicatorCode: string, startTime?: bigint | null, endTime?: bigint | null, limit?: number | null): Promise } /** Fund position */ @@ -3171,7 +3171,7 @@ export interface EconomicIndicatorData { unit: MultiLanguageText unitPrefix: MultiLanguageText } -/** Response for economicIndicator */ +/** Response for macrodata */ export interface EconomicIndicatorResponse { info: EconomicIndicatorInfo data: Array diff --git a/nodejs/src/fundamental/context.rs b/nodejs/src/fundamental/context.rs index c886e27d3..1ec05f3f4 100644 --- a/nodejs/src/fundamental/context.rs +++ b/nodejs/src/fundamental/context.rs @@ -290,14 +290,14 @@ impl FundamentalContext { /// List macroeconomic indicators #[napi] - pub async fn economic_indicator_list( + pub async fn macrodata_indicators( &self, offset: Option, limit: Option, ) -> Result> { Ok(self .ctx - .economic_indicator_list(offset, limit) + .macrodata_indicators(offset, limit) .await .map_err(ErrorNewType)? .into_iter() @@ -307,7 +307,7 @@ impl FundamentalContext { /// Get historical data for a macroeconomic indicator #[napi] - pub async fn economic_indicator( + pub async fn macrodata( &self, indicator_code: String, start_time: Option, @@ -316,7 +316,7 @@ impl FundamentalContext { ) -> Result { Ok(self .ctx - .economic_indicator(indicator_code, start_time, end_time, limit) + .macrodata(indicator_code, start_time, end_time, limit) .await .map_err(ErrorNewType)? .into()) diff --git a/python/pysrc/longbridge/openapi.pyi b/python/pysrc/longbridge/openapi.pyi index 99f1bf54b..1949e792b 100644 --- a/python/pysrc/longbridge/openapi.pyi +++ b/python/pysrc/longbridge/openapi.pyi @@ -9922,7 +9922,7 @@ class FundamentalContext: """ ... - def economic_indicator_list( + def macrodata_indicators( self, offset: int | None = None, limit: int | None = None, @@ -9939,7 +9939,7 @@ class FundamentalContext: """ ... - def economic_indicator( + def macrodata( self, indicator_code: str, start_time: int | None = None, @@ -9950,7 +9950,7 @@ class FundamentalContext: Get historical data for a macroeconomic indicator. Args: - indicator_code: External vendor code from ``economic_indicator_list`` + indicator_code: External vendor code from ``macrodata_indicators`` start_time: Data start Unix timestamp (optional) end_time: Data end Unix timestamp (optional) limit: Max records to return (default 100, max 100) @@ -10115,7 +10115,7 @@ class EconomicIndicatorInfo: """Metadata for one macroeconomic indicator.""" indicator_code: str - """External vendor code (input to economic_indicator)""" + """External vendor code (input to macrodata)""" source_org: str country: str name: MultiLanguageText @@ -10145,7 +10145,7 @@ class EconomicIndicatorData: class EconomicIndicatorResponse: - """Response for economic_indicator.""" + """Response for macrodata.""" info: EconomicIndicatorInfo data: list[EconomicIndicatorData] diff --git a/python/src/fundamental/context.rs b/python/src/fundamental/context.rs index 099ee33f1..61e6605ea 100644 --- a/python/src/fundamental/context.rs +++ b/python/src/fundamental/context.rs @@ -210,14 +210,14 @@ impl FundamentalContext { } /// List macroeconomic indicators. - fn economic_indicator_list( + fn macrodata_indicators( &self, offset: Option, limit: Option, ) -> PyResult> { Ok(self .ctx - .economic_indicator_list(offset, limit) + .macrodata_indicators(offset, limit) .map_err(ErrorNewType)? .into_iter() .map(Into::into) @@ -225,7 +225,7 @@ impl FundamentalContext { } /// Get historical data for a macroeconomic indicator. - fn economic_indicator( + fn macrodata( &self, indicator_code: String, start_time: Option, @@ -234,7 +234,7 @@ impl FundamentalContext { ) -> PyResult { Ok(self .ctx - .economic_indicator(indicator_code, start_time, end_time, limit) + .macrodata(indicator_code, start_time, end_time, limit) .map_err(ErrorNewType)? .into()) } diff --git a/python/src/fundamental/context_async.rs b/python/src/fundamental/context_async.rs index e82b480ce..044d07cd4 100644 --- a/python/src/fundamental/context_async.rs +++ b/python/src/fundamental/context_async.rs @@ -319,7 +319,7 @@ impl AsyncFundamentalContext { } /// List macroeconomic indicators. Returns awaitable. - fn economic_indicator_list( + fn macrodata_indicators( &self, py: Python<'_>, offset: Option, @@ -328,7 +328,7 @@ impl AsyncFundamentalContext { let ctx = self.ctx.clone(); pyo3_async_runtimes::tokio::future_into_py(py, async move { Ok(ctx - .economic_indicator_list(offset, limit) + .macrodata_indicators(offset, limit) .await .map_err(ErrorNewType)? .into_iter() @@ -339,7 +339,7 @@ impl AsyncFundamentalContext { } /// Get historical data for a macroeconomic indicator. Returns awaitable. - fn economic_indicator( + fn macrodata( &self, py: Python<'_>, indicator_code: String, @@ -350,7 +350,7 @@ impl AsyncFundamentalContext { let ctx = self.ctx.clone(); pyo3_async_runtimes::tokio::future_into_py(py, async move { Ok(EconomicIndicatorResponse::from( - ctx.economic_indicator(indicator_code, start_time, end_time, limit) + ctx.macrodata(indicator_code, start_time, end_time, limit) .await .map_err(ErrorNewType)?, )) diff --git a/rust/src/blocking/fundamental.rs b/rust/src/blocking/fundamental.rs index e2fb48d04..70f258665 100644 --- a/rust/src/blocking/fundamental.rs +++ b/rust/src/blocking/fundamental.rs @@ -290,4 +290,28 @@ impl FundamentalContextSync { self.rt .call(move |ctx| async move { ctx.etf_asset_allocation(symbol).await }) } + + /// List macroeconomic indicators + pub fn macrodata_indicators( + &self, + offset: Option, + limit: Option, + ) -> Result> { + self.rt + .call(move |ctx| async move { ctx.macrodata_indicators(offset, limit).await }) + } + + /// Get historical data for a macroeconomic indicator + pub fn macrodata( + &self, + indicator_code: impl Into + Send + 'static, + start_time: Option, + end_time: Option, + limit: Option, + ) -> Result { + self.rt.call(move |ctx| async move { + ctx.macrodata(indicator_code, start_time, end_time, limit) + .await + }) + } } diff --git a/rust/src/fundamental/context.rs b/rust/src/fundamental/context.rs index 1a83cedb4..d415fcd3e 100644 --- a/rust/src/fundamental/context.rs +++ b/rust/src/fundamental/context.rs @@ -830,12 +830,12 @@ impl FundamentalContext { .await } - // ── economic_indicator ──────────────────────────────────────────────── + // ── macrodata ──────────────────────────────────────────────── /// List macroeconomic indicators. /// /// Path: `GET /v1/quote/macrodata` - pub async fn economic_indicator_list( + pub async fn macrodata_indicators( &self, offset: Option, limit: Option, @@ -856,7 +856,7 @@ impl FundamentalContext { /// Get historical data for a macroeconomic indicator. /// /// Path: `GET /v1/quote/macrodata/{indicator_code}` - pub async fn economic_indicator( + pub async fn macrodata( &self, indicator_code: impl Into, start_time: Option, diff --git a/rust/src/fundamental/types.rs b/rust/src/fundamental/types.rs index f2220ae1e..93e3047eb 100644 --- a/rust/src/fundamental/types.rs +++ b/rust/src/fundamental/types.rs @@ -1563,7 +1563,7 @@ pub struct AssetAllocationResponse { pub info: Vec, } -// ── economic_indicator ───────────────────────────────────────────────────── +// ── macrodata ───────────────────────────────────────────────────── /// Localized text in simplified Chinese, traditional Chinese, and English #[derive(Debug, Clone, Default, Serialize, Deserialize)] @@ -1582,7 +1582,7 @@ pub struct MultiLanguageText { /// Metadata for one macroeconomic indicator #[derive(Debug, Clone, Serialize, Deserialize)] pub struct EconomicIndicatorInfo { - /// External vendor code (used as input to `economic_indicator`) + /// External vendor code (used as input to `macrodata`) pub indicator_code: String, /// Publishing organisation #[serde(default)] @@ -1617,7 +1617,7 @@ pub struct EconomicIndicatorInfo { pub start_date: Option, } -/// Response for [`crate::FundamentalContext::economic_indicator_list`] +/// Response for [`crate::FundamentalContext::macrodata_list`] #[derive(Debug, Clone, Serialize, Deserialize)] pub struct EconomicIndicatorListResponse { /// Indicator list @@ -1657,7 +1657,7 @@ pub struct EconomicIndicatorData { pub unit_prefix: MultiLanguageText, } -/// Response for [`crate::FundamentalContext::economic_indicator`] +/// Response for [`crate::FundamentalContext::macrodata`] #[derive(Debug, Clone, Serialize, Deserialize)] pub struct EconomicIndicatorResponse { /// Indicator metadata From bc843093a80597ea20af8dc2f6878cc75cbbdf0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Tue, 9 Jun 2026 19:59:48 +0800 Subject: [PATCH 04/28] fix: change macrodata start_time/end_time params to OffsetDateTime (RFC3339) Input params now accept OffsetDateTime and are serialized as RFC3339 (2024-01-01T00:00:00Z) to match API requirements. - Rust/Python: Option - Node.js: Option unix seconds (converted internally) - Java: Option - Go: *time.Time Co-Authored-By: Claude Sonnet 4.6 (1M context) --- .../fundamental/FundamentalContext.java | 2 +- java/src/fundamental_context.rs | 8 +++++--- nodejs/src/fundamental/context.rs | 14 +++++++++++++- python/pysrc/longbridge/openapi.pyi | 4 ++-- python/src/fundamental/context.rs | 11 ++++++++--- python/src/fundamental/context_async.rs | 15 ++++++++++----- rust/src/blocking/fundamental.rs | 4 ++-- rust/src/fundamental/context.rs | 16 ++++++++++------ 8 files changed, 51 insertions(+), 23 deletions(-) diff --git a/java/javasrc/src/main/java/com/longbridge/fundamental/FundamentalContext.java b/java/javasrc/src/main/java/com/longbridge/fundamental/FundamentalContext.java index db692ef20..f8d7b842c 100644 --- a/java/javasrc/src/main/java/com/longbridge/fundamental/FundamentalContext.java +++ b/java/javasrc/src/main/java/com/longbridge/fundamental/FundamentalContext.java @@ -343,7 +343,7 @@ public CompletableFuture getMacrodataIndicators(Integer } /** Get historical data for a macroeconomic indicator. */ - public CompletableFuture getMacrodata(String indicatorCode, Long startTime, Long endTime, Integer limit) throws OpenApiException { + public CompletableFuture getMacrodata(String indicatorCode, java.time.OffsetDateTime startTime, java.time.OffsetDateTime endTime, Integer limit) throws OpenApiException { return AsyncCallback.executeTask((callback) -> { SdkNative.fundamentalContextMacrodata(raw, indicatorCode, startTime, endTime, limit, callback); }); diff --git a/java/src/fundamental_context.rs b/java/src/fundamental_context.rs index b5869ce1a..b4d2487ac 100644 --- a/java/src/fundamental_context.rs +++ b/java/src/fundamental_context.rs @@ -300,13 +300,15 @@ pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextMa jni_result(&mut env, (), |env| { let context = &*(context as *const ContextObj); let indicator_code: String = FromJValue::from_jvalue(env, indicator_code.into())?; - let start_time: Option = FromJValue::from_jvalue(env, start_time.into())?; - let end_time: Option = FromJValue::from_jvalue(env, end_time.into())?; + let start_time: Option = + FromJValue::from_jvalue(env, start_time.into())?; + let end_time: Option = + FromJValue::from_jvalue(env, end_time.into())?; let limit: Option = FromJValue::from_jvalue(env, limit.into())?; async_util::execute(env, callback, async move { Ok(context .ctx - .economic_indicator(indicator_code, start_time, end_time, limit) + .macrodata(indicator_code, start_time, end_time, limit) .await?) })?; Ok(()) diff --git a/nodejs/src/fundamental/context.rs b/nodejs/src/fundamental/context.rs index 1ec05f3f4..c9d6bc8d2 100644 --- a/nodejs/src/fundamental/context.rs +++ b/nodejs/src/fundamental/context.rs @@ -314,9 +314,21 @@ impl FundamentalContext { end_time: Option, limit: Option, ) -> Result { + use time::OffsetDateTime; Ok(self .ctx - .macrodata(indicator_code, start_time, end_time, limit) + .macrodata( + indicator_code, + start_time + .map(OffsetDateTime::from_unix_timestamp) + .transpose() + .map_err(|e| napi::Error::from_reason(e.to_string()))?, + end_time + .map(OffsetDateTime::from_unix_timestamp) + .transpose() + .map_err(|e| napi::Error::from_reason(e.to_string()))?, + limit, + ) .await .map_err(ErrorNewType)? .into()) diff --git a/python/pysrc/longbridge/openapi.pyi b/python/pysrc/longbridge/openapi.pyi index 1949e792b..773bc5a5b 100644 --- a/python/pysrc/longbridge/openapi.pyi +++ b/python/pysrc/longbridge/openapi.pyi @@ -9942,8 +9942,8 @@ class FundamentalContext: def macrodata( self, indicator_code: str, - start_time: int | None = None, - end_time: int | None = None, + start_time: datetime | None = None, + end_time: datetime | None = None, limit: int | None = None, ) -> "EconomicIndicatorResponse": """ diff --git a/python/src/fundamental/context.rs b/python/src/fundamental/context.rs index 61e6605ea..3612893dd 100644 --- a/python/src/fundamental/context.rs +++ b/python/src/fundamental/context.rs @@ -228,13 +228,18 @@ impl FundamentalContext { fn macrodata( &self, indicator_code: String, - start_time: Option, - end_time: Option, + start_time: Option, + end_time: Option, limit: Option, ) -> PyResult { Ok(self .ctx - .macrodata(indicator_code, start_time, end_time, limit) + .macrodata( + indicator_code, + start_time.map(|t| t.0), + end_time.map(|t| t.0), + limit, + ) .map_err(ErrorNewType)? .into()) } diff --git a/python/src/fundamental/context_async.rs b/python/src/fundamental/context_async.rs index 044d07cd4..3789922d9 100644 --- a/python/src/fundamental/context_async.rs +++ b/python/src/fundamental/context_async.rs @@ -343,16 +343,21 @@ impl AsyncFundamentalContext { &self, py: Python<'_>, indicator_code: String, - start_time: Option, - end_time: Option, + start_time: Option, + end_time: Option, limit: Option, ) -> PyResult> { let ctx = self.ctx.clone(); pyo3_async_runtimes::tokio::future_into_py(py, async move { Ok(EconomicIndicatorResponse::from( - ctx.macrodata(indicator_code, start_time, end_time, limit) - .await - .map_err(ErrorNewType)?, + ctx.macrodata( + indicator_code, + start_time.map(|t| t.0), + end_time.map(|t| t.0), + limit, + ) + .await + .map_err(ErrorNewType)?, )) }) .map(|b| b.unbind()) diff --git a/rust/src/blocking/fundamental.rs b/rust/src/blocking/fundamental.rs index 70f258665..633c424d7 100644 --- a/rust/src/blocking/fundamental.rs +++ b/rust/src/blocking/fundamental.rs @@ -305,8 +305,8 @@ impl FundamentalContextSync { pub fn macrodata( &self, indicator_code: impl Into + Send + 'static, - start_time: Option, - end_time: Option, + start_time: Option, + end_time: Option, limit: Option, ) -> Result { self.rt.call(move |ctx| async move { diff --git a/rust/src/fundamental/context.rs b/rust/src/fundamental/context.rs index d415fcd3e..b975f6e9b 100644 --- a/rust/src/fundamental/context.rs +++ b/rust/src/fundamental/context.rs @@ -855,20 +855,24 @@ impl FundamentalContext { /// Get historical data for a macroeconomic indicator. /// + /// `start_time` and `end_time` filter by release timestamp. + /// /// Path: `GET /v1/quote/macrodata/{indicator_code}` pub async fn macrodata( &self, indicator_code: impl Into, - start_time: Option, - end_time: Option, + start_time: Option, + end_time: Option, limit: Option, ) -> Result { + use time::format_description::well_known::Rfc3339; + #[derive(Serialize)] struct Query { #[serde(skip_serializing_if = "Option::is_none")] - start_time: Option, + start_time: Option, #[serde(skip_serializing_if = "Option::is_none")] - end_time: Option, + end_time: Option, #[serde(skip_serializing_if = "Option::is_none")] limit: Option, } @@ -878,8 +882,8 @@ impl FundamentalContext { .http_cli .request(Method::GET, path) .query_params(Query { - start_time, - end_time, + start_time: start_time.map(|dt| dt.format(&Rfc3339).unwrap_or_default()), + end_time: end_time.map(|dt| dt.format(&Rfc3339).unwrap_or_default()), limit, }) .response::>() From 4f8c1637f81e07a6a066c7574b14d510c803ea3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Wed, 10 Jun 2026 09:38:09 +0800 Subject: [PATCH 05/28] fix: macrodata params use YYYY-MM-DD date strings start_date -> start_time: YYYY-MM-DDT00:00:00Z end_date -> end_time: YYYY-MM-DDT23:59:59Z Co-Authored-By: Claude Sonnet 4.6 (1M context) --- .../fundamental/FundamentalContext.java | 9 ++++++--- java/src/fundamental_context.rs | 8 +++----- nodejs/index.d.ts | 2 +- nodejs/src/fundamental/context.rs | 18 +++--------------- python/pysrc/longbridge/openapi.pyi | 8 ++++---- python/src/fundamental/context.rs | 11 +++-------- python/src/fundamental/context_async.rs | 15 +++++---------- rust/src/blocking/fundamental.rs | 6 +++--- rust/src/fundamental/context.rs | 14 +++++++------- 9 files changed, 35 insertions(+), 56 deletions(-) diff --git a/java/javasrc/src/main/java/com/longbridge/fundamental/FundamentalContext.java b/java/javasrc/src/main/java/com/longbridge/fundamental/FundamentalContext.java index f8d7b842c..797d27970 100644 --- a/java/javasrc/src/main/java/com/longbridge/fundamental/FundamentalContext.java +++ b/java/javasrc/src/main/java/com/longbridge/fundamental/FundamentalContext.java @@ -342,10 +342,13 @@ public CompletableFuture getMacrodataIndicators(Integer }); } - /** Get historical data for a macroeconomic indicator. */ - public CompletableFuture getMacrodata(String indicatorCode, java.time.OffsetDateTime startTime, java.time.OffsetDateTime endTime, Integer limit) throws OpenApiException { + /** + * Get historical data for a macroeconomic indicator. + * startDate and endDate are date strings in "YYYY-MM-DD" format. + */ + public CompletableFuture getMacrodata(String indicatorCode, String startDate, String endDate, Integer limit) throws OpenApiException { return AsyncCallback.executeTask((callback) -> { - SdkNative.fundamentalContextMacrodata(raw, indicatorCode, startTime, endTime, limit, callback); + SdkNative.fundamentalContextMacrodata(raw, indicatorCode, startDate, endDate, limit, callback); }); } } diff --git a/java/src/fundamental_context.rs b/java/src/fundamental_context.rs index b4d2487ac..207827e56 100644 --- a/java/src/fundamental_context.rs +++ b/java/src/fundamental_context.rs @@ -300,15 +300,13 @@ pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextMa jni_result(&mut env, (), |env| { let context = &*(context as *const ContextObj); let indicator_code: String = FromJValue::from_jvalue(env, indicator_code.into())?; - let start_time: Option = - FromJValue::from_jvalue(env, start_time.into())?; - let end_time: Option = - FromJValue::from_jvalue(env, end_time.into())?; + let start_date: Option = FromJValue::from_jvalue(env, start_time.into())?; + let end_date: Option = FromJValue::from_jvalue(env, end_time.into())?; let limit: Option = FromJValue::from_jvalue(env, limit.into())?; async_util::execute(env, callback, async move { Ok(context .ctx - .macrodata(indicator_code, start_time, end_time, limit) + .macrodata(indicator_code, start_date, end_date, limit) .await?) })?; Ok(()) diff --git a/nodejs/index.d.ts b/nodejs/index.d.ts index 08e99d698..d77fe554d 100644 --- a/nodejs/index.d.ts +++ b/nodejs/index.d.ts @@ -621,7 +621,7 @@ export declare class FundamentalContext { /** List macroeconomic indicators */ macrodataIndicators(offset?: number | null, limit?: number | null): Promise> /** Get historical data for a macroeconomic indicator */ - macrodata(indicatorCode: string, startTime?: bigint | null, endTime?: bigint | null, limit?: number | null): Promise + macrodata(indicatorCode: string, startDate?: string | null, endDate?: string | null, limit?: number | null): Promise } /** Fund position */ diff --git a/nodejs/src/fundamental/context.rs b/nodejs/src/fundamental/context.rs index c9d6bc8d2..171ba7689 100644 --- a/nodejs/src/fundamental/context.rs +++ b/nodejs/src/fundamental/context.rs @@ -310,25 +310,13 @@ impl FundamentalContext { pub async fn macrodata( &self, indicator_code: String, - start_time: Option, - end_time: Option, + start_date: Option, + end_date: Option, limit: Option, ) -> Result { - use time::OffsetDateTime; Ok(self .ctx - .macrodata( - indicator_code, - start_time - .map(OffsetDateTime::from_unix_timestamp) - .transpose() - .map_err(|e| napi::Error::from_reason(e.to_string()))?, - end_time - .map(OffsetDateTime::from_unix_timestamp) - .transpose() - .map_err(|e| napi::Error::from_reason(e.to_string()))?, - limit, - ) + .macrodata(indicator_code, start_date, end_date, limit) .await .map_err(ErrorNewType)? .into()) diff --git a/python/pysrc/longbridge/openapi.pyi b/python/pysrc/longbridge/openapi.pyi index 773bc5a5b..cfe20267a 100644 --- a/python/pysrc/longbridge/openapi.pyi +++ b/python/pysrc/longbridge/openapi.pyi @@ -9942,8 +9942,8 @@ class FundamentalContext: def macrodata( self, indicator_code: str, - start_time: datetime | None = None, - end_time: datetime | None = None, + start_date: str | None = None, + end_date: str | None = None, limit: int | None = None, ) -> "EconomicIndicatorResponse": """ @@ -9951,8 +9951,8 @@ class FundamentalContext: Args: indicator_code: External vendor code from ``macrodata_indicators`` - start_time: Data start Unix timestamp (optional) - end_time: Data end Unix timestamp (optional) + start_date: Start date in ``"YYYY-MM-DD"`` format (optional) + end_date: End date in ``"YYYY-MM-DD"`` format (optional) limit: Max records to return (default 100, max 100) Returns: diff --git a/python/src/fundamental/context.rs b/python/src/fundamental/context.rs index 3612893dd..42f5ecb7b 100644 --- a/python/src/fundamental/context.rs +++ b/python/src/fundamental/context.rs @@ -228,18 +228,13 @@ impl FundamentalContext { fn macrodata( &self, indicator_code: String, - start_time: Option, - end_time: Option, + start_date: Option, + end_date: Option, limit: Option, ) -> PyResult { Ok(self .ctx - .macrodata( - indicator_code, - start_time.map(|t| t.0), - end_time.map(|t| t.0), - limit, - ) + .macrodata(indicator_code, start_date, end_date, limit) .map_err(ErrorNewType)? .into()) } diff --git a/python/src/fundamental/context_async.rs b/python/src/fundamental/context_async.rs index 3789922d9..8a9e85df0 100644 --- a/python/src/fundamental/context_async.rs +++ b/python/src/fundamental/context_async.rs @@ -343,21 +343,16 @@ impl AsyncFundamentalContext { &self, py: Python<'_>, indicator_code: String, - start_time: Option, - end_time: Option, + start_date: Option, + end_date: Option, limit: Option, ) -> PyResult> { let ctx = self.ctx.clone(); pyo3_async_runtimes::tokio::future_into_py(py, async move { Ok(EconomicIndicatorResponse::from( - ctx.macrodata( - indicator_code, - start_time.map(|t| t.0), - end_time.map(|t| t.0), - limit, - ) - .await - .map_err(ErrorNewType)?, + ctx.macrodata(indicator_code, start_date, end_date, limit) + .await + .map_err(ErrorNewType)?, )) }) .map(|b| b.unbind()) diff --git a/rust/src/blocking/fundamental.rs b/rust/src/blocking/fundamental.rs index 633c424d7..ea757facb 100644 --- a/rust/src/blocking/fundamental.rs +++ b/rust/src/blocking/fundamental.rs @@ -305,12 +305,12 @@ impl FundamentalContextSync { pub fn macrodata( &self, indicator_code: impl Into + Send + 'static, - start_time: Option, - end_time: Option, + start_date: Option + Send + 'static>, + end_date: Option + Send + 'static>, limit: Option, ) -> Result { self.rt.call(move |ctx| async move { - ctx.macrodata(indicator_code, start_time, end_time, limit) + ctx.macrodata(indicator_code, start_date, end_date, limit) .await }) } diff --git a/rust/src/fundamental/context.rs b/rust/src/fundamental/context.rs index b975f6e9b..7f211b015 100644 --- a/rust/src/fundamental/context.rs +++ b/rust/src/fundamental/context.rs @@ -855,18 +855,18 @@ impl FundamentalContext { /// Get historical data for a macroeconomic indicator. /// - /// `start_time` and `end_time` filter by release timestamp. + /// `start_date` and `end_date` are date strings in `"YYYY-MM-DD"` format. + /// `start_date` is sent as `YYYY-MM-DDT00:00:00Z`; `end_date` is sent as + /// `YYYY-MM-DDT23:59:59Z`. /// /// Path: `GET /v1/quote/macrodata/{indicator_code}` pub async fn macrodata( &self, indicator_code: impl Into, - start_time: Option, - end_time: Option, + start_date: Option>, + end_date: Option>, limit: Option, ) -> Result { - use time::format_description::well_known::Rfc3339; - #[derive(Serialize)] struct Query { #[serde(skip_serializing_if = "Option::is_none")] @@ -882,8 +882,8 @@ impl FundamentalContext { .http_cli .request(Method::GET, path) .query_params(Query { - start_time: start_time.map(|dt| dt.format(&Rfc3339).unwrap_or_default()), - end_time: end_time.map(|dt| dt.format(&Rfc3339).unwrap_or_default()), + start_time: start_date.map(|d| format!("{}T00:00:00Z", d.into())), + end_time: end_date.map(|d| format!("{}T23:59:59Z", d.into())), limit, }) .response::>() From 72fe7280dc03abec0466e39e7d3cf90813d2a96d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Wed, 10 Jun 2026 09:44:35 +0800 Subject: [PATCH 06/28] refactor: rename EconomicIndicator* types to Macrodata* prefix EconomicIndicatorInfo -> MacrodataIndicatorInfo EconomicIndicatorData -> MacrodataRecord EconomicIndicatorResponse -> MacrodataResponse Co-Authored-By: Claude Sonnet 4.6 (1M context) --- .../EconomicIndicatorResponse.java | 7 ------ .../fundamental/FundamentalContext.java | 4 ++-- ...rInfo.java => MacrodataIndicatorInfo.java} | 2 +- ...ndicatorData.java => MacrodataRecord.java} | 2 +- .../fundamental/MacrodataResponse.java | 7 ++++++ java/src/types/classes.rs | 12 +++++----- nodejs/index.d.ts | 14 ++++++------ nodejs/src/fundamental/context.rs | 4 ++-- nodejs/src/fundamental/types.rs | 22 +++++++++---------- python/pysrc/longbridge/openapi.pyi | 18 +++++++-------- python/src/fundamental/context.rs | 4 ++-- python/src/fundamental/context_async.rs | 4 ++-- python/src/fundamental/mod.rs | 6 ++--- python/src/fundamental/types.rs | 22 +++++++++---------- rust/src/fundamental/context.rs | 6 ++--- rust/src/fundamental/types.rs | 12 +++++----- 16 files changed, 73 insertions(+), 73 deletions(-) delete mode 100644 java/javasrc/src/main/java/com/longbridge/fundamental/EconomicIndicatorResponse.java rename java/javasrc/src/main/java/com/longbridge/fundamental/{EconomicIndicatorInfo.java => MacrodataIndicatorInfo.java} (94%) rename java/javasrc/src/main/java/com/longbridge/fundamental/{EconomicIndicatorData.java => MacrodataRecord.java} (92%) create mode 100644 java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataResponse.java diff --git a/java/javasrc/src/main/java/com/longbridge/fundamental/EconomicIndicatorResponse.java b/java/javasrc/src/main/java/com/longbridge/fundamental/EconomicIndicatorResponse.java deleted file mode 100644 index 6a2740a91..000000000 --- a/java/javasrc/src/main/java/com/longbridge/fundamental/EconomicIndicatorResponse.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.longbridge.fundamental; - -/** Response for {@link FundamentalContext#getEconomicIndicator}. */ -public class EconomicIndicatorResponse { - public EconomicIndicatorInfo info; - public EconomicIndicatorData[] data; -} diff --git a/java/javasrc/src/main/java/com/longbridge/fundamental/FundamentalContext.java b/java/javasrc/src/main/java/com/longbridge/fundamental/FundamentalContext.java index 797d27970..4c73489ee 100644 --- a/java/javasrc/src/main/java/com/longbridge/fundamental/FundamentalContext.java +++ b/java/javasrc/src/main/java/com/longbridge/fundamental/FundamentalContext.java @@ -336,7 +336,7 @@ public CompletableFuture getValuationComparison(Val } /** List macroeconomic indicators. */ - public CompletableFuture getMacrodataIndicators(Integer offset, Integer limit) throws OpenApiException { + public CompletableFuture getMacrodataIndicators(Integer offset, Integer limit) throws OpenApiException { return AsyncCallback.executeTask((callback) -> { SdkNative.fundamentalContextMacrodataIndicators(raw, offset, limit, callback); }); @@ -346,7 +346,7 @@ public CompletableFuture getMacrodataIndicators(Integer * Get historical data for a macroeconomic indicator. * startDate and endDate are date strings in "YYYY-MM-DD" format. */ - public CompletableFuture getMacrodata(String indicatorCode, String startDate, String endDate, Integer limit) throws OpenApiException { + public CompletableFuture getMacrodata(String indicatorCode, String startDate, String endDate, Integer limit) throws OpenApiException { return AsyncCallback.executeTask((callback) -> { SdkNative.fundamentalContextMacrodata(raw, indicatorCode, startDate, endDate, limit, callback); }); diff --git a/java/javasrc/src/main/java/com/longbridge/fundamental/EconomicIndicatorInfo.java b/java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataIndicatorInfo.java similarity index 94% rename from java/javasrc/src/main/java/com/longbridge/fundamental/EconomicIndicatorInfo.java rename to java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataIndicatorInfo.java index b7ea08601..99e72805b 100644 --- a/java/javasrc/src/main/java/com/longbridge/fundamental/EconomicIndicatorInfo.java +++ b/java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataIndicatorInfo.java @@ -1,7 +1,7 @@ package com.longbridge.fundamental; /** Metadata for one macroeconomic indicator. */ -public class EconomicIndicatorInfo { +public class MacrodataIndicatorInfo { /** External vendor code (input to getEconomicIndicator). */ public String indicatorCode; public String sourceOrg; diff --git a/java/javasrc/src/main/java/com/longbridge/fundamental/EconomicIndicatorData.java b/java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataRecord.java similarity index 92% rename from java/javasrc/src/main/java/com/longbridge/fundamental/EconomicIndicatorData.java rename to java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataRecord.java index c81fa359c..d1553de99 100644 --- a/java/javasrc/src/main/java/com/longbridge/fundamental/EconomicIndicatorData.java +++ b/java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataRecord.java @@ -1,7 +1,7 @@ package com.longbridge.fundamental; /** One historical data point for a macroeconomic indicator. */ -public class EconomicIndicatorData { +public class MacrodataRecord { /** Statistical period (e.g. 2024-Q1, 2024-03). */ public String period; public String releaseAt; diff --git a/java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataResponse.java b/java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataResponse.java new file mode 100644 index 000000000..6937d12c9 --- /dev/null +++ b/java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataResponse.java @@ -0,0 +1,7 @@ +package com.longbridge.fundamental; + +/** Response for {@link FundamentalContext#getEconomicIndicator}. */ +public class MacrodataResponse { + public MacrodataIndicatorInfo info; + public MacrodataRecord[] data; +} diff --git a/java/src/types/classes.rs b/java/src/types/classes.rs index 4061f93c7..8ac0640f2 100644 --- a/java/src/types/classes.rs +++ b/java/src/types/classes.rs @@ -2705,8 +2705,8 @@ impl_java_class!( ); impl_java_class!( - "com/longbridge/fundamental/EconomicIndicatorInfo", - longbridge::fundamental::EconomicIndicatorInfo, + "com/longbridge/fundamental/MacrodataIndicatorInfo", + longbridge::fundamental::MacrodataIndicatorInfo, [ indicator_code, source_org, @@ -2722,8 +2722,8 @@ impl_java_class!( ); impl_java_class!( - "com/longbridge/fundamental/EconomicIndicatorData", - longbridge::fundamental::EconomicIndicatorData, + "com/longbridge/fundamental/MacrodataRecord", + longbridge::fundamental::MacrodataRecord, [ period, release_at, @@ -2738,8 +2738,8 @@ impl_java_class!( ); impl_java_class!( - "com/longbridge/fundamental/EconomicIndicatorResponse", - longbridge::fundamental::EconomicIndicatorResponse, + "com/longbridge/fundamental/MacrodataResponse", + longbridge::fundamental::MacrodataResponse, [ info, #[java(objarray)] diff --git a/nodejs/index.d.ts b/nodejs/index.d.ts index d77fe554d..d64c2aab9 100644 --- a/nodejs/index.d.ts +++ b/nodejs/index.d.ts @@ -619,9 +619,9 @@ export declare class FundamentalContext { */ etfAssetAllocation(symbol: string): Promise /** List macroeconomic indicators */ - macrodataIndicators(offset?: number | null, limit?: number | null): Promise> + macrodataIndicators(offset?: number | null, limit?: number | null): Promise> /** Get historical data for a macroeconomic indicator */ - macrodata(indicatorCode: string, startDate?: string | null, endDate?: string | null, limit?: number | null): Promise + macrodata(indicatorCode: string, startDate?: string | null, endDate?: string | null, limit?: number | null): Promise } /** Fund position */ @@ -3144,7 +3144,7 @@ export interface MultiLanguageText { traditionalChinese: string } /** Metadata for one macroeconomic indicator */ -export interface EconomicIndicatorInfo { +export interface MacrodataIndicatorInfo { indicatorCode: string sourceOrg: string country: string @@ -3158,7 +3158,7 @@ export interface EconomicIndicatorInfo { startDate: bigint | null } /** One historical data point for a macroeconomic indicator */ -export interface EconomicIndicatorData { +export interface MacrodataRecord { period: string /** Release datetime (unix timestamp in seconds; null if unset) */ releaseAt: bigint | null @@ -3172,9 +3172,9 @@ export interface EconomicIndicatorData { unitPrefix: MultiLanguageText } /** Response for macrodata */ -export interface EconomicIndicatorResponse { - info: EconomicIndicatorInfo - data: Array +export interface MacrodataResponse { + info: MacrodataIndicatorInfo + data: Array } export declare const enum AssetType { diff --git a/nodejs/src/fundamental/context.rs b/nodejs/src/fundamental/context.rs index 171ba7689..402bf14bd 100644 --- a/nodejs/src/fundamental/context.rs +++ b/nodejs/src/fundamental/context.rs @@ -294,7 +294,7 @@ impl FundamentalContext { &self, offset: Option, limit: Option, - ) -> Result> { + ) -> Result> { Ok(self .ctx .macrodata_indicators(offset, limit) @@ -313,7 +313,7 @@ impl FundamentalContext { start_date: Option, end_date: Option, limit: Option, - ) -> Result { + ) -> Result { Ok(self .ctx .macrodata(indicator_code, start_date, end_date, limit) diff --git a/nodejs/src/fundamental/types.rs b/nodejs/src/fundamental/types.rs index 476d4fe3c..186e847be 100644 --- a/nodejs/src/fundamental/types.rs +++ b/nodejs/src/fundamental/types.rs @@ -1927,7 +1927,7 @@ impl From for MultiLanguageText { /// Metadata for one macroeconomic indicator #[napi_derive::napi(object)] #[derive(Debug, Clone)] -pub struct EconomicIndicatorInfo { +pub struct MacrodataIndicatorInfo { pub indicator_code: String, pub source_org: String, pub country: String, @@ -1941,8 +1941,8 @@ pub struct EconomicIndicatorInfo { pub start_date: Option, } -impl From for EconomicIndicatorInfo { - fn from(v: lb::EconomicIndicatorInfo) -> Self { +impl From for MacrodataIndicatorInfo { + fn from(v: lb::MacrodataIndicatorInfo) -> Self { Self { indicator_code: v.indicator_code, source_org: v.source_org, @@ -1961,7 +1961,7 @@ impl From for EconomicIndicatorInfo { /// One historical data point for a macroeconomic indicator #[napi_derive::napi(object)] #[derive(Debug, Clone)] -pub struct EconomicIndicatorData { +pub struct MacrodataRecord { pub period: String, /// Release datetime (unix timestamp in seconds; null if unset) pub release_at: Option, @@ -1975,8 +1975,8 @@ pub struct EconomicIndicatorData { pub unit_prefix: MultiLanguageText, } -impl From for EconomicIndicatorData { - fn from(v: lb::EconomicIndicatorData) -> Self { +impl From for MacrodataRecord { + fn from(v: lb::MacrodataRecord) -> Self { Self { period: v.period, release_at: v.release_at.map(|dt| dt.unix_timestamp()), @@ -1994,13 +1994,13 @@ impl From for EconomicIndicatorData { /// Response for economic_indicator #[napi_derive::napi(object)] #[derive(Debug, Clone)] -pub struct EconomicIndicatorResponse { - pub info: EconomicIndicatorInfo, - pub data: Vec, +pub struct MacrodataResponse { + pub info: MacrodataIndicatorInfo, + pub data: Vec, } -impl From for EconomicIndicatorResponse { - fn from(v: lb::EconomicIndicatorResponse) -> Self { +impl From for MacrodataResponse { + fn from(v: lb::MacrodataResponse) -> Self { Self { info: v.info.into(), data: v.data.into_iter().map(Into::into).collect(), diff --git a/python/pysrc/longbridge/openapi.pyi b/python/pysrc/longbridge/openapi.pyi index cfe20267a..948800629 100644 --- a/python/pysrc/longbridge/openapi.pyi +++ b/python/pysrc/longbridge/openapi.pyi @@ -9926,7 +9926,7 @@ class FundamentalContext: self, offset: int | None = None, limit: int | None = None, - ) -> list["EconomicIndicatorInfo"]: + ) -> list["MacrodataIndicatorInfo"]: """ List macroeconomic indicators. @@ -9935,7 +9935,7 @@ class FundamentalContext: limit: Page size (default 100, max 1000) Returns: - List of :class:`EconomicIndicatorInfo` + List of :class:`MacrodataIndicatorInfo` """ ... @@ -9945,7 +9945,7 @@ class FundamentalContext: start_date: str | None = None, end_date: str | None = None, limit: int | None = None, - ) -> "EconomicIndicatorResponse": + ) -> "MacrodataResponse": """ Get historical data for a macroeconomic indicator. @@ -9956,7 +9956,7 @@ class FundamentalContext: limit: Max records to return (default 100, max 100) Returns: - :class:`EconomicIndicatorResponse` + :class:`MacrodataResponse` """ ... @@ -10111,7 +10111,7 @@ class MultiLanguageText: traditional_chinese: str -class EconomicIndicatorInfo: +class MacrodataIndicatorInfo: """Metadata for one macroeconomic indicator.""" indicator_code: str @@ -10129,7 +10129,7 @@ class EconomicIndicatorInfo: """Start date of data coverage""" -class EconomicIndicatorData: +class MacrodataRecord: """One historical data point for a macroeconomic indicator.""" period: str @@ -10144,11 +10144,11 @@ class EconomicIndicatorData: unit_prefix: MultiLanguageText -class EconomicIndicatorResponse: +class MacrodataResponse: """Response for macrodata.""" - info: EconomicIndicatorInfo - data: list[EconomicIndicatorData] + info: MacrodataIndicatorInfo + data: list[MacrodataRecord] # ── MarketContext ───────────────────────────────────────────────── diff --git a/python/src/fundamental/context.rs b/python/src/fundamental/context.rs index 42f5ecb7b..d19837cfe 100644 --- a/python/src/fundamental/context.rs +++ b/python/src/fundamental/context.rs @@ -214,7 +214,7 @@ impl FundamentalContext { &self, offset: Option, limit: Option, - ) -> PyResult> { + ) -> PyResult> { Ok(self .ctx .macrodata_indicators(offset, limit) @@ -231,7 +231,7 @@ impl FundamentalContext { start_date: Option, end_date: Option, limit: Option, - ) -> PyResult { + ) -> PyResult { Ok(self .ctx .macrodata(indicator_code, start_date, end_date, limit) diff --git a/python/src/fundamental/context_async.rs b/python/src/fundamental/context_async.rs index 8a9e85df0..e88fc642f 100644 --- a/python/src/fundamental/context_async.rs +++ b/python/src/fundamental/context_async.rs @@ -332,7 +332,7 @@ impl AsyncFundamentalContext { .await .map_err(ErrorNewType)? .into_iter() - .map(EconomicIndicatorInfo::from) + .map(MacrodataIndicatorInfo::from) .collect::>()) }) .map(|b| b.unbind()) @@ -349,7 +349,7 @@ impl AsyncFundamentalContext { ) -> PyResult> { let ctx = self.ctx.clone(); pyo3_async_runtimes::tokio::future_into_py(py, async move { - Ok(EconomicIndicatorResponse::from( + Ok(MacrodataResponse::from( ctx.macrodata(indicator_code, start_date, end_date, limit) .await .map_err(ErrorNewType)?, diff --git a/python/src/fundamental/mod.rs b/python/src/fundamental/mod.rs index 761de5d1e..ec20bfd9c 100644 --- a/python/src/fundamental/mod.rs +++ b/python/src/fundamental/mod.rs @@ -75,9 +75,9 @@ pub(crate) fn register_types(parent: &Bound) -> PyResult<()> { parent.add_class::()?; parent.add_class::()?; parent.add_class::()?; - parent.add_class::()?; - parent.add_class::()?; - parent.add_class::()?; + parent.add_class::()?; + parent.add_class::()?; + parent.add_class::()?; parent.add_class::()?; parent.add_class::()?; Ok(()) diff --git a/python/src/fundamental/types.rs b/python/src/fundamental/types.rs index 05376e9be..d79b1b6fd 100644 --- a/python/src/fundamental/types.rs +++ b/python/src/fundamental/types.rs @@ -1990,7 +1990,7 @@ impl From for MultiLanguageText { /// Metadata for one macroeconomic indicator #[pyclass(get_all, skip_from_py_object)] #[derive(Debug, Clone)] -pub(crate) struct EconomicIndicatorInfo { +pub(crate) struct MacrodataIndicatorInfo { pub indicator_code: String, pub source_org: String, pub country: String, @@ -2003,8 +2003,8 @@ pub(crate) struct EconomicIndicatorInfo { pub start_date: Option, } -impl From for EconomicIndicatorInfo { - fn from(v: lb::EconomicIndicatorInfo) -> Self { +impl From for MacrodataIndicatorInfo { + fn from(v: lb::MacrodataIndicatorInfo) -> Self { Self { indicator_code: v.indicator_code, source_org: v.source_org, @@ -2023,7 +2023,7 @@ impl From for EconomicIndicatorInfo { /// One historical data point for a macroeconomic indicator #[pyclass(get_all, skip_from_py_object)] #[derive(Debug, Clone)] -pub(crate) struct EconomicIndicatorData { +pub(crate) struct MacrodataRecord { pub period: String, pub release_at: Option, pub actual_value: String, @@ -2035,8 +2035,8 @@ pub(crate) struct EconomicIndicatorData { pub unit_prefix: MultiLanguageText, } -impl From for EconomicIndicatorData { - fn from(v: lb::EconomicIndicatorData) -> Self { +impl From for MacrodataRecord { + fn from(v: lb::MacrodataRecord) -> Self { Self { period: v.period, release_at: v.release_at.map(crate::time::PyOffsetDateTimeWrapper), @@ -2054,13 +2054,13 @@ impl From for EconomicIndicatorData { /// Response for economic_indicator #[pyclass(get_all, skip_from_py_object)] #[derive(Debug, Clone)] -pub(crate) struct EconomicIndicatorResponse { - pub info: EconomicIndicatorInfo, - pub data: Vec, +pub(crate) struct MacrodataResponse { + pub info: MacrodataIndicatorInfo, + pub data: Vec, } -impl From for EconomicIndicatorResponse { - fn from(v: lb::EconomicIndicatorResponse) -> Self { +impl From for MacrodataResponse { + fn from(v: lb::MacrodataResponse) -> Self { Self { info: v.info.into(), data: v.data.into_iter().map(Into::into).collect(), diff --git a/rust/src/fundamental/context.rs b/rust/src/fundamental/context.rs index 7f211b015..6c1d40943 100644 --- a/rust/src/fundamental/context.rs +++ b/rust/src/fundamental/context.rs @@ -839,7 +839,7 @@ impl FundamentalContext { &self, offset: Option, limit: Option, - ) -> Result> { + ) -> Result> { #[derive(Serialize)] struct Query { #[serde(skip_serializing_if = "Option::is_none")] @@ -866,7 +866,7 @@ impl FundamentalContext { start_date: Option>, end_date: Option>, limit: Option, - ) -> Result { + ) -> Result { #[derive(Serialize)] struct Query { #[serde(skip_serializing_if = "Option::is_none")] @@ -886,7 +886,7 @@ impl FundamentalContext { end_time: end_date.map(|d| format!("{}T23:59:59Z", d.into())), limit, }) - .response::>() + .response::>() .send() .with_subscriber(self.0.log_subscriber.clone()) .await? diff --git a/rust/src/fundamental/types.rs b/rust/src/fundamental/types.rs index 93e3047eb..d587ad7a0 100644 --- a/rust/src/fundamental/types.rs +++ b/rust/src/fundamental/types.rs @@ -1581,7 +1581,7 @@ pub struct MultiLanguageText { /// Metadata for one macroeconomic indicator #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct EconomicIndicatorInfo { +pub struct MacrodataIndicatorInfo { /// External vendor code (used as input to `macrodata`) pub indicator_code: String, /// Publishing organisation @@ -1622,12 +1622,12 @@ pub struct EconomicIndicatorInfo { pub struct EconomicIndicatorListResponse { /// Indicator list #[serde(default)] - pub data: Vec, + pub data: Vec, } /// One historical data point for a macroeconomic indicator #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct EconomicIndicatorData { +pub struct MacrodataRecord { /// Statistical period (e.g. `2024-Q1`, `2024-03`) #[serde(default)] pub period: String, @@ -1659,10 +1659,10 @@ pub struct EconomicIndicatorData { /// Response for [`crate::FundamentalContext::macrodata`] #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct EconomicIndicatorResponse { +pub struct MacrodataResponse { /// Indicator metadata - pub info: EconomicIndicatorInfo, + pub info: MacrodataIndicatorInfo, /// Historical data points #[serde(default)] - pub data: Vec, + pub data: Vec, } From c419216195acab476adda77b0bc277c86a1ae84b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Wed, 10 Jun 2026 09:46:10 +0800 Subject: [PATCH 07/28] refactor: simplify Macrodata type names MacrodataIndicatorInfo -> MacrodataIndicator MacrodataRecord -> Macrodata Co-Authored-By: Claude Sonnet 4.6 (1M context) --- .../fundamental/FundamentalContext.java | 2 +- .../{MacrodataRecord.java => Macrodata.java} | 2 +- ...ndicatorInfo.java => MacrodataIndicator.java} | 2 +- .../fundamental/MacrodataResponse.java | 4 ++-- java/src/types/classes.rs | 8 ++++---- nodejs/index.d.ts | 10 +++++----- nodejs/src/fundamental/context.rs | 2 +- nodejs/src/fundamental/types.rs | 16 ++++++++-------- python/pysrc/longbridge/openapi.pyi | 12 ++++++------ python/src/fundamental/context.rs | 2 +- python/src/fundamental/context_async.rs | 2 +- python/src/fundamental/mod.rs | 4 ++-- python/src/fundamental/types.rs | 16 ++++++++-------- rust/src/fundamental/context.rs | 2 +- rust/src/fundamental/types.rs | 10 +++++----- 15 files changed, 47 insertions(+), 47 deletions(-) rename java/javasrc/src/main/java/com/longbridge/fundamental/{MacrodataRecord.java => Macrodata.java} (93%) rename java/javasrc/src/main/java/com/longbridge/fundamental/{MacrodataIndicatorInfo.java => MacrodataIndicator.java} (94%) diff --git a/java/javasrc/src/main/java/com/longbridge/fundamental/FundamentalContext.java b/java/javasrc/src/main/java/com/longbridge/fundamental/FundamentalContext.java index 4c73489ee..85144d65e 100644 --- a/java/javasrc/src/main/java/com/longbridge/fundamental/FundamentalContext.java +++ b/java/javasrc/src/main/java/com/longbridge/fundamental/FundamentalContext.java @@ -336,7 +336,7 @@ public CompletableFuture getValuationComparison(Val } /** List macroeconomic indicators. */ - public CompletableFuture getMacrodataIndicators(Integer offset, Integer limit) throws OpenApiException { + public CompletableFuture getMacrodataIndicators(Integer offset, Integer limit) throws OpenApiException { return AsyncCallback.executeTask((callback) -> { SdkNative.fundamentalContextMacrodataIndicators(raw, offset, limit, callback); }); diff --git a/java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataRecord.java b/java/javasrc/src/main/java/com/longbridge/fundamental/Macrodata.java similarity index 93% rename from java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataRecord.java rename to java/javasrc/src/main/java/com/longbridge/fundamental/Macrodata.java index d1553de99..9eadc8aa7 100644 --- a/java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataRecord.java +++ b/java/javasrc/src/main/java/com/longbridge/fundamental/Macrodata.java @@ -1,7 +1,7 @@ package com.longbridge.fundamental; /** One historical data point for a macroeconomic indicator. */ -public class MacrodataRecord { +public class Macrodata { /** Statistical period (e.g. 2024-Q1, 2024-03). */ public String period; public String releaseAt; diff --git a/java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataIndicatorInfo.java b/java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataIndicator.java similarity index 94% rename from java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataIndicatorInfo.java rename to java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataIndicator.java index 99e72805b..deefd5eb8 100644 --- a/java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataIndicatorInfo.java +++ b/java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataIndicator.java @@ -1,7 +1,7 @@ package com.longbridge.fundamental; /** Metadata for one macroeconomic indicator. */ -public class MacrodataIndicatorInfo { +public class MacrodataIndicator { /** External vendor code (input to getEconomicIndicator). */ public String indicatorCode; public String sourceOrg; diff --git a/java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataResponse.java b/java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataResponse.java index 6937d12c9..b4e4cb1d5 100644 --- a/java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataResponse.java +++ b/java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataResponse.java @@ -2,6 +2,6 @@ /** Response for {@link FundamentalContext#getEconomicIndicator}. */ public class MacrodataResponse { - public MacrodataIndicatorInfo info; - public MacrodataRecord[] data; + public MacrodataIndicator info; + public Macrodata[] data; } diff --git a/java/src/types/classes.rs b/java/src/types/classes.rs index 8ac0640f2..22c3d5733 100644 --- a/java/src/types/classes.rs +++ b/java/src/types/classes.rs @@ -2705,8 +2705,8 @@ impl_java_class!( ); impl_java_class!( - "com/longbridge/fundamental/MacrodataIndicatorInfo", - longbridge::fundamental::MacrodataIndicatorInfo, + "com/longbridge/fundamental/MacrodataIndicator", + longbridge::fundamental::MacrodataIndicator, [ indicator_code, source_org, @@ -2722,8 +2722,8 @@ impl_java_class!( ); impl_java_class!( - "com/longbridge/fundamental/MacrodataRecord", - longbridge::fundamental::MacrodataRecord, + "com/longbridge/fundamental/Macrodata", + longbridge::fundamental::Macrodata, [ period, release_at, diff --git a/nodejs/index.d.ts b/nodejs/index.d.ts index d64c2aab9..8db26c69c 100644 --- a/nodejs/index.d.ts +++ b/nodejs/index.d.ts @@ -619,7 +619,7 @@ export declare class FundamentalContext { */ etfAssetAllocation(symbol: string): Promise /** List macroeconomic indicators */ - macrodataIndicators(offset?: number | null, limit?: number | null): Promise> + macrodataIndicators(offset?: number | null, limit?: number | null): Promise> /** Get historical data for a macroeconomic indicator */ macrodata(indicatorCode: string, startDate?: string | null, endDate?: string | null, limit?: number | null): Promise } @@ -3144,7 +3144,7 @@ export interface MultiLanguageText { traditionalChinese: string } /** Metadata for one macroeconomic indicator */ -export interface MacrodataIndicatorInfo { +export interface MacrodataIndicator { indicatorCode: string sourceOrg: string country: string @@ -3158,7 +3158,7 @@ export interface MacrodataIndicatorInfo { startDate: bigint | null } /** One historical data point for a macroeconomic indicator */ -export interface MacrodataRecord { +export interface Macrodata { period: string /** Release datetime (unix timestamp in seconds; null if unset) */ releaseAt: bigint | null @@ -3173,8 +3173,8 @@ export interface MacrodataRecord { } /** Response for macrodata */ export interface MacrodataResponse { - info: MacrodataIndicatorInfo - data: Array + info: MacrodataIndicator + data: Array } export declare const enum AssetType { diff --git a/nodejs/src/fundamental/context.rs b/nodejs/src/fundamental/context.rs index 402bf14bd..f35d19544 100644 --- a/nodejs/src/fundamental/context.rs +++ b/nodejs/src/fundamental/context.rs @@ -294,7 +294,7 @@ impl FundamentalContext { &self, offset: Option, limit: Option, - ) -> Result> { + ) -> Result> { Ok(self .ctx .macrodata_indicators(offset, limit) diff --git a/nodejs/src/fundamental/types.rs b/nodejs/src/fundamental/types.rs index 186e847be..dc41ba60f 100644 --- a/nodejs/src/fundamental/types.rs +++ b/nodejs/src/fundamental/types.rs @@ -1927,7 +1927,7 @@ impl From for MultiLanguageText { /// Metadata for one macroeconomic indicator #[napi_derive::napi(object)] #[derive(Debug, Clone)] -pub struct MacrodataIndicatorInfo { +pub struct MacrodataIndicator { pub indicator_code: String, pub source_org: String, pub country: String, @@ -1941,8 +1941,8 @@ pub struct MacrodataIndicatorInfo { pub start_date: Option, } -impl From for MacrodataIndicatorInfo { - fn from(v: lb::MacrodataIndicatorInfo) -> Self { +impl From for MacrodataIndicator { + fn from(v: lb::MacrodataIndicator) -> Self { Self { indicator_code: v.indicator_code, source_org: v.source_org, @@ -1961,7 +1961,7 @@ impl From for MacrodataIndicatorInfo { /// One historical data point for a macroeconomic indicator #[napi_derive::napi(object)] #[derive(Debug, Clone)] -pub struct MacrodataRecord { +pub struct Macrodata { pub period: String, /// Release datetime (unix timestamp in seconds; null if unset) pub release_at: Option, @@ -1975,8 +1975,8 @@ pub struct MacrodataRecord { pub unit_prefix: MultiLanguageText, } -impl From for MacrodataRecord { - fn from(v: lb::MacrodataRecord) -> Self { +impl From for Macrodata { + fn from(v: lb::Macrodata) -> Self { Self { period: v.period, release_at: v.release_at.map(|dt| dt.unix_timestamp()), @@ -1995,8 +1995,8 @@ impl From for MacrodataRecord { #[napi_derive::napi(object)] #[derive(Debug, Clone)] pub struct MacrodataResponse { - pub info: MacrodataIndicatorInfo, - pub data: Vec, + pub info: MacrodataIndicator, + pub data: Vec, } impl From for MacrodataResponse { diff --git a/python/pysrc/longbridge/openapi.pyi b/python/pysrc/longbridge/openapi.pyi index 948800629..ec4d6a064 100644 --- a/python/pysrc/longbridge/openapi.pyi +++ b/python/pysrc/longbridge/openapi.pyi @@ -9926,7 +9926,7 @@ class FundamentalContext: self, offset: int | None = None, limit: int | None = None, - ) -> list["MacrodataIndicatorInfo"]: + ) -> list["MacrodataIndicator"]: """ List macroeconomic indicators. @@ -9935,7 +9935,7 @@ class FundamentalContext: limit: Page size (default 100, max 1000) Returns: - List of :class:`MacrodataIndicatorInfo` + List of :class:`MacrodataIndicator` """ ... @@ -10111,7 +10111,7 @@ class MultiLanguageText: traditional_chinese: str -class MacrodataIndicatorInfo: +class MacrodataIndicator: """Metadata for one macroeconomic indicator.""" indicator_code: str @@ -10129,7 +10129,7 @@ class MacrodataIndicatorInfo: """Start date of data coverage""" -class MacrodataRecord: +class Macrodata: """One historical data point for a macroeconomic indicator.""" period: str @@ -10147,8 +10147,8 @@ class MacrodataRecord: class MacrodataResponse: """Response for macrodata.""" - info: MacrodataIndicatorInfo - data: list[MacrodataRecord] + info: MacrodataIndicator + data: list[Macrodata] # ── MarketContext ───────────────────────────────────────────────── diff --git a/python/src/fundamental/context.rs b/python/src/fundamental/context.rs index d19837cfe..775563652 100644 --- a/python/src/fundamental/context.rs +++ b/python/src/fundamental/context.rs @@ -214,7 +214,7 @@ impl FundamentalContext { &self, offset: Option, limit: Option, - ) -> PyResult> { + ) -> PyResult> { Ok(self .ctx .macrodata_indicators(offset, limit) diff --git a/python/src/fundamental/context_async.rs b/python/src/fundamental/context_async.rs index e88fc642f..a2742b113 100644 --- a/python/src/fundamental/context_async.rs +++ b/python/src/fundamental/context_async.rs @@ -332,7 +332,7 @@ impl AsyncFundamentalContext { .await .map_err(ErrorNewType)? .into_iter() - .map(MacrodataIndicatorInfo::from) + .map(MacrodataIndicator::from) .collect::>()) }) .map(|b| b.unbind()) diff --git a/python/src/fundamental/mod.rs b/python/src/fundamental/mod.rs index ec20bfd9c..64d6484ae 100644 --- a/python/src/fundamental/mod.rs +++ b/python/src/fundamental/mod.rs @@ -75,8 +75,8 @@ pub(crate) fn register_types(parent: &Bound) -> PyResult<()> { parent.add_class::()?; parent.add_class::()?; parent.add_class::()?; - parent.add_class::()?; - parent.add_class::()?; + parent.add_class::()?; + parent.add_class::()?; parent.add_class::()?; parent.add_class::()?; parent.add_class::()?; diff --git a/python/src/fundamental/types.rs b/python/src/fundamental/types.rs index d79b1b6fd..358e18c81 100644 --- a/python/src/fundamental/types.rs +++ b/python/src/fundamental/types.rs @@ -1990,7 +1990,7 @@ impl From for MultiLanguageText { /// Metadata for one macroeconomic indicator #[pyclass(get_all, skip_from_py_object)] #[derive(Debug, Clone)] -pub(crate) struct MacrodataIndicatorInfo { +pub(crate) struct MacrodataIndicator { pub indicator_code: String, pub source_org: String, pub country: String, @@ -2003,8 +2003,8 @@ pub(crate) struct MacrodataIndicatorInfo { pub start_date: Option, } -impl From for MacrodataIndicatorInfo { - fn from(v: lb::MacrodataIndicatorInfo) -> Self { +impl From for MacrodataIndicator { + fn from(v: lb::MacrodataIndicator) -> Self { Self { indicator_code: v.indicator_code, source_org: v.source_org, @@ -2023,7 +2023,7 @@ impl From for MacrodataIndicatorInfo { /// One historical data point for a macroeconomic indicator #[pyclass(get_all, skip_from_py_object)] #[derive(Debug, Clone)] -pub(crate) struct MacrodataRecord { +pub(crate) struct Macrodata { pub period: String, pub release_at: Option, pub actual_value: String, @@ -2035,8 +2035,8 @@ pub(crate) struct MacrodataRecord { pub unit_prefix: MultiLanguageText, } -impl From for MacrodataRecord { - fn from(v: lb::MacrodataRecord) -> Self { +impl From for Macrodata { + fn from(v: lb::Macrodata) -> Self { Self { period: v.period, release_at: v.release_at.map(crate::time::PyOffsetDateTimeWrapper), @@ -2055,8 +2055,8 @@ impl From for MacrodataRecord { #[pyclass(get_all, skip_from_py_object)] #[derive(Debug, Clone)] pub(crate) struct MacrodataResponse { - pub info: MacrodataIndicatorInfo, - pub data: Vec, + pub info: MacrodataIndicator, + pub data: Vec, } impl From for MacrodataResponse { diff --git a/rust/src/fundamental/context.rs b/rust/src/fundamental/context.rs index 6c1d40943..ac9d5aa1f 100644 --- a/rust/src/fundamental/context.rs +++ b/rust/src/fundamental/context.rs @@ -839,7 +839,7 @@ impl FundamentalContext { &self, offset: Option, limit: Option, - ) -> Result> { + ) -> Result> { #[derive(Serialize)] struct Query { #[serde(skip_serializing_if = "Option::is_none")] diff --git a/rust/src/fundamental/types.rs b/rust/src/fundamental/types.rs index d587ad7a0..caf93e324 100644 --- a/rust/src/fundamental/types.rs +++ b/rust/src/fundamental/types.rs @@ -1581,7 +1581,7 @@ pub struct MultiLanguageText { /// Metadata for one macroeconomic indicator #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct MacrodataIndicatorInfo { +pub struct MacrodataIndicator { /// External vendor code (used as input to `macrodata`) pub indicator_code: String, /// Publishing organisation @@ -1622,12 +1622,12 @@ pub struct MacrodataIndicatorInfo { pub struct EconomicIndicatorListResponse { /// Indicator list #[serde(default)] - pub data: Vec, + pub data: Vec, } /// One historical data point for a macroeconomic indicator #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct MacrodataRecord { +pub struct Macrodata { /// Statistical period (e.g. `2024-Q1`, `2024-03`) #[serde(default)] pub period: String, @@ -1661,8 +1661,8 @@ pub struct MacrodataRecord { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct MacrodataResponse { /// Indicator metadata - pub info: MacrodataIndicatorInfo, + pub info: MacrodataIndicator, /// Historical data points #[serde(default)] - pub data: Vec, + pub data: Vec, } From 4206088a0871f13034ecc56685139244e5b71e16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Wed, 10 Jun 2026 10:54:06 +0800 Subject: [PATCH 08/28] fix: use rfc3339_opt for macrodata timestamps and fix list field name - start_date/release_at/next_release_at: timestamp_opt -> rfc3339_opt (API returns RFC3339 strings, not unix seconds) - EconomicIndicatorListResponse: rename data field to list Co-Authored-By: Claude Sonnet 4.6 (1M context) --- rust/src/fundamental/types.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rust/src/fundamental/types.rs b/rust/src/fundamental/types.rs index caf93e324..e07c59dba 100644 --- a/rust/src/fundamental/types.rs +++ b/rust/src/fundamental/types.rs @@ -1611,7 +1611,7 @@ pub struct MacrodataIndicator { /// Start date of data coverage #[serde( default, - with = "crate::serde_utils::timestamp_opt", + with = "crate::serde_utils::rfc3339_opt", rename = "start_date" )] pub start_date: Option, @@ -1621,7 +1621,7 @@ pub struct MacrodataIndicator { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct EconomicIndicatorListResponse { /// Indicator list - #[serde(default)] + #[serde(default, rename = "list")] pub data: Vec, } @@ -1632,7 +1632,7 @@ pub struct Macrodata { #[serde(default)] pub period: String, /// Release datetime - #[serde(default, with = "crate::serde_utils::timestamp_opt")] + #[serde(default, with = "crate::serde_utils::rfc3339_opt")] pub release_at: Option, /// Actual value #[serde(default)] @@ -1647,7 +1647,7 @@ pub struct Macrodata { #[serde(default)] pub revised_value: String, /// Next release datetime - #[serde(default, with = "crate::serde_utils::timestamp_opt")] + #[serde(default, with = "crate::serde_utils::rfc3339_opt")] pub next_release_at: Option, /// Unit (multilingual) #[serde(default)] From 591849df355b51a8ea417f6382ebdfe2264f092e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Wed, 10 Jun 2026 11:31:05 +0800 Subject: [PATCH 09/28] fix(ci): fix format and stale method name in Java JNI binding Co-Authored-By: Claude Sonnet 4.6 (1M context) --- .claude/worktrees/agent-a962fdff6e0c7fa74 | 1 + java/src/fundamental_context.rs | 5 +- nodejs/test_new_fundamental.js | 63 +++++++++++++++++++++++ rust/src/blocking/fundamental.rs | 4 +- 4 files changed, 67 insertions(+), 6 deletions(-) create mode 160000 .claude/worktrees/agent-a962fdff6e0c7fa74 create mode 100644 nodejs/test_new_fundamental.js diff --git a/.claude/worktrees/agent-a962fdff6e0c7fa74 b/.claude/worktrees/agent-a962fdff6e0c7fa74 new file mode 160000 index 000000000..4e7e05692 --- /dev/null +++ b/.claude/worktrees/agent-a962fdff6e0c7fa74 @@ -0,0 +1 @@ +Subproject commit 4e7e0569270443e306621e9a97d98059fa59a9ec diff --git a/java/src/fundamental_context.rs b/java/src/fundamental_context.rs index 207827e56..61e11d495 100644 --- a/java/src/fundamental_context.rs +++ b/java/src/fundamental_context.rs @@ -277,10 +277,7 @@ pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextMa let offset: Option = FromJValue::from_jvalue(env, offset.into())?; let limit: Option = FromJValue::from_jvalue(env, limit.into())?; async_util::execute(env, callback, async move { - Ok(context - .ctx - .economic_indicator_list(offset, limit) - .await?) + Ok(context.ctx.macrodata_indicators(offset, limit).await?) })?; Ok(()) }) diff --git a/nodejs/test_new_fundamental.js b/nodejs/test_new_fundamental.js new file mode 100644 index 000000000..e8400435c --- /dev/null +++ b/nodejs/test_new_fundamental.js @@ -0,0 +1,63 @@ +const { FundamentalContext, Config, OAuth } = require('./index.js') + +const pf = { pass: 0, fail: 0 } +async function check(name, fn) { + process.stdout.write(` ${name.padEnd(58)}`) + try { + const r = await fn() + console.log(`OK ${r}`) + pf.pass++ + } catch (e) { + console.log(`FAIL ${e.message || e}`) + pf.fail++ + } +} + +async function main() { + const oauth = await OAuth.build('fd52fbc5-02a9-47f5-ad30-0842c841aae9', (_, url) => { + console.log('Open:', url) + }) + const cfg = Config.fromOAuth(oauth) + const ctx = FundamentalContext.new(cfg) + + console.log('\n=== FundamentalContext — new APIs (Node.js) ===') + + await check('businessSegments(AAPL.US)', async () => { + const r = await ctx.businessSegments('AAPL.US') + return `${r.business.length} segments` + }) + + await check('businessSegmentsHistory(AAPL.US, qf, null)', async () => { + const r = await ctx.businessSegmentsHistory('AAPL.US', 'qf', null) + return `${r.historical.length} periods` + }) + + await check('institutionRatingViews(AAPL.US)', async () => { + const r = await ctx.institutionRatingViews('AAPL.US') + return `${r.elist.length} months` + }) + + let bkId = 'BK/US/IN00258' + await check('industryRank(US, 0, 0, 10)', async () => { + const r = await ctx.industryRank('US', '0', '0', 10) + const total = r.items.reduce((s, g) => s + g.lists.length, 0) + if (r.items[0]?.lists[0]?.counterId) bkId = r.items[0].lists[0].counterId + return `${total} industries, first: ${bkId}` + }) + + await check('industryPeers(BK/US/..., US, null)', async () => { + const r = await ctx.industryPeers(bkId, 'US', null) + const children = r.chain?.next?.length ?? 0 + return `top:${r.top.name} children:${children}` + }) + + await check('financialReportSnapshot(AAPL.US)', async () => { + const r = await ctx.financialReportSnapshot('AAPL.US', null, null, null) + return `${r.ticker} ${r.fpStart}–${r.fpEnd}` + }) + + console.log(`\nPASS: ${pf.pass} FAIL: ${pf.fail}`) + if (pf.fail > 0) process.exit(1) +} + +main().catch(e => { console.error(e); process.exit(1) }) diff --git a/rust/src/blocking/fundamental.rs b/rust/src/blocking/fundamental.rs index ea757facb..5338f275d 100644 --- a/rust/src/blocking/fundamental.rs +++ b/rust/src/blocking/fundamental.rs @@ -296,7 +296,7 @@ impl FundamentalContextSync { &self, offset: Option, limit: Option, - ) -> Result> { + ) -> Result> { self.rt .call(move |ctx| async move { ctx.macrodata_indicators(offset, limit).await }) } @@ -308,7 +308,7 @@ impl FundamentalContextSync { start_date: Option + Send + 'static>, end_date: Option + Send + 'static>, limit: Option, - ) -> Result { + ) -> Result { self.rt.call(move |ctx| async move { ctx.macrodata(indicator_code, start_date, end_date, limit) .await From a73cbe6a54a14e3782b2510084f9f0601d8adb9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Wed, 10 Jun 2026 11:31:23 +0800 Subject: [PATCH 10/28] chore: remove accidentally committed test file and worktree Co-Authored-By: Claude Sonnet 4.6 (1M context) --- .claude/worktrees/agent-a962fdff6e0c7fa74 | 1 - nodejs/test_new_fundamental.js | 63 ----------------------- 2 files changed, 64 deletions(-) delete mode 160000 .claude/worktrees/agent-a962fdff6e0c7fa74 delete mode 100644 nodejs/test_new_fundamental.js diff --git a/.claude/worktrees/agent-a962fdff6e0c7fa74 b/.claude/worktrees/agent-a962fdff6e0c7fa74 deleted file mode 160000 index 4e7e05692..000000000 --- a/.claude/worktrees/agent-a962fdff6e0c7fa74 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 4e7e0569270443e306621e9a97d98059fa59a9ec diff --git a/nodejs/test_new_fundamental.js b/nodejs/test_new_fundamental.js deleted file mode 100644 index e8400435c..000000000 --- a/nodejs/test_new_fundamental.js +++ /dev/null @@ -1,63 +0,0 @@ -const { FundamentalContext, Config, OAuth } = require('./index.js') - -const pf = { pass: 0, fail: 0 } -async function check(name, fn) { - process.stdout.write(` ${name.padEnd(58)}`) - try { - const r = await fn() - console.log(`OK ${r}`) - pf.pass++ - } catch (e) { - console.log(`FAIL ${e.message || e}`) - pf.fail++ - } -} - -async function main() { - const oauth = await OAuth.build('fd52fbc5-02a9-47f5-ad30-0842c841aae9', (_, url) => { - console.log('Open:', url) - }) - const cfg = Config.fromOAuth(oauth) - const ctx = FundamentalContext.new(cfg) - - console.log('\n=== FundamentalContext — new APIs (Node.js) ===') - - await check('businessSegments(AAPL.US)', async () => { - const r = await ctx.businessSegments('AAPL.US') - return `${r.business.length} segments` - }) - - await check('businessSegmentsHistory(AAPL.US, qf, null)', async () => { - const r = await ctx.businessSegmentsHistory('AAPL.US', 'qf', null) - return `${r.historical.length} periods` - }) - - await check('institutionRatingViews(AAPL.US)', async () => { - const r = await ctx.institutionRatingViews('AAPL.US') - return `${r.elist.length} months` - }) - - let bkId = 'BK/US/IN00258' - await check('industryRank(US, 0, 0, 10)', async () => { - const r = await ctx.industryRank('US', '0', '0', 10) - const total = r.items.reduce((s, g) => s + g.lists.length, 0) - if (r.items[0]?.lists[0]?.counterId) bkId = r.items[0].lists[0].counterId - return `${total} industries, first: ${bkId}` - }) - - await check('industryPeers(BK/US/..., US, null)', async () => { - const r = await ctx.industryPeers(bkId, 'US', null) - const children = r.chain?.next?.length ?? 0 - return `top:${r.top.name} children:${children}` - }) - - await check('financialReportSnapshot(AAPL.US)', async () => { - const r = await ctx.financialReportSnapshot('AAPL.US', null, null, null) - return `${r.ticker} ${r.fpStart}–${r.fpEnd}` - }) - - console.log(`\nPASS: ${pf.pass} FAIL: ${pf.fail}`) - if (pf.fail > 0) process.exit(1) -} - -main().catch(e => { console.error(e); process.exit(1) }) From 65a99d4b86429776144940d8a6f6fe039c266b5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Wed, 10 Jun 2026 11:50:17 +0800 Subject: [PATCH 11/28] fix: handle null MultiLanguageText in MacrodataIndicator describe field can be null in API response; use null_as_default deserializer to map null -> Default (empty strings). Co-Authored-By: Claude Sonnet 4.6 (1M context) --- rust/src/fundamental/types.rs | 2 +- rust/src/serde_utils.rs | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/rust/src/fundamental/types.rs b/rust/src/fundamental/types.rs index e07c59dba..8ab4f1d44 100644 --- a/rust/src/fundamental/types.rs +++ b/rust/src/fundamental/types.rs @@ -1603,7 +1603,7 @@ pub struct MacrodataIndicator { #[serde(default)] pub category: String, /// Description (multilingual) - #[serde(default)] + #[serde(default, deserialize_with = "crate::serde_utils::null_as_default")] pub describe: MultiLanguageText, /// Importance — higher is more important #[serde(default)] diff --git a/rust/src/serde_utils.rs b/rust/src/serde_utils.rs index 85858134b..21512bf95 100644 --- a/rust/src/serde_utils.rs +++ b/rust/src/serde_utils.rs @@ -462,3 +462,12 @@ where StringOrInt::String(s) => s.parse::().map_err(serde::de::Error::custom), } } + +/// Deserializer that maps a JSON `null` to the type's `Default` value. +pub(crate) fn null_as_default<'de, D, T>(d: D) -> Result +where + D: Deserializer<'de>, + T: Deserialize<'de> + Default, +{ + Ok(Option::::deserialize(d)?.unwrap_or_default()) +} From 18076a0e488093f07bfdf76d62fdd789f99ea414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Wed, 10 Jun 2026 12:07:40 +0800 Subject: [PATCH 12/28] fix(java): wrap Vec in ObjectArray for JNI return Vec does not implement IntoJValue; ObjectArray does. Co-Authored-By: Claude Sonnet 4.6 (1M context) --- java/src/fundamental_context.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/java/src/fundamental_context.rs b/java/src/fundamental_context.rs index 61e11d495..fd9612f4b 100644 --- a/java/src/fundamental_context.rs +++ b/java/src/fundamental_context.rs @@ -277,7 +277,9 @@ pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextMa let offset: Option = FromJValue::from_jvalue(env, offset.into())?; let limit: Option = FromJValue::from_jvalue(env, limit.into())?; async_util::execute(env, callback, async move { - Ok(context.ctx.macrodata_indicators(offset, limit).await?) + Ok(ObjectArray( + context.ctx.macrodata_indicators(offset, limit).await?, + )) })?; Ok(()) }) From 3117cf0f61c9fdacc80f1941dbe9ff68206c5d60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Wed, 10 Jun 2026 13:39:46 +0800 Subject: [PATCH 13/28] chore: update nodejs/index.d.ts with auto-generated types from napi build Co-Authored-By: Claude Sonnet 4.6 (1M context) --- nodejs/index.d.ts | 86 +++++++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 41 deletions(-) diff --git a/nodejs/index.d.ts b/nodejs/index.d.ts index 8db26c69c..9f942929d 100644 --- a/nodejs/index.d.ts +++ b/nodejs/index.d.ts @@ -619,9 +619,9 @@ export declare class FundamentalContext { */ etfAssetAllocation(symbol: string): Promise /** List macroeconomic indicators */ - macrodataIndicators(offset?: number | null, limit?: number | null): Promise> + macrodataIndicators(offset?: number | undefined | null, limit?: number | undefined | null): Promise> /** Get historical data for a macroeconomic indicator */ - macrodata(indicatorCode: string, startDate?: string | null, endDate?: string | null, limit?: number | null): Promise + macrodata(indicatorCode: string, startDate?: string | undefined | null, endDate?: string | undefined | null, limit?: number | undefined | null): Promise } /** Fund position */ @@ -3137,45 +3137,6 @@ export interface AssetAllocationResponse { /** Asset allocation groups */ info: Array } -/** Localized text in simplified Chinese, traditional Chinese, and English */ -export interface MultiLanguageText { - english: string - simplifiedChinese: string - traditionalChinese: string -} -/** Metadata for one macroeconomic indicator */ -export interface MacrodataIndicator { - indicatorCode: string - sourceOrg: string - country: string - name: MultiLanguageText - adjustmentFactor: string - periodicity: string - category: string - describe: MultiLanguageText - importance: number - /** Start date of data coverage (unix timestamp in seconds; null if unset) */ - startDate: bigint | null -} -/** One historical data point for a macroeconomic indicator */ -export interface Macrodata { - period: string - /** Release datetime (unix timestamp in seconds; null if unset) */ - releaseAt: bigint | null - actualValue: string - previousValue: string - forecastValue: string - revisedValue: string - /** Next release datetime (unix timestamp in seconds; null if unset) */ - nextReleaseAt: bigint | null - unit: MultiLanguageText - unitPrefix: MultiLanguageText -} -/** Response for macrodata */ -export interface MacrodataResponse { - info: MacrodataIndicator - data: Array -} export declare const enum AssetType { /** Unknown */ @@ -4516,6 +4477,42 @@ export declare const enum Language { EN = 2 } +/** One historical data point for a macroeconomic indicator */ +export interface Macrodata { + period: string + /** Release datetime (unix timestamp in seconds; null if unset) */ + releaseAt?: number + actualValue: string + previousValue: string + forecastValue: string + revisedValue: string + /** Next release datetime (unix timestamp in seconds; null if unset) */ + nextReleaseAt?: number + unit: MultiLanguageText + unitPrefix: MultiLanguageText +} + +/** Metadata for one macroeconomic indicator */ +export interface MacrodataIndicator { + indicatorCode: string + sourceOrg: string + country: string + name: MultiLanguageText + adjustmentFactor: string + periodicity: string + category: string + describe: MultiLanguageText + importance: number + /** Start date of data coverage (unix timestamp in seconds; null if unset) */ + startDate?: number +} + +/** Response for economic_indicator */ +export interface MacrodataResponse { + info: MacrodataIndicator + data: Array +} + export declare const enum Market { /** Unknown */ Unknown = 0, @@ -4558,6 +4555,13 @@ export interface MarketTimeItem { delaySubStatus: number } +/** Localized text in simplified Chinese, traditional Chinese, and English */ +export interface MultiLanguageText { + english: string + simplifiedChinese: string + traditionalChinese: string +} + /** Options for listing topics created by the current authenticated user */ export interface MyTopicsRequest { /** Page number (default 1) */ From b52beed3f5055ab35264fe758aa58dea7b4b0e81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Wed, 10 Jun 2026 13:58:39 +0800 Subject: [PATCH 14/28] refactor: rename EconomicIndicatorListResponse to MacrodataIndicatorListResponse Co-Authored-By: Claude Sonnet 4.6 (1M context) --- rust/src/fundamental/context.rs | 2 +- rust/src/fundamental/types.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/src/fundamental/context.rs b/rust/src/fundamental/context.rs index ac9d5aa1f..f13dbf149 100644 --- a/rust/src/fundamental/context.rs +++ b/rust/src/fundamental/context.rs @@ -847,7 +847,7 @@ impl FundamentalContext { #[serde(skip_serializing_if = "Option::is_none")] limit: Option, } - let resp: EconomicIndicatorListResponse = self + let resp: MacrodataIndicatorListResponse = self .get("/v1/quote/macrodata", Query { offset, limit }) .await?; Ok(resp.data) diff --git a/rust/src/fundamental/types.rs b/rust/src/fundamental/types.rs index 8ab4f1d44..a84d9fc3f 100644 --- a/rust/src/fundamental/types.rs +++ b/rust/src/fundamental/types.rs @@ -1619,7 +1619,7 @@ pub struct MacrodataIndicator { /// Response for [`crate::FundamentalContext::macrodata_list`] #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct EconomicIndicatorListResponse { +pub struct MacrodataIndicatorListResponse { /// Indicator list #[serde(default, rename = "list")] pub data: Vec, From 329264979bd4e832188816771fcf9a454b5789df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Wed, 10 Jun 2026 14:05:56 +0800 Subject: [PATCH 15/28] chore: release 4.3.1 --- CHANGELOG.md | 12 ++++++++++++ Cargo.toml | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 707c9ed47..a196aac63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [4.3.1] - 2026-06-12 + +### Added + +- **All languages:** `FundamentalContext` gains `macrodata_indicators(offset, limit)` — list all macroeconomic indicators via `GET /v1/quote/macrodata` +- **All languages:** `FundamentalContext` gains `macrodata(indicator_code, start_date, end_date, limit)` — historical data for a specific indicator via `GET /v1/quote/macrodata/{indicator_code}`; `start_date` / `end_date` accept `"YYYY-MM-DD"` strings +- New types: `MultiLanguageText`, `MacrodataIndicator`, `Macrodata`, `MacrodataResponse` + +### Fixed + +- `MacrodataIndicator.describe`: handle `null` response from API without deserializing error + ## [4.3.0] ### Added diff --git a/Cargo.toml b/Cargo.toml index 815991451..b21cdf2dc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ resolver = "3" members = ["rust", "python", "nodejs", "java", "c"] [workspace.package] -version = "4.3.0" +version = "4.3.1" edition = "2024" [profile.release] From 99e1863e323a7f205914b93eabccb4f3036d680a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Wed, 10 Jun 2026 17:00:01 +0800 Subject: [PATCH 16/28] fix: handle null for name/unit/unit_prefix/info in Macrodata types - MacrodataIndicator.name: #[serde(default)] -> null_as_default - Macrodata.unit / unit_prefix: same - MacrodataResponse.info: add null_as_default (was missing entirely) - Derive Default on MacrodataIndicator and Macrodata to support null_as_default Co-Authored-By: Claude Sonnet 4.6 (1M context) --- rust/src/fundamental/types.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/rust/src/fundamental/types.rs b/rust/src/fundamental/types.rs index a84d9fc3f..fb4f29051 100644 --- a/rust/src/fundamental/types.rs +++ b/rust/src/fundamental/types.rs @@ -1580,7 +1580,7 @@ pub struct MultiLanguageText { } /// Metadata for one macroeconomic indicator -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Default, Serialize, Deserialize)] pub struct MacrodataIndicator { /// External vendor code (used as input to `macrodata`) pub indicator_code: String, @@ -1591,7 +1591,7 @@ pub struct MacrodataIndicator { #[serde(default)] pub country: String, /// Indicator name (multilingual) - #[serde(default)] + #[serde(default, deserialize_with = "crate::serde_utils::null_as_default")] pub name: MultiLanguageText, /// Adjustment factor #[serde(default)] @@ -1626,7 +1626,7 @@ pub struct MacrodataIndicatorListResponse { } /// One historical data point for a macroeconomic indicator -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Default, Serialize, Deserialize)] pub struct Macrodata { /// Statistical period (e.g. `2024-Q1`, `2024-03`) #[serde(default)] @@ -1650,10 +1650,10 @@ pub struct Macrodata { #[serde(default, with = "crate::serde_utils::rfc3339_opt")] pub next_release_at: Option, /// Unit (multilingual) - #[serde(default)] + #[serde(default, deserialize_with = "crate::serde_utils::null_as_default")] pub unit: MultiLanguageText, /// Unit prefix / data scale (multilingual, e.g. millions / billions) - #[serde(default)] + #[serde(default, deserialize_with = "crate::serde_utils::null_as_default")] pub unit_prefix: MultiLanguageText, } @@ -1661,6 +1661,7 @@ pub struct Macrodata { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct MacrodataResponse { /// Indicator metadata + #[serde(default, deserialize_with = "crate::serde_utils::null_as_default")] pub info: MacrodataIndicator, /// Historical data points #[serde(default)] From e29b3c0ec9945a52c93139390e35aaeb808282ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Wed, 10 Jun 2026 17:50:31 +0800 Subject: [PATCH 17/28] feat(macrodata): add country filter, count field, offset param - macrodata_indicators: add country param (MacrodataCountry enum), returns MacrodataIndicatorListResponse with count - macrodata: add offset param for pagination, response includes count - Add MacrodataImportance (1=Low/2=Medium/3=High) and MacrodataCountry enums Co-Authored-By: Claude Sonnet 4.6 (1M context) --- .../main/java/com/longbridge/SdkNative.java | 4 +- .../fundamental/FundamentalContext.java | 13 ++-- .../MacrodataIndicatorListResponse.java | 8 ++ .../fundamental/MacrodataResponse.java | 4 +- java/src/fundamental_context.rs | 30 ++++++- java/src/types/classes.rs | 13 +++- nodejs/src/fundamental/context.rs | 12 +-- nodejs/src/fundamental/types.rs | 62 ++++++++++++++- python/src/fundamental/context.rs | 12 +-- python/src/fundamental/context_async.rs | 16 ++-- python/src/fundamental/mod.rs | 2 + python/src/fundamental/types.rs | 62 ++++++++++++++- rust/src/fundamental/context.rs | 17 ++-- rust/src/fundamental/types.rs | 78 ++++++++++++++++++- 14 files changed, 292 insertions(+), 41 deletions(-) create mode 100644 java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataIndicatorListResponse.java diff --git a/java/javasrc/src/main/java/com/longbridge/SdkNative.java b/java/javasrc/src/main/java/com/longbridge/SdkNative.java index 6f9f5927d..891ae360a 100644 --- a/java/javasrc/src/main/java/com/longbridge/SdkNative.java +++ b/java/javasrc/src/main/java/com/longbridge/SdkNative.java @@ -452,11 +452,11 @@ public static native void fundamentalContextGetFinancialReportSnapshot(long cont AsyncCallback callback); public static native void fundamentalContextMacrodataIndicators(long context, - Object offset, Object limit, + Object country, Object offset, Object limit, AsyncCallback callback); public static native void fundamentalContextMacrodata(long context, - Object indicatorCode, Object startTime, Object endTime, Object limit, + Object indicatorCode, Object startTime, Object endTime, Object offset, Object limit, AsyncCallback callback); public static native void portfolioContextProfitAnalysisFlows(long context, Object opts, diff --git a/java/javasrc/src/main/java/com/longbridge/fundamental/FundamentalContext.java b/java/javasrc/src/main/java/com/longbridge/fundamental/FundamentalContext.java index 85144d65e..8486cd247 100644 --- a/java/javasrc/src/main/java/com/longbridge/fundamental/FundamentalContext.java +++ b/java/javasrc/src/main/java/com/longbridge/fundamental/FundamentalContext.java @@ -335,10 +335,13 @@ public CompletableFuture getValuationComparison(Val }); } - /** List macroeconomic indicators. */ - public CompletableFuture getMacrodataIndicators(Integer offset, Integer limit) throws OpenApiException { + /** + * List macroeconomic indicators. + * country: ISO country code string (e.g. "US", "CN", "EU"); pass null for all countries. + */ + public CompletableFuture getMacrodataIndicators(String country, Integer offset, Integer limit) throws OpenApiException { return AsyncCallback.executeTask((callback) -> { - SdkNative.fundamentalContextMacrodataIndicators(raw, offset, limit, callback); + SdkNative.fundamentalContextMacrodataIndicators(raw, country, offset, limit, callback); }); } @@ -346,9 +349,9 @@ public CompletableFuture getMacrodataIndicators(Integer of * Get historical data for a macroeconomic indicator. * startDate and endDate are date strings in "YYYY-MM-DD" format. */ - public CompletableFuture getMacrodata(String indicatorCode, String startDate, String endDate, Integer limit) throws OpenApiException { + public CompletableFuture getMacrodata(String indicatorCode, String startDate, String endDate, Integer offset, Integer limit) throws OpenApiException { return AsyncCallback.executeTask((callback) -> { - SdkNative.fundamentalContextMacrodata(raw, indicatorCode, startDate, endDate, limit, callback); + SdkNative.fundamentalContextMacrodata(raw, indicatorCode, startDate, endDate, offset, limit, callback); }); } } diff --git a/java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataIndicatorListResponse.java b/java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataIndicatorListResponse.java new file mode 100644 index 000000000..dd4fc6802 --- /dev/null +++ b/java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataIndicatorListResponse.java @@ -0,0 +1,8 @@ +package com.longbridge.fundamental; + +/** Response for {@link FundamentalContext#getMacrodataIndicators}. */ +public class MacrodataIndicatorListResponse { + public MacrodataIndicator[] data; + /** Total number of indicators matching the query. */ + public int count; +} diff --git a/java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataResponse.java b/java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataResponse.java index b4e4cb1d5..f3532ee24 100644 --- a/java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataResponse.java +++ b/java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataResponse.java @@ -1,7 +1,9 @@ package com.longbridge.fundamental; -/** Response for {@link FundamentalContext#getEconomicIndicator}. */ +/** Response for {@link FundamentalContext#getMacrodata}. */ public class MacrodataResponse { public MacrodataIndicator info; public Macrodata[] data; + /** Total number of historical data points. */ + public int count; } diff --git a/java/src/fundamental_context.rs b/java/src/fundamental_context.rs index fd9612f4b..a507153ce 100644 --- a/java/src/fundamental_context.rs +++ b/java/src/fundamental_context.rs @@ -268,18 +268,38 @@ pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextMa mut env: JNIEnv, _class: JClass, context: i64, + country: JObject, offset: JObject, limit: JObject, callback: JObject, ) { jni_result(&mut env, (), |env| { let context = &*(context as *const ContextObj); + let country: Option = FromJValue::from_jvalue(env, country.into())?; + let country = country.and_then(|s| { + use longbridge::fundamental::MacrodataCountry::*; + match s.as_str() { + "US" => Some(UnitedStates), + "CN" => Some(China), + "EU" => Some(EuroZone), + "JP" => Some(Japan), + "UK" => Some(UnitedKingdom), + "DE" => Some(Germany), + "FR" => Some(France), + "AU" => Some(Australia), + "CA" => Some(Canada), + "KR" => Some(SouthKorea), + "IN" => Some(India), + "BR" => Some(Brazil), + "HK" => Some(HongKong), + "SG" => Some(Singapore), + _ => None, + } + }); let offset: Option = FromJValue::from_jvalue(env, offset.into())?; let limit: Option = FromJValue::from_jvalue(env, limit.into())?; async_util::execute(env, callback, async move { - Ok(ObjectArray( - context.ctx.macrodata_indicators(offset, limit).await?, - )) + Ok(context.ctx.macrodata_indicators(country, offset, limit).await?) })?; Ok(()) }) @@ -293,6 +313,7 @@ pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextMa indicator_code: JObject, start_time: JObject, end_time: JObject, + offset: JObject, limit: JObject, callback: JObject, ) { @@ -301,11 +322,12 @@ pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextMa let indicator_code: String = FromJValue::from_jvalue(env, indicator_code.into())?; let start_date: Option = FromJValue::from_jvalue(env, start_time.into())?; let end_date: Option = FromJValue::from_jvalue(env, end_time.into())?; + let offset: Option = FromJValue::from_jvalue(env, offset.into())?; let limit: Option = FromJValue::from_jvalue(env, limit.into())?; async_util::execute(env, callback, async move { Ok(context .ctx - .macrodata(indicator_code, start_date, end_date, limit) + .macrodata(indicator_code, start_date, end_date, offset, limit) .await?) })?; Ok(()) diff --git a/java/src/types/classes.rs b/java/src/types/classes.rs index 22c3d5733..a941e6b80 100644 --- a/java/src/types/classes.rs +++ b/java/src/types/classes.rs @@ -2737,13 +2737,24 @@ impl_java_class!( ] ); +impl_java_class!( + "com/longbridge/fundamental/MacrodataIndicatorListResponse", + longbridge::fundamental::MacrodataIndicatorListResponse, + [ + #[java(objarray)] + data, + count + ] +); + impl_java_class!( "com/longbridge/fundamental/MacrodataResponse", longbridge::fundamental::MacrodataResponse, [ info, #[java(objarray)] - data + data, + count ] ); diff --git a/nodejs/src/fundamental/context.rs b/nodejs/src/fundamental/context.rs index f35d19544..323d2a38e 100644 --- a/nodejs/src/fundamental/context.rs +++ b/nodejs/src/fundamental/context.rs @@ -292,17 +292,16 @@ impl FundamentalContext { #[napi] pub async fn macrodata_indicators( &self, + country: Option, offset: Option, limit: Option, - ) -> Result> { + ) -> Result { Ok(self .ctx - .macrodata_indicators(offset, limit) + .macrodata_indicators(country.map(Into::into), offset, limit) .await .map_err(ErrorNewType)? - .into_iter() - .map(Into::into) - .collect()) + .into()) } /// Get historical data for a macroeconomic indicator @@ -312,11 +311,12 @@ impl FundamentalContext { indicator_code: String, start_date: Option, end_date: Option, + offset: Option, limit: Option, ) -> Result { Ok(self .ctx - .macrodata(indicator_code, start_date, end_date, limit) + .macrodata(indicator_code, start_date, end_date, offset, limit) .await .map_err(ErrorNewType)? .into()) diff --git a/nodejs/src/fundamental/types.rs b/nodejs/src/fundamental/types.rs index dc41ba60f..b0e13ef0c 100644 --- a/nodejs/src/fundamental/types.rs +++ b/nodejs/src/fundamental/types.rs @@ -1924,6 +1924,64 @@ impl From for MultiLanguageText { } } +/// Country code for filtering macroeconomic indicators +#[napi_derive::napi] +#[derive(Debug, Copy, Clone)] +pub enum MacrodataCountry { + UnitedStates, + China, + EuroZone, + Japan, + UnitedKingdom, + Germany, + France, + Australia, + Canada, + SouthKorea, + India, + Brazil, + HongKong, + Singapore, +} + +impl From for lb::MacrodataCountry { + fn from(v: MacrodataCountry) -> Self { + match v { + MacrodataCountry::UnitedStates => lb::MacrodataCountry::UnitedStates, + MacrodataCountry::China => lb::MacrodataCountry::China, + MacrodataCountry::EuroZone => lb::MacrodataCountry::EuroZone, + MacrodataCountry::Japan => lb::MacrodataCountry::Japan, + MacrodataCountry::UnitedKingdom => lb::MacrodataCountry::UnitedKingdom, + MacrodataCountry::Germany => lb::MacrodataCountry::Germany, + MacrodataCountry::France => lb::MacrodataCountry::France, + MacrodataCountry::Australia => lb::MacrodataCountry::Australia, + MacrodataCountry::Canada => lb::MacrodataCountry::Canada, + MacrodataCountry::SouthKorea => lb::MacrodataCountry::SouthKorea, + MacrodataCountry::India => lb::MacrodataCountry::India, + MacrodataCountry::Brazil => lb::MacrodataCountry::Brazil, + MacrodataCountry::HongKong => lb::MacrodataCountry::HongKong, + MacrodataCountry::Singapore => lb::MacrodataCountry::Singapore, + } + } +} + +/// Response for macrodata_indicators +#[napi_derive::napi(object)] +#[derive(Debug, Clone)] +pub struct MacrodataIndicatorListResponse { + pub data: Vec, + pub count: i32, +} + +impl From for MacrodataIndicatorListResponse { + fn from(v: lb::MacrodataIndicatorListResponse) -> Self { + Self { + data: v.data.into_iter().map(Into::into).collect(), + count: v.count, + } + } +} + /// Metadata for one macroeconomic indicator #[napi_derive::napi(object)] #[derive(Debug, Clone)] @@ -1991,12 +2049,13 @@ impl From for Macrodata { } } -/// Response for economic_indicator +/// Response for macrodata #[napi_derive::napi(object)] #[derive(Debug, Clone)] pub struct MacrodataResponse { pub info: MacrodataIndicator, pub data: Vec, + pub count: i32, } impl From for MacrodataResponse { @@ -2004,6 +2063,7 @@ impl From for MacrodataResponse { Self { info: v.info.into(), data: v.data.into_iter().map(Into::into).collect(), + count: v.count, } } } diff --git a/python/src/fundamental/context.rs b/python/src/fundamental/context.rs index 775563652..ab4709b0d 100644 --- a/python/src/fundamental/context.rs +++ b/python/src/fundamental/context.rs @@ -212,16 +212,15 @@ impl FundamentalContext { /// List macroeconomic indicators. fn macrodata_indicators( &self, + country: Option, offset: Option, limit: Option, - ) -> PyResult> { + ) -> PyResult { Ok(self .ctx - .macrodata_indicators(offset, limit) + .macrodata_indicators(country.map(Into::into), offset, limit) .map_err(ErrorNewType)? - .into_iter() - .map(Into::into) - .collect()) + .into()) } /// Get historical data for a macroeconomic indicator. @@ -230,11 +229,12 @@ impl FundamentalContext { indicator_code: String, start_date: Option, end_date: Option, + offset: Option, limit: Option, ) -> PyResult { Ok(self .ctx - .macrodata(indicator_code, start_date, end_date, limit) + .macrodata(indicator_code, start_date, end_date, offset, limit) .map_err(ErrorNewType)? .into()) } diff --git a/python/src/fundamental/context_async.rs b/python/src/fundamental/context_async.rs index a2742b113..be1ad7c64 100644 --- a/python/src/fundamental/context_async.rs +++ b/python/src/fundamental/context_async.rs @@ -322,18 +322,17 @@ impl AsyncFundamentalContext { fn macrodata_indicators( &self, py: Python<'_>, + country: Option, offset: Option, limit: Option, ) -> PyResult> { let ctx = self.ctx.clone(); pyo3_async_runtimes::tokio::future_into_py(py, async move { - Ok(ctx - .macrodata_indicators(offset, limit) - .await - .map_err(ErrorNewType)? - .into_iter() - .map(MacrodataIndicator::from) - .collect::>()) + Ok(MacrodataIndicatorListResponse::from( + ctx.macrodata_indicators(country.map(Into::into), offset, limit) + .await + .map_err(ErrorNewType)?, + )) }) .map(|b| b.unbind()) } @@ -345,12 +344,13 @@ impl AsyncFundamentalContext { indicator_code: String, start_date: Option, end_date: Option, + offset: Option, limit: Option, ) -> PyResult> { let ctx = self.ctx.clone(); pyo3_async_runtimes::tokio::future_into_py(py, async move { Ok(MacrodataResponse::from( - ctx.macrodata(indicator_code, start_date, end_date, limit) + ctx.macrodata(indicator_code, start_date, end_date, offset, limit) .await .map_err(ErrorNewType)?, )) diff --git a/python/src/fundamental/mod.rs b/python/src/fundamental/mod.rs index 64d6484ae..474d41eaf 100644 --- a/python/src/fundamental/mod.rs +++ b/python/src/fundamental/mod.rs @@ -75,6 +75,8 @@ pub(crate) fn register_types(parent: &Bound) -> PyResult<()> { parent.add_class::()?; parent.add_class::()?; parent.add_class::()?; + parent.add_class::()?; + parent.add_class::()?; parent.add_class::()?; parent.add_class::()?; parent.add_class::()?; diff --git a/python/src/fundamental/types.rs b/python/src/fundamental/types.rs index 358e18c81..dd3631d25 100644 --- a/python/src/fundamental/types.rs +++ b/python/src/fundamental/types.rs @@ -1987,6 +1987,64 @@ impl From for MultiLanguageText { } } +/// Country code for filtering macroeconomic indicators +#[pyclass] +#[derive(Debug, Copy, Clone)] +pub(crate) enum MacrodataCountry { + UnitedStates, + China, + EuroZone, + Japan, + UnitedKingdom, + Germany, + France, + Australia, + Canada, + SouthKorea, + India, + Brazil, + HongKong, + Singapore, +} + +impl From for lb::MacrodataCountry { + fn from(v: MacrodataCountry) -> Self { + match v { + MacrodataCountry::UnitedStates => lb::MacrodataCountry::UnitedStates, + MacrodataCountry::China => lb::MacrodataCountry::China, + MacrodataCountry::EuroZone => lb::MacrodataCountry::EuroZone, + MacrodataCountry::Japan => lb::MacrodataCountry::Japan, + MacrodataCountry::UnitedKingdom => lb::MacrodataCountry::UnitedKingdom, + MacrodataCountry::Germany => lb::MacrodataCountry::Germany, + MacrodataCountry::France => lb::MacrodataCountry::France, + MacrodataCountry::Australia => lb::MacrodataCountry::Australia, + MacrodataCountry::Canada => lb::MacrodataCountry::Canada, + MacrodataCountry::SouthKorea => lb::MacrodataCountry::SouthKorea, + MacrodataCountry::India => lb::MacrodataCountry::India, + MacrodataCountry::Brazil => lb::MacrodataCountry::Brazil, + MacrodataCountry::HongKong => lb::MacrodataCountry::HongKong, + MacrodataCountry::Singapore => lb::MacrodataCountry::Singapore, + } + } +} + +/// Response for macrodata_indicators +#[pyclass(get_all, skip_from_py_object)] +#[derive(Debug, Clone)] +pub(crate) struct MacrodataIndicatorListResponse { + pub data: Vec, + pub count: i32, +} + +impl From for MacrodataIndicatorListResponse { + fn from(v: lb::MacrodataIndicatorListResponse) -> Self { + Self { + data: v.data.into_iter().map(Into::into).collect(), + count: v.count, + } + } +} + /// Metadata for one macroeconomic indicator #[pyclass(get_all, skip_from_py_object)] #[derive(Debug, Clone)] @@ -2051,12 +2109,13 @@ impl From for Macrodata { } } -/// Response for economic_indicator +/// Response for macrodata #[pyclass(get_all, skip_from_py_object)] #[derive(Debug, Clone)] pub(crate) struct MacrodataResponse { pub info: MacrodataIndicator, pub data: Vec, + pub count: i32, } impl From for MacrodataResponse { @@ -2064,6 +2123,7 @@ impl From for MacrodataResponse { Self { info: v.info.into(), data: v.data.into_iter().map(Into::into).collect(), + count: v.count, } } } diff --git a/rust/src/fundamental/context.rs b/rust/src/fundamental/context.rs index f13dbf149..4b3bc21b3 100644 --- a/rust/src/fundamental/context.rs +++ b/rust/src/fundamental/context.rs @@ -834,23 +834,26 @@ impl FundamentalContext { /// List macroeconomic indicators. /// + /// Pass `country` to filter by country code (e.g. `MacrodataCountry::UnitedStates`). + /// /// Path: `GET /v1/quote/macrodata` pub async fn macrodata_indicators( &self, + country: Option, offset: Option, limit: Option, - ) -> Result> { + ) -> Result { #[derive(Serialize)] struct Query { + #[serde(skip_serializing_if = "Option::is_none")] + country: Option, #[serde(skip_serializing_if = "Option::is_none")] offset: Option, #[serde(skip_serializing_if = "Option::is_none")] limit: Option, } - let resp: MacrodataIndicatorListResponse = self - .get("/v1/quote/macrodata", Query { offset, limit }) - .await?; - Ok(resp.data) + self.get("/v1/quote/macrodata", Query { country, offset, limit }) + .await } /// Get historical data for a macroeconomic indicator. @@ -865,6 +868,7 @@ impl FundamentalContext { indicator_code: impl Into, start_date: Option>, end_date: Option>, + offset: Option, limit: Option, ) -> Result { #[derive(Serialize)] @@ -874,6 +878,8 @@ impl FundamentalContext { #[serde(skip_serializing_if = "Option::is_none")] end_time: Option, #[serde(skip_serializing_if = "Option::is_none")] + offset: Option, + #[serde(skip_serializing_if = "Option::is_none")] limit: Option, } let path = format!("/v1/quote/macrodata/{}", indicator_code.into()); @@ -884,6 +890,7 @@ impl FundamentalContext { .query_params(Query { start_time: start_date.map(|d| format!("{}T00:00:00Z", d.into())), end_time: end_date.map(|d| format!("{}T23:59:59Z", d.into())), + offset, limit, }) .response::>() diff --git a/rust/src/fundamental/types.rs b/rust/src/fundamental/types.rs index fb4f29051..b50ce88d6 100644 --- a/rust/src/fundamental/types.rs +++ b/rust/src/fundamental/types.rs @@ -1565,6 +1565,76 @@ pub struct AssetAllocationResponse { // ── macrodata ───────────────────────────────────────────────────── +/// Country code for filtering macroeconomic indicators +#[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize)] +pub enum MacrodataCountry { + /// United States + #[serde(rename = "US")] + UnitedStates, + /// China + #[serde(rename = "CN")] + China, + /// Euro Zone + #[serde(rename = "EU")] + EuroZone, + /// Japan + #[serde(rename = "JP")] + Japan, + /// United Kingdom + #[serde(rename = "UK")] + UnitedKingdom, + /// Germany + #[serde(rename = "DE")] + Germany, + /// France + #[serde(rename = "FR")] + France, + /// Australia + #[serde(rename = "AU")] + Australia, + /// Canada + #[serde(rename = "CA")] + Canada, + /// South Korea + #[serde(rename = "KR")] + SouthKorea, + /// India + #[serde(rename = "IN")] + India, + /// Brazil + #[serde(rename = "BR")] + Brazil, + /// Hong Kong + #[serde(rename = "HK")] + HongKong, + /// Singapore + #[serde(rename = "SG")] + Singapore, +} + +/// Importance level of a macroeconomic indicator +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +pub enum MacrodataImportance { + /// Low importance + Low = 1, + /// Medium importance + Medium = 2, + /// High importance + High = 3, +} + +impl MacrodataImportance { + /// Convert from raw API integer value + pub fn from_i32(v: i32) -> Option { + match v { + 1 => Some(Self::Low), + 2 => Some(Self::Medium), + 3 => Some(Self::High), + _ => None, + } + } +} + /// Localized text in simplified Chinese, traditional Chinese, and English #[derive(Debug, Clone, Default, Serialize, Deserialize)] pub struct MultiLanguageText { @@ -1617,12 +1687,15 @@ pub struct MacrodataIndicator { pub start_date: Option, } -/// Response for [`crate::FundamentalContext::macrodata_list`] +/// Response for [`crate::FundamentalContext::macrodata_indicators`] #[derive(Debug, Clone, Serialize, Deserialize)] pub struct MacrodataIndicatorListResponse { /// Indicator list #[serde(default, rename = "list")] pub data: Vec, + /// Total number of indicators matching the query + #[serde(default)] + pub count: i32, } /// One historical data point for a macroeconomic indicator @@ -1666,4 +1739,7 @@ pub struct MacrodataResponse { /// Historical data points #[serde(default)] pub data: Vec, + /// Total number of historical data points + #[serde(default)] + pub count: i32, } From 103ea5b9b1fa445b341f108676a22e9492bd305e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Wed, 10 Jun 2026 17:53:19 +0800 Subject: [PATCH 18/28] fix: trim MacrodataCountry to 6 supported countries (HK/CN/US/EU/JP/SG) Co-Authored-By: Claude Sonnet 4.6 (1M context) --- java/src/fundamental_context.rs | 12 ++------- nodejs/src/fundamental/types.rs | 46 +++++++-------------------------- python/src/fundamental/types.rs | 40 +++------------------------- rust/src/fundamental/types.rs | 36 +++++--------------------- 4 files changed, 22 insertions(+), 112 deletions(-) diff --git a/java/src/fundamental_context.rs b/java/src/fundamental_context.rs index a507153ce..93d2bfeff 100644 --- a/java/src/fundamental_context.rs +++ b/java/src/fundamental_context.rs @@ -279,19 +279,11 @@ pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextMa let country = country.and_then(|s| { use longbridge::fundamental::MacrodataCountry::*; match s.as_str() { - "US" => Some(UnitedStates), + "HK" => Some(HongKong), "CN" => Some(China), + "US" => Some(UnitedStates), "EU" => Some(EuroZone), "JP" => Some(Japan), - "UK" => Some(UnitedKingdom), - "DE" => Some(Germany), - "FR" => Some(France), - "AU" => Some(Australia), - "CA" => Some(Canada), - "KR" => Some(SouthKorea), - "IN" => Some(India), - "BR" => Some(Brazil), - "HK" => Some(HongKong), "SG" => Some(Singapore), _ => None, } diff --git a/nodejs/src/fundamental/types.rs b/nodejs/src/fundamental/types.rs index b0e13ef0c..b1f99a013 100644 --- a/nodejs/src/fundamental/types.rs +++ b/nodejs/src/fundamental/types.rs @@ -1928,59 +1928,33 @@ impl From for MultiLanguageText { #[napi_derive::napi] #[derive(Debug, Copy, Clone)] pub enum MacrodataCountry { - UnitedStates, + /// Hong Kong SAR China + HongKong, + /// China (Mainland) China, + /// United States + UnitedStates, + /// Euro Zone EuroZone, + /// Japan Japan, - UnitedKingdom, - Germany, - France, - Australia, - Canada, - SouthKorea, - India, - Brazil, - HongKong, + /// Singapore Singapore, } impl From for lb::MacrodataCountry { fn from(v: MacrodataCountry) -> Self { match v { - MacrodataCountry::UnitedStates => lb::MacrodataCountry::UnitedStates, + MacrodataCountry::HongKong => lb::MacrodataCountry::HongKong, MacrodataCountry::China => lb::MacrodataCountry::China, + MacrodataCountry::UnitedStates => lb::MacrodataCountry::UnitedStates, MacrodataCountry::EuroZone => lb::MacrodataCountry::EuroZone, MacrodataCountry::Japan => lb::MacrodataCountry::Japan, - MacrodataCountry::UnitedKingdom => lb::MacrodataCountry::UnitedKingdom, - MacrodataCountry::Germany => lb::MacrodataCountry::Germany, - MacrodataCountry::France => lb::MacrodataCountry::France, - MacrodataCountry::Australia => lb::MacrodataCountry::Australia, - MacrodataCountry::Canada => lb::MacrodataCountry::Canada, - MacrodataCountry::SouthKorea => lb::MacrodataCountry::SouthKorea, - MacrodataCountry::India => lb::MacrodataCountry::India, - MacrodataCountry::Brazil => lb::MacrodataCountry::Brazil, - MacrodataCountry::HongKong => lb::MacrodataCountry::HongKong, MacrodataCountry::Singapore => lb::MacrodataCountry::Singapore, } } } -/// Response for macrodata_indicators -#[napi_derive::napi(object)] -#[derive(Debug, Clone)] -pub struct MacrodataIndicatorListResponse { - pub data: Vec, - pub count: i32, -} - -impl From for MacrodataIndicatorListResponse { - fn from(v: lb::MacrodataIndicatorListResponse) -> Self { - Self { - data: v.data.into_iter().map(Into::into).collect(), - count: v.count, - } - } -} /// Metadata for one macroeconomic indicator #[napi_derive::napi(object)] diff --git a/python/src/fundamental/types.rs b/python/src/fundamental/types.rs index dd3631d25..cc70b61c5 100644 --- a/python/src/fundamental/types.rs +++ b/python/src/fundamental/types.rs @@ -1991,59 +1991,27 @@ impl From for MultiLanguageText { #[pyclass] #[derive(Debug, Copy, Clone)] pub(crate) enum MacrodataCountry { - UnitedStates, + HongKong, China, + UnitedStates, EuroZone, Japan, - UnitedKingdom, - Germany, - France, - Australia, - Canada, - SouthKorea, - India, - Brazil, - HongKong, Singapore, } impl From for lb::MacrodataCountry { fn from(v: MacrodataCountry) -> Self { match v { - MacrodataCountry::UnitedStates => lb::MacrodataCountry::UnitedStates, + MacrodataCountry::HongKong => lb::MacrodataCountry::HongKong, MacrodataCountry::China => lb::MacrodataCountry::China, + MacrodataCountry::UnitedStates => lb::MacrodataCountry::UnitedStates, MacrodataCountry::EuroZone => lb::MacrodataCountry::EuroZone, MacrodataCountry::Japan => lb::MacrodataCountry::Japan, - MacrodataCountry::UnitedKingdom => lb::MacrodataCountry::UnitedKingdom, - MacrodataCountry::Germany => lb::MacrodataCountry::Germany, - MacrodataCountry::France => lb::MacrodataCountry::France, - MacrodataCountry::Australia => lb::MacrodataCountry::Australia, - MacrodataCountry::Canada => lb::MacrodataCountry::Canada, - MacrodataCountry::SouthKorea => lb::MacrodataCountry::SouthKorea, - MacrodataCountry::India => lb::MacrodataCountry::India, - MacrodataCountry::Brazil => lb::MacrodataCountry::Brazil, - MacrodataCountry::HongKong => lb::MacrodataCountry::HongKong, MacrodataCountry::Singapore => lb::MacrodataCountry::Singapore, } } } -/// Response for macrodata_indicators -#[pyclass(get_all, skip_from_py_object)] -#[derive(Debug, Clone)] -pub(crate) struct MacrodataIndicatorListResponse { - pub data: Vec, - pub count: i32, -} - -impl From for MacrodataIndicatorListResponse { - fn from(v: lb::MacrodataIndicatorListResponse) -> Self { - Self { - data: v.data.into_iter().map(Into::into).collect(), - count: v.count, - } - } -} /// Metadata for one macroeconomic indicator #[pyclass(get_all, skip_from_py_object)] diff --git a/rust/src/fundamental/types.rs b/rust/src/fundamental/types.rs index b50ce88d6..8fda7fc64 100644 --- a/rust/src/fundamental/types.rs +++ b/rust/src/fundamental/types.rs @@ -1568,45 +1568,21 @@ pub struct AssetAllocationResponse { /// Country code for filtering macroeconomic indicators #[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize)] pub enum MacrodataCountry { + /// Hong Kong SAR China + #[serde(rename = "HK")] + HongKong, + /// China (Mainland) + #[serde(rename = "CN")] + China, /// United States #[serde(rename = "US")] UnitedStates, - /// China - #[serde(rename = "CN")] - China, /// Euro Zone #[serde(rename = "EU")] EuroZone, /// Japan #[serde(rename = "JP")] Japan, - /// United Kingdom - #[serde(rename = "UK")] - UnitedKingdom, - /// Germany - #[serde(rename = "DE")] - Germany, - /// France - #[serde(rename = "FR")] - France, - /// Australia - #[serde(rename = "AU")] - Australia, - /// Canada - #[serde(rename = "CA")] - Canada, - /// South Korea - #[serde(rename = "KR")] - SouthKorea, - /// India - #[serde(rename = "IN")] - India, - /// Brazil - #[serde(rename = "BR")] - Brazil, - /// Hong Kong - #[serde(rename = "HK")] - HongKong, /// Singapore #[serde(rename = "SG")] Singapore, From 792e00f5921482d17714ac05c6c9fd717abfb549 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Wed, 10 Jun 2026 17:55:45 +0800 Subject: [PATCH 19/28] fix: convert MacrodataCountry code to API full name before request SDK accepts HK/CN/US/EU/JP/SG shortcodes; serde renames to full strings ('Hong Kong SAR China'/'China (Mainland)'/etc.) when serializing to query params. Java JNI also accepts both shortcodes and full strings. Co-Authored-By: Claude Sonnet 4.6 (1M context) --- java/src/fundamental_context.rs | 12 ++++++------ rust/src/fundamental/types.rs | 14 +++++++------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/java/src/fundamental_context.rs b/java/src/fundamental_context.rs index 93d2bfeff..ed06654c0 100644 --- a/java/src/fundamental_context.rs +++ b/java/src/fundamental_context.rs @@ -279,12 +279,12 @@ pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextMa let country = country.and_then(|s| { use longbridge::fundamental::MacrodataCountry::*; match s.as_str() { - "HK" => Some(HongKong), - "CN" => Some(China), - "US" => Some(UnitedStates), - "EU" => Some(EuroZone), - "JP" => Some(Japan), - "SG" => Some(Singapore), + "HK" | "Hong Kong SAR China" => Some(HongKong), + "CN" | "China (Mainland)" => Some(China), + "US" | "United States" => Some(UnitedStates), + "EU" | "Euro Zone" => Some(EuroZone), + "JP" | "Japan" => Some(Japan), + "SG" | "Singapore" => Some(Singapore), _ => None, } }); diff --git a/rust/src/fundamental/types.rs b/rust/src/fundamental/types.rs index 8fda7fc64..7ba2f3547 100644 --- a/rust/src/fundamental/types.rs +++ b/rust/src/fundamental/types.rs @@ -1565,26 +1565,26 @@ pub struct AssetAllocationResponse { // ── macrodata ───────────────────────────────────────────────────── -/// Country code for filtering macroeconomic indicators +/// Country for filtering macroeconomic indicators #[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize)] pub enum MacrodataCountry { /// Hong Kong SAR China - #[serde(rename = "HK")] + #[serde(rename = "Hong Kong SAR China")] HongKong, /// China (Mainland) - #[serde(rename = "CN")] + #[serde(rename = "China (Mainland)")] China, /// United States - #[serde(rename = "US")] + #[serde(rename = "United States")] UnitedStates, /// Euro Zone - #[serde(rename = "EU")] + #[serde(rename = "Euro Zone")] EuroZone, /// Japan - #[serde(rename = "JP")] + #[serde(rename = "Japan")] Japan, /// Singapore - #[serde(rename = "SG")] + #[serde(rename = "Singapore")] Singapore, } From 4e3e0124a8f58414654bce43983a0e5e0cbc3a56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Wed, 10 Jun 2026 18:03:09 +0800 Subject: [PATCH 20/28] fix(python): restore MacrodataIndicatorListResponse struct lost in refactor Co-Authored-By: Claude Sonnet 4.6 (1M context) --- python/src/fundamental/types.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/python/src/fundamental/types.rs b/python/src/fundamental/types.rs index cc70b61c5..62fd03dbd 100644 --- a/python/src/fundamental/types.rs +++ b/python/src/fundamental/types.rs @@ -2013,6 +2013,23 @@ impl From for lb::MacrodataCountry { } +/// Response for macrodata_indicators +#[pyclass(get_all, skip_from_py_object)] +#[derive(Debug, Clone)] +pub(crate) struct MacrodataIndicatorListResponse { + pub data: Vec, + pub count: i32, +} + +impl From for MacrodataIndicatorListResponse { + fn from(v: lb::MacrodataIndicatorListResponse) -> Self { + Self { + data: v.data.into_iter().map(Into::into).collect(), + count: v.count, + } + } +} + /// Metadata for one macroeconomic indicator #[pyclass(get_all, skip_from_py_object)] #[derive(Debug, Clone)] From fd091ea8f4cf0f2d322a36e41bf6beb4b8b57c15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Wed, 10 Jun 2026 18:05:01 +0800 Subject: [PATCH 21/28] fix(ci): apply cargo fmt formatting fixes --- java/src/fundamental_context.rs | 5 ++++- nodejs/src/fundamental/types.rs | 1 - python/src/fundamental/types.rs | 1 - rust/src/fundamental/context.rs | 11 +++++++++-- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/java/src/fundamental_context.rs b/java/src/fundamental_context.rs index ed06654c0..79efc40d7 100644 --- a/java/src/fundamental_context.rs +++ b/java/src/fundamental_context.rs @@ -291,7 +291,10 @@ pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextMa let offset: Option = FromJValue::from_jvalue(env, offset.into())?; let limit: Option = FromJValue::from_jvalue(env, limit.into())?; async_util::execute(env, callback, async move { - Ok(context.ctx.macrodata_indicators(country, offset, limit).await?) + Ok(context + .ctx + .macrodata_indicators(country, offset, limit) + .await?) })?; Ok(()) }) diff --git a/nodejs/src/fundamental/types.rs b/nodejs/src/fundamental/types.rs index b1f99a013..9eb830a7b 100644 --- a/nodejs/src/fundamental/types.rs +++ b/nodejs/src/fundamental/types.rs @@ -1955,7 +1955,6 @@ impl From for lb::MacrodataCountry { } } - /// Metadata for one macroeconomic indicator #[napi_derive::napi(object)] #[derive(Debug, Clone)] diff --git a/python/src/fundamental/types.rs b/python/src/fundamental/types.rs index 62fd03dbd..ce36b4faa 100644 --- a/python/src/fundamental/types.rs +++ b/python/src/fundamental/types.rs @@ -2012,7 +2012,6 @@ impl From for lb::MacrodataCountry { } } - /// Response for macrodata_indicators #[pyclass(get_all, skip_from_py_object)] #[derive(Debug, Clone)] diff --git a/rust/src/fundamental/context.rs b/rust/src/fundamental/context.rs index 4b3bc21b3..526343128 100644 --- a/rust/src/fundamental/context.rs +++ b/rust/src/fundamental/context.rs @@ -852,8 +852,15 @@ impl FundamentalContext { #[serde(skip_serializing_if = "Option::is_none")] limit: Option, } - self.get("/v1/quote/macrodata", Query { country, offset, limit }) - .await + self.get( + "/v1/quote/macrodata", + Query { + country, + offset, + limit, + }, + ) + .await } /// Get historical data for a macroeconomic indicator. From 21be43d62143cf6d64ae3589083de44b013d7945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Wed, 10 Jun 2026 18:13:08 +0800 Subject: [PATCH 22/28] fix: restore MacrodataIndicatorListResponse in nodejs types; use String for country query param MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit serde_urlencoded cannot serialize enums — convert MacrodataCountry to its API string value before building the query struct. Co-Authored-By: Claude Sonnet 4.6 (1M context) --- nodejs/src/fundamental/types.rs | 17 +++++++++++++++++ rust/src/fundamental/context.rs | 15 +++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/nodejs/src/fundamental/types.rs b/nodejs/src/fundamental/types.rs index 9eb830a7b..193387422 100644 --- a/nodejs/src/fundamental/types.rs +++ b/nodejs/src/fundamental/types.rs @@ -1955,6 +1955,23 @@ impl From for lb::MacrodataCountry { } } +/// Response for macrodata_indicators +#[napi_derive::napi(object)] +#[derive(Debug, Clone)] +pub struct MacrodataIndicatorListResponse { + pub data: Vec, + pub count: i32, +} + +impl From for MacrodataIndicatorListResponse { + fn from(v: lb::MacrodataIndicatorListResponse) -> Self { + Self { + data: v.data.into_iter().map(Into::into).collect(), + count: v.count, + } + } +} + /// Metadata for one macroeconomic indicator #[napi_derive::napi(object)] #[derive(Debug, Clone)] diff --git a/rust/src/fundamental/context.rs b/rust/src/fundamental/context.rs index 526343128..91d7a4803 100644 --- a/rust/src/fundamental/context.rs +++ b/rust/src/fundamental/context.rs @@ -846,16 +846,27 @@ impl FundamentalContext { #[derive(Serialize)] struct Query { #[serde(skip_serializing_if = "Option::is_none")] - country: Option, + country: Option, #[serde(skip_serializing_if = "Option::is_none")] offset: Option, #[serde(skip_serializing_if = "Option::is_none")] limit: Option, } + let country_str = country.map(|c| { + match c { + MacrodataCountry::HongKong => "Hong Kong SAR China", + MacrodataCountry::China => "China (Mainland)", + MacrodataCountry::UnitedStates => "United States", + MacrodataCountry::EuroZone => "Euro Zone", + MacrodataCountry::Japan => "Japan", + MacrodataCountry::Singapore => "Singapore", + } + .to_string() + }); self.get( "/v1/quote/macrodata", Query { - country, + country: country_str, offset, limit, }, From 0dece23ba1a4ef5ae6a49e1a8f1767c5cdc7680f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Wed, 10 Jun 2026 18:22:49 +0800 Subject: [PATCH 23/28] fix(ci): apply nightly cargo fmt to fix all formatting issues Co-Authored-By: Claude Sonnet 4.6 (1M context) --- nodejs/index.d.ts | 29 ++++++++++++++++++++++++++--- nodejs/index.js | 1 + rust/src/blocking/fundamental.rs | 8 +++++--- rust/src/fundamental/context.rs | 3 ++- 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/nodejs/index.d.ts b/nodejs/index.d.ts index 9f942929d..5eaac8a84 100644 --- a/nodejs/index.d.ts +++ b/nodejs/index.d.ts @@ -619,9 +619,9 @@ export declare class FundamentalContext { */ etfAssetAllocation(symbol: string): Promise /** List macroeconomic indicators */ - macrodataIndicators(offset?: number | undefined | null, limit?: number | undefined | null): Promise> + macrodataIndicators(country?: MacrodataCountry | undefined | null, offset?: number | undefined | null, limit?: number | undefined | null): Promise /** Get historical data for a macroeconomic indicator */ - macrodata(indicatorCode: string, startDate?: string | undefined | null, endDate?: string | undefined | null, limit?: number | undefined | null): Promise + macrodata(indicatorCode: string, startDate?: string | undefined | null, endDate?: string | undefined | null, offset?: number | undefined | null, limit?: number | undefined | null): Promise } /** Fund position */ @@ -4492,6 +4492,22 @@ export interface Macrodata { unitPrefix: MultiLanguageText } +/** Country code for filtering macroeconomic indicators */ +export declare const enum MacrodataCountry { + /** Hong Kong SAR China */ + HongKong = 0, + /** China (Mainland) */ + China = 1, + /** United States */ + UnitedStates = 2, + /** Euro Zone */ + EuroZone = 3, + /** Japan */ + Japan = 4, + /** Singapore */ + Singapore = 5 +} + /** Metadata for one macroeconomic indicator */ export interface MacrodataIndicator { indicatorCode: string @@ -4507,10 +4523,17 @@ export interface MacrodataIndicator { startDate?: number } -/** Response for economic_indicator */ +/** Response for macrodata_indicators */ +export interface MacrodataIndicatorListResponse { + data: Array + count: number +} + +/** Response for macrodata */ export interface MacrodataResponse { info: MacrodataIndicator data: Array + count: number } export declare const enum Market { diff --git a/nodejs/index.js b/nodejs/index.js index a8cb5ec7a..fa943da93 100644 --- a/nodejs/index.js +++ b/nodejs/index.js @@ -689,6 +689,7 @@ module.exports.FlowDirection = nativeBinding.FlowDirection module.exports.Granularity = nativeBinding.Granularity module.exports.InstitutionRecommend = nativeBinding.InstitutionRecommend module.exports.Language = nativeBinding.Language +module.exports.MacrodataCountry = nativeBinding.MacrodataCountry module.exports.Market = nativeBinding.Market module.exports.OptionDirection = nativeBinding.OptionDirection module.exports.OptionType = nativeBinding.OptionType diff --git a/rust/src/blocking/fundamental.rs b/rust/src/blocking/fundamental.rs index 5338f275d..4e303a7c6 100644 --- a/rust/src/blocking/fundamental.rs +++ b/rust/src/blocking/fundamental.rs @@ -294,11 +294,12 @@ impl FundamentalContextSync { /// List macroeconomic indicators pub fn macrodata_indicators( &self, + country: Option, offset: Option, limit: Option, - ) -> Result> { + ) -> Result { self.rt - .call(move |ctx| async move { ctx.macrodata_indicators(offset, limit).await }) + .call(move |ctx| async move { ctx.macrodata_indicators(country, offset, limit).await }) } /// Get historical data for a macroeconomic indicator @@ -307,10 +308,11 @@ impl FundamentalContextSync { indicator_code: impl Into + Send + 'static, start_date: Option + Send + 'static>, end_date: Option + Send + 'static>, + offset: Option, limit: Option, ) -> Result { self.rt.call(move |ctx| async move { - ctx.macrodata(indicator_code, start_date, end_date, limit) + ctx.macrodata(indicator_code, start_date, end_date, offset, limit) .await }) } diff --git a/rust/src/fundamental/context.rs b/rust/src/fundamental/context.rs index 91d7a4803..10f4af551 100644 --- a/rust/src/fundamental/context.rs +++ b/rust/src/fundamental/context.rs @@ -834,7 +834,8 @@ impl FundamentalContext { /// List macroeconomic indicators. /// - /// Pass `country` to filter by country code (e.g. `MacrodataCountry::UnitedStates`). + /// Pass `country` to filter by country code (e.g. + /// `MacrodataCountry::UnitedStates`). /// /// Path: `GET /v1/quote/macrodata` pub async fn macrodata_indicators( From 779f78cef639dbd2d656c9fcce9cea4e35ba07df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Thu, 11 Jun 2026 10:02:06 +0800 Subject: [PATCH 24/28] refactor: rename macrodata -> macroeconomic in all interfaces and types Co-Authored-By: Claude Sonnet 4.6 (1M context) --- .../main/java/com/longbridge/SdkNative.java | 4 +- .../fundamental/FundamentalContext.java | 8 ++-- .../MacrodataIndicatorListResponse.java | 8 ---- .../fundamental/MacrodataResponse.java | 9 ---- .../{Macrodata.java => Macroeconomic.java} | 2 +- ...cator.java => MacroeconomicIndicator.java} | 2 +- .../MacroeconomicIndicatorListResponse.java | 8 ++++ .../fundamental/MacroeconomicResponse.java | 9 ++++ java/src/fundamental_context.rs | 10 ++--- java/src/types/classes.rs | 12 ++--- nodejs/index.d.ts | 20 ++++----- nodejs/src/fundamental/context.rs | 14 +++--- nodejs/src/fundamental/types.rs | 44 +++++++++---------- python/pysrc/longbridge/openapi.pyi | 24 +++++----- python/src/fundamental/context.rs | 14 +++--- python/src/fundamental/context_async.rs | 14 +++--- python/src/fundamental/mod.rs | 8 ++-- python/src/fundamental/types.rs | 44 +++++++++---------- rust/src/fundamental/context.rs | 28 ++++++------ rust/src/fundamental/types.rs | 24 +++++----- 20 files changed, 153 insertions(+), 153 deletions(-) delete mode 100644 java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataIndicatorListResponse.java delete mode 100644 java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataResponse.java rename java/javasrc/src/main/java/com/longbridge/fundamental/{Macrodata.java => Macroeconomic.java} (93%) rename java/javasrc/src/main/java/com/longbridge/fundamental/{MacrodataIndicator.java => MacroeconomicIndicator.java} (94%) create mode 100644 java/javasrc/src/main/java/com/longbridge/fundamental/MacroeconomicIndicatorListResponse.java create mode 100644 java/javasrc/src/main/java/com/longbridge/fundamental/MacroeconomicResponse.java diff --git a/java/javasrc/src/main/java/com/longbridge/SdkNative.java b/java/javasrc/src/main/java/com/longbridge/SdkNative.java index 891ae360a..dadca70c6 100644 --- a/java/javasrc/src/main/java/com/longbridge/SdkNative.java +++ b/java/javasrc/src/main/java/com/longbridge/SdkNative.java @@ -451,11 +451,11 @@ public static native void fundamentalContextGetFinancialReportSnapshot(long cont Object opts, AsyncCallback callback); - public static native void fundamentalContextMacrodataIndicators(long context, + public static native void fundamentalContextMacroeconomicIndicators(long context, Object country, Object offset, Object limit, AsyncCallback callback); - public static native void fundamentalContextMacrodata(long context, + public static native void fundamentalContextMacroeconomic(long context, Object indicatorCode, Object startTime, Object endTime, Object offset, Object limit, AsyncCallback callback); diff --git a/java/javasrc/src/main/java/com/longbridge/fundamental/FundamentalContext.java b/java/javasrc/src/main/java/com/longbridge/fundamental/FundamentalContext.java index 8486cd247..4c22e256a 100644 --- a/java/javasrc/src/main/java/com/longbridge/fundamental/FundamentalContext.java +++ b/java/javasrc/src/main/java/com/longbridge/fundamental/FundamentalContext.java @@ -339,9 +339,9 @@ public CompletableFuture getValuationComparison(Val * List macroeconomic indicators. * country: ISO country code string (e.g. "US", "CN", "EU"); pass null for all countries. */ - public CompletableFuture getMacrodataIndicators(String country, Integer offset, Integer limit) throws OpenApiException { + public CompletableFuture getMacroeconomicIndicators(String country, Integer offset, Integer limit) throws OpenApiException { return AsyncCallback.executeTask((callback) -> { - SdkNative.fundamentalContextMacrodataIndicators(raw, country, offset, limit, callback); + SdkNative.fundamentalContextMacroeconomicIndicators(raw, country, offset, limit, callback); }); } @@ -349,9 +349,9 @@ public CompletableFuture getMacrodataIndicators( * Get historical data for a macroeconomic indicator. * startDate and endDate are date strings in "YYYY-MM-DD" format. */ - public CompletableFuture getMacrodata(String indicatorCode, String startDate, String endDate, Integer offset, Integer limit) throws OpenApiException { + public CompletableFuture getMacroeconomic(String indicatorCode, String startDate, String endDate, Integer offset, Integer limit) throws OpenApiException { return AsyncCallback.executeTask((callback) -> { - SdkNative.fundamentalContextMacrodata(raw, indicatorCode, startDate, endDate, offset, limit, callback); + SdkNative.fundamentalContextMacroeconomic(raw, indicatorCode, startDate, endDate, offset, limit, callback); }); } } diff --git a/java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataIndicatorListResponse.java b/java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataIndicatorListResponse.java deleted file mode 100644 index dd4fc6802..000000000 --- a/java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataIndicatorListResponse.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.longbridge.fundamental; - -/** Response for {@link FundamentalContext#getMacrodataIndicators}. */ -public class MacrodataIndicatorListResponse { - public MacrodataIndicator[] data; - /** Total number of indicators matching the query. */ - public int count; -} diff --git a/java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataResponse.java b/java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataResponse.java deleted file mode 100644 index f3532ee24..000000000 --- a/java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataResponse.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.longbridge.fundamental; - -/** Response for {@link FundamentalContext#getMacrodata}. */ -public class MacrodataResponse { - public MacrodataIndicator info; - public Macrodata[] data; - /** Total number of historical data points. */ - public int count; -} diff --git a/java/javasrc/src/main/java/com/longbridge/fundamental/Macrodata.java b/java/javasrc/src/main/java/com/longbridge/fundamental/Macroeconomic.java similarity index 93% rename from java/javasrc/src/main/java/com/longbridge/fundamental/Macrodata.java rename to java/javasrc/src/main/java/com/longbridge/fundamental/Macroeconomic.java index 9eadc8aa7..caca0ccda 100644 --- a/java/javasrc/src/main/java/com/longbridge/fundamental/Macrodata.java +++ b/java/javasrc/src/main/java/com/longbridge/fundamental/Macroeconomic.java @@ -1,7 +1,7 @@ package com.longbridge.fundamental; /** One historical data point for a macroeconomic indicator. */ -public class Macrodata { +public class Macroeconomic { /** Statistical period (e.g. 2024-Q1, 2024-03). */ public String period; public String releaseAt; diff --git a/java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataIndicator.java b/java/javasrc/src/main/java/com/longbridge/fundamental/MacroeconomicIndicator.java similarity index 94% rename from java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataIndicator.java rename to java/javasrc/src/main/java/com/longbridge/fundamental/MacroeconomicIndicator.java index deefd5eb8..c83d4fd5a 100644 --- a/java/javasrc/src/main/java/com/longbridge/fundamental/MacrodataIndicator.java +++ b/java/javasrc/src/main/java/com/longbridge/fundamental/MacroeconomicIndicator.java @@ -1,7 +1,7 @@ package com.longbridge.fundamental; /** Metadata for one macroeconomic indicator. */ -public class MacrodataIndicator { +public class MacroeconomicIndicator { /** External vendor code (input to getEconomicIndicator). */ public String indicatorCode; public String sourceOrg; diff --git a/java/javasrc/src/main/java/com/longbridge/fundamental/MacroeconomicIndicatorListResponse.java b/java/javasrc/src/main/java/com/longbridge/fundamental/MacroeconomicIndicatorListResponse.java new file mode 100644 index 000000000..b62e637c6 --- /dev/null +++ b/java/javasrc/src/main/java/com/longbridge/fundamental/MacroeconomicIndicatorListResponse.java @@ -0,0 +1,8 @@ +package com.longbridge.fundamental; + +/** Response for {@link FundamentalContext#getMacroeconomicIndicators}. */ +public class MacroeconomicIndicatorListResponse { + public MacroeconomicIndicator[] data; + /** Total number of indicators matching the query. */ + public int count; +} diff --git a/java/javasrc/src/main/java/com/longbridge/fundamental/MacroeconomicResponse.java b/java/javasrc/src/main/java/com/longbridge/fundamental/MacroeconomicResponse.java new file mode 100644 index 000000000..e84c46569 --- /dev/null +++ b/java/javasrc/src/main/java/com/longbridge/fundamental/MacroeconomicResponse.java @@ -0,0 +1,9 @@ +package com.longbridge.fundamental; + +/** Response for {@link FundamentalContext#getMacroeconomic}. */ +public class MacroeconomicResponse { + public MacroeconomicIndicator info; + public Macroeconomic[] data; + /** Total number of historical data points. */ + public int count; +} diff --git a/java/src/fundamental_context.rs b/java/src/fundamental_context.rs index 79efc40d7..163b2fd45 100644 --- a/java/src/fundamental_context.rs +++ b/java/src/fundamental_context.rs @@ -264,7 +264,7 @@ pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextVa } #[unsafe(no_mangle)] -pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextMacrodataIndicators( +pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextMacroeconomicIndicators( mut env: JNIEnv, _class: JClass, context: i64, @@ -277,7 +277,7 @@ pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextMa let context = &*(context as *const ContextObj); let country: Option = FromJValue::from_jvalue(env, country.into())?; let country = country.and_then(|s| { - use longbridge::fundamental::MacrodataCountry::*; + use longbridge::fundamental::MacroeconomicCountry::*; match s.as_str() { "HK" | "Hong Kong SAR China" => Some(HongKong), "CN" | "China (Mainland)" => Some(China), @@ -293,7 +293,7 @@ pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextMa async_util::execute(env, callback, async move { Ok(context .ctx - .macrodata_indicators(country, offset, limit) + .macroeconomic_indicators(country, offset, limit) .await?) })?; Ok(()) @@ -301,7 +301,7 @@ pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextMa } #[unsafe(no_mangle)] -pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextMacrodata( +pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextMacroeconomic( mut env: JNIEnv, _class: JClass, context: i64, @@ -322,7 +322,7 @@ pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextMa async_util::execute(env, callback, async move { Ok(context .ctx - .macrodata(indicator_code, start_date, end_date, offset, limit) + .macroeconomic(indicator_code, start_date, end_date, offset, limit) .await?) })?; Ok(()) diff --git a/java/src/types/classes.rs b/java/src/types/classes.rs index a941e6b80..03f9e53e4 100644 --- a/java/src/types/classes.rs +++ b/java/src/types/classes.rs @@ -2705,8 +2705,8 @@ impl_java_class!( ); impl_java_class!( - "com/longbridge/fundamental/MacrodataIndicator", - longbridge::fundamental::MacrodataIndicator, + "com/longbridge/fundamental/MacroeconomicIndicator", + longbridge::fundamental::MacroeconomicIndicator, [ indicator_code, source_org, @@ -2738,8 +2738,8 @@ impl_java_class!( ); impl_java_class!( - "com/longbridge/fundamental/MacrodataIndicatorListResponse", - longbridge::fundamental::MacrodataIndicatorListResponse, + "com/longbridge/fundamental/MacroeconomicIndicatorListResponse", + longbridge::fundamental::MacroeconomicIndicatorListResponse, [ #[java(objarray)] data, @@ -2748,8 +2748,8 @@ impl_java_class!( ); impl_java_class!( - "com/longbridge/fundamental/MacrodataResponse", - longbridge::fundamental::MacrodataResponse, + "com/longbridge/fundamental/MacroeconomicResponse", + longbridge::fundamental::MacroeconomicResponse, [ info, #[java(objarray)] diff --git a/nodejs/index.d.ts b/nodejs/index.d.ts index 5eaac8a84..7ad449ed6 100644 --- a/nodejs/index.d.ts +++ b/nodejs/index.d.ts @@ -619,9 +619,9 @@ export declare class FundamentalContext { */ etfAssetAllocation(symbol: string): Promise /** List macroeconomic indicators */ - macrodataIndicators(country?: MacrodataCountry | undefined | null, offset?: number | undefined | null, limit?: number | undefined | null): Promise + macroeconomicIndicators(country?: MacroeconomicCountry | undefined | null, offset?: number | undefined | null, limit?: number | undefined | null): Promise /** Get historical data for a macroeconomic indicator */ - macrodata(indicatorCode: string, startDate?: string | undefined | null, endDate?: string | undefined | null, offset?: number | undefined | null, limit?: number | undefined | null): Promise + macroeconomic(indicatorCode: string, startDate?: string | undefined | null, endDate?: string | undefined | null, offset?: number | undefined | null, limit?: number | undefined | null): Promise } /** Fund position */ @@ -4493,7 +4493,7 @@ export interface Macrodata { } /** Country code for filtering macroeconomic indicators */ -export declare const enum MacrodataCountry { +export declare const enum MacroeconomicCountry { /** Hong Kong SAR China */ HongKong = 0, /** China (Mainland) */ @@ -4509,7 +4509,7 @@ export declare const enum MacrodataCountry { } /** Metadata for one macroeconomic indicator */ -export interface MacrodataIndicator { +export interface MacroeconomicIndicator { indicatorCode: string sourceOrg: string country: string @@ -4523,15 +4523,15 @@ export interface MacrodataIndicator { startDate?: number } -/** Response for macrodata_indicators */ -export interface MacrodataIndicatorListResponse { - data: Array +/** Response for macroeconomic_indicators */ +export interface MacroeconomicIndicatorListResponse { + data: Array count: number } -/** Response for macrodata */ -export interface MacrodataResponse { - info: MacrodataIndicator +/** Response for macroeconomic */ +export interface MacroeconomicResponse { + info: MacroeconomicIndicator data: Array count: number } diff --git a/nodejs/src/fundamental/context.rs b/nodejs/src/fundamental/context.rs index 323d2a38e..3fdc33587 100644 --- a/nodejs/src/fundamental/context.rs +++ b/nodejs/src/fundamental/context.rs @@ -290,15 +290,15 @@ impl FundamentalContext { /// List macroeconomic indicators #[napi] - pub async fn macrodata_indicators( + pub async fn macroeconomic_indicators( &self, - country: Option, + country: Option, offset: Option, limit: Option, - ) -> Result { + ) -> Result { Ok(self .ctx - .macrodata_indicators(country.map(Into::into), offset, limit) + .macroeconomic_indicators(country.map(Into::into), offset, limit) .await .map_err(ErrorNewType)? .into()) @@ -306,17 +306,17 @@ impl FundamentalContext { /// Get historical data for a macroeconomic indicator #[napi] - pub async fn macrodata( + pub async fn macroeconomic( &self, indicator_code: String, start_date: Option, end_date: Option, offset: Option, limit: Option, - ) -> Result { + ) -> Result { Ok(self .ctx - .macrodata(indicator_code, start_date, end_date, offset, limit) + .macroeconomic(indicator_code, start_date, end_date, offset, limit) .await .map_err(ErrorNewType)? .into()) diff --git a/nodejs/src/fundamental/types.rs b/nodejs/src/fundamental/types.rs index 193387422..e062ddc40 100644 --- a/nodejs/src/fundamental/types.rs +++ b/nodejs/src/fundamental/types.rs @@ -1927,7 +1927,7 @@ impl From for MultiLanguageText { /// Country code for filtering macroeconomic indicators #[napi_derive::napi] #[derive(Debug, Copy, Clone)] -pub enum MacrodataCountry { +pub enum MacroeconomicCountry { /// Hong Kong SAR China HongKong, /// China (Mainland) @@ -1942,29 +1942,29 @@ pub enum MacrodataCountry { Singapore, } -impl From for lb::MacrodataCountry { - fn from(v: MacrodataCountry) -> Self { +impl From for lb::MacroeconomicCountry { + fn from(v: MacroeconomicCountry) -> Self { match v { - MacrodataCountry::HongKong => lb::MacrodataCountry::HongKong, - MacrodataCountry::China => lb::MacrodataCountry::China, - MacrodataCountry::UnitedStates => lb::MacrodataCountry::UnitedStates, - MacrodataCountry::EuroZone => lb::MacrodataCountry::EuroZone, - MacrodataCountry::Japan => lb::MacrodataCountry::Japan, - MacrodataCountry::Singapore => lb::MacrodataCountry::Singapore, + MacroeconomicCountry::HongKong => lb::MacroeconomicCountry::HongKong, + MacroeconomicCountry::China => lb::MacroeconomicCountry::China, + MacroeconomicCountry::UnitedStates => lb::MacroeconomicCountry::UnitedStates, + MacroeconomicCountry::EuroZone => lb::MacroeconomicCountry::EuroZone, + MacroeconomicCountry::Japan => lb::MacroeconomicCountry::Japan, + MacroeconomicCountry::Singapore => lb::MacroeconomicCountry::Singapore, } } } -/// Response for macrodata_indicators +/// Response for macroeconomic_indicators #[napi_derive::napi(object)] #[derive(Debug, Clone)] -pub struct MacrodataIndicatorListResponse { - pub data: Vec, +pub struct MacroeconomicIndicatorListResponse { + pub data: Vec, pub count: i32, } -impl From for MacrodataIndicatorListResponse { - fn from(v: lb::MacrodataIndicatorListResponse) -> Self { +impl From for MacroeconomicIndicatorListResponse { + fn from(v: lb::MacroeconomicIndicatorListResponse) -> Self { Self { data: v.data.into_iter().map(Into::into).collect(), count: v.count, @@ -1975,7 +1975,7 @@ impl From for MacrodataIndicatorListResponse /// Metadata for one macroeconomic indicator #[napi_derive::napi(object)] #[derive(Debug, Clone)] -pub struct MacrodataIndicator { +pub struct MacroeconomicIndicator { pub indicator_code: String, pub source_org: String, pub country: String, @@ -1989,8 +1989,8 @@ pub struct MacrodataIndicator { pub start_date: Option, } -impl From for MacrodataIndicator { - fn from(v: lb::MacrodataIndicator) -> Self { +impl From for MacroeconomicIndicator { + fn from(v: lb::MacroeconomicIndicator) -> Self { Self { indicator_code: v.indicator_code, source_org: v.source_org, @@ -2039,17 +2039,17 @@ impl From for Macrodata { } } -/// Response for macrodata +/// Response for macroeconomic #[napi_derive::napi(object)] #[derive(Debug, Clone)] -pub struct MacrodataResponse { - pub info: MacrodataIndicator, +pub struct MacroeconomicResponse { + pub info: MacroeconomicIndicator, pub data: Vec, pub count: i32, } -impl From for MacrodataResponse { - fn from(v: lb::MacrodataResponse) -> Self { +impl From for MacroeconomicResponse { + fn from(v: lb::MacroeconomicResponse) -> Self { Self { info: v.info.into(), data: v.data.into_iter().map(Into::into).collect(), diff --git a/python/pysrc/longbridge/openapi.pyi b/python/pysrc/longbridge/openapi.pyi index ec4d6a064..0053b5927 100644 --- a/python/pysrc/longbridge/openapi.pyi +++ b/python/pysrc/longbridge/openapi.pyi @@ -9922,11 +9922,11 @@ class FundamentalContext: """ ... - def macrodata_indicators( + def macroeconomic_indicators( self, offset: int | None = None, limit: int | None = None, - ) -> list["MacrodataIndicator"]: + ) -> list["MacroeconomicIndicator"]: """ List macroeconomic indicators. @@ -9935,28 +9935,28 @@ class FundamentalContext: limit: Page size (default 100, max 1000) Returns: - List of :class:`MacrodataIndicator` + List of :class:`MacroeconomicIndicator` """ ... - def macrodata( + def macroeconomic( self, indicator_code: str, start_date: str | None = None, end_date: str | None = None, limit: int | None = None, - ) -> "MacrodataResponse": + ) -> "MacroeconomicResponse": """ Get historical data for a macroeconomic indicator. Args: - indicator_code: External vendor code from ``macrodata_indicators`` + indicator_code: External vendor code from ``macroeconomic_indicators`` start_date: Start date in ``"YYYY-MM-DD"`` format (optional) end_date: End date in ``"YYYY-MM-DD"`` format (optional) limit: Max records to return (default 100, max 100) Returns: - :class:`MacrodataResponse` + :class:`MacroeconomicResponse` """ ... @@ -10111,11 +10111,11 @@ class MultiLanguageText: traditional_chinese: str -class MacrodataIndicator: +class MacroeconomicIndicator: """Metadata for one macroeconomic indicator.""" indicator_code: str - """External vendor code (input to macrodata)""" + """External vendor code (input to macroeconomic)""" source_org: str country: str name: MultiLanguageText @@ -10144,10 +10144,10 @@ class Macrodata: unit_prefix: MultiLanguageText -class MacrodataResponse: - """Response for macrodata.""" +class MacroeconomicResponse: + """Response for macroeconomic.""" - info: MacrodataIndicator + info: MacroeconomicIndicator data: list[Macrodata] diff --git a/python/src/fundamental/context.rs b/python/src/fundamental/context.rs index ab4709b0d..5d4dd8639 100644 --- a/python/src/fundamental/context.rs +++ b/python/src/fundamental/context.rs @@ -210,31 +210,31 @@ impl FundamentalContext { } /// List macroeconomic indicators. - fn macrodata_indicators( + fn macroeconomic_indicators( &self, - country: Option, + country: Option, offset: Option, limit: Option, - ) -> PyResult { + ) -> PyResult { Ok(self .ctx - .macrodata_indicators(country.map(Into::into), offset, limit) + .macroeconomic_indicators(country.map(Into::into), offset, limit) .map_err(ErrorNewType)? .into()) } /// Get historical data for a macroeconomic indicator. - fn macrodata( + fn macroeconomic( &self, indicator_code: String, start_date: Option, end_date: Option, offset: Option, limit: Option, - ) -> PyResult { + ) -> PyResult { Ok(self .ctx - .macrodata(indicator_code, start_date, end_date, offset, limit) + .macroeconomic(indicator_code, start_date, end_date, offset, limit) .map_err(ErrorNewType)? .into()) } diff --git a/python/src/fundamental/context_async.rs b/python/src/fundamental/context_async.rs index be1ad7c64..1fe4f9d5c 100644 --- a/python/src/fundamental/context_async.rs +++ b/python/src/fundamental/context_async.rs @@ -319,17 +319,17 @@ impl AsyncFundamentalContext { } /// List macroeconomic indicators. Returns awaitable. - fn macrodata_indicators( + fn macroeconomic_indicators( &self, py: Python<'_>, - country: Option, + country: Option, offset: Option, limit: Option, ) -> PyResult> { let ctx = self.ctx.clone(); pyo3_async_runtimes::tokio::future_into_py(py, async move { - Ok(MacrodataIndicatorListResponse::from( - ctx.macrodata_indicators(country.map(Into::into), offset, limit) + Ok(MacroeconomicIndicatorListResponse::from( + ctx.macroeconomic_indicators(country.map(Into::into), offset, limit) .await .map_err(ErrorNewType)?, )) @@ -338,7 +338,7 @@ impl AsyncFundamentalContext { } /// Get historical data for a macroeconomic indicator. Returns awaitable. - fn macrodata( + fn macroeconomic( &self, py: Python<'_>, indicator_code: String, @@ -349,8 +349,8 @@ impl AsyncFundamentalContext { ) -> PyResult> { let ctx = self.ctx.clone(); pyo3_async_runtimes::tokio::future_into_py(py, async move { - Ok(MacrodataResponse::from( - ctx.macrodata(indicator_code, start_date, end_date, offset, limit) + Ok(MacroeconomicResponse::from( + ctx.macroeconomic(indicator_code, start_date, end_date, offset, limit) .await .map_err(ErrorNewType)?, )) diff --git a/python/src/fundamental/mod.rs b/python/src/fundamental/mod.rs index 474d41eaf..fb120360d 100644 --- a/python/src/fundamental/mod.rs +++ b/python/src/fundamental/mod.rs @@ -75,11 +75,11 @@ pub(crate) fn register_types(parent: &Bound) -> PyResult<()> { parent.add_class::()?; parent.add_class::()?; parent.add_class::()?; - parent.add_class::()?; - parent.add_class::()?; - parent.add_class::()?; + parent.add_class::()?; + parent.add_class::()?; + parent.add_class::()?; parent.add_class::()?; - parent.add_class::()?; + parent.add_class::()?; parent.add_class::()?; parent.add_class::()?; Ok(()) diff --git a/python/src/fundamental/types.rs b/python/src/fundamental/types.rs index ce36b4faa..d6eb99209 100644 --- a/python/src/fundamental/types.rs +++ b/python/src/fundamental/types.rs @@ -1990,7 +1990,7 @@ impl From for MultiLanguageText { /// Country code for filtering macroeconomic indicators #[pyclass] #[derive(Debug, Copy, Clone)] -pub(crate) enum MacrodataCountry { +pub(crate) enum MacroeconomicCountry { HongKong, China, UnitedStates, @@ -1999,29 +1999,29 @@ pub(crate) enum MacrodataCountry { Singapore, } -impl From for lb::MacrodataCountry { - fn from(v: MacrodataCountry) -> Self { +impl From for lb::MacroeconomicCountry { + fn from(v: MacroeconomicCountry) -> Self { match v { - MacrodataCountry::HongKong => lb::MacrodataCountry::HongKong, - MacrodataCountry::China => lb::MacrodataCountry::China, - MacrodataCountry::UnitedStates => lb::MacrodataCountry::UnitedStates, - MacrodataCountry::EuroZone => lb::MacrodataCountry::EuroZone, - MacrodataCountry::Japan => lb::MacrodataCountry::Japan, - MacrodataCountry::Singapore => lb::MacrodataCountry::Singapore, + MacroeconomicCountry::HongKong => lb::MacroeconomicCountry::HongKong, + MacroeconomicCountry::China => lb::MacroeconomicCountry::China, + MacroeconomicCountry::UnitedStates => lb::MacroeconomicCountry::UnitedStates, + MacroeconomicCountry::EuroZone => lb::MacroeconomicCountry::EuroZone, + MacroeconomicCountry::Japan => lb::MacroeconomicCountry::Japan, + MacroeconomicCountry::Singapore => lb::MacroeconomicCountry::Singapore, } } } -/// Response for macrodata_indicators +/// Response for macroeconomic_indicators #[pyclass(get_all, skip_from_py_object)] #[derive(Debug, Clone)] -pub(crate) struct MacrodataIndicatorListResponse { - pub data: Vec, +pub(crate) struct MacroeconomicIndicatorListResponse { + pub data: Vec, pub count: i32, } -impl From for MacrodataIndicatorListResponse { - fn from(v: lb::MacrodataIndicatorListResponse) -> Self { +impl From for MacroeconomicIndicatorListResponse { + fn from(v: lb::MacroeconomicIndicatorListResponse) -> Self { Self { data: v.data.into_iter().map(Into::into).collect(), count: v.count, @@ -2032,7 +2032,7 @@ impl From for MacrodataIndicatorListResponse /// Metadata for one macroeconomic indicator #[pyclass(get_all, skip_from_py_object)] #[derive(Debug, Clone)] -pub(crate) struct MacrodataIndicator { +pub(crate) struct MacroeconomicIndicator { pub indicator_code: String, pub source_org: String, pub country: String, @@ -2045,8 +2045,8 @@ pub(crate) struct MacrodataIndicator { pub start_date: Option, } -impl From for MacrodataIndicator { - fn from(v: lb::MacrodataIndicator) -> Self { +impl From for MacroeconomicIndicator { + fn from(v: lb::MacroeconomicIndicator) -> Self { Self { indicator_code: v.indicator_code, source_org: v.source_org, @@ -2093,17 +2093,17 @@ impl From for Macrodata { } } -/// Response for macrodata +/// Response for macroeconomic #[pyclass(get_all, skip_from_py_object)] #[derive(Debug, Clone)] -pub(crate) struct MacrodataResponse { - pub info: MacrodataIndicator, +pub(crate) struct MacroeconomicResponse { + pub info: MacroeconomicIndicator, pub data: Vec, pub count: i32, } -impl From for MacrodataResponse { - fn from(v: lb::MacrodataResponse) -> Self { +impl From for MacroeconomicResponse { + fn from(v: lb::MacroeconomicResponse) -> Self { Self { info: v.info.into(), data: v.data.into_iter().map(Into::into).collect(), diff --git a/rust/src/fundamental/context.rs b/rust/src/fundamental/context.rs index 10f4af551..be0212c9c 100644 --- a/rust/src/fundamental/context.rs +++ b/rust/src/fundamental/context.rs @@ -830,20 +830,20 @@ impl FundamentalContext { .await } - // ── macrodata ──────────────────────────────────────────────── + // ── macroeconomic ──────────────────────────────────────────────── /// List macroeconomic indicators. /// /// Pass `country` to filter by country code (e.g. - /// `MacrodataCountry::UnitedStates`). + /// `MacroeconomicCountry::UnitedStates`). /// /// Path: `GET /v1/quote/macrodata` - pub async fn macrodata_indicators( + pub async fn macroeconomic_indicators( &self, - country: Option, + country: Option, offset: Option, limit: Option, - ) -> Result { + ) -> Result { #[derive(Serialize)] struct Query { #[serde(skip_serializing_if = "Option::is_none")] @@ -855,12 +855,12 @@ impl FundamentalContext { } let country_str = country.map(|c| { match c { - MacrodataCountry::HongKong => "Hong Kong SAR China", - MacrodataCountry::China => "China (Mainland)", - MacrodataCountry::UnitedStates => "United States", - MacrodataCountry::EuroZone => "Euro Zone", - MacrodataCountry::Japan => "Japan", - MacrodataCountry::Singapore => "Singapore", + MacroeconomicCountry::HongKong => "Hong Kong SAR China", + MacroeconomicCountry::China => "China (Mainland)", + MacroeconomicCountry::UnitedStates => "United States", + MacroeconomicCountry::EuroZone => "Euro Zone", + MacroeconomicCountry::Japan => "Japan", + MacroeconomicCountry::Singapore => "Singapore", } .to_string() }); @@ -882,14 +882,14 @@ impl FundamentalContext { /// `YYYY-MM-DDT23:59:59Z`. /// /// Path: `GET /v1/quote/macrodata/{indicator_code}` - pub async fn macrodata( + pub async fn macroeconomic( &self, indicator_code: impl Into, start_date: Option>, end_date: Option>, offset: Option, limit: Option, - ) -> Result { + ) -> Result { #[derive(Serialize)] struct Query { #[serde(skip_serializing_if = "Option::is_none")] @@ -912,7 +912,7 @@ impl FundamentalContext { offset, limit, }) - .response::>() + .response::>() .send() .with_subscriber(self.0.log_subscriber.clone()) .await? diff --git a/rust/src/fundamental/types.rs b/rust/src/fundamental/types.rs index 7ba2f3547..87c88c5e7 100644 --- a/rust/src/fundamental/types.rs +++ b/rust/src/fundamental/types.rs @@ -1563,11 +1563,11 @@ pub struct AssetAllocationResponse { pub info: Vec, } -// ── macrodata ───────────────────────────────────────────────────── +// ── macroeconomic ───────────────────────────────────────────────────── /// Country for filtering macroeconomic indicators #[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize)] -pub enum MacrodataCountry { +pub enum MacroeconomicCountry { /// Hong Kong SAR China #[serde(rename = "Hong Kong SAR China")] HongKong, @@ -1590,7 +1590,7 @@ pub enum MacrodataCountry { /// Importance level of a macroeconomic indicator #[derive(Debug, Copy, Clone, Eq, PartialEq)] -pub enum MacrodataImportance { +pub enum MacroeconomicImportance { /// Low importance Low = 1, /// Medium importance @@ -1599,7 +1599,7 @@ pub enum MacrodataImportance { High = 3, } -impl MacrodataImportance { +impl MacroeconomicImportance { /// Convert from raw API integer value pub fn from_i32(v: i32) -> Option { match v { @@ -1627,8 +1627,8 @@ pub struct MultiLanguageText { /// Metadata for one macroeconomic indicator #[derive(Debug, Clone, Default, Serialize, Deserialize)] -pub struct MacrodataIndicator { - /// External vendor code (used as input to `macrodata`) +pub struct MacroeconomicIndicator { + /// External vendor code (used as input to `macroeconomic`) pub indicator_code: String, /// Publishing organisation #[serde(default)] @@ -1663,12 +1663,12 @@ pub struct MacrodataIndicator { pub start_date: Option, } -/// Response for [`crate::FundamentalContext::macrodata_indicators`] +/// Response for [`crate::FundamentalContext::macroeconomic_indicators`] #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct MacrodataIndicatorListResponse { +pub struct MacroeconomicIndicatorListResponse { /// Indicator list #[serde(default, rename = "list")] - pub data: Vec, + pub data: Vec, /// Total number of indicators matching the query #[serde(default)] pub count: i32, @@ -1706,12 +1706,12 @@ pub struct Macrodata { pub unit_prefix: MultiLanguageText, } -/// Response for [`crate::FundamentalContext::macrodata`] +/// Response for [`crate::FundamentalContext::macroeconomic`] #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct MacrodataResponse { +pub struct MacroeconomicResponse { /// Indicator metadata #[serde(default, deserialize_with = "crate::serde_utils::null_as_default")] - pub info: MacrodataIndicator, + pub info: MacroeconomicIndicator, /// Historical data points #[serde(default)] pub data: Vec, From b7b366452855756a2dc3343f45ac41677c7b3a58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Thu, 11 Jun 2026 10:05:49 +0800 Subject: [PATCH 25/28] refactor: rename Macrodata (data point type) to Macroeconomic Co-Authored-By: Claude Sonnet 4.6 (1M context) --- java/src/types/classes.rs | 4 ++-- nodejs/src/fundamental/types.rs | 8 ++++---- python/src/fundamental/mod.rs | 2 +- python/src/fundamental/types.rs | 8 ++++---- rust/src/fundamental/types.rs | 4 ++-- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/java/src/types/classes.rs b/java/src/types/classes.rs index 03f9e53e4..285f3611c 100644 --- a/java/src/types/classes.rs +++ b/java/src/types/classes.rs @@ -2722,8 +2722,8 @@ impl_java_class!( ); impl_java_class!( - "com/longbridge/fundamental/Macrodata", - longbridge::fundamental::Macrodata, + "com/longbridge/fundamental/Macroeconomic", + longbridge::fundamental::Macroeconomic, [ period, release_at, diff --git a/nodejs/src/fundamental/types.rs b/nodejs/src/fundamental/types.rs index e062ddc40..e66916ff5 100644 --- a/nodejs/src/fundamental/types.rs +++ b/nodejs/src/fundamental/types.rs @@ -2009,7 +2009,7 @@ impl From for MacroeconomicIndicator { /// One historical data point for a macroeconomic indicator #[napi_derive::napi(object)] #[derive(Debug, Clone)] -pub struct Macrodata { +pub struct Macroeconomic { pub period: String, /// Release datetime (unix timestamp in seconds; null if unset) pub release_at: Option, @@ -2023,8 +2023,8 @@ pub struct Macrodata { pub unit_prefix: MultiLanguageText, } -impl From for Macrodata { - fn from(v: lb::Macrodata) -> Self { +impl From for Macroeconomic { + fn from(v: lb::Macroeconomic) -> Self { Self { period: v.period, release_at: v.release_at.map(|dt| dt.unix_timestamp()), @@ -2044,7 +2044,7 @@ impl From for Macrodata { #[derive(Debug, Clone)] pub struct MacroeconomicResponse { pub info: MacroeconomicIndicator, - pub data: Vec, + pub data: Vec, pub count: i32, } diff --git a/python/src/fundamental/mod.rs b/python/src/fundamental/mod.rs index fb120360d..810101751 100644 --- a/python/src/fundamental/mod.rs +++ b/python/src/fundamental/mod.rs @@ -78,7 +78,7 @@ pub(crate) fn register_types(parent: &Bound) -> PyResult<()> { parent.add_class::()?; parent.add_class::()?; parent.add_class::()?; - parent.add_class::()?; + parent.add_class::()?; parent.add_class::()?; parent.add_class::()?; parent.add_class::()?; diff --git a/python/src/fundamental/types.rs b/python/src/fundamental/types.rs index d6eb99209..c541cb7c9 100644 --- a/python/src/fundamental/types.rs +++ b/python/src/fundamental/types.rs @@ -2065,7 +2065,7 @@ impl From for MacroeconomicIndicator { /// One historical data point for a macroeconomic indicator #[pyclass(get_all, skip_from_py_object)] #[derive(Debug, Clone)] -pub(crate) struct Macrodata { +pub(crate) struct Macroeconomic { pub period: String, pub release_at: Option, pub actual_value: String, @@ -2077,8 +2077,8 @@ pub(crate) struct Macrodata { pub unit_prefix: MultiLanguageText, } -impl From for Macrodata { - fn from(v: lb::Macrodata) -> Self { +impl From for Macroeconomic { + fn from(v: lb::Macroeconomic) -> Self { Self { period: v.period, release_at: v.release_at.map(crate::time::PyOffsetDateTimeWrapper), @@ -2098,7 +2098,7 @@ impl From for Macrodata { #[derive(Debug, Clone)] pub(crate) struct MacroeconomicResponse { pub info: MacroeconomicIndicator, - pub data: Vec, + pub data: Vec, pub count: i32, } diff --git a/rust/src/fundamental/types.rs b/rust/src/fundamental/types.rs index 87c88c5e7..9bee91e22 100644 --- a/rust/src/fundamental/types.rs +++ b/rust/src/fundamental/types.rs @@ -1676,7 +1676,7 @@ pub struct MacroeconomicIndicatorListResponse { /// One historical data point for a macroeconomic indicator #[derive(Debug, Clone, Default, Serialize, Deserialize)] -pub struct Macrodata { +pub struct Macroeconomic { /// Statistical period (e.g. `2024-Q1`, `2024-03`) #[serde(default)] pub period: String, @@ -1714,7 +1714,7 @@ pub struct MacroeconomicResponse { pub info: MacroeconomicIndicator, /// Historical data points #[serde(default)] - pub data: Vec, + pub data: Vec, /// Total number of historical data points #[serde(default)] pub count: i32, From 537bc839c20592016f2b5468f4be78c75af4c30d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Thu, 11 Jun 2026 10:09:56 +0800 Subject: [PATCH 26/28] refactor: rename all remaining macrodata -> macroeconomic Co-Authored-By: Claude Sonnet 4.6 (1M context) --- nodejs/index.d.ts | 4 ++-- python/pysrc/longbridge/openapi.pyi | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/nodejs/index.d.ts b/nodejs/index.d.ts index 7ad449ed6..56b157e18 100644 --- a/nodejs/index.d.ts +++ b/nodejs/index.d.ts @@ -4478,7 +4478,7 @@ export declare const enum Language { } /** One historical data point for a macroeconomic indicator */ -export interface Macrodata { +export interface Macroeconomic { period: string /** Release datetime (unix timestamp in seconds; null if unset) */ releaseAt?: number @@ -4532,7 +4532,7 @@ export interface MacroeconomicIndicatorListResponse { /** Response for macroeconomic */ export interface MacroeconomicResponse { info: MacroeconomicIndicator - data: Array + data: Array count: number } diff --git a/python/pysrc/longbridge/openapi.pyi b/python/pysrc/longbridge/openapi.pyi index 0053b5927..8186b1c8f 100644 --- a/python/pysrc/longbridge/openapi.pyi +++ b/python/pysrc/longbridge/openapi.pyi @@ -10129,7 +10129,7 @@ class MacroeconomicIndicator: """Start date of data coverage""" -class Macrodata: +class Macroeconomic: """One historical data point for a macroeconomic indicator.""" period: str @@ -10148,7 +10148,7 @@ class MacroeconomicResponse: """Response for macroeconomic.""" info: MacroeconomicIndicator - data: list[Macrodata] + data: list[Macroeconomic] # ── MarketContext ───────────────────────────────────────────────── From 226eec240949fd9d796d5d71ea0d9c23240282c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Thu, 11 Jun 2026 10:13:59 +0800 Subject: [PATCH 27/28] style: apply cargo fmt --- rust/src/blocking/fundamental.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/rust/src/blocking/fundamental.rs b/rust/src/blocking/fundamental.rs index 4e303a7c6..d580a0484 100644 --- a/rust/src/blocking/fundamental.rs +++ b/rust/src/blocking/fundamental.rs @@ -292,27 +292,28 @@ impl FundamentalContextSync { } /// List macroeconomic indicators - pub fn macrodata_indicators( + pub fn macroeconomic_indicators( &self, - country: Option, + country: Option, offset: Option, limit: Option, - ) -> Result { - self.rt - .call(move |ctx| async move { ctx.macrodata_indicators(country, offset, limit).await }) + ) -> Result { + self.rt.call(move |ctx| async move { + ctx.macroeconomic_indicators(country, offset, limit).await + }) } /// Get historical data for a macroeconomic indicator - pub fn macrodata( + pub fn macroeconomic( &self, indicator_code: impl Into + Send + 'static, start_date: Option + Send + 'static>, end_date: Option + Send + 'static>, offset: Option, limit: Option, - ) -> Result { + ) -> Result { self.rt.call(move |ctx| async move { - ctx.macrodata(indicator_code, start_date, end_date, offset, limit) + ctx.macroeconomic(indicator_code, start_date, end_date, offset, limit) .await }) } From 82b417e6b64875776bc0898f4befd0cf96307e67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E7=AB=A0=E6=B4=AA?= Date: Thu, 11 Jun 2026 10:15:30 +0800 Subject: [PATCH 28/28] docs: update CHANGELOG for macroeconomic API with correct naming --- CHANGELOG.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a196aac63..a1329525e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,13 +8,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- **All languages:** `FundamentalContext` gains `macrodata_indicators(offset, limit)` — list all macroeconomic indicators via `GET /v1/quote/macrodata` -- **All languages:** `FundamentalContext` gains `macrodata(indicator_code, start_date, end_date, limit)` — historical data for a specific indicator via `GET /v1/quote/macrodata/{indicator_code}`; `start_date` / `end_date` accept `"YYYY-MM-DD"` strings -- New types: `MultiLanguageText`, `MacrodataIndicator`, `Macrodata`, `MacrodataResponse` +- **All languages:** `FundamentalContext` gains `macroeconomic_indicators(country, offset, limit)` — list macroeconomic indicators via `GET /v1/quote/macrodata`; filter by country (`MacroeconomicCountry::HongKong / China / UnitedStates / EuroZone / Japan / Singapore`); response includes `count` (total matching) +- **All languages:** `FundamentalContext` gains `macroeconomic(indicator_code, start_date, end_date, offset, limit)` — historical data for a specific indicator via `GET /v1/quote/macrodata/{indicator_code}`; `start_date` / `end_date` accept `"YYYY-MM-DD"` strings; response includes `count` (total data points) +- New types: `MultiLanguageText`, `MacroeconomicCountry`, `MacroeconomicImportance`, `MacroeconomicIndicator`, `MacroeconomicIndicatorListResponse`, `Macroeconomic`, `MacroeconomicResponse` ### Fixed -- `MacrodataIndicator.describe`: handle `null` response from API without deserializing error +- `MacroeconomicIndicator.describe` / `name` / `MacroeconomicResponse.info`: handle `null` responses from API without deserializing error ## [4.3.0]