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

2.1 使用API 获取账户信息、 获取行情数据、 获取K线数据、 获取市场深度信息

Author: 发明者量化-小小梦, Created: 2016-11-05 16:41:04, Updated: 2019-08-01 09:31:23

2.1 使用API 获取账户信息、 获取行情数据、 获取K线数据、 获取市场深度信息

终于到了第二章了,通过前面一章的游览,应该对于 发明者量化 的各个功能有一定的了解。接下来开始写代码啦!


  • 使用API 获取账户信息

    假设通过第一章的游览已经添加好了托管者、交易所,当然我们可以使用 发明者量化 模拟盘进行代码测试。

    首先我们先创建一个策略,就叫测试1吧 img

    策略编辑界面 img img

    代码如下:

function main() {
    Log(exchange.GetAccount()); // 看过API 文档后知道, exchange就是交易所对象,实际上策略有个全局变量
                                // exchanges 数组,这个数组存放的就是你创建机器人或者回测时添加的交易所(可以是多个)
                                // 添加1个交易所 exchanges 数组就只包含1个交易所对象,即添加的交易所对象。
                                // 那么 exchange 和 exchanges 是什么关系呢? 其实 exchange 就是 exchanges[0] ,
                                // exchange 就是 exchanges 数组的第一个元素(这里这个元素是交易所对象)。
                                
                                // Log()函数应该也不陌生吧,这个API 就是输出一条日志,日志内容就是Log括号里面的参数。
}

创建一个机器人 也叫 测试1 绑定名称为 “测试1”的策略,用 发明者量化 模拟盘测试一下。 img img

策略瞬间运行完成,显示了一条账户信息。 img

显示出来了,我们去和模拟盘的账户信息对比下。 img

  • 获取行情数据

function main() {
    Log(exchange.GetAccount()); // 已经知道怎么获取 主交易所 账户信息了
    //下面我们来试试 不停的获取行情数据。 
    while(true){ // 这里用一个无限循环的结构来不停的获取 交易所行情数据。
        Log("行情数据:", exchange.GetTicker()); // 哇! Log() 函数的括号里面可以写2个参数,第一个参数是: "行情数据:"
                                               // 第二个参数是 exchange.GetTicker() 这个函数的返回值。就是主交易所的行情数据。
                                               // 注意 Log() 函数的参数要用 逗号分隔。
        Sleep(1000);   // 咦~ 这个又是什么? 答:机器人程序 执行循环也需要休息!它可是执行很快的哦!(一秒N次)
                       // Sleep 函数的作用就是让程序暂停一会儿,括号里面的参数 1000 是 毫秒数, 1秒 = 1000毫秒。Sleep(1000);就是暂停1000毫秒。
                       // 不要小看这个参数,这个参数控制了程序的轮询频率,间接影响访问 交易所API 的频率,有些交易所API访问过于频繁可是会拒绝访问的。
    }
}

img 注: 可能有同学会发现GetTicker 函数获取的数据最高价和最低价差很多,这讲下,GetTicker 返回的行情数据的High,Low 是交易所约定的周期内的最高、最低价,具体是看交易所设定。上面测试的是 发明者量化 模拟盘, 发明者量化 模拟盘设定的是模拟盘开始运行到此刻的最高价、最低价。

  • 获取K线数据

    我们先看下API文档的描述:
GetRecords(Period)	返回一个K线历史, K线周期在创建机器人时指定, Record数组结构
不加参数, 默认返回添加机器人时时指量的K线周期, 但也可以自定义K线周期
支持: PERIOD_M1 指1分钟, PERIOD_M5 指5分钟, PERIOD_M15 指15分钟, PERIOD_M30 指30分钟, PERIOD_H1 指1小时, PERIOD_D1 指一天

我们写一段代码测试一下 获取默认周期(5分钟)的K线数据。

function main() {
    Log(exchange.GetAccount()); // 已经知道怎么获取 主交易所 账户信息了
    //下面我们来试试 不停的获取行情数据。 
    var records = exchanges[0].GetRecords();  // 按照默认周期获取K线数据
    Log("records:", records);  // 在日志中输出 获取到的K线数据。
}

显示输出: records: [{“Time”:1478260200000,“Open”:4765.14,“High”:4773,“Low”:4764.54,“Close”:4769.47,“Volume”:5211.539999999999}, {“Time”:1478260500000,“Open”:4769.47,“High”:4773.01,“Low”:4764,“Close”:4764.78,“Volume”:3742.250000000002}, {“Time”:1478260800000,“Open”:4764.78,“High”:4782,“Low”:4764,“Close”:4781.28,“Volume”:7929.090000000004}, {“Time”:1478261100000,“Open”:4781.28,“High”:4795,“Low”:4774,“Close”:4792.02,“Volume”:11793.540000000006}, {“Time”:1478261400000,“Open”:4792.02,“High”:4792.96,“Low”:4781,“Close”:4786.78,“Volume”:9204.90000000001}, {“Time”:1478261700000,“Open”:4786.51,“High”:4788.66,“Low”:4775,“Close”:4775.31,“Volume”:7722.3399999999965}]

可以看出 变量 records 是一个 结构数组, 是按照K线时间顺序 从远(索引0)到近(索引records.length - 1)顺序排列。 我们顺便了解一下K线:(有些图表是红色代表阳线,绿色代表阴线,有些则是相反颜色表示。) img 看下平台的5分钟为周期的K线示例图表。 img 注意: 一个K线周期完成后,其数值才是确定的。在实际运用中我们调用var records = exchanges[0].GetRecords(); 返回的数据records数组中的最后一个元素 即: records[records.length - 1] ,在其周期完成之前是不停变动的。甚至有可能在最后一秒,由阳线变阴线。

GetRecords 函数在不加参数时是按照策略设置的默认周期返回数据。也可以传入参数来指定K线的周期。目前回测系统已经支持GetRecords传入参数来指定周期(不加参数按照默认周期返回数据),使得策略回测时能同时使用不同周期。

  • 获取市场深度信息

    GetDepth 返回一个Depth结构
function main() {
    var depth = exchanges[0].GetDepth();   //获取市场深度信息,  返回订单薄信息,一个对象包含2个属性,每个属性是一个对象数组。
    Log("depth:", depth);    // 日志中输出,一下的输出是 整理过的格式,是方便读者理解,实际上是所有内容都在一行显示的。
}

以上代码回测显示如下:

depth: 
{"Asks":[{"Price":4726.07,"Amount":15},   // 卖单数组,回测时,数据都是模拟出来的,所以Amount 都是 15,索引为0的是卖一,依次类推。
         {"Price":4726.08,"Amount":15},
         {"Price":4726.09,"Amount":15},
         {"Price":4726.1,"Amount":15},
         {"Price":4726.11,"Amount":15},
         {"Price":4726.12,"Amount":15},
         {"Price":4726.13,"Amount":15},
         {"Price":4726.14,"Amount":15},
         {"Price":4726.15,"Amount":15},
         {"Price":4726.16,"Amount":15},
         {"Price":4726.17,"Amount":15}],
"Bids":[{"Price":4726.05,"Amount":15},   //  买单数组,索引为0的是买一, 向后依次类推。
        {"Price":4726.04,"Amount":15},
        {"Price":4726.03,"Amount":15},
        {"Price":4726.02,"Amount":15},
        {"Price":4726.01,"Amount":15},
        {"Price":4726,"Amount":15},
        {"Price":4725.99,"Amount":15},
        {"Price":4725.98,"Amount":15},
        {"Price":4725.97,"Amount":15},
        {"Price":4725.96,"Amount":15},
        {"Price":4725.95,"Amount":15}]
}

对应的订单薄 是这样的(这里是OKCoin的真实数据)。实际过程中市场深度信息(订单薄)是变化很快的,有兴趣的同学可以注册OKCoin,然后登录看一下。

img

有了市场深度信息(盘口数据)怎么用呢? 盘口数据是有很多用途的,举个例子比如吃单(当然也有挂单)。

function main() {    
    var depth = exchanges[0].GetDepth();    // 获取市场深度
    Log("depth:", depth);                   // 日志输出显示
    Log(exchanges[0].GetAccount());         // 输出 吃单前的 账户信息
    var buyPrice = depth.Asks[0].Price;     // 设置吃卖单的价格,即卖一,
                                            // 有时为确保吃单成功,这样处理:var buyPrice = depth.Asks[0].Price + slidePrice;
    var buyAmount = depth.Asks[0].Amount;   // 吃卖单的量
    exchanges[0].Buy(buyPrice, buyAmount);  // 执行买入操作, 吃掉卖一 这个单子
    Log(exchanges[0].GetAccount());         // 显示买入后的  账户信息,对比初始账户信息。可以对比出 买入操作的成交的数量。
}

在 发明者量化 模拟盘运行的结果: img


More

flydog 补充一下问题的发现之二,我选择美国公用托管者后,机器人列表里面没有了那个警示符号,但是运行后,已然是日志里面没人输出任何信息,提示没有日志信息

flydog 补充一下问题的发现:在机器人列表里面,状态是“红上三角号里有个感叹号”,好像是异常提示。

flydog 小小梦,你好,我在用平台模拟测试的,第一步测试账户信息,没有日志输出,提示错误,不知道问题出在哪里?(在策略栏中编写回测没有问题,但是放到机器人里面就不行 了,请指教,谢谢) 机器人测试代码: function main() { Log(exchange.GetAccount()); Log("test"); } 结果: 测试1 策略: 测试1 (最后更新 2018-09-13 14:25:33) 日期: 创建于 2018-09-13 14:07:57 最近开始于 2018-09-13 14:40:24 停止于 2018-09-13 14:40:25 状态: K线周期 1分钟 有错误 托管于 中国 : 42.236.82.38 - linux/amd64 (公用), ID: 118025 交易平台: BotVS/BTC_USD

flydog 小小梦,你好,我在用平台模拟测试的,第一步测试账户信息,没有日志输出,提示错误,不知道问题出在哪里?(在策略栏中编写回测没有问题,但是放到机器人里面就不行 了,请指教,谢谢) 机器人测试代码: function main() { Log(exchange.GetAccount()); Log("test"); } 结果: 测试1 策略: 测试1 (最后更新 2018-09-13 14:25:33) 日期: 创建于 2018-09-13 14:07:57 最近开始于 2018-09-13 14:40:24 停止于 2018-09-13 14:40:25 状态: K线周期 1分钟 有错误 托管于 中国 : 42.236.82.38 - linux/amd64 (公用), ID: 118025 交易平台: BotVS/BTC_USD

hokshelato 模拟的时候调用 `exchange.GetTicker()`,经常会出现 **GetTicker: timeout**,请问是为什么?

dyhhu 你好,实盘仿真的数据用的是那个交易所的实盘数据?

bijiasuo xuexizhong

shandianliyu 请问 exchange.GetDepth() 返回的是当前交易所的全部挂单信息吗?会不会因为挂单太多,而只返回一部分数据?

maohbao GetRecords(Period) 返回一个K线历史,但是这个K线历史数据包含多少个K线bar,这个在哪里指定?

pengliheng 好吧,我密匙错了,已改正

pengliheng GetAccount: 签名不匹配 怎么弄,梦哥哥

Andy2simple 为什么模拟盘depth的amount都是15? 模拟盘是拿的过去的数据,还是随机生成的数据?如果是过去的数据,amount是可以有值的。

cjz140 record是一个函数,length是什么?depth是一个对象?对象和函数如何区分?比如depth(Asks(price,amount)),这里的depth是对象,asks是数组?price和amount是属性?

FangBei slidePrice 是什么?

发明者量化-小小梦 好的 如果还有问题 可以加QQ 官方群 @管理员

flydog 谢谢这么多的回复,我按照提示,再试一试

发明者量化-小小梦 不知道是不是 公共托管者的问题,您可以用私有托管者 测试下 ,私有托管者应该是 可以的, 您在自己电脑上部署一个 就行。

发明者量化-小小梦 您用 自己的私有托管者 试下。

发明者量化-小小梦 这个可能要具体看下 策略 是什么样的执行逻辑,也可能 策略正常运行 , 只是 没有触发任何操作。

发明者量化-小小梦 有红色叹号 是机器人运行 报错,需要检查下机器人日志,或者 托管者 日志 信息。

发明者量化-小小梦 最近网络问题,另外 在 模拟盘 行情没有更新的时候 是 超时的,可以 使用 exchange.IO("mode") 调整 行情获取 模式。

发明者量化-小小梦 实盘仿真 是一个 24小时运行的 仿真模拟盘, 是跟随几个 主流交易所 的行情 走的,所有 使用 模拟盘的用户都是 这个仿真盘的参与者,行情不会和 参考的交易所 完全一致,但是大概走势是一致的。

shandianliyu 好的,这下明白,多谢了

发明者量化-小小梦 实盘级别回测 ,买卖1档 是真实数据。

shandianliyu 非常感谢。另外请问一下, 在模拟回测的实盘级仿真时,exchange.GetDepth() 返回的是BotVS拟合的数据还是真实历史数据?根据返回的情况来看,不太像真实历史数据。

发明者量化-小小梦 返回的档数 具体多少 看交易所 API 接口提供, 有些交易所 返回的多些有的少些,并且有的交易所 接口支持 深度 合并,有的没有支持,具体还是看交易所实现的,BotVS 封装的是默认返回数据,如果想直接调用, 可以使用 exchange.IO 函数 ,设定参数 调用(这个函数免签名,详见 API 文档)。

发明者量化-小小梦 这个不能指定 , 返回多少条K线 是交易所 具体推送的, 各个交易所 可能 推送的数量不一样,另外一些交易所 没有提供 K线接口,托管者 会自行收集 交易所的交易记录,生成K线,这个K线就是 从第一根 开始 累积的。

发明者量化-小小梦 ^^ 最开始 我也老弄错~

发明者量化-小小梦 好的, 我们考虑下,这个问题主要有2点: - 1、深度数据量太庞大,每秒都在变化,而且是很快的速度变化,我们看到的实际盘口 也仅仅是切片数据。 - 2、即使 做出实际深度数据,但是 因为 此时此刻回测 中参与者仅仅是我们自己, 并没有其他参与者,还是无法准确模拟出订单薄深度环境。其实和目前的回测系统差别不大。 不过我们会考虑尽量优化贴近真实情况的, 感谢提出建议 ^^

Andy2simple 深度数据是还没有发生的,价格曲线都是过去发生的。个人认为过去和将来的数据共同判决当前的买卖才更靠谱。强烈建议把深度数据也记录下来。

发明者量化-小小梦 深度数据 量太大了 如果全部记录 ,会非常多的。所以 深度数据 除了第一档 其他都是 模拟数值。

发明者量化-小小梦 records 是一个 变量, 用来接收 API 函数 GetRecords 返回的 K线数据, length 是 JS 语言中 数组类型变量的 长度属性,代表数组长度(即其中元素个数),depth 类似 records 也是一个变量 用来接收 GetDepth 函数返回的深度数据,这些 records、depth、ticker 的 数据结构在 API 文档 可以找到。

发明者量化-小小梦 滑价,翻译的有点直白,就是为了吃单 加的一点点价格,更容易成交。