手把手教你实现一个商品期货计划委托工具

论坛 期权论坛 期权     
宽客在线   2020-4-24 23:46   1890   0
在做商品期货交易时,并非都是全自动的交易策略,有很多半自动的程序化交易工具代替人工盯盘。这类工具虽然算不上完整的策略,但是也是基于使用者的交易意图,有条理的进行交易,也算是一种最简单的交易策略吧。


下面我们就一起来实现一个交易工具,对于半自动的交易工具可能会有很多需求,我们简单整理一些需求实现出来,对于更加高级、复杂的需求可以后续优化升级。


[h2]商品期货计划委托工具(教学)[/h2]计划委托
制定委托任务,由策略参数设置的价格线,下单手数,多空方向,触发方式,确定任务。
止盈
计划委托订单成交以后,根据设置的止盈价格,创建计划止盈任务。
止损
计划委托订单成交以后,根据设置的止损价格,创建计划止损任务。
止损反手
根据止损任务触发后,制定反手任务。



有了以上需求,我们就可以逐一把功能实现,首先分析一下,止盈、止损动作是建立在开始的计划委托订单成交,有持仓以后,再产生的动作,所以止盈、止损是基于,第一个计划委托订单成交以后再创建。止损反手同样也是基于止损完成以后再产生的动作。大致是这样的一个流程。




所以这里遇到第一个问题,我们设计时,如何让一个任务完成以后,自动创建另一个后续任务呢?这个问题解决很简单,FMZ量化交易平台提供了强大的模板类库,用自带的商品期货交易类库就可以轻松解决。每个策略创建时都会在模板栏中自带这个类库,勾选上,保存策略即可引用。




回到我们的问题,如何让一个任务完成后,自动创建预先设置好的另一个任务,我们使用「商品期货交易类库」中的$.NewTaskQueue()函数创建的交易队列控制对象就可以。


策略中定义的全局变量
  1. // 全局变量
复制代码
  1. var _TaskQueue = []    // 任务队列,数据结构是一个数组。
复制代码
  1. var ENTRUST = 0        // 定义的任务类型,ENTRUST 代表计划委托
复制代码
  1. var STOPLOSS = 1       // 代表止损委托
复制代码
  1. var STOPPROFIT = 2     // 代表止盈委托
复制代码
  1. var BACKHAND = 3       // 代表反手委托
复制代码
  1. var dictTaskType = ["委托任务", "止损任务", "止盈任务", "反手任务"]     // 委托类型的中文参照,用于程序中显示这些名字
复制代码
复制代码
  1. var q = $.NewTaskQueue()   // 创建 商品期货交易类库 交易队列控制对象。
复制代码
如何使用这个对象 q呢?很简单,如下代码。task.taskSymbol为当前任务的合约代码,task.taskDirection为当前任务的交易方向,task.taskAmount为当前任务的下单数量。最后function(tradeTask, ret) {...就是解决我们问题的回调函数。可以在当前任务完成后,触发执行这个回调函数,这样我们把后续任务的创建操作写在这个回调函数中就可以轻松实现。
  1. q.pushTask(exchange, task.taskSymbol, task.taskDirection, task.taskAmount, function(tradeTask, ret) {
复制代码
  1.     Log(tradeTask.desc, ret, "XX委托完成")
复制代码
  1.     if (ret) {
复制代码
  1.         // 回调,创建后续任务
复制代码
  1.         // ...
复制代码
  1.         // ..
复制代码
  1.         // .
复制代码
  1.     }
复制代码
  1. })
复制代码
完整策略代码
  1. // 全局变量
复制代码
  1. var _TaskQueue = []
复制代码
  1. var ENTRUST = 0
复制代码
  1. var STOPLOSS = 1
复制代码
  1. var STOPPROFIT = 2
复制代码
  1. var BACKHAND = 3
复制代码
  1. var dictTaskType = ["委托任务", "止损任务", "止盈任务", "反手任务"]
复制代码
复制代码
  1. var q = $.NewTaskQueue()
复制代码
复制代码
复制代码
  1. function closeTask (taskType) {
复制代码
  1.     for (var i = 0; i < _TaskQueue.length; i++) {
复制代码
  1.         if (taskType == _TaskQueue[i].taskType) {
复制代码
  1.             _TaskQueue[i].taskFinished = true
复制代码
  1.             Log("关闭任务:", dictTaskType[taskType])
复制代码
  1.         }
复制代码
  1.     }
复制代码
  1. }
复制代码
复制代码
  1. // 任务处理对象
复制代码
  1. function TaskQueueProcess () {
复制代码
  1.     // 获取行情
复制代码
  1.     exchange.SetContractType(_EntrustSymbol)
复制代码
  1.     var ticker = _C(exchange.GetTicker)
复制代码
复制代码
  1.     for (var i = 0; i < _TaskQueue.length; i++) {
复制代码
  1.         var task = _TaskQueue[i]
复制代码
  1.         if (task.taskFinished == false && task.taskType == ENTRUST && task.taskTrigger * ticker.Last >= task.taskTrigger * task.taskPrice) {
复制代码
  1.             q.pushTask(exchange, task.taskSymbol, task.taskDirection, task.taskAmount, function(tradeTask, ret) {
复制代码
  1.                 Log(tradeTask.desc, ret, "委托完成")
复制代码
  1.                 if (ret) {
复制代码
  1.                     // 回调,创建后续任务
复制代码
  1.                     if (_EntrustStopLossPrice != -1) {     // 创建止损任务
复制代码
  1.                         var newTask = {
复制代码
  1.                             taskType : STOPLOSS,
复制代码
  1.                             taskSymbol : task.taskSymbol,
复制代码
  1.                             taskPrice : _EntrustStopLossPrice,
复制代码
  1.                             taskAmount : task.taskAmount,
复制代码
  1.                             taskDirection : task.taskDirection == "buy" ? "closebuy" : "closesell",
复制代码
  1.                             taskTrigger : -1,              // 低于 价格触发
复制代码
  1.                             taskFinished : false
复制代码
  1.                         }
复制代码
  1.                         _TaskQueue.push(newTask)
复制代码
  1.                         Log("创建止损任务", newTask, "#FF0000")
复制代码
  1.                     }
复制代码
  1.                     if (_EntrustStopProfitPrice != -1) {   // 创建止盈任务
复制代码
  1.                         var newTask = {
复制代码
  1.                             taskType : STOPPROFIT,
复制代码
  1.                             taskSymbol : task.taskSymbol,
复制代码
  1.                             taskPrice : _EntrustStopProfitPrice,
复制代码
  1.                             taskAmount : task.taskAmount,
复制代码
  1.                             taskDirection : task.taskDirection == "buy" ? "closebuy" : "closesell",
复制代码
  1.                             taskTrigger : 1,               // 高于 价格触发
复制代码
  1.                             taskFinished : false
复制代码
  1.                         }
复制代码
  1.                         _TaskQueue.push(newTask)
复制代码
  1.                         Log("创建止盈任务", newTask, "#FF0000")
复制代码
  1.                     }
复制代码
  1.                 }
复制代码
  1.             })
复制代码
  1.             task.taskFinished = true
复制代码
  1.             break
复制代码
  1.         } else if (task.taskFinished == false && task.taskType == STOPLOSS && ticker.Last * task.taskTrigger >= task.taskPrice * task.taskTrigger) {
复制代码
  1.             q.pushTask(exchange, task.taskSymbol, task.taskDirection, task.taskAmount, function(tradeTask, ret) {
复制代码
  1.                 Log(tradeTask.desc, ret, "止损完成")
复制代码
  1.                 // 关闭止盈任务
复制代码
  1.                 closeTask(STOPPROFIT)
复制代码
  1.                 if (ret) {
复制代码
  1.                     // 回调,创建后续任务
复制代码
  1.                     if (_EntrustStopLossBackhandPrice != -1) {
复制代码
  1.                         var newTask = {
复制代码
  1.                             taskType : BACKHAND,
复制代码
  1.                             taskSymbol : task.taskSymbol,
复制代码
  1.                             taskPrice : _EntrustStopLossBackhandPrice,
复制代码
  1.                             taskAmount : task.taskAmount,
复制代码
  1.                             taskDirection : task.taskDirection == "closebuy" ? "sell" : "buy",
复制代码
  1.                             taskTrigger : task.taskDirection == "closebuy" ? -1 : 1,   // -1 小于时触发, 1大于时触发
复制代码
  1.                             taskFinished : false
复制代码
  1.                         }
复制代码
  1.                         _TaskQueue.push(newTask)
复制代码
  1.                         Log("创建反手任务", newTask, "#FF0000")
复制代码
  1.                     }
复制代码
  1.                 }
复制代码
  1.             })
复制代码
  1.             task.taskFinished = true
复制代码
  1.             break
复制代码
  1.         } else if (task.taskFinished == false && task.taskType == STOPPROFIT && ticker.Last * task.taskTrigger >= task.taskPrice * task.taskTrigger) {
复制代码
  1.             q.pushTask(exchange, task.taskSymbol, task.taskDirection, task.taskAmount, function(tradeTask, ret) {
复制代码
  1.                 Log(tradeTask.desc, ret, "止盈完成")
复制代码
  1.                 // 关闭止损任务
复制代码
  1.                 closeTask(STOPLOSS)
复制代码
  1.             })
复制代码
  1.             task.taskFinished = true
复制代码
  1.             break
复制代码
  1.         } else if (task.taskFinished == false && task.taskType == BACKHAND && ticker.Last * task.taskTrigger >= task.taskPrice * task.taskTrigger) {
复制代码
  1.             q.pushTask(exchange, task.taskSymbol, task.taskDirection, task.taskAmount, function(tradeTask, ret) {
复制代码
  1.                 Log(tradeTask.desc, ret, "反手完成")
复制代码
  1.             })
复制代码
  1.             task.taskFinished = true
复制代码
  1.             break
复制代码
  1.         }
复制代码
  1.     }
复制代码
  1.     q.poll()
复制代码
  1. }
复制代码
复制代码
  1. function main() {
复制代码
  1.     if (_IsRecovery) {
复制代码
  1.         recoveryData = _G("_TaskQueue")
复制代码
  1.         if (!recoveryData) {
复制代码
  1.             _TaskQueue = recoveryData
复制代码
  1.         } else {
复制代码
  1.             Log("没有可用于恢复的数据")
复制代码
  1.         }
复制代码
  1.     }
复制代码
复制代码
  1.     // 根据参数生成任务
复制代码
[code]    if (_EntrustSymbol == "null" || _EntrustPrice
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:20
帖子:4
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP