這是個啥
背景故事很簡單:作為一個日常關注行情的“韭菜”,我有一個不太高效的習慣——同時打開無數個看盤軟件和網頁,在混亂的窗口切換中迷失自我,最終收穫的往往只有焦慮,外加瀏覽器那令人窒息的標籤頁堆疊。為了徹底治癒這種低效,我決定動手打造一個專屬工具:在一個頁面內集成所有高頻功能,涵蓋實時行情、板塊動態、分時走勢、K 線分析、資金流向以及篩選器。
這就誕生了 stock-dashboard:一個完全基於 React + TypeScript + Vite 技術棧的前端大屏。所有數據直接由 stock-sdk 驅動,這意味着項目完全摒棄了後端服務,不需要運行任何 Python 定時任務,也不依賴什麼“神秘朋友的高端服務器”。純前端直連數據源,所見即所得,一切都安排得井井有條。
直接上在線演示鏈接:stock-dashboard (友情提示:摸魚期間請謹慎使用,建議配合小窗口模式)。

核心解密:數據層架構設計
為了保持代碼整潔,我將所有針對 stock-sdk 的調用邏輯都封裝在了 src/services/sdk.ts 中。
這裏主要實施了三個既實用又不矯情的工程化策略:
-
全局單例與自動重試機制
通過new StockSDK({ timeout, retry })初始化實例。面對網絡波動或接口偶爾抽風的情況,SDK 內置的自動重試機制(支持最大 3 次重試及指數退避算法)能完美兜底。 -
智能內存緩存(TTL 策略)
對於行業或概念列表這類變動頻率極低的數據(畢竟它們不會在幾秒內發生劇變),直接上緩存減少無效請求;而對於實時行情,則設置了 2~3 秒的生存期(TTL),既保證了數據的時效性,又避免了無意義的高頻請求轟炸接口。 -
分層隔離:頁面僅對接服務層
翻閲src/pages/**下的代碼,你幾乎找不到new StockSDK()的身影。UI 層只負責調用諸如getFullQuotes / getTodayTimeline / getKlineWithIndicators等經過二次封裝的業務方法,而類型定義則直接複用stock-sdk的導出。
順便展示兩段核心代碼骨架,後續的所有功能模塊皆構建於此基礎之上:
// src/services/sdk.ts
export const sdk = new StockSDK({ timeout: 30000, retry: { maxRetries: 3, baseDelay: 1000, maxDelay: 10000, backoffMultiplier: 2 } });
export async function getFullQuotes(codes: string[], useCache = true) {
const key = getCacheKey('getFullQuotes', codes);
if (useCache) {
return withCache(key, DEFAULT_TTL.quotes, () => sdk.getFullQuotes(codes));
}
return sdk.getFullQuotes(codes);
}
// src/services/sdk.ts
export async function getAllAShareQuotes(options?: { batchSize?: number; concurrency?: number; onProgress?: (completed: number, total: number) => void }) {
return sdk.getAllAShareQuotes(options);
}
功能拆解:各模塊如何玩轉 stock-sdk 數據?
路由配置位於 src/router/index.tsx,而各個功能頁面則模塊化地分佈在 src/pages/* 目錄下。接下也就是大家最關心的——按“用户交互路徑”來逐一覆盤。
1) 全局搜索:告別手動翻代碼的痛苦
搜索欄組件位於 src/components/layout/Header.tsx,其背後的魔法僅需一行代碼:
search(keyword)映射到stock-sdk的sdk.search(keyword)
為了優化體驗,我添加了 300ms 的輸入防抖處理。搜索結果完美支持個股與板塊的混合查詢,點擊即達:
- 行業板塊跳轉至:
/boards/industry/:code - 概念板塊跳轉至:
/boards/concept/:code - 個股詳情跳轉至:
/s/:code
順手還利用 localStorage 實現了一個簡單的歷史記錄功能(src/services/storage.ts),畢竟很多時候,我們尋找的不是新標的,而是昨天沒看完的那個它。
2) 儀表盤 Dashboard:行情概覽與自選速覽
對應頁面文件:src/pages/Dashboard/Dashboard.tsx。
數據獲取邏輯非常直白粗暴:
- 指數行情:調用
getFullQuotes(MAIN_INDICES)一次性獲取上證、深成指、科創 50 等關鍵指數。 - 板塊概況:並行調用
getIndustryList()和getConceptList()。 - 自選股預覽:先從存儲服務
src/services/storage.ts讀取自選列表,再通過getFullQuotes(watchlistCodes.slice(0, 50))批量獲取前 50 只行情的快照。
為了保證數據的鮮活度,配合 usePolling Hook(src/hooks/usePolling.ts)實現了每 5 秒自動輪詢。貼心的是,當頁面處於後台不可見狀態時,輪詢會自動掛起,絕不浪費你的瀏覽器資源。
額外提一句:目前 Dashboard 上的“榜單”主要展示板塊數據。如果想做全市場的個股排名,技術路徑完全可以參考後面提到的“一日持股法”,也就是直接利用 getAllAShareQuotes 接口。
3) 市場熱力圖 Heatmap:一圖看懂資金流向

實現文件位於 src/pages/Heatmap/Heatmap.tsx,底層依賴 ECharts 的矩形樹圖(Treemap)。
根據觀察視角的不同,數據源也各異:
- 行業視角:直接用
getIndustryList(),因為返回的數據中已經包含了漲跌幅、換手率及領漲股信息。 - 概念視角:同理,調用
getConceptList()。 - 自選視角:獲取所有自選代碼
getAllWatchlistCodes()後,通過getAllQuotesByCodes(codes.slice(0, topK))批量拉取。
至於“全市場個股”熱力圖(代碼預留了接口,暫未開啓),實現邏輯也不復雜:
- 通過
getIndustryConstituents(industryCode)獲取特定板塊成分股。 - 用
getAllQuotesByCodes(stockCodes)把行情數據補齊。 - 最後組裝數據餵給 Treemap 組件。
熱力圖最大的魅力在於:告別枯燥的數字列表,紅綠相間的色塊讓你瞬間洞察市場強弱結構。
4) 龍虎榜 Rankings:觀察市場風向標

頁面路徑:src/pages/Rankings/Rankings.tsx。
實現方式屬於“簡單粗暴且有效”:
- 並行獲取
getIndustryList()和getConceptList()。 - 前端直接根據
changePercent(漲跌幅)或turnoverRate(換手率)進行排序,截取 Top 50。
目前的榜單本質上是“板塊排行榜”。如果未來要擴展到全市場個股排行,技術方案與後文的“選股器”一致。
5) 板塊透視:追蹤領漲先鋒
板塊列表頁位於 src/pages/Boards/Boards.tsx:
getIndustryList()與getConceptList()一把梭。- 所謂的 Tab 切換,僅僅是前端對不同數據源數組的渲染切換。
- 當然也支持按板塊名稱或領漲股進行檢索。
詳情頁見 src/pages/Boards/BoardDetail.tsx,這裏展示了 API 的組合拳能力(按行業/概念分流):
- 基礎信息:直接複用列表數據,減少一次網絡請求。
- 成分股列表:調用
getIndustryConstituents(code)或getConceptConstituents(code)。 - 板塊走勢:拉取
getIndustryKline或getConceptKline。 - 盤口快照:通過
getIndustrySpot或getConceptSpot獲取。
為了保證流暢度,板塊 K 線圖目前只截取了最近 60 根數據,防止縮放圖表時瀏覽器渲染壓力過大。
6) 自選監控 Watchlist:只看我在意的
核心頁面:src/pages/Watchlist/Watchlist.tsx。所有的增刪改查邏輯都封裝在 src/services/storage.ts 中。
行情刷新主要依賴:
getAllQuotesByCodes(normalizedActiveCodes)
特別提一下這裏的細節處理:在請求前我會先通過 normalizeStockCode(位於 src/utils/format.ts)對代碼進行標準化格式化,有效防止了 SZ000001、sz000001 和 000001 這種“一碼多式”造成的去重失敗或數據請求異常。
7) 個股深度分析 StockDetail:全維數據一覽無餘

頁面位置:src/pages/StockDetail/StockDetail.tsx。這是整個項目中承載信息量最大的頁面,因為它聚合了極高密度的信息。
它聚合了多維度的 API 數據:
- 實時報價:
getFullQuotes([code]) - 當日分時圖(1分鐘級):
getTodayTimeline(code) - 分鐘級 K 線(5/15/30/60):
getMinuteKline(code, { period }) - 歷史 K 線(日/周/月)及復權:
getKlineWithIndicators(code, { period, adjust: 'qfq', indicators }) - 資金流向監測:
getFundFlow([code]) - 盤口大單監控:
getPanelLargeOrder([code])
我個人非常推崇 getKlineWithIndicators 這個接口:只需傳入你想要的指標參數(如 MA, MACD, KDJ, RSI, BOLL等),SDK 就能把計算好的指標數據連同 K 線一起返回。前端只需負責繪圖,徹底告別了在前端手寫複雜技術指標計算邏輯的噩夢(少寫代碼 = 少出 Bug = 長命百歲)。
在這裏,輪詢策略也做了精細化分層:
- 基礎行情:2 秒/次
- 分時圖:3 秒/次
- 資金流向:10 秒/次
8) 策略掃描器 Scanner:量化交易的初體驗
頁面:src/pages/Scanner/Scanner.tsx。
掃描邏輯簡述如下:
- 確定股票池:
- 既可以是你的“自選股列表”。
- 也可以是某個板塊的成分股,例如調用
getIndustryConstituents('BK0475')。
- 批量分析:
- 遍歷每隻股票,調用
getKlineWithIndicators獲取帶指標的 K 線數據。
- 遍歷每隻股票,調用
- 信號匹配:
- 前端邏輯判斷最近兩根 K 線是否滿足預設形態(如均線金叉、MACD 金叉、RSI 超買超賣等)。
雖然這個功能帶有一定的“心裏安慰”屬性,但它確確實實把模糊的“看漲感覺”轉化為了可執行的“觸發條件”。
9) 個性化設置 Settings:打造順手的工具

頁面:src/pages/Settings/Settings.tsx。
這個頁面並沒有調用任何 stock-sdk 接口,它的使命是將你的使用偏好(刷新頻率、紅漲綠跌配色、各類指標的默認參數等)持久化保存到 localStorage。這樣,無論何時打開頁面,它都還是那個你最熟悉的樣子。
重頭戲:一日持股策略(尾盤選股)——前端實現的全市場掃描

該功能位於 src/pages/EndOfDayPicker/EndOfDayPicker.tsx。我在這個頁面實現了一套經典的“三步走”選股漏斗,其核心動力源自強大的 getAllAShareQuotes 接口。
第一階段:全量 A 股行情抓取
// src/pages/EndOfDayPicker/EndOfDayPicker.tsx
const quotes = await getAllAShareQuotes({
batchSize: 500,
concurrency: 5,
onProgress: (completed, total) => setLoadingProgress({ completed, total, stage: '數據加載中...' }),
});
這一步調用的是 SDK 的重磅接口:
sdk.getAllAShareQuotes(options?: GetAllAShareQuotesOptions): Promise<FullQuote[]>- 參數
batchSize控制單次批大小(默認 500),concurrency控制併發數(默認 7)。
我採取了相對穩健的策略(併發設為 5),兼顧了瀏覽器的性能負載和網絡穩定性。配合 onProgress 回調,用户能看到實時的進度條反饋,體驗流暢不卡頓,不會誤以為網頁卡死。
第二階段:基礎指標粗篩
拿到全市場 5000+ 只股票的 FullQuote 數據後,我們先進行一輪粗篩(字段直接取自 FullQuote):
- 流通市值 (
circulatingMarketCap) - 量比 (
volumeRatio) - 漲跌幅 (
changePercent) - 換手率 (
turnoverRate) - ST/風險股過濾
這一步邏輯封裝在 filterStocksBasic() 中,通常能把目標池從 5000+ 縮減到幾百甚至幾十只,如果不篩這一刀,後續拉取分時數據會直接把瀏覽器送走。
第三階段:分時圖形態精選
對於粗篩剩下的候選股,我們再進行更細緻的分時圖分析:
- 調用
getTodayTimeline(fullCode)拉取分時數據(注意拼接 sh/sz/bj 前綴)。 - 計算核心強度指標:
timelineAboveAvgRatio(即:現價高於均價的時間佔比,由price和avgPrice對比得出)。
為了防止瀏覽器崩潰,filterWithTimeline() 中手動控制了分時數據請求的併發量(batchSize = 5)。
最終結果按 timelineAboveAvgRatio 降序排列,並在列表中展示迷你的分時走勢圖。這樣一來,尾盤選股的效率直接起飛。
寫在最後:誰需要這個工具?
如果你渴望擁有一個“既能看盤、又能篩股、還能順便管理自選”的輕量級看板,同時極其排斥維護後端服務或編寫複雜的 Python 腳本,那麼這個純前端方案絕對是你的不二之選。核心思路就是利用 stock-sdk 將強大的數據能力引入前端,剩下的就是單純的 UI 組裝與邏輯編排。
本地啓動非常簡單:
yarn install
yarn dev
最後不得不俗套地提醒一句:頁面底部的 disclaimer “僅供學習參考,不構成投資建議”並非擺設。代碼雖可自信敲,投資仍需謹慎行。
傳送門
- 在線看板: https://chengzuopeng.github.io/stock-dashboard/
- SDK 文檔: https://stock-sdk.linkdiary.cn/
- SDK 演練場: https://stock-sdk.linkdiary.cn/playground/