seawolf2357 commited on
Commit
c93cf9e
Β·
verified Β·
1 Parent(s): 96479b6

Update templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +130 -19
templates/index.html CHANGED
@@ -143,6 +143,7 @@
143
  .research-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; flex-wrap: wrap; gap: 10px; }
144
  .research-ticker { font-size: 1.8em; font-weight: 800; background: linear-gradient(135deg, #00d9ff, #00ff88); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
145
  .rating-badge { padding: 10px 20px; border-radius: 25px; font-size: 1em; font-weight: 700; }
 
146
  .rating-buy { background: #2ed573; color: #1a1a2e; }
147
  .rating-hold { background: #ffa502; color: #1a1a2e; }
148
  .rating-sell { background: #ff4757; color: white; }
@@ -423,21 +424,28 @@
423
  <div class="metrics-grid">
424
  <div class="metric-card">
425
  <div class="metric-label">ν˜„μž¬κ°€</div>
426
- <div class="metric-value">${{ "{:,.2f}".format(report.current_price) }}</div>
427
- </div>
428
- <div class="metric-card">
429
- <div class="metric-label">λͺ©ν‘œκ°€</div>
430
- <div class="metric-value" style="color: #00ff88;">${{ "{:,.2f}".format(report.target_price) }}</div>
431
- </div>
432
- <div class="metric-card">
433
- <div class="metric-label">μƒμŠΉμ—¬λ ₯</div>
434
- <div class="metric-value" style="color: #00d9ff;">+{{ report.upside }}%</div>
435
- </div>
436
- <div class="metric-card">
437
- <div class="metric-label">리슀크</div>
438
- <div class="metric-value">{{ report.risk_level }}</div>
 
 
 
 
 
 
 
 
439
  </div>
440
- </div>
441
  <div class="soma-agent soma-supervisor">
442
  <div class="soma-header">
443
  <div class="soma-icon" style="background: #9b59b6;">πŸ‘”</div>
@@ -668,8 +676,51 @@
668
  <div class="metric-card"><div class="metric-label">ν˜„μž¬κ°€</div><div class="metric-value" id="result-current-price">-</div></div>
669
  <div class="metric-card"><div class="metric-label">λͺ©ν‘œκ°€</div><div class="metric-value" style="color: #00ff88;" id="result-target-price">-</div></div>
670
  <div class="metric-card"><div class="metric-label">투자의견</div><div class="metric-value" style="color: #00d9ff;" id="result-rating">-</div></div>
671
- <div class="metric-card"><div class="metric-label">μƒμŠΉμ—¬λ ₯</div><div class="metric-value" style="color: #2ed573;" id="result-upside">-</div></div>
672
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
673
  <div class="deep-section" style="background: rgba(0,217,255,0.1); border: 1px solid rgba(0,217,255,0.3);"><h3>πŸ“‹ 핡심 μš”μ•½</h3><div class="content" id="result-executive-summary"></div></div>
674
  <div class="deep-section"><h3>🏒 νšŒμ‚¬ κ°œμš”</h3><div class="content" id="result-company-overview"></div></div>
675
  <div class="deep-section"><h3>πŸ’° 재무 뢄석</h3><div class="content" id="result-financial-analysis"></div></div>
@@ -1399,6 +1450,46 @@
1399
  return text.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>').replace(/\n/g, '<br>');
1400
  }
1401
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1402
  function initAnalysisCharts(report) {
1403
  [metricsChartInstance, priceChartInstance, riskChartInstance, growthChartInstance].forEach(c => c && c.destroy());
1404
  const cp = report.current_price || 100, tp = report.target_price || 112;
@@ -1504,7 +1595,9 @@
1504
  document.getElementById('result-current-price').textContent = report.current_price ? `$${report.current_price.toLocaleString()}` : '-';
1505
  document.getElementById('result-target-price').textContent = report.target_price ? `$${report.target_price.toLocaleString()}` : '-';
1506
  document.getElementById('result-rating').textContent = report.rating || 'Buy';
1507
- document.getElementById('result-upside').textContent = report.upside ? `+${report.upside}%` : '-';
 
 
1508
 
1509
  setTimeout(() => initAnalysisCharts(report), 100);
1510
 
@@ -1602,10 +1695,28 @@
1602
  <div class="metric-label">투자의견</div>
1603
  <div class="metric-value">${document.getElementById('result-rating')?.textContent || '-'}</div>
1604
  </div>
1605
- <div class="metric">
1606
- <div class="metric-label">μƒμŠΉμ—¬λ ₯</div>
1607
- <div class="metric-value">${document.getElementById('result-upside')?.textContent || '-'}</div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1608
  </div>
 
1609
  </div>
1610
 
1611
  <div class="section">
 
143
  .research-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; flex-wrap: wrap; gap: 10px; }
144
  .research-ticker { font-size: 1.8em; font-weight: 800; background: linear-gradient(135deg, #00d9ff, #00ff88); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
145
  .rating-badge { padding: 10px 20px; border-radius: 25px; font-size: 1em; font-weight: 700; }
146
+ .rating-strong-buy { background: linear-gradient(135deg, #00ff88, #00d9ff); color: #1a1a2e; }
147
  .rating-buy { background: #2ed573; color: #1a1a2e; }
148
  .rating-hold { background: #ffa502; color: #1a1a2e; }
149
  .rating-sell { background: #ff4757; color: white; }
 
424
  <div class="metrics-grid">
425
  <div class="metric-card">
426
  <div class="metric-label">ν˜„μž¬κ°€</div>
427
+ <div class="metric-value">${{ "{:,.2f}".format(report.current_price) }}</div>
428
+ </div>
429
+ <div class="metric-card">
430
+ <div class="metric-label">λͺ©ν‘œκ°€</div>
431
+ <div class="metric-value" style="color: #00ff88;">${{ "{:,.2f}".format(report.target_price) }}</div>
432
+ </div>
433
+ <div class="metric-card">
434
+ <div class="metric-label">πŸ“‰ ν•˜λ½ 리슀크</div>
435
+ <div class="metric-value" style="color: #ff4757;">{{ report.get('expected_downside', -10) }}%</div>
436
+ <div style="font-size: 0.7em; color: #888;">{{ report.get('down_probability', 45) }}% ν™•λ₯ </div>
437
+ </div>
438
+ <div class="metric-card" style="background: rgba(0,217,255,0.15); border: 1px solid rgba(0,217,255,0.3);">
439
+ <div class="metric-label">🎯 κΈ°λŒ€ 수읡</div>
440
+ <div class="metric-value" style="color: #00d9ff;">{% set pred = report.get('base_prediction', report.get('upside', 8)) %}{% if pred >= 0 %}+{% endif %}{{ pred }}%</div>
441
+ <div style="font-size: 0.7em; color: #888;">R/R {{ report.get('risk_reward', 1.5) }}:1</div>
442
+ </div>
443
+ <div class="metric-card">
444
+ <div class="metric-label">πŸ“ˆ μƒμŠΉ 잠재λ ₯</div>
445
+ <div class="metric-value" style="color: #00ff88;">+{{ report.get('expected_upside', 15) }}%</div>
446
+ <div style="font-size: 0.7em; color: #888;">{{ report.get('up_probability', 55) }}% ν™•λ₯ </div>
447
+ </div>
448
  </div>
 
449
  <div class="soma-agent soma-supervisor">
450
  <div class="soma-header">
451
  <div class="soma-icon" style="background: #9b59b6;">πŸ‘”</div>
 
676
  <div class="metric-card"><div class="metric-label">ν˜„μž¬κ°€</div><div class="metric-value" id="result-current-price">-</div></div>
677
  <div class="metric-card"><div class="metric-label">λͺ©ν‘œκ°€</div><div class="metric-value" style="color: #00ff88;" id="result-target-price">-</div></div>
678
  <div class="metric-card"><div class="metric-label">투자의견</div><div class="metric-value" style="color: #00d9ff;" id="result-rating">-</div></div>
 
679
  </div>
680
+
681
+ <!-- 탄λ ₯μ„± 예츑 μ‹œκ°μ  UI -->
682
+ <div class="elasticity-container" style="margin-bottom: 25px; padding: 20px; background: rgba(0,0,0,0.3); border-radius: 15px; border: 1px solid rgba(255,255,255,0.1);">
683
+ <h4 style="color: #00d9ff; margin-bottom: 15px; text-align: center;">πŸ“Š 탄λ ₯μ„± 예츑</h4>
684
+
685
+ <!-- μ‹œκ°μ  λ°” -->
686
+ <div class="elasticity-bar-container" style="position: relative; height: 50px; margin: 20px 0;">
687
+ <div class="elasticity-scale" style="display: flex; justify-content: space-between; font-size: 11px; color: #888; margin-bottom: 5px;">
688
+ <span id="elasticity-min">-30%</span>
689
+ <span>0%</span>
690
+ <span id="elasticity-max">+40%</span>
691
+ </div>
692
+ <div class="elasticity-track" style="position: relative; height: 20px; background: linear-gradient(to right, #ff4757 0%, #ff4757 40%, #888 40%, #888 45%, #00ff88 45%, #00ff88 100%); border-radius: 10px; overflow: hidden;">
693
+ <!-- 예츑 λ²”μœ„ ν‘œμ‹œ -->
694
+ <div id="elasticity-range" style="position: absolute; height: 100%; background: rgba(0,217,255,0.4); border: 2px solid #00d9ff; border-radius: 8px;"></div>
695
+ <!-- 기본 예츑치 마컀 -->
696
+ <div id="elasticity-marker" style="position: absolute; top: -8px; width: 4px; height: 36px; background: #fff; border-radius: 2px; box-shadow: 0 0 10px rgba(255,255,255,0.8);"></div>
697
+ </div>
698
+ </div>
699
+
700
+ <!-- 수치 ν‘œμ‹œ - ν™•λ₯  κ°•μ‘° -->
701
+ <div style="display: flex; justify-content: space-between; gap: 15px; margin-top: 20px;">
702
+ <div style="flex: 1; text-align: center; padding: 15px; background: rgba(255,71,87,0.15); border-radius: 10px; border: 1px solid rgba(255,71,87,0.3);">
703
+ <div style="font-size: 12px; color: #ff6b7a; margin-bottom: 5px;">πŸ“‰ ν•˜λ½ 리슀크</div>
704
+ <div id="result-downside" style="font-size: 22px; font-weight: bold; color: #ff4757;">-</div>
705
+ <div style="font-size: 11px; color: #888; margin-top: 3px;"><span id="result-down-prob">-</span> ν™•λ₯ </div>
706
+ </div>
707
+ <div style="flex: 1; text-align: center; padding: 15px; background: rgba(0,217,255,0.15); border-radius: 10px; border: 1px solid rgba(0,217,255,0.3);">
708
+ <div style="font-size: 12px; color: #00d9ff; margin-bottom: 5px;">🎯 κΈ°λŒ€ 수읡</div>
709
+ <div id="result-prediction" style="font-size: 24px; font-weight: bold; color: #00d9ff;">-</div>
710
+ <div style="font-size: 11px; color: #888; margin-top: 3px;">R/R <span id="result-rr">-</span></div>
711
+ </div>
712
+ <div style="flex: 1; text-align: center; padding: 15px; background: rgba(0,255,136,0.15); border-radius: 10px; border: 1px solid rgba(0,255,136,0.3);">
713
+ <div style="font-size: 12px; color: #00ff88; margin-bottom: 5px;">πŸ“ˆ μƒμŠΉ 잠재λ ₯</div>
714
+ <div id="result-upside" style="font-size: 22px; font-weight: bold; color: #00ff88;">-</div>
715
+ <div style="font-size: 11px; color: #888; margin-top: 3px;"><span id="result-up-prob">-</span> ν™•λ₯ </div>
716
+ </div>
717
+ </div>
718
+
719
+ <div style="text-align: center; margin-top: 12px; font-size: 11px; color: #666;">
720
+ β€» AI 기반 뢄석이며 μ‹€μ œ 투자 손읡을 보μž₯ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€
721
+ </div>
722
+ </div>
723
+
724
  <div class="deep-section" style="background: rgba(0,217,255,0.1); border: 1px solid rgba(0,217,255,0.3);"><h3>πŸ“‹ 핡심 μš”μ•½</h3><div class="content" id="result-executive-summary"></div></div>
725
  <div class="deep-section"><h3>🏒 νšŒμ‚¬ κ°œμš”</h3><div class="content" id="result-company-overview"></div></div>
726
  <div class="deep-section"><h3>πŸ’° 재무 뢄석</h3><div class="content" id="result-financial-analysis"></div></div>
 
1450
  return text.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>').replace(/\n/g, '<br>');
1451
  }
1452
 
1453
+ function updateElasticityUI(report) {
1454
+ // 탄λ ₯μ„± 데이터 μΆ”μΆœ (κΈ°λ³Έκ°’ μ„€μ •)
1455
+ const upside = report.expected_upside || 15;
1456
+ const downside = report.expected_downside || -10;
1457
+ const prediction = report.base_prediction || report.upside || 8;
1458
+ const upProb = report.up_probability || 55;
1459
+ const downProb = report.down_probability || 45;
1460
+ const riskReward = report.risk_reward || 1.5;
1461
+
1462
+ // 수치 ν‘œμ‹œ
1463
+ document.getElementById('result-upside').textContent = `+${upside}%`;
1464
+ document.getElementById('result-downside').textContent = `${downside}%`;
1465
+ document.getElementById('result-prediction').textContent = prediction >= 0 ? `+${prediction}%` : `${prediction}%`;
1466
+ document.getElementById('result-prediction').style.color = prediction >= 0 ? '#00d9ff' : '#ff4757';
1467
+ document.getElementById('result-up-prob').textContent = `${upProb}%`;
1468
+ document.getElementById('result-down-prob').textContent = `${downProb}%`;
1469
+ document.getElementById('result-rr').textContent = `${riskReward}:1`;
1470
+
1471
+ // μ‹œκ°μ  λ°” μ—…λ°μ΄νŠΈ
1472
+ const minVal = Math.min(downside, -30);
1473
+ const maxVal = Math.max(upside, 40);
1474
+ const range = maxVal - minVal;
1475
+
1476
+ // μŠ€μΌ€μΌ 라벨 μ—…λ°μ΄νŠΈ
1477
+ document.getElementById('elasticity-min').textContent = `${Math.round(minVal)}%`;
1478
+ document.getElementById('elasticity-max').textContent = `+${Math.round(maxVal)}%`;
1479
+
1480
+ // λ²”μœ„ λ°” μœ„μΉ˜ 계산 (downside ~ upside)
1481
+ const rangeLeft = ((downside - minVal) / range) * 100;
1482
+ const rangeRight = ((upside - minVal) / range) * 100;
1483
+ const rangeEl = document.getElementById('elasticity-range');
1484
+ rangeEl.style.left = `${rangeLeft}%`;
1485
+ rangeEl.style.width = `${rangeRight - rangeLeft}%`;
1486
+
1487
+ // κΈ°λ³Έ 예츑 마컀 μœ„μΉ˜
1488
+ const markerPos = ((prediction - minVal) / range) * 100;
1489
+ const markerEl = document.getElementById('elasticity-marker');
1490
+ markerEl.style.left = `calc(${markerPos}% - 2px)`;
1491
+ }
1492
+
1493
  function initAnalysisCharts(report) {
1494
  [metricsChartInstance, priceChartInstance, riskChartInstance, growthChartInstance].forEach(c => c && c.destroy());
1495
  const cp = report.current_price || 100, tp = report.target_price || 112;
 
1595
  document.getElementById('result-current-price').textContent = report.current_price ? `$${report.current_price.toLocaleString()}` : '-';
1596
  document.getElementById('result-target-price').textContent = report.target_price ? `$${report.target_price.toLocaleString()}` : '-';
1597
  document.getElementById('result-rating').textContent = report.rating || 'Buy';
1598
+
1599
+ // 탄λ ₯μ„± 예츑 UI μ—…λ°μ΄νŠΈ
1600
+ updateElasticityUI(report);
1601
 
1602
  setTimeout(() => initAnalysisCharts(report), 100);
1603
 
 
1695
  <div class="metric-label">투자의견</div>
1696
  <div class="metric-value">${document.getElementById('result-rating')?.textContent || '-'}</div>
1697
  </div>
1698
+ </div>
1699
+
1700
+ <div class="section" style="background: #f0f8ff; border-left-color: #0099cc;">
1701
+ <div class="section-title">πŸ“Š 수읡λ₯  전망</div>
1702
+ <div style="display: flex; justify-content: space-around; text-align: center; margin: 15px 0;">
1703
+ <div>
1704
+ <div style="color: #cc0000; font-size: 12px;">πŸ“‰ ν•˜λ½ 리슀크</div>
1705
+ <div style="font-size: 20px; font-weight: bold; color: #cc0000;">${document.getElementById('result-downside')?.textContent || '-'}</div>
1706
+ <div style="font-size: 11px; color: #666;">${document.getElementById('result-down-prob')?.textContent || '-'} ν™•λ₯ </div>
1707
+ </div>
1708
+ <div>
1709
+ <div style="color: #0066cc; font-size: 12px;">🎯 κΈ°λŒ€ 수읡</div>
1710
+ <div style="font-size: 24px; font-weight: bold; color: #0066cc;">${document.getElementById('result-prediction')?.textContent || '-'}</div>
1711
+ <div style="font-size: 11px; color: #666;">R/R ${document.getElementById('result-rr')?.textContent || '-'}</div>
1712
+ </div>
1713
+ <div>
1714
+ <div style="color: #009966; font-size: 12px;">πŸ“ˆ μƒμŠΉ 잠재λ ₯</div>
1715
+ <div style="font-size: 20px; font-weight: bold; color: #009966;">${document.getElementById('result-upside')?.textContent || '-'}</div>
1716
+ <div style="font-size: 11px; color: #666;">${document.getElementById('result-up-prob')?.textContent || '-'} ν™•λ₯ </div>
1717
+ </div>
1718
  </div>
1719
+ <div style="text-align: center; font-size: 10px; color: #999;">β€» AI 기반 뢄석이며 μ‹€μ œ 투자 손읡을 보μž₯ν•˜μ§€ οΏ½οΏ½μŠ΅λ‹ˆλ‹€</div>
1720
  </div>
1721
 
1722
  <div class="section">