1. 技术面分析模块的整体设计思路
在股票分析系统中,技术面分析模块扮演着数据加工者的角色。这个模块的核心任务是将原始的K线数据转化为可供LLM理解的结构化技术指标摘要。不同于传统技术分析软件直接给出买卖信号的做法,我们的设计理念是"指标计算+简明参考",把最终的决策权交给能够综合多维度信息的LLM模型。
从工程架构角度看,这个模块采用了典型的数据处理流水线设计:
- 数据输入层:通过yfinance API获取K线数据
- 指标计算层:并行计算各类技术指标
- 逻辑判断层:根据指标值生成状态描述
- 输出格式化层:整理为LLM友好的结构化数据
这种分层设计使得每个环节都可以独立优化。比如当需要新增RSI指标时,只需在指标计算层添加相应函数,不会影响其他模块的正常工作。
2. 核心指标计算原理与实现细节
2.1 移动平均线(MA)的计算与趋势判断
移动平均线是技术分析中最基础的指标之一。我们的系统计算了四个关键周期的MA值:
python复制def calculate_ma(close_prices, windows=[5,10,20,60]):
ma_values = {}
for window in windows:
ma_values[f'MA{window}'] = close_prices.rolling(window=window).mean().iloc[-1]
return ma_values
趋势判断逻辑包含两个维度:
- 价格位置关系:当前价格相对于各MA线的位置(上方/下方)
- 均线排列形态:检查是否形成MA5>MA10>MA20>MA60的多头排列
这些布尔判断结果会存入trend_ma字典,为后续的LLM分析提供结构化输入。
2.2 MACD指标的计算与状态判断
MACD是一个结合了趋势和动量特征的复合指标。我们的实现采用标准参数(12,26,9):
python复制def _macd(close_prices, fast=12, slow=26, signal=9):
ema_fast = close_prices.ewm(span=fast, adjust=False).mean()
ema_slow = close_prices.ewm(span=slow, adjust=False).mean()
macd_line = ema_fast - ema_slow
signal_line = macd_line.ewm(span=signal, adjust=False).mean()
histogram = macd_line - signal_line
return {
'macd': macd_line.iloc[-1],
'signal': signal_line.iloc[-1],
'hist': histogram.iloc[-1],
'above_zero': macd_line.iloc[-1] > 0,
'golden_cross': (macd_line.iloc[-2] < signal_line.iloc[-2])
& (macd_line.iloc[-1] > signal_line.iloc[-1])
}
状态判断重点关注:
- MACD线与信号线的相对位置(金叉/死叉)
- MACD线与零轴的关系
- 柱状图的扩张/收缩趋势
2.3 KDJ指标的超买超卖判断
KDJ指标反映了价格的动量变化,特别适合判断短期超买超卖状态:
python复制def _kdj(high_prices, low_prices, close_prices, n=9):
lowest_low = low_prices.rolling(window=n).min()
highest_high = high_prices.rolling(window=n).max()
rsv = (close_prices - lowest_low) / (highest_high - lowest_low) * 100
K = rsv.ewm(com=2).mean()
D = K.ewm(com=2).mean()
J = 3*K - 2*D
return {
'K': K.iloc[-1],
'D': D.iloc[-1],
'J': J.iloc[-1],
'overbought': K.iloc[-1] > 80,
'oversold': K.iloc[-1] < 20
}
3. 入场/离场参考的生成逻辑
技术面分析最核心的价值在于为交易决策提供参考。我们的系统采用多指标综合判断的方式生成交易建议:
3.1 离场信号生成规则
- 趋势破位判断:
- 价格跌破MA20:考虑部分减仓
- 价格跌破MA60:考虑清仓离场
- 波动性止损:
- 基于ATR(14)计算动态止损位(1.5倍ATR)
- 当前价格与近期高点的回撤幅度
python复制def _compute_exit_levels(close_prices, ma_values, atr_value):
exit_rules = []
current_price = close_prices.iloc[-1]
# MA破位规则
if current_price < ma_values['MA20']:
exit_rules.append(f"跌破20日均线{ma_values['MA20']:.2f},考虑减仓")
if current_price < ma_values['MA60']:
exit_rules.append(f"跌破60日均线{ma_values['MA60']:.2f},建议离场")
# ATR止损规则
stop_loss_price = current_price - 1.5 * atr_value
exit_rules.append(f"根据波动率,止损参考价:{stop_loss_price:.2f}")
return exit_rules
3.2 入场信号生成规则
- 趋势确认:
- 价格站稳MA20上方
- 出现MA多头排列
- 突破信号:
- 突破近期高点
- MACD金叉配合
python复制def _compute_entry_levels(high_prices, close_prices, ma_values, macd_status):
entry_rules = []
current_price = close_prices.iloc[-1]
recent_high = high_prices.iloc[-20:].max()
# 趋势入场规则
if current_price > ma_values['MA20']:
entry_rules.append(f"站稳20日均线{ma_values['MA20']:.2f}上方,可考虑入场")
# 突破规则
if current_price > recent_high:
entry_rules.append(f"突破近期高点{recent_high:.2f},强势信号")
# MACD配合
if macd_status['golden_cross']:
entry_rules.append("MACD出现金叉,买入信号增强")
return entry_rules
4. 不同K线周期的处理策略
系统需要适配不同时间维度的分析需求,主要处理两类K线:
4.1 日K线(interval=1d)处理
- 默认获取6个月数据(约120根K线)
- 确保计算MA60有足够数据
- 技术指标参数保持标准值
- 盘前盘后数据通过prepost参数控制
4.2 分时K线(1m/5m/15m/30m/60m)处理
- 默认获取5天数据(1分钟线约480根)
- 动态调整计算窗口:
- MA60 → MA30(当数据不足时)
- KDJ计算窗口从9调整为5
- 更注重短期指标变化:
- 增加对成交量突变的检测
- 缩短ATR计算周期
python复制def adjust_parameters_for_intraday(interval):
params = {
'ma_window': 60,
'kdj_window': 9,
'atr_window': 14
}
if interval.endswith('m'):
params['ma_window'] = 30 if interval == '1m' else 45
params['kdj_window'] = 5
params['atr_window'] = 10
return params
5. 异常情况处理机制
在实际运行中会遇到各种数据问题,系统设计了完善的容错机制:
5.1 数据不足处理
- 检查K线数量是否满足最小要求:
- 日K:至少60根(完整计算MA60)
- 分K:至少30根
- 检查数据列是否完整(必须包含OHLC)
- 返回结构化的错误信息:
python复制{
'ok': False,
'reason': '历史数据不足(仅35根K线,需要至少60根)',
'required': 60,
'actual': 35
}
5.2 数据异常检测
- 价格异常波动检测(单根K线涨跌幅>10%)
- 成交量异常检测(突然放大10倍以上)
- 数据连续性检查(缺失交易日)
提示:当检测到数据异常时,除了返回错误信息,还会在日志中记录详细情况供后续分析。
6. 与LLM模块的对接设计
技术面分析结果需要转化为适合LLM处理的格式:
6.1 数据结构化输出
python复制technical_summary = {
'trend_ma': {
'MA5': 152.34,
'MA20': 148.56,
'price_above_MA5': True,
'bullish_arrangement': True
},
'macd_summary': {
'status': '零轴上金叉',
'hist_trend': '扩大'
},
'entry_note': "突破前高155.00可考虑入场",
'exit_note': "跌破148.50建议减仓"
}
6.2 Prompt构建策略
在full_analysis模块中,技术面信息会被整合为自然语言描述:
code复制技术面分析:
- 趋势:价格(154.20)位于所有均线之上,呈多头排列(MA5>MA10>MA20>MA60)
- MACD:零轴上方金叉,柱状线扩大
- KDJ:K值65,未超买
- 入场参考:突破前高155.00可考虑入场
- 离场参考:跌破148.50建议减仓
7. 性能优化实践
在处理高频数据时,我们采用了多种优化手段:
7.1 计算加速技巧
- 使用向量化运算替代循环
- 并行计算独立指标
- 缓存中间结果(如EMA计算)
python复制# 向量化计算示例
def vectorized_ma(close_prices, windows):
return {
f'MA{w}': close_prices.rolling(w).mean().iloc[-1]
for w in windows
}
7.2 内存优化
- 及时释放不再使用的DataFrame
- 使用高效的数据类型(float32替代float64)
- 分批处理超长K线序列
8. 测试验证方案
为确保指标计算的准确性,我们建立了多层次的测试体系:
8.1 单元测试
- 对比TA-Lib计算结果验证核心指标
- 边界测试(极短K线序列)
- 异常输入测试(空数据、NaN值)
8.2 回测验证
- 选取典型股票的历史数据
- 验证交易建议的合理性
- 分析不同市场环境下的表现
9. 扩展性与维护性设计
系统架构支持方便的指标扩展:
9.1 新增指标流程
- 在technical.py中添加计算函数
- 编写对应的状态判断逻辑
- 集成到get_technical_summary输出中
- 更新Prompt构建逻辑
9.2 参数配置化
所有技术指标参数通过配置文件管理:
yaml复制technical_params:
ma_windows: [5,10,20,60]
macd_params:
fast: 12
slow: 26
signal: 9
kdj_window: 9
10. 实际应用中的经验总结
经过大量实盘验证,我们积累了一些关键经验:
- 多时间框架验证:日线看趋势,小时线找时机
- 指标共振原则:至少两个指标同向时才更可靠
- 量价配合分析:突破必须伴随成交量放大
- 参数适应性调整:不同波动率的股票需要微调参数
注意:技术指标具有滞后性,应结合基本面分析综合判断。特别是在财报发布前后,技术信号可能会失效。