/* PRESERVATION-SOURCE-BEGIN app.js:8905-9051 */ function exportStocks() { exportRows("涨停池", getVisibleStocks(), [ ["股票代码", "code"], ["股票名称", "name"], ["连板", "streak"], ["涨幅%", "change"], ["价格", "price"], ["所属板块", "sector"], ["涨停原因", "reason"], ["首封", "first_time"], ["最后封板", "last_time"], ["开板次数", "open_times"], ["换手率%", "turnover_rate"], ["成交额亿", "amount_billion"], ["封单额万", "seal_amount_million"], ]); } function exportBroken() { exportRows("炸板池", getVisibleBrokenRows(), [ ["股票代码", "code"], ["股票名称", "name"], ["现价涨幅%", "change"], ["距涨停%", "limitGap"], ["价格", "price"], ["所属板块", "sector"], ["首次触板", "first_time"], ["开板次数", "open_times"], ["换手率%", "turnover_rate"], ["成交额亿", "amount_billion"], ]); } function exportDown() { exportRows("跌停板", getVisibleDownRows(), [ ["股票代码", "code"], ["股票名称", "name"], ["跌幅%", "change"], ["价格", "price"], ["所属板块", "sector"], ["换手率%", "turnover_rate"], ["成交额亿", "amount_billion"], ]); } function exportYesterday() { exportRows("昨日涨停", getVisibleYesterdayRows(), [ ["股票代码", "code"], ["股票名称", "name"], ["昨日高度", "prior_streak"], ["今日涨幅%", "current_change"], ["今日结果", "outcome"], ["当前高度", "current_streak"], ["所属板块", "sector"], ]); } function exportLadder() { const rows = (state.dashboard?.ladders || []).flatMap((group) => (group.stocks || []).map((stock) => ({ level: group.label || group.level, ...stock, }))); exportRows("市场天梯", rows, [ ["梯队", "level"], ["股票代码", "code"], ["股票名称", "name"], ["所属板块", "sector"], ["封板时间", "first_time"], ["开板次数", "open_times"], ["封单额万", "seal_amount_million"], ["成交额亿", "amount_billion"], ]); } function exportRotation() { const sectorMap = new Map((state.dashboard?.sectors || []).map((sector) => [sector.name, sector])); const rows = (state.dashboard?.sector_rotation || []).map((row) => ({ ...row, average_change: sectorMap.get(row.name)?.change ?? 0, })); exportRows("板块轮动", rows, [ ["排名", "rank"], ["板块", "name"], ["趋势", "trend"], ["今日涨停", "count"], ["昨日涨停", "previous_count"], ["变化", "delta"], ["强度", "strength"], ["最高板", "max_streak"], ["平均涨幅%", "average_change"], ["领涨股", "leader"], ["涨停股成交额亿", "amount_billion"], ]); } function exportSentimentHistory() { const rows = state.sentimentHistory?.rows || []; if (!rows.length) { showToast("暂无可导出的情绪周期数据"); return; } const exportRowsData = rows.map((row) => ({ ...row, breadth_score: row.components?.breadth?.score, limit_ecology_score: row.components?.limit_ecology?.score, profit_effect_score: row.components?.profit_effect?.score, ladder_structure_score: row.components?.ladder_structure?.score, liquidity_score: row.components?.liquidity?.score, })); exportRows("情绪周期", exportRowsData, [ ["交易日", "trade_date"], ["情绪温度", "score"], ["周期阶段", "phase"], ["方向", "direction"], ["涨停", "limit_up_count"], ["首板", "first_board_count"], ["二板", "second_board_count"], ["三板以上", "three_plus_count"], ["连板高度", "max_height"], ["炸板", "broken_count"], ["跌停", "limit_down_count"], ["昨日涨停", "previous_limit_count"], ["昨日涨停红盘", "previous_positive_count"], ["昨日涨停红盘率%", "previous_positive_rate"], ["市场宽度", "breadth_score"], ["涨停生态", "limit_ecology_score"], ["赚钱效应", "profit_effect_score"], ["连板结构", "ladder_structure_score"], ["成交活跃度", "liquidity_score"], ]); } function exportDragonTiger() { const rows = (state.dragonTiger?.traders || []).flatMap((trader) => ( (trader.operations || []).map((operation) => ({ trader_name: trader.name, identity_type: dragonIdentityLabel(trader.identity_type), ...operation, })) )); exportRows("游资龙虎榜", rows, [ ["游资或席位", "trader_name"], ["身份", "identity_type"], ["股票代码", "code"], ["股票名称", "name"], ["方向", "direction"], ["涨幅%", "change"], ["买入百万元", "buy_million"], ["卖出百万元", "sell_million"], ["净额百万元", "net_buy_million"], ["关联席位", "seat_name"], ["上榜原因", "reason"], ]); } function exportHotMoneyProfiles() { const rows = state.hotMoneyProfiles?.profiles || []; if (!rows.length) { showToast("暂无可导出的游资档案"); return; } downloadCsv( `游资档案-${todayString()}.csv`, ["游资名称", "简介", "关联营业部", "席位数量"], rows.map((profile) => [ profile.name, profile.description, (profile.organizations || []).join(";"), number(profile.organization_count), ]), ); } function exportRows(label, rows, columns) { const headers = columns.map(([header]) => header); const data = rows.map((row) => columns.map(([, key]) => row[key] ?? "")); downloadCsv(`${label}-${state.dashboard.meta.trade_date}.csv`, headers, data); } function downloadCsv(filename, headers, rows) { const lines = [headers, ...rows].map((row) => row.map(csvCell).join(",")); const blob = new Blob(["\ufeff", lines.join("\r\n")], { type: "text/csv;charset=utf-8" }); const url = URL.createObjectURL(blob); const anchor = document.createElement("a"); anchor.href = url; anchor.download = filename; anchor.click(); URL.revokeObjectURL(url); showToast(`已导出 ${rows.length} 条数据`); } function csvCell(value) { let text = String(value ?? ""); if (/^[=+\-@]/.test(text)) text = `'${text}`; return `"${text.replaceAll('"', '""')}"`; } /* PRESERVATION-SOURCE-END app.js:8905-9051 */