feat: dealer flow, mirror portfolio (M21), options convexity, FINRA short interest, alert producers, vendor gate
CI / Test & Type-Check (push) Canceled after 0s
CI / Test & Type-Check (push) Canceled after 0s
Snapshot of in-progress module work across multiple slices: - Dealer Flow: dealerExposureEngine, dealerMapService, dealerMapExplain, dealerMapIntegrity, dealerMapReplay, dealerStudyEngine, hanStyleLevels - Mirror Portfolio (M21): fundRepository, captureIngest, mirrorAlertProducers, fund holdings strip, live book, position capture ingest - Options: BSM, NormalizedOptionSurface types, OptionsChainRouter, ConvexityGate, option legs panel - Alert producers: vixLevel, rotation, thesis, unlock, portfolioRisk, mirror (fund_capture, fund_13f, mirror_diff) - FINRA short interest adapter + queue integration - SEC company tickers adapter + ingest (symbol search index seed) - Vendor gate (rate-limit-first data plane, ADR-0009) - CUSIP registry, reverse 13F refresh, stock float service - LRU cache, portfolio backtest engine - Frontend: dealer-flow, funds, journal, lab, monitor, plan, portfolio, reports, screener, strategies, theses, guided-start, exits, more pages - Volume profile, workspace profile, visibility-aware poll - ADRs 0010 (mirror math not advice), 0011 (symbol search index) - VENDOR_INTEGRATIONS.md, END_USER_TEST.md - .gitignore: exclude DBs, .DS_Store, local config, agent scratch
This commit is contained in:
@@ -4,6 +4,8 @@
|
||||
// Cache with weekly staleness (macro data is slow-moving).
|
||||
|
||||
import type { CacheEntry } from '../cache/CacheRepository.ts';
|
||||
import type { FetchResult } from '../adapters/SourceAdapter.ts';
|
||||
import { vendorFetch } from '../services/vendorGate.ts';
|
||||
|
||||
export interface FredSeries {
|
||||
seriesId: string;
|
||||
@@ -14,7 +16,7 @@ export interface FredSeries {
|
||||
|
||||
export interface FredAdapter {
|
||||
sourceKind: 'fred';
|
||||
fetchOne(key: string): Promise<CacheEntry<FredSeries | unknown>>;
|
||||
fetchOne(key: string): Promise<FetchResult>;
|
||||
series(seriesId: string): Promise<CacheEntry<FredSeries>>;
|
||||
}
|
||||
|
||||
@@ -30,12 +32,17 @@ export class FredAdapterImpl implements FredAdapter {
|
||||
this.apiKey = apiKey ?? process.env.FRED_API_KEY ?? '';
|
||||
}
|
||||
|
||||
async fetchOne(key: string): Promise<CacheEntry<FredSeries | unknown>> {
|
||||
async fetchOne(key: string): Promise<FetchResult> {
|
||||
// key format: "fred:series:{seriesId}"
|
||||
const parts = key.split(':');
|
||||
if (parts.length >= 3 && parts[0] === 'fred' && parts[1] === 'series') {
|
||||
const seriesId = parts[2];
|
||||
return this.series(seriesId);
|
||||
const entry = await this.series(seriesId);
|
||||
return {
|
||||
value: entry.value as FredSeries,
|
||||
ttlClass: 'fred_macro',
|
||||
provenance: entry.provenance ?? { fetchedAt: new Date().toISOString(), sourceKind: 'fred' },
|
||||
};
|
||||
}
|
||||
throw new Error(`Unknown FRED cache key: ${key}`);
|
||||
}
|
||||
@@ -46,7 +53,10 @@ export class FredAdapterImpl implements FredAdapter {
|
||||
}
|
||||
|
||||
const url = `${FRED_BASE}/series/observations?series_id=${seriesId}&api_key=${this.apiKey}&file_type=json&limit=100&sort_order=desc`;
|
||||
const resp = await fetch(url);
|
||||
const resp = await vendorFetch('fred', url, {
|
||||
accept: 'application/json',
|
||||
hostAllowlist: /api\.stlouisfed\.org/i,
|
||||
});
|
||||
if (!resp.ok) {
|
||||
let detail = '';
|
||||
try {
|
||||
@@ -93,4 +103,5 @@ export const FRED_SERIES = {
|
||||
FED_FUNDS: 'FEDFUNDS',
|
||||
HEAVY_TRUCK_SALES: 'HTRUCKSSAAR',
|
||||
MANUFACTURING_ACTIVITY: 'IPMAN',
|
||||
CONSUMER_SENTIMENT: 'UMCSENT',
|
||||
} as const;
|
||||
|
||||
@@ -185,7 +185,7 @@ export function generateMacroCommentary(
|
||||
? shortTermWithEvents(upcomingEvents.join(', '))
|
||||
: SHORT_TERM_NO_EVENTS,
|
||||
longTerm: LONG_TERM_MAP[classification.regime],
|
||||
disclaimer: 'This commentary is for educational purposes only and is not investment advice. '
|
||||
disclaimer: 'Educational observation only. '
|
||||
+ 'Past performance does not guarantee future results. Always do your own research '
|
||||
+ 'before making investment decisions.',
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user