feat: add confluence.signalHistory API route
Returns signal fire history for a symbol (last 6 months) with slot names and body types. Used by the upcoming confluence chart to plot signal markers on price data.
This commit is contained in:
@@ -33,7 +33,7 @@ import { computeOwnershipPercentages, fetchAndPersistFloat } from '../services/s
|
|||||||
import { EdgarAdapter } from '../adapters/EdgarAdapter.ts';
|
import { EdgarAdapter } from '../adapters/EdgarAdapter.ts';
|
||||||
import { OptionsAdapter, parseOptionChainRows } from '../adapters/OptionsAdapter.ts';
|
import { OptionsAdapter, parseOptionChainRows } from '../adapters/OptionsAdapter.ts';
|
||||||
import type { OptionChainRow, OptionGreeks } from '../adapters/OptionsAdapter.ts';
|
import type { OptionChainRow, OptionGreeks } from '../adapters/OptionsAdapter.ts';
|
||||||
import { CONFLUENCE_SLOTS, slotsByFamily, type SlotFamily } from '../confluence/confluenceSlots.ts';
|
import { CONFLUENCE_SLOTS, slotsByFamily, type SlotFamily, confluenceslotById } from '../confluence/confluenceSlots.ts';
|
||||||
import { CONFLUENCE_SLOT_IDS } from '../confluence/confluenceSlots.ts';
|
import { CONFLUENCE_SLOT_IDS } from '../confluence/confluenceSlots.ts';
|
||||||
import { ConfluenceRepository, rackFromSlots } from '../db/confluenceRepository.ts';
|
import { ConfluenceRepository, rackFromSlots } from '../db/confluenceRepository.ts';
|
||||||
import { runSlotBacktest, signalHistoryToStats, type ConfluenceFireEvent } from '../confluence/confluenceBacktest.ts';
|
import { runSlotBacktest, signalHistoryToStats, type ConfluenceFireEvent } from '../confluence/confluenceBacktest.ts';
|
||||||
@@ -5473,6 +5473,32 @@ const confluenceRouter = router({
|
|||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
/** Signal fire history for a symbol (last 6 months). Used by the confluence chart. */
|
||||||
|
signalHistory: publicProcedure
|
||||||
|
.input(z.object({ symbol: z.string().min(1).max(12) }))
|
||||||
|
.query(({ ctx, input }) => {
|
||||||
|
const symbol = input.symbol.toUpperCase();
|
||||||
|
const repo = new ConfluenceRepository(ctx.db);
|
||||||
|
const allFires = repo.listSignalsForSymbol(symbol);
|
||||||
|
// Filter to last 6 months
|
||||||
|
const cutoff = new Date();
|
||||||
|
cutoff.setMonth(cutoff.getMonth() - 6);
|
||||||
|
const cutoffStr = cutoff.toISOString();
|
||||||
|
const fires = allFires
|
||||||
|
.filter((f) => f.firedAt >= cutoffStr)
|
||||||
|
.map((f) => {
|
||||||
|
const meta = confluenceslotById.get(f.slotId);
|
||||||
|
return {
|
||||||
|
slotId: f.slotId,
|
||||||
|
slotName: meta?.name ?? f.slotId,
|
||||||
|
body: (meta?.body ?? 'bull') as 'bull' | 'bear' | 'exit',
|
||||||
|
firedAt: f.firedAt,
|
||||||
|
qualityAtFire: f.qualityAtFire,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return { fires };
|
||||||
|
}),
|
||||||
|
|
||||||
/** Create or update a user-owned rack. */
|
/** Create or update a user-owned rack. */
|
||||||
saveRack: protectedProcedure
|
saveRack: protectedProcedure
|
||||||
.input(z.object({
|
.input(z.object({
|
||||||
|
|||||||
@@ -1472,6 +1472,16 @@ export const api = {
|
|||||||
}>("confluence.backtest", { symbol, ...(opts?.weeks ? { weeks: opts.weeks } : {}) }),
|
}>("confluence.backtest", { symbol, ...(opts?.weeks ? { weeks: opts.weeks } : {}) }),
|
||||||
scorecard: (symbol?: string) =>
|
scorecard: (symbol?: string) =>
|
||||||
trpcQuery<{ slots: unknown[]; note: string }>("confluence.scorecard", symbol ? { symbol } : {}),
|
trpcQuery<{ slots: unknown[]; note: string }>("confluence.scorecard", symbol ? { symbol } : {}),
|
||||||
|
signalHistory: (symbol: string) =>
|
||||||
|
trpcQuery<{
|
||||||
|
fires: Array<{
|
||||||
|
slotId: string;
|
||||||
|
slotName: string;
|
||||||
|
body: 'bull' | 'bear' | 'exit';
|
||||||
|
firedAt: string;
|
||||||
|
qualityAtFire: string;
|
||||||
|
}>;
|
||||||
|
}>("confluence.signalHistory", { symbol }),
|
||||||
saveRack: (input: { id?: string; name: string; description?: string; slotIds: string[] }) =>
|
saveRack: (input: { id?: string; name: string; description?: string; slotIds: string[] }) =>
|
||||||
trpcMutate<{ id: string; name: string; slotIds: string[]; isSystem: boolean; description: string | null }>("confluence.saveRack", input),
|
trpcMutate<{ id: string; name: string; slotIds: string[]; isSystem: boolean; description: string | null }>("confluence.saveRack", input),
|
||||||
corridorSnapshot: (symbol: string) =>
|
corridorSnapshot: (symbol: string) =>
|
||||||
|
|||||||
Reference in New Issue
Block a user