资源加载中... loading...

验证方式

调用扩展API接口时有两种验证方式,支持token验证和直接验证。

token验证

使用md5加密方式验证,PythonGolang语言调用例子:

#!/usr/bin/python
# -*- coding: utf-8 -*-
import time
import json
import ssl
ssl._create_default_https_context = ssl._create_unverified_context

try:
    import md5
    import urllib2
    from urllib import urlencode
except:
    import hashlib as md5
    import urllib.request as urllib2
    from urllib.parse import urlencode

accessKey = ''   # your API KEY
secretKey = ''   

def api(method, *args):
    d = {
        'version': '1.0',
        'access_key': accessKey,
        'method': method,
        'args': json.dumps(list(args)),
        'nonce': int(time.time() * 1000),
        }

    d['sign'] = md5.md5(('%s|%s|%s|%d|%s' % (d['version'], d['method'], d['args'], d['nonce'], secretKey)).encode('utf-8')).hexdigest()
    # 注意: urllib2.urlopen 函数,超时问题,可以设置超时时间,urllib2.urlopen('https://www.fmz.com/api/v1', urlencode(d).encode('utf-8'), timeout=10) 设置超时 10秒
    return json.loads(urllib2.urlopen('https://www.fmz.com/api/v1', urlencode(d).encode('utf-8')).read().decode('utf-8'))

# 返回托管者列表
print(api('GetNodeList'))
# 返回交易所列表
print(api('GetPlatformList'))
# GetRobotList(offset, length, robotStatus, label),传-1代表获取全部
print(api('GetRobotList', 0, 5, -1, 'member2'))
# CommandRobot(robotId, cmd)向实盘发送命令
print(api('CommandRobot', 123, 'ok'))
# StopRobot(robotId)返回实盘状态代码
print(api('StopRobot', 123))  
# RestartRobot(robotId)返回实盘状态代码
print(api('RestartRobot', 123))
# GetRobotDetail(robotId)返回实盘详细信息
print(api('GetRobotDetail', 123))
package main

import (
    "fmt"
    "time"
    "encoding/json"
    "crypto/md5"
    "encoding/hex"
    "net/http"
    "io/ioutil"
    "strconv"
    "net/url"
)

// 填写自己的FMZ平台api key
var apiKey string = ""                                  
// 填写自己的FMZ平台secret key
var secretKey string = ""                               
var baseApi string = "https://www.fmz.com/api/v1"

func api(method string, args ... interface{}) (ret interface{}) {
    // 处理args
    jsonStr, err := json.Marshal(args)
    if err != nil {
        panic(err)
    }

    params := map[string]string{
        "version" : "1.0", 
        "access_key" : apiKey,
        "method" : method,
        "args" : string(jsonStr),
        "nonce" : strconv.FormatInt(time.Now().UnixNano() / 1e6, 10),
    }    

    data := fmt.Sprintf("%s|%s|%s|%v|%s", params["version"], params["method"], params["args"], params["nonce"], secretKey)
    h := md5.New()
    h.Write([]byte(data))
    sign := h.Sum(nil)

    params["sign"] = hex.EncodeToString(sign)

    // http request 
    client := &http.Client{}

    // request 
    urlValue := url.Values{}
    for k, v := range params {
        urlValue.Add(k, v)
    }
    urlStr := urlValue.Encode()
    request, err := http.NewRequest("GET", baseApi + "?" + urlStr, nil)
    if err != nil {
        panic(err)
    }    

    resp, err := client.Do(request)
    if err != nil {
        panic(err)
    }

    defer resp.Body.Close()

    b, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }

    ret = string(b)
    return 
}

func main() {
    settings := map[string]interface{}{
        "name": "hedge test",
        "strategy": 104150,                      
        // K线周期参数,60即为60秒
        "period": 60,                           
        "node" : 73938,                         
        "appid": "member2",                
        "exchanges": []interface{}{
            map[string]interface{}{
                "eid": "Exchange", 
                "label" : "test_bjex", 
                "pair": "BTC_USDT", 
                "meta" : map[string]interface{}{
                    // 填写access key
                    "AccessKey": "",                                
                    // 填写secret key
                    "SecretKey": "",                                
                    "Front" : "http://127.0.0.1:6666/exchange",
                },
            },
        },
    }

    method := "RestartRobot"
    fmt.Println("调用接口:", method)
    ret := api(method, 124577, settings)
    fmt.Println("main ret:", ret)
}

直接验证

支持不使用token验证(直接传secret_key验证),可以生成一个用来直接访问的URL。例如直接给实盘发交互指令的URL,可以用于Trading View或其它场景的WebHook回调。对于扩展API接口CommandRobot()函数,不进行nonce校验,不限制该接口的访问频率、访问次数。

例如:创建的扩展API KEY中的AccessKey为:xxxSecretKey为:yyy。访问以下链接即可向实盘Id为186515的实盘发送交互指令消息,消息内容为字符串:"ok12345"

https://www.fmz.com/api/v1?access_key=xxx&secret_key=yyy&method=CommandRobot&args=[186515,"ok12345"]

支持直接验证方式下,获取请求中的Body数据,仅支持CommandRobot接口。例如在Trading ViewWebHook URL中设置:

https://www.fmz.com/api/v1?access_key=xxx&secret_key=yyy&method=CommandRobot&args=[186515,+""]

注意需要按照此格式设置:args=[186515,+""]186515是发明者量化交易平台的实盘Id。Trading View消息框中设置(要发送的请求中的Body数据):

  • JSON格式:

https://www.fmz.com![image](/upload/asset/16d8a37ef80d9ccd0079.png)

  {"close": {{close}}, "name": "aaa"}
- 文本格式:
  
  https://www.fmz.com![image](/upload/asset/16d8a506dfbb6c60a077.png)
  
  ```plaintext
  BTCUSDTPERP 穿过(Crossing) 39700.00 close: {{close}}

```Python```、```Golang```语言调用例子:

```python
#!/usr/bin/python
# -*- coding: utf-8 -*-

import json
import ssl

ssl._create_default_https_context = ssl._create_unverified_context

try:
    import urllib2
except:
    import urllib.request as urllib2

accessKey = 'your accessKey'
secretKey = 'your secretKey'

def api(method, *args):
    return json.loads(urllib2.urlopen(('https://www.fmz.com/api/v1?access_key=%s&secret_key=%s&method=%s&args=%s' % (accessKey, secretKey, method, json.dumps(list(args)))).replace(' ', '')).read().decode('utf-8'))

# 如果API KEY没有该接口权限,调用print(api('RestartRobot', 186515)) 会失败,返回数据:{'code': 4, 'data': None}
# print(api('RestartRobot', 186515))

# 打印Id为:186515的实盘详细信息
print(api('GetRobotDetail', 186515))
package main

import (
    "fmt"
    "encoding/json"
    "net/http"
    "io/ioutil"
    "net/url"
)

// 填写自己的FMZ平台api key
var apiKey string = "your access_key"

// 填写自己的FMZ平台secret key
var secretKey string = "your secret_key"
var baseApi string = "https://www.fmz.com/api/v1"

func api(method string, args ... interface{}) (ret interface{}) {
    jsonStr, err := json.Marshal(args)
    if err != nil {
        panic(err)
    }
    
    params := map[string]string{
        "access_key" : apiKey,
        "secret_key" : secretKey,
        "method" : method,
        "args" : string(jsonStr),
    }    

    // http request 
    client := &http.Client{}

    // request 
    urlValue := url.Values{}
    for k, v := range params {
        urlValue.Add(k, v)
    }
    urlStr := urlValue.Encode()
    request, err := http.NewRequest("GET", baseApi + "?" + urlStr, nil)
    if err != nil {
        panic(err)
    }    

    resp, err := client.Do(request)
    if err != nil {
        panic(err)
    }

    defer resp.Body.Close()

    b, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }

    ret = string(b)
    return 
}

func main() {
    method := "GetRobotDetail"
    fmt.Println("调用接口:", method)
    ret := api(method, 186515)
    fmt.Println("main ret:", ret)
}

使用发明者量化交易平台扩展API实现TradingView报警信号交易 使用发明者量化交易平台扩展API实现TradingView报警信号交易,B站视频链接

实盘状态码 扩展API接口详解