输入/搜索内容
入门
平台基础
编写策略
开发工具
回测系统
进阶专题
数据与研究
扩展API接口
AI接入
创建ApiKey
验证方式
扩展API接口详解
GetAccount
GetNodeList
DeleteNode
GetExchangeList
GetPlatformList
GetStrategyList
GetRobotGroupList
GetRobotList
GetRobotDetail
GetRobotLogs
NewRobot
RestartRobot
StopRobot
CommandRobot
DeleteRobot
PluginRun
pub
扩展API接口返回码
实盘状态码

把一条消息推送到运行中实盘订阅的频道,供平台外部的系统(TradingView 的 Webhook 告警、自建交易系统、监控脚本等)向实盘发送数据。实盘用GetChannelData读取,频道机制见策略实盘间通信。

与其它方法不同,pub不需要API KEY,也不签名:请求地址是https://www.fmz.com/api/v1?method=pub&robot={robotId}&channel={channel},消息放在请求体中(POST)。知道实盘Id和频道名的任何人都能推送,所以频道名要用难以猜到的随机字符串,策略也要把收到的内容当作不可信的输入来校验。

示例

接收端策略:订阅频道,把收到的JSON消息解析出来,并用id区分新旧消息。

javascript
// 接收端实盘(假设实盘Id为123456) var CHANNEL = "6BC42A119B5DBFA2188A8279DA3B5C30" function main() { var lastId = null while (true) { var msg = GetChannelData(CHANNEL) // 第一次调用即订阅,返回null if (typeof msg == "string") { var obj = null try { obj = JSON.parse(msg) // 请求体是JSON文本时再解析一次 } catch (e) { Log("非JSON消息:", msg) } if (obj && obj.id != lastId) { // 频道只保存最新一条,用id判断是否是新消息 lastId = obj.id Log("收到外部消息:", obj) } } Sleep(1000) } }
python
import json CHANNEL = "6BC42A119B5DBFA2188A8279DA3B5C30" def main(): lastId = None while True: msg = GetChannelData(CHANNEL) # 第一次调用即订阅,返回None if isinstance(msg, str): try: obj = json.loads(msg) # 请求体是JSON文本时再解析一次 except ValueError: obj = None Log("非JSON消息:", msg) if isinstance(obj, dict) and obj.get("id") != lastId: lastId = obj.get("id") Log("收到外部消息:", obj) Sleep(1000)

返回值

类型描述

object

推送成功时code为0,data字段见下方属性表;没有实盘订阅该频道(或频道名不合规、robot为空)时,HTTP状态码为500,code为5。

参数

名称类型必填描述

robot

number

是

接收消息的实盘Id(URL参数)。该实盘必须正在运行,并且已经订阅了channel频道。

channel

string

是

频道名(URL参数),建议用32位随机字符串(UUID去掉连字符)。不能是纯数字(纯数字会被当作实盘Id,即实盘自己的频道);少于10个字符的频道名不会投递。

message

string

否

消息内容。POST请求时取整个请求体,可以是JSON、普通文本等任意文本;不是POST时取URL参数message。

属性

名称类型描述

data.status

string

推送成功时为ok。

data.robot

number

本次请求的robot参数。

data.channel

string

本次请求的channel参数。

data.message

string

本次推送的消息。

data.affected

number

收到消息的托管者数量。

备注

投递规则
  • 先订阅、后推送:实盘第一次调用GetChannelData(channel)即订阅该频道(返回空值),订阅随托管者心跳上报,稍等片刻后外部系统才能推送成功。没有实盘订阅时请求失败。
  • 消息投递到robot实盘所在的托管者,该托管者上所有订阅了同一频道的实盘都会收到;其它托管者上的实盘收不到。
  • 频道只保存最新一条消息,不排队:GetChannelData()每次返回最近收到的一条,读取不会清除它。需要区分新旧消息时,在消息中带上递增的编号或时间戳。
  • 每个实盘最多订阅10个频道(含其它实盘的频道),超出时GetChannelData()返回空值并记录错误日志channel subscriber exceed limit。
  • 实盘收到的是字符串(请求体原文)。请求体是JSON文本时,策略需要自己再解析一次。

推送请求示例

外部系统推送一条消息:

bash
curl -X POST \ "https://www.fmz.com/api/v1?method=pub&robot=123456&channel=6BC42A119B5DBFA2188A8279DA3B5C30" \ -d '{"id": 1, "action": "buy", "symbol": "BTC_USDT"}'

在TradingView中使用时,把上面的URL填入告警的Webhook地址,告警消息内容就是请求体。

返回示例
json
{ "code": 0, "data": { "status": "ok", "robot": 123456, "channel": "6BC42A119B5DBFA2188A8279DA3B5C30", "message": "{\"id\": 1, \"action\": \"buy\", \"symbol\": \"BTC_USDT\"}", "affected": 1 } }

没有实盘订阅该频道时:

json
{ "code": 5, "error": "No subscribers for channel: 6BC42A119B5DBFA2188A8279DA3B5C30", "data": null }