Python技术迷

Python量化交易入门:一个超过4万赞的量化交易框架

别一上来就 pip install vnpy,然后急着写个均线策略去跑实盘。

量化交易最容易骗人的地方,不是策略多复杂,而是你本地回测看着挺顺,一接行情、一接委托、一遇到撤单、断线、滑点、夜盘切换,整套东西立马露馅。

vn.py,也叫 VeighNa,厉害的地方不在于它能帮你写出“稳赚策略”。这话我一般先按住。它真正值钱的是:把行情、交易接口、事件驱动、策略模块、回测、风控这些脏活,先给你搭了个架子。

Image

我核了一眼现在的项目状态,GitHub 上 vnpy/vnpy 已经是 40k star、11.6k fork,确实不是那种没人用的小玩具。官方对它的定位也很直接:基于 Python 的开源量化交易系统开发框架,后来逐步长成多功能量化交易平台。

这东西入门时别先盯着“策略收益率”。我一般会先看三件事:

行情怎么进来。

信号怎么生成。

委托出去之前,有没有风控挡一下。

很多人写量化,第一段代码长这样:

if fast_ma > slow_ma:
    buy()
else:
    sell()

看着清爽,实盘里我不太信这种代码。因为它没说账户还有多少钱,没说当前有没有持仓,没说连续触发信号怎么办,也没说价格异常怎么办。

我更愿意先写一个很笨的小骨架,把交易动作压住:

from dataclasses import dataclass
from collections import deque

@dataclass
classTick:
    symbol: str
    price: float
    ts: str

classTinyRisk:
def__init__(self, max_pos: int, max_price_jump: float):
        self.max_pos = max_pos
        self.max_price_jump = max_price_jump
        self.last_price = None

defallow(self, price: float, next_pos: int) -> bool:
if abs(next_pos) > self.max_pos:
            print(f"[risk] position blocked, next_pos={next_pos}")
returnFalse

if self.last_price and abs(price / self.last_price - 1) > self.max_price_jump:
            print(f"[risk] price jump blocked, last={self.last_price}, now={price}")
returnFalse

        self.last_price = price
returnTrue

classMaStrategy:
def__init__(self, symbol: str):
        self.symbol = symbol
        self.window = deque(maxlen=20)
        self.pos = 0
        self.risk = TinyRisk(max_pos=2, max_price_jump=0.03)

defon_tick(self, tick: Tick):
if tick.symbol != self.symbol:
return

        self.window.append(tick.price)
if len(self.window) < 20:
return

        fast = sum(list(self.window)[-5:]) / 5
        slow = sum(self.window) / 20

if fast > slow and self.pos <= 0:
            self.send_order("BUY", tick.price, 1)

elif fast < slow and self.pos >= 0:
            self.send_order("SELL", tick.price, 1)

defsend_order(self, side: str, price: float, volume: int):
        next_pos = self.pos + volume if side == "BUY"else self.pos - volume

ifnot self.risk.allow(price, next_pos):
return

        self.pos = next_pos
        print(f"[order] {side} price={price:.2f}, volume={volume}, pos={self.pos}")

这段不是 vn.py 的正式策略模板,我故意没写成那种“复制就去连实盘”的样子。入门先把这个流程看懂,比背一堆指标有用。

vn.py 的完整工程里,策略不是孤零零跑的。它下面有交易接口,上面有策略应用,中间靠事件流转。官方文档里也能看到,它不只是 CTA 策略,还有回测、价差套利、组合策略、算法交易、数据记录、历史数据管理、风控、RPC 等模块。

这也是我觉得新手容易误判的地方。

你以为自己在学“量化策略”,其实你得先补一堆工程课。

比如行情进来太快,策略消费慢了怎么办?

比如下单返回超时,是订单没发出去,还是柜台收到了但回报没回来?

比如撤单失败,下一次信号还要不要继续发?

比如回测里成交在收盘价,实盘里盘口已经滑走两个价位了。

这些东西,Excel 里看不见,Notebook 里也不太疼。等你真接交易接口了,它就开始疼。

所以用 vn.py 入门,我更建议按这个顺序来。

先装环境。PyPI 上 vnpy 当前要求 Python 3.10 及以上,并且项目标记为 Production/Stable。

python -m venv .venv
source .venv/bin/activate

python -m pip install -U pip wheel
python -m pip install vnpy

如果你是在 Windows 上折腾,别一边用系统 Python,一边用 Anaconda,一边又让 IDE 指到另一个解释器。量化框架的依赖不少,环境一乱,报错能把人看烦。

装完别急着写策略,先跑一段本地行情回放,把日志打出来:

raw_prices = [10.01, 10.03, 10.05, 10.02, 10.08, 10.12, 10.10,
10.16, 10.20, 10.22, 10.18, 10.15, 10.13, 10.09,
10.05, 10.02, 9.98, 10.01, 10.04, 10.08, 10.13]

strategy = MaStrategy("rb_test")

for i, price in enumerate(raw_prices):
    tick = Tick(symbol="rb_test", price=price, ts=f"09:30:{i:02d}")
    strategy.on_tick(tick)

我看策略,第一眼不是看赚了多少,而是看日志顺不顺。

有没有重复下单。

有没有空仓还卖。

有没有价格跳变还追进去。

有没有仓位超限还继续发。

这几个问题挡不住,收益曲线画得再漂亮也没什么意义。

vn.py 适合什么人?

适合已经知道自己要搭交易系统的人。你不想从 socket、柜台接口、事件引擎、数据落库这些地方从零开始造轮子,那它很合适。

但它不适合那种“给我一个框架,我想明天开始自动赚钱”的人。

量化交易入门,最该先学的不是因子,也不是机器学习,而是敬畏交易链路。行情、信号、风控、委托、回报、持仓,每一步都得对上。

vn.py 把架子给你了,剩下的坑,还是得自己一个一个填。