以文本方式查看主题

-  金字塔客服中心 - 专业程序化交易软件提供商  (http://weistock.com/bbs/index.asp)
--  金字塔软件问题提交  (http://weistock.com/bbs/list.asp?boardid=2)
----  数组函数有BUG  (http://weistock.com/bbs/dispbbs.asp?boardid=2&id=171659)

--  作者:不良人
--  发布时间:2019/8/15 13:53:59
--  数组函数有BUG

BUG描述:
数组在调试时是完全正确,无错误的。但是加载到图表时,数组出现了错误,凭空多了未知的数组元素

 

公式代码简单描述:(代码在文末)
本公式,通过zig函数找到高低点(本贴不是讨论未来函数,所以请不要纠结未来函数),将高低点存入zu、zuF、zuG等数组内,然后通过zuF[i]<zuF[i+1] and zuG[i]<zuG[i+1]这个判断,将上涨的开始位置SZkaishi和上涨的结束位置SZjieshu,存入SZ开始和SZ结束这两个数组中,然后用矩形函数DRAWRECT画出来。

这时候问题来了,在调试窗口中“数组SZ开始和数组SZ结束”这两个数组是正确的,但是加载到图表,除了画出来正确的数组还会画出错误的数组。经测试,如果将画矩形函数换成画椭圆函数也是同样结果,说明BUG出现在图表时的数组上(请注意调试时数组是正确的,不会多出来),请查证。

 

图文演示BUG:
下图1,可以看到矩形1和矩形2,其中矩形1是凭空出来的,因为数组出现了错误


图片点击可在新窗口打开查看此主题相关图片如下:错误1.png
图片点击可在新窗口打开查看

下图2关闭公式后再次打开公式,矩形1消失了。可以看到正确的矩形框出了上涨的部分。


图片点击可在新窗口打开查看此主题相关图片如下:1.png
图片点击可在新窗口打开查看

下图3,有矩形1和矩形2和矩形3,其中矩形1是凭空出来的

图片点击可在新窗口打开查看此主题相关图片如下:cuo2.png
图片点击可在新窗口打开查看

下图4,关闭公式后再次打开公式,矩形1消失了。可以看到正确的矩形框出了上涨的部分。

图片点击可在新窗口打开查看此主题相关图片如下:2.png
图片点击可在新窗口打开查看


由于一个帖子只允许5个图片,所以跟贴中还有一个例子,(错误的数组不总是出现在前面,请看下一贴)


--  作者:不良人
--  发布时间:2019/8/15 14:01:39
--  

下图5,有矩形1和矩形2,其中矩形2是凭空出来的


图片点击可在新窗口打开查看此主题相关图片如下:cuo3.png
图片点击可在新窗口打开查看

下图6,关闭公式后再次打开公式,矩形2消失了。可以看到正确的矩形框出了上涨的部分。

图片点击可在新窗口打开查看此主题相关图片如下:3.png
图片点击可在新窗口打开查看

查证时,请多看几个股票,有的股票没问题,有的股票就不行,大概翻看6个股票就有一个显示错误,我的软件版本为5.12和5.02都有此问题。

附代码如下:

以下内容为程序代码:

1 //主图叠加,序列模式
2
3 {-----------------定义变量--------------------}
4 a:ZIG(3,5);
5 谷:=ref(a,1)>a and refx(a,1)>a;{每个谷的K线位置处,置为1(true)}
6 峰:=ref(a,1)<a and refx(a,1)<a;{每个峰的K线位置处,置为1(true)}
7 drawnumber(谷,l,a,2);{每个谷显示谷值}
8 drawnumber(峰,h,a,2);{每个峰显示峰值}
9
10 转向点:=谷 or 峰;
11
12 zongF:=COUNT(峰,0); {统计总数,共有多少峰}
13 zongG:=COUNT(谷,0); {统计总数,共有多少谷}
14 zong:=COUNT(转向点,0);{统计总数,共有多少转向点}
15
16 常数zongF:=CONST(zongF); //常数化
17 常数zongG:=CONST(zongG); //常数化
18 常数zong:=CONST(zong); //常数化
19
20 if 常数zong<7 then goto 跳转点_退出公式; //若转向点总数不足7,则跳过
21 {-----------------定义变量---------END--------}
22
23 {-------------每个转向点存入数组--------------}
24
25 variable:zu[zong]=0; {定义数组,用于存入每个转向点的数值,长度等于转向点的总数}
26 variable:zuF[zongF]=0;{定义数组,用于存入每个峰的数值,长度等于峰的总数}
27 variable:zuG[zongG]=0;{定义数组,用于存入每个谷的数值,长度等于谷的总数}
28
29 variable:zhouqi[zong]=0; {定义数组,每个转向点距离今天多少周期,长度等于转向点的总数}
30 variable:zhouqiF[zongF]=0;{定义数组,每个峰距离今天多少周期,长度等于峰的总数}
31 variable:zhouqiG[zongG]=0;{定义数组,每个谷距离今天多少周期,长度等于谷的总数}
32
33 variable:datee[zong]=0; {定义数组,每个转向点日期,长度等于转向点的总数}
34 variable:dateF[zongF]=0;{定义数组,每个峰日期,长度等于峰的总数}
35 variable:dateG[zongG]=0;{定义数组,每个谷日期,长度等于谷的总数}
36
37 //正序存入
38 ii:=1;{ii在FOR循环内使用}
39 for i=常数zong downto 1 do BEGIN
40 zu[i]:=ref(a,SUMBARS(转向点,ii)-1); {每个转向点的数值存入数组,正序,第一下标为最远的那个转向点}
41 zhouqi[i]:=SUMBARS(转向点,ii)-1; {存入每个转向点距离今天多少周期,正序}
42 datee[i]:=ref(DATE,SUMBARS(转向点,ii)-1);{存入每个转向点的日期,正序}
43 ii:=ii+1;
44 END;
45
46 ii:=1;{ii在FOR循环内使用}
47 for i=常数zongF downto 1 do BEGIN
48 zuF[i]:=ref(a,SUMBARS(峰,ii)-1); {每个峰的数值存入数组,正序,第一下标为最远的那个转向点}
49 zhouqiF[i]:=SUMBARS(峰,ii)-1; {存入每个峰距离今天多少周期,正序}
50 dateF[i]:=ref(DATE,SUMBARS(峰,ii)-1); {存入每个峰的日期,正序}
51 ii:=ii+1;
52 END;
53
54 ii:=1;{ii在FOR循环内使用}
55 for i=常数zongG downto 1 do BEGIN
56 zuG[i]:=ref(a,SUMBARS(谷,ii)-1); {每个谷的数值存入数组,正序,第一下标为最远的那个转向点}
57 zhouqiG[i]:=SUMBARS(谷,ii)-1; {存入每个谷距离今天多少周期,正序}
58 dateG[i]:=ref(DATE,SUMBARS(谷,ii)-1); {存入每个谷的日期,正序}
59 ii:=ii+1;
60 END;
61 {---------------每个转向点存入数组------END--------}
62
63
64 {---------------------修正数组---------------------}
65 {no.1------总数为奇数时删除起始点----------}
66 //若zu数组为奇数,则将第一个开始的转向点删除,将数组修正为总数是偶数的数组
67
68 nn:=UBOUND(zu);//取得数组最大下标(长度)
69 求商取整:=INTPART(nn/2);//商若有小数则为奇数
70
71 IF (nn/2) - 求商取整 <>0 then BEGIN;//总数不为偶数时
72     if zu[1]>zu[2] then begin//起始转向点大于第二个转向点时
73     REMOVEBOUND(zuF,1);
74     REMOVEBOUND(zhouqiF,1);
75     REMOVEBOUND(dateF,1);
76     end;
77     else begin
78     REMOVEBOUND(zuG,1);
79     REMOVEBOUND(zhouqiG,1);
80     REMOVEBOUND(dateG,1);
81     end;
82     
83     REMOVEBOUND(zu,1);
84     REMOVEBOUND(zhouqi,1);
85     REMOVEBOUND(datee,1);
86 END;
87 {---------------------修正数组----------END--------}
88
89
90 {---------------------循环判断上涨------------------}
91 variable:SZ开始[1]=0;//定义数组,上涨
92 variable:SZ结束[1]=0;
93
94 SZkaishi:=0;//临时变量,名为"开始",用于临时保存上涨阶段的开始位置
95 SZjieshu:=0;//临时变量,名为"结束",用于临时保存上涨阶段的结束位置
96
97
98 //判断第一转向点为谷or峰
99 one:=0; //0为谷,1为峰
100 if zu[1]>zu[2] then one:=1;
101
102 常数zongF:=UBOUND(zuF); //常数化
103 常数zongG:=UBOUND(zuG); //常数化
104 常数zong:=UBOUND(zu); //常数化
105
106 ii:=1;//ii在下面FOR循环内使用
107 IF one=0 then begin//第一转向点为谷时
108     for i=1 to 常数zongF-1 do BEGIN //-1的目的是防止溢出数组//常数zongF和常数zongG是一样大的
109     if zuF[i]<zuF[i+1] and zuG[i]<zuG[i+1] then begin //用4个高低点判断上涨
110     if SZkaishi<>0 then begin
111         SZjieshu:=dateF[i+1]; //更新结束的位置 存入临时变量SZjieshu内
112     end;
113     if SZkaishi=0 then begin
114     SZkaishi:=dateG[i]; //将开始的位置存入临时变量SZkaishi内
115     SZjieshu:=dateF[i+1]; //将结束的位置存入临时变量SZjieshu内
116     end;
117 end;
118
119 else begin
120     if SZkaishi<>0 then begin
121         SZ开始[ii]:=SZkaishi;
122         SZ结束[ii]:=SZjieshu;
123         
124         SZkaishi:=0;//初始化
125         SZjieshu:=0;//初始化
126         
127         ii:=ii+1;
128         SETUBOUND(SZ开始,ii);//扩充数组,新扩的下标数值为0
129         SETUBOUND(SZ结束,ii);
130     end;
131     end;
132     end;
133
134 if i=常数zongF then begin//前FOR循环结束后,将尚未存入的存入数组内
135 if SZkaishi<>0 then begin
136     SZ开始[ii]:=SZkaishi;
137     SZ结束[ii]:=SZjieshu;
138     
139     SZkaishi:=0;//初始化
140     SZjieshu:=0;//初始化
141 end;
142 end;
143
144 //删除数组内的空数组
145     qude:=UBOUND(SZ开始);//取得最大下标
146     if SZ开始[qude]=0 then begin
147         REMOVEBOUND(SZ开始,qude);
148         REMOVEBOUND(SZ结束,qude);
149     end;
150 END;
151
152 IF one=1 then begin//第一转向点为峰时
153     for i=1 to 常数zongF-2 do BEGIN //因舍弃第一个转向点,所以必须-2
154     if zuF[i+1]<zuF[i+2] and zuG[i]<zuG[i+1] then begin //用4个高低点判断上涨
155     if SZkaishi<>0 then begin
156         SZjieshu:=dateF[i+2]; //更新结束的位置 存入临时变量SZjieshu内
157     end;
158     if SZkaishi=0 then begin
159     SZkaishi:=dateG[i]; //将开始的位置存入临时变量SZkaishi内
160     SZjieshu:=dateF[i+2]; //将结束的位置存入临时变量SZjieshu内
161     end;
162 end;
163
164 else begin
165     if SZkaishi<>0 then begin
166         SZ开始[ii]:=SZkaishi;
167         SZ结束[ii]:=SZjieshu;
168         
169         SZkaishi:=0;//初始化
170         SZjieshu:=0;//初始化
171         
172         ii:=ii+1;
173         SETUBOUND(SZ开始,ii);//扩充数组,新扩的下标数值为0
174         SETUBOUND(SZ结束,ii);
175     end;
176     end;
177     end;
178
179 if i=常数zongF-1 then begin//前FOR循环结束后,将尚未存入的存入数组内
180 if SZkaishi<>0 then begin
181     SZ开始[ii]:=SZkaishi;
182     SZ结束[ii]:=SZjieshu;
183     
184     SZkaishi:=0;//初始化
185     SZjieshu:=0;//初始化
186 end;
187 end;
188
189 //删除数组内的空数组
190     qude:=UBOUND(SZ开始);//取得最大下标
191     if SZ开始[qude]=0 then begin
192         REMOVEBOUND(SZ开始,qude);
193         REMOVEBOUND(SZ结束,qude);
194     end;
195 END;
196
197 {-------------------------绘图-------------------------}
198 sz开始zong:=UBOUND(SZ开始);
199
200 for i=1 to sz开始zong do BEGIN//上涨绘图
201
202     末位开始:SZ开始[i];//用来图表测试BUG
203     末位结束:SZ结束[i];//用来图表测试BUG
204     
205 DRAWRECT(DATE=SZ开始[i],l,DATE=SZ结束[i],h,TRUE,COLORRED,1,VTSOLID);//矩形
206
207 //DRAWELLIPSE(DATE=SZ开始[i],l,DATE=SZ结束[i],h,TRUE,COLORRED,1,VTSOLID);//椭圆
208 end;
209
210 {-------------------------绘图----------END------------}
211
212 跳转点_退出公式@;


--  作者:yukizzc
--  发布时间:2019/8/15 16:28:25
--  
我这边来回切换并没有问题,您看下
--  作者:yukizzc
--  发布时间:2019/8/15 16:28:57
--  
 下载信息  [文件大小:   下载次数: ]
图片点击可在新窗口打开查看点击浏览该文件:img_3328.rar


--  作者:banzhuan
--  发布时间:2019/8/16 13:36:27
--  
本地已核实该现象,问题会进行反馈
--  作者:不良人
--  发布时间:2019/9/15 16:14:00
--  您好,请跟进这个BUG
我找到原因了,是因为数组没有释放内存,切换股票时,上一个股票的数组的元素未释放内存造成的,请问怎么释放内存?
--  作者:wenarm
--  发布时间:2019/9/16 9:47:05
--  

pel没有这类操作函数。


--  作者:不良人
--  发布时间:2019/9/19 16:39:10
--  
那切换股票时,软件应该自己清空数组内存,不该把这只股票的数组显示到下一个股票上吧?
--  作者:wenarm
--  发布时间:2019/9/19 16:58:29
--  

pel的数组是保存在固定的一段内存中的,而你切换后其取值结果越界后,就直接取到了其他品种的数据。这个问题后面版本会修正的。

[此贴子已经被作者于2019/9/19 17:03:07编辑过]

--  作者:不良人
--  发布时间:2019/9/20 15:52:57
--  
是的,您说的太对了,事情正如您所说,期待下个版本的更新