在本文中,我們將深入研究使用 Node.js、Express 和 OpenAI API 建立專業級股票報告產生器。我們的重點是編寫高品質、可維護的程式碼,同時保留 OpenAI API 互動中使用的提示訊息的完整性。該應用程式將獲取股票數據,執行情緒和行業分析,並產生全面的投資報告。
我們的目標是建立一個 API 端點,為給定的股票代碼產生詳細的投資報告。該報告將包括:
我們將從外部API取得股票數據,並使用OpenAI API進行進階分析,確保提示資訊已準確保留。
建立一個新目錄並初始化 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
// 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}`); });
在 utils/helpers.js 中,我們將定義用於資料擷取和處理的實用函數。
mkdir stock-report-generator cd stock-report-generator npm init -y
在routes/report.js中,定義取得股票資料的函數。
npm install express axios
mkdir routes utils data touch app.js routes/report.js utils/helpers.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}`); });
// 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, };
// 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; } }
確保你的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
我們建立了一個高品質的庫存報告產生器,具有以下功能:
在整個開發過程中,我們專注於編寫專業、可維護的程式碼,並提供了詳細的解釋和註釋。
免責聲明:此應用程式僅用於教育目的。確保遵守所有 API 服務條款並適當處理敏感資料。
以上是使用 Node.js、Express 和 OpenAI API 建立高品質股票報告產生器的詳細內容。更多資訊請關注PHP中文網其他相關文章!