feat: Unraid deploy, dealer-flow heatmap, confluence zones, 13F capture
Ship Node production images, Unraid compose, and Gitea CI/CD (test then push registry images; cron script if no runner). Rebuild dealer flow as a heatmap-first map with integrity gates and chart helpers. Add confluence zone rules, session clock, capture evidence, and tighter 13F/queue/options paths, plus the matching UI and tests.
This commit is contained in:
@@ -53,6 +53,11 @@ export interface CandleResolution {
|
||||
*/
|
||||
export interface CandleProvider {
|
||||
resolve(symbol: string, granularity: SlotGranularity): Promise<CandleResolution>;
|
||||
/**
|
||||
* Honest historical cut: candles with ts <= asOf only. Never folds a live quote.
|
||||
* Used by replay so a past evaluation cannot see tomorrow's close.
|
||||
*/
|
||||
resolveAsOf(symbol: string, granularity: SlotGranularity, asOf: string): Promise<CandleResolution>;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -173,4 +178,22 @@ export class CacheCandleProvider implements CandleProvider {
|
||||
isStale,
|
||||
};
|
||||
}
|
||||
|
||||
async resolveAsOf(symbol: string, granularity: SlotGranularity, asOf: string): Promise<CandleResolution> {
|
||||
const sym = symbol.toUpperCase();
|
||||
const cutoff = asOf.slice(0, 10);
|
||||
const entry = await this._cache.get<PriceCandle[]>(`yfinance:candles:${sym}:${granularity}`);
|
||||
const stored = (entry?.value ?? []).slice();
|
||||
const candles = stored.filter((c) => (c.ts ?? '').slice(0, 10) <= cutoff);
|
||||
const lastTs = candles.length > 0 ? (candles[candles.length - 1].ts ?? '').slice(0, 10) : '';
|
||||
return {
|
||||
symbol: sym,
|
||||
granularity,
|
||||
candles,
|
||||
asOf: lastTs || cutoff,
|
||||
lastBar: 'yfinance',
|
||||
realtimeFolded: false,
|
||||
isStale: entry?.isStale ?? true,
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user