ホームページ > ウェブフロントエンド > jsチュートリアル > Node.js、Express、OpenAI API を使用した高品質の株価レポート ジェネレーターの構築

Node.js、Express、OpenAI API を使用した高品質の株価レポート ジェネレーターの構築

Barbara Streisand
リリース: 2024-11-04 14:54:43
オリジナル
656 人が閲覧しました

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

この記事では、Node.js、Express、OpenAI API を使用したプロ仕様の株価レポート ジェネレーターの作成について詳しく説明します。私たちは、OpenAI API の対話で使用されるプロンプト メッセージの整合性を維持しながら、高品質で保守可能なコードを作成することに重点を置きます。このアプリケーションは株式データを取得し、センチメントと業界の分析を実行し、包括的な投資レポートを生成します。

目次

  1. プロジェクト概要
  2. 環境のセットアップ
  3. Express サーバーの作成
  4. データの取得と処理
  5. OpenAI API との統合
  6. 最終レポートの作成
  7. アプリケーションのテスト
  8. 結論

プロジェクト概要

私たちの目標は、特定の株価ティッカーの詳細な投資レポートを生成する 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 Initialization: Express をインポートし、アプリケーションを初期化します。
  • ミドルウェア: Express.json() を使用して JSON リクエスト本文を解析します。
  • ルーティング: レポート ルーターを /api パスにマウントします。
  • サーバーリスニング: 指定されたポートでサーバーを起動します。

データの取得と処理

ヘルパー関数の作成

utils/helpers.js で、データのフェッチと処理のためのユーティリティ関数を定義します。

mkdir stock-report-generator
cd stock-report-generator
npm init -y
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
  • getLast YearDates: 前年の開始日と終了日を計算します。
  • 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;
  }
}
ログイン後にコピー
  • provideFinalAnalysis: 収集されたすべてのデータを組み込んで、プロンプト メッセージを慎重に作成します。
  • プロンプトの整合性: 元のプロンプト メッセージが変更または破損していないことを保証します。

アプリケーションのテスト

ルートハンドラーの定義

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 と 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
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
  • レスポンス: サーバーは、生成されたレポートを含む 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 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート