最近内卷传得越来越厉害,回头看看自己从毕业到现在这十几年,似乎也没存下啥东东,如果哪天裸辞(或被炒掉),身上这点积蓄好像也坚持不了太久呢,就这样中年危机的感觉忽如其来。
很早之前也了解过基金、股票这类的投资理财产品,但是由于各种原因,也只是时不时的在网上随便挑几支,买一点,几年过去了,好像也没赚到什么钱,看来投资这事儿还真不是随手买买,佛系理财能干得了的,是时候认真学习理财了。
在知乎上找了一个live课程(个人觉得简七讲得就挺好的)学习了一段时间,确实让我对理财投资有了新的理解,基于自己还是一名打工人的现状,还是买基金靠谱一点,毕竟有专业人士操盘呢,只要选好了定投就行。可这么多基金怎么选呢?又怕app上推荐的其实是广告,其收益并不靠谱。思来想去,对呀!咱可以参考行业网站呀,比如晨星网。这个网站早在几年前就关注到了,可是实在搞不懂它上面各种指标到底啥意思(还是懒啊),所以也就没在继续研究了。不过现在不一样了,有压力就有动力,那就仔细研究下吧。经过一系列的网上学习,大致上对晨星的各项风险指标有了初步的理解,对怎么选基金也有了个人的判断,好啦,现在理论有了,就差实践了。可是当我抱着一夜暴富的信心打开蚂蚁财富的时候,才发现理论和现实有些脱钩,这可怎么选呀。
显然蚂蚁财富并没有对每一个基金做详细的分析,不过想想也对,投资有风险嘛。谁也不敢拍着胸脯说跟着我买绝对不亏的。
不过理解归理解,我还是得想想办法怎么快速选出我可以买的基金,晨星上基金资料最全,但是光是看基金列表都有500多页,这可得选到啥时候啊。不过都走到这一步了,自然就得让我们的爬虫小工具来辅助自己了。
基金爬虫
爬虫最主要的任务是自动从晨星网上将基金各种信息都爬下来,并保存在数据库当中,然后根据自己定义的规则对基金进行排序,这样排在前面的就是符合自己购买风格的基金啦。
基金爬虫在jackluson的基础上做了重新编码和逻辑调整。对于辅助挑选基金这个需求,脚本需要能抓取晨星上所有基金的晨星评级、购买单价、买入卖出手续费以及几大风险指标。等数据准备好之后,再按照一定的规则从数据库中查询出来即可。
脚本主要逻辑是通过访问三个网址来获取必要信息。通过登录让浏览器具有合法访问的session,然后通过遍历基金列表页面获取所有基金的基本信息(其中最重要的是晨星代码),然后通过组合出详情页(https://www.morningstar.cn/quicktake/晨星代码)获取某一个指定基金的风险指标数据。
主逻辑调通以后,外部只需要依据规则调用对应的接口函数即可。
import os,sys
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from support.website.morningstar import MorningStar
def initDriver():
driver = webdriver.Remote(
command_executor="http://chrome:4444/wd/hub",
desired_capabilities=DesiredCapabilities.CHROME
)
driver.implicitly_wait(10)
return driver
def close(driver):
driver.close()
driver.quit()
if __name__ == "__main__":
driver = initDriver()
ms = MorningStar(driver)
try:
if(ms.login(os.getenv("MS_USERNAME"), os.getenv("MS_PASSWORD"), None)):
ms.refluseFundInfo(sys.argv[1] == "True", sys.argv[2], sys.argv[3])
finally:
ms.close()
close(driver)
调用方式仍然套用《Selenium在线执行》中设计的模板。
完整代码已上传至Gitee
前端
后端数据准备就绪后,前端反而简单了许多,在原《二手房热力图》的基础上,新增一个table页即可。作为五流前端工程师就不自嗨了,勉强看看效果吧。
搜索功能目前暂不提供,仅有一个输入框而已。
遗留问题
一开始我以为就是爬一个较大数据量的网站嘛,最多耗时长点而已。可没成想第一次运行脚本,小云的负载直接填满,CPU使用率持续100%、内存占用率持续超98%,云平台连发两封告警邮件。而且持续时间之长,跑了3个小时也没跑完,期间导致系统使用出现各种异常比如:vim打不开,命令查询无响应,docker子网络中断等等。我粗略估计了一下,照这个进度一晚上应该是搞不定了,并且对我其他正在运行的服务也可能带来影响(目前云上共运行11个docker,提供了网关,网盘,图床,数据库等一系列的服务)。所以我决定把任务拆分成多个子任务,放在每天的凌晨执行,这也是迫使我《趟坑cron》的原因之一。
当然也许使用诸如分布式爬虫或更优秀爬虫框架能解决我这一问题,不过考虑到我就这么一朵小云,且算力就这么一点,我觉得还是不折腾了吧,等以后有机会再去学习各种花式操作。所以这一问题就先遗留下来了。
附 晨星风险说明
基金风险平均回报
平均回报为年度化的平均月几何回报,得出数据未必与过去一年实际年度回报相等。
标准差
反映计算期内总回报率的波动幅度,即基金每月的总回报率相对于平均月回报率的偏差程度,波动越大,标准差也越大。
夏普比率
夏普比率是衡量基金风险调整后收益的指标之一,反映了基金承担单位风险所获得的超额回报率(Excess Returns),即基金总回报率高于同期无风险收益率的部分,一般情况下,该比率越高,基金承担单位风险得到的超额回报率越高。
晨星风险系数
晨星风险系数反映计算期内相对于同类基金,基金收益向下波动的风险。其计算方法为:相对无风险收益率的基金平均损失除以同类别平均损失。一般情况下,该指标越大,下行风险越高。
相对表现阿尔法系数(α)
阿尔法系数(α)是基金的实际收益和按照β系数计算的期望收益之间的差额。其计算方法如下:超额收益是基金的收益减去无风险投资收益(在中国为1年期银行定期存款收益);期望收益是贝塔系数β和市场收益的乘积,反映基金由于市场整体变动而获得的收益;超额收益和期望收益的差额即α系数。
贝塔系数(β)
贝塔系数衡量基金收益相对于业绩评价基准收益的总体波动性,是一个相对指标。β越高,意味着基金相对于业绩评价基准的波动性越大。β大于1 ,则基金的波动性大于业绩评价基准的波动性。反之亦然。如果β为1 ,则市场上涨10%,基金上涨10%;市场下滑10%,基金相应下滑10%。如果β为 1.1,市场上涨10%时,基金上涨11%, ;市场下滑10%时,基金下滑11% 。如果β为 0.9, 市场上涨10%时,基金上涨9% ;市场下滑10%时,基金下滑9% 。
R平方
R平方(R-squared)是反映业绩基准的变动对基金表现的影响,影响程度以0至100计。如果R平方值等于100 ,表示基金回报的变动完全由业绩基准的变动所致;若R平方值等于35,即35%的基金回报可归因于业绩基准的变动。简言之,R平方值愈低,由业绩基准变动导致的基金业绩的变动便愈少。此外,R平方也可用来确定贝塔系数(β)或阿尔法系数(α)的准确性。一般而言,基金的R平方值愈高,其两个系数的准确性便愈高。