输入/搜索内容
入门
欢迎使用发明者量化交易平台
快速开始
密钥安全性
平台基础
账号与计费
实盘计费与充值
子账号
交易所
通用协议
本地凭据文件
交易所特殊说明
证券与期货
加密货币
托管者
策略库
实盘
编写策略
开发工具
回测系统
进阶专题
数据与研究
对外接口

请求格式

向https://www.fmz.com/api/v1发送POST请求,参数以表单(application/x-www-form-urlencoded)提交。服务端也接受把同样的参数放在URL查询串中的GET请求,但参数会留在各处的访问日志里,推荐使用POST。

参数说明
version版本号,固定为1.0。
access_keyAPI KEY的AccessKey。
method调用的方法名,例如GetNodeList。
args方法参数组成的JSON字符串:按顺序排列的数组(如[]、[123, "ok"]),或按参数名传值的对象(如{"robotId": 123}),见扩展API接口详解。不传时按[]处理。
nonce毫秒时间戳。与服务器时间相差不能超过1小时,并且必须大于这把API KEY上一次请求使用的nonce。
sign签名,计算方法见下文。

请求中不包含SecretKey。

签名方式

按下面的格式拼接字符串,其中args是实际提交的JSON字符串原文:

plaintext
version + "|" + method + "|" + args + "|" + nonce + "|" + secretKey

对拼接结果计算MD5,转换为32位小写十六进制字符串,作为sign的值。

Python示例

python
import hashlib import json import time import urllib.parse import urllib.request ACCESS_KEY = '' # API KEY 的 AccessKey SECRET_KEY = '' # API KEY 的 SecretKey def api(method, *args, **kwargs): d = { 'version': '1.0', 'access_key': ACCESS_KEY, 'method': method, # 位置参数传数组,关键字参数传对象(按参数名传值) 'args': json.dumps(kwargs if kwargs else list(args)), 'nonce': int(time.time() * 1000), } s = '%s|%s|%s|%d|%s' % (d['version'], d['method'], d['args'], d['nonce'], SECRET_KEY) d['sign'] = hashlib.md5(s.encode('utf-8')).hexdigest() body = urllib.parse.urlencode(d).encode('utf-8') with urllib.request.urlopen('https://www.fmz.com/api/v1', body, timeout=10) as resp: return json.loads(resp.read().decode('utf-8')) print(api('GetNodeList')) # 托管者列表 print(api('GetRobotList', appId='member2')) # 按参数名传值:标签为 member2 的实盘 print(api('CommandRobot', 123, 'ok')) # 向实盘 123 发送交互命令 print(api('GetRobotDetail', 123)) # 实盘 123 的详细信息

Go示例

mylang
package main import ( "crypto/md5" "encoding/hex" "encoding/json" "fmt" "io" "net/http" "net/url" "strconv" "time" ) const ( accessKey = "" // API KEY 的 AccessKey secretKey = "" // API KEY 的 SecretKey baseAPI = "https://www.fmz.com/api/v1" ) var client = &http.Client{Timeout: 10 * time.Second} func api(method string, args ...interface{}) (string, error) { if args == nil { args = []interface{}{} } b, err := json.Marshal(args) if err != nil { return "", err } nonce := strconv.FormatInt(time.Now().UnixMilli(), 10) sum := md5.Sum([]byte("1.0|" + method + "|" + string(b) + "|" + nonce + "|" + secretKey)) form := url.Values{ "version": {"1.0"}, "access_key": {accessKey}, "method": {method}, "args": {string(b)}, "nonce": {nonce}, "sign": {hex.EncodeToString(sum[:])}, } resp, err := client.PostForm(baseAPI, form) if err != nil { return "", err } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) return string(body), err } func main() { ret, err := api("GetNodeList") fmt.Println(ret, err) // 用新的配置重启实盘 123,settings 字段见「扩展API接口详解」中的实盘配置说明 settings := map[string]interface{}{ "name": "hedge test", "strategy": 456, "period": 60, "node": 789, "exchanges": []interface{}{ map[string]interface{}{"pid": 1001, "pair": "BTC_USDT"}, }, } ret, err = api("RestartRobot", 123, settings) fmt.Println(ret, err) }