富途证券
通过富途的FutuOpenD网关交易港股、美股、A股(A股通)和期货,支持实盘与模拟交易。需要运行托管者能访问到的FutuOpenD(交易所配置中的服务器地址,默认为本机127.0.0.1:11111)。牛牛号在FutuOpenD中登录,交易所配置只填FutuOpenD地址和富途交易密码;FutuOpenD需要关闭RSA加密(托管者按明文协议与它通信)。配置交易所对象、运行FutuOpenD等操作参看富途证券配置说明文档。
名称与配置
exchange.GetName():Futures_Futu(证券与期货);别名:Futu。
| 配置项 | 必填 | 默认值 | 说明 |
|---|---|---|---|
| 服务器地址 | 是 | 127.0.0.1:11111 | FutuOpenD监听的IP和端口,例如127.0.0.1:11111。 |
| 交易密码 | 是 | — | 富途交易密码,用于解锁交易、访问账户信息。 |
| 模拟盘 | 否 | 不勾选 | — |
交易对与合约代码
交易对示例:00700.HK、AAPL.US、600519.SH
品种代码格式为代码.市场,用exchange.SetContractType()(或exchange.SetCurrency())设置,整段代码作为当前品种。市场后缀:HK港股、US美股、SH沪市、SZ深市、SG新加坡期货、JP日本期货。查询、撤单、改单也接受旧写法HK.00700。exchange.GetMarkets()只列出本策略已经设置过的品种。
专属IO指令
| 指令 | 参数 | 说明 | 返回值 |
|---|---|---|---|
refresh | bool | 交易类查询(GetOrder、GetOrders、GetPositions、GetAccount、GetAssets)是否刷新OpenD缓存,默认刷新;传false后使用缓存,不传参数时不做改动。(详见表下) | — |
accounts | — | 获取富途返回的全部交易账户列表(原始数据,也包括与实盘/模拟盘设置不匹配、不被使用的账户)。 | — |
lock | — | 锁定交易。 | 成功返回空值。 |
unlock | — | 用配置的交易密码解锁交易。交易类请求遇到富途要求解锁时也会自动解锁一次再重试,一般不需要手动调用。 | 成功返回空值。 |
instrument | symbol | 获取品种静态信息,例如exchange.IO("instrument", "00700.HK");查询过的品种会出现在exchange.GetMarkets()中。 | {instrument, InstrumentID, InstrumentName, VolumeMultiple, IsTrading, SecType, info, ...},VolumeMultiple为每手数量(期权、期货为合约乘数),info为富途静态信息原文(JSON字符串)。 |
timeout | number | 设置与OpenD通信的超时时间(毫秒),默认20000,取值限制在100到600000之间。 | {"ok": true, "timeout": 实际生效的毫秒数} |
statusDetail | — | 获取连接状态详情。与FutuOpenD的连接在第一次请求时建立,此前connected为false。 | {"connected":..., "server":..., "simulate":...} |
historyKlines | object | 按时间范围获取历史K线(富途历史K线接口,有额度限制),参数{symbol, interval, begin, end, limit}:symbol必填(不会自动使用当前品种);interval单位为秒,只能是exchange.GetRecords()的原生周期;begin、end为YYYY-MM-DD格式的日期,缺省为最近7天加上interval×limit的时长到明天;limit为每页条数(最多1000,缺省1000),会自动翻页取完整个范围。(详见表下) | K线数组,每项{time, open, high, low, close, volume}(小写字段,time为毫秒时间戳)。 |
status | — | 固定返回true(兼容旧版),连接状态请用statusDetail。 | — |
wait | [number] | 兼容旧版的探针:富途连接器没有行情和订单推送,不等待,固定返回true。 | — |
表中长说明的其余部分:
refresh:刷新缓存的查询受富途频率限制(每30秒最多10次)。historyKlines:K线为前复权。
通用指令base、currency见exchange.IO。
不支持通用指令api(调用时报错并返回空值)。
常用用法
查看富途返回的全部交易账户,手动解锁、锁定交易
javascript
function main() {
// 原始账户行:trdEnv 0模拟、1真实;accStatus 0可用
exchange.IO("accounts").forEach(function (a) {
Log("账户:", a.accID, "trdEnv:", a.trdEnv, "accType:", a.accType,
"accStatus:", a.accStatus, "市场权限:", a.trdMarketAuthList)
})
// 交易请求遇到需要解锁时会自动解锁一次,一般不用手动调用;成功、失败都返回空值
exchange.IO("unlock")
var err = GetLastError()
Log(err ? "解锁失败: " + err : "已解锁")
// ... 交易 ...
exchange.IO("lock")
}
按日期范围获取历史K线
javascript
function main() {
// symbol 必填;interval 为秒,只能是原生周期;超过 limit 条时自动翻页
var bars = exchange.IO("historyKlines", {
symbol: "00700.HK", interval: 86400, begin: "2026-01-01", end: "2026-06-30"
})
if (!bars) {
Log("获取失败:", GetLastError())
return
}
Log("共", bars.length, "根")
bars.slice(-3).forEach(function (b) {
Log(_D(b.time), "开:", b.open, "高:", b.high, "低:", b.low, "收:", b.close, "量:", b.volume)
})
}
查询品种的静态信息(每手股数、证券类型)
javascript
function main() {
var r = exchange.IO("instrument", "00700.HK")
Log(r.InstrumentName, "每手股数:", r.VolumeMultiple, "SecType:", r.SecType,
"未退市:", r.IsTrading)
var basic = JSON.parse(r.info) // 富途静态信息原文
Log("上市日期:", basic.listTime)
// 查询过的品种会出现在 GetMarkets 中
Log(Object.keys(exchange.GetMarkets()))
}
检查与FutuOpenD的连接,调整超时,高频轮询时改读缓存
javascript
function main() {
// status、wait 是兼容旧版的探针,固定返回 true,不能用来判断连接
Log(exchange.IO("status"), exchange.IO("wait"))
exchange.SetContractType("00700.HK") // 向 FutuOpenD 查询品种,此时建立连接
var d = exchange.IO("statusDetail")
Log("已连接:", d.connected, "FutuOpenD:", d.server, "模拟盘:", d.simulate)
Log("超时(毫秒):", exchange.IO("timeout", 60000).timeout)
// 交易类查询改读 FutuOpenD 的缓存,不受每30秒10次的刷新限制
exchange.IO("refresh", false)
while (true) {
var pos = exchange.GetPositions()
Log("持仓数:", pos ? pos.length : GetLastError())
Sleep(1000)
}
}
函数支持差异
不支持(调用时报错并返回空值):exchange.GetFundings、exchange.SetMarginLevel、exchange.CreateConditionOrder、exchange.ModifyConditionOrder、exchange.CancelConditionOrder。
以回退方式支持:
exchange.GetRecords:原生周期为1分钟、3分钟、5分钟、15分钟、30分钟、1小时、1天、1周、1月;其它周期由托管者合成。exchange.GetConditionOrder:没有单独查询条件单的接口,在该品种当前的条件单和最近90天的历史条件单(最多100条)中查找。条件单是用下单函数的选项对象指定orderType(10到15)下的富途原生订单,见注意事项。
保证金、账户与模拟盘
账户:富途用TrdMarket区分市场(1香港、2美国、3大陆、4香港A股通、5期货)。exchange.GetAccount()的Balance、FrozenBalance、Equity、UPnL取当前品种所在市场的币种(例如00700.HK为HKD,未设置带市场后缀的品种时为香港市场),Stocks、FrozenStocks为0;Info中有accounts(交易账户列表)和funds(各市场的trdMarket、currency与资金明细)。exchange.GetAssets()按币种汇总所有已授权市场的资金。实盘使用融资(Margin)账户、模拟盘使用现金(Cash)账户,只使用状态正常且有市场权限的账户;没有匹配的账户时报错并列出可用账户。
模拟盘:勾选「模拟盘」接入富途模拟交易。通过FutuOpenD接入模拟交易时,有些股票代码不支持,因而无法交易(富途牛牛手机App上可以模拟交易)。
注意事项
- 不支持
exchange.IO("api", ...)。 exchange.SetDirection()、exchange.Buy()/exchange.Sell()、exchange.CancelOrder()、exchange.ModifyOrder()、exchange.GetOrder()等交易函数的用法与期货市场相同。- 富途下单只有买入、卖出两个方向,没有开平仓标志:
closebuy(平多)按卖出提交,closesell(平空)按买入提交,股票与期货相同。为避免平仓单在没有持仓时开出反向仓位,托管者提交平仓单前先查询该品种的持仓:没有对应方向的持仓、可平数量(持有数量减去冻结数量)小于下单数量,或持仓查询失败时,不下单、报错并返回空值。期货持仓按具体月份合约记录,用主连代码平仓会因查不到持仓而被拒绝。同一品种不能同时持有多头和空头。查询到的订单不区分开平,Offset按开仓给出(富途回报为「买回」的订单除外)。 - 交易类查询默认每次都向富途服务端刷新,受富途频率限制(每30秒最多10次),超过会报错;高频轮询时用
exchange.IO("refresh", false)改为使用FutuOpenD的缓存,FutuOpenD收到新数据时自动更新缓存。 FutuOpenD按登录的IP地址区分地区,非大陆IP登录的账户获取行情时有所限制,具体查阅富途官方文档。- 交易所对象配置的交易对不是
代码.市场形式(例如00700)时,exchange.GetCurrency()返回配置的值,exchange.GetContractType()返回空字符串,表示还没有设置品种;需要先调用exchange.SetContractType("00700.HK"),否则不传品种的行情、交易函数报错并返回空值。 exchange.GetDepth()订阅富途的买卖盘(摆盘)后返回最多10档,订阅会占用富途的订阅额度。没有买卖盘权限、订阅额度用完,或盘口没有档位(收盘、停牌)时,退回快照里的买一、卖一,这时Info中source为snapshot,orderBookError写明原因。- 下单数量是股数(期货、期权为张数),不是金额,市价买单也一样;价格传
-1或0时按富途市价单提交。限价单实盘默认GTC(一直有效)、模拟盘默认当日有效,市价单当日有效;不支持ioc、fok和postOnly。下单默认允许在全部交易时段(含盘前盘后)成交。 - 富途专属下单参数通过下单函数最后的选项对象传入,原样交给富途:
orderType(Trd_Common.OrderType数值,10止损市价、11止损限价、12触及市价、13触及限价、14跟踪止损市价、15跟踪止损限价)、auxPrice(触发价)、trailType、trailValue、trailSpread、timeInForce(0当日有效、1一直有效)、session、fillOutsideRTH、adjustPrice、adjustSideAndLimit、remark、trdSide(直接指定方向数值,指定后不做平仓前的持仓检查)。用orderType下的条件单与普通订单在同一个订单列表里:exchange.GetOrders()、exchange.GetConditionOrders()都能查到,用exchange.CancelOrder()撤销。 exchange.ModifyOrder()原地修改限价单的价格和数量,订单号不变;只改其中一项时另一项沿用原单;市价单不能修改。exchange.GetOrders()、exchange.GetPositions()不传品种时返回所有已授权市场的全部挂单、持仓。exchange.GetHistoryOrders()只返回已完结的订单,不传品种时查全部品种,不传起始时间时查最近90天,结果按时间升序,指定条数时保留最近的若干条。exchange.GetTickers()不传参数时返回本策略已设置或查询过的品种的行情。exchange.GetRecords()每次最多1000根,K线为前复权;exchange.GetTrades()默认100条、最多1000条。exchange.GetMarkets()中股票的CtVal为1(每手股数见Info中的lotSize),期权、期货的CtVal为合约乘数。TickSize为当前价位的最小价格变动(港股价位分档,随价格变化)。