/
CATEGORY
React
/
5. 串接 TradingView 開發的圖表套件,並透過 Server 端呼叫外部的富果 API

5. 串接 TradingView 開發的圖表套件,並透過 Server 端呼叫外部的富果 API

MUKI AI Summary

「股票小特助」第五篇介紹如何串接 TradingView 圖表套件,並透過 Server 端呼叫富果 API。首頁功能包括一年內的大盤指數及台股即時報價。使用富果 API 提供的行情和交易 API,並建議未開戶者使用台灣證券交易所的 openAPI。

使用 TradingView 的 Lightweight Charts 套件,方便地將富果 API 的股市資料轉換成圖表。Next.js 的 Server Components 用於從 Server 端呼叫 API,提高首次繪製速度及 SEO。兩種 API 呼叫方法:'use client' 和 'use server',分別適用於前後端的資料處理與畫面渲染。...

我的「股票小特助」系列文,終於來到了第五篇,要正式開始寫 code 啦!

首頁畫面與功能

首頁預期會長這樣,有兩個功能:

  1. 一年內的大盤指數
    富果 API 撈取資料的範圍,最多就是一年,所以我只能放一年的資料 XD
  2. 台股即時報價
    目前是先撈出當前的所有價格,並且要「手動」點按鈕更新,還沒串 WebSocket
    但在串 WebSocket 之前,會先處理資料,預計加入搜尋、頁碼 ... 等功能。

而今天要分享的,就是首頁上方的圖表,包含我是怎麼用 TradingView 套件製作的,以及怎麼從 client 端 call API 到用 server 端 call 外部 API (富果 API)

富果 API

我使用的股票 API 是富果股市 API,富果 API 分兩塊:

  1. 行情 API
    所有人只要註冊成為富果會員,都能使用
  2. 交易 API
    僅限玉山證券富果帳戶的顧客使用,因為他要串接證券資料。
    如果有想要開戶,歡迎使用我的推薦碼,可以一起賺現金回饋唷:f-03feb04

我的股票小特助會同時用到行情 API 與交易 API,但只要不牽扯到交易,大部分的功能都能用行情 API 解決,所以有興趣的朋友可以直接註冊成為富果會員

如果你沒有富果帳戶也不想開戶的話,可以考慮用台灣證券交易所的 openAPI 串接,但我還是會用富果 API 串接,因此如果你想跟著一起練習,可能要請你自行去對照與選擇台灣證券交易所的 API 了唷 QQ。

使用歷史行情 API 取得一年內的股市資料

我在首頁使用的 API 是 Historical Candles,他可以取得 1 年內的上市櫃歷史股價,富果的文件寫得非常詳細,我這邊就不贅述了,直接跟大家分享我使用的參數與股票代碼。

// API 位置,股票代碼 IX0001
const apiTSEIndexUrl = 'https://api.fugle.tw/marketdata/v1.0/stock/historical/candles/IX0001'

const fetchTSEIndex = async () => {
  try {
    const headers = {
	  'X-API-KEY': { 你的金鑰 },
      'Content-Type': 'application/json'
    }
    const payload = {
      from: '2023-01-01',
      to: '2023-06-30',
      fields: 'open,high,low,close,volume'
    }
    const response = await axios.get(apiTSEIndexUrl, {
      headers: headers,
      params: payload,
    })
    return response.data.data
  } catch (error) {
    console.error('error', error)
  }
}

▼ 用 postman 試打,成功取得資料

使用 TradingView 圖表套件:Lightweight Charts

我之前比較常用 Apache ECharts 圖表套件,但這次要接的是股市資料,所以我就在想,那用 TradingView 提供的圖表套件,會不會不需要太多的設定,就能輕鬆達成我要的圖表資訊呢?

有了這樣的想法,我就決定改用 TradingView 圖表套件試試看,初步試用下來,因為股市資料的格式算通用?所以我從富果 API 拿到的資料,幾乎不需要處理,就能放到 Lightweight Charts 使用,還蠻方便的。不過老實說,Apache ECharts 的文件還是寫得比較清楚,而且還有很多範例可以看 XD

安裝 TradingView Lightweight Charts

▼ 可用 npm 快速安裝,我安裝的版本是 v4.1.1

$ npm install lightweight-charts

▼ 取得股市資料後,用 createChart 初始化圖表,再帶入資料即可

'use client'
import { createChart } from 'lightweight-charts'

const TSE = () => {
  const [tseIndex, setTSEIndex] = useState<any>([])
  
  useEffect(() => {
  	// 取得股市資料
    setTSEIndex(response)
  }, [])
  
  useEffect(() => {
    const parentElement = document.getElementById('TSE') as HTMLElement
    const chartWidth = parentElement.clientWidth
    const chartHeight = parentElement.clientHeight
    
    const chart = createChart(parentElement, {
      width: chartWidth,
      height: chartHeight
    })
    
    const data = tseIndex.map((item) => {
   	  // 這邊要做 key mapping,但不複雜
      return {
        time: item.date,
        open: item.open,
        close: item.close,
        high: item.high,
        low: item.low,
        value: item.close
      }
    }
    data.reverse()
    
    const candlestickSeries = chart.addCandlestickSeries({
      upColor: '#EF5350',
      downColor: '#26A69A',
      borderVisible: false,
      wickUpColor: '#EF5350', 
      wickDownColor: '#26A69A'
    })
    
    candlestickSeries.setData(data)
    
  }, [tseIndex])
  
  return (
    <>
      <div id="TSE"></div>
    </>
  )
}

export default TSE

透過以上程式碼可以發現,處理數據那一段真的簡便很多,也不需要像 Apache ECharts,需要額外寫 function 處理資料

▼ 如果要改成黑底或調整其他的樣式,可以在 createChart() 設定。

改用 Server 端呼叫外部 API

我之所以使用 Next.js 來做 Side Project,就是看中他的 Server Components 功能,我不需要從 Client Call API,資料的事情就交給 Server 端,前端專注處理畫面即可。

接下來要分享的是,我如何把富果的股票 API,改成用 Server 端呼叫

從 Server 端呼叫 API

在 Next.js 裡,我們可以使用 'use client' 以及 'use server' 告訴 Next.js 現在走的是 client component 或是 server component。

你可以往上翻,看到前面我呼叫 api 時的頁面第一行用的是 'use client',表示我用 client component;而現在我要使用的是 'use server'

▼ 在 app 資料夾底下,新增檔案 api/TSE.action.tsx

'use server'

const apiTSEIndexUrl = 'https://api.fugle.tw/marketdata/v1.0/stock/historical/candles/IX0001'

export async function fetchTSEIndex() {
  try {
    const headers = {
      'X-API-KEY': { 你的金鑰 },
      'Content-Type': 'application/json'
    }
    const payload = new URLSearchParams({
      from: '2023-01-01',
      to: '2023-06-30',
      fields: 'open,high,low,close,volume'
    })
    const response = await fetch(`${apiTSEIndexUrl}?${payload}`, {
      headers: headers,
    })
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    const data = await response.json()
    console.log('data', data)
    return data.data
  } catch (error) {
    console.error('API 請求錯誤:', error)
  }
}

關於我改用 fetch() 的原因

我原本是用 axios 呼叫 API,但在 Server 端改成了 fetch()
關於在 Next.js 的 Server Components 該使用 fetch() 還是 axios
我有寫一篇相關文章介紹,歡迎各位參考:用 Next.js 的 Server Components 時,該用 fetch() 還是 axios 呼叫 api?
如有任何錯誤的地方,也請指正我,謝謝 🙏

▼ 再回到一開始的 app/component/TSE.tsx 檔案,將原本呼叫 API 的 function 整個拿掉,改從 server 端撈取

'use client'
import React, { useEffect, useState, useTransition } from 'react'
import { fetchTSEIndex } from '../api/TSE.action'

const TSE = () => {
  const [isPending, startTransition] = useTransition()
  const [tseIndex, setTSEIndex] = useState<any>([])
  
  useEffect(() => {
    startTransition(async () => {
      const response = await fetchTSEIndex()
      setTSEIndex(response)
    })
  }, [])
}

從 fetchTSEIndex 取得資料後,後面的步驟都一樣:將資料處理完成,並用圖表渲染出來

什麼是 useTransition Hook

使用 useTransition 可以幫助我們更新狀態的同時,也不會阻塞 UI 的渲染的。
例如我用了 startTransition() 傳入一個異步函數,而裡面的程式碼在執行時的狀態更新會標記成 transition,這表示,如果 fetchTSEIndex() 的回應比較久,我後面的 UI 渲染也不會被中斷,又或者使用者有各種按鈕點擊行為時,也不會被中斷

從 Server 端取資料的好處

我們讓網站內容先在 Server 端生成,再傳送至 Client 端,可以加快首次繪製的速度 (First Contentful Paint,FCP),並改善 SEO。

另外我們也能在 Next.js 建立 API,所以可以在同個應用程式中,處理前後端的邏輯,可以有效減少開發的複雜性,例如前面所說,後端專注資料處理,前端專注畫面,讓我們提高開發效率。

後記

在這篇文章中,跟大家分享了如何使用 Next.js 和富果 API 來建立一個股票資訊網站,並分享了兩種呼叫 API 的方法:'use client' 以及 'use server',以及 TradingView 的圖表套件:Lightweight Charts 是怎麼接這些資料的。

如果有任何問題或想法,都歡迎留言給我,感謝你的閱讀!

歡迎給我點鼓勵,讓我知道你來過 :)

26
MUKI says:

如果文章有幫助到你,歡迎分享給更多人知道。文章內容皆為 MUKI 本人的原創文章,我會經常更新文章以及修正錯誤內容,因此轉載時建議保留原出處,避免出現版本不一致或已過時的資訊。

本文地址:https://muki.tw/next-js-tradingview-chart-server-api/ 已複製

Subscribe
Notify of
guest

0 則留言
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Copyright © since 2008 MUKI space* / omegaSS theme All Rights Reserved.