-
Notifications
You must be signed in to change notification settings - Fork 35
Expand file tree
/
Copy pathtdx_exporter.py
More file actions
215 lines (169 loc) · 6.57 KB
/
Copy pathtdx_exporter.py
File metadata and controls
215 lines (169 loc) · 6.57 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
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
通达信自选股导出工具
生成通达信可导入的自选股文件
"""
import struct
from typing import List
from pathlib import Path
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
class TDXExporter:
"""通达信自选股导出器"""
@staticmethod
def export_to_text(codes: List[str], output_file: str = "selected_stocks.txt"):
"""
导出为文本文件(最简单,手动导入)
Args:
codes: 股票代码列表
output_file: 输出文件路径
"""
with open(output_file, 'w', encoding='utf-8') as f:
for code in codes:
# 去掉市场前缀,通达信格式
clean_code = code.replace('sh', '').replace('sz', '')
# 确定市场代码
if code.lower().startswith('sh') or code.startswith('6'):
market = '1' # 上海
else:
market = '0' # 深圳
# 格式: 市场代码\t股票代码
f.write(f"{market}\t{clean_code}\n")
logger.info(f"导出文本文件成功: {output_file}, 共 {len(codes)} 只股票")
return output_file
@staticmethod
def export_to_csv(codes: List[str], names: List[str] = None, output_file: str = "selected_stocks.csv"):
"""
导出为CSV文件
Args:
codes: 股票代码列表
names: 股票名称列表
output_file: 输出文件路径
"""
import csv
with open(output_file, 'w', encoding='utf-8-sig', newline='') as f:
writer = csv.writer(f)
writer.writerow(['市场', '代码', '名称'])
for i, code in enumerate(codes):
clean_code = code.replace('sh', '').replace('sz', '')
if code.lower().startswith('sh') or code.startswith('6'):
market = '上海'
else:
market = '深圳'
name = names[i] if names and i < len(names) else ''
writer.writerow([market, clean_code, name])
logger.info(f"导出CSV文件成功: {output_file}, 共 {len(codes)} 只股票")
return output_file
@staticmethod
def generate_import_instructions(output_file: str) -> str:
"""
生成导入说明
Args:
output_file: 输出文件路径
Returns:
导入说明文本
"""
instructions = f"""
通达信自选股导入说明
===================
方法一: 使用文本文件导入(推荐)
1. 打开通达信软件
2. 进入自选股界面(快捷键: Ctrl+D 或点击"自选")
3. 右键点击空白处,选择"批量导入"
4. 选择文件: {output_file}
5. 确认导入
方法二: 手动添加
1. 打开通达信软件
2. 进入自选股界面
3. 逐个输入股票代码添加
注意事项:
- 导入前建议备份现有自选股
- 导入后请检查是否有重复股票
- 部分停牌或退市股票可能无法导入
"""
return instructions
@staticmethod
def export_with_metrics(
codes: List[str],
metrics_list: List[dict],
output_file: str = "selected_stocks_detailed.csv"
):
"""
导出详细信息(包含选股指标)
Args:
codes: 股票代码列表
metrics_list: 指标列表
output_file: 输出文件路径
"""
import csv
# 收集所有指标字段
all_fields = set()
for metrics in metrics_list:
if metrics:
all_fields.update(metrics.keys())
all_fields = sorted(list(all_fields))
with open(output_file, 'w', encoding='utf-8-sig', newline='') as f:
writer = csv.writer(f)
# 写入表头
header = ['市场', '代码'] + all_fields
writer.writerow(header)
# 写入数据
for i, code in enumerate(codes):
clean_code = code.replace('sh', '').replace('sz', '')
if code.lower().startswith('sh') or code.startswith('6'):
market = '上海'
else:
market = '深圳'
row = [market, clean_code]
metrics = metrics_list[i] if i < len(metrics_list) else {}
for field in all_fields:
value = metrics.get(field, '') if metrics else ''
# 格式化数值
if isinstance(value, float):
value = f"{value:.2f}"
row.append(value)
writer.writerow(row)
logger.info(f"导出详细CSV文件成功: {output_file}, 共 {len(codes)} 只股票")
return output_file
def export_selection_results(results: List, export_format: str = "csv") -> dict:
"""
导出选股结果
Args:
results: SelectionResult列表
export_format: 导出格式(text/csv/detailed)
Returns:
导出信息字典
"""
exporter = TDXExporter()
codes = [r.code for r in results]
names = [r.name or '' for r in results]
metrics_list = [r.metrics for r in results]
exported_files = []
if export_format == "text":
file = exporter.export_to_text(codes)
exported_files.append(file)
elif export_format == "csv":
file = exporter.export_to_csv(codes, names)
exported_files.append(file)
elif export_format == "detailed":
file = exporter.export_with_metrics(codes, metrics_list)
exported_files.append(file)
else: # all
exported_files.append(exporter.export_to_text(codes))
exported_files.append(exporter.export_to_csv(codes, names))
if any(metrics_list):
exported_files.append(exporter.export_with_metrics(codes, metrics_list))
# 生成导入说明
instructions = exporter.generate_import_instructions(exported_files[0])
# 保存说明文件
instructions_file = "导入说明.txt"
with open(instructions_file, 'w', encoding='utf-8') as f:
f.write(instructions)
exported_files.append(instructions_file)
return {
'files': exported_files,
'count': len(codes),
'instructions': instructions
}