美文网首页程序员的量化世界量化交易股神
使用BotVS 快速迭代你的量化交易灵感(1)

使用BotVS 快速迭代你的量化交易灵感(1)

作者: 发明者量化FMZ | 来源:发表于2017-05-25 18:52 被阅读253次

    在量化交易的世界,有着千变万化的方法、思路、策略、模型、算法。我们可以天马行空的想象,比如我也是经常头脑风暴般的闪出灵感,迅速在手边能找到的任何可以记录信息的东西上写下。当然这些想法贯穿了很多学科或者领域如: 博弈论、统计学、哲学、金融、经济学、数学、物理学等等。有些是我们掌握的,有些是我们需要学习补充的。检验这些灵感的最好的办法就是让它们实践一下,如何以最快的速度实现成为可运行的策略呢?
    在BotVS 上快速实现你的想法!

    我们可以举个例子:

    最近在研究网格策略,手边就有一个 毛坯 策略,很想检验一下。我们用商品期货的 rb(螺纹钢)这个合约做标的物。

    策略简介如下:

    (1) 资金分10份
    (2) 触发入场条件(做多或做空),使用一份资金入场
    (3) 以做多为例:设置当前初始线(入场价),按着一定规则(如:止损线=0.8 * 入场价)浮动止盈线和止损线,可以设置,(浮动止盈线-中线)= 1.2(中线-止损线)
    (4) 当后续的价格触发止损线,所有资金平仓出局
    (5) 当后续价格触到浮动止盈线,将中线上移到浮动止盈线,同时根据此时的中线计算新的止损线和浮动止盈线,与此同时,加码一份资金
    (6) 重复(5),直到达到条件(4),平所有仓位
    (7) 入场:以前一日收盘价上下0.5*ATR为上下轨,突破上轨做多一份资金,突破下轨做空一份资金。

    这个策略我心里也没底,但是好奇心还是让我很想实现一下 跑跑看。(虽然小本本记录下了一堆头脑风暴,但篇幅有限。)

    开始动手:
    我们首先要分析一下想法或者思路的内容,给各个细节、需求打上标签分类,逐步实现。

    (1) 资金分10份 : 初始化工作,写在程序开始。

    (2) 触发入场条件(做多或做空),使用一份资金入场 : 运行中的触发 一般写在程序主循环逻辑中。

    (3) 以做多为例:..... : 触发一个方向操作后的 动作。 条件(2)完成后实现

    (4)、 (5) : 为 (3)完成后的 分支操作。

    (6) 重复(5),直到达到条件(4),平所有仓位 : 构成了逻辑循环 ,在程序主要循环中实现。

    (7) 入场:以前一.... : 明确2个方向的 起始触发条件。

    2.先写一个策略程序框架:

    在BotVS 上的策略广场上有很多不错的范例,我们采用一个很常用的轮询式的策略框架。使用的语言为 JavaScript 。

    // 参数变量 (待填写)
    
    // 全局变量 (待填写)
    var Interval = 500;          // 轮询时间 , 毫秒  , 500 毫秒 = 0.5 秒
    
    // 功能函数 (待填写)
    function loop(){             // 主循环函数
        
    }
    
    // 入口函数 main 
    function main(){
        // 程序的初始化工作 (待填写)
        
        
        // 主循环, 程序完成初始化后在此 循环执行,直到手动关闭。
        var LoginState = null;
        var nowTimeStamp = 0;
        while(true){
            nowTimeStamp = new Date().getTime();
            if(exchange.IO("status") == true){
                LoginState = true;
                loop();
            }else{
                LoginState = false;
            }
            LogStatus("时间:", _D(nowTimeStamp), LoginState ? "已连接服务器" : "未连接服务器!"/*, 待显示的一些信息可以写在此处,如账户信息,实时行情,程序状态*/)
            Sleep(Interval);     //  暂停 0.5 秒, 避免轮询频率过高,访问交易所服务器过于频繁导致问题。
        }
    }
    
    function onexit(){
        // 做一些在程序停止时的 收尾工作。(待填写)
        
        Log("程序退出!");
    }
    
    3、按照开始的分析,这里可以逐步往框架里面填写代码实现功能。
    
    我们先实现:资金分10份 ,这个是在程序 初始化这个位置实现代码分割资金。
    
    // 参数变量 (待填写)
    var ContractType = "rb1710";  // 标的物合约代码   ,螺纹钢 1710 合约 目前主力合约
    var UsedRatio = 0.5
    // 全局变量 (待填写)
    var Interval = 500;           // 轮询时间 , 毫秒  , 500 毫秒 = 0.5 秒
    var Balance_Unit = 0;
    var ContractTypeInfo = null;  // 合约信息
    var initAccount = null;       // 初始账户信息
    var LONG = 1;
    var SHORT = 2;
    // 功能函数 (待填写)
    function loop(){              // 主循环函数
        
    }
    
    function CheckBalance_Unit(Direction){
        ContractTypeInfo = exchange.SetContractType(ContractType);
        Log("标的物合约信息:", ContractTypeInfo);
        Balance_Unit = _N(initAccount.Balance * UsedRatio / 10, 2);
        Log("账户信息:", initAccount, "资金分配 10份,一份为:", Balance_Unit);
    
        var ticker = _C(exchange.GetTicker);
        var OneContractMargin = ContractTypeInfo.VolumeMultiple * ticker.Last * (Direction == LONG ? ContractTypeInfo.LongMarginRatio : ContractTypeInfo.ShortMarginRatio);
        if(Balance_Unit < OneContractMargin * 1.2){
            throw "最新价格:" + ticker.Last + "调整系数1.2" + " ,资金可用部分的10分之一 不足 开" + (Direction == LONG ? "多" : "空") + "1手合约," + "1手合约需:" + OneContractMargin;
        }else{
            Log("最新价格:" + ticker.Last + "调整系数1.2" + "1份资金 可开:", Direction == LONG ? "多" : "空", _N(Balance_Unit / OneContractMargin, 0));
        }
        var nowAccount = _C(exchange.GetAccount);
        if(nowAccount.Balance < Balance_Unit){
            throw "当前账户资金已小于初始资金可用部分的十分之一。当前资金:" + nowAccount.Balance + ", 初始资金可用部分的十分之一为:" + Balance_Unit;
        }else if(nowAccount.Balance < OneContractMargin * 1.2){
            throw "资金不足:" + JSON.stringify(nowAccount) + ", 系数1.2,1手合约保证金:" + OneContractMargin;
        }
    }
    
    // 入口函数 main 
    function main(){
        // 程序的初始化工作 (待填写)
        while(true){
            if(exchange.IO("status") == true && (initAccount = exchange.GetAccount()) !== null){
                break;
            }
            LogStatus("等待交易时间获取账户信息初始化!" + "时间:", new Date());
            Sleep(Interval);
        }
        CheckBalance_Unit(LONG);
        CheckBalance_Unit(SHORT);
        
        // 主循环, 程序完成初始化后在此 循环执行,直到手动关闭。
        var LoginState = null;
        var nowTimeStamp = 0;
        while(true){
            nowTimeStamp = new Date().getTime();
            if(exchange.IO("status") == true){
                LoginState = true;
                loop();
            }else{
                LoginState = false;
            }
            LogStatus("时间:", _D(nowTimeStamp), LoginState ? "已连接服务器" : "未连接服务器!"/*, 待显示的一些信息可以写在此处,如账户信息,实时行情,程序状态*/)
            Sleep(Interval);     //  暂停 0.5 秒, 避免轮询频率过高,访问交易所服务器过于频繁导致问题。
        }
    }
    
    function onexit(){
        // 做一些在程序停止时的 收尾工作。(待填写)
        
        Log("程序退出!");
    }
    

    代码扩展了一些全局变量用来储存运行中的数据, 增加了程序在 主要逻辑 开始运行前的 资金校验,计算资金可用部分分为10份,其中一份资金是否足够开多或者开空一手合约。
    在程序运行中也需要处理资金监控的问题,避免资金不足重复错误报单。
    视频地址:KSDD1.mp4KSDD2.mov.mp4
    下篇我们继续完善!

    相关文章

      网友评论

      • laoyaoshine:梦总 6666
        发明者量化FMZ:@laoyaoshine 好的 ,我研究一个,这个文章的思路是网上找的,自己实现了一下,不知道是我写的不对 还是策略思路问题,回测效果 不太好。
        laoyaoshine: @F_r_eedom 梦总 直接上回撤小于1收益高的策略
        发明者量化FMZ:@laoyaoshine 感谢支持 ^^ , 以后出更多的文章和视频 方便大家学习量化策略程序的编写。

      本文标题:使用BotVS 快速迭代你的量化交易灵感(1)

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