每一步:
1. 交易所每秒钟生成成千上万笔行情(最新价、成交量、买卖挂单……)
2. CTP行情服务�?/strong>把这些数据打包好,等着你的程序�?订阅"(就像你订阅了一个公众号,有新文章就推送给你)
3. 你的程序说:"给我螺纹�?505的行情,我要实时看�?
4. CTP服务�?/strong>收到你的订阅请求后,每有新的螺纹钢行情,就往下推一条数据给�?/p>
5. 你的程序收到数据,处理——比如打印出来、存下来、画�?/p>
这里面有一个关键概念:CTP�?推�?模式,不是你"拉取"模式�?/strong> 什么意思?你不用每隔一秒去�?现在价格多少了?"。你只需要说一�?我要看螺纹钢行情",之后行情来了服务器会自动推给你�?/p>
就像你不用每隔五分钟去查快递到哪了,快递到了自然会发短信�?/p>
好,理论讲完了。动手�?/p>
上一个测试程序连上了CTP就立刻断开了,因为它只验证"能不能连"。这一集的程序不一样——连上之后,它要赖着不走,持续接收行情�?/p>
创建文件
二、写出你第一�?看得见行�?的程�?/h2>
get_market_data.py,把下面的代码复制进去:import time
from ctpbee import CtpBee
from ctpbee.constant import TickData, BarData, OrderData, TradeData, PositionData
from ctpbee.constant import Direction, Offset, Exchange, Status, OrderType
创建应用实例
app = CtpBee("my_first_strategy", "market_data")
============ 你的账户信息 ============
把这四个值换成你自己的SimNow账户
BROKER_ID = "9999" # 经纪公司代码
USER_ID = "你的SimNow账号" # 改成你的
PASSWORD = "你的密码" # 改成你的
TD_ADDRESS = "tcp://180.168.146.187:10130" # 交易前置地址
MD_ADDRESS = "tcp://180.168.146.187:10131" # 行情前置地址
====================================
config = {
"CONNECT_INFO": {
"brokerid": BROKER_ID,
"userid": USER_ID,
"password": PASSWORD,
"td_address": TD_ADDRESS,
"md_address": MD_ADDRESS,
}
}
app.config.from_mapping(config)
============================================
核心:收到行情的时候,你想做什么?
============================================
@app.route(handler="on_tick")
def on_tick(tick):
"""
每次收到一笔行情(Tick),这个函数就会自动被调用�? tick 是一�?TickData 对象,里面装着最新的一笔行情数据�? """
# 只打印:品种、最新价、成交量、时�? print(
f"📊 {tick.symbol} | "
f"最新价: {tick.last_price:.2f} | "
f"成交�? {tick.volume} | "
f"时间: {tick.datetime}"
)
============ 启动 ============
if __name__ == "__main__":
print("🔌 正在连接CTP行情...")
print(f" 行情地址: {MD_ADDRESS}")
print(f" 交易地址: {TD_ADDRESS}")
print(f" 用户�? {USER_ID}")
print("-" * 50)
app.start()
print("�?连接成功,正在接收行�?..")
print(" �?Ctrl+C 可以停止程序")
print("=" * 50)
try:
# 让程序一直跑着,接收行�? while True:
time.sleep(1)
except KeyboardInterrupt:
print("\n\n🛑 程序已停止�?)
app.release()
别复制过去就跑了。每一行是什么意思,咱们过一遍�?/p>
from ctpbee import CtpBee
from ctpbee.constant import TickData, BarData, OrderData, TradeData, PositionData
from ctpbee.constant import Direction, Offset, Exchange, Status, OrderType
from ctpbee import CtpBee �?把CTP工具箱搬进来。CtpBee这个类是你的"总控制器",通过它你能做所有CTP操作�?/p>
下面那两行导入了一堆常量和数据类型。你现在不需要全懂。只需要知�?TickData �?一笔行情数�?的类型,后面函数的参数要声明它�?/p>
app = CtpBee("my_first_strategy", "market_data")
"my_first_strategy" 是你的策略名字(随便取)�?code>"market_data" 是你的应用名(也随便取)。这俩名字只是用来区分不同的程序,你改什么都可以�?/p>
BROKER_ID = "9999"
USER_ID = "你的SimNow账号"
PASSWORD = "你的密码"
TD_ADDRESS = "tcp://180.168.146.187:10130"
MD_ADDRESS = "tcp://180.168.146.187:10131"
五个变量,每个都很好理解�?/p>
注意这两个地址是不一样的——td和md分开的。很多新手会把它们写反,导致能连上但收不到行情(或者反过来)。查不出问题,抓耳挠腮一个小时,最后发现是地址写错了�?/p>
你现在知道了,就不踩这个坑�?/p>
@app.route(handler="on_tick")
def on_tick(tick):
print(
f"📊 {tick.symbol} | "
f"最新价: {tick.last_price:.2f} | "
f"成交�? {tick.volume} | "
f"时间: {tick.datetime}"
)
这是整个程序的心脏。拆开看:
@app.route(handler="on_tick") �?这是一�?注册"操作。你在告诉ctpbee�?嘿,当有新行情到来的时候,调用下面这个函数�?
这里�?on_tick 是ctpbee规定的一个事件名。当CTP服务器推送一笔行情给你时,ctpbee会自动触发这个事件,然后执行你写�?on_tick 函数�?/p>
你不需要主动调用这个函数�?strong>系统会替你调用�?/strong>
tick 是什么?
tick 是一笔行情数据的完整快照。它的各个字段:
| 字段 | 含义 | 示例 |
tick.symbol | 合约代码 | rb2505(螺纹钢2505�?/td> |
tick.last_price | 最新成交价 | 3789.00 |
tick.volume | 当日累计成交�?/td> | 152340 |
tick.open_interest | 持仓�?/td> | 523400 |
tick.bid_price_1 | 买一�?/td> | 3788.00 |
tick.ask_price_1 | 卖一�?/td> | 3789.00 |
tick.datetime | 行情时间 | 2026-06-06 09:00:01 |
比你看交易软件上那个报价还详细。因为这里面不只是最新价�?strong>买卖五档的挂单、成交量、持仓量全有�?/strong>
后面的策略里,你判断要不要下单,就是看这些字段�?/p>
app.start()
while True:
time.sleep(1)
app.start() 是启动。程序连上CTP,登录,确认结算,然后开始接收行情�?/p>
while True: time.sleep(1) 是一�?死循�?——让程序一直跑着,别退出。后面那�?except KeyboardInterrupt 是当你按 Ctrl+C 的时候,程序优雅地关闭�?/p>
把代码保存为 get_market_data.py,打开命令行,进入文件所在目录,敲:
python get_market_data.py
你会看到�?/p>
🔌 正在连接CTP行情...
行情地址: tcp://180.168.146.187:10131
交易地址: tcp://180.168.146.187:10130
用户�? 你的SimNow账号
--------------------------------------------------
�?连接成功,正在接收行�?..
�?Ctrl+C 可以停止程序
==================================================
📊 rb2505 | 最新价: 3789.00 | 成交�? 152340 | 时间: 2026-06-06 09:00:01
📊 rb2505 | 最新价: 3788.00 | 成交�? 152342 | 时间: 2026-06-06 09:00:02
📊 rb2505 | 最新价: 3791.00 | 成交�? 152345 | 时间: 2026-06-06 09:00:02
📊 rb2505 | 最新价: 3790.00 | 成交�? 152348 | 时间: 2026-06-06 09:00:03
...
恭喜。你的程序现在长着眼睛了�?/p>
从这一刻起,期货市场里发生的每一笔成交,你的程序都看得到。比你肉眼盯盘快几百倍,比你手动刷新软件准确得多�?/p>
——这就是程序化交易的第一块砖。后面的所有东西——下单、止损、策略逻辑、回测、AI辅助——都是在这块砖上垒起来的�?/p>
ConnectionRefusedError: [WinError 10061] 连接被拒�?
可能原因�?/strong>
CTP: 用户当前状态为:未授权
可能原因�?/strong>
CTP: 合约不存�?
可能原因�?/strong>
代码里没有指定品种,你的程序默认可能只订阅了一个合约。没关系,这一集的目标�?收到行情",能收到就行。下一集会教你怎么指定要哪个品种的行情�?/p>
1. 行情数据的流动路�?/strong>:交易所 �?CTP �?你的程序
2. CTP是推送模�?/strong>:你不用反复问,行情自己�?/p>
3. 4. 5. 实际跑通了第一个能接收行情的程�?/strong> �?集会非常刺激�?/p>
你现在眼睛能看见了。下一步是什么? 手�?/strong> �?集:写你的第一个交易策略�?/strong> �?思路"�?完整代码",用程序下第一笔单�?/p>
你会写一个真实的策略——比�?价格突破昨天高点就买�?——然后看着你的程序自动下单、成交、持仓。不再是只看行情,而是真正�?做交�?�?/p>
明天见�?/p>
*本系列面向零基础读者。有疑问加微�?futures886 或在评论区留言�? 果子量化 - AI驱动的期货程序化交易平台 官网�?a href="https://gocxh.com">gocxh.com | 微信:futures886on_tick 是行情入�?/strong>:每次有新行情,系统自动调用这个函数tick 对象里有你需要的所有数�?/strong>:最新价、成交量、持仓、买卖五�?/p>
下一集预�?/h2>