3、Python基础速通:数据类型、控制流、函数、面向对象编程基础

说实话,很多做量化交易的朋友,一上来就急着写策略、跑回测。结果呢?连个DataFrame都操作不明白,报错信息也看不懂。我见过太多这样的案例了。

Python基础不牢,后面写策略代码就是给自己挖坑。今天这一章,咱们就把地基打扎实。别急,我带你快速过一遍最核心的内容。

Python 量化交易基础速通 数据类型 控制流 函数 面向对象 int, float, str, list if, for, while def, 参数, 返回值 class, 封装, 继承 量化交易 = 数据 + 逻辑 + 复用 + 扩展

3.1 数据类型:量化交易的基本单元

Python的数据类型,说白了就是用来装数据的容器。你想想看,股票代码、价格、成交量,这些不都是数据吗?

3.1.1 数字类型

整型(int)和浮点型(float)是最常用的。我个人习惯用float来存价格,因为涉及到小数。

# 股票价格
price = 12.58  # float
volume = 10000  # int
print(type(price))  # <class 'float'>
💡 小提示: 计算收益率时,记得把整型转成浮点型,否则Python会做整数除法。比如 5/2 是2.5,但 5//2 是2。

3.1.2 字符串

股票代码、日期这些,用字符串存最合适。我在项目中遇到过一个问题:从API拿到的股票代码是"000001",结果存成int变成了1。嗯,这里要注意,股票代码一定要用字符串。

stock_code = "000001"  # 字符串
stock_name = '平安银行'
print(f"股票代码: {stock_code}, 名称: {stock_name}")

3.1.3 列表与元组

列表(list)是可变的,元组(tuple)不可变。我一般用列表存动态数据,比如当日所有成交记录。元组用来存固定配置,比如交易参数。

# 列表 - 可增删改
trade_records = [12.5, 12.6, 12.55]
trade_records.append(12.7)

# 元组 - 不可变
config = ("AAPL", 100, 150.0)  # 股票代码,数量,止损价

3.1.4 字典

字典是量化交易中最常用的数据结构。为什么?因为天然适合存键值对,比如股票代码对应价格。

# 实时行情快照
market_snapshot = {
    "000001": 12.58,
    "000002": 15.20,
    "600519": 1850.00
}
print(market_snapshot["000001"])  # 12.58
📌 重点: 字典的查询速度是O(1),比列表快得多。如果你要频繁查找数据,用字典准没错。

3.2 控制流:让代码有逻辑

控制流就是告诉代码什么时候该做什么。没有控制流,代码就是一潭死水。

3.2.1 条件判断

if-elif-else,这个太基础了。但我想说的是,写量化策略时,条件判断一定要清晰,别嵌套太多层。

current_price = 12.58
buy_threshold = 12.50
sell_threshold = 13.00

if current_price <= buy_threshold:
    print("触发买入信号")
elif current_price >= sell_threshold:
    print("触发卖出信号")
else:
    print("持仓观望")
⚠️ 避坑指南: 我曾经写过一段代码,if条件里用了 and 和 or 混在一起,结果逻辑全乱了。后来我养成了一个习惯:复杂条件用括号明确优先级。

3.2.2 循环

for循环用来遍历数据,while循环用来做条件等待。我个人习惯用for更多,因为量化交易里大部分场景是遍历历史数据。

# 遍历历史价格
prices = [12.5, 12.6, 12.55, 12.7, 12.65]
for i, price in enumerate(prices):
    print(f"第{i+1}个价格: {price}")

# 计算移动平均
total = 0
for price in prices:
    total += price
ma = total / len(prices)
print(f"移动平均: {ma:.2f}")

3.3 函数:把逻辑封装起来

函数是代码复用的基础。你想想看,计算移动平均这个操作,你会在策略里用很多次吧?写成函数,一劳永逸。

3.3.1 定义函数

def calculate_ma(prices, period=5):
    """计算移动平均线"""
    if len(prices) < period:
        return None
    return sum(prices[-period:]) / period

# 使用
prices = [12.5, 12.6, 12.55, 12.7, 12.65]
ma_5 = calculate_ma(prices)
print(f"5日均线: {ma_5}")
💡 小提示: 函数一定要写文档字符串(docstring),就是那个三引号里的内容。我刚开始也不写,结果三个月后看自己的代码,完全想不起来这个函数是干嘛的。

3.3.2 参数传递

Python的参数传递,说白了就是传引用。但不可变对象(如int、str)在函数内修改不会影响外部,可变对象(如list)会。

def add_price(prices, new_price):
    prices.append(new_price)  # 会修改原列表
    return prices

my_prices = [12.5, 12.6]
add_price(my_prices, 12.7)
print(my_prices)  # [12.5, 12.6, 12.7]
⚠️ 避坑指南: 我曾经在函数里直接修改了传入的列表,结果影响了全局数据,回测结果全错了。后来我养成了习惯:如果不想修改原数据,用 copy() 复制一份。

3.4 面向对象编程基础:构建你的交易系统

面向对象编程(OOP),说白了就是把数据和操作数据的方法打包在一起。对于量化交易来说,一个策略就是一个对象。

3.4.1 类与对象

class TradingStrategy:
    """交易策略基类"""
    def __init__(self, name, initial_capital):
        self.name = name
        self.capital = initial_capital
        self.positions = {}
    
    def buy(self, stock_code, price, volume):
        cost = price * volume
        if self.capital >= cost:
            self.capital -= cost
            self.positions[stock_code] = volume
            print(f"买入 {stock_code}: {volume}股, 花费 {cost:.2f}")
        else:
            print("资金不足")
    
    def show_status(self):
        print(f"策略: {self.name}, 剩余资金: {self.capital:.2f}")
        print(f"持仓: {self.positions}")

# 使用
my_strategy = TradingStrategy("均线策略", 100000)
my_strategy.buy("000001", 12.58, 1000)
my_strategy.show_status()

3.4.2 封装与继承

封装就是把内部实现藏起来,只暴露接口。继承就是复用父类的代码。我一般会先写一个基类,然后不同的策略继承它。

class MovingAverageStrategy(TradingStrategy):
    """均线策略 - 继承自TradingStrategy"""
    def __init__(self, name, initial_capital, short_period=5, long_period=20):
        super().__init__(name, initial_capital)
        self.short_period = short_period
        self.long_period = long_period
    
    def generate_signal(self, prices):
        """生成交易信号"""
        if len(prices) < self.long_period:
            return "hold"
        
        short_ma = sum(prices[-self.short_period:]) / self.short_period
        long_ma = sum(prices[-self.long_period:]) / self.long_period
        
        if short_ma > long_ma:
            return "buy"
        elif short_ma < long_ma:
            return "sell"
        else:
            return "hold"

# 使用
ma_strategy = MovingAverageStrategy("双均线策略", 100000, 5, 20)
signal = ma_strategy.generate_signal([12.5, 12.6, 12.55, 12.7, 12.65, 12.8, 12.75])
print(f"信号: {signal}")
📌 重点: 面向对象编程的核心思想是「高内聚,低耦合」。每个类只负责一件事,类与类之间尽量减少依赖。这样你的代码才好维护、好扩展。

3.5 本章小结

好了,这一章的内容就这些。数据类型是基础,控制流是逻辑,函数是复用,面向对象是架构。这四个东西串起来,你就能写出结构清晰的量化交易代码了。

我个人建议,学完这一章后,马上动手写一个小程序:用字典存股票数据,用函数计算指标,用类封装策略。别光看不练,代码这东西,敲多了自然就熟了。

专注资料整理