资源加载中... loading...

CTA策略之商品期货黑色系多头择时策略

Author: 扫地僧, Date: 2021-10-26 14:37:39
Tags: 商品期货趋势My语言

一、摘要

最近大宗商品开始史无前例疯狂上涨模式,成为期货圈热门话题,不管是媒体还是国家监管层均有极大关注。对于交易者来说,在全球大宗商品持续通胀的情况下,择时做多就显得更有意义。本篇文章就以国内商品期货黑色系为标的,开发一个多头择时策略。

二、大宗商品上涨原因

为何最近大宗商品疯狂上涨,尤其是黑色系频繁上演涨停潮?综合各方观点来看,主要有以下几方面原因: 1、美元指数持续下跌 2020年新冠肺炎疫情暴发以来,美元指数持续下跌,而大宗商品是以美元计价的,持续的弱美元走势,间接推动了商品价格的上涨。

2、货币供应量 2020年疫情之后,全球主要经济体央行集体放水,尤其是美欧日三国M2同比增速超过20%,在各国央行宽松政策不变的情况下,市场通胀预期仍然强烈。

3、全球经济复苏 随着各国疫苗接种顺利,经济回暖,大宗商品需求反弹,全球制造业采购经理指数(PMI)持续扩张,制造业的复苏对工业品价格形成支撑。

三、美元指数与大宗商品

2021年与我们日常生活息息相关的上游物资,不知不觉均出现明显上涨。正如巴菲特所言这一切都拜美联储宽松的货币和财政政策所赐,由于疫情期间美国出台的一系列天量刺激措施,全球的经济复苏已经裹挟着通胀奔涌而来。 img 图片来源:新浪财经、东方财富

如图所示,上图是美元指数从2018年5月至今的数据,下图是大宗商品指数从2018年8月至今的数据,从图中可以看出,美元指数和大宗商品指数始终呈相反的走势。

大宗商品上涨是全球性问题,并不只是只有国内大宗商品价格上涨。而美元作为大宗商品标价用货币,两者关系大致上类似价格和需求量的关系,即大宗商品价格的变化通常与美元相反,通常美元指数下跌,大宗商品上涨。

四、货币供应量与费雪方程式

费雪方程式可以解释货币供应量、物价水平、国民收入之间的数量关系,公式如下:

MV=PQ

其中:

  • M:货币总量
  • V:货币周转速率
  • P:商品价格
  • Q:商品数量

由于疫情的出现,导致产品滞销,进而导致企业贷款需求减少,那么货币周转速率(V)就会降低,费雪方程式(MV=PQ)就会失去平衡(左边变小),如果不加以控制就会出现通货紧缩的风险,为了减缓费雪方程式左边的MV下降速度,全球主要央行采取的方法是开启印钞机,增大货币总量(M)应对。

而如今,疫情过后经济复苏,货币周转率(V)已经接近正常,但超发的货币(M)一时半会收不回来,导致费雪方程式(MV=PQ)又失去平衡(左边变大)。

那么既然费雪方程式(MV=PQ)是等式,相应的方程式右边也会变大,不是商品价格(P)变大,就是商品数量(Q)变大,或者同时变大。但是我们知道商品数量变大是需要一个过程的,是需要一定时间的,那么市场会启动自我修复,在商品数量(M)不可能立刻变大的情况下,只能是商品价格(P)变大。

综上尽管市场种种短期波动具有不确定性,但2021年可能是大宗商品牛市真正开始的一年。好了,话不多说,接下来我们就以国内商品期货黑色系为标的,开发一个多头择时策略。

五、策略逻辑及实现

商品期货黑色系多头择时策略是通过有针对性的对标历史数据、市场规律、交易模式等方面的分析,采用固定的、数量化的交易模式,来发掘其中的交易机会并实现盈利。该策略以优宽(youquant.com)量化的MY语言来实现交易策略的具体实施。具体策略逻辑为:

  • 计算前4根K线最高价与开盘价的差的均值
  • 计算HO1、HO2、HO3、HO4均值
  • 计算多头开仓信号
  • 计算多头平仓信号
  • 下单交易

第1步:计算前4根K线最高价与开盘价的差的均值

HO1 := REF(H, 1) - REF(O, 1);
HO2 := REF(H, 2) - REF(O, 2);
HO3 := REF(H, 3) - REF(O, 3);
HO4 := REF(H, 4) - REF(O, 4);
HTO := (HO1 + HO2 + HO3 + HO4) / 4;

第2步:计算HO1、HO2、HO3、HO4均值

LINE := O - HTO * N;

第3步:计算多头开仓信号

D1 := REF(C, 1) < REF(C, 2);
D2 := REF(C, 2) < REF(C, 3);
D3 := REF(C, 3) < REF(C, 4);
D := D1 && D2 && D3 && C > LINE;

第4步:计算多头平仓信号

K1 := REF(C, 1) > REF(C, 2);
K2 := REF(C, 2) > REF(C, 3);
K3 := REF(C, 3) > REF(C, 4);
K := K1 && K2 && K3 && C <= LINE;
T1 := BARSLAST(BARSLAST(K) < BARSLAST(D));
DT := IFELSE(T1 <= REF(T1, 1), 0, (C - VALUEWHEN(T1 = 1, C)));

第5步:下单交易

D, BK;
T1 < 5 && T1 > 3 && DT < 7, SP;

六、策略回测

  • 回测开始日期:2015-02-22
  • 回测结束日期:2021-05-12
  • 数据品种:螺纹钢指数
  • 数据周期:日线
  • 滑点:开平仓各2跳

回测配置 img

回测绩效 img

资金曲线 img


(*backtest
start: 2015-02-22 00:00:00
end: 2021-05-07 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]
args: [["ContractType","rb000",126961]]
*)

HO1 := REF(H, 1) - REF(O, 1);
HO2 := REF(H, 2) - REF(O, 2);
HO3 := REF(H, 3) - REF(O, 3);
HO4 := REF(H, 4) - REF(O, 4);
HTO := (HO1 + HO2 + HO3 + HO4) / 4;
LINE := O - HTO * N;
D1 := REF(C, 1) < REF(C, 2);
D2 := REF(C, 2) < REF(C, 3);
D3 := REF(C, 3) < REF(C, 4);
D := D1 && D2 && D3 && C > LINE;
K1 := REF(C, 1) > REF(C, 2);
K2 := REF(C, 2) > REF(C, 3);
K3 := REF(C, 3) > REF(C, 4);
K := K1 && K2 && K3 && C <= LINE;
T1 := BARSLAST(BARSLAST(K) < BARSLAST(D));
DT := IFELSE(T1 <= REF(T1, 1), 0, (C - VALUEWHEN(T1 = 1, C)));
D, BK;
T1 < 5 && T1 > 3 && DT < 7, SP;
template: strategy.tpl:40:21: executing "strategy.tpl" at <.api.GetStrategyListByName>: wrong number of args for GetStrategyListByName: want 7 got 6