1、最简单的 同花顺公式 错在哪啊?
公式入门
我们大多数的用户并不是完全了解“公式编辑器”的意义,简单地,我们可以从以下几个角度进行理解:
一、指标分析:
“公式编辑器”好比是一个工作母床,通过这个工作母床可以制造出所需要的各式各样的零件,同样,在指标分析的工作中,利用编辑器可以编写出相应的分析
条件,这种方法是在技术分析当中最为常用的方法之一。例如,指标KD、指标MA等等,通过对这些指标的观察、分析,找出一些合适的条件作为买入卖出点。当
然,我们也许需要的是一些自己的指标,一些自己的准确的指标,更多的MB、MC、MD等等,这一切我们通过“公式编辑器”可以实现。
二、条件选股:
编写公式都要用到什么东西?
我们留下了许多问题--都是公式编写的基础问题,所以我们这节课来解决这些基础的问题。
什么是技术指标?
MA均线就是一种技术指标,我们在炒股的时候,经常会将一些行情数据进行数学计算得出一些曲线等等,方便我们掌握股市的变动情况。
什么是条件选股?
简单讲,就是按照您的设定的条件用电脑帮助您完成一些太多太复杂的挑选--比如您有一些好的心得和方法,可使有1000多只股票,您就是有100双眼睛有时也不
一定可以看得过来,这时电脑就派上用场了!
什么是参数?
比如讲:10日均线,您可以把10日当作参数,好处在于,您觉得需要修改成5日的时候,就可以使用一些简单的方法,例如参数精灵来很方便的修改和调整。参数
需要名字,例如M就不错。还要规定参数的范围,例如1日至260日。这样我们就可以在1到260之间任意调节M的值了,M最常用的数填在“缺省”一栏,例如你最喜
欢用10日均线,那就填10吧。
什么是周期?
这么解释吧!我们有的投资者喜欢使用日线图作技术分析;有的喜欢用5分钟的K线;有的喜欢使用长一点时间的,例如周线。所以在公式设计中,允许不同喜好
的使用者选择不同的分析时间--就是可以选择不同的周期。
什么是函数?
函数在公式编写非常重要,如果作个比喻,我们用一种语言去告诉电脑我的想法,并且让它去帮我做,那么函数就是这种语言的单词。
我们在公式编辑器中选择插入函数,就可以看到里面有许多的函数,我们在附录中有一个简表,大家可以到那里去检索!
例一:
一根K线有四个价格组成:
最高价:HIGH
收盘价:CLOSE
最低价:LOW
开盘价:OPEN
成交量:VOL
成交额:AMO
例二:
两条均线不断地交叉,就专门设定了一条函数来描述两条线交叉:CROSS(X,Y)
假如下图中的两条均线一条名叫X,另外一条叫Y
CROSS(X,Y)表示X向上穿过了Y
CROSS(Y,X)表示Y向上穿过了X
例三:
前面的CLOSE,还是VOL,都表示当天,或者您使用的不是日线,那就表示本周期的数据,那么前几天的怎么表示呢?
REF(X,M)
例如:
REF(Close,5)表示5天前的收盘;
REF(Vol,10)表示10天前的成交量;
这里的M就是参数,您现在明白了什么是参数了吗?
例四:
如果我想把两个条件并列在一起怎么办?
AND
X AND Y就表示条件X和条件Y
好了!本课结束吧--有点稍慢,下面会好一些!
编写一条最简单的指标线
通过前几课的学习,我们今天开始使用软件的公式编辑功能编写我们自己的第一条指标线。
其实不难,你应该对自己有信心!
按照主菜单-工具-公式**-选择-“技术指标”-点击“新建”,然后在公式编辑器中留下你的第一行脚印吧!
点击:“确认”,现在看一下我们第一条指标线。
这条指标线与你的想法相符吗?
总结与补充:
1、如果选择:“主图叠加”,我们的指标线会与K线图显示在同一个图形框中,现在我们的指标线显示在其下方,即“副图”中;
2、参数可以有,也可以没有,但是鼓励大家设置参数,这是非常好的习惯;
3、一个句子完了,别忘了以分号结尾;
你的公式写得对不对,可以通过“测试公式”来检查,如果错了,它会告诉你错在哪里。
编写最常用的均量和均价线
均价线,不就是那个“移动平均线MA”什么的吗?不过,话说回来,听说10个人里面有11个人都在使用,我可得学习学习!
原理是??
5日平均线=(今天收盘价+昨天收盘价+.....--5天前的收盘价)/5;
10日平均线=(今天收盘价+昨天收盘价+......+10天前的收盘价)/10;
150日平均线=(今天收盘价+昨天收盘价+......+150天前的收盘价)/150;
200日平均线......不是这么麻烦吧?难道我每天都要写这么多得数才得到一条平均线????
你有什么办法?
MA1=MA(CLOSE,5);
MA2=MA(CLOSE,10);
MA3=MA(CLOSE,50);
......
当然是有简单的方法了!你把我在上面说过的话写下来,按照前面几课讲的,写在公式的编辑栏当中就可以了!
注意:
“MA”表示的就是计算平均值。
在括号内写上计算的对象和计算的时间长度。
MA1,MA2,MA3......是好几条指标线,别忘记了用分号把它们分开。
最后呢?电脑自己会把它们一起画出来。
均量线???
均价线都有了,照着葫芦画瓢,把收盘价CLOSE换成成交量VOL就行了!
MA1:MA(VOL,5);
MA2:MA(VOL,10);
MA3:MA(VOL,150);
MA4:MA(VOL,200);
今天有几只发生MA金叉?
我们学习了编写MA移动平均线,关于这几条指标线如何使用?我想大家可能都比我清楚。例如短期均线和长期均线发生了金叉或者死叉,......等等,葛兰维尔
的八项法则......如果说如何用分析家软件编写一个条件,让电脑把今天两个市场的股票中所有发生了黄金交叉的股票选出来呢?
想知道吗?这就是“条件选股”,按照“条件”电脑自动“选择股票”出来,可以供您分析,要不然的话,技术分析的投资者都会累死了!
跟我学!
第一步:“工具”栏中选中“公式**器”
第二步:我们现在选择“新建”一个“条件选股”公式,结果出现了下面的编辑栏!然后在里面写上您的条件!
第三步:按照说明书上的步骤选股就行了!
注意:
1、在条件选股中点击“新建”;
2、原来MA5:MA(CLOSE,5);
表示的是一条指标线,可是现在我们在条件选股当中只要引用它,不需要把它画出来。所以我们在冒号的后面加一个符号,表示等会要引用它:MA5:=MA(CLOSE
,5);
这个在分析家的公式编辑中,叫做“中间表达式”。
X=1;
Y=X+1;
Y=?
我们学过上面的数学,都知道把X=1代入到Y的计算中去,“X=1;”就是一个中间表达式,您明白了吗?
条件选股总结:
1、指标和条件选股在结构上没有差别,只是在内容上,条件选股要多加上我们的条件,比如大于10,或者交叉等等!
2、中间表达式可以帮助我们清晰的表达我们的公式,不至于使公式的结构特别的混乱!
如何编写BIAS指标?
如果大家都是均线的忠实爱好者的话,那么大家一定牢牢记得在均线大师哥南威尔的8***则当中的第四条和第五条中曾经提到了当股价偏离均线太远的时候,便
会向它靠拢,但是并不提到多远才会靠拢--为了解决这个问题,也为了我们更好地用客观数据来体现股价运动的过程,乖离率这个指标应运而生。
本课我们的任务就是通过对乖离率的原理到编写方法的学习来加强我们对公式设计的理解。
首先,什么是乖离率?
以当日的均线价格为准,股价和均价之间的差距称为乖离程度,以乖离程度除以均价的百分比就是乖离率。
当日股价与10日均线的乖离率=(当日股价-10日均价)/10日均价*100;
当日股价与20日均线的乖离率=(当日股价-20日均价)/20日均价*100;
当日股价与30日均线的乖离率=(当日股价-30日均价)/30日均价*100;
原理就是这么简单,可是怎么使用呢?您别急,所用的指标其实都是在观察当中得出一定的启示,您先实现这几条指标线,让它们以图形的方式出现在您的面前
,然后您再去观察,一定会事半功倍!
比如编写10日乖离率
第一步:乖离率的命名,崇尚人家的习惯,依旧使用BIAS,那么第一条就叫做BIAS1好了!
第二步:当日股价用CLOSE表示;
10均价我们在前一节课刚刚学过,顺手拈来,用MA(CLOSE,10)表示;
第三步:一样使用加减乘除符号以及括号,只是要注意只有小括号,没有中大括号,那么公式就有了--
BIAS1:(CLOSE-MA(CLOSE,10))/MA(CLOSE,10)*100;
这样的话我们在技术指标编辑器中将另外两条指标也同样写下来,就得到了BIAS指标,请看下图:
第四步:就是您得自己好好观察您的指标公式在各个股票的表现,得出您自己的结论,因为每一个投资者即使是在使用同样一个指标的时候,都会有不同的理解
,我们无法判断优劣,但是有一条可以告诉我们答案,那就是永远让市场说话,因为它永远是对的!
如果您不介意的话,可以参考BIAS,不过仅供参考!
您明白怎么编写了吗?
====================================================================================
我能不能直接用写好的指标公式?
我想用KD指标选股,能不能直接写成“D>20”就可以执行了?
当然可以!考虑到了这种偷懒的做法,所以我们一共提供了两种供偷懒的人士使用,其中一种与上面的要求只是在写法上稍有不同!
第一个方法:
第一步:在条件选股的编辑器中点击“引入指标公式”。
引入“其他公式”。然后,我们从中选择一个,例如“KD”,让我们来看一下结果如何?
第二步:上一步的操作结果请看右边的图形,系统自动的把KD指标的整个编写内容搬来了!
现在需要我们做的就是:续上一行条件“D<20”,OK!完成!
有没有简单的方法?
第二个方法:就一句话:“KDJ,D”<20;
“KDJ,D”
表示现在我要是用KDJ指标当中的D指标,不过大家要看清楚是怎么写的哦!写错了计算机可是不会改错的!
总结:
用上面的方法可以引用所有指标,所以不必写那么多!
注意格式上,两边用引号括起来,指标名称KDJ和指标线名称D之间用“,”隔开!
额外加餐
现在我们可以很方便的做另外一件事了,我们可以将通常说的KDJ买入条件完整的表达出来了:
“KD指标发生了黄金交叉,并且D<20”
T1:=“KDJ,K”;--引用K线;
T2:=“KDJ,D”;--引用D线;
条件: AND在分析家中就表示“并且”,将两个条件并列起来
CROSS(T1,T2)ANDT2<20;
第九课 放量、缩量、上涨、下跌、收阳、收阴
在前面的学习当中,我们见到了一些基本的表达方法、方式,今天我们的任务是学习一些常见的概念如何编写,例如上面所列出来的放量、上涨等等,因为这些
都是在公式编写过程当中要用到的基本的小的形态特征,许多的技术指标的选股条件都是由它们组成的。
放量:
1、今日比昨日的成交量放大了1倍:
VOL/REF(VOL,1)>2;
2、今日的五日均量比前五天的五日均量放大了3倍:
AA:=MA(VOL,5);
BB:=REF(AA,5);
AA/BB>4;
3、今天的成交量达到了整个流通盘的10%以上:
VOL/CAPITAL>10/100;
(注意,10%的表达式是10/100,或者0.1)
缩量:
1、今日比昨日的成交量缩小了1倍:
VOL/REF(VOL,1)<0.5;
2、今日的五日均量比前五天的五日均量缩小了一半:
AA:=MA(VOL,1)<0.5;
BB:=REF(AA,5);
AA/BB<0.5;
3、今天的成交量不足整个流通盘的0.5%:
VOL/CAPITAL<0.5/100;
上涨:
1、今日涨幅达到了7%以上:
CLOSE/REF(CLOSE,1)>1.07;
2、十日均价继续上涨:
AA:=MA(CLOSE,10);
BB:=REE(AA,1);
AA>BB;
下跌:
同上面的表达方式一样,将方向改变了而已:
收阳、收阴:
1、当天收阳:CLOSE>OPEN;
2、当天收阴:CLOSE<OPEN;
高开、低开:
1、当天股价高开,言下之意开盘高于昨日收盘:OPEN>REF(CLOSE,1);
2、当天股价低开:OPEN<REF(CLOSE,1);
跳空:
跳空亦有向上和向下两种:
当日开盘在昨日最高之上,即为向上跳空:OPEN>REF(HIGH,1);
反之,开盘小于昨日的最高价,为向下跳空:POEN<REF(LOW,1);
事实上,我们在编公式的过程,就是将这些条件有机地结合起来作为我们判断的条件。举一个很简单的例子,如果是K线形态呈现出放量上攻的态势,那么如何编
写这个公式呢?高开高走又应该如何编写呢?
我们把放量和上涨的两个条件组合在一起,让某一天的形态特征同时满足两个条件就达到目的;同样地将高开的高走两个条件结合在一起,也就找到了我们所需
的条件。
结果就是:
放量上攻之一,以上面所举例组合:
AA:=VOL/REF(VOL,1)>2;
BB:=CLOSE/REF(CLOSE,1)>1.07;
AA AND BB;
高开高走:
AA:=OPEN>REF(CLOSE,1);
BB:=CLOSE>OPEN;
AA AND BB;
OK!本课到此结束,留下一个问题,看看您有没有真正的理解,向上跳空之后两天内并未回补如何编写呢?
提示:实际上就是昨天发生了跳空缺口,这两天的最低价一直在两天前的最高价之上。
AA:=REF(OPEN,1)>REF(HIGH,2);
BB:=REF(LOW,1)>REF(HIGH,2);
CC:=LOW>REF(HIGH,2);
AA AND BB AND CC;
仔细一想,若BB成立,AA一定成立,AA实际上没有存在的必要,你想通了吗?
更简单的方法,下面的一句话可以的上面的四句:
COUNT(LOW>REF(HIGH,2),2)=2;
第十课 涨停板攻击?
学了这么多了,应该教点实战的内容了!我们来学习一下别人的经验,“涨停板追击”,同时这里面还润孕育着一个简单但是又颇有意义的道理!
一、量化的概念
我们都知道,按规定涨幅不得超过10%,但是由于四舍五入的关系,常常有9.98%、10.23%等等的涨停板,所以我们要找一个合适的数值,然后用分析家的语言告
诉计算机,这个过程学名叫量化!
比如我们考察之后,决定让大于9.99%的都为涨停。
二、编写公式
其实就一句话:今日收盘除以昨日收盘的值大于1.0999
X:=CLOSE/REF(CLOSE,1)>1.0999;
三、测试我们的条件
大家都知测试的功能,要不然你怎么知道你的经验在历史上的表现是好还是不好呢?
按照下图指引进入条件选股的界面,之后选中您的条件,具体办法请参见(使用说明书)。然后填入测试时间和测试标准!
在这里我们的测试方法是:
测试时间是从2000/01/01到2001/03/02,测试股票共计583只,初始投入100,000元。
当满足买入公式中定义的条件时,也就是涨停板时,按照收盘价使用相同资金买入一只股票,当满足以下平仓条件时按照收盘价平仓;买入5日后强制平仓或者亏
损达到3%止损平仓或者利润达到5%止赢平仓,然后按照以上的规则统计在测试的时间段内的所有交易的状况。
这是一种追涨的短线方法,所以测试的时间我们只用5天,目标利润为5%,(非常抱歉,因为其中的设置和选择方法十分灵活而且需要较好的理解能力,所以我们
在这里就不介绍具体的内容了)
点击开始测试!一切OK!来看结果吧!
1、从成功率上看,实际达到5%的获利要求的交易次数67.89%,我们已经比较满意这个结果了,可是要用于实战,可不可以再提高呢?
2、所谓的提高就是优化的一个内容,简单说,优化就是让它更好!优化我们的条件,让它的表现更好!
3、加上一个缩量的条件,比如当日成交量小于5日的均量;Y:=VOL<MA(VOL,5);大家可以做一下测试,看看结果如何!以下是同样测试条件下的结果。 X
AND Y;
您满意吗?我们的成功率已达到了80%,剩下的任务就是您如何操作的问题了!
注:请大家考虑一下在实战当中,如果您按此买入可不可行?
总结:编写公式并不是为了编公式而编写复杂的公式,您个人对某一个特征或者形态的理解最重要。所以光有经验不够,您还得把它转化成您自己的应对策略!
您需要不断总结、测试、优化您的公式。
第十一课 多头排列--良好的上升趋势
均线的多头排列一直以来都被大家视为一种良好的上升趋势的表现,因为这种形态的形成需要较长的时间,和较大的能量,而被主力或者庄家利用作为骗线的可
能性就比较小,股市当中也遵循惯性的原理,当一个趋势形成之后,要改变它,是不容易的,因为股价有着沿着原来的运动方向上的惯性!
首先,让我们来看看几种多头排列:
5、10、30日均线:5、10、30日均线:30、60、90日均线:
在图一中和图二中我们采用的是同一周期的均线,即都是5、10、30日均线,我们可以观察到在同一周期下的均线排列有相同之处,也有很大不同之处:图一中的
5日均线=10日均线、30日均线平滑优美,而在图二中的5日和10日均线不断的碰及30日均线然后上升;
在图三中我们选用的是30、60、90日均线,相对来说均线的多头排列也显得很平滑。
为什么会有这样的差别呢?如果您要是认真一点的话,就可以发现原来前两图的K线走得不一样,一个一波拉到头,一个分成几波拉到头,而在图三当中我们采用
了较长周期的均线系统,从而在一定程度上过滤了这种现象,具体在使用的过程中,您可要多注意它们的区别!
好了,我们来看一下如何编写,拿第一个为例,观察它们的特征:
5/10/30日均线依次从上而下的排列,这种情况维持一段时间,假设我们这里定为4天以上:
5/10/30日均线依次从上而下的排列:
AA:=MA(CLOSE,5);
BB:=MA(CLOSE,10);
CC:=MA(CLOSE,30);
T1:=AA>BB AND BB>CC;
以上情况维持一段时间,假设我们这里定为4天以上:
COUNT(T1,4)=4;
COUNT(X,N)表示统计在N天内满足条件X的有几天。
最终的结果就是如下所示:
AA:=MA(CLOSE,5);
BB:=MA(CLOSE,10);
CC:=MA(CLOSE,30);
T1:=AA>BB AND BB>CC;
COUNT(T1,4 )=4
编写完毕,我们在上面的例子当中,举的是最简单的一个,其实您在编写的过程当中,还可以加上一些比较准确地描述,以取得更好的效果,例如同时三条均线
向上发散等,当然还有您自己的心得。
=================================================================
第十二课 逃顶K线形态之--黄昏之星
一、概念学习
当市场出现一条大阳线后,通常会产生跳空高开的情况,有时便会出现十字星或类似十字星的小阴线(小阳线)。另一种相反的情况是出现在一条大阴线后,在
这两种情况下形成的类似十字星的K线都被称为“星型线”。
当该形态出现在一段上升行情的当中,就很容易形成所谓的经典K线形态--黄昏之星。
二、编制过程
通过我们前面的学习,其实已经可以比较轻松的编制这个条件了--前人已经清晰地把这个形态的具体特征描述出来,剩下的工作就是把这些特征用数字表示--这
就是前面提到的量化的过程!
该图组合一共由三根K线合成,我们按照以下的步骤一步一步地一边寻找每日K线的特征,一边进行编写:
为了结构简单起见,首先将二天的高开低收用中间表达式表达出来,因为我们在后面的编写过程中会分别使用到这些数据。
1、今日K线的:开-a1, a1:=open;
收-a2, a2:=close;
高-a3, a3:=high;
2、昨天K线的:开-b1, b1:=ref(open,1);
收-b2, b2:=ref(close,1);
高-b3, b3:=ref(high,1);
低-b4, b4:=ref(low,1);
3、前天K线的:开-c1, c1:=ref(open,2);
收-c2, c2:=ref(close,2);
高-c3, c3:=ref(high,2);
低-c4, c4:=ref(low,2);
4、我们将会分别描述出三天的K线形态,然后汇总,首先我们观察今日K线的特征,今天是一根低开低走的大阴线,我们给它一些数字上的定义:
a、今日开盘价小于昨日收盘价; aa:=a1<b2 and
b、今日的阴线实体较长,我们用开盘价和收盘价相比,长度大于4%:a1/a2>1.04;
5、昨日K线的特征,是一根十字形态的K线,并且在左右两根K线之上,分别表达为:
a、昨日跳开,高于前天的收盘: bb:=b1>c3
b、昨日收盘同样在缺口之上: and b2>c3
c、线形实体长度很小,也就是昨日开盘和收盘之差比昨日开盘的值小于0.01:and abs(b1-b2)/b1<0.01
d、K线有上下影线,可以表示为最高价和最低价不等于收盘价也不等于开盘价:and b3>b1 and b3>b2 and b4<b1 and b4<b2
e、当日的最高价为20天以来的最高价: and b3=hhv(high,20);
6、前日K线的特征:股价大幅上扬,幅度较前一日收盘高出4%并且收盘大于开盘:cc:=c2/ref(close,3)>1.04 and c2>c1;
综合选股条件:最后我们将三天的K线特征会合起来,合成一个最后的条件就是由图所示内容: aa and bb and cc
另外,团IDC网上有许多产品团购,便宜有口碑
2、股票开盘价今日和昨日的怎么相差很悬殊??如昨日是30,今日就变成15了
像你说的这种情况是因为分红除权,30变15是因为10股送十股,也就是说假如你有1手分红后就变成两手了,其实就是切大饼,跟没送一样
3、大数据概念上市公司有哪些?
?
4、如何通过雪球查询股票之前的变动状况
一. 雪球公司介绍
雪球 聪明的投资者都在这里。
web 1.0:新闻资讯,股价信息,K线图
web 2.0:SNS 订阅,分享,聊天
web 3.0:移动 APP,交易闭环
雪球现在员工数还不到100,其中技术人员占一半。去年9月C轮融资4kw刀。我们现在的技术栈由下列组件组成:Java,Scala,Akka,Finagle,Nodejs,Docker ,Hadoop。我们当前是租用IDC机房自建私有云,正在往“公私混合云”方向发展。
在雪球上,用户可以获取沪深港美2w+股票的新闻信息,股价变化情况,也可以获取债券,期货,基金,比特币,信托,理财,私募等等理财产品的各类信息,也可以关注雪球用户建立的百万组合,订阅它们的实时调仓信息,还可以关注雪球大V。雪球当前有百万日活跃用户,每天有4亿的API调用。App Store 财务免费榜第 18 名。历史上曾排到财务第二,总免费榜第 19。
二. 雪球当前总体架构
作为一个典型的移动互联网创业公司,雪球的总体架构也是非常典型的设计:
最上层是三个端:web端,android端和iOS端。流量比例大约为 2:4:4 。web3.0 的交易功能,在 web 端并不提供。
接入层以及下面的几个层,都在我们的自建机房内部。雪球当前只部署了一个机房,还属于单机房时代。正在进行“私有云+公有云混合部署”方案推进过程中。
我们当前使用 nodejs 作为 web 端模板引擎。nodejs 模块与android 和 ios 的 app 模块一起属于大前端团队负责。
再往下是位于 nginx 后面的 api 模块。跟 linkedin 的 leo 和微博的 v4 一样,雪球也有一个遗留的大一统系统,名字就叫 snowball 。最初,所有的逻辑都在 snowball 中实现的。后来慢慢的拆出去了很多 rpc 服务,再后来慢慢的拆出去了一些 http api 做成了独立业务,但即便如此,snowball 仍然是雪球系统中最大的一个部署单元。
在需要性能的地方,我们使用 netty 搭建了一些独立的接口,比如 quoto server,是用来提供开盘期间每秒一次的股价查询服务,单机 qps 5w+,这个一会再细说;而 IM 服务,起初设计里是用来提供聊天服务,而现在,它最大的用途是提供一个可靠的 push 通道,提供 5w/s 的消息下发容量,这个也一会再细说。
雪球的服务化拆分及治理采用 twitter 开源的 finagle rpc 框架,并在上面进行了一些二次开发和定制。定制的功能主要集中在 access log 增强,和 fail fast,fail over 策略及降级开关等。 finagle 的实现比较复杂,debug 和二次开发的门槛较高,团队内部对此也进行了一些讨论。
雪球的业务比较复杂,在服务层中,大致可以分为几类:第一类是web1.0,2.0 及基础服务,我们称为社区,包括用户,帖子,新闻,股价,搜索等等,类比对象就是新浪财经门户+微博;第二类是组合及推荐,主要提供股票投资策略的展示和建议,类比对象是美国的motif;第三类是通道,类似股市中的“支付宝”,接入多家券商,提供瞬间开户,一键下单等等各种方便操作的功能。
雪球的业务实现中,包含很多异步计算逻辑,比如搜索建索引,比如股票涨跌停发通知,比如组合收益计算等等,为此,我们设计了一个独立的 Thread/Task 模块,方便管理所有的后台计算任务。但随着这些 task 越来越多,逻辑差异越来越大,一个统一的模块并不是总是最佳的方案,所以,我们又把它拆成了两大类:流式的,和批量式的。
雪球的推荐体系包括组合推荐“买什么”和个性化推荐。我们最近正在重新梳理我们的大数据体系,这个感兴趣的话可以单聊。
最下面是基础设施层。雪球基础设施层包括:redis,mysql,mq,zk,hdfs,以及容器 docker。
线上服务之外,我们的开发及后台设施也很典型:gitlab开发,jenkins打包,zabbix 监控系统向 openfalcon 迁移,redimine向confluence迁移,jira,以及内部开发的 skiing 后台管理系统。
** 三. 雪球架构优化历程**
首先描述一下标题中的“股市动荡”定语修饰词吧:
上证指数从年初的3000点半年时间涨到了5000多,6月12号达到最高点5200点,然后就急转直下,最大单日跌幅 8.48%,一路跌回4000点以下。最近一周都在3900多徘徊。
3月最后一周,A股开户 166万户,超过历史最高纪录 2007年5月第二周165万户。
4月份,证监会宣布A股支持单用户开设多账户。
6月底,证金公司代表国家队入场救市。
7月份,证监会宣布严打场外配资。
中国好声音广告第一晚,带来超过平时峰值200倍的注册量
挑战:小 VS 大:
小:小公司的体量,团队小,机器规模小
大:堪比大公司的业务线数量,业务复杂度,瞬间峰值冲击
雪球的业务线 = 1个新浪财经 + 1 个微博 + 1 个 motif + 1 个大智慧/同花顺。由于基数小,API调用瞬间峰值大约为平时峰值的 30+ 倍。
挑战:快速增长,移动互联网 + 金融,风口,A股大盘剧烈波动。
首先,在app端,在我们核心业务从 web2.0 sns 向 3.0 移动交易闭环进化的过程中,我们开发了一个自己的 hybrid 框架:本地原生框架,加离线 h5 页面,以此来支撑我们的快速业务迭代。当前,雪球前端可以做到 2 周一个版本,且同时并行推进 3 个版本:一个在 app store 等待审核上线,一个在内测或公测,一个在开发。我们的前端架构师孟祥宇在今年的 wot 上有一个关于这方面的详细分享,有兴趣的可以稍后再深入了解。
雪球App实践—构建灵活、可靠的Hybrid框架 http://wot.51cto.com/2015mobile/ http://down.51cto.com/data/2080769
另外,为了保障服务的可用性,我们做了一系列的“端到端服务质量监控”。感兴趣的可以搜索我今年4月份在环信SM meetup上做的分享《移动时代端到端的稳定性保障》。其中在 app 端,我们采用了一种代价最小的数据传输方案:对用户的网络流量,电池等额外消耗几乎为0
每个请求里带上前一个请求的结果
succ or fail : 1 char
失败原因:0 - 1 char
请求接口编号: 1 char
请求耗时:2 - 3 char
其它:网络制式,etc
炒股的人大多都会盯盘:即在开盘期间,开着一个web页面或者app,实时的看股价的上下跳动。说到“实时”,美股港股当前都是流式的数据推送,但国内的A股,基本上都是每隔一段时间给出一份系统中所有股票现价的一个快照。这个时间间隔,理论上是3秒,实际上一般都在5秒左右。 交了钱签了合同,雪球作为合作方就可以从交易所下属的数据公司那里拿到数据了,然后提供给自己的用户使用。
刚才介绍总体架构图的时候有提到 quote server ,说到这是需要性能的地方。
业务场景是这样的,雪球上个人主页,开盘期间,每秒轮询一次当前用户关注的股票价格变动情况。在内部,所有的组合收益计算,每隔一段时间需要获取一下当前所有股票的实时价格。起初同时在线用户不多,这个接口就是一个部署在 snowball 中的普通接口,股价信息被实时写入 redis ,读取的时候就从 redis 中读。后来,A股大涨,snowball 抗不住了。于是我们就做了一个典型的优化:独立 server + 本地内存存储。开盘期间每次数据更新后,数据接收组件主动去更新 quote server 内存中的数据。 后续进一步优化方案是将这个接口以及相关的处理逻辑都迁移到公有云上去。
对于那些不盯盘的人,最实用的功能就是股价提醒了。在雪球上,你除了可以关注用户,还可以关注股票。如果你关注的某只股票涨了或跌了,我们都可以非常及时的通知你。雪球上热门股票拥有超过 50w 粉丝(招商银行,苏宁云商)粉丝可以设置:当这支股票涨幅或跌幅超过 x%(默认7%)时提醒我。曾经连续3天,每天超过1000股跌停,证监会开了一个会,于是接下来2天超过1000股涨停
原来做法:
股票涨(跌)x%,扫一遍粉丝列表,过滤出所有符合条件的粉丝,推送消息
新做法:
预先建立索引,开盘期间载入内存
1%:uid1,uid2
2%:uid3,uid4,uid5
3%:uid6
问题:有时候嫌太及时了:频繁跌停,打开跌停,再跌停,再打开。。。的时候
内部线上记录:
4台机器。
单条消息延时 99% 小于 30秒。
下一步优化目标:99% 小于 10 秒
IM 系统最初的设计目标是为雪球上的用户提供一个聊天的功能:
送达率第一
雪球IM:Netty + 自定义网络协议
Akka : 每个在线client一个actor
推模式:client 在线情况下使用推模式
多端同步:单账号多端可登录,并保持各种状态同步
移动互联网时代,除了微信qq以外的所有IM,都转型成了推送通道,核心指标变成了瞬间峰值性能。原有架构很多地方都不太合适了。
优化:
分配更多资源:推送账号actor池
精简业务逻辑:重复消息只存id,实时提醒内容不推历史设备,不更新非活跃设备的session列表等等
本地缓存:拉黑等无法精简的业务逻辑迁移到本地缓存
优化代码:异步加密存储,去除不合理的 akka 使用
akka这个解释一下:akka 有一个自己的 log adapter,内部使用一个 actor 来处理所有的 log event stream 。当瞬间峰值到来的时候,这个 event stream 一下子就堵了上百万条 log ,导致 gc 颠簸非常严重。最后的解决办法是,绕过 akka 的 log adapter,直接使用 logback 的 appender
线上记录:5w/s (主动限速)的推送持续 3 分钟,p99 性能指标无明显变化
7月10号我们在中国好声音上做了3期广告。在广告播出之前,我们针对广告可能带来的对系统的冲击进行了压力测试,主要是新用户注册模块,当时预估广告播出期间2小时新注册100万
压测发现 DB 成为瓶颈:
昵称检测 cache miss > 40%
昵称禁用词 where like 模糊查询
手机号是否注册 cache miss > 80%
注册新用户:5 insert
优化:
redis store:昵称,手机号
本地存储:昵称禁用词
业务流程优化:DB insert 操作同步改异步
下一步优化计划:
将 sns 系统中所有的上行操作都改成类似的异步模式
接口调用时中只更新缓存,而且主动设置5分钟过期,然后写一个消息到 mq 队列,队列处理程序拿到消息再做其它耗时操作。
为了支持失败重试,需要将主要的资源操作步骤都做成幂等。
前置模块HA:
合作方合规要求:业务单元部署到合作方内网,用户的敏感数据不允许离开进程内存
业务本身要求:业务单元本身为有状态服务,业务单元高可用
解决方案:
使用 Hazelcast In-Memory Data Grid 的 replication map 在多个 jvm 实例之间做数据同步。
java 启动参数加上 -XX:+DisableAttachMechanism -XX:-UsePerfData,禁止 jstack,jmap 等等 jdk 工具连接
关于前置模块,其实还有很多很奇葩的故事,鉴于时间关系,这里就不展开讲了。以后有机会可以当笑话给大家讲。
组合净值计算性能优化:
一支股票可能在超过20万个组合里(南车北车中车,暴风科技)
离线计算,存储计算后的结果
股价3秒变一次,涉及到这支股票的所有组合理论上也需要每 3 秒重新计算一次
大家可能会问,为什么不用户请求时,实时计算呢?这是因为“组合净值”中还包括分红送配,分股,送股,拆股,合股,现金,红利等等,业务太过复杂,开发初期经常需要调整计算逻辑,所以就设计成后台离线计算模式了。当前正在改造,将分红送配逻辑做成离线计算,股价组成的净值实时计算。接口请求是,将实时计算部分和离线计算部分合并成最终结果。
实际上,我们的计算逻辑是比较低效的:循环遍历所有的组合,对每个组合,获取所有的价值数据,然后计算。完成一遍循环后,立即开始下一轮循环。
优化:
分级:活跃用户的活跃组合,其它组合。
批量:拉取当前所有股票的现价到 JVM 内存里,这一轮的所有组合计算都用这一份股价快照。
关于这个话题的更详细内容,感兴趣的可以参考雪球组合业务总监张岩枫在今年的 arch summit 深圳大会上的分享:构建高可用的雪球投资组合系统技术实践 http://sz2015.archsummit.com/speakers/201825
最后,我们还做了一些通用的架构和性能优化,包括jdk升级到8,开发了一个基于 zookeeper 的 config center 和开关降级系统
四. 聊聊关于架构优化的一些总结和感想
在各种场合经常听说的架构优化,一般都是优化某一个具体的业务模块,将性能优化到极致。而在雪球,我们做的架构优化更多的是从问题出发,解决实际问题,解决到可以接受的程度即可。可能大家看起来会觉得很凌乱,而且每个事情单独拎出来好像都不是什么大事。
我们在对一个大服务做架构优化时,一般是往深入的本质进行挖掘;当我们面对一堆架构各异的小服务时,“架构优化”的含义其实是有一些不一样的。大部分时候,我们并不需要(也没有办法)深入到小服务的最底层进行优化,而是去掉或者优化原来明显不合理的地方就可以了。
在快速迭代的创业公司,我们可能不会针对某一个服务做很完善的架构设计和代码实现,当出现各种问题时,也不会去追求极致的优化,而是以解决瓶颈问题为先。
即使我们经历过一回将 snowball 拆分服务化的过程,但当我们重新上一个新的业务时,我们依然选择将它做成一个大一统的服务。只是这一次,我们会提前定义好每个模块的 service 接口,为以后可能的服务化铺好路。
在创业公司里,重写是不能接受的;大的重构,从时间和人力投入上看,一般也是无法承担的。而“裱糊匠”式做法,哪里有性能问题就加机器,加缓存,加数据库,有可用性问题就加重试,加log,出故障就加流程,加测试,这也不是雪球团队工作方式。我们一般都采用最小改动的方式,即,准确定义问题,定位问题根源,找到问题本质,制定最佳方案,以最小的改动代价,将问题解决到可接受的范围内。
我们现在正在所有的地方强推3个数据指标:qps,p99,error rate。每个技术人员对自己负责的服务,一定要有最基本的数据指标意识。数字,是发现问题,定位根源,找到本质的最重要的依赖条件。没有之一。
我们的原则:保持技术栈的一致性和简单性,有节制的尝试新技术,保持所有线上服务依赖的技术可控,简单来说,能 hold 住。
能用cache的地方绝不用db,能异步的地方,绝不同步。俗称的:吃一堑,长一智。
特事特办:业务在发展,需求在变化,实现方式也需要跟着变化。简单的来说:遗留系统的优化,最佳方案就是砍需求,呵呵。