简介这份资源是策略为王论坛上通过SVN获取的开源交易软件源代码面向对股票行情系统与交易客户端实现感兴趣的开发者尤其适合具备C基础、希望研究行情展示与交易功能完整链路的中高级学习者。压缩包共1299个文件约10.54MB以215个cpp源文件与219个h头文件为核心配合11个vcproj工程文件、2个sln解决方案及lib、def等编译配置另有bmp、ico等界面资源与少量htm、txt说明文档已用VS2008编译通过并可正常运行。软件基本覆盖行情、K线、实时走势图等常见交易功能读者可据此梳理客户端模块划分、界面绘制与数据接收逻辑并对照工程结构理解各组件协作方式。目前已有1143人学习下载适合作为研究行情推送与交易软件架构的参考底本。1. 策略为王一套开源交易软件源码能帮你把行情和策略跑通到什么程度很多人第一次接触量化交易都是从“我想验证一个想法”开始的。比如你盯上了某只股票的均线金叉想回测过去三年的表现结果发现要么得买商业软件要么得自己从零搭行情接口、撮合逻辑、账户管理。这套“策略为王”开源交易软件源码解决的正是这个尴尬它把股票行情接入、策略编写、回测执行、交易信号输出这几块拼在一起给你一个能跑起来的骨架。适合两类人——想学交易系统内部结构的开发者以及手里有策略想法、缺一套可改可调框架的量化爱好者。下面我按“能干什么、怎么跑、怎么改”的顺序把这套源码拆开讲。2. 技术栈与目录结构先看清这套交易软件由哪些模块拼起来拿到一份交易软件源码最怕上来就找 main 函数。我一般先看目录因为目录结构基本暴露了作者的分层思路。这套项目的组织方式比较典型行情、策略、交易、数据四条线分开中间靠事件或接口串起来。理解了这个分层后面改代码才不会牵一发动全身。2.1 技术选型为什么是 Python 轻量数据库从源码的依赖文件看这套系统的主语言是 Python版本在 3.8 以上。选 Python 做交易软件不稀奇原因是策略表达快、生态里行情和数值计算库多。核心依赖大致分三类行情获取用 requests 或现成的行情 SDK数据处理用 pandas 和 numpy存储用 SQLite 或 MySQL。前端部分如果是桌面端常见做法是 PyQt 或 Tkinter如果是 Web 端则是 Flask 或 FastAPI 加一个简单页面。这里有个血泪经验交易软件对时间精度敏感Python 的 datetime 在跨时区、跨市场时容易翻车。源码里如果统一用带时区的时间戳存储说明作者踩过坑如果只存字符串你二次开发时得自己补上。数据库选 SQLite 的好处是零配置、单文件适合个人回测但如果你要跑多策略并发或高频数据SQLite 的写锁会成为瓶颈常见做法是换成 MySQL 或时序库。模块常见技术作用行情接入requests / 行情 SDK拉取股票实时与历史 K 线策略引擎纯 Python 类加载策略、逐 bar 驱动回测撮合pandas模拟成交、计算收益数据存储SQLite / MySQL存行情、订单、持仓界面展示PyQt / Flask看行情、看回测曲线2.2 目录结构四个核心目录各管一摊源码的顶层目录一般长这样我按职责拆开说project/ ├── config/ # 配置文件行情源、数据库、策略参数 ├── data/ # 行情数据与本地缓存 ├── strategy/ # 策略文件一个策略一个 py ├── engine/ # 回测引擎、撮合、账户 ├── trader/ # 实盘/模拟交易接口 ├── ui/ # 界面或 Web 路由 └── main.py # 入口串起行情→策略→交易config/里通常有一个settings.py或config.yaml写着行情接口地址、数据库连接串、初始资金。strategy/是二次开发的主战场每个策略继承一个基类实现on_bar或on_tick方法。engine/是黑匣子负责按时间顺序喂数据、调策略、记成交。trader/区分模拟和实盘模拟盘直接走引擎实盘则对接券商接口。ui/看项目形态桌面端是窗口类Web 端是路由函数。提示先读main.py和engine/里的回测主循环这两处决定了数据怎么流动。策略文件反而可以最后看因为它是插拔式的。2.3 数据流一根 K 线从接口到策略的路径这套系统的数据流不复杂但每一步都有可改的点。行情模块拉取数据后先落库或进内存缓存然后由引擎按时间排序逐根 K 线推给策略。策略产生信号后交给撮合模块判断能否成交成交结果更新账户持仓和资金最后写回数据库并推给界面。# engine/backtest.py 简化示意 def run(self, strategy, bars): for bar in bars: # 按时间顺序逐根驱动 self.account.update_price(bar) # 先按最新价更新持仓市值 signal strategy.on_bar(bar) # 策略返回买卖信号 if signal: order self.risk.check(signal, self.account) # 风控过滤 if order: trade self.matcher.match(order, bar) # 模拟撮合 self.account.apply(trade) # 更新账户 return self.account.summary() # 输出收益、回撤等指标这段循环里bars是排好序的 K 线列表strategy.on_bar是你写的策略入口risk.check做仓位和资金校验matcher.match决定成交价和成交量。参数上撮合价常见用当根收盘价或下一根开盘价前者偏乐观后者更接近实盘。改策略时只需要动strategy/下的文件引擎和账户不用碰这是这套结构最舒服的地方。3. 跑起来从装依赖到看到第一张回测曲线源码能不能跑通决定了你对它的信任度。这一章按实际顺序走环境准备、配置行情源、导入数据、跑回测、看结果。每一步我都标出容易卡住的地方新手照着做基本能出图。3.1 环境准备与依赖安装先确认 Python 版本源码里如果有requirements.txt直接装没有的话按 import 反推。常见命令如下# 建议用虚拟环境避免污染全局 python -m venv venv source venv/bin/activate # Windows 用 venv\Scripts\activate # 安装核心依赖版本按源码实际 import 调整 pip install pandas numpy requests sqlalchemy pip install PyQt5 # 如果是桌面端界面装完之后先跑python main.py --help或直接python main.py看报错缺什么。常见缺的是行情 SDK 或数据库驱动按提示补装即可。注意不要一上来就装最新版 pandas交易软件里有些旧写法在新版 pandas 上会报FutureWarning甚至行为变化源码如果锁了版本就按锁的来。3.2 配置行情源与数据库打开config/settings.py重点看三项行情接口地址、数据库路径、初始资金。行情源如果是公开接口通常需要填一个 token 或直接可用如果是本地 CSV则指定数据目录。数据库默认 SQLite 的话路径写相对路径即可首次运行会自动建表。# config/settings.py 示例 MARKET_API https://example-quote-api.local/kline # 行情接口 DB_URL sqlite:///data/trade.db # 本地库 INIT_CASH 1000000 # 初始资金 COMMISSION 0.0003 # 佣金费率 SLIPPAGE 0.001 # 滑点INIT_CASH影响回测收益率的分母改它不会改变策略逻辑但会让绝对收益数字变化。COMMISSION和SLIPPAGE是回测真实度的关键很多人回测曲线漂亮、实盘拉胯就是这两项设成 0 了。我一般把佣金设到万三、滑点设到千一先看策略还成不成立。3.3 导入历史数据并跑通回测数据导入有两种方式接口拉取或本地文件导入。源码里一般有data/loader.py之类的脚本。以 CSV 导入为例# data/loader.py 简化示意 import pandas as pd from sqlalchemy import create_engine df pd.read_csv(data/600000.csv) # 列date, open, high, low, close, volume df[date] pd.to_datetime(df[date]) # 统一时间类型 engine create_engine(sqlite:///data/trade.db) df.to_sql(kline, engine, if_existsappend, indexFalse) print(f导入 {len(df)} 条 K 线)导入后跑回测命令通常是python main.py --strategy ma_cross --start 2022-01-01 --end 2024-12-31。参数里--strategy对应strategy/下的文件名--start和--end控制回测区间。跑完看输出目录里的收益曲线图或控制台指标重点看年化收益、最大回撤、胜率、交易次数。交易次数太少说明信号太稀疏太多说明手续费吃掉了利润。注意如果回测结果全是 0 或没有交易先查数据日期范围和策略参数是否匹配再查撮合模块是否因为资金不足拒绝了所有订单。4. 核心模块拆解策略基类、撮合引擎与账户管理怎么写能跑通只是第一步真正决定这套源码能不能为你所用是看懂三个核心模块策略怎么被加载和驱动、订单怎么被撮合、账户怎么记账。这三块改明白了你就能把自己的想法塞进去而不是被框架牵着走。4.1 策略基类一个 on_bar 方法就是全部入口源码里的策略通常继承一个BaseStrategy必须实现on_bar可选实现on_init和on_order。基类负责持有账户引用、记录信号、提供下单方法。# strategy/base.py 简化示意 class BaseStrategy: def __init__(self, context): self.ctx context # 上下文账户、数据、参数 self.params context.params def on_init(self): pass # 初始化指标、订阅数据 def on_bar(self, bar): raise NotImplementedError # 子类必须实现 def buy(self, price, volume): return self.ctx.order(buy, price, volume) def sell(self, price, volume): return self.ctx.order(sell, price, volume)context是策略和引擎之间的桥梁里面挂着账户、当前持仓、历史数据窗口。buy和sell不直接成交只是把订单丢给引擎这样回测和实盘可以共用同一套策略代码。参数通过context.params传入常见做法是从配置文件或命令行读取避免把参数写死在策略里。一个均线策略大概长这样# strategy/ma_cross.py class MaCross(BaseStrategy): def on_init(self): self.fast self.params.get(fast, 5) self.slow self.params.get(slow, 20) def on_bar(self, bar): closes self.ctx.history(close, self.slow) # 取最近 N 根收盘价 if len(closes) self.slow: return fast_ma sum(closes[-self.fast:]) / self.fast slow_ma sum(closes) / self.slow if fast_ma slow_ma and not self.ctx.position: self.buy(bar.close, self.ctx.max_volume()) elif fast_ma slow_ma and self.ctx.position: self.sell(bar.close, self.ctx.position)history取历史窗口position是当前持仓max_volume按可用资金算最大可买量。这段代码里没有考虑滑点和手续费因为那些在引擎层统一处理策略只管信号。这种职责分离是这套源码值得学的地方。4.2 撮合引擎成交价和成交量怎么定撮合模块决定回测可信度。常见做法是按当根 K 线的收盘价成交或者按下一根开盘价成交。成交量受限于资金、持仓和涨跌停规则。# engine/matcher.py 简化示意 class Matcher: def match(self, order, bar): if order.side buy: price bar.close * (1 self.slippage) # 买入加滑点 volume min(order.volume, self.max_buy(bar)) else: price bar.close * (1 - self.slippage) # 卖出减滑点 volume min(order.volume, self.max_sell(bar)) if volume 0: return None fee price * volume * self.commission return Trade(order.side, price, volume, fee)max_buy要考虑可用资金和涨停无法买入的情况max_sell要考虑持仓和跌停无法卖出。滑点方向必须对买方不利、对卖方不利否则回测会虚高。手续费按成交额乘费率卖出时如果市场有印花税也要在这里扣。4.3 账户管理持仓、资金与收益曲线账户模块负责记账买入扣现金、加持仓卖出加现金、减持仓每天收盘算一次总资产。收益曲线就是总资产序列。# engine/account.py 简化示意 class Account: def __init__(self, cash): self.cash cash self.position 0 self.equity_curve [] def apply(self, trade): amount trade.price * trade.volume if trade.side buy: self.cash - amount trade.fee self.position trade.volume else: self.cash amount - trade.fee self.position - trade.volume def update_price(self, bar): equity self.cash self.position * bar.close self.equity_curve.append(equity)equity_curve是画收益曲线的数据源也是算最大回撤的依据。这里有个容易忽略的点持仓市值要用最新价更新否则曲线是阶梯状的。如果源码里没有update_price说明它只在成交时更新回测曲线会失真二次开发时得补上。5. 避坑与排查跑这套交易源码时最容易翻车的五件事交易软件源码的坑大多不在语法而在数据和时序。下面五条是我拆这类项目时反复遇到的每条按现象、原因、解决写照着排查能省不少时间。5.1 回测曲线完美但实盘完全不是一回事现象回测年化很高实盘一跑就亏。原因通常是回测用了未来数据比如用当根收盘价算信号又用当根收盘价成交或者滑点手续费设成 0。解决把成交价改成下一根开盘价佣金和滑点按真实水平设再跑一遍看策略还成不成立。5.2 行情数据缺失导致指标计算报错现象策略跑到某一天突然抛异常提示数组越界或 NaN。原因历史数据有停牌缺口或者日期没排序。解决导入数据后先做完整性检查按日期排序、去重、补缺失交易日策略里对len(closes)做足判断。5.3 数据库锁死导致回测卡住现象多策略同时跑时程序卡住不动。原因SQLite 写锁只允许一个写操作并发回测会互相等。解决回测阶段把数据读进内存不频繁写库或者换 MySQL每个策略用独立连接。5.4 时间戳时区不一致导致信号错位现象明明当天该出的信号第二天才触发。原因行情时间是 UTC策略按本地时间比较。解决全链路统一时区入库前转成同一时区策略里不要混用 naive 和 aware 时间。5.5 实盘接口和模拟接口行为不一致现象模拟盘成交正常接实盘后订单被拒。原因实盘有最小交易单位、涨跌停、可用资金冻结等规则模拟盘没模拟。解决在trader/层加一层校验把最小手数、涨跌停价、冻结资金都补上让模拟和实盘走同一套风控。6. 二次开发把自有策略接进框架并验证的三个动作这套源码的价值不在它自带的均线策略而在你能否把自己的想法快速接进去、快速证伪。我一般分三步走先写一个最小策略跑通链路再用样本外数据验证最后把参数和风控抽出来做成可配置。下面用一个动量策略举例。第一步新建strategy/momentum.py只实现on_bar逻辑尽量简单# strategy/momentum.py class Momentum(BaseStrategy): def on_init(self): self.window self.params.get(window, 20) self.threshold self.params.get(threshold, 0.05) def on_bar(self, bar): closes self.ctx.history(close, self.window 1) if len(closes) self.window 1: return ret closes[-1] / closes[0] - 1 # 窗口内涨幅 if ret self.threshold and not self.ctx.position: self.buy(bar.close, self.ctx.max_volume()) elif ret -self.threshold and self.ctx.position: self.sell(bar.close, self.ctx.position)window是回看周期threshold是触发阈值。参数不写死从命令行或配置传入方便后面批量调参。第二步样本外验证。把数据切成训练段和验证段训练段调参验证段只看不调。命令上可以用--start和--end分段跑对比两段的最大回撤和胜率。如果训练段好、验证段崩说明过拟合回去简化逻辑或加风控。第三步把风控抽出来。在engine/risk.py里加单笔最大仓位、单日最大亏损、连续亏损熔断。这些规则不写在策略里因为策略只管信号风控是全局的。改完之后用同一组参数重跑看收益曲线是否更平滑。改造点改哪里验证方法新策略strategy/新增文件跑通回测看交易次数调参数命令行或config/训练段/验证段对比加风控engine/risk.py看最大回撤是否下降换数据源data/loader.py检查日期连续性和字段从那以后我每次接新策略都强制先跑一遍最小链路确认数据、撮合、账户三块没问题再往里加逻辑。这套源码的结构刚好支持这种节奏策略插拔、引擎不动、风控独立。你要是手里有想法不妨先把它跑起来再按上面的路子改一版自己的策略比空想靠谱得多。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?