diff --git a/java/Makefile.toml b/java/Makefile.toml index 4cc9c5312..f0cd17036 100644 --- a/java/Makefile.toml +++ b/java/Makefile.toml @@ -94,6 +94,13 @@ args = [ "javasrc/src/main/java/com/longport/quote/CreateWatchlistGroupResponse.java", "javasrc/src/main/java/com/longport/quote/DeleteWatchlistGroup.java", "javasrc/src/main/java/com/longport/quote/UpdateWatchlistGroup.java", + "javasrc/src/main/java/com/longport/quote/WarrantStatus.java", + "javasrc/src/main/java/com/longport/quote/WarrantSortBy.java", + "javasrc/src/main/java/com/longport/quote/SortOrderType.java", + "javasrc/src/main/java/com/longport/quote/FilterWarrantInOutBoundsType.java", + "javasrc/src/main/java/com/longport/quote/FilterWarrantExpiryDate.java", + "javasrc/src/main/java/com/longport/quote/WarrantInfo.java", + "javasrc/src/main/java/com/longport/quote/QueryWarrantOptions.java", "javasrc/src/main/java/com/longport/trade/AccountBalance.java", "javasrc/src/main/java/com/longport/trade/BalanceType.java", diff --git a/java/c/com_longport_SdkNative.h b/java/c/com_longport_SdkNative.h index 6653b8463..9778b20ea 100644 --- a/java/c/com_longport_SdkNative.h +++ b/java/c/com_longport_SdkNative.h @@ -311,6 +311,14 @@ JNIEXPORT void JNICALL Java_com_longport_SdkNative_quoteContextOptionChainInfoBy JNIEXPORT void JNICALL Java_com_longport_SdkNative_quoteContextWarrantIssuers (JNIEnv *, jclass, jlong, jobject); +/* + * Class: com_longport_SdkNative + * Method: quoteContextWarrantList + * Signature: (JLcom/longport/quote/QueryWarrantOptions;Lcom/longport/AsyncCallback;)V + */ +JNIEXPORT void JNICALL Java_com_longport_SdkNative_quoteContextWarrantList + (JNIEnv *, jclass, jlong, jobject, jobject); + /* * Class: com_longport_SdkNative * Method: quoteContextTradingSession diff --git a/java/javasrc/src/main/java/com/longport/SdkNative.java b/java/javasrc/src/main/java/com/longport/SdkNative.java index 3cba1eb9d..6d7a51959 100644 --- a/java/javasrc/src/main/java/com/longport/SdkNative.java +++ b/java/javasrc/src/main/java/com/longport/SdkNative.java @@ -102,6 +102,9 @@ public static native void quoteContextOptionChainInfoByDate(long context, String public static native void quoteContextWarrantIssuers(long context, AsyncCallback callback); + public static native void quoteContextWarrantList(long context, QueryWarrantOptions opts, + AsyncCallback callback); + public static native void quoteContextTradingSession(long context, AsyncCallback callback); public static native void quoteContextTradingDays(long context, Market market, LocalDate begin, LocalDate end, diff --git a/java/javasrc/src/main/java/com/longport/quote/FilterWarrantExpiryDate.java b/java/javasrc/src/main/java/com/longport/quote/FilterWarrantExpiryDate.java new file mode 100644 index 000000000..0ec2a7a2c --- /dev/null +++ b/java/javasrc/src/main/java/com/longport/quote/FilterWarrantExpiryDate.java @@ -0,0 +1,8 @@ +package com.longport.quote; + +public enum FilterWarrantExpiryDate { + LT_3, + Between_3_6, + Between_6_12, + GT_12, +} diff --git a/java/javasrc/src/main/java/com/longport/quote/FilterWarrantInOutBoundsType.java b/java/javasrc/src/main/java/com/longport/quote/FilterWarrantInOutBoundsType.java new file mode 100644 index 000000000..14417436b --- /dev/null +++ b/java/javasrc/src/main/java/com/longport/quote/FilterWarrantInOutBoundsType.java @@ -0,0 +1,6 @@ +package com.longport.quote; + +public enum FilterWarrantInOutBoundsType { + In, + Out, +} diff --git a/java/javasrc/src/main/java/com/longport/quote/QueryWarrantOptions.java b/java/javasrc/src/main/java/com/longport/quote/QueryWarrantOptions.java new file mode 100644 index 000000000..88fa2cc30 --- /dev/null +++ b/java/javasrc/src/main/java/com/longport/quote/QueryWarrantOptions.java @@ -0,0 +1,45 @@ +package com.longport.quote; + +@SuppressWarnings("unused") +public class QueryWarrantOptions { + private String symbol; + private WarrantSortBy sortBy; + private SortOrderType sortType; + private WarrantType[] warrantType; + private int[] issuer; + private FilterWarrantExpiryDate[] expiryDate; + private FilterWarrantInOutBoundsType[] priceType; + private WarrantStatus[] status; + + public QueryWarrantOptions(String symbol, WarrantSortBy sortBy, SortOrderType sortType) { + this.symbol = symbol; + this.sortBy = sortBy; + this.sortType = sortType; + } + + public QueryWarrantOptions setWarrantType(WarrantType[] warrantType) { + this.warrantType = warrantType; + return this; + } + + public QueryWarrantOptions setIssuer(int[] issuer) { + this.issuer = issuer; + return this; + } + + public QueryWarrantOptions setExpiryDate(FilterWarrantExpiryDate[] expiryDate) { + this.expiryDate = expiryDate; + return this; + } + + public QueryWarrantOptions setPriceType(FilterWarrantInOutBoundsType[] priceType) { + this.priceType = priceType; + return this; + } + + public QueryWarrantOptions setStatus(WarrantStatus[] status) { + this.status = status; + return this; + } + +} diff --git a/java/javasrc/src/main/java/com/longport/quote/QuoteContext.java b/java/javasrc/src/main/java/com/longport/quote/QuoteContext.java index c2712f321..3db53501f 100644 --- a/java/javasrc/src/main/java/com/longport/quote/QuoteContext.java +++ b/java/javasrc/src/main/java/com/longport/quote/QuoteContext.java @@ -654,6 +654,39 @@ public CompletableFuture getWarrantIssuers() }); } + /** + * Query warrant list + * + *
+     * {@code
+     * import com.longport.*;
+     * import com.longport.quote.*;
+     * 
+     * class Main {
+     *     public static void main(String[] args) throws Exception {
+     *         try (Config config = Config.fromEnv(); QuoteContext ctx = QuoteContext.create(config).get()) {
+     *             QueryWarrantOptions opts = new QueryWarrantOptions("700.HK", WarrantSortBy.LastDone,
+     *                     SortOrderType.Ascending);
+     *             IssuerInfo[] resp = ctx.queryWarrantList(opts).get();
+     *             for (IssuerInfo obj : resp) {
+     *                 System.out.println(obj);
+     *             }
+     *         }
+     *     }
+     * }
+     * }
+     * 
+ * + * @return A Future representing the result of the operation + * @throws OpenApiException If an error occurs + */ + public CompletableFuture queryWarrantList(QueryWarrantOptions opts) + throws OpenApiException { + return AsyncCallback.executeTask((callback) -> { + SdkNative.quoteContextWarrantList(this.raw, opts, callback); + }); + } + /** * Get trading session of the day * diff --git a/java/javasrc/src/main/java/com/longport/quote/SortOrderType.java b/java/javasrc/src/main/java/com/longport/quote/SortOrderType.java new file mode 100644 index 000000000..6d1b44542 --- /dev/null +++ b/java/javasrc/src/main/java/com/longport/quote/SortOrderType.java @@ -0,0 +1,6 @@ +package com.longport.quote; + +public enum SortOrderType { + Ascending, + Descending, +} diff --git a/java/javasrc/src/main/java/com/longport/quote/WarrantInfo.java b/java/javasrc/src/main/java/com/longport/quote/WarrantInfo.java new file mode 100644 index 000000000..5c15ee107 --- /dev/null +++ b/java/javasrc/src/main/java/com/longport/quote/WarrantInfo.java @@ -0,0 +1,146 @@ +package com.longport.quote; + +import java.math.BigDecimal; +import java.time.LocalDate; + +public class WarrantInfo { + private String symbol; + private WarrantType warrantType; + private String name; + private BigDecimal lastDone; + private BigDecimal changeRate; + private BigDecimal changeValue; + private long volume; + private BigDecimal turnover; + private LocalDate expiryDate; + private BigDecimal strikePrice; + private BigDecimal upperStrikePrice; + private BigDecimal lowerStrikePrice; + private long outstandingQty; + private BigDecimal outstandingRatio; + private BigDecimal premium; + private BigDecimal itmOtm; + private BigDecimal impliedVolatility; + private BigDecimal delta; + private BigDecimal callPrice; + private BigDecimal toCallPrice; + private BigDecimal effectiveLeverage; + private BigDecimal leverageRatio; + private BigDecimal conversionRatio; + private BigDecimal balancePoint; + private WarrantStatus status; + + public String getSymbol() { + return symbol; + } + + public WarrantType getWarrantType() { + return warrantType; + } + + public String getName() { + return name; + } + + public BigDecimal getLastDone() { + return lastDone; + } + + public BigDecimal getChangeRate() { + return changeRate; + } + + public BigDecimal getChangeValue() { + return changeValue; + } + + public long getVolume() { + return volume; + } + + public BigDecimal getTurnover() { + return turnover; + } + + public LocalDate getExpiryDate() { + return expiryDate; + } + + public BigDecimal getStrikePrice() { + return strikePrice; + } + + public BigDecimal getUpperStrikePrice() { + return upperStrikePrice; + } + + public BigDecimal getLowerStrikePrice() { + return lowerStrikePrice; + } + + public long getOutstandingQty() { + return outstandingQty; + } + + public BigDecimal getOutstandingRatio() { + return outstandingRatio; + } + + public BigDecimal getPremium() { + return premium; + } + + public BigDecimal getItmOtm() { + return itmOtm; + } + + public BigDecimal getImpliedVolatility() { + return impliedVolatility; + } + + public BigDecimal getDelta() { + return delta; + } + + public BigDecimal getCallPrice() { + return callPrice; + } + + public BigDecimal getToCallPrice() { + return toCallPrice; + } + + public BigDecimal getEffectiveLeverage() { + return effectiveLeverage; + } + + public BigDecimal getLeverageRatio() { + return leverageRatio; + } + + public BigDecimal getConversionRatio() { + return conversionRatio; + } + + public BigDecimal getBalancePoint() { + return balancePoint; + } + + public WarrantStatus getStatus() { + return status; + } + + @Override + public String toString() { + return "WarrantInfo [symbol=" + symbol + ", warrantType=" + warrantType + ", name=" + name + ", lastDone=" + + lastDone + ", changeRate=" + changeRate + ", changeValue=" + changeValue + ", volume=" + volume + + ", turnover=" + turnover + ", expiryDate=" + expiryDate + ", strikePrice=" + strikePrice + + ", upperStrikePrice=" + upperStrikePrice + ", lowerStrikePrice=" + lowerStrikePrice + + ", outstandingQty=" + outstandingQty + ", outstandingRatio=" + outstandingRatio + ", premium=" + + premium + ", itmOtm=" + itmOtm + ", impliedVolatility=" + impliedVolatility + ", delta=" + delta + + ", callPrice=" + callPrice + ", toCallPrice=" + toCallPrice + ", effectiveLeverage=" + + effectiveLeverage + ", leverageRatio=" + leverageRatio + ", conversionRatio=" + conversionRatio + + ", balancePoint=" + balancePoint + ", status=" + status + "]"; + } + +} diff --git a/java/javasrc/src/main/java/com/longport/quote/WarrantSortBy.java b/java/javasrc/src/main/java/com/longport/quote/WarrantSortBy.java new file mode 100644 index 000000000..c94513f97 --- /dev/null +++ b/java/javasrc/src/main/java/com/longport/quote/WarrantSortBy.java @@ -0,0 +1,26 @@ +package com.longport.quote; + +public enum WarrantSortBy { + LastDone, + ChangeRate, + ChangeValue, + Volume, + Turnover, + ExpiryDate, + StrikePrice, + UpperStrikePrice, + LowerStrikePrice, + OutstandingQuantity, + OutstandingRatio, + Premium, + ItmOtm, + ImpliedVolatility, + Delta, + CallPrice, + ToCallPrice, + EffectiveLeverage, + LeverageRatio, + ConversionRatio, + BalancePoint, + Status, +} diff --git a/java/javasrc/src/main/java/com/longport/quote/WarrantStatus.java b/java/javasrc/src/main/java/com/longport/quote/WarrantStatus.java new file mode 100644 index 000000000..a9b44cb43 --- /dev/null +++ b/java/javasrc/src/main/java/com/longport/quote/WarrantStatus.java @@ -0,0 +1,7 @@ +package com.longport.quote; + +public enum WarrantStatus { + Suspend, + PrepareList, + Normal, +} diff --git a/java/src/init.rs b/java/src/init.rs index 71c227ea6..6f91faab2 100644 --- a/java/src/init.rs +++ b/java/src/init.rs @@ -85,6 +85,11 @@ pub extern "system" fn Java_com_longport_SdkNative_init<'a>( longport::quote::OptionType, longport::quote::OptionDirection, longport::quote::WarrantType, + longport::quote::WarrantStatus, + longport::quote::SortOrderType, + longport::quote::WarrantSortBy, + longport::quote::FilterWarrantExpiryDate, + longport::quote::FilterWarrantInOutBoundsType, longport::quote::Period, longport::quote::AdjustType, longport::quote::SecurityBoard, @@ -129,6 +134,7 @@ pub extern "system" fn Java_com_longport_SdkNative_init<'a>( longport::quote::Candlestick, longport::quote::StrikePriceInfo, longport::quote::IssuerInfo, + longport::quote::WarrantInfo, longport::quote::MarketTradingSession, longport::quote::TradingSessionInfo, longport::quote::MarketTradingDays, diff --git a/java/src/quote_context.rs b/java/src/quote_context.rs index 1ca69fab9..8a7111b06 100644 --- a/java/src/quote_context.rs +++ b/java/src/quote_context.rs @@ -8,8 +8,9 @@ use jni::{ }; use longport::{ quote::{ - AdjustType, CalcIndex, Period, PushEvent, PushEventDetail, RequestCreateWatchlistGroup, - RequestUpdateWatchlistGroup, SecuritiesUpdateMode, SubFlags, + AdjustType, CalcIndex, FilterWarrantExpiryDate, FilterWarrantInOutBoundsType, Period, + PushEvent, PushEventDetail, RequestCreateWatchlistGroup, RequestUpdateWatchlistGroup, + SecuritiesUpdateMode, SortOrderType, SubFlags, WarrantSortBy, WarrantStatus, WarrantType, }, Config, Market, QuoteContext, }; @@ -22,6 +23,7 @@ use crate::{ init::QUOTE_CONTEXT_CLASS, types::{ get_field, set_field, CreateWatchlistGroupResponse, FromJValue, IntoJValue, ObjectArray, + PrimaryArray, }, }; @@ -710,6 +712,48 @@ pub unsafe extern "system" fn Java_com_longport_SdkNative_quoteContextWarrantIss }) } +#[no_mangle] +pub unsafe extern "system" fn Java_com_longport_SdkNative_quoteContextWarrantList( + mut env: JNIEnv, + _class: JClass, + context: i64, + opts: JObject, + callback: JObject, +) { + jni_result(&mut env, (), |env| { + let context = &*(context as *const ContextObj); + let symbol: String = get_field(env, &opts, "symbol")?; + let sort_by: WarrantSortBy = get_field(env, &opts, "sortBy")?; + let sort_type: SortOrderType = get_field(env, &opts, "sortType")?; + let warrant_type: ObjectArray = get_field(env, &opts, "warrantType")?; + let issuer: PrimaryArray = get_field(env, &opts, "issuer")?; + let expiry_date: ObjectArray = + get_field(env, &opts, "expiryDate")?; + let price_type: ObjectArray = + get_field(env, &opts, "priceType")?; + let status: ObjectArray = get_field(env, &opts, "status")?; + + async_util::execute(env, callback, async move { + Ok(ObjectArray( + context + .ctx + .warrant_list( + symbol, + sort_by, + sort_type, + Some(&warrant_type.0), + Some(&issuer.0), + Some(&expiry_date.0), + Some(&price_type.0), + Some(&status.0), + ) + .await?, + )) + })?; + Ok(()) + }) +} + #[no_mangle] pub unsafe extern "system" fn Java_com_longport_SdkNative_quoteContextTradingSession( mut env: JNIEnv, diff --git a/java/src/types/classes.rs b/java/src/types/classes.rs index caf6ae40d..b4e2a26a4 100644 --- a/java/src/types/classes.rs +++ b/java/src/types/classes.rs @@ -532,6 +532,38 @@ impl_java_class!( ] ); +impl_java_class!( + "com/longport/quote/WarrantInfo", + longport::quote::WarrantInfo, + [ + symbol, + warrant_type, + name, + last_done, + change_rate, + change_value, + volume, + turnover, + expiry_date, + strike_price, + upper_strike_price, + lower_strike_price, + outstanding_qty, + outstanding_ratio, + premium, + itm_otm, + implied_volatility, + delta, + call_price, + to_call_price, + effective_leverage, + leverage_ratio, + conversion_ratio, + balance_point, + status, + ] +); + impl_java_class!( "com/longport/trade/PushOrderChanged", longport::trade::PushOrderChanged, diff --git a/java/src/types/enum_types.rs b/java/src/types/enum_types.rs index 892a31df8..6e66f4edf 100644 --- a/java/src/types/enum_types.rs +++ b/java/src/types/enum_types.rs @@ -236,6 +236,59 @@ impl_java_enum!( ] ); +impl_java_enum!( + "com/longport/quote/WarrantStatus", + longport::quote::WarrantStatus, + [Suspend, PrepareList, Normal] +); + +impl_java_enum!( + "com/longport/quote/SortOrderType", + longport::quote::SortOrderType, + [Ascending, Descending] +); + +impl_java_enum!( + "com/longport/quote/WarrantSortBy", + longport::quote::WarrantSortBy, + [ + LastDone, + ChangeRate, + ChangeValue, + Volume, + Turnover, + ExpiryDate, + StrikePrice, + UpperStrikePrice, + LowerStrikePrice, + OutstandingQuantity, + OutstandingRatio, + Premium, + ItmOtm, + ImpliedVolatility, + Delta, + CallPrice, + ToCallPrice, + EffectiveLeverage, + LeverageRatio, + ConversionRatio, + BalancePoint, + Status, + ] +); + +impl_java_enum!( + "com/longport/quote/FilterWarrantExpiryDate", + longport::quote::FilterWarrantExpiryDate, + [LT_3, Between_3_6, Between_6_12, GT_12] +); + +impl_java_enum!( + "com/longport/quote/FilterWarrantInOutBoundsType", + longport::quote::FilterWarrantInOutBoundsType, + [In, Out] +); + impl_java_enum!( "com/longport/trade/OrderSide", longport::trade::OrderSide, diff --git a/java/src/types/primary_array.rs b/java/src/types/primary_array.rs index 3b7c63aa3..f33d2b55f 100644 --- a/java/src/types/primary_array.rs +++ b/java/src/types/primary_array.rs @@ -20,7 +20,11 @@ impl JSignature for PrimaryArray { impl FromJValue for PrimaryArray { fn from_jvalue(env: &mut JNIEnv, value: JValueOwned) -> Result { unsafe { - let value = value.l()?.into(); + let value = value.l()?; + if value.is_null() { + return Ok(PrimaryArray(Vec::new())); + } + let value = value.into(); let array = env.get_array_elements::(&value, ReleaseMode::CopyBack)?; Ok(PrimaryArray( std::slice::from_raw_parts(array.as_ptr(), array.len()).to_vec(), @@ -40,7 +44,11 @@ impl IntoJValue for PrimaryArray { impl FromJValue for PrimaryArray { fn from_jvalue(env: &mut JNIEnv, value: JValueOwned) -> Result { unsafe { - let value = value.l()?.into(); + let value = value.l()?; + if value.is_null() { + return Ok(PrimaryArray(Vec::new())); + } + let value = value.into(); let array = env.get_array_elements::(&value, ReleaseMode::CopyBack)?; Ok(PrimaryArray( std::slice::from_raw_parts(array.as_ptr(), array.len()).to_vec(), @@ -60,7 +68,11 @@ impl IntoJValue for PrimaryArray { impl FromJValue for PrimaryArray { fn from_jvalue(env: &mut JNIEnv, value: JValueOwned) -> Result { unsafe { - let value = value.l()?.into(); + let value = value.l()?; + if value.is_null() { + return Ok(PrimaryArray(Vec::new())); + } + let value = value.into(); let array = env.get_array_elements::(&value, ReleaseMode::CopyBack)?; Ok(PrimaryArray( std::slice::from_raw_parts(array.as_ptr(), array.len()) diff --git a/java/test/Main.java b/java/test/Main.java index e67445bfc..ba28eecfd 100644 --- a/java/test/Main.java +++ b/java/test/Main.java @@ -1,30 +1,19 @@ -import java.time.LocalDateTime; -import java.time.LocalDate; -import java.util.Arrays; - import com.longport.*; import com.longport.quote.*; class Main { public static void main(String[] args) throws Exception { - try (Config config = Config.fromEnv(); QuoteContext ctx = QuoteContext.create(config).get()) { - System.out.println("get candlesticks by offset"); - System.out.println("===================="); - - Candlestick[] candlesticks = ctx - .getHistoryCandlesticksByOffset("700.HK", Period.Day, AdjustType.NoAdjust, false, - LocalDateTime.of(2023, 8, 18, 0, 0, 0, 0), 10) - .get(); - System.out.println(Arrays.toString(candlesticks)); - - System.out.println("get candlesticks by date"); - System.out.println("===================="); - - Candlestick[] candlesticks2 = ctx - .getHistoryCandlesticksByDate("700.HK", Period.Day, AdjustType.NoAdjust, - LocalDate.of(2022, 5, 5), LocalDate.of(2022, 6, 23)) - .get(); - System.out.println(Arrays.toString(candlesticks2)); + try (Config config = Config.fromEnv(); + QuoteContext ctx = QuoteContext.create(config).get()) { + QueryWarrantOptions opts = new QueryWarrantOptions("700.HK", + WarrantSortBy.LastDone, + SortOrderType.Ascending) + .setExpiryDate(new FilterWarrantExpiryDate[] { FilterWarrantExpiryDate.LT_3 }) + .setStatus(new WarrantStatus[] { WarrantStatus.Normal }); + WarrantInfo[] resp = ctx.queryWarrantList(opts).get(); + for (WarrantInfo obj : resp) { + System.out.println(obj); + } } } }