Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
46259e3
feat(fundamental): add economic_indicator_list and economic_indicator…
hogan-yuan Jun 9, 2026
400acd0
fix: align timestamp types with other SDK methods
hogan-yuan Jun 9, 2026
6a63c8a
refactor: rename macrodata_list to macrodata_indicators
hogan-yuan Jun 9, 2026
bc84309
fix: change macrodata start_time/end_time params to OffsetDateTime (R…
hogan-yuan Jun 9, 2026
4f8c163
fix: macrodata params use YYYY-MM-DD date strings
hogan-yuan Jun 10, 2026
72fe728
refactor: rename EconomicIndicator* types to Macrodata* prefix
hogan-yuan Jun 10, 2026
c419216
refactor: simplify Macrodata type names
hogan-yuan Jun 10, 2026
4206088
fix: use rfc3339_opt for macrodata timestamps and fix list field name
hogan-yuan Jun 10, 2026
591849d
fix(ci): fix format and stale method name in Java JNI binding
hogan-yuan Jun 10, 2026
a73cbe6
chore: remove accidentally committed test file and worktree
hogan-yuan Jun 10, 2026
65a99d4
fix: handle null MultiLanguageText in MacrodataIndicator
hogan-yuan Jun 10, 2026
18076a0
fix(java): wrap Vec<MacrodataIndicator> in ObjectArray for JNI return
hogan-yuan Jun 10, 2026
3117cf0
chore: update nodejs/index.d.ts with auto-generated types from napi b…
hogan-yuan Jun 10, 2026
b52beed
refactor: rename EconomicIndicatorListResponse to MacrodataIndicatorL…
hogan-yuan Jun 10, 2026
3292649
chore: release 4.3.1
hogan-yuan Jun 10, 2026
99e1863
fix: handle null for name/unit/unit_prefix/info in Macrodata types
hogan-yuan Jun 10, 2026
e29b3c0
feat(macrodata): add country filter, count field, offset param
hogan-yuan Jun 10, 2026
103ea5b
fix: trim MacrodataCountry to 6 supported countries (HK/CN/US/EU/JP/SG)
hogan-yuan Jun 10, 2026
792e00f
fix: convert MacrodataCountry code to API full name before request
hogan-yuan Jun 10, 2026
4e3e012
fix(python): restore MacrodataIndicatorListResponse struct lost in re…
hogan-yuan Jun 10, 2026
fd091ea
fix(ci): apply cargo fmt formatting fixes
hogan-yuan Jun 10, 2026
21be43d
fix: restore MacrodataIndicatorListResponse in nodejs types; use Stri…
hogan-yuan Jun 10, 2026
0dece23
fix(ci): apply nightly cargo fmt to fix all formatting issues
hogan-yuan Jun 10, 2026
ebb624b
Merge remote-tracking branch 'origin/main' into feat/economic-indicator
hogan-yuan Jun 10, 2026
779f78c
refactor: rename macrodata -> macroeconomic in all interfaces and types
hogan-yuan Jun 11, 2026
b7b3664
refactor: rename Macrodata (data point type) to Macroeconomic
hogan-yuan Jun 11, 2026
537bc83
refactor: rename all remaining macrodata -> macroeconomic
hogan-yuan Jun 11, 2026
226eec2
style: apply cargo fmt
hogan-yuan Jun 11, 2026
82b417e
docs: update CHANGELOG for macroeconomic API with correct naming
hogan-yuan Jun 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 `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

- `MacroeconomicIndicator.describe` / `name` / `MacroeconomicResponse.info`: handle `null` responses from API without deserializing error

## [4.3.0]

### Added
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
8 changes: 8 additions & 0 deletions java/javasrc/src/main/java/com/longbridge/SdkNative.java
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,14 @@ public static native void fundamentalContextGetFinancialReportSnapshot(long cont
Object opts,
AsyncCallback callback);

public static native void fundamentalContextMacroeconomicIndicators(long context,
Object country, Object offset, Object limit,
AsyncCallback callback);

public static native void fundamentalContextMacroeconomic(long context,
Object indicatorCode, Object startTime, Object endTime, Object offset, Object limit,
AsyncCallback callback);

public static native void portfolioContextProfitAnalysisFlows(long context, Object opts,
AsyncCallback callback);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -334,4 +334,24 @@ public CompletableFuture<ValuationComparisonResponse> getValuationComparison(Val
SdkNative.fundamentalContextValuationComparison(raw, opts, callback);
});
}

/**
* List macroeconomic indicators.
* country: ISO country code string (e.g. "US", "CN", "EU"); pass null for all countries.
*/
public CompletableFuture<MacroeconomicIndicatorListResponse> getMacroeconomicIndicators(String country, Integer offset, Integer limit) throws OpenApiException {
return AsyncCallback.executeTask((callback) -> {
SdkNative.fundamentalContextMacroeconomicIndicators(raw, country, offset, limit, callback);
});
}

/**
* Get historical data for a macroeconomic indicator.
* startDate and endDate are date strings in "YYYY-MM-DD" format.
*/
public CompletableFuture<MacroeconomicResponse> getMacroeconomic(String indicatorCode, String startDate, String endDate, Integer offset, Integer limit) throws OpenApiException {
return AsyncCallback.executeTask((callback) -> {
SdkNative.fundamentalContextMacroeconomic(raw, indicatorCode, startDate, endDate, offset, limit, callback);
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.longbridge.fundamental;

/** One historical data point for a macroeconomic indicator. */
public class Macroeconomic {
/** 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;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.longbridge.fundamental;

/** Metadata for one macroeconomic indicator. */
public class MacroeconomicIndicator {
/** 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;
}
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -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;
}
66 changes: 66 additions & 0 deletions java/src/fundamental_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,3 +262,69 @@ pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextVa
Ok(())
})
}

#[unsafe(no_mangle)]
pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextMacroeconomicIndicators(
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<String> = FromJValue::from_jvalue(env, country.into())?;
let country = country.and_then(|s| {
use longbridge::fundamental::MacroeconomicCountry::*;
match s.as_str() {
"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,
}
});
let offset: Option<i32> = FromJValue::from_jvalue(env, offset.into())?;
let limit: Option<i32> = FromJValue::from_jvalue(env, limit.into())?;
async_util::execute(env, callback, async move {
Ok(context
.ctx
.macroeconomic_indicators(country, offset, limit)
.await?)
})?;
Ok(())
})
}

#[unsafe(no_mangle)]
pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextMacroeconomic(
mut env: JNIEnv,
_class: JClass,
context: i64,
indicator_code: JObject,
start_time: JObject,
end_time: JObject,
offset: 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_date: Option<String> = FromJValue::from_jvalue(env, start_time.into())?;
let end_date: Option<String> = FromJValue::from_jvalue(env, end_time.into())?;
let offset: Option<i32> = FromJValue::from_jvalue(env, offset.into())?;
let limit: Option<i32> = FromJValue::from_jvalue(env, limit.into())?;
async_util::execute(env, callback, async move {
Ok(context
.ctx
.macroeconomic(indicator_code, start_date, end_date, offset, limit)
.await?)
})?;
Ok(())
})
}
60 changes: 60 additions & 0 deletions java/src/types/classes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2698,6 +2698,66 @@ impl_java_class!(
]
);

impl_java_class!(
"com/longbridge/fundamental/MultiLanguageText",
longbridge::fundamental::MultiLanguageText,
[english, simplified_chinese, traditional_chinese]
);

impl_java_class!(
"com/longbridge/fundamental/MacroeconomicIndicator",
longbridge::fundamental::MacroeconomicIndicator,
[
indicator_code,
source_org,
country,
name,
adjustment_factor,
periodicity,
category,
describe,
importance,
start_date
]
);

impl_java_class!(
"com/longbridge/fundamental/Macroeconomic",
longbridge::fundamental::Macroeconomic,
[
period,
release_at,
actual_value,
previous_value,
forecast_value,
revised_value,
next_release_at,
unit,
unit_prefix
]
);

impl_java_class!(
"com/longbridge/fundamental/MacroeconomicIndicatorListResponse",
longbridge::fundamental::MacroeconomicIndicatorListResponse,
[
#[java(objarray)]
data,
count
]
);

impl_java_class!(
"com/longbridge/fundamental/MacroeconomicResponse",
longbridge::fundamental::MacroeconomicResponse,
[
info,
#[java(objarray)]
data,
count
]
);

// ── MarketContext: top movers / rank ──────────────────────────────

impl_java_class!(
Expand Down
70 changes: 70 additions & 0 deletions nodejs/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,10 @@ export declare class FundamentalContext {
* industry)
*/
etfAssetAllocation(symbol: string): Promise<AssetAllocationResponse>
/** List macroeconomic indicators */
macroeconomicIndicators(country?: MacroeconomicCountry | undefined | null, offset?: number | undefined | null, limit?: number | undefined | null): Promise<MacroeconomicIndicatorListResponse>
/** Get historical data for a macroeconomic indicator */
macroeconomic(indicatorCode: string, startDate?: string | undefined | null, endDate?: string | undefined | null, offset?: number | undefined | null, limit?: number | undefined | null): Promise<MacroeconomicResponse>
}

/** Fund position */
Expand Down Expand Up @@ -4473,6 +4477,65 @@ export declare const enum Language {
EN = 2
}

/** One historical data point for a macroeconomic indicator */
export interface Macroeconomic {
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
}

/** Country code for filtering macroeconomic indicators */
export declare const enum MacroeconomicCountry {
/** 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 MacroeconomicIndicator {
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 macroeconomic_indicators */
export interface MacroeconomicIndicatorListResponse {
data: Array<MacroeconomicIndicator>
count: number
}

/** Response for macroeconomic */
export interface MacroeconomicResponse {
info: MacroeconomicIndicator
data: Array<Macroeconomic>
count: number
}

export declare const enum Market {
/** Unknown */
Unknown = 0,
Expand Down Expand Up @@ -4515,6 +4578,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) */
Expand Down
1 change: 1 addition & 0 deletions nodejs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading
Loading