[原创] 零基础入门商品期货程序化交易(1)

不同于区块链资产交易,商品期货交易属于传统交易领域。程序化交易入门有一定门槛,特别是大部分传统交易领域的交易者对于交易都很精通,但是对于程序化相关的知识、计算机知识等知之甚少。以至于认为商品期货程序化非常的难,想做到根据自己的思路自由、灵活的开发交易策略更是难上加难。那么本文就从实践出发,带领你从0基础进入商品期货程序化交易的大门。

交易所、期货公司

我们先来说说什么是商品期货。商品期货交易简单说就是大宗商品入库注册形成仓单,然后在商品期货交易所挂牌交易,交易的是标准化的合约。一手合约对应了一定数量的实物,例如一手rb螺纹钢合约对应10吨螺纹钢。

交易所主要有:
上期所:贵金属等
大商所:农产品等
郑商所:化工等
中金所:金融衍生品等

  • 交互、报单过程

    首先,要在交易所交易这些商品期货合约,你需要一个账户,所以便有了期货公司。你在期货公司开设账户,入金交易。不论是手动交易,例如使用一些软件(文华财经等),向期货公司打电话报单(现在很少了),还是使用一些程序化交易软件发送请求到期货公司前置机去交易,下的交易单都会由期货公司发送到交易所去。这个过程需要了解。

    用户下单(软件、策略程序等)->期货公司(前置机服务器)->交易所(系统)
    
  • 协议

    即使是手动交易,也要借助于软件。那么这些软件或者我们写的交易策略程序是如何和期货公司前置机通信的呢?
    通常用这两种:CTP协议易盛协议
    在某个期货公司开户后,通常是默认开通CTP协议的,CTP协议也是使用的最多的,具体开通或者停止都是电联期货公司提出申请。
    以FMZ量化交易平台为例:
    在配置商品期货账户时,需要指定是那种协议接入。

    期货公司的账户开通了哪种协议接入,这里就使用对应的选项就可以了。

  • 期货公司

    期货公司国内有很多,根据大小规模分级别,通常在A类期货公司开户,大的期货公司设备投入之类的比较多一些,更加易用、稳定。
    推荐使用宏源期货,A类期货公司,手续费可以优惠至交易所标准加1分钱。
    期货公司通常在交易所手续费、保证金基础上增加一部分手续费、保证金,每家期货公司各不相同,如果需要了解,可以具体咨询期货公司。
    一般期货公司都支持CTP/易盛协议,通常是默认开通CTP协议,但是不排除有些期货公司默认什么都不开通,具体需要和期货公司沟通确认。

  • 看穿式认证

    行业要求,期货公司目前需要看穿式认证过的软件程序才给接入前置机。目前FMZ上在配置期货公司账户信息时,输入期货公司名称时,可以输入“看穿式”来筛选出目前已经看穿式认证过的期货公司,如图:

    如果你配置的期货公司账号是这些带有看穿式认证过的期货公司,不用任何其它设置,直接配置资金账号、密码即可使用。

    其它没有认证过的期货公司账号,则需要自行向期货公司做看穿式认证(过程通常比较长,很繁琐),认证后获取到appidappid对应的授权码配置,如图:

  • 合约

    以上提到的交易所对于合约代码定义并不是完全统一定义的,这类问题经常有新同学问到。我们看一些软件上对于不同品种命名更是各种各样。

    我们以FMZ量化交易平台上对于合约代码的命名标准为例,在API文档上地址:https://www.fmz.com/api#期货交易

    例如上期所的螺纹钢品种,合约代码是rb开头,加上4个数字。rb2110即为螺纹钢这个品种,2021年10月份交割的合约。

    可以看到实际就是这样组成的合约代码:rb-21-10
    

    大商所的铁矿石,合约代码为i开头,加上4个数字。i2109即为铁矿石这个品种,2021年9月交割的合约。

    可以看到实际就是这样组成的合约代码:i-21-09
    

    郑商所的甲醇,合约代码为MA开头,加上3个数字。MA109即为甲醇这个品种,2021年9月交割的合约。

    可以看到实际就是这样组成的合约代码:MA-1-09
    

    要注意合约代码是区分大小写的,写错了肯定程序会报错的。

    可以编写一个策略打印出所有品种的信息,虽然刚开始入门就接触到编写代码有点难,但是不用怕。这里仅仅作为测试使用。

    function main(){
        while(true){
            if(exchange.IO("status")){         
                var products_CZCE_Tbl = {
                    "type" : "table", 
                    "title" : "郑商所 CZCE", 
                    "cols" : ["商品名称(ProductName)", "合约代码短名(ProductID)" , "一跳价格(PriceTick)", "一手合约乘数(VolumeMultiple)", "交易所代码(ExchangeID)"], 
                    "rows" : [] 
                }
                var products_DCE_Tbl = {
                    "type" : "table", 
                    "title" : "大商所 DCE", 
                    "cols" : ["商品名称(ProductName)", "合约代码短名(ProductID)" , "一跳价格(PriceTick)", "一手合约乘数(VolumeMultiple)", "交易所代码(ExchangeID)"], 
                    "rows" : [] 
                }
                var products_SHFE_Tbl = {
                    "type" : "table", 
                    "title" : "上期所 SHFE", 
                    "cols" : ["商品名称(ProductName)", "合约代码短名(ProductID)" , "一跳价格(PriceTick)", "一手合约乘数(VolumeMultiple)", "交易所代码(ExchangeID)"], 
                    "rows" : [] 
                }
                var products_other_Tbl = {
                    "type" : "table", 
                    "title" : "其它", 
                    "cols" : ["商品名称(ProductName)", "合约代码短名(ProductID)" , "一跳价格(PriceTick)", "一手合约乘数(VolumeMultiple)", "交易所代码(ExchangeID)"], 
                    "rows" : [] 
                }
                exchange.IO("products").forEach(function(product) {
                    if (product.ExchangeID == "CZCE") {
                        products_CZCE_Tbl.rows.push([product.ProductName, product.ProductID, product.PriceTick, product.VolumeMultiple, product.ExchangeID])
                    } else if (product.ExchangeID == "DCE") {
                        products_DCE_Tbl.rows.push([product.ProductName, product.ProductID, product.PriceTick, product.VolumeMultiple, product.ExchangeID])
                    } else if (product.ExchangeID == "SHFE") {
                        products_SHFE_Tbl.rows.push([product.ProductName, product.ProductID, product.PriceTick, product.VolumeMultiple, product.ExchangeID])
                    } else {
                        products_other_Tbl.rows.push([product.ProductName, product.ProductID, product.PriceTick, product.VolumeMultiple, product.ExchangeID])
                    }                
                })
                LogStatus(_D(), "已经连接CTP", "\n`" + JSON.stringify([products_CZCE_Tbl, products_DCE_Tbl, products_SHFE_Tbl, products_other_Tbl]) + "`")  
                Sleep(1000 * 60 * 5)
            } else {
                LogStatus(_D(), "未连接CTP !")
            }
            Sleep(1000)
        }
    }
    

    策略代码运行起来就会显示如图列表信息,可以查询到所有的品种代码。

  • 实际使用时配置交易所的问题

    首先我们来学习如何在FMZ上配置一个商品期货交易所对象(简单说就是配置一个商品期货账号到FMZ上,用于让策略自动化操作这个账户从而交易)。

    当注册好FMZ账号之后,登录。点击控制中心,跳转到控制中心页面。

    然后点击交易所,跳转至交易所页面。

    接着点击添加交易所按钮,跳转至交易所对象配置页面。

    我们以FMZ已经做过看穿式认证的期货公司,宏源期货为例子,宏源期货默认开通CTP协议。
    所以我们设置协议为CTP协议,然后只用配置上资金账号密码即可。

    通常,左侧的期货公司前置机IP地址等信息是用默认的就可以的,但是如果出现网络访问不到前置机。可以试试调整使用其它线路、IP。

    • 1、如果资金账号、密码设置错误了,在使用时会发生报错:

      看到这个错误,那一定是账号或者密码配置错误了,具体检查。通常最简单的办法就是删除配置的,仔细、细心的重新配置一个。

    • 2、如果使用的期货公司是FMZ没有支持看穿式认证的期货公司,也会无法通过期货公司前置机认证,导致报错。

    • 3、如果错误登录次数过多,例如用错误密码一直尝试登录,期货公司系统会禁止登录。

  • 实践一下

    可以配置一下自己的期货公司账户到FMZ平台,然后使用本篇中展示所有合约品种的策略代码,运行起来一个实盘。

    在FMZ控制中心页面,点击策略库,跳转到策略库页面。再点击新建策略按钮,跳转至新建策略页面。

    然后到控制中心页面,点击实盘,跳转到实盘页面。再点击创建实盘按钮,跳转到实盘创建页面。

    往下看,到页面下部。

    一个实盘策略就创建好了,这个策略会以表格形式显示所有的期货交易品种。我们在实盘页面添加上的这个“华泰期货次席(看穿式监管)”在代码里具体对应的是什么呢?可能有的同学已经猜到,这个添加的 华泰期货次席(看穿式监管) 对应的就是代码里的交易所对象exchange

免责声明:信息仅供参考,不构成投资及交易建议。投资者据此操作,风险自担。
如果觉得文章对你有用,请随意赞赏收藏
相关推荐
相关下载
登录后评论
Copyright © 2019 宽客在线