borsa / nextjs-app /src /lib /technical /summary.ts
veteroner's picture
feat: live position monitoring with charts + trading system production ready
656ac31
import type { TrendAnalysis, ChartFormation, CandlestickPattern, AnalysisSummary } from './types'
export function buildSummary(
rsiVal: number | null,
macdHist: number | null,
trend: TrendAnalysis,
formations: ChartFormation[],
candlePatterns: CandlestickPattern[],
bbPosition: number | null, // 0=below lower, 0.5=middle, 1=above upper
stochK: number | null,
): AnalysisSummary {
let score = 0
const reasons: string[] = []
// RSI
if (rsiVal !== null) {
if (rsiVal < 30) { score += 20; reasons.push(`RSI aşırı satım bölgesinde (${rsiVal.toFixed(1)}) - alım fırsatı`) }
else if (rsiVal < 40) { score += 10; reasons.push(`RSI düşük bölgede (${rsiVal.toFixed(1)})`) }
else if (rsiVal > 70) { score -= 20; reasons.push(`RSI aşırı alım bölgesinde (${rsiVal.toFixed(1)}) - satış baskısı olabilir`) }
else if (rsiVal > 60) { score -= 5; reasons.push(`RSI yüksek bölgede (${rsiVal.toFixed(1)})`) }
}
// MACD
if (macdHist !== null) {
if (macdHist > 0) { score += 15; reasons.push('MACD histogram pozitif - yükseliş momentumu') }
else { score -= 15; reasons.push('MACD histogram negatif - düşüş momentumu') }
}
// Trend
score += (trend.strength - 50) * 0.5
if (trend.shortTerm === 'Yükseliş') { score += 10; reasons.push('Kısa vadeli yükseliş trendinde') }
else if (trend.shortTerm === 'Düşüş') { score -= 10; reasons.push('Kısa vadeli düşüş trendinde') }
// Bollinger
if (bbPosition !== null) {
if (bbPosition < 0.2) { score += 15; reasons.push('Bollinger alt bandına yakın - potansiyel dönüş noktası') }
else if (bbPosition > 0.8) { score -= 10; reasons.push('Bollinger üst bandına yakın - aşırı alım') }
}
// Stochastic
if (stochK !== null) {
if (stochK < 20) { score += 10; reasons.push('Stokastik aşırı satım bölgesinde') }
else if (stochK > 80) { score -= 10; reasons.push('Stokastik aşırı alım bölgesinde') }
}
// Chart formations
for (const f of formations.slice(0, 3)) {
if (f.type === 'bullish') { score += 15; reasons.push(`${f.name} formasyonu tespit edildi (yükseliş)`) }
else if (f.type === 'bearish') { score -= 15; reasons.push(`${f.name} formasyonu tespit edildi (düşüş)`) }
}
// Recent candle patterns
const recent = candlePatterns.filter((p) => p.index >= candlePatterns.length - 5)
for (const p of recent.slice(0, 3)) {
if (p.type === 'bullish') { score += 8; reasons.push(`${p.name} mum formasyonu (yükseliş)`) }
else if (p.type === 'bearish') { score -= 8; reasons.push(`${p.name} mum formasyonu (düşüş)`) }
}
score = Math.max(-100, Math.min(100, Math.round(score)))
let signal: AnalysisSummary['overallSignal'] = 'BEKLE'
if (score >= 40) signal = 'GÜÇLÜ AL'
else if (score >= 15) signal = 'AL'
else if (score <= -40) signal = 'GÜÇLÜ SAT'
else if (score <= -15) signal = 'SAT'
return { overallSignal: signal, score, reasons }
}