ids-apis 1.0.337

IDS APIs in Rust
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
// @generated
// This file is @generated by prost-build.
// ============================================================================
// Pair Entity
// ============================================================================

/// Pair 전략 — 두 심볼의 가격 조건에 따른 동시 주문 설정
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Pair {
    /// 리소스 이름 (pairs/{id})
    #[prost(string, tag="1")]
    pub name: ::prost::alloc::string::String,
    /// Pair ID
    #[prost(int32, tag="2")]
    pub id: i32,
    /// 전략 이름 (고유)
    #[prost(string, tag="3")]
    pub display_name: ::prost::alloc::string::String,
    /// Portfolio ID
    #[prost(int32, tag="4")]
    pub portfolio_id: i32,
    /// Base 엔트리
    #[prost(message, optional, tag="5")]
    pub base: ::core::option::Option<PairEntry>,
    /// Counter 엔트리
    #[prost(message, optional, tag="6")]
    pub counter: ::core::option::Option<PairEntry>,
    /// 상태
    #[prost(enumeration="PairStatus", tag="9")]
    pub status: i32,
    /// 생성 시간
    #[prost(message, optional, tag="11")]
    pub create_time: ::core::option::Option<super::super::super::google::protobuf::Timestamp>,
    /// 수정 시간
    #[prost(message, optional, tag="12")]
    pub update_time: ::core::option::Option<super::super::super::google::protobuf::Timestamp>,
    /// 트리거 — 언제 발사할지. 실행(execution)과 독립적으로 조합한다.
    #[prost(message, optional, tag="13")]
    pub trigger: ::core::option::Option<TriggerCondition>,
    /// 실행 — 발사 시 무엇을 할지. 트리거(trigger)와 독립적으로 조합한다.
    #[prost(message, optional, tag="14")]
    pub execution: ::core::option::Option<OrderExecution>,
    /// ETF↔Future NAV 환산 설정 — TargetNavQuantityImbalance 트리거·BaseMakeCounterIocAndBalance/CounterIocTpSlExecution
    /// execution 이 공유. NAV 미사용 페어는 미설정.
    #[prost(message, optional, tag="15")]
    pub nav: ::core::option::Option<Nav>,
}
// ============================================================================
// Pair Entry
// ============================================================================

/// 페어의 한쪽 엔트리 (단일 심볼 주문 스펙)
///
/// execution 종류별 필드 사용:
/// - DualSubmitExecution: side/quantity/price_source 사용 (지정가 = price_source 추출 가격).
/// - BaseMakeCounterIocAndBalanceExecution (IOC imbalance):
///    - base.side / base.quantity: 사용 (deficit 트리거 방향 / 사이클 base 주문 수량).
///    - counter.side: 사용자가 직접 지정 (정방향 ETF → base.side 반대, 역방향 ETF → base.side 와 동일).
///    - counter.quantity: 무시 (런타임 = base.quantity × hedge_ratio).
///    - price_source (양 슬롯): 무시. base 가격 = base.side 1호가(=BestMake) 고정,
///      counter 가격 = NAV 기반 BEP 고정. 사용자가 지정해도 서버에서 UNSPECIFIED 로 정규화.
/// - CounterIocTpSlExecution: counter 엔트리만 사용.
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct PairEntry {
    /// 종목 심볼
    #[prost(string, tag="1")]
    pub symbol: ::prost::alloc::string::String,
    /// 주문에 사용할 펀드 코드
    #[prost(string, tag="2")]
    pub fund_code: ::prost::alloc::string::String,
    /// 주문 방향
    #[prost(enumeration="PairSide", tag="3")]
    pub side: i32,
    /// 주문 수량 (1 이상)
    /// BaseMakeCounterIocAndBalanceExecution: base 는 필수(사이클 주문 수량), counter 는 0 허용(런타임 = base × hedge_ratio).
    #[prost(int64, tag="4")]
    pub quantity: i64,
    /// 참조 가격 소스 (entry.side 기준 자기/상대 호가).
    /// BaseMakeCounterIocAndBalanceExecution 에선 무시(base 가격은 항상 base.side 의 1호가). 입력값은 UNSPECIFIED 로 정규화된다.
    #[prost(enumeration="PriceSource", tag="5")]
    pub price_source: i32,
}
// ============================================================================
// Pair Condition (oneof wrapper)
// ============================================================================

/// 페어 가격 비교 조건 (세 가지 variant 중 하나)
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct PairCondition {
    #[prost(oneof="pair_condition::Kind", tags="1, 2, 3")]
    pub kind: ::core::option::Option<pair_condition::Kind>,
}
/// Nested message and enum types in `PairCondition`.
pub mod pair_condition {
    #[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, Copy, PartialEq, ::prost::Oneof)]
    pub enum Kind {
        /// 절대 스프레드 금액 기준
        #[prost(message, tag="1")]
        SpreadAmount(super::SpreadAmountCondition),
        /// 상대 스프레드 (bps) 기준
        #[prost(message, tag="2")]
        SpreadBps(super::SpreadBpsCondition),
        /// 가격 비율 기준
        #[prost(message, tag="3")]
        PriceRatio(super::PriceRatioCondition),
    }
}
/// 절대 스프레드 금액 조건 (|base - counter| >= threshold)
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct SpreadAmountCondition {
    /// 스프레드 임계값 (원, 1 이상)
    #[prost(int64, tag="1")]
    pub threshold: i64,
    /// 트리거 방향
    #[prost(enumeration="SpreadDirection", tag="2")]
    pub direction: i32,
}
/// 상대 스프레드 (bps) 조건 (|spread| / mid * 10000 >= threshold_bps, base 기준)
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct SpreadBpsCondition {
    /// 스프레드 임계값 (bps, 1bp = 0.01%)
    #[prost(double, tag="1")]
    pub threshold_bps: f64,
    /// 트리거 방향
    #[prost(enumeration="SpreadDirection", tag="2")]
    pub direction: i32,
}
/// 가격 비율 조건 (base / counter)
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct PriceRatioCondition {
    /// 최소 비율 (이 값 미만이면 CounterHigh 트리거)
    #[prost(double, tag="1")]
    pub min_ratio: f64,
    /// 최대 비율 (이 값 초과 시 BaseHigh 트리거)
    #[prost(double, tag="2")]
    pub max_ratio: f64,
}
/// ETF↔Future 페어의 NAV 환산 설정 — 트리거(TargetNav)와 실행(counter BEP)이 공유.
/// base/counter 중 한쪽이 ETF, 다른쪽이 Future 여야 한다 (방향 무관).
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct Nav {
    #[prost(enumeration="EtfNavKind", tag="1")]
    pub nav_kind: i32,
    /// Bid 방향 산출용 basis (원). forward/inverse 양방향에 동일 모델 파라미터로 적용.
    #[prost(int64, tag="2")]
    pub bid_basis: i64,
    /// Ask 방향 산출용 basis (원)
    #[prost(int64, tag="3")]
    pub ask_basis: i64,
}
// ============================================================================
// TriggerCondition — 트리거 축
// ============================================================================

/// 트리거 — 언제 발사할지. 실행(OrderExecution)과 독립적으로 조합한다.
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct TriggerCondition {
    #[prost(oneof="trigger_condition::Kind", tags="1, 2, 3")]
    pub kind: ::core::option::Option<trigger_condition::Kind>,
}
/// Nested message and enum types in `TriggerCondition`.
pub mod trigger_condition {
    #[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, Copy, PartialEq, ::prost::Oneof)]
    pub enum Kind {
        /// 양 슬롯 참조가격 비교 트리거 (구 SimultaneousCompare 의 트리거부)
        #[prost(message, tag="1")]
        PriceSpread(super::PriceSpreadTrigger),
        /// base 자기측(BestMake) 1호가 수량 불균형 트리거. base.side 가 담당 deficit 방향.
        #[prost(message, tag="2")]
        BestMakeQuantityImbalance(super::BestMakeQuantityImbalanceTrigger),
        /// counter 시세로 base 의 NAV 목표가를 환산해, base 자기측(BestMake) 1호가가
        /// 목표가와 정확히 일치하면서 수량 불균형일 때 발사. nav 파라미터는 Pair.nav 공유 설정 사용.
        #[prost(message, tag="3")]
        TargetNavQuantityImbalance(super::TargetNavQuantityImbalanceTrigger),
    }
}
/// 양 슬롯 참조가격 비교 트리거
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct PriceSpreadTrigger {
    /// 가격 비교 조건
    #[prost(message, optional, tag="1")]
    pub condition: ::core::option::Option<PairCondition>,
    /// 트리거 후 재트리거까지 대기시간 (ms)
    #[prost(uint64, tag="2")]
    pub cooldown_ms: u64,
}
/// base 자기측(BestMake) 1호가 수량 불균형 트리거. base.side 가 담당 deficit 방향.
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct BestMakeQuantityImbalanceTrigger {
    /// base 1호가 imbalance 가 이 비율 미만이면 트리거
    #[prost(double, tag="1")]
    pub threshold_ratio: f64,
    /// 트리거 후 재트리거까지 대기시간 (ms)
    #[prost(uint64, tag="2")]
    pub cooldown_ms: u64,
}
/// counter 시세로 base 의 NAV 목표가를 환산해, base 자기측(BestMake) 1호가가
/// 목표가와 정확히 일치하면서 수량 불균형일 때 발사. nav 파라미터는 Pair.nav 공유 설정 사용.
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct TargetNavQuantityImbalanceTrigger {
    /// 수량 불균형 임계 (BestMakeQuantityImbalanceTrigger 와 동일 판정식)
    #[prost(double, tag="1")]
    pub threshold_ratio: f64,
    /// 트리거 후 재트리거까지 대기시간 (ms)
    #[prost(uint64, tag="2")]
    pub cooldown_ms: u64,
}
// ============================================================================
// OrderExecution — 실행 축
// ============================================================================

/// 실행 — 발사 시 무엇을 할지. 트리거와 독립적으로 조합한다.
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct OrderExecution {
    #[prost(oneof="order_execution::Kind", tags="1, 2, 3, 4")]
    pub kind: ::core::option::Option<order_execution::Kind>,
}
/// Nested message and enum types in `OrderExecution`.
pub mod order_execution {
    #[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, Copy, PartialEq, ::prost::Oneof)]
    pub enum Kind {
        /// 양측 동시 발주 (구 SimultaneousCompare 의 실행부)
        #[prost(message, tag="1")]
        DualSubmit(super::DualSubmitExecution),
        /// base Limit + counter IOC + settle/recovery/balance
        #[prost(message, tag="2")]
        BaseMakeCounterIocAndBalance(super::BaseMakeCounterIocAndBalanceExecution),
        /// base 무발주 — counter(ETF) 상대호가±entry_aggressive_ticks pseudo-IOC 진입 + TP/SL 청산
        #[prost(message, tag="3")]
        CounterIocTpSl(super::CounterIocTpSlExecution),
        /// base Limit + counter 잔류지정가(상대호가±틱, IOC 아님) + settle/recovery/balance
        #[prost(message, tag="4")]
        BaseMakeCounterTakeAndBalance(super::BaseMakeCounterTakeAndBalanceExecution),
    }
}
/// 양측 동시 발주 (구 SimultaneousCompare 의 실행부)
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct DualSubmitExecution {
    /// 주문 유형
    #[prost(enumeration="PairOrderType", tag="1")]
    pub order_type: i32,
}
/// base Limit + counter IOC + settle/recovery/balance
///
/// PairEntry 필드 매핑:
///    - base.symbol / base.fund_code / base.side / base.quantity: 사용 (필수).
///    - counter.symbol / counter.fund_code / counter.side: 사용 (필수, 사용자가 직접 지정).
///      정방향 ETF → counter.side = base.side 반대, 역방향 ETF → counter.side = base.side 와 동일.
///    - counter.quantity: 무시 (런타임 = base.quantity × hedge_ratio). 0 으로 비워도 된다.
///    - PairEntry.price_source (양 슬롯): 무시. base 가격은 base.side 의 1호가(=BestMake),
///      counter 가격은 NAV 기반 BEP. 서버에서 UNSPECIFIED 로 정규화한다.
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct BaseMakeCounterIocAndBalanceExecution {
    /// base 측 잔량 비율이 이 값을 초과하면 base 공격적 정정→강제 체결
    #[prost(double, tag="4")]
    pub recovery_ratio: f64,
    /// base 슬롯 공격적 정정 시 상대호가(cross price) 보다 얼마나 더 공격적으로 낼지 (tick 단위).
    /// 0 이면 상대호가/ref 그대로. Bid 면 +N*tick, Ask 면 -N*tick.
    #[prost(uint32, tag="7")]
    pub base_recovery_aggressive_ticks: u32,
    /// counter 슬롯 공격적 정정 시 상대호가에서 얼마나 더 공격적으로 낼지 (tick 단위).
    /// 0 이면 BEP 그대로. counter.side 가 Bid 면 +N*tick, Ask 면 -N*tick.
    #[prost(uint32, tag="8")]
    pub counter_recovery_aggressive_ticks: u32,
}
/// base 무발주 — counter(ETF) 상대호가±entry_aggressive_ticks pseudo-IOC 진입,
/// 마지막 진입 체결가 기준 take_profit_ticks/stop_loss_ticks 틱 익절/손절(TP/SL),
/// exit_delay_ms 경과 후 판정. 진입은 상대 1호가에서 entry_aggressive_ticks 만큼
/// 공격적으로 제출 후 잔량 즉시 취소(pseudo-IOC). 청산은 체결될 때까지 호가 추적(amend).
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct CounterIocTpSlExecution {
    /// 익절 임계 (틱)
    #[prost(uint32, tag="4")]
    pub take_profit_ticks: u32,
    /// 손절 임계 (틱)
    #[prost(uint32, tag="5")]
    pub stop_loss_ticks: u32,
    /// 청산 발주 시 상대 1호가 대비 추가 공격 틱 (0 = 상대호가 그대로)
    #[prost(uint32, tag="6")]
    pub exit_aggressive_ticks: u32,
    /// 진입 발주 시 상대 1호가에서 추가로 공격적으로 낼 틱 수 (0 = 상대호가 그대로).
    /// 진입은 BEP 가 아니라 상대호가 ± n틱의 pseudo-IOC (접수 후 잔량 즉시 취소).
    #[prost(uint32, tag="7")]
    pub entry_aggressive_ticks: u32,
    /// 익절/손절 판정 대기 시간 (ms). 마지막 진입 체결 시각부터 이 시간 경과 후 판정 시작.
    #[prost(uint64, tag="8")]
    pub exit_delay_ms: u64,
}
/// base Limit + counter 잔류지정가(상대호가±틱, IOC 아님) + settle/recovery/balance
///
/// BaseMakeCounterIocAndBalanceExecution 과 구조가 동일하되, counter 주문 가격이 NAV BEP IOC 가 아니라
/// counter 오더북 상대호가 ± counter_aggressive_ticks 틱의 지정가(체결까지 호가창에 잔류, 취소 없음)이다.
/// NAV 파라미터(Pair.nav)는 이 execution 에서 사용하지 않는다.
///
/// PairEntry 필드 매핑:
///    - base.symbol / base.fund_code / base.side / base.quantity: 사용 (필수).
///    - counter.symbol / counter.fund_code / counter.side: 사용 (필수, 사용자가 직접 지정).
///    - counter.quantity: 무시 (런타임 = base.quantity × hedge_ratio). 0 으로 비워도 된다.
///    - PairEntry.price_source (양 슬롯): 무시. base 가격은 base.side 의 1호가(=BestMake),
///      counter 가격은 상대호가 ± counter_aggressive_ticks. 서버에서 UNSPECIFIED 로 정규화한다.
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct BaseMakeCounterTakeAndBalanceExecution {
    /// base 호가 잔량 회복 비율. 회복 시 base 잔량을 상대호가로 공격 정정(강제 체결).
    #[prost(double, tag="1")]
    pub recovery_ratio: f64,
    /// base 공격 정정 시 상대호가 대비 추가 틱. 0 이면 상대호가 그대로.
    /// Bid 면 +N*tick, Ask 면 -N*tick.
    #[prost(uint32, tag="4")]
    pub base_recovery_aggressive_ticks: u32,
    /// 종단 counter cover 발주 시 추가 틱. 0 이면 상대호가 그대로.
    /// counter.side 가 Bid 면 +N*tick, Ask 면 -N*tick.
    #[prost(uint32, tag="5")]
    pub counter_recovery_aggressive_ticks: u32,
    /// counter 진입 주문가 = counter 상대호가 ± 이 틱 수 (0 = 상대호가 그대로).
    /// counter.side 가 Bid 면 +N*tick (더 공격적), Ask 면 -N*tick.
    #[prost(uint32, tag="6")]
    pub counter_aggressive_ticks: u32,
}
// ============================================================================
// Request / Response Messages — CRUD
// ============================================================================

#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct GetPairRequest {
    /// 리소스 이름 (pairs/{id})
    #[prost(string, tag="1")]
    pub pair: ::prost::alloc::string::String,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct ListPairsRequest {
    /// 페이지 크기 (optional)
    #[prost(int32, optional, tag="1")]
    pub page_size: ::core::option::Option<i32>,
    /// 페이지 토큰 (optional, for pagination)
    #[prost(string, optional, tag="2")]
    pub page_token: ::core::option::Option<::prost::alloc::string::String>,
    /// 필터링 조건 (optional, AIP-160)
    ///
    /// Available Fields:
    /// * status - 상태 (ACTIVE / PAUSED / ARCHIVED)
    /// * portfolio_id - Portfolio ID
    ///
    /// Examples:
    /// * status=ACTIVE
    /// * portfolio_id=1
    #[prost(string, tag="3")]
    pub filter: ::prost::alloc::string::String,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct ListPairsResponse {
    /// Pair 목록
    #[prost(message, repeated, tag="1")]
    pub pairs: ::prost::alloc::vec::Vec<Pair>,
    /// 다음 페이지 토큰
    #[prost(string, tag="2")]
    pub next_page_token: ::prost::alloc::string::String,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct CreatePairRequest {
    /// 생성할 Pair
    #[prost(message, optional, tag="1")]
    pub pair: ::core::option::Option<Pair>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct UpdatePairRequest {
    /// 수정할 Pair
    #[prost(message, optional, tag="1")]
    pub pair: ::core::option::Option<Pair>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct DeletePairRequest {
    /// 리소스 이름 (pairs/{id})
    #[prost(string, tag="1")]
    pub pair: ::prost::alloc::string::String,
}
// ============================================================================
// Request / Response Messages — Lifecycle
// ============================================================================

#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct ActivatePairRequest {
    /// 리소스 이름 (pairs/{id})
    #[prost(string, tag="1")]
    pub pair: ::prost::alloc::string::String,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct PausePairRequest {
    /// 리소스 이름 (pairs/{id})
    #[prost(string, tag="1")]
    pub pair: ::prost::alloc::string::String,
}
// ============================================================================
// Pair Execution Log (사이클별 기록)
// ============================================================================

/// 페어 실행 로그 레코드
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct PairExecutionLog {
    /// Pair ID
    #[prost(int32, tag="1")]
    pub pair_id: i32,
    /// 시그널 시나리오 (예: "BASE_HIGH", "COUNTER_HIGH")
    #[prost(string, tag="2")]
    pub scenario: ::prost::alloc::string::String,
    /// 실행 결과
    #[prost(enumeration="PairExecutionOutcome", tag="3")]
    pub outcome: i32,
    /// Base 측 주문 ID (발주 성공 시)
    #[prost(uint64, optional, tag="4")]
    pub base_order_id: ::core::option::Option<u64>,
    /// Counter 측 주문 ID (발주 성공 시)
    #[prost(uint64, optional, tag="5")]
    pub counter_order_id: ::core::option::Option<u64>,
    /// Base 참조 가격 (원, raw int64)
    #[prost(int64, tag="6")]
    pub base_price: i64,
    /// Counter 참조 가격 (원, raw int64)
    #[prost(int64, tag="7")]
    pub counter_price: i64,
    /// 스프레드 (base - counter, 원, raw int64)
    #[prost(int64, tag="8")]
    pub spread: i64,
    /// 발주 시각
    #[prost(message, optional, tag="9")]
    pub dispatched_at: ::core::option::Option<super::super::super::google::protobuf::Timestamp>,
    /// 상세 내용 (오류 메시지 등, optional)
    #[prost(string, optional, tag="10")]
    pub detail: ::core::option::Option<::prost::alloc::string::String>,
    /// Base 슬롯 최종 체결 수량
    #[prost(int64, tag="11")]
    pub base_qty: i64,
    /// Counter 슬롯 최종 체결 수량
    #[prost(int64, tag="12")]
    pub counter_qty: i64,
    /// Base 슬롯 실제 평균 체결가 (원, raw int64; 미체결이면 0)
    #[prost(int64, tag="13")]
    pub base_fill_price: i64,
    /// Counter 슬롯 실제 평균 체결가 (원, raw int64; 미체결이면 0)
    #[prost(int64, tag="14")]
    pub counter_fill_price: i64,
    /// IOC 모드에서 트리거 마켓데이터 수신 시점부터 base 최초 주문 제출 직후까지의 경과 (us)
    /// 비IOC 모드 또는 미적용 시 0
    #[prost(int64, tag="15")]
    pub trigger_to_base_submit_us: i64,
    /// IOC 모드에서 트리거 마켓데이터 수신 시점부터 counter 최초 주문 제출 직후까지의 경과 (us)
    /// 비IOC 모드 또는 미적용 시 0
    #[prost(int64, tag="16")]
    pub trigger_to_counter_submit_us: i64,
    /// round-trip exit 슬롯 체결 수량 (CounterIocTpSl 전용; base+counter 실행은 미설정)
    #[prost(int64, optional, tag="17")]
    pub exit_qty: ::core::option::Option<i64>,
    /// exit 슬롯 실제 평균 체결가 (원, raw int64; CounterIocTpSl 전용)
    #[prost(int64, optional, tag="18")]
    pub exit_fill_price: ::core::option::Option<i64>,
    /// exit 슬롯 주문 ID — 정정 추적 시 lineage 최종 ID (CounterIocTpSl 전용)
    #[prost(uint64, optional, tag="19")]
    pub exit_order_id: ::core::option::Option<u64>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct ListPairExecutionLogsRequest {
    /// 리소스 이름 (pairs/{id})
    #[prost(string, tag="1")]
    pub pair: ::prost::alloc::string::String,
    /// 페이지 크기 (기본: 50, 최대: 200)
    #[prost(int32, optional, tag="2")]
    pub page_size: ::core::option::Option<i32>,
    /// 페이지 토큰 (다음 페이지 조회용)
    #[prost(string, optional, tag="3")]
    pub page_token: ::core::option::Option<::prost::alloc::string::String>,
    /// 정렬 기준 (기본: dispatched_at DESC)
    #[prost(string, tag="4")]
    pub order_by: ::prost::alloc::string::String,
    /// outcome 필터 (UNSPECIFIED = 전체, 그 외 값이면 해당 outcome만 반환)
    #[prost(enumeration="PairExecutionOutcome", tag="5")]
    pub outcome: i32,
    /// 날짜 필터 (YYYY-MM-DD, KST 기준 해당 일자만 조회. 빈 문자열이면 전체)
    #[prost(string, tag="6")]
    pub date: ::prost::alloc::string::String,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct ListPairExecutionLogsResponse {
    /// 실행 로그 목록
    #[prost(message, repeated, tag="1")]
    pub execution_logs: ::prost::alloc::vec::Vec<PairExecutionLog>,
    /// 다음 페이지 토큰
    #[prost(string, tag="2")]
    pub next_page_token: ::prost::alloc::string::String,
    /// 전체 건수
    #[prost(int32, tag="3")]
    pub total_count: i32,
}
// ============================================================================
// Real-time Status Streaming
// ============================================================================

/// StreamPairStatus 요청
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct StreamPairStatusRequest {
    /// 리소스 이름 (pairs/{id})
    #[prost(string, tag="1")]
    pub pair: ::prost::alloc::string::String,
}
/// 페어 단일 슬롯 실시간 상태 스냅샷
/// (태그 번호는 클라이언트 UI 계약으로 보존됨)
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
pub struct FillStatus {
    /// 미체결 수량 (submitted - filled)
    #[prost(int64, tag="1")]
    pub unfilled_quantity: i64,
    /// 누적 체결 수량 (현재 세션 메모리 카운터, 재시작 시 0)
    #[prost(int64, tag="2")]
    pub filled_quantity: i64,
    /// 체결 VWAP (milli-won 단위)
    #[prost(int64, tag="3")]
    pub avg_fill_price: i64,
    /// 누적 발주 수량 (현재 세션 메모리 카운터)
    #[prost(int64, tag="4")]
    pub submitted_quantity: i64,
}
/// StreamPairStatus 스트리밍 응답 — 페어 상태 스냅샷
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct PairStatusUpdate {
    /// 리소스 이름 (pairs/{id})
    #[prost(string, tag="1")]
    pub pair: ::prost::alloc::string::String,
    /// Base 슬롯 상태
    #[prost(message, optional, tag="2")]
    pub base: ::core::option::Option<FillStatus>,
    /// Counter 슬롯 상태
    #[prost(message, optional, tag="3")]
    pub counter: ::core::option::Option<FillStatus>,
    /// 스냅샷 시각
    #[prost(message, optional, tag="4")]
    pub updated_at: ::core::option::Option<super::super::super::google::protobuf::Timestamp>,
    /// exit(청산) 슬롯 상태 — CounterIocTpSl round-trip 전용.
    /// base+counter 실행(DualSubmit/BaseMakeCounterIoc 등)은 0으로 채워짐.
    #[prost(message, optional, tag="5")]
    pub exit: ::core::option::Option<FillStatus>,
}
// ============================================================================
// Pair Statistics
// ============================================================================

/// GetPairStatistics 요청
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct GetPairStatisticsRequest {
    /// 리소스 이름 (pairs/{id})
    #[prost(string, tag="1")]
    pub pair: ::prost::alloc::string::String,
}
/// 페어 누적 통계 스냅샷 (인메모리 카운터 기반)
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct PairStatistics {
    /// 리소스 이름 (pairs/{id})
    #[prost(string, tag="1")]
    pub pair: ::prost::alloc::string::String,
    /// base + counter 누적 발주 수량
    #[prost(int64, tag="2")]
    pub total_submitted: i64,
    /// base + counter 누적 체결 수량
    #[prost(int64, tag="3")]
    pub total_filled: i64,
    /// 발주 성공 횟수
    #[prost(int64, tag="4")]
    pub execution_count: i64,
    /// 실현 손익 (milli-won). 현재 메모리 카운터 기반.
    #[prost(int64, tag="5")]
    pub realized_pnl: i64,
}
/// 주문 방향
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
#[repr(i32)]
pub enum PairSide {
    Unspecified = 0,
    /// 매수
    Bid = 1,
    /// 매도
    Ask = 2,
}
impl PairSide {
    /// String value of the enum field names used in the ProtoBuf definition.
    ///
    /// The values are not transformed in any way and thus are considered stable
    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
    pub fn as_str_name(&self) -> &'static str {
        match self {
            PairSide::Unspecified => "PAIR_SIDE_UNSPECIFIED",
            PairSide::Bid => "PAIR_SIDE_BID",
            PairSide::Ask => "PAIR_SIDE_ASK",
        }
    }
    /// Creates an enum from field names used in the ProtoBuf definition.
    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
        match value {
            "PAIR_SIDE_UNSPECIFIED" => Some(Self::Unspecified),
            "PAIR_SIDE_BID" => Some(Self::Bid),
            "PAIR_SIDE_ASK" => Some(Self::Ask),
            _ => None,
        }
    }
}
/// 참조 가격 소스 (entry.side 기준 자기/상대 호가).
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
#[repr(i32)]
pub enum PriceSource {
    Unspecified = 0,
    /// 자기호가 (entry.side 와 같은 방향의 1호가). Bid 주문 → bid1, Ask 주문 → ask1.
    BestMake = 5,
    /// 상대호가 (entry.side 반대 방향의 1호가). Bid 주문 → ask1, Ask 주문 → bid1.
    BestTake = 6,
}
impl PriceSource {
    /// String value of the enum field names used in the ProtoBuf definition.
    ///
    /// The values are not transformed in any way and thus are considered stable
    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
    pub fn as_str_name(&self) -> &'static str {
        match self {
            PriceSource::Unspecified => "PRICE_SOURCE_UNSPECIFIED",
            PriceSource::BestMake => "PRICE_SOURCE_BEST_MAKE",
            PriceSource::BestTake => "PRICE_SOURCE_BEST_TAKE",
        }
    }
    /// Creates an enum from field names used in the ProtoBuf definition.
    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
        match value {
            "PRICE_SOURCE_UNSPECIFIED" => Some(Self::Unspecified),
            "PRICE_SOURCE_BEST_MAKE" => Some(Self::BestMake),
            "PRICE_SOURCE_BEST_TAKE" => Some(Self::BestTake),
            _ => None,
        }
    }
}
/// 스프레드 방향 (어느 쪽이 비쌀 때 트리거할지)
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
#[repr(i32)]
pub enum SpreadDirection {
    Unspecified = 0,
    /// Base가 비쌀 때만 트리거
    BaseHigh = 1,
    /// Counter가 비쌀 때만 트리거
    CounterHigh = 2,
    /// 양방향
    Both = 3,
}
impl SpreadDirection {
    /// String value of the enum field names used in the ProtoBuf definition.
    ///
    /// The values are not transformed in any way and thus are considered stable
    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
    pub fn as_str_name(&self) -> &'static str {
        match self {
            SpreadDirection::Unspecified => "SPREAD_DIRECTION_UNSPECIFIED",
            SpreadDirection::BaseHigh => "SPREAD_DIRECTION_BASE_HIGH",
            SpreadDirection::CounterHigh => "SPREAD_DIRECTION_COUNTER_HIGH",
            SpreadDirection::Both => "SPREAD_DIRECTION_BOTH",
        }
    }
    /// Creates an enum from field names used in the ProtoBuf definition.
    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
        match value {
            "SPREAD_DIRECTION_UNSPECIFIED" => Some(Self::Unspecified),
            "SPREAD_DIRECTION_BASE_HIGH" => Some(Self::BaseHigh),
            "SPREAD_DIRECTION_COUNTER_HIGH" => Some(Self::CounterHigh),
            "SPREAD_DIRECTION_BOTH" => Some(Self::Both),
            _ => None,
        }
    }
}
/// 페어 주문 유형
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
#[repr(i32)]
pub enum PairOrderType {
    Unspecified = 0,
    /// 지정가
    Limit = 1,
    /// 시장가
    Market = 2,
    /// 공격적 지정가 (상대 최우선 호가 기반)
    Aggressive = 3,
}
impl PairOrderType {
    /// String value of the enum field names used in the ProtoBuf definition.
    ///
    /// The values are not transformed in any way and thus are considered stable
    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
    pub fn as_str_name(&self) -> &'static str {
        match self {
            PairOrderType::Unspecified => "PAIR_ORDER_TYPE_UNSPECIFIED",
            PairOrderType::Limit => "PAIR_ORDER_TYPE_LIMIT",
            PairOrderType::Market => "PAIR_ORDER_TYPE_MARKET",
            PairOrderType::Aggressive => "PAIR_ORDER_TYPE_AGGRESSIVE",
        }
    }
    /// Creates an enum from field names used in the ProtoBuf definition.
    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
        match value {
            "PAIR_ORDER_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
            "PAIR_ORDER_TYPE_LIMIT" => Some(Self::Limit),
            "PAIR_ORDER_TYPE_MARKET" => Some(Self::Market),
            "PAIR_ORDER_TYPE_AGGRESSIVE" => Some(Self::Aggressive),
            _ => None,
        }
    }
}
// ============================================================================
// Pair Status
// ============================================================================

/// Pair 상태
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
#[repr(i32)]
pub enum PairStatus {
    Unspecified = 0,
    /// 운영 중 (hot loop 동작)
    Active = 1,
    /// 일시 중지
    Paused = 2,
    /// 보관 (더 이상 사용 안 함)
    Archived = 3,
}
impl PairStatus {
    /// String value of the enum field names used in the ProtoBuf definition.
    ///
    /// The values are not transformed in any way and thus are considered stable
    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
    pub fn as_str_name(&self) -> &'static str {
        match self {
            PairStatus::Unspecified => "PAIR_STATUS_UNSPECIFIED",
            PairStatus::Active => "PAIR_STATUS_ACTIVE",
            PairStatus::Paused => "PAIR_STATUS_PAUSED",
            PairStatus::Archived => "PAIR_STATUS_ARCHIVED",
        }
    }
    /// Creates an enum from field names used in the ProtoBuf definition.
    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
        match value {
            "PAIR_STATUS_UNSPECIFIED" => Some(Self::Unspecified),
            "PAIR_STATUS_ACTIVE" => Some(Self::Active),
            "PAIR_STATUS_PAUSED" => Some(Self::Paused),
            "PAIR_STATUS_ARCHIVED" => Some(Self::Archived),
            _ => None,
        }
    }
}
// ============================================================================
// ETF NAV Kind
// ============================================================================

/// ETF NAV 계산 공식 종류
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
#[repr(i32)]
pub enum EtfNavKind {
    Unspecified = 0,
    /// 지수 추종 헷지 프라이싱: (future + basis) * multiple + cash
    IndexTrackingHedge = 1,
    /// 선물 베이시스 기반: unit_delta * future / (prev_index + basis) + cash
    FutureBasis = 2,
    /// 레버리지/인버스 ETF용 선물 기반
    LeverageFuture = 3,
    /// PDF 구성종목 기반 헷지 프라이싱 (단일 선물 구성종목 전제, flatten 필수)
    PdfDecomposeHedge = 4,
}
impl EtfNavKind {
    /// String value of the enum field names used in the ProtoBuf definition.
    ///
    /// The values are not transformed in any way and thus are considered stable
    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
    pub fn as_str_name(&self) -> &'static str {
        match self {
            EtfNavKind::Unspecified => "ETF_NAV_KIND_UNSPECIFIED",
            EtfNavKind::IndexTrackingHedge => "ETF_NAV_KIND_INDEX_TRACKING_HEDGE",
            EtfNavKind::FutureBasis => "ETF_NAV_KIND_FUTURE_BASIS",
            EtfNavKind::LeverageFuture => "ETF_NAV_KIND_LEVERAGE_FUTURE",
            EtfNavKind::PdfDecomposeHedge => "ETF_NAV_KIND_PDF_DECOMPOSE_HEDGE",
        }
    }
    /// Creates an enum from field names used in the ProtoBuf definition.
    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
        match value {
            "ETF_NAV_KIND_UNSPECIFIED" => Some(Self::Unspecified),
            "ETF_NAV_KIND_INDEX_TRACKING_HEDGE" => Some(Self::IndexTrackingHedge),
            "ETF_NAV_KIND_FUTURE_BASIS" => Some(Self::FutureBasis),
            "ETF_NAV_KIND_LEVERAGE_FUTURE" => Some(Self::LeverageFuture),
            "ETF_NAV_KIND_PDF_DECOMPOSE_HEDGE" => Some(Self::PdfDecomposeHedge),
            _ => None,
        }
    }
}
/// 페어 실행 결과
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
#[repr(i32)]
pub enum PairExecutionOutcome {
    Unspecified = 0,
    /// 발주 성공
    Submitted = 1,
    /// 사전 검증 실패로 스킵
    SkippedPreValidation = 2,
    /// 쿨다운 중 스킵
    SkippedCooldown = 3,
    /// 사전 계산 없음으로 스킵
    SkippedNoPrecomputed = 4,
    /// 한쪽만 발주 성공 (부분 실패)
    PartialFailure = 5,
    /// 전체 실패
    Failed = 6,
    /// 체결 수량 없음으로 스킵 (filled qty = 0)
    SkippedNoFilled = 7,
}
impl PairExecutionOutcome {
    /// String value of the enum field names used in the ProtoBuf definition.
    ///
    /// The values are not transformed in any way and thus are considered stable
    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
    pub fn as_str_name(&self) -> &'static str {
        match self {
            PairExecutionOutcome::Unspecified => "PAIR_EXECUTION_OUTCOME_UNSPECIFIED",
            PairExecutionOutcome::Submitted => "PAIR_EXECUTION_OUTCOME_SUBMITTED",
            PairExecutionOutcome::SkippedPreValidation => "PAIR_EXECUTION_OUTCOME_SKIPPED_PRE_VALIDATION",
            PairExecutionOutcome::SkippedCooldown => "PAIR_EXECUTION_OUTCOME_SKIPPED_COOLDOWN",
            PairExecutionOutcome::SkippedNoPrecomputed => "PAIR_EXECUTION_OUTCOME_SKIPPED_NO_PRECOMPUTED",
            PairExecutionOutcome::PartialFailure => "PAIR_EXECUTION_OUTCOME_PARTIAL_FAILURE",
            PairExecutionOutcome::Failed => "PAIR_EXECUTION_OUTCOME_FAILED",
            PairExecutionOutcome::SkippedNoFilled => "PAIR_EXECUTION_OUTCOME_SKIPPED_NO_FILLED",
        }
    }
    /// Creates an enum from field names used in the ProtoBuf definition.
    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
        match value {
            "PAIR_EXECUTION_OUTCOME_UNSPECIFIED" => Some(Self::Unspecified),
            "PAIR_EXECUTION_OUTCOME_SUBMITTED" => Some(Self::Submitted),
            "PAIR_EXECUTION_OUTCOME_SKIPPED_PRE_VALIDATION" => Some(Self::SkippedPreValidation),
            "PAIR_EXECUTION_OUTCOME_SKIPPED_COOLDOWN" => Some(Self::SkippedCooldown),
            "PAIR_EXECUTION_OUTCOME_SKIPPED_NO_PRECOMPUTED" => Some(Self::SkippedNoPrecomputed),
            "PAIR_EXECUTION_OUTCOME_PARTIAL_FAILURE" => Some(Self::PartialFailure),
            "PAIR_EXECUTION_OUTCOME_FAILED" => Some(Self::Failed),
            "PAIR_EXECUTION_OUTCOME_SKIPPED_NO_FILLED" => Some(Self::SkippedNoFilled),
            _ => None,
        }
    }
}
include!("kdo.v1.pair.tonic.rs");
include!("kdo.v1.pair.serde.rs");
// @@protoc_insertion_point(module)