深圳融克迪特科技有限公司 Logo,金融科技,量化交易,软件开发

深圳融克迪特科技有限公司

RONG CREDIT TECHNOLOGY CO., LTD.

基础入门

【Python 系列 第4讲】函数封装:写一个收益率计算器

本讲把上一讲的收益率循环收进一个最小函数,明确输入、处理过程与返回值,让初学者第一次感受到代码复用带来的结构收益,并为后面的筛选、异常处理和摘要生成打下接口基础。

2026-04-26 智铨研究 阅读时长 7 分钟

目录

  1. 本节目标
  2. 为什么第 4 讲要先写“收益率计算器”
  3. 沿用第 3 讲的价格列表示例
  4. 四步写出一个最小收益率函数
  5. 先写函数名和输入参数
  6. 把上一讲的循环移进函数体
  7. 记得把结果返回出去
  8. 真正调用并检查输出
  9. 怎样判断这个“收益率计算器”真的可用
  10. 函数返回的是列表
  11. 结果条数仍然正确
  12. 函数能处理另一组价格
  13. 第一个结果和手算一致
  14. 函数为什么总写着写着就不对了
  15. 为什么函数里还要重新建returns
  16. 为什么return不能省
  17. 函数名为什么要写清楚
  18. 是不是所有代码都该马上封装成函数
  19. 哪些情况仍然算本讲完成
  20. 把函数和主流程拆开写
  21. 第 4 讲建立的是“复用意识”
  22. 完成标准
  23. 系列衔接
  24. 风险揭示与免责声明

Python · 入门短课

  1. 第 1 讲【Python 系列 第1讲】Python环境检查:先打印一组收盘价
  2. 第 2 讲【Python 系列 第2讲】列表和字典:装下价格与日期
  3. 第 3 讲【Python 系列 第3讲】for循环:批量计算日收益率
  4. 第 4 讲【Python 系列 第4讲】函数封装:写一个收益率计算器
  5. 第 5 讲【Python 系列 第5讲】条件判断:筛出上涨交易日
  6. 第 6 讲【Python 系列 第6讲】CSV读写:保存再读回价格表
  7. 第 7 讲【Python 系列 第7讲】异常处理:避开空值和除零
  8. 第 8 讲【Python 系列 第8讲】生成一份行情摘要

【Python 系列 第4讲】函数封装:写一个收益率计算器

1. 本节目标

第 4 讲开始把前一讲已经写出来的循环,收进一个可重复调用的小函数里。目标很具体:写一个最小收益率计算器,让你以后换一组价格时,不用每次都重新拼整段循环。这一步对 Python 入门很关键,因为从这里开始,你就不只是“把代码跑通”,而是在主动整理自己的代码结构。

学完这一讲后,你可以直接完成下面几件事:

  1. 理解函数的输入、处理过程和返回值。
  2. 把收益率计算逻辑封装成一个可复用函数。
  3. 用同一个函数处理不同价格列表。

函数封装做好以后,后面加条件判断、异常处理和摘要统计时,代码会明显更稳。

2. 为什么第 4 讲要先写“收益率计算器”

到第 3 讲为止,你已经能用循环批量算出收益率了。但如果你每次都把那段循环原样复制一遍,代码很快会变得重复,而且一旦要改逻辑,就得处处同步修改。第 4 讲要解决的,就是这个最常见的入门问题:相同动作怎么只写一次

收益率计算器之所以适合作为第一类函数,是因为它满足三个条件:

  1. 输入清楚,就是一组价格。
  2. 输出明确,就是一组收益率。
  3. 中间逻辑你已经在上一讲练过,不会被新公式分散注意力。

所以这节课的重点不是“函数语法有多高级”,而是让你第一次感受到封装带来的实际好处。

3. 沿用第 3 讲的价格列表示例

prices = [12.34, 12.80, 12.65, 13.10]

这节课仍然不用第三方库,也不引入更大数据。当前重点是函数边界,而不是样本规模。

4. 四步写出一个最小收益率函数

下面四步分别处理“先定输入”“再写主体”“然后返回结果”“最后真正调用”。

5. 先写函数名和输入参数

def calc_simple_returns(prices):
    pass

这里的 prices 就是函数输入。它的意思很简单:外面谁给我一组价格,我就按这组价格去算。

6. 把上一讲的循环移进函数体

def calc_simple_returns(prices):
    returns = []
    for i in range(1, len(prices)):
        prev_price = prices[i - 1]
        curr_price = prices[i]
        ret = (curr_price - prev_price) / prev_price
        returns.append(ret)

你会发现,函数体里的核心逻辑和第 3 讲几乎一样。第 4 讲真正新增的,不是公式,而是把它包进了一个边界更清楚的容器里。

7. 记得把结果返回出去

def calc_simple_returns(prices):
    returns = []
    for i in range(1, len(prices)):
        prev_price = prices[i - 1]
        curr_price = prices[i]
        ret = (curr_price - prev_price) / prev_price
        returns.append(ret)
    return returns

很多初学者第一次写函数时,最容易漏掉的就是 return。如果没有这句,函数虽然运行了,但外面拿不到结果。

8. 真正调用并检查输出

prices = [12.34, 12.80, 12.65, 13.10]
returns = calc_simple_returns(prices)

print(returns)
for ret in returns:
    print(f"日收益率: {ret:.2%}")

到这一步,你已经不需要在主流程里再展开整段循环,只要把价格交给函数即可。

9. 怎样判断这个“收益率计算器”真的可用

当前不需要复杂测试,把输入、输出和复用这三点验证清楚就够了。

10. 函数返回的是列表

returns = calc_simple_returns(prices)
assert isinstance(returns, list)

11. 结果条数仍然正确

assert len(returns) == len(prices) - 1

12. 函数能处理另一组价格

other_prices = [20.00, 20.50, 20.10]
other_returns = calc_simple_returns(other_prices)
assert len(other_returns) == 2

13. 第一个结果和手算一致

assert abs(returns[0] - ((12.80 - 12.34) / 12.34)) < 1e-9

只要这几条都成立,就说明你已经把收益率逻辑真正封装成了一个后面还能继续用的工具。

14. 函数为什么总写着写着就不对了

第 4 讲最常见的问题,不在公式,而在函数边界。

15. 为什么函数里还要重新建returns

因为函数最好自己管理自己的中间变量。这样外面的代码更干净,也不容易和别的列表混在一起。

16. 为什么return不能省

因为不返回,外部就拿不到结果。你会看到函数跑完了,但 returns = calc_simple_returns(prices) 得到的是 None

17. 函数名为什么要写清楚

因为后面你很可能还会写筛选函数、摘要函数。函数名如果太含糊,代码一多就会很难读。

18. 是不是所有代码都该马上封装成函数

也不是。第 4 讲先封装收益率,是因为这段逻辑已经重复出现,而且后面还会继续复用。是否封装,关键看“会不会反复用”。

19. 哪些情况仍然算本讲完成

  1. 函数里变量名不一定非要和示例完全一致,但输入输出关系必须清楚。
  2. 你可以先只返回原始小数收益率,不一定马上格式化成百分比。
  3. 当前不要求给函数写类型注解,第 4 讲先把封装意识建立起来。
  4. 如果你用另一组价格测试函数,只要结果长度和公式都对,就算通过。

20. 把函数和主流程拆开写

def calc_simple_returns(prices):
    returns = []
    for i in range(1, len(prices)):
        prev_price = prices[i - 1]
        curr_price = prices[i]
        returns.append((curr_price - prev_price) / prev_price)
    return returns


prices = [12.34, 12.80, 12.65, 13.10]
returns = calc_simple_returns(prices)
print(returns)

这种“上面定义函数,下面调用函数”的写法,后面会越来越常见。尽早习惯,会让你的 Python 代码更像一个可复用的小工具,而不是一次性脚本。

21. 第 4 讲建立的是“复用意识”

很多初学者在这一讲之前,写代码的方式更像是在回答一道题:把结果算出来就结束。函数封装带来的变化是,你开始站在下一次还要再用的角度写代码。这个视角很重要,因为真实的量化研究工作里,几乎没有哪个动作只做一次。

从这个角度看,第 4 讲写出的不只是一个收益率函数,而是你第一次主动为后续步骤整理出一个稳定接口。

22. 完成标准

如果你现在已经能把收益率计算封装成一个函数,并且换一组价格也能继续调用它,那第 4 讲就算完成。

23. 系列衔接

本讲是《Python量化入门短课》的第 4/8 讲,当前主题是《函数封装:写一个收益率计算器》。

上一讲:第 3 讲《for循环:批量计算日收益率》。

下一讲:第 5 讲《条件判断:筛出上涨交易日》。

后续安排:第 6 讲《CSV读写:保存再读回价格表》;第 7 讲《异常处理:避开空值和除零》。

24. 风险揭示与免责声明

风险揭示与免责声明

本页面内容仅用于量化研究与技术交流,旨在展示研究方法与流程,不构成对任何金融产品、证券或衍生品的要约、招揽、推荐或保证。

本文所涉历史数据、回测结果与示例参数不代表未来表现,也不应作为投资决策依据。

市场存在波动、流动性与执行偏差等不确定性,任何策略均可能出现收益波动或阶段性失效。

读者应结合自身风险承受能力进行独立判断,并在必要时咨询持牌专业机构意见。