feat: implement comprehensive Technical Analysis fundamentals
- Add TECHNICAL_ANALYSIS_BASICS.md with complete indicator explanations - Add TA_QUICK_REFERENCE.md for quick lookup - Enhance AI analysis prompts with TA principles integration - Improve JSON response structure with dedicated analysis sections - Add cross-layout consensus analysis for higher confidence signals - Include timeframe-specific risk assessment and position sizing - Add educational content for RSI, MACD, EMAs, Stochastic RSI, VWAP, OBV - Implement layout-specific analysis (AI vs DIY layouts) - Add momentum, trend, and volume analysis separation - Update README with TA documentation references - Create implementation summary and test files
This commit is contained in:
@@ -63,26 +63,45 @@ export default function ScreenshotGallery({
|
||||
return `${tf}m`
|
||||
}
|
||||
|
||||
// Create sorted screenshot data with timeframes
|
||||
// Helper function to detect layout from filename
|
||||
const detectLayout = (filename: string) => {
|
||||
if (filename.includes('_ai_')) return 'AI'
|
||||
if (filename.includes('_diy_') || filename.includes('_Diy module_')) return 'DIY'
|
||||
return 'Default'
|
||||
}
|
||||
|
||||
// Create screenshot data with layout and timeframe information
|
||||
const screenshotData = screenshots.map((screenshot, index) => {
|
||||
const screenshotUrl = typeof screenshot === 'string'
|
||||
? screenshot
|
||||
: (screenshot as any)?.url || String(screenshot)
|
||||
const filename = screenshotUrl.split('/').pop() || ''
|
||||
const timeframe = timeframes[index] || extractTimeframeFromFilename(filename)
|
||||
const layout = detectLayout(filename)
|
||||
|
||||
return {
|
||||
screenshot,
|
||||
screenshotUrl,
|
||||
filename,
|
||||
timeframe,
|
||||
layout,
|
||||
index,
|
||||
sortOrder: timeframeToMinutes(timeframe)
|
||||
}
|
||||
})
|
||||
|
||||
// Sort by timeframe (smallest to largest)
|
||||
const sortedData = screenshotData.sort((a, b) => a.sortOrder - b.sortOrder)
|
||||
// Group screenshots by layout
|
||||
const aiScreenshots = screenshotData
|
||||
.filter(item => item.layout === 'AI')
|
||||
.sort((a, b) => a.sortOrder - b.sortOrder)
|
||||
|
||||
const diyScreenshots = screenshotData
|
||||
.filter(item => item.layout === 'DIY')
|
||||
.sort((a, b) => a.sortOrder - b.sortOrder)
|
||||
|
||||
const defaultScreenshots = screenshotData
|
||||
.filter(item => item.layout === 'Default')
|
||||
.sort((a, b) => a.sortOrder - b.sortOrder)
|
||||
|
||||
// Helper function to format screenshot URL
|
||||
const formatScreenshotUrl = (screenshot: string | any) => {
|
||||
@@ -94,24 +113,24 @@ export default function ScreenshotGallery({
|
||||
return `/api/image?file=${filename}`
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Gallery Grid */}
|
||||
<div className="mt-6 p-4 bg-gradient-to-br from-purple-500/10 to-indigo-500/10 border border-purple-500/30 rounded-lg">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<h4 className="text-lg font-bold text-white flex items-center">
|
||||
<span className="w-6 h-6 bg-gradient-to-br from-purple-400 to-purple-600 rounded-lg flex items-center justify-center mr-2 text-sm">
|
||||
📸
|
||||
</span>
|
||||
Chart Screenshots
|
||||
</h4>
|
||||
// Helper function to render a screenshot row
|
||||
const renderScreenshotRow = (screenshots: any[], title: string, icon: string, bgGradient: string) => {
|
||||
if (screenshots.length === 0) return null
|
||||
|
||||
return (
|
||||
<div className="mb-6">
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
<h5 className={`text-sm font-bold text-white flex items-center bg-gradient-to-r ${bgGradient} px-3 py-1 rounded-lg`}>
|
||||
<span className="mr-2">{icon}</span>
|
||||
{title}
|
||||
</h5>
|
||||
<div className="text-xs text-gray-400">
|
||||
{sortedData.length} captured • Click to enlarge
|
||||
{screenshots.length} screenshot{screenshots.length !== 1 ? 's' : ''}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
{sortedData.map((item, displayIndex) => {
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-3">
|
||||
{screenshots.map((item, displayIndex) => {
|
||||
const imageUrl = formatScreenshotUrl(item.screenshot)
|
||||
|
||||
return (
|
||||
@@ -124,7 +143,7 @@ export default function ScreenshotGallery({
|
||||
<div className="aspect-video bg-gray-800 flex items-center justify-center relative">
|
||||
<img
|
||||
src={imageUrl}
|
||||
alt={`${symbol} - ${item.timeframe} chart`}
|
||||
alt={`${symbol} - ${item.timeframe} chart (${item.layout} Layout)`}
|
||||
className="w-full h-full object-cover"
|
||||
onError={(e: any) => {
|
||||
const target = e.target as HTMLImageElement
|
||||
@@ -168,6 +187,57 @@ export default function ScreenshotGallery({
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Gallery Grid */}
|
||||
<div className="mt-6 p-4 bg-gradient-to-br from-purple-500/10 to-indigo-500/10 border border-purple-500/30 rounded-lg">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<h4 className="text-lg font-bold text-white flex items-center">
|
||||
<span className="w-6 h-6 bg-gradient-to-br from-purple-400 to-purple-600 rounded-lg flex items-center justify-center mr-2 text-sm">
|
||||
📸
|
||||
</span>
|
||||
Chart Screenshots
|
||||
</h4>
|
||||
<div className="text-xs text-gray-400">
|
||||
{screenshotData.length} captured • Click to enlarge
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* AI Layout Row */}
|
||||
{renderScreenshotRow(
|
||||
aiScreenshots,
|
||||
'AI Layout - RSI, EMAs, MACD',
|
||||
'🤖',
|
||||
'from-blue-500/30 to-cyan-500/30'
|
||||
)}
|
||||
|
||||
{/* DIY Layout Row */}
|
||||
{renderScreenshotRow(
|
||||
diyScreenshots,
|
||||
'DIY Module Layout - Stochastic RSI, VWAP, OBV',
|
||||
'🔧',
|
||||
'from-orange-500/30 to-yellow-500/30'
|
||||
)}
|
||||
|
||||
{/* Default Layout Row (if any) */}
|
||||
{renderScreenshotRow(
|
||||
defaultScreenshots,
|
||||
'Default Layout',
|
||||
'📊',
|
||||
'from-purple-500/30 to-indigo-500/30'
|
||||
)}
|
||||
|
||||
{/* No Screenshots Message */}
|
||||
{screenshotData.length === 0 && (
|
||||
<div className="text-center py-8 text-gray-400">
|
||||
<div className="text-3xl mb-2">📊</div>
|
||||
<div className="text-sm">No screenshots available</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Enlarged Image Modal */}
|
||||
{enlargedImage && (
|
||||
|
||||
Reference in New Issue
Block a user