borsa / nextjs-app /src /components /TechnicalIndicators.tsx
veteroner's picture
fix: ruthless audit v2 - 19 US market issues resolved
fdbd2ea
'use client'
import { TechnicalIndicator } from '@/types'
export function TechnicalIndicators({ indicators, market = 'bist' }: { indicators: TechnicalIndicator; market?: 'bist' | 'us' }) {
const isUS = market === 'us'
const dateText = (() => {
const raw = indicators?.date
if (!raw) return '-'
const d = new Date(String(raw))
return Number.isFinite(d.getTime()) ? d.toLocaleDateString(isUS ? 'en-US' : 'tr-TR') : '-'
})()
return (
<div className="rounded-lg p-6">
<h2 className="text-lg font-bold text-gray-200 mb-6">{isUS ? 'Technical Indicators' : 'Teknik Göstergeler'}</h2>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{/* Moving Averages */}
<IndicatorGroup title={isUS ? 'Moving Averages' : 'Hareketli Ortalamalar'}>
<IndicatorItem label="SMA 5" value={indicators.sma_5} />
<IndicatorItem label="SMA 10" value={indicators.sma_10} />
<IndicatorItem label="SMA 20" value={indicators.sma_20} />
<IndicatorItem label="SMA 50" value={indicators.sma_50} />
<IndicatorItem label="SMA 200" value={indicators.sma_200} />
<IndicatorItem label="EMA 12" value={indicators.ema_12} />
<IndicatorItem label="EMA 26" value={indicators.ema_26} />
</IndicatorGroup>
{/* Oscillators */}
<IndicatorGroup title={isUS ? 'Oscillators' : 'Osilatörler'}>
<IndicatorItem
label="RSI (14)"
value={indicators.rsi_14}
colorize={(val) =>
val > 70 ? 'text-red-400' :
val < 30 ? 'text-green-400' :
'text-gray-200'
}
/>
<IndicatorItem label="MACD" value={indicators.macd} precision={4} />
<IndicatorItem label="MACD Signal" value={indicators.macd_signal} precision={4} />
<IndicatorItem label="MACD Histogram" value={indicators.macd_histogram} precision={4} />
<IndicatorItem label="Stochastic K" value={indicators.stochastic_k} />
<IndicatorItem label="Stochastic D" value={indicators.stochastic_d} />
<IndicatorItem label="Williams %R" value={indicators.williams_r} />
<IndicatorItem label="CCI (20)" value={indicators.cci_20} precision={2} />
{'mfi_14' in indicators && (
<IndicatorItem label="MFI (14)" value={indicators.mfi_14 ?? null} precision={2} />
)}
{'roc_10' in indicators && (
<IndicatorItem label="ROC (10)" value={indicators.roc_10 ?? null} precision={2} />
)}
{'momentum_10' in indicators && (
<IndicatorItem label="Momentum (10)" value={indicators.momentum_10 ?? null} precision={2} />
)}
</IndicatorGroup>
{/* Volatility */}
<IndicatorGroup title={isUS ? 'Volatility' : 'Volatilite'}>
<IndicatorItem label={isUS ? 'Bollinger Upper' : 'Bollinger Üst'} value={indicators.bollinger_upper} />
<IndicatorItem label={isUS ? 'Bollinger Middle' : 'Bollinger Orta'} value={indicators.bollinger_middle} />
<IndicatorItem label={isUS ? 'Bollinger Lower' : 'Bollinger Alt'} value={indicators.bollinger_lower} />
<IndicatorItem label="ATR (14)" value={indicators.atr_14} precision={4} />
{'parabolic_sar' in indicators && (
<IndicatorItem label="PSAR" value={indicators.parabolic_sar ?? null} precision={4} />
)}
</IndicatorGroup>
</div>
<div className="mt-4 pt-4 border-t border-gray-700 text-sm text-gray-500">
{isUS ? 'Last updated:' : 'Son güncelleme:'} {dateText}
</div>
</div>
)
}
function IndicatorGroup({
title,
children
}: {
title: string
children: React.ReactNode
}) {
return (
<div className="space-y-3">
<h3 className="font-semibold text-gray-400 text-sm uppercase tracking-wide">
{title}
</h3>
<div className="space-y-2">
{children}
</div>
</div>
)
}
function IndicatorItem({
label,
value,
precision = 2,
colorize
}: {
label: string
value: number | null
precision?: number
colorize?: (value: number) => string
}) {
const displayValue = value !== null && value !== undefined
? value.toFixed(precision)
: '-'
const colorClass = value !== null && colorize
? colorize(value)
: 'text-gray-200'
return (
<div className="flex items-center justify-between py-1">
<span className="text-sm text-gray-400">{label}</span>
<span className={`text-sm font-semibold font-mono ${colorClass}`}>
{displayValue}
</span>
</div>
)
}