179 lines
No EOL
4.6 KiB
TypeScript
179 lines
No EOL
4.6 KiB
TypeScript
import {
|
|
BaseHandler,
|
|
Disabled,
|
|
Handler,
|
|
Operation,
|
|
ScheduledOperation,
|
|
} from '@stock-bot/handlers';
|
|
import type { DataIngestionServices } from '../../types';
|
|
import type { OperationRegistry } from '../../shared/operation-manager';
|
|
import { createQMOperationRegistry } from './shared/operation-provider';
|
|
import {
|
|
checkSessions,
|
|
createSession,
|
|
deduplicateSymbols,
|
|
scheduleEventsUpdates,
|
|
scheduleFilingsUpdates,
|
|
scheduleFinancialsUpdates,
|
|
scheduleIntradayUpdates,
|
|
schedulePriceUpdates,
|
|
scheduleSymbolInfoUpdates,
|
|
searchSymbols,
|
|
spiderSymbol,
|
|
updateEvents,
|
|
updateExchangeStats,
|
|
updateExchangeStatsAndDeduplicate,
|
|
updateFilings,
|
|
updateFinancials,
|
|
updateIntradayBars,
|
|
updatePrices,
|
|
updateSymbolInfo
|
|
} from './actions';
|
|
|
|
@Handler('qm')
|
|
export class QMHandler extends BaseHandler<DataIngestionServices> {
|
|
public operationRegistry: OperationRegistry;
|
|
|
|
constructor(services: any) {
|
|
super(services); // Handler name read from @Handler decorator
|
|
|
|
// Initialize operation registry with QM provider
|
|
createQMOperationRegistry(this.mongodb, this.logger)
|
|
.then(registry => {
|
|
this.operationRegistry = registry;
|
|
})
|
|
.catch(error => {
|
|
this.logger.error('Failed to initialize QM operations', { error });
|
|
});
|
|
}
|
|
|
|
/**
|
|
* SESSIONS
|
|
*/
|
|
@ScheduledOperation('check-sessions', '*/1 * * * *', {
|
|
priority: 8,
|
|
immediately: true,
|
|
description: 'Check and maintain QM sessions every 1 minutes',
|
|
})
|
|
checkSessions = checkSessions;
|
|
|
|
@Operation('create-session')
|
|
createSession = createSession;
|
|
|
|
/**
|
|
* SYMBOLS
|
|
*/
|
|
@Operation('search-symbols')
|
|
searchSymbols = searchSymbols;
|
|
|
|
@Disabled()
|
|
@ScheduledOperation('spider-symbols', '0 0 * * 0', {
|
|
priority: 9,
|
|
immediately: false,
|
|
description: 'Weekly comprehensive symbol search using QM API spider - runs every Saturday at midnight'
|
|
})
|
|
spiderSymbol = spiderSymbol;
|
|
|
|
/**
|
|
* EXCHANGE STATS & DEDUPLICATION
|
|
*/
|
|
@Operation('update-exchange-stats')
|
|
updateExchangeStats = updateExchangeStats;
|
|
|
|
@Operation('deduplicate-symbols')
|
|
deduplicateSymbols = deduplicateSymbols;
|
|
|
|
@Operation('update-exchange-stats-and-deduplicate')
|
|
updateExchangeStatsAndDeduplicate = updateExchangeStatsAndDeduplicate;
|
|
|
|
@ScheduledOperation('schedule-exchange-stats-and-dedup', '0 1 * * *', {
|
|
priority: 7,
|
|
immediately: false,
|
|
description: 'Update exchange statistics and deduplicate symbols daily at 1 AM'
|
|
})
|
|
scheduleExchangeStatsAndDedup = updateExchangeStatsAndDeduplicate;
|
|
|
|
/**
|
|
* SYMBOL INFO
|
|
*/
|
|
@Operation('update-symbol-info')
|
|
updateSymbolInfo = updateSymbolInfo;
|
|
|
|
// @Disabled()
|
|
@ScheduledOperation('schedule-symbol-info-updates', '0 */6 * * *', {
|
|
priority: 7,
|
|
immediately: false,
|
|
description: 'Check for symbols needing info updates every 6 hours'
|
|
})
|
|
scheduleSymbolInfoUpdates = scheduleSymbolInfoUpdates;
|
|
|
|
/**
|
|
* FINANCIALS
|
|
*/
|
|
@Operation('update-financials')
|
|
updateFinancials = updateFinancials;
|
|
|
|
// @Disabled()
|
|
@ScheduledOperation('schedule-financials-updates', '0 2 * * *', {
|
|
priority: 6,
|
|
immediately: false,
|
|
description: 'Check for symbols needing financials updates daily at 2 AM'
|
|
})
|
|
scheduleFinancialsUpdates = scheduleFinancialsUpdates;
|
|
|
|
/**
|
|
* EVENTS (Dividends, Splits, Earnings)
|
|
*/
|
|
@Operation('update-events')
|
|
updateEvents = updateEvents;
|
|
|
|
// @Disabled()
|
|
@ScheduledOperation('schedule-events-updates', '0 3 * * *', {
|
|
priority: 6,
|
|
immediately: false,
|
|
description: 'Check for symbols needing events updates daily at 3 AM'
|
|
})
|
|
scheduleEventsUpdates = scheduleEventsUpdates;
|
|
|
|
/**
|
|
* FILINGS
|
|
*/
|
|
@Operation('update-filings')
|
|
updateFilings = updateFilings;
|
|
|
|
@Disabled()
|
|
@ScheduledOperation('schedule-filings-updates', '0 */8 * * *', {
|
|
priority: 5,
|
|
immediately: false,
|
|
description: 'Check for symbols needing filings updates every 8 hours'
|
|
})
|
|
scheduleFilingsUpdates = scheduleFilingsUpdates;
|
|
|
|
/**
|
|
* PRICE DATA
|
|
*/
|
|
@Operation('update-prices')
|
|
updatePrices = updatePrices;
|
|
|
|
// @Disabled()
|
|
@ScheduledOperation('schedule-price-updates', '0 */6 * * *', {
|
|
priority: 8,
|
|
immediately: false,
|
|
description: 'Check for symbols needing price updates every 6 hours'
|
|
})
|
|
schedulePriceUpdates = schedulePriceUpdates;
|
|
|
|
/**
|
|
* INTRADAY DATA
|
|
*/
|
|
@Operation('update-intraday-bars')
|
|
updateIntradayBars = updateIntradayBars;
|
|
|
|
@Disabled()
|
|
@ScheduledOperation('schedule-intraday-updates', '*/30 * * * *', {
|
|
priority: 9,
|
|
immediately: false,
|
|
description: 'Check for symbols needing intraday updates every 30 minutes'
|
|
})
|
|
scheduleIntradayUpdates = scheduleIntradayUpdates;
|
|
} |