This commit is contained in:
parent
b757e0d2c6
commit
a028da1903
|
|
@ -63,38 +63,30 @@ const MARKET_LABELS = {
|
||||||
|
|
||||||
// Helper function to extract decision from Risk Manager's final decision
|
// Helper function to extract decision from Risk Manager's final decision
|
||||||
const extractDecisionFromReport = (report: SavedReport): { action: string; color: string } => {
|
const extractDecisionFromReport = (report: SavedReport): { action: string; color: string } => {
|
||||||
// First try the decision.action field (processed decision)
|
|
||||||
if (report.result.decision?.action) {
|
|
||||||
const action = report.result.decision.action;
|
|
||||||
const actionLower = action.toLowerCase();
|
|
||||||
const color = actionLower.includes("buy")
|
|
||||||
? "text-green-600"
|
|
||||||
: actionLower.includes("sell")
|
|
||||||
? "text-red-600"
|
|
||||||
: "text-yellow-600";
|
|
||||||
return { action, color };
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper function to find decision in text
|
// Helper function to find "最終交易提案" specifically
|
||||||
const findDecision = (text: string): { action: string; color: string } | null => {
|
const findFinalProposal = (text: string): { action: string; color: string } | null => {
|
||||||
if (!text) return null;
|
if (!text || typeof text !== 'string') return null;
|
||||||
|
|
||||||
// Keep original text for Chinese matching
|
// Match "最終交易提案:持有" - this is the ONLY pattern we care about for trader's decision
|
||||||
const originalText = text;
|
const match = text.match(/最終交易提案[::]\s*(買入|賣出|持有)/);
|
||||||
const lowerText = text.toLowerCase();
|
if (match) {
|
||||||
|
const decision = match[1];
|
||||||
// Priority 1: Look for "最終交易提案" (Trader's final proposal) - HIGHEST PRIORITY
|
|
||||||
// Use more flexible regex to handle various whitespace/formatting
|
|
||||||
const finalProposalMatch = originalText.match(/最終交易提案[::]\s*(買入|賣出|持有)/);
|
|
||||||
if (finalProposalMatch) {
|
|
||||||
const decision = finalProposalMatch[1];
|
|
||||||
if (decision === "買入") return { action: "買入", color: "text-green-600" };
|
if (decision === "買入") return { action: "買入", color: "text-green-600" };
|
||||||
if (decision === "賣出") return { action: "賣出", color: "text-red-600" };
|
if (decision === "賣出") return { action: "賣出", color: "text-red-600" };
|
||||||
if (decision === "持有") return { action: "持有", color: "text-yellow-600" };
|
if (decision === "持有") return { action: "持有", color: "text-yellow-600" };
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
// Priority 2: Look for "最終決策" or "最終建議"
|
// Helper function to find other decision patterns
|
||||||
const finalDecisionMatch = originalText.match(/最終(?:決策|建議)[::]\s*(買入|賣出|持有)/);
|
const findOtherDecision = (text: string): { action: string; color: string } | null => {
|
||||||
|
if (!text || typeof text !== 'string') return null;
|
||||||
|
|
||||||
|
const lowerText = text.toLowerCase();
|
||||||
|
|
||||||
|
// Look for "最終決策" or "最終建議"
|
||||||
|
const finalDecisionMatch = text.match(/最終(?:決策|建議)[::]\s*(買入|賣出|持有)/);
|
||||||
if (finalDecisionMatch) {
|
if (finalDecisionMatch) {
|
||||||
const decision = finalDecisionMatch[1];
|
const decision = finalDecisionMatch[1];
|
||||||
if (decision === "買入") return { action: "買入", color: "text-green-600" };
|
if (decision === "買入") return { action: "買入", color: "text-green-600" };
|
||||||
|
|
@ -102,17 +94,7 @@ const extractDecisionFromReport = (report: SavedReport): { action: string; color
|
||||||
if (decision === "持有") return { action: "持有", color: "text-yellow-600" };
|
if (decision === "持有") return { action: "持有", color: "text-yellow-600" };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Priority 3: Look for "建議:" at the END of a line (to avoid mid-sentence matches)
|
// English patterns
|
||||||
const suggestionMatch = originalText.match(/建議[::]\s*(買入|賣出|持有)\s*$/m);
|
|
||||||
if (suggestionMatch) {
|
|
||||||
const decision = suggestionMatch[1];
|
|
||||||
if (decision === "買入") return { action: "買入", color: "text-green-600" };
|
|
||||||
if (decision === "賣出") return { action: "賣出", color: "text-red-600" };
|
|
||||||
if (decision === "持有") return { action: "持有", color: "text-yellow-600" };
|
|
||||||
}
|
|
||||||
|
|
||||||
// Priority 4: English keywords with word boundaries (case insensitive)
|
|
||||||
// Only match if it's a clear recommendation pattern
|
|
||||||
if (lowerText.match(/(?:final|recommendation|decision)[:\s]*(buy|long)/i)) {
|
if (lowerText.match(/(?:final|recommendation|decision)[:\s]*(buy|long)/i)) {
|
||||||
return { action: "買入", color: "text-green-600" };
|
return { action: "買入", color: "text-green-600" };
|
||||||
}
|
}
|
||||||
|
|
@ -126,31 +108,45 @@ const extractDecisionFromReport = (report: SavedReport): { action: string; color
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Priority 1: Check trader's investment plan FIRST (交易員建議最優先)
|
// ====== PRIORITY 1: Trader's "最終交易提案" - HIGHEST PRIORITY ======
|
||||||
const traderReport = report.result.reports?.trader_investment_plan;
|
const traderReport = report.result.reports?.trader_investment_plan;
|
||||||
if (traderReport && typeof traderReport === 'string') {
|
if (traderReport) {
|
||||||
const decision = findDecision(traderReport);
|
const decision = findFinalProposal(traderReport);
|
||||||
|
if (decision) {
|
||||||
|
console.log(`📊 Found trader decision: ${decision.action}`);
|
||||||
|
return decision;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ====== PRIORITY 2: Check final_trade_decision ======
|
||||||
|
const finalTradeDecision = report.result.reports?.final_trade_decision;
|
||||||
|
if (finalTradeDecision) {
|
||||||
|
const decision = findFinalProposal(finalTradeDecision) || findOtherDecision(finalTradeDecision);
|
||||||
if (decision) return decision;
|
if (decision) return decision;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Priority 2: Check risk manager's final decision
|
// ====== PRIORITY 3: Check risk_debate_state judge decision ======
|
||||||
const finalDecision = report.result.reports?.final_trade_decision;
|
|
||||||
if (finalDecision && typeof finalDecision === 'string') {
|
|
||||||
const decision = findDecision(finalDecision);
|
|
||||||
if (decision) return decision;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Priority 3: Check risk debate state judge decision
|
|
||||||
const riskJudge = report.result.reports?.risk_debate_state?.judge_decision;
|
const riskJudge = report.result.reports?.risk_debate_state?.judge_decision;
|
||||||
if (riskJudge && typeof riskJudge === 'string') {
|
if (riskJudge) {
|
||||||
const decision = findDecision(riskJudge);
|
const decision = findOtherDecision(riskJudge);
|
||||||
if (decision) return decision;
|
if (decision) return decision;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Priority 4: Check any field that might contain decision
|
// ====== PRIORITY 4: Fall back to decision.action field ======
|
||||||
|
if (report.result.decision?.action) {
|
||||||
|
const action = report.result.decision.action;
|
||||||
|
const actionLower = action.toLowerCase();
|
||||||
|
const color = actionLower.includes("buy")
|
||||||
|
? "text-green-600"
|
||||||
|
: actionLower.includes("sell")
|
||||||
|
? "text-red-600"
|
||||||
|
: "text-yellow-600";
|
||||||
|
return { action, color };
|
||||||
|
}
|
||||||
|
|
||||||
|
// ====== PRIORITY 5: Search in other report fields ======
|
||||||
const allReports = report.result.reports;
|
const allReports = report.result.reports;
|
||||||
if (allReports) {
|
if (allReports) {
|
||||||
// Try to find decision in any report text
|
|
||||||
const reportTexts = [
|
const reportTexts = [
|
||||||
allReports.market_report,
|
allReports.market_report,
|
||||||
allReports.sentiment_report,
|
allReports.sentiment_report,
|
||||||
|
|
@ -159,10 +155,8 @@ const extractDecisionFromReport = (report: SavedReport): { action: string; color
|
||||||
].filter(t => t && typeof t === 'string');
|
].filter(t => t && typeof t === 'string');
|
||||||
|
|
||||||
for (const text of reportTexts) {
|
for (const text of reportTexts) {
|
||||||
if (text.includes("最終交易提案")) {
|
const decision = findFinalProposal(text);
|
||||||
const decision = findDecision(text);
|
if (decision) return decision;
|
||||||
if (decision) return decision;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue