Heim  >  Artikel  >  Web-Frontend  >  Erstellen eines hochwertigen Aktienberichtgenerators mit Node.js, Express und OpenAI API

Erstellen eines hochwertigen Aktienberichtgenerators mit Node.js, Express und OpenAI API

Barbara Streisand
Barbara StreisandOriginal
2024-11-04 14:54:43622Durchsuche

Building a High-Quality Stock Report Generator with Node.js, Express, and OpenAI API

In diesem Artikel befassen wir uns mit der Erstellung eines professionellen Aktienberichtgenerators mithilfe von Node.js, Express und der OpenAI-API. Unser Fokus wird auf dem Schreiben von qualitativ hochwertigem, wartbarem Code liegen und gleichzeitig die Integrität der Eingabeaufforderungsnachrichten wahren, die in den OpenAI-API-Interaktionen verwendet werden. Die Anwendung ruft Aktiendaten ab, führt Stimmungs- und Branchenanalysen durch und erstellt einen umfassenden Investitionsbericht.

Inhaltsverzeichnis

  1. Projektübersicht
  2. Einrichten der Umgebung
  3. Erstellen des Express-Servers
  4. Daten abrufen und verarbeiten
  5. Integration mit OpenAI API
  6. Erstellung des Abschlussberichts
  7. Testen der Anwendung
  8. Fazit

Projektübersicht

Unser Ziel ist es, einen API-Endpunkt zu erstellen, der einen detaillierten Investitionsbericht für einen bestimmten Börsenticker generiert. Der Bericht enthält Folgendes:

  • Unternehmensübersicht
  • Finanzielle Leistung
  • Managementdiskussion und -analyse (MDA)
  • Stimmungsanalyse
  • Branchenanalyse
  • Risiken und Chancen
  • Anlageempfehlung

Wir rufen Bestandsdaten von externen APIs ab und verwenden die OpenAI-API für erweiterte Analysen, um sicherzustellen, dass die Eingabeaufforderungen genau erhalten bleiben.

Einrichten der Umgebung

Voraussetzungen

  • Node.jsauf Ihrem Computer installiert
  • OpenAI-API-Schlüssel (Wenn Sie keinen haben, melden Sie sich bei OpenAI an)

Initialisieren des Projekts

Erstellen Sie ein neues Verzeichnis und initialisieren Sie ein Node.js-Projekt:

mkdir stock-report-generator
cd stock-report-generator
npm init -y

Installieren Sie die erforderlichen Abhängigkeiten:

npm install express axios

Richten Sie die Projektstruktur ein:

mkdir routes utils data
touch app.js routes/report.js utils/helpers.js

Erstellen des Express-Servers

app.js einrichten

// 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-Initialisierung: Importieren Sie Express und initialisieren Sie die Anwendung.
  • Middleware: Verwenden Sie express.json(), um JSON-Anfragetexte zu analysieren.
  • Routing: Mounten Sie den Berichtsrouter im /api-Pfad.
  • Serverüberwachung: Starten Sie den Server am angegebenen Port.

Daten abrufen und verarbeiten

Hilfsfunktionen erstellen

In utils/helpers.js definieren wir Hilfsfunktionen zum Abrufen und Verarbeiten von Daten.

mkdir stock-report-generator
cd stock-report-generator
npm init -y
  • getLastYearDates: Berechnet das Start- und Enddatum für das Vorjahr.
  • objectToString: Konvertiert ein Objekt in eine lesbare Zeichenfolge, mit Ausnahme der angegebenen Schlüssel.
  • fetchData: Verarbeitet GET-Anfragen an externe APIs und gibt Daten oder einen Standardwert zurück.
  • readLocalJson: Liest Daten aus lokalen JSON-Dateien.

Implementieren des Abrufens von Bestandsdaten

Definieren Sie in „routes/report.js“ Funktionen zum Abrufen von Bestandsdaten.

npm install express axios
  • fetchStockData: Ruft gleichzeitig mehrere Datenpunkte ab und verarbeitet die Ergebnisse.
  • Datenverarbeitung: Formatiert und transformiert Daten für die spätere Verwendung.
  • Fehlerbehandlung: Protokolliert Fehler und gibt sie zur Behandlung auf höherer Ebene erneut aus.

Integration mit der OpenAI-API

OpenAI API-Interaktionsfunktion

mkdir routes utils data
touch app.js routes/report.js utils/helpers.js
  • analyzeWithOpenAI: Verwaltet die Kommunikation mit der OpenAI-API.
  • API-Konfiguration: Legt Parameter wie Modell und Temperatur fest.
  • Fehlerbehandlung: Protokolliert und löst Fehler zur Upstream-Behandlung aus.

Durchführen einer Stimmungsanalyse

// 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: Erstellt Aufforderungsnachrichten und ruft die OpenAI-API zur Analyse auf.
  • Prompt-Design: Stellt sicher, dass die Prompt-Nachrichten klar sind und den notwendigen Kontext enthalten.

Analyse der Branche

// 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: Ähnlich der Stimmungsanalyse, konzentriert sich jedoch auf einen breiteren Branchenkontext.
  • Prompt-Erhaltung: Behält die Integrität der ursprünglichen Prompt-Nachrichten bei.

Erstellen des Abschlussberichts

Zusammenstellung aller Daten

// 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;
  }
}
  • FinalAnalysis bereitstellen: Erstellt sorgfältig Aufforderungsnachrichten unter Einbeziehung aller gesammelten Daten.
  • Prompt-Integrität: Stellt sicher, dass die ursprünglichen Prompt-Nachrichten nicht verändert oder beschädigt werden.

Testen der Anwendung

Definieren des Routenhandlers

Fügen Sie den Routenhandler inroutes/report.js hinzu:

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;
  }
}
  • Eingabevalidierung: Prüft, ob das Tickersymbol bereitgestellt wird.
  • Datenerfassung: Ruft gleichzeitig Bestandsdaten ab und führt Analysen durch.
  • Fehlerbehandlung: Protokolliert Fehler und sendet im Fehlerfall eine 500-Antwort.

Starten des Servers

Stellen Sie sicher, dass Ihre app.js und Routes/report.js korrekt eingerichtet sind, und starten Sie dann den Server:

/**
 * 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);
}

Senden einer Testanfrage

Verwenden Sie Curl oder Postman, um eine POST-Anfrage zu senden:

mkdir stock-report-generator
cd stock-report-generator
npm init -y
  • Antwort: Der Server sollte ein JSON-Objekt zurückgeben, das den generierten Bericht enthält.

Abschluss

Wir haben einen hochwertigen Aktienberichtsgenerator mit den folgenden Funktionen entwickelt:

  • Bestandsdaten abrufen und verarbeitenvon externen APIs.
  • Durchführung erweiterter Analysenmit der OpenAI-API.
  • Erstellung eines umfassenden Anlageberichts und gleichzeitige Gewährleistung der Integrität der prompten Meldungen.

Während des Entwicklungsprozesses haben wir uns darauf konzentriert, professionellen, wartbaren Code zu schreiben und detaillierte Erklärungen und Anmerkungen bereitzustellen.

Best Practices implementiert

  • Modulare Codestruktur: Funktionen sind zur Wiederverwendbarkeit und Übersichtlichkeit modularisiert.
  • Asynchrone Operationen: Verwendet async/await und Promise.all für effiziente asynchrone Programmierung.
  • Fehlerbehandlung: Umfassende Try-Catch-Blöcke und Fehlermeldungen.
  • API-Abstraktion: Separate API-Interaktionslogik für bessere Wartbarkeit.
  • Prompt Engineering: Sorgfältig entworfene Prompt-Nachrichten für die OpenAI-API, um die gewünschte Ausgabe zu erzielen.
  • Eingabevalidierung: Auf erforderliche Eingabeparameter überprüft, um unnötige Fehler zu vermeiden.
  • Code-Dokumentation: JSDoc-Kommentare zum besseren Verständnis und zur besseren Wartung hinzugefügt.

Nächste Schritte

  • Caching: Implementieren Sie Caching-Mechanismen, um redundante API-Aufrufe zu reduzieren.
  • Authentifizierung: Sichern Sie die API-Endpunkte mit Authentifizierung und Ratenbegrenzung.
  • Frontend-Entwicklung: Erstellen Sie eine Benutzeroberfläche für die Interaktion mit der Anwendung.
  • Zusätzliche Analysen: Integrieren Sie technische Analysen oder andere Finanzmodelle.

Referenzen

  • Node.js-Dokumentation
  • Express.js-Dokumentation
  • Axios-Dokumentation
  • OpenAI API-Referenz

Haftungsausschluss: Diese Anwendung dient nur zu Bildungszwecken. Stellen Sie die Einhaltung aller API-Nutzungsbedingungen sicher und gehen Sie angemessen mit sensiblen Daten um.

Das obige ist der detaillierte Inhalt vonErstellen eines hochwertigen Aktienberichtgenerators mit Node.js, Express und OpenAI API. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn