// @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,
    /// 주문 tp_code (NONE=일반, LP=유동성공급자). 이 레그의 신규 주문에 적용. 미지정 시 NONE.
    #[prost(enumeration="super::hedge::OrderTpCode", tag="7")]
    pub tp_code: 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,
    /// NAV 베이시스 (선물 가격 축, base=선물 기준 단일값).
    /// 양수면 선물 목표가를 보수적으로 조정.
    #[prost(int64, tag="2")]
    pub basis: i64,
    /// 선물-ETF basis 동기화 버스 구독 여부.
    /// true 이면 pair가 버스 이벤트를 수신해 Nav.basis를 자동 갱신한다. 기본 false.
    #[prost(bool, tag="4")]
    pub basis_subscribe_enabled: bool,
}
// ============================================================================
// TriggerCondition — 트리거 축
// ============================================================================

/// 트리거 — 언제 발사할지. 실행(OrderExecution)과 독립적으로 조합한다.
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, 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, 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,
    /// base 의 bid·ask 1호가 수량이 모두 이 값을 초과해야 트리거 발사. 0 = 미설정.
    #[prost(int64, tag="4")]
    pub min_base_qty: i64,
}
/// counter 시세로 base 의 NAV 목표가를 환산해, base 자기측(BestMake) 1호가가
/// 목표가와 정확히 일치하면서 수량 불균형일 때 발사. nav 파라미터는 Pair.nav 공유 설정 사용.
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct TargetNavQuantityImbalanceTrigger {
    /// 수량 불균형 임계 (BestMakeQuantityImbalanceTrigger 와 동일 판정식)
    #[prost(double, tag="1")]
    pub threshold_ratio: f64,
    /// 트리거 후 재트리거까지 대기시간 (ms)
    #[prost(uint64, tag="2")]
    pub cooldown_ms: u64,
    /// qty imbalance 판정 전용 심볼 (미지정=base.symbol 동일, 기존 동작).
    /// 지정 시 해당 호가(예: 현물)의 deficit_side 로 qty_gate 평가. price_gate(NAV 비교)와 주문 발주는 base 유지.
    #[prost(string, optional, tag="3")]
    pub imbalance_symbol: ::core::option::Option<::prost::alloc::string::String>,
    /// base 의 bid·ask 1호가 수량이 모두 이 값을 초과해야 트리거 발사. 0 = 미설정.
    #[prost(int64, tag="5")]
    pub min_base_qty: i64,
}
// ============================================================================
// 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,
    /// 발주 시각
    #[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>,
    /// 발주가 대비 체결 평균가 슬리피지(원). side 반영해 불리하게 체결될수록 양수
    /// (매수=체결−발주, 매도=발주−체결). base 무발주 execution(CounterIocTpSl)에선 base_slippage=0.
    #[prost(int64, tag="20")]
    pub base_slippage: i64,
    /// 발주가 대비 체결 평균가 슬리피지(원). side 반영해 불리하게 체결될수록 양수
    /// (매수=체결−발주, 매도=발주−체결). base 무발주 execution(CounterIocTpSl)에선 base_slippage=0.
    #[prost(int64, tag="21")]
    pub counter_slippage: i64,
    /// 실행 사이클 상관 id — IOC 엔진의 exchange_time 기반.
    /// DualSubmit(fire-and-forget)·사이클 시작 전 스킵 경로는 사이클이 없어 미설정(null).
    #[prost(uint32, optional, tag="22")]
    pub cycle_id: ::core::option::Option<u32>,
}
#[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,
    /// 시작 시각 필터 (HH:MM, KST. date와 함께 사용. 빈 문자열이면 해당 일자 00:00부터)
    #[prost(string, tag="7")]
    pub start_time: ::prost::alloc::string::String,
    /// 종료 시각 필터 (HH:MM, KST. date와 함께 사용. 빈 문자열이면 해당 일자 끝까지. 지정 시 해당 분까지 포함)
    #[prost(string, tag="8")]
    pub end_time: ::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,
}
/// StreamPairConfig 요청
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct StreamPairConfigRequest {
    /// 리소스 이름 (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)