From 0ee057e5f16e776a1c22e9c953359d617d5d01d2 Mon Sep 17 00:00:00 2001 From: Sunli Date: Fri, 29 Mar 2024 11:24:22 +0800 Subject: [PATCH] add QuoteContext::warrant_list method --- c/cbindgen.toml | 7 + c/csrc/include/longport.h | 349 ++++++++++++-- c/src/quote_context/context.rs | 82 +++- c/src/quote_context/enum_types.rs | 138 ++++++ c/src/quote_context/types.rs | 421 +++++++++++++---- c/src/types/mod.rs | 1 + cpp/include/quote_context.hpp | 16 +- cpp/include/types.hpp | 198 ++++++-- cpp/src/convert.hpp | 269 +++++++++-- cpp/src/quote_context.cpp | 83 +++- .../java/com/longport/quote/QuoteContext.java | 13 - .../com/longport/quote/SecurityCalcIndex.java | 105 ++--- java/src/types/classes.rs | 104 ++--- nodejs/Cargo.toml | 4 +- nodejs/index.d.ts | 218 +++++++-- nodejs/index.js | 8 +- nodejs/src/quote/context.rs | 75 ++- nodejs/src/quote/types.rs | 222 +++++++-- python/Makefile.toml | 2 +- python/pysrc/longport/openapi.pyi | 442 ++++++++++++++++-- python/src/quote/context.rs | 53 ++- python/src/quote/mod.rs | 7 + python/src/quote/types.rs | 222 +++++++-- rust/crates/httpclient/src/geo.rs | 11 +- rust/crates/proto/openapi-protobufs | 2 +- rust/crates/proto/src/longportapp.quote.v1.rs | 6 +- rust/src/blocking/quote.rs | 51 +- rust/src/config.rs | 12 +- rust/src/quote/cmd_code.rs | 3 + rust/src/quote/context.rs | 67 ++- rust/src/quote/core.rs | 41 +- rust/src/quote/mod.rs | 14 +- rust/src/quote/types.rs | 357 +++++++++++--- 33 files changed, 2992 insertions(+), 611 deletions(-) diff --git a/c/cbindgen.toml b/c/cbindgen.toml index a39ab9ec9..93d46c175 100644 --- a/c/cbindgen.toml +++ b/c/cbindgen.toml @@ -113,6 +113,12 @@ cpp_compat = true "CSecuritiesUpdateMode" = "lb_securities_update_mode_t" "CCalcIndex" = "lb_calc_index_t" "CSecurityCalcIndex" = "lb_security_calc_index_t" +"CSortOrderType" = "lb_sort_order_type_t" +"CWarrantSortBy" = "lb_warrant_sort_by_t" +"CFilterWarrantExpiryDate" = "lb_filter_warrant_expiry_date_t" +"CFilterWarrantInOutBoundsType" = "lb_filter_warrant_in_out_bounds_type_t" +"CWarrantStatus" = "lb_warrant_status_t" +"CWarrantInfo" = "lb_warrant_info_t" [export] include = [ @@ -146,4 +152,5 @@ include = [ "COrderDetail", "CEstimateMaxPurchaseQuantityResponse", "CSecurityCalcIndex", + "CWarrantInfo", ] diff --git a/c/csrc/include/longport.h b/c/csrc/include/longport.h index 67d900086..e2fed5eaf 100644 --- a/c/csrc/include/longport.h +++ b/c/csrc/include/longport.h @@ -336,6 +336,42 @@ typedef enum lb_deduction_status_t { DeductionStatusDone, } lb_deduction_status_t; +/** + * Filter warrant expiry date type + */ +typedef enum lb_filter_warrant_expiry_date_t { + /** + * Less than 3 months + */ + WarrantExpiryDate_LT_3, + /** + * 3 - 6 months + */ + WarrantExpiryDate_Between_3_6, + /** + * 6 - 12 months + */ + WarrantExpiryDate_Between_6_12, + /** + * Greater than 12 months + */ + WarrantExpiryDate_GT_12, +} lb_filter_warrant_expiry_date_t; + +/** + * Filter warrant in/out of the bounds type + */ +typedef enum lb_filter_warrant_in_out_bounds_type_t { + /** + * In bounds + */ + WarrantInOutBoundsType_In, + /** + * Out bounds + */ + WarrantInOutBoundsType_Out, +} lb_filter_warrant_in_out_bounds_type_t; + /** * Language identifer */ @@ -808,6 +844,20 @@ typedef enum lb_security_board_t { SecurityBoardSGSector, } lb_security_board_t; +/** + * Sort order type + */ +typedef enum lb_sort_order_type_t { + /** + * Ascending + */ + SortOrderAscending, + /** + * Descending + */ + SortOrderDescending, +} lb_sort_order_type_t; + /** * Time in force Type */ @@ -948,6 +998,118 @@ typedef enum lb_trigger_status_t { TriggerStatusReleased, } lb_trigger_status_t; +/** + * Warrant sort by + */ +typedef enum lb_warrant_sort_by_t { + /** + * Last done + */ + WarrantSortByLastDone, + /** + * Change rate + */ + WarrantSortByChangeRate, + /** + * Change value + */ + WarrantSortByChangeValue, + /** + * Volume + */ + WarrantSortByVolume, + /** + * Turnover + */ + WarrantSortByTurnover, + /** + * Expiry date + */ + WarrantSortByExpiryDate, + /** + * Strike price + */ + WarrantSortByStrikePrice, + /** + * Upper strike price + */ + WarrantSortByUpperStrikePrice, + /** + * Lower strike price + */ + WarrantSortByLowerStrikePrice, + /** + * Outstanding quantity + */ + WarrantSortByOutstandingQuantity, + /** + * Outstanding ratio + */ + WarrantSortByOutstandingRatio, + /** + * Premium + */ + WarrantSortByPremium, + /** + * In/out of the bound + */ + WarrantSortByItmOtm, + /** + * Implied volatility + */ + WarrantSortByImpliedVolatility, + /** + * Greek value delta + */ + WarrantSortByDelta, + /** + * Call price + */ + WarrantSortByCallPrice, + /** + * Price interval from the call price + */ + WarrantSortByToCallPrice, + /** + * Effective leverage + */ + WarrantSortByEffectiveLeverage, + /** + * Leverage ratio + */ + WarrantSortByLeverageRatio, + /** + * Conversion ratio + */ + WarrantSortByConversionRatio, + /** + * Breakeven point + */ + WarrantSortByBalancePoint, + /** + * Status + */ + WarrantSortByStatus, +} lb_warrant_sort_by_t; + +/** + * Warrant status + */ +typedef enum lb_warrant_status_t { + /** + * Suspend + */ + WarrantStatusSuspend, + /** + * Prepare List + */ + WarrantStatusPrepareList, + /** + * Normal + */ + WarrantStatusNormal, +} lb_warrant_status_t; + /** * Warrant type */ @@ -3117,7 +3279,7 @@ typedef struct lb_security_calc_index_t { /** * Change ratio */ - const double *change_rate; + const struct lb_decimal_t *change_rate; /** * Volume */ @@ -3129,11 +3291,11 @@ typedef struct lb_security_calc_index_t { /** * Year-to-date change ratio */ - const double *ytd_change_rate; + const struct lb_decimal_t *ytd_change_rate; /** * Turnover rate */ - const double *turnover_rate; + const struct lb_decimal_t *turnover_rate; /** * Total market value */ @@ -3145,39 +3307,39 @@ typedef struct lb_security_calc_index_t { /** * Amplitude */ - const double *amplitude; + const struct lb_decimal_t *amplitude; /** * Volume ratio */ - const double *volume_ratio; + const struct lb_decimal_t *volume_ratio; /** * PE (TTM) */ - const double *pe_ttm_ratio; + const struct lb_decimal_t *pe_ttm_ratio; /** * PB */ - const double *pb_ratio; + const struct lb_decimal_t *pb_ratio; /** * Dividend ratio (TTM) */ - const double *dividend_ratio_ttm; + const struct lb_decimal_t *dividend_ratio_ttm; /** * Five days change ratio */ - const double *five_day_change_rate; + const struct lb_decimal_t *five_day_change_rate; /** * Ten days change ratio */ - const double *ten_day_change_rate; + const struct lb_decimal_t *ten_day_change_rate; /** * Half year change ratio */ - const double *half_year_change_rate; + const struct lb_decimal_t *half_year_change_rate; /** * Five minutes change ratio */ - const double *five_minutes_change_rate; + const struct lb_decimal_t *five_minutes_change_rate; /** * Expiry date */ @@ -3201,23 +3363,23 @@ typedef struct lb_security_calc_index_t { /** * Outstanding ratio */ - const double *outstanding_ratio; + const struct lb_decimal_t *outstanding_ratio; /** * Premium */ - const double *premium; + const struct lb_decimal_t *premium; /** * In/out of the bound */ - const double *itm_otm; + const struct lb_decimal_t *itm_otm; /** * Implied volatility */ - const double *implied_volatility; + const struct lb_decimal_t *implied_volatility; /** * Warrant delta */ - const double *warrant_delta; + const struct lb_decimal_t *warrant_delta; /** * Call price */ @@ -3229,19 +3391,19 @@ typedef struct lb_security_calc_index_t { /** * Effective leverage */ - const double *effective_leverage; + const struct lb_decimal_t *effective_leverage; /** * Leverage ratio */ - const double *leverage_ratio; + const struct lb_decimal_t *leverage_ratio; /** * Conversion ratio */ - const double *conversion_ratio; + const struct lb_decimal_t *conversion_ratio; /** * Breakeven point */ - const double *balance_point; + const struct lb_decimal_t *balance_point; /** * Open interest */ @@ -3249,25 +3411,131 @@ typedef struct lb_security_calc_index_t { /** * Delta */ - const double *delta; + const struct lb_decimal_t *delta; /** * Gamma */ - const double *gamma; + const struct lb_decimal_t *gamma; /** * Theta */ - const double *theta; + const struct lb_decimal_t *theta; /** * Vega */ - const double *vega; + const struct lb_decimal_t *vega; /** * Rho */ - const double *rho; + const struct lb_decimal_t *rho; } lb_security_calc_index_t; +/** + * Warrant info + */ +typedef struct lb_warrant_info_t { + /** + * Security code + */ + const char *symbol; + /** + * Warrant type + */ + enum lb_warrant_type_t warrant_type; + /** + * Security name + */ + const char *name; + /** + * Latest price + */ + const struct lb_decimal_t *last_done; + /** + * Quote change rate + */ + const struct lb_decimal_t *change_rate; + /** + * Quote change + */ + const struct lb_decimal_t *change_value; + /** + * Volume + */ + int64_t volume; + /** + * Turnover + */ + const struct lb_decimal_t *turnover; + /** + * Expiry date + */ + struct lb_date_t expiry_date; + /** + * Strike price + */ + const struct lb_decimal_t *strike_price; + /** + * Upper strike price + */ + const struct lb_decimal_t *upper_strike_price; + /** + * Lower strike price + */ + const struct lb_decimal_t *lower_strike_price; + /** + * Outstanding quantity + */ + int64_t outstanding_qty; + /** + * Outstanding ratio + */ + const struct lb_decimal_t *outstanding_ratio; + /** + * Premium + */ + const struct lb_decimal_t *premium; + /** + * In/out of the bound + */ + const struct lb_decimal_t *itm_otm; + /** + * Implied volatility + */ + const struct lb_decimal_t *implied_volatility; + /** + * Delta + */ + const struct lb_decimal_t *delta; + /** + * Call price + */ + const struct lb_decimal_t *call_price; + /** + * Price interval from the call price + */ + const struct lb_decimal_t *to_call_price; + /** + * Effective leverage + */ + const struct lb_decimal_t *effective_leverage; + /** + * Leverage ratio + */ + const struct lb_decimal_t *leverage_ratio; + /** + * Conversion ratio + */ + const struct lb_decimal_t *conversion_ratio; + /** + * Breakeven point + */ + const struct lb_decimal_t *balance_point; + /** + * Status + */ + enum lb_warrant_status_t status; +} lb_warrant_info_t; + #ifdef __cplusplus extern "C" { #endif // __cplusplus @@ -3612,6 +3880,26 @@ void lb_quote_context_warrant_issuers(const struct lb_quote_context_t *ctx, lb_async_callback_t callback, void *userdata); +/** + * Query warrant list + */ +void lb_quote_context_warrant_list(const struct lb_quote_context_t *ctx, + const char *symbol, + enum lb_warrant_sort_by_t sort_by, + enum lb_sort_order_type_t sort_order, + const enum lb_warrant_type_t *warrant_type, + uintptr_t num_warrant_type, + const int32_t *issuer, + uintptr_t num_issuer, + const enum lb_filter_warrant_expiry_date_t *expiry_date, + uintptr_t num_expiry_date, + const enum lb_filter_warrant_in_out_bounds_type_t *price_type, + uintptr_t num_price_type, + const enum lb_warrant_status_t *status, + uintptr_t num_status, + lb_async_callback_t callback, + void *userdata); + /** * Get trading session of the day */ @@ -3656,15 +3944,6 @@ void lb_quote_context_calc_indexes(const struct lb_quote_context_t *ctx, lb_async_callback_t callback, void *userdata); -/** - * Get watchlist - * - * Deprecated, use `lb_quote_context_watchlist` instead. - */ -void lb_quote_context_watch_list(const struct lb_quote_context_t *ctx, - lb_async_callback_t callback, - void *userdata); - /** * Get watchlist */ diff --git a/c/src/quote_context/context.rs b/c/src/quote_context/context.rs index c6dc82fb1..c778fc5bc 100644 --- a/c/src/quote_context/context.rs +++ b/c/src/quote_context/context.rs @@ -19,7 +19,10 @@ use crate::{ callback::{CFreeUserDataFunc, Callback}, config::CConfig, quote_context::{ - enum_types::{CAdjustType, CCalcIndex, CPeriod}, + enum_types::{ + CAdjustType, CCalcIndex, CFilterWarrantExpiryDate, CFilterWarrantInOutBoundsType, + CPeriod, CSortOrderType, CWarrantSortBy, CWarrantStatus, CWarrantType, + }, types::{ CCandlestickOwned, CCapitalDistributionResponseOwned, CCapitalFlowLineOwned, CCreateWatchlistGroup, CIntradayLineOwned, CIssuerInfoOwned, CMarketTradingDaysOwned, @@ -29,7 +32,7 @@ use crate::{ CRealtimeQuoteOwned, CSecurityBrokersOwned, CSecurityCalcIndexOwned, CSecurityDepthOwned, CSecurityQuoteOwned, CSecurityStaticInfoOwned, CStrikePriceInfoOwned, CSubscriptionOwned, CTradeOwned, CUpdateWatchlistGroup, - CWarrantQuoteOwned, CWatchlistGroupOwned, LB_WATCHLIST_GROUP_NAME, + CWarrantInfoOwned, CWarrantQuoteOwned, CWatchlistGroupOwned, LB_WATCHLIST_GROUP_NAME, LB_WATCHLIST_GROUP_SECURITIES, }, }, @@ -726,6 +729,69 @@ pub unsafe extern "C" fn lb_quote_context_warrant_issuers( }); } +/// Query warrant list +#[no_mangle] +pub unsafe extern "C" fn lb_quote_context_warrant_list( + ctx: *const CQuoteContext, + symbol: *const c_char, + sort_by: CWarrantSortBy, + sort_order: CSortOrderType, + warrant_type: *const CWarrantType, + num_warrant_type: usize, + issuer: *const i32, + num_issuer: usize, + expiry_date: *const CFilterWarrantExpiryDate, + num_expiry_date: usize, + price_type: *const CFilterWarrantInOutBoundsType, + num_price_type: usize, + status: *const CWarrantStatus, + num_status: usize, + callback: CAsyncCallback, + userdata: *mut c_void, +) { + let ctx_inner = (*ctx).ctx.clone(); + let symbol = cstr_to_rust(symbol); + let sort_by = sort_by.into(); + let sort_order = sort_order.into(); + let warrant_type = std::slice::from_raw_parts(warrant_type, num_warrant_type) + .iter() + .copied() + .map(Into::into) + .collect::>(); + let issuer = std::slice::from_raw_parts(issuer, num_issuer).to_vec(); + let expiry_date = std::slice::from_raw_parts(expiry_date, num_expiry_date) + .iter() + .copied() + .map(Into::into) + .collect::>(); + let price_type = std::slice::from_raw_parts(price_type, num_price_type) + .iter() + .copied() + .map(Into::into) + .collect::>(); + let status = std::slice::from_raw_parts(status, num_status) + .iter() + .copied() + .map(Into::into) + .collect::>(); + execute_async(callback, ctx, userdata, async move { + let rows: CVec = ctx_inner + .warrant_list( + symbol, + sort_by, + sort_order, + Some(&warrant_type), + Some(&issuer), + Some(&expiry_date), + Some(&price_type), + Some(&status), + ) + .await? + .into(); + Ok(rows) + }); +} + /// Get trading session of the day #[no_mangle] pub unsafe extern "C" fn lb_quote_context_trading_session( @@ -820,18 +886,6 @@ pub unsafe extern "C" fn lb_quote_context_calc_indexes( }); } -/// Get watchlist -/// -/// Deprecated, use `lb_quote_context_watchlist` instead. -#[no_mangle] -pub unsafe extern "C" fn lb_quote_context_watch_list( - ctx: *const CQuoteContext, - callback: CAsyncCallback, - userdata: *mut c_void, -) { - lb_quote_context_watchlist(ctx, callback, userdata); -} - /// Get watchlist #[no_mangle] pub unsafe extern "C" fn lb_quote_context_watchlist( diff --git a/c/src/quote_context/enum_types.rs b/c/src/quote_context/enum_types.rs index e7cf3061e..8ccf08512 100644 --- a/c/src/quote_context/enum_types.rs +++ b/c/src/quote_context/enum_types.rs @@ -414,3 +414,141 @@ pub enum CCalcIndex { #[c(remote = "Rho")] CalcIndexRho, } + +/// Sort order type +#[derive(Debug, Copy, Clone, Eq, PartialEq, CEnum)] +#[c(remote = "longport::quote::SortOrderType")] +#[repr(C)] +pub enum CSortOrderType { + /// Ascending + #[c(remote = "Ascending")] + SortOrderAscending, + /// Descending + #[c(remote = "Descending")] + SortOrderDescending, +} + +/// Warrant sort by +#[derive(Debug, Copy, Clone, Eq, PartialEq, CEnum)] +#[c(remote = "longport::quote::WarrantSortBy")] +#[allow(clippy::enum_variant_names)] +#[repr(C)] +pub enum CWarrantSortBy { + /// Last done + #[c(remote = "LastDone")] + WarrantSortByLastDone, + /// Change rate + #[c(remote = "ChangeRate")] + WarrantSortByChangeRate, + /// Change value + #[c(remote = "ChangeValue")] + WarrantSortByChangeValue, + /// Volume + #[c(remote = "Volume")] + WarrantSortByVolume, + /// Turnover + #[c(remote = "Turnover")] + WarrantSortByTurnover, + /// Expiry date + #[c(remote = "ExpiryDate")] + WarrantSortByExpiryDate, + /// Strike price + #[c(remote = "StrikePrice")] + WarrantSortByStrikePrice, + /// Upper strike price + #[c(remote = "UpperStrikePrice")] + WarrantSortByUpperStrikePrice, + /// Lower strike price + #[c(remote = "LowerStrikePrice")] + WarrantSortByLowerStrikePrice, + /// Outstanding quantity + #[c(remote = "OutstandingQuantity")] + WarrantSortByOutstandingQuantity, + /// Outstanding ratio + #[c(remote = "OutstandingRatio")] + WarrantSortByOutstandingRatio, + /// Premium + #[c(remote = "Premium")] + WarrantSortByPremium, + /// In/out of the bound + #[c(remote = "ItmOtm")] + WarrantSortByItmOtm, + /// Implied volatility + #[c(remote = "ImpliedVolatility")] + WarrantSortByImpliedVolatility, + /// Greek value delta + #[c(remote = "Delta")] + WarrantSortByDelta, + /// Call price + #[c(remote = "CallPrice")] + WarrantSortByCallPrice, + /// Price interval from the call price + #[c(remote = "ToCallPrice")] + WarrantSortByToCallPrice, + /// Effective leverage + #[c(remote = "EffectiveLeverage")] + WarrantSortByEffectiveLeverage, + /// Leverage ratio + #[c(remote = "LeverageRatio")] + WarrantSortByLeverageRatio, + /// Conversion ratio + #[c(remote = "ConversionRatio")] + WarrantSortByConversionRatio, + /// Breakeven point + #[c(remote = "BalancePoint")] + WarrantSortByBalancePoint, + /// Status + #[c(remote = "Status")] + WarrantSortByStatus, +} + +/// Filter warrant expiry date type +#[derive(Debug, Copy, Clone, Eq, PartialEq, CEnum)] +#[c(remote = "longport::quote::FilterWarrantExpiryDate")] +#[allow(non_camel_case_types)] +#[repr(C)] +pub enum CFilterWarrantExpiryDate { + /// Less than 3 months + #[c(remote = "LT_3")] + WarrantExpiryDate_LT_3, + /// 3 - 6 months + #[c(remote = "Between_3_6")] + WarrantExpiryDate_Between_3_6, + /// 6 - 12 months + #[c(remote = "Between_6_12")] + WarrantExpiryDate_Between_6_12, + /// Greater than 12 months + #[c(remote = "GT_12")] + WarrantExpiryDate_GT_12, +} + +/// Filter warrant in/out of the bounds type +#[derive(Debug, Copy, Clone, Eq, PartialEq, CEnum)] +#[c(remote = "longport::quote::FilterWarrantInOutBoundsType")] +#[allow(non_camel_case_types)] +#[repr(C)] +pub enum CFilterWarrantInOutBoundsType { + /// In bounds + #[c(remote = "In")] + WarrantInOutBoundsType_In, + /// Out bounds + #[c(remote = "Out")] + WarrantInOutBoundsType_Out, +} + +/// Warrant status +#[derive(Debug, Copy, Clone, Eq, PartialEq, CEnum)] +#[c(remote = "longport::quote::WarrantStatus")] +#[allow(clippy::enum_variant_names)] +#[repr(C)] +pub enum CWarrantStatus { + /// Suspend + #[c(remote = "Suspend")] + WarrantStatusSuspend, + /// Prepare List + #[c(remote = "PrepareList")] + WarrantStatusPrepareList, + /// Normal + #[c(remote = "Normal")] + WarrantStatusNormal, +} diff --git a/c/src/quote_context/types.rs b/c/src/quote_context/types.rs index fb9b7824b..5dc0bdb88 100644 --- a/c/src/quote_context/types.rs +++ b/c/src/quote_context/types.rs @@ -7,13 +7,13 @@ use longport::quote::{ PushDepth, PushQuote, PushTrades, RealtimeQuote, SecurityBoard, SecurityBrokers, SecurityCalcIndex, SecurityDepth, SecurityQuote, SecurityStaticInfo, StrikePriceInfo, Subscription, Trade, TradeDirection, TradeSession, TradeStatus, TradingSessionInfo, - WarrantQuote, WarrantType, WatchlistGroup, WatchlistSecurity, + WarrantInfo, WarrantQuote, WarrantType, WatchlistGroup, WatchlistSecurity, }; use crate::{ quote_context::enum_types::{ COptionDirection, COptionType, CPeriod, CSecuritiesUpdateMode, CSecurityBoard, - CTradeDirection, CTradeSession, CTradeStatus, CWarrantType, + CTradeDirection, CTradeSession, CTradeStatus, CWarrantStatus, CWarrantType, }, types::{CDate, CDecimal, CMarket, COption, CString, CTime, CVec, ToFFI}, }; @@ -2148,37 +2148,37 @@ pub struct CSecurityCalcIndex { /// Change value pub change_value: *const CDecimal, /// Change ratio - pub change_rate: *const f64, + pub change_rate: *const CDecimal, /// Volume pub volume: *const i64, /// Turnover pub turnover: *const CDecimal, /// Year-to-date change ratio - pub ytd_change_rate: *const f64, + pub ytd_change_rate: *const CDecimal, /// Turnover rate - pub turnover_rate: *const f64, + pub turnover_rate: *const CDecimal, /// Total market value pub total_market_value: *const CDecimal, /// Capital flow pub capital_flow: *const CDecimal, /// Amplitude - pub amplitude: *const f64, + pub amplitude: *const CDecimal, /// Volume ratio - pub volume_ratio: *const f64, + pub volume_ratio: *const CDecimal, /// PE (TTM) - pub pe_ttm_ratio: *const f64, + pub pe_ttm_ratio: *const CDecimal, /// PB - pub pb_ratio: *const f64, + pub pb_ratio: *const CDecimal, /// Dividend ratio (TTM) - pub dividend_ratio_ttm: *const f64, + pub dividend_ratio_ttm: *const CDecimal, /// Five days change ratio - pub five_day_change_rate: *const f64, + pub five_day_change_rate: *const CDecimal, /// Ten days change ratio - pub ten_day_change_rate: *const f64, + pub ten_day_change_rate: *const CDecimal, /// Half year change ratio - pub half_year_change_rate: *const f64, + pub half_year_change_rate: *const CDecimal, /// Five minutes change ratio - pub five_minutes_change_rate: *const f64, + pub five_minutes_change_rate: *const CDecimal, /// Expiry date pub expiry_date: *const CDate, /// Strike price @@ -2190,39 +2190,39 @@ pub struct CSecurityCalcIndex { /// Outstanding quantity pub outstanding_qty: *const i64, /// Outstanding ratio - pub outstanding_ratio: *const f64, + pub outstanding_ratio: *const CDecimal, /// Premium - pub premium: *const f64, + pub premium: *const CDecimal, /// In/out of the bound - pub itm_otm: *const f64, + pub itm_otm: *const CDecimal, /// Implied volatility - pub implied_volatility: *const f64, + pub implied_volatility: *const CDecimal, /// Warrant delta - pub warrant_delta: *const f64, + pub warrant_delta: *const CDecimal, /// Call price pub call_price: *const CDecimal, /// Price interval from the call price pub to_call_price: *const CDecimal, /// Effective leverage - pub effective_leverage: *const f64, + pub effective_leverage: *const CDecimal, /// Leverage ratio - pub leverage_ratio: *const f64, + pub leverage_ratio: *const CDecimal, /// Conversion ratio - pub conversion_ratio: *const f64, + pub conversion_ratio: *const CDecimal, /// Breakeven point - pub balance_point: *const f64, + pub balance_point: *const CDecimal, /// Open interest pub open_interest: *const i64, /// Delta - pub delta: *const f64, + pub delta: *const CDecimal, /// Gamma - pub gamma: *const f64, + pub gamma: *const CDecimal, /// Theta - pub theta: *const f64, + pub theta: *const CDecimal, /// Vega - pub vega: *const f64, + pub vega: *const CDecimal, /// Rho - pub rho: *const f64, + pub rho: *const CDecimal, } pub(crate) struct CSecurityCalcIndexOwned { @@ -2233,37 +2233,37 @@ pub(crate) struct CSecurityCalcIndexOwned { /// Change value change_value: COption, /// Change ratio - change_rate: COption, + change_rate: COption, /// Volume volume: COption, /// Turnover turnover: COption, /// Year-to-date change ratio - ytd_change_rate: COption, + ytd_change_rate: COption, /// Turnover rate - turnover_rate: COption, + turnover_rate: COption, /// Total market value total_market_value: COption, /// Capital flow capital_flow: COption, /// Amplitude - amplitude: COption, + amplitude: COption, /// Volume ratio - volume_ratio: COption, + volume_ratio: COption, /// PE (TTM) - pe_ttm_ratio: COption, + pe_ttm_ratio: COption, /// PB - pb_ratio: COption, + pb_ratio: COption, /// Dividend ratio (TTM) - dividend_ratio_ttm: COption, + dividend_ratio_ttm: COption, /// Five days change ratio - five_day_change_rate: COption, + five_day_change_rate: COption, /// Ten days change ratio - ten_day_change_rate: COption, + ten_day_change_rate: COption, /// Half year change ratio - half_year_change_rate: COption, + half_year_change_rate: COption, /// Five minutes change ratio - five_minutes_change_rate: COption, + five_minutes_change_rate: COption, /// Expiry date expiry_date: COption, /// Strike price @@ -2275,39 +2275,39 @@ pub(crate) struct CSecurityCalcIndexOwned { /// Outstanding quantity outstanding_qty: COption, /// Outstanding ratio - outstanding_ratio: COption, + outstanding_ratio: COption, /// Premium - premium: COption, + premium: COption, /// In/out of the bound - itm_otm: COption, + itm_otm: COption, /// Implied volatility - implied_volatility: COption, + implied_volatility: COption, /// Warrant delta - warrant_delta: COption, + warrant_delta: COption, /// Call price call_price: COption, /// Price interval from the call price to_call_price: COption, /// Effective leverage - effective_leverage: COption, + effective_leverage: COption, /// Leverage ratio - leverage_ratio: COption, + leverage_ratio: COption, /// Conversion ratio - conversion_ratio: COption, + conversion_ratio: COption, /// Breakeven point - balance_point: COption, + balance_point: COption, /// Open interest open_interest: COption, /// Delta - delta: COption, + delta: COption, /// Gamma - gamma: COption, + gamma: COption, /// Theta - theta: COption, + theta: COption, /// Vega - vega: COption, + vega: COption, /// Rho - rho: COption, + rho: COption, } impl From for CSecurityCalcIndexOwned { @@ -2452,44 +2452,305 @@ impl ToFFI for CSecurityCalcIndexOwned { symbol: symbol.to_ffi_type(), last_done: last_done.to_ffi_type().to_ffi_type(), change_value: change_value.to_ffi_type().to_ffi_type(), - change_rate: change_rate.to_ffi_type(), + change_rate: change_rate.to_ffi_type().to_ffi_type(), volume: volume.to_ffi_type(), turnover: turnover.to_ffi_type().to_ffi_type(), - ytd_change_rate: ytd_change_rate.to_ffi_type(), - turnover_rate: turnover_rate.to_ffi_type(), + ytd_change_rate: ytd_change_rate.to_ffi_type().to_ffi_type(), + turnover_rate: turnover_rate.to_ffi_type().to_ffi_type(), total_market_value: total_market_value.to_ffi_type().to_ffi_type(), capital_flow: capital_flow.to_ffi_type().to_ffi_type(), - amplitude: amplitude.to_ffi_type(), - volume_ratio: volume_ratio.to_ffi_type(), - pe_ttm_ratio: pe_ttm_ratio.to_ffi_type(), - pb_ratio: pb_ratio.to_ffi_type(), - dividend_ratio_ttm: dividend_ratio_ttm.to_ffi_type(), - five_day_change_rate: five_day_change_rate.to_ffi_type(), - ten_day_change_rate: ten_day_change_rate.to_ffi_type(), - half_year_change_rate: half_year_change_rate.to_ffi_type(), - five_minutes_change_rate: five_minutes_change_rate.to_ffi_type(), + amplitude: amplitude.to_ffi_type().to_ffi_type(), + volume_ratio: volume_ratio.to_ffi_type().to_ffi_type(), + pe_ttm_ratio: pe_ttm_ratio.to_ffi_type().to_ffi_type(), + pb_ratio: pb_ratio.to_ffi_type().to_ffi_type(), + dividend_ratio_ttm: dividend_ratio_ttm.to_ffi_type().to_ffi_type(), + five_day_change_rate: five_day_change_rate.to_ffi_type().to_ffi_type(), + ten_day_change_rate: ten_day_change_rate.to_ffi_type().to_ffi_type(), + half_year_change_rate: half_year_change_rate.to_ffi_type().to_ffi_type(), + five_minutes_change_rate: five_minutes_change_rate.to_ffi_type().to_ffi_type(), expiry_date: expiry_date.to_ffi_type(), strike_price: strike_price.to_ffi_type().to_ffi_type(), upper_strike_price: upper_strike_price.to_ffi_type().to_ffi_type(), lower_strike_price: lower_strike_price.to_ffi_type().to_ffi_type(), outstanding_qty: outstanding_qty.to_ffi_type(), - outstanding_ratio: outstanding_ratio.to_ffi_type(), - premium: premium.to_ffi_type(), - itm_otm: itm_otm.to_ffi_type(), - implied_volatility: implied_volatility.to_ffi_type(), - warrant_delta: warrant_delta.to_ffi_type(), + outstanding_ratio: outstanding_ratio.to_ffi_type().to_ffi_type(), + premium: premium.to_ffi_type().to_ffi_type(), + itm_otm: itm_otm.to_ffi_type().to_ffi_type(), + implied_volatility: implied_volatility.to_ffi_type().to_ffi_type(), + warrant_delta: warrant_delta.to_ffi_type().to_ffi_type(), call_price: call_price.to_ffi_type().to_ffi_type(), to_call_price: to_call_price.to_ffi_type().to_ffi_type(), - effective_leverage: effective_leverage.to_ffi_type(), - leverage_ratio: leverage_ratio.to_ffi_type(), - conversion_ratio: conversion_ratio.to_ffi_type(), - balance_point: balance_point.to_ffi_type(), + effective_leverage: effective_leverage.to_ffi_type().to_ffi_type(), + leverage_ratio: leverage_ratio.to_ffi_type().to_ffi_type(), + conversion_ratio: conversion_ratio.to_ffi_type().to_ffi_type(), + balance_point: balance_point.to_ffi_type().to_ffi_type(), open_interest: open_interest.to_ffi_type(), - delta: delta.to_ffi_type(), - gamma: gamma.to_ffi_type(), - theta: theta.to_ffi_type(), - vega: vega.to_ffi_type(), - rho: rho.to_ffi_type(), + delta: delta.to_ffi_type().to_ffi_type(), + gamma: gamma.to_ffi_type().to_ffi_type(), + theta: theta.to_ffi_type().to_ffi_type(), + vega: vega.to_ffi_type().to_ffi_type(), + rho: rho.to_ffi_type().to_ffi_type(), + } + } +} + +/// Warrant info +#[repr(C)] +pub struct CWarrantInfo { + /// Security code + pub symbol: *const c_char, + /// Warrant type + pub warrant_type: CWarrantType, + /// Security name + pub name: *const c_char, + /// Latest price + pub last_done: *const CDecimal, + /// Quote change rate + pub change_rate: *const CDecimal, + /// Quote change + pub change_value: *const CDecimal, + /// Volume + pub volume: i64, + /// Turnover + pub turnover: *const CDecimal, + /// Expiry date + pub expiry_date: CDate, + /// Strike price + pub strike_price: *const CDecimal, + /// Upper strike price + pub upper_strike_price: *const CDecimal, + /// Lower strike price + pub lower_strike_price: *const CDecimal, + /// Outstanding quantity + pub outstanding_qty: i64, + /// Outstanding ratio + pub outstanding_ratio: *const CDecimal, + /// Premium + pub premium: *const CDecimal, + /// In/out of the bound + pub itm_otm: *const CDecimal, + /// Implied volatility + pub implied_volatility: *const CDecimal, + /// Delta + pub delta: *const CDecimal, + /// Call price + pub call_price: *const CDecimal, + /// Price interval from the call price + pub to_call_price: *const CDecimal, + /// Effective leverage + pub effective_leverage: *const CDecimal, + /// Leverage ratio + pub leverage_ratio: *const CDecimal, + /// Conversion ratio + pub conversion_ratio: *const CDecimal, + /// Breakeven point + pub balance_point: *const CDecimal, + /// Status + pub status: CWarrantStatus, +} + +pub(crate) struct CWarrantInfoOwned { + /// Security code + pub symbol: CString, + /// Warrant type + pub warrant_type: CWarrantType, + /// Security name + pub name: CString, + /// Latest price + pub last_done: CDecimal, + /// Quote change rate + pub change_rate: CDecimal, + /// Quote change + pub change_value: CDecimal, + /// Volume + pub volume: i64, + /// Turnover + pub turnover: CDecimal, + /// Expiry date + pub expiry_date: CDate, + /// Strike price + pub strike_price: Option, + /// Upper strike price + pub upper_strike_price: Option, + /// Lower strike price + pub lower_strike_price: Option, + /// Outstanding quantity + pub outstanding_qty: i64, + /// Outstanding ratio + pub outstanding_ratio: CDecimal, + /// Premium + pub premium: CDecimal, + /// In/out of the bound + pub itm_otm: Option, + /// Implied volatility + pub implied_volatility: Option, + /// Delta + pub delta: Option, + /// Call price + pub call_price: Option, + /// Price interval from the call price + pub to_call_price: Option, + /// Effective leverage + pub effective_leverage: Option, + /// Leverage ratio + pub leverage_ratio: CDecimal, + /// Conversion ratio + pub conversion_ratio: Option, + /// Breakeven point + pub balance_point: Option, + /// Status + pub status: CWarrantStatus, +} + +impl ToFFI for CWarrantInfoOwned { + type FFIType = CWarrantInfo; + + fn to_ffi_type(&self) -> Self::FFIType { + let CWarrantInfoOwned { + 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, + } = self; + CWarrantInfo { + symbol: symbol.to_ffi_type(), + warrant_type: *warrant_type, + name: name.to_ffi_type(), + last_done: last_done.to_ffi_type(), + change_rate: change_rate.to_ffi_type(), + change_value: change_value.to_ffi_type(), + volume: *volume, + turnover: turnover.to_ffi_type(), + expiry_date: expiry_date.to_ffi_type(), + strike_price: strike_price + .as_ref() + .map(ToFFI::to_ffi_type) + .unwrap_or(std::ptr::null()), + upper_strike_price: upper_strike_price + .as_ref() + .map(ToFFI::to_ffi_type) + .unwrap_or(std::ptr::null()), + lower_strike_price: lower_strike_price + .as_ref() + .map(ToFFI::to_ffi_type) + .unwrap_or(std::ptr::null()), + outstanding_qty: *outstanding_qty, + outstanding_ratio: outstanding_ratio.to_ffi_type(), + premium: premium.to_ffi_type(), + itm_otm: itm_otm + .as_ref() + .map(ToFFI::to_ffi_type) + .unwrap_or(std::ptr::null()), + implied_volatility: implied_volatility + .as_ref() + .map(ToFFI::to_ffi_type) + .unwrap_or(std::ptr::null()), + delta: delta + .as_ref() + .map(ToFFI::to_ffi_type) + .unwrap_or(std::ptr::null()), + call_price: call_price + .as_ref() + .map(ToFFI::to_ffi_type) + .unwrap_or(std::ptr::null()), + to_call_price: to_call_price + .as_ref() + .map(ToFFI::to_ffi_type) + .unwrap_or(std::ptr::null()), + effective_leverage: effective_leverage + .as_ref() + .map(ToFFI::to_ffi_type) + .unwrap_or(std::ptr::null()), + leverage_ratio: leverage_ratio.to_ffi_type(), + conversion_ratio: conversion_ratio + .as_ref() + .map(ToFFI::to_ffi_type) + .unwrap_or(std::ptr::null()), + balance_point: balance_point + .as_ref() + .map(ToFFI::to_ffi_type) + .unwrap_or(std::ptr::null()), + status: *status, + } + } +} + +impl From for CWarrantInfoOwned { + fn from(resp: WarrantInfo) -> Self { + let 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, + } = resp; + CWarrantInfoOwned { + symbol: symbol.into(), + warrant_type: warrant_type.into(), + name: name.into(), + last_done: last_done.into(), + change_rate: change_rate.into(), + change_value: change_value.into(), + volume, + turnover: turnover.into(), + expiry_date: expiry_date.into(), + strike_price: strike_price.map(Into::into), + upper_strike_price: upper_strike_price.map(Into::into), + lower_strike_price: lower_strike_price.map(Into::into), + outstanding_qty, + outstanding_ratio: outstanding_ratio.into(), + premium: premium.into(), + itm_otm: itm_otm.map(Into::into), + implied_volatility: implied_volatility.map(Into::into), + delta: delta.map(Into::into), + call_price: call_price.map(Into::into), + to_call_price: to_call_price.map(Into::into), + effective_leverage: effective_leverage.map(Into::into), + leverage_ratio: leverage_ratio.into(), + conversion_ratio: conversion_ratio.map(Into::into), + balance_point: balance_point.map(Into::into), + status: status.into(), } } } diff --git a/c/src/types/mod.rs b/c/src/types/mod.rs index f8b391612..abc0689e9 100644 --- a/c/src/types/mod.rs +++ b/c/src/types/mod.rs @@ -45,6 +45,7 @@ impl ToFFI for i64 { impl ToFFI for *const *const T { type FFIType = *const T; + #[inline] fn to_ffi_type(&self) -> Self::FFIType { if self.is_null() { std::ptr::null() diff --git a/cpp/include/quote_context.hpp b/cpp/include/quote_context.hpp index 3b6d3d869..939b96387 100644 --- a/cpp/include/quote_context.hpp +++ b/cpp/include/quote_context.hpp @@ -168,6 +168,18 @@ class QuoteContext void warrant_issuers( AsyncCallback> callback) const; + /// Query warrant list + void warrant_list( + const std::string& symbol, + WarrantSortBy sort_by, + SortOrderType sort_order, + const std::vector& warrant_type, + const std::vector& issuer, + const std::vector& expiry_date, + const std::vector& price_type, + const std::vector& status, + AsyncCallback> callback) const; + /// Get trading session of the day void trading_session( AsyncCallback> callback) @@ -198,10 +210,6 @@ class QuoteContext const std::vector& indexes, AsyncCallback> callback) const; - /// Get watchlist - [[deprecated("use `watchlist` instead")]] void watch_list( - AsyncCallback> callback) const; - /// Get watchlist void watchlist( AsyncCallback> callback) const; diff --git a/cpp/include/types.hpp b/cpp/include/types.hpp index 7ad13ac18..3f8f93ead 100644 --- a/cpp/include/types.hpp +++ b/cpp/include/types.hpp @@ -897,37 +897,37 @@ struct SecurityCalcIndex /// Change value std::optional change_value; /// Change ratio - std::optional change_rate; + std::optional change_rate; /// Volume std::optional volume; /// Turnover std::optional turnover; /// Year-to-date change ratio - std::optional ytd_change_rate; + std::optional ytd_change_rate; /// Turnover rate - std::optional turnover_rate; + std::optional turnover_rate; /// Total market value std::optional total_market_value; /// Capital flow std::optional capital_flow; /// Amplitude - std::optional amplitude; + std::optional amplitude; /// Volume ratio - std::optional volume_ratio; + std::optional volume_ratio; /// PE (TTM) - std::optional pe_ttm_ratio; + std::optional pe_ttm_ratio; /// PB - std::optional pb_ratio; + std::optional pb_ratio; /// Dividend ratio (TTM) - std::optional dividend_ratio_ttm; + std::optional dividend_ratio_ttm; /// Five days change ratio - std::optional five_day_change_rate; + std::optional five_day_change_rate; /// Ten days change ratio - std::optional ten_day_change_rate; + std::optional ten_day_change_rate; /// Half year change ratio - std::optional half_year_change_rate; + std::optional half_year_change_rate; /// Five minutes change ratio - std::optional five_minutes_change_rate; + std::optional five_minutes_change_rate; /// Expiry date std::optional expiry_date; /// Strike price @@ -939,39 +939,185 @@ struct SecurityCalcIndex /// Outstanding quantity std::optional outstanding_qty; /// Outstanding ratio - std::optional outstanding_ratio; + std::optional outstanding_ratio; /// Premium - std::optional premium; + std::optional premium; /// In/out of the bound - std::optional itm_otm; + std::optional itm_otm; /// Implied volatility - std::optional implied_volatility; + std::optional implied_volatility; /// Warrant delta - std::optional warrant_delta; + std::optional warrant_delta; /// Call price std::optional call_price; /// Price interval from the call price std::optional to_call_price; /// Effective leverage - std::optional effective_leverage; + std::optional effective_leverage; /// Leverage ratio - std::optional leverage_ratio; + std::optional leverage_ratio; /// Conversion ratio - std::optional conversion_ratio; + std::optional conversion_ratio; /// Breakeven point - std::optional balance_point; + std::optional balance_point; /// Open interest std::optional open_interest; /// Delta - std::optional delta; + std::optional delta; /// Gamma - std::optional gamma; + std::optional gamma; /// Theta - std::optional theta; + std::optional theta; /// Vega - std::optional vega; + std::optional vega; /// Rho - std::optional rho; + std::optional rho; +}; + +/// Sort order type +enum class SortOrderType +{ + /// Ascending + Ascending, + /// Descending + Descending, +}; + +/// Warrant sort by +enum class WarrantSortBy +{ + /// Last done + LastDone, + /// Change rate + ChangeRate, + /// Change value + ChangeValue, + /// Volume + Volume, + /// Turnover + Turnover, + /// Expiry date + ExpiryDate, + /// Strike price + StrikePrice, + /// Upper strike price + UpperStrikePrice, + /// Lower strike price + LowerStrikePrice, + /// Outstanding quantity + OutstandingQuantity, + /// Outstanding ratio + OutstandingRatio, + /// Premium + Premium, + /// In/out of the bound + ItmOtm, + /// Implied volatility + ImpliedVolatility, + /// Greek value Delta + Delta, + /// Call price + CallPrice, + /// Price interval from the call price + ToCallPrice, + /// Effective leverage + EffectiveLeverage, + /// Leverage ratio + LeverageRatio, + /// Conversion ratio + ConversionRatio, + /// Breakeven point + BalancePoint, + /// Status + Status, +}; + +/// Filter warrant expiry date type +enum class FilterWarrantExpiryDate +{ + /// Less than 3 months + LT_3, + /// 3 - 6 months + Between_3_6, + /// 6 - 12 months + Between_6_12, + /// Greater than 12 months + GT_12, +}; + +/// Filter warrant in/out of the bounds type +enum class FilterWarrantInOutBoundsType +{ + /// In bounds + In, + /// Out bounds + Out, +}; + +/// Warrant status +enum class WarrantStatus +{ + /// Suspend + Suspend, + /// Prepare List + PrepareList, + /// Normal + Normal, +}; + +/// Warrant info +struct WarrantInfo +{ + /// Security code + std::string symbol; + /// Warrant type + WarrantType warrant_type; + /// Security name + std::string name; + /// Latest price + Decimal last_done; + /// Quote change rate + Decimal change_rate; + /// Quote change + Decimal change_value; + /// Volume + int64_t volume; + /// Turnover + Decimal turnover; + /// Expiry date + Date expiry_date; + /// Strike price + std::optional strike_price; + /// Upper strike price + std::optional upper_strike_price; + /// Lower strike price + std::optional lower_strike_price; + /// Outstanding quantity + int64_t outstanding_qty; + /// Outstanding ratio + Decimal outstanding_ratio; + /// Premium + Decimal premium; + /// In/out of the bound + std::optional itm_otm; + /// Implied volatility + std::optional implied_volatility; + /// Delta + std::optional delta; + /// Call price + std::optional call_price; + /// Price interval from the call price + std::optional to_call_price; + /// Effective leverage + std::optional effective_leverage; + /// Leverage ratio + Decimal leverage_ratio; + /// Conversion ratio + std::optional conversion_ratio; + /// Breakeven point + std::optional balance_point; + /// Status + WarrantStatus status; }; } // namespace quote diff --git a/cpp/src/convert.hpp b/cpp/src/convert.hpp index 058268ca5..afd8f04be 100644 --- a/cpp/src/convert.hpp +++ b/cpp/src/convert.hpp @@ -18,6 +18,8 @@ using longport::quote::CapitalDistributionResponse; using longport::quote::CapitalFlowLine; using longport::quote::Depth; using longport::quote::DerivativeType; +using longport::quote::FilterWarrantExpiryDate; +using longport::quote::FilterWarrantInOutBoundsType; using longport::quote::IntradayLine; using longport::quote::IssuerInfo; using longport::quote::MarketTradingDays; @@ -41,6 +43,7 @@ using longport::quote::SecurityCalcIndex; using longport::quote::SecurityDepth; using longport::quote::SecurityQuote; using longport::quote::SecurityStaticInfo; +using longport::quote::SortOrderType; using longport::quote::StrikePriceInfo; using longport::quote::SubFlags; using longport::quote::Subscription; @@ -49,7 +52,10 @@ using longport::quote::TradeDirection; using longport::quote::TradeSession; using longport::quote::TradeStatus; using longport::quote::TradingSessionInfo; +using longport::quote::WarrantInfo; using longport::quote::WarrantQuote; +using longport::quote::WarrantSortBy; +using longport::quote::WarrantStatus; using longport::quote::WarrantType; using longport::quote::WatchlistGroup; using longport::quote::WatchlistSecurity; @@ -627,6 +633,27 @@ convert(lb_warrant_type_t ty) } } +inline lb_warrant_type_t +convert(WarrantType ty) +{ + switch (ty) { + case WarrantType::Unknown: + return WarrantTypeUnknown; + case WarrantType::Put: + return WarrantTypePut; + case WarrantType::Call: + return WarrantTypeCall; + case WarrantType::Bull: + return WarrantTypeBull; + case WarrantType::Bear: + return WarrantTypeBear; + case WarrantType::Inline: + return WarrantTypeInline; + default: + throw std::invalid_argument("unreachable"); + } +} + inline WarrantQuote convert(const lb_warrant_quote_t* quote) { @@ -1724,31 +1751,39 @@ convert(const lb_security_calc_index_t* resp) resp->last_done ? std::optional{ Decimal(resp->last_done) } : std::nullopt, resp->change_value ? std::optional{ Decimal(resp->change_value) } : std::nullopt, - resp->change_rate ? std::optional{ *resp->change_rate } : std::nullopt, + resp->change_rate ? std::optional{ Decimal(resp->change_rate) } + : std::nullopt, resp->volume ? std::optional{ *resp->volume } : std::nullopt, resp->turnover ? std::optional{ Decimal(resp->turnover) } : std::nullopt, - resp->ytd_change_rate ? std::optional{ *resp->ytd_change_rate } + resp->ytd_change_rate ? std::optional{ Decimal(resp->ytd_change_rate) } : std::nullopt, - resp->turnover_rate ? std::optional{ *resp->turnover_rate } : std::nullopt, + resp->turnover_rate ? std::optional{ Decimal(resp->turnover_rate) } + : std::nullopt, resp->total_market_value ? std::optional{ Decimal(resp->total_market_value) } : std::nullopt, resp->capital_flow ? std::optional{ Decimal(resp->capital_flow) } : std::nullopt, - resp->amplitude ? std::optional{ *resp->amplitude } : std::nullopt, - resp->volume_ratio ? std::optional{ *resp->volume_ratio } : std::nullopt, - resp->pe_ttm_ratio ? std::optional{ *resp->pe_ttm_ratio } : std::nullopt, - resp->pb_ratio ? std::optional{ *resp->pb_ratio } : std::nullopt, - resp->dividend_ratio_ttm ? std::optional{ *resp->dividend_ratio_ttm } - : std::nullopt, - resp->five_day_change_rate ? std::optional{ *resp->five_day_change_rate } - : std::nullopt, - resp->ten_day_change_rate ? std::optional{ *resp->ten_day_change_rate } - : std::nullopt, - resp->half_year_change_rate ? std::optional{ *resp->half_year_change_rate } - : std::nullopt, + resp->amplitude ? std::optional{ Decimal(resp->amplitude) } : std::nullopt, + resp->volume_ratio ? std::optional{ Decimal(resp->volume_ratio) } + : std::nullopt, + resp->pe_ttm_ratio ? std::optional{ Decimal(resp->pe_ttm_ratio) } + : std::nullopt, + resp->pb_ratio ? std::optional{ Decimal(resp->pb_ratio) } : std::nullopt, + resp->dividend_ratio_ttm + ? std::optional{ Decimal(resp->dividend_ratio_ttm) } + : std::nullopt, + resp->five_day_change_rate + ? std::optional{ Decimal(resp->five_day_change_rate) } + : std::nullopt, + resp->ten_day_change_rate + ? std::optional{ Decimal(resp->ten_day_change_rate) } + : std::nullopt, + resp->half_year_change_rate + ? std::optional{ Decimal(resp->half_year_change_rate) } + : std::nullopt, resp->five_minutes_change_rate - ? std::optional{ *resp->five_minutes_change_rate } + ? std::optional{ Decimal(resp->five_minutes_change_rate) } : std::nullopt, resp->expiry_date ? std::optional{ convert(resp->expiry_date) } : std::nullopt, @@ -1762,30 +1797,200 @@ convert(const lb_security_calc_index_t* resp) : std::nullopt, resp->outstanding_qty ? std::optional{ *resp->outstanding_qty } : std::nullopt, - resp->outstanding_ratio ? std::optional{ *resp->outstanding_ratio } + resp->outstanding_ratio ? std::optional{ Decimal(resp->outstanding_ratio) } : std::nullopt, - resp->premium ? std::optional{ *resp->premium } : std::nullopt, - resp->itm_otm ? std::optional{ *resp->itm_otm } : std::nullopt, - resp->implied_volatility ? std::optional{ *resp->implied_volatility } - : std::nullopt, - resp->warrant_delta ? std::optional{ *resp->warrant_delta } : std::nullopt, + resp->premium ? std::optional{ Decimal(resp->premium) } : std::nullopt, + resp->itm_otm ? std::optional{ Decimal(resp->itm_otm) } : std::nullopt, + resp->implied_volatility + ? std::optional{ Decimal(resp->implied_volatility) } + : std::nullopt, + resp->warrant_delta ? std::optional{ Decimal(resp->warrant_delta) } + : std::nullopt, resp->call_price ? std::optional{ Decimal(resp->call_price) } : std::nullopt, resp->to_call_price ? std::optional{ Decimal(resp->to_call_price) } : std::nullopt, - resp->effective_leverage ? std::optional{ *resp->effective_leverage } - : std::nullopt, - resp->leverage_ratio ? std::optional{ *resp->leverage_ratio } + resp->effective_leverage + ? std::optional{ Decimal(resp->effective_leverage) } + : std::nullopt, + resp->leverage_ratio ? std::optional{ Decimal(resp->leverage_ratio) } : std::nullopt, - resp->conversion_ratio ? std::optional{ *resp->conversion_ratio } + resp->conversion_ratio ? std::optional{ Decimal(resp->conversion_ratio) } : std::nullopt, - resp->balance_point ? std::optional{ *resp->balance_point } : std::nullopt, + resp->balance_point ? std::optional{ Decimal(resp->balance_point) } + : std::nullopt, resp->open_interest ? std::optional{ *resp->open_interest } : std::nullopt, - resp->delta ? std::optional{ *resp->delta } : std::nullopt, - resp->gamma ? std::optional{ *resp->gamma } : std::nullopt, - resp->theta ? std::optional{ *resp->theta } : std::nullopt, - resp->vega ? std::optional{ *resp->vega } : std::nullopt, - resp->rho ? std::optional{ *resp->rho } : std::nullopt, + resp->delta ? std::optional{ Decimal(resp->delta) } : std::nullopt, + resp->gamma ? std::optional{ Decimal(resp->gamma) } : std::nullopt, + resp->theta ? std::optional{ Decimal(resp->theta) } : std::nullopt, + resp->vega ? std::optional{ Decimal(resp->vega) } : std::nullopt, + resp->rho ? std::optional{ Decimal(resp->rho) } : std::nullopt, + }; +} + +inline lb_sort_order_type_t +convert(SortOrderType ty) +{ + switch (ty) { + case SortOrderType::Ascending: + return SortOrderAscending; + case SortOrderType::Descending: + return SortOrderDescending; + default: + throw std::invalid_argument("unreachable"); + } +} + +inline lb_warrant_sort_by_t +convert(WarrantSortBy ty) +{ + switch (ty) { + case WarrantSortBy::LastDone: + return WarrantSortByLastDone; + case WarrantSortBy::ChangeRate: + return WarrantSortByChangeRate; + case WarrantSortBy::ChangeValue: + return WarrantSortByChangeValue; + case WarrantSortBy::Volume: + return WarrantSortByVolume; + case WarrantSortBy::Turnover: + return WarrantSortByTurnover; + case WarrantSortBy::ExpiryDate: + return WarrantSortByExpiryDate; + case WarrantSortBy::StrikePrice: + return WarrantSortByStrikePrice; + case WarrantSortBy::UpperStrikePrice: + return WarrantSortByUpperStrikePrice; + case WarrantSortBy::LowerStrikePrice: + return WarrantSortByLowerStrikePrice; + case WarrantSortBy::OutstandingQuantity: + return WarrantSortByOutstandingQuantity; + case WarrantSortBy::OutstandingRatio: + return WarrantSortByOutstandingRatio; + case WarrantSortBy::Premium: + return WarrantSortByPremium; + case WarrantSortBy::ItmOtm: + return WarrantSortByItmOtm; + case WarrantSortBy::ImpliedVolatility: + return WarrantSortByImpliedVolatility; + case WarrantSortBy::Delta: + return WarrantSortByDelta; + case WarrantSortBy::CallPrice: + return WarrantSortByCallPrice; + case WarrantSortBy::ToCallPrice: + return WarrantSortByToCallPrice; + case WarrantSortBy::EffectiveLeverage: + return WarrantSortByEffectiveLeverage; + case WarrantSortBy::LeverageRatio: + return WarrantSortByLeverageRatio; + case WarrantSortBy::ConversionRatio: + return WarrantSortByConversionRatio; + case WarrantSortBy::BalancePoint: + return WarrantSortByBalancePoint; + case WarrantSortBy::Status: + return WarrantSortByStatus; + default: + throw std::invalid_argument("unreachable"); + } +} + +inline lb_filter_warrant_expiry_date_t +convert(FilterWarrantExpiryDate ty) +{ + switch (ty) { + case FilterWarrantExpiryDate::LT_3: + return WarrantExpiryDate_LT_3; + case FilterWarrantExpiryDate::Between_3_6: + return WarrantExpiryDate_Between_3_6; + case FilterWarrantExpiryDate::Between_6_12: + return WarrantExpiryDate_Between_6_12; + case FilterWarrantExpiryDate::GT_12: + return WarrantExpiryDate_GT_12; + default: + throw std::invalid_argument("unreachable"); + } +} + +inline lb_filter_warrant_in_out_bounds_type_t +convert(FilterWarrantInOutBoundsType ty) +{ + switch (ty) { + case FilterWarrantInOutBoundsType::In: + return WarrantInOutBoundsType_In; + case FilterWarrantInOutBoundsType::Out: + return WarrantInOutBoundsType_Out; + default: + throw std::invalid_argument("unreachable"); + } +} + +inline lb_warrant_status_t +convert(WarrantStatus ty) +{ + switch (ty) { + case WarrantStatus::Suspend: + return WarrantStatusSuspend; + case WarrantStatus::PrepareList: + return WarrantStatusPrepareList; + case WarrantStatus::Normal: + return WarrantStatusNormal; + default: + throw std::invalid_argument("unreachable"); + } +} + +inline WarrantStatus +convert(lb_warrant_status_t ty) +{ + switch (ty) { + case WarrantStatusSuspend: + return WarrantStatus::Suspend; + case WarrantStatusPrepareList: + return WarrantStatus::PrepareList; + case WarrantStatusNormal: + return WarrantStatus::Normal; + default: + throw std::invalid_argument("unreachable"); + } +} + +inline WarrantInfo +convert(lb_warrant_info_t info) +{ + return WarrantInfo{ + info.symbol, + convert(info.warrant_type), + info.name, + Decimal(info.last_done), + Decimal(info.change_rate), + Decimal(info.change_value), + info.volume, + Decimal(info.turnover), + convert(&info.expiry_date), + info.strike_price ? std::optional{ Decimal(info.strike_price) } + : std::nullopt, + info.upper_strike_price ? std::optional{ Decimal(info.upper_strike_price) } + : std::nullopt, + info.lower_strike_price ? std::optional{ Decimal(info.lower_strike_price) } + : std::nullopt, + info.outstanding_qty, + Decimal(info.outstanding_ratio), + Decimal(info.premium), + info.itm_otm ? std::optional{ Decimal(info.itm_otm) } : std::nullopt, + info.implied_volatility ? std::optional{ Decimal(info.implied_volatility) } + : std::nullopt, + info.delta ? std::optional{ Decimal(info.delta) } : std::nullopt, + info.call_price ? std::optional{ Decimal(info.call_price) } : std::nullopt, + info.to_call_price ? std::optional{ Decimal(info.to_call_price) } + : std::nullopt, + info.effective_leverage ? std::optional{ Decimal(info.effective_leverage) } + : std::nullopt, + Decimal(info.leverage_ratio), + info.conversion_ratio ? std::optional{ Decimal(info.conversion_ratio) } + : std::nullopt, + info.balance_point ? std::optional{ Decimal(info.balance_point) } + : std::nullopt, + convert(info.status), }; } diff --git a/cpp/src/quote_context.cpp b/cpp/src/quote_context.cpp index 32fdb63f9..2e843736c 100644 --- a/cpp/src/quote_context.cpp +++ b/cpp/src/quote_context.cpp @@ -837,6 +837,82 @@ QuoteContext::warrant_issuers( new AsyncCallback>(callback)); } +void +QuoteContext::warrant_list( + const std::string& symbol, + WarrantSortBy sort_by, + SortOrderType sort_order, + const std::vector& warrant_type, + const std::vector& issuer, + const std::vector& expiry_date, + const std::vector& price_type, + const std::vector& status, + AsyncCallback> callback) const +{ + std::vector c_warrant_type; + std::transform(warrant_type.cbegin(), + warrant_type.cend(), + std::back_inserter(c_warrant_type), + [](auto row) { return convert(row); }); + + std::vector c_expiry_date; + std::transform(expiry_date.cbegin(), + expiry_date.cend(), + std::back_inserter(c_expiry_date), + [](auto row) { return convert(row); }); + + std::vector c_price_type; + std::transform(price_type.cbegin(), + price_type.cend(), + std::back_inserter(c_price_type), + [](auto row) { return convert(row); }); + + std::vector c_status; + std::transform(status.cbegin(), + status.cend(), + std::back_inserter(c_status), + [](auto row) { return convert(row); }); + + lb_quote_context_warrant_list( + ctx_, + symbol.c_str(), + convert(sort_by), + convert(sort_order), + c_warrant_type.data(), + c_warrant_type.size(), + issuer.data(), + issuer.size(), + c_expiry_date.data(), + c_expiry_date.size(), + c_price_type.data(), + c_price_type.size(), + c_status.data(), + c_status.size(), + [](auto res) { + auto callback_ptr = + callback::get_async_callback>( + res->userdata); + QuoteContext ctx((const lb_quote_context_t*)res->ctx); + Status status(res->error); + + if (status) { + auto rows = (const lb_warrant_info_t*)res->data; + std::vector rows2; + std::transform(rows, + rows + res->length, + std::back_inserter(rows2), + [](auto row) { return convert(row); }); + + (*callback_ptr)(AsyncResult>( + ctx, std::move(status), &rows2)); + } else { + (*callback_ptr)(AsyncResult>( + ctx, std::move(status), nullptr)); + } + }, + new AsyncCallback>(callback)); +} + void QuoteContext::trading_session( AsyncCallback> callback) const @@ -1016,13 +1092,6 @@ QuoteContext::calc_indexes( new AsyncCallback>(callback)); } -void -QuoteContext::watch_list( - AsyncCallback> callback) const -{ - watchlist(callback); -} - void QuoteContext::watchlist( AsyncCallback> callback) const 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 87f7d3cd9..c2712f321 100644 --- a/java/javasrc/src/main/java/com/longport/quote/QuoteContext.java +++ b/java/javasrc/src/main/java/com/longport/quote/QuoteContext.java @@ -795,19 +795,6 @@ public CompletableFuture getCalcIndexes(String[] symbols, C }); } - /** - * Get watchlist - * - * Deprecated: Use `getWatchlist` instead - */ - @Deprecated - public CompletableFuture getWatchList() - throws OpenApiException { - return AsyncCallback.executeTask((callback) -> { - SdkNative.quoteContextWatchlist(this.raw, callback); - }); - } - /** * Get watchlist * diff --git a/java/javasrc/src/main/java/com/longport/quote/SecurityCalcIndex.java b/java/javasrc/src/main/java/com/longport/quote/SecurityCalcIndex.java index 85683df41..a17024741 100644 --- a/java/javasrc/src/main/java/com/longport/quote/SecurityCalcIndex.java +++ b/java/javasrc/src/main/java/com/longport/quote/SecurityCalcIndex.java @@ -11,37 +11,37 @@ public class SecurityCalcIndex { /// Change value private BigDecimal changeValue; /// Change ratio - private double changeRate; + private BigDecimal changeRate; /// Volume private long volume; /// Turnover private BigDecimal turnover; /// Year-to-date change ratio - private double ytdChangeRate; + private BigDecimal ytdChangeRate; /// Turnover rate - private double turnoverRate; + private BigDecimal turnoverRate; /// Total market value private BigDecimal totalMarketValue; /// Capital flow private BigDecimal capitalFlow; /// Amplitude - private double amplitude; + private BigDecimal amplitude; /// Volume ratio - private double volumeRatio; + private BigDecimal volumeRatio; /// PE (TTM) - private double peTtmRatio; + private BigDecimal peTtmRatio; /// PB - private double pbRatio; + private BigDecimal pbRatio; /// Dividend ratio (TTM) - private double dividendRatioTtm; + private BigDecimal dividendRatioTtm; /// Five days change ratio - private double fiveDayChangeRate; + private BigDecimal fiveDayChangeRate; /// Ten days change ratio - private double tenDayChangeRate; + private BigDecimal tenDayChangeRate; /// Half year change ratio - private double halfYearChangeRate; + private BigDecimal halfYearChangeRate; /// Five minutes change ratio - private double fiveMinutesChangeRate; + private BigDecimal fiveMinutesChangeRate; /// Expiry date private LocalDate expiryDate; /// Strike price @@ -53,39 +53,39 @@ public class SecurityCalcIndex { /// Outstanding quantity private long outstandingQty; /// Outstanding ratio - private double outstandingRatio; + private BigDecimal outstandingRatio; /// Premium - private double premium; + private BigDecimal premium; /// In/out of the bound - private double itmOtm; + private BigDecimal itmOtm; /// Implied volatility - private double impliedVolatility; + private BigDecimal impliedVolatility; /// Warrant delta - private double warrantDelta; + private BigDecimal warrantDelta; /// Call price private BigDecimal callPrice; /// Price interval from the call price private BigDecimal toCallPrice; /// Effective leverage - private double effectiveLeverage; + private BigDecimal effectiveLeverage; /// Leverage ratio - private double leverageRatio; + private BigDecimal leverageRatio; /// Conversion ratio - private double conversionRatio; + private BigDecimal conversionRatio; /// Breakeven point - private double balancePoint; + private BigDecimal balancePoint; /// Open interest private long openInterest; /// Delta - private double delta; + private BigDecimal delta; /// Gamma - private double gamma; + private BigDecimal gamma; /// Theta - private double theta; + private BigDecimal theta; /// Vega - private double vega; + private BigDecimal vega; /// Rho - private double rho; + private BigDecimal rho; public String getSymbol() { return symbol; @@ -99,7 +99,7 @@ public BigDecimal getChangeValue() { return changeValue; } - public double getChangeRate() { + public BigDecimal getChangeRate() { return changeRate; } @@ -111,11 +111,11 @@ public BigDecimal getTurnover() { return turnover; } - public double getYtdChangeRate() { + public BigDecimal getYtdChangeRate() { return ytdChangeRate; } - public double getTurnoverRate() { + public BigDecimal getTurnoverRate() { return turnoverRate; } @@ -127,39 +127,39 @@ public BigDecimal getCapitalFlow() { return capitalFlow; } - public double getAmplitude() { + public BigDecimal getAmplitude() { return amplitude; } - public double getVolumeRatio() { + public BigDecimal getVolumeRatio() { return volumeRatio; } - public double getPeTtmRatio() { + public BigDecimal getPeTtmRatio() { return peTtmRatio; } - public double getPbRatio() { + public BigDecimal getPbRatio() { return pbRatio; } - public double getDividendRatioTtm() { + public BigDecimal getDividendRatioTtm() { return dividendRatioTtm; } - public double getFiveDayChangeRate() { + public BigDecimal getFiveDayChangeRate() { return fiveDayChangeRate; } - public double getTenDayChangeRate() { + public BigDecimal getTenDayChangeRate() { return tenDayChangeRate; } - public double getHalfYearChangeRate() { + public BigDecimal getHalfYearChangeRate() { return halfYearChangeRate; } - public double getFiveMinutesChangeRate() { + public BigDecimal getFiveMinutesChangeRate() { return fiveMinutesChangeRate; } @@ -183,23 +183,23 @@ public long getOutstandingQty() { return outstandingQty; } - public double getOutstandingRatio() { + public BigDecimal getOutstandingRatio() { return outstandingRatio; } - public double getPremium() { + public BigDecimal getPremium() { return premium; } - public double getItmOtm() { + public BigDecimal getItmOtm() { return itmOtm; } - public double getImpliedVolatility() { + public BigDecimal getImpliedVolatility() { return impliedVolatility; } - public double getWarrantDelta() { + public BigDecimal getWarrantDelta() { return warrantDelta; } @@ -211,19 +211,19 @@ public BigDecimal getToCallPrice() { return toCallPrice; } - public double getEffectiveLeverage() { + public BigDecimal getEffectiveLeverage() { return effectiveLeverage; } - public double getLeverageRatio() { + public BigDecimal getLeverageRatio() { return leverageRatio; } - public double getConversionRatio() { + public BigDecimal getConversionRatio() { return conversionRatio; } - public double getBalancePoint() { + public BigDecimal getBalancePoint() { return balancePoint; } @@ -231,23 +231,23 @@ public long getOpenInterest() { return openInterest; } - public double getDelta() { + public BigDecimal getDelta() { return delta; } - public double getGamma() { + public BigDecimal getGamma() { return gamma; } - public double getTheta() { + public BigDecimal getTheta() { return theta; } - public double getVega() { + public BigDecimal getVega() { return vega; } - public double getRho() { + public BigDecimal getRho() { return rho; } @@ -269,4 +269,5 @@ public String toString() { + balancePoint + ", openInterest=" + openInterest + ", delta=" + delta + ", gamma=" + gamma + ", theta=" + theta + ", vega=" + vega + ", rho=" + rho + "]"; } + } diff --git a/java/src/types/classes.rs b/java/src/types/classes.rs index faa50c773..caf6ae40d 100644 --- a/java/src/types/classes.rs +++ b/java/src/types/classes.rs @@ -303,44 +303,44 @@ pub(crate) struct SecurityCalcIndex { pub(crate) symbol: String, pub(crate) last_done: Option, pub(crate) change_value: Option, - pub(crate) change_rate: f64, + pub(crate) change_rate: Option, pub(crate) volume: i64, pub(crate) turnover: Option, - pub(crate) ytd_change_rate: f64, - pub(crate) turnover_rate: f64, + pub(crate) ytd_change_rate: Option, + pub(crate) turnover_rate: Option, pub(crate) total_market_value: Option, pub(crate) capital_flow: Option, - pub(crate) amplitude: f64, - pub(crate) volume_ratio: f64, - pub(crate) pe_ttm_ratio: f64, - pub(crate) pb_ratio: f64, - pub(crate) dividend_ratio_ttm: f64, - pub(crate) five_day_change_rate: f64, - pub(crate) ten_day_change_rate: f64, - pub(crate) half_year_change_rate: f64, - pub(crate) five_minutes_change_rate: f64, + pub(crate) amplitude: Option, + pub(crate) volume_ratio: Option, + pub(crate) pe_ttm_ratio: Option, + pub(crate) pb_ratio: Option, + pub(crate) dividend_ratio_ttm: Option, + pub(crate) five_day_change_rate: Option, + pub(crate) ten_day_change_rate: Option, + pub(crate) half_year_change_rate: Option, + pub(crate) five_minutes_change_rate: Option, pub(crate) expiry_date: Option, pub(crate) strike_price: Option, pub(crate) upper_strike_price: Option, pub(crate) lower_strike_price: Option, pub(crate) outstanding_qty: i64, - pub(crate) outstanding_ratio: f64, - pub(crate) premium: f64, - pub(crate) itm_otm: f64, - pub(crate) implied_volatility: f64, - pub(crate) warrant_delta: f64, + pub(crate) outstanding_ratio: Option, + pub(crate) premium: Option, + pub(crate) itm_otm: Option, + pub(crate) implied_volatility: Option, + pub(crate) warrant_delta: Option, pub(crate) call_price: Option, pub(crate) to_call_price: Option, - pub(crate) effective_leverage: f64, - pub(crate) leverage_ratio: f64, - pub(crate) conversion_ratio: f64, - pub(crate) balance_point: f64, + pub(crate) effective_leverage: Option, + pub(crate) leverage_ratio: Option, + pub(crate) conversion_ratio: Option, + pub(crate) balance_point: Option, pub(crate) open_interest: i64, - pub(crate) delta: f64, - pub(crate) gamma: f64, - pub(crate) theta: f64, - pub(crate) vega: f64, - pub(crate) rho: f64, + pub(crate) delta: Option, + pub(crate) gamma: Option, + pub(crate) theta: Option, + pub(crate) vega: Option, + pub(crate) rho: Option, } impl From for SecurityCalcIndex { @@ -393,44 +393,44 @@ impl From for SecurityCalcIndex { symbol, last_done, change_value, - change_rate: change_rate.unwrap_or_default(), + change_rate, volume: volume.unwrap_or_default(), turnover, - ytd_change_rate: ytd_change_rate.unwrap_or_default(), - turnover_rate: turnover_rate.unwrap_or_default(), + ytd_change_rate, + turnover_rate, total_market_value, capital_flow, - amplitude: amplitude.unwrap_or_default(), - volume_ratio: volume_ratio.unwrap_or_default(), - pe_ttm_ratio: pe_ttm_ratio.unwrap_or_default(), - pb_ratio: pb_ratio.unwrap_or_default(), - dividend_ratio_ttm: dividend_ratio_ttm.unwrap_or_default(), - five_day_change_rate: five_day_change_rate.unwrap_or_default(), - ten_day_change_rate: ten_day_change_rate.unwrap_or_default(), - half_year_change_rate: half_year_change_rate.unwrap_or_default(), - five_minutes_change_rate: five_minutes_change_rate.unwrap_or_default(), + amplitude, + volume_ratio, + pe_ttm_ratio, + pb_ratio, + dividend_ratio_ttm, + five_day_change_rate, + ten_day_change_rate, + half_year_change_rate, + five_minutes_change_rate, expiry_date, strike_price, upper_strike_price, lower_strike_price, outstanding_qty: outstanding_qty.unwrap_or_default(), - outstanding_ratio: outstanding_ratio.unwrap_or_default(), - premium: premium.unwrap_or_default(), - itm_otm: itm_otm.unwrap_or_default(), - implied_volatility: implied_volatility.unwrap_or_default(), - warrant_delta: warrant_delta.unwrap_or_default(), + outstanding_ratio, + premium, + itm_otm, + implied_volatility, + warrant_delta, call_price, to_call_price, - effective_leverage: effective_leverage.unwrap_or_default(), - leverage_ratio: leverage_ratio.unwrap_or_default(), - conversion_ratio: conversion_ratio.unwrap_or_default(), - balance_point: balance_point.unwrap_or_default(), + effective_leverage, + leverage_ratio, + conversion_ratio, + balance_point, open_interest: open_interest.unwrap_or_default(), - delta: delta.unwrap_or_default(), - gamma: gamma.unwrap_or_default(), - theta: theta.unwrap_or_default(), - vega: vega.unwrap_or_default(), - rho: rho.unwrap_or_default(), + delta, + gamma, + theta, + vega, + rho, } } } diff --git a/nodejs/Cargo.toml b/nodejs/Cargo.toml index fe26dd1f8..8e147b14d 100644 --- a/nodejs/Cargo.toml +++ b/nodejs/Cargo.toml @@ -10,13 +10,13 @@ crate-type = ["cdylib"] longport = { path = "../rust" } longport-nodejs-macros = { path = "crates/macros" } -napi = { version = "2.14.1", default-features = false, features = [ +napi = { version = "2.16.1", default-features = false, features = [ "napi4", "chrono_date", "async", "serde-json", ] } -napi-derive = "2.14.1" +napi-derive = "2.16.1" rust_decimal = { version = "1.23.1", features = ["maths"] } chrono = "0.4.19" time = { version = "0.3.9", features = ["macros", "formatting"] } diff --git a/nodejs/index.d.ts b/nodejs/index.d.ts index a31244575..e9d9a9ed6 100644 --- a/nodejs/index.d.ts +++ b/nodejs/index.d.ts @@ -227,6 +227,87 @@ export const enum SecurityBoard { /** SG Industry Board */ SGSector = 24 } +/** Sort order type */ +export const enum SortOrderType { + /** Ascending */ + Ascending = 0, + /** Descending */ + Descending = 1 +} +/** Warrant sort by */ +export const enum WarrantSortBy { + /** Last done */ + LastDone = 0, + /** Change rate */ + ChangeRate = 1, + /** Change value */ + ChangeValue = 2, + /** Volume */ + Volume = 3, + /** Turnover */ + Turnover = 4, + /** Expiry date */ + ExpiryDate = 5, + /** Strike price */ + StrikePrice = 6, + /** Upper strike price */ + UpperStrikePrice = 7, + /** Lower strike price */ + LowerStrikePrice = 8, + /** Outstanding quantity */ + OutstandingQuantity = 9, + /** Outstanding ratio */ + OutstandingRatio = 10, + /** Premium */ + Premium = 11, + /** In/out of the bound */ + ItmOtm = 12, + /** Implied volatility */ + ImpliedVolatility = 13, + /** Greek value delta */ + Delta = 14, + /** Call price */ + CallPrice = 15, + /** Price interval from the call price */ + ToCallPrice = 16, + /** Effective leverage */ + EffectiveLeverage = 17, + /** Leverage ratio */ + LeverageRatio = 18, + /** Conversion ratio */ + ConversionRatio = 19, + /** Breakeven point */ + BalancePoint = 20, + /** Status */ + Status = 21 +} +/** Filter warrant expiry date type */ +export const enum FilterWarrantExpiryDate { + /** Less than 3 months */ + LT_3 = 0, + /** 3 - 6 months */ + Between_3_6 = 1, + /** 6 - 12 months */ + Between_6_12 = 2, + /** Greater than 12 months */ + GT_12 = 3 +} +/** Filter warrant in/out of the bounds type */ +export const enum FilterWarrantInOutBoundsType { + /** In bounds */ + In = 0, + /** Out bounds */ + Out = 1 +} +/** Warrant status */ +export const enum WarrantStatus { + /** Suspend */ + Suspend = 0, + /** Prepare List */ + PrepareList = 1, + /** Normal */ + Normal = 2 +} /** Securities update mode */ export const enum SecuritiesUpdateMode { /** Add securities */ @@ -1162,6 +1243,23 @@ export class QuoteContext { * ``` */ warrantIssuers(): Promise> + /** + * Query warrant list + * + * #### Example + * ```javascript + * const { Config, QuoteContext, WarrantSortBy, SortOrderType } = require("longport") + * let config = Config.fromEnv() + * QuoteContext.new(config) + * .then((ctx) => ctx.warrantList("700.HK", WarrantSortBy.LastDone, SortOrderType.Asc)) + * .then((resp) => { + * for (let obj of resp) { + * console.log(obj.toString()) + * } + * }) + * ``` + */ + warrantList(symbol: string, sortBy: WarrantSortBy, sortOrder: SortOrderType, warrantType?: Array | undefined | null, issuer?: Array | undefined | null, expiryDate?: Array | undefined | null, priceType?: Array | undefined | null, status?: Array | undefined | null): Promise> /** * Get trading session of the day * @@ -1230,18 +1328,8 @@ export class QuoteContext { * ``` */ capitalDistribution(symbol: string): Promise - /** - * Get watchlist - * - * Deprecated: use `watchlist` instead - */ + /** Get calc indexes */ calcIndexes(symbols: Array, indexes: Array): Promise> - /** - * Get watchlist - * - * Deprecated: use `watchlist` instead - */ - watchList(): Promise> /** * Get watchlist * @@ -1745,6 +1833,60 @@ export class IssuerInfo { /** Issuer name (zh-HK) */ get nameHk(): string } +/** Warrant info */ +export class WarrantInfo { + toString(): string + /** Security code */ + get symbol(): string + /** Warrant type */ + get warrantType(): WarrantType + /** Security name */ + get name(): string + /** Latest price */ + get lastDone(): Decimal + /** Quote change rate */ + get changeRate(): Decimal + /** Quote change */ + get changeVal(): Decimal + /** Volume */ + get volume(): number + /** Turnover */ + get turnover(): Decimal + /** Expiry date */ + get expiryDate(): NaiveDate + /** Strike price */ + get strikePrice(): Decimal | null + /** Upper strike price */ + get upperStrikePrice(): Decimal | null + /** Lower strike price */ + get lowerStrikePrice(): Decimal | null + /** Outstanding quantity */ + get outstandingQty(): number + /** Outstanding ratio */ + get outstandingRatio(): Decimal + /** Premium */ + get premium(): Decimal + /** In/out of the bound */ + get itmOtm(): Decimal | null + /** Implied volatility */ + get impliedVolatility(): Decimal | null + /** Delta */ + get delta(): Decimal | null + /** Call price */ + get callPrice(): Decimal | null + /** Price interval from the call price */ + get toCallPrice(): Decimal | null + /** Effective leverage */ + get effectiveLeverage(): Decimal | null + /** Leverage ratio */ + get leverageRatio(): Decimal + /** Conversion ratio */ + get conversionRatio(): Decimal | null + /** Breakeven point */ + get balancePoint(): Decimal | null + /** Status */ + get status(): WarrantStatus +} /** The information of trading session */ export class TradingSessionInfo { toString(): string @@ -1907,37 +2049,37 @@ export class SecurityCalcIndex { /** Change value */ get changeValue(): Decimal | null /** Change ratio */ - get changeRate(): number | null + get changeRate(): Decimal | null /** Volume */ get volume(): number | null /** Turnover */ get turnover(): Decimal | null /** Year-to-date change ratio */ - get ytdChangeRate(): number | null + get ytdChangeRate(): Decimal | null /** Turnover rate */ - get turnoverRate(): number | null + get turnoverRate(): Decimal | null /** Total market value */ get totalMarketValue(): Decimal | null /** Capital flow */ get capitalFlow(): Decimal | null /** Amplitude */ - get amplitude(): number | null + get amplitude(): Decimal | null /** Volume ratio */ - get volumeRatio(): number | null + get volumeRatio(): Decimal | null /** PE (TTM) */ - get peTtmRatio(): number | null + get peTtmRatio(): Decimal | null /** PB */ - get pbRatio(): number | null + get pbRatio(): Decimal | null /** Dividend ratio (TTM) */ - get dividendRatioTtm(): number | null + get dividendRatioTtm(): Decimal | null /** Five days change ratio */ - get fiveDayChangeRate(): number | null + get fiveDayChangeRate(): Decimal | null /** Ten days change ratio */ - get tenDayChangeRate(): number | null + get tenDayChangeRate(): Decimal | null /** Half year change ratio */ - get halfYearChangeRate(): number | null + get halfYearChangeRate(): Decimal | null /** Five minutes change ratio */ - get fiveMinutesChangeRate(): number | null + get fiveMinutesChangeRate(): Decimal | null /** Expiry date */ get expiryDate(): NaiveDate | null /** Strike price */ @@ -1949,39 +2091,39 @@ export class SecurityCalcIndex { /** Outstanding quantity */ get outstandingQty(): number | null /** Outstanding ratio */ - get outstandingRatio(): number | null + get outstandingRatio(): Decimal | null /** Premium */ - get premium(): number | null + get premium(): Decimal | null /** In/out of the bound */ - get itmOtm(): number | null + get itmOtm(): Decimal | null /** Implied volatility */ - get impliedVolatility(): number | null + get impliedVolatility(): Decimal | null /** Warrant delta */ - get warrantDelta(): number | null + get warrantDelta(): Decimal | null /** Call price */ get callPrice(): Decimal | null /** Price interval from the call price */ get toCallPrice(): Decimal | null /** Effective leverage */ - get effectiveLeverage(): number | null + get effectiveLeverage(): Decimal | null /** Leverage ratio */ - get leverageRatio(): number | null + get leverageRatio(): Decimal | null /** Conversion ratio */ - get conversionRatio(): number | null + get conversionRatio(): Decimal | null /** Breakeven point */ - get balancePoint(): number | null + get balancePoint(): Decimal | null /** Open interest */ get openInterest(): number | null /** Delta */ - get delta(): number | null + get delta(): Decimal | null /** Gamma */ - get gamma(): number | null + get gamma(): Decimal | null /** Theta */ - get theta(): number | null + get theta(): Decimal | null /** Vega */ - get vega(): number | null + get vega(): Decimal | null /** Rho */ - get rho(): number | null + get rho(): Decimal | null } /** Naive date type */ export class NaiveDate { @@ -2737,7 +2879,7 @@ export class StockPosition { /** Market */ get market(): Market /** Initial position before market opening */ - get initQuantity(): Decimal | null + get initQuantity(): number | null } /** Margin ratio */ export class MarginRatio { diff --git a/nodejs/index.js b/nodejs/index.js index 87c64eec8..00b26f559 100644 --- a/nodejs/index.js +++ b/nodejs/index.js @@ -295,7 +295,7 @@ if (!nativeBinding) { throw new Error(`Failed to load native binding`) } -const { Config, Decimal, HttpClient, QuoteContext, PushQuoteEvent, PushDepthEvent, PushBrokersEvent, PushTradesEvent, PushCandlestickEvent, Subscription, DerivativeType, TradeStatus, TradeSession, SubType, TradeDirection, OptionType, OptionDirection, WarrantType, Period, AdjustType, SecurityBoard, SecurityStaticInfo, PrePostQuote, SecurityQuote, OptionQuote, WarrantQuote, Depth, SecurityDepth, Brokers, SecurityBrokers, ParticipantInfo, Trade, IntradayLine, Candlestick, StrikePriceInfo, IssuerInfo, TradingSessionInfo, MarketTradingSession, RealtimeQuote, PushQuote, PushDepth, PushBrokers, PushTrades, PushCandlestick, MarketTradingDays, CapitalFlowLine, CapitalDistribution, CapitalDistributionResponse, WatchlistGroup, WatchlistSecurity, SecuritiesUpdateMode, CalcIndex, SecurityCalcIndex, NaiveDate, Time, NaiveDatetime, TradeContext, TopicType, Execution, OrderStatus, OrderSide, OrderType, OrderTag, TimeInForceType, TriggerStatus, OutsideRTH, Order, CommissionFreeStatus, DeductionStatus, ChargeCategoryCode, OrderHistoryDetail, OrderChargeFee, OrderChargeItem, OrderChargeDetail, OrderDetail, PushOrderChanged, SubmitOrderResponse, CashInfo, AccountBalance, BalanceType, CashFlowDirection, CashFlow, FundPositionsResponse, FundPositionChannel, FundPosition, StockPositionsResponse, StockPositionChannel, StockPosition, MarginRatio, EstimateMaxPurchaseQuantityResponse, Market, Language } = nativeBinding +const { Config, Decimal, HttpClient, QuoteContext, PushQuoteEvent, PushDepthEvent, PushBrokersEvent, PushTradesEvent, PushCandlestickEvent, Subscription, DerivativeType, TradeStatus, TradeSession, SubType, TradeDirection, OptionType, OptionDirection, WarrantType, Period, AdjustType, SecurityBoard, SecurityStaticInfo, PrePostQuote, SecurityQuote, OptionQuote, WarrantQuote, Depth, SecurityDepth, Brokers, SecurityBrokers, ParticipantInfo, Trade, IntradayLine, Candlestick, StrikePriceInfo, IssuerInfo, SortOrderType, WarrantSortBy, FilterWarrantExpiryDate, FilterWarrantInOutBoundsType, WarrantInfo, WarrantStatus, TradingSessionInfo, MarketTradingSession, RealtimeQuote, PushQuote, PushDepth, PushBrokers, PushTrades, PushCandlestick, MarketTradingDays, CapitalFlowLine, CapitalDistribution, CapitalDistributionResponse, WatchlistGroup, WatchlistSecurity, SecuritiesUpdateMode, CalcIndex, SecurityCalcIndex, NaiveDate, Time, NaiveDatetime, TradeContext, TopicType, Execution, OrderStatus, OrderSide, OrderType, OrderTag, TimeInForceType, TriggerStatus, OutsideRTH, Order, CommissionFreeStatus, DeductionStatus, ChargeCategoryCode, OrderHistoryDetail, OrderChargeFee, OrderChargeItem, OrderChargeDetail, OrderDetail, PushOrderChanged, SubmitOrderResponse, CashInfo, AccountBalance, BalanceType, CashFlowDirection, CashFlow, FundPositionsResponse, FundPositionChannel, FundPosition, StockPositionsResponse, StockPositionChannel, StockPosition, MarginRatio, EstimateMaxPurchaseQuantityResponse, Market, Language } = nativeBinding module.exports.Config = Config module.exports.Decimal = Decimal @@ -333,6 +333,12 @@ module.exports.IntradayLine = IntradayLine module.exports.Candlestick = Candlestick module.exports.StrikePriceInfo = StrikePriceInfo module.exports.IssuerInfo = IssuerInfo +module.exports.SortOrderType = SortOrderType +module.exports.WarrantSortBy = WarrantSortBy +module.exports.FilterWarrantExpiryDate = FilterWarrantExpiryDate +module.exports.FilterWarrantInOutBoundsType = FilterWarrantInOutBoundsType +module.exports.WarrantInfo = WarrantInfo +module.exports.WarrantStatus = WarrantStatus module.exports.TradingSessionInfo = TradingSessionInfo module.exports.MarketTradingSession = MarketTradingSession module.exports.RealtimeQuote = RealtimeQuote diff --git a/nodejs/src/quote/context.rs b/nodejs/src/quote/context.rs index a1f9a47e5..dc1fd8986 100644 --- a/nodejs/src/quote/context.rs +++ b/nodejs/src/quote/context.rs @@ -14,10 +14,12 @@ use crate::{ requests::{CreateWatchlistGroup, DeleteWatchlistGroup, UpdateWatchlistGroup}, types::{ AdjustType, CalcIndex, Candlestick, CapitalDistributionResponse, CapitalFlowLine, - IntradayLine, IssuerInfo, MarketTradingDays, MarketTradingSession, OptionQuote, - ParticipantInfo, Period, RealtimeQuote, SecurityBrokers, SecurityCalcIndex, - SecurityDepth, SecurityQuote, SecurityStaticInfo, StrikePriceInfo, SubType, SubTypes, - Subscription, Trade, WarrantQuote, WatchlistGroup, + FilterWarrantExpiryDate, FilterWarrantInOutBoundsType, IntradayLine, IssuerInfo, + MarketTradingDays, MarketTradingSession, OptionQuote, ParticipantInfo, Period, + RealtimeQuote, SecurityBrokers, SecurityCalcIndex, SecurityDepth, SecurityQuote, + SecurityStaticInfo, SortOrderType, StrikePriceInfo, SubType, SubTypes, Subscription, + Trade, WarrantInfo, WarrantQuote, WarrantSortBy, WarrantStatus, WarrantType, + WatchlistGroup, }, }, time::{NaiveDate, NaiveDatetime}, @@ -691,6 +693,59 @@ impl QuoteContext { .collect() } + /// Query warrant list + /// + /// #### Example + /// ```javascript + /// const { Config, QuoteContext, WarrantSortBy, SortOrderType } = require("longport") + /// let config = Config.fromEnv() + /// QuoteContext.new(config) + /// .then((ctx) => ctx.warrantList("700.HK", WarrantSortBy.LastDone, SortOrderType.Asc)) + /// .then((resp) => { + /// for (let obj of resp) { + /// console.log(obj.toString()) + /// } + /// }) + /// ``` + #[napi] + #[allow(clippy::too_many_arguments)] + pub async fn warrant_list( + &self, + symbol: String, + sort_by: WarrantSortBy, + sort_order: SortOrderType, + warrant_type: Option>, + issuer: Option>, + expiry_date: Option>, + price_type: Option>, + status: Option>, + ) -> Result> { + let warrant_type: Option> = + warrant_type.map(|v| v.into_iter().map(Into::into).collect()); + let expiry_date: Option> = + expiry_date.map(|v| v.into_iter().map(Into::into).collect()); + let price_type: Option> = + price_type.map(|v| v.into_iter().map(Into::into).collect()); + let status: Option> = + status.map(|v| v.into_iter().map(Into::into).collect()); + self.ctx + .warrant_list( + symbol, + sort_by.into(), + sort_order.into(), + warrant_type.as_deref(), + issuer.as_deref(), + expiry_date.as_deref(), + price_type.as_deref(), + status.as_deref(), + ) + .await + .map_err(ErrorNewType)? + .into_iter() + .map(TryInto::try_into) + .collect() + } + /// Get trading session of the day /// /// #### Example @@ -795,9 +850,7 @@ impl QuoteContext { .try_into() } - /// Get watchlist - /// - /// Deprecated: use `watchlist` instead + /// Get calc indexes #[napi] pub async fn calc_indexes( &self, @@ -813,14 +866,6 @@ impl QuoteContext { .collect() } - /// Get watchlist - /// - /// Deprecated: use `watchlist` instead - #[napi] - pub async fn watch_list(&self) -> Result> { - self.watchlist().await - } - /// Get watchlist /// /// #### Example diff --git a/nodejs/src/quote/types.rs b/nodejs/src/quote/types.rs index e1129de1c..856288218 100644 --- a/nodejs/src/quote/types.rs +++ b/nodejs/src/quote/types.rs @@ -657,6 +657,176 @@ pub struct IssuerInfo { name_hk: String, } +/// Sort order type +#[napi_derive::napi] +#[derive(Debug, JsEnum, Hash, Eq, PartialEq)] +#[js(remote = "longport::quote::SortOrderType")] +pub enum SortOrderType { + /// Ascending + Ascending, + /// Descending + Descending, +} + +/// Warrant sort by +#[napi_derive::napi] +#[derive(Debug, JsEnum, Hash, Eq, PartialEq)] +#[js(remote = "longport::quote::WarrantSortBy")] +pub enum WarrantSortBy { + /// Last done + LastDone, + /// Change rate + ChangeRate, + /// Change value + ChangeValue, + /// Volume + Volume, + /// Turnover + Turnover, + /// Expiry date + ExpiryDate, + /// Strike price + StrikePrice, + /// Upper strike price + UpperStrikePrice, + /// Lower strike price + LowerStrikePrice, + /// Outstanding quantity + OutstandingQuantity, + /// Outstanding ratio + OutstandingRatio, + /// Premium + Premium, + /// In/out of the bound + ItmOtm, + /// Implied volatility + ImpliedVolatility, + /// Greek value delta + Delta, + /// Call price + CallPrice, + /// Price interval from the call price + ToCallPrice, + /// Effective leverage + EffectiveLeverage, + /// Leverage ratio + LeverageRatio, + /// Conversion ratio + ConversionRatio, + /// Breakeven point + BalancePoint, + /// Status + Status, +} + +/// Filter warrant expiry date type +#[napi_derive::napi] +#[derive(Debug, JsEnum, Hash, Eq, PartialEq)] +#[js(remote = "longport::quote::FilterWarrantExpiryDate")] +#[allow(non_camel_case_types)] +pub enum FilterWarrantExpiryDate { + /// Less than 3 months + LT_3, + /// 3 - 6 months + Between_3_6, + /// 6 - 12 months + Between_6_12, + /// Greater than 12 months + GT_12, +} + +/// Filter warrant in/out of the bounds type +#[napi_derive::napi] +#[derive(Debug, JsEnum, Hash, Eq, PartialEq)] +#[js(remote = "longport::quote::FilterWarrantInOutBoundsType")] +pub enum FilterWarrantInOutBoundsType { + /// In bounds + In, + /// Out bounds + Out, +} + +/// Warrant info +#[napi_derive::napi] +#[derive(Debug, JsObject)] +#[js(remote = "longport::quote::WarrantInfo")] +pub struct WarrantInfo { + /// Security code + symbol: String, + /// Warrant type + warrant_type: WarrantType, + /// Security name + name: String, + /// Latest price + last_done: Decimal, + /// Quote change rate + change_rate: Decimal, + /// Quote change + change_value: Decimal, + /// Volume + volume: i64, + /// Turnover + turnover: Decimal, + /// Expiry date + expiry_date: NaiveDate, + /// Strike price + #[js(opt)] + strike_price: Option, + /// Upper strike price + #[js(opt)] + upper_strike_price: Option, + /// Lower strike price + #[js(opt)] + lower_strike_price: Option, + /// Outstanding quantity + outstanding_qty: i64, + /// Outstanding ratio + outstanding_ratio: Decimal, + /// Premium + premium: Decimal, + /// In/out of the bound + #[js(opt)] + itm_otm: Option, + /// Implied volatility + #[js(opt)] + implied_volatility: Option, + /// Delta + #[js(opt)] + delta: Option, + /// Call price + #[js(opt)] + call_price: Option, + /// Price interval from the call price + #[js(opt)] + to_call_price: Option, + /// Effective leverage + #[js(opt)] + effective_leverage: Option, + /// Leverage ratio + leverage_ratio: Decimal, + /// Conversion ratio + #[js(opt)] + conversion_ratio: Option, + /// Breakeven point + #[js(opt)] + balance_point: Option, + /// Status + status: WarrantStatus, +} + +/// Warrant status +#[napi_derive::napi] +#[derive(Debug, JsEnum, Hash, Eq, PartialEq)] +#[js(remote = "longport::quote::WarrantStatus")] +pub enum WarrantStatus { + /// Suspend + Suspend, + /// Prepare List + PrepareList, + /// Normal + Normal, +} + /// The information of trading session #[napi_derive::napi] #[derive(Debug, JsObject, Copy, Clone)] @@ -980,7 +1150,7 @@ pub struct SecurityCalcIndex { change_value: Option, /// Change ratio #[js(opt)] - change_rate: Option, + change_rate: Option, /// Volume #[js(opt)] volume: Option, @@ -989,10 +1159,10 @@ pub struct SecurityCalcIndex { turnover: Option, /// Year-to-date change ratio #[js(opt)] - ytd_change_rate: Option, + ytd_change_rate: Option, /// Turnover rate #[js(opt)] - turnover_rate: Option, + turnover_rate: Option, /// Total market value #[js(opt)] total_market_value: Option, @@ -1001,31 +1171,31 @@ pub struct SecurityCalcIndex { capital_flow: Option, /// Amplitude #[js(opt)] - amplitude: Option, + amplitude: Option, /// Volume ratio #[js(opt)] - volume_ratio: Option, + volume_ratio: Option, /// PE (TTM) #[js(opt)] - pe_ttm_ratio: Option, + pe_ttm_ratio: Option, /// PB #[js(opt)] - pb_ratio: Option, + pb_ratio: Option, /// Dividend ratio (TTM) #[js(opt)] - dividend_ratio_ttm: Option, + dividend_ratio_ttm: Option, /// Five days change ratio #[js(opt)] - five_day_change_rate: Option, + five_day_change_rate: Option, /// Ten days change ratio #[js(opt)] - ten_day_change_rate: Option, + ten_day_change_rate: Option, /// Half year change ratio #[js(opt)] - half_year_change_rate: Option, + half_year_change_rate: Option, /// Five minutes change ratio #[js(opt)] - five_minutes_change_rate: Option, + five_minutes_change_rate: Option, /// Expiry date #[js(opt)] expiry_date: Option, @@ -1043,19 +1213,19 @@ pub struct SecurityCalcIndex { outstanding_qty: Option, /// Outstanding ratio #[js(opt)] - outstanding_ratio: Option, + outstanding_ratio: Option, /// Premium #[js(opt)] - premium: Option, + premium: Option, /// In/out of the bound #[js(opt)] - itm_otm: Option, + itm_otm: Option, /// Implied volatility #[js(opt)] - implied_volatility: Option, + implied_volatility: Option, /// Warrant delta #[js(opt)] - warrant_delta: Option, + warrant_delta: Option, /// Call price #[js(opt)] call_price: Option, @@ -1064,32 +1234,32 @@ pub struct SecurityCalcIndex { to_call_price: Option, /// Effective leverage #[js(opt)] - effective_leverage: Option, + effective_leverage: Option, /// Leverage ratio #[js(opt)] - leverage_ratio: Option, + leverage_ratio: Option, /// Conversion ratio #[js(opt)] - conversion_ratio: Option, + conversion_ratio: Option, /// Breakeven point #[js(opt)] - balance_point: Option, + balance_point: Option, /// Open interest #[js(opt)] open_interest: Option, /// Delta #[js(opt)] - delta: Option, + delta: Option, /// Gamma #[js(opt)] - gamma: Option, + gamma: Option, /// Theta #[js(opt)] - theta: Option, + theta: Option, /// Vega #[js(opt)] - vega: Option, + vega: Option, /// Rho #[js(opt)] - rho: Option, + rho: Option, } diff --git a/python/Makefile.toml b/python/Makefile.toml index b9e1f100c..fbd4edf3d 100644 --- a/python/Makefile.toml +++ b/python/Makefile.toml @@ -12,7 +12,7 @@ args = ["install", "maturin>=1.0,<2.0"] command = "pip" args = [ "install", - "target/wheels/longport-1.0.13-cp311-none-win_amd64.whl", + "target/wheels/longport-1.0.19-cp311-none-win_amd64.whl", "-I", ] dependencies = ["python"] diff --git a/python/pysrc/longport/openapi.pyi b/python/pysrc/longport/openapi.pyi index 923cfe76f..084bb64e1 100644 --- a/python/pysrc/longport/openapi.pyi +++ b/python/pysrc/longport/openapi.pyi @@ -1419,6 +1419,360 @@ class IssuerInfo: Issuer name (zh-HK) """ +class WarrantStatus: + """ + Warrant status + """ + + class Suspend(WarrantStatus): + """ + Suspend + """ + + class PrepareList(WarrantStatus): + """ + Prepare List + """ + + class Normal(WarrantStatus): + """ + Normal + """ + +class WarrantType: + """ + Warrant type + """ + + class Unknown(WarrantType): + """ + Unknown + """ + + class Call(WarrantType): + """ + Call + """ + + class Put(WarrantType): + """ + Put + """ + + class Bull(WarrantType): + """ + Bull + """ + + class Bear(WarrantType): + """ + Bear + """ + + class Inline(WarrantType): + """ + Inline + """ + +class SortOrderType: + """ + Sort order type + """ + + class Ascending(SortOrderType): + """ + Ascending + """ + + class Descending(SortOrderType): + """ + Descending + """ + +class WarrantSortBy: + """ + Warrant sort by + """ + + class LastDone(WarrantSortBy): + """ + LastDone + """ + + class ChangeRate(WarrantSortBy): + """ + Change rate + """ + + class ChangeValue(WarrantSortBy): + """ + Change value + """ + + class Volume(WarrantSortBy): + """ + Volume + """ + + class Turnover(WarrantSortBy): + """ + Turnover + """ + + class ExpiryDate(WarrantSortBy): + """ + Expiry date + """ + + class StrikePrice(WarrantSortBy): + """ + Strike price + """ + + class UpperStrikePrice(WarrantSortBy): + """ + Upper strike price + """ + + class LowerStrikePrice(WarrantSortBy): + """ + Lower strike price + """ + + class OutstandingQuantity(WarrantSortBy): + """ + Outstanding quantity + """ + + class OutstandingRatio(WarrantSortBy): + """ + Outstanding ratio + """ + + class Premium(WarrantSortBy): + """ + Premium + """ + + class ItmOtm(WarrantSortBy): + """ + In/out of the bound + """ + + class ImpliedVolatility(WarrantSortBy): + """ + Implied volatility + """ + + class Delta(WarrantSortBy): + """ + Greek value delta + """ + + class CallPrice(WarrantSortBy): + """ + Call price + """ + + class ToCallPrice(WarrantSortBy): + """ + Price interval from the call price + """ + + class EffectiveLeverage(WarrantSortBy): + """ + Effective leverage + """ + + class LeverageRatio(WarrantSortBy): + """ + Leverage ratio + """ + + class ConversionRatio(WarrantSortBy): + """ + Conversion ratio + """ + + class BalancePoint(WarrantSortBy): + """ + Breakeven point + """ + + class Status(WarrantSortBy): + """ + Status + """ + +class FilterWarrantExpiryDate: + """ + Filter warrant expiry date type + """ + + class LT_3(FilterWarrantExpiryDate): + """ + Less than 3 months + """ + + class Between_3_6(FilterWarrantExpiryDate): + """ + 3 - 6 months + """ + + class Between_6_12(FilterWarrantExpiryDate): + """ + 6 - 12 months + """ + + class GT_12(FilterWarrantExpiryDate): + """ + Greater than 12 months + """ + +class FilterWarrantInOutBoundsType: + """ + Filter warrant in/out of the bounds type + """ + + class In(FilterWarrantInOutBoundsType): + """ + In bounds + """ + + class Out(FilterWarrantInOutBoundsType): + """ + Out bounds + """ + +class WarrantInfo: + """ + Warrant info + """ + + symbol: str + """ + Security code + """ + + warrant_type: Type[WarrantType] + """ + Warrant type + """ + + name: str + """ + Security name + """ + + last_done: Decimal + """ + Latest price + """ + + change_rate: Decimal + """ + Quote change rate + """ + + change_value: Decimal + """ + Quote change + """ + + volume: int + """ + Volume + """ + + turnover: Decimal + """ + Turnover + """ + + expiry_date: date + """ + Expiry date + """ + + strike_price: Optional[Decimal] + """ + Strike price + """ + + upper_strike_price: Optional[Decimal] + """ + Upper strike price + """ + + lower_strike_price: Optional[Decimal] + """ + Lower strike price + """ + + outstanding_qty: int + """ + Outstanding quantity + """ + + outstanding_ratio: Decimal + """ + Outstanding ratio + """ + + premium: Decimal + """ + Premium + """ + + itm_otm: Optional[Decimal] + """ + In/out of the bound + """ + + implied_volatility: Optional[Decimal] + """ + Implied volatility + """ + + delta: Optional[Decimal] + """ + Greek value delta + """ + + call_price: Optional[Decimal] + """ + Call price + """ + + to_call_price: Optional[Decimal] + """ + Price interval from the call price + """ + + effective_leverage: Optional[Decimal] + """ + Effective leverage + """ + + leverage_ratio: Decimal + """ + Leverage ratio + """ + + conversion_ratio: Optional[Decimal] + """ + Conversion ratio + """ + + balance_point: Optional[Decimal] + """ + Breakeven point + """ + + status: Type[WarrantStatus] + """ + Status + """ class TradingSessionInfo: """ @@ -1892,7 +2246,7 @@ class SecurityCalcIndex: Change value """ - change_rate: Optional[float] + change_rate: Optional[Decimal] """ Change ratio """ @@ -1907,12 +2261,12 @@ class SecurityCalcIndex: Turnover """ - ytd_change_rate: Optional[float] + ytd_change_rate: Optional[Decimal] """ Year-to-date change ratio """ - turnover_rate: Optional[float] + turnover_rate: Optional[Decimal] """ turnover_rate """ @@ -1927,47 +2281,47 @@ class SecurityCalcIndex: Capital flow """ - amplitude: Optional[float] + amplitude: Optional[Decimal] """ Amplitude """ - volume_ratio: Optional[float] + volume_ratio: Optional[Decimal] """ Volume ratio """ - pe_ttm_ratio: Optional[float] + pe_ttm_ratio: Optional[Decimal] """ PE (TTM) """ - pb_ratio: Optional[float] + pb_ratio: Optional[Decimal] """ PB """ - dividend_ratio_ttm: Optional[float] + dividend_ratio_ttm: Optional[Decimal] """ Dividend ratio (TTM) """ - five_day_change_rate: Optional[float] + five_day_change_rate: Optional[Decimal] """ Five days change ratio """ - ten_day_change_rate: Optional[float] + ten_day_change_rate: Optional[Decimal] """ Ten days change ratio """ - half_year_change_rate: Optional[float] + half_year_change_rate: Optional[Decimal] """ Half year change ratio """ - five_minutes_change_rate: Optional[float] + five_minutes_change_rate: Optional[Decimal] """ Five minutes change ratio """ @@ -1997,27 +2351,27 @@ class SecurityCalcIndex: Outstanding quantity """ - outstanding_ratio: Optional[float] + outstanding_ratio: Optional[Decimal] """ Outstanding ratio """ - premium: Optional[float] + premium: Optional[Decimal] """ Premium """ - itm_otm: Optional[float] + itm_otm: Optional[Decimal] """ In/out of the bound """ - implied_volatility: Optional[float] + implied_volatility: Optional[Decimal] """ Implied volatility """ - warrant_delta: Optional[float] + warrant_delta: Optional[Decimal] """ Warrant delta """ @@ -2032,22 +2386,22 @@ class SecurityCalcIndex: Price interval from the call price """ - effective_leverage: Optional[float] + effective_leverage: Optional[Decimal] """ Effective leverage """ - leverage_ratio: Optional[float] + leverage_ratio: Optional[Decimal] """ Leverage ratio """ - conversion_ratio: Optional[float] + conversion_ratio: Optional[Decimal] """ Conversion ratio """ - balance_point: Optional[float] + balance_point: Optional[Decimal] """ Breakeven point """ @@ -2057,27 +2411,27 @@ class SecurityCalcIndex: Open interest """ - delta: Optional[float] + delta: Optional[Decimal] """ Delta """ - gamma: Optional[float] + gamma: Optional[Decimal] """ Gamma """ - theta: Optional[float] + theta: Optional[Decimal] """ Theta """ - vega: Optional[float] + vega: Optional[Decimal] """ Vega """ - rho: Optional[float] + rho: Optional[Decimal] """ Rho """ @@ -2520,6 +2874,35 @@ class QuoteContext: print(resp) """ + def warrant_list(self, symbol: str, sort_by: Type[WarrantSortBy], sort_order: Type[SortOrderType], warrant_type: Optional[List[Type[WarrantType]]] = None, issuer: Optional[List[int]] = None, expiry_date: Optional[List[Type[FilterWarrantExpiryDate]]] = None, price_type: Optional[List[Type[FilterWarrantInOutBoundsType]]] = None, status: Optional[List[Type[WarrantStatus]]] = None) -> List[WarrantInfo]: + """ + Get warrant list + + Args: + symbol: Security code + sort_by: Sort by field + sort_order: Sort order + warrant_type: Filter by warrant type + issuer: Filter by issuer + expiry_date: Filter by expiry date + price_type: Filter by price type + status: Filter by status + + Returns: + Warrant list + + Examples: + :: + + from longport.openapi import QuoteContext, Config, WarrantSortBy, SortOrderType + + config = Config.from_env() + ctx = QuoteContext(config) + + resp = ctx.warrant_list("700.HK", WarrantSortBy.LastDone, SortOrderType.Ascending) + print(resp) + """ + def trading_session(self) -> List[MarketTradingSession]: """ Get trading session of the day @@ -2634,13 +3017,6 @@ class QuoteContext: print(resp) """ - def watch_list(self) -> List[WatchlistGroup]: - """ - Get watch list - - Deprecated: use instead `watchlist` - """ - def watchlist(self) -> List[WatchlistGroup]: """ Get watch list diff --git a/python/src/quote/context.rs b/python/src/quote/context.rs index 13b37ecee..5b8e789a2 100644 --- a/python/src/quote/context.rs +++ b/python/src/quote/context.rs @@ -15,10 +15,12 @@ use crate::{ push::handle_push_event, types::{ AdjustType, CalcIndex, Candlestick, CapitalDistributionResponse, CapitalFlowLine, - IntradayLine, IssuerInfo, MarketTradingDays, MarketTradingSession, OptionQuote, - ParticipantInfo, Period, RealtimeQuote, SecuritiesUpdateMode, SecurityBrokers, - SecurityCalcIndex, SecurityDepth, SecurityQuote, SecurityStaticInfo, StrikePriceInfo, - SubType, SubTypes, Subscription, Trade, WarrantQuote, WatchlistGroup, + FilterWarrantExpiryDate, FilterWarrantInOutBoundsType, IntradayLine, IssuerInfo, + MarketTradingDays, MarketTradingSession, OptionQuote, ParticipantInfo, Period, + RealtimeQuote, SecuritiesUpdateMode, SecurityBrokers, SecurityCalcIndex, SecurityDepth, + SecurityQuote, SecurityStaticInfo, SortOrderType, StrikePriceInfo, SubType, SubTypes, + Subscription, Trade, WarrantInfo, WarrantQuote, WarrantSortBy, WarrantStatus, + WarrantType, WatchlistGroup, }, }, time::{PyDateWrapper, PyOffsetDateTimeWrapper}, @@ -342,6 +344,44 @@ impl QuoteContext { .collect() } + /// Query warrant list + #[allow(clippy::too_many_arguments)] + fn warrant_list( + &self, + symbol: String, + sort_by: WarrantSortBy, + sort_order: SortOrderType, + warrant_type: Option>, + issuer: Option>, + expiry_date: Option>, + price_type: Option>, + status: Option>, + ) -> PyResult> { + let warrant_type: Option> = + warrant_type.map(|v| v.into_iter().map(Into::into).collect()); + let expiry_date: Option> = + expiry_date.map(|v| v.into_iter().map(Into::into).collect()); + let price_type: Option> = + price_type.map(|v| v.into_iter().map(Into::into).collect()); + let status: Option> = + status.map(|v| v.into_iter().map(Into::into).collect()); + self.ctx + .warrant_list( + symbol, + sort_by.into(), + sort_order.into(), + warrant_type.as_deref(), + issuer.as_deref(), + expiry_date.as_deref(), + price_type.as_deref(), + status.as_deref(), + ) + .map_err(ErrorNewType)? + .into_iter() + .map(TryInto::try_into) + .collect() + } + /// Get trading session of the day fn trading_session(&self) -> PyResult> { self.ctx @@ -397,11 +437,6 @@ impl QuoteContext { .collect() } - /// Get watch list - fn watch_list(&self) -> PyResult> { - self.watchlist() - } - /// Get watch list fn watchlist(&self) -> PyResult> { self.ctx diff --git a/python/src/quote/mod.rs b/python/src/quote/mod.rs index 4dbbd6b9c..af3e4b25f 100644 --- a/python/src/quote/mod.rs +++ b/python/src/quote/mod.rs @@ -41,6 +41,13 @@ pub(crate) fn register_types(parent: &PyModule) -> 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/quote/types.rs b/python/src/quote/types.rs index 5763f232e..cbbe0e8e9 100644 --- a/python/src/quote/types.rs +++ b/python/src/quote/types.rs @@ -650,6 +650,176 @@ pub(crate) struct IssuerInfo { name_hk: String, } +/// Sort order type +#[pyclass] +#[derive(PyEnum, Debug, Copy, Clone, Hash, Eq, PartialEq)] +#[py(remote = "longport::quote::SortOrderType")] +pub enum SortOrderType { + /// Ascending + Ascending, + /// Descending + Descending, +} + +/// Warrant sort by +#[pyclass] +#[derive(PyEnum, Debug, Copy, Clone, Hash, Eq, PartialEq)] +#[py(remote = "longport::quote::WarrantSortBy")] +pub enum WarrantSortBy { + /// Last done + LastDone, + /// Change rate + ChangeRate, + /// Change value + ChangeValue, + /// Volume + Volume, + /// Turnover + Turnover, + /// Expiry date + ExpiryDate, + /// Strike price + StrikePrice, + /// Upper strike price + UpperStrikePrice, + /// Lower strike price + LowerStrikePrice, + /// Outstanding quantity + OutstandingQuantity, + /// Outstanding ratio + OutstandingRatio, + /// Premium + Premium, + /// In/out of the bound + ItmOtm, + /// Implied volatility + ImpliedVolatility, + /// Greek value delta + Delta, + /// Call price + CallPrice, + /// Price interval from the call price + ToCallPrice, + /// Effective leverage + EffectiveLeverage, + /// Leverage ratio + LeverageRatio, + /// Conversion ratio + ConversionRatio, + /// Breakeven point + BalancePoint, + /// Status + Status, +} + +/// Filter warrant expiry date type +#[pyclass] +#[derive(PyEnum, Debug, Copy, Clone, Hash, Eq, PartialEq)] +#[py(remote = "longport::quote::FilterWarrantExpiryDate")] +#[allow(non_camel_case_types)] +pub enum FilterWarrantExpiryDate { + /// Less than 3 months + LT_3, + /// 3 - 6 months + Between_3_6, + /// 6 - 12 months + Between_6_12, + /// Greater than 12 months + GT_12, +} + +/// Filter warrant in/out of the bounds type +#[pyclass] +#[derive(PyEnum, Debug, Copy, Clone, Hash, Eq, PartialEq)] +#[py(remote = "longport::quote::FilterWarrantInOutBoundsType")] +pub enum FilterWarrantInOutBoundsType { + /// In bounds + In, + /// Out bounds + Out, +} + +/// Warrant info +#[pyclass] +#[derive(Debug, Clone, PyObject)] +#[py(remote = "longport::quote::WarrantInfo")] +pub(crate) struct WarrantInfo { + /// Security code + symbol: String, + /// Warrant type + warrant_type: WarrantType, + /// Security name + name: String, + /// Latest price + last_done: PyDecimal, + /// Quote change rate + change_rate: PyDecimal, + /// Quote change + change_value: PyDecimal, + /// Volume + volume: i64, + /// Turnover + turnover: PyDecimal, + /// Expiry date + expiry_date: PyDateWrapper, + /// Strike price + #[py(opt)] + strike_price: Option, + /// Upper strike price + #[py(opt)] + upper_strike_price: Option, + /// Lower strike price + #[py(opt)] + lower_strike_price: Option, + /// Outstanding quantity + outstanding_qty: i64, + /// Outstanding ratio + outstanding_ratio: PyDecimal, + /// Premium + premium: PyDecimal, + /// In/out of the bound + #[py(opt)] + itm_otm: Option, + /// Implied volatility + #[py(opt)] + implied_volatility: Option, + /// Delta + #[py(opt)] + delta: Option, + /// Call price + #[py(opt)] + call_price: Option, + /// Price interval from the call price + #[py(opt)] + to_call_price: Option, + /// Effective leverage + #[py(opt)] + effective_leverage: Option, + /// Leverage ratio + leverage_ratio: PyDecimal, + /// Conversion ratio + #[py(opt)] + conversion_ratio: Option, + /// Breakeven point + #[py(opt)] + balance_point: Option, + /// Status + status: WarrantStatus, +} + +/// Warrant status +#[pyclass] +#[derive(PyEnum, Debug, Copy, Clone, Hash, Eq, PartialEq)] +#[py(remote = "longport::quote::WarrantStatus")] +pub enum WarrantStatus { + /// Suspend + Suspend, + /// Prepare List + PrepareList, + /// Normal + Normal, +} + /// The information of trading session #[pyclass] #[derive(Debug, PyObject, Copy, Clone)] @@ -970,7 +1140,7 @@ pub(crate) struct SecurityCalcIndex { change_value: Option, /// Change ratio #[py(opt)] - change_rate: Option, + change_rate: Option, /// Volume #[py(opt)] volume: Option, @@ -979,10 +1149,10 @@ pub(crate) struct SecurityCalcIndex { turnover: Option, /// Year-to-date change ratio #[py(opt)] - ytd_change_rate: Option, + ytd_change_rate: Option, /// Turnover rate #[py(opt)] - turnover_rate: Option, + turnover_rate: Option, /// Total market value #[py(opt)] total_market_value: Option, @@ -991,31 +1161,31 @@ pub(crate) struct SecurityCalcIndex { capital_flow: Option, /// Amplitude #[py(opt)] - amplitude: Option, + amplitude: Option, /// Volume ratio #[py(opt)] - volume_ratio: Option, + volume_ratio: Option, /// PE (TTM) #[py(opt)] - pe_ttm_ratio: Option, + pe_ttm_ratio: Option, /// PB #[py(opt)] - pb_ratio: Option, + pb_ratio: Option, /// Dividend ratio (TTM) #[py(opt)] - dividend_ratio_ttm: Option, + dividend_ratio_ttm: Option, /// Five days change ratio #[py(opt)] - five_day_change_rate: Option, + five_day_change_rate: Option, /// Ten days change ratio #[py(opt)] - ten_day_change_rate: Option, + ten_day_change_rate: Option, /// Half year change ratio #[py(opt)] - half_year_change_rate: Option, + half_year_change_rate: Option, /// Five minutes change ratio #[py(opt)] - five_minutes_change_rate: Option, + five_minutes_change_rate: Option, /// Expiry date #[py(opt)] expiry_date: Option, @@ -1033,19 +1203,19 @@ pub(crate) struct SecurityCalcIndex { outstanding_qty: Option, /// Outstanding ratio #[py(opt)] - outstanding_ratio: Option, + outstanding_ratio: Option, /// Premium #[py(opt)] - premium: Option, + premium: Option, /// In/out of the bound #[py(opt)] - itm_otm: Option, + itm_otm: Option, /// Implied volatility #[py(opt)] - implied_volatility: Option, + implied_volatility: Option, /// Warrant delta #[py(opt)] - warrant_delta: Option, + warrant_delta: Option, /// Call price #[py(opt)] call_price: Option, @@ -1054,32 +1224,32 @@ pub(crate) struct SecurityCalcIndex { to_call_price: Option, /// Effective leverage #[py(opt)] - effective_leverage: Option, + effective_leverage: Option, /// Leverage ratio #[py(opt)] - leverage_ratio: Option, + leverage_ratio: Option, /// Conversion ratio #[py(opt)] - conversion_ratio: Option, + conversion_ratio: Option, /// Breakeven point #[py(opt)] - balance_point: Option, + balance_point: Option, /// Open interest #[py(opt)] open_interest: Option, /// Delta #[py(opt)] - delta: Option, + delta: Option, /// Gamma #[py(opt)] - gamma: Option, + gamma: Option, /// Theta #[py(opt)] - theta: Option, + theta: Option, /// Vega #[py(opt)] - vega: Option, + vega: Option, /// Rho #[py(opt)] - rho: Option, + rho: Option, } diff --git a/rust/crates/httpclient/src/geo.rs b/rust/crates/httpclient/src/geo.rs index 3accea4c2..d74092ef0 100644 --- a/rust/crates/httpclient/src/geo.rs +++ b/rust/crates/httpclient/src/geo.rs @@ -5,8 +5,8 @@ use std::{ // because we may call `is_cn` multi times in a short time, we cache the result thread_local! { - static LAST_PING: Cell> = Cell::new(None); - static LAST_PING_REGION: RefCell = RefCell::new(String::new()); + static LAST_PING: Cell> = const { Cell::new(None) }; + static LAST_PING_REGION: RefCell = const { RefCell::new(String::new()) }; } fn region() -> Option { @@ -41,13 +41,10 @@ async fn ping() -> Option { else { return None; }; - let Some(region) = resp + let region = resp .headers() .get("X-Ip-Region") - .and_then(|v| v.to_str().ok()) - else { - return None; - }; + .and_then(|v| v.to_str().ok())?; LAST_PING.set(Some(Instant::now())); LAST_PING_REGION.replace(region.to_string()); Some(region.to_string()) diff --git a/rust/crates/proto/openapi-protobufs b/rust/crates/proto/openapi-protobufs index 05b060582..927048ab6 160000 --- a/rust/crates/proto/openapi-protobufs +++ b/rust/crates/proto/openapi-protobufs @@ -1 +1 @@ -Subproject commit 05b060582b0e71065166a3adc187125db68dbd22 +Subproject commit 927048ab66670505f44132b9fa146c8e817794ac diff --git a/rust/crates/proto/src/longportapp.quote.v1.rs b/rust/crates/proto/src/longportapp.quote.v1.rs index ad4689f8c..272e3c4ec 100644 --- a/rust/crates/proto/src/longportapp.quote.v1.rs +++ b/rust/crates/proto/src/longportapp.quote.v1.rs @@ -479,8 +479,10 @@ pub struct FilterWarrant { pub conversion_ratio: ::prost::alloc::string::String, #[prost(string, tag="23")] pub balance_point: ::prost::alloc::string::String, - #[prost(string, tag="24")] - pub state: ::prost::alloc::string::String, + #[prost(int32, tag="24")] + pub status: i32, + #[prost(int32, tag="25")] + pub r#type: i32, } #[derive(Clone, PartialEq, ::prost::Message)] pub struct MarketTradePeriodResponse { diff --git a/rust/src/blocking/quote.rs b/rust/src/blocking/quote.rs index ffad36aeb..de346db3d 100644 --- a/rust/src/blocking/quote.rs +++ b/rust/src/blocking/quote.rs @@ -6,11 +6,12 @@ use crate::{ blocking::runtime::BlockingRuntime, quote::{ AdjustType, CalcIndex, Candlestick, CapitalDistributionResponse, CapitalFlowLine, - IntradayLine, IssuerInfo, MarketTradingDays, MarketTradingSession, OptionQuote, - ParticipantInfo, Period, PushEvent, RealtimeQuote, RequestCreateWatchlistGroup, - RequestUpdateWatchlistGroup, SecurityBrokers, SecurityCalcIndex, SecurityDepth, - SecurityQuote, SecurityStaticInfo, StrikePriceInfo, SubFlags, Subscription, Trade, - WarrantQuote, WatchlistGroup, + FilterWarrantExpiryDate, FilterWarrantInOutBoundsType, IntradayLine, IssuerInfo, + MarketTradingDays, MarketTradingSession, OptionQuote, ParticipantInfo, Period, PushEvent, + RealtimeQuote, RequestCreateWatchlistGroup, RequestUpdateWatchlistGroup, SecurityBrokers, + SecurityCalcIndex, SecurityDepth, SecurityQuote, SecurityStaticInfo, SortOrderType, + StrikePriceInfo, SubFlags, Subscription, Trade, WarrantInfo, WarrantQuote, WarrantSortBy, + WarrantStatus, WarrantType, WatchlistGroup, }, Config, Market, QuoteContext, Result, }; @@ -553,6 +554,39 @@ impl QuoteContextSync { .call(move |ctx| async move { ctx.warrant_issuers().await }) } + /// Query warrant list + #[allow(clippy::too_many_arguments)] + pub fn warrant_list( + &self, + symbol: impl Into + Send + 'static, + sort_by: WarrantSortBy, + sort_order: SortOrderType, + warrant_type: Option<&[WarrantType]>, + issuer: Option<&[i32]>, + expiry_date: Option<&[FilterWarrantExpiryDate]>, + price_type: Option<&[FilterWarrantInOutBoundsType]>, + status: Option<&[WarrantStatus]>, + ) -> Result> { + let warrant_type = warrant_type.map(|v| v.to_vec()); + let issuer = issuer.map(|v| v.to_vec()); + let expiry_date = expiry_date.map(|v| v.to_vec()); + let price_type = price_type.map(|v| v.to_vec()); + let status = status.map(|v| v.to_vec()); + self.rt.call(move |ctx| async move { + ctx.warrant_list( + symbol, + sort_by, + sort_order, + warrant_type.as_deref(), + issuer.as_deref(), + expiry_date.as_deref(), + price_type.as_deref(), + status.as_deref(), + ) + .await + }) + } + /// Get trading session of the day /// /// # Examples @@ -675,13 +709,6 @@ impl QuoteContextSync { .call(move |ctx| async move { ctx.calc_indexes(symbols, indexes).await }) } - /// Get watchlist - #[deprecated = "Use `watchlist` instead"] - pub fn watch_list(&self) -> Result> { - self.rt - .call(move |ctx| async move { ctx.watchlist().await }) - } - /// Get watchlist /// /// # Examples diff --git a/rust/src/config.rs b/rust/src/config.rs index 21d6d628f..7dcbe3b1b 100644 --- a/rust/src/config.rs +++ b/rust/src/config.rs @@ -1,6 +1,7 @@ use http::Method; pub(crate) use http::{header, HeaderValue, Request}; use longport_httpcli::{is_cn, HttpClient, HttpClientConfig, Json}; +use num_enum::IntoPrimitive; use serde::{Deserialize, Serialize}; use time::OffsetDateTime; use tokio_tungstenite::tungstenite::client::IntoClientRequest; @@ -13,15 +14,16 @@ const CN_QUOTE_WS_URL: &str = "wss://openapi-quote.longportapp.cn/v2"; const CN_TRADE_WS_URL: &str = "wss://openapi-trade.longportapp.cn/v2"; /// Language identifier -#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, IntoPrimitive)] #[allow(non_camel_case_types)] +#[repr(i32)] pub enum Language { /// zh-CN - ZH_CN, + ZH_CN = 0, /// zh-HK - ZH_HK, + ZH_HK = 2, /// en - EN, + EN = 1, } impl Language { @@ -40,7 +42,7 @@ pub struct Config { pub(crate) http_cli_config: HttpClientConfig, pub(crate) quote_ws_url: String, pub(crate) trade_ws_url: String, - language: Language, + pub(crate) language: Language, } impl Config { diff --git a/rust/src/quote/cmd_code.rs b/rust/src/quote/cmd_code.rs index d16769690..21181af8f 100644 --- a/rust/src/quote/cmd_code.rs +++ b/rust/src/quote/cmd_code.rs @@ -52,6 +52,9 @@ pub(crate) const GET_OPTION_CHAIN_INFO_BY_DATE: u8 = 21; /// Get Warrant Issuer IDs pub(crate) const GET_WARRANT_ISSUER_IDS: u8 = 22; +/// Get Filtered Warrant +pub(crate) const GET_FILTERED_WARRANT: u8 = 23; + /// Get Security Capital Flow Intraday pub(crate) const GET_CAPITAL_FLOW_INTRADAY: u8 = 24; diff --git a/rust/src/quote/context.rs b/rust/src/quote/context.rs index f7c3717de..85c45e8e7 100644 --- a/rust/src/quote/context.rs +++ b/rust/src/quote/context.rs @@ -13,16 +13,19 @@ use crate::{ cmd_code, core::{Command, Core}, sub_flags::SubFlags, - types::SecuritiesUpdateMode, + types::{ + FilterWarrantExpiryDate, FilterWarrantInOutBoundsType, SecuritiesUpdateMode, + SortOrderType, WarrantSortBy, WarrantStatus, + }, utils::{format_date, parse_date}, AdjustType, CalcIndex, Candlestick, CapitalDistributionResponse, CapitalFlowLine, IntradayLine, IssuerInfo, MarketTradingDays, MarketTradingSession, OptionQuote, ParticipantInfo, Period, PushEvent, RealtimeQuote, RequestCreateWatchlistGroup, RequestUpdateWatchlistGroup, SecurityBrokers, SecurityCalcIndex, SecurityDepth, - SecurityQuote, SecurityStaticInfo, StrikePriceInfo, Subscription, Trade, WarrantQuote, - WatchlistGroup, + SecurityQuote, SecurityStaticInfo, StrikePriceInfo, Subscription, Trade, WarrantInfo, + WarrantQuote, WarrantType, WatchlistGroup, }, - serde_utils, Config, Error, Market, Result, + serde_utils, Config, Error, Language, Market, Result, }; const PARTICIPANT_INFO_CACHE_TIMEOUT: Duration = Duration::from_secs(30 * 60); @@ -34,6 +37,7 @@ const TRADING_SESSION_CACHE_TIMEOUT: Duration = Duration::from_secs(60 * 60 * 2) /// Quote context #[derive(Clone)] pub struct QuoteContext { + language: Language, http_cli: HttpClient, command_tx: mpsc::UnboundedSender, cache_participants: Cache>, @@ -50,6 +54,7 @@ impl QuoteContext { pub async fn try_new( config: Arc, ) -> Result<(Self, mpsc::UnboundedReceiver)> { + let language = config.language; let http_cli = config.create_http_client(); let (command_tx, command_rx) = mpsc::unbounded_channel(); let (push_tx, push_rx) = mpsc::unbounded_channel(); @@ -59,6 +64,7 @@ impl QuoteContext { tokio::spawn(core.run()); Ok(( QuoteContext { + language, http_cli, command_tx, cache_participants: Cache::new(PARTICIPANT_INFO_CACHE_TIMEOUT), @@ -918,6 +924,53 @@ impl QuoteContext { .await } + /// Query warrant list + #[allow(clippy::too_many_arguments)] + pub async fn warrant_list( + &self, + symbol: impl Into, + sort_by: WarrantSortBy, + sort_order: SortOrderType, + warrant_type: Option<&[WarrantType]>, + issuer: Option<&[i32]>, + expiry_date: Option<&[FilterWarrantExpiryDate]>, + price_type: Option<&[FilterWarrantInOutBoundsType]>, + status: Option<&[WarrantStatus]>, + ) -> Result> { + let resp = self + .request::<_, quote::WarrantFilterListResponse>( + cmd_code::GET_FILTERED_WARRANT, + quote::WarrantFilterListRequest { + symbol: symbol.into(), + filter_config: Some(quote::FilterConfig { + sort_by: sort_by.into(), + sort_order: sort_order.into(), + sort_offset: 0, + sort_count: 0, + r#type: warrant_type + .map(|types| types.iter().map(|ty| (*ty).into()).collect()) + .unwrap_or_default(), + issuer: issuer.map(|types| types.to_vec()).unwrap_or_default(), + expiry_date: expiry_date + .map(|e| e.iter().map(|e| (*e).into()).collect()) + .unwrap_or_default(), + price_type: price_type + .map(|types| types.iter().map(|ty| (*ty).into()).collect()) + .unwrap_or_default(), + status: status + .map(|status| status.iter().map(|status| (*status).into()).collect()) + .unwrap_or_default(), + }), + language: self.language.into(), + }, + ) + .await?; + resp.warrant_list + .into_iter() + .map(TryInto::try_into) + .collect::>>() + } + /// Get trading session of the day /// /// Reference: @@ -1114,12 +1167,6 @@ impl QuoteContext { .collect()) } - /// Get watchlist - #[deprecated(note = "Use `watchlist` instead")] - pub async fn watch_list(&self) -> Result> { - self.watchlist().await - } - /// Get watchlist /// /// Reference: diff --git a/rust/src/quote/core.rs b/rust/src/quote/core.rs index ab2845bd9..98b867cc1 100644 --- a/rust/src/quote/core.rs +++ b/rust/src/quote/core.rs @@ -626,38 +626,29 @@ impl Core { .get_mut(&symbol) .map(|data| &mut data.candlesticks) { - if periods.remove(&period).is_some() { - if period == Period::Day { - unsubscribe_quote = true; - } else { - if periods.is_empty() - || (periods.len() == 1 && periods.contains_key(&Period::Day)) - { - unsubscribe_quote = true; - } - } + if periods.remove(&period).is_some() && period == Period::Day { + unsubscribe_quote = true; } - if unsubscribe_quote { - if !self + if unsubscribe_quote + && !self .subscriptions .get(&symbol) .copied() .unwrap_or_else(SubFlags::empty) .contains(unsubscribe_sub_flags) - { - self.ws_cli - .request( - cmd_code::UNSUBSCRIBE, - None, - UnsubscribeRequest { - symbol: vec![symbol], - sub_type: unsubscribe_sub_flags.into(), - unsub_all: false, - }, - ) - .await?; - } + { + self.ws_cli + .request( + cmd_code::UNSUBSCRIBE, + None, + UnsubscribeRequest { + symbol: vec![symbol], + sub_type: unsubscribe_sub_flags.into(), + unsub_all: false, + }, + ) + .await?; } } diff --git a/rust/src/quote/mod.rs b/rust/src/quote/mod.rs index 37fd46f9c..bf3294464 100644 --- a/rust/src/quote/mod.rs +++ b/rust/src/quote/mod.rs @@ -18,12 +18,14 @@ pub use push_types::{ pub use sub_flags::SubFlags; pub use types::{ Brokers, CalcIndex, Candlestick, CapitalDistribution, CapitalDistributionResponse, - CapitalFlowLine, Depth, DerivativeType, IntradayLine, IssuerInfo, MarketTradingDays, - MarketTradingSession, OptionDirection, OptionQuote, OptionType, ParticipantInfo, PrePostQuote, - RealtimeQuote, RequestCreateWatchlistGroup, RequestUpdateWatchlistGroup, SecuritiesUpdateMode, - SecurityBoard, SecurityBrokers, SecurityCalcIndex, SecurityDepth, SecurityQuote, - SecurityStaticInfo, StrikePriceInfo, Subscription, Trade, TradeDirection, TradingSessionInfo, - WarrantQuote, WarrantType, WatchlistGroup, WatchlistSecurity, + CapitalFlowLine, Depth, DerivativeType, FilterWarrantExpiryDate, FilterWarrantInOutBoundsType, + IntradayLine, IssuerInfo, MarketTradingDays, MarketTradingSession, OptionDirection, + OptionQuote, OptionType, ParticipantInfo, PrePostQuote, RealtimeQuote, + RequestCreateWatchlistGroup, RequestUpdateWatchlistGroup, SecuritiesUpdateMode, SecurityBoard, + SecurityBrokers, SecurityCalcIndex, SecurityDepth, SecurityQuote, SecurityStaticInfo, + SortOrderType, StrikePriceInfo, Subscription, Trade, TradeDirection, TradingSessionInfo, + WarrantInfo, WarrantQuote, WarrantSortBy, WarrantStatus, WarrantType, WatchlistGroup, + WatchlistSecurity, }; // pub use types::{FilterWarrantExpiryDate, // FilterWarrantStatus,Language,SortType}; diff --git a/rust/src/quote/types.rs b/rust/src/quote/types.rs index 73f2ea2c0..a358ead0b 100644 --- a/rust/src/quote/types.rs +++ b/rust/src/quote/types.rs @@ -1,5 +1,5 @@ use longport_proto::quote::{self, Period, TradeSession, TradeStatus}; -use num_enum::{FromPrimitive, IntoPrimitive}; +use num_enum::{FromPrimitive, IntoPrimitive, TryFromPrimitive}; use rust_decimal::Decimal; use serde::{Deserialize, Serialize}; use strum_macros::{Display, EnumString}; @@ -503,7 +503,7 @@ impl TryFrom for OptionQuote { } /// Warrant type -#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, EnumString, IntoPrimitive)] +#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, EnumString, IntoPrimitive, TryFromPrimitive)] #[repr(i32)] pub enum WarrantType { /// Unknown @@ -803,55 +803,258 @@ impl From for IssuerInfo { } } -// /// Sort type -// #[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, IntoPrimitive)] -// #[repr(i32)] -// pub enum SortType { -// /// Ascending -// Ascending = 0, -// /// Descending -// Descending = 1, -// } - -// /// Filter warrant expiry date type -// #[allow(non_camel_case_types)] -// #[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, IntoPrimitive)] -// #[repr(i32)] -// pub enum FilterWarrantExpiryDate { -// /// Less than 3 months -// LT_3 = 1, -// /// 3 - 6 months -// Between_3_6 = 2, -// /// 6 - 12 months -// Between_6_12 = 3, -// /// Greater than 12 months -// GT_12 = 4, -// } - -// /// Filter warrant status type -// #[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, IntoPrimitive)] -// #[repr(i32)] -// pub enum FilterWarrantStatus { -// /// Suspend -// Suspend = 2, -// /// Prepare List -// PrepareList = 3, -// /// Normal -// Normal = 4, -// } - -// /// Language type -// #[allow(non_camel_case_types)] -// #[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, IntoPrimitive)] -// #[repr(i32)] -// pub enum Language { -// /// zh-CN -// ZH_CN = 0, -// /// en -// EN = 1, -// /// zh-HK -// ZH_HK = 2, -// } +/// Sort order type +#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, IntoPrimitive)] +#[repr(i32)] +pub enum SortOrderType { + /// Ascending + Ascending = 0, + /// Descending + Descending = 1, +} + +/// Warrant sort by +#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, IntoPrimitive)] +#[repr(i32)] +pub enum WarrantSortBy { + /// Last done + LastDone = 0, + /// Change rate + ChangeRate = 1, + /// Change value + ChangeValue = 2, + /// Volume + Volume = 3, + /// Turnover + Turnover = 4, + /// Expiry date + ExpiryDate = 5, + /// Strike price + StrikePrice = 6, + /// Upper strike price + UpperStrikePrice = 7, + /// Lower strike price + LowerStrikePrice = 8, + /// Outstanding quantity + OutstandingQuantity = 9, + /// Outstanding ratio + OutstandingRatio = 10, + /// Premium + Premium = 11, + /// In/out of the bound + ItmOtm = 12, + /// Implied volatility + ImpliedVolatility = 13, + /// Greek value Delta + Delta = 14, + /// Call price + CallPrice = 15, + /// Price interval from the call price + ToCallPrice = 16, + /// Effective leverage + EffectiveLeverage = 17, + /// Leverage ratio + LeverageRatio = 18, + /// Conversion ratio + ConversionRatio = 19, + /// Breakeven point + BalancePoint = 20, + /// Status + Status = 21, +} + +/// Filter warrant expiry date type +#[allow(non_camel_case_types)] +#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, IntoPrimitive)] +#[repr(i32)] +pub enum FilterWarrantExpiryDate { + /// Less than 3 months + LT_3 = 1, + /// 3 - 6 months + Between_3_6 = 2, + /// 6 - 12 months + Between_6_12 = 3, + /// Greater than 12 months + GT_12 = 4, +} + +/// Filter warrant in/out of the bounds type +#[allow(non_camel_case_types)] +#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, IntoPrimitive)] +#[repr(i32)] +pub enum FilterWarrantInOutBoundsType { + /// In bounds + In = 1, + /// Out bounds + Out = 2, +} + +/// Warrant status +#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, IntoPrimitive, TryFromPrimitive)] +#[repr(i32)] +pub enum WarrantStatus { + /// Suspend + Suspend = 2, + /// Prepare List + PrepareList = 3, + /// Normal + Normal = 4, +} + +/// Warrant info +#[derive(Debug, Clone)] +pub struct WarrantInfo { + /// Security code + pub symbol: String, + /// Warrant type + pub warrant_type: WarrantType, + /// Security name + pub name: String, + /// Latest price + pub last_done: Decimal, + /// Quote change rate + pub change_rate: Decimal, + /// Quote change + pub change_value: Decimal, + /// Volume + pub volume: i64, + /// Turnover + pub turnover: Decimal, + /// Expiry date + pub expiry_date: Date, + /// Strike price + pub strike_price: Option, + /// Upper strike price + pub upper_strike_price: Option, + /// Lower strike price + pub lower_strike_price: Option, + /// Outstanding quantity + pub outstanding_qty: i64, + /// Outstanding ratio + pub outstanding_ratio: Decimal, + /// Premium + pub premium: Decimal, + /// In/out of the bound + pub itm_otm: Option, + /// Implied volatility + pub implied_volatility: Option, + /// Delta + pub delta: Option, + /// Call price + pub call_price: Option, + /// Price interval from the call price + pub to_call_price: Option, + /// Effective leverage + pub effective_leverage: Option, + /// Leverage ratio + pub leverage_ratio: Decimal, + /// Conversion ratio + pub conversion_ratio: Option, + /// Breakeven point + pub balance_point: Option, + /// Status + pub status: WarrantStatus, +} + +impl TryFrom for WarrantInfo { + type Error = Error; + + fn try_from(info: quote::FilterWarrant) -> Result { + let r#type = WarrantType::try_from(info.r#type) + .map_err(|err| Error::parse_field_error("type", err))?; + + match r#type { + WarrantType::Unknown => unreachable!(), + WarrantType::Call | WarrantType::Put => Ok(Self { + symbol: info.symbol, + warrant_type: r#type, + name: info.name, + last_done: info.last_done.parse().unwrap_or_default(), + change_rate: info.change_rate.parse().unwrap_or_default(), + change_value: info.change_val.parse().unwrap_or_default(), + volume: info.volume, + turnover: info.turnover.parse().unwrap_or_default(), + expiry_date: parse_date(&info.expiry_date) + .map_err(|err| Error::parse_field_error("expiry_date", err))?, + strike_price: Some(info.last_done.parse().unwrap_or_default()), + upper_strike_price: None, + lower_strike_price: None, + outstanding_qty: info.outstanding_qty.parse().unwrap_or_default(), + outstanding_ratio: info.outstanding_ratio.parse().unwrap_or_default(), + premium: info.premium.parse().unwrap_or_default(), + itm_otm: Some(info.last_done.parse().unwrap_or_default()), + implied_volatility: Some(info.last_done.parse().unwrap_or_default()), + delta: Some(info.last_done.parse().unwrap_or_default()), + call_price: None, + to_call_price: None, + effective_leverage: Some(info.last_done.parse().unwrap_or_default()), + leverage_ratio: info.leverage_ratio.parse().unwrap_or_default(), + conversion_ratio: Some(info.last_done.parse().unwrap_or_default()), + balance_point: Some(info.last_done.parse().unwrap_or_default()), + status: WarrantStatus::try_from(info.status) + .map_err(|err| Error::parse_field_error("state", err))?, + }), + WarrantType::Bull | WarrantType::Bear => Ok(Self { + symbol: info.symbol, + warrant_type: r#type, + name: info.name, + last_done: info.last_done.parse().unwrap_or_default(), + change_rate: info.change_rate.parse().unwrap_or_default(), + change_value: info.change_val.parse().unwrap_or_default(), + volume: info.volume, + turnover: info.turnover.parse().unwrap_or_default(), + expiry_date: parse_date(&info.expiry_date) + .map_err(|err| Error::parse_field_error("expiry_date", err))?, + strike_price: Some(info.last_done.parse().unwrap_or_default()), + upper_strike_price: None, + lower_strike_price: None, + outstanding_qty: info.outstanding_qty.parse().unwrap_or_default(), + outstanding_ratio: info.outstanding_ratio.parse().unwrap_or_default(), + premium: info.premium.parse().unwrap_or_default(), + itm_otm: Some(info.last_done.parse().unwrap_or_default()), + implied_volatility: None, + delta: None, + call_price: Some(info.call_price.parse().unwrap_or_default()), + to_call_price: Some(info.to_call_price.parse().unwrap_or_default()), + effective_leverage: None, + leverage_ratio: info.leverage_ratio.parse().unwrap_or_default(), + conversion_ratio: Some(info.last_done.parse().unwrap_or_default()), + balance_point: Some(info.last_done.parse().unwrap_or_default()), + status: WarrantStatus::try_from(info.status) + .map_err(|err| Error::parse_field_error("state", err))?, + }), + WarrantType::Inline => Ok(Self { + symbol: info.symbol, + warrant_type: r#type, + name: info.name, + last_done: info.last_done.parse().unwrap_or_default(), + change_rate: info.change_rate.parse().unwrap_or_default(), + change_value: info.change_val.parse().unwrap_or_default(), + volume: info.volume, + turnover: info.turnover.parse().unwrap_or_default(), + expiry_date: parse_date(&info.expiry_date) + .map_err(|err| Error::parse_field_error("expiry_date", err))?, + strike_price: None, + upper_strike_price: Some(info.upper_strike_price.parse().unwrap_or_default()), + lower_strike_price: Some(info.lower_strike_price.parse().unwrap_or_default()), + outstanding_qty: info.outstanding_qty.parse().unwrap_or_default(), + outstanding_ratio: info.outstanding_ratio.parse().unwrap_or_default(), + premium: info.premium.parse().unwrap_or_default(), + itm_otm: None, + implied_volatility: None, + delta: None, + call_price: None, + to_call_price: None, + effective_leverage: None, + leverage_ratio: info.leverage_ratio.parse().unwrap_or_default(), + conversion_ratio: None, + balance_point: None, + status: WarrantStatus::try_from(info.status) + .map_err(|err| Error::parse_field_error("state", err))?, + }), + } + } +} /// The information of trading session #[derive(Debug, Clone)] @@ -1262,37 +1465,37 @@ pub struct SecurityCalcIndex { /// Change value pub change_value: Option, /// Change ratio - pub change_rate: Option, + pub change_rate: Option, /// Volume pub volume: Option, /// Turnover pub turnover: Option, /// Year-to-date change ratio - pub ytd_change_rate: Option, + pub ytd_change_rate: Option, /// Turnover rate - pub turnover_rate: Option, + pub turnover_rate: Option, /// Total market value pub total_market_value: Option, /// Capital flow pub capital_flow: Option, /// Amplitude - pub amplitude: Option, + pub amplitude: Option, /// Volume ratio - pub volume_ratio: Option, + pub volume_ratio: Option, /// PE (TTM) - pub pe_ttm_ratio: Option, + pub pe_ttm_ratio: Option, /// PB - pub pb_ratio: Option, + pub pb_ratio: Option, /// Dividend ratio (TTM) - pub dividend_ratio_ttm: Option, + pub dividend_ratio_ttm: Option, /// Five days change ratio - pub five_day_change_rate: Option, + pub five_day_change_rate: Option, /// Ten days change ratio - pub ten_day_change_rate: Option, + pub ten_day_change_rate: Option, /// Half year change ratio - pub half_year_change_rate: Option, + pub half_year_change_rate: Option, /// Five minutes change ratio - pub five_minutes_change_rate: Option, + pub five_minutes_change_rate: Option, /// Expiry date pub expiry_date: Option, /// Strike price @@ -1304,39 +1507,39 @@ pub struct SecurityCalcIndex { /// Outstanding quantity pub outstanding_qty: Option, /// Outstanding ratio - pub outstanding_ratio: Option, + pub outstanding_ratio: Option, /// Premium - pub premium: Option, + pub premium: Option, /// In/out of the bound - pub itm_otm: Option, + pub itm_otm: Option, /// Implied volatility - pub implied_volatility: Option, + pub implied_volatility: Option, /// Warrant delta - pub warrant_delta: Option, + pub warrant_delta: Option, /// Call price pub call_price: Option, /// Price interval from the call price pub to_call_price: Option, /// Effective leverage - pub effective_leverage: Option, + pub effective_leverage: Option, /// Leverage ratio - pub leverage_ratio: Option, + pub leverage_ratio: Option, /// Conversion ratio - pub conversion_ratio: Option, + pub conversion_ratio: Option, /// Breakeven point - pub balance_point: Option, + pub balance_point: Option, /// Open interest pub open_interest: Option, /// Delta - pub delta: Option, + pub delta: Option, /// Gamma - pub gamma: Option, + pub gamma: Option, /// Theta - pub theta: Option, + pub theta: Option, /// Vega - pub vega: Option, + pub vega: Option, /// Rho - pub rho: Option, + pub rho: Option, } impl SecurityCalcIndex {