syntax = "proto3";

package exchain.orderbook.v1;

option go_package = "github.com/exchain/go-exchain/exchain/protocol/orderbook/v1;orderbookv1";

import "nebula/v1/transaction.proto";
import "google/api/annotations.proto";

option java_multiple_files = true;
option java_package = "com.exchain.protocol.orderbook.v1";
option java_outer_classname = "ExChainOrderBookProto";

import "google/protobuf/timestamp.proto";


message PlaceLimitOrderRequest {
  exchain.nebula.v1.Transaction transaction = 1;
}

message PlaceMarketOrderRequest {
  exchain.nebula.v1.Transaction transaction = 1;
}

message CancelOrderRequest {
  exchain.nebula.v1.Transaction transaction = 1;
}

message SignProxyRequest {
  exchain.nebula.v1.Transaction transaction = 1;
}

message Response {
    bytes data = 1;
}

service Orderbook {
  rpc PlaceLimitOrder (PlaceLimitOrderRequest) returns (Response) {
    option (google.api.http) = {
        post: "/exchain/v1/orderbook/place_limit_order"
        body: "*"
    };
  }
  rpc PlaceMarketOrder (PlaceMarketOrderRequest) returns (Response) {
    option (google.api.http) = {
        post: "/exchain/v1/orderbook/place_market_order"
        body: "*"
    };
  }
  rpc CancelOrder (CancelOrderRequest) returns (Response) {
    option (google.api.http) = {
        post: "/exchain/v1/orderbook/cancel_order"
        body: "*"
    };
  }
  rpc SignProxy (SignProxyRequest) returns (Response) {
    option (google.api.http) = {
        post: "/exchain/v1/orderbook/sign_proxy"
        body: "*"
    };
  }
}


message Symbol {
  string base_asset = 1;
  string quote_asset = 2;
}

message PaginationRequest {
  int32 page = 1;
  int32 limit = 2;
}

message PaginationResponse {
  int32 total = 1;
  int32 page = 2;
  int32 limit = 3;
}

message PriceLevel {
  string price = 1;
  string quantity = 2;
}

message OrderBookEntry {
  string price = 1;
  string quantity = 2;
  int64 order_count = 3; // 可选，此价格的订单数量
}

// 订单簿快照
message OrderBookSnapshot {
  string symbol = 1;
  int64 last_update_id = 2;
  google.protobuf.Timestamp time = 3;
  repeated OrderBookEntry bids = 4; // 按价格从高到低排序
  repeated OrderBookEntry asks = 5; // 按价格从低到高排序
}

// 订单簿增量更新
message OrderBookDelta {
  string symbol = 1;
  int64 first_update_id = 2;
  int64 last_update_id = 3;
  google.protobuf.Timestamp time = 4;
  repeated OrderBookEntry bids = 5; // 价格为0表示删除此价格级别
  repeated OrderBookEntry asks = 6; // 价格为0表示删除此价格级别
}

// 获取订单簿快照请求
message GetOrderBookRequest {
  string symbol = 1;
  int32 limit = 2; // 可选，每侧显示的价格级别数，默认100，最大1000
}

// 获取订单簿快照响应
message GetOrderBookResponse {
  OrderBookSnapshot snapshot = 1;
}

// 订阅订单簿增量更新请求
message SubscribeOrderBookRequest {
  string symbol = 1;
  string update_speed = 2; // 可选，如"100ms"、"1000ms"等
}

// 订阅订单簿增量更新响应（流式）
message SubscribeOrderBookResponse {
  oneof update {
    OrderBookSnapshot snapshot = 1; // 初始快照
    OrderBookDelta delta = 2; // 后续增量更新
  }
}

// 获取订单簿顶部价位请求
message GetOrderBookTickerRequest {
  string symbol = 1; // 可选，不提供则返回所有交易对
}

// 订单簿顶部价位
message OrderBookTicker {
  string symbol = 1;
  string bid_price = 2;
  string bid_qty = 3;
  string ask_price = 4;
  string ask_qty = 5;
  google.protobuf.Timestamp time = 6;
}

// 获取订单簿顶部价位响应
message GetOrderBookTickerResponse {
  repeated OrderBookTicker tickers = 1;
}

// ======================== 系统API消息定义 ========================

message PingRequest {}
message PingResponse {}

message ServerTimeRequest {}
message ServerTimeResponse {
  google.protobuf.Timestamp server_time = 1;
}

message ExchangeInfoRequest {
  string symbol = 1; // 可选，指定交易对
}

message RateLimit {
  string rate_limit_type = 1;
  string interval = 2;
  int32 interval_num = 3;
  int64 limit = 4;
}

message SymbolFilter {
  string filter_type = 1;
  string min_price = 2;
  string max_price = 3;
  string tick_size = 4;
  string min_qty = 5;
  string max_qty = 6;
  string step_size = 7;
  string min_notional = 8;
  bool apply_to_market = 9;
  int32 avg_price_mins = 10;
  string multiplier_up = 11;
  string multiplier_down = 12;
  int32 limit = 13;
}

message SymbolInfo {
  string symbol = 1;
  string status = 2;
  string base_asset = 3;
  int32 base_asset_precision = 4;
  string quote_asset = 5;
  int32 quote_asset_precision = 6;
  repeated string order_types = 7;
  bool iceberg_allowed = 8;
  bool oco_allowed = 9;
  bool quote_order_qty_market_allowed = 10;
  bool allow_trailing_stop = 11;
  bool cancel_replace_allowed = 12;
  bool is_spot_trading_allowed = 13;
  bool is_margin_trading_allowed = 14;
  repeated SymbolFilter filters = 15;
  repeated string permissions = 16;
}

message ExchangeInfoResponse {
  string timezone = 1;
  google.protobuf.Timestamp server_time = 2;
  repeated RateLimit rate_limits = 3;
  repeated SymbolInfo symbols = 4;
}

// ======================== 市场数据API消息定义 ========================

message TradesRequest {
  string symbol = 1;
  int32 limit = 2; // 可选，默认500
}

message Trade {
  int64 id = 1;
  string price = 2;
  string qty = 3;
  string quote_qty = 4;
  google.protobuf.Timestamp time = 5;
  bool is_buyer_maker = 6;
  bool is_best_match = 7;
}

message TradesResponse {
  repeated Trade trades = 1;
}

message HistoricalTradesRequest {
  string symbol = 1;
  int64 from_id = 2; // 可选，从哪个交易ID开始
  int32 limit = 3; // 可选，默认500
}

message HistoricalTradesResponse {
  repeated Trade trades = 1;
}

message AggTradesRequest {
  string symbol = 1;
  int64 from_id = 2; // 可选
  google.protobuf.Timestamp start_time = 3; // 可选
  google.protobuf.Timestamp end_time = 4; // 可选
  int32 limit = 5; // 可选，默认500
}

message AggTrade {
  int64 id = 1;
  string price = 2;
  string qty = 3;
  int64 first_id = 4;
  int64 last_id = 5;
  google.protobuf.Timestamp time = 6;
  bool is_buyer_maker = 7;
  bool is_best_match = 8;
}

message AggTradesResponse {
  repeated AggTrade agg_trades = 1;
}

enum KlineInterval {
  KLINE_INTERVAL_UNSPECIFIED = 0;
  KLINE_INTERVAL_1m = 1;
  KLINE_INTERVAL_3m = 2;
  KLINE_INTERVAL_5m = 3;
  KLINE_INTERVAL_15m = 4;
  KLINE_INTERVAL_30m = 5;
  KLINE_INTERVAL_1h = 6;
  KLINE_INTERVAL_2h = 7;
  KLINE_INTERVAL_4h = 8;
  KLINE_INTERVAL_6h = 9;
  KLINE_INTERVAL_8h = 10;
  KLINE_INTERVAL_12h = 11;
  KLINE_INTERVAL_1d = 12;
  KLINE_INTERVAL_3d = 13;
  KLINE_INTERVAL_1w = 14;
  KLINE_INTERVAL_1M = 15;
}

message KlinesRequest {
  string symbol = 1;
  KlineInterval interval = 2;
  google.protobuf.Timestamp start_time = 3; // 可选
  google.protobuf.Timestamp end_time = 4; // 可选
  int32 limit = 5; // 可选，默认500
}

message Kline {
  google.protobuf.Timestamp open_time = 1;
  string open = 2;
  string high = 3;
  string low = 4;
  string close = 5;
  string volume = 6;
  google.protobuf.Timestamp close_time = 7;
  string quote_asset_volume = 8;
  int32 trade_count = 9;
  string taker_buy_base_asset_volume = 10;
  string taker_buy_quote_asset_volume = 11;
}

message KlinesResponse {
  repeated Kline klines = 1;
}

message TickerPriceRequest {
  string symbol = 1; // 可选，不提供则返回所有交易对
}

message TickerPrice {
  string symbol = 1;
  string price = 2;
  google.protobuf.Timestamp time = 3;
}

message TickerPriceResponse {
  repeated TickerPrice tickers = 1;
}

message Ticker24hrRequest {
  string symbol = 1; // 可选，不提供则返回所有交易对
}

message Ticker24hr {
  string symbol = 1;
  string price_change = 2;
  string price_change_percent = 3;
  string weighted_avg_price = 4;
  string prev_close_price = 5;
  string last_price = 6;
  string last_qty = 7;
  string bid_price = 8;
  string bid_qty = 9;
  string ask_price = 10;
  string ask_qty = 11;
  string open_price = 12;
  string high_price = 13;
  string low_price = 14;
  string volume = 15;
  string quote_volume = 16;
  google.protobuf.Timestamp open_time = 17;
  google.protobuf.Timestamp close_time = 18;
  int64 first_id = 19;
  int64 last_id = 20;
  int64 count = 21;
}

message Ticker24hrResponse {
  repeated Ticker24hr tickers = 1;
}

// ======================== 交易API消息定义 ========================

enum OrderSide {
  ORDER_SIDE_UNSPECIFIED = 0;
  ORDER_SIDE_BUY = 1;
  ORDER_SIDE_SELL = 2;
}

enum OrderType {
  ORDER_TYPE_UNSPECIFIED = 0;
  ORDER_TYPE_LIMIT = 1;
  ORDER_TYPE_MARKET = 2;
  ORDER_TYPE_STOP_LOSS = 3;
  ORDER_TYPE_STOP_LOSS_LIMIT = 4;
  ORDER_TYPE_TAKE_PROFIT = 5;
  ORDER_TYPE_TAKE_PROFIT_LIMIT = 6;
  ORDER_TYPE_LIMIT_MAKER = 7;
}

enum TimeInForce {
  TIME_IN_FORCE_UNSPECIFIED = 0;
  TIME_IN_FORCE_GTC = 1; // Good Till Cancel
  TIME_IN_FORCE_IOC = 2; // Immediate or Cancel
  TIME_IN_FORCE_FOK = 3; // Fill or Kill
}

enum OrderResponseType {
  ORDER_RESPONSE_TYPE_UNSPECIFIED = 0;
  ORDER_RESPONSE_TYPE_ACK = 1;
  ORDER_RESPONSE_TYPE_RESULT = 2;
  ORDER_RESPONSE_TYPE_FULL = 3;
}

enum OrderStatus {
  ORDER_STATUS_UNSPECIFIED = 0;
  ORDER_STATUS_NEW = 1;
  ORDER_STATUS_PARTIALLY_FILLED = 2;
  ORDER_STATUS_FILLED = 3;
  ORDER_STATUS_CANCELED = 4;
  ORDER_STATUS_PENDING_CANCEL = 5;
  ORDER_STATUS_REJECTED = 6;
  ORDER_STATUS_EXPIRED = 7;
}

message OrderRequest {
  string symbol = 1;
  OrderSide side = 2;
  OrderType type = 3;
  TimeInForce time_in_force = 4; // 可选
  string quantity = 5; // 可选
  string quote_order_qty = 6; // 可选
  string price = 7; // 可选
  string new_client_order_id = 8; // 可选
  string stop_price = 9; // 可选
  string iceberg_qty = 10; // 可选
  OrderResponseType new_order_resp_type = 11; // 可选
  int32 recv_window = 12; // 可选
  google.protobuf.Timestamp timestamp = 13;
}

message Fill {
  string price = 1;
  string qty = 2;
  string commission = 3;
  string commission_asset = 4;
  int64 trade_id = 5;
}

message OrderResponse {
  string symbol = 1;
  int64 order_id = 2;
  string client_order_id = 3;
  google.protobuf.Timestamp transact_time = 4;
  string price = 5;
  string orig_qty = 6;
  string executed_qty = 7;
  string cummulative_quote_qty = 8;
  OrderStatus status = 9;
  TimeInForce time_in_force = 10;
  OrderType type = 11;
  OrderSide side = 12;
  repeated Fill fills = 13; // 仅在FULL响应类型中
}

message TestOrderRequest {
  string symbol = 1;
  OrderSide side = 2;
  OrderType type = 3;
  TimeInForce time_in_force = 4; // 可选
  string quantity = 5; // 可选
  string quote_order_qty = 6; // 可选
  string price = 7; // 可选
  string new_client_order_id = 8; // 可选
  string stop_price = 9; // 可选
  string iceberg_qty = 10; // 可选
  int32 recv_window = 11; // 可选
  google.protobuf.Timestamp timestamp = 12;
}

message TestOrderResponse {}

message OrderStatusRequest {
  string symbol = 1;
  int64 order_id = 2; // order_id 和 orig_client_order_id 必须二选一
  string orig_client_order_id = 3;
  int32 recv_window = 4; // 可选
  google.protobuf.Timestamp timestamp = 5;
}

message OrderStatusResponse {
  string symbol = 1;
  int64 order_id = 2;
  string client_order_id = 3;
  string price = 4;
  string orig_qty = 5;
  string executed_qty = 6;
  string cummulative_quote_qty = 7;
  OrderStatus status = 8;
  TimeInForce time_in_force = 9;
  OrderType type = 10;
  OrderSide side = 11;
  string stop_price = 12;
  string iceberg_qty = 13;
  google.protobuf.Timestamp time = 14;
  google.protobuf.Timestamp update_time = 15;
  bool is_working = 16;
  string orig_quote_order_qty = 17;
}

message CancelOrderRequest {
  string symbol = 1;
  int64 order_id = 2; // order_id 和 orig_client_order_id 必须二选一
  string orig_client_order_id = 3;
  string new_client_order_id = 4; // 可选
  int32 recv_window = 5; // 可选
  google.protobuf.Timestamp timestamp = 6;
}

message CancelOrderResponse {
  string symbol = 1;
  string orig_client_order_id = 2;
  int64 order_id = 3;
  string client_order_id = 4;
}

message CancelAllOrdersRequest {
  string symbol = 1;
  int32 recv_window = 2; // 可选
  google.protobuf.Timestamp timestamp = 3;
}

message CancelAllOrdersResponse {
  repeated CancelOrderResponse orders = 1;
}

message OpenOrdersRequest {
  string symbol = 1; // 可选
  int32 recv_window = 2; // 可选
  google.protobuf.Timestamp timestamp = 3;
}

message OpenOrdersResponse {
  repeated OrderStatusResponse orders = 1;
}

message AllOrdersRequest {
  string symbol = 1;
  int64 order_id = 2; // 可选
  google.protobuf.Timestamp start_time = 3; // 可选
  google.protobuf.Timestamp end_time = 4; // 可选
  int32 limit = 5; // 可选, 默认500
  int32 recv_window = 6; // 可选
  google.protobuf.Timestamp timestamp = 7;
}

message AllOrdersResponse {
  repeated OrderStatusResponse orders = 1;
}

// OCO (One-Cancels-Other) 订单
message NewOCORequest {
  string symbol = 1;
  string list_client_order_id = 2; // 可选
  OrderSide side = 3;
  string quantity = 4;
  string limit_client_order_id = 5; // 可选
  string price = 6;
  string limit_iceberg_qty = 7; // 可选
  string stop_client_order_id = 8; // 可选
  string stop_price = 9;
  string stop_limit_price = 10; // 可选
  string stop_iceberg_qty = 11; // 可选
  TimeInForce stop_limit_time_in_force = 12; // 可选
  int32 recv_window = 13; // 可选
  google.protobuf.Timestamp timestamp = 14;
}

message OCOOrder {
  string symbol = 1;
  int64 order_id = 2;
  string client_order_id = 3;
}

message OCOResponse {
  int64 order_list_id = 1;
  string contingency_type = 2;
  string list_status_type = 3;
  string list_order_status = 4;
  string list_client_order_id = 5;
  google.protobuf.Timestamp transaction_time = 6;
  repeated OCOOrder orders = 7;
}

message GetOCORequest {
  int64 order_list_id = 1; // order_list_id 和 orig_client_order_id 二选一
  string orig_client_order_id = 2;
  int32 recv_window = 3; // 可选
  google.protobuf.Timestamp timestamp = 4;
}

message GetOCOResponse {
  OCOResponse oco = 1;
}

message CancelOCORequest {
  string symbol = 1;
  int64 order_list_id = 2; // order_list_id, list_client_order_id, 和 new_client_order_id 三选一
  string list_client_order_id = 3;
  string new_client_order_id = 4; // 可选
  int32 recv_window = 5; // 可选
  google.protobuf.Timestamp timestamp = 6;
}

message CancelOCOResponse {
  OCOResponse oco = 1;
}

// ======================== 账户API消息定义 ========================

message AccountInfoRequest {
  int32 recv_window = 1; // 可选
  google.protobuf.Timestamp timestamp = 2;
}

message AssetBalance {
  string asset = 1;
  string free = 2;
  string locked = 3;
}

message AccountInfoResponse {
  int32 maker_commission = 1;
  int32 taker_commission = 2;
  int32 buyer_commission = 3;
  int32 seller_commission = 4;
  bool can_trade = 5;
  bool can_withdraw = 6;
  bool can_deposit = 7;
  google.protobuf.Timestamp update_time = 8;
  string account_type = 9;
  repeated AssetBalance balances = 10;
  repeated string permissions = 11;
}

message MyTradesRequest {
  string symbol = 1;
  int64 order_id = 2; // 可选
  google.protobuf.Timestamp start_time = 3; // 可选
  google.protobuf.Timestamp end_time = 4; // 可选
  int64 from_id = 5; // 可选
  int32 limit = 6; // 可选, 默认500
  int32 recv_window = 7; // 可选
  google.protobuf.Timestamp timestamp = 8;
}

message MyTrade {
  string symbol = 1;
  int64 id = 2;
  int64 order_id = 3;
  string price = 4;
  string qty = 5;
  string quote_qty = 6;
  string commission = 7;
  string commission_asset = 8;
  google.protobuf.Timestamp time = 9;
  bool is_buyer = 10;
  bool is_maker = 11;
  bool is_best_match = 12;
}

message MyTradesResponse {
  repeated MyTrade trades = 1;
}

// ======================== 服务定义 ========================

// 系统API服务 - 提供基本系统功能
service SystemApi {
  // 测试连接
  rpc Ping(PingRequest) returns (PingResponse) {
    option (google.api.http) = {
      get: "/exchain/v1/ping"
    };
  }

  // 获取服务器时间
  rpc GetServerTime(ServerTimeRequest) returns (ServerTimeResponse) {
    option (google.api.http) = {
      get: "/exchain/v1/time"
    };
  }

  // 获取交易所信息
  rpc GetExchangeInfo(ExchangeInfoRequest) returns (ExchangeInfoResponse) {
    option (google.api.http) = {
      get: "/exchain/v1/exchangeInfo"
    };
  }
}

// 市场数据API - 提供市场数据查询
service MarketApi {
  // 获取订单簿
  rpc GetOrderBook(GetOrderBookRequest) returns (GetOrderBookResponse) {
    option (google.api.http) = {
      get: "/exchain/v1/depth"
    };
  }

  // 订阅订单簿更新(流)
  rpc SubscribeOrderBook(SubscribeOrderBookRequest) returns (stream SubscribeOrderBookResponse) {}

  // 获取订单簿顶部价格
  rpc GetOrderBookTicker(GetOrderBookTickerRequest) returns (GetOrderBookTickerResponse) {
    option (google.api.http) = {
      get: "/exchain/v1/ticker/bookTicker"
    };
  }

  // 获取最近成交
  rpc GetTrades(TradesRequest) returns (TradesResponse) {
    option (google.api.http) = {
      get: "/exchain/v1/trades"
    };
  }

  // 获取历史成交
  rpc GetHistoricalTrades(HistoricalTradesRequest) returns (HistoricalTradesResponse) {
    option (google.api.http) = {
      get: "/exchain/v1/historicalTrades"
    };
  }

  // 获取聚合成交
  rpc GetAggTrades(AggTradesRequest) returns (AggTradesResponse) {
    option (google.api.http) = {
      get: "/exchain/v1/aggTrades"
    };
  }

  // 获取K线数据
  rpc GetKlines(KlinesRequest) returns (KlinesResponse) {
    option (google.api.http) = {
      get: "/exchain/v1/klines"
    };
  }

  // 获取24小时价格变动统计
  rpc Get24hrTicker(Ticker24hrRequest) returns (Ticker24hrResponse) {
    option (google.api.http) = {
      get: "/exchain/v1/ticker/24hr"
    };
  }

  // 获取最新价格
  rpc GetTickerPrice(TickerPriceRequest) returns (TickerPriceResponse) {
    option (google.api.http) = {
      get: "/exchain/v1/ticker/price"
    };
  }
}

// 交易API服务 - 提供订单操作
service TradeApi {
  // 测试下单
  rpc TestOrder(TestOrderRequest) returns (TestOrderResponse) {
    option (google.api.http) = {
      post: "/exchain/v1/order/test"
      body: "*"
    };
  }

  // 下单
  rpc CreateOrder(OrderRequest) returns (OrderResponse) {
    option (google.api.http) = {
      post: "/exchain/v1/order"
      body: "*"
    };
  }

  // 查询订单
  rpc GetOrder(OrderStatusRequest) returns (OrderStatusResponse) {
    option (google.api.http) = {
      get: "/exchain/v1/order"
    };
  }

  // 撤销订单
  rpc CancelOrder(CancelOrderRequest) returns (CancelOrderResponse) {
    option (google.api.http) = {
      delete: "/exchain/v1/order"
    };
  }

  // 撤销单一交易对的所有订单
  rpc CancelAllOrders(CancelAllOrdersRequest) returns (CancelAllOrdersResponse) {
    option (google.api.http) = {
      delete: "/exchain/v1/openOrders"
    };
  }

  // 查询当前挂单
  rpc GetOpenOrders(OpenOrdersRequest) returns (OpenOrdersResponse) {
    option (google.api.http) = {
      get: "/exchain/v1/openOrders"
    };
  }

  // 查询所有订单
  rpc GetAllOrders(AllOrdersRequest) returns (AllOrdersResponse) {
    option (google.api.http) = {
      get: "/exchain/v1/allOrders"
    };
  }
}

// 账户API服务 - 提供账户信息
service AccountApi {
  // 获取账户信息
  rpc GetAccountInfo(AccountInfoRequest) returns (AccountInfoResponse) {
    option (google.api.http) = {
      get: "/exchain/v1/account"
    };
  }

  // 获取账户交易历史
  rpc GetMyTrades(MyTradesRequest) returns (MyTradesResponse) {
    option (google.api.http) = {
      get: "/exchain/v1/myTrades"
    };
  }
}

// 订单簿专用服务 - 提供订单簿功能
service OrderBookApi {
  // 获取完整订单簿
  rpc GetFullOrderBook(GetOrderBookRequest) returns (GetOrderBookResponse) {
    option (google.api.http) = {
      get: "/exchain/v1/orderbook/depth"
    };
  }

  // 获取聚合订单簿(合并相似价格)
  rpc GetAggregatedOrderBook(GetOrderBookRequest) returns (GetOrderBookResponse) {
    option (google.api.http) = {
      get: "/exchain/v1/orderbook/aggregated"
    };
  }

  // 订阅实时订单簿更新
  rpc StreamOrderBook(SubscribeOrderBookRequest) returns (stream SubscribeOrderBookResponse) {}

  // 获取最近订单簿更新记录
  rpc GetOrderBookUpdates(GetOrderBookRequest) returns (stream OrderBookDelta) {
    option (google.api.http) = {
      get: "/exchain/v1/orderbook/updates"
    };
  }
}
