2 views
shy3130/tick-stock-panel
TSP自托管、零运维的 A 股「选股 + 监控 + 回测」量化工作台 | LLM能力驱使策略定制+个股分析+复盘 | 自由接入第三方数据源与个性化扩展数据 | 个人开源
Python★ 5,176+44 that day#7 on trending
C62.4/100
Duplication74
3.7% in python, tsx, typescript, bash, powershell, javascript, perlDead code83
2%Complexity40
66.8% The score is jscpd's own --health model: markup, data and text left out, tests kept. The numbers below are the trending scan's.
3.76%duplicated code · 6,153 of 163,575 lines
475clones in code
443code files of 807 scanned
3.65%duplicated over all files · 663 clones
Most complex files
- frontend/src/pages/backtest/StrategyBacktest.tsx935 cx
- backend/app/backtest/engine.py869 cx
- backend/app/backtest/matrix.py757 cx
- frontend/src/pages/LimitUpLadder.tsx610 cx
- frontend/src/components/monitor/RuleEditor.tsx601 cx
- frontend/src/pages/Watchlist.tsx587 cx
- backend/app/tickflow/repository.py563 cx
- frontend/src/lib/api.ts489 cx
- backend/app/strategy/monitor.py468 cx
- backend/app/services/quote_service.py459 cx
Dead code 2.04% unused · 87 findings
- backend/app/plugins/fuyao/provider.pyunused-file
- backend/app/strategy/builtin/factor_rank_research.pyunused-file
- frontend/src/components/CandlestickChart.tsxunused-file
- backend/app/strategy/market_data.pyunused-file
- backend/app/strategy/builtin/ma_convergence_breakout.pyunused-file
- backend/app/strategy/builtin/pullback_to_support.pyunused-file
- backend/app/strategy/builtin/macd_golden.pyunused-file
- backend/app/strategy/builtin/platform_consolidation_breakout.pyunused-file
- backend/app/strategy/builtin/rsi_midline_pullback.pyunused-file
- backend/app/strategy/builtin/strong_open.pyunused-file
The code number leaves out tests, fixtures, docs, examples, data files, styles, translations and vendored code.
Largest clones in the code
- 78 lines in 2 placestsx1,087 tokens
707 <span className="rounded-full bg-blue-400/10 px-2 py-0.5 text-[10px] text-blue-300">强度 {stat.heatScore.toFixed(0)}</span> 708 </div> 709 <div className="mt-1.5 flex flex-wrap gap-x-4 gap-y-1 text-xs text-muted"> 710 <span>{stat.count} 只成分</span> 711 <span className={priceColorClass(stat.avgPct)}>平均 {stat.avgPct != null ? fmtPct(stat.avgPct) : '—'}</span> 712 <span>上涨占比 {(stat.upRate * 100).toFixed(0)}%</span> 713 <span>成交额 {fmtBigNum(stat.totalAmount)}</span> 714 {stat.avgTurnover != null && <span>均换手 {stat.avgTurnover.toFixed(2)}%</span>} 715 </div> 716</div>First 10 of 78 lines.
- 85 lines in 2 placestsx887 tokens
552 items: ConceptStat[] 553 mode: 'up' | 'down' 554 selectedKey: string | null 555 onSelect: (key: string) => void 556 onStockClick: (symbol: string, name?: string, navList?: NavItem[]) => void 557 activeSymbol: string | null 558}) { 559 const toneText = mode === 'up' ? 'text-bull' : 'text-bear' 560 const toneBorder = mode === 'up' ? 'border-bull/20' : 'border-bear/20' 561 const toneBg = mode === 'up' ? 'bg-bull/10' : 'bg-bear/10'First 10 of 85 lines.
- 36 lines in 4 placestypescript238 tokensfrontend/src/lib/api.ts:3408–3443frontend/src/lib/api.ts:3555–3584frontend/src/lib/api.ts:3597–3626frontend/src/lib/api.ts:3886–3915
3408 body: JSON.stringify({ symbol, focus: focus ?? '' }), 3409}) 3410if (!res.ok) { 3411 let detail = '' 3412 try { const j = JSON.parse(await res.text()); detail = j.detail ?? j.message ?? '' } catch { /* ignore */ } 3413 const msg = detail || `${res.status} ${res.statusText}` 3414 toast(msg, 'error') 3415 throw new Error(msg) 3416} 3417if (!res.body) throw new Error('响应无 body')First 10 of 36 lines.
7 more
- 84 lines in 2 placestsx688 tokens
- 44 lines in 2 placestsx580 tokens
- 57 lines in 2 placestsx562 tokens
- 55 lines in 2 placespython462 tokens
- 48 lines in 2 placespython415 tokens
- 61 lines in 2 placestsx413 tokens
- 8 lines in 5 placespython102 tokensbackend/app/strategy/builtin/broken_board_recovery.py:79–86backend/app/strategy/builtin/low_volatility_leader.py:76–83backend/app/strategy/builtin/macd_below_zero_revival.py:77–84backend/app/strategy/builtin/platform_consolidation_breakout.py:87–94backend/app/strategy/builtin/pullback_to_support.py:93–100
Largest clones over all files, tests and data included
- 78 lines in 2 placestsx1,087 tokens
707 <span className="rounded-full bg-blue-400/10 px-2 py-0.5 text-[10px] text-blue-300">强度 {stat.heatScore.toFixed(0)}</span> 708 </div> 709 <div className="mt-1.5 flex flex-wrap gap-x-4 gap-y-1 text-xs text-muted"> 710 <span>{stat.count} 只成分</span> 711 <span className={priceColorClass(stat.avgPct)}>平均 {stat.avgPct != null ? fmtPct(stat.avgPct) : '—'}</span> 712 <span>上涨占比 {(stat.upRate * 100).toFixed(0)}%</span> 713 <span>成交额 {fmtBigNum(stat.totalAmount)}</span> 714 {stat.avgTurnover != null && <span>均换手 {stat.avgTurnover.toFixed(2)}%</span>} 715 </div> 716</div>First 10 of 78 lines.
- 85 lines in 2 placestsx887 tokens
552 items: ConceptStat[] 553 mode: 'up' | 'down' 554 selectedKey: string | null 555 onSelect: (key: string) => void 556 onStockClick: (symbol: string, name?: string, navList?: NavItem[]) => void 557 activeSymbol: string | null 558}) { 559 const toneText = mode === 'up' ? 'text-bull' : 'text-bear' 560 const toneBorder = mode === 'up' ? 'border-bull/20' : 'border-bear/20' 561 const toneBg = mode === 'up' ? 'bg-bull/10' : 'bg-bear/10'First 10 of 85 lines.
- 36 lines in 4 placestypescript238 tokensfrontend/src/lib/api.ts:3408–3443frontend/src/lib/api.ts:3555–3584frontend/src/lib/api.ts:3597–3626frontend/src/lib/api.ts:3886–3915
3408 body: JSON.stringify({ symbol, focus: focus ?? '' }), 3409}) 3410if (!res.ok) { 3411 let detail = '' 3412 try { const j = JSON.parse(await res.text()); detail = j.detail ?? j.message ?? '' } catch { /* ignore */ } 3413 const msg = detail || `${res.status} ${res.statusText}` 3414 toast(msg, 'error') 3415 throw new Error(msg) 3416} 3417if (!res.body) throw new Error('响应无 body')First 10 of 36 lines.
- 84 lines in 2 placestsx688 tokens
- 44 lines in 2 placestsx580 tokens
By format, code only
| Format | Files | Lines | Clones | Duplicated lines | Duplication |
|---|---|---|---|---|---|
| python | 210 | 86,072 | 246 | 2,720 | 3.16% |
| tsx | 160 | 64,192 | 195 | 2,748 | 4.28% |
| typescript | 60 | 11,696 | 33 | 679 | 5.81% |
| javascript | 1 | 293 | 1 | 6 | 2.05% |
| bash | 10 | 847 | 0 | 0 | 0% |
| powershell | 1 | 301 | 0 | 0 | 0% |
| perl | 1 | 174 | 0 | 0 | 0% |
By format, all files
| Format | Files | Lines | Clones | Duplicated lines | Duplication |
|---|---|---|---|---|---|
| python | 489 | 139,232 | 413 | 4,616 | 3.32% |
| tsx | 168 | 65,044 | 201 | 2,795 | 4.3% |
| typescript | 67 | 12,110 | 36 | 700 | 5.78% |
| markdown | 29 | 7,129 | 5 | 53 | 0.74% |
| markup | 10 | 296 | 5 | 57 | 19.26% |
| bash | 16 | 911 | 1 | 3 | 0.33% |
| yaml | 9 | 600 | 1 | 53 | 8.83% |
| javascript | 1 | 293 | 1 | 6 | 2.05% |
| powershell | 1 | 301 | 0 | 0 | 0% |
| text | 8 | 251 | 0 | 0 | 0% |
Trending appearances
| Day | Rank | Stars | Files | Lines | Clones | All files | Code | Health | Commit |
|---|---|---|---|---|---|---|---|---|---|
| Sep 26, 2026 | #7 | 5,176 (+44) | 807 | 226,727 | 663 | 3.65% | 3.76% | C 62.4 | 529be95 |
Want this for your own project? Install jscpd and run jscpd ., or measure it the way the baselines were measured.