资讯动态

PyCharm联手CodeArts打造模拟炒股小助手:AI结对编程实践

发布时间:2026/10/17 0:36:41 来源:尧图企业网站定制
最近用 PyCharm 配合 CodeArts 代码智能体从零搭了一个模拟炒股小助手。开头先坦白我没接任何真实行情接口数据是模拟生成的买卖逻辑也是简化版目标是练一练“人和 AI 结对编程”的完整流程顺便把量化交易里的建仓、持仓、结算、收益计算这些概念落到代码上。做完之后最大的感受是这类工具已经不是“帮你补全函数”的级别了而是能参与需求拆解、数据结构设计、代码审查的协作搭档。这篇就记录一下整个项目的拆解思路、关键实现和踩坑实录想试 AI 辅助开发的接着往下看。这个项目适合三类人刚学 Python 想找个完整练手项目的对量化交易感兴趣但不想碰真实资金和合规问题的以及想评估代码智能体在多文件项目中到底能帮多少忙的。我用的组合是 PyCharm 社区版 CodeArts 插件成本为零功能足够。1. 项目选型与整体设计1.1 为什么选 PyCharm CodeArts 这套组合先说 IDE。PyCharm 是目前 Python 开发里公认最顺手的工具调试器、代码补全、重构、Git 集成开箱即用。社区版免费对个人项目来说完全够用。我用它的原因很朴素项目里既有数据计算又有界面逻辑断点调试比打 print 效率高太多尤其是排查交易逻辑算错持仓这种问题单靠眼睛看代码会疯。再说代码智能体。CodeArts 是华为云出的智能开发助手以插件形式嵌进 PyCharm支持自然语言生成代码、代码解释、单元测试生成、代码审查这些能力。我选它的一个现实原因是中文理解能力强描述需求时不用在脑子里先翻译成英文变量名的水平直接说“帮我写一个根据收盘价计算 5 日均线的函数”它给出的实现基本能直接跑。另一个原因是它支持上下文感知能读懂当前文件甚至项目里相关文件的代码结构不是那种“你贴一段代码我改一段”的机械补全。这套组合的实际分工是这样的PyCharm 提供工程管理、调试、运行环境CodeArts 负责需求到代码的转换、重复代码的生成、算法的初步实现我做决策——哪些代码要采用、逻辑边界在哪里、架构怎么组织。说白了AI 是双手我是指挥。1.2 模拟炒股小助手的功能清单开始写代码之前先把需求列清楚。一个模拟炒股助手最核心的功能就四块行情模拟生成股票的开盘价、收盘价、最高价、最低价、成交量的日线数据账户管理模拟初始资金、持仓股票、可用余额、冻结资金交易执行买入、卖出支持市价单和限价单计算手续费和滑点收益统计实时计算持仓市值、总资产、收益率画资产曲线我特意没有加入任何市场预测、技术指标买卖信号这类“玄学”功能因为项目的定位是模拟交易环境而不是预测股价。这个定位非常重要——它决定了整个系统的边界。很多人在做类似项目时总想往里面加“智能选股”最后搞得数据接口、策略逻辑、回测框架缠在一起项目从一个练习变成无底洞。模拟炒股就是模拟炒股把交易流程跑通、把账算对就已经是合格的项目了。另外加了一个数据持久化的需求退出程序后账户状态要存到本地文件下次启动自动恢复。这个功能让项目从“能跑”变成了“能用”也多了一个练手点序列化、文件读写、异常恢复。2. 核心功能拆解与实现方案2.1 行情数据的获取与处理行情数据是整个系统的基础也是最容易踩坑的地方。真实项目里一般从数据源拉历史行情但做模拟器时有一个巨大的便利数据是自己生成的想怎么造就怎么造。我用的是几何布朗运动模型来模拟股价走势这名字听着唬人原理其实不复杂股价的涨跌幅服从正态分布且有一定漂移趋势。核心公式是# 收盘价 前一日收盘价 * exp(日收益率) # 日收益率 漂移项 波动项 * 标准正态随机数对应到代码就是将标准库 random.gauss 稍加封装。生成 K 线序列时我先用上述模型生成收盘价序列然后根据收盘价反推开盘价开盘价在前一日收盘价附近波动最高价为当日开盘、收盘中的较高值加上一个小幅随机量最低价同理取低值。这段逻辑如果自己从零手写大概需要半小时还要考虑各种边界条件。让我用 CodeArts 的时候我给的指令是用 Python 生成一个股票模拟行情模块 1. 基于几何布朗运动生成收盘价序列 2. 由收盘价反推开盘价、最高价、最低价 3. 返回 pandas DataFrame包含 date, open, close, high, low, volume 4. 支持设置随机种子保证结果可复现它会直接生成一个完整的类模块构造函数里接收初始价格、日均收益率、年化波动率、交易天数这些参数。这里要特别强调可复现性——模拟实验最怕每次跑结果都不一样无法对比交易策略的好坏所以必须在初始化函数里加 random.seed。2.2 交易逻辑与持仓管理交易逻辑是模拟炒股小助手的中枢这里面的坑最多。核心要处理的问题有三个买入时的资金校验、卖出时的持仓校验、以及成交价格与手续费的确定。先说买入流程一个完整的买入操作应该是这样的计算买入数量对应需要的资金含手续费校验可用余额是否充足冻结资金成交后更新持仓增加股票数量降低可用余额记录交易流水卖出的流程是对称的校验持仓数量是否足够成交后增加资金余额减少持仓数量计算盈亏并记录。这里有一个很容易被忽略的细节买入和卖出不是瞬间完成的中间有一个“委托”状态。真实交易里委托挂出去未必立刻成交所以账户里有“可用资金”和“冻结资金”两个概念。简化版模拟器可以不做委托状态机但是资金冻结这个动作最好保留否则后面想扩展成“挂单等待成交”的模式时要重构一大片代码。手续费的计算规则我参考了常见券商的费率框架佣金万分之三双向收取最低 5 元、印花税千分之一仅卖出收取、过户费十万分之一仅沪市股票收取。这部分逻辑不复杂但细节多。我在让 AI 生成时是这样描述的实现一个交易费用计算函数 - 输入股票代码、方向buy/sell、价格、数量 - 佣金成交金额的0.03%不足5元按5元收取买卖双向 - 印花税成交金额的0.1%仅卖出收取 - 过户费成交金额的0.001%仅买入收取模拟沪市规则 - 买入总成本 成交金额 佣金 过户费 - 卖出净收入 成交金额 - 佣金 - 印花税 - 过户费费用计算的边界条件最容易被 AI 写错比如买入时不足 5 元佣金按 5 元收这个逻辑如果把它加到卖出的净收入计算里方向反了账就会算错。这类问题靠人工审查非常难发现因为代码读起来逻辑通顺但算出来的数字就是不对。我的经验是写完之后一定要用几个手工算过的案例去验证。2.3 结果评估与收益曲线模拟交易的最后一步是评估。这个模块纯计算没什么坑但视觉化呈现的效果决定项目的完成度。我用 matplotlib 画两条曲线一条是账户总资产的每日变化另一条是持仓股票的价格走势。两条线放在同一张图里用双 Y 轴展示能直观地看到资产和股价的联动关系。这里有一个值得说的点数据结构的组织方式决定了后面画图、统计的复杂度。我在设计时让账户模块维护一份每日资产快照列表每完成一笔交易或每个交易日结束时就把总资产、持仓市值、可用资金记录一个元组加到列表里。这样画图时直接用这个列表渲染不需要回头去交易流水里重新算。class DailySnapshot: def __init__(self, date, total_asset, market_value, cash): self.date date self.total_asset total_asset self.market_value market_value self.cash cash这类代码让 AI 写的时候关键是把需求描述清楚——要什么字段、用什么单位、小数精度怎么处理。我特别加了“金额保留两位小数”的要求避免浮点数精度问题在统计时冒出来。3. 人机协作的实操过程3.1 让 AI 先生成主干框架整个开发过程最省时间的环节是让 CodeArts 生成项目的主干框架。我给出的指令是描述整个系统的模块划分和每个模块的职责让 AI 先搭一个项目树出来。这一步相当于让 AI 做架构师虽然它给出的模块划分不一定完美但能提供合理的起点。我的做法是把这个指令直接发给 CodeArts模拟炒股小助手项目模块划分如下 - data_market.py行情模拟生成日 K 线数据 - account.py账户类管理资金与持仓 - trade.py交易执行包含手续费计算 - stats.py统计与图表绘制 - main.py主程序入口命令行交互 请为每个模块生成对应的 Python 文件框架包含类定义、主要方法签名和 docstring方法内部先用 pass 占位。这个模式有个好处AI 生成的框架文件之间结构统一每个模块的接口命名风格一致。如果你让 AI 逐文件生成完整实现最后拼接起来时大概率会因为命名风格不统一而大量返工。先生成接口骨架再逐个填充实现是多人协作项目里也在用的套路和 AI 协作时同样适用。3.2 逐步细化交易逻辑的对话式开发框架搭好后核心的交易模块我没有一次性让 AI 写给完整代码而是分了三轮对话一步步细化。第一轮让它实现支出校验逻辑第二轮实现持仓更新逻辑第三轮实现交易流水记录。每一轮对话时我会把上一轮生成的代码贴回去加上本轮需求。这里面的效率差异很大。直接一次性说“写一个完整的交易系统”能得到的代码但多半是教科书写法纯函数、无状态、所有参数从外部传入。倒不是说这种写法不好而是它和你账户类的状态管理方式对不上后面装修起来反而费劲。分步对话的好处是每一步都清楚地知道它是在给哪个模块加能力生成代码直接嵌进现有类里不用做适配。我写的一段关键提示词是这样的在 Account 类中新增 buy(stock_code, price, quantity) 方法 1. 先计算总成本和手续费 2. 检查 self.available_cash 是否充足不足抛异常 3. 扣减可用现金 4. 更新持仓字典 self.positions 5. 返回交易结果字典 注意不要扣减冻结资金我们目前不做挂单功能注意到最后那句话了吗这个“边界声明”非常关键。AI 模型很容易根据自己的预训练知识把买流程做成完整的委托状态机加入冻结、挂单、撤单逻辑。如果你不声明不要什么生成的代码往往比预期复杂一个量级而且这些多余的逻辑不是你写的调试时完全是一头雾水。3.3 用 AI 排查边界 bug 的经验有一类 bug靠看代码很难发现但靠描述症状让 AI 定位反而效率很高。我遇到过一个典型问题连续交易多笔之后账户总资产比实际值多了几分钱。这是浮点数累计误差导致的但项目里所有金额我都做了四舍五入理论上不该出现误差。我把这个问题直接描述给 CodeArts账户类中的 total_asset 属性值不对比手动计算的值大 0.03。每次买卖时手续费都按 Decimal 计算并转成 float 存储。帮我检查 update_snapshot 方法中总资产的计算逻辑。它很快定位到问题我的买入方法里更新现金时用的是 Decimal 运算但持仓市值更新用的是 float 运算两者精度不一致导致快照累计时出现系统性误差。它给出的修改方案很直接所有涉及金额的计算统一用 Decimal仅在最终输出和绘图时转换为 float。这个案例让我印象很深。在传统的开发流程里这种问题要手工加日志、打断点、逐步跟踪至少半小时起步。用 AI 描述症状再定位几分钟搞定。前提是你能清楚描述问题现象以及提供相关代码。所以项目里每个方法都有清晰 docstring这一点特别重要因为 AI 要理解你的代码逻辑很大程度上依赖上下文中的注释。3.4 主程序联调与交互界面主程序用的是最简单的命令行交互打印菜单读取用户输入调用对应方法。界面虽然简陋但作为流程验证足够了。如果用 PyQt 或 Tkinter 做图形界面工期至少翻倍反而冲淡了核心主题。我在生成 main.py 时给出的要求是写一个命令行交互主程序 1. 启动时从 data.json 加载账户状态若不存在则初始化 1000000 资金 2. 显示当前持仓和资产概况 3. 循环显示操作菜单1查询行情 2买入 3卖出 4查看持仓 5查看资产曲线 6退出 4. 每次操作完成后自动保存账户状态菜单逻辑本身不复杂但有一点值得注意程序读取用户输入时要做好异常处理用户输入了非数字字符、买入数量为负数、卖出数量超过持仓量这些都要捕获并给出提示而不是让程序崩溃。AI 生成的初版代码只会处理正常输入路径各种异常处理基本都需要我追加补充这个环节人工参与的价值很大。4. 常见问题与排查技巧实录4.1 行情数据长度与交易日期不同步第一个遇到的坑模拟生成的行情数据是 250 个交易日但账户快照只有交易日执行的交易才记录导致两个列表长度不一致画图时 matplotlib 报 dimension mismatch 错误。排查思路很简单打印两个列表的长度发现差了 3 天。原因是程序启动时先模拟生成行情如果此时还没有发生任何交易账户快照列表就是空的。一开始我以为这是数据处理问题后来才意识到是设计问题——快照应该在每一天都记录而不是只记录交易日。修改方式是交易日循环的每一天结束时都执行快照无论当天是否发生交易。这算是一个“程序逻辑正确但设计不合理”的典型案例AI 很难帮你发现因为它看到的每一段代码语法都正确、逻辑都能自洽但合并到一起组件之间的时序关系出问题了。4.2 AI 生成的代码有隐藏假设CodeArts 在实现遍历持仓卖出时默认生成一个 for 循环内部做动态修改列表的操作。这个代码在某些情况下能跑通但如果期间发生了持仓清零for 循环下次迭代时就会出问题列表被修改导致迭代器失效或者比重低的元素被跳过。这个属于 Python 的经典坑不要在遍历列表时修改列表。解决办法是遍历列表的副本或者收集要修改的键循环结束后统一处理。之所以说这是 AI 生成代码的隐藏假设是因为模型的训练数据里类似“遍历持仓然后全部卖出”的场景很多它倾向于直接写for stock_code in self.positions: self.sell(stock_code, ...)这行代码在持仓只有一只股票时工作正常两只呢大概率也正常。直到出现三只持仓且第一只卖出后触发清零剩下的股票可能被跳过。排查这类问题时单纯报错信息往往不明显因为程序不会崩只是结果不对。我最后的解决方式是在卖出函数开头打印一行日志输出执行卖出的股票代码和当前持仓列表长度才在日志里看到问题。4.3 交易费用精度与四舍五入策略金额计算最好是全程 Decimal。但 Decimal 和 float 混用时有个隐蔽坑Decimal 的上下文精度默认是 28 位而 float 只有 15 位有效数字。如果在 Decimal 运算后转 float 再转回 Decimal精度就白设了。我的方案是设计一个统一的金额格式化函数from decimal import Decimal, ROUND_HALF_UP def fmt_money(value): if isinstance(value, float): value Decimal(str(value)) return value.quantize(Decimal(0.01), roundingROUND_HALF_UP)注意 Decimal(str(value)) 不是 Decimal(value)这两个是有本质区别的。前者把 float 的字符串表示传进去精度不会损失后者直接传 float 对象可能引入二进制浮点数的完整尾数。模拟炒股项目因为不涉及真实资金精度稍微偏差一点好像无所谓但如果你打算把这类代码迁移到其他需要记账的场景这个坑会让你重写所有核心模块。从练习的角度把精度问题处理好相当于提前踩了一遍真实量化交易开发者的日常工作。4.4 让 AI 解释不清楚的代码CodeArts 偶尔会生成一些它自己也解释不清楚的代码。我遇到过一次它生成的技术指标计算函数里有一段奇怪的数组切片操作我问它为什么这么写它给的解释是“用于处理边界情况”。后来我手工推演了一遍发现这段操作完全多余删掉之后输出不变。这个现象提醒我一个事实AI 生成的代码没有“意图”只有“相关性”。它生成一段代码是因为训练数据里类似场景出现过类似写法不代表这段代码真的有用。所以审查 AI 生成的代码时要带着一种“怀疑考古”的心态看到不理解的代码段就删掉跑一遍测试验证它是否真的必要。这也解释了为什么我认为 AI 结对编程的最低门槛不是会写代码而是能读懂代码。你要能判断“这段代码在做什么”“这段代码是否合理”才能有效地审查和取舍。5. 一些值得记住的协作技巧和 CodeArts 配合完成这个项目后我总结了几条适用于任何 AI 编程工具的经验。第一条是让 AI 写代码前先描述清楚“不要什么”。很多人在写提示词时只描述目标不设边界。为了得到符合预期的结果我养成了在提示词里补充“不要挂单功能”“不要接入真实行情”“不要自动交易”这类否定式约束的习惯效果立竿见影。第二条是代码模块之间通过接口解耦。AI 生成代码时非常依赖上下文如果模块之间高度耦合你让它修改其中一个模块它会因为无法理解全局结构而生成一堆垃圾代码。把模块之间的调用关系设计得像 API 一样清晰——每个方法只接收必要参数返回结构化结果——AI 理解和生成代码的准确率会大幅提升。第三条是每次让 AI 做出修改后跑一遍全量测试确认旧功能没被破坏。我用最简单的 assert 写了几个回归测试脚本验证买入后资金减少的数量等于成本加手续费验证卖出后持仓减少数量正确验证多次买卖后总资产不变忽略手续费后。这些测试代码加起来不到 50 行但它们能保证 AI 在修改一个模块时不会悄无声息地把另一个模块改坏。最后一条是关于项目边界的。模拟炒股小助手从一开始就被我定义为“不接真实行情、不提供投资建议、不可用于实盘交易”的纯学习工具。想把它升级成更接近真实的系统可以按这个路线迭代加入限价挂单与撮合逻辑、加入多股票组合、引入回测模块让历史行情驱动模拟交易、接入真实财经数据 API 做基本面研究。我个人在做完这个项目后的体会是AI 协作开发的最大价值不是减少打字量而是省掉了那些“我知道怎么做但很烦做”的部分——生成重复的类定义、写样板代码、排查精度问题。真正的难点比如设计数据结构、定义交易规则、审查 AI 生成代码的正确性依然需要由人来完成。换句话说AI 当了高效的实习生而你要做合格的导师——自己得先懂业务才能指导 AI 把活干对。先把模拟炒股的数据流跑通再考虑往上加功能这条路走下来非常顺推荐你也试试。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑