当前位置:首页>python>Python 打造自己的基金交易系统(4):实现模拟交易及持仓综合收益计算

Python 打造自己的基金交易系统(4):实现模拟交易及持仓综合收益计算

  • 2026-10-14 03:45:12
Python 打造自己的基金交易系统(4):实现模拟交易及持仓综合收益计算

本期效果抢先看

买卖操作:直接双击曲线的点就可弹出买入卖出操作,自定任意买卖点。
买入后自动加入持仓列表并计算收益:
右键选中持仓基金可删除持仓,也可直接清空持仓。
多条持仓可累计计算收益,如果你在多个平台持有基金,直接就可以帮你显示出总持仓收益,对于买基金的人来说超级方便!!!!
同时,只要你历史爬取数据足够,能让你回测任意时段的收益,模拟定投,这在基金软件中都是VIP的功能。

本期主要更新内容

主要代码如下:
界面调整:
        # ========== 界面布局(新增持仓区域) ==========        main_frame = ttk.Frame(self.root)        main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)        # 左侧区域:自选+持仓        left_total_frame = ttk.Frame(main_frame)        left_total_frame.pack(side=tk.LEFT, fill=tk.Y, padx=(0, 10))        # 自选基金区域        fav_frame = ttk.LabelFrame(left_total_frame, text="自选基金(数据库存储)")        fav_frame.pack(fill=tk.X, padx=0, pady=(0, 10))        self.fav_listbox = tk.Listbox(fav_frame, font=("微软雅黑", 8), width=80, height=10)        self.fav_listbox.pack(padx=5, pady=5)        self.fav_listbox.bind("<Double-Button-1>", self.fav_double_click)        # 自选操作按钮        fav_btn_frame = ttk.Frame(fav_frame)        fav_btn_frame.pack(padx=5, pady=5, fill=tk.X)        ttk.Button(fav_btn_frame, text="添加到自选", command=self.add_to_fav).pack(side=tk.LEFT, padx=2)        ttk.Button(fav_btn_frame, text="移除自选", command=self.remove_fav).pack(side=tk.LEFT, padx=2)        self.refresh_fav_list()        # 新增:持仓基金区域        position_frame = ttk.LabelFrame(left_total_frame, text="持仓基金(盈亏计算)")        position_frame.pack(fill=tk.BOTH, expand=True)        # 持仓列表        self.position_listbox = tk.Listbox(position_frame, font=("微软雅黑", 8), width=80, height=8)        self.position_listbox.pack(padx=5, pady=5, fill=tk.BOTH, expand=True)        # ========== 新增:绑定右键菜单 ==========        # 创建右键菜单        self.position_menu = tk.Menu(self.root, tearoff=0)        self.position_menu.add_command(label="删除该持仓", command=self.delete_selected_position)        # 绑定右键点击事件        def show_position_menu(event):            # 获取点击位置的列表项            try:                # 定位选中的列表项                self.position_listbox.selection_clear(0, tk.END)                self.position_listbox.selection_set(self.position_listbox.nearest(event.y))                # 显示右键菜单                self.position_menu.post(event.x_root, event.y_root)            except:                pass        self.position_listbox.bind("<Button-3>", show_position_menu)  # 绑定右键点击        # 持仓操作按钮        position_btn_frame = ttk.Frame(position_frame)        position_btn_frame.pack(padx=5, pady=5, fill=tk.X)        ttk.Button(position_btn_frame, text="刷新持仓", command=self.refresh_position_list).pack(side=tk.LEFT, padx=2)        ttk.Button(position_btn_frame, text="清空持仓", command=self.clear_all_position).pack(side=tk.LEFT, padx=2)        # 持仓汇总信息        self.position_summary_label = ttk.Label(position_frame, text="总盈亏:0.00元 | 总盈亏率:0.00%",                                                font=("微软雅黑", 10, "bold"), foreground="#e63946")        self.position_summary_label.pack(padx=5, pady=5)
交易部分:
    # ========== 完善交易操作逻辑(写入数据库+关闭弹窗) ==========    def trade_fund(self, fund_code, fund_name, trade_date, unit_nav, trade_type, op_dialog=None):        """执行基金买入/卖出操作"""        try:            # 获取交易金额            if trade_type == 'buy':                amount = float(self.buy_amount_var.get())            else:                amount = float(self.sell_amount_var.get())            if amount <= 0:                messagebox.showwarning("提示", "交易金额必须大于0!")                return            # 卖出前检查持仓            if trade_type == 'sell':                # 计算剩余持仓份额                position_sql = '''                SELECT                     SUM(CASE WHEN trade_type='buy' THEN trade_share ELSE 0 END) as buy_shares,                    SUM(CASE WHEN trade_type='sell' THEN trade_share ELSE 0 END) as sell_shares                FROM fund_holdings                 WHERE fund_code=?                '''                position_data = self.db_query(position_sql, (fund_code,))                if not position_data:                    messagebox.showwarning("提示", "该基金暂无持仓,无法卖出!")                    return                buy_shares = position_data[0]['buy_shares'] or 0                sell_shares = position_data[0]['sell_shares'] or 0                remaining_shares = buy_shares - sell_shares                # 计算可卖出最大金额                max_sell_amount = remaining_shares * unit_nav                if amount > max_sell_amount:                    messagebox.showwarning("提示", f"可卖出最大金额为{max_sell_amount:.2f}元,当前输入金额超出限制!")                    return            # 计算交易份额            trade_share = amount / unit_nav            # 插入交易记录到fund_holdings表            self.db_execute('''            INSERT INTO fund_holdings             (fund_code, trade_type, trade_amount, trade_share, trade_date, trade_nav)            VALUES (?, ?, ?, ?, ?, ?)            ''', (fund_code, trade_type, amount, trade_share, trade_date, unit_nav))            # 关闭弹窗(新增:处理op_dialog参数)            if op_dialog:                op_dialog.destroy()            # 刷新持仓列表            self.refresh_position_list()            trade_text = "买入" if trade_type == 'buy' else "卖出"            messagebox.showinfo("成功",                 f"{trade_text}成功!\n基金:{fund_name}({fund_code})\n日期:{trade_date}\n金额:{amount:.2f}元\n净值:{unit_nav:.4f}\n份额:{trade_share:.4f}"            )        except ValueError:            messagebox.showerror("错误", "请输入有效的数字金额!")        except Exception as e:            messagebox.showerror("错误", f"交易失败:{str(e)}")

运行示例程序领取

后台回复关键词【基金系统04】,领取本期「可运行的exe程序」,直接下载就能用!
关注我,下期更新添加买点/买点/成本线。
#Python实战 #基金工具 #爬虫 #可视化 #新手教程

最新文章

随机文章