Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
d35f634
feat(config): add x-dc-region data-center routing from credentials
huacnlee Jun 30, 2026
4e60df8
fix(httpcli): strip us_/ap_ region prefix from OAuth bearer token
huacnlee Jun 30, 2026
b449553
fix(dc-region): don't strip region prefix from tokens; add staging WS…
hogan-yuan Jul 1, 2026
005e0c6
chore: apply cargo fmt
hogan-yuan Jul 1, 2026
7ad89e7
fix(dc-region): staging always uses openapi-global endpoints; dc rout…
hogan-yuan Jul 1, 2026
b119427
chore: remove http_url_staging/quote_ws_url_staging/trade_ws_url_stag…
hogan-yuan Jul 1, 2026
9932146
fix(oauth): update staging URL to use openapi-global.longbridge.xyz
hogan-yuan Jul 1, 2026
bc9d3ba
feat: Add per-request dc_restrict API for region-limited endpoints
huacnlee Jul 2, 2026
019de31
feat(us): add US-market APIs across Rust, Python, Node.js, Java
hogan-yuan Jul 2, 2026
344ee86
feat(us): add Python/Node.js/Java bindings for Quote and Trade US APIs
hogan-yuan Jul 2, 2026
b7fd5d7
chore(python): add US-market API type stubs to openapi.pyi
hogan-yuan Jul 2, 2026
4f6d4fe
fix(ci): remove stray .claude worktree, add to .gitignore; apply rust…
hogan-yuan Jul 2, 2026
21e67ca
fix: use symbol param (e.g. AAPL.US) instead of counter_id for all US…
hogan-yuan Jul 2, 2026
a7ead43
fix(ci): rename counter_id to symbol in Python/Node.js US method bind…
hogan-yuan Jul 2, 2026
493118c
fix: correct CryptoOverview path to /v1/gemini/us/crypto-overview
hogan-yuan Jul 2, 2026
60de0b6
fix: CryptoOverview accepts BTCUSD/BTC/USD, converts to VA/HAS/BTCUSD
hogan-yuan Jul 2, 2026
2050c94
feat: CryptoOverview supports BTCUSD.HAS → VA/HAS/BTCUSD format
hogan-yuan Jul 2, 2026
c905912
refactor: CryptoOverview only accepts PAIR.EXCHANGE format (e.g. BTCU…
hogan-yuan Jul 2, 2026
f7e718e
refactor: consolidate crypto symbol↔counter_id into symbol_to_counter…
hogan-yuan Jul 2, 2026
cf4e977
fix: detect crypto symbols by CRYPTO_EXCHANGES list (HAS) not market …
hogan-yuan Jul 2, 2026
67d54f9
feat: add BKKT to CRYPTO_EXCHANGES alongside HAS
hogan-yuan Jul 3, 2026
92515e5
feat: add OSL to CRYPTO_EXCHANGES (HAS, OSL, BKKT)
hogan-yuan Jul 3, 2026
0822fc9
fix: update USAssetOverview and USRealizedPL types to match real API …
hogan-yuan Jul 3, 2026
b6ddb1f
fix: update USAssetOverview and USRealizedPL types to match real API …
hogan-yuan Jul 3, 2026
f0aa0da
fix: convert counter_id→symbol and asset_timestamp→OffsetDateTime in …
hogan-yuan Jul 3, 2026
189d703
fix: strip us_m_/hk_m_ routing prefix before sending JWT in Authoriza…
hogan-yuan Jul 3, 2026
6901848
Revert "fix: strip us_m_/hk_m_ routing prefix before sending JWT in A…
hogan-yuan Jul 3, 2026
9f720d7
fix(ci): update USCryptoEntry field names and asset_timestamp type in…
hogan-yuan Jul 3, 2026
42e229d
fix: remove industry_symbol/industry_counter_id from USCryptoEntry (a…
hogan-yuan Jul 3, 2026
9abbe64
fix: USOrderDetail path /v1/orders/:order_id, remove is_attached param
hogan-yuan Jul 3, 2026
dd77774
docs: annotate crypto exchanges with region (US:BKKT, HK:HAS/OSL)
hogan-yuan Jul 3, 2026
44b834f
fix(review): P0/P1 issues from PR review
hogan-yuan Jul 3, 2026
653eedd
fix(review-2): P0 fixes — stubs/bindings sync for USCryptoOverview, U…
hogan-yuan Jul 3, 2026
d65c9d7
fix: convert CryptoOverview counter_id to symbol in Rust/Python/Node.…
hogan-yuan Jul 3, 2026
582c660
fix(review-3): P0/P1 fixes
hogan-yuan Jul 3, 2026
c62dc2b
docs: clarify us_order_detail and usQueryOrders return types in stubs
hogan-yuan Jul 3, 2026
2750828
fix: USRankTag.rank_type is i32/number (API returns integer, not string)
hogan-yuan Jul 3, 2026
414b115
refactor: Rust us_query_orders uses GetUSHistoryOrders (ergonomic, ma…
hogan-yuan Jul 3, 2026
1e468b0
fix(review-7): simplify us_query_orders to ergonomic params across al…
hogan-yuan Jul 3, 2026
be8ffb6
fix: update Python stub us_query_orders to ergonomic signature
hogan-yuan Jul 3, 2026
bfa1eb9
docs: fix stale us_query_orders Args docstring in Python stubs
hogan-yuan Jul 5, 2026
73c25f5
fix(review-10): add GetUSRealizedPLOptions struct — consistent with G…
hogan-yuan Jul 5, 2026
1815cf8
revert: CryptoOverview back to explicit PAIR.EXCHANGE symbol format
hogan-yuan Jul 5, 2026
68c5be4
docs: add BTCUSD.BKKT example to us_crypto_overview Rust doc
hogan-yuan Jul 5, 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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
.vscode
*.log
cmake.build
.claude/
build

# Eclipse IDE
Expand Down
131 changes: 131 additions & 0 deletions java/src/fundamental_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,3 +330,134 @@ pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextMa
Ok(())
})
}

// ── US-market JNI stubs
// ─────────────────────────────────────────────────────── All US APIs return
// JSON strings; Java callers parse with Gson/Jackson.

macro_rules! us_counter_id_method {
($jni_name:ident, $method:ident) => {
#[unsafe(no_mangle)]
pub unsafe extern "system" fn $jni_name(
mut env: JNIEnv,
_class: JClass,
context: i64,
counter_id: JObject,
callback: JObject,
) {
jni_result(&mut env, (), |env| {
let context = &*(context as *const ContextObj);
let counter_id: String = FromJValue::from_jvalue(env, counter_id.into())?;
async_util::execute(env, callback, async move {
let resp = context.ctx.$method(counter_id).await?;
Ok(serde_json::to_string(&resp).unwrap_or_default())
})?;
Ok(())
})
}
};
}

macro_rules! us_counter_id_report_method {
($jni_name:ident, $method:ident) => {
#[unsafe(no_mangle)]
pub unsafe extern "system" fn $jni_name(
mut env: JNIEnv,
_class: JClass,
context: i64,
counter_id: JObject,
report: JObject,
callback: JObject,
) {
jni_result(&mut env, (), |env| {
let context = &*(context as *const ContextObj);
let counter_id: String = FromJValue::from_jvalue(env, counter_id.into())?;
let report: String = FromJValue::from_jvalue(env, report.into())?;
async_util::execute(env, callback, async move {
let resp = context.ctx.$method(counter_id, report).await?;
Ok(serde_json::to_string(&resp).unwrap_or_default())
})?;
Ok(())
})
}
};
}

us_counter_id_method!(
Java_com_longbridge_SdkNative_fundamentalContextUsCompanyOverview,
us_company_overview
);
us_counter_id_method!(
Java_com_longbridge_SdkNative_fundamentalContextUsValuationOverview,
us_valuation_overview
);
us_counter_id_report_method!(
Java_com_longbridge_SdkNative_fundamentalContextUsFinancialOverview,
us_financial_overview
);
us_counter_id_report_method!(
Java_com_longbridge_SdkNative_fundamentalContextUsKeyFinancialMetrics,
us_key_financial_metrics
);
us_counter_id_report_method!(
Java_com_longbridge_SdkNative_fundamentalContextUsAnalystConsensus,
us_analyst_consensus
);
us_counter_id_method!(
Java_com_longbridge_SdkNative_fundamentalContextUsEtfDividendInfo,
us_etf_dividend_info
);
us_counter_id_method!(
Java_com_longbridge_SdkNative_fundamentalContextUsCompanyDividends,
us_company_dividends
);

#[unsafe(no_mangle)]
pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextUsFinancialStatementV3(
mut env: JNIEnv,
_class: JClass,
context: i64,
counter_id: JObject,
kind: JObject,
report: JObject,
callback: JObject,
) {
jni_result(&mut env, (), |env| {
let context = &*(context as *const ContextObj);
let counter_id: String = FromJValue::from_jvalue(env, counter_id.into())?;
let kind: String = FromJValue::from_jvalue(env, kind.into())?;
let report: String = FromJValue::from_jvalue(env, report.into())?;
async_util::execute(env, callback, async move {
let resp = context
.ctx
.us_financial_statement_v3(counter_id, kind, report)
.await?;
Ok(serde_json::to_string(&resp).unwrap_or_default())
})?;
Ok(())
})
}

#[unsafe(no_mangle)]
pub unsafe extern "system" fn Java_com_longbridge_SdkNative_fundamentalContextUsEtfFiles(
mut env: JNIEnv,
_class: JClass,
context: i64,
counter_id: JObject,
size: JObject,
callback: JObject,
) {
jni_result(&mut env, (), |env| {
let context = &*(context as *const ContextObj);
let counter_id: String = FromJValue::from_jvalue(env, counter_id.into())?;
let size: Option<i32> = FromJValue::from_jvalue(env, size.into())?;
async_util::execute(env, callback, async move {
let resp = context
.ctx
.us_etf_files(counter_id, size.map(|s| s as u32))
.await?;
Ok(serde_json::to_string(&resp).unwrap_or_default())
})?;
Ok(())
})
}
19 changes: 19 additions & 0 deletions java/src/quote_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1282,3 +1282,22 @@ pub unsafe extern "system" fn Java_com_longbridge_SdkNative_quoteContextOptionVo
Ok(())
})
}

#[unsafe(no_mangle)]
pub unsafe extern "system" fn Java_com_longbridge_SdkNative_quoteContextUsCryptoOverview(
mut env: JNIEnv,
_class: JClass,
context: i64,
symbol: JObject,
callback: JObject,
) {
jni_result(&mut env, (), |env| {
let context = &*(context as *const ContextObj);
let symbol: String = FromJValue::from_jvalue(env, symbol.into())?;
async_util::execute(env, callback, async move {
let resp = context.ctx.us_crypto_overview(symbol).await?;
Ok(serde_json::to_string(&resp).unwrap_or_default())
})?;
Ok(())
})
}
107 changes: 104 additions & 3 deletions java/src/trade_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ use jni::{
JNIEnv, JavaVM,
errors::Result,
objects::{GlobalRef, JClass, JObject, JString},
sys::jobjectArray,
sys::{jboolean, jobjectArray},
};
use longbridge::{
Config, Decimal, Market, TradeContext,
trade::{
BalanceType, EstimateMaxPurchaseQuantityOptions, GetCashFlowOptions,
GetFundPositionsOptions, GetHistoryExecutionsOptions, GetHistoryOrdersOptions,
GetStockPositionsOptions, GetTodayExecutionsOptions, GetTodayOrdersOptions, OrderSide,
OrderStatus, OrderType, OutsideRTH, PushEvent, ReplaceOrderOptions, SubmitOrderOptions,
TimeInForceType, TopicType,
OrderStatus, OrderType, OutsideRTH, PushEvent, QueryUSOrdersOptions, ReplaceOrderOptions,
SubmitOrderOptions, TimeInForceType, TopicType,
},
};
use parking_lot::Mutex;
Expand Down Expand Up @@ -625,3 +625,104 @@ pub unsafe extern "system" fn Java_com_longbridge_SdkNative_tradeContextEstimate
Ok(())
})
}

// ── US-market JNI stubs ──────────────────────────────────────────────────────

#[unsafe(no_mangle)]
pub unsafe extern "system" fn Java_com_longbridge_SdkNative_tradeContextUsQueryOrders(
mut env: JNIEnv,
_class: JClass,
context: i64,
symbol: JObject,
action: i64,
start_at: i64,
end_at: i64,
query_type: i64,
page: i64,
limit: i64,
callback: JObject,
) {
jni_result(&mut env, (), |env| {
let context = &*(context as *const ContextObj);
let symbol_str: String = FromJValue::from_jvalue(env, symbol.into())?;
let us_opts = longbridge::trade::GetUSHistoryOrders {
symbol: if symbol_str.is_empty() {
None
} else {
Some(symbol_str)
},
side: match action {
1 => longbridge::trade::OrderSide::Buy,
2 => longbridge::trade::OrderSide::Sell,
_ => longbridge::trade::OrderSide::Unknown,
},
start_at,
end_at,
query_type: query_type as i32,
page: page as i32,
limit: limit as i32,
};
async_util::execute(env, callback, async move {
let resp = context.ctx.us_query_orders(us_opts).await?;
Ok(serde_json::to_string(&resp).unwrap_or_default())
})?;
Ok(())
})
}

#[unsafe(no_mangle)]
pub unsafe extern "system" fn Java_com_longbridge_SdkNative_tradeContextUsOrderDetail(
mut env: JNIEnv,
_class: JClass,
context: i64,
order_id: JObject,
callback: JObject,
) {
jni_result(&mut env, (), |env| {
let context = &*(context as *const ContextObj);
let order_id: String = FromJValue::from_jvalue(env, order_id.into())?;
async_util::execute(env, callback, async move {
let resp = context.ctx.us_order_detail(order_id).await?;
Ok(serde_json::to_string(&resp).unwrap_or_default())
})?;
Ok(())
})
}

#[unsafe(no_mangle)]
pub unsafe extern "system" fn Java_com_longbridge_SdkNative_tradeContextUsAssetOverview(
mut env: JNIEnv,
_class: JClass,
context: i64,
callback: JObject,
) {
jni_result(&mut env, (), |env| {
let context = &*(context as *const ContextObj);
async_util::execute(env, callback, async move {
let resp = context.ctx.us_asset_overview().await?;
Ok(serde_json::to_string(&resp).unwrap_or_default())
})?;
Ok(())
})
}

#[unsafe(no_mangle)]
pub unsafe extern "system" fn Java_com_longbridge_SdkNative_tradeContextUsRealizedPl(
mut env: JNIEnv,
_class: JClass,
context: i64,
currency: JObject,
category: JObject,
callback: JObject,
) {
jni_result(&mut env, (), |env| {
let context = &*(context as *const ContextObj);
let currency: String = FromJValue::from_jvalue(env, currency.into())?;
let category: Option<String> = FromJValue::from_jvalue(env, category.into()).ok();
async_util::execute(env, callback, async move {
let resp = context.ctx.us_realized_pl(longbridge::trade::GetUSRealizedPLOptions { currency, category: category.unwrap_or_default() }).await?;
Ok(serde_json::to_string(&resp).unwrap_or_default())
})?;
Ok(())
})
}
Loading
Loading