UNPKG

@gabriel3615/ta_analysis

Version:

stock ta analysis

1,042 lines (1,041 loc) 50.6 kB
import { PatternDirection, } from '../analysis/basic/patterns/analyzeMultiTimeframePatterns.js'; import { RiskLevel, SignalStrength, TimeframePriority, TradeDirection, } from '../types.js'; /** * 确定入场策略 */ export function determineEntryStrategy(direction, currentPrice, keyLevels, patternAnalysis, confidenceScore) { // 默认入场策略 const entryStrategy = { idealEntryPrice: currentPrice, alternativeEntryPrice: currentPrice, entryType: 'immediate', entryConditions: [], priceZones: { ideal: [currentPrice * 0.99, currentPrice * 1.01], acceptable: [currentPrice * 0.98, currentPrice * 1.02], }, timeWindow: '1-3个交易日内', riskLevel: RiskLevel.Medium, }; // 根据交易方向确定入场策略 if (direction === TradeDirection.Long) { // 寻找当前价格下方最近的支撑位 const supportLevels = keyLevels .filter(level => level.type === 'support' && level.price < currentPrice) .sort((a, b) => b.price - a.price); if (supportLevels.length > 0) { // 如果有支撑位,建议在回调至支撑位时入场 entryStrategy.idealEntryPrice = supportLevels[0].price; entryStrategy.entryType = 'pullback'; entryStrategy.priceZones.ideal = [ supportLevels[0].price * 0.99, supportLevels[0].price * 1.01, ]; if (supportLevels.length > 1) { entryStrategy.alternativeEntryPrice = supportLevels[1].price; entryStrategy.priceZones.acceptable = [ supportLevels[1].price * 0.99, supportLevels[0].price * 1.01, ]; } else { entryStrategy.priceZones.acceptable = [ supportLevels[0].price * 0.97, supportLevels[0].price * 1.02, ]; } } else { // 如果没有清晰的支撑位,考虑突破当前价格上方的阻力位 const resistanceLevels = keyLevels .filter(level => level.type === 'resistance' && level.price > currentPrice) .sort((a, b) => a.price - b.price); if (resistanceLevels.length > 0 && (resistanceLevels[0].price - currentPrice) / currentPrice < 0.05) { // 如果最近的阻力位不超过当前价格5%,考虑突破入场 entryStrategy.idealEntryPrice = resistanceLevels[0].price * 1.01; entryStrategy.entryType = 'breakout'; entryStrategy.priceZones.ideal = [ resistanceLevels[0].price, resistanceLevels[0].price * 1.02, ]; entryStrategy.priceZones.acceptable = [ resistanceLevels[0].price * 0.99, resistanceLevels[0].price * 1.03, ]; } } // 添加入场条件 entryStrategy.entryConditions = [ { type: 'price', description: entryStrategy.entryType === 'pullback' ? `价格回调至${entryStrategy.idealEntryPrice.toFixed(2)}附近的支撑位` : entryStrategy.entryType === 'breakout' ? `价格突破${entryStrategy.idealEntryPrice.toFixed(2)}阻力位` : `价格接近${entryStrategy.idealEntryPrice.toFixed(2)}`, priority: 'critical', }, { type: 'volume', description: entryStrategy.entryType === 'pullback' ? '回调时成交量萎缩,反弹时成交量放大' : '突破时成交量明显放大', priority: 'important', }, ]; // 添加形态相关条件 if (patternAnalysis.timeframeAnalyses.some(tfa => tfa.dominantPattern && tfa.dominantPattern.direction === PatternDirection.Bullish && tfa.dominantPattern.reliability > 70)) { entryStrategy.entryConditions.push({ type: 'pattern', description: '确认技术形态完成且未出现失败信号', priority: 'important', }); } } else if (direction === TradeDirection.Short) { // 寻找当前价格上方最近的阻力位 const resistanceLevels = keyLevels .filter(level => level.type === 'resistance' && level.price > currentPrice) .sort((a, b) => a.price - b.price); if (resistanceLevels.length > 0) { // 如果有阻力位,建议在反弹至阻力位时入场 entryStrategy.idealEntryPrice = resistanceLevels[0].price; entryStrategy.entryType = 'pullback'; entryStrategy.priceZones.ideal = [ resistanceLevels[0].price * 0.99, resistanceLevels[0].price * 1.01, ]; if (resistanceLevels.length > 1) { entryStrategy.alternativeEntryPrice = resistanceLevels[1].price; entryStrategy.priceZones.acceptable = [ resistanceLevels[0].price * 0.99, resistanceLevels[1].price * 1.01, ]; } else { entryStrategy.priceZones.acceptable = [ resistanceLevels[0].price * 0.98, resistanceLevels[0].price * 1.03, ]; } } else { // 如果没有清晰的阻力位,考虑突破当前价格下方的支撑位 const supportLevels = keyLevels .filter(level => level.type === 'support' && level.price < currentPrice) .sort((a, b) => b.price - a.price); if (supportLevels.length > 0 && (currentPrice - supportLevels[0].price) / currentPrice < 0.05) { // 如果最近的支撑位不超过当前价格下方5%,考虑突破入场 entryStrategy.idealEntryPrice = supportLevels[0].price * 0.99; entryStrategy.entryType = 'breakout'; entryStrategy.priceZones.ideal = [ supportLevels[0].price * 0.98, supportLevels[0].price, ]; entryStrategy.priceZones.acceptable = [ supportLevels[0].price * 0.97, supportLevels[0].price * 1.01, ]; } } // 添加入场条件 entryStrategy.entryConditions = [ { type: 'price', description: entryStrategy.entryType === 'pullback' ? `价格反弹至${entryStrategy.idealEntryPrice.toFixed(2)}附近的阻力位` : entryStrategy.entryType === 'breakout' ? `价格突破${entryStrategy.idealEntryPrice.toFixed(2)}支撑位` : `价格接近${entryStrategy.idealEntryPrice.toFixed(2)}`, priority: 'critical', }, { type: 'volume', description: entryStrategy.entryType === 'pullback' ? '反弹时成交量萎缩,下跌时成交量放大' : '突破时成交量明显放大', priority: 'important', }, ]; // 添加形态相关条件 if (patternAnalysis.timeframeAnalyses.some(tfa => tfa.dominantPattern && tfa.dominantPattern.direction === PatternDirection.Bearish && tfa.dominantPattern.reliability > 70)) { entryStrategy.entryConditions.push({ type: 'pattern', description: '确认技术形态完成且未出现失败信号', priority: 'important', }); } } // 根据信号强度和一致性调整入场策略 if (confidenceScore > 80) { // 高度确信的信号可以更积极入场 if (entryStrategy.entryType === 'immediate') { entryStrategy.entryConditions.push({ type: 'time', description: '可以立即入场,不需要额外确认信号', priority: 'optional', }); } else { entryStrategy.timeWindow = '1-2个交易日内'; } entryStrategy.riskLevel = RiskLevel.Low; } else if (confidenceScore < 50) { // 低确信度的信号需要更谨慎 entryStrategy.entryConditions.push({ type: 'indicator', description: '等待其他技术指标确认信号后再入场', priority: 'important', }); entryStrategy.timeWindow = '3-5个交易日内耐心等待合适入场点'; entryStrategy.riskLevel = RiskLevel.High; } return entryStrategy; } /** * 确定出场策略 */ export function determineExitStrategy(direction, keyLevels, entryPrice, chipAnalysis, patternAnalysis, volatilityAnalysis // 新增:考虑波动率 ) { // 默认出场策略 const exitStrategy = { takeProfitLevels: [], stopLossLevels: [], timeBasedExit: '持仓超过30个交易日且没有明显向有利方向发展时考虑退出', maximumHoldingPeriod: '45个交易日', }; // 根据波动率调整出场策略 let volatilityAdjustment = 1; if (volatilityAnalysis) { const volatilityRegime = volatilityAnalysis.volatilityAnalysis.volatilityRegime; // 高波动率环境下需要更快的出场 if (volatilityRegime === 'high') { volatilityAdjustment = 0.7; // 缩短30%的持仓时间 } else if (volatilityRegime === 'extreme') { volatilityAdjustment = 0.5; // 缩短50%的持仓时间 } else if (volatilityRegime === 'low') { volatilityAdjustment = 1.3; // 延长30%的持仓时间 } // 更新时间相关的出场策略 const baseHoldingPeriod = 30; exitStrategy.timeBasedExit = `持仓${Math.round(baseHoldingPeriod * volatilityAdjustment)}个交易日后仍未达到第一个止盈位,考虑减仓或退出`; exitStrategy.maximumHoldingPeriod = `${Math.round(baseHoldingPeriod * 1.5 * volatilityAdjustment)}个交易日,无论盈亏均考虑清仓`; } // 确定止盈位 if (direction === TradeDirection.Long) { // 找出当前价格上方的阻力位 const resistanceLevels = keyLevels .filter(level => level.type === 'resistance' && level.price > entryPrice) .sort((a, b) => a.price - b.price); // 从形态分析中找出目标价位 const patternTargets = patternAnalysis.timeframeAnalyses .filter(tfa => tfa.dominantPattern && tfa.dominantPattern.direction === PatternDirection.Bullish) .map(tfa => tfa.dominantPattern?.priceTarget) .filter(price => price && price > entryPrice) .sort((a, b) => (a || 0) - (b || 0)); // 组合阻力位和目标价位 const takeProfitCandidates = [ ...resistanceLevels.map(r => r.price), ...patternTargets, ] .filter(Boolean) .sort((a, b) => a - b); // 选择1-3个止盈位 if (takeProfitCandidates.length > 0) { // 第一个止盈位(短期) const firstTP = takeProfitCandidates[0]; const firstTPRatio = (firstTP - entryPrice) / entryPrice; exitStrategy.takeProfitLevels.push({ price: firstTP, proportion: 0.3, // 30%仓位 reasoning: `第一个阻力位,约${(firstTPRatio * 100).toFixed(1)}%收益`, }); // 第二个止盈位(中期) if (takeProfitCandidates.length > 1) { const secondTP = takeProfitCandidates[1]; const secondTPRatio = (secondTP - entryPrice) / entryPrice; exitStrategy.takeProfitLevels.push({ price: secondTP, proportion: 0.4, // 40%仓位 reasoning: `第二个阻力位/目标价,约${(secondTPRatio * 100).toFixed(1)}%收益`, }); // 第三个止盈位(长期) if (takeProfitCandidates.length > 2) { const thirdTP = takeProfitCandidates[2]; const thirdTPRatio = (thirdTP - entryPrice) / entryPrice; exitStrategy.takeProfitLevels.push({ price: thirdTP, proportion: 0.3, // 剩余30%仓位 reasoning: `长期目标价/主要阻力位,约${(thirdTPRatio * 100).toFixed(1)}%收益`, }); } else { // 如果没有第三个明确的阻力位,计算一个基于前两个的延伸目标 const extrapolatedTP = secondTP + (secondTP - firstTP); const extrapolatedTPRatio = (extrapolatedTP - entryPrice) / entryPrice; exitStrategy.takeProfitLevels.push({ price: extrapolatedTP, proportion: 0.3, // 剩余30%仓位 reasoning: `基于图表投射的延伸目标,约${(extrapolatedTPRatio * 100).toFixed(1)}%收益`, }); } } else { // 如果只有一个阻力位,根据该位置计算更远的目标 const projectedTP = firstTP * 1.05; // 简单地增加5% const projectedTPRatio = (projectedTP - entryPrice) / entryPrice; exitStrategy.takeProfitLevels.push({ price: projectedTP, proportion: 0.7, // 剩余70%仓位 reasoning: `基于唯一阻力位推算的延伸目标,约${(projectedTPRatio * 100).toFixed(1)}%收益`, }); } } else { // 如果没有清晰的阻力位,设置百分比目标 exitStrategy.takeProfitLevels.push({ price: entryPrice * 1.05, // 5% 利润 proportion: 0.5, // 50% 仓位 reasoning: '基于入场价格5%涨幅的初始目标', }); exitStrategy.takeProfitLevels.push({ price: entryPrice * 1.1, // 10% 利润 proportion: 0.5, // 剩余50% 仓位 reasoning: '基于入场价格10%涨幅的延伸目标', }); } } else if (direction === TradeDirection.Short) { // 找出当前价格下方的支撑位 const supportLevels = keyLevels .filter(level => level.type === 'support' && level.price < entryPrice) .sort((a, b) => b.price - a.price); // 从形态分析中找出目标价位 const patternTargets = patternAnalysis.timeframeAnalyses .filter(tfa => tfa.dominantPattern && tfa.dominantPattern.direction === PatternDirection.Bearish) .map(tfa => tfa.dominantPattern?.priceTarget) .filter(price => price && price < entryPrice) .sort((a, b) => (b || 0) - (a || 0)); // 组合支撑位和目标价位 const takeProfitCandidates = [ ...supportLevels.map(r => r.price), ...patternTargets, ] .filter(Boolean) .sort((a, b) => b - a); // 降序排列,先找最高的支撑位 // 选择1-3个止盈位 if (takeProfitCandidates.length > 0) { // 第一个止盈位(短期) const firstTP = takeProfitCandidates[0]; const firstTPRatio = (entryPrice - firstTP) / entryPrice; exitStrategy.takeProfitLevels.push({ price: firstTP, proportion: 0.3, // 30% 仓位 reasoning: `第一个支撑位,约${(firstTPRatio * 100).toFixed(1)}%收益`, }); // 第二个止盈位(中期) if (takeProfitCandidates.length > 1) { const secondTP = takeProfitCandidates[1]; const secondTPRatio = (entryPrice - secondTP) / entryPrice; exitStrategy.takeProfitLevels.push({ price: secondTP, proportion: 0.4, // 40% 仓位 reasoning: `第二个支撑位/目标价,约${(secondTPRatio * 100).toFixed(1)}%收益`, }); // 第三个止盈位(长期) if (takeProfitCandidates.length > 2) { const thirdTP = takeProfitCandidates[2]; const thirdTPRatio = (entryPrice - thirdTP) / entryPrice; exitStrategy.takeProfitLevels.push({ price: thirdTP, proportion: 0.3, // 剩余30% 仓位 reasoning: `长期目标价/主要支撑位,约${(thirdTPRatio * 100).toFixed(1)}%收益`, }); } else { // 如果没有第三个支撑位,计算延伸目标 const extrapolatedTP = secondTP - (firstTP - secondTP); const extrapolatedTPRatio = (entryPrice - extrapolatedTP) / entryPrice; exitStrategy.takeProfitLevels.push({ price: extrapolatedTP, proportion: 0.3, // 剩余30% 仓位 reasoning: `基于图表投射的延伸目标,约${(extrapolatedTPRatio * 100).toFixed(1)}%收益`, }); } } else { // 如果只有一个支撑位,根据该位置计算更远的目标 const projectedTP = firstTP * 0.95; // 简单地降低5% const projectedTPRatio = (entryPrice - projectedTP) / entryPrice; exitStrategy.takeProfitLevels.push({ price: projectedTP, proportion: 0.7, // 剩余70% 仓位 reasoning: `基于唯一支撑位推算的延伸目标,约${(projectedTPRatio * 100).toFixed(1)}%收益`, }); } } else { // 如果没有清晰的支撑位,设置百分比目标 exitStrategy.takeProfitLevels.push({ price: entryPrice * 0.95, // 做空5% 利润 proportion: 0.5, // 50% 仓位 reasoning: '基于入场价格5%跌幅的初始目标', }); exitStrategy.takeProfitLevels.push({ price: entryPrice * 0.9, // 做空10% 利润 proportion: 0.5, // 剩余50% 仓位 reasoning: '基于入场价格10%跌幅的延伸目标', }); } } // 确定止损位置 if (direction === TradeDirection.Long) { // 做多仓位的止损设置 const potentialStopLevels = []; // 首先查找入场价下方的支撑位 const supportLevels = keyLevels .filter(level => level.type === 'support' && level.price < entryPrice) .sort((a, b) => b.price - a.price); if (supportLevels.length > 0) { // 使用最高的支撑位下方作为止损 potentialStopLevels.push(supportLevels[0].price * 0.99); // 如果有第二个支撑位,也考虑作为备选止损 if (supportLevels.length > 1) { potentialStopLevels.push(supportLevels[1].price * 0.99); } } // 查找形态分析中的止损建议 const patternStopLoss = findPatternStopLoss(patternAnalysis, direction); if (patternStopLoss && patternStopLoss < entryPrice) { potentialStopLevels.push(patternStopLoss); } // 如果没有找到合适的止损位,使用固定百分比止损 if (potentialStopLevels.length === 0) { potentialStopLevels.push(entryPrice * 0.95); // 入场价下方5% } // 将止损位添加到策略中 exitStrategy.stopLossLevels = potentialStopLevels.map((price, index) => { const stopRatio = (entryPrice - price) / entryPrice; return { price, type: index === 0 ? 'fixed' : 'trailing', reasoning: index === 0 ? `主要止损位,风险${(stopRatio * 100).toFixed(1)}%` : `次要止损位,风险${(stopRatio * 100).toFixed(1)}%`, }; }); } else if (direction === TradeDirection.Short) { // 做空仓位的止损设置 const potentialStopLevels = []; // 查找入场价上方的阻力位 const resistanceLevels = keyLevels .filter(level => level.type === 'resistance' && level.price > entryPrice) .sort((a, b) => a.price - b.price); if (resistanceLevels.length > 0) { // 使用最低的阻力位上方作为止损 potentialStopLevels.push(resistanceLevels[0].price * 1.01); // 如果有第二个阻力位,也考虑作为备选止损 if (resistanceLevels.length > 1) { potentialStopLevels.push(resistanceLevels[1].price * 1.01); } } // 查找形态分析中的止损建议 const patternStopLoss = findPatternStopLoss(patternAnalysis, direction); if (patternStopLoss && patternStopLoss > entryPrice) { potentialStopLevels.push(patternStopLoss); } // 如果没有找到合适的止损位,使用固定百分比止损 if (potentialStopLevels.length === 0) { potentialStopLevels.push(entryPrice * 1.05); // 入场价上方5% } // 将止损位添加到策略中 exitStrategy.stopLossLevels = potentialStopLevels.map((price, index) => { const stopRatio = (price - entryPrice) / entryPrice; return { price, type: index === 0 ? 'fixed' : 'trailing', reasoning: index === 0 ? `主要止损位,风险${(stopRatio * 100).toFixed(1)}%` : `次要止损位,风险${(stopRatio * 100).toFixed(1)}%`, }; }); } return exitStrategy; } /** * 从形态分析中找出止损位建议 */ export function findPatternStopLoss(patternAnalysis, direction) { // 寻找与交易方向一致且可靠性高的形态 const relevantPatterns = patternAnalysis.timeframeAnalyses .filter(tfa => tfa.dominantPattern && ((tfa.dominantPattern.direction === PatternDirection.Bullish && direction === TradeDirection.Long) || (tfa.dominantPattern.direction === PatternDirection.Bearish && direction === TradeDirection.Short)) && tfa.dominantPattern.reliability > 60) .map(tfa => tfa.dominantPattern); // 如果有多个形态,按照可靠性降序排序 relevantPatterns.sort((a, b) => (b?.reliability || 0) - (a?.reliability || 0)); // 返回最可靠形态的止损建议 return relevantPatterns[0]?.stopLoss || null; } /** * 确定风险管理策略 */ export function determineRiskManagement(direction, entryStrategy, exitStrategy, confidenceScore, signalStrength, volatilityAnalysis // 新增:考虑波动率 ) { // 默认风险管理参数 const riskManagement = { suggestionPosition: 0.1, // 默认使用10%的账户资金 riskRewardRatio: 1.0, maxLoss: '账户总资金的1%', volatilityConsideration: '标准波动性考虑', adjustmentTriggers: [], }; // 根据波动率调整仓位和风险考虑 if (volatilityAnalysis) { const volatilityRegime = volatilityAnalysis.volatilityAnalysis.volatilityRegime; if (volatilityRegime === 'high') { riskManagement.volatilityConsideration = '高波动性市场,建议分批建仓并使用较紧的止损'; riskManagement.suggestionPosition *= 0.8; // 减少20%仓位 riskManagement.adjustmentTriggers.push('波动率继续增加时考虑进一步减仓'); } else if (volatilityRegime === 'extreme') { riskManagement.volatilityConsideration = '极端波动性市场,建议最小仓位交易并随时准备退出'; riskManagement.suggestionPosition *= 0.6; // 减少40%仓位 riskManagement.adjustmentTriggers.push('波动率继续处于极高水平时考虑暂停新入场'); } else if (volatilityRegime === 'low') { // 检查布林带挤压情况 if (volatilityAnalysis.volatilityAnalysis.bollingerBandWidth < 3.5) { riskManagement.volatilityConsideration = '低波动性市场但布林带挤压,可能即将爆发,建议做好准备'; // 不调整仓位,但增加警告 riskManagement.adjustmentTriggers.push('波动率突然增加时准备快速调整仓位'); } else { riskManagement.volatilityConsideration = '低波动性市场,可小幅增加仓位'; riskManagement.suggestionPosition *= 1.2; // 增加20%仓位 } } } // 根据信号强度调整仓位 if (signalStrength === SignalStrength.Strong) { riskManagement.suggestionPosition = 0.2; // 强信号使用20%资金 } else if (signalStrength === SignalStrength.Moderate) { riskManagement.suggestionPosition = 0.15; // 中等信号使用15%资金 } else if (signalStrength === SignalStrength.Weak) { riskManagement.suggestionPosition = 0.1; // 弱信号使用10%资金 } else if (signalStrength === SignalStrength.Neutral || signalStrength === SignalStrength.Conflicting) { riskManagement.suggestionPosition = 0.05; // 中性或冲突信号使用5%资金 } // 根据信心分数调整 riskManagement.suggestionPosition *= 0.5 + confidenceScore / 200; // 增加或减少高达50%的仓位 // 根据入场策略的风险级别调整 if (entryStrategy.riskLevel === RiskLevel.High) { riskManagement.suggestionPosition *= 0.7; // 高风险入场减少30%仓位 } else if (entryStrategy.riskLevel === RiskLevel.Low) { riskManagement.suggestionPosition *= 1.2; // 低风险入场增加20%仓位 } // 确保仓位在合理范围内 riskManagement.suggestionPosition = Math.min(0.3, Math.max(0.05, riskManagement.suggestionPosition)); // 计算风险回报比(方向敏感,选择合理的止损与收益测度) if (exitStrategy.takeProfitLevels.length > 0 && exitStrategy.stopLossLevels.length > 0) { const entry = entryStrategy.idealEntryPrice; const stopPrices = exitStrategy.stopLossLevels.map(l => l.price); let chosenStop = stopPrices[0]; if (direction === TradeDirection.Long) { const below = stopPrices.filter(p => p < entry); // 取最贴近入场价的下方止损(风险最小) chosenStop = below.length > 0 ? Math.max(...below) : stopPrices.reduce((a, b) => Math.abs(a - entry) < Math.abs(b - entry) ? a : b); } else if (direction === TradeDirection.Short) { const above = stopPrices.filter(p => p > entry); // 取最贴近入场价的上方止损 chosenStop = above.length > 0 ? Math.min(...above) : stopPrices.reduce((a, b) => Math.abs(a - entry) < Math.abs(b - entry) ? a : b); } const potentialRisk = Math.max(1e-8, Math.abs(entry - chosenStop)); const weightedReward = calculateWeightedReward(direction, entry, exitStrategy.takeProfitLevels); const potentialReward = Math.max(0, weightedReward); riskManagement.riskRewardRatio = potentialReward / potentialRisk; } // 设置最大损失 const maxLossPercentage = 1 - riskManagement.suggestionPosition > 0.95 ? 1.0 // 如果仓位很小,风险较低 : 2.0; // 如果仓位较大,可接受更高风险 riskManagement.maxLoss = `账户总资金的${maxLossPercentage.toFixed(1)}%`; // 设置调整触发条件 riskManagement.adjustmentTriggers.push('当价格达到第一个止盈位时,将止损上调至成本价'); if (confidenceScore < 60) { riskManagement.adjustmentTriggers.push('如果交易初期出现不利走势,可提前减仓50%'); } return riskManagement; } /** * 计算加权平均潜在收益 */ export function calculateWeightedReward(direction, entryPrice, takeProfitLevels) { if (takeProfitLevels.length === 0) return 0; let weightedReward = 0; let totalProportion = 0; for (const level of takeProfitLevels) { const reward = direction === TradeDirection.Long ? level.price - entryPrice : entryPrice - level.price; weightedReward += reward * level.proportion; totalProportion += level.proportion; } return totalProportion > 0 ? weightedReward / totalProportion : 0; } /** * 生成警告信息 */ export function generateWarnings(chipAnalysis, patternAnalysis, direction, signalStrength) { const warnings = []; // 检查信号强度 if (signalStrength === SignalStrength.Weak) { warnings.push('信号强度较弱,建议减小仓位并严格设置止损'); } else if (signalStrength === SignalStrength.Conflicting) { warnings.push('筹码分析与形态分析出现信号冲突,建议额外谨慎'); } // 检查时间周期冲突 if (chipAnalysis.timeframeConflicts.length > 0) { warnings.push(`存在时间周期冲突: ${chipAnalysis.timeframeConflicts.join('; ')}`); } // 检查趋势一致性 if (chipAnalysis.trendConsistency === '弱') { warnings.push('趋势一致性较弱,各时间周期走势不明朗'); } // 检查形态分析的可靠性 if (patternAnalysis.signalStrength < 50) { warnings.push('图表形态信号不够明确,请寻求额外确认'); } // 检查方向与多数时间周期的一致性 if (direction === TradeDirection.Long && chipAnalysis.timeframeAlignment.includes('看空')) { warnings.push('多数时间周期呈看空状态,与当前交易方向冲突'); } else if (direction === TradeDirection.Short && chipAnalysis.timeframeAlignment.includes('看多')) { warnings.push('多数时间周期呈看多状态,与当前交易方向冲突'); } // 检查主要时间周期与长期趋势的一致性 if (direction === TradeDirection.Long && chipAnalysis.longTermOutlook.includes('看空')) { warnings.push('长期趋势看空,当前多头操作可能是逆势交易'); } else if (direction === TradeDirection.Short && chipAnalysis.longTermOutlook.includes('看多')) { warnings.push('长期趋势看多,当前空头操作可能是逆势交易'); } // 检查获利筹码比例(如果适用) const timeframe = chipAnalysis.timeframes.find(tf => tf.timeframe === chipAnalysis.primaryTimeframe); if (timeframe && direction === TradeDirection.Long && timeframe.analysis.profitChipsPercentage > 80) { warnings.push('获利筹码比例过高,可能面临较大抛压'); } else if (timeframe && direction === TradeDirection.Short && timeframe.analysis.profitChipsPercentage < 20) { warnings.push('套牢筹码比例过高, 可能面临较大买盘支撑'); } return warnings; } /** * 生成确认信号条件 */ export function generateConfirmationSignals(direction, chipAnalysis, patternAnalysis) { const confirmationSignals = []; // 添加成交量确认条件 if (direction === TradeDirection.Long) { confirmationSignals.push({ type: 'volume', description: '向上突破时成交量明显放大,至少高于前5日平均成交量的1.5倍', priority: 'important', }); } else if (direction === TradeDirection.Short) { confirmationSignals.push({ type: 'volume', description: '向下突破时成交量明显放大,至少高于前5日平均成交量的1.5倍', priority: 'important', }); } // 添加形态确认条件 const relevantPattern = patternAnalysis.timeframeAnalyses.find(tfa => tfa.timeframe === chipAnalysis.primaryTimeframe)?.dominantPattern; if (relevantPattern && relevantPattern.status === 'completed') { confirmationSignals.push({ type: 'pattern', description: `确认${relevantPattern.patternType}形态完成突破,价格站稳颈线/突破位`, priority: 'critical', }); } // 添加时间周期一致性确认 if (chipAnalysis.timeframeAlignment.includes('中性') || chipAnalysis.alignmentStrength < 70) { confirmationSignals.push({ type: 'indicator', description: '多个时间周期指标转向一致,确认交易方向', priority: 'important', }); } // 添加价格行为确认 if (direction === TradeDirection.Long) { confirmationSignals.push({ type: 'price', description: '价格站稳关键阻力位上方,且收盘价连续2天保持在该位置上方', priority: 'important', }); } else if (direction === TradeDirection.Short) { confirmationSignals.push({ type: 'price', description: '价格跌破关键支撑位,且收盘价连续2天保持在该位置下方', priority: 'important', }); } return confirmationSignals; } /** * 生成无效信号条件 */ export function generateInvalidationConditions(direction, chipAnalysis, patternAnalysis, keyLevels, exitStrategy) { const invalidationConditions = []; // 添加止损触发条件 if (exitStrategy.stopLossLevels.length > 0) { invalidationConditions.push({ type: 'price', description: `价格触及主要止损位${exitStrategy.stopLossLevels[0].price.toFixed(2)}`, priority: 'critical', }); } // 添加关键价位失效条件 if (direction === TradeDirection.Long) { // 找出关键支撑位 const criticalSupport = keyLevels .filter(level => level.type === 'support' && level.strength === 'strong') .sort((a, b) => b.price - a.price)[0]; if (criticalSupport) { invalidationConditions.push({ type: 'price', description: `价格跌破强支撑位${criticalSupport.price.toFixed(2)}且无法快速收复`, priority: 'important', }); } } else if (direction === TradeDirection.Short) { // 找出关键阻力位 const criticalResistance = keyLevels .filter(level => level.type === 'resistance' && level.strength === 'strong') .sort((a, b) => a.price - b.price)[0]; if (criticalResistance) { invalidationConditions.push({ type: 'price', description: `价格突破强阻力位${criticalResistance.price.toFixed(2)}且无法快速回落`, priority: 'important', }); } } // 添加形态失效条件 const dominantPattern = patternAnalysis.timeframeAnalyses.find(tfa => tfa.timeframe === chipAnalysis.primaryTimeframe)?.dominantPattern; if (dominantPattern) { invalidationConditions.push({ type: 'pattern', description: `${dominantPattern.patternType}形态失败,出现与预期相反的突破`, priority: 'important', }); } // 添加时间周期转向条件 invalidationConditions.push({ type: 'indicator', description: `${chipAnalysis.primaryTimeframe === 'weekly' ? '周线' : chipAnalysis.primaryTimeframe === 'daily' ? '日线' : '小时'}指标发生明显转向,与交易方向相反`, priority: 'important', }); // 添加市场环境变化条件 invalidationConditions.push({ type: 'time', description: '长时间(超过预期持仓时间一半)无法向有利方向发展', priority: 'optional', }); return invalidationConditions; } /** * 分配时间周期优先级 * @param timeframes 时间周期 * @param primaryTimeframe 主要时间周期 * @returns 带有优先级的时间周期映射 */ function assignTimeframePriorities(timeframes, primaryTimeframe = 'daily') { const priorities = {}; // 首先设置主要时间周期 priorities[primaryTimeframe] = TimeframePriority.Primary; // 按照日线>周线>小时线的优先级顺序分配剩余优先级 const remainingTimeframes = timeframes.filter(tf => tf !== primaryTimeframe); if (remainingTimeframes.includes('daily') && primaryTimeframe !== 'daily') { priorities['daily'] = TimeframePriority.Secondary; } else if (remainingTimeframes.includes('weekly') && primaryTimeframe !== 'weekly') { priorities['weekly'] = TimeframePriority.Secondary; } else if (remainingTimeframes.includes('1hour') && primaryTimeframe !== '1hour') { priorities['1hour'] = TimeframePriority.Secondary; } // 分配第三优先级 const assignedTimeframes = Object.keys(priorities); const lastTimeframe = remainingTimeframes.find(tf => !assignedTimeframes.includes(tf)); if (lastTimeframe) { priorities[lastTimeframe] = TimeframePriority.Tertiary; } return priorities; } /** * 生成关键观察点 */ export function generateKeyObservations(chipAnalysis, patternAnalysis, keyLevels) { const observations = []; // 获取时间周期优先级 const timeframePriorities = assignTimeframePriorities(chipAnalysis.timeframes.map(tf => tf.timeframe), chipAnalysis.primaryTimeframe); // 添加各时间周期优先级信息 observations.push(`时间周期优先级: 主要=${Object.keys(timeframePriorities).find(key => timeframePriorities[key] === TimeframePriority.Primary)}, 次要=${Object.keys(timeframePriorities).find(key => timeframePriorities[key] === TimeframePriority.Secondary)}, 第三=${Object.keys(timeframePriorities).find(key => timeframePriorities[key] === TimeframePriority.Tertiary)}`); // 添加筹码分布特征 const primaryTimeframe = chipAnalysis.timeframes.find(tf => tf.timeframe === chipAnalysis.primaryTimeframe); if (primaryTimeframe) { observations.push(`${chipAnalysis.primaryTimeframe === 'weekly' ? '周线' : chipAnalysis.primaryTimeframe === 'daily' ? '日线' : '小时'}筹码集中度: ${primaryTimeframe.analysis.concentrationLevel}`); observations.push(`筹码形态: ${primaryTimeframe.analysis.chipShape}`); observations.push(`获利盘比例: ${primaryTimeframe.analysis.profitChipsPercentage.toFixed(1)}%`); } // 添加趋势特征 observations.push(`趋势方向: ${chipAnalysis.trendDirection}, 一致性: ${chipAnalysis.trendConsistency}`); // 添加主要形态特征 const dominantPattern = patternAnalysis.timeframeAnalyses.find(tfa => tfa.timeframe === chipAnalysis.primaryTimeframe)?.dominantPattern; if (dominantPattern) { observations.push(`主导形态: ${dominantPattern.patternType}, 可靠性: ${dominantPattern.reliability}/100`); observations.push(`形态描述: ${dominantPattern.description}`); } // 添加关键价位 const supports = keyLevels .filter(level => level.type === 'support') .sort((a, b) => b.price - a.price); const resistances = keyLevels .filter(level => level.type === 'resistance') .sort((a, b) => a.price - b.price); if (supports.length > 0) { observations.push(`主要支撑位: ${supports .slice(0, Math.min(3, supports.length)) .map(s => s.price.toFixed(2)) .join(', ')}`); } if (resistances.length > 0) { observations.push(`主要阻力位: ${resistances .slice(0, Math.min(3, resistances.length)) .map(r => r.price.toFixed(2)) .join(', ')}`); } // 添加时间周期一致性 observations.push(`时间周期一致性: ${chipAnalysis.timeframeAlignment}, 强度: ${chipAnalysis.alignmentStrength}%`); // 添加短中长期展望 observations.push(`短期展望(小时): ${chipAnalysis.shortTermOutlook}, 中期展望(日线): ${chipAnalysis.mediumTermOutlook}, 长期展望(周线): ${chipAnalysis.longTermOutlook}`); return observations; } /** * 生成主要理由描述 */ export function generatePrimaryRationale(direction, chipAnalysis, patternAnalysis) { if (direction === TradeDirection.Neutral) { return '综合分析显示市场信号中性,无明确交易方向'; } let rationale = direction === TradeDirection.Long ? '做多理由: ' : '做空理由: '; // 添加筹码分析理由 if (direction === TradeDirection.Long) { if (chipAnalysis.combinedBuySignalStrength > 60) { rationale += `筹码分析显示强烈买入信号(${chipAnalysis.combinedBuySignalStrength}/100),`; // 添加详细理由 if (chipAnalysis.timeframeAlignment.includes('看多')) { rationale += `多个时间周期一致看多(${chipAnalysis.alignmentStrength}%),`; } const primaryTimeframe = chipAnalysis.timeframes.find(tf => tf.timeframe === chipAnalysis.primaryTimeframe); if (primaryTimeframe) { if (primaryTimeframe.analysis.profitChipsPercentage < 50) { rationale += '获利筹码比例较低,抛压有限,'; } if (primaryTimeframe.analysis.concentrationLevel.includes('高')) { rationale += '筹码分布集中,支撑强劲,'; } } } else { rationale += `筹码分析显示中性偏多信号(${chipAnalysis.combinedBuySignalStrength}/100),`; } } else { if (chipAnalysis.combinedShortSignalStrength > 60) { rationale += `筹码分析显示强烈卖出信号(${chipAnalysis.combinedShortSignalStrength}/100),`; // 添加详细理由 if (chipAnalysis.timeframeAlignment.includes('看空')) { rationale += `多个时间周期一致看空(${chipAnalysis.alignmentStrength}%),`; } const primaryTimeframe = chipAnalysis.timeframes.find(tf => tf.timeframe === chipAnalysis.primaryTimeframe); if (primaryTimeframe) { if (primaryTimeframe.analysis.profitChipsPercentage > 70) { rationale += '获利筹码比例较高,抛压巨大,'; } if (primaryTimeframe.analysis.concentrationLevel.includes('分散')) { rationale += '筹码分布分散,支撑较弱,'; } } } else { rationale += `筹码分析显示中性偏空信号(${chipAnalysis.combinedShortSignalStrength}/100),`; } } // 添加形态分析理由 if (direction === TradeDirection.Long && patternAnalysis.combinedSignal === PatternDirection.Bullish) { rationale += `形态分析显示看涨信号(${patternAnalysis.signalStrength}/100),`; // 添加主要形态描述 const bullishPatterns = patternAnalysis.timeframeAnalyses .filter(tfa => tfa.dominantPattern?.direction === PatternDirection.Bullish) .sort((a, b) => (b.dominantPattern?.reliability || 0) - (a.dominantPattern?.reliability || 0)); if (bullishPatterns.length > 0 && bullishPatterns[0].dominantPattern) { rationale += `${bullishPatterns[0].timeframe === 'weekly' ? '周线' : bullishPatterns[0].timeframe === 'daily' ? '日线' : '小时'}出现${bullishPatterns[0].dominantPattern.patternType}形态,`; } } else if (direction === TradeDirection.Short && patternAnalysis.combinedSignal === PatternDirection.Bearish) { rationale += `形态分析显示看跌信号(${patternAnalysis.signalStrength}/100),`; // 添加主要形态描述 const bearishPatterns = patternAnalysis.timeframeAnalyses .filter(tfa => tfa.dominantPattern?.direction === PatternDirection.Bearish) .sort((a, b) => (b.dominantPattern?.reliability || 0) - (a.dominantPattern?.reliability || 0)); if (bearishPatterns.length > 0 && bearishPatterns[0].dominantPattern) { rationale += `${bearishPatterns[0].timeframe === 'weekly' ? '周线' : bearishPatterns[0].timeframe === 'daily' ? '日线' : '小时'}出现${bearishPatterns[0].dominantPattern.patternType}形态,`; } } else { rationale += '形态分析信号不明确,'; } // 添加趋势分析 rationale += `市场整体处于${chipAnalysis.trendDirection},趋势一致性${chipAnalysis.trendConsistency}。`; return rationale; } /** * 生成次要理由描述 */ export function generateSecondaryRationale(direction, chipAnalysis, timeframeConsistency, timeframeConsistencyStrength) { if (direction === TradeDirection.Neutral) { return '各时间周期信号混合,建议观望等待更明确方向'; } let rationale = '辅助理由: '; // 添加时间周期一致性 if (timeframeConsistency === '看多' && direction === TradeDirection.Long) { rationale += `多个时间周期一致看多(${timeframeConsistencyStrength}%),`; } else if (timeframeConsistency === '看空' && direction === TradeDirection.Short) { rationale += `多个时间周期一致看空(${timeframeConsistencyStrength}%),`; } else if (timeframeConsistency === '中性') { rationale += '各时间周期呈中性状态,'; } else { rationale += `时间周期一致性较弱(${timeframeConsistencyStrength}%),`; } // 添加技术指标信号 const primaryTimeframe = chipAnalysis.timeframes.find(tf => tf.timeframe === chipAnalysis.primaryTimeframe); if (primaryTimeframe) { rationale += `${chipAnalysis.primaryTimeframe === 'weekly' ? '周线' : chipAnalysis.primaryTimeframe === 'daily' ? '日线' : '小时'}技术指标: `; if (primaryTimeframe.analysis.macdSignal) { rationale += `MACD ${primaryTimeframe.analysis.macdSignal},`; } if (primaryTimeframe.analysis.rsiLevel) { rationale += `RSI ${primaryTimeframe.analysis.rsiLevel},`; } if (primaryTimeframe.analysis.bollingerStatus) { rationale += `布林带 ${primaryTimeframe.analysis.bollingerStatus},`; } } // 添加支撑阻力位情况 if (direction === TradeDirection.Long) { if (chipAnalysis.aggregatedSupportLevels.length > 0) { rationale += `多个时间周期确认的支撑位: ${chipAnalysis.aggregatedSupportLevels .slice(0, 2) .map(level => level.toFixed(2)) .join(', ')},`; } } else { if (chipAnalysis.aggregatedResistanceLevels.length > 0) { rationale += `多个时间周期确认的阻力位: ${chipAnalysis.aggregatedResistanceLevels .slice(0, 2) .map(level => level.toFixed(2)) .join(', ')},`; } } // 添加短中长期展望 rationale += `短期(小时)${chipAnalysis.shortTermOutlook},中期(日线)${chipAnalysis.mediumTermOutlook},长期(周线)${chipAnalysis.longTermOutlook}。`; return rationale; } /** * 生成总结 */ export function generateSummary(symbol, direction, signalStrength, confidenceScore, patternDesc, entryPrice, volumeAnalysis, volatilityAnalysis, takeProfitPrice, stopLossPrice) { if (direction === TradeDirection.Neutral) { return `${symbol}当前无明确交易信号,建议观望等待更清晰的市场方向。信号强度: ${signalStrength},确信度: ${confidenceScore.toFixed(2)}/100。`; } let summary = `${symbol}${direction === TradeDirection.Long ? '做多' : '做空'}信号,信号强度: ${signalStrength},确信度: ${confidenceScore.toFixed(2)}/100。建议入场价格: ${entryPrice.toFixed(2)}\n`; summary += `形态分析: ${patternDesc}\n`; // 新增:添加积累分布线分析 if (volumeAnalysis) { summary += `\n积累分布线分析: ${volumeAnalysis.volumeAnalysis.adTrend === 'bullish' ? '资金流入占优' : volumeAnalysis.volumeAnalysis.adTrend === 'bearish' ? '资金流出占优' : '资金流向中性'}`; if (volumeAnalysis.volumeAnalysis.divergence.type !== 'none') { summary += `,检测到${volumeAnalysis.volumeAnalysis.divergence.type === 'bullish' ? '看涨' : volumeAnalysis.volumeAnalysis.divergence.type === 'bearish' ? '看跌' : volumeAnalysis.volumeAnalysis.divergence.type === 'hidden_bullish' ? '隐藏看涨' : '隐藏看跌'}背离`; } summary += `\n`; } // 新增:添加波动率分析 if (volatilityAnalysis) { summary += `\n波动率分析: ${volatilityAnalysis.volatilityAnalysis.volatilityRegime === 'low' ? '低波动' : volatilityAnalysis.volatilityAnalysis.volatilityRegime === 'medium' ? '中等波动' : volatilityAnalysis.volatilityAnalysis.volatilityRegime === 'high' ? '高波动' : '极端波动'}环境,${volatilityAnalysis.volatilityAnalysis.volatilityTrend}\n`; } if (takeProfitPrice) { summary += `,目标价格: ${takeProfitPrice.toFixed(2)}`; } if (stopLossPrice) { summary += `,止损价格: ${stopLossPrice.toFixed(2)}`; } summary += `。`; return summary; }