4、Python基础速通(下):条件判断与循环、函数定义与使用、文件读写操作、异常处理
好,咱们接着上节课的内容往下走。上回我们把Python的数据类型和运算符捋了一遍,算是把"食材"备齐了。今天这堂课,咱们要开始真正"炒菜"了——也就是控制程序的执行流程、封装可复用的逻辑、跟文件打交道,以及处理那些让人头疼的异常情况。
我个人觉得,这四块内容是量化交易脚本里最常用的基本功。你想想看,一个策略无非就是:判断条件是否满足 → 循环处理数据 → 调用函数执行逻辑 → 读写配置文件或日志 → 遇到错误别崩盘。嗯,就是这么回事。
4.1 条件判断:让程序学会"看情况办事"
量化交易里最核心的逻辑是什么?说白了就是"如果A成立,就做B;否则做C"。比如:如果5日均线上穿20日均线,就买入;否则空仓观望。这就是条件判断的典型应用。
Python的条件判断用 if、elif、else 来实现。语法很简单,但有几个坑我得提前跟你说。
# 基础结构
price = 10.5
if price > 10:
print("价格高于10元,考虑卖出")
elif price < 8:
print("价格低于8元,考虑买入")
else:
print("价格在8-10之间,持有观望")
# 注意:Python用缩进来表示代码块,不是花括号!
# 我见过太多新手在这里翻车了
我曾经在写一个回测脚本时,因为
if 和 elif 的顺序搞反了,导致策略信号全部错乱。记住:if 从上往下判断,一旦满足某个条件,后面的 elif 和 else 就不再执行了。所以要把最严格的条件放在最前面。
还有一个常用的技巧——三元表达式。适合简单的二选一场景:
# 传统写法
if volume > 10000:
status = "活跃"
else:
status = "不活跃"
# 三元表达式(一行搞定)
status = "活跃" if volume > 10000 else "不活跃"
4.2 循环:批量处理数据的利器
做量化交易,你经常要处理成千上万条K线数据。一条条写代码?那得写到猴年马月。这时候就需要循环出马了。
Python有两种循环:for 和 while。我个人90%的场景都用 for,因为它更直观、更安全。
# for循环:遍历列表
prices = [10.2, 10.5, 10.3, 10.8, 10.1]
for price in prices:
print(f"当前价格: {price}")
# 带索引的遍历(用enumerate)
for i, price in enumerate(prices):
print(f"第{i+1}根K线,价格: {price}")
# while循环:条件满足就一直跑
balance = 10000
while balance > 0:
trade_loss = 500
balance -= trade_loss
print(f"交易亏损,剩余资金: {balance}")
print("爆仓了...")
写循环时一定要小心死循环。我有个同事曾经在while循环里忘了更新条件变量,结果程序跑了一整夜,把服务器CPU干到100%。嗯,第二天他就被约谈了。
建议:能用
for 就别用 while,除非你真的需要无限循环(比如实时行情推送)。
循环里还有两个控制语句:break(跳出整个循环)和 continue(跳过本次循环)。
# break示例:找到第一个满足条件的就停
for price in prices:
if price > 10.5:
print(f"找到目标价格: {price}")
break # 找到了,后面的不用看了
# continue示例:跳过不符合条件的数据
for price in prices:
if price < 10.0:
continue # 低于10块的跳过,不处理
print(f"处理价格: {price}")
4.3 函数定义与使用:把逻辑"打包"起来
你想想看,如果每次计算均线都要写一遍循环,那代码得多臃肿?函数就是用来解决这个问题的——把一段逻辑封装起来,起个名字,随用随调。
# 定义一个计算移动平均线的函数
def calculate_ma(prices, window=5):
"""
计算移动平均线
:param prices: 价格列表
:param window: 窗口大小,默认5
:return: 移动平均值列表
"""
ma_list = []
for i in range(len(prices)):
if i < window - 1:
ma_list.append(None) # 前几个数据不够,填None
else:
avg = sum(prices[i-window+1:i+1]) / window
ma_list.append(avg)
return ma_list
# 调用函数
prices = [10, 11, 12, 13, 14, 15, 16]
ma5 = calculate_ma(prices, window=5)
print(f"5日均线: {ma5}")
这里有几个要点:
- 参数默认值:
window=5表示如果不传这个参数,默认用5。我在项目中经常用这个特性,让函数更灵活。 - 文档字符串:函数开头的三引号注释,方便别人(包括未来的你)理解函数用途。
- 返回值:用
return把结果传出来。没有return的函数默认返回None。
一个好的函数应该只负责一个功能。比如:计算均线的函数就别在里面画图,画图另写一个函数。这样代码好维护,也好测试。
另外,Python还支持匿名函数(lambda),适合写一些简单的、一次性使用的逻辑:
# lambda示例:对价格列表排序
prices = [10.5, 8.2, 12.1, 9.8]
# 按价格降序排序
sorted_prices = sorted(prices, key=lambda x: -x)
print(sorted_prices) # [12.1, 10.5, 9.8, 8.2]
4.4 文件读写操作:让数据"持久化"
程序跑完,数据就丢了?那可不行。量化交易里,你要把策略参数、交易日志、回测结果都保存下来。文件读写就是干这个的。
Python内置的 open() 函数是文件操作的入口。我强烈建议你用 with 语句,它会自动帮你关闭文件,省心又安全。
# 写入文件
with open("trade_log.txt", "w", encoding="utf-8") as f:
f.write("2024-01-01, 买入, 100股, 价格10.5\n")
f.write("2024-01-02, 卖出, 100股, 价格11.2\n")
# 文件自动关闭,不用操心
# 读取文件
with open("trade_log.txt", "r", encoding="utf-8") as f:
content = f.read() # 一次性读取全部
print(content)
# 逐行读取(适合大文件)
with open("trade_log.txt", "r", encoding="utf-8") as f:
for line in f:
print(line.strip()) # strip()去掉换行符
| 模式 | 说明 | 常用场景 |
|---|---|---|
'r' |
只读模式 | 读取配置文件、历史数据 |
'w' |
写入模式(覆盖) | 保存新的日志、结果 |
'a' |
追加模式 | 持续记录交易日志 |
'r+' |
读写模式 | 需要同时读写的场景 |
读写中文文件时,一定要指定
encoding="utf-8"。我曾经在Windows上写了一个策略,没指定编码,结果换到Linux服务器上跑,中文全变成乱码了。排查了半天才发现是编码问题。
4.5 异常处理:让程序"摔倒了还能爬起来"
程序跑着跑着,突然遇到网络断开、文件不存在、数据格式不对……然后就崩溃了?这在实际交易中是不能接受的。异常处理就是给程序穿上"防弹衣"。
# 基本结构:try-except
try:
price = float(input("请输入价格: "))
result = 100 / price
print(f"计算结果: {result}")
except ValueError:
print("输入的不是有效数字,请重新输入")
except ZeroDivisionError:
print("价格不能为0,请重新输入")
except Exception as e:
print(f"发生了未知错误: {e}")
else:
print("没有发生异常,正常执行")
finally:
print("无论是否异常,这行都会执行")
为什么要有 finally?你想想看,如果程序在读取文件时出错了,但文件已经打开了,这时候需要关闭文件。finally 就是用来做这种"善后工作"的。
不要滥用异常处理。只捕获你预期可能发生的异常,并且给出有意义的提示信息。我曾经见过有人写
except: pass,把所有异常都吞掉了,结果程序出了bug完全不知道,数据全错了还在跑。那叫掩耳盗铃。
你还可以主动抛出异常,用于校验参数:
def trade(stock_code, quantity):
if not isinstance(stock_code, str) or len(stock_code) != 6:
raise ValueError("股票代码必须是6位字符串")
if quantity <= 0:
raise ValueError("交易数量必须大于0")
print(f"正在交易: {stock_code}, 数量: {quantity}")
# 调用
try:
trade("600519", 100) # 正确
trade("123", -5) # 会抛出异常
except ValueError as e:
print(f"交易参数错误: {e}")
好了,以上就是Python基础速通的下半部分。这四块内容——条件判断、循环、函数、文件操作、异常处理——是写量化交易脚本的"四梁八柱"。你把这些练熟了,后面写策略框架、回测引擎、实盘接口的时候,就会感觉游刃有余。
记住:代码是写给人看的,顺便让机器执行。所以写的时候多想想"别人能不能看懂"、"半年后的我自己能不能看懂"。嗯,就这样,去练练手吧。