R语言在保险资产管理中的应用实践分享

参加“保险公司经济资本研讨会”的发言稿

谭显英

2019/11/14

来源

10月中旬应芳姐邀请,回系里分享了R在保险资管中的一些应用,主要是给大家普及下R可以做什么。自己实在临场发挥的水平不佳,就事先准备了一份发言稿。还是用心准备了好几天,所以就简单地整理后分享了出来。

R语言在数据建模的各个环节都可以扮演重要的作用

“可重复化”对于研究和提高工作效率都是非常重要

数据建模/数据分析的步骤

数据分析相关的工作,从大的环节来讲,可以归纳为三个步骤:数据准备(Input) -> 数据建模(Modeling) -> 数据结果 (Output) 。当然,这是一个不断重复的过程,在得到结果后,我们需要对它进行审视和分析,并以此对数据和模型进行调整,不断循环。经过近30年的发展,R语言已经建立起了强大的软件生态能够对数据分析的各个环节给以较好的支持。

数据准备环节

数据准备的环节就是从各种数据源读取原始数据,进行预处理,整合变换成适合模型的结构化数据的过程。

金融行业数据的特点——数据源繁杂、数据量相对较大

从资产类别来讲有股票、债券等标准化的产品能从第三方咨询数据库取得,也有债权计划和信托这样的非标准化产品只能靠人工记录,境内资产的信息万得全一些,境外资产的信息又只能依靠彭博,有些数据只能通过爬取网站的数据获得……

R语言能够提供较完备的工具来获取各种渠道的数据,比如csv等文本数据可以用data.table::fread()或者readr, Excel的数据可以用readxl,万得的数据WindR,彭博的数据Rblp,数据库无论是SQL Sever, Oracle, Access, MySQL,SQLite都有很好的支持,网页爬虫当然也没问题。

真实世界的复杂带来了原始数据的复杂,原始数据的复杂导致了数据处理的复杂

实际数据分析工作中,可以毫不夸张地说,90%的时间都是在“清理”和“整合”数据上,对于金融行业尤甚。由于数据永远不会是完美无缺的,都有各种各样的“特点”。数据的预处理就是通过抓住数据的特点来整合得到模型需要的数据结构的过程,数据本身的复杂性导致了数据处理的过程有可能非常复杂,要求理想的数据处理的工具具有如下特点:

另外,对于大型数据而言,数据处理的速度显得尤为重要。得益于R是一个由“统计学家”开发的语言,R在数据处理的方面的工具算得上是“地表最强”。举一个简单的例子,金融数据大部分都是和时间紧密相关——时间面板数据,我现在有一张表A是不同日期某个组合持有的证券信息,有另外一张表B是不同日期下所有证券的某个信息,比如价格。现在我需要得到表A每一行证券在对应日期“可获得的最新价格”,应该怎么做?R语言的data.table包就可以允许你一句话完成这项工作B[A, roll = TRUE, on = .(CODE, DATE)],而且速度极快(如果表B是千万行级别,基本也能在1秒内完成)。

模型搭建

R语言对于大部分同学来说,用它的目的就是因为某个“新”的统计方法在R里面有现成的包可以用。所以,R语言的另外一个特性就是里面有大量现成的统计计量工具可以使用,而且质量都相对较高。这得益于R在统计学家中的流行以及CRAN——R包的官方网站——对于质量的严格控制。

模型搭建需要统计工具,但并不是所有的工作都是R语言所擅长的。比如,R语言是一个解释型的动态语言,它的运作原理和设计原则决定了它适合进行能够向量化的统计科学类计算,对于某些特定的细节问题,使用C/C++等更那么”计算机”一点的语言可能会更适合。再比如,对于机器学习尤其是深度学习这个领域,python相关的库或者现成的代码会更丰富。R是一种具有粘结其他语言能力的编程语言,可以很方便地调用C/C++/Python相关的函数代码。

实务工作中,不同的工作和任务都是相互关联而不是完全独立的。这意味着,函数/模型的分享机制非常重要。比如,许多工作都需要从公司数据库中读取数据,我们希望每个脚本都能非常简单地建立起同数据库的链接,而不是复制粘贴一大堆配置代码,这样既不美观也有很大的维护问题。因为任何一个具体的模型/工作/函数——都必须要随着业务实践的发展不停地迭代更新。R语言有一套非常完善和强大的扩展机制——就是包package——能够非常方便地用来固化和分享模型代码。 通过这种方式,R包的这种方式能够使得工具或者知识的迭代更新同实际工作流程很好地结合起来。比如,在修复问题或者增加新的功能后,其他同事只需要运行下更新包就能自动得到新的代码。

另外,R语言具有极好的前后兼容性以及跨平台的特性。公司的模型往往会被使用很多年,我们既希望通过升级R版本和相关包的版本来使用最新的语言特性,也希望自己以前写的代码能够一直运行下去,而不是出现各种各样的bug。R语言是非常重视前后兼容性,以至于也许20年前写的R代码至今仍然可以被完美的运行。随着业务越来越复杂,之前写的代码可能就需要被应用到一些起初没有计划过的场景,比如linux服务器上。R语言优秀的跨平台特性,让你可以直接切换平台而不需要额外的调整修改。

最后,不得不提及的是R语言的开源属性和其健康的社区环境。开源的属性保证了对于任何具体的计算函数,我们只要愿意都可以分析其源代码,而不会有任何“黑箱”情况的存在。更重要的是,开源意味着更多的人能够方便地参与到R语言的进化过程中去,这意味着新的技术新的方法新的工具能够很快地在R语言中被应用。健康的社区环境意味着,我们在搜寻特定技术问题答案时,能够很快地找到结果乃至获得全球各地R用户的帮助,这对于初学者来讲有着非常重要的意义。另外,R语言包的文档帮助系统非常完善,很多包都有大量的详尽的帮助文档和使用介绍等信息,让上手变得更加容易

结果输出

R有着强大的画图功能。也许有不少同学是因为需要画图才用的R。ggplot2是一个非常著名的包,它是根据the grammar of graphics这本书,建立了一套数据和图形的关系,能够方便地制作各种其他工具难以完成的图形。

当然除了传统的静态图形外,近些年来R建立起了较好的web相关的技术生态,许多javascript的图形库都能够使用R语言轻松调用并展现。例如,百度的echarts库是一个可以用来展现各种动态图形的库,但是恐怕只有计算机专业的童鞋才懂得怎么直接使用,而且和数据分析的环节脱节非常不方便。在R语言里,你可以简单地执行这样一句话,就能够把“数据”转换为精美的echarts动态图,而不用去操心背后的技术细节。

R是对“文学化编程”支持得最好的语言之一,也是最早开始支持这个特性的语言之一,这让自动化报告变得更加容易。 实际工作中,不少报告的日常更新并不会涉及到结构的变化,而是根据新的数据按照原来的模板进行重新生成。“文学化编程”指的是,把报告的文字和编程语言相结合的方式撰写,运行该文档的时候,文档中的代码部分会自动地转换为对应的值,既实现了报告的自动更新,又让文字和数据的关联变得更加紧密。knitr/rmarkdown/blogdown/bookdown让自动化报告、个人博客甚至写书都变得非常简单。

漂亮直观的的模型交互界面交互方式能让我们更好更快地去理解数据理解模型和发现规律。也许我们在阅读报告的时候总是会想如果把参数调成这个样子,结果就是什么样呢?但我们是学精算学统计的不是做计算机的,更何况复杂的交互系统需要的工程处理一点也不简单。shiny是R世界的一个非常神奇的工具,通过它一个不会IT的童鞋也能够方便地搭建一个可以交互的Web应用程序,用来展现我们的模型

总结

R语言具有强大的数据分析表达能力,具有丰富的数据处理工具,具有很棒的人机/语言间交互能力,具有出色的可扩展性以及健康的软件生态环境,这让它成为了最适合数据分析和建模的语言之一。

保险资产管理公司中的应用示例

保险资产管理投资组合分析系统

保险资产管理的数据非常复杂,原因:

  1. 资产类别很丰富——公募、私募、场内、场外、证券、非标、境内、境外、外币、衍生品,不同的资产往往对应着不同的数据源,同一个资产其数据维度也很丰富;
  2. 投资组合很多,母公司的账户加第三方的产品数量往往达到成百上千的级别;
  3. 资管行业是一个变化很快的行业,不断会遇到新的市场环境、新的投资品种和新的监管要求。

投资组合的管理第一步是需要清晰地认清组合信息,然而整合多账户多资产的信息是一个非常困难的事情,因为这需要对不同数据源的整合和资产管理的业务都非常了解,更重要的是还要及时不断地满足各种变化产生的新需求。复杂的业务本质导致IT和软件公司无法给出准确的信息表,业内惯常的做法是,在系统中导出原始表后进行手工的加工和核对,再利用这张核对过的持仓表来完成后续模型指标的计算更新等。

这样做有很多弊端:

  1. 人工参与的环节太多既低效又容易出错;
  2. 市场变化万千,我们需要及时的信息,但这种方式难以及时地得到及时准确地有效信息;
  3. 受制于源数据的难以复制性,系统化组合分析报告系统变成了奢求。

R语言具有很强的数据整合处理加工能力,借助于此我们使用R语言直接从财务估值系统、交易系统、咨询数据库等信息源获取原始数据进行直接的解析(parse),实现了业内最好的投资组合基础数据库之一,包含了全方位的持仓、交易、损益、现金流、证券衍生信息等多维度的信息,而且由于解析速度快,能实现和财务估值系统的快速同步。另外由于整个解析过程清晰透明,对于每一个产生数据点,其来源都能得到清晰地追溯(这一点非常重要,因为各种数据的错误是难免的,当分析报告中出现异常时,你需要清晰地知道是数据的错误还是计算逻辑的错误)。

在解决了核心基础数据库的准确性和可重复性后,我们首先通过R包的形式将许多常用的分析函数进行固化,这样其他同事进行相关分析操作的时候只需要使用这个函数就可以了。

在这个基础上,对于日常的工作我们搭建了三种不同的方式来处理:

  1. 脚本形式:也就是一系列的程序代码用来完成一个具体的任务。这种工作往往都是其他同事或者客户的各种数据需求,需要的时候我们运行下这个脚本,这个脚本可以生成一个Excel并自动打开,我们粘到邮件或者PPT中去即可;
  2. 自动化的报告形式:对于常规性的分析报告等,我们会做好LaTeX或者R Markdown的模板,自动按天或者按周运行,系统会自动生成好报告后发送到相关收件人的邮箱中,也或者会挂到公司内网中;
  3. 基于Shiny的Web应用程序:之前介绍过Shiny可以用来帮助我们很快速地开发出一个特定的网页形式的应用程序,用户可以控制不同的选项从而得到自己想要的结果。对于同事经常需要了解的,非报告形式的信息,我们利用Shiny(结合Docker技术进行规模化部署)搭建了一个系统,可以查询不同时间段、不同投资组合(或者多个不同投资组合)的各种信息或指标,还有很多贴心的小功能,比如把不同部门的工作计划Excel表自动转为漂亮的工作计划PDF等……

总结,通过R语言为工具,我们能够将复杂困难的工作一点一点地通过代码固化下来,将任务分解掉,从而使得工作变得简单也更加的有趣。

股票多因子量化策略开发及回测系统

股票多因子框架,就是将股票的特征进行数据化——打标签,然后对标签进行分析和探索,力图找到一些规律(模型)来构建一个有较好收益风险比的量化策略的过程。数据上的一些特点有,数据量相对较大,维度很丰富,细节处理繁琐。建模设计中最关键的一点是要在保证计算速度和计算逻辑清晰性的同时,避免任何可能地使用到未来信息。因为未来信息在实际交易中是无法获取的,包含未来信息的研究在真实交易中往往会表现得很糟糕。

前面提到,研究的过程是不断重复的过程,重复的速度部分地决定了我们研究的速度。由于整个处理涉及到大量的细节,没办法进行向量化处理,必须得一个元素一个元素地进行处理,我们最后选择了C++作为核心计算引擎的语言。使用C++的好处我简单提一下,一方面C++使用得当的情况下是可以把计算速度达到飞快的程度。另外一方面,面向对象编程的思想在解决某些问题时非常有用,比如回测的模型如果选择搭建和真实交易环境一样的模型,也就是投资经理-风控-交易室-交易所-清算的模型,会让整个模型对于交易细节的控制能更直观和更丰富。又比如利用代理对象的思想就能够完全规避掉计算逻辑中使用未来数据的可能(当然数据和思想上的未来数据是永远也无法完全根除的),同时又几乎不影响计算速度。得益于R对于C和C++语言良好的支持,我们只需要专注于使用C++完成它最擅长的事情——计算,对于C++不太擅长得数据输入和结果输出等,我们还是可以利用R语言来出色地完成。这样的结合使得整个模型的搭建效率提高了,而且计算速度和可维护性等都变得更好了。

最后

希望能看到越来越多的小伙伴加入R语言的大家庭,把R语言应用到实际工作和学习中。