@kamuira/stock-analyzer 1.2.2 → 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/analyze.js +0 -3
  2. package/index.html +27 -19
  3. package/package.json +1 -1
package/analyze.js CHANGED
@@ -35,9 +35,6 @@ const WATCH_LIST = {
35
35
  'sh600111': '北方稀土',
36
36
  'sh601318': '中国平安',
37
37
  'sh601066': '中信建投',
38
- 'tw2330': '台积电',
39
- 'tw2317': '鸿海',
40
- 'tw2454': '联发科',
41
38
  };
42
39
 
43
40
  // ==================== 数据获取 ====================
package/index.html CHANGED
@@ -333,32 +333,32 @@
333
333
  // 回测结果卡片
334
334
  if (backtestData && !backtestData.error) {
335
335
  const bt = backtestData;
336
- const s3 = bt.summary['3'] || {winRate:0,avgReturn:0};
337
- const s5 = bt.summary['5'] || {winRate:0,avgReturn:0};
338
- const s10 = bt.summary['10'] || {winRate:0,avgReturn:0};
336
+ const long = bt.long || {total:0,winRate:0,avgReturn:0,totalReturn:0,avgWin:0,avgLoss:0,avgHoldDays:0};
339
337
  const gradeColor = bt.grade === '优秀' ? '#4caf50' : bt.grade === '良好' ? '#2196f3' : bt.grade === '一般' ? '#ff9800' : '#f44336';
338
+ const winRateColor = long.winRate >= 55 ? '#4caf50' : long.winRate >= 50 ? '#ff9800' : '#f44336';
339
+ const avgReturnColor = long.avgReturn > 1.5 ? '#4caf50' : long.avgReturn > 0 ? '#ff9800' : '#f44336';
340
340
  const safeName = (bt.name||'').replace(/['"<>&]/g, '');
341
341
  html += `<div style="background:#1a2530;border:1px solid ${gradeColor};margin-bottom:20px;padding:20px;border-radius:10px">
342
342
  <h3 style="color:${gradeColor};margin-bottom:12px;font-size:15px">回测验证: ${safeName} (${bt.code}) — 评级: ${bt.grade}</h3>
343
- <div style="font-size:12px;color:#888;margin-bottom:10px">数据: ${bt.dataRange} | 买入信号${bt.buySignals} | 卖出信号${bt.sellSignals}次</div>
344
- <div style="display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-bottom:12px">
343
+ <div style="font-size:12px;color:#888;margin-bottom:10px">数据: ${bt.dataRange || '-'} | 引擎: ${bt.engine || '-'} | 做多交易 ${long.total} 笔 | 平均持仓 ${long.avgHoldDays || 0} 天</div>
344
+ ${long.total > 0 ? `<div style="display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-bottom:12px">
345
345
  <div style="text-align:center;padding:8px;background:#141e28;border-radius:6px">
346
- <div style="font-size:11px;color:#888">3日胜率</div>
347
- <div style="font-size:18px;font-weight:bold;color:${s3.winRate>=55?'#4caf50':'#ff9800'}">${s3.winRate}%</div>
348
- <div style="font-size:11px;color:#888">均收益 ${s3.avgReturn}%</div>
346
+ <div style="font-size:11px;color:#888">做多胜率</div>
347
+ <div style="font-size:18px;font-weight:bold;color:${winRateColor}">${long.winRate}%</div>
348
+ <div style="font-size:11px;color:#888">${long.wins||0}胜 / ${long.losses||0}负</div>
349
349
  </div>
350
350
  <div style="text-align:center;padding:8px;background:#141e28;border-radius:6px">
351
- <div style="font-size:11px;color:#888">5日胜率</div>
352
- <div style="font-size:18px;font-weight:bold;color:${s5.winRate>=55?'#4caf50':'#ff9800'}">${s5.winRate}%</div>
353
- <div style="font-size:11px;color:#888">均收益 ${s5.avgReturn}%</div>
351
+ <div style="font-size:11px;color:#888">单笔均收益</div>
352
+ <div style="font-size:18px;font-weight:bold;color:${avgReturnColor}">${long.avgReturn}%</div>
353
+ <div style="font-size:11px;color:#888">累计 ${long.totalReturn}%</div>
354
354
  </div>
355
355
  <div style="text-align:center;padding:8px;background:#141e28;border-radius:6px">
356
- <div style="font-size:11px;color:#888">10日胜率</div>
357
- <div style="font-size:18px;font-weight:bold;color:${s10.winRate>=55?'#4caf50':'#ff9800'}">${s10.winRate}%</div>
358
- <div style="font-size:11px;color:#888">均收益 ${s10.avgReturn}%</div>
356
+ <div style="font-size:11px;color:#888">盈亏比</div>
357
+ <div style="font-size:18px;font-weight:bold;color:#fff">${long.avgWin || 0} / ${long.avgLoss || 0}</div>
358
+ <div style="font-size:11px;color:#888">均盈 / 均亏</div>
359
359
  </div>
360
- </div>
361
- <button onclick="saveToShortcuts('${bt.code}','${safeName}','${s5.winRate}','${bt.grade}')" style="padding:8px 16px;border:1px solid ${gradeColor};border-radius:6px;background:transparent;color:${gradeColor};cursor:pointer;font-size:13px">+ 加入快捷列表</button>
360
+ </div>` : `<div style="padding:12px;text-align:center;color:#888;font-size:13px;background:#141e28;border-radius:6px;margin-bottom:12px">回测周期内无做多入场信号</div>`}
361
+ <button onclick="saveToShortcuts('${bt.code}','${safeName}','${long.winRate}','${bt.grade}')" style="padding:8px 16px;border:1px solid ${gradeColor};border-radius:6px;background:transparent;color:${gradeColor};cursor:pointer;font-size:13px">+ 加入快捷列表</button>
362
362
  <span style="font-size:11px;color:#666;margin-left:10px">加入后可在顶部快速访问</span>
363
363
  </div>`;
364
364
  }
@@ -406,11 +406,11 @@
406
406
  <div style="display:grid;grid-template-columns:1fr 1fr;gap:14px">
407
407
  <div style="background:#122a1a;border:1px solid #2d5a2d;border-radius:10px;padding:16px">
408
408
  <div style="font-size:14px;font-weight:bold;color:#4caf50;margin-bottom:10px">买入操作</div>
409
- ${buyConditions.map(c => `<div style="padding:8px 0;border-bottom:1px solid rgba(255,255,255,0.05);font-size:13px;color:#ccc"><span style="display:inline-block;padding:2px 8px;border-radius:4px;font-size:11px;margin-right:6px;background:#2d4a2d;color:#8bc34a">${c.priority}</span>${c.condition}</div>`).join('')}
409
+ ${buyConditions.map(c => { const m = (typeof c === 'string' ? c : '').match(/^\[([^\]]+)\]\s*(.*)$/); const p = m ? m[1] : ''; const t = m ? m[2] : (c || ''); return `<div style="padding:8px 0;border-bottom:1px solid rgba(255,255,255,0.05);font-size:13px;color:#ccc">${p ? `<span style="display:inline-block;padding:2px 8px;border-radius:4px;font-size:11px;margin-right:6px;background:#2d4a2d;color:#8bc34a">${p}</span>` : ''}${t}</div>`; }).join('')}
410
410
  </div>
411
411
  <div style="background:#2a1a1a;border:1px solid #5a2d2d;border-radius:10px;padding:16px">
412
412
  <div style="font-size:14px;font-weight:bold;color:#f44336;margin-bottom:10px">卖出/止损</div>
413
- ${sellConditions.map(c => `<div style="padding:8px 0;border-bottom:1px solid rgba(255,255,255,0.05);font-size:13px;color:#ccc"><span style="display:inline-block;padding:2px 8px;border-radius:4px;font-size:11px;margin-right:6px;background:#4a2d2d;color:#ff8a80">${c.priority}</span>${c.condition}</div>`).join('')}
413
+ ${sellConditions.map(c => { const m = (typeof c === 'string' ? c : '').match(/^\[([^\]]+)\]\s*(.*)$/); const p = m ? m[1] : ''; const t = m ? m[2] : (c || ''); return `<div style="padding:8px 0;border-bottom:1px solid rgba(255,255,255,0.05);font-size:13px;color:#ccc">${p ? `<span style="display:inline-block;padding:2px 8px;border-radius:4px;font-size:11px;margin-right:6px;background:#4a2d2d;color:#ff8a80">${p}</span>` : ''}${t}</div>`; }).join('')}
414
414
  </div>
415
415
  </div>
416
416
  ${rr ? `<div style="display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-top:14px">
@@ -450,7 +450,15 @@
450
450
 
451
451
  // 支撑压力位
452
452
  html += `<div class="levels">
453
- ${sr.map(s => `<div class="level-item"><div class="level-label">${s.label || s.description || ''}</div><div class="level-value">${s.value || ''}</div>${s.reliability ? `<div style="font-size:11px;color:#888;margin-top:2px">触及${s.touchCount}次 反弹${s.bounceCount}次 可靠性:${s.reliability}</div>` : ''}</div>`).join('')}
453
+ ${(sr || []).map(s => {
454
+ if (typeof s === 'string') {
455
+ const idx = s.lastIndexOf(': ');
456
+ const label = idx > -1 ? s.slice(0, idx) : s;
457
+ const value = idx > -1 ? s.slice(idx + 2) : '';
458
+ return `<div class="level-item"><div class="level-label">${label}</div><div class="level-value">${value}</div></div>`;
459
+ }
460
+ return `<div class="level-item"><div class="level-label">${s.label || s.description || ''}</div><div class="level-value">${s.value || ''}</div>${s.reliability ? `<div style="font-size:11px;color:#888;margin-top:2px">触及${s.touchCount}次 反弹${s.bounceCount}次 可靠性:${s.reliability}</div>` : ''}</div>`;
461
+ }).join('')}
454
462
  </div>`;
455
463
 
456
464
  // 各指标详情
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kamuira/stock-analyzer",
3
- "version": "1.2.2",
3
+ "version": "1.2.3",
4
4
  "preferGlobal": true,
5
5
  "description": "A股/台股综合技术分析工具 - 支持实时分析、回测验证、买卖建议",
6
6
  "main": "server.js",