Skip to main content

使用富果行情 API 結合 LINE Notify 實現到價提醒服務

· 13 min read
Kevin Wang

股票市場瞬息萬變,您是一個無法時常盯盤的投資人嗎?透過「到價提醒」的設置,當滿足設定的條件時,可以讓您在第一時間獲得通知,進而決定是否拋售表現不佳的個股,或者買進未來更看好的公司。本文將說明如何使用富果 Realtime API 並結合 LINE Notify 服務,打造一個屬於自己的到價提醒通知。

什麼是 LINE Notify?

LINE Notify 是 LINE 提供的免費服務,它是一個特殊的 LINE 官方帳號,只要與服務提供者完成連動後,就可以透過 LINE Notify 發送通知給使用者。不過,仍有以下限制需要注意:

  • 一個有效的個人存取權杖每小時最多能發送 1000 則訊息。
  • 發送的文字訊息不可以超過 1000 個字元。
  • 訊息格式只允許文字、圖片和基本貼圖。

事前準備

在開始進行實作之前,我們必須先取得 富果行情 API 金鑰 以及 LINE Notify 個人存取權杖

圖解:取得富果行情 API 金鑰

STEP 1:前往富果帳戶開發者網站首頁(developer.fugle.tw),點選「文件」→「行情」。

圖1

STEP 2:跳轉頁面後,點選「金鑰申請」。

圖2

STEP 3:「金鑰申請及管理」頁面下,即可新增行情 API 金鑰。

圖3

取得 API token 後,就可以使用 富果即時行情 API。在開發者方案下,日內行情、行情快照與歷史行情 API 每分鐘可以請求 600 次;WebSocket API 可以訂閱 300 檔股票,並且可同時有 2 個連線數。基本上可以滿足一般用戶的需要。

圖解:取得 LINE Notify 存取權杖

STEP 1:前往 LINE Notify 首頁(notify-bot.line.me),登入你的 LINE 帳號後,點選「個人頁面」。

圖4

STEP 2:跳轉頁面後,選擇「發行權杖」。

圖5

STEP 3:接著會跳出一個表單視窗。請填寫權杖名稱,然後接收通知的聊天室請選擇「透過1對1聊天接收Line Notify的通知」,然後點選「發行」。

圖6

STEP 4:LINE Notify 將產生你的個人存取權杖 (Access Token)。因為這段代碼只會出現一次,請務必記住這組權杖代碼。

圖7

STEP 5:完成後,在「連動的服務」清單裡,就會出現我們剛剛所設定的服務。

圖8

info

LINE Notify 授權是基於 OAuth 2.0 的授權碼(Authorization Code)模式,如果我們的應用程式是提供給他人使用時,就需要先取得該使用者的授權。因為我們使用 LINE Notify 訊息推播的對象是自己,所以不需要走這個授權流程,這裡我們直接選擇「發行權杖」即可。

實戰!到價提醒通知

以下我們以 Node.js 為例,手把手教您如何實作出一個基本的到價提醒功能。

安裝套件

為了方便存取 Fugle Realtime API 以及 LINE Notify,我們主要會使用到 @fugle/marketdata 以及 line-notify-sdk 套件。請確認已經安裝 Node.js 開發環境,並在 Terminal 執行以下指令:

$ npm install --save @fugle/marketdata line-notify-sdk dotenv js-yaml luxon numeral

主程式

我們將使用 Node.js 及一些相關的套件和模組來實現這個到價提醒功能。以下是程式碼的主要結構和流程:

'use strict'

// 引入所需的套件和模組
require('dotenv').config();
const fs = require('fs');
const yaml = require('js-yaml');
const notifySDK = require('line-notify-sdk');
const numeral = require('numeral');
const { DateTime } = require('luxon');
const { WebSocketClient } = require('@fugle/marketdata');

// 獲取環境變數設定
const apiKey = process.env.FUGLE_MARKETDATA_API_KEY;
const token = process.env.LINE_NOTIFY_ACCESS_TOKEN;

// 主要邏輯執行區塊
async function main() {
try {
// 讀取設定檔
const config = yaml.load(fs.readFileSync('./config.yml', 'utf8'));
const alerts = new Map(Object.entries(config.alerts));

// 建立 LINE Notify 服務和富果行情 API 的 WebSocket 連接
const notify = new notifySDK();
const client = new WebSocketClient({ apiKey });
const stock = client.stock;

// 監聽行情資料變化
if (alerts.size) {
const symbols = Array.from(alerts.keys());
await stock.connect();
stock.subscribe({ channel: 'aggregates', symbols });

stock.on('message', (message) => {
const { event, data } = JSON.parse(message);
if (event === 'data') checkMatches(data);
});
}

// 檢查符合條件的行情資料
function checkMatches(data) {
// 擷取行情資料中的相關數據
const { symbol, lastTrade, lastUpdated } = data;
if (lastTrade?.time !== lastUpdated) return;

// 檢查符合條件的監控股票
const alert = alerts.get(symbol);
if (!alert) return;

// 根據監控條件進行判斷
const compare = {
'>': (value, target) => value > target,
'>=': (value, target) => value >= target,
'=': (value, target) => value === target,
'<=': (value, target) => value <= target,
'<': (value, target) => value < target,
};

// 符合條件時,發送通知
if (alert.type === 'price' && compare[alert.comparator](lastTrade.price, alert.target)) {
sendAlert(alert, data);
}
}

// 發送通知
function sendAlert(alert, data) {
// 擷取相關數據
const { symbol, name, lastPrice, change, changePercent, lastUpdated } = data;

// 格式化時間
const time = DateTime
.fromMillis(Math.floor(lastUpdated / 1000))
.toFormat('yyyy/MM/dd HH:mm:ss');

// 建構通知內容
const message = [''].concat([
`<<${alert.title}>>`,
`${alert.message}`,
`---`,
`${name} (${symbol})`,
`成交: ${numeral(lastPrice).format('0.00')}`,
`漲跌: ${numeral(change).format('+0.00')} (${numeral(changePercent).format('+0.00')}%)`,
`時間: ${time}`,
]).join('\n');

// 發送 LINE Notify 通知
notify.notify(token, message)
.then(() => console.log(message))
.catch((e) => console.log(e));

// 從監控清單中刪除該股票
alerts.delete(symbol);
}
} catch (e) {
console.log(e)
}
}

// 執行主要邏輯
main();

實作細節

讓我們逐一解釋這段程式碼的實作細節:

  1. 引入套件和模組

程式碼一開始使用 require 關鍵字引入所需的套件和模組。這些套件和模組包括 dotenvfsjs-yamlline-notify-sdknumeralluxon`` 和 @fugle/marketdata`。這些套件和模組提供了讀取環境變數、操作檔案、解析 YAML 格式、與 LINE Notify 服務互動、格式化數字、處理日期和時間以及連接富果行情 API 的能力。

  1. 獲取環境變數設定

這段程式碼使用 process.env 物件從環境變數中讀取富果行情 API 金鑰和 LINE Notify 存取權杖。環境變數的設定可以在專案目錄下新增 .env 檔案中設定:

FUGLE_MARKETDATA_API_KEY=
LINE_NOTIFY_ACCESS_TOKEN=

然後透過 dotenv 套件來讀取 .env 檔案並將其設定載入到程式中。

  1. 主要邏輯執行區塊

主要的邏輯執行區塊是 main 函式,它使用 async/await 來聲明為非同步函式。程式的進入點在 main() 的呼叫。

main() 函式中,首先從檔案系統中讀取設定檔 config.yml。這個設定檔設定了你所要監控股票的條件,可以包含一個或多個。例如:

---
alerts:
2330:
title: 到價提醒
message: 台積電突破600元
type: price
comparator: ">"
target: 600

設定檔 config.yml 透過使用 yaml.load() 方法將其解析為 JavaScript 物件。然後,建立一個 Map 物件來存儲從設定檔中獲取的股票價格監控條件。

接下來,建立 LINE Notify 服務的客戶端實體 notify 和富果行情 API 的 WebSocket 連接客戶端物件 client,並且從中取得表示台股市場資料的 stock 物件。

如果有監控條件,則進行 WebSocket 連接、訂閱股票市場資料、並監聽市場資料的變化。當收到市場資料變化的訊息時,解析訊息並檢查是否符合監控條件,如果符合則呼叫 checkMatches() 函式。

checkMatches() 函式用於檢查市場資料是否符合監控條件。它擷取市場資料中的相關數據,例如股票代號、最後交易價格和最後更新時間。接著,根據監控條件中的股票代號和監控股價的目標值,檢查最後交易價格是否符合條件。如果符合條件,則呼叫 sendAlert() 函式發送通知。

sendAlert() 函式用於發送 LINE Notify 通知。它從市場資料中獲取相關數據,並使用 luxon 函式庫將最後更新時間轉換為指定格式的時間字串。然後,建立通知的內容字串,包括標題、訊息和股票資訊等。最後,使用 LINE Notify 服務的 notify.notify() 方法發送通知,並在成功或失敗時輸出相關訊息。完成通知後,從監控清單中刪除該股票。

  1. 錯誤處理

程式碼使用 try/catch 塊來捕獲可能發生的錯誤,並輸出錯誤訊息。如果有錯誤發生,將錯誤訊息輸出到控制台。

  1. 執行主要邏輯

最後,在程式碼的最後,呼叫 main() 函式開始執行主要的邏輯。這將觸發程式的運行,連接富果行情 API 的 WebSocket 服務並開始監控股票價格的變化。如果符合監控條件,則會透過 LINE Notify 發送通知。

執行程式

完成程式撰寫後,我們可以在終端機執行以下指令啟動應用程式:

$ node app.js

如果盤中到達你所設定的警示條件,程式就會透過 LINE Notify 即時發送通知。

圖9

關於完整的程式碼,請參考我們的在 GitHub 上的 範例程式儲存庫

結語

在本篇文章中,我們介紹了使用 Node.js 實作一個股價監控程式,並且實現透過 LINE Notify 服務發送通知的功能。這個程式使用富果行情 API 提供的股票市場資料,透過 WebSocket 進行即時監控。當符合特定條件的股票價格變動發生時,程式會使用 LINE Notify 服務發送即時通知。

這個程式提供了一個靈活的框架,可以根據自己的需求進行擴展和定製。你可以根據不同的監控條件來設定股票價格的觸發條件,以滿足自己的需求。

希望這篇文章對於理解如何使用富果行情 API 監控股價有幫助。透過富果行情 API,你可以打造屬於自己的股市小幫手。祝你在投資和交易中取得成功!