聊聊量化投资项目以及项目总结
你好。我的朋友。我是一个2022年运气欠佳的人,年初公司融资受阻,杭州部门被裁,然后来到新公司搞量化投资的项目,因项目经理PUA,组内所有人员与其都有冲突,所以我在转正前一天,裸辞。
人,不会永远都走背字,否极泰来。上份工作太糟心,休息4天,给自己回回血,然后利用这段时间,充电学习。
这篇文章,会写两大部分,第一部分是技术相关的东西,以及项目整体的设计;第二部分是,回顾团队建设以及心灵鸡汤,如果不喜欢看,第二部分可以略过。
第一部分:
项目背景:
量化投资。具体来说,做的是投资管理系统,是服务于量化投资人员,或是投资个体人员,将投资策略的历史收益情况展现给用户,辅助用户来做出投资决策。(如果想有感官的认识,大家可以在支付宝上,买个50块钱基金,上面的一些介绍以及走势等等,是最最基本的雏形)
项目技术架构:
微服务架构Spring-cloud(网关Gateway、nacos作为注册中心和配置中心、服务调用Feign、负载均衡Ribbon、熔断器Hystrix)
前后分离:
Nginx、Java 8、SSM、maven、Redis、docker(docker-compose)、git
Mysql、Linux(Centos)、阿里云服务器
前端:Vue 2.X
业务:
将策略从成立以来到今日为止的每一天收益以曲线的形式展示出来。时间段可以包括:成立以来,近3年,近1年,近半年,3个月,1个月等。
此外,还可以按照区间收益、年度收益、季度收益、月度收益,通过柱状图和列表来展示上述数据。
不同的策略可以组合成不同的分类,不同的分类同时又可以组成不同的组合。这种多样性的组合,目的就是鸡蛋不放在一个篮子中。在大盘稳定的情况下,可以保证用户的正收益。
业务中的核心:
策略的每天净值。
收益曲线是由点组成,那么这些点就是策略的净值。由策略创建组合,组合的净值,也是由策略的净值拟合得到的。净值缺失检测,每天更新净值,净值拟合绘画曲线,通过净值来计算收益率等核心功能全是围绕这个净值展开的。
净值的数据量有多大?
每年365天,一共255个交易日,每个交易日,每个策略都会产生一条策略净值。那么1000个策略10年的数据量:1000*255*10= 2,550,000.(大家先记住这个数据量,随我慢慢往下看)
项目中,3个月,我完成的任务:
1.列表、柱状图、净值曲线显示等,性能优化。
2.指导初、中级人员
3.复杂功能(复利加仓)的实现,修复线上OOM和数据库死锁问题
4.搭建组内底层基础设施(Jenkins、Docker环境、docker-compose)
5.技术分享(消息队列RabbitMq和线程池)以及技术文档编写
6.Http协议切换Https协议
接下里针对上述完成的任务做具体的说明,以供大家参考:
1.列表、柱状图、净值曲线显示等,性能优化
====>
做性能优化,首先要找到慢的地方,接手时,优化的功能逻辑不是我开发的,我不熟悉,所以只能用StopWath工具类,在代码中,打印时间戳,找到每个小功能的时间耗时。然后针对各个问题做逐步测分析、性能问题定位,最后优化。
当时发现的问题:
①sql部分:
有的表需要添加索引;
创建联合索引时要考虑到索引中,字段的顺序,最左匹配原则;
业务上出发,可以减少表中不必要的限制条件
for循环中的单次查询变成批量查询(这个问题出现的原因,跟开发者沟通过,是由于开发阶段时间任务紧,所以,一切从简,不考虑性能。开发完成需求是首要目标,性能优化,那是下个阶段的事情了。这个事情,我在两家公司都发现了这个问题,不能单独说是开发者的问题。任务的工期、开发者的技术素质、开发流程等,各个方面都应该为这个问题负责);
explain sql语句,查看sql的执行计划,看看是否有可以优化的空间;
②单次查询,改成批量查询
例如查询某一策略成立以来的收益,那么成立以来就包括近1月、近3月、近半年、近1年等,那么以前查询多次sql,现在可以变成查询一次时间段最长的sql,然后将结果在业务代码中按照时间段分割。这样减少sql发行的次数。
③业务流程上的考虑
查询一次列表数据,只有几百条数据,但是耗时1000多ms,这个不正常。系统中耗时的地方,要么是IO,要么是计算。debug,跟了一遍业务流程,发现列表取出来的数据,每次都是实时计算得到的,而那些数据,在净值不发生变化时,是根本不会变化的。那么,这个性能痛点找到了,因此。将计算的逻辑提取出来,提前计算好,存到db的表中,每次查询时去表中读取计算后的值。当满足业务的一定条件,会通过消息队列,触发更新表中数据的业务计算逻辑。
优化后,这个列表接口耗时从1000多个ms,下降到100 ms。优化完成。
2.指导初、中级人员
5.技术分享(消息队列RabbitMq和线程池)以及技术文档编写
====>
这一部分,我是将我所学交给他们,软件这一行业,更像一门手艺,一代一代传承(有点夸张了)。
当初毕业时,有人带的我,教我。如今,我也会善待下面的人,只要下面的人愿意学习,我会尽自己所能指导。
现在的人,大家都很聪明,都有上进心,想变得优秀,都愿意做有挑战的事情。因为这部分可以帮助大家涨本事、涨工资。可是,有时没有机会或是没有能力去做。
那么,此时能做的,应该是尽自己所能为组内做一些事情。
例如:我可以改成这个bug,我可以做好这个文档,我可以梳理好这个业务,或是我可以将自己负责的业务以及技术分享给大家。这都是很好的。
我将当时选择RabbitMq的原因以及线程池的使用注意事项以及不停机动态修改线程池参数,跟大家进行了分享。
组内选择RabbitMq的原因:
项目前期用户数量不会太多,估计前期几十到几百足矣。并发量不大。同时,金融项目中,业务非常复杂,以及调研了组内人员使用消息中间件的情况,最后选择了RabbitMq。
第二部分:
这部分本来想写组内项目经理PUA的事情。但是,如今社会,有种很怪的现象,喜欢比惨,那么,姑且这部分忽略那些令人讨厌的PUA故事,转而给自己以及身处困境的你,打打气。
一起跨过这个小小的困难。
在这里,关于团队方面,我要和大家进行探讨。
(1)如何保证团队的稳定?
我看过统计资料,并和身边的同事们聊天,离职原因很大的一个要素是团队的leader。
leader对人对事要公正,要能够照顾下面的兄弟。
建立技术团队中,人员的梯度(初级、中级、高级),这样让下面的人看到上一级优秀的人员,向他们学习,让大家有干劲。有助于团队整体进步。
招募人员时,了解人员的需求,了解他们的背景经历。
(2)如何保证项目的工期和质量?
首先,根据产品的需求和预算,从低成本、易扩展、上手快等方面出发,搭建合理的架构平台。在技术选型方面,我会考虑技术的通用性,使用的人数是否够多(这样在遇到一些问题时,便于解决)。
最合适的技术,才是正确的。技术上没有好坏。
项目前期作为组长可以写一些demo代码让大家参考,但是不要提交。同时,要引入阿里的cp3(代码check插件),以及SonarQube等检测工具(检测bug以及代码异味);同时在提交代码时,要对代码进行review,在前期保证一个好的开端,减少后期返工的麻烦。然后再Jira上可以统计相关bug,并在组内展开,减少同类型的bug。
工期设定方面,可以尝试从期限日开始逆推,拆分成各个小目标,可以以周或是月为单位。这样的话,便于工期的把控。如果出现了延迟,那么,适当增加人员还是加班,或是人员对某一技术领域不熟悉,那么这时需要团队负责人根据实际情况出发,发现问题、定位问题、解决问题。短期的工期延迟,不是大问题。
技术上的问题100%是可以解决的,取决于时间和成本。
有时你会加班到深夜,独自下班,然后第二天还会被埋怨;有时,面对巨大压力,内心有种想哭的冲动。有时,一个人身体不舒服,只好自己随便百度一下,买了点药,随便一吃,希望能挺过去。。。
好好爱自己,给自己一个可以放下的理由。如今的社会,不会把人饿死,现在失意只是暂时的,短暂的停歇是为了让自己充电提升,理顺目标,更好地前行。
Don't cry. You 're loved. You 're strong.
等经历过这一切,某一天,回头望去,你会知道,你所经历的这一切,是值得的。有一个使命或是有一件老天安排的事情在等着你。