# 量化交易

  通俗的讲,交易就像烹饪一样,平常我们都是亲自下厨,奈何生活中琐事繁多,或多或少的影响到菜品的口感。而量化交易就是一台炒菜机器人,我们只需要标准化做菜流程,然后设置烹饪顺序、翻炒时间、火候温度等控制选项。就可以稳定做出符合自己饮食习惯的饭菜。

图表程序使用指南

# 图表机制与策略实现

  图表量化交易是一种理想型的交易方式,基于历史k线进行理论仓位管理,并将理论仓位的信号标注在对应的k线图中。当最新k上出现仓位变化时,通知实际账户跟随下单。这种机制类似于使用GPS导航,导航系统会在行驶路线沿线上标记出经过的加油站。当车辆向前行驶到达指定加油站时,会语音通知驾驶员进站加油。

对照关系

  1. GPS导航 <=> 图表程序化
  2. 导航中显示的路线 <=> K线图
  3. 沿线标记的加油站 <=> 交易信号
  4. 语音通知驾驶员 <=> 告知实际账户

图表策略特性

  1. 图表策略不支持锁仓,所以必须遵循开仓前先平反向仓位。
  2. 图表策略无法直接对实际账户进行仓位管理。
  3. 图表策略只能基于历史k线计算理论仓位等信息,因此可以将图表理解成为是理想化的模型环境,它没有所谓委托未成交的状态。

例如:MACD突破零轴金死叉交易策略实现,同时要求按照一开一平原则。

思路分析:

  1. 关于MACD实现过程不再赘述,金叉表示从下上穿0轴时的状态(并非一个持续的过程),因此我们使用CROSS函数。
  2. HOLDING函数是图表的理论持仓,它有三种状态,HOLDING=0代表没有持仓; HOLDING>0代表持有多头理论持仓;HOLDING<0代表持有空头理论持仓。
    因此可以根据HOLDING的状态判断,实现一开一平的信号过滤机制。
//技术指标部分
DIFF :=EMA(CLOSE,12) - EMA(CLOSE,26);
DEA  :=EMA(DIFF,9);
MACD :=2*(DIFF-DEA);

//程序化交易下单部分
//平空开多条件
if CROSS(MACD,0)=1 then begin 
    平空:SELLSHORT(HOLDING<0,1,MARKET);
    开多:BUY(HOLDING=0,1,MARKET);
end

//平多开空条件
if CROSS(0,MACD)=1 then begin 
    平多:SELL(HOLDING>0,1,MARKET);
    开空:BUYSHORT(HOLDING=0,1,MARKET);
end

当前持仓:HOLDING,COLORGRAY,LINETHICK0;
当前资产:ASSET,NOAXIS,COLORGRAY;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

含有BUY、SELL等这类图表专属的交易函数的策略,统称为图表交易系统。

思考

  1. 上述策略逻辑中,为什么开仓前都会先平反向仓位?
  2. 上述策略加载后,账户没有实际登录,为什么会显示资金和仓位?

# 如何实现止盈止损

基于上节图表策略实现增加盈利50个价位时止盈,亏损20个价位时止损代码逻辑:

分析

  1. 止盈50个价位:

    • 多头时,最新价高于开仓价则为盈利;
    • 空头时,最新价小于开仓价则为盈利; 盈利的判断
  2. 止损20个价位:

    • 多头时,最新价小于开仓价则为亏损;
    • 空头时,最新价高于开仓价则为亏损;

综合上述分析结果,止盈止损实现的代码如下所示:

//止盈止损部分************************
//多头方向的盈损判断:最新行情大于持仓均价为盈利,反之亏损
if HOLDING>0 then BEGIN
	//多头止盈
	IF C-AVGENTERPRICE>50*MINDIFF THEN BEGIN
		多头止盈:SELL(1,HOLDING,MARKET);
	END
	
	//多头止损
	IF AVGENTERPRICE-C>20*MINDIFF THEN BEGIN
		SELL(1,HOLDING,MARKET);
	END
END

//空头方向的盈损判断:最新行情小于持仓均价为盈利,反之亏损
if HOLDING<0 then BEGIN
	//空头止盈,
	IF AVGENTERPRICE-C>50*MINDIFF THEN BEGIN
		SELLSHORT(1,HOLDING,MARKET);
	END
	
	//空头止损
	IF C-AVGENTERPRICE>20*MINDIFF THEN BEGIN
		SELLSHORT(1,HOLDING,MARKET);
	END
END
//************************************
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

那么止盈止损的代码一般应该放在MACD突破零轴金死叉交易策略的什么位置呢?

按照常识只有开仓后才能进行止损止盈,所以放在主干下单语句之后。

//技术指标部分
DIFF :=EMA(CLOSE,12) - EMA(CLOSE,26);
DEA  :=EMA(DIFF,9);
MACD :=2*(DIFF-DEA);

//程序化交易下单部分
//平空开多条件
if CROSS(MACD,0)=1 then begin 
    平空:SELLSHORT(HOLDING<0,1,MARKET);
    开多:BUY(HOLDING=0,1,MARKET);
end

//平多开空条件
if CROSS(0,MACD)=1 then begin 
    平多:SELL(HOLDING>0,1,MARKET);
    开空:BUYSHORT(HOLDING=0,1,MARKET);
end

//止盈止损部分************************
//多头方向的盈损判断:最新行情大于持仓均价为盈利,反之亏损
if HOLDING>0 then BEGIN
	//多头止盈
	IF C-AVGENTERPRICE>50*MINDIFF THEN BEGIN
		多头止盈:SELL(1,HOLDING,MARKET);
	END
	
	//多头止损
	IF AVGENTERPRICE-C>20*MINDIFF THEN BEGIN
		SELL(1,HOLDING,MARKET);
	END
END

//空头方向的盈损判断:最新行情小于持仓均价为盈利,反之亏损
if HOLDING<0 then BEGIN
	//空头止盈,
	IF AVGENTERPRICE-C>50*MINDIFF THEN BEGIN
		SELLSHORT(1,HOLDING,MARKET);
	END
	
	//空头止损
	IF C-AVGENTERPRICE>20*MINDIFF THEN BEGIN
		SELLSHORT(1,HOLDING,MARKET);
	END
END
//************************************


当前持仓:HOLDING,COLORGRAY,LINETHICK0;
当前资产:ASSET,NOAXIS,COLORGRAY;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

# 图表显示与内存的关系

图表交易时,理论信号都在K线图中标记显示,那么是否需要将参与计算的k线都显示在屏幕可视范围之内呢?

我们通过一个示例进行分析,由图可知:当前图表中共计加载561根k线数据;一屏显示的k线数量为68根k线。

//在第50根k上开多1手
buy(BARPOS=50,1,MARKET);
当前持仓:HOLDING,COLORRED,LINETHICK0;
K线位置:BARPOS,LINETHICK0;
1
2
3
4

  分析动图,虽然没有看到信号标记,但是我们通过图表中当前持仓的值,可知当前窗口中持仓为1手,此时我们向右平移显示K线直至到第50根k线处可看到信号标记,因此可以得出结论:
图表的K信号的计算,只和加载的数量有关(使用到的内存),与当前窗口显示的数量没有必然关系。类似于一个房间的大小,不是通过窗户的尺寸决定的。这里房间的大小等同于是使用的内存、窗户尺寸等同于图表显示的范围。

解惑

  1. 为什么在没有启动程序化交易时,使用键盘缩放k线时,信号会发生变化?

答:这是因为缩放k线时,图表会自动调整当前加载的k线数量,因此由于数据量发生变化,其信号结果也可能跟随发生变化。

# 为何信号与实际交易不一致?

  既然图表是一种所见即所得的交易方式,那么信号不一致的情况是怎么出现的?
首先我们知道图表中的显示的开平信号标记都是基于历史k线计算得到的结果。对于最近一次计算结果与当时实时计算的结果之间产生的差异可以分为以下两种情况:

  1. 图表有信号标记,但是图表程序化没有下单记录。
  2. 图表没有信号标记,但是图表程序化中存在下单记录。

  我们还以GPS导航作为类比,假设我们某一天需要对过去行驶过的路线进行复查,我们通过GPS将两地之间的加油站重新标记,将加油记录与GPS中的加油站信息进行对照(比如当时按照逢偶数加油站则加油的原则);我们可能也会发现:

  1. 某加油记录在地图中找不到对应的加油站。
  2. 地图上的某个加油站没有对应的加油记录存在。

  造成加油记录与加油站没有一一对应的原因,不外乎是当时途径的加油站发生了搬迁,或者是新建加油站;甚至可能是因为规划原因道路发生了变化,造成加油站不在新的线路之上。产生这种差异归根到底就是时间的变迁。造成我们现在看到的参照与当时有所出入。

图表程序化其实标记的信号点都是最新一次计算的结果,它并不能完全代表当时K线生成中结果。

  1. 图表有信号标记,但是图表程序化没有下单记录。
    原因:现在看到的图表信号标记,但是没有对应的下单记录。
    • 当时图表没有信号,信号是在K线走完之后才产生的。产生这种变化一般是由于之后的数据量发生变化、或使用到未来函数等原因,造成两次计算存在差异。
    • 当时图表有信号,程序化没有下单记录。产生这种现象,一般设置有关,例如忘记启动程序化,或程序化检测信号采用固定时间间隔方式,当时每次检测时间点都没有捕获到信号(例如:程序化间隔时间远大于一根k的周期时间、或者当时信号出现在两次检测区间的间隙,又或者是信号出现在当根k最后一次检测之后)最终所谓的漏单。
        注:1. 在正常的检测间隔时间内,信号始终在检测间隔范围内出现再消失,每次都能完美躲过检测的概率几乎不存在。
  2. 图表中没有信号标记,但是图表程序化中存在下单记录。
    • 当时图表有信号,但是由于之后的重新计算,原来符合条件的位置先在不在满足了。这种情况和当时图表没有信号的原因基本一样,和当时图表没有信号是一个互逆的情况。