BotVS 商品期货 量化 测试入门 策略

作者: 发明者量化FMZ | 来源:发表于2017-11-09 12:59 被阅读62次
    • 为什么要写这个策略代码呢?

    原因很简单,在平时测试托管者功能的时候,每次要对 BotVS 各个 API 进行测试。每次的测试代码很大程度上类似,干脆就写个 测试策略吧。写好以后,感觉不仅可以测试托管者。同样对于 初识 BotVS量化平台的 新同学 在学习使用商品期货 仿真账户 或者 实盘的时候也是个很好的工具。

    • 用途:

      如上所述,该策略仅仅是为了方便BotVS新用户快速熟悉 BotVS 商品期货程序化交易,测试模拟账户、实盘账户下单 等功能 。透过对该策略的源代码的剖析和学习也可以学习到 策略编写方面的一些技巧、经验。

    那么简单介绍下吧!

    • 显示UI

      UI
    • 策略参数

      参数

      参数很简单,只有2个,第一个是 程序轮询间隔 (BotVS 策略是轮询架构的),该参数可以控制每次轮询后暂停多少毫秒,防止策略访问 交易所过于频繁。第二个参数就是 合约代码了,默认的是 rb1801 即 :螺纹钢1801合约

    • 交互

      交互

      交互就是 策略使用时主要用到的 功能了。

      • 修改合约


        changeSymbol

      可以在该交互控件 中填写 合约代码,如填写 MA801 ,后点击 changeSymbol 就可以将 策略中当前的合约代码 比如 rb1801 切换成 MA801。

      • 开当前合约 多单:

        编辑框写上开仓手数,点击 OPEN_LONG 按钮就会 进行开多仓操作。

      • 开空 同理不赘述

      • 按数量平仓:

        点击 COVER 就会按编辑框写入的 数量平仓,如果 此时 同时持有多头和空头仓位,会随机先平 一边,如果平仓数量大于一边的数量,会平完后,按剩余的计划数量继续平仓另一边。(鉴于测试的时候同时持有多空的情况不多,所以平仓没有单独写)

      • 获取当前合约合约未完成的订单:
        点击后在日志 显示区域会 显示出 未完成的订单(挂单状态)

      • 获取当前合约指定ID的订单

        可以 传入 一个 ID 获取 该ID 的订单

      • 获取当前合约持仓信息:

        获取当前的合约的持仓。

      • 获取所有合约持仓信息:

        获取所有持仓信息 列表 (数组形式)

      • 取消订单:

        编辑框 写入 要取消的订单的 ID 号 ,点击 CANCEL_ORDER 就可以取消挂单。

      • 调用JS 代码 ,可以在编辑框内写 要执行的 JS 代码, 点击 按钮 JS_CODE 就可以执行。

    源码:

    // 商品期货 测试 程序
    /*
    1、 行情部分测试
    2、 交易 测试
    3、 交互界面
    
    */
    // var _Interval = 500
    // var _StrContractType = "rb1801"
    
    
    //
    var CONNECTED = 1
    var NOTCONNECTED = 2
    var _TableObj = {
        type : "table",
        title : "test",
        cols : ["value"],
        rows : [],
    }
    var _templeteObj = null
    // var _isFirst = true
    var _chart = null       // 配置对象 ,并非控制对象
    var _chartObj = null
    var _LogStatusMessage = ""
    
    function E(obj) {
        if(!obj){
            return obj
        }
    
        var cloneObj = function(obj) { // 深拷贝 对象函数
            var str, newobj = obj.constructor === Array ? [] : {};
            if (typeof obj !== 'object') {
                return;
            } else if (JSON) {
                str = JSON.stringify(obj); //系列化对象
                newobj = JSON.parse(str); //还原
            } else {
                for (var i in obj) {
                    newobj[i] = typeof obj[i] === 'object' ?
                        cloneObj(obj[i]) : obj[i];
                }
            }
            return newobj;
        }
        
        if(obj && typeof(obj) == "object" && typeof(obj.Info) !== "undefined"){
            var newObj = cloneObj(obj)
            delete newObj.Info
            return newObj
        }else if(typeof(obj.length) == "number"){
            ///*
            var newArray = []
            for(var n = 0; n < obj.length; n++){
                newArray.push(E(obj[n]))
            }
            return newArray
            //*/
            /*
            var newObj = cloneObj(obj)
            delete newObj.Info
            return newObj
            */
        }else{
            // Log(obj, "is not object or not have attribute 'Info'")
            return obj
        }
    }
    
    function onTick(symbol){
        if(!$.IsTrading(symbol)){
            _LogStatusMessage = symbol + " 不在交易时间段内!" + "#FF0000"
            return
        }else{
            _LogStatusMessage = symbol + " 在交易时间段!"
        }
    
        var contractTypeInfo = exchange.SetContractType(symbol)
        if(!contractTypeInfo){
            return
        }
    
        var account = exchange.GetAccount()
        var ticker = exchange.GetTicker()
        var records = exchange.GetRecords()
        var depth = exchange.GetDepth()
        
        if(!account || !ticker || !depth || !records || records.length < 2){
            return
        }
        
        _TableObj.rows = []   // 每次清空
        _TableObj.rows.push([JSON.stringify(E(contractTypeInfo))])
        _TableObj.rows.push([JSON.stringify(E(account))])
        _TableObj.rows.push([JSON.stringify(E(ticker))])
        _TableObj.rows.push([JSON.stringify(E(records[records.length - 1])) + JSON.stringify(E(records[records.length - 2])) + " records.length : " + records.length])
        _TableObj.rows.push([JSON.stringify(E(depth.Asks[0])) + JSON.stringify(E(depth.Bids[0])) + "Asks`s length is:" + depth.Asks.length + "Bids`s length is:" + depth.Bids.length])
    
        _chartObj = $.PlotRecords(records, "K线")
    
        /*
        if(_isFirst){
            _chart.reset()
            _isFirst = false
        }
        */
    }
    
    function Custom_GetPositons(symbol){
        var positions = exchange.GetPosition()
        if(!positions){
            Log("Custom_GetPositons failed", positions)
        }
        if(typeof(symbol) != "undefined"){
            Log("PD_LONG:", E(_templeteObj.GetPosition(symbol, PD_LONG, positions)))
            Log("PD_SHORT:", E(_templeteObj.GetPosition(symbol, PD_SHORT, positions)))
            Log("positions:", E(positions))
        }else{
            Log("positions:", E(positions))
        }
    }
    
    function Custom_Buy(symbol, amount){
        // exchange.SetDirection("buy")
        if(!$.IsTrading(symbol)){
            Log(symbol, " 不在交易时间段内,禁止下单!")
            return
        }
        var tradeInfo = _templeteObj.OpenLong(symbol, amount)
        Log(tradeInfo)
    }
    
    function Custom_Pending_Buy(diffPrice, amount, direction){
        if(!$.IsTrading(_StrContractType)){
            Log(_StrContractType, " 不在交易时间段内,禁止下单!")
            return
        }
        exchange.SetContractType(_StrContractType)
        var ticker = _C(exchange.GetTicker)
        exchange.SetDirection(direction)
        var id = exchange.Buy(ticker.Last - diffPrice, amount)
        Log("id:", id)
    }
    
    function Custom_Pending_Sell(diffPrice, amount, direction){
        if(!$.IsTrading(_StrContractType)){
            Log(_StrContractType, " 不在交易时间段内,禁止下单!")
            return
        }
        exchange.SetContractType(_StrContractType)
        var ticker = _C(exchange.GetTicker)
        exchange.SetDirection(direction)
        var id = exchange.Sell(ticker.Last + diffPrice, amount) 
        Log("id:", id)
    }
    
    function Custom_Sell(symbol, amount){
        // exchange.SetDirection("sell")
        if(!$.IsTrading(symbol)){
            Log(symbol, " 不在交易时间段内,禁止下单!")
            return
        }
        var tradeInfo = _templeteObj.OpenShort(symbol, amount)
        Log(tradeInfo)
    }
    
    function Custom_Cover(symbol, amount){
        if(!$.IsTrading(symbol)){
            Log(symbol, " 不在交易时间段内,禁止下单!")
            return
        }
        _templeteObj.Cover(symbol, amount)
    }
    
    function ChangeContractType(symbol){
        _StrContractType = symbol
        Log("测试 合约更改为:", _StrContractType)
        Log("清空图表!", "#FF0000")
        if(_chartObj){
            _chartObj.reset()
            $.SetPreBarTime(0)
        }
    }
    
    function Custom_GetPendingOrders(symbol){
        var orders = _C(exchange.GetOrders)
        if(orders.length == 0){
            Log(E(orders))
        }
        for(var i = 0 ; i < orders.length ; i++){
            if(typeof(symbol) == "undefined"){
                Log(E(orders[i]))
            }else{
                if(symbol == orders[i].ContractType){
                    Log(E(orders[i]))
                }else if(i == orders.length - 1){
                    Log(E(orders))
                }
            }
        }
    }
    
    function Custom_GetOrder(symbol, id){
        _C(exchange.SetContractType, symbol)
        var order = exchange.GetOrder(id)
        if(!order){
            Log("GetOrder failed, the order is", order)
            return false
        }else{
            Log(E(order))
        }
    }
    
    function Custom_CancelOrder(symbol, id){
        Log("取消的订单 id 是:", symbol, id)
        if(typeof(id) == "undefined"){
            id = symbol
            symbol = _StrContractType
        }
    
        if(!$.IsTrading(symbol)){
            Log(symbol, " 不在交易时间段内,禁止下单!")
            return
        }
    
        exchange.CancelOrder(id)  // CancelOrder(orderId)
    }
    
    function main(){
        LogReset()
        Log("启动!")
    
        _chart = $.GetCfg()
        Chart(_chart).reset()
    
        SetErrorFilter("login");
        var connectState = null
        _templeteObj = $.NewPositionManager()
    
        while(true){
            if(exchange.IO("status")){
                onTick(_StrContractType)       
                connectState = CONNECTED     
            }else{
                
                connectState = NOTCONNECTED
            }
            
            var cmd = GetCommand()
            if(cmd){
                Log("接收到命令:", cmd, "#0000FF")
                var array_cmd = cmd.split(':')
                if(array_cmd.length > 2){
                    for(var idx = 2; idx < array_cmd.length; idx++){
                        array_cmd[1] += (':' + array_cmd[idx])
                    }
                    array_cmd = [array_cmd[0], array_cmd[1]]       // 重新赋值
                }
            
                if(array_cmd.length == 1){                     // button
                    switch(array_cmd[0]){
                        case "GET_PNEDING" :
                            Custom_GetPendingOrders(_StrContractType)
                            break
                        case "GET_ALL_POSITION" :
                            Custom_GetPositons()
                            break
                        default :
                            Log("unknow command:" + array_cmd, "#FF0000")
                    }
                }else if(array_cmd.length == 2){ // other
                    switch(array_cmd[0]){
                        case "OPEN_LONG" :
                            var amount = parseInt(array_cmd[1])
                            Custom_Buy(_StrContractType, amount)
                            break
                        case "OPEN_SHORT":
                            var amount = parseInt(array_cmd[1])
                            Custom_Sell(_StrContractType, amount)
                            break
                        case "COVER" :
                            var amount = parseInt(array_cmd[1])
                            Custom_Cover(_StrContractType, amount)
                            break
                        case "GET_ORDER" :
                            Custom_GetOrder(_StrContractType, array_cmd[1])
                            break
                        case "GET_POSITION" :
                            if(array_cmd[1] == "空"){
                                Custom_GetPositons(_StrContractType)
                            }else{
                                Custom_GetPositons(array_cmd[1])
                            }
                            break
                        case "changeSymbol" :
                            ChangeContractType(array_cmd[1]) 
                            break
                        case "CANCEL_ORDER" :   
                            // Log("CANCEL_ORDER:", array_cmd)            
                            Custom_CancelOrder(array_cmd[1])
                            break
                        case "JS_CODE" :
                            var js = cmd.split(':', 2)[1];  // 分割 返回的消息 字符串, 限制返回2个, 把索引为1的 元素 赋值给 名为js 的变量 
                            Log("执行调试代码:", js);         // 输出 执行的代码
                            try {                           // 异常检测
                                eval(js);                   // 执行 eval函数, 该函数执行传入的参数(代码)。
                            } catch(e) {                    // 抛出异常
                                Log("Exception", e);        // 输出错误信息
                            }
                            break
                        default :
                            Log("unknow command:" + array_cmd, "#FF0000")
                    }
                }
            }
            var strConnectState = connectState == CONNECTED ? "已经连接!" : "未连接!"
            LogStatus(_D(), strConnectState, _LogStatusMessage, '\n`' + JSON.stringify(_TableObj) + '`' + '\n' + 
                'Custom_CancelOrder("", "")    // symbol, id' + '\n' + 
                'Custom_Pending_Buy( , , "")    // diffPrice, amount, direction' + '\n' +
                'Custom_Pending_Sell( , , "")    // diffPrice, amount, direction' + '\n' )
            Sleep(_Interval)
        }
    }
    

    测试 截图:


    1.png 2.png 3.png

    要注意 测试 自己的 账号要在 商品期货 开市时间。

    策略源码地址: https://www.botvs.com/strategy/59120

    BotVS 量化未来

    相关文章

      网友评论

        本文标题:BotVS 商品期货 量化 测试入门 策略

        本文链接:https://www.haomeiwen.com/subject/bfypmxtx.html