Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ 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).

## [Unreleased]

### Added

- **All languages:** `QuoteContext` gains `etf_asset_allocation(symbol)` — queries `GET /v1/quote/etf-asset-allocation` for ETF asset allocation grouped by element type (`Holdings` / `Regional` / `AssetClass` / `Industry`); returns `AssetAllocationResponse` with report date, position ratios, localized names, and per-holding detail

## [4.2.2]

### Fixed
Expand Down
9 changes: 9 additions & 0 deletions c/cbindgen.toml
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,12 @@ cpp_compat = true
"COptionVolumeStats" = "lb_option_volume_stats_t"
"COptionVolumeDailyStat" = "lb_option_volume_daily_stat_t"
"COptionVolumeDaily" = "lb_option_volume_daily_t"
"CElementType" = "lb_element_type_t"
"CLocaleName" = "lb_locale_name_t"
"CHoldingDetail" = "lb_holding_detail_t"
"CAssetAllocationItem" = "lb_asset_allocation_item_t"
"CAssetAllocationGroup" = "lb_asset_allocation_group_t"
"CAssetAllocationResponse" = "lb_asset_allocation_response_t"
# FundamentalContext new types
"CShareholderTopResponse" = "lb_shareholder_top_response_t"
"CShareholderDetailResponse" = "lb_shareholder_detail_response_t"
Expand Down Expand Up @@ -441,6 +447,9 @@ include = [
"CShortTradesItem", "CShortTradesResponse",
"COptionVolumeStats",
"COptionVolumeDailyStat", "COptionVolumeDaily",
"CElementType",
"CLocaleName", "CHoldingDetail",
"CAssetAllocationItem", "CAssetAllocationGroup", "CAssetAllocationResponse",
# FundamentalContext new types
"CShareholderTopResponse", "CShareholderDetailResponse",
"CValuationHistoryPoint", "CValuationComparisonItem", "CValuationComparisonResponse",
Expand Down
152 changes: 151 additions & 1 deletion c/csrc/include/longbridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -1594,6 +1594,32 @@ typedef enum lb_asset_type_t {
AssetTypeCrypto,
} lb_asset_type_t;

/**
* ETF asset allocation element type
*/
typedef enum lb_element_type_t {
/**
* Unknown
*/
ElementTypeUnknown,
/**
* Holdings
*/
ElementTypeHoldings,
/**
* Regional
*/
ElementTypeRegional,
/**
* Asset class
*/
ElementTypeAssetClass,
/**
* Industry
*/
ElementTypeIndustry,
} lb_element_type_t;

typedef struct lb_alert_context_t lb_alert_context_t;

/**
Expand Down Expand Up @@ -7111,7 +7137,8 @@ typedef struct lb_calendar_events_response_t {
*/
uintptr_t num_list;
/**
* Pagination cursor; pass as start to fetch the next page, empty when there are no more pages.
* Pagination cursor; pass as start to fetch the next page, empty when
* there are no more pages.
*/
const char *next_date;
} lb_calendar_events_response_t;
Expand Down Expand Up @@ -8318,6 +8345,120 @@ typedef struct lb_option_volume_daily_t {
uintptr_t num_stats;
} lb_option_volume_daily_t;

/**
* Localized name entry (locale → name)
*/
typedef struct lb_locale_name_t {
/**
* Locale (e.g. `zh-CN`)
*/
const char *locale;
/**
* Localized name
*/
const char *name;
} lb_locale_name_t;

/**
* Holding detail of an ETF asset allocation element (holdings only)
*/
typedef struct lb_holding_detail_t {
/**
* Industry ID
*/
const char *industry_id;
/**
* Industry name
*/
const char *industry_name;
/**
* Index counter ID (e.g. `BK/US/CP99000`)
*/
const char *index;
/**
* Index name
*/
const char *index_name;
/**
* Holding type (e.g. `E` for stock)
*/
const char *holding_type;
/**
* Holding type name
*/
const char *holding_type_name;
} lb_holding_detail_t;

/**
* One element of an ETF asset allocation group
*/
typedef struct lb_asset_allocation_item_t {
/**
* Element name
*/
const char *name;
/**
* Security code (holdings only, e.g. `NVDA`)
*/
const char *code;
/**
* Position ratio (e.g. `0.0861114`)
*/
const char *position_ratio;
/**
* Security symbol (holdings only, e.g. `NVDA.US`)
*/
const char *symbol;
/**
* Pointer to array of localized name entries
*/
const struct lb_locale_name_t *name_locales;
/**
* Number of elements in the localized name array
*/
uintptr_t num_name_locales;
/**
* Holding detail (holdings only, maybe null)
*/
const struct lb_holding_detail_t *holding_detail;
} lb_asset_allocation_item_t;

/**
* One ETF asset allocation group (grouped by element type)
*/
typedef struct lb_asset_allocation_group_t {
/**
* Report date (e.g. `20260601`)
*/
const char *report_date;
/**
* Element type of this group
*/
enum lb_element_type_t asset_type;
/**
* Pointer to array of elements
*/
const struct lb_asset_allocation_item_t *lists;
/**
* Number of elements in the array
*/
uintptr_t num_lists;
} lb_asset_allocation_group_t;

/**
* ETF asset allocation response
*/
typedef struct lb_asset_allocation_response_t {
/**
* Pointer to array of asset allocation groups
*/
const struct lb_asset_allocation_group_t *info;
/**
* Number of elements in the array
*/
uintptr_t num_info;
} lb_asset_allocation_response_t;

/**
* Top-shareholder list response. `data` is a NUL-terminated JSON string.
*/
Expand Down Expand Up @@ -10186,6 +10327,15 @@ void lb_quote_context_option_volume_daily(const struct lb_quote_context_t *ctx,
lb_async_callback_t callback,
void *userdata);

/**
* Get ETF asset allocation (holdings / regional / asset class / industry).
* Returns `CAssetAllocationResponse`.
*/
void lb_quote_context_etf_asset_allocation(const struct lb_quote_context_t *ctx,
const char *symbol,
lb_async_callback_t callback,
void *userdata);

const struct lb_screener_context_t *lb_screener_context_new(const struct lb_config_t *config);

void lb_screener_context_retain(const struct lb_screener_context_t *ctx);
Expand Down
20 changes: 20 additions & 0 deletions c/src/quote_context/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1290,3 +1290,23 @@ pub unsafe extern "C" fn lb_quote_context_option_volume_daily(
Ok(resp)
});
}

/// Get ETF asset allocation (holdings / regional / asset class / industry).
/// Returns `CAssetAllocationResponse`.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn lb_quote_context_etf_asset_allocation(
ctx: *const CQuoteContext,
symbol: *const c_char,
callback: CAsyncCallback,
userdata: *mut c_void,
) {
use crate::{quote_context::types::CAssetAllocationResponseOwned, types::CCow};
let ctx_inner = (*ctx).ctx.clone();
let symbol = cstr_to_rust(symbol);
execute_async(callback, ctx, userdata, async move {
let resp: CCow<CAssetAllocationResponseOwned> = CCow::new(
CAssetAllocationResponseOwned::from(ctx_inner.etf_asset_allocation(symbol).await?),
);
Ok(resp)
});
}
23 changes: 23 additions & 0 deletions c/src/quote_context/enum_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -632,3 +632,26 @@ pub enum CGranularity {
#[c(remote = "Monthly")]
GranularityMonthly,
}

/// ETF asset allocation element type
#[derive(Debug, Copy, Clone, Eq, PartialEq, CEnum)]
#[c(remote = "longbridge::quote::ElementType")]
#[allow(clippy::enum_variant_names)]
#[repr(C)]
pub enum CElementType {
/// Unknown
#[c(remote = "Unknown")]
ElementTypeUnknown,
/// Holdings
#[c(remote = "Holdings")]
ElementTypeHoldings,
/// Regional
#[c(remote = "Regional")]
ElementTypeRegional,
/// Asset class
#[c(remote = "AssetClass")]
ElementTypeAssetClass,
/// Industry
#[c(remote = "Industry")]
ElementTypeIndustry,
}
Loading
Loading