# 实时 K 线（SSE）

> 实时 K 线的 SSE 契约：snapshot、forming、closed 与 status 帧。

Source: https://kcq.nebutra.com/zh/docs/market-data/live-bars


<Callout>
  生成自 

  [`packages/core/src/data/live/types.ts`](https://github.com/TsekaLuk/KLineChartQuant/blob/1aa5e22c61313a34d08878ad895e604e0d4a85e9/packages/core/src/data/live/types.ts)

   与 

  [`barsLive.ts`](https://github.com/TsekaLuk/KLineChartQuant/blob/1aa5e22c61313a34d08878ad895e604e0d4a85e9/packages/core/src/data/live/impl/barsLive.ts)

  .
</Callout>

连接器通过 Server-Sent Events 向图表推送实时 K 线。一条连接只承载一个序列：数据源、代码、周期与 K 线聚合方式。任一维度变化都会关闭旧流、建立新流。

Endpoint [#endpoint]

```http
GET /api/v1/market-data/sources/{sourceId}/stream?symbol=…&period=…&barAggregation=…&instrumentId=…
Accept: text/event-stream
```

| 查询参数                        | 必填 |
| --------------------------- | -- |
| <code>symbol</code>         | 是  |
| <code>period</code>         | 是  |
| <code>barAggregation</code> | 是  |
| <code>instrumentId</code>   | —  |

`instrumentId` 是已解析品种的稳定 id，仅在已知时发送，用于区分在两个交易所同名的裸代码。

帧 [#帧]

每个 SSE `data:` 行是一个 JSON 帧。注释行（`:` 心跳）和空数据会被忽略。

| `type`                | 字段                                                                                                               | 含义                                     |
| --------------------- | ---------------------------------------------------------------------------------------------------------------- | -------------------------------------- |
| <code>snapshot</code> | <code>symbol: string</code> <code>period: string</code> <code>bars: LiveBar\[]</code>                            | 序列尾部全量。首帧和重连后发送；图表整批写入，并清空暂存的收线。       |
| <code>forming</code>  | <code>symbol: string</code> <code>period: string</code> <code>bar: LiveBar</code>                                | 正在形成的 K 线。与暂存的收线合并为一次原子写入。             |
| <code>closed</code>   | <code>symbol: string</code> <code>period: string</code> <code>bar: LiveBar</code>                                | 某根 K 线的终值。暂存到下一根 forming 到达（或断流）时一起写入。 |
| <code>status</code>   | <code>symbol: string</code> <code>period: string</code> <code>status: string</code> <code>detail?: string</code> | 该订阅的连接器状态，可附 detail，不修改 K 线。           |

LiveBar [#livebar]

| 字段                     | 类型                  | 必填 |
| ---------------------- | ------------------- | -- |
| <code>timestamp</code> | <code>number</code> | 是  |
| <code>open</code>      | <code>number</code> | 是  |
| <code>high</code>      | <code>number</code> | 是  |
| <code>low</code>       | <code>number</code> | 是  |
| <code>close</code>     | <code>number</code> | 是  |
| <code>volume</code>    | <code>number</code> | —  |
| <code>turnover</code>  | <code>number</code> | —  |

`timestamp` 为 UTC 毫秒。缺省的 `volume` 与 `turnover` 写为 0。

```text
data: {"type":"snapshot","symbol":"600519","period":"1min","bars":[…]}

data: {"type":"forming","symbol":"600519","period":"1min","bar":{"timestamp":…,"open":…,"high":…,"low":…,"close":…}}

data: {"type":"closed","symbol":"600519","period":"1min","bar":{…}}
```

连接状态 [#连接状态]

流会报告 `connecting`、`connected`、`disconnected`。浏览器的 EventSource 会自动重连；连接器可凭 `Last-Event-ID` 补发错过的帧。
