社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

量化教程:python计算10万变100万,不同参数组合,需要的交易笔数(本金、胜率、盈亏比..)

一场孤独的自我修行 • 6 天前 • 74 次点击  


数据是个宝,研究少烦恼

挖的深,看的远,找规律

做笔记,练盘感,多总结

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

股票量化教程:自学计划书框架

量化教程:常见术语解释,小白快速入门

量化教程:8个认知误区解析,回测胜率高 = 实盘盈利??

量化教程:主流回测框架的深度对比

量化教程:Python在量化交易中的应用

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

量化教程:通达信量化接口函数TdxQuant+Tkinter综合示例演示(带你速成速学)

聊聊通达信开放TdxQuant,对普通投资者有哪些好处?

量化教程:对(重点指数+板块+概念+细分行业+标的)月线数据回测2.0

量化教程:对大盘指数月线回测 1.0(TdxQuant+pandas+Tkinter)

Python指数月线回测系统,回测逻辑3种新写法

量化教程:在通达信里面运行Tq策略后,窗口出现闪退的3种解决办法。

股票精简节点记事本 3.0(tkinter+json+reportlab)

固定盈亏模型计算工具 – 使用说明书

1. 功能简介:本工具用于计算在不同初始本金、胜率、盈亏比和固定盈利金额下,达到 100 万元目标 所需的交易笔数期望值,并展示盈利/亏损笔数的期望分布。所有结果以表格形式呈现,支持点击列头排序,程序启动时自动生成文本报告。

2. 运行方式:直接运行 Python 脚本。启动后弹出图形窗口,同时自动保存计算结果至 fixed_amount_results_with_winloss.txt,并弹出保存成功提示。

3. 界面说明

表格区域:显示所有参数组合的计算结果,共 8 列:
本金、胜率、盈亏比、盈利金额、亏损金额、所需总笔数、期望盈利笔数、期望亏损笔数。
滚动条:支持垂直和水平滚动,方便查看全部数据。
列头点击:单击任意列标题,表格按该列升序排列;再次单击切换为降序。无效策略(永远无法达到100万的策略,用∞ 和 -表示)始终排在末尾。
4. 数据含义
盈利金额:每次盈利的固定值(用户设定的参数)。
亏损金额 = 盈利金额 / 盈亏比。
期望净收益 = 胜率 × 盈利 − 败率 × 亏损。若 ≤ 0,则策略无效,所需总笔数显示为 ∞。
所需总笔数 = ⌈(目标 − 本金) / 期望净收益⌉(有效策略时)。
期望盈利笔数 = 总笔数 × 胜率,期望亏损笔数 = 总笔数 × (1 − 胜率),均四舍五入保留两位小数。

5. 保存文件

文件名:fixed_amount_results_with_winloss.txt
内容与表格数据一致,按“所需总笔数”升序排列(∞ 置末),并附带计算说明。文件生成于程序所在目录,每次启动会覆盖旧文件。
6. 注意事项
所有参数均为预设值(本金、胜率、盈利金额、盈亏比),如需修改,请编辑源代码中的列表。
表格排序仅影响界面显示,不影响生成的 TXT 文件顺序(始终按默认规则排序)。关闭窗口即退出程序,无需额外操作。

完整源码如下

# -*- coding: utf-8 -*-# @Author : 小红牛# 微信公众号:gxzfp888import mathimport itertoolsimport tkinter as tkfrom tkinter import ttkfrom tkinter import ttk, messagebox
class FixedAmountApp:    """固定盈亏模型 - 结果展示、排序及 TXT 导出"""
    def __init__(self, root):        self.root = root        self.root.title("小红牛微信公众号:gxzfp888——对以下参数组合模型,达到100万所需的笔数,点击表头可排序")        self.root.geometry("1100x600")
        # 列配置        self.columns = [            ('principal''本金'100'center'),            ('win_rate''胜率'80'center'),            ('rr_ratio''盈亏比'80'center'),            ('profit''盈利金额'100'center'),            ('loss''亏损金额'100'center'),            ('total_rounds''所需总笔数'120'center'),            ('win_expected''期望盈利笔数'130'center'),            ('loss_expected''期望亏损笔数'130'center'),        ]        self.col_names = [c[0for c in self.columns]
        # 计算原始数据(使用 itertools.product)        self.raw_data = self.calculate_data()
        # 默认按“总笔数升序,∞ 排最后”排序(用于显示和保存)        self.data = self.get_default_sorted_data()
        # 创建 Treeview        self.tree = ttk.Treeview(root, columns=self.col_names, show='headings')        vsb = ttk.Scrollbar(root, orient='vertical', command=self.tree.yview)        hsb = ttk.Scrollbar(root, orient='horizontal', command=self.tree.xview)        self.tree.configure(yscrollcommand=vsb.set, xscrollcommand=hsb.set)
        self.tree.grid(row=0, column=0, sticky='nsew')        vsb.grid(row=0, column=1, sticky='ns')        hsb.grid(row=1, column=0, sticky='ew')        root.grid_rowconfigure(0, weight=1)        root.grid_columnconfigure(0, weight=1)
        # 设置列标题和宽度        for  col_id, header, width, anchor in self.columns:            self.tree.heading(col_id, text=header, command=lambda c=col_id: self.on_column_click(c))            self.tree.column(col_id, width=width, anchor=anchor)
        self.sort_col = None        self.sort_reverse = False
        # 插入数据        self.insert_data()
        # 保存 TXT 文件(调用 save_to_txt 即可)        self.save_to_txt()   # 如需自动保存,取消注释;或手动调用
    def calculate_data(self):        """使用 itertools.product 计算所有组合,返回原始数据列表"""        TARGET = 1_000_000        principals = [100000200000300000500000]        win_rates = [0.40.50.60.7]        profit_amounts = [10002000300040005000700010000]        rr_ratios = [1234]
        raw = []        # 四层循环 → itertools.product        for principal, p, profit, rr in itertools.product(principals, win_rates, profit_amounts, rr_ratios):            loss = profit / rr            expected = p * profit - (1 - p) * loss            if expected <= 0:                total = float('inf')      # 无效策略                win_exp = None                loss_exp = None            else:                need = TARGET - principal                total = math.ceil(need / expected)                if total 0:                    total = 0                win_exp = round(total * p, 2)                loss_exp = round(total * (1 - p), 2)
            raw.append((principal, p, rr, profit, loss, total, win_exp, loss_exp))        return raw
    def get_default_sorted_data(self):        """按原始排序规则:总笔数升序,∞(inf)排最后"""        finite = [r for r in self.raw_data if r[5] != float('inf')]        infinite = [r for r in self.raw_data if r[5] == float('inf')]        finite.sort(key=lambda x: x[5])   # 升序        return finite + infinite
    def format_row(self, row):        """将原始数据行转换为显示字符串列表"""        principal, p, rr, profit, loss, total, win_exp, loss_exp = row        return (            str(principal),            f"{p*100:.0f}%",            f"{rr}:1",            str(profit),            f"{loss:.2f}",            "∞" if total == float('inf'else str(total),            "-" if win_exp is None  else f"{win_exp:.2f}",            "-" if loss_exp is None else f"{loss_exp:.2f}",        )
    def insert_data(self):        """清空并重新填充 Treeview"""        for item in self.tree.get_children():            self.tree.delete(item)        for row in self.data:            self.tree.insert('''end', values=self.format_row(row))
    def sort_by_column(self, col_name, reverse):        """按列排序 self.data(处理特殊值 inf / None)"""        col_idx = self.col_names.index(col_name)
        if col_name == 'total_rounds':            finite = [r for r in self.data if r[col_idx] != float('inf')]            infinite = [r for r in self.data if r[col_idx] == float('inf')]            finite.sort(key=lambda x: x[col_idx], reverse=reverse)            self.data = finite + infinite
        elif col_name in ('win_expected''loss_expected'):            valid = [r for r in self.data if r[col_idx] is not None]            invalid = [r for r in self.data if r[col_idx] is None]            valid.sort(key=lambda x: x[col_idx], reverse=reverse)            self.data = valid + invalid
        else:            self.data.sort(key=lambda x: x[col_idx], reverse=reverse)
        self.insert_data()
    def on_column_click(self, col_name):        """处理列头点击,切换排序方向"""        if self.sort_col == col_name:            self.sort_reverse = not self.sort_reverse        else:            self.sort_col = col_name            self.sort_reverse = False        self.sort_by_column(self.sort_col, self.sort_reverse)
    def save_to_txt(self, filename="fixed_amount_results_with_winloss.txt"):        """保存默认排序结果到 TXT 文件(与原始输出格式一致)"""        data = self.get_default_sorted_data()   # 始终按原始规则排序        with open(filename, "w", encoding="utf-8"as f:            f.write("说明:\n")            f.write("1. 盈利金额固定,亏损金额 = 盈利金额 / 盈亏比\n")            f.write("2. 期望净收益 = 胜率×盈利 - 败率×亏损,若≤0则无法达到\n")            f.write("3. 所需总笔数 = ceil((目标 - 本金) / 期望净收益)\n")            f.write("4. 期望盈利笔数 = 总笔数 × 胜率,期望亏损笔数 = 总笔数 × (1-胜率),均为期望值(保留两位小数)\n")            f.write("-" * 90 + "\n")            f.write("固定盈亏金额模型 - 达到100万所需的盈利/亏损笔数期望值(每次投入初始本金)\n")            f.write("-" * 90 + "\n\n")            f.write(f" {'本金':>3} {'胜率':>6} {'盈亏比':>6} {'盈利金额':>6} {'亏损金额':>6} {'所需总笔数':>6} {'期望盈利笔数':>6} {'期望亏损笔数':>6}\n")            f.write("-" * 90 + "\n")            for row in data:                principal, p, rr, profit, loss, total, win_exp, loss_exp = row                win_rate_str = f"{p*100:.0f}%"                rr_str = f"{rr}:1"                loss_str = f"{loss:.2f}"                total_str = "∞" if total == float('inf'else str(total)                win_exp_str = "-" if win_exp is None else f"{win_exp:.2f}"                loss_exp_str = "-" if loss_exp is None else f"{loss_exp:.2f}"                f.write(f"{principal:>8} {win_rate_str:>6} {rr_str:>8} {profit:>10} {loss_str:>10}  {total_str:>12} {win_exp_str:>14} {loss_exp_str:>14}\n")
        # 使用弹窗提示,替代原来的 print        messagebox.showinfo("提示"f"结果已保存至 {filename}")

if __name__ == "__main__":    root = tk.Tk()    app = FixedAmountApp(root)    root.mainloop()

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


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


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

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

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

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

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

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

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

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/198476