feat: 新增外部因素分析模块+综合评分引擎+算法文档重构
新增模块: - fund_flow_analyzer.py: 主力资金流向分析(P0, ±20) - market_sentiment.py: 市场情绪指标(P1, ±10) - external_factors.py: 北向资金/美股/大宗商品/汇率(P2-P4,P7) - news_analyzer.py: 公告/并购/政策面LLM分析(P5-P6) - score_engine.py: 综合评分引擎,整合技术面+外部因素 路由更新: - analysis.py: deep_analyze接入综合评分,根据最终评级修正买卖建议 - market.py: 新增4个外部因素API端点 - trades.py: 交易路由更新 算法文档重构: - 章节重排: 技术面(二三)→外部因素(四)→买卖决策(五)→数据源(六)→性能(七) - 架构图更新为五层,标注章节对应 - 5.1/5.2标注纯技术面,5.3整合外部因素修正推荐
This commit is contained in:
@@ -92,10 +92,24 @@
|
||||
scanSummaryCollapsed: false,
|
||||
fullScanSignalDist: [],
|
||||
|
||||
// 找牛股
|
||||
bullStocksData: null, // { stages: {1:[...], 2:[...]}, summary: {}, stage_info: [...] }
|
||||
// 找牛股(保留兼容)
|
||||
bullStocksData: null,
|
||||
bullStocksLoading: false,
|
||||
bullActiveStage: 2, // 默认显示阶段2=龙抬头(最佳买点)
|
||||
bullActiveStage: 2,
|
||||
|
||||
// 个股深析
|
||||
deepCode: '',
|
||||
deepReport: null,
|
||||
deepLoading: false,
|
||||
|
||||
// 模型页子tab
|
||||
modelSubTab: 'system',
|
||||
|
||||
// 买入分析
|
||||
buyAnalysisList: [],
|
||||
buyAnalysisLoading: false,
|
||||
buyAnalysisProgress: 0,
|
||||
buyAnalysisTotal: 0,
|
||||
|
||||
// 交易记录页面
|
||||
trades: [],
|
||||
@@ -2239,7 +2253,7 @@
|
||||
params: holding ? { holdingStocks: holding } : {}
|
||||
});
|
||||
if (resp.data.success) {
|
||||
this.bullStocksData = resp.data; // { stages, summary, total, stage_info }
|
||||
this.bullStocksData = resp.data;
|
||||
} else {
|
||||
this.showToast(resp.data.error || '获取牛股数据失败', 'error');
|
||||
}
|
||||
@@ -2251,6 +2265,75 @@
|
||||
}
|
||||
},
|
||||
|
||||
async fetchDeepAnalysis() {
|
||||
const code = (this.deepCode || '').trim();
|
||||
if (!code || code.length < 6) {
|
||||
this.showToast('请输入6位股票代码', 'error');
|
||||
return;
|
||||
}
|
||||
this.deepLoading = true;
|
||||
this.deepReport = null;
|
||||
try {
|
||||
const resp = await axios.post('/api/deep_analyze', { stock_code: code });
|
||||
if (resp.data.success) {
|
||||
this.deepReport = resp.data.report;
|
||||
} else {
|
||||
this.showToast(resp.data.error || '分析失败', 'error');
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('深度分析失败:', err);
|
||||
this.showToast('深度分析失败: ' + (err.response?.data?.error || err.message), 'error');
|
||||
} finally {
|
||||
this.deepLoading = false;
|
||||
}
|
||||
},
|
||||
|
||||
async fetchBuyAnalysis() {
|
||||
if (this.buyAnalysisLoading) return;
|
||||
this.buyAnalysisLoading = true;
|
||||
this.buyAnalysisList = [];
|
||||
this.buyAnalysisProgress = 0;
|
||||
try {
|
||||
const scanResp = await axios.get('/api/scan_results', {
|
||||
params: { per_page: 200, recommend_text: '买入' }
|
||||
});
|
||||
if (!scanResp.data.success) {
|
||||
this.showToast('获取买入推荐失败', 'error');
|
||||
return;
|
||||
}
|
||||
const buyStocks = scanResp.data.results || [];
|
||||
this.buyAnalysisTotal = buyStocks.length;
|
||||
if (buyStocks.length === 0) {
|
||||
this.showToast('当前无买入推荐股票', 'info');
|
||||
return;
|
||||
}
|
||||
const results = [];
|
||||
for (let i = 0; i < buyStocks.length; i++) {
|
||||
this.buyAnalysisProgress = i + 1;
|
||||
try {
|
||||
const resp = await axios.post('/api/deep_analyze', {
|
||||
stock_code: buyStocks[i].code,
|
||||
skip_llm: true
|
||||
});
|
||||
if (resp.data.success) {
|
||||
const report = resp.data.report;
|
||||
report._expanded = false;
|
||||
results.push(report);
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('分析失败:', buyStocks[i].code, e.message);
|
||||
}
|
||||
}
|
||||
results.sort((a, b) => b.deep_score - a.deep_score);
|
||||
this.buyAnalysisList = results;
|
||||
} catch (err) {
|
||||
console.error('买入分析失败:', err);
|
||||
this.showToast('买入分析失败: ' + (err.message || '未知错误'), 'error');
|
||||
} finally {
|
||||
this.buyAnalysisLoading = false;
|
||||
}
|
||||
},
|
||||
|
||||
getBullStageStocks(stageNum) {
|
||||
if (!this.bullStocksData || !this.bullStocksData.stages) return [];
|
||||
return this.bullStocksData.stages[String(stageNum)] || [];
|
||||
|
||||
Reference in New Issue
Block a user