使用 Node.js、Express 和 OpenAI API 建立高品質股票報告產生器
在本文中,我們將深入研究使用 Node.js、Express 和 OpenAI API 建立專業級股票報告產生器。我們的重點是編寫高品質、可維護的程式碼,同時保留 OpenAI API 互動中使用的提示訊息的完整性。該應用程式將獲取股票數據,執行情緒和行業分析,並產生全面的投資報告。
目錄
- 專案概況
- 設定環境
- 建立 Express 伺服器
- 取得與處理資料
- 與 OpenAI API 整合
- 產生最終報告
- 測試應用程式
- 結論
項目概況
我們的目標是建立一個 API 端點,為給定的股票代碼產生詳細的投資報告。該報告將包括:
- 公司概況
- 財務表現
- 管理階層討論與分析(MDA)
- 情緒分析
- 產業分析
- 風險與機會
- 投資建議
我們將從外部API取得股票數據,並使用OpenAI API進行進階分析,確保提示資訊已準確保留。
設定環境
先決條件
- Node.js 安裝在您的電腦上
- OpenAI API 金鑰(如果您沒有,請在 OpenAI 註冊)
初始化專案
建立一個新目錄並初始化 Node.js 專案:
mkdir stock-report-generator cd stock-report-generator npm init -y
安裝必要的依賴項:
npm install express axios
設定項目結構:
mkdir routes utils data touch app.js routes/report.js utils/helpers.js
創建 Express 伺服器
設定 app.js
// app.js const express = require('express'); const reportRouter = require('./routes/report'); const app = express(); app.use(express.json()); app.use('/api', reportRouter); const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`Server is running on port ${PORT}`); });
- Express 初始化:導入 Express 並初始化應用程式。
- 中間件:使用express.json()解析JSON請求體。
- 路由:將報告路由器掛載到/api路徑上。
- 伺服器監聽:在指定連接埠啟動伺服器。
取得和處理數據
建立輔助函數
在 utils/helpers.js 中,我們將定義用於資料擷取和處理的實用函數。
mkdir stock-report-generator cd stock-report-generator npm init -y
- getLastYearDates:計算上一年的開始和結束日期。
- objectToString:將物件轉換為可讀字串,不包括指定的鍵。
- fetchData:處理對外部 API 的 GET 要求,傳回資料或預設值。
- readLocalJson:從本機 JSON 檔案讀取資料。
實施股票數據獲取
在routes/report.js中,定義取得股票資料的函數。
npm install express axios
- fetchStockData:並發取得多個資料點並處理結果。
- 資料處理:格式化和轉換資料以供後續使用。
- 錯誤處理:記錄錯誤並重新拋出它們以進行更高級別的處理。
與 OpenAI API 集成
OpenAI API互動功能
mkdir routes utils data touch app.js routes/report.js utils/helpers.js
- analyzeWithOpenAI:處理與 OpenAI API 的通訊。
- API配置:設定模型、溫度等參數。
- 錯誤處理:記錄並拋出上游處理的錯誤。
執行情緒分析
// app.js const express = require('express'); const reportRouter = require('./routes/report'); const app = express(); app.use(express.json()); app.use('/api', reportRouter); const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`Server is running on port ${PORT}`); });
- performSentimentAnalysis:建構提示訊息並呼叫OpenAI API進行分析。
- 提示設計:確保提示訊息清晰並包含必要的上下文。
產業分析
// utils/helpers.js const axios = require('axios'); const fs = require('fs'); const path = require('path'); const BASE_URL = 'https://your-data-api.com'; // Replace with your actual data API /** * Get the start and end dates for the last year. * @returns {object} - An object containing `start` and `end` dates. */ function getLastYearDates() { const now = new Date(); const end = now.toISOString().split('T')[0]; now.setFullYear(now.getFullYear() - 1); const start = now.toISOString().split('T')[0]; return { start, end }; } /** * Convert an object to a string, excluding specified keys. * @param {object} obj - The object to convert. * @param {string[]} excludeKeys - Keys to exclude. * @returns {string} - The resulting string. */ function objectToString(obj, excludeKeys = []) { return Object.entries(obj) .filter(([key]) => !excludeKeys.includes(key)) .map(([key, value]) => `${key}: ${value}`) .join('\n'); } /** * Fetch data from a specified endpoint with given parameters. * @param {string} endpoint - API endpoint. * @param {object} params - Query parameters. * @param {any} defaultValue - Default value if the request fails. * @returns {Promise<any>} - The fetched data or default value. */ async function fetchData(endpoint, params = {}, defaultValue = null) { try { const response = await axios.get(`${BASE_URL}${endpoint}`, { params }); return response.data || defaultValue; } catch (error) { console.error(`Error fetching data from ${endpoint}:`, error.message); return defaultValue; } } /** * Read data from a local JSON file. * @param {string} fileName - Name of the JSON file. * @returns {any} - The parsed data. */ function readLocalJson(fileName) { const filePath = path.join(__dirname, '../data', fileName); const data = fs.readFileSync(filePath, 'utf-8'); return JSON.parse(data); } module.exports = { fetchData, objectToString, getLastYearDates, readLocalJson, };
- analyzeIndustry:與情緒分析類似,但專注於更廣泛的產業背景。
- 提示保留:保持原始提示訊息的完整性。
產生最終報告
編譯所有數據
// routes/report.js const express = require('express'); const { fetchData, objectToString, getLastYearDates, readLocalJson, } = require('../utils/helpers'); const router = express.Router(); /** * Fetches stock data including historical prices, financials, MDA, and main business info. * @param {string} ticker - Stock ticker symbol. * @returns {Promise<object>} - An object containing all fetched data. */ async function fetchStockData(ticker) { try { const dates = getLastYearDates(); const [historicalData, financialData, mdaData, businessData] = await Promise.all([ fetchData('/stock_zh_a_hist', { symbol: ticker, period: 'weekly', start_date: dates.start, end_date: dates.end, }, []), fetchData('/stock_financial_benefit_ths', { code: ticker, indicator: '按年度', }, [{}]), fetchData('/stock_mda', { code: ticker }, []), fetchData('/stock_main_business', { code: ticker }, []), ]); const hist = historicalData[historicalData.length - 1]; const currentPrice = (hist ? hist['开盘'] : 'N/A') + ' CNY'; const historical = historicalData .map((item) => objectToString(item, ['股票代码'])) .join('\n----------\n'); const zsfzJson = readLocalJson('zcfz.json'); const balanceSheet = objectToString(zsfzJson.find((item) => item['股票代码'] === ticker)); const financial = objectToString(financialData[0]); const mda = mdaData.map(item => `${item['报告期']}\n${item['内容']}`).join('\n-----------\n'); const mainBusiness = businessData.map(item => `主营业务: ${item['主营业务']}\n产品名称: ${item['产品名称']}\n产品类型: ${item['产品类型']}\n经营范围: ${item['经营范围']}` ).join('\n-----------\n'); return { currentPrice, historical, balanceSheet, mda, mainBusiness, financial }; } catch (error) { console.error('Error fetching stock data:', error.message); throw error; } }
- 提供最終分析:精心製作提示訊息,合併所有收集的資料。
- 提示完整性:確保原始提示訊息不會被更改或損壞。
測試應用程式
定義路由處理程序
在routes/report.js中加入路由處理程序:
const axios = require('axios'); const OPENAI_API_KEY = 'your-openai-api-key'; // Replace with your OpenAI API key /** * Interacts with the OpenAI API to get completion results. * @param {array} messages - Array of messages, including system prompts and user messages. * @returns {Promise<string>} - The AI's response. */ async function analyzeWithOpenAI(messages) { try { const headers = { 'Authorization': `Bearer ${OPENAI_API_KEY}`, 'Content-Type': 'application/json', }; const requestData = { model: 'gpt-4', temperature: 0.3, messages: messages, }; const response = await axios.post( 'https://api.openai.com/v1/chat/completions', requestData, { headers } ); return response.data.choices[0].message.content.trim(); } catch (error) { console.error('Error fetching analysis from OpenAI:', error.message); throw error; } }
- 輸入驗證:檢查是否提供了股票代號。
- 資料收集:同時取得股票資料並執行分析。
- 錯誤處理:記錄錯誤並在失敗時發送 500 回應。
啟動伺服器
確保你的app.js和routes/report.js設定正確,然後啟動伺服器:
/** * Performs sentiment analysis on news articles using the OpenAI API. * @param {string} ticker - Stock ticker symbol. * @returns {Promise<string>} - Sentiment analysis summary. */ async function performSentimentAnalysis(ticker) { const systemPrompt = `You are a sentiment analysis assistant. Analyze the sentiment of the given news articles for ${ticker} and provide a summary of the overall sentiment and any notable changes over time. Be measured and discerning. You are a skeptical investor.`; const tickerNewsResponse = await fetchData('/stock_news_specific', { code: ticker }, []); const newsText = tickerNewsResponse .map(item => `${item['文章来源']} Date: ${item['发布时间']}\n${item['新闻内容']}`) .join('\n----------\n'); const messages = [ { role: 'system', content: systemPrompt }, { role: 'user', content: `News articles for ${ticker}:\n${newsText || 'N/A'}\n----\nProvide a summary of the overall sentiment and any notable changes over time.`, }, ]; return await analyzeWithOpenAI(messages); }
發送測試請求
使用curl或Postman發送POST請求:
mkdir stock-report-generator cd stock-report-generator npm init -y
- 回應:伺服器應傳回一個包含產生報表的 JSON 物件。
結論
我們建立了一個高品質的庫存報告產生器,具有以下功能:
- 從外部 API 取得並處理股票資料。
- 使用 OpenAI API 執行進階分析。
- 產生全面的投資報告,同時確保提示資訊的完整性。
在整個開發過程中,我們專注於編寫專業、可維護的程式碼,並提供了詳細的解釋和註釋。
實施的最佳實踐
- 模組化程式碼結構:函數被模組化以實現可重複使用性和清晰度。
- 非同步操作:使用async/await和Promise.all進行高效率的非同步程式設計。
- 錯誤處理:全面的 try-catch 區塊和錯誤訊息。
- API 抽象:分離的 API 互動邏輯,以提高可維護性。
- 提示工程:為OpenAI API精心設計提示訊息,以達到期望的輸出。
- 輸入驗證:檢查所需的輸入參數,以防止不必要的錯誤。
- 程式碼文件:新增了JSDoc註釋,以便更好地理解和維護。
下一步
- 快取:實作快取機制以減少冗餘的API呼叫。
- 驗證:透過驗證和速率限制來保護 API 端點。
- 前端開發:建立用於與應用程式互動的使用者介面。
- 其他分析:納入技術分析或其他財務模型。
參考
- Node.js 文件
- Express.js 文件
- Axios 文件
- OpenAI API 參考
免責聲明:此應用程式僅用於教育目的。確保遵守所有 API 服務條款並適當處理敏感資料。
以上是使用 Node.js、Express 和 OpenAI API 建立高品質股票報告產生器的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

JavaScript不需要安裝,因為它已內置於現代瀏覽器中。你只需文本編輯器和瀏覽器即可開始使用。 1)在瀏覽器環境中,通過標籤嵌入HTML文件中運行。 2)在Node.js環境中,下載並安裝Node.js後,通過命令行運行JavaScript文件。
