乐于分享
好东西不私藏

Excel转通达信自定义数据工具2.0(pandas+tkinter)

Excel转通达信自定义数据工具2.0(pandas+tkinter)

数据是个宝,研究少烦恼

挖的深,看的远,找规律

做笔记,练盘感,多总结

★★★★博文原创不易,源码使用过程中,如有疑问的地方,欢迎大家指正留言交流。喜欢的老铁可以点赞+收藏分享+置顶,小红牛在此表示感谢。★★

Python股票热点方向+龙头标的复盘系统6.66

股票热点数据分类统计系统3.0(padans+matplotlib+sqlite3)

股票精简节点记事本2.0优化版(tkinter+json)

量化教程: 教你快速上车,通达信量化平台(TdxQuant太强了,真香啊)

对复盘系统sqlites数据库中的,数据按时间截取数据

Python处理复盘系统中,sqlite3数据库中的json热点和行业字段

模拟炒股K线训练系统2.0(threading+mplfinance)

股票自选股公告系统1.0

(简易版)Ex写通达信自定义序列+外部数据1.0

使用Excel制作通达信自定义外部数据,安排!!!

关于小红牛软件,不再对外出售的正式说明!!

小红牛软件用户使用说明书(2)

龙虎榜小红牛软件帮助说明书

关于小红牛,通达信自定义数据指标的说明文档

通达信自定义数据系统,自定义游资席位的增加方法

通达信历史自定义数据替换教程@signals

教你在通达信中设置,和查看15个财经网站的股票数据

通达信指标公式28:龙虎榜股票池——主力控盘度的计算方法

通达信自定义数据的制作+导入+显示+选股

Tdx#自定义数据常用的指标编写与注释

通达信实现股票联动,消息号优化探测的方法1.2

200条复盘核心及细分点(仅供参考)

200条关于热点和龙头股的理解(仅供参考)

龙头股Vs跟风股(杂毛)200条(仅供参考)

通达信指标公式34:避雷参考,选股前,必须优先排除有垃圾属性的股。

通达信指标公式33:严重异动提醒,计算10/30日的涨跌幅偏离值

Excel转通达信自定义数据工具2.0 使用说明书

一、软件功能:将Excel表格中的数据转换为通达信软件可识别的自定义数据格式(外部数据/序列数据),支持自动处理股票代码前缀及市场类型。

需要安装的模块,时间久了忘了pandas里面是否包含openpyxl,如果不包含自己安装一下。

pip install pandaspip install openpyxl

二、操作步骤

加载Excel文件
点击【读取Excel数据】,选择包含股票代码和数据列的.xlsx或.xls文件。
要求:Excel数据的第一列必须为股票代码列(格式不限,如sh600519、600519.sh或纯数字代码,会自动处理前缀后缀)。
选择数据列:在左侧列表中单击选中要导出的数据列(数值或文本列)。
设置输出模式:不同的数据类型,格式不一样
外部数据生成格式 代码|数值|0.000。
序列数据生成格式 代码|日期|数值(用于序列数据,日期需手动填写)。设置序列数据的日期,在“设置序列数据日期”输入框中,可以填写(YYYYMMDD)你的数据时间,默认为当前时间。
预览并保存:点击【预览并保存】,右侧预览区显示转换结果,同时自动生成.txt文件,保存位置与Excel文件相同。文件命名规则:{列名}{模式}{日期}_{原文件名}.txt

完整源码如下

# -*- coding: utf-8 -*-# @Author : 小红牛# 微信公众号:gxzfp888import tkinter as tkfrom tkinter import filedialog, messagebox, scrolledtextfrom datetime import datetime, timedeltaimport pandas as pdimport osclass StockDataProcessor:    def __init__(self, root):        self.root = root        self.root.title("Excel转通达信自定义数据工具2.0——小红牛微信公众号:gxzfp888")        self.root.geometry("1000x700")        self.root.resizable(TrueTrue)        # 数据变量        self.df_data = None        self.current_headers = []        self.excel_path = ""        # 模式变量        self.data_type = tk.StringVar(value="external")        # 构建界面        self.create_widgets()    # ---------- 工具函数 ----------    @staticmethod    def extract_code(s):        """从 'sh600519' 或 '600519.sh' 中提取6位数字代码"""        if s[0].isalpha():          # 前缀格式,如 sh600519            return s[-6:]           # 取右边6个字符        elif s[-1].isalpha():       # 后缀格式,如 600519.sh            return s[:6]            # 取左边6个字符        else:            return s                # 已经是纯数字    @staticmethod    def get_stock_type(code):        if code.startswith(('60''68')):            return '1'        elif code.startswith(('30''00')):            return '0'        elif code.startswith('92'):            return '2'        else:            return '3'    # 处理股票代码前后缀+类型    def fm_stock_code(self, raw_code):        code = self.extract_code(raw_code)                return f"{self.get_stock_type(code)}|{code}"    @staticmethod    def get_workday_today():        today = datetime.today().date()        if today.weekday() == 5:      # 周六            return today - timedelta(days=1)        elif today.weekday() == 6:    # 周日            return today - timedelta(days=2)        else:            return today    @staticmethod    def format_date(date_obj):        return date_obj.strftime("%Y%m%d")    # ---------- 业务逻辑 ----------    def load_excel(self):        file_path = filedialog.askopenfilename(            title="选择Excel文件",            filetypes=[("Excel files""*.xlsx *.xls"), ("All files""*.*")]        )        if not file_path:            return        try:            self.df_data = pd.read_excel(file_path)            self.current_headers = self.df_data.columns.tolist()            # 更新 Listbox            self.listbox.delete(0, tk.END)            for h in self.current_headers:                self.listbox.insert(tk.END, h)            # 更新路径显示            self.excel_path = file_path            self.entry_path.delete(0, tk.END)            self.entry_path.insert(0, file_path)            messagebox.showinfo("成功"f"已加载 {len(self.df_data)} 行,{len(self.current_headers)} 列")        except Exception as e:            messagebox.showerror("错误"f"读取Excel失败:{e}")            self.df_data = None    def preview_and_save(self):        """处理数据并直接保存(含预览)"""        if self.df_data is None:            messagebox.showerror("错误""请先加载 Excel 文件")            return        selected = self.listbox.curselection()        if not selected:            messagebox.showerror("错误""请先在列表中选中一个数据列")            return        col_index = selected[0]        col_name = self.current_headers[col_index]        # 第一列为股票代码列        first_col = self.df_data.columns[0]        stock_codes_raw = self.df_data[first_col]        data_col = self.df_data[col_name]        # 获取日期(用于文件名)        date_val = self.entry_date.get().strip()        if not date_val:            date_val = self.format_date(self.get_workday_today())        if not (len(date_val) == 8 and date_val.isdigit()):            messagebox.showerror("错误""时间标签应为8位数字(YYYYMMDD),请修正日期输入框")            return        mode = self.data_type.get()        lines = []        if mode == "external":            for raw_code, val in zip(stock_codes_raw, data_col):                if pd.isna(raw_code) or pd.isna(val):                    continue                code = self.fm_stock_code(raw_code)                lines.append(f"{code}|{val}\n|0.000")            if not lines:                messagebox.showwarning("警告""没有有效数据行,未保存")                return            # 预览            self.text_display.delete(1.0, tk.END)            self.text_display.insert(tk.END, "\n".join(lines))            # 保存文件:使用选项值+外部+日期+基础名            base_name = os.path.splitext(os.path.basename(self.excel_path))[0]            filename = f"{col_name}外部{date_val}_{base_name}.txt"            with open(filename, "w", encoding="utf-8"as f:                f.write("\n".join(lines))            messagebox.showinfo("保存成功"f"外部数据已保存至:{filename}")        elif mode == "sequence":            # 序列数据使用日期输入框的值作为数据标签            seq_date = date_val   # 与文件名中的日期保持一致            for raw_code, val in zip(stock_codes_raw, data_col):                if pd.isna(raw_code) or pd.isna(val):                    continue                code = self.fm_stock_code(raw_code)                lines.append(f"{code}|{seq_date}|{val}")            if not lines:                messagebox.showwarning("警告""没有有效数据行,未保存")                return            # 预览            self.text_display.delete(1.0, tk.END)            self.text_display.insert(tk.END, "\n".join(lines))            base_name = os.path.splitext(os.path.basename(self.excel_path))[0]            filename = f"{col_name}序列{date_val}_{base_name}.txt"            with open(filename, "w", encoding="utf-8"as f:                f.write("\n".join(lines))            messagebox.showinfo("保存成功"f"序列数据已保存至:{filename}")        else:            messagebox.showerror("错误""未知模式")    # ---------- 界面布局(优化版)----------    def create_widgets(self):        # 顶部:文件路径区域        top_frame = tk.Frame(self.root)        top_frame.pack(fill=tk.X, padx=10, pady=5)        tk.Label(top_frame, text="Excel文件:").pack(side=tk.LEFT, padx=5)        self.entry_path = tk.Entry(top_frame, relief=tk.SUNKEN, bg="white")        self.entry_path.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5)        btn_load = tk.Button(top_frame, text="读取Excel数据", command=self.load_excel, width=12)        btn_load.pack(side=tk.LEFT, padx=5)        # 中间:左右分区(左侧列名列表,右侧模式与保存)        middle_frame = tk.Frame(self.root)        middle_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)        # 左侧:数据列标题列表框        left_frame = tk.LabelFrame(middle_frame, text="选择数据列标题(单击选中一列)", padx=5, pady=5)        left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)        listbox_frame = tk.Frame(left_frame)        listbox_frame.pack(fill=tk.BOTH, expand=True)        self.listbox = tk.Listbox(listbox_frame, height=15)        scrollbar = tk.Scrollbar(listbox_frame, orient=tk.VERTICAL, command=self.listbox.yview)        self.listbox.configure(yscrollcommand=scrollbar.set)        self.listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)        # 右侧:输出模式 + 日期输入 + 保存按钮        right_frame = tk.LabelFrame(middle_frame, text="参数设置", padx=10, pady=10)        right_frame.pack(side=tk.RIGHT, fill=tk.Y, padx=5)        # 模式选择        tk.Label(right_frame, text="输出模式:", anchor="w").pack(anchor=tk.W, pady=(0,5))        rb_external = tk.Radiobutton(right_frame, text="外部数据(代码|数值或文本|0.000)",                                     variable=self.data_type, value="external")        rb_external.pack(anchor=tk.W, pady=2)        rb_sequence = tk.Radiobutton(right_frame, text="序列数据(代码|日期|数值)",                                     variable=self.data_type, value="sequence")        rb_sequence.pack(anchor=tk.W, pady=2)        # 日期输入(始终显示)        date_frame = tk.Frame(right_frame)        date_frame.pack(fill=tk.X, pady=10)        tk.Label(date_frame, text="设置序列数据日期 (YYYYMMDD):").pack(side=tk.LEFT)        default_date = self.format_date(self.get_workday_today())        self.entry_date = tk.Entry(date_frame, width=12)        self.entry_date.insert(0, default_date)        self.entry_date.pack(side=tk.RIGHT)        # 保存按钮(放在右侧底部)        btn_save = tk.Button(right_frame, text="预览并保存", command=self.preview_and_save,                             bg="lightblue", font=("微软雅黑"10), width=15)        btn_save.pack(pady=15)        # 底部:结果预览区域        preview_frame = tk.LabelFrame(self.root, text="预览结果", padx=5, pady=5)        preview_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)        self.text_display = scrolledtext.ScrolledText(preview_frame, height=12, wrap=tk.WORD)        self.text_display.pack(fill=tk.BOTH, expand=True)if __name__ == "__main__":    root = tk.Tk()    app = StockDataProcessor(root)    root.mainloop()

温馨提示:股市有风险,投资需谨慎。本文所写内容仅供粉丝们参考使用,仅为个人研究观点表述,股友们须自己思考与分析股市。

-!! 完毕 ,感谢您的收看!!-

-------★历史博文集合★------

股软件龙虎榜小红牛分析系统资金大单系统

通达信主附图指标改选股器通达信自定义数据系统

自定义数据其他股软Ex系统 每日收盘数据

通达信小技巧  tdx指标编写教程Tdx指标公式

龙虎榜教程游资盈亏数据产业链上下游  股学堂

量化教程指标回测Python  我的股票笔记