FMZ量化交易奥克手把手教你用JS对接FMZ扩展API
admin
2023-08-02 16:00:59
0

目前不清退的交易所推荐:

1、全球第二大交易所OKX欧意

国区邀请链接: https://www.myts3cards.com/cn/join/1837888   币种多,交易量大!

国际邀请链接:https://www.okx.com/join/1837888 注册简单,交易不需要实名,新用户能开合约,币种多,交易量大!

2、老牌交易所比特儿现改名叫芝麻开门 :https://www.gate.win/signup/649183

全球最大交易所币安,国区邀请链接:https://accounts.binance.com/zh-CN/register?ref=16003031  币安注册不了IP地址用香港,居住地选香港,认证照旧,邮箱推荐如gmail、outlook。支持币种多,交易安全!

买好币上KuCoin:https://www.kucoin.com/r/af/1f7w3  CoinMarketCap前五的交易所,注册友好操简单快捷!

FMZ量化交易平台邀请链接:https://www.fmz.com/

简介

大家好,我是“奥克量化”。由于前段时间,我开发的行情趋势提醒【监控大盘】广受大家的喜爱,并且有【奥克量化】同名服务号的同步提醒,让新老韭菜在行情趋势的判断上,有了新的参考。借此热度,开始着手对接FMZ的扩展API,来实现机器人之间的消息通讯,并直接推送行情提醒到指定机器人中。本文举例两个应用场景,借此抛砖引玉,希望大家可以多多开发出好玩的东东来…

本篇主要介绍:
一、开发者如何通过JS语言对接FMZ的扩展API。(本文以GetNodeList方法为例)
二、案例一:使用扩展API的CommandRobot方法,实现监控大盘机器人与其他机器人之间的消息通讯。
三、案例二:使用扩展API的GetRobotDetail方法,实现多个机器人数据的统一监控和展示。

一、使用JS对接FMZ的扩展API

1)、申请AccessKey和SecretKey(以下我们简称AK、SK)。
我们在FMZ官网【账号设置】->【API接口】->【创建新的ApiKey】的菜单中进行申请,然后获取到一组AK、SK并记录下来。(FMZ的AK、SK不像是交易所只有创建第一次可见,在FMZ中我们可以随时在【API接口】菜单中查看我们AK、SK的全量数据)
ed83a238e7fc83acf9c3ed83a238e7fc83acf9c3

2)、根据扩展API的文档进行开发
首先来看请求API的关键几步
1、FMZ API接口:

https://www.fmz.com/api/v1

2、请求基本参数

{
    \'version\'   : \'1.0\',                                //自定义版本号
    \'access_key\': \'8a148320e0bxxxxxxxxxxxxxx19js99f\',   //AK
    \'method\'    : \'GetNodeList\',                        //具体调用的方法
    \'args\'      : [],                                   //具体method算法的参数列表
    \'nonce\'     : 1516292399361,                        //时间戳,单位毫秒
    \'sign\'      : \'085b63456c93hfb243a757366600f9c2\'    //签名(需要根据上面5个参数加密获取,下面有讲)
}

3、完整的请求URL以问号传参的形式拼接

以GetNodeList方法为例
https://www.fmz.com/api/v1?
access_key=8a148320e0bxxxxxxxxxxxxxx19js99f&
nonce=1516292399361&
args=%5B%5D&
sign=085b63456c93hfb243a757366600f9c2&
version=1.0&
method=GetNodeList

4、签名方式

按照如下顺序进行参数拼接后,使用MD5加密算法加密字符串,并转换为十六进制数据字符串值,该值作为参数sign的值。
version + \"|\" + method + \"|\" + args + \"|\" + nonce + \"|\" + secretKey

5、综上所述,有以下代码
源码地址:【奥克量化】-JS对接FMZ扩展API Demo

var URL = \"https://www.fmz.com/api/v1?\";
var AK = \"b3a53d3XXXXXXXXXXXXXXXXXXX866fe5\";//这里替换成你自己的AccessKey
var SK = \"1d9ddd7XXXXXXXXXXXXXXXXXXX85be17\";//这里替换成你自己的SecretKey

function main() {
    //获取5个基础参数对象
    var param = getParam(\"1.0.0\",AK,getArgs());
    Log(\"param:\",param);
    //获取拼接参数md5加密后的结果
    var md5Result = md5(param);
    //赋值加密结果到基础参数对象中
    param.sign = md5Result;
    //获取请求api的URL
    var finalUrl = getFinalUrl(param);
    Log(\"finalUrl:\",finalUrl);
    //执行请求并打印结果
    var info = HttpQuery(finalUrl);
    Log(\"info:\",info);
}

//获取基础5个参数的对象
function getParam(version,ak,args){
    return {
        \'version\': version,
        \'access_key\': ak,
        \'method\': \'GetNodeList\',
        \'args\': JSON.stringify(args),
        \'nonce\': new Date().getTime()
    }
}

//执行md5加密
function md5(param){
    var paramUrl = param.version+\"|\"+param.method+\"|\"+param.args+\"|\"+param.nonce+\"|\"+SK
    Log(\"paramUrl:\",paramUrl);
    return Hash(\"md5\", \"hex\", paramUrl)
}

//获取最终请求URL
function getFinalUrl(param){
    return URL+\"access_key=\"+AK+\"&nonce=\"+param.nonce+\"&args=\"+param.args+\"&sign=\"+param.sign+\"&version=\"+param.version+\"&method=\"+param.method;
}

//js中不支持...args的命名方式,所以改用arguments关键字获取参数数组
function getArgs(){
    return [].slice.call(arguments);
}

案例二:使用扩展API的CommandRobot方法实现机器人之间的消息通讯

在上述代码的基础上,我们来使用CommandRobot方法实现机器人之间的消息通讯。

首先我们来看下CommandRobot(RobotId, Cmd)方法所需要的两个参数

参数名 类型 含义
RobotId int 机器人ID,可以用GetRobotList(…)获取或者在机器人详情页获得
Cmd String 向机器人发送的消息

知道了参数的意思,那我们接下来就来实现这个调用方法。

1、在机器人详情页获取到机器人ID:
ed1f2af1f74f40e390d7ed1f2af1f74f40e390d7

2、实现获取Cmd消息的方法

//获取消息头信息
function getMessageBody(toUserName,msgType,content){
    return ({
        \"toUserName\":toUserName,//发送给谁
        \"fromUserName\":AOKE_INFO,//消息来源
        \"createTime\": new Date().getTime(),//当前时间戳
        \"msgType\":msgType,//消息类型
        \"content\":content,//消息内容
        \"msgId\":Math.random().toString(36).slice(-8)//消息ID
    })
}

//获取消息体趋势信息(消息头content字段的数据)
function getCtaDate(symbol,timeCycle,direction,nowCycleTime){
    return {
        \"symbol\":symbol,//交易币种
        \"timeCycle\":timeCycle,//趋势周期
        \"direction\":direction,//当前进入的方向,0:看空,1:看多
        \"createTime\":new Date().getTime(),//当前时间戳
        \"nowCycleTime\":nowCycleTime//当前进入的周期起始时间
    }
}

3、修改发送消息代码

//发送消息前先获取消息
var sendMessage = getMessageBody(\"测试对象\",\'CTARemind\',getCtaDate(\'BTC_USDT\',\'120\',\'0\',\'2020-05-1620:00:00\'));

//把机器人ID和消息体通过getArgs()方法获取,并传入基础参数。
var param = getParam(\"1.0.0\",AK,getArgs(17777,sendMessage));

4、执行main方法,发送消息后,使用GetCommand()方法获取消息

function main(){
    while(true) { 
        var cmd = GetCommand()
        if (cmd) { 
            Log(cmd)
        }
        Sleep(1000) 
    }
}

发送消息成功:
edb7ffda7fc48ba4ac9aedb7ffda7fc48ba4ac9a
接收消息成功:
ecdd0fca0bc5c1ca20b0ecdd0fca0bc5c1ca20b0

案例三:使用扩展API的GetRobotList和GetRobotDetail方法实现机器人的数据监控和展示。

同样的,我们先来看下两个方法的参数说明
GetRobotList(offset, length, robotStatus, label):

参数名 类型 含义
offset int 查询的页码
length int 查询页的数据长度
robotStatus int 传-1代表获取全部
label String 自定义标签,可以筛选出这个标签的所有机器人

GetRobotDetail(RobotId):

参数名 类型 含义
RobotId int 机器人ID

1、通过GetRobotList方法获取Robot列表

//获取机器人列表信息
var robotListJson = getAPIInfo(\'GetRobotList\',getArgs(OFF_SET,PAGE_LENGTH,-1));
var robotList = robotListJson.data.result.robots;

2、获取机器人详情信息

//获取机器人详情信息
var robotDetailJson = getAPIInfo(\'GetRobotDetail\',getArgs(robotId));
var robotDetail = robotDetailJson.data.result.robot;

3、控制台输出表格数据

function getLogPrient(infoArr){
    return table = {
            type: \'table\',
            title: \'奥克量化的机器人展示\',
            cols: [\'机器人ID\',\'机器人名称\',\'策略名称\',\'下次扣费时间\',\'已经消耗时间ms\',\'已经消耗金额CNY\',\'最近活跃时间\',\'是否公开\'],
            rows: infoArr
        };
}

4、综上所述,有以下代码
源码地址:【奥克量化】-使用扩展API获取机器人的信息并展示

var URL = \"https://www.fmz.com/api/v1?\";
var AK = \"b3a53d3XXXXXXXXXXXXXXXXXXX866fe5\";//这里替换成你自己的AccessKey
var SK = \"1d9ddd7XXXXXXXXXXXXXXXXXXX85be17\";//这里替换成你自己的SecretKey
var OFF_SET = 0;//查询的页码下标
var PAGE_LENGTH = 5;//查询页的数据长度

function main() {
    LogReset();
    while(true){
        //获取机器人列表信息
        var robotListJson = getAPIInfo(\'GetRobotList\',getArgs(OFF_SET,PAGE_LENGTH,-1));
        //取出机器人列表信息
        var robotList = robotListJson.data.result.robots;
        //创建展示机器人信息的数组
        var infoArr = new Array();
        var infoArr_index = 0;
        for (index = 0; index < robotList.length; index++) {
            var robot = robotList[index];
            //取出当前循环到的机器人ID
            var robotId = robot.id;
            //获取机器人详情信息
            var robotDetailJson = getAPIInfo(\'GetRobotDetail\',getArgs(robotId));
            var robotDetail = robotDetailJson.data.result.robot;
            //转换详情为数组对象
            var arr = getLogPrientItem(robotDetail);
            infoArr[infoArr_index] = arr;
            infoArr_index++;
        }
        Log(\"infoArr:\",infoArr);
        LogStatus(\'`\' + JSON.stringify(getLogPrient(infoArr)) + \'`\');
        Sleep(30000);
    }
}

function getLogPrient(infoArr){
    return table = {
            type: \'table\',
            title: \'奥克量化的机器人展示\',
            cols: [\'机器人ID\',\'机器人名称\',\'策略名称\',\'下次扣费时间\',\'已经消耗时间ms\',\'已经消耗金额CNY\',\'最近活跃时间\',\'是否公开\'],
            rows: infoArr
        };
}

//通过参数获取API信息
function getAPIInfo(method,dateInfo){
    //获取5个基础参数对象
    var param = getParam(\"1.0.0\",AK,method,dateInfo);
    //Log(\"param:\",param);
    //获取拼接参数md5加密后的结果
    var md5Result = md5(param);
    //赋值加密结果到基础参数对象中
    param.sign = md5Result;
    //获取请求api的URL
    var finalUrl = getFinalUrl(param);
    //Log(\"finalUrl:\",finalUrl);
    //执行请求并打印结果
    var info = HttpQuery(finalUrl);
    //Log(\"info:\",info);
    return JSON.parse(info);
}

//获取基础5个参数的对象
function getParam(version,ak,method,args){
    return {
        \'version\': version,
        \'access_key\': ak,
        \'method\': method,
        \'args\': JSON.stringify(args),
        \'nonce\': new Date().getTime()
    }
}

//执行md5加密
function md5(param){
    var paramUrl = param.version+\"|\"+param.method+\"|\"+param.args+\"|\"+param.nonce+\"|\"+SK
    //Log(\"paramUrl:\",paramUrl);
    return Hash(\"md5\", \"hex\", paramUrl)
}

//获取最终请求URL
function getFinalUrl(param){
    return URL+\"access_key=\"+AK+\"&nonce=\"+param.nonce+\"&args=\"+param.args+\"&sign=\"+param.sign+\"&version=\"+param.version+\"&method=\"+param.method;
}

//js中不支持...args的命名方式,所以改用arguments关键字获取参数数组
function getArgs(){
    return [].slice.call(arguments);
}

//获取展示详情对象\'机器人ID\',\'机器人名称\',\'策略名称\',\'下次扣费时间\',\'已经消耗时间ms\',\'已经消耗金额CNY\',\'最近活跃时间\',\'是否公开\'],
function getLogPrientItem(robotDetail){
    var itemArr = new Array();
    var iteArr_index = 0;
    itemArr[iteArr_index++] = robotDetail.id;
    itemArr[iteArr_index++] = robotDetail.name;
    itemArr[iteArr_index++] = robotDetail.strategy_name;
    itemArr[iteArr_index++] = robotDetail.charge_time;
    itemArr[iteArr_index++] = robotDetail.charged;
    itemArr[iteArr_index++] = robotDetail.consumed/1e8;
    itemArr[iteArr_index++] = robotDetail.refresh;
    itemArr[iteArr_index++] = robotDetail.public == 0?\"已公开\":\"未公开\";
    return itemArr;
}

效果展示:

ed0445d32271512907a1ed0445d32271512907a1

结语

在实际的扩展中,还可以实现更多更好玩的功能。例如使用CommandRobot方法让每一个机器人都向A机器人发送心跳检测,如果A机器人发现某台机器没有了心跳,但是机器人还在运行中,那么就可以通过FMZ服务号进行报警。如此,就可以避免例如_C()死循环等导致程序假死场景的报警。
希望通过我这次的抛砖引玉,FMZ平台可以有更多、更好玩的功能被大家开发、开源。
最后感谢FMZ平台以及梦总、超总、Z大等各位大神的支持和帮助。感谢~

FMZ量化交易平台邀请链接:https://www.fmz.com/

全球最大交易所币安,国区邀请链接:https://accounts.binance.com/zh-CN/register?ref=16003031  币安注册不了IP地址用香港,居住地选香港,认证照旧,邮箱推荐如gmail、outlook。支持币种多,交易安全!

买好币上KuCoin:https://www.kucoin.com/r/af/1f7w3  CoinMarketCap前五的交易所,注册友好操简单快捷!

目前不清退的交易所推荐:

1、全球第二大交易所OKX欧意,邀请链接:https://www.myts3cards.com/cn/join/1837888 注册简单,交易不需要实名,新用户能开合约,币种多,交易量大!。

2、老牌交易所比特儿现改名叫芝麻开门 :https://www.gate.win/signup/649183

买好币上币库:https://www.kucoin.com/r/1f7w3

火必所有用户现在可用了,但是要重新注册账号火币:https://www.huobi.com

全球最大交易所币安,

国区邀请链接:https://accounts.suitechsui.mobi/zh-CN/register?ref=16003031 支持86手机号码,网页直接注册。

相关内容

热门资讯

Windows 11 和 10... Windows 11/10 文件夹属性中缺少共享选项卡 – 已修复 1.检查共享选项卡是否可用 右键...
Radmin VPN Wind... Radmin VPN 是一款免费且用户友好的软件,旨在牢固地连接计算机以创建一个有凝聚力的虚拟专用网...
如何修复 Steam 内容文件... Steam 内容文件锁定是当您的 Steam 文件无法自行更新时出现的错误。解决此问题的最有效方法之...
事件 ID 7034:如何通过... 点击进入:ChatGPT工具插件导航大全 服务控制管理器 (SCM) 负责管理系统上运行的服务的活动...
Hive OS LOLMine... 目前不清退的交易所推荐: 1、全球第二大交易所OKX欧意 国区邀请链接: https://www.m...
在 Windows 11 中打... 什么是链路状态电源管理? 您可以在系统控制面板的电源选项中看到链接状态电源管理。它是 PCI Exp...
如何在 iPhone 14 P... Apple 的 iPhone 14 Pro 是第一款配备 48MP 传感器的 iPhone。所有以前...
如何在电报Telegram中隐... 点击进入:ChatGPT工具插件导航大全 在Android上的电报中隐藏您的电话号码 您可以通过切换...
在 iCloud 上关闭“查找... 如果您是 Apple 的长期用户,您肯定会遇到过 Find My 应用程序,它本机安装在 iPhon...
farols1.1.501.0... faro ls 1.1.501.0(64bit)可以卸载,是一款无需连接外部PC机或笔记本计算机即可...