# 变量对比
本节只围绕普通变量、VARIABLE、GLOBALVARIABLE三者在K线上执行的关系进行分析。希望可以帮助大家进一步理解全局变量的特性。
普通变量:策略每次被执行,普通变量都会进行一次初始化操作,即普通变量每次执行策略都被创建和销毁。前后两次的运行结果并不会被传递。
VARIABLE变量:当策略在第一根K上被执行时,VARIABLE变量进行初始化操作,之后VARIABLE变量都基于上根K上的最终结果进行运算;
- 补充:在最新k上时,策略虽然会被多次执行,但是VARIABLE变量同样是使用上根k上的最终结果在最新k上运算,即VARIABLE变量无法获得同根k上的上次执行结果。
- 此变量应用于图表。
GLOBALVARIABLE变量:当策略被加载启用时,GLOBALVARIABLE变量进行初始化操作,GLOBALVARIABLE变量的仅在最新k上有效并且基于上一次的运行结果进行运算。
- 此变量应用于后台。
EXT***变量:它等于一个微型数据库,适用也非常简单,通过写入函数EXTGBDATASET和读取函数EXTGBDATA直接操作即可。类似于生活使用便签纸留言,将备忘内容写上后,再在指定的地方读取即可。
说明
- 它不存在初始化过程,不会因为软件重启等因素的影响而发生变化。
- 它作用于整个金字塔中,因此在使用EXTGBDATASET写入数据时,要留心变量名因为重复造成的干扰。
例如:A策略和B策略之间本身不存在交互行为,但是通过EXTGBDATASET写入同为X变量的值。那么A策略和B策略之间则产生了干扰。这种干扰会造成两个策略的执行逻辑发生紊乱。
SETREGVAL和SETREGVAL:它们代表的两组函数,分别是操作配置文件和注册表。其作用范围都是整个计算机,通过它们可以做到客户端之间的交互。两组函数唯一的区别在于记录的数据位置不同。
变量标识 | 名称类型 | 作用范围 | 解析 |
---|---|---|---|
无 | 普通变量 | 单根K线 | 只在当根K线生效,当指标换到下一根K线进行计算时就会被再次初始化。 |
VARIABLE | 全局变量 | 首根K至最后一根k线 | 指标加载后,定义语句在第一根K线处初始化为设定值,后面的K线调用此全局变量计算时,调用到的值是上一根K线计算的返回值。当行情更新,指标重新刷新时,那么此变量又会在第一根K线处被定义语句初始化。 |
GLOBALVARIABLE | 超全局变量 | 指标加载至停止运行期间 | 指标加载时对全局变量定义的语句进行一次初始化,之后定义语句都不会再对其初行初始化直至停止运行指标。 |
EXTGBDATA | 单值全局变量 | 整个金字塔软件范围内 | 设置了初始值之后,只要是在金字塔软件范围内,任意的指标、手工或者其他方式都可软修改它的值,并且在整个软件范围内共享这个值。因此,它不存在绝对意义的初始化。 |
SETREGVAL | 注册表全局变量 | 整个计算机范围内 | 将变量存储机注册表中,因此在整都计算机内都可以调用这个值。 |
WRITEINIFILE | 写配置文件 | 整个计算机范围内 | 将变量存储在本地配置文件内,因此在整都计算机内都可以该配置文件调用这个值。 |
# 全局变量的应用
应用遵循规则
- 全局变量的整个变化过程应该形成一个闭环,即初始值-->赋值1-->赋值2-->...-->初始值.
- 全局变量用于状态标记时,每种状态应该对应一个状态值,否者逻辑可能发生紊乱。
全局变量的使用场景一般就是以下几种情况:
// 定义全局变量,来控制当天交易次数
variable:num=0;
//限定一天最多交易5次
cs:=5;
ma5:ma(close,5);
ma20:ma(close,20);
cond1:=cross(ma5,ma20);
cond2:=cross(ma20,ma5);
//开仓条件,其中子条件num<cs用于判断控制开仓次数。
if cond1 and holding=0 and num<cs then
begin
buy(1,1,market);
num:=num+1;
end
if cond2 and holding>0 then sell(1,1,market);
// 收盘时将num赋值为0,否者第二天无法再进行开仓
if time=closetime(0) then num:=0;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
说明
- 图表策略只能使用variable全局变量,其他全局变量不符合图表的运行计算机制慎用。
- 后台策略推荐使用GLOBALVARIABLE,如果使用ext全局变量控制时,需要注意ext定义的变量名,否者在多品种多测策略操作时,存在相同的ext变量名时,结果会紊乱。
//该策略适用于图表程序化交易
//该策略适用于分钟周期
//仅供演示使用,请勿直接用于实盘
VARIABLE:FLAG=0; //定义全局变量标记FLAG,初始值为0
INPUT:SS(1,1,100,1); //定义开仓手数
//交易条件
N:BARSLAST(DATE<>REF(DATE,1))+1; //当日K线数量
MA5:=MA(C,5);
MA20:=MA(C,20);
CON1:CROSS(MA5,MA20) AND N>=3;
CON2:CROSS(MA20,MA5) AND N>=3;
//开仓语句。开仓后,FLAG标记置为1
IF CON1 THEN BEGIN
BUY(HOLDING=0,SS,MARKET);
FLAG:=1;
END
//平仓语句
IF CON2 AND FLAG=0 THEN begin
SELL(HOLDING>0,HOLDING,MARKET);
end
//交易日结束时,FLAG平仓标记置为0;
IF TIME=CLOSETIME(0) THEN begin
FLAG:=0;
end
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
说明
- 使用全局变量互锁特性,将每个逻辑通过唯一的ID编码进行排列,从而形成特有的执行过程。
通过上述代码的学习,我们大致了解逻辑互锁的整个过程,那么实际使用中,这种方法更常用于分阶段性加减仓逻辑管理中。如下代码:
//持仓2手,如果赢利在75-100个价位之间开始回落,
//盈利回落到15个价位以内时止盈平仓1手,之后回落亏损20个价位后触发止损结束。
VARIABLE:sellflag=0;
//盈利在75-100个价位之间时,标记状态,用此状态开启回落止盈止损逻辑监测
IF C-AvGENTERPRICE>=75*MINDIFF and C-AvGENTERPRICE<100*MINDIFF and sellflag=0 THEN BEGIN
sellflag:=1;
END
// 盈利已经离开75-100区间,回落至盈利15个价位以内时。
IF C-AvGENTERPRICE<=15*MINDIFF and sellflag=1 THEN BEGIN
SELL(1,1,MARKET);
END
IF AvGENTERPRICE-C>=20*MINDIFF and sellflag=1 THEN BEGIN
SELL(1,1,MARKET);
//仓位已经平完,状态重置为初始值,等待进行下次开仓
sellflag:=0;
END
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
A策略
//赋值A_X=3
EXTGBDATASET('A_X',3);
2
B策略
//赋值B_Y
EXTGBDATASET('B_Y',7);
2
计算A、B两策略之和。
SUM_AB:=EXTGBDATA('A')+EXTGBDATA('B')
上述简单逻辑可以帮助我们理解EXT***全局变量进行数据传递的特点,EXT***全局变量也是实现净持仓统计的方法之一。
说明
- EXT***类的全局变量没有历史值,它只适用于后台策略中,
- 它也可以像其他全局变量一样,应用在
计数统计
、逻辑互锁
的使用场景中。
//A有三种数值状态:1,0,最新价;
//当A=1时表示当前有持仓,A=0时表示移动止损执行完毕,A=最新价时用于比较价格是否回落
//将A赋值为1,表示当前有持仓
IF TBUYHOLDINGEX( '','' ,0 )>0 AND EXTGBDATA('a' )=0 THEN BEGIN
EXTGBDATASET( 'a',1 );
END
//使A始终表示监控开始后的最高价
IF DYNAINFO( 7)>EXTGBDATA('a' ) and EXTGBDATA('a' )>0 THEN BEGIN
EXTGBDATASET( 'a',DYNAINFO( 7));
END
//发现价格回落止损,并将A赋值为0表示移动止损动作完成
IF EXTGBDATA('a' )-DYNAINFO( 7)>5*MINDIFF and EXTGBDATA('a' )>0 THEN BEGIN
TSELL(1,1,MKT );
EXTGBDATASET( 'a',0);
END
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
因为移动止损中的最高价是判断回落的依据,在实际使用中,我们不希望它受到重启等因素的影响而发生变化。因此采用EXT***是最佳解决方法。
我们只需要在设置EXT***全局变量时,保证变量名称的唯一性即可。因此使用STKLABEL函数与变量a组合成变量名即可。
注意:如果是多策略同品种交易,可以使用FORMULANAME作为区分名称的一部分。(策略名称尽可能简单,否者容易超出长度限制)
//A有三种数值状态:1,0,最新价;
//当A=1时表示当前有持仓,A=0时表示移动止损执行完毕,A=最新价时用于比较价格是否回落
//将A赋值为1,表示当前有持仓
IF TBUYHOLDINGEX( '','' ,0 )>0 AND EXTGBDATA(STKLABEL&'_a' )=0 THEN BEGIN
EXTGBDATASET( STKLABEL&'_a',1 );
END
//使A始终表示监控开始后的最高价
IF DYNAINFO( 7)>EXTGBDATA(STKLABEL&'_a' ) and EXTGBDATA(STKLABEL&'_a' )>0 THEN BEGIN
EXTGBDATASET( STKLABEL&'_a',DYNAINFO( 7));
END
//发现价格回落止损,并将A赋值为0表示移动止损动作完成
IF EXTGBDATA(STKLABEL&'_a' )-DYNAINFO( 7)>5*MINDIFF and EXTGBDATA(STKLABEL&'_a' )>0 THEN BEGIN
TSELL(1,1,MKT );
EXTGBDATASET( STKLABEL&'_a',0);
END
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18