feat: add stock database with prisma for portfolio persistence
- Initialize Prisma with SQLite and Stock model - Create database service layer with singleton client - Add API routes for stock CRUD operations - Integrate database with analyze page to persist ticker entries - Add Playwright tests for stock database functionality
This commit is contained in:
@@ -11,7 +11,7 @@ export class FundamentalsAnalyst {
|
||||
|
||||
constructor(client: OpenRouterClient, config?: FundamentalsConfig) {
|
||||
this.client = client;
|
||||
this.model = config?.model ?? "google/gemini-2.0-flash-exp:free";
|
||||
this.model = config?.model ?? "openai/gpt-oss-120b:free";
|
||||
}
|
||||
|
||||
getModel(): string {
|
||||
|
||||
@@ -11,7 +11,7 @@ export class BullishResearcher {
|
||||
|
||||
constructor(client: OpenRouterClient, model?: string) {
|
||||
this.client = client;
|
||||
this.model = model ?? "google/gemini-2.0-flash-exp:free";
|
||||
this.model = model ?? "openai/gpt-oss-120b:free";
|
||||
}
|
||||
|
||||
async research(ticker: string, reports: AnalystReport[]): Promise<DebateRound> {
|
||||
@@ -48,7 +48,7 @@ export class BearishResearcher {
|
||||
|
||||
constructor(client: OpenRouterClient, model?: string) {
|
||||
this.client = client;
|
||||
this.model = model ?? "google/gemini-2.0-flash-exp:free";
|
||||
this.model = model ?? "openai/gpt-oss-120b:free";
|
||||
}
|
||||
|
||||
async research(ticker: string, reports: AnalystReport[]): Promise<DebateRound> {
|
||||
|
||||
@@ -16,7 +16,7 @@ export class SentimentAnalyst {
|
||||
|
||||
constructor(client: OpenRouterClient, config?: SentimentConfig) {
|
||||
this.client = client;
|
||||
this.model = config?.model ?? "google/gemini-2.0-flash-exp:free";
|
||||
this.model = config?.model ?? "openai/gpt-oss-120b:free";
|
||||
}
|
||||
|
||||
getModel(): string {
|
||||
|
||||
@@ -19,7 +19,7 @@ export class TechnicalAnalyst {
|
||||
|
||||
constructor(client: OpenRouterClient, config?: TechnicalAnalystConfig) {
|
||||
this.client = client;
|
||||
this.model = config?.model ?? "google/gemini-2.0-flash-exp:free";
|
||||
this.model = config?.model ?? "openai/gpt-oss-120b:free";
|
||||
}
|
||||
|
||||
getModel(): string {
|
||||
|
||||
@@ -11,7 +11,7 @@ export class Trader {
|
||||
|
||||
constructor(client: OpenRouterClient, model?: string) {
|
||||
this.client = client;
|
||||
this.model = model ?? "google/gemini-2.0-flash-exp:free";
|
||||
this.model = model ?? "openai/gpt-oss-120b:free";
|
||||
}
|
||||
|
||||
async decide(
|
||||
|
||||
@@ -6,6 +6,11 @@ import { BullishResearcher, BearishResearcher } from "./researchers";
|
||||
import { Trader } from "./trader";
|
||||
import type { AnalystReport, DebateRound, TradingDecision, AgentSignal } from "../types/agents";
|
||||
|
||||
export interface GraphStep {
|
||||
step: "analysts" | "debate" | "trader";
|
||||
data: AnalystReport[] | DebateRound[] | TradingDecision;
|
||||
}
|
||||
|
||||
export class TradingGraph {
|
||||
private client: OpenRouterClient;
|
||||
private model: string;
|
||||
@@ -18,7 +23,7 @@ export class TradingGraph {
|
||||
|
||||
constructor(client: OpenRouterClient, model?: string) {
|
||||
this.client = client;
|
||||
this.model = model ?? "google/gemini-2.0-flash-exp:free";
|
||||
this.model = model ?? "openai/gpt-oss-120b:free";
|
||||
|
||||
this.fundamentalsAnalyst = new FundamentalsAnalyst(client, { model: this.model });
|
||||
this.technicalAnalyst = new TechnicalAnalyst(client, { model: this.model });
|
||||
@@ -36,9 +41,15 @@ export class TradingGraph {
|
||||
sentimentData: { headlines: string[]; source?: "news" | "social" | "stocktwits" };
|
||||
}
|
||||
): Promise<TradingDecision> {
|
||||
console.log(`[TradingGraph] Starting analysis for ${ticker} with model ${this.model}`);
|
||||
|
||||
const reports = await this.runAnalysts(ticker, input);
|
||||
const debates = await this.runDebate(ticker, reports);
|
||||
const decision = await this.trader.decide(ticker, reports, debates);
|
||||
|
||||
console.log(`[TradingGraph] Analysis complete for ${ticker}`);
|
||||
console.log(`[TradingGraph] Decision: ${decision.action} (confidence: ${decision.confidence})`);
|
||||
|
||||
return decision;
|
||||
}
|
||||
|
||||
@@ -50,21 +61,33 @@ export class TradingGraph {
|
||||
sentimentData: { headlines: string[]; source?: "news" | "social" | "stocktwits" };
|
||||
}
|
||||
): Promise<AnalystReport[]> {
|
||||
console.log(`[TradingGraph] Running analysts for ${ticker}...`);
|
||||
|
||||
const [fundamentals, technical, sentiment] = await Promise.all([
|
||||
this.fundamentalsAnalyst.analyze(ticker, input.financialData),
|
||||
this.technicalAnalyst.analyze(ticker, input.technicalData),
|
||||
this.sentimentAnalyst.analyze(ticker, input.sentimentData),
|
||||
]);
|
||||
|
||||
console.log(`[TradingGraph] Analyst reports complete:`, {
|
||||
fundamentals: fundamentals.signal,
|
||||
technical: technical.signal,
|
||||
sentiment: sentiment.signal,
|
||||
});
|
||||
|
||||
return [fundamentals, technical, sentiment];
|
||||
}
|
||||
|
||||
private async runDebate(ticker: string, reports: AnalystReport[]): Promise<DebateRound[]> {
|
||||
console.log(`[TradingGraph] Running debate for ${ticker}...`);
|
||||
|
||||
const [bullish, bearish] = await Promise.all([
|
||||
this.bullishResearcher.research(ticker, reports),
|
||||
this.bearishResearcher.research(ticker, reports),
|
||||
]);
|
||||
|
||||
console.log(`[TradingGraph] Debate complete`);
|
||||
|
||||
return [
|
||||
{
|
||||
bullishView: bullish.bullishView,
|
||||
|
||||
Reference in New Issue
Block a user