基于市场资金流向分析的 Suibian 期货策略
摘要
1 问题重述
1.1 问题重述
2 符号说明及名字定义
3 问题分析与求解
3.1 资金流向指标的定义
3.2 持仓量、成交量和价格的关系
3.3 基于资金流模型的期货量化策略设计
3.3.1 策略概况
3.3.2 计算因子的构建
3.3.3 入场条件
3.3.4 加仓条件
3.3.5 平仓(止盈止损)条件
3.3.6 策略绩效
4 参考文献
5 附录
资金流向是一个成熟的技术指标,能帮助投资者透过价格涨跌的迷雾看到其他投资者的行为。而由于期货市场上有做空机制,所以无法直接采用股票市场的资金流向公式。因此需要从持仓量、成交量、当前价格涨跌等因素来看期货的资金流向。
本文工作主要是包括三个方面:
(1)运用分钟级的持仓量的变化定义期货资金流向指标。
(2)由 10 种持仓量、成交量与当前价格变化的关系图总结出对应未来一段时间的价格走势,以此分析当前市场的买卖双方力量和总结出这些情况对应的期货价格走势。
(3)用这 10 种持仓量、成交量与价格的关系改进海龟策略的计算因子以及开仓、加仓、平仓的触发条件,随后生成一个新的 Suibian 策略,并对活跃的商品期货进行回测,选定年化收益率高和回撤率低的商品期货进行组合投资。最后,生成策略报告。
【关键字】 持仓量 成交量 资金流模型 海龟策略 Suibian 策略
使用 2011 年 1 月 1 日至 2013 年 12 月 31 日的商品期货历史数据,构造资金流模型,分析资金流向规律,以此设计一个商品期货量化交易策略,并使用 Auto-Trader 回测引擎对 2014 年 1 月 1 日至 2015 年 12 月 31 日的数据进行策略回测。
问题 1 要求我们根据分钟级的 K 线数据构造资金流向模型。资金的流向和资金的流量。是一个成熟的技术指标。由于期货市场有做空的机制,交易者可以是买入者也可以是卖空者,买入和卖空一首期货都属于持仓和资金的流入。但是,卖空者若大量卖空期货,持仓量和成交量均上升,资金流入而期货价格却下跌。因此,用交易价格的张得是无法直接界定资金的流入或是流出的。
这里,我们可以根据持仓量的变化定义资金流指标。持仓量越大,该期货合约到期前平仓交易和实物交割量的总和就越大,成交量也就越大。因此,分析持仓量的变化可推测资金在期货市场的流向。持仓量增加,表明资金流入期货市场,持仓量减少,表明资金流出期货市场。
下面建立基于持仓量之差的资金流向模型:
T 时刻的资金流:
M o n e y F l o w T = O p e n i n t e r e s t T − O p e n i n t e r e s t T − 1 Money \ Flow_T = Openinterest_T-Openinterest_{T-1} Money FlowT=OpeninterestT−OpeninterestT−1
O p e n i n t e r e s t T Openinterest_T OpeninterestT表示第 T T T 时刻的持仓量, T T T 时刻持仓量与 T − 1 T-1 T−1 时刻持仓量只差即为资金流;
若 Money Flow>0,则表示 T 时刻持仓量大于 T-1 时刻的持仓量,即总体表现为资金流入;
若 Money Flow<0,则表示 T 时刻持仓量大于 T-1 时刻的持仓量,即总体表现为资金流出;
若 Money Flow=0,则表示 T 时刻持仓量等于 T-1 时刻的持仓量,即资金流入与资金流出相抵消,总体表现为资金流不变。
问题 2 要求我们分析资金流向对未来商品期货的价格的影响。
在此,我们总结了持仓量和成交量之间的关系,以及成交量、持仓量和现在价格的变化对未来期货价格变化的影响的 8 中情况:
期货市场中的持仓量与成交量之间的关系:
· 买入者和卖空者同时入市时,持仓量会增加,成交量增加
· 买卖双方有一方做平仓交易时,持仓量不变,成交量增加
· 买卖双方均做平仓交易时,持仓量下降,成交量增加
情况 1:
从图中可以观察出,1-5 分钟内,价格上涨,持仓量增加,后 5-10 分钟内,第 5-7 分钟的价格是上涨的,由此说明前五分钟内,新买方正在大量收购,市场看涨,未来一段时间内价格会继续上涨。
情况 2:
1-5 分钟的持仓量增加,成交量在上升,价格却下跌,而后面的 5-10分钟内,第 5-7 分钟的价格显示出下跌的趋势,由此可以得出,前五分钟内,新卖空方正在大量补仓,市场看跌,未来一段时间内的价格仍会继续下跌。
1-5 分钟的成交量、持仓量和价格均下跌,后 5-10 分钟的价格显现下跌的趋势,但是趋势比前五分钟较缓和。由此可以得出,前五分钟内,买卖双方均在平仓,买入者正在平仓止损,卖空者在进行获利了结,但是成交量减少,说明新的卖空者并没有增加,未来一段时间内的跌势会缓和。
1-5 分钟的价格随成交量、持仓量下跌而上涨,后 5-10 分钟的价格仍然继续上涨,但是趋势比前五分钟较缓和。由此可以得出,前五分钟内,买卖双方均在平仓,买入者正在进行获利了结,卖空者在平仓止损,但是成交量减少,说明新的买入者并没有增加,未来一段时间内的涨势会缓和。
1-5 分钟的持仓量和价格都在增加,而成交量却下降,后 5-10 分钟的价格仍然继续上涨(左图)或转为下跌(右图),而且来势凶猛。由此可以得出,前五分钟内,买卖双方看法分歧加大,资金对抗逐步升级,而且对抗结果并未明朗,并且处于一种动态平衡状况,成交量逐步减少,等待最后的突破。所以在未来一段时间,价格有可能急剧上升或者急剧下降,很少有假突破发生。
1-5 分钟的价格随成交量上涨、持仓量下跌而上涨,后 5-10 分钟内,由前五分钟的上涨转为下跌。由此可以得出,前五分钟内,买卖双方均在平仓,而此时价格上涨,说明是卖空者在平仓止损而买多者在进行获利了结,未来价格会由上涨转为下跌。
情况 7:
1-5 分钟的价格随成交量下跌、持仓量上涨而下跌,后 5-10 分钟内,从 第 5-9 分钟,价格的下跌转为急剧上升(左图)获价格由前五分钟的下跌变成急剧下跌。由此可以得出,前五分钟内,由于买卖双方看法分歧加大,资金对抗逐步升级,使得持仓量上升,而且对抗结果并未明朗,并且处于一种动态平衡状况,成交量逐步减少,双方都在等待最后的突破。所以在未来一段时间,价格有可能急剧上升或者急剧下降,很少有假突破发生。
1-5 分钟的价格随成交量上涨而下跌,成交量上涨,后 5-10 分钟的价格由之前的下跌转为上涨。由此可以得出,前五分钟内,买卖双方均在平仓,买方平仓止损,卖方进行获利了结,说明未来价格会反转上升。
利用上文提及的资金流模型(即持仓量、成交量、当前价格与未来价格之间的八种关系)对海龟策略的入场、平仓、加仓和计算因子进行改进,得到一个新的期货量化策略:
利用分钟级 K 线数据,根据上述总结出的 10 种情况构造计算因子。选取 7 分钟的持仓量、成交量、价格数据,定义触发条件:
Value=1(买多):
{ V o l u m e 5 − V o l u m e 1 > 0 O p e n i n t e r e s t 5 − O p e n i n t e r e s t 1 > 0 C l o s e 5 − C l o s e 1 > 0 \left\{ \begin{aligned} Volume_5-Volume_1>0 \\ Openinterest_5-Openinterest_1>0\\ Close_5-Close_1>0 \end{aligned} \right. ⎩⎪⎨⎪⎧Volume5−Volume1>0Openinterest5−Openinterest1>0Close5−Close1>0
或
{ V o l u m e 5 − V o l u m e 1 < 0 O p e n i n t e r e s t 5 − O p e n i n t e r e s t 1 < 0 C l o s e 5 − C l o s e 1 > 0 \left\{ \begin{aligned} Volume_5-Volume_1<0 \\ Openinterest_5-Openinterest_1<0\\ Close_5-Close_1>0 \end{aligned} \right. ⎩⎪⎨⎪⎧Volume5−Volume1<0Openinterest5−Openinterest1<0Close5−Close1>0
或
{ V o l u m e 5 − V o l u m e 1 > 0 O p e n i n t e r e s t 5 − O p e n i n t e r e s t 1 < 0 C l o s e 5 − C l o s e 1 < 0 \left\{ \begin{aligned} Volume_5-Volume_1>0 \\ Openinterest_5-Openinterest_1<0\\ Close_5-Close_1<0 \end{aligned} \right. ⎩⎪⎨⎪⎧Volume5−Volume1>0Openinterest5−Openinterest1<0Close5−Close1<0
或
{ V o l u m e 5 − V o l u m e 1 < 0 O p e n i n t e r e s t 5 − O p e n i n t e r e s t 1 > 0 C l o s e 5 − C l o s e 1 > 0 C l o s e 7 − C l o s e 5 > 0 \left\{ \begin{aligned} Volume_5-Volume_1<0 \\ Openinterest_5-Openinterest_1>0\\ Close_5-Close_1>0\\ Close_7-Close_5>0 \end{aligned} \right. ⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧Volume5−Volume1<0Openinterest5−Openinterest1>0Close5−Close1>0Close7−Close5>0
或
{ V o l u m e 5 − V o l u m e 1 < 0 O p e n i n t e r e s t 5 − O p e n i n t e r e s t 1 > 0 C l o s e 5 − C l o s e 1 < 0 C l o s e 7 − C l o s e 5 > 0 \left\{ \begin{aligned} Volume_5-Volume_1<0 \\ Openinterest_5-Openinterest_1>0\\ Close_5-Close_1<0\\ Close_7-Close_5>0 \end{aligned} \right. ⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧Volume5−Volume1<0Openinterest5−Openinterest1>0Close5−Close1<0Close7−Close5>0
Value=-1(卖空):
{ V o l u m e 5 − V o l u m e 1 > 0 O p e n i n t e r e s t 5 − O p e n i n t e r e s t 1 > 0 C l o s e 5 − C l o s e 1 < 0 \left\{ \begin{aligned} Volume_5-Volume_1>0 \\ Openinterest_5-Openinterest_1>0\\ Close_5-Close_1<0 \end{aligned} \right. ⎩⎪⎨⎪⎧Volume5−Volume1>0Openinterest5−Openinterest1>0Close5−Close1<0
或
{ V o l u m e 5 − V o l u m e 1 < 0 O p e n i n t e r e s t 5 − O p e n i n t e r e s t 1 < 0 C l o s e 5 − C l o s e 1 < 0 \left\{ \begin{aligned} Volume_5-Volume_1<0 \\ Openinterest_5-Openinterest_1<0\\ Close_5-Close_1<0 \end{aligned} \right. ⎩⎪⎨⎪⎧Volume5−Volume1<0Openinterest5−Openinterest1<0Close5−Close1<0
或
{ V o l u m e 5 − V o l u m e 1 > 0 O p e n i n t e r e s t 5 − O p e n i n t e r e s t 1 < 0 C l o s e 5 − C l o s e 1 > 0 \left\{ \begin{aligned} Volume_5-Volume_1>0 \\ Openinterest_5-Openinterest_1<0\\ Close_5-Close_1>0 \end{aligned} \right. ⎩⎪⎨⎪⎧Volume5−Volume1>0Openinterest5−Openinterest1<0Close5−Close1>0
或
{ V o l u m e 5 − V o l u m e 1 < 0 O p e n i n t e r e s t 5 − O p e n i n t e r e s t 1 > 0 C l o s e 5 − C l o s e 1 > 0 C l o s e 7 − C l o s e 5 < 0 \left\{ \begin{aligned} Volume_5-Volume_1<0 \\ Openinterest_5-Openinterest_1>0\\ Close_5-Close_1>0\\ Close_7-Close_5<0 \end{aligned} \right. ⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧Volume5−Volume1<0Openinterest5−Openinterest1>0Close5−Close1>0Close7−Close5<0
或
{ V o l u m e 5 − V o l u m e 1 < 0 O p e n i n t e r e s t 5 − O p e n i n t e r e s t 1 > 0 C l o s e 5 − C l o s e 1 < 0 C l o s e 7 − C l o s e 5 < 0 \left\{ \begin{aligned} Volume_5-Volume_1<0 \\ Openinterest_5-Openinterest_1>0\\ Close_5-Close_1<0\\ Close_7-Close_5<0 \end{aligned} \right. ⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧Volume5−Volume1<0Openinterest5−Openinterest1>0Close5−Close1<0Close7−Close5<0
对于之前时段均没有仓位的账户而言,当计算因子 value=1 时买多,计算因子 value=-1 时卖空。
计算因子定义:
Value=1(买多):
{ V o l u m e 5 − 1.05 × V o l u m e 1 > 0 O p e n i n t e r e s t 5 − 1.05 × O p e n i n t e r e s t 1 > 0 C l o s e 5 − 1.05 × C l o s e 1 > 0 \left\{ \begin{aligned} Volume_5-1.05 \times Volume_1>0 \\ Openinterest_5-1.05 \times Openinterest_1>0\\ Close_5-1.05 \times Close_1>0 \end{aligned} \right. ⎩⎪⎨⎪⎧Volume5−1.05×Volume1>0Openinterest5−1.05×Openinterest1>0Close5−1.05×Close1>0
或
{ V o l u m e 5 − 1.05 × V o l u m e 1 < 0 O p e n i n t e r e s t 5 − 1.05 × O p e n i n t e r e s t 1 < 0 1.05 × C l o s e 5 − C l o s e 1 > 0 \left\{ \begin{aligned} Volume_5-1.05 \times Volume_1<0 \\ Openinterest_5-1.05 \times Openinterest_1<0\\ 1.05 \times Close_5-Close_1>0 \end{aligned} \right. ⎩⎪⎨⎪⎧Volume5−1.05×Volume1<0Openinterest5−1.05×Openinterest1<01.05×Close5−Close1>0
或
{ 1.05 × V o l u m e 5 − V o l u m e 1 > 0 O p e n i n t e r e s t 5 − 1.05 × O p e n i n t e r e s t 1 < 0 C l o s e 5 − 1.05 × C l o s e 1 < 0 \left\{ \begin{aligned} 1.05 \times Volume_5-Volume_1>0 \\ Openinterest_5-1.05 \times Openinterest_1<0\\ Close_5-1.05 \times Close_1<0 \end{aligned} \right. ⎩⎪⎨⎪⎧1.05×Volume5−Volume1>0Openinterest5−1.05×Openinterest1<0Close5−1.05×Close1<0
或
{ V o l u m e 5 − 1.05 × V o l u m e 1 < 0 1.05 × O p e n i n t e r e s t 5 − O p e n i n t e r e s t 1 > 0 1.05 × C l o s e 5 − C l o s e 1 > 0 1.05 × C l o s e 7 − C l o s e 5 > 0 \left\{ \begin{aligned} Volume_5-1.05 \times Volume_1<0 \\ 1.05 \times Openinterest_5-Openinterest_1>0\\ 1.05 \times Close_5-Close_1>0\\ 1.05 \times Close_7-Close_5>0 \end{aligned} \right. ⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧Volume5−1.05×Volume1<01.05×Openinterest5−Openinterest1>01.05×Close5−Close1>01.05×Close7−Close5>0
或
{ V o l u m e 5 − 1.05 × V o l u m e 1 < 0 1.05 × O p e n i n t e r e s t 5 − O p e n i n t e r e s t 1 > 0 C l o s e 5 − 1.05 × C l o s e 1 < 0 1.05 × C l o s e 7 − C l o s e 5 > 0 \left\{ \begin{aligned} Volume_5-1.05 \times Volume_1<0 \\ 1.05 \times Openinterest_5-Openinterest_1>0\\ Close_5-1.05 \times Close_1<0\\ 1.05 \times Close_7-Close_5>0 \end{aligned} \right. ⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧Volume5−1.05×Volume1<01.05×Openinterest5−Openinterest1>0Close5−1.05×Close1<01.05×Close7−Close5>0
Value=-1(卖空):
{ 1.05 × V o l u m e 5 − V o l u m e 1 > 0 1.05 × O p e n i n t e r e s t 5 − O p e n i n t e r e s t 1 > 0 C l o s e 5 − 1.05 × C l o s e 1 < 0 \left\{ \begin{aligned} 1.05 \times Volume_5-Volume_1>0 \\ 1.05 \times Openinterest_5-Openinterest_1>0\\ Close_5-1.05 \times Close_1<0 \end{aligned} \right. ⎩⎪⎨⎪⎧1.05×Volume5−Volume1>01.05×Openinterest5−Openinterest1>0Close5−1.05×Close1<0
或
{ V o l u m e 5 − 1.05 × V o l u m e 1 < 0 O p e n i n t e r e s t 5 − 1.05 × O p e n i n t e r e s t 1 < 0 C l o s e 5 − 1.05 × C l o s e 1 < 0 \left\{ \begin{aligned} Volume_5-1.05 \times Volume_1<0 \\ Openinterest_5-1.05 \times Openinterest_1<0\\ Close_5-1.05 \times Close_1<0 \end{aligned} \right. ⎩⎪⎨⎪⎧Volume5−1.05×Volume1<0Openinterest5−1.05×Openinterest1<0Close5−1.05×Close1<0
或
{ 1.05 × V o l u m e 5 − V o l u m e 1 > 0 O p e n i n t e r e s t 5 − 1.05 × O p e n i n t e r e s t 1 < 0 1.05 × C l o s e 5 − C l o s e 1 > 0 \left\{ \begin{aligned} 1.05 \times Volume_5-Volume_1>0 \\ Openinterest_5-1.05 \times Openinterest_1<0\\ 1.05 \times Close_5-Close_1>0 \end{aligned} \right. ⎩⎪⎨⎪⎧1.05×Volume5−Volume1>0Openinterest5−1.05×Openinterest1<01.05×Close5−Close1>0
或
{ V o l u m e 5 − 1.05 × V o l u m e 1 < 0 1.05 × O p e n i n t e r e s t 5 − O p e n i n t e r e s t 1 > 0 1.05 × C l o s e 5 − C l o s e 1 > 0 C l o s e 7 − 1.05 × C l o s e 5 < 0 \left\{ \begin{aligned} Volume_5-1.05 \times Volume_1<0 \\ 1.05 \times Openinterest_5-Openinterest_1>0\\ 1.05 \times Close_5-Close_1>0\\ Close_7-1.05 \times Close_5<0 \end{aligned} \right. ⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧Volume5−1.05×Volume1<01.05×Openinterest5−Openinterest1>01.05×Close5−Close1>0Close7−1.05×Close5<0
或
{ V o l u m e 5 − 1.05 × V o l u m e 1 < 0 1.05 × O p e n i n t e r e s t 5 − O p e n i n t e r e s t 1 > 0 C l o s e 5 − 1.05 × C l o s e 1 < 0 C l o s e 7 − 1.05 × C l o s e 5 < 0 \left\{ \begin{aligned} Volume_5-1.05 \times Volume_1<0 \\ 1.05 \times Openinterest_5-Openinterest_1>0\\ Close_5-1.05 \times Close_1<0\\ Close_7-1.05 \times Close_5<0 \end{aligned} \right. ⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧Volume5−1.05×Volume1<01.05×Openinterest5−Openinterest1>0Close5−1.05×Close1<0Close7−1.05×Close5<0
加仓条件:
当持有多仓,且当前 value=1 时,加多仓
当持有空仓,且当前 value=-1 时,加空仓
持有多仓时,当(开 盘价-收盘价 )>min(开盘价 × 0.08,1.5 ×加仓时的计算因子)时,把仓位调整到 0;
持有空仓时,当(开盘价-收盘价)>2× 空仓时的计算因子时,把仓位调整到 0。
利用 2014 年 1 月 1 日至 2015 年 12 月 31 日的数据,对活跃的商品期货进行回测,排序得出年化收益率排名最高的前 5 种商品期货:
由于这 5 种商品期货的夏普比率、calmar 比率、sortion 比率以及净利/最大潜在亏损等比率的结果都不错且接近,因此根据回撤率的高低再进行期货的组合。
由于其他指标都表现良好且接近,因此根据年化收益率高和回撤率低可挑选出热轧卷板+铁矿石+玻璃商品期货组合在本策略中的表现是最好的。因此,在本策略中,选取这三个商品期货作为标的,运行策略,得出总权益曲线和买入持有权益曲线的对比图:
总体交易策略分析:
[1] 成交量与持仓量的关系:http://blog.sina.com.cn/s/blog_0e61fdce0102vvbc.html
[2] 期货成交量与持仓量的关系:https://zhidao.baidu.com/question/553202487.html
[3] Digquant 社区链接:http://www.digquant.com.cn/
Suibian.m
function Suibian(bInit,bDayBegin,cellPar)%
global g_idxKDay;
global g_idxSignal;
global openPrice;
global addTime;
global TLen;
M = cellPar{
1};
N=cellPar{
2};
LimitTime=cellPar{
3};
if bInit
traderSetParalMode(false);%默认是 true,因子计算函数并行执行,速度快,不
能调试,false 串行执行可以设断点调试
g_idxKDay = traderRegKData('min',1);%扩充低频数据。回测开始时点向前扩充 1
天的日线数据
TLen = length(g_idxKDay(:,1));
g_idxSignal = traderRegUserIndi(@getSignal,{
g_idxKDay,M,N});%注册用户自建的
外部因子。getSignal:因子计算的函数名。{
g_idxKDay,M,N}:函数入参
openPrice = nan(1,TLen);%返回 1*TLen 的 NaN 矩阵
addTime = nan(1,TLen);
else
dSignal = traderGetRegUserIndi(g_idxSignal,2);%根据已注册的用户自建因子序
列获取数据索引序列 2:序列长度,数值类型。例 120,表示返回从当前开始往前的
120 个数据序列。
mp=traderGetAccountPositionV2(1,1:TLen);%获得当前仓位信息。g_idxSignal:
账户句柄索引序列号,
%可以为单个数字或一个序列。如 3 表示序列中第三个,(2,10)表示第二个和
第十个,(3:7)表示从第三个到第七个。
%1:TLen:交易标的索引序列号,可以为单个数字或一个序列。如 3 表示序列中第三个,
(2,10)表示第二个和第十个,(3:7)表示从第三个到第七个。
buyList = [];
sellList = [];
datas = traderGetRegKData(g_idxKDay,1,false);%根据已注册的数据序列获取 K 线
数据;可通过此函数获取该时段内重要的价量数据。
%g_idxKDay:注册数据时返回的索引序列号 1:序列长度 false:不补齐
for i=1:TLen
dataDay = datas(8*(i-1)+1:8*i,:);% 每一天数据进行循环:
datas(1:8,:),datas(9:16,:)
% 数据长度足够;数据非空;当日的成交价不为 0;当日高收不同
if length(dSignal(i,:))~=2 || isempty(dataDay) || dataDay(6,end) ==0 ||
dataDay(3,end)- dataDay(4,end)==0
continue;
end
if mp(i)~=0
if isnan(openPrice(i))
openPrice(i) = dataDay(2,end);
end
if sign(mp(i))*(openPrice(i)-dataDay(5,end))> min(openPrice(i)*0.08,1.5*
dSignal(i+TLen,end)) ||...
sign(mp(i))*(dataDay(5,end)-openPrice(i))>2*dSignal(i+TLen,end)
traderPositionToV2(1,i,0,0,'market','close');%调仓到指定仓位。
%1:账户句柄索引序列号,可以为单个数字或一个序列。如 3 表示
序列中第三个,(2,10)表示第二个和第十个,(3:7)表示从第三个到第七个。
%i:交易标的索引序列号,可以为单个数字或一个序列。如 3 表示
序列中第三个,(2,10)表示第二个和第十个,(3:7)表示从第三个到第七个。
%0:目标仓位,如-5 表示调整至 5 手空单。
%0:价格,此处为下单价格
%market:下单价格类型,字符串格式,允许值如下:?’market’:
市价? ‘limit’:限价
%close:订单标记
elseif sign(mp(i))*(dataDay(5,end)-openPrice(i))>
min(openPrice(i)*0.08,1.5* dSignal(i+TLen,end))
openPrice(i) = dataDay(5,end);
end
end
if mp(i) ==0 %建仓
openPrice(i) = nan;
if dSignal(i,end-1)~=1 && dSignal(i,end)==1
buyList = [buyList,i];
addTime(i) =1;
elseif dSignal(i,end-1)~=-1 && dSignal(i,end)==-1
sellList = [sellList,i];
addTime(i) =1;
end
else %加仓
if mp(i)>0 && addTime(i)<LimitTime && dSignal(i+TLen,end-1) == 1 &&
dSignal(i+TLen,end) == 1
buyList = [buyList,i];
openPrice(i) = dataDay(5,end);
addTime(i) =1 + addTime(i);
elseif mp(i)<0 && addTime(i)<LimitTime && dSignal(i+TLen,end-1) == -1
&& dSignal(i+TLen,end) == -1
sellList = [sellList,i];
openPrice(i) = dataDay(5,end);
addTime(i) =1 + addTime(i);
end
end
end
if length(buyList)+ length(sellList) ==0
return
end
[ValidCash,MarketCap,~,~,~] =traderGetAccountInfoV2(1);%通过账户句柄索引序
列号获得账户当前资金情况。
coefs = traderGetFutureInfoV2(1:TLen);%获取期货信息,此处获取的是合约乘数
percash = min(ValidCash/(length(buyList)+ length(sellList)),MarketCap/TLen);
for t = 1: length(buyList)
coef =coefs(buyList(t));
price = max(dSignal(TLen+buyList(t),end)*100,datas(8*(buyList(t)-1)+5,end));
amount = floor(percash/coef/price/(2^(addTime(buyList(t))-1)));
if amount >=1
traderDirectBuyV2(1,buyList(t),amount,0,'market','buy1');%开多单
end
end
for t = 1: length(sellList)
coef = coefs(sellList(t));
price = max(dSignal(TLen+sellList(t),end)*100,datas(8*(sellList(t)-1)+5,end));
amount = floor(percash/coef/price/(2^(addTime(sellList(t))-1)));
if amount >=1
traderDirectSellV2(1,sellList(t),amount,0,'market','buy1');%开多单
end
end
end
end
function value=getSignal(cellPar,bpPFCell)
idxK =cellPar{
1};
M = cellPar{
2};
N = cellPar{
3};
[targetNum,~]=size(idxK);
value=nan(1,targetNum*2);
regKMatrixs = traderGetRegKData(idxK,15,false,bpPFCell);
for i = 1:targetNum
if (regKMatrixs(8+8*(i-1),end)>regKMatrixs(8+8*(i-1),end-4) &&
regKMatrixs(6+8*(i-1),end)>regKMatrixs(6+8*(i-1),end-4) &&
regKMatrixs(5+8*(i-1),end)>regKMatrixs(5+8*(i-1),end-4)) || ...
(regKMatrixs(8+8*(i-1),end)<regKMatrixs(8+8*(i-1),end-4) &&
regKMatrixs(6+8*(i-1),end)<regKMatrixs(6+8*(i-1),end-4) &&
regKMatrixs(5+8*(i-1),end)>regKMatrixs(5+8*(i-1),end-4))...
|| (regKMatrixs(8+8*(i-1),end)>regKMatrixs(8+8*(i-1),end-4) &&
regKMatrixs(6+8*(i-1),end)<regKMatrixs(6+8*(i-1),end-4) &&
regKMatrixs(5+8*(i-1),end)<regKMatrixs(5+8*(i-1),end-4))...
|| (regKMatrixs(8+8*(i-1),end-2)>regKMatrixs(8+8*(i-1),end-6) &&
regKMatrixs(6+8*(i-1),end-2)<regKMatrixs(6+8*(i-1),end-6) &&
regKMatrixs(5+8*(i-1),end-2)>regKMatrixs(5+8*(i-1),end-6) &&
regKMatrixs(5+8*(i-1),end)>regKMatrixs(5+8*(i-1),end-2))...
|| (regKMatrixs(8+8*(i-1),end-2)>regKMatrixs(8+8*(i-1),end-6) &&
regKMatrixs(6+8*(i-1),end-2)<regKMatrixs(6+8*(i-1),end-6) &&
regKMatrixs(5+8*(i-1),end-2)<regKMatrixs(5+8*(i-1),end-6) &&
regKMatrixs(5+8*(i-1),end)>regKMatrixs(5+8*(i-1),end-2))
value(i)=1;
elseif (regKMatrixs(8+8*(i-1),end)>regKMatrixs(8+8*(i-1),end-4) &&
regKMatrixs(6+8*(i-1),end)>regKMatrixs(6+8*(i-1),end-4) &&
regKMatrixs(5+8*(i-1),end)<regKMatrixs(5+8*(i-1),end-4))|| ...
(regKMatrixs(8+8*(i-1),end)<regKMatrixs(8+8*(i-1),end-4) &&
regKMatrixs(6+8*(i-1),end)<regKMatrixs(6+8*(i-1),end-4) &&
regKMatrixs(5+8*(i-1),end)<regKMatrixs(5+8*(i-1),end-4))...
|| (regKMatrixs(8+8*(i-1),end)>regKMatrixs(8+8*(i-1),end-4) &&
regKMatrixs(6+8*(i-1),end)<regKMatrixs(6+8*(i-1),end-4) &&
regKMatrixs(5+8*(i-1),end)>regKMatrixs(5+8*(i-1),end-4))...
|| (regKMatrixs(8+8*(i-1),end-2)>regKMatrixs(8+8*(i-1),end-6) &&
regKMatrixs(6+8*(i-1),end-2)<regKMatrixs(6+8*(i-1),end-6) &&
regKMatrixs(5+8*(i-1),end-2)>regKMatrixs(5+8*(i-1),end-6) &&
regKMatrixs(5+8*(i-1),end)<regKMatrixs(5+8*(i-1),end-2))...
|| (regKMatrixs(8+8*(i-1),end-2)>regKMatrixs(8+8*(i-1),end-6) &&
regKMatrixs(6+8*(i-1),end-2)<regKMatrixs(6+8*(i-1),end-6) &&
regKMatrixs(5+8*(i-1),end-2)<regKMatrixs(5+8*(i-1),end-6) &&
regKMatrixs(5+8*(i-1),end)<regKMatrixs(5+8*(i-1),end-2))
value(i)= -1;
end
if (regKMatrixs(8+8*(i-1),end)>1.05*regKMatrixs(8+8*(i-1),end-4) &&
regKMatrixs(6+8*(i-1),end)>1.05*regKMatrixs(6+8*(i-1),end-4) &&
regKMatrixs(5+8*(i-1),end)>1.05*regKMatrixs(5+8*(i-1),end-4)) || ...
(1.05*regKMatrixs(8+8*(i-1),end)<regKMatrixs(8+8*(i-1),end-4) &&
1.05*regKMatrixs(6+8*(i-1),end)<regKMatrixs(6+8*(i-1),end-4) &&
regKMatrixs(5+8*(i-1),end)>1.05*regKMatrixs(5+8*(i-1),end-4))...
|| (regKMatrixs(8+8*(i-1),end)>1.05*regKMatrixs(8+8*(i-1),end-4) &&
1.05*regKMatrixs(6+8*(i-1),end)<regKMatrixs(6+8*(i-1),end-4) &&
1.05*regKMatrixs(5+8*(i-1),end)<regKMatrixs(5+8*(i-1),end-4))...
|| (regKMatrixs(8+8*(i-1),end-2)>1.05*regKMatrixs(8+8*(i-1),end-6) &&
1.05*regKMatrixs(6+8*(i-1),end-2)<regKMatrixs(6+8*(i-1),end-6) &&
regKMatrixs(5+8*(i-1),end-2)>1.05*regKMatrixs(5+8*(i-1),end-6) &&
regKMatrixs(5+8*(i-1),end)>1.05*regKMatrixs(5+8*(i-1),end-2))...
|| (regKMatrixs(8+8*(i-1),end-2)>1.05*regKMatrixs(8+8*(i-1),end-6) &&
1.05*regKMatrixs(6+8*(i-1),end-2)<regKMatrixs(6+8*(i-1),end-6) &&
1.05*regKMatrixs(5+8*(i-1),end-2)<regKMatrixs(5+8*(i-1),end-6) &&
regKMatrixs(5+8*(i-1),end)>1.05*regKMatrixs(5+8*(i-1),end-2))
value(i + targetNum)=1;
elseif (regKMatrixs(8+8*(i-1),end)>1.05*regKMatrixs(8+8*(i-1),end-4) &&
regKMatrixs(6+8*(i-1),end)>1.05*regKMatrixs(6+8*(i-1),end-4) &&
1.05*regKMatrixs(5+8*(i-1),end)<regKMatrixs(5+8*(i-1),end-4))|| ...
(1.05*regKMatrixs(8+8*(i-1),end)<regKMatrixs(8+8*(i-1),end-4) &&
1.05*regKMatrixs(6+8*(i-1),end)<regKMatrixs(6+8*(i-1),end-4) &&
1.05*regKMatrixs(5+8*(i-1),end)<regKMatrixs(5+8*(i-1),end-4))...
|| (regKMatrixs(8+8*(i-1),end)>1.05*regKMatrixs(8+8*(i-1),end-4) &&
1.05*regKMatrixs(6+8*(i-1),end)<regKMatrixs(6+8*(i-1),end-4) &&
regKMatrixs(5+8*(i-1),end)>1.05*regKMatrixs(5+8*(i-1),end-4))...
|| (regKMatrixs(8+8*(i-1),end-2)>1.05*regKMatrixs(8+8*(i-1),end-6) &&
1.05*regKMatrixs(6+8*(i-1),end-2)<regKMatrixs(6+8*(i-1),end-6) &&
regKMatrixs(5+8*(i-1),end-2)>1.05*regKMatrixs(5+8*(i-1),end-6) &&
1.05*regKMatrixs(5+8*(i-1),end)<regKMatrixs(5+8*(i-1),end-2))...
|| (regKMatrixs(8+8*(i-1),end-2)>1.05*regKMatrixs(8+8*(i-1),end-6) &&
1.05*regKMatrixs(6+8*(i-1),end-2)<regKMatrixs(6+8*(i-1),end-6) &&
1.05*regKMatrixs(5+8*(i-1),end-2)<regKMatrixs(5+8*(i-1),end-6) &&
1.05*regKMatrixs(5+8*(i-1),end)<regKMatrixs(5+8*(i-1),end-2))
value(i + targetNum)= -1;
end
end
end
RunSuibiantest.m
clear all;
clc;
%targetList(1).Market = 'DCE';
%targetList(1).Code = 'i0000';
targetList(1).Market = 'CZCE';
targetList(1).Code = 'FG000';
targetList(2).Market = 'SHFE';
targetList(2).Code = 'hc0000';
targetList(3).Market = 'DCE';
targetList(3).Code = 'I0000';
%Code(1).code = {
'CU0000', 'PB0000', 'RB0000','RU0000', 'ZN0000'};
% DCE 大连商品交易所
%\Code(2).code = {
'A0000','B0000', 'BB0000','C0000', 'CS0000','FB0000','I0000', 'J0000',
'JD0000', 'JM0000', 'L0000', 'M0000', 'P0000', 'PP0000', 'V0000', 'Y0000'};
% 'CZCE' 郑州商品交易所
% Code(3).code = {
'CF000', 'FG000', 'JR000', 'LR000', 'MA000', 'OI000', 'PM000', 'RI000',
'RM000', 'RS000', 'SF000', 'SM000', 'SR000', 'TA000', 'WH000','TC000'};
% Code(2).code = {
'AG0000','AU0000'};
% ml=1;
% for i = 1:length(Code(2).code)
% targetList(ml).Market = 'SHFE';
% targetList(ml).Code = cell2mat(Code(2).code(i));
% ml = ml+1;
% end
M =5; %计算轨道周期
N=20; %计算 ATR 周期
LimitTime=5;
traderSetBacktest(1000000000,0.000026,0.02,0,1,0,0);
AccountList(1) = {
'FutureBackReplay'};
tic;
traderRunBacktestV2('SuibianTest_Suibian',@Suibian,{
M,N,LimitTime},AccountList,targetList
,'min',1,20140101,20151231,'FWard');
toc;
22