$npx -y skills add algoderiv/agent-skills --skill tqsdkTianQin SDK (tqsdk) - Python量化交易框架,用于期货/期权/股票交易策略开发、回测与实盘交易
| 1 | # TqSdk 开发指南 |
| 2 | |
| 3 | TqSdk 是由信易科技开发的开源 Python 量化交易库,基于快期交易及行情服务器体系,支持期货、期权、股票的行情获取、策略开发、回测与实盘交易。 |
| 4 | |
| 5 | ## 何时使用本技能 |
| 6 | |
| 7 | 当用户需要以下内容时触发: |
| 8 | - 使用 TqSdk 编写量化交易策略 |
| 9 | - 获取期货/期权/股票实时行情、K线、Tick 数据 |
| 10 | - 进行策略回测(支持 Tick 级和 K 线级) |
| 11 | - 配置实盘交易、模拟交易账户 |
| 12 | - 使用 TargetPosTask 进行目标持仓交易 |
| 13 | - 使用技术指标(ta/tafunc)进行策略分析 |
| 14 | - 使用算法交易模块(TWAP/VWAP) |
| 15 | - 调试 TqSdk 异步编程模型相关问题 |
| 16 | |
| 17 | ## 安装 |
| 18 | |
| 19 | ```bash |
| 20 | # 安装/升级 |
| 21 | pip install tqsdk -U |
| 22 | |
| 23 | # 国内镜像(推荐) |
| 24 | pip install tqsdk -U -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host=pypi.tuna.tsinghua.edu.cn |
| 25 | ``` |
| 26 | |
| 27 | **环境要求:** Python 3, Windows 7+ / macOS / Linux |
| 28 | **注意:** TqSdk 使用 asyncio,部分 IDE(如 Spyder)不支持。推荐使用 VS Code、Cursor、Trae 等支持 asyncio 的 IDE。 |
| 29 | |
| 30 | ## 核心概念 |
| 31 | |
| 32 | ### 编程模型 |
| 33 | |
| 34 | TqSdk 使用**单线程异步模型**,核心循环为: |
| 35 | |
| 36 | ```python |
| 37 | from tqsdk import TqApi, TqAuth |
| 38 | |
| 39 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) |
| 40 | |
| 41 | # 1. 获取数据引用对象 |
| 42 | quote = api.get_quote("SHFE.rb2401") |
| 43 | klines = api.get_kline_serial("SHFE.rb2401", 60) |
| 44 | |
| 45 | # 2. 在循环中等待数据更新 |
| 46 | while True: |
| 47 | api.wait_update() |
| 48 | # 3. 使用 is_changing() 判断哪个对象更新了 |
| 49 | if api.is_changing(quote): |
| 50 | print(f"最新价: {quote.last_price}") |
| 51 | if api.is_changing(klines): |
| 52 | print(f"最新K线收盘价: {klines.close.iloc[-1]}") |
| 53 | |
| 54 | api.close() |
| 55 | ``` |
| 56 | |
| 57 | **关键要点:** |
| 58 | - `get_quote()`、`get_kline_serial()` 等返回的是**引用对象**,值在 `wait_update()` 时自动更新 |
| 59 | - 每个引用对象只需调用一次获取函数 |
| 60 | - `wait_update()` 是阻塞函数,收到数据包才返回 |
| 61 | - `is_changing()` 判断指定对象在最近一次 `wait_update` 中是否被更新 |
| 62 | |
| 63 | ### 合约代码格式 |
| 64 | |
| 65 | 格式:`交易所代码.合约代码`(大小写敏感) |
| 66 | |
| 67 | ```python |
| 68 | # 期货合约 |
| 69 | "SHFE.cu2401" # 上期所铜 |
| 70 | "DCE.m2401" # 大商所豆粕 |
| 71 | "CZCE.SR401" # 郑商所白糖(注意:郑商所字母大写,三位数字) |
| 72 | "CFFEX.IF2401" # 中金所沪深300股指 |
| 73 | "INE.sc2401" # 上期能源原油 |
| 74 | "GFEX.si2401" # 广期所工业硅 |
| 75 | |
| 76 | # 期权合约 |
| 77 | "DCE.m2401-C-3500" # 大商所豆粕看涨期权 |
| 78 | "SHFE.au2404C480" # 上期所黄金看涨期权 |
| 79 | "CFFEX.IO2402-C-4000" # 中金所沪深300股指期权 |
| 80 | |
| 81 | # 主连/指数 |
| 82 | "KQ.m@CFFEX.IF" # 中金所IF主连合约 |
| 83 | "KQ.i@SHFE.bu" # 上期所沥青指数 |
| 84 | |
| 85 | # 外盘 |
| 86 | "KQD.m@CBOT.ZS" # 美黄豆主连 |
| 87 | |
| 88 | # 跨期组合 |
| 89 | "CZCE.SPD SR401&SR403" # 郑商所跨期 |
| 90 | "DCE.SP a2409&a2501" # 大商所跨期 |
| 91 | |
| 92 | # 股票(专业版) |
| 93 | "SSE.600000" # 上交所浦发银行 |
| 94 | "SZSE.000001" # 深交所平安银行 |
| 95 | ``` |
| 96 | |
| 97 | ## 账户类型 |
| 98 | |
| 99 | ### 模拟交易(免费) |
| 100 | |
| 101 | ```python |
| 102 | from tqsdk import TqApi, TqAuth |
| 103 | |
| 104 | # 临时模拟账户(程序结束后数据丢失) |
| 105 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) |
| 106 | |
| 107 | # 指定初始资金的模拟账户 |
| 108 | from tqsdk import TqSim |
| 109 | api = TqApi(TqSim(init_balance=100000), auth=TqAuth("快期账户", "账户密码")) |
| 110 | ``` |
| 111 | |
| 112 | ### 快期模拟交易(持久化) |
| 113 | |
| 114 | ```python |
| 115 | from tqsdk import TqApi, TqKq, TqAuth |
| 116 | # 快期模拟账户,数据持久保存,与快期APP互通 |
| 117 | api = TqApi(TqKq(), auth=TqAuth("快期账户", "账户密码")) |
| 118 | ``` |
| 119 | |
| 120 | ### 实盘交易(专业版) |
| 121 | |
| 122 | ```python |
| 123 | from tqsdk import TqApi, TqAccount, TqAuth |
| 124 | api = TqApi(TqAccount("H海通期货", "账号", "密码"), auth=TqAuth("快期账户", "账户密码")) |
| 125 | ``` |
| 126 | |
| 127 | ### 直连 CTP |
| 128 | |
| 129 | ```python |
| 130 | from tqsdk import TqApi, TqCtp, TqAuth |
| 131 | api = TqApi(TqCtp("tcp://180.168.xxx:41205", "tcp://180.168.xxx:41205", "账号", "密码"), |
| 132 | auth=TqAuth("快期账户", "账户密码")) |
| 133 | ``` |
| 134 | |
| 135 | ### 多账户 |
| 136 | |
| 137 | ```python |
| 138 | from tqsdk import TqApi, TqMultiAccount, TqAccount, TqSim, TqAuth |
| 139 | api = TqApi(TqMultiAccount([TqAccount("H海通期货", "账号1", "密码1"), TqSim()]), |
| 140 | auth=TqAuth("快期账户", "账户密码")) |
| 141 | ``` |
| 142 | |
| 143 | ## 行情数据 |
| 144 | |
| 145 | ### 实时行情 |
| 146 | |
| 147 | ```python |
| 148 | quote = api.get_quote("SHFE.cu2401") |
| 149 | # 主要字段: |
| 150 | # quote.last_price 最新价 |
| 151 | # quote.bid_price1 买一价 |
| 152 | # quote.ask_price1 卖一价 |
| 153 | # quote.volume 成交量 |
| 154 | # quote.open_interest 持仓量 |
| 155 | # quote.upper_limit 涨停价 |
| 156 | # quote.lower_limit 跌停价 |
| 157 | # quote.volume_multiple 合约乘数 |
| 158 | # quote.price_tick 最小变动价位 |
| 159 | ``` |
| 160 | |
| 161 | ### K线数据 |
| 162 | |
| 163 | ```python |
| 164 | # K线周期以秒数表示,最多获取最后 8000 根 |
| 165 | klines = api.get_kline_serial("SHFE.cu2401", 60) # 1分钟线 |
| 166 | klines = api.get_kline_serial("SHFE.cu2401", 60*60) # 1小时线 |
| 167 | klines = api.get_kline_serial("SHFE.cu2401", 60*60*24) # 日线 |
| 168 | klines = api.get_kline_serial("SHFE.cu2401", 10) # 10秒线 |
| 169 | |
| 170 | # klines 是 pandas.DataFrame,包含列: |
| 171 | # datetime, open, high, low, close, volume, open_oi, close_oi |
| 172 | |
| 173 | # 常见用法 |
| 174 | print(klines.close.iloc[-1]) # 最新K线收盘价 |
| 175 | ma = klines.close.rolling(20).mean() # 20周期均线 |
| 176 | print(klines.close.iloc[-3:]) # 最近3根K线收盘价 |
| 177 | |
| 178 | # 检测新K线 |
| 179 | while True: |
| 180 | api.wait_update() |
| 181 | if api.is_changing(klines.iloc[-1], "datetime"): |
| 182 | print("新K线产生") |
| 183 | ``` |
| 184 | |
| 185 | ### Tick 数据 |
| 186 | |
| 187 | ```python |
| 188 | ticks = api.get_tick_serial("SHFE.cu2401") |
| 189 | # 返回 pandas.DataFrame,包含 datetime, last_price, volume 等列 |
| 190 | ``` |
| 191 | |
| 192 | ## 交易操作 |
| 193 | |
| 194 | ### 下单/撤单 |
| 195 | |
| 196 | ```python |
| 197 | # 限价单 |
| 198 | order = api.insert_order("SHFE.rb2401", "BUY", "OPEN", volume=3, limit_price=4000) |
| 199 | |
| 200 | # 市价单 |
| 201 | order = api.insert_order("SHFE.rb2401", "BUY", "OPEN", volume=3) |
| 202 | |
| 203 | # 等待成交 |
| 204 | while order.status != "FINISHED": |
| 205 | api.wait_update() |
| 206 | |
| 207 | # 撤单 |
| 208 | api.cancel_order(order) |
| 209 | |
| 210 | # 查看委托单状态 |
| 211 | # order.status: ALIVE(活跃)/ FINISHED(完成) |
| 212 | # order.volume_orign: 委托手数 |
| 213 | # order.volume_left: 未成交手数 |
| 214 | ``` |
| 215 | |
| 216 | ### 账户与持仓查询 |
| 217 | |
| 218 | ```python |
| 219 | # 账户资金 |
| 220 | account = api.get_account() |
| 221 | print(account.balance) # 账户权益 |
| 222 | print(account.available) # 可用资金 |
| 223 | |
| 224 | # 持仓查询 |
| 225 | position = api.get_position("SHFE.rb2401") |
| 226 | print(position.pos_long) # 多头持仓 |
| 227 | print(position.pos_short) # 空头持仓 |
| 228 | ``` |
| 229 | |
| 230 | ### TargetPosTask 目标持仓 |
| 231 | |
| 232 | 自动管理下单撤单,调整到目标仓位: |
| 233 | |
| 234 | ```python |
| 235 | from tqsdk import TqApi, TqAuth, TargetPosTask |
| 236 | |
| 237 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) |
| 238 | target_pos = TargetPosTask(api, "SHFE.rb2401") |
| 239 | |
| 240 | # 设置目标持仓 |
| 241 | target_pos.set_target_volume(5) # 多头5手 |
| 242 | target_pos.set_target_volume(-3) # 空头3手 |
| 243 | target_pos.set_target_volume(0) # 平仓 |
| 244 | |
| 245 | # 价格模式 |
| 246 | target_p |