套利的没有想象中那么复杂,它不需要太多的金融理论知识,也不需要太过复杂的数学或统计模型,套利本质上就是赚取价格从不合理到回归合理之间的利润而已。 00:0000:00 一、摘要 可能有人对“套利”这个词很陌生,但“套利”在现实生活中却很常见。比如:便利店老板从批发市场以 0.5 元买入一瓶矿泉水,然后在店里以 1 元的价格出售,最后赚取 0.5 元的差价。这个过程其实就类似套利。金融市场上的套利跟这个道理差不多,只不过套利的形式有多种多样。 二、什么是套利 在商品期货市场中,理论上 5 月份交割的苹果合约价格减去 10 月交割的苹果合约价格,其结果应该接近于 0 或者稳定在一定的价格区间内。但事实上由于受到天气、市场供需等诸多因素的原因,近期和远期合约价格在一段时间内会分别受到不同程度的影响,价差也会出现较大幅度的波动。 除了跨期套利外,还有买入出口国大豆同时卖出进口国大豆,或者卖出出口国大豆同时买入进口国大豆的跨市场套利;买入上游原材料铁矿石同时卖出下游成品螺纹钢,或者卖出上游原材料铁矿石同时买入下游成品螺纹钢的跨品种套利等等。 三、什么是期现套利 但是上面这几种套利方法,虽然字面上是“套利”,并不属于纯粹意义上的套利,它们本质上还是属于有风险的投机,只不过这种投机的方式是做多或做空价差。虽然价差在大部分时间内趋于稳定,但也可能出现很长时间不回归的行情。 期现套利最大的特点是理论上无风险,主要是根据基差状态,计算利润区间。如果基差过大,就可以买入现货,同时做空期货,等待基差重新归零,就可以期货和现货双边平仓,赚取基差的利润。主要有两种方法:双平套利和交割套利。 四、商品期现套利通道 说起来简单,最复杂的一个环节是商品现货交易,这其中涉及到仓单、税务等等一系列问题。首先需要一个与投资范围相关的公司,如果是交割套利期货账户必须是公司法人的,如果双平套利就需要一个可靠的销售渠道。网上有很多现货交易的网站,如:卓创网、上海有色网等等。 需要注意的是,现货交易通常有 17%~20%的增值税,所以如果是双平套利,在买入现货后需要做空 1.2~1.25 倍的期货。如果是交割套利,在买入现货后需要做空相同比例的期货,还需要考虑手续费、运输、仓库等成本。当然这一切的前提是期现的基差足够大,有足够的边界。 五、如何获取现货、基差数据 现货和基差的数据网上有很多种,大部分是以表格的形式呈现,这显然不合适用来分析判断行情。发明者量化(FMZ.COM)已经内置了商品期货基本面数据,包括现货数据和基差数据。只需要调用一个函数就可以获取每个品种的现货和基差价格,并且支持 2016 年至今的历史数据。 # 回测配置 '''backtest start: 2020-06-01 00:00:00 end: 2020-06-02 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] ''' # 策略入口 def main(): while True: ret = exchange.GetData("GDP") # 调用国内生产总值数据 Log(ret) # 打印数据 Sleep(1000 * 60 * 60 * 24 * 30) 返回结果 { "季度": "2006年第1季度", "国内生产总值": { "绝对值(亿元)": 47078.9, "同比增长": 0.125 }, "第一产业": { "绝对值(亿元)": 3012.7, "同比增长": 0.044 }, "第三产业": { "绝对值(亿元)": 22647.4, "同比增长": 0.131 }, "第二产业": { "绝对值(亿元)": 21418.7, "同比增长": 0.131 } } 六、现货和基差图表实现 让我们用发明者量化,以图表的形式,把现货价格和基差价格实现出来。首先注册并登陆发明者量化官网(FMZ.COM),点击控制中心,点击策略库+新建策略。在左上角下拉菜单中选择 Python,并填入策略的名字。 第一步:编写策略框架 # 策略主函数 def onTick(): pass # 策略入口 def main(): while True: # 进入循环模式 onTick() # 执行策略主函数 Sleep(1000 * 60 * 60 * 24) # 策略休眠一天 策略框架是两个函数,main 函数是策略的入口,主要功能是交易之前的预处理,程序会先从 main 函数开始执行,然后进入无线循环模式,重复执行 onTick 函数,onTick 函数是策略的主函数,主要执行核心代码。 第二步:增加图表功能 # 全局变量 # 期现图表 cfgA = { "extension": { "layout": 'single', "col": 6, "height": "500px", }, "title": { "text": "期现图表" }, "xAxis": { "type": "datetime" }, "series": [{ "name": "期货价格", "data": [], }, { "name": "现货价格", "data": [], } ] } # 基差图表 cfgB = { "extension": { "layout": 'single', "col": 6, "height": "500px", }, "title": { "text": "基差图表" }, "xAxis": { "type": "datetime" }, "series": [{ "name": "基差价格", "data": [], }] } chart = Chart([cfgA, cfgB]) # 创建一个图表对象 # 策略主函数 def onTick(): chart.add(0, []) # 绘制图表 chart.add(1, []) # 绘制图表 chart.add(2, []) # 绘制图表 chart.update([cfgA, cfgB]) # 更新图表 # 策略入口 def main(): LogReset() # 运行前先清空之前的Log日志信息 chart.reset() # 运行前先清空之前的图表信息 while True: # 进入循环模式 onTick() # 执行策略主函数 Sleep(1000 * 60 * 60 * 24) # 策略休眠一天 在这个策略中,一共创建了 2 个图表,并左右分布排列。其中左图 cfgA 是期现图表,包含期货价格和现货价格,右图 cfgB 是基差图表。然后调用发明者量化内置的 Python 版画线类库创建一个 chart 对象。最后是在 onTick 函数中实时更新图表中的数据。 第三步:获取数据 last_spot_price = 0 # 保存最后一个有效的现货价格 last_basis_price = 0 # 保存最后一个有效的基差价格 def onTick(): global last_basis_price, last_spot_price # 导入全局变量 exchange.SetContractType("i888") # 订阅期货品种 futures = _C(exchange.GetRecords)[-1] # 获取最新K线数据 futures_ts = futures.Time # 获取最新K线期货时间戳 futures_price = futures.Close # 获取最新K线收盘价 spot = exchange.GetData("SPOTPRICE") # 获取现货数据 spot_ts = spot.Time # 获取现货时间戳 if '铁矿石' in spot.Data: spot_price = spot.Data['铁矿石'] last_spot_price = spot_price else: spot_price = last_spot_price basis = exchange.GetData("BASIS") # 获取基差数据 basis_ts = basis.Time # 获取基差时间戳 if '铁矿石' in basis.Data: basis_price = basis.Data['铁矿石'] last_basis_price = basis_price else: basis_price = last_basis_price 我们一共需要获取三种数据:期货价格、现货价格、基差价格。获取期货价格很简单,直接使用 SetContractType 函数订阅期货品种,再使用 GetRecords 函数就可以获取 K 线的收盘价。现货和基差的价格,可以使用之前介绍的方法,使用 GetData 函数调用基本面数据代码,返回的是包含时间戳的字典数据。 七、图表展示 八、获取完整策略代码 # fmz@b72930603791887d7452f25f23a13bde '''backtest start: 2017-01-01 00:00:00 end: 2020-06-01 00:00:00 period: 1d basePeriod: 1d exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] ''' # 全局变量 # 期现图表 cfgA = { "extension": { "layout": 'single', "col": 6, "height": "500px", }, "title": { "text": "期现图表" }, "xAxis": { "type": "datetime" }, "series": [{ "name": "期货价格", "data": [], }, { "name": "现货价格", "data": [], } ] } # 基差图表 cfgB = { "extension": { "layout": 'single', "col": 6, "height": "500px", }, "title": { "text": "基差图表" }, "xAxis": { "type": "datetime" }, "series": [{ "name": "基差价格", "data": [], }] } last_spot_price = 0 # 保存最后一个有效的现货价格 last_basis_price = 0 # 保存最后一个有效的基差价格 chart = Chart([cfgA, cfgB]) # 创建一个图表对象 def onTick(): global last_basis_price, last_spot_price # 导入全局变量 exchange.SetContractType("i888") # 订阅期货品种 futures = _C(exchange.GetRecords)[-1] # 获取最新K线数据 futures_ts = futures.Time # 获取最新K线期货时间戳 futures_price = futures.Close # 获取最新K线收盘价 Log('期货价格:', futures_ts, futures_price) spot = exchange.GetData("SPOTPRICE") # 获取现货数据 spot_ts = spot.Time # 获取现货时间戳 if '铁矿石' in spot.Data: spot_price = spot.Data['铁矿石'] last_spot_price = spot_price else: spot_price = last_spot_price Log('现货价格:', spot_ts, spot_price) basis = exchange.GetData("BASIS") # 获取基差数据 basis_ts = basis.Time # 获取基差时间戳 if '铁矿石' in basis.Data: basis_price = basis.Data['铁矿石'] last_basis_price = basis_price else: basis_price = last_basis_price Log('基差价格:', basis_ts, basis_price) chart.add(0, [futures_ts, futures_price]) # 绘制图表 chart.add(1, [spot_ts, spot_price]) # 绘制图表 chart.add(2, [basis_ts, basis_price]) # 绘制图表 chart.update([cfgA, cfgB]) # 更新图表 Log('---------') # 策略入口 def main(): LogReset() # 运行前先清空之前的Log日志信息 chart.reset() # 运行前先清空之前的图表信息 while True: # 进入循环模式 onTick() # 执行策略主函数 Sleep(1000 * 60 * 60 * 24) # 策略休眠一天 完整策略已经发布到发明者量化(FMZ.COM)的策略广场,或者可以点下下方链接直接使用。 九、结尾 套利的没有想象中那么复杂,它不需要太多的金融理论知识,也不需要太过复杂的数学或统计模型,套利本质上就是赚取价格从不合理到回归合理之间的利润而已。市场行情每年都在变化,对于交易者而言,最好不要把历史数据完全照搬到现在,而是结合当下数据研究基差是否合理。 本文来源:发明者量化 —- 编译者/作者:发明者量化 玩币族申明:玩币族作为开放的资讯翻译/分享平台,所提供的所有资讯仅代表作者个人观点,与玩币族平台立场无关,且不构成任何投资理财建议。文章版权归原作者所有。 |
基于发明者量化基本面数据的商品期现套利图表
2020-07-20 发明者量化 来源:火星财经
- 上一篇:ETH正在为重大举措做准备,但很可能回落至200美元
- 下一篇:计数员王纯|超级君
相关阅读:
- 比特币期货/合约对目前市场的影响2020-08-02
- 比特币期货交易员押注看涨价格行动,但步伐并不快2020-08-01
- 随着OI激增,BitMEX在衍生品交易所中领先2020-08-01
- $ 1.2B比特币期货和期权合约刚刚到期—接下来是什么?2020-08-01
- Bkkt飙升的BTC期货交易2020-08-01