この記事では、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 と Route/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 中国語 Web サイトの他の関連記事を参照してください。