# Lịch Sử Phiên Bản

> Các thay đổi qua từng phiên bản vnstock-js

## 2.0.0

1.x có hai bộ API song song làm cùng một việc, mỗi chỗ trả tiền một đơn vị (nghìn đồng, triệu đồng, tỷ đồng), và phải gọi `init()` trước khi dùng. Bản 2.0 viết lại từ đầu: một API, mọi số tiền là đồng, không cần khởi tạo, chạy được trên Node, serverless và trình duyệt.

```ts
// 1.x
import vnstock from 'vnstock-js'
await vnstock.init()
const history = await vnstock.stock.quote({ ticker: 'FPT', start: '2026-01-01' })
// [{ date: '2026-01-02', close: 125.8, ... }]   giá theo nghìn đồng

// 2.0
import { vn } from 'vnstock-js'
const history = await vn.stock('FPT').history({ from: '2026-01-01' })
// [{ time: '2026-01-02', close: 125800, ... }]  giá theo đồng
```

Không có lớp tương thích với 1.x. Trước khi nâng cấp, đọc [Nâng cấp từ v1](/docs/getting-started/migration): có bảng đối chiếu từng lời gọi và mục Đơn vị. Đơn vị là chỗ dễ sai nhất: đổi lời gọi mà giữ phép nhân chia cũ thì code vẫn chạy, nhưng số lệch 1.000 lần.

### Thay đổi không tương thích

**Đơn vị.** Mọi số tiền là đồng:

| Dữ liệu | 1.x | 2.0 |
|---|---|---|
| Giá cổ phiếu (nến, bảng giá, trần, sàn, tham chiếu) | nghìn đồng | đồng |
| Giá trị giao dịch của nến | triệu đồng | đồng |
| Thanh khoản thị trường, khối ngoại toàn sàn | tỷ đồng | đồng |
| Vốn hoá, báo cáo tài chính, giá vàng | tuỳ nguồn | đồng (vàng: đồng/lượng) |
| `context().performance` | phân số (`0.05`) | phần trăm (`5`) |

Không đổi: chỉ số vẫn là điểm, `changePct` vẫn là phần trăm. Tỷ số tài chính là phân số (`roe: 0.15` là 15%).

**API.**

- Một điểm vào: `import { vn, createClient } from 'vnstock-js'`. `vn.stock('FPT')` và `vn.index('VNINDEX')` trả về handle, các hàm cấp thị trường nằm ngay trên client (`vn.market()`, `vn.screen()`, `vn.prices()`, `vn.gold()`...).
- Gỡ toàn bộ API 1.x: default export, class `Vnstock`, `stock`, `market`, `commodity`, `news`, `realtime`, `watchlist` và các hàm easy mode `quickQuote`, `recentHistory`, `compareSymbols`, `topMovers`.
- Không còn `init()` và `NotInitializedError`. Danh mục mã, lịch nghỉ, tỷ số quý tự tải ở lần dùng đầu.
- Chỉ báo chuyển sang `vnstock-js/indicators`.
- Watchlist rời khỏi SDK, còn ở CLI `vnstock watchlist` và tool MCP `watchlist` (đọc file `~/.vnstock-js/watchlist.json` cũ).

**Tên trường và tham số.**

- Tham số luôn là `symbol`, không còn `ticker`.
- Nến có `time` thay cho `date`, theo giờ Việt Nam: `2026-10-16` cho nến ngày, `2026-10-16T09:15:00+07:00` cho nến trong phiên. Nến trong phiên có `value` là giá trị luỹ kế từ đầu phiên.
- Bảng giá trả `Quote`: `ref`, `ceiling`, `floor`, `volume`, `value`, `bids`, `asks`... thay cho `referencePrice`, `ceilingPrice`, `totalVolume`, `totalValue`, `bidPrices`...
- Khoảng thời gian `1d 5d 1mo 3mo 6mo ytd 1y 2y 5y max` hoặc `{ from, to }`, khung nến `1m 5m 15m 30m 1h 1d 1w 1mo`. Viết kiểu cũ như `6m` thì báo lỗi kèm gợi ý.
- Sàng lọc dùng `where: { pe: { lt: 15 } }` và `sort: '-roe'` thay cho `filters`, `sortBy`, `order`.
- `vn.symbols()` và `vn.search()` trả sàn `HOSE` thay cho `HSX`.

**Môi trường.** Cần Node 18 trở lên. Đã gỡ axios và date-fns, mọi request đi qua `fetch` có sẵn. `watch()` ở chế độ stream cần WebSocket: có sẵn từ Node 22, Node 18 đến 21 cài thêm `ws`.

### Mới

**Chạy ở mọi nơi.**

- `createClient({ proxy, timeout, retries, storage, fetch, preload })`. Handle tạo đồng bộ, không gọi mạng cho tới lần dùng đầu. Gõ sai mã thì lời gọi đầu tiên báo lỗi kèm `Did you mean "FPT"?`.
- Core không đụng ổ đĩa nên chạy trên Vercel, Cloudflare Workers, Deno, Bun. Cache qua `Storage`: mặc định trong bộ nhớ, `fileStorage()` ở `vnstock-js/node` lưu vào `~/.vnstock-js`.
- Proxy cho trình duyệt ở `vnstock-js/proxy` (`nextHandler()`, `workerHandler()`, `expressHandler()`), vì VietCap chặn CORS. Proxy chỉ chuyển tiếp tới hai host VietCap theo danh sách đường dẫn cố định, không phải open proxy.
- Build cả CommonJS và ESM. Entry gốc bundle được cho trình duyệt mà không cần `fs`, `path`, `events` hay `ws`.
- Lỗi có `hint` chỉ cách sửa, và `JSON.stringify` được.

**Dữ liệu.**

- Lịch sử khối ngoại: `vn.stock('FPT').foreign('3mo')`, `vn.market.foreign({ range: '1mo' })`. VietCap chỉ cho xem phiên hiện tại, nên repo tự ghi lại mỗi ngày. Dữ liệu có từ năm 2026.
- Thanh khoản trong phiên: `vn.market.intraday()` trả thanh khoản luỹ kế theo phút, so với phiên trước tại cùng giờ.
- Báo cáo tài chính trả `{ unit: 'VND', fields, rows }` theo năm hoặc quý, kèm lịch sử tỷ số.
- Gộp nến 5m, 15m, 30m, 1w, 1mo phía client.

**Danh mục, theo dõi giá, cảnh báo.**

- `vn.portfolio({ positions, cash })` định giá danh mục theo giá hiện tại, nhóm theo môi giới và theo ngành. `cost` là giá vốn mỗi cổ phiếu, tính bằng đồng.
- `vn.watch(['FPT', 'VCB'], cb)` dùng chung một WebSocket cho mọi watcher; `mode: 'poll'` cho serverless và trình duyệt.
- `alert({ when: 'breakout' })` báo một lần mỗi phiên khi giá vượt đỉnh N phiên. `when` nhận cả hàm `(tick) => boolean`.

**Phân tích.**

- Chỉ báo mới: vùng hỗ trợ/kháng cự, vùng quá mua/quá bán, bảy mẫu nến đảo chiều, tín hiệu Turtle, breakout có xác nhận khối lượng, sức khoẻ thị trường theo William O'Neil. Gọi nhanh qua `vn.stock('FPT').patterns()` và `vn.index('VNINDEX').health()`.
- Backtest kiểu event study: `vn.stock('FPT').backtest('breakout', { tp: 7, sl: 4, hold: 10 })`. Vào lệnh ở giá mở cửa phiên sau tín hiệu; phiên chạm cả chốt lời lẫn cắt lỗ thì tính cắt lỗ trước. `tp`, `sl` tính bằng phần trăm. Chưa tính phí, trượt giá, trần sàn.
- Phiên tương tự (thử nghiệm): `similar()` tìm các phiên trong 5 năm có trạng thái kỹ thuật giống phiên gần nhất, và giá đã đi bao nhiêu sau 5, 20, 60 phiên.

**Cho AI agent.**

- `AGENTS.md` đi kèm package: quy tắc đơn vị và công thức mẫu cho coding agent. Mọi API công khai có JSDoc kèm ví dụ, đọc được ngay từ `.d.ts`. Mọi khối code trong README và AGENTS.md được type-check trong CI.
- MCP có 27 tool, thêm `find_patterns`, `get_foreign_history`, `portfolio_summary`, `backtest_signal`, `find_similar_setups`. Tên 22 tool cũ giữ nguyên.
- CLI thêm `patterns`, `similar`, `backtest`, `gold`, `compare`, `watchlist`, `screen`, `portfolio`. Thêm `--json` để lấy dữ liệu thô.

### Sửa

Các lỗi này có ở 1.x:

- Lịch sử giá bỏ qua ngày bắt đầu: `stock.quote({ start })` luôn trả 365 phiên tính lùi từ hôm nay, và khoảng dài hơn khoảng 1,5 năm bị cắt mất phần đầu.
- Ngày (`end`, `asOf`, ngày sự kiện, tin tức) lệch một ngày tuỳ múi giờ của máy chạy. Nay luôn đọc theo giờ Việt Nam.
- `changePct` luôn `null` ở `quickQuote`, `compareSymbols` và tool MCP `get_quote`.
- Tỷ lệ sở hữu của cổ đông và ban lãnh đạo nhỏ hơn thật 100 lần (6,8% hiện thành 0,068%). Nay là phân số đúng: `0.068` là 6,8%.
- Giá bạc BTMC gấp 10 lần, và `gold()` trả hàng trăm dòng lặp. Nay mỗi sản phẩm còn một dòng mới nhất. Đồng xu vàng bị bỏ khỏi kết quả, vì nguồn báo giá cả đồng xu, không quy được ra đồng/lượng.
- Độ mạnh xu hướng phụ thuộc mức giá: cùng một xu hướng, mã giá 5 nghìn và mã giá 125 nghìn cho độ mạnh khác nhau.
- CLI crash khi thoát trên Windows (`UV_HANDLE_CLOSING`).

## 1.5.1

Bản vá cho môi trường serverless và cách báo lỗi mạng.

### Sửa

- **`import "vnstock-js"` không còn làm sập app trên Vercel, AWS Lambda hay Cloudflare.** Trước đây chỉ cần nạp package là ném `ENOENT: mkdir '/home/.../.vnstock-js'` và mọi route trả 500, kể cả app không hề dùng watchlist. Nguyên nhân: instance `watchlist` được tạo ở cấp module, mà storage lại tạo thư mục trong home ngay lúc khởi tạo, trong khi serverless không có home ghi được.

  Storage nay không đụng ổ đĩa lúc khởi tạo. Thư mục chỉ tạo ở lần ghi đầu tiên, và nếu home không ghi được thì tự chuyển sang thư mục tạm thay vì ném lỗi.

- **Request đứt giữa chừng không còn bị báo là `HTTP 200: OK`.** Phản hồi lớn có thể đứt khi đang tải thân dữ liệu, sau khi header 200 đã về, khiến thư viện đọc nhầm thành lỗi HTTP thành công. Ngoài thông báo vô nghĩa, request kiểu này còn không được thử lại lần nào. Nay nhận diện đúng là lỗi truyền tải, ném `NetworkError` và thử lại theo backoff.

Không breaking. Chạy trên máy cá nhân không thấy khác biệt.

## 1.5.0

Nhóm API mức thị trường: độ rộng, thanh khoản, khối ngoại, bối cảnh cho AI.

### Thêm

- **`market.breadth({ exchange })`**: số mã tăng, giảm, đứng giá, trần, sàn. Sàn nhận `HOSE` (mặc định), `HNX`, `UPCOM`, `ALL`.
- **`market.liquidity({ index, asOf })`**: giá trị giao dịch toàn sàn, kèm phiên trước và % thay đổi.
- **`market.foreignFlow({ exchange, top })`** và **`stock.foreignFlow(symbol)`**: mua, bán, ròng của khối ngoại, kèm top mua bán ròng.
- **`market.overview({ exchange })`**: gộp chỉ số, thanh khoản, độ rộng, khối ngoại trong một lời gọi.
- **`market.aiContext({ exchange, asOf })`**: regime thị trường, thanh khoản so với trung bình 20 phiên, độ rộng, khối ngoại.
- **`asOf`** cho `stock.aiContext()` và `stock.toAIPrompt()`: tính chỉ báo tại cuối một phiên quá khứ.
- **`init({ ratios: true })`**: tải bộ chỉ số theo quý dựng sẵn từ GitHub, cache 24h. Sàng lọc theo ROE, ROA, biên lợi nhuận không gọi mạng lần nào.
- **MCP lên 22 tool** (trước 13): thêm nhóm thị trường và lấp các module chưa lộ ra MCP là tin tức, báo cáo tài chính, sàng lọc, hàng hoá, watchlist.
- **CLI**: `vnstock market` và `vnstock foreign [symbol]`.

Đơn vị tiền nhóm thị trường là **tỷ VND**, output kèm trường `unit`.

### Breaking

- **Giá chỉ số không còn chia 1000.** `VNINDEX` trước trả `1.66901`, nay trả `1669.01` điểm. Nếu code đang nhân 1000 để bù thì bỏ đi.
- **`goldPriceGiaVangNet()` trả dữ liệu đã chuẩn hoá.** Field đổi tên: `type_code` thành `code`, `type` thành `name`, `buy` thành `buyPrice`, `sell` thành `sellPrice`.
- **`screening.screen()` bắt buộc có phạm vi**: phải truyền `group` hoặc `exchange`, không thì ném `InvalidParameterError`.

### Sửa

- **`screening` chuyển sang REST.** Endpoint GraphQL cũ trả body rỗng nên `screen()` trả mảng rỗng, người dùng đọc nhầm thành "không mã nào khớp". Bản mới lọc theo bảng giá trước rồi mới gọi chỉ số cho các mã sống sót.
- **Lỗi mạng nay serialize được.** Trước đây `cause` giữ nguyên đối tượng axios chứa socket trỏ vòng, nên `JSON.stringify(err)` ném lỗi và log qua Sentry hay pino bị hỏng.
- **`asOf` lệch một ngày**, do biên `end` của endpoint là loại trừ.
- **CLI nuốt lệnh mới**: `vnstock market` từng bị hiểu nhầm là mã chứng khoán.

## 1.4.3

### Thêm

- **`QuoteHistory.value`**: giá trị giao dịch từng bar, đơn vị **triệu VND**.
- **`QuoteHistory.symbol`**: mở khoá batch nhiều mã cho `quote.history({ symbols: [...] })`. Một request cho cả danh sách thay vì N request, giảm nguy cơ 429.

Không breaking, cả hai đều là trường optional.

## 1.4.2

### Thêm

- **MCP tool `get_dividends`** và **`get_corporate_events`**: lịch cổ tức và sự kiện doanh nghiệp (ĐHCĐ, phát hành, niêm yết, giao dịch nội bộ).

### Sửa

- **Root export thiếu `macd`, `bollinger`, `atr`**: ba indicator này có từ 1.4.0 nhưng quên re-export, buộc phải import qua subpath. Nay import thẳng từ `vnstock-js`.

## 1.4.1

### Thêm

- **`superTrend(candles, opts?)`**: chỉ báo theo xu hướng, mặc định `period=10, multiplier=3`.
- **`ichimoku(candles, opts?)`** và **`ichimokuFutureCloud()`**: mây Ichimoku, bản thứ hai cho projection 26 phiên tới.
- **`aiContext`** nay kèm `superTrend` và `ichimoku`, và phân loại xu hướng có tính tới hai chỉ báo này.
- **`VciAdapter({ cache })`**: cache TTL cho các endpoint ít đổi. Mặc định bật, tắt bằng `{ cache: false }`.

### Sửa

- **Nhận diện Cloudflare Error 1015**: ném `RateLimitError` và retry với backoff 30s, 60s, 120s thay vì báo lỗi chung.
- **`goldPriceSJC()` deprecated**: endpoint trả 403 từ IP ngoài Việt Nam. Dùng `goldPriceBTMC()` hoặc `goldPriceGiaVangNet()`.

## 1.4.0

Chuyển định vị từ SDK dữ liệu sang bộ công cụ nghiên cứu cho AI.

### Thêm

- **MCP server** (`vnstock mcp`): dùng được với Claude Desktop, Cursor, VS Code. 11 tool song ngữ.
- **Indicators v2**: `macd`, `bollinger`, `atr`.
- **`stock.aiContext(symbol)`**: JSON có cấu trúc gồm xu hướng, snapshot chỉ báo, kháng cự hỗ trợ, z-score khối lượng, hiệu suất 1d/7d/30d/90d.
- **`stock.toAIPrompt(symbol, { lang })`**: bản văn xuôi cho LLM không dùng MCP.
- **Easy mode**: `quickQuote`, `recentHistory`, `compareSymbols`, `topMovers`.
- **Watchlist** `vnstock.watchlist`: CRUD, lưu tại `~/.vnstock-js/watchlist.json`.

Không breaking. Code 1.3.x chạy y nguyên.

## 1.3.3

### Thêm

- **Module `news`**: tin tức tài chính Việt Nam từ [news-crawler](https://github.com/ttqteo/news-crawler). `news.byDate(date?)`, `news.bySource(source, date?)`, `news.search(keyword, date?)`.

### Sửa

- **Listing, Company, Financial hoạt động trở lại.** Ba module này chuyển từ GraphQL (offline từ khoảng 04/2026) sang REST mới của Vietcap. API công khai không đổi.

### Còn tồn tại

- `listing.allSymbols()` vẫn bỏ qua vì endpoint trả 403.
- `screening` chưa chuyển REST, để dành bản sau.

## 1.3.2

### Thêm

- **CLI tự phát hiện bản mới**: kiểm tra ngầm registry npm, in banner ở cuối output. Cache 24h, timeout 2s, tự tắt khi chạy trong CI hoặc khi đặt `VNSTOCK_NO_UPDATE_CHECK=1`.

### Sửa

- **`history --range 1d`** tính đúng `Change %` cho phiên cũ nhất, nhờ fetch thêm buffer 10 phiên để có mốc so sánh.

## 1.3.1

Bản vá cho CLI sau khi release 1.3.0.

### Sửa
- **`history --range 7d`** giờ trả đúng ~7 phiên (trước đây trả ~365 phiên do VCI API bỏ qua `start` khi `countBack` mặc định lớn). Handler tự tính `countBack` theo khoảng ngày và filter lại kết quả.
- **Hiển thị giá:** làm tròn tối đa 2 chữ số thập phân, cắt số 0 cuối. Không còn `56.291760000000004k`.
- **`symbols --exchange HOSE`** giờ hoạt động (trước đây trả rỗng vì data lưu `HSX`). `Directory.getByExchange` tự map `HOSE` → `HSX`.
- **`symbols` mặc định trả đầy đủ** (trước đây tự cắt ở 50). `--limit N` chỉ áp dụng khi user chỉ định.
- **`vnstock -v`** cho `--version` (trước đây dùng `-V` hoa mặc định của commander). Version đọc từ `package.json` thay vì hardcode. `--verbose` ở sub-command bỏ alias `-v` để tránh xung đột.

### Thêm
- **Header cho `history` và `symbols`:** ví dụ `VCB  2026-04-07 → 2026-04-14  (5 phiên)` và `HOSE  (702 mã)`.
- **`docs/local-test.md`**: hướng dẫn `npm link`, watch mode, `npm pack`, debug CLI trước khi release.
- **`npm run dev`**: `tsc --watch` để auto rebuild khi sửa code.

## 1.3.0

### Breaking
- **`await init()` bắt buộc** trước khi dùng symbol lookup hoặc calendar API. Symbol và holiday data không còn bundle trong package, fetch runtime từ raw GitHub để luôn mới.

  ```typescript
  import { init } from "vnstock-js";

  await init();   // gọi 1 lần lúc khởi động app
  ```

  `init()` nhận options: `symbolsUrl`, `holidaysUrl`, `ttl`, `force`, `cacheDir`, `noCache`, `timeout`.

### Tính năng mới
- **Remote data module**: symbols/holidays fetch từ `raw.githubusercontent.com/ttqteo/vnstock-js/master/data/*.json`
- **Disk cache** tại `~/.vnstock-js/cache/`, TTL mặc định 24h
- **Offline fallback**: fetch fail thì dùng cache cũ
- **`NotInitializedError`** và **`DataUnavailableError`** error types
- **CLI tool**: cài `npm i -g vnstock-js` hoặc `npx vnstock-js <command>`:
  - `vnstock quote <SYMBOL>`: snapshot 1 mã
  - `vnstock history <SYMBOL> [--from 7d|1w|1m|1y] [--range 7d] [--limit N]`: OHLCV
  - `vnstock search <QUERY>`: tìm mã theo tên/ticker
  - `vnstock symbols [--exchange HOSE|HNX|UPCOM]`: liệt kê mã
  - Flags chung: `--json`, `--csv`, `--no-color`, `-v, --verbose`. Non-TTY auto plain text.

### Realtime hardening
- **Sửa:** `unsubscribe()` giờ gửi unsub message cho server. Message routing phân biệt quote/JSON/plain text. Loại bỏ WebSocket `ping()` vô nghĩa (browser không còn reset oan ~40s).
- **Dead-man's switch** thay heartbeat: reconnect nếu không nhận message nào trong `deadManTimeout` (mặc định 60s).
- **Breaking (minor):** bỏ `RealtimeClientOptions.heartbeatInterval` và `heartbeatTimeout`, thay bằng `deadManTimeout?: number`.

### Thay đổi
- `data/*.json` không còn bundle trong npm package.

## 1.2.0 (03-04-2026)

### Tính năng mới
- **Symbol Directory** -- danh sách ~3300 mã offline với search theo tên/mã/ngành, relevance ranking, VN30 boost
- **Market Calendar** -- `isTradeDay`, `nextTradeDay`, `prevTradeDay`, `holidays`, giờ giao dịch sàn HOSE
- **Rate limit auto-wait** -- gặp HTTP 429 tự động chờ theo `Retry-After` header rồi retry

### API mới
- `stock.search(query, { limit })` -- tìm mã cổ phiếu offline
- `listing.search()`, `listing.getBySymbol()`, `listing.getByExchange()`, `listing.getByIndustry()`, `listing.allLocal()`
- `market.calendar.isTradeDay(date)`, `nextTradeDay(date)`, `prevTradeDay(date)`, `holidays(year)`, `session()`

### Nội bộ
- `fetchWithRetry` hỗ trợ `rateLimitWait` option (mặc định 5s)
- Thêm `SymbolInfo`, `TradingSession` types
- Thêm script `npm run update-symbols`
- Bundle `data/symbols.json` và `data/holidays.json` trong npm package

## 1.1.0 (03-04-2026)

### Tính năng mới
- **Error taxonomy** -- 6 custom error classes: `VnstockError`, `NetworkError`, `RateLimitError`, `ApiError`, `InvalidSymbolError`, `InvalidParameterError`, `ParseError`
- **Realtime v2** -- `RealtimeClient` dùng EventEmitter pattern, auto-reconnect với exponential backoff, heartbeat, subscribe queue
- **Adapter pattern** -- `StockDataAdapter` interface + `VciAdapter`, chuẩn bị cho multi-source sau này
- **FinancialStatement typing** -- thêm 7 optional typed fields (revenue, grossProfit, netIncome, totalAssets, totalEquity, totalDebt, operatingCashFlow)

### Thay đổi breaking
- Realtime API cũ (`VnstockRealtime.connect/subscribe/parseData`) thay bằng `realtime.create()` + `RealtimeClient` event emitter
- `realtime` giờ là top-level export, không còn trên `Vnstock` class hay `stock` object

### Nội bộ
- Pipeline `fetchWithRetry` wrap axios errors thành custom error classes
- Tất cả validation dùng `InvalidParameterError` thay vì `throw new Error`
- Core modules (quote, trading, listing, financial, company) gọi qua adapter thay vì trực tiếp URL

## 1.0.1 (02-04-2026)

- Xóa dependency `xlsx` (2 CVE: Prototype Pollution + ReDoS)
- Chuyển sang VCB JSON API thay vì parse Excel
- Sửa RSI type signature (`period` giờ optional)
- Thêm request timeout 15 giây
- Bổ sung fields thiếu trong `ScreenResult`
- Bỏ duplicate `QuoteHistory` type
- Sửa mapping index WebSocket SSI realtime data

## 1.0.0 (02-04-2026)

Breaking changes so với v0.5.x. Refactor toàn bộ kiến trúc.

### Kiến trúc mới

- **Pipeline architecture** -- Request Pipeline (fetch + retry) -> Transform Pipeline (parse, clean, rename, normalize, shape)
- Tất cả output chuẩn hóa: Array of Objects, camelCase, giá chia 1000, ISO dates
- Retry tự động 2 lần với exponential backoff cho lỗi 5xx/timeout

### Tính năng mới

- **Sàng lọc cổ phiếu** (`stock.screening`) -- lọc theo PE, ROE, vốn hóa
- **Chỉ báo kỹ thuật** -- SMA, EMA, RSI (pure functions)
- **Company mở rộng** -- affiliates, analysisReports, insiderDeals
- TypeScript interfaces đầy đủ cho tất cả output

### Thay đổi breaking

- Output format thay đổi hoàn toàn (giá chia 1000, field names đổi)
- `stock.price()` -> `stock.quote()`
- `stock.company()` giờ là factory method trả về Company instance
- `VnstockTypes` trỏ sang normalized types
- Realtime `parseData()` trả về `RealtimeQuote` với field names mới

## 0.5.1

- Sửa lỗi nhỏ

## 0.5.0

- Thêm realtime WebSocket từ SSI
- Đổi `stock.price` -> `stock.quote`
- Thêm `trading.topGainers`, `trading.topLosers`

## 0.4.x

- Thêm giá vàng SJC
- Sửa lỗi Company
- Tái cấu trúc codebase

## 0.3.x

- Bỏ hỗ trợ TCBS
- Thêm giá vàng GiaVang.net

## 0.2.0

- Hỗ trợ VCI: listing, báo cáo tài chính
- Thêm tỷ giá VCB

## 0.1.0

- Phiên bản đầu tiên
- Giá giao dịch, lịch sử giá từ VCI và TCBS
- Giá vàng Việt Nam
