零基础入门商品期货程序化交易(2)


上篇文章我们一起学习了商品期货交易方面的一些基础概念、常识。本篇我们继续从实际出发,学习商品期货程序化交易策略的基础设计。
内容讲解以CTP协议为例(不清楚CTP这个名词的可以看一下上篇文章)。

所有操作的前提--和期货公司前置机连接

我们已经学习了一个重要的概念就是我们的交易程序不是直接连通商品期货交易所的。而是我们的交易程序连接的是期货公司的前置机服务器,我们的策略程序触发交易时一系列的操作例如下单、撤单、查询账户资产、获取行情等请求都是和期货公司前置机交互的。那有的同学可能会问:“我们的交易程序下的单只提交到了期货公司前置机服务器,那么最终是怎么到交易所的?毕竟交易所才是最终撮合交易的地方。”

我们的交易策略程序和期货公司前置机交互,至于下单、撤单请求最终怎么到交易所,那就是期货公司前置机和交易所的业务范围了,可以不予考虑。当然,以上只是简单描述。实际情况例如CTP协议,当策略程序和期货公司前置机建立连接之后期货公司前置机会主动推送行情和一些消息。我们不过多研究CTP协议,这里只了解即可。

在FMZ上设计商品期货交易策略的第一个需要牢记的概念就是:“确保和期货公司前置机连接成功”。策略程序中所有的操作都必须基于和期货公司前置机连接成功的前提之下。所以就有了FMZ API文档中描述的商品期货策略基础框架(以JavaScript语言编写策略为例):

function main(){
    while(true){
        // 需要在判断exchange.IO("status")函数返回true,即为真值时才可调用行情、交易等函数
        if(exchange.IO("status")){
            exchange.SetContractType("MA000")
            var ticker = exchange.GetTicker()
            Log("MA000 ticker:", ticker)
            LogStatus(_D(), "已经连接CTP !")
        } else {
            LogStatus(_D(), "未连接CTP !")
        }
    }
}

可能有的同学看到代码就直接感到头大了。不用怕,本篇文章带你彻底征服这段代码。

function
首先我们来说说function这个单词,这个单词是JavaScript语言的关键字,所谓关键字就是这门编程语言中定义好的一个名称,这个名称只用于一个用途。function的用途就是创建一个函数。那么有萌新同学又会问了:“什么是函数?”。简单说,函数就是你输入给它一些参数,它给你反馈一些数据,或者做一些处理,或者执行一些逻辑。

那么function这个单词的作用在JavaScript语言中就是创建一个函数。接着往function后面看,是另一个单词:main。这个main并不是关键字,只是一个名称,意思为“主要的”。function后面跟着main就是说这里创建了一个函数,这个函数名称叫main。再往后看是一对小括号(),如果你创建的函数需要传参数,在这个小括号内就可以写上形式参数,这里不做深究,暂且知道就行。我们创建的这个名为main的函数是没有参数的,所以这里()里面就是空空的。
继续往后看,如下图中的红色标记:

又是一对儿符号,但是这里是一对儿{}花括号。我们把花括号连带其中的代码内容称为函数体,就是你要让函数做的操作统统写在这里,OK我们也不做深究。至此我们学会了如何创建一个函数了,那么动手实践实践,我们利用FMZ的回测系统,很方便的可以学习JavaScript语言。

使用回测系统测试、学习

我们登陆FMZ平台之后,点击控制中心,然后点击策略库,然后点击新建策略按钮。然后设置语言为JavaScript语言,如图:

创建策略时,默认给出的代码是:

function main() {
    return exchange.GetName();
}

这个默认的代码是一个main函数,这个main函数只执行一句代码:return exchange.GetName();先不做深究。(这里顺便回顾一下,还记得我们开始讲的么?商品期货必须要先判断连接上前置机服务器)我们清空代码编辑区。

我们就可以练习创建一个函数了,我们在代码编辑区键入:

function main() {

}

这样我们就在策略中创建了一个函数,名为main,我们可以运行一下。

点击模拟回测切换到回测页面,使用回测系统测试。

  • 1、设置回测的交易所对象为商品期货
  • 2、添加这个设置好的交易所对象。
  • 3、显示添加上了。
  • 4、点击回测按钮测试策略代码。

发现没任何动静!! 因为我们函数体里什么都没写嘛!如果我们在main函数的函数体中写上一句输出语句Log("你好 FMZ!"),例如:

function main() {
    Log("你好 FMZ!")
}

那么再次点击模拟回测按钮运行一下,就可以看到有日志输出了。

至于Log这个是什么?这个语句就是打印日志信息用的,详细用法后续再讲,暂且了解即可。

主函数main

我们经过实践,创建了一个策略。在策略中创建了一个函数名为main。可能有的同学会问如果我创建的函数名字不叫main呢?回测测试时策略还会运行起来么?

答案肯定是:不行。FMZ上策略是必须从main函数作为入口执行的,如果你的策略中没有创建main函数将会报错,有兴趣的可以动手试下,比如上例子中main改为main1,虽然名字只加上了一个字符1。所以我们又学到了,策略必须有main函数。

函数体中的while语句

while又是一个要学习的编程语言关键字,这个关键字的意思是执行一个循环。while关键字后面跟着是一个小括号(),这个小括号里面的表达式是while循环是否能执行的条件。这里可以看到这个小括号()中写着一个truetrue是一个布尔值并且为真值,意思就是“这个循环是否能执行的条件”是一直为真,这个循环在没有其它跳出循环的语句影响下,会一直执行(如果该循环体中,没有其它跳出循环的语句,那么这个循环就叫死循环,因为会一直不停的执行循环体)。在while语句的()循环条件之后紧跟着就是循环体了,循环体代码是由{}花括号包裹住的。

关于“表达式”这个名词,简单说就是一个由变量、运算符等组合起来的式子,这个式子是有值的。可以是各种条件、计算的组合,在用作循环的条件时,这个表达式的值的真假决定了循环的是否执行,在以后的量化交易策略编程学习中,还会遇到,这里暂且了解即可。{}花括号之内的一行一行的代码,就是每次循环时要逐行执行的代码了。

if (条件表达式) {触发时执行的代码} else {触发时执行的代码}语句

学习完了while循环,我们看循环体中另一个关键字if...elseif语句可以单独使用,也可以和if else或者else一起配合使用。

我们先看if的用法,if语句的意思就如同这个单词的字面意思“如果”。if之后跟着一个小括号()我们都已经很熟悉了,这里小括号里面也是需要写入一个表达式,作为条件判断,这里可能你听得一脸懵!没关系,我们动手来实践下。运用我们上面学习到的知识,我们很容易写出一个main函数,用来在回测系统中测试学习这个if语句。

function main() {
    if (1) {
        Log("1为真值,所以条件触发")
    }
    
    if (0) {
        Log("0为假值,能触发就见鬼了 >_< ")
    }
}

可以看到1这个数值也可以作为一个表达式,它的值为真。所以上图中触发了if条件语句的执行代码Log("1为真值,所以条件触发")。可以看到这句代码也是被{}包裹,在Javascript语言中{}包裹的代码为代码块,里面可以是一行代码,也可以是N行代码。

测试中,第一个if判断,由于条件为真(1这个值恒为真),所以执行了这个if语句携带的代码块中的代码。第二个if判断,由于条件为假(0这个值恒为假),所以没有执行这个if语句携带的代码块中的代码,{}中的Log("0为假值,能触发就见鬼了 >_< ")这句代码。

说完了if语句,那else语句呢?做什么用的?else是要和if配合一起用的,作用简单说就是在组合使用中,if的条件如果没触发就执行else后面的代码块。来看这个例子:

function main() {
    if (0) {
        Log("0为假值,能触发就见鬼了 >_< ")
    } else {
        Log("当你看到这句话输出时,代码里上面那个if条件一定是假的!不信去看看代码   ( ̄ ii  ̄;) 吸溜 ( ̄ \"  ̄;) ")
    }
}

先讲到这里,下篇继续。