x-anchors:
  sub-send: &sub-send
    description: |
      ## Subscribe
      Multiple subscriptions could be opened within the same websocket.

      The auction data of different markets to be subscribed are controlled by the parameters in
      the subscription message listed below.

      Two topics are available:
      - `noii` — Net Order Imbalance Indicator updates (available during Lockdown phase only)
      - `phase` — Auction phase transition notifications
  sub-ack-noii: &sub-ack-noii
    description: |
      ## Receive NOII
    messages:
      - $ref: "#/channels/data/messages/subscribe-ack"
      - $ref: "#/channels/data/messages/subscribe-msg-0-noii"
      - $ref: "#/channels/data/messages/subscribe-msg-1-noii"
  sub-ack-phase: &sub-ack-phase
    description: |
      ## Receive Phase
    messages:
      - $ref: "#/channels/data/messages/subscribe-ack"
      - $ref: "#/channels/data/messages/subscribe-msg-0-phase"
      - $ref: "#/channels/data/messages/subscribe-msg-1-phase"

  sub-ack: &sub-ack
    description: |
      After subscribing, the server sends:
      - an acknowledgement
      - followed by incremental updates.
    messages:
      - $ref: "#/channels/data/messages/subscribe-ack"
      - $ref: "#/channels/data/messages/subscribe-msg-0-noii"
      - $ref: "#/channels/data/messages/subscribe-msg-1-noii"
      - $ref: "#/channels/data/messages/subscribe-msg-0-phase"
      - $ref: "#/channels/data/messages/subscribe-msg-1-phase"

  props-topic-asset: &props-topic-asset
    params:
      type: object
      required:
        - topic
        - symbol
      properties:
        topic:
          type: string
          description: '"noii" or "phase"'
          example: "noii"
        symbol:
          type: string
          description: Market symbol, such as BTCUSDC
          example: "BTCUSDC"

  props-suback-msg: &props-suback-msg
    example: "Successfully subscribed (noii BTCUSDC)"
  props-unsub-ack-msg: &props-unsub-ack-msg
    example: "Successfully unsubscribed (noii BTCUSDC)"

  type-noii: &type-noii
    dataType:
      type: string
      description: \"V1TANoii\"
      example: "V1TANoii"
  schema-noii: &schema-noii
    type: object
    properties:
      auctionId:
        type: string
        description: Auction identifier
      eventType:
        type: string
        description: "UPDATE (periodic NOII during lockdown) or CROSS (auction cross completed)"
        enum:
          - UPDATE
          - CROSS
        example: "UPDATE"
      symbol:
        type: string
        description: Market symbol
        example: "BTCUSDC"
      timestamp:
        type: string
        description: Event timestamp, ISO 8601 with millisecond as string
      clearingPrice:
        type: string
        description: Final clearing price (applicable for CROSS eventType)
      farPrice:
        type: string
        description: Indicative clearing price from auction orders (applicable for UPDATE eventType)
      referencePrice:
        type: string
        description: "Last Trade Price on Regular Continuous Orderbook; if not available, then Index Price"
      imbalanceDirection:
        type: string
        description: "BUY, SELL, or NONE"
        enum:
          - BUY
          - SELL
          - NONE
        example: "BUY"
      imbalanceQuantity:
        type: string
        description: Imbalance quantity
      pairedQuantity:
        type: string
        description: Matched volume

  type-auctionPhase: &type-auctionPhase
    dataType:
      type: string
      description: \"V1TAAuctionPhase\"
      example: "V1TAAuctionPhase"
  schema-phase: &schema-phase
    type: object
    properties:
      auctionId:
        type: string
        description: Auction identifier
      eventType:
        type: string
        description: "AUCTION_STARTED, AUCTION_LOCKDOWN, AUCTION_CROSS_POSTPONED, or AUCTION_CROSS_COMPLETED"
        enum:
          - AUCTION_STARTED
          - AUCTION_LOCKDOWN
          - AUCTION_CROSS_POSTPONED
          - AUCTION_CROSS_COMPLETED
        example: "AUCTION_STARTED"
      phase:
        type: string
        description: Current auction phase
        enum:
          - ACCUMULATION
          - LOCKDOWN
          - CROSS
          - COOLING
        example: "ACCUMULATION"
      symbol:
        type: string
        description: Market symbol
        example: "BTCUSDC"
      timestamp:
        type: string
        description: Event timestamp, ISO 8601 with millisecond as string
      startTime:
        type: string
        description: Accumulation start time, ISO 8601 with millisecond as string
      lockdownTime:
        type: string
        description: Lockdown start time, ISO 8601 with millisecond as string
      scheduledCrossTime:
        type: string
        description: Scheduled cross time, ISO 8601 with millisecond as string
      createAuctionOrderEnabled:
        type: boolean
        description: Whether new auction orders can be placed in the current phase
      amendAuctionOrderEnabled:
        type: boolean
        description: Whether existing auction orders can be amended in the current phase
      cancelAuctionOrderEnabled:
        type: boolean
        description: Whether existing auction orders can be cancelled in the current phase
      message:
        type: string
        description: Optional message (e.g. reason for postponement)
      createdAt:
        type: string
        description: denotes the time the phase event was created, ISO 8601 with millisecond as string
      updatedAt:
        type: string
        description: denotes the time the phase event was last updated, ISO 8601 with millisecond as string

  props-subscribe-msg-0-noii: &props-subscribe-msg-0-noii
    title: NOII Snapshot
    summary: Initial NOII state on subscribe
    payload:
      type: object
      properties:
        type:
          type: string
          description: \"snapshot\"
          example: "snapshot"
        <<: *type-noii
        data:
          type: array
          description: List of NOII entries
          items:
            <<: *schema-noii
  props-subscribe-msg-1-noii: &props-subscribe-msg-1-noii
    title: NOII Update
    summary: Net Order Imbalance Indicator update during lockdown or cross result
    payload:
      type: object
      properties:
        type:
          type: string
          description: \"update\"
          example: "update"
        <<: *type-noii
        data:
          description: A single NOII entry
          <<: *schema-noii

  props-subscribe-msg-0-phase: &props-subscribe-msg-0-phase
    title: Phase Snapshot
    summary: Initial auction phase state on subscribe
    payload:
      type: object
      properties:
        type:
          type: string
          description: \"snapshot\"
          example: "snapshot"
        <<: *type-auctionPhase
        data:
          type: array
          description: Current auction phase
          items:
            <<: *schema-phase
  props-subscribe-msg-1-phase: &props-subscribe-msg-1-phase
    title: Phase Update
    summary: Auction phase transition notification
    payload:
      type: object
      properties:
        type:
          type: string
          description: \"update\"
          example: "update"
        <<: *type-auctionPhase
        data:
          description: A single phase update
          <<: *schema-phase

  props-json-rpc-required: &props-json-rpc-required
    type: object
    required:
      - jsonrpc
      - type
      - method
      - params
      - id
  props-json-rpc: &props-json-rpc
    jsonrpc:
      type: string
      description: '"2.0"'
      example: "2.0"
    id:
      type: string
      description: Request identifier
      example: "1"
  props-cmd: &props-cmd
    type:
      description: '"command"'
      example: "command"
  props-result: &props-result
    responseCodeName:
      type: string
      description: '"OK"'
      example: "OK"
  props-result-str: &props-result-str
    responseCode:
      type: string
      description: "200"
      example: "200"
  props-result-int: &props-result-int
    responseCode:
      type: integer
      description: "200"
      example: 200
  props-rejection: &props-rejection
    payload:
      type: object
      properties:
        <<: *props-json-rpc
        error:
          type: object
          properties:
            code:
              type: string
              description: a high-level code for the error
              example: "-32602"
            errorCode:
              type: string
              description: a precise typed error code
              example: "29013"
            errorCodeName:
              type: string
              description: An explanation of which value was invalid
              example: "'abcde' is not a valid topic"

  op-send: &op-send
    action: send
    channel:
      $ref: "#/channels/data"
  op-receive: &op-receive
    action: receive
    channel:
      $ref: "#/channels/data"

asyncapi: 3.0.0
info:
  title: "Auction Feed"
  version: "1.0.0"
  description: |
    The Auction Feed provides real-time auction data for markets with auctions enabled.

    Two topics are available:

    - `noii` - Net Order Imbalance Indicator (NOII) updates. Available during the Lockdown phase only, providing periodic snapshots of indicative clearing price, imbalance direction/quantity, and matched volume. A final `CROSS` event is sent when the auction cross completes.
    - `phase` - Auction phase transition notifications. Sends events when the auction starts (`AUCTION_STARTED`), enters lockdown (`AUCTION_LOCKDOWN`), is postponed (`AUCTION_CROSS_POSTPONED`), or completes (`AUCTION_CROSS_COMPLETED`).

    ```
    /trading-api/v1/market-data/auction
    ```

servers:
  prod-public:
    host: api.exchange.bullish.com
    protocol: wss
    description: Production / Public
  prod-registered:
    host: registered.api.exchange.bullish.com
    protocol: wss
    description: Production / Registered
  prod-direct:
    host: prod.access.bullish.com
    protocol: wss
    description: Production / Direct Connect
  simnext-public:
    host: api.simnext.bullish-test.com
    protocol: wss
    description: SimNext / Public
  simnext-registered:
    host: registered.api.simnext.bullish-test.com
    protocol: wss
    description: SimNext / Registered
  simnext-direct:
    host: simnext.access.bullish.com
    protocol: wss
    description: SimNext / Direct Connect

channels:
  data:
    address: /trading-api/v1/market-data/auction
    messages:
      subscribe:
        title: Subscription
        summary: Let you subscribe to a given topic
        payload:
          <<: *props-json-rpc-required
          properties:
            method:
              type: string
              description: '"subscribe"'
              example: "subscribe"
            <<: [*props-json-rpc, *props-cmd, *props-topic-asset]
      subscribe-ack:
        title: Acknowledgment
        summary: Confirm the topic being subscribed
        payload:
          type: object
          properties:
            <<: *props-json-rpc
            result:
              type: object
              properties:
                <<: [*props-result, *props-result-str]
                message:
                  type: string
                  description: Confirmation of what has been subscribed
                  <<: *props-suback-msg
      subscribe-msg-0-noii:
        <<: *props-subscribe-msg-0-noii
      subscribe-msg-1-noii:
        <<: *props-subscribe-msg-1-noii
      subscribe-msg-0-phase:
        <<: *props-subscribe-msg-0-phase
      subscribe-msg-1-phase:
        <<: *props-subscribe-msg-1-phase
      subscribe-nack:
        title: Rejection
        summary: Explain why the topic could not be subscribed
        <<: *props-rejection
      keepalive-ping:
        title: Keepalive Ping
        payload:
          <<: *props-json-rpc-required
          properties:
            method:
              type: string
              description: '"keepalivePing"'
              example: "keepalivePing"
            params:
              type: object
            <<: [*props-json-rpc, *props-cmd]
      keepalive-pong:
        title: Keepalive Pong
        payload:
          type: object
          properties:
            <<: *props-json-rpc
            result:
              type: object
              properties:
                <<: [*props-result, *props-result-int]
                message:
                  type: string
                  description: '"Keep alive pong"'
                  example: "Keep alive pong"

operations:
  subscribe:
    <<: [*op-send, *sub-send]
    messages:
      - $ref: "#/channels/data/messages/subscribe"
  receive-noii:
    <<: [*op-receive, *sub-ack-noii]
    messages:
      - $ref: "#/channels/data/messages/subscribe-msg-0-noii"
      - $ref: "#/channels/data/messages/subscribe-msg-1-noii"
  receive-phase:
    <<: [*op-receive, *sub-ack-phase]
    messages:
      - $ref: "#/channels/data/messages/subscribe-msg-0-phase"
      - $ref: "#/channels/data/messages/subscribe-msg-1-phase"
  subscribe-nack:
    <<: *op-receive
    description: In case of *invalid* subscription message, an error rejection would be sent.
    messages:
      - $ref: "#/channels/data/messages/subscribe-nack"

  keepalive-ping:
    <<: *op-send
    description: |
      ## Keepalive
      In case nothing is subscribed to, keep the websocket connection alive.
    messages:
      - $ref: "#/channels/data/messages/keepalive-ping"
  keepalive-pong:
    <<: *op-receive
    description: |
      Acknowledgement returned by the server in response to a keepalive-ping.
    messages:
      - $ref: "#/channels/data/messages/keepalive-pong"
