Strasmore Research
Học tập Matt ConnorBởi Matt Connor

Quant workbench A-share tự lưu trữ là gì?

Tìm hiểu quant workbench A-share tự vận hành dựa trên React, FastAPI và scheduler, cùng bốn điểm cần kiểm tra trước khi sàng lọc hoặc backtest trên máy riêng.

Một quant workbench tự lưu trữ cho thị trường cổ phiếu A là một trang web duy nhất dùng để sàng lọc thị trường, theo dõi danh sách mã, chạy backtest và viết báo cáo tổng kết sau phiên. Công cụ này chạy trên máy do bạn kiểm soát thay vì terminal của công ty môi giới. Một dự án được cấp phép theo MIT, tickflow-stock-panel, tích hợp toàn bộ chức năng đó qua một port duy nhất. Tính đến tháng 8 năm 2026, dự án đã có khoảng 2.800 GitHub star. Danh sách tính năng là phần dễ đọc. Chính lớp nền bên dưới mới quyết định liệu các chức năng đó có còn hoạt động trong quý tới hay không.

Một quant workbench A-share tự vận hành gồm những gì

Kiến trúc này đủ ngắn để bạn có thể ghi nhớ. Dựa trên code và tài liệu tại commit tháng 8/2026, cấu trúc gồm:

  • Một trang web được xây dựng bằng React và TypeScript.
  • Một dịch vụ Python sử dụng FastAPI, kèm scheduler để làm mới dữ liệu theo lịch định sẵn.
  • Một kho dữ liệu cục bộ: các tệp Parquet lưu trên ổ đĩa, được truy vấn bằng DuckDB và tính toán bằng Polars.
  • Một công cụ backtesting là vectorbt, sử dụng các tệp dữ liệu đó.
  • Một vendor SDK lấy mọi mức giá được hiển thị trên bảng điều khiển.

Hãy lưu ý những thành phần không xuất hiện. Không có thành phần nào trong stack này kết nối với sở giao dịch. Bảng điều khiển thực hiện tính toán; vendor cung cấp dữ liệu. “Self-hosted” chỉ mô tả nơi code chạy, không cho biết các con số đến từ đâu. Việc sở hữu dữ liệu giá gốc là nhiệm vụ của lớp bên dưới, hồ dữ liệu thị trường A-share cục bộ, và đây là yếu tố khiến mọi thành phần phía trên có thể được thay thế.

Gói miễn phí của nguồn dữ liệu cung cấp những gì

Một biến môi trường quyết định panel có thể truy cập những gì. Để trống vendor key, dự án sẽ chạy ở chế độ mà tài liệu gọi là None: nhận dữ liệu giá hằng ngày trong quá khứ từ một endpoint miễn phí, còn dữ liệu của phiên hiện tại chỉ xuất hiện sau khi thị trường đóng cửa khoảng one to two giờ. Điền key vào sẽ mở quyền truy cập theo tier trả phí. Đây là gói miễn phí có thể sử dụng cho công việc cuối ngày, nhưng hoàn toàn không phù hợp với dữ liệu intraday. Các điều khoản này có thể được vendor nhắc lại khi gia hạn.

Maintainer nêu rõ thỏa thuận này:

Dự án này chỉ phục vụ học tập và nghiên cứu định lượng, không cấu thành bất kỳ khuyến nghị đầu tư nào. Kết quả backtest không đại diện cho lợi nhuận trong tương lai.
Dự án là mã nguồn mở cá nhân, dựa trên nguồn dữ liệu TickFlow, không phải dự án chính thức của TickFlow.
README, shy3130/tickflow-stock-panel, đọc ngày 13 tháng 8 năm 2026

Nói cách khác, dự án phục vụ học tập và nghiên cứu định lượng, “không cấu thành khuyến nghị đầu tư”, kết quả backtest không đại diện cho lợi nhuận trong tương lai và là “một dự án mã nguồn mở cá nhân, không phải sản phẩm chính thức của TickFlow”. Đây là bài học có tính nền tảng của toàn bộ mô hình này. Zero-ops loại bỏ phần việc vận hành khỏi công việc của bạn. Nhưng sự phụ thuộc vẫn giữ nguyên: bạn đang thuê dữ liệu từ một công ty chưa từng cam kết hỗ trợ panel này. README cũng giới hạn mục đích sử dụng ở học tập và nghiên cứu, trong khi tệp giấy phép sử dụng MIT.

Vì sao nên ghim commit SHA thay vì số phiên bản

Commit SHA là mã nhận dạng dài 40 ký tự do git gán cho mỗi thay đổi đã lưu. Mã này xác định chính xác một trạng thái của mã nguồn và không thay đổi theo thời gian.

Khi kiểm tra vào ngày 13 tháng 8 năm 2026, kho mã không có nội dung nào trên trang GitHub Releases. Kho có 31 version tag, từ v0.1.31 đến v0.1.88, nhưng bị ngắt quãng về số thứ tự và không kèm ghi chú. Tag mới nhất trỏ đến một commit ngày 31 tháng 7 năm 2026, trong khi branch mặc định đã có các thay đổi đến ngày 6 tháng 8 năm 2026. Một tag đi sau branch và không có ghi chú không thể cho bạn biết chính xác mình đang sử dụng mã nào.

Vì vậy, hãy ghi lại SHA. Commit đầu branch mặc định vào ngày 6 tháng 8 năm 2026 là ecfddb451e97f6fc9a7e43ac33e4ef0e69933b33. Hãy checkout commit đó và ghi lại bên cạnh mọi kết luận bạn rút ra từ các backtest. Sau sáu tuần, câu “tôi đã chạy bản mới nhất” không cho biết điều gì.

Theo tài liệu, bước khởi đầu gồm hai dòng lệnh: sao chép file môi trường mẫu thành .env, sau đó chạy docker compose up --build để phục vụ panel trên port 3018. Đây là hướng dẫn của maintainer tại commit đó, không phải quy trình đã được kiểm thử; quá trình build sẽ tải image và cần kết nối mạng, trong khi bài viết này chưa kiểm tra phần đó. Quy trình phát triển (./dev.sh hoặc .\dev.ps1 trên Windows) yêu cầu Python 3.11 trở lên, Node 20 trở lên, cùng các package manager uvpnpm.

Dữ liệu tính năng chiến lược LLM gửi đi và nơi gửi

Tính năng tạo chiến lược, bình luận về từng cổ phiếu và bài viết đánh giá đều là tùy chọn. Để trống AI_API_KEY thì toàn bộ giao diện này vẫn bị ẩn. Khi điền giá trị, bạn cũng thiết lập AI_PROVIDER (một endpoint tương thích với OpenAI hoặc Ollama), AI_BASE_URL, AI_MODELAI_DAILY_TOKEN_BUDGET. AI_DAILY_TOKEN_BUDGET sẽ ngừng các lệnh gọi khi đã sử dụng hết hạn mức token trong ngày.

Hướng kết nối rất quan trọng. Prompt của bạn và mọi dữ liệu ngữ cảnh mà bảng điều khiển đính kèm sẽ rời khỏi máy và được gửi đến endpoint bạn đã cấu hình. Nếu trỏ base URL đến một API được lưu trữ trên máy chủ của nhà cung cấp, yêu cầu sẽ được gửi đến công ty đó. Nếu trỏ đến một runtime trong mạng riêng của bạn, dữ liệu sẽ ở lại trong hệ thống của bạn. Tự lưu trữ bảng điều khiển không có nghĩa là tự lưu trữ model. Các key được lưu dưới dạng văn bản thuần trong .env tại thư mục gốc của dự án. Bạn cũng có thể chỉnh sửa chúng trên trang cài đặt, được bảo vệ bằng mật khẩu dashboard dài tối thiểu sáu ký tự. Bài viết của chúng tôi về các yếu tố alpha do LLM tạo ra trình bày những điểm mà các chiến lược do máy tạo thường thất bại.

Bộ backtester có mô hình hóa chi phí giao dịch không?

Bộ backtester quảng bá khả năng xử lý T+1, hoa hồng, slippage và lệnh stop-loss. Việc các tùy chọn này tồn tại không có nghĩa là chúng đã được thiết lập. Một backtest khớp lệnh tại giá đóng cửa được hiển thị với chi phí bằng 0 đồng nghĩa với giả định giao dịch là miễn phí. Điều đó không đúng. Một basis point bằng một phần trăm của một phần trăm. Bảng dưới đây đo chênh lệch trung bình giữa giá bid tốt nhất và giá offer tốt nhất, tính theo basis point, trên sáu mã niêm yết tại Mỹ trong một giờ giữa phiên ngày 17 tháng 6 năm 2026.

Truy vấnChi phí crossing spread: spread niêm yết bình quân, sáu mã niêm yết tại Mỹ, giữa phiên ngày 17/6/2026
Câu lệnh SQL chính xác đằng sau mỗi con số
SELECT
    ticker                                                                       AS symbol,
    round(avg(toFloat64(ask_price) - toFloat64(bid_price))
          / avg((toFloat64(ask_price) + toFloat64(bid_price)) / 2) * 10000, 2)   AS spread_bps
FROM global_markets.cache_stocks_quotes
WHERE ticker IN ('SPY', 'AAPL', 'MSFT', 'NVDA', 'KO', 'F')
  AND sip_timestamp >= toDateTime('2026-06-17 15:00:00', 'UTC')
  AND sip_timestamp <  toDateTime('2026-06-17 16:00:00', 'UTC')
  AND bid_price > 0
  AND ask_price > bid_price
GROUP BY ticker
ORDER BY spread_bps
Run this yourself

Mã có spread hẹp nhất trong bảng, SPY, có spread trung bình là 0.29 bps trong giờ đó. Mã có spread rộng nhất, F, có spread 6.98 bps. Nhà đầu tư phải vượt qua khoảng chênh lệch này hai lần: một lần khi vào lệnh và một lần khi thoát lệnh. Vì vậy, chi phí của một vòng giao dịch vào khoảng gấp đôi con số được hiển thị, chưa tính hoa hồng.

Thời điểm giao dịch cũng quan trọng không kém việc chọn mã. Bảng tiếp theo chọn một trong các mã đó và đo quãng đường giá di chuyển trong một phút, sau đó tính trung bình theo các khung nửa giờ trong cùng ngày.

Truy vấnGiá di chuyển bao xa trong một phút: KO, theo giờ New York, ngày 17/6/2026
Câu lệnh SQL chính xác đằng sau mỗi con số
SELECT
    formatDateTime(
        toStartOfInterval(toTimeZone(window_start, 'America/New_York'), INTERVAL 30 MINUTE),
        '%H:%i')                                                                 AS et_time,
    round(avg((toFloat64(high) - toFloat64(low)) / toFloat64(close)) * 10000, 1)  AS range_bps
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'KO'
  AND window_start >= toDateTime('2026-06-17 12:00:00', 'UTC')
  AND window_start <  toDateTime('2026-06-17 21:00:00', 'UTC')
  AND volume > 0
  AND close > 0
GROUP BY et_time
ORDER BY et_time
Run this yourself

Bảng bắt đầu tại 08:00, trước phiên giao dịch chính thức. Khi đó, biên độ di chuyển trung bình trong mỗi phút là 0 bps: các phút có phát sinh giao dịch đều chỉ ghi nhận một mức giá. Khung cuối cùng, 16:30, nằm sau giờ đóng cửa và có mức trung bình 4.2 bps. Backtest chọn một điểm trong mỗi khoảng dao động đó và xem đó là giá khớp lệnh. Hãy đọc cả đường cong thay vì chỉ nhìn các điểm đầu và cuối: cùng một giả định có thể có lợi ở một số giờ nhưng bất lợi ở những giờ khác. Quy định đối với cổ phiếu A cũng làm tăng tác động này, vì T+1 khiến cổ phiếu mua hôm nay không thể được bán cho đến phiên kế tiếp, còn biên độ giá hằng ngày có thể khiến một lệnh thoát theo mô hình hoàn toàn không thể thực hiện. Phần hướng dẫn của chúng tôi về một backtest có thể tái lập cho thấy một thiết lập có cơ sở cần ghi nhận những gì; còn sai lệch nhìn trước dữ liệu trình bày một cách khác khiến đường cong trông đẹp nhưng trở nên sai lệch.

Điều chỉnh hay không điều chỉnh: vấn đề về nguồn dữ liệu

Các hành động doanh nghiệp là nơi một screener có thể âm thầm gây hiểu nhầm. Một cổ phiếu chia theo tỷ lệ ten-for-one sẽ ghi nhận mức giảm 90% trong ngày chia, dù không nhà đầu tư nào mất một xu. Bảng dưới đây liệt kê twelve đợt forward split lớn nhất trên các mã niêm yết tại Mỹ trong giai đoạn từ ngày 1 tháng 1 đến ngày 13 tháng 8 năm 2026.

Truy vấnMười hai đợt forward stock split lớn nhất trên các mã niêm yết tại Mỹ, từ 1/1 đến 13/8/2026
Câu lệnh SQL chính xác đằng sau mỗi con số
SELECT
    ticker                                                            AS symbol,
    formatDateTime(execution_date, '%b %e, %Y')                       AS effective_on,
    round(any(toFloat64(split_to)) / any(toFloat64(split_from)), 2)   AS shares_after_per_share
FROM global_markets.stocks_splits
WHERE execution_date >= toDate('2026-01-01')
  AND execution_date <= toDate('2026-08-13')
  AND split_from > 0
  AND split_to > split_from
  AND ticker NOT IN ('SPCX')
GROUP BY ticker, execution_date
ORDER BY shares_after_per_share DESC, execution_date DESC
LIMIT 12
Run this yourself

Đợt lớn nhất biến một cổ phiếu thành 10000 cổ phiếu, có hiệu lực từ Feb 10, 2026. Những tỷ lệ như vậy không phải là mức four-for-one quen thuộc; nguồn dữ liệu corporate action đưa toàn bộ các tỷ lệ vào cùng một cột. Đợt nhỏ nhất trong twelve đợt vẫn biến một cổ phiếu thành 20 cổ phiếu, đủ để khiến biểu đồ không điều chỉnh trông như một cú sập. Một bộ lọc momentum đọc giá thô sẽ đánh dấu tất cả các trường hợp này là sự cố sụt giảm. Các nguồn dữ liệu Trung Quốc cũng gặp vấn đề tương tự theo cách gọi riêng, cung cấp ba phiên bản cho mỗi chuỗi dữ liệu: không điều chỉnh, điều chỉnh theo hướng tương lai và điều chỉnh ngược về quá khứ. Hãy xác định phiên bản nào đã được panel của bạn tải. Lịch sử giá đã điều chỉnh theo split trình bày cách tính.

Cần kiểm tra gì trước khi tự lưu trữ các công cụ tương tự

  • Nguồn gốc dữ liệu. Dữ liệu do nhà cung cấp nào cung cấp, theo giấy phép nào, và gói miễn phí có bao phủ đúng mục đích sử dụng của bạn hay không.
  • Quản lý API key. API key được lưu ở đâu trên ổ đĩa, ai có thể truy cập trang cài đặt, và máy đó có bị đưa ra ngoài mạng riêng của bạn hay không.
  • Mô hình hóa chi phí. Công cụ backtest có tính phí hoa hồng, trượt giá và các quy tắc riêng của thị trường hay không. Đồng thời, cần biết các trường này được đặt ở mức nào khi bạn để nguyên mặc định.
  • Quy trình cập nhật. Ghi lại chính xác commit đã triển khai cùng với kết quả, để có thể tái lập kết quả sau nhiều tháng.

Câu hỏi thường gặp

Một workbench định lượng A-share tự lưu trữ có miễn phí vận hành không?

Mã nguồn được cấp phép theo MIT và miễn phí. Dữ liệu là vấn đề riêng: khi để trống vendor key, dự án này chuyển sang sử dụng dữ liệu nến ngày lịch sử miễn phí. Dữ liệu của phiên hiện tại sẽ có sau khi thị trường đóng cửa từ một đến two hours. Mọi dữ liệu nhanh hơn hoặc chuyên sâu hơn đều thuộc các gói trả phí của nhà cung cấp.

“Tự lưu trữ” thực sự có nghĩa là gì trong trường hợp này?

Trang web, scheduler, các tệp đã lưu và backtester đều chạy trên máy tính hoặc server của bạn. Bạn không cần tài khoản trên nền tảng của bên khác. Điều đó không có nghĩa dữ liệu thuộc về bạn. Các tính năng AI tùy chọn vẫn chạy từ xa, trừ khi bạn kết nối chúng với một model trên mạng nội bộ của mình.

Tính năng LLM có gửi dữ liệu của tôi cho bên thứ ba không?

Có, khi được bật. Dữ liệu sẽ được gửi đến endpoint tương thích với OpenAI mà bạn cấu hình. Tính năng này mặc định bị tắt. Khi để trống AI key, không có dữ liệu nào rời khỏi máy.

Vì sao nên ghim commit SHA thay vì version tag?

Tính đến ngày 13 tháng 8 năm 2026, repository này chưa có bản phát hành hoặc release notes được công bố. Tag mới nhất còn trỏ đến mã nguồn cũ hơn branch mặc định. Khi đó, “Latest” chỉ có nghĩa là nội dung branch tại ngày bạn clone repository. Trong khi đó, commit SHA xác định chính xác phiên bản. Nguyên tắc này cũng được áp dụng rộng rãi trong tài liệu giao dịch định lượng mã nguồn mở: hãy ghim đúng phiên bản bạn đã chạy.

Ghi chú xác minh

Mọi chi tiết về kiến trúc và cấu hình nêu trên đều được đọc từ repository công khai vào ngày 13 tháng 8 năm 2026, tại commit ecfddb451e97f6fc9a7e43ac33e4ef0e69933b33, là commit đầu branch mặc định và được tạo ngày 6 tháng 8 năm 2026. Trang Releases không có nội dung nào. Danh sách tag gồm 31 version tag từ v0.1.31 đến v0.1.88. Tag mới nhất trỏ đến một commit được tạo ngày 31 tháng 7 năm 2026. Các câu được trích dẫn là nguyên văn của maintainer, lấy từ README thay vì diễn giải. Lệnh khởi động container cũng được trích từ README và chưa được chạy trong bài viết này.

Các bảng thị trường là dữ liệu của các mã niêm yết tại Mỹ, được cố định theo những ngày trong quá khứ để các con số không thay đổi. Mục đích là minh họa hai bước kiểm tra có thể áp dụng cho mọi thị trường: chi phí khớp lệnh và điều chỉnh theo corporate action. Các bảng này không nhằm mô tả thị trường Trung Quốc.


Mỗi bảng trong bài đều đi kèm SQL đã tạo ra bảng đó và có thể mở rộng để xem bên dưới. Để chạy cùng một kiểm tra spread trên danh sách mã của bạn trước khi đưa một mã vào screener, hãy yêu cầu bằng tiếng Anh tự nhiên trên terminal Strasmore.

#open-source#backtesting#screening#a-shares#self-hosted