-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmodels.py
More file actions
200 lines (162 loc) · 6.52 KB
/
models.py
File metadata and controls
200 lines (162 loc) · 6.52 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
import pandas as pd
import numpy as np
def calculate_enhanced_fundamental_score(stock_code, df, alpha_factors):
"""增强版基本面评分"""
try:
score_details = {}
total_score = 0
# 1. 估值合理性 (25分)
pe_score = 0
pb_score = 0
if '市盈率' in df.columns and pd.notna(df['市盈率'].iloc[-1]):
pe_ratio = df['市盈率'].iloc[-1]
if 8 < pe_ratio < 15:
pe_score = 15
elif 15 <= pe_ratio < 25:
pe_score = 10
elif 25 <= pe_ratio < 35:
pe_score = 5
else:
pe_score = 0
if '市净率' in df.columns and pd.notna(df['市净率'].iloc[-1]):
pb_ratio = df['市净率'].iloc[-1]
if 0.8 < pb_ratio < 2:
pb_score = 10
elif 2 <= pb_ratio < 3:
pb_score = 5
else:
pb_score = 0
valuation_score = pe_score + pb_score
score_details['估值评分'] = valuation_score
total_score += valuation_score
# 2. 成长性 (20分)
momentum_20d = alpha_factors.get('momentum_20d', 0)
momentum_60d = alpha_factors.get('momentum_60d', 0)
if momentum_60d > 20:
growth_score = 20
elif momentum_60d > 10:
growth_score = 15
elif momentum_60d > 0:
growth_score = 10
elif momentum_60d > -10:
growth_score = 5
else:
growth_score = 0
score_details['成长性评分'] = growth_score
total_score += growth_score
# 3. 流动性 (15分)
turnover_ratio = alpha_factors.get('turnover_ratio', 1)
volume_ratio_20d = alpha_factors.get('volume_ratio_20d', 1)
if turnover_ratio > 1.2 and volume_ratio_20d > 1.1:
liquidity_score = 15
elif turnover_ratio > 1.0 and volume_ratio_20d > 1.0:
liquidity_score = 10
elif turnover_ratio > 0.8:
liquidity_score = 5
else:
liquidity_score = 0
score_details['流动性评分'] = liquidity_score
total_score += liquidity_score
# 4. 技术面配合 (15分)
macd_signal = alpha_factors.get('macd_signal', 0)
rsi_position = alpha_factors.get('rsi_position', 0)
tech_score = 0
if macd_signal > 0:
tech_score += 8
if -0.3 < rsi_position < 0.3:
tech_score += 7
score_details['技术面评分'] = tech_score
total_score += tech_score
# 5. 市场位置 (10分)
price_position = alpha_factors.get('price_position', 0.5)
if 0.3 < price_position < 0.7:
position_score = 10
elif 0.2 < price_position < 0.8:
position_score = 7
else:
position_score = 3
score_details['位置评分'] = position_score
total_score += position_score
# 6. 稳定性 (10分)
volatility_20d = alpha_factors.get('volatility_20d', 10)
if volatility_20d < 3:
stability_score = 10
elif volatility_20d < 5:
stability_score = 7
elif volatility_20d < 7:
stability_score = 5
else:
stability_score = 0
score_details['稳定性评分'] = stability_score
total_score += stability_score
# 7. 量价协同 (5分)
price_volume_corr = alpha_factors.get('price_volume_corr', 0)
if price_volume_corr > 0.3:
pv_score = 5
elif price_volume_corr > 0:
pv_score = 3
else:
pv_score = 0
score_details['量价协同评分'] = pv_score
total_score += pv_score
score_details['总分'] = total_score
score_details['市值'] = df['总市值(元)'].iloc[-1]
score_details['换手率'] = alpha_factors.get('turnover_mean_20d', 0)
score_details['趋势'] = momentum_20d
score_details['波动率'] = volatility_20d
# 过滤基本面得分为0的股票
if total_score == 0:
return None
return score_details
except Exception as e:
print(f"计算 {stock_code} 增强基本面评分失败: {e}")
return None
def _get_risk_level(volatility, liquidity):
"""获取风险等级"""
if volatility < 3 and liquidity > 1.2:
return "低风险"
elif volatility < 5 and liquidity > 1.0:
return "中风险"
else:
return "高风险"
def predict_enhanced_price_movement(stock_code, alpha_factors, tech_signals, fund_score):
"""增强版价格走势预测"""
try:
momentum_5d = alpha_factors.get('momentum_5d', 0)
momentum_20d = alpha_factors.get('momentum_20d', 0)
momentum_60d = alpha_factors.get('momentum_60d', 0)
tech_score = tech_signals.get('技术信号得分', 0)
fundamental_score = fund_score.get('总分', 0)
volatility_20d = alpha_factors.get('volatility_20d', 5)
vol_adjust = min(1.5, max(0.5, 5 / volatility_20d))
liquidity_factor = alpha_factors.get('turnover_ratio', 1)
liquidity_adjust = min(1.3, max(0.7, liquidity_factor))
prediction_5d = (
momentum_5d * 0.2 +
momentum_20d * 0.3 +
tech_score * 0.3 +
fundamental_score * 0.2
) / 10 * vol_adjust * liquidity_adjust
prediction_15d = (
momentum_20d * 0.25 +
momentum_60d * 0.25 +
tech_score * 0.25 +
fundamental_score * 0.25
) / 8 * vol_adjust * liquidity_adjust
confidence_factors = [
min(100, tech_score * 2),
min(100, fundamental_score * 1.5),
min(100, (100 - volatility_20d * 10)),
min(100, liquidity_factor * 50)
]
confidence = sum(confidence_factors) / len(confidence_factors)
confidence = min(95, max(30, confidence))
return {
'5日预测涨幅': round(prediction_5d, 2),
'15日预测涨幅': round(prediction_15d, 2),
'置信度': round(confidence, 1),
'风险等级': _get_risk_level(volatility_20d, liquidity_factor)
}
except Exception as e:
print(f"预测 {stock_code} 增强价格走势失败: {e}")
return None