港股api實時行情的時間邊界:一位金融系講師的創業踩坑筆記
一、研究痛點:數據時間與交易時間的混淆
港股並非全天連續交易,開市前、午間休市、收市後都有數據,但狀態不同。我們曾遇過一個案例:早上9:05收到港股api推送的數據,系統卻標記為「連續交易中」,導致基金客戶的風控模組誤報。排查後發現,代碼只寫了簡單的判斷,沒有考慮下午16:00之後的時間,也沒有區分9:00-9:30的競價階段。更麻煩的是,服務器若跑在UTC時區,直接用datetime.now()比較,就會產生系統性偏差。
這些問題的根源在於沒有把「數據時間」和「交易時間」分開。
二、數據需求:定義港股交易時段
我們通常將港股一天拆成以下區間:
時段香港時間程序處理開市前競價09:00–09:30預開市數據上午交易09:30–12:00正常交易午間休市12:00–13:00非連續交易下午交易13:00–16:00正常交易收市後16:00 之後非正常交易
一個常見的錯誤寫法是:
if current_time >= time(9, 30): market_open = True這個寫法沒有限制結束時間,下午17:00也會被判斷成開市。我們後來改為區間判斷:
def is_market_open(t): morning = time(9, 30) <= t < time(12, 0) afternoon = time(13, 0) <= t < time(16, 0) return morning or afternoon這樣邏輯清楚很多。
三、支持:API時間戳的時區標準化
港股api返回的通常是Unix timestamp,例如:
{ "symbol": "00700.HK", "price": 520.5, "timestamp": 1788226200}Unix timestamp本身沒有「香港時間」概念,我們需要先轉換成帶時區的datetime:
from datetime import datetimefrom zoneinfo import ZoneInfotimestamp = 1788226200dt = datetime.fromtimestamp( timestamp, tz=ZoneInfo("Asia/Hong_Kong"))print(dt)這樣即使服務器部署在美國、新加坡或UTC環境,得到的時間都是香港時間。實際接入AllTick API時,我們也先做這層轉換,再進行交易時段判斷和K線聚合。
四、開市前數據不應與連續成交混淆
9:00到9:30雖然有行情數據,但市場仍在競價,不能簡單標記為開市。我們使用狀態來區分:
def get_market_status(t): if time(9, 0) <= t < time(9, 30): return "pre_open" if time(9, 30) <= t < time(12, 0): return "morning" if time(12, 0) <= t < time(13, 0): return "break" if time(13, 0) <= t < time(16, 0): return "afternoon" return "closed"前端可以顯示「開市前」,策略只接受morning和afternoon的數據,避免競價階段的噪聲。
五、跨日期與交易日曆的學術價值
午夜判斷也是常見痛點。例如:
if current_time > time(16, 0): status = "closed"凌晨1點確實會被判為收市後,但如果需要同時判斷「當前交易日」,就必須使用完整的日期時間。我們的經驗是:時間段用datetime.time,交易日用datetime.date,兩者分開維護。香港公眾假期和颱風休市需獨立交易日曆,不能只依賴週一到週五。
實時tick生成1分鐘K線時,邊界更嚴格。09:29:59和09:30:00屬於不同週期,我們採用左閉右開區間:
09:30:00 <= tick_time < 09:31:00
這樣每條tick只進入一個K線週期。
六、可擴展的行情處理流程
我們目前的處理流程如下:
API實時數據 ↓解析 timestamp ↓轉換為 Asia/Hong_Kong ↓判斷交易日期 ↓判斷交易時段 ↓過濾/分類行情 ↓K線聚合或策略計算將交易時段、時區、交易日曆抽成配置,避免在業務代碼中散落09:30、16:00等魔法數字。時間邊界處理看似基礎,卻是行情系統可靠性的第一道關卡。希望這篇筆記能為你提供一些參考。
喜欢我的作品吗?别忘了给予支持与赞赏,让我知道在创作的路上有你陪伴,一起延续这份热忱!