Rumah  >  Artikel  >  hujung hadapan web  >  Membina Penjana Laporan Saham Berkualiti Tinggi dengan API Node.js, Express dan OpenAI

Membina Penjana Laporan Saham Berkualiti Tinggi dengan API Node.js, Express dan OpenAI

Barbara Streisand
Barbara Streisandasal
2024-11-04 14:54:43622semak imbas

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

Dalam artikel ini, kami akan mendalami tentang mencipta penjana laporan saham gred profesional menggunakan Node.js, Express dan OpenAI API. Tumpuan kami adalah pada menulis kod yang berkualiti tinggi dan boleh diselenggara sambil mengekalkan integriti mesej segera yang digunakan dalam interaksi API OpenAI. Aplikasi ini akan mengambil data saham, melakukan analisis sentimen dan industri serta menjana laporan pelaburan yang komprehensif.

Jadual Kandungan

  1. Gambaran Keseluruhan Projek
  2. Menyediakan Persekitaran
  3. Mencipta Pelayan Ekspres
  4. Mengambil dan Memproses Data
  5. Menyepadukan dengan OpenAI API
  6. Menjana Laporan Akhir
  7. Menguji Aplikasi
  8. Kesimpulan

Gambaran Keseluruhan Projek

Matlamat kami adalah untuk membina titik akhir API yang menjana laporan pelaburan terperinci untuk penanda saham tertentu. Laporan itu akan merangkumi:

  • Gambaran Keseluruhan Syarikat
  • Prestasi Kewangan
  • Perbincangan dan Analisis Pengurusan (MDA)
  • Analisis Sentimen
  • Analisis Industri
  • Risiko dan Peluang
  • Syor Pelaburan

Kami akan mengambil data stok daripada API luaran dan menggunakan API OpenAI untuk analisis lanjutan, memastikan mesej gesaan disimpan dengan tepat.

Menyediakan Persekitaran

Prasyarat

  • Node.js dipasang pada mesin anda
  • Kunci API OpenAI (Jika anda tidak mempunyainya, daftar di OpenAI)

Memulakan Projek

Buat direktori baharu dan mulakan projek Node.js:

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

Pasang kebergantungan yang diperlukan:

npm install express axios

Sediakan struktur projek:

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

Mencipta Pelayan Ekspres

Menyediakan 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}`);
});
  • Permulaan Ekspres: Import Ekspres dan mulakan aplikasi.
  • Perisian Tengah: Gunakan express.json() untuk menghuraikan badan permintaan JSON.
  • Penghalaan: Lekapkan penghala laporan pada laluan /api.
  • Mendengar Pelayan: Mulakan pelayan pada port yang ditentukan.

Mengambil dan Memproses Data

Mencipta Fungsi Pembantu

Dalam utils/helpers.js, kami akan mentakrifkan fungsi utiliti untuk pengambilan dan pemprosesan data.

mkdir stock-report-generator
cd stock-report-generator
npm init -y
  • getLastYearDates: Mengira tarikh mula dan tamat untuk tahun sebelumnya.
  • objectToString: Menukar objek kepada rentetan yang boleh dibaca, tidak termasuk kunci yang ditentukan.
  • fetchData: Mengendalikan permintaan GET kepada API luaran, mengembalikan data atau nilai lalai.
  • readLocalJson: Membaca data daripada fail JSON setempat.

Melaksanakan Pengambilan Data Stok

Dalam route/report.js, tentukan fungsi untuk mengambil data stok.

npm install express axios
  • fetchStockData: Secara serentak mengambil berbilang titik data dan memproses hasilnya.
  • Pemprosesan Data: Memformat dan mengubah data untuk kegunaan seterusnya.
  • Pengendalian Ralat: Log ralat dan buang semula untuk pengendalian peringkat lebih tinggi.

Mengintegrasikan dengan OpenAI API

Fungsi Interaksi OpenAI API

mkdir routes utils data
touch app.js routes/report.js utils/helpers.js
  • analyzeWithOpenAI: Mengendalikan komunikasi dengan OpenAI API.
  • Konfigurasi API: Menetapkan parameter seperti model dan suhu.
  • Pengendalian Ralat: Merakam dan membuang ralat untuk pengendalian huluan.

Melakukan Analisis Sentimen

// 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: Membina mesej segera dan memanggil API OpenAI untuk analisis.
  • Reka Bentuk Segera: Memastikan mesej gesaan adalah jelas dan termasuk konteks yang diperlukan.

Menganalisis Industri

// 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: Sama seperti analisis sentimen tetapi menumpukan pada konteks industri yang lebih luas.
  • Pemeliharaan Segera: Mengekalkan integriti mesej gesaan asal.

Menjana Laporan Akhir

Menyusun Semua Data

// 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: Buat mesej segera dengan teliti, menggabungkan semua data yang dikumpul.
  • Integriti Segera: Memastikan mesej gesaan asal tidak diubah atau rosak.

Menguji Aplikasi

Menentukan Pengendali Laluan

Tambahkan pengendali laluan dalam route/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;
  }
}
  • Pengesahan Input: Menyemak sama ada simbol ticker disediakan.
  • Pengumpulan Data: Pada masa yang sama mengambil data stok dan melakukan analisis.
  • Pengendalian Ralat: Log ralat dan menghantar 500 respons sekiranya berlaku kegagalan.

Memulakan Pelayan

Pastikan app.js dan route/report.js anda disediakan dengan betul, kemudian mulakan pelayan:

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

Menghantar Permintaan Ujian

Gunakan curl atau Posmen untuk menghantar permintaan POST:

mkdir stock-report-generator
cd stock-report-generator
npm init -y
  • Respons: Pelayan harus mengembalikan objek JSON yang mengandungi laporan yang dijana.

Kesimpulan

Kami telah membina penjana laporan saham berkualiti tinggi dengan keupayaan berikut:

  • Mengambil dan memproses data stok daripada API luaran.
  • Melakukan analisis lanjutan menggunakan OpenAI API.
  • Menjana laporan pelaburan yang komprehensif, sambil memastikan integriti mesej segera.

Sepanjang proses pembangunan, kami menumpukan pada menulis kod profesional, boleh diselenggara dan memberikan penjelasan dan anotasi terperinci.

Amalan Terbaik Dilaksanakan

  • Struktur Kod Modular: Fungsi dimodulasi untuk kebolehgunaan semula dan kejelasan.
  • Operasi Asynchronous: Menggunakan async/wait and Promise.all untuk pengaturcaraan tak segerak yang cekap.
  • Pengendalian Ralat: Sekatan cuba-tangkap komprehensif dan mesej ralat.
  • Abstraksi API: Logik interaksi API yang diasingkan untuk kebolehselenggaraan yang lebih baik.
  • Kejuruteraan Segera: Mesej gesaan direka dengan teliti untuk API OpenAI untuk mencapai output yang diingini.
  • Pengesahan Input: Disemak untuk parameter input yang diperlukan untuk mengelakkan ralat yang tidak perlu.
  • Dokumentasi Kod: Menambah ulasan JSDoc untuk pemahaman dan penyelenggaraan yang lebih baik.

Langkah Seterusnya

  • Caching: Laksanakan mekanisme caching untuk mengurangkan panggilan API yang berlebihan.
  • Pengesahan: Lindungi titik akhir API dengan pengesahan dan pengehadan kadar.
  • Pembangunan Depan: Bina antara muka pengguna untuk berinteraksi dengan aplikasi.
  • Analisis Tambahan: Menggabungkan analisis teknikal atau model kewangan lain.

Rujukan

  • Dokumentasi Node.js
  • Dokumentasi Express.js
  • Dokumentasi Axios
  • Rujukan API OpenAI

Penafian: Permohonan ini adalah untuk tujuan pendidikan sahaja. Pastikan pematuhan dengan semua syarat perkhidmatan API dan kendalikan data sensitif dengan sewajarnya.

Atas ialah kandungan terperinci Membina Penjana Laporan Saham Berkualiti Tinggi dengan API Node.js, Express dan OpenAI. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn