วิธีสร้างระบบ Quant หุ้น A-share แบบโฮสต์เอง
เจาะลึกการสร้างเครื่องมือวิเคราะห์เชิงปริมาณสำหรับหุ้น A-share บนเครื่องของคุณเอง พร้อมปัจจัยสำคัญสี่ประการที่ต้องตรวจสอบก่อนเริ่มใช้งานจริงในเดือนสิงหาคม 2026 เพื่อความเสถียรของระบบ
เครื่องมือวิเคราะห์เชิงปริมาณสำหรับหุ้น A-share แบบโฮสต์เอง
เครื่องมือวิเคราะห์เชิงปริมาณสำหรับหุ้น A-share แบบโฮสต์เองเป็นหน้าเว็บเดียวที่ใช้คัดกรองตลาด ติดตามรายชื่อหุ้น ดำเนินการทดสอบย้อนหลัง (backtest) และเขียนบทวิเคราะห์หลังปิดตลาด โดยทำงานบนเครื่องที่คุณควบคุมเองแทนที่จะใช้เทอร์มินัลของโบรกเกอร์ โครงการที่ใช้สัญญาอนุญาตแบบ MIT อย่าง tickflow-stock-panel ได้รวบรวมฟังก์ชันทั้งหมดนี้ไว้ภายใต้พอร์ตเดียว และมีผู้ให้ดาวบน GitHub ประมาณสองพันแปดร้อยดวง ณ เดือนสิงหาคม 2026 รายการฟีเจอร์เป็นส่วนที่อ่านเข้าใจได้ง่าย แต่ชั้นโครงสร้างเบื้องหลังต่างหากที่เป็นตัวตัดสินว่าระบบเหล่านี้จะยังคงใช้งานได้ในไตรมาสถัดไปหรือไม่
องค์ประกอบของระบบ Quant workbench สำหรับหุ้น A-share ที่โฮสต์ด้วยตนเอง
สถาปัตยกรรมของระบบนี้เรียบง่ายจนสามารถทำความเข้าใจได้โดยไม่ซับซ้อน จากการตรวจสอบโค้ดและเอกสาร ณ เดือนสิงหาคม 2026 ระบบประกอบด้วย:
- หน้าเว็บที่สร้างด้วย React และ TypeScript
- บริการ Python ที่ใช้ FastAPI พร้อมตัวจัดตารางเวลา (scheduler) เพื่ออัปเดตข้อมูลตามช่วงเวลาที่กำหนด
- แหล่งจัดเก็บข้อมูลในเครื่อง: ไฟล์ Parquet บนดิสก์ ซึ่งสืบค้นด้วย DuckDB และประมวลผลด้วย Polars
- เครื่องมือทำ Backtesting คือ vectorbt ซึ่งเชื่อมต่อกับไฟล์เหล่านั้น
- SDK จากผู้ให้บริการข้อมูลที่ดึงราคาหุ้นทุกตัวที่แสดงบนหน้าจอ
โปรดสังเกตสิ่งที่ขาดหายไป ไม่มีส่วนใดใน Stack นี้ที่เชื่อมต่อโดยตรงกับตลาดหลักทรัพย์ หน้าจอทำหน้าที่ประมวลผล ส่วนผู้ให้บริการทำหน้าที่จัดหาข้อมูล คำว่า "โฮสต์ด้วยตนเอง" อธิบายถึงสถานที่ที่โค้ดทำงาน แต่ไม่ได้ระบุถึงแหล่งที่มาของตัวเลข การเป็นเจ้าของข้อมูลราคาดิบเป็นหน้าที่ของเลเยอร์ที่อยู่ด้านล่าง ซึ่งก็คือ local A-share market data lake และสิ่งนี้เองที่ทำให้ทุกส่วนที่อยู่เหนือขึ้นไปสามารถเปลี่ยนทดแทนได้
สิ่งที่ระดับบริการฟรีของแหล่งข้อมูลครอบคลุม
ตัวแปรสภาพแวดล้อมหนึ่งตัวเป็นตัวกำหนดสิ่งที่พาเนลสามารถมองเห็นได้ หากปล่อยคีย์ของผู้ให้บริการว่างไว้ โปรเจกต์จะทำงานในโหมดที่เอกสารเรียกว่า None ซึ่งจะแสดงแท่งราคาแบบรายวันย้อนหลังผ่านจุดเชื่อมต่อข้อมูลฟรี โดยข้อมูลของรอบการซื้อขายปัจจุบันจะปรากฏขึ้นหลังจากตลาดปิดไปแล้วหนึ่งถึงสองชั่วโมง หากกรอกคีย์ดังกล่าวจะสามารถเข้าถึงข้อมูลตามระดับบริการที่ชำระเงิน นี่ถือเป็นระดับบริการฟรีที่ใช้งานได้สำหรับการทำงานแบบสิ้นวัน แต่เป็นข้อจำกัดที่ชัดเจนสำหรับข้อมูลระหว่างวัน ภายใต้เงื่อนไขที่ผู้ให้บริการสามารถเปลี่ยนแปลงได้ทุกเมื่อที่มีการต่ออายุ
ผู้ดูแลโปรเจกต์ได้ระบุถึงข้อตกลงนี้ไว้อย่างตรงไปตรงมาว่า:
โครงการนี้มีไว้เพื่อการศึกษาและการวิจัยเชิงปริมาณเท่านั้น ไม่ถือเป็นคำแนะนำในการลงทุนใดๆ ผลการทดสอบย้อนหลังไม่ได้เป็นตัวแทนของผลตอบแทนในอนาคต
โครงการนี้เป็นโครงการโอเพนซอร์สส่วนบุคคล โดยใช้แหล่งข้อมูล TickFlow ไม่ใช่โครงการอย่างเป็นทางการของ TickFlow
README, shy3130/tickflow-stock-panel, อ่านเมื่อ 13 สิงหาคม 2026
สรุปเป็นภาษาไทยคือ โปรเจกต์นี้มีไว้เพื่อการศึกษาและการวิจัยเชิงปริมาณ โดย "ไม่ถือเป็นคำแนะนำในการลงทุน" ผลการทดสอบย้อนหลังไม่ได้เป็นตัวแทนของผลตอบแทนในอนาคต และเป็น "โครงการโอเพนซอร์สส่วนบุคคล ไม่ใช่ผลิตภัณฑ์อย่างเป็นทางการของ TickFlow" นี่คือบทเรียนที่สำคัญของงานประเภทนี้ การใช้ระบบ Zero-ops ช่วยลดภาระงานด้านปฏิบัติการของคุณ แต่ยังคงทิ้งภาระเรื่องการพึ่งพาไว้ที่เดิม นั่นคือคุณกำลังเช่าข้อมูลจากบริษัทที่ไม่เคยตกลงที่จะสนับสนุนพาเนลนี้ นอกจากนี้ไฟล์ README ยังจำกัดการใช้งานไว้เพียงเพื่อการศึกษาและการวิจัย ในขณะที่ไฟล์ใบอนุญาตเป็นแบบ MIT
เหตุใดจึงควรระบุ commit SHA แทนการใช้หมายเลขเวอร์ชัน
commit SHA คือรหัสลายนิ้วมือความยาวสี่สิบตัวอักษรที่ git กำหนดให้กับการเปลี่ยนแปลงทุกครั้งที่บันทึก รหัสดังกล่าวระบุสถานะที่แน่นอนของโค้ดเพียงสถานะเดียวอย่างถาวร
จากการอ่านข้อมูลเมื่อวันที่ 13 สิงหาคม 2026 พบว่า repository ดังกล่าวไม่มีข้อมูลใด ๆ ในหน้า GitHub Releases แต่มีการระบุ version tag ไว้สามสิบเอ็ดรายการ ตั้งแต่ v0.1.31 ถึง v0.1.88 โดยมีการเว้นช่วงหมายเลขและไม่มีบันทึกกำกับไว้ tag ล่าสุดชี้ไปยัง commit เมื่อวันที่ 31 กรกฎาคม 2026 ในขณะที่ default branch ได้ดำเนินการต่อไปจนถึงงานของวันที่ 6 สิงหาคม 2026 การใช้ tag ที่ล้าหลังกว่า branch และไม่มีบันทึกกำกับไม่สามารถบอกได้ว่าคุณกำลังได้รับสิ่งใด
ดังนั้น ให้จดบันทึก SHA ไว้ head ของ default branch ณ วันที่ 6 สิงหาคม 2026 คือ ecfddb451e97f6fc9a7e43ac33e4ef0e69933b33 ให้ตรวจสอบ commit นั้นและบันทึกไว้ข้างข้อสรุปใด ๆ ที่คุณได้จากการทำ backtest เมื่อเวลาผ่านไปหกสัปดาห์ คำกล่าวที่ว่า "ฉันรันเวอร์ชันล่าสุดแล้ว" จะไม่สามารถอธิบายรายละเอียดใด ๆ ได้เลย
ขั้นตอนเริ่มต้นที่ระบุไว้มีสองบรรทัด คือคัดลอกไฟล์ตัวอย่าง environment ไปที่ .env จากนั้นรัน docker compose up --build ซึ่งจะเปิดใช้งาน panel บน port 3018 คำสั่งเหล่านี้เป็นคำแนะนำของผู้ดูแลระบบ ณ commit นั้น มากกว่าจะเป็นเส้นทางที่ผ่านการทดสอบแล้ว เนื่องจากกระบวนการ build จะดึง image และต้องการการเข้าถึงเครือข่ายซึ่งหน้านี้ยังไม่ได้ดำเนินการ ส่วนเส้นทางการพัฒนา (./dev.sh หรือ .\dev.ps1 บน Windows) ต้องการ Python 3.11 หรือใหม่กว่า, Node 20 หรือใหม่กว่า และตัวจัดการแพ็กเกจ uv และ pnpm
สิ่งที่ฟีเจอร์กลยุทธ์ LLM ส่งออกไป และปลายทาง
การสร้างกลยุทธ์ บทวิเคราะห์หุ้นรายตัว และการเขียนสรุปผลการทบทวนเป็นทางเลือกเสริม หากเว้นว่าง AI_API_KEY ไว้ ส่วนแสดงผลทั้งหมดจะยังคงปิดอยู่ แต่หากกรอกข้อมูลลงไป คุณจะต้องตั้งค่า AI_PROVIDER (endpoint ที่รองรับ OpenAI หรือ Ollama), AI_BASE_URL, AI_MODEL และ AI_DAILY_TOKEN_BUDGET ซึ่งจะหยุดการเรียกใช้งานทันทีเมื่อโควตาโทเค็นประจำวันถูกใช้จนหมด
ทิศทางการรับส่งข้อมูลมีความสำคัญ คำสั่ง (prompt) ของคุณและบริบทใดก็ตามที่พาเนลแนบไปด้วย จะถูกส่งออกจากเครื่องของคุณไปยัง endpoint ที่คุณกำหนดไว้ หากคุณชี้ base URL ไปยัง API ที่โฮสต์ไว้ภายนอก คำขอจะถูกส่งไปยังบริษัทนั้น แต่หากคุณชี้ไปยัง runtime บนเครือข่ายของคุณเอง ข้อมูลก็จะอยู่ภายใน การโฮสต์พาเนลด้วยตนเองไม่ได้หมายความว่าเป็นการโฮสต์ตัวโมเดลด้วยตนเอง คีย์ต่างๆ จะถูกเก็บไว้ในรูปแบบข้อความธรรมดาใน .env ที่รูทของโปรเจกต์ และยังสามารถแก้ไขได้จากหน้าการตั้งค่า ซึ่งอยู่หลังรหัสผ่านแดชบอร์ดที่มีความยาวขั้นต่ำหกตัวอักษร หมายเหตุของเราใน ปัจจัยอัลฟาที่สร้างโดย LLM ครอบคลุมถึงจุดที่กลยุทธ์ที่เขียนโดยเครื่องมักจะเกิดข้อผิดพลาด
Does the backtester model trading costs?
The backtester advertises T+1 handling, commissions, slippage and stop-losses. Those switches existing is not the same as those switches being set, and a backtest that fills at the printed close with costs at zero is a claim that trading is free. It is not. A basis point is one hundredth of one percent. The panel below measures the average gap between the best bid and the best offer, in basis points, across six US listings over one midday hour on 17 June 2026.
SQL เบื้องหลังตัวเลขแต่ละตัว
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_bpsThe tightest name in the panel, SPY, quoted an average 0.29 bps over that hour. The widest, F, quoted 6.98 bps. Cross that gap twice, once to get in and once to get out, and the round trip costs about double the figure shown, before commissions.
Timing costs as much as naming. The next panel takes one of those listings and measures how far its price traveled inside a single minute, averaged into half-hour buckets across the same day.
SQL เบื้องหลังตัวเลขแต่ละตัว
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_timeThe panel opens at 08:00, before the regular session, where the average minute bar measured 0 bps of travel: the minutes that traded at all sat on a single price. The last bucket, 16:30, sits after the close and averaged 4.2 bps. A backtest picks one point out of each of those ranges and calls it the fill. Read the curve rather than the endpoints: the same assumption is generous in some hours and punitive in others. A-share rules add their own weight, since T+1 keeps shares bought today from being sold until the next session, and daily price limits can remove a modeled exit entirely. Our walkthrough of a reproducible backtest shows what a defensible setup records, and look-ahead bias covers the other way a clean-looking curve goes wrong.
จะปรับปรุงหรือไม่ปรับปรุง: คำถามเรื่องที่มาของข้อมูล
Corporate action คือจุดที่เครื่องมือคัดกรองหุ้นมักทำให้เกิดความเข้าใจผิดโดยไม่รู้ตัว หุ้นที่แตกพาร์ในอัตราสิบต่อหนึ่งจะแสดงราคาลดลงร้อยละเก้าสิบในวันนั้น ทั้งที่ไม่มีใครสูญเสียเงินแม้แต่เซนต์เดียว ตารางด้านล่างแสดงรายการการแตกหุ้น (forward split) ที่ใหญ่ที่สุดสิบสองรายการในตลาดหุ้นสหรัฐฯ ระหว่างวันที่ 1 มกราคม ถึง 13 สิงหาคม 2026
SQL เบื้องหลังตัวเลขแต่ละตัว
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รายการที่ใหญ่ที่สุดเปลี่ยนหุ้นหนึ่งหุ้นให้เป็น 10000 หุ้น โดยมีผลตั้งแต่วันที่ Feb 10, 2026 อัตราส่วนขนาดนี้ไม่ใช่การแตกหุ้นสี่ต่อหนึ่งแบบทั่วไป ข้อมูล corporate action จะรวมทุกอัตราส่วนไว้ในคอลัมน์เดียว รายการที่เล็กที่สุดในสิบสองรายการนี้ยังคงเปลี่ยนหุ้นหนึ่งหุ้นให้เป็น 20 หุ้น ซึ่งเพียงพอที่จะทำให้กราฟที่ไม่ได้ปรับปรุงราคาดูเหมือนการพังทลายของราคาหุ้น เครื่องมือคัดกรองหุ้นตามโมเมนตัมที่อ่านราคาดิบจะระบุว่าหุ้นเหล่านี้ทั้งหมดเป็นหุ้นที่ราคาดิ่งลง ข้อมูลจากจีนก็ประสบปัญหาเดียวกันในรูปแบบของตนเอง โดยมีการส่งข้อมูลสามรูปแบบสำหรับทุกซีรีส์ ได้แก่ แบบไม่ปรับปรุง แบบปรับปรุงไปข้างหน้า และแบบปรับปรุงย้อนหลัง ผู้ใช้งานต้องทราบว่าตารางของคุณโหลดข้อมูลประเภทใดมา ประวัติราคาที่ปรับปรุงผลจากการแตกหุ้น จะอธิบายรายละเอียดเกี่ยวกับการคำนวณดังกล่าว
สิ่งที่ควรตรวจสอบก่อนการติดตั้งใช้งานด้วยตนเอง (Self-host)
- ที่มาของข้อมูล (Data provenance): ตรวจสอบว่ามาจากผู้ให้บริการรายใด ภายใต้ใบอนุญาตประเภทใด และระดับการใช้งานฟรีครอบคลุมวัตถุประสงค์ที่คุณต้องการหรือไม่
- การจัดการกุญแจ (Key handling): ตรวจสอบว่า API keys ถูกจัดเก็บไว้ที่ตำแหน่งใดในดิสก์ ใครสามารถเข้าถึงหน้าการตั้งค่าได้บ้าง และเครื่องคอมพิวเตอร์มีการเชื่อมต่อออกสู่ภายนอกเครือข่ายส่วนตัวของคุณหรือไม่
- การสร้างแบบจำลองต้นทุน (Cost modelling): ตรวจสอบว่าระบบ backtester มีการคำนวณค่าคอมมิชชั่น ค่า slippage และกฎเกณฑ์ของตลาดรวมอยู่ด้วยหรือไม่ รวมถึงตรวจสอบค่าเริ่มต้นในช่องเหล่านั้นว่าแสดงผลอย่างไรเมื่อคุณไม่ได้ปรับเปลี่ยน
- เส้นทางการอัปเดต (The update path): บันทึกเลข commit ที่คุณติดตั้งใช้งานจริงไว้คู่กับผลลัพธ์ เพื่อให้สามารถทำซ้ำกระบวนการเดิมได้อีกครั้งในอีกหลายเดือนข้างหน้า
คำถามที่พบบ่อย
การใช้งาน quant workbench สำหรับหุ้น A-share แบบโฮสต์เองมีค่าใช้จ่ายหรือไม่?
โค้ดดังกล่าวอยู่ภายใต้สัญญาอนุญาต MIT และใช้งานได้ฟรี ส่วนข้อมูลเป็นอีกประเด็นหนึ่ง หากเว้นว่างช่องใส่กุญแจของผู้ให้บริการไว้ โปรเจกต์นี้จะดึงข้อมูลย้อนหลังแบบรายวันฟรี โดยข้อมูลของรอบการซื้อขายปัจจุบันจะมาถึงหลังจากตลาดปิดหนึ่งถึงสองชั่วโมง หากต้องการข้อมูลที่รวดเร็วหรือละเอียดกว่านั้น จะต้องใช้งานผ่านระดับบริการแบบชำระเงินของผู้ให้บริการ
คำว่าโฮสต์เอง (self-hosted) ในที่นี้หมายความว่าอย่างไร?
หน้าเว็บ ตัวจัดตารางเวลา ไฟล์ที่จัดเก็บ และระบบ backtester ทั้งหมดจะทำงานบนเครื่องหรือเซิร์ฟเวอร์ของคุณเอง โดยไม่ต้องมีบัญชีบนแพลตฟอร์มของผู้อื่น แต่ไม่ได้หมายความว่าข้อมูลนั้นเป็นของคุณ และฟีเจอร์ AI ที่เป็นตัวเลือกเสริมจะยังคงทำงานผ่านระบบทางไกล เว้นแต่คุณจะกำหนดให้เชื่อมต่อกับโมเดลที่อยู่บนเครือข่ายของคุณเอง
ฟีเจอร์ LLM ส่งข้อมูลของฉันไปยังบุคคลที่สามหรือไม่?
เมื่อเปิดใช้งาน ข้อมูลจะถูกส่งไปยัง endpoint ที่รองรับ OpenAI ตามที่คุณกำหนดค่าไว้ ฟีเจอร์นี้จะถูกปิดไว้เป็นค่าเริ่มต้น หากไม่ใส่กุญแจ AI ก็จะไม่มีข้อมูลใดออกจากเครื่องของคุณ
ทำไมต้องระบุ commit SHA แทนที่จะใช้ version tag?
ณ วันที่ 13 สิงหาคม 2026 คลังข้อมูลนี้ยังไม่มีการเผยแพร่ release หรือบันทึกประจำรุ่น และ tag ล่าสุดยังชี้ไปยังโค้ดที่เก่ากว่าสาขาหลัก (default branch) ดังนั้นคำว่า "ล่าสุด" จึงหมายถึงสิ่งที่อยู่ในสาขา ณ วันที่คุณโคลนข้อมูลมา ในขณะที่ commit SHA มีความแม่นยำกว่า หลักการเดียวกันนี้ถูกนำมาใช้กับ สื่อการเรียนรู้ด้าน quant trading แบบ open-source โดยทั่วไป คือให้ระบุเวอร์ชันที่คุณใช้งานจริง
บันทึกการตรวจสอบ
รายละเอียดด้านสถาปัตยกรรมและการกำหนดค่าทั้งหมดข้างต้นถูกอ่านจากคลังข้อมูลสาธารณะเมื่อวันที่ 13 สิงหาคม 2026 ที่ commit ecfddb451e97f6fc9a7e43ac33e4ef0e69933b33 ซึ่งเป็นส่วนหัวของสาขาหลัก ลงวันที่ 6 สิงหาคม 2026 หน้า Releases ไม่มีการระบุข้อมูลใด ๆ รายการ tag มีทั้งหมด 31 รายการ ตั้งแต่ v0.1.31 ถึง v0.1.88 โดยรายการล่าสุดชี้ไปยัง commit ที่ลงวันที่ 31 กรกฎาคม 2026 ข้อความที่ยกมาเป็นข้อความของผู้ดูแลระบบเอง ซึ่งคัดลอกมาจากไฟล์ README ไม่ใช่การเรียบเรียงใหม่ คำสั่งเริ่มการทำงานของ container อ้างอิงจากไฟล์ README ดังกล่าวและไม่ได้ถูกนำมาดำเนินการในที่นี้
แผงข้อมูลตลาดเป็นรายการหุ้นในสหรัฐฯ ซึ่งถูกตรึงไว้กับวันที่ในอดีตเพื่อให้ตัวเลขคงที่ ข้อมูลเหล่านี้มีไว้เพื่อสาธิตการตรวจสอบสองประการที่ใช้ได้กับทุกตลาด ได้แก่ ต้นทุนการซื้อขาย (execution cost) และการปรับปรุงรายการจากเหตุการณ์องค์กร (corporate-action adjustment) ไม่ใช่เพื่ออธิบายตลาดจีนแต่อย่างใด
แผงข้อมูลทุกรายการที่นี่มาพร้อมกับคำสั่ง SQL ที่ใช้สร้างข้อมูล ซึ่งสามารถขยายดูได้ด้านล่าง หากต้องการตรวจสอบ spread แบบเดียวกันกับรายชื่อหุ้นของคุณเองก่อนที่จะนำไปใส่ในเครื่องมือคัดกรองหุ้น (screener) สามารถสอบถามได้ด้วยภาษาอังกฤษทั่วไปผ่านเทอร์มินัล Strasmore