Files
AITrader/app/agents/technical.ts
T

92 lines
2.4 KiB
TypeScript

import { OpenRouterClient } from "../lib/openrouter";
import type { AnalystReport, AgentSignal, SignalType } from "../types/agents";
export interface TechnicalData {
prices: number[];
sma: number;
ema: number;
rsi: number;
macd: number;
}
export interface TechnicalAnalystConfig {
model?: string;
}
export class TechnicalAnalyst {
private client: OpenRouterClient;
private model: string;
constructor(client: OpenRouterClient, config?: TechnicalAnalystConfig) {
this.client = client;
this.model = config?.model ?? "google/gemini-2.0-flash-exp:free";
}
getModel(): string {
return this.model;
}
async analyze(ticker: string, data: TechnicalData): Promise<AnalystReport> {
const messages = [
{
role: "system" as const,
content:
"You are a technical analyst. Analyze the technical indicators (SMA, EMA, RSI, MACD) for the given ticker and provide a bullish, bearish, or neutral signal with reasoning. Respond in JSON format with 'signal', 'confidence', and 'reasoning' fields.",
},
{
role: "user" as const,
content: `Analyze ${ticker} technical data:
SMA: ${data.sma}
EMA: ${data.ema}
RSI: ${data.rsi}
MACD: ${data.macd}
Prices: ${data.prices.slice(-10).join(", ")}`,
},
];
const response = await this.client.createChatCompletion(
messages,
this.model
);
const parsedResponse = response as {
choices?: Array<{ message?: { content?: string } }>;
};
const content = parsedResponse.choices?.[0]?.message?.content ?? "";
let signal: SignalType = "neutral";
let confidence = 0.5;
let reasoning = content;
try {
const parsed = JSON.parse(content);
if (
parsed.signal === "bullish" ||
parsed.signal === "bearish" ||
parsed.signal === "neutral"
) {
signal = parsed.signal;
confidence = parsed.confidence ?? 0.5;
reasoning = parsed.reasoning ?? content;
}
} catch {
const lowerContent = content.toLowerCase();
if (lowerContent.includes("bullish")) signal = "bullish";
else if (lowerContent.includes("bearish")) signal = "bearish";
}
const agentSignal: AgentSignal = {
agent: "technical",
signal,
confidence,
reasoning,
timestamp: new Date().toISOString(),
};
return {
analyst: "technical",
report: content,
signal: agentSignal,
};
}
}