-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathanalyzer.py
More file actions
246 lines (206 loc) · 10.6 KB
/
analyzer.py
File metadata and controls
246 lines (206 loc) · 10.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
import indicators
import models
import data_loader
import report_generator
import visualization
class AdvancedStockAnalyzer:
def __init__(self, data_folder):
"""
高级股票分析器
Args:
data_folder (str): 股票数据文件夹路径
"""
self.data_folder = data_folder
self.stock_data = {}
self.fundamental_scores = {}
self.technical_signals = {}
self.alpha_factors = {}
def load_stock_data(self):
"""加载所有股票数据"""
self.stock_data = data_loader.load_stock_data(self.data_folder)
def calculate_alpha_factors(self, stock_code):
"""计算Alpha因子"""
if stock_code not in self.stock_data:
return None
return indicators.calculate_alpha_factors(stock_code, self.stock_data[stock_code]['data'])
def calculate_enhanced_fundamental_score(self, stock_code):
"""增强版基本面评分"""
if stock_code not in self.stock_data:
return None
df = self.stock_data[stock_code]['data']
stock_name = self.stock_data[stock_code]['name']
# 基础筛选
passed, reason = indicators.basic_filter(stock_code, stock_name, df)
if not passed:
return None
alpha_factors = self.alpha_factors.get(stock_code, {})
return models.calculate_enhanced_fundamental_score(stock_code, df, alpha_factors)
def detect_enhanced_technical_signals(self, stock_code):
"""增强版技术信号检测"""
if stock_code not in self.stock_data:
return None
df = self.stock_data[stock_code]['data']
alpha_factors = self.alpha_factors.get(stock_code, {})
return indicators.detect_enhanced_technical_signals(stock_code, df, alpha_factors)
def detect_short_term_technical_signals(self, stock_code):
"""检测短线技术信号"""
if stock_code not in self.stock_data:
return None
df = self.stock_data[stock_code]['data']
return indicators.detect_short_term_technical_signals(stock_code, df)
def predict_enhanced_price_movement(self, stock_code):
"""增强版价格走势预测"""
if stock_code not in self.stock_data:
return None
alpha_factors = self.alpha_factors.get(stock_code, {})
tech_signals = self.technical_signals.get(stock_code, {})
fund_score = self.fundamental_scores.get(stock_code, {})
return models.predict_enhanced_price_movement(stock_code, alpha_factors, tech_signals, fund_score)
def generate_kline_chart(self, stock_code, days=60):
"""生成K线图"""
if stock_code not in self.stock_data:
return None
df = self.stock_data[stock_code]['data']
name = self.stock_data[stock_code]['name']
return visualization.generate_kline_chart(stock_code, name, df, days)
def _get_main_signals(self, tech_signals):
"""获取主要技术信号"""
signals = []
signal_names = {
'MACD金叉': 'MACD金叉',
'RSI企稳': 'RSI企稳',
'强势回调反包': '强势回调',
'量能突破': '量能突破',
'价格突破': '价格突破',
'连续阳线': '连续阳线',
'量价协同': '量价协同',
'相对强势': '相对强势'
}
for signal_key, signal_name in signal_names.items():
if tech_signals.get(signal_key, False):
signals.append(signal_name)
return signals[:3]
def _get_short_term_signals(self, tech_signals):
"""获取短线技术信号"""
signals = []
signal_names = {
'MACD金叉': 'MACD金叉',
'MACD强势': 'MACD强势',
'RSI适中': 'RSI适中',
'RSI超卖': 'RSI超卖',
'价格突破': '价格突破',
'成交量放大': '成交量放大',
'连续上涨': '连续上涨',
'换手率活跃': '换手率活跃'
}
for signal_key, signal_name in signal_names.items():
if tech_signals.get(signal_key, False):
signals.append(signal_name)
return signals[:3]
def _get_investment_advice(self, comprehensive_score, prediction):
"""获取投资建议"""
if prediction:
confidence = prediction.get('置信度', 0)
risk_level = prediction.get('风险等级', '中风险')
if comprehensive_score >= 80 and confidence >= 70:
return f"强烈推荐 ({risk_level})"
elif comprehensive_score >= 60 and confidence >= 60:
return f"推荐 ({risk_level})"
elif comprehensive_score >= 40 and confidence >= 50:
return f"关注 ({risk_level})"
else:
return f"观望 ({risk_level})"
else:
return "数据不足"
def generate_stock_recommendations(self):
"""生成股票推荐(综合评分,15支)"""
recommendations = []
for stock_code in self.stock_data:
if (stock_code in self.fundamental_scores and
stock_code in self.technical_signals and
stock_code in self.alpha_factors):
fund_score = self.fundamental_scores[stock_code]
tech_signals = self.technical_signals[stock_code]
prediction = self.predict_enhanced_price_movement(stock_code)
total_score = fund_score.get('总分', 0)
tech_score = tech_signals.get('技术信号得分', 0)
comprehensive_score = total_score * 0.6 + tech_score * 0.4
recommendation = {
'股票代码': stock_code,
'股票名称': self.stock_data[stock_code]['name'],
'综合得分': round(comprehensive_score, 1),
'基本面得分': total_score,
'技术面得分': tech_score,
'预测信息': prediction,
'市值': fund_score.get('市值', 0),
'当前价格': self.stock_data[stock_code]['data']['收盘价'].iloc[-1],
'换手率': round(fund_score.get('换手率', 0), 2),
'20日趋势': round(fund_score.get('趋势', 0), 2),
'波动率': round(fund_score.get('波动率', 0), 2),
'主要信号': self._get_main_signals(tech_signals),
'投资建议': self._get_investment_advice(comprehensive_score, prediction)
}
recommendations.append(recommendation)
recommendations.sort(key=lambda x: x['综合得分'], reverse=True)
return recommendations[:15]
def get_short_term_stocks(self, n=20):
"""获取短线技术信号股票推荐(10-20支)"""
tech_sorted = []
for stock_code in self.stock_data:
# 计算短线技术信号
short_term_signals = self.detect_short_term_technical_signals(stock_code)
if short_term_signals and short_term_signals.get('技术信号得分', 0) > 20:
tech_sorted.append((stock_code, short_term_signals['技术信号得分']))
tech_sorted.sort(key=lambda x: x[1], reverse=True)
short_term_stocks = []
for stock_code, tech_score in tech_sorted[:n]:
if stock_code in self.fundamental_scores and self.fundamental_scores[stock_code].get('总分', 0) > 0:
stock_info = {
'股票代码': stock_code,
'股票名称': self.stock_data[stock_code]['name'],
'综合得分': round(self.fundamental_scores[stock_code].get('总分', 0) * 0.6 + tech_score * 0.4, 1),
'基本面得分': self.fundamental_scores[stock_code].get('总分', 0),
'技术面得分': tech_score,
'预测信息': self.predict_enhanced_price_movement(stock_code),
'市值': self.fundamental_scores[stock_code].get('市值', 0),
'当前价格': self.stock_data[stock_code]['data']['收盘价'].iloc[-1],
'换手率': round(self.fundamental_scores[stock_code].get('换手率', 0), 2),
'20日趋势': round(self.fundamental_scores[stock_code].get('趋势', 0), 2),
'波动率': round(self.fundamental_scores[stock_code].get('波动率', 0), 2),
'主要信号': self._get_short_term_signals(self.detect_short_term_technical_signals(stock_code)),
'投资建议': self._get_investment_advice(
round(self.fundamental_scores[stock_code].get('总分', 0) * 0.6 + tech_score * 0.4, 1),
self.predict_enhanced_price_movement(stock_code)
)
}
short_term_stocks.append(stock_info)
return short_term_stocks[:min(len(short_term_stocks), n)]
def generate_html_report(self, recommendations, short_term_stocks):
return report_generator.generate_html_report(recommendations, short_term_stocks)
def run_enhanced_analysis(self):
"""运行增强版分析"""
print("\n开始增强版股票分析...")
self.load_stock_data()
if not self.stock_data:
print("没有可用的股票数据")
return [], []
print("\n计算Alpha因子...")
for stock_code in self.stock_data:
factors = self.calculate_alpha_factors(stock_code)
if factors:
self.alpha_factors[stock_code] = factors
print("\n计算增强基本面评分...")
for stock_code in self.stock_data:
score = self.calculate_enhanced_fundamental_score(stock_code)
if score:
self.fundamental_scores[stock_code] = score
print("\n检测增强技术信号...")
for stock_code in self.stock_data:
signals = self.detect_enhanced_technical_signals(stock_code)
if signals:
self.technical_signals[stock_code] = signals
print("\n生成综合选股结果...")
recommendations = self.generate_stock_recommendations()
print("\n生成短线技术信号推荐...")
short_term_stocks = self.get_short_term_stocks()
return recommendations, short_term_stocks