dceapi_rs/
models.rs

1//! Data models for the DCE API.
2//!
3//! This module contains all request and response structures used by the API.
4
5use serde::{Deserialize, Deserializer, Serialize};
6use serde_json::Value;
7
8/// Helper function to deserialize a nullable string as an empty string.
9fn deserialize_nullable_string<'de, D>(deserializer: D) -> Result<String, D::Error>
10where
11    D: Deserializer<'de>,
12{
13    let opt: Option<String> = Option::deserialize(deserializer)?;
14    Ok(opt.unwrap_or_default())
15}
16
17/// Deserialize a string or number to i64
18fn deserialize_string_or_i64<'de, D>(deserializer: D) -> Result<i64, D::Error>
19where
20    D: Deserializer<'de>,
21{
22    use serde::de::Error;
23    use serde_json::Value;
24
25    let value = Value::deserialize(deserializer)?;
26    match value {
27        Value::Number(n) => n.as_i64().ok_or_else(|| D::Error::custom("invalid number")),
28        Value::String(s) => s
29            .parse::<i64>()
30            .map_err(|_| D::Error::custom("invalid string number")),
31        Value::Null => Ok(0),
32        _ => Err(D::Error::custom("expected string or number")),
33    }
34}
35
36// ============================================================================
37// Common Response Models
38// ============================================================================
39
40/// API common response wrapper.
41#[derive(Debug, Clone, Deserialize)]
42pub struct ApiResponse {
43    /// Response code.
44    pub code: i32,
45    /// Response message (field name is "msg" in the API).
46    #[serde(alias = "message", default)]
47    pub msg: String,
48    /// Response data (raw JSON).
49    #[serde(default)]
50    pub data: Value,
51}
52
53/// Token response from authentication endpoint.
54#[derive(Debug, Clone, Deserialize)]
55#[serde(rename_all = "camelCase")]
56pub struct TokenResponse {
57    /// Token type (e.g., "Bearer").
58    pub token_type: String,
59    /// Access token.
60    #[serde(rename = "token")]
61    pub access_token: String,
62    /// Token expiry time in seconds.
63    pub expires_in: i32,
64}
65
66// ============================================================================
67// News/Article Models (资讯数据模型)
68// ============================================================================
69
70/// Article information.
71#[derive(Debug, Clone, Serialize, Deserialize)]
72#[serde(rename_all = "camelCase")]
73pub struct Article {
74    /// Article ID.
75    #[serde(default, deserialize_with = "deserialize_nullable_string")]
76    pub id: String,
77    /// Article version.
78    #[serde(default, deserialize_with = "deserialize_nullable_string")]
79    pub version: String,
80    /// Article title.
81    #[serde(default, deserialize_with = "deserialize_nullable_string")]
82    pub title: String,
83    /// Article subtitle.
84    #[serde(default, deserialize_with = "deserialize_nullable_string")]
85    pub sub_title: String,
86    /// Article summary.
87    #[serde(
88        rename = "infoSummary",
89        default,
90        deserialize_with = "deserialize_nullable_string"
91    )]
92    pub summary: String,
93    /// Source ID.
94    #[serde(default, deserialize_with = "deserialize_nullable_string")]
95    pub source_id: String,
96    /// Display date.
97    #[serde(default, deserialize_with = "deserialize_nullable_string")]
98    pub show_date: String,
99    /// Release date.
100    #[serde(default, deserialize_with = "deserialize_nullable_string")]
101    pub release_date: String,
102    /// Article content.
103    #[serde(default, deserialize_with = "deserialize_nullable_string")]
104    pub content: String,
105    /// Keywords.
106    #[serde(default, deserialize_with = "deserialize_nullable_string")]
107    pub keywords: String,
108    /// Entity type (e.g., "HTML").
109    #[serde(default, deserialize_with = "deserialize_nullable_string")]
110    pub entity_type: String,
111    /// Title image URL.
112    #[serde(default, deserialize_with = "deserialize_nullable_string")]
113    pub title_image_url: String,
114    /// Article static URL.
115    #[serde(default, deserialize_with = "deserialize_nullable_string")]
116    pub article_static_url: String,
117    /// Article dynamic URL.
118    #[serde(default, deserialize_with = "deserialize_nullable_string")]
119    pub article_dynamic_url: String,
120    /// Page name.
121    #[serde(default, deserialize_with = "deserialize_nullable_string")]
122    pub page_name: String,
123    /// Creation date.
124    #[serde(default, deserialize_with = "deserialize_nullable_string")]
125    pub create_date: String,
126}
127
128/// Request for paginated article list.
129#[derive(Debug, Clone, Serialize)]
130#[serde(rename_all = "camelCase")]
131pub struct GetArticleByPageRequest {
132    /// Column ID (e.g., "244" for announcements).
133    pub column_id: String,
134    /// Page number (1-indexed).
135    pub page_no: i32,
136    /// Page size.
137    pub page_size: i32,
138    /// Site ID. Defaults to 5.
139    pub site_id: i32,
140}
141
142/// Response for paginated article list.
143#[derive(Debug, Clone, Deserialize)]
144#[serde(rename_all = "camelCase")]
145pub struct GetArticleByPageResponse {
146    /// Column ID.
147    pub column_id: String,
148    /// Status code.
149    #[serde(default, deserialize_with = "deserialize_nullable_string")]
150    pub status: String,
151    /// Status information.
152    #[serde(default, deserialize_with = "deserialize_nullable_string")]
153    pub status_info: String,
154    /// List of articles.
155    pub result_list: Vec<Article>,
156    /// Total count of articles.
157    pub total_count: i32,
158}
159
160// ============================================================================
161// Common Data Models (通用数据模型)
162// ============================================================================
163
164/// Trade date information.
165#[derive(Debug, Clone, Deserialize)]
166#[serde(rename_all = "camelCase")]
167pub struct TradeDate {
168    /// Trade date string.
169    #[serde(
170        rename = "tradeDate",
171        default,
172        deserialize_with = "deserialize_nullable_string"
173    )]
174    pub date: String,
175}
176
177/// Variety (commodity) information.
178#[derive(Debug, Clone, Deserialize)]
179#[serde(rename_all = "camelCase")]
180pub struct Variety {
181    /// Variety code/ID.
182    #[serde(
183        rename = "varietyId",
184        default,
185        deserialize_with = "deserialize_nullable_string"
186    )]
187    pub code: String,
188    /// Variety name in Chinese.
189    #[serde(
190        rename = "varietyName",
191        default,
192        deserialize_with = "deserialize_nullable_string"
193    )]
194    pub name: String,
195    /// Variety name in English.
196    #[serde(
197        rename = "varietyEnglishName",
198        default,
199        deserialize_with = "deserialize_nullable_string"
200    )]
201    pub english_name: String,
202    /// Picture URL.
203    #[serde(default, deserialize_with = "deserialize_nullable_string")]
204    pub pic: String,
205    /// Variety type.
206    #[serde(
207        rename = "varietyType",
208        default,
209        deserialize_with = "deserialize_nullable_string"
210    )]
211    pub variety_type: String,
212}
213
214// ============================================================================
215// Market Data Models (行情数据模型)
216// ============================================================================
217
218/// Quote data for a contract.
219#[derive(Debug, Clone, Deserialize)]
220#[serde(rename_all = "camelCase")]
221pub struct Quote {
222    /// Variety name.
223    #[serde(default, deserialize_with = "deserialize_nullable_string")]
224    pub variety: String,
225    /// Variety order/code.
226    #[serde(
227        rename = "varietyOrder",
228        default,
229        deserialize_with = "deserialize_nullable_string"
230    )]
231    pub variety_order: String,
232    /// Contract ID.
233    #[serde(
234        rename = "contractId",
235        default,
236        deserialize_with = "deserialize_nullable_string"
237    )]
238    pub contract_id: String,
239    /// Delivery month (for night quotes).
240    #[serde(
241        rename = "delivMonth",
242        default,
243        deserialize_with = "deserialize_nullable_string"
244    )]
245    pub deliv_month: String,
246    /// Open price.
247    #[serde(default, deserialize_with = "deserialize_nullable_string")]
248    pub open: String,
249    /// High price.
250    #[serde(default, deserialize_with = "deserialize_nullable_string")]
251    pub high: String,
252    /// Low price.
253    #[serde(default, deserialize_with = "deserialize_nullable_string")]
254    pub low: String,
255    /// Close price.
256    #[serde(default, deserialize_with = "deserialize_nullable_string")]
257    pub close: String,
258    /// Last clearing price (前结算价).
259    #[serde(
260        rename = "lastClear",
261        default,
262        deserialize_with = "deserialize_nullable_string"
263    )]
264    pub last_clear: String,
265    /// Last price (最新价, for night quotes).
266    #[serde(
267        rename = "lastPrice",
268        default,
269        deserialize_with = "deserialize_nullable_string"
270    )]
271    pub last_price: String,
272    /// Clearing/settlement price (结算价).
273    #[serde(
274        rename = "clearPrice",
275        default,
276        deserialize_with = "deserialize_nullable_string"
277    )]
278    pub clear_price: String,
279    /// Price difference (涨跌).
280    #[serde(default, deserialize_with = "deserialize_nullable_string")]
281    pub diff: String,
282    /// Price difference 1 (涨跌1).
283    #[serde(default, deserialize_with = "deserialize_nullable_string")]
284    pub diff1: String,
285    /// Declare price (买价/卖价, for night quotes).
286    #[serde(
287        rename = "declarePrice",
288        default,
289        deserialize_with = "deserialize_nullable_string"
290    )]
291    pub declare_price: String,
292    /// Volume (成交量).
293    #[serde(rename = "volumn", default)]
294    pub volume: i64,
295    /// Open interest (持仓量).
296    #[serde(rename = "openInterest", default)]
297    pub open_interest: i64,
298    /// Open interest difference (持仓量变化).
299    #[serde(rename = "diffI", default)]
300    pub diff_i: i64,
301    /// Turnover (成交额).
302    #[serde(default, deserialize_with = "deserialize_nullable_string")]
303    pub turnover: String,
304    /// Variety name in English.
305    #[serde(
306        rename = "varietyEn",
307        default,
308        deserialize_with = "deserialize_nullable_string"
309    )]
310    pub variety_en: String,
311    /// Turnover in English format.
312    #[serde(
313        rename = "turnoverEn",
314        default,
315        deserialize_with = "deserialize_nullable_string"
316    )]
317    pub turnover_en: String,
318    /// Delta (期权).
319    #[serde(default, deserialize_with = "deserialize_nullable_string")]
320    pub delta: String,
321    /// Exercise quantity sum (行权量).
322    #[serde(rename = "matchQtySum", default)]
323    pub match_qty_sum: i64,
324    /// Turnover difference.
325    #[serde(
326        rename = "diffT",
327        default,
328        deserialize_with = "deserialize_nullable_string"
329    )]
330    pub diff_t: String,
331    /// Volume rate (期权期货成交比).
332    #[serde(
333        rename = "volumnRate",
334        default,
335        deserialize_with = "deserialize_nullable_string"
336    )]
337    pub volumn_rate: String,
338    /// Open interest rate (期权期货持仓比).
339    #[serde(
340        rename = "openInterestRate",
341        default,
342        deserialize_with = "deserialize_nullable_string"
343    )]
344    pub open_interest_rate: String,
345    /// Period over period change.
346    #[serde(
347        rename = "periodOverPeriodChg",
348        default,
349        deserialize_with = "deserialize_nullable_string"
350    )]
351    pub period_over_period_chg: String,
352    /// Volume difference.
353    #[serde(rename = "diffV", default)]
354    pub diff_v: Option<i64>,
355    /// Implied volatility (隐含波动率).
356    #[serde(
357        rename = "impliedVolatility",
358        default,
359        deserialize_with = "deserialize_nullable_string"
360    )]
361    pub implied_volatility: String,
362    /// Series ID (期权系列).
363    #[serde(
364        rename = "seriesId",
365        default,
366        deserialize_with = "deserialize_nullable_string"
367    )]
368    pub series_id: String,
369    /// Average open interest (日均持仓量).
370    #[serde(rename = "avgOpenInterest", default)]
371    pub avg_open_interest: i64,
372}
373
374/// Request for day/night quotes.
375#[derive(Debug, Clone, Serialize)]
376#[serde(rename_all = "camelCase")]
377pub struct QuotesRequest {
378    /// Variety ID.
379    #[serde(skip_serializing_if = "Option::is_none")]
380    pub variety_id: Option<String>,
381    /// Variety code (for night quotes).
382    #[serde(skip_serializing_if = "Option::is_none")]
383    pub variety: Option<String>,
384    /// Trade date (YYYYMMDD format).
385    pub trade_date: String,
386    /// Trade type ("1" = futures, "2" = options).
387    pub trade_type: String,
388    /// Language.
389    #[serde(skip_serializing_if = "Option::is_none")]
390    pub lang: Option<String>,
391    /// Statistics type for options: 0=contract, 1=series, 2=variety.
392    #[serde(skip_serializing_if = "Option::is_none")]
393    pub statistics_type: Option<i32>,
394}
395
396/// Request for weekly quotes.
397#[derive(Debug, Clone, Serialize)]
398#[serde(rename_all = "camelCase")]
399pub struct WeekQuotesRequest {
400    /// Variety code.
401    pub variety_code: String,
402    /// Year.
403    pub year: i32,
404    /// Week number.
405    pub week: i32,
406}
407
408/// Request for monthly quotes.
409#[derive(Debug, Clone, Serialize)]
410#[serde(rename_all = "camelCase")]
411pub struct MonthQuotesRequest {
412    /// Variety code.
413    pub variety_code: String,
414    /// Year.
415    pub year: i32,
416    /// Month.
417    pub month: i32,
418}
419
420// ============================================================================
421// Delivery Data Models (交割数据模型)
422// ============================================================================
423
424/// Delivery data.
425#[derive(Debug, Clone, Deserialize)]
426#[serde(rename_all = "camelCase")]
427pub struct DeliveryData {
428    /// Variety name.
429    #[serde(default, deserialize_with = "deserialize_nullable_string")]
430    pub variety: String,
431    /// Contract ID.
432    #[serde(default, deserialize_with = "deserialize_nullable_string")]
433    pub contract_id: String,
434    /// Delivery date.
435    #[serde(default, deserialize_with = "deserialize_nullable_string")]
436    pub delivery_date: String,
437    /// Delivery quantity.
438    #[serde(default)]
439    pub delivery_qty: i64,
440    /// Delivery amount.
441    #[serde(default, deserialize_with = "deserialize_nullable_string")]
442    pub delivery_amt: String,
443}
444
445/// Request for delivery data.
446#[derive(Debug, Clone, Serialize)]
447#[serde(rename_all = "camelCase")]
448pub struct DeliveryDataRequest {
449    /// Variety ID.
450    pub variety_id: String,
451    /// Start month (YYYYMM format).
452    pub start_month: String,
453    /// End month (YYYYMM format).
454    pub end_month: String,
455    /// Variety type ("0" = physical delivery, "1" = average price delivery).
456    pub variety_type: String,
457}
458
459/// Delivery match data.
460#[derive(Debug, Clone, Deserialize)]
461#[serde(rename_all = "camelCase")]
462pub struct DeliveryMatch {
463    /// Contract ID.
464    #[serde(default, deserialize_with = "deserialize_nullable_string")]
465    pub contract_id: String,
466    /// Match date.
467    #[serde(default, deserialize_with = "deserialize_nullable_string")]
468    pub match_date: String,
469    /// Buy member ID.
470    #[serde(default, deserialize_with = "deserialize_nullable_string")]
471    pub buy_member_id: String,
472    /// Sell member ID.
473    #[serde(default, deserialize_with = "deserialize_nullable_string")]
474    pub sell_member_id: String,
475    /// Delivery quantity.
476    #[serde(default)]
477    pub delivery_qty: i64,
478    /// Delivery price.
479    #[serde(default, deserialize_with = "deserialize_nullable_string")]
480    pub delivery_price: String,
481}
482
483/// Request for delivery match data.
484#[derive(Debug, Clone, Serialize)]
485#[serde(rename_all = "camelCase")]
486pub struct DeliveryMatchRequest {
487    /// Variety ID.
488    pub variety_id: String,
489    /// Contract ID ("all" for all contracts).
490    pub contract_id: String,
491    /// Start month (YYYYMM format).
492    pub start_month: String,
493    /// End month (YYYYMM format).
494    pub end_month: String,
495}
496
497/// Warehouse receipt daily report response.
498#[derive(Debug, Clone, Deserialize)]
499#[serde(rename_all = "camelCase")]
500pub struct WarehouseReceipt {
501    /// Entity list containing warehouse receipt details.
502    #[serde(rename = "entityList", default)]
503    pub entity_list: Vec<WarehouseReceiptDetail>,
504    /// Whether has agio flag.
505    #[serde(
506        rename = "ifAgioFlag",
507        default,
508        deserialize_with = "deserialize_nullable_string"
509    )]
510    pub if_agio_flag: String,
511    /// Agio delivery type.
512    #[serde(
513        rename = "agioDeliType",
514        default,
515        deserialize_with = "deserialize_nullable_string"
516    )]
517    pub agio_deli_type: String,
518    /// Whether has agio brand flag.
519    #[serde(
520        rename = "ifAgioBrandFlag",
521        default,
522        deserialize_with = "deserialize_nullable_string"
523    )]
524    pub if_agio_brand_flag: String,
525}
526
527/// Warehouse receipt detail entry.
528#[derive(Debug, Clone, Deserialize)]
529#[serde(rename_all = "camelCase")]
530pub struct WarehouseReceiptDetail {
531    /// Variety order.
532    #[serde(
533        rename = "varietyOrder",
534        default,
535        deserialize_with = "deserialize_nullable_string"
536    )]
537    pub variety_order: String,
538    /// Group code order.
539    #[serde(
540        rename = "groupCodeOrder",
541        default,
542        deserialize_with = "deserialize_nullable_string"
543    )]
544    pub group_code_order: String,
545    /// Warehouse code order.
546    #[serde(
547        rename = "whCodeOrder",
548        default,
549        deserialize_with = "deserialize_nullable_string"
550    )]
551    pub wh_code_order: String,
552    /// Warehouse type.
553    #[serde(
554        rename = "whType",
555        default,
556        deserialize_with = "deserialize_nullable_string"
557    )]
558    pub wh_type: String,
559    /// Variety name.
560    #[serde(default, deserialize_with = "deserialize_nullable_string")]
561    pub variety: String,
562    /// Generation date.
563    #[serde(
564        rename = "genDate",
565        default,
566        deserialize_with = "deserialize_nullable_string"
567    )]
568    pub gen_date: String,
569    /// Warehouse abbreviation.
570    #[serde(
571        rename = "whAbbr",
572        default,
573        deserialize_with = "deserialize_nullable_string"
574    )]
575    pub wh_abbr: String,
576    /// Delivery abbreviation.
577    #[serde(
578        rename = "deliveryAbbr",
579        default,
580        deserialize_with = "deserialize_nullable_string"
581    )]
582    pub delivery_abbr: String,
583    /// Yesterday's warehouse bill quantity (lots).
584    #[serde(rename = "lastWbillQty", default)]
585    pub last_wbill_qty: i64,
586    /// Registered warehouse bill quantity.
587    #[serde(rename = "regWbillQty", default)]
588    pub reg_wbill_qty: i64,
589    /// Logout warehouse bill quantity.
590    #[serde(rename = "logoutWbillQty", default)]
591    pub logout_wbill_qty: i64,
592    /// Today's warehouse bill quantity (lots).
593    #[serde(rename = "wbillQty", default)]
594    pub wbill_qty: i64,
595    /// Difference (lots).
596    #[serde(default)]
597    pub diff: i64,
598}
599
600/// Request for warehouse receipt data (daily report).
601#[derive(Debug, Clone, Serialize)]
602#[serde(rename_all = "camelCase")]
603pub struct WarehouseReceiptRequest {
604    /// Variety ID ("all" for all varieties).
605    pub variety_id: String,
606    /// Trade date (YYYYMMDD format).
607    pub trade_date: String,
608}
609
610/// Delivery cost data.
611#[derive(Debug, Clone, Deserialize)]
612#[serde(rename_all = "camelCase")]
613pub struct DeliveryCost {
614    /// Variety name.
615    #[serde(default, deserialize_with = "deserialize_nullable_string")]
616    pub variety: String,
617    /// Earnest rate.
618    #[serde(default, deserialize_with = "deserialize_nullable_string")]
619    pub earnest_rate: String,
620    /// Unit.
621    #[serde(default, deserialize_with = "deserialize_nullable_string")]
622    pub unit: String,
623    /// Delivery fee.
624    #[serde(default, deserialize_with = "deserialize_nullable_string")]
625    pub delivery_fee: String,
626    /// Fee rate.
627    #[serde(default, deserialize_with = "deserialize_nullable_string")]
628    pub fee_rate: String,
629    /// Start date.
630    #[serde(default, deserialize_with = "deserialize_nullable_string")]
631    pub start_date: String,
632    /// End date.
633    #[serde(default, deserialize_with = "deserialize_nullable_string")]
634    pub end_date: String,
635}
636
637/// Warehouse premium data.
638/// Warehouse premium response wrapper.
639#[derive(Debug, Clone, Deserialize)]
640#[serde(rename_all = "camelCase")]
641pub struct WarehousePremiumResponse {
642    /// Entity list containing warehouse premium details.
643    #[serde(rename = "entityList", default)]
644    pub entity_list: Vec<WarehousePremium>,
645    /// Whether has agio flag.
646    #[serde(
647        rename = "ifAgioFlag",
648        default,
649        deserialize_with = "deserialize_nullable_string"
650    )]
651    pub if_agio_flag: String,
652}
653
654/// Warehouse premium data.
655#[derive(Debug, Clone, Deserialize)]
656#[serde(rename_all = "camelCase")]
657pub struct WarehousePremium {
658    /// Variety ID.
659    #[serde(default, deserialize_with = "deserialize_nullable_string")]
660    pub variety_id: String,
661    /// Variety name.
662    #[serde(default, deserialize_with = "deserialize_nullable_string")]
663    pub variety_name: String,
664    /// Valid date.
665    #[serde(default, deserialize_with = "deserialize_nullable_string")]
666    pub valid_date: String,
667    /// Warehouse code.
668    #[serde(
669        rename = "whCode",
670        default,
671        deserialize_with = "deserialize_nullable_string"
672    )]
673    pub wh_code: String,
674    /// Warehouse name.
675    #[serde(
676        rename = "whName",
677        default,
678        deserialize_with = "deserialize_nullable_string"
679    )]
680    pub wh_name: String,
681    /// Average premium (元/吨).
682    #[serde(
683        rename = "avgAgio",
684        default,
685        deserialize_with = "deserialize_nullable_string"
686    )]
687    pub avg_agio: String,
688    /// Warehouse group abbreviation.
689    #[serde(
690        rename = "whGroupAbbr",
691        default,
692        deserialize_with = "deserialize_nullable_string"
693    )]
694    pub wh_group_abbr: String,
695    /// Brand abbreviation.
696    #[serde(
697        rename = "brandAbbr",
698        default,
699        deserialize_with = "deserialize_nullable_string"
700    )]
701    pub brand_abbr: String,
702}
703
704// ============================================================================
705// Member Data Models (会员数据模型)
706// ============================================================================
707
708/// Ranking data entry.
709#[derive(Debug, Clone, Deserialize)]
710#[serde(rename_all = "camelCase")]
711pub struct Ranking {
712    /// Rank position.
713    #[serde(default, deserialize_with = "deserialize_nullable_string")]
714    pub rank: String,
715    /// Volume member abbreviation.
716    #[serde(
717        rename = "qtyAbbr",
718        default,
719        deserialize_with = "deserialize_nullable_string"
720    )]
721    pub qty_abbr: String,
722    /// Today's volume.
723    #[serde(rename = "todayQty", default)]
724    pub today_qty: i64,
725    /// Volume change.
726    #[serde(rename = "qtySub", default)]
727    pub qty_sub: i64,
728    /// Buy member abbreviation.
729    #[serde(
730        rename = "buyAbbr",
731        default,
732        deserialize_with = "deserialize_nullable_string"
733    )]
734    pub buy_abbr: String,
735    /// Today's buy quantity.
736    #[serde(rename = "todayBuyQty", default)]
737    pub today_buy_qty: i64,
738    /// Buy quantity change.
739    #[serde(rename = "buySub", default)]
740    pub buy_sub: i64,
741    /// Sell member abbreviation.
742    #[serde(
743        rename = "sellAbbr",
744        default,
745        deserialize_with = "deserialize_nullable_string"
746    )]
747    pub sell_abbr: String,
748    /// Today's sell quantity.
749    #[serde(rename = "todaySellQty", default)]
750    pub today_sell_qty: i64,
751    /// Sell quantity change.
752    #[serde(rename = "sellSub", default)]
753    pub sell_sub: i64,
754}
755
756/// Request for daily ranking.
757#[derive(Debug, Clone, Serialize)]
758#[serde(rename_all = "camelCase")]
759pub struct DailyRankingRequest {
760    /// Variety ID.
761    pub variety_id: String,
762    /// Contract ID.
763    pub contract_id: String,
764    /// Trade date.
765    pub trade_date: String,
766    /// Trade type ("1" = futures, "2" = options).
767    pub trade_type: String,
768}
769
770/// Response for daily ranking.
771#[derive(Debug, Clone, Deserialize)]
772#[serde(rename_all = "camelCase")]
773pub struct DailyRankingResponse {
774    /// Contract ID.
775    #[serde(
776        rename = "contractId",
777        default,
778        deserialize_with = "deserialize_nullable_string"
779    )]
780    pub contract_id: String,
781    /// Today's total volume.
782    #[serde(rename = "todayQty", default)]
783    pub today_qty: i64,
784    /// Volume change.
785    #[serde(rename = "qtySub", default)]
786    pub qty_sub: i64,
787    /// Today's buy quantity.
788    #[serde(rename = "todayBuyQty", default)]
789    pub today_buy_qty: i64,
790    /// Buy quantity change.
791    #[serde(rename = "buySub", default)]
792    pub buy_sub: i64,
793    /// Today's sell quantity.
794    #[serde(rename = "todaySellQty", default)]
795    pub today_sell_qty: i64,
796    /// Sell quantity change.
797    #[serde(rename = "sellSub", default)]
798    pub sell_sub: i64,
799    /// Volume ranking list.
800    #[serde(rename = "qtyFutureList", default)]
801    pub qty_future_list: Vec<Ranking>,
802    /// Buy ranking list.
803    #[serde(rename = "buyFutureList", default)]
804    pub buy_future_list: Vec<Ranking>,
805    /// Sell ranking list.
806    #[serde(rename = "sellFutureList", default)]
807    pub sell_future_list: Vec<Ranking>,
808}
809
810/// Request for phase ranking.
811#[derive(Debug, Clone, Serialize)]
812#[serde(rename_all = "camelCase")]
813pub struct PhaseRankingRequest {
814    /// Variety code.
815    pub variety: String,
816    /// Start month.
817    pub start_month: String,
818    /// End month.
819    pub end_month: String,
820    /// Trade type.
821    pub trade_type: String,
822}
823
824/// Phase ranking data.
825#[derive(Debug, Clone, Deserialize)]
826#[serde(rename_all = "camelCase")]
827pub struct PhaseRanking {
828    /// Sequence number.
829    #[serde(default, deserialize_with = "deserialize_nullable_string")]
830    pub seq: String,
831    /// Member ID.
832    #[serde(
833        rename = "memberId",
834        default,
835        deserialize_with = "deserialize_nullable_string"
836    )]
837    pub member_id: String,
838    /// Member name.
839    #[serde(
840        rename = "memberName",
841        default,
842        deserialize_with = "deserialize_nullable_string"
843    )]
844    pub member_name: String,
845    /// Monthly volume.
846    #[serde(rename = "monthQty", default)]
847    pub month_qty: f64,
848    /// Volume ratio.
849    #[serde(rename = "qtyRatio", default)]
850    pub qty_ratio: f64,
851    /// Monthly amount.
852    #[serde(rename = "monthAmt", default)]
853    pub month_amt: f64,
854    /// Amount ratio.
855    #[serde(rename = "amtRatio", default)]
856    pub amt_ratio: f64,
857}
858
859// ============================================================================
860// Trade Parameter Models (交易参数数据模型)
861// ============================================================================
862
863/// Trade parameter data.
864#[derive(Debug, Clone, Deserialize)]
865#[serde(rename_all = "camelCase")]
866pub struct TradeParam {
867    /// Contract ID.
868    #[serde(
869        rename = "contractId",
870        default,
871        deserialize_with = "deserialize_nullable_string"
872    )]
873    pub contract_id: String,
874    /// Speculative buy margin rate.
875    #[serde(rename = "specBuyRate", default)]
876    pub spec_buy_rate: f64,
877    /// Speculative buy margin.
878    #[serde(rename = "specBuy", default)]
879    pub spec_buy: f64,
880    /// Hedge buy margin rate.
881    #[serde(rename = "hedgeBuyRate", default)]
882    pub hedge_buy_rate: f64,
883    /// Hedge buy margin.
884    #[serde(rename = "hedgeBuy", default)]
885    pub hedge_buy: f64,
886    /// Rise limit rate.
887    #[serde(rename = "riseLimitRate", default)]
888    pub rise_limit_rate: f64,
889    /// Rise limit price.
890    #[serde(rename = "riseLimit", default)]
891    pub rise_limit: f64,
892    /// Fall limit price.
893    #[serde(rename = "fallLimit", default)]
894    pub fall_limit: f64,
895    /// Position limit style.
896    #[serde(default, deserialize_with = "deserialize_nullable_string")]
897    pub style: String,
898    /// Non-futures company member futures position quota.
899    #[serde(rename = "selfTotBuyPosiQuota", default)]
900    pub self_tot_buy_posi_quota: Option<f64>,
901    /// Non-futures company member options position quota.
902    #[serde(rename = "selfTotBuyPosiQuotaSerLimit", default)]
903    pub self_tot_buy_posi_quota_ser_limit: Option<f64>,
904    /// Client futures position quota.
905    #[serde(rename = "clientBuyPosiQuota", default)]
906    pub client_buy_posi_quota: Option<f64>,
907    /// Client options position quota.
908    #[serde(rename = "clientBuyPosiQuotaSerLimit", default)]
909    pub client_buy_posi_quota_ser_limit: Option<f64>,
910    /// Contract limit.
911    #[serde(
912        rename = "contractLimit",
913        default,
914        deserialize_with = "deserialize_nullable_string"
915    )]
916    pub contract_limit: String,
917    /// Variety limit.
918    #[serde(
919        rename = "varietyLimit",
920        default,
921        deserialize_with = "deserialize_nullable_string"
922    )]
923    pub variety_limit: String,
924    /// Trade date.
925    #[serde(
926        rename = "tradeDate",
927        default,
928        deserialize_with = "deserialize_nullable_string"
929    )]
930    pub trade_date: String,
931}
932
933/// Request for day trade parameters.
934#[derive(Debug, Clone, Serialize)]
935#[serde(rename_all = "camelCase")]
936pub struct DayTradeParamRequest {
937    /// Variety ID.
938    pub variety_id: String,
939    /// Trade type.
940    pub trade_type: String,
941    /// Language.
942    pub lang: String,
943}
944
945/// Contract information.
946#[derive(Debug, Clone, Deserialize)]
947#[serde(rename_all = "camelCase")]
948pub struct ContractInfo {
949    /// Contract ID.
950    #[serde(
951        rename = "contractId",
952        default,
953        deserialize_with = "deserialize_nullable_string"
954    )]
955    pub contract_id: String,
956    /// Variety code.
957    #[serde(default, deserialize_with = "deserialize_nullable_string")]
958    pub variety: String,
959    /// Variety order.
960    #[serde(
961        rename = "varietyOrder",
962        default,
963        deserialize_with = "deserialize_nullable_string"
964    )]
965    pub variety_order: String,
966    /// Contract unit.
967    #[serde(default)]
968    pub unit: i32,
969    /// Minimum tick.
970    #[serde(default, deserialize_with = "deserialize_nullable_string")]
971    pub tick: String,
972    /// Start trade date.
973    #[serde(
974        rename = "startTradeDate",
975        default,
976        deserialize_with = "deserialize_nullable_string"
977    )]
978    pub start_trade_date: String,
979    /// End trade date.
980    #[serde(
981        rename = "endTradeDate",
982        default,
983        deserialize_with = "deserialize_nullable_string"
984    )]
985    pub end_trade_date: String,
986    /// End delivery date.
987    #[serde(
988        rename = "endDeliveryDate",
989        default,
990        deserialize_with = "deserialize_nullable_string"
991    )]
992    pub end_delivery_date: String,
993    /// Trade type.
994    #[serde(
995        rename = "tradeType",
996        default,
997        deserialize_with = "deserialize_nullable_string"
998    )]
999    pub trade_type: String,
1000}
1001
1002/// Request for contract information.
1003#[derive(Debug, Clone, Serialize)]
1004#[serde(rename_all = "camelCase")]
1005pub struct ContractInfoRequest {
1006    /// Variety ID.
1007    pub variety_id: String,
1008    /// Trade type.
1009    pub trade_type: String,
1010    /// Language.
1011    pub lang: String,
1012}
1013
1014/// Arbitrage contract information.
1015#[derive(Debug, Clone, Deserialize)]
1016#[serde(rename_all = "camelCase")]
1017pub struct ArbitrageContract {
1018    /// Arbitrage strategy name.
1019    #[serde(
1020        rename = "arbiName",
1021        default,
1022        deserialize_with = "deserialize_nullable_string"
1023    )]
1024    pub arbi_name: String,
1025    /// Variety name.
1026    #[serde(
1027        rename = "varietyName",
1028        default,
1029        deserialize_with = "deserialize_nullable_string"
1030    )]
1031    pub variety_name: String,
1032    /// Arbitrage contract ID.
1033    #[serde(
1034        rename = "arbiContractId",
1035        default,
1036        deserialize_with = "deserialize_nullable_string"
1037    )]
1038    pub arbi_contract_id: String,
1039    /// Maximum order size.
1040    #[serde(rename = "maxHand", default)]
1041    pub max_hand: i32,
1042    /// Minimum tick.
1043    #[serde(default)]
1044    pub tick: f64,
1045}
1046
1047/// Request for arbitrage contracts.
1048#[derive(Debug, Clone, Serialize)]
1049#[serde(rename_all = "camelCase")]
1050pub struct ArbitrageContractRequest {
1051    /// Language.
1052    pub lang: String,
1053}
1054
1055// ============================================================================
1056// Settlement Parameter Models (结算参数数据模型)
1057// ============================================================================
1058
1059/// Settlement parameter data.
1060#[derive(Debug, Clone, Deserialize)]
1061#[serde(rename_all = "camelCase")]
1062pub struct SettleParam {
1063    /// Variety code.
1064    #[serde(default, deserialize_with = "deserialize_nullable_string")]
1065    pub variety: String,
1066    /// Variety order.
1067    #[serde(
1068        rename = "varietyOrder",
1069        default,
1070        deserialize_with = "deserialize_nullable_string"
1071    )]
1072    pub variety_order: String,
1073    /// Contract ID.
1074    #[serde(
1075        rename = "contractId",
1076        default,
1077        deserialize_with = "deserialize_nullable_string"
1078    )]
1079    pub contract_id: String,
1080    /// Clearing/settlement price.
1081    #[serde(
1082        rename = "clearPrice",
1083        default,
1084        deserialize_with = "deserialize_nullable_string"
1085    )]
1086    pub clear_price: String,
1087    /// Open fee.
1088    #[serde(
1089        rename = "openFee",
1090        default,
1091        deserialize_with = "deserialize_nullable_string"
1092    )]
1093    pub open_fee: String,
1094    /// Offset fee.
1095    #[serde(
1096        rename = "offsetFee",
1097        default,
1098        deserialize_with = "deserialize_nullable_string"
1099    )]
1100    pub offset_fee: String,
1101    /// Short open fee (intraday).
1102    #[serde(
1103        rename = "shortOpenFee",
1104        default,
1105        deserialize_with = "deserialize_nullable_string"
1106    )]
1107    pub short_open_fee: String,
1108    /// Short offset fee (intraday).
1109    #[serde(
1110        rename = "shortOffsetFee",
1111        default,
1112        deserialize_with = "deserialize_nullable_string"
1113    )]
1114    pub short_offset_fee: String,
1115    /// Position limit style.
1116    #[serde(default, deserialize_with = "deserialize_nullable_string")]
1117    pub style: String,
1118    /// Speculative buy margin rate.
1119    #[serde(
1120        rename = "specBuyRate",
1121        default,
1122        deserialize_with = "deserialize_nullable_string"
1123    )]
1124    pub spec_buy_rate: String,
1125    /// Speculative sell margin rate.
1126    #[serde(
1127        rename = "specSellRate",
1128        default,
1129        deserialize_with = "deserialize_nullable_string"
1130    )]
1131    pub spec_sell_rate: String,
1132    /// Hedge buy margin rate.
1133    #[serde(
1134        rename = "hedgeBuyRate",
1135        default,
1136        deserialize_with = "deserialize_nullable_string"
1137    )]
1138    pub hedge_buy_rate: String,
1139    /// Hedge sell margin rate.
1140    #[serde(
1141        rename = "hedgeSellRate",
1142        default,
1143        deserialize_with = "deserialize_nullable_string"
1144    )]
1145    pub hedge_sell_rate: String,
1146}
1147
1148/// Request for settlement parameters.
1149#[derive(Debug, Clone, Serialize)]
1150#[serde(rename_all = "camelCase")]
1151pub struct SettleParamRequest {
1152    /// Variety ID.
1153    pub variety_id: String,
1154    /// Trade date.
1155    pub trade_date: String,
1156    /// Trade type.
1157    pub trade_type: String,
1158    /// Language.
1159    pub lang: String,
1160}
1161
1162// ============================================================================
1163// Extended Market Models (扩展行情数据模型)
1164// ============================================================================
1165
1166/// Request for variety month/year statistics.
1167#[derive(Debug, Clone, Serialize)]
1168#[serde(rename_all = "camelCase")]
1169pub struct VarietyMonthYearStatRequest {
1170    /// Trade month (YYYYMM format).
1171    pub trade_month: String,
1172    /// Trade type ("1" = futures, "2" = options).
1173    pub trade_type: String,
1174    /// Language ("zh" or "en").
1175    pub lang: String,
1176}
1177
1178/// Variety monthly/yearly statistics.
1179#[derive(Debug, Clone, Deserialize)]
1180#[serde(rename_all = "camelCase")]
1181pub struct VarietyMonthYearStat {
1182    /// Variety name.
1183    #[serde(default, deserialize_with = "deserialize_nullable_string")]
1184    pub variety: String,
1185    /// This month volume.
1186    #[serde(rename = "thisMonthVolumn", default)]
1187    pub this_month_volumn: i64,
1188    /// Volume year-over-year comparison.
1189    #[serde(
1190        rename = "volumnBalance",
1191        default,
1192        deserialize_with = "deserialize_nullable_string"
1193    )]
1194    pub volumn_balance: String,
1195    /// Volume month-over-month comparison.
1196    #[serde(
1197        rename = "volumnChain",
1198        default,
1199        deserialize_with = "deserialize_nullable_string"
1200    )]
1201    pub volumn_chain: String,
1202    /// This year volume.
1203    #[serde(rename = "thisYearVolumn", default)]
1204    pub this_year_volumn: i64,
1205    /// Year volume year-over-year comparison.
1206    #[serde(
1207        rename = "yearVolumnChain",
1208        default,
1209        deserialize_with = "deserialize_nullable_string"
1210    )]
1211    pub year_volumn_chain: String,
1212    /// This month turnover.
1213    #[serde(
1214        rename = "thisMonthTurnover",
1215        default,
1216        deserialize_with = "deserialize_nullable_string"
1217    )]
1218    pub this_month_turnover: String,
1219    /// Turnover year-over-year comparison.
1220    #[serde(
1221        rename = "turnoverBalance",
1222        default,
1223        deserialize_with = "deserialize_nullable_string"
1224    )]
1225    pub turnover_balance: String,
1226    /// Turnover month-over-month comparison.
1227    #[serde(
1228        rename = "turnoverChain",
1229        default,
1230        deserialize_with = "deserialize_nullable_string"
1231    )]
1232    pub turnover_chain: String,
1233    /// This year turnover.
1234    #[serde(
1235        rename = "thisYearTurnover",
1236        default,
1237        deserialize_with = "deserialize_nullable_string"
1238    )]
1239    pub this_year_turnover: String,
1240    /// Year turnover year-over-year comparison.
1241    #[serde(
1242        rename = "yearTurnoverChain",
1243        default,
1244        deserialize_with = "deserialize_nullable_string"
1245    )]
1246    pub year_turnover_chain: String,
1247    /// This month open interest.
1248    #[serde(rename = "thisMonthOpeni", default)]
1249    pub this_month_openi: i64,
1250    /// Open interest year-over-year comparison.
1251    #[serde(
1252        rename = "openiBalance",
1253        default,
1254        deserialize_with = "deserialize_nullable_string"
1255    )]
1256    pub openi_balance: String,
1257    /// Open interest month-over-month comparison.
1258    #[serde(
1259        rename = "openiChain",
1260        default,
1261        deserialize_with = "deserialize_nullable_string"
1262    )]
1263    pub openi_chain: String,
1264}
1265
1266/// Request for contract monthly max statistics.
1267#[derive(Debug, Clone, Serialize)]
1268#[serde(rename_all = "camelCase")]
1269pub struct ContractMonthMaxRequest {
1270    /// Start month (YYYYMM format).
1271    pub start_month: String,
1272    /// End month (YYYYMM format).
1273    pub end_month: String,
1274    /// Statistics content: "0"=volume, "1"=turnover, "2"=open_interest, "3"=price.
1275    pub stat_content: String,
1276    /// Trade type ("1" = futures, "2" = options).
1277    pub trade_type: String,
1278    /// Language ("zh" or "en").
1279    pub lang: String,
1280}
1281
1282/// Contract monthly max - Volume statistics.
1283#[derive(Debug, Clone, Deserialize)]
1284#[serde(rename_all = "camelCase")]
1285pub struct ContractMonthMaxVolume {
1286    /// Contract ID.
1287    #[serde(
1288        rename = "contractId",
1289        default,
1290        deserialize_with = "deserialize_nullable_string"
1291    )]
1292    pub contract_id: String,
1293    /// Total volume.
1294    #[serde(rename = "sumAmount", default)]
1295    pub sum_amount: i64,
1296    /// Maximum volume.
1297    #[serde(rename = "maxAmount", default)]
1298    pub max_amount: i64,
1299    /// Date of maximum volume.
1300    #[serde(
1301        rename = "maxAmountDate",
1302        default,
1303        deserialize_with = "deserialize_nullable_string"
1304    )]
1305    pub max_amount_date: String,
1306    /// Minimum volume.
1307    #[serde(rename = "minAmount", default)]
1308    pub min_amount: i64,
1309    /// Date of minimum volume.
1310    #[serde(
1311        rename = "minAmountDate",
1312        default,
1313        deserialize_with = "deserialize_nullable_string"
1314    )]
1315    pub min_amount_date: String,
1316    /// Average daily volume.
1317    #[serde(rename = "avgAmount", default)]
1318    pub avg_amount: i64,
1319}
1320
1321/// Contract monthly max - Turnover statistics.
1322#[derive(Debug, Clone, Deserialize)]
1323#[serde(rename_all = "camelCase")]
1324pub struct ContractMonthMaxTurnover {
1325    /// Contract ID.
1326    #[serde(
1327        rename = "contractId",
1328        default,
1329        deserialize_with = "deserialize_nullable_string"
1330    )]
1331    pub contract_id: String,
1332    /// Total turnover.
1333    #[serde(
1334        rename = "sumTurnover",
1335        default,
1336        deserialize_with = "deserialize_nullable_string"
1337    )]
1338    pub sum_turnover: String,
1339    /// Maximum turnover.
1340    #[serde(
1341        rename = "maxTurnover",
1342        default,
1343        deserialize_with = "deserialize_nullable_string"
1344    )]
1345    pub max_turnover: String,
1346    /// Date of maximum turnover.
1347    #[serde(
1348        rename = "maxTurnoverDate",
1349        default,
1350        deserialize_with = "deserialize_nullable_string"
1351    )]
1352    pub max_turnover_date: String,
1353    /// Minimum turnover.
1354    #[serde(
1355        rename = "minTurnover",
1356        default,
1357        deserialize_with = "deserialize_nullable_string"
1358    )]
1359    pub min_turnover: String,
1360    /// Date of minimum turnover.
1361    #[serde(
1362        rename = "minTurnoverDate",
1363        default,
1364        deserialize_with = "deserialize_nullable_string"
1365    )]
1366    pub min_turnover_date: String,
1367    /// Average daily turnover.
1368    #[serde(
1369        rename = "avgTurnover",
1370        default,
1371        deserialize_with = "deserialize_nullable_string"
1372    )]
1373    pub avg_turnover: String,
1374}
1375
1376/// Contract monthly max - Open Interest statistics.
1377#[derive(Debug, Clone, Deserialize)]
1378#[serde(rename_all = "camelCase")]
1379pub struct ContractMonthMaxOpeni {
1380    /// Contract ID.
1381    #[serde(
1382        rename = "contractId",
1383        default,
1384        deserialize_with = "deserialize_nullable_string"
1385    )]
1386    pub contract_id: String,
1387    /// Total open interest.
1388    #[serde(rename = "sumOpeni", default)]
1389    pub sum_openi: i64,
1390    /// Maximum open interest.
1391    #[serde(rename = "maxOpeni", default)]
1392    pub max_openi: i64,
1393    /// Date of maximum open interest.
1394    #[serde(
1395        rename = "maxOpeniDate",
1396        default,
1397        deserialize_with = "deserialize_nullable_string"
1398    )]
1399    pub max_openi_date: String,
1400    /// Minimum open interest.
1401    #[serde(rename = "minOpeni", default)]
1402    pub min_openi: i64,
1403    /// Date of minimum open interest.
1404    #[serde(
1405        rename = "minOpeniDate",
1406        default,
1407        deserialize_with = "deserialize_nullable_string"
1408    )]
1409    pub min_openi_date: String,
1410    /// Average daily open interest.
1411    #[serde(rename = "avgOpeni", default)]
1412    pub avg_openi: i64,
1413}
1414
1415/// Contract monthly max - Price statistics.
1416#[derive(Debug, Clone, Deserialize)]
1417#[serde(rename_all = "camelCase")]
1418pub struct ContractMonthMaxPrice {
1419    /// Contract ID.
1420    #[serde(
1421        rename = "contractId",
1422        default,
1423        deserialize_with = "deserialize_nullable_string"
1424    )]
1425    pub contract_id: String,
1426    /// Opening price at period start.
1427    #[serde(default, deserialize_with = "deserialize_nullable_string")]
1428    pub open: String,
1429    /// Closing price at period end.
1430    #[serde(default, deserialize_with = "deserialize_nullable_string")]
1431    pub close: String,
1432    /// Highest price.
1433    #[serde(default, deserialize_with = "deserialize_nullable_string")]
1434    pub high: String,
1435    /// Date of highest price.
1436    #[serde(
1437        rename = "highDate",
1438        default,
1439        deserialize_with = "deserialize_nullable_string"
1440    )]
1441    pub high_date: String,
1442    /// Lowest price.
1443    #[serde(default, deserialize_with = "deserialize_nullable_string")]
1444    pub low: String,
1445    /// Date of lowest price.
1446    #[serde(
1447        rename = "lowDate",
1448        default,
1449        deserialize_with = "deserialize_nullable_string"
1450    )]
1451    pub low_date: String,
1452    /// Settlement price at period end.
1453    #[serde(
1454        rename = "clearPrice",
1455        default,
1456        deserialize_with = "deserialize_nullable_string"
1457    )]
1458    pub clear_price: String,
1459}
1460
1461/// Request for rise/fall event (trading limit) query.
1462#[derive(Debug, Clone, Serialize)]
1463#[serde(rename_all = "camelCase")]
1464pub struct RiseFallEventRequest {
1465    /// Start date (YYYYMMDD format).
1466    pub start_date: String,
1467    /// End date (YYYYMMDD format).
1468    pub end_date: String,
1469    /// Variety ID ("all" for all varieties).
1470    pub variety_id: String,
1471    /// Language ("zh" or "en").
1472    pub lang: String,
1473}
1474
1475/// Rise/fall event (trading limit) information.
1476#[derive(Debug, Clone, Deserialize)]
1477#[serde(rename_all = "camelCase")]
1478pub struct RiseFallEvent {
1479    /// Trade date.
1480    #[serde(
1481        rename = "tradeDate",
1482        default,
1483        deserialize_with = "deserialize_nullable_string"
1484    )]
1485    pub trade_date: String,
1486    /// Contract ID.
1487    #[serde(
1488        rename = "contractId",
1489        default,
1490        deserialize_with = "deserialize_nullable_string"
1491    )]
1492    pub contract_id: String,
1493    /// Direction (limit up/down).
1494    #[serde(default, deserialize_with = "deserialize_nullable_string")]
1495    pub direction: String,
1496    /// Number of times.
1497    #[serde(default)]
1498    pub times: i32,
1499}
1500
1501/// Request for division price info.
1502#[derive(Debug, Clone, Serialize)]
1503#[serde(rename_all = "camelCase")]
1504pub struct DivisionPriceInfoRequest {
1505    /// Variety ID.
1506    pub variety_id: String,
1507    /// Trade date (YYYYMMDD format).
1508    pub trade_date: String,
1509    /// Trade type ("1" = futures, "2" = options).
1510    pub trade_type: String,
1511}
1512
1513/// Division price information (分时结算参考价).
1514#[derive(Debug, Clone, Deserialize)]
1515#[serde(rename_all = "camelCase")]
1516pub struct DivisionPriceInfo {
1517    /// Calculate date (交易日期).
1518    #[serde(
1519        rename = "calculateDate",
1520        default,
1521        deserialize_with = "deserialize_nullable_string"
1522    )]
1523    pub calculate_date: String,
1524    /// Calculate time (计算时间).
1525    #[serde(
1526        rename = "calculateTime",
1527        default,
1528        deserialize_with = "deserialize_nullable_string"
1529    )]
1530    pub calculate_time: String,
1531    /// Variety name (品种名称).
1532    #[serde(
1533        rename = "varietyName",
1534        default,
1535        deserialize_with = "deserialize_nullable_string"
1536    )]
1537    pub variety_name: String,
1538    /// Variety name in English.
1539    #[serde(
1540        rename = "varietyEnName",
1541        default,
1542        deserialize_with = "deserialize_nullable_string"
1543    )]
1544    pub variety_en_name: String,
1545    /// Contract ID (合约).
1546    #[serde(
1547        rename = "contractId",
1548        default,
1549        deserialize_with = "deserialize_nullable_string"
1550    )]
1551    pub contract_id: String,
1552    /// Settlement reference price (结算参考价).
1553    #[serde(rename = "clearPrice", default)]
1554    pub clear_price: f64,
1555    /// Series ID (期权系列).
1556    #[serde(
1557        rename = "seriesId",
1558        default,
1559        deserialize_with = "deserialize_nullable_string"
1560    )]
1561    pub series_id: String,
1562    /// Volatility (结算参考隐含波动率).
1563    #[serde(default)]
1564    pub volatility: f64,
1565}
1566
1567// ============================================================================
1568// Extended Trade Models (扩展交易参数模型)
1569// ============================================================================
1570
1571/// Request for trading parameters by variety.
1572#[derive(Debug, Clone, Serialize)]
1573#[serde(rename_all = "camelCase")]
1574pub struct TradingParamRequest {
1575    /// Language ("zh" or "en").
1576    pub lang: String,
1577}
1578
1579/// Trading parameters for a variety.
1580#[derive(Debug, Clone, Deserialize)]
1581#[serde(rename_all = "camelCase")]
1582pub struct TradingParam {
1583    /// Variety ID.
1584    #[serde(
1585        rename = "varietyId",
1586        default,
1587        deserialize_with = "deserialize_nullable_string"
1588    )]
1589    pub variety_id: String,
1590    /// Variety name.
1591    #[serde(
1592        rename = "varietyName",
1593        default,
1594        deserialize_with = "deserialize_nullable_string"
1595    )]
1596    pub variety_name: String,
1597    /// Trading margin rate (speculation).
1598    #[serde(
1599        rename = "tradingMarginRateSpeculation",
1600        default,
1601        deserialize_with = "deserialize_nullable_string"
1602    )]
1603    pub trading_margin_rate_speculation: String,
1604    /// Trading margin rate (hedging).
1605    #[serde(
1606        rename = "tradingMarginRateHedging",
1607        default,
1608        deserialize_with = "deserialize_nullable_string"
1609    )]
1610    pub trading_margin_rate_hedging: String,
1611    /// Price limit for existing contracts.
1612    #[serde(
1613        rename = "priceLimitExistingContract",
1614        default,
1615        deserialize_with = "deserialize_nullable_string"
1616    )]
1617    pub price_limit_existing_contract: String,
1618    /// Price limit for new contracts.
1619    #[serde(
1620        rename = "priceLimitNewContract",
1621        default,
1622        deserialize_with = "deserialize_nullable_string"
1623    )]
1624    pub price_limit_new_contract: String,
1625    /// Price limit for delivery month.
1626    #[serde(
1627        rename = "priceLimitDeliveryMonth",
1628        default,
1629        deserialize_with = "deserialize_nullable_string"
1630    )]
1631    pub price_limit_delivery_month: String,
1632    /// Trading margin rate (speculation) - Day N.
1633    #[serde(
1634        rename = "tradingMarginRateSpeculationN",
1635        default,
1636        deserialize_with = "deserialize_nullable_string"
1637    )]
1638    pub trading_margin_rate_speculation_n: String,
1639    /// Trading margin rate (hedging) - Day N.
1640    #[serde(
1641        rename = "tradingMarginRateHedgingN",
1642        default,
1643        deserialize_with = "deserialize_nullable_string"
1644    )]
1645    pub trading_margin_rate_hedging_n: String,
1646    /// Settlement margin rate (speculation/hedging) - Day N.
1647    #[serde(
1648        rename = "settlementMarginRateHedgingN",
1649        default,
1650        deserialize_with = "deserialize_nullable_string"
1651    )]
1652    pub settlement_margin_rate_hedging_n: String,
1653    /// Price limit - Day N.
1654    #[serde(
1655        rename = "priceLimitN",
1656        default,
1657        deserialize_with = "deserialize_nullable_string"
1658    )]
1659    pub price_limit_n: String,
1660    /// Trading margin rate (speculation/hedging) - Day N+1.
1661    #[serde(
1662        rename = "tradingMarginRateN1",
1663        default,
1664        deserialize_with = "deserialize_nullable_string"
1665    )]
1666    pub trading_margin_rate_n1: String,
1667    /// Settlement margin rate (speculation/hedging) - Day N+1.
1668    #[serde(
1669        rename = "settlementMarginRateHedgingN1",
1670        default,
1671        deserialize_with = "deserialize_nullable_string"
1672    )]
1673    pub settlement_margin_rate_hedging_n1: String,
1674    /// Price limit - Day N+1.
1675    #[serde(
1676        rename = "priceLimitN1",
1677        default,
1678        deserialize_with = "deserialize_nullable_string"
1679    )]
1680    pub price_limit_n1: String,
1681    /// Trading margin rate (speculation/hedging) - Day N+2.
1682    #[serde(
1683        rename = "tradingMarginRateN2",
1684        default,
1685        deserialize_with = "deserialize_nullable_string"
1686    )]
1687    pub trading_margin_rate_n2: String,
1688    /// Price limit - Day N+2.
1689    #[serde(
1690        rename = "priceLimitN2",
1691        default,
1692        deserialize_with = "deserialize_nullable_string"
1693    )]
1694    pub price_limit_n2: String,
1695    /// Trading limit.
1696    #[serde(
1697        rename = "tradingLimit",
1698        default,
1699        deserialize_with = "deserialize_nullable_string"
1700    )]
1701    pub trading_limit: String,
1702    /// Speculative open fee.
1703    #[serde(
1704        rename = "specOpenFee",
1705        default,
1706        deserialize_with = "deserialize_nullable_string"
1707    )]
1708    pub spec_open_fee: String,
1709    /// Speculative offset fee.
1710    #[serde(
1711        rename = "specOffsetFee",
1712        default,
1713        deserialize_with = "deserialize_nullable_string"
1714    )]
1715    pub spec_offset_fee: String,
1716    /// Speculative short open fee (intraday).
1717    #[serde(
1718        rename = "specShortOpenFee",
1719        default,
1720        deserialize_with = "deserialize_nullable_string"
1721    )]
1722    pub spec_short_open_fee: String,
1723    /// Speculative short offset fee (intraday).
1724    #[serde(
1725        rename = "specShortOffsetFee",
1726        default,
1727        deserialize_with = "deserialize_nullable_string"
1728    )]
1729    pub spec_short_offset_fee: String,
1730    /// Hedge open fee.
1731    #[serde(
1732        rename = "hedgeOpenFee",
1733        default,
1734        deserialize_with = "deserialize_nullable_string"
1735    )]
1736    pub hedge_open_fee: String,
1737    /// Hedge offset fee.
1738    #[serde(
1739        rename = "hedgeOffsetFee",
1740        default,
1741        deserialize_with = "deserialize_nullable_string"
1742    )]
1743    pub hedge_offset_fee: String,
1744    /// Hedge short open fee (intraday).
1745    #[serde(
1746        rename = "hedgeShortOpenFee",
1747        default,
1748        deserialize_with = "deserialize_nullable_string"
1749    )]
1750    pub hedge_short_open_fee: String,
1751    /// Hedge short offset fee (intraday).
1752    #[serde(
1753        rename = "hedgeShortOffsetFee",
1754        default,
1755        deserialize_with = "deserialize_nullable_string"
1756    )]
1757    pub hedge_short_offset_fee: String,
1758    /// Fee style.
1759    #[serde(
1760        rename = "feeStyle",
1761        default,
1762        deserialize_with = "deserialize_nullable_string"
1763    )]
1764    pub fee_style: String,
1765    /// Fee style (English).
1766    #[serde(
1767        rename = "feeStyleEn",
1768        default,
1769        deserialize_with = "deserialize_nullable_string"
1770    )]
1771    pub fee_style_en: String,
1772    /// Delivery fee.
1773    #[serde(
1774        rename = "deliveryFee",
1775        default,
1776        deserialize_with = "deserialize_nullable_string"
1777    )]
1778    pub delivery_fee: String,
1779    /// Maximum hand (order size).
1780    #[serde(
1781        rename = "maxHand",
1782        default,
1783        deserialize_with = "deserialize_nullable_string"
1784    )]
1785    pub max_hand: String,
1786}
1787
1788/// Request for margin arbitrage performance parameters.
1789#[derive(Debug, Clone, Serialize)]
1790#[serde(rename_all = "camelCase")]
1791pub struct MarginArbiPerfParaRequest {
1792    /// Variety ID.
1793    pub variety_id: String,
1794}
1795
1796/// Margin arbitrage performance parameters.
1797#[derive(Debug, Clone, Deserialize)]
1798#[serde(rename_all = "camelCase")]
1799pub struct MarginArbiPerfPara {
1800    /// Variety.
1801    #[serde(default, deserialize_with = "deserialize_nullable_string")]
1802    pub variety: String,
1803    /// Strategy name.
1804    #[serde(
1805        rename = "strategyName",
1806        default,
1807        deserialize_with = "deserialize_nullable_string"
1808    )]
1809    pub strategy_name: String,
1810    /// Trading margin rate (speculation).
1811    #[serde(
1812        rename = "tradingMarginRateSpeculation",
1813        default,
1814        deserialize_with = "deserialize_nullable_string"
1815    )]
1816    pub trading_margin_rate_speculation: String,
1817    /// Trading margin rate (hedging).
1818    #[serde(
1819        rename = "tradingMarginRateHedging",
1820        default,
1821        deserialize_with = "deserialize_nullable_string"
1822    )]
1823    pub trading_margin_rate_hedging: String,
1824    /// Open fee.
1825    #[serde(
1826        rename = "openFee",
1827        default,
1828        deserialize_with = "deserialize_nullable_string"
1829    )]
1830    pub open_fee: String,
1831    /// Offset fee.
1832    #[serde(
1833        rename = "offsetFee",
1834        default,
1835        deserialize_with = "deserialize_nullable_string"
1836    )]
1837    pub offset_fee: String,
1838    /// Short open fee.
1839    #[serde(
1840        rename = "shortOpenFee",
1841        default,
1842        deserialize_with = "deserialize_nullable_string"
1843    )]
1844    pub short_open_fee: String,
1845    /// Short offset fee.
1846    #[serde(
1847        rename = "shortOffsetFee",
1848        default,
1849        deserialize_with = "deserialize_nullable_string"
1850    )]
1851    pub short_offset_fee: String,
1852}
1853
1854/// Request for new contract information.
1855#[derive(Debug, Clone, Serialize)]
1856#[serde(rename_all = "camelCase")]
1857pub struct NewContractInfoRequest {
1858    /// Trade date (YYYYMMDD format).
1859    pub trade_date: String,
1860    /// Trade type ("1" = futures, "2" = options).
1861    pub trade_type: String,
1862    /// Language.
1863    #[serde(skip_serializing_if = "Option::is_none")]
1864    pub lang: Option<String>,
1865}
1866
1867/// New contract information.
1868#[derive(Debug, Clone, Deserialize)]
1869#[serde(rename_all = "camelCase")]
1870pub struct NewContractInfo {
1871    /// Trade type.
1872    #[serde(
1873        rename = "tradeType",
1874        default,
1875        deserialize_with = "deserialize_nullable_string"
1876    )]
1877    pub trade_type: String,
1878    /// Variety.
1879    #[serde(default, deserialize_with = "deserialize_nullable_string")]
1880    pub variety: String,
1881    /// Variety order.
1882    #[serde(
1883        rename = "varietyOrder",
1884        default,
1885        deserialize_with = "deserialize_nullable_string"
1886    )]
1887    pub variety_order: String,
1888    /// Contract ID.
1889    #[serde(
1890        rename = "contractId",
1891        default,
1892        deserialize_with = "deserialize_nullable_string"
1893    )]
1894    pub contract_id: String,
1895    /// Start trade date.
1896    #[serde(
1897        rename = "startTradeDate",
1898        default,
1899        deserialize_with = "deserialize_nullable_string"
1900    )]
1901    pub start_trade_date: String,
1902    /// Reference price unit.
1903    #[serde(
1904        rename = "refPriceUnit",
1905        default,
1906        deserialize_with = "deserialize_nullable_string"
1907    )]
1908    pub ref_price_unit: String,
1909    /// No rise limit.
1910    #[serde(
1911        rename = "noRiseLimit",
1912        default,
1913        deserialize_with = "deserialize_nullable_string"
1914    )]
1915    pub no_rise_limit: String,
1916    /// No fall limit.
1917    #[serde(
1918        rename = "noFallLimit",
1919        default,
1920        deserialize_with = "deserialize_nullable_string"
1921    )]
1922    pub no_fall_limit: String,
1923}
1924
1925/// Request for main series information (做市商持续报价合约).
1926#[derive(Debug, Clone, Serialize)]
1927#[serde(rename_all = "camelCase")]
1928pub struct MainSeriesInfoRequest {
1929    /// Variety ID ("all" for all varieties).
1930    pub variety_id: String,
1931    /// Trade date (YYYYMMDD format).
1932    pub trade_date: String,
1933}
1934
1935/// Main series information (market maker contracts).
1936#[derive(Debug, Clone, Deserialize)]
1937#[serde(rename_all = "camelCase")]
1938pub struct MainSeriesInfo {
1939    /// Trade date.
1940    #[serde(
1941        rename = "tradeDate",
1942        default,
1943        deserialize_with = "deserialize_nullable_string"
1944    )]
1945    pub trade_date: String,
1946    /// Variety ID.
1947    #[serde(
1948        rename = "varietyId",
1949        default,
1950        deserialize_with = "deserialize_nullable_string"
1951    )]
1952    pub variety_id: String,
1953    /// Series ID.
1954    #[serde(
1955        rename = "seriesId",
1956        default,
1957        deserialize_with = "deserialize_nullable_string"
1958    )]
1959    pub series_id: String,
1960    /// Contract ID.
1961    #[serde(
1962        rename = "contractId",
1963        default,
1964        deserialize_with = "deserialize_nullable_string"
1965    )]
1966    pub contract_id: String,
1967}
1968
1969// ============================================================================
1970// Extended Delivery Models (扩展交割数据模型)
1971// ============================================================================
1972
1973/// Request for TC congregate delivery (一次性交割卖方仓单查询).
1974#[derive(Debug, Clone, Serialize)]
1975#[serde(rename_all = "camelCase")]
1976pub struct TcCongregateDeliveryRequest {
1977    /// Variety code ("all" for all varieties).
1978    pub variety: String,
1979    /// Contract month (YYYYMM format).
1980    pub contract_month: String,
1981}
1982
1983/// TC congregate delivery information.
1984#[derive(Debug, Clone, Deserialize)]
1985#[serde(rename_all = "camelCase")]
1986pub struct TcCongregateDelivery {
1987    /// Variety ID.
1988    #[serde(
1989        rename = "varietyId",
1990        default,
1991        deserialize_with = "deserialize_nullable_string"
1992    )]
1993    pub variety_id: String,
1994    /// Variety name.
1995    #[serde(
1996        rename = "varietyName",
1997        default,
1998        deserialize_with = "deserialize_nullable_string"
1999    )]
2000    pub variety_name: String,
2001    /// Contract.
2002    #[serde(default, deserialize_with = "deserialize_nullable_string")]
2003    pub contract: String,
2004    /// Warehouse name.
2005    #[serde(
2006        rename = "warehouseName",
2007        default,
2008        deserialize_with = "deserialize_nullable_string"
2009    )]
2010    pub warehouse_name: String,
2011    /// Warehouse bill quantity.
2012    #[serde(
2013        rename = "wbillQuantity",
2014        default,
2015        deserialize_with = "deserialize_nullable_string"
2016    )]
2017    pub wbill_quantity: String,
2018    /// Agreeable place.
2019    #[serde(
2020        rename = "agreeablePlace",
2021        default,
2022        deserialize_with = "deserialize_nullable_string"
2023    )]
2024    pub agreeable_place: String,
2025    /// Agreeable brand.
2026    #[serde(
2027        rename = "agreeableBrand",
2028        default,
2029        deserialize_with = "deserialize_nullable_string"
2030    )]
2031    pub agreeable_brand: String,
2032    /// Agreeable quality.
2033    #[serde(
2034        rename = "agreeableQuality",
2035        default,
2036        deserialize_with = "deserialize_nullable_string"
2037    )]
2038    pub agreeable_quality: String,
2039    /// Agreeable quantity.
2040    #[serde(
2041        rename = "agreeableQuantity",
2042        default,
2043        deserialize_with = "deserialize_nullable_string"
2044    )]
2045    pub agreeable_quantity: String,
2046    /// Agreeable spread.
2047    #[serde(
2048        rename = "agreeableSpread",
2049        default,
2050        deserialize_with = "deserialize_nullable_string"
2051    )]
2052    pub agreeable_spread: String,
2053    /// Contacts.
2054    #[serde(default, deserialize_with = "deserialize_nullable_string")]
2055    pub contracts: String,
2056    /// Contact way (method).
2057    #[serde(
2058        rename = "contractWay",
2059        default,
2060        deserialize_with = "deserialize_nullable_string"
2061    )]
2062    pub contract_way: String,
2063    /// Warehouse group name.
2064    #[serde(
2065        rename = "whGroupName",
2066        default,
2067        deserialize_with = "deserialize_nullable_string"
2068    )]
2069    pub wh_group_name: String,
2070}
2071
2072/// Request for roll delivery seller intention (滚动交割卖方交割意向表).
2073#[derive(Debug, Clone, Serialize)]
2074#[serde(rename_all = "camelCase")]
2075pub struct RollDeliverySellerIntentionRequest {
2076    /// Variety code ("all" for all varieties).
2077    pub variety: String,
2078    /// Query date (YYYYMMDD format).
2079    pub date: String,
2080}
2081
2082/// Roll delivery seller intention.
2083#[derive(Debug, Clone, Deserialize)]
2084#[serde(rename_all = "camelCase")]
2085pub struct RollDeliverySellerIntention {
2086    /// Variety ID.
2087    #[serde(
2088        rename = "varietyId",
2089        default,
2090        deserialize_with = "deserialize_nullable_string"
2091    )]
2092    pub variety_id: String,
2093    /// Variety name.
2094    #[serde(
2095        rename = "varietyName",
2096        default,
2097        deserialize_with = "deserialize_nullable_string"
2098    )]
2099    pub variety_name: String,
2100    /// Contract.
2101    #[serde(default, deserialize_with = "deserialize_nullable_string")]
2102    pub contract: String,
2103    /// Type (e.g. 仓库/车板).
2104    #[serde(
2105        rename = "type",
2106        default,
2107        deserialize_with = "deserialize_nullable_string"
2108    )]
2109    pub type_: String,
2110    /// Warehouse code.
2111    #[serde(
2112        rename = "warehouseCode",
2113        default,
2114        deserialize_with = "deserialize_nullable_string"
2115    )]
2116    pub warehouse_code: String,
2117    /// Warehouse name.
2118    #[serde(
2119        rename = "warehouseName",
2120        default,
2121        deserialize_with = "deserialize_nullable_string"
2122    )]
2123    pub warehouse_name: String,
2124    /// Quantity (string in doc).
2125    #[serde(default, deserialize_with = "deserialize_nullable_string")]
2126    pub quantity: String,
2127    /// Agreeable place.
2128    #[serde(
2129        rename = "agreeablePlace",
2130        default,
2131        deserialize_with = "deserialize_nullable_string"
2132    )]
2133    pub agreeable_place: String,
2134    /// Agreeable brand.
2135    #[serde(
2136        rename = "agreeableBrand",
2137        default,
2138        deserialize_with = "deserialize_nullable_string"
2139    )]
2140    pub agreeable_brand: String,
2141    /// Agreeable quality.
2142    #[serde(
2143        rename = "agreeableQuality",
2144        default,
2145        deserialize_with = "deserialize_nullable_string"
2146    )]
2147    pub agreeable_quality: String,
2148    /// Agreeable quantity.
2149    #[serde(
2150        rename = "agreeableQuantity",
2151        default,
2152        deserialize_with = "deserialize_nullable_string"
2153    )]
2154    pub agreeable_quantity: String,
2155    /// Agreeable spread.
2156    #[serde(
2157        rename = "agreeableSpread",
2158        default,
2159        deserialize_with = "deserialize_nullable_string"
2160    )]
2161    pub agreeable_spread: String,
2162    /// Contacts.
2163    #[serde(default, deserialize_with = "deserialize_nullable_string")]
2164    pub contracts: String,
2165    /// Contact way (method).
2166    #[serde(
2167        rename = "contractWay",
2168        default,
2169        deserialize_with = "deserialize_nullable_string"
2170    )]
2171    pub contract_way: String,
2172    /// Trade date.
2173    #[serde(
2174        rename = "tradeDate",
2175        default,
2176        deserialize_with = "deserialize_nullable_string"
2177    )]
2178    pub trade_date: String,
2179    /// Warehouse group name.
2180    #[serde(
2181        rename = "whGroupName",
2182        default,
2183        deserialize_with = "deserialize_nullable_string"
2184    )]
2185    pub wh_group_name: String,
2186    /// Delivery way.
2187    #[serde(
2188        rename = "deliveryWay",
2189        default,
2190        deserialize_with = "deserialize_nullable_string"
2191    )]
2192    pub delivery_way: String,
2193}
2194
2195/// Request for bonded delivery settlement price (交割结算价).
2196#[derive(Debug, Clone, Serialize)]
2197#[serde(rename_all = "camelCase")]
2198pub struct BondedDeliveryRequest {
2199    /// Start date (YYYYMMDD format).
2200    pub start_date: String,
2201    /// End date (YYYYMMDD format).
2202    pub end_date: String,
2203}
2204
2205/// Bonded delivery settlement price.
2206#[derive(Debug, Clone, Deserialize)]
2207#[serde(rename_all = "camelCase")]
2208pub struct BondedDelivery {
2209    /// Delivery date.
2210    #[serde(
2211        rename = "deliveryDate",
2212        default,
2213        deserialize_with = "deserialize_nullable_string"
2214    )]
2215    pub delivery_date: String,
2216    /// Delivery way.
2217    #[serde(
2218        rename = "deliveryWay",
2219        default,
2220        deserialize_with = "deserialize_nullable_string"
2221    )]
2222    pub delivery_way: String,
2223    /// Variety ID (e.g. i-铁矿石).
2224    #[serde(
2225        rename = "varietyId",
2226        default,
2227        deserialize_with = "deserialize_nullable_string"
2228    )]
2229    pub variety_id: String,
2230    /// Contract ID.
2231    #[serde(
2232        rename = "contractId",
2233        default,
2234        deserialize_with = "deserialize_nullable_string"
2235    )]
2236    pub contract_id: String,
2237    /// Warehouse abbreviation.
2238    #[serde(
2239        rename = "whAbbr",
2240        default,
2241        deserialize_with = "deserialize_nullable_string"
2242    )]
2243    pub wh_abbr: String,
2244    /// Bonded delivery price.
2245    #[serde(
2246        rename = "bondedDeliveryPrice",
2247        default,
2248        deserialize_with = "deserialize_nullable_string"
2249    )]
2250    pub bonded_delivery_price: String,
2251    /// Delivery price.
2252    #[serde(
2253        rename = "deliveryPrice",
2254        default,
2255        deserialize_with = "deserialize_nullable_string"
2256    )]
2257    pub delivery_price: String,
2258}
2259
2260/// Request for TD bonded delivery settlement price (保税交割结算价).
2261#[derive(Debug, Clone, Serialize)]
2262#[serde(rename_all = "camelCase")]
2263pub struct TdBondedDeliveryRequest {
2264    /// Start date (YYYYMMDD format).
2265    pub start_date: String,
2266    /// End date (YYYYMMDD format).
2267    pub end_date: String,
2268}
2269
2270/// TD bonded delivery settlement price (same structure as BondedDelivery).
2271pub type TdBondedDelivery = BondedDelivery;
2272
2273/// Request for factory spot agio (basis spread).
2274#[derive(Debug, Clone, Serialize)]
2275#[serde(rename_all = "camelCase")]
2276pub struct FactorySpotAgioRequest {
2277    /// Variety ID.
2278    pub variety_id: String,
2279    /// Trade date (YYYYMMDD format).
2280    pub trade_date: String,
2281}
2282
2283/// Factory spot agio (price difference for fiberboard).
2284#[derive(Debug, Clone, Deserialize)]
2285#[serde(rename_all = "camelCase")]
2286pub struct FactorySpotAgio {
2287    /// Sequence number.
2288    #[serde(default, deserialize_with = "deserialize_nullable_string")]
2289    pub seq_no: String,
2290    /// Factory abbreviation (Warehouse abbreviation).
2291    #[serde(
2292        rename = "whAbbr",
2293        default,
2294        deserialize_with = "deserialize_nullable_string"
2295    )]
2296    pub wh_abbr: String,
2297    /// Variety ID.
2298    #[serde(default, deserialize_with = "deserialize_nullable_string")]
2299    pub variety_id: String,
2300    /// Variety name.
2301    #[serde(default, deserialize_with = "deserialize_nullable_string")]
2302    pub variety_name: String,
2303    /// Warehouse code.
2304    #[serde(
2305        rename = "whCode",
2306        default,
2307        deserialize_with = "deserialize_nullable_string"
2308    )]
2309    pub wh_code: String,
2310    /// Thickness (mm).
2311    #[serde(default, deserialize_with = "deserialize_nullable_string")]
2312    pub bh: String,
2313    /// Density min (g/cm3).
2314    #[serde(default, deserialize_with = "deserialize_nullable_string")]
2315    pub mdmin: String,
2316    /// Density max (g/cm3).
2317    #[serde(default, deserialize_with = "deserialize_nullable_string")]
2318    pub mdmax: String,
2319    /// Formaldehyde (mg/m3).
2320    #[serde(default, deserialize_with = "deserialize_nullable_string")]
2321    pub jq: String,
2322    /// Price difference (Agio).
2323    #[serde(default, deserialize_with = "deserialize_nullable_string")]
2324    pub agio: String,
2325    /// Min exchange amount.
2326    #[serde(
2327        rename = "minExchangeAmount",
2328        default,
2329        deserialize_with = "deserialize_nullable_string"
2330    )]
2331    pub min_exchange_amount: String,
2332    /// Warehouse address.
2333    #[serde(
2334        rename = "whAddr",
2335        default,
2336        deserialize_with = "deserialize_nullable_string"
2337    )]
2338    pub wh_addr: String,
2339    /// Contact person.
2340    #[serde(
2341        rename = "connectPerson",
2342        default,
2343        deserialize_with = "deserialize_nullable_string"
2344    )]
2345    pub connect_person: String,
2346    /// Telephone.
2347    #[serde(default, deserialize_with = "deserialize_nullable_string")]
2348    pub tel: String,
2349}
2350
2351/// Request for plywood delivery commodity.
2352#[derive(Debug, Clone, Serialize)]
2353#[serde(rename_all = "camelCase")]
2354pub struct PlywoodDeliveryCommodityRequest {
2355    /// Variety ID.
2356    pub variety_id: String,
2357}
2358
2359/// Plywood delivery commodity.
2360#[derive(Debug, Clone, Deserialize)]
2361#[serde(rename_all = "camelCase")]
2362pub struct PlywoodDeliveryCommodity {
2363    /// Apply ID.
2364    #[serde(default, deserialize_with = "deserialize_nullable_string")]
2365    pub apply_id: String,
2366    /// Warehouse name.
2367    #[serde(
2368        rename = "whName",
2369        default,
2370        deserialize_with = "deserialize_nullable_string"
2371    )]
2372    pub wh_name: String,
2373    /// Warehouse abbreviation.
2374    #[serde(
2375        rename = "whAbbr",
2376        default,
2377        deserialize_with = "deserialize_nullable_string"
2378    )]
2379    pub wh_abbr: String,
2380    /// Upload file ID.
2381    #[serde(
2382        rename = "uploadFileId",
2383        default,
2384        deserialize_with = "deserialize_nullable_string"
2385    )]
2386    pub upload_file_id: String,
2387    /// File size.
2388    #[serde(default)]
2389    pub file_size: i64,
2390    /// Upload file name.
2391    #[serde(
2392        rename = "uploadFileName",
2393        default,
2394        deserialize_with = "deserialize_nullable_string"
2395    )]
2396    pub upload_file_name: String,
2397}