work on prices
This commit is contained in:
parent
77bba31456
commit
2f5eaef19c
2 changed files with 46 additions and 32 deletions
|
|
@ -28,26 +28,25 @@ async function getOperationTracker(handler: QMHandler): Promise<QMOperationTrack
|
|||
export async function updatePrices(
|
||||
this: QMHandler,
|
||||
input: {
|
||||
symbol: string;
|
||||
symbolId: number;
|
||||
qmSearchCode: string;
|
||||
lastRecordDate?: Date;
|
||||
},
|
||||
_context?: ExecutionContext
|
||||
): Promise<{
|
||||
success: boolean;
|
||||
symbol: string;
|
||||
qmSearchCode: string;
|
||||
message: string;
|
||||
data?: any;
|
||||
}> {
|
||||
const { symbol, symbolId, qmSearchCode } = input;
|
||||
const { qmSearchCode, lastRecordDate } = input;
|
||||
|
||||
this.logger.info('Fetching daily prices', { symbol, symbolId });
|
||||
this.logger.info(`Fetching daily prices ${qmSearchCode}`, { qmSearchCode });
|
||||
|
||||
const sessionManager = QMSessionManager.getInstance();
|
||||
sessionManager.initialize(this.cache, this.logger);
|
||||
|
||||
// Get a session - you'll need to add the appropriate session ID for prices
|
||||
const sessionId = QM_SESSION_IDS.LOOKUP; // TODO: Update with correct session ID
|
||||
const sessionId = QM_SESSION_IDS.PRICES;
|
||||
const session = await sessionManager.getSession(sessionId);
|
||||
|
||||
if (!session || !session.uuid) {
|
||||
|
|
@ -57,15 +56,20 @@ export async function updatePrices(
|
|||
try {
|
||||
// Build API request for daily prices
|
||||
const searchParams = new URLSearchParams({
|
||||
symbol: symbol,
|
||||
symbolId: symbolId.toString(),
|
||||
qmodTool: 'DailyPrices',
|
||||
webmasterId: '500',
|
||||
days: '30' // Get last 30 days
|
||||
zeroTradeDays: 'false',
|
||||
start: lastRecordDate?.toISOString().split('T')[0] ?? '1960-01-01',
|
||||
interval: '1',
|
||||
marketSession: 'mkt',
|
||||
freq: 'day',
|
||||
adjusted: 'false',
|
||||
adjustmentType: 'none',
|
||||
unadjusted: 'true',
|
||||
datatype: 'eod',
|
||||
symbol: qmSearchCode,
|
||||
});
|
||||
|
||||
// https://app.quotemedia.com/datatool/getEnhancedChartData.json?zeroTradeDays=false&start=2025-06-22&interval=1&marketSession=mkt&freq=day&adjusted=true&adjustmentType=none&unadjusted=false&datatype=int&symbol=AAPL
|
||||
// TODO: Update with correct prices endpoint
|
||||
const apiUrl = `${QM_CONFIG.BASE_URL}/datatool/prices.json?${searchParams.toString()}`;
|
||||
const apiUrl = `${QM_CONFIG.PRICES_URL}?${searchParams.toString()}`;
|
||||
|
||||
const response = await fetch(apiUrl, {
|
||||
method: 'GET',
|
||||
|
|
@ -77,31 +81,40 @@ export async function updatePrices(
|
|||
throw new Error(`QM API request failed: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
|
||||
const priceData = await response.json();
|
||||
|
||||
const responseData = await response.json();
|
||||
|
||||
// Update session success stats
|
||||
await sessionManager.incrementSuccessfulCalls(sessionId, session.uuid);
|
||||
|
||||
const priceData = responseData.results?.history[0].eoddata || [];
|
||||
|
||||
if(!priceData || priceData.length === 0) {
|
||||
this.logger.warn(`No price data found for symbol ${qmSearchCode}`);
|
||||
return {
|
||||
success: false,
|
||||
qmSearchCode,
|
||||
message: `No price data found for symbol ${qmSearchCode}`
|
||||
};
|
||||
}
|
||||
|
||||
// Process and store price data
|
||||
if (priceData && priceData.length > 0) {
|
||||
// Store prices in a separate collection
|
||||
const processedPrices = priceData.map((price: any) => ({
|
||||
...price,
|
||||
symbol,
|
||||
symbolId,
|
||||
date: new Date(price.date),
|
||||
updated_at: new Date()
|
||||
qmSearchCode,
|
||||
dateTime: new Date(price.date),
|
||||
}));
|
||||
|
||||
await this.mongodb.batchUpsert(
|
||||
'qmPrices',
|
||||
processedPrices,
|
||||
['symbol', 'date'] // Unique keys
|
||||
['qmSearchCode', 'date'] // Unique keys
|
||||
);
|
||||
|
||||
// Find the latest price date
|
||||
const latestDate = processedPrices.reduce((latest: Date, price: any) =>
|
||||
price.date > latest ? price.date : latest,
|
||||
price.dateTime > latest ? price.dateTime : latest,
|
||||
new Date(0)
|
||||
);
|
||||
|
||||
|
|
@ -114,26 +127,26 @@ export async function updatePrices(
|
|||
});
|
||||
|
||||
this.logger.info('Prices updated successfully', {
|
||||
symbol,
|
||||
qmSearchCode,
|
||||
priceCount: priceData.length,
|
||||
latestDate
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
symbol,
|
||||
message: `Prices updated for ${symbol}`,
|
||||
qmSearchCode,
|
||||
message: `Prices updated for ${qmSearchCode}`,
|
||||
data: {
|
||||
count: priceData.length,
|
||||
latestDate
|
||||
}
|
||||
};
|
||||
} else {
|
||||
this.logger.warn('No price data returned from API', { symbol });
|
||||
this.logger.warn('No price data returned from API', { qmSearchCode });
|
||||
return {
|
||||
success: false,
|
||||
symbol,
|
||||
message: `No price data found for symbol ${symbol}`
|
||||
qmSearchCode,
|
||||
message: `No price data found for qmSearchCode ${qmSearchCode}`
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -144,7 +157,7 @@ export async function updatePrices(
|
|||
}
|
||||
|
||||
this.logger.error('Error fetching prices', {
|
||||
symbol,
|
||||
qmSearchCode,
|
||||
error: error instanceof Error ? error.message : 'Unknown error'
|
||||
});
|
||||
|
||||
|
|
@ -156,7 +169,7 @@ export async function updatePrices(
|
|||
|
||||
return {
|
||||
success: false,
|
||||
symbol,
|
||||
qmSearchCode,
|
||||
message: `Failed to fetch prices: ${error instanceof Error ? error.message : 'Unknown error'}`
|
||||
};
|
||||
}
|
||||
|
|
@ -177,7 +190,7 @@ export async function schedulePriceUpdates(
|
|||
symbolsQueued: number;
|
||||
errors: number;
|
||||
}> {
|
||||
const { limit = 100, forceUpdate = false } = input;
|
||||
const { limit = 1, forceUpdate = false } = input;
|
||||
const tracker = await getOperationTracker(this);
|
||||
|
||||
this.logger.info('Scheduling price updates', { limit, forceUpdate });
|
||||
|
|
@ -219,8 +232,6 @@ export async function schedulePriceUpdates(
|
|||
}
|
||||
|
||||
await this.scheduleOperation('update-prices', {
|
||||
symbol: doc.symbol,
|
||||
symbolId: doc.symbolId,
|
||||
qmSearchCode: doc.qmSearchCode
|
||||
}, {
|
||||
priority: 7, // High priority for price data
|
||||
|
|
|
|||
|
|
@ -8,11 +8,13 @@ import { getRandomUserAgent } from "@stock-bot/utils";
|
|||
export const QM_SESSION_IDS = {
|
||||
LOOKUP: 'dc8c9930437f65d30f6597768800957017bac203a0a50342932757c8dfa158d6', // lookup endpoint
|
||||
SYMBOL: '1e1d7cb1de1fd2fe52684abdea41a446919a5fe12776dfab88615ac1ce1ec2f6', // getProfiles
|
||||
PRICES: '5ad521e05faf5778d567f6d0012ec34d6cdbaeb2462f41568f66558bc7b4ced9', // getEnhancedChartData
|
||||
// EDS: '', //
|
||||
// FILINGS: '', //
|
||||
// PRICES: '', //
|
||||
// FINANCIALS: '', //
|
||||
// INTRADAY: '', //
|
||||
// '5ad521e05faf5778d567f6d0012ec34d6cdbaeb2462f41568f66558bc7b4ced9' // getEhnachedChartData
|
||||
// '5ad521e05faf5778d567f6d0012ec34d6cdbaeb2462f41568f66558bc7b4ced9': [], //4488d072b
|
||||
// cc1cbdaf040f76db8f4c94f7d156b9b9b716e1a7509ec9c74a48a47f6b6b9f87: [], //97ff00cf3 // getQuotes
|
||||
// '74963ff42f1db2320d051762b5d3950ff9eab23f9d5c5b592551b4ca0441d086': [], //32ca24e394b // getSplitsBySymbol getBrokerRatingsBySymbol getDividendsBySymbol getEarningsSurprisesBySymbol getEarningsEventsBySymbol
|
||||
|
|
@ -35,6 +37,7 @@ export const QM_CONFIG = {
|
|||
SESSION_PATH: '/auth/g/authenticate/dataTool/v0/500',
|
||||
LOOKUP_URL: 'https://app.quotemedia.com/datatool/lookup.json',
|
||||
SYMBOL_URL: 'https://app.quotemedia.com/datatool/getProfiles.json',
|
||||
PRICES_URL: 'https://app.quotemedia.com/datatool/getEnhancedChartData.json',
|
||||
} as const;
|
||||
|
||||
// Session management settings
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue