BREAKING CHANGE(stocks): Unify stock provider API to discriminated IStockDataRequest and add company name/fullname enrichment
This commit is contained in:
@@ -2,15 +2,11 @@ import * as plugins from '../../plugins.js';
|
||||
import type { IStockProvider, IProviderConfig } from '../interfaces/provider.js';
|
||||
import type {
|
||||
IStockPrice,
|
||||
IStockQuoteRequest,
|
||||
IStockBatchQuoteRequest,
|
||||
IStockDataRequest,
|
||||
IStockCurrentRequest,
|
||||
IStockHistoricalRequest,
|
||||
IStockIntradayRequest,
|
||||
IStockBatchCurrentRequest,
|
||||
IPaginatedResponse,
|
||||
TSortOrder
|
||||
IStockBatchCurrentRequest
|
||||
} from '../interfaces/stockprice.js';
|
||||
|
||||
/**
|
||||
@@ -239,30 +235,6 @@ export class MarketstackProvider implements IStockProvider {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Legacy: Fetch latest EOD price for a single ticker
|
||||
* @deprecated Use fetchData with IStockDataRequest instead
|
||||
*/
|
||||
public async fetchPrice(request: IStockQuoteRequest): Promise<IStockPrice> {
|
||||
// Map legacy request to new format
|
||||
return this.fetchCurrentPrice({
|
||||
type: 'current',
|
||||
ticker: request.ticker
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Legacy: Fetch latest EOD prices for multiple tickers
|
||||
* @deprecated Use fetchData with IStockDataRequest instead
|
||||
*/
|
||||
public async fetchPrices(request: IStockBatchQuoteRequest): Promise<IStockPrice[]> {
|
||||
// Map legacy request to new format
|
||||
return this.fetchBatchCurrentPrices({
|
||||
type: 'batch',
|
||||
tickers: request.tickers
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the Marketstack API is available and accessible
|
||||
*/
|
||||
@@ -349,12 +321,49 @@ export class MarketstackProvider implements IStockProvider {
|
||||
low: data.low,
|
||||
adjusted: data.adj_close !== undefined, // If adj_close exists, price is adjusted
|
||||
dataType: dataType,
|
||||
fetchedAt: fetchedAt
|
||||
fetchedAt: fetchedAt,
|
||||
|
||||
// Company identification
|
||||
companyName: data.company_name || data.name || undefined,
|
||||
companyFullName: this.buildCompanyFullName(data)
|
||||
};
|
||||
|
||||
return stockPrice;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build full company name with exchange and ticker information
|
||||
* Example: "Apple Inc (NASDAQ:AAPL)"
|
||||
*/
|
||||
private buildCompanyFullName(data: any): string | undefined {
|
||||
// Check if API already provides full name
|
||||
if (data.full_name || data.long_name) {
|
||||
return data.full_name || data.long_name;
|
||||
}
|
||||
|
||||
// Build from available data
|
||||
const companyName = data.company_name || data.name;
|
||||
const exchangeCode = data.exchange_code; // e.g., "NASDAQ"
|
||||
const symbol = data.symbol; // e.g., "AAPL"
|
||||
|
||||
if (!companyName) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// If we have exchange and symbol, build full name: "Apple Inc (NASDAQ:AAPL)"
|
||||
if (exchangeCode && symbol) {
|
||||
return `${companyName} (${exchangeCode}:${symbol})`;
|
||||
}
|
||||
|
||||
// If we only have symbol: "Apple Inc (AAPL)"
|
||||
if (symbol) {
|
||||
return `${companyName} (${symbol})`;
|
||||
}
|
||||
|
||||
// Otherwise just return company name
|
||||
return companyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format date to YYYY-MM-DD for API requests
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
import * as plugins from '../../plugins.js';
|
||||
import type { IStockProvider, IProviderConfig } from '../interfaces/provider.js';
|
||||
import type { IStockPrice, IStockQuoteRequest, IStockBatchQuoteRequest } from '../interfaces/stockprice.js';
|
||||
import type {
|
||||
IStockPrice,
|
||||
IStockDataRequest,
|
||||
IStockCurrentRequest,
|
||||
IStockBatchCurrentRequest
|
||||
} from '../interfaces/stockprice.js';
|
||||
|
||||
export class YahooFinanceProvider implements IStockProvider {
|
||||
public name = 'Yahoo Finance';
|
||||
@@ -17,7 +22,28 @@ export class YahooFinanceProvider implements IStockProvider {
|
||||
|
||||
constructor(private config?: IProviderConfig) {}
|
||||
|
||||
public async fetchPrice(request: IStockQuoteRequest): Promise<IStockPrice> {
|
||||
/**
|
||||
* Unified data fetching method
|
||||
*/
|
||||
public async fetchData(request: IStockDataRequest): Promise<IStockPrice | IStockPrice[]> {
|
||||
switch (request.type) {
|
||||
case 'current':
|
||||
return this.fetchCurrentPrice(request);
|
||||
case 'batch':
|
||||
return this.fetchBatchCurrentPrices(request);
|
||||
case 'historical':
|
||||
throw new Error('Yahoo Finance provider does not support historical data. Use Marketstack provider instead.');
|
||||
case 'intraday':
|
||||
throw new Error('Yahoo Finance provider does not support intraday data yet. Use Marketstack provider instead.');
|
||||
default:
|
||||
throw new Error(`Unsupported request type: ${(request as any).type}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch current price for a single ticker
|
||||
*/
|
||||
private async fetchCurrentPrice(request: IStockCurrentRequest): Promise<IStockPrice> {
|
||||
try {
|
||||
const url = `${this.baseUrl}/v8/finance/chart/${request.ticker}`;
|
||||
const response = await plugins.smartrequest.SmartRequest.create()
|
||||
@@ -64,7 +90,10 @@ export class YahooFinanceProvider implements IStockProvider {
|
||||
}
|
||||
}
|
||||
|
||||
public async fetchPrices(request: IStockBatchQuoteRequest): Promise<IStockPrice[]> {
|
||||
/**
|
||||
* Fetch batch current prices
|
||||
*/
|
||||
private async fetchBatchCurrentPrices(request: IStockBatchCurrentRequest): Promise<IStockPrice[]> {
|
||||
try {
|
||||
const symbols = request.tickers.join(',');
|
||||
const url = `${this.baseUrl}/v8/finance/spark?symbols=${symbols}&range=1d&interval=5m`;
|
||||
@@ -123,7 +152,7 @@ export class YahooFinanceProvider implements IStockProvider {
|
||||
public async isAvailable(): Promise<boolean> {
|
||||
try {
|
||||
// Test with a well-known ticker
|
||||
await this.fetchPrice({ ticker: 'AAPL' });
|
||||
await this.fetchData({ type: 'current', ticker: 'AAPL' });
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.warn('Yahoo Finance provider is not available:', error);
|
||||
|
||||
Reference in New Issue
Block a user