Type/to search
8
Follow
1372
Followers
2.4 获取订单信息、取消订单、获取所有未完成的订单信息
Tutorials
Created 2016-11-08 17:04:56  Updated 2017-10-11 10:20:06
 20
 5831

获取订单信息、取消订单、获取所有未完成的订单信息


  • GetOrder 、 GetOrders 、 CancelOrder 函数的使用

    本节我们来实现两个 自定义的函数 CancelPendingOrders 和 StripOrders 来实现取消所有未完成的挂单,以此学习这几个API 。(其实在之前我们已经使用过。)首先看下订单的类型这2个宏定义。(有兴趣的同学可以打印看下。)
订单的类型:Order结构里的Type值 [ ORDER_TYPE_BUY :买单 ORDER_TYPE_SELL :卖单 ]
  • 自定义的 CancelPendingOrders 函数用到了GetOrders、CancelOrder(摘自数字货币交易类库): 取消所有未完成的挂单,可以指定类型。

    测试的源码:
var RetryDelay = 500; function CancelPendingOrders(e, orderType) { // 取消所有未完成的挂单, 参数1 是指定 取消哪个交易所的单子, // 参数2 是指取消的类型(可以只取消买单或者卖单) while (true) { // 循环 var orders = e.GetOrders(); // 根据参数指定的交易所对象 e , 调用API GetOrders // 获取该交易所 所有未完成的挂单。赋值给 变量 orders if (!orders) { // 如果出现异常错误 导致 API GetOrders 返回的 数据 是 null , // !null 为 真, 执行 if 分支(即if 后面大括号内的代码)。 Sleep(RetryDelay); // 暂停 RetryDelay(数值) 毫秒。 continue; // 忽略下面的代码,重新执行循环。 即:var orders = e.GetOrders(); // 并再次判断 !orders } var processed = 0; // 处理计数 for (var j = 0; j < orders.length; j++) { // 遍历 orders 变量(结构数组) if (typeof(orderType) === 'number' && orders[j].Type !== orderType) { // 如果 函数CancelPendingOrders 参数传入了 orderType, // 并且 orderType 不等于当前索引 orders[j]的Type属性。 符合这个条件即:当前的orders[j]不是要取消的单子。 continue; // 跳过一下,继续循环。 } e.CancelOrder(orders[j].Id, orders[j]); // 根据当前索引,取出orders 元素的Id 属性,传入 API // CancelOrder 函数,第二个参数是便于观察额外打印出来。 processed++; // 处理计数 自加 if (j < (orders.length - 1)) { // 当索引值 小于 最后一个索引时 Sleep(RetryDelay); // 暂停 RetryDelay 毫秒 } } if (processed === 0) { // 如果处理计数 没有增长,依然为初始的0 , 即 没有订单要取消。 break; // 跳出 while 循环 } } } function main() { var ticker = exchange.GetTicker(); // 获取 初始时的行情数据 // 下一些不会成交的单子, 让单子 处于 pending 状态 var ID1 = exchange.Buy(ticker.Last - 100, 0.1); var ID2 = exchange.Buy(ticker.Last - 150, 0.2); var ID3 = exchange.Sell(ticker.Last + 100, 0.3); // 我们来看下,调用 GetOrders 返回的数据是不是 这些未完成的挂单。 var pendingOrders = exchange.GetOrders(); for(var i = 0 ; i < pendingOrders.length; i++){ Log("pendingOrders[", i, "]:", pendingOrders[i]); } //接下来 我们调用上面 我们自定义的 函数 CancelPendingOrders 来取消全部的 买单挂单。 CancelPendingOrders(exchange, ORDER_TYPE_BUY); // 取消类型为 ORDER_TYPE_BUY的 未完成的单子(即 未完成的挂单) Sleep(2000); Log("orders : ", exchange.GetOrders()); }

回测结果:

img

可以看到只取消了买入挂单,调用CancelPendingOrders函数后,再次调用GetOrders 依然可以获取卖出的挂单(还没取消,也没完成)。

  • 再来看下 自定义的函数 StripOrders ,用到了GetOrder (同样是摘自 数字货币交易类库): 取消除参数指定的orderId 以外的所有未成交的挂单。

var RetryDelay = 500; // 声明一个变量 用来控制 暂停多少 毫秒 function StripOrders(e, orderId) { var order = null; // 声明 并初始化一个 order 值为 null if (typeof(orderId) == 'undefined') { // 如果没有传入参数 orderId 则执行 if 内代码 orderId = null; // 给orderId 初始化 null } while (true) { // 循环 var dropped = 0; // 每次循环初始 计数 为 0 var orders = _C(e.GetOrders); // 获取 所有未完成的订单 for (var i = 0; i < orders.length; i++) { // 遍历所有未完成的订单 if (orders[i].Id == orderId) { // 找出参数指定的订单ID , 如果没有传入 orderId 参数将不会触发这个条件 order = orders[i]; // 如果找出,就把参数指定的ID 的订单 赋值给 order } else { // 不是参数指定的 用以下代码处理 var extra = ""; if (orders[i].DealAmount > 0) { // 判断该未成交的挂单是否 有部分成交,处理有部分成交的情况 extra = "成交: " + orders[i].DealAmount; } else { // 处理 完全没有成交的情况 extra = "未成交"; } // 取消挂单 e.CancelOrder(orders[i].Id, orders[i].Type == ORDER_TYPE_BUY ? "买单" : "卖单", extra); dropped++; // 计数累加 } } if (dropped === 0) { // 当没有计数累加(没有挂单可以处理取消,即取消完成) break; // 跳出 while } Sleep(RetryDelay); // 暂停RetryDelay 毫秒 } return order; // 返回 指定的 orderId 的挂单 } function main() { var ticker = exchange.GetTicker(); // 获取 初始时的行情数据 // 下一些不会成交的单子, 让单子 处于 pending 状态 var ID1 = exchange.Buy(ticker.Last - 100, 0.1); var ID2 = exchange.Buy(ticker.Last - 150, 0.2); var ID3 = exchange.Sell(ticker.Last + 100, 0.3); // 我们来看下,调用 GetOrders 返回的数据是不是 这些未完成的挂单。 var pendingOrders = exchange.GetOrders(); for(var i = 0 ; i < pendingOrders.length; i++){ Log("pendingOrders[", i, "]:", pendingOrders[i]); } //接下来 我们调用上面 我们自定义的 函数 CancelPendingOrders 来取消全部的 买单挂单。 var order = StripOrders(exchange, ID3); // 取消指定除ID3 以外的其它未成交的挂单 Log("order:", order); // 输出 StripOrders 返回的值 }

回测结果:
img
可以看到 函数 StripOrders 取消了除ID3 以外的所有未完成的挂单。

通过这两个自定义的函数 应该可以 初步掌握 GetOrder 、 GetOrders 、 CancelOrder 三个API的用法。

Related Recommendations
Comment
All comments (13)

    默认都是买btc的么?我要其他的,咋整

    8 years ago

    参见 这个新手问题汇总, 第四个 问题 : https://www.botvs.com/bbs-topic/1427
    可以 在创建 机器人的时候 使用自定义控件。
    在回测的时候 只有 有限的几种 (回测 无法使用 自定义控件 设置交易对)

    8 years ago

    是不是下面
    while (true) { // 循环
    var orders = e.GetOrders(); // 根据参数指定的交易所对象 e , 调用API GetOrders
    // 获取该交易所 所有未完成的挂单。赋值给 变量 orders
    if (!orders) { // 如果出现异常错误 导致 API GetOrders 返回的 数据 是 null ,
    // !null 为 真, 执行 if 分支(即if 后面大括号内的代码)。
    Sleep(RetryDelay); // 暂停 RetryDelay(数值) 毫秒。
    continue; // 忽略下面的代码,重新执行循环。 即:var orders = e.GetOrders();
    // 并再次判断 !orders
    }

    这段代码和 var orders = _C(e.GetOrders); 作用是一样的?? 对吧?

    9 years ago

    起到的 作用是一样的

    9 years ago

    为何第一个例子中 var orders = e.GetOrders(); 不需要用_C()函数呢?不怕返回null吗?

    9 years ago

    紧跟的if 进行了 判断,如果 出现 null 则 continue

    9 years ago

    typeof(orderType) === 'number' && orders[j].Type !== orderType) ,这里如果不要typeof(orderType) === 'number' ,只要后面的 orders[j].Type !== orderType,或者只要前面,不要后面。会发生什么样可能的错误?

    9 years ago

    这个就是判断 ,在实际调用 CancelPendingOrders 函数时 , 传入的参数 类型是不是 符合要求。

    9 years ago

    就是前面 === 和 !== 都是不等于,为何不能用一个? 还有这里的‘number’是字符串还是什么?我看打了个引号

    9 years ago

    1、 == 是判断 是否两边相等, === 是严格判断, 大部分 差不多,有时候有区别,具体可以看JS 语言文档。
    2、typeof(orderType) === 'number' ,这个 'number' 是字符串, 这个就是 使用JS 的 typeof 去判断类型, 如果是 数值类型 就会返回 'number'

    9 years ago

    如果是 数值类型 就会返回 ‘number’,这句话理解的不太好

    9 years ago

    比如 :

    var a = 12 Log(typeof(a)) // 就会打印出 "number"

    img

    9 years ago

    Python版
    img
    img

    9 years ago
  • 1
Forums
PINE Language
Get the app
iPhone Download
© 2015 - ∞ INVENTOR PTE LTD (SG)