知识点: 算术左移低位补0;算术右移,若符号位为0,高位补0;若符号位为1,高位补1;
ZigZag indicator in Python
I would like to create a zigzag indicator for stocks. I'm working with python and my english is bad so my appologies for that. I took part of my code from: Pandas: Zigzag segmentation of data based on local minima-maxima
The problem is the zigzag I would like is this (Metastock zigzag indicator): And my zigzag code looks like(note you can change the percent with a filter):
unless you know exactly how the first was implemented it's impossible to reproduce. If you dont know, how in earth you expect us to help you? Stil my gut tell me it's dependent on the start point, you have ~600 I guess the above one has more points.
The points are the same. Both starts in 2018-01-01 and end in 2020-06-17. maybe it's help you to understand how zigzag works: investopedia.com/terms/z/zig_zag_indicator.asp @eusoubrasileiro
mt4|外汇交易|NewZigzag指标
于是我们根据需要把MT4自带的Zigzag指标进行了改良,写成了New Zigzag指标,在New Zigzag指标下我们只需要填写一个参数,那就是每一个Zigzag线段的线段长度。比如我们设置线段长度为300个小点,那么需要价格的回调幅度至少在300小点以上,New Zigzag指标才会把这段价格的回调标记成为一个线段,相比MT4自带的Zigzag更加科学,而且在价格剧烈波动的时候也能有效的把形成时间较短的有效线段给予标记(如下图所示,橙色线段同样为MT4自带的Zigzag指标,红色是New Zigzag指标):
zigzag算法详解
sif_666 于 2020-12-18 22:13:40 发布 7319 收藏 12
zigzag编码的出现是为了解决varint对负数编码效率低的问题。zigzag编码的原理非常简单,就是将有符号整数映射为无符号整数。在实现上,映射通过移位即可实现,而不需要使用映射表来存储。
zigzag编码原理解析
例如,对于正整数1,其补码(当代计算机中实际按补码表示整数)按位展开,即为(00000000 00000000 00000000 0000000 1 )补,显然,我们可以只用一个字节甚至1bit来存储有效数据。
例如,对于负数-1,(11111111 11111111 11111111 11111111)补,全为1,并没有压缩的空间了啊!怎么办?
我们知道补码的最高位是符号位,对于负数,符号位为1,它阻碍了对于无意义0的压缩;既然有阻碍,那就得想办法解决这个阻碍;是否可以将符号位移动到补码的最后,然后数据位整体左移1位,这样就能把这个“阻碍”解决呢?
( 1 1111111 11111111 11111111 11111111)补
符号位移动到最低位,数据位整体相对左移1位
(11111111 11111111 11111111 1111111 1 )移位
对于绝对值小的负数,冗余的前导1还是很多;似乎解决的并不彻底
把数据位 按位取反 ,符号位 保持不变
(00000000_00000000_00000000_0000000 1 )取反
对于非负整数,只需完成 符号位移到最低位,数据位整体左移1位
( NewZigzag指标 0 0000000 00000000 00000000 00000001)补
(00000000 00000000 00000000 0000001 0 )移位
知识点:
算术左移低位补0;算术右移,若符号位为0,高位补0;若符号位为1,高位补1;
对于 n=-1 (NewZigzag指标 32位),( 1 1111111 11111111 11111111 11111111)补
n >> 31,b= (11111111 11111111 11111111 1111111 1 )补 ,符号位移到最低位
c=a^b, c= (00000000 00000000 0000000 0000000 1 )补 ,将-1“编码”成了1,与前面的分析一致
因为a中数据位 冗余的前导1 刚好与b中数据位 冗余的前导1 相对应,那么进行异或操作时,就能将这些 冗余的前导1 消除掉,数据位完成了 取反 动作,这样便能压缩数据了
对于 n=1 (32位),(00000000 00000000 00000000 0000000 1 )补
n NewZigzag指标 >> 31,b= (00000000 00000000 00000000 0000000 0 )补 ,符号位移到最低位
c=a^b,c= (00000000 00000000 00000000 000000 10 )补 ,将1“编码”成了2,与前面的分析一致
综上所述,对于32位整数, (n<<1)^(n>>31) ,即能实现zigzag编码。如此精妙,彩!
zigzag解码原理解析
对于 zigzag编码的值2 ,(00000000 00000000 00000000 00000010)补
n >> 1, a = (00000000 NewZigzag指标 00000000 00000000 00000001)补 ,整体右移,还原数据位
-(n&1),b = -(2&1)10 = -(0)10 = (00000000 00000000 00000000 00000000)补 ,最低位按位与,取负号,还原符号位
c=a^b,c = (00000000 00000000 00000000 00000001)补 ,将 zigzag编码值2 解码还原成了 1
对于 zigzag编码的值3 ,(00000000 00000000 00000000 00000011)补
n >> 1, a = (00000000 00000000 00000000 00000001)补 ,整体右移,还原数据位
-(n&1),b = -(3&1)10 = -(1)10 = (11111111 11111111 11111111 11111111)补 ,最低位按位与,取负号,还原符号位
c=a^b,c = (11111111 11111111 11111111 11111110)补 ,将 zigzag编码值3 解码还原成了 -2
MQL5:zig-zag 指标
幺零做点正事吧 于 2016-07-06 16:22:22 发布 3700 收藏 6
MQL5 官方实现
MQL5 官方实现十分地烂,辣鸡,很多无用的变量,程序冗长,不一致,效率低下。
感觉是多个菜鸟合作写出来的,有一些没有用的变量都没有删掉。
不过,先来看看MQL5的官方实现:
- 区间是否会越界?如果越界了怎么处理?
可能,但程序保证 startPos - depth >= 0 ,不过官方这样做仍有后果:永远无法引用 array[0] 。 - 在区间中遇到多个最值点如何处理?
取索引号最大的,因为是从 startPos 开始倒序搜索,并且采取了尽量少更新最值的策略,所以结果就是取索引号最大的。
-
搜索深度(ExtDepth)
上述【辅助函数】中用于计算区间最大/最小的索引号的函数中使用的参数depth,即区间长度。
(实际上在Zig-Zag指标中在区间中搜索最值总是使用 ExtDepth 作为区间长度,默认为12)
最大点数差(ExtDeviation)
实际上,要将点数转化成价格: deviation = ExtDeviation * _Point; ( _Point 是一个点的价格)
正常情况下,希望当前的最高/低价格处于一个区间。
- 当前柱的最高价不高于上一个高点价位共 ExtDeviation (点)
- 当前柱的最低价不低于上一个低点价位共 ExtDeviation (点)
如果这两个条件不满足,即价格超出了上一个高点与上一个低点所划定的区间,要进行回退重算高低点。
正常情况下是不需要回退重计算的,但同时也不会产生新的Zig-Zag转折点。
重计算区域的选取
最多只需要变动最新的两个Zig-Zag就可以完成重计算,这两个Zig-Zag的值一个是高点一个是低点,即只有最新的Zig-Zag高、低点是不稳定的。
所以我们需要向前找3个Zig-Zag点,重新计算从第三新的Zig-Zag点之后的指标值。
在 (rates_total - 100, rates_total) 区间中找到至多3个Zig-Zag点。
- 如果这个区间中有至少3个Zig-Zag点,取最新的3个。
- 如果这个区间中有0~2个Zig-Zag点(异常),取 rates_total - 99 (区间中最早的柱) 作为 Zig-Zag 点。
注意:实际上100柱内不到3个 Zig-Zag点这个情况是异常的,官方实现中有这样的漏洞,没有对这种情况进行特殊的处理,也没有报警告。
这个100是程序预设的常量,要求程序从100柱才开始计算指标:越大则取不到3个Zig-Zag的异常越不容易发生,但是同时计算指标的起点会延后,会损失更多的数据。
实际上这个设计完全可以用程序逻辑来规避,官方的实现不是一个好的设计。
- 如果是低点,接下来应该是一个 \/ 形状的凹槽(Pike)
高Zig-Zag + 低Zig-Zag + 当前点 - 如果是高点,接下来应该是一个 /\ 形状的凸起(Sill)
低Zig-Zag + 高Zig-Zag + 当前点
最后抹除这个最早的Zig-Zag点之后的所有指标数据(不包括原始价格数据),因为要进行重算。
最新的一组高、低点划定了一个价格区间: [lastLow - deviation, lastHigh + deviation]
如果当前价格超出了这个区间,就要进行回退计算,试图修改最新的高/低点。
参数 ExtBackstep 回退步数,默认是3。
设当前计算到 X 号柱,回退时仅考虑 [X - ExtBackstep, X) 这个区间中是否有高(低)点,如果有,判断当前价格(X号柱的最高(低)价)是否比这个高(低)点更高(低),如果是,重设这个高(低)点到X号柱。
回退计算的触发条件有两个:
1. 在 ExtDepth 长度的区间内发现了新的高(低)点。
2. 当前柱的价格超过限定的区间。