跳到主要内容
工程的博客

现代化风险管理第1部分:流数据摄取,快速模型开发和大规模蒙特卡罗模拟

2020年5月27日 工程的博客

分享这篇文章

该加速器的第2部分在这里

管理金融服务内部的风险在过去几年中,特别是在银行业内部,复杂性有所增加。首先,新框架(如FRTB)正在被引入,这可能需要巨大的计算能力和分析多年历史数据的能力。与此同时,监管机构要求他们监管的银行提高透明度和可解释性。最后,新技术和商业模式的引入意味着对健全风险治理的需求空前高涨。然而,银行业有效满足这些需求的能力并非易事。依赖本地基础设施的传统银行已无法有效管理风险。银行必须放弃传统技术的计算效率低下,并建立一个灵活的现代风险管理实践,能够通过使用数据和高级分析快速响应市场和经济波动。最近的经验表明,随着新威胁的出现,历史数据和汇总风险模型很快就会失去预测价值。风险分析师必须用替代数据集来增强传统数据,以便探索新的方法来识别和量化其业务面临的风险,无论是大规模的还是实时的。

在这篇博客中,我们将展示如何通过使用Databricks统一数据分析平台的各种组件(Delta Lake, Apache SparkTM和MLflow)来实现传统的风险价值(VaR)计算的现代化,从而实现更灵活和前瞻性的风险管理方法。bob体育客户端下载

Databricks架构用于使传统的VaR计算现代化。

第一个系列的笔记本将涵盖多个数据工程和数据科学的挑战,必须解决有效的现代化风险管理实践:

  • 使用Delta Lake来获得市场数据的统一视图
  • 利用MLflow作为模型开发和部署的交付工具
  • 使用Apache Spark进行大规模的蒙特卡罗模拟

为了获得更敏捷和前瞻性的风险管理方法,有效地分割蒙特卡洛模拟的能力将在第二篇博客文章中介绍,更多地关注风险分析师的角色。

使用Delta Lake实现数据管理现代化

随着大数据和基于云的技术的兴起,IT领域在过去十年发生了巨大的变化。然而,大多数金融服务机构仍然依赖大型机和非分布式数据库来进行核心风险操作,如VaR计算,只将部分下游流程转移到现代数据湖和云基础设施。因此,银行正在落后于技术曲线,他们目前的风险管理做法已不足以适应现代经济。现代化的风险管理从数据开始。具体来说,通过改变观察数据的镜头:不是成本,而是资产。

旧方法:当数据被视为成本时在美国,金融服务机构限制了风险分析师探索“假设”情景的能力,并限制了他们的汇总数据孤岛,仅满足预定义的风险策略。随着时间的推移,维护筒仓的刚性导致工程师在已经脆弱的工作流的基础上分支新的流程并创建新的聚合视图,以适应不断变化的需求。矛盾的是,不断努力将数据作为低成本的本地商品,导致了一个更脆弱的生态系统,因此维护整体生态系统的成本更高。为了保证数据的及时性和可靠性,失败的进程(下面注释为X符号)有太多的下游影响。因此,考虑到所有移动的组件和相互依赖关系(如下图所示),拥有日内(和可靠的)市场风险视图变得越来越复杂,并且成本过高。
传统的风险管理方法优先考虑保持低数据成本,使财务风险管理人员处于不利地位。

现代方法:当数据被视为一种资产时,组织接受数据的多用途特性,服务于多个用例(如风险价值和预期不足),并支持各种特别分析(如了解特定国家的风险暴露)。风险分析师不再局限于对风险的狭隘看法,可以采用更灵活的方法进行风险管理。通过统一流和批处理ETL,确保ACID遵从性和模式执行,三角洲湖为您的数据湖带来性能和可靠性,通过铜层、银层和金层逐步提高数据的质量和相关性,弥合操作流程和分析数据之间的差距。

金融风险管理的现代方法强调提高数据的质量和相关性,弥合操作过程和分析数据之间的差距。

在本演示中,我们将评估由多个行业的40种工具组成的拉丁美洲股票投资组合的各种投资的风险水平,并将所有回报存储在一个集中的Delta Lake表中,该表将驱动我们所有的风险价值计算(在第2部分演示中介绍)。

各种拉丁美洲金融工具的风险组合样本。

在本演示中,我们使用python yfinance库访问雅虎财经的每日收盘价。在现实生活中,人们可以直接从源系统获取市场数据(例如从大型机更改数据捕获)到Delta Lake表,将原始信息存储在Bronze表上,并将经过整理/验证的数据实时存储在Silver表上。

利用Delta Lake上可用的核心数据,我们应用一个简单的窗口函数来计算每日日志回报,并将结果输出到金表中,为风险建模和分析做好准备。

@udf(“双重”)def compute_return (第一个关闭):返回浮动(np。日志关闭/第一个))窗口=Window.partitionBy (“股票”) .orderBy (“日期”) .rowsBetween (10
              火花\.read \表格(stock_data_silver) \.withColumn(“第一次”,F.first (“关闭”).窗口)) \.withColumn(“返回”,compute_return (“第一”“关闭”)) \选择“日期”“股票”“返回”.write \.format \(“δ”).mode \(“覆盖”).saveAsTable (stock_data_gold)

在下面的示例中,我们展示了AVAL (Grupo AVAL Acciones y Valores s.a.)的特定投资数据片段,这是一家在哥伦比亚运营的金融服务公司。考虑到其股价在2020年3月后的预期下跌,我们可以评估其对我们整体风险投资组合的影响。

Databricks使用的样本数据来说明现代金融风险和数据管理方法的有效性。

用MLFlow简化模型开发

虽然定量分析并不是一个新概念,但最近数据科学的兴起和数据量的爆炸式增长揭示了银行运营模型的主要低效之处。在没有任何行业标准的情况下,数据科学家通常会尽最大努力进行操作。这通常意味着针对单个节点上的数据样本训练模型,并在整个开发过程中手动跟踪模型,从而导致较长的发布周期(将模型交付到生产环境可能需要6到12个月)。较长的模型开发周期阻碍了它们快速适应新出现的威胁和动态地减轻相关风险的能力。在这种模式下,金融服务机构面临的主要挑战是减少模型开发到生产的时间,而不以牺牲治理和法规为代价,也不为更脆弱的数据科学生态系统做出贡献。

MLflow是通过为模型开发带来不变性和透明度来管理机器学习生命周期的事实上的标准,但并不局限于人工智能。银行对模型的定义通常相当广泛,包括从Excel宏到基于规则的系统或最先进的机器学习的任何金融模型,所有这些模型都可以从Databricks统一数据分析平台内MLflow提供的中央模型注册表中受益。bob体育客户端下载

再现模型开发

在这个例子中,我们想要训练一个新的模型来预测给定市场指标(如标准普尔500指数、原油和国债)的股票回报。我们可以检索“AS OF”数据,以确保完整的模型再现性和审计遵从性。三角洲湖的这种能力通常被称为“时间旅行”。结果数据集将在所有实验中保持一致,并且可以原样访问以用于审计目的。

描述market_return历史;选择*market_return时间戳作为“2020-05-04”选择*market_return版本作为2

为了在他们的模型中选择正确的特征,定量分析人员经常在Spark和熊猫dataframes。我们将在这里展示如何从pyspark上下文切换到python上下文,以便提取市场因素的相关性。Databricks交互式笔记本具有内置的可视化功能,并且完全支持使用Matplotlib, seaborn(或R的ggplot2)。

factor_returns_pd=factor_returns_df.toPandas ()factor_corr=factor_returns_pd。相关系数方法=“枪兵”, min_periods=12

由Databricks交互式笔记本生成的样本方差-协方差表,证明了其构建预测风险模型的有效性和严谨性。

假设我们的指标是不相关的(它们是相关的),并且可以预测我们的投资组合回报(它们可能是相关的),我们想把这个图表记录下来,作为我们成功实验的证据。这表明内部审计、模型验证功能以及监管机构以最高质量标准进行了模型探索,并以实证结果为主导。

mlflow.log_artifact (“/ tmp / correlation.png”

并行训练模型

随着投资组合中工具数量的增加,我们可能希望并行地训练模型。这可以通过如下简单的Pandas UDF函数实现。为了方便起见(模型在现实生活中可能更复杂),我们想要训练一个简单的线性回归模型,并将所有模型系数聚合为一个n x m矩阵(n是工具的数量,m是来自我们的市场因素的特征的数量)。

schema = StructType([StructField (“股票”、StringType ()真正的),StructField (“重量”ArrayType (FloatType ()),真正的])@pandas_udf (模式,PandasUDFType。GROUPED_MAPdeftrain_model组,pdf):X = np.array(pdf[“特性”])X = sm。add_constant (X,预谋=真正的Y = np.array(pdf[“返回”])模型= sm。OLS (y, X) .fit ()w_df = pd.DataFrame(data=[[model.]params]],列= (“重量”])w_df [“股票”= group[0返回w_dfmodels_df = x_train.groupBy()“股票”苹果(train_model) .toPandas ()

结果数据集(每个模型的权重)可以很容易地收集回内存并记录到MLflow中,作为我们实验剩余部分的候选模型。在下图中,我们报告了根据哥伦比亚石油和天然气生产商Ecopetrol s.a.的模型得出的预测和实际股票回报。

MLflow保留的示例模型输出可视化,以及实验、其修订和底层数据,提供了完全的透明性、可追溯性和上下文。

我们的实验现在与独立验证单元(IVU)提交所需的所有证据一起存储在MLflow中,这可能是您的一部分模型风险管理框架。值得注意的是,这个实验不仅与我们的笔记本相连,而且与它的精确修订有关,为独立专家和监管机构带来了我们模型的完全可追溯性,以及模型验证所需的所有必要背景。

蒙特卡罗模拟在Apache Spark的规模

风险价值是模拟随机游走的过程,包括可能的结果和最坏的情况(n)。在(t)天的时间内,95%的风险值是最差的5%试验中的最佳情况。因此,我们希望生成足够的模拟,以涵盖在我们投资组合中所有工具观察到的90天历史市场波动的情况下可能出现的一系列结果。考虑到每个仪器所需的模拟数量,该系统必须在设计时考虑到高度的并行性,从而使风险值成为在基于云的环境中执行的完美工作负载。风险管理是顶级银行评估云计算分析并通过Databricks运行时加速价值的首要原因。

创建多变量分布

尽管业内建议进行2万至3万次模拟,但计算混合投资组合的风险价值的主要复杂性不在于衡量单个资产的回报,而在于衡量它们之间的相关性。在投资组合层面,市场指标可以在本地python中优雅地操作,而不必将复杂的矩阵计算转移到分布式框架。由于操作多个书籍和投资组合很常见,因此通过并行分布矩阵计算,可以轻松地扩展相同的过程。我们使用最近90天的市场回报来计算今天的波动性(提取平均值和协方差)。

Def retrieve_market_factors(from_date, to_date):from_ts=F.to_date (F.lit (from_date))。(TimestampType ())to_ts=F.to_date (F.lit (to_date))。(TimestampType ())f_ret=spark.table market_return_table \过滤器(F.col (“日期”>from_ts) \过滤器(F.col (“日期”
              我们生成一个具体的市场条件通过采样一个点市场的多元预测(我们的市场因素的个别正态分布的叠加)。这提供了一个特征向量,可以注入到我们的模型中,以预测我们的金融工具的回报。
defsimulate_marketF_ret_avg, f_ret_cov, seed):np.random。种子(年代eed = seed)返回np.random。multivariate_normal (f_ret_avg f_ret_cov)

在规模上进行一致和独立的试验

模拟风险值的另一个复杂性是通过使用“种子”小心地固定随机数来避免自相关性。我们希望每个试验都是独立的,尽管不同工具之间是一致的(每个模拟头寸的市场条件是相同的)。请参阅下面创建独立且一致的试验集的示例-将同一块运行两次将产生完全相同的市场向量集。

seed_init =42种子= [seed_init + x]xnp.arange (010)]Market_data = [simulate_market(f_ret_avg, f_ret_cov, s)]年代种子)Market_df = pd。DataFrame (market_data、列= feature_names)market_df [“关注”] =种子

在分布式环境中,我们希望集群中的每个执行者负责跨多个仪器的多个模拟。我们定义了我们的种子策略,这样每个执行器将负责num_instruments x (num_simulations / num_executors)试验。给定100,000个蒙特卡罗模拟,在我们的投资组合中并行50个执行器和10个工具,每个执行器将运行20,000个工具回报。

#修复我们的最初的种子今天的实验trial_date=datetime.strptime (“2020-05-01”' % Y - % - % d 'seed_init=int(trial_date.timestamp ())#创建我们的种子策略遗嘱执行人种子=[[seed_init+x, x并行性)xnp.arange (0,运行)seed_pdf=pd。DataFrame(数据=种子,列=“种子”“执行人”])seed_sdf=spark.createDataFrame seed_pdf .repartition(并行性,“执行人”#评估缓存我们的重分区策略seed_sdf.cache ()seed_sdf。()

我们将每个执行者的种子集合分组,并通过使用Pandas UDF为每个模型生成试验。请注意,可能有多种方法可以实现相同的目标,但这种方法的好处是可以完全控制并行性的级别,以确保不会出现热点,也不会让执行器闲置等待其他任务完成。

@pandas_udf ('ticker字符串,种子int,试验浮点数', PandasUDFType。GROUPED_MAPdefrun_trialspdf):#检索我们的广播模型和90天的市场波动Models = model_dict.valuef_ret_avg = f_ret_avg_B.valuef_ret_cov = f_ret_cov_B.value
              试验= []种子np.array (pdf.seed):Market_features = simulate_market(f_ret_avg, f_ret_cov, seed)股票行情自动收录器、模型models_dict.items ():Trial = model.predict(market_features)试用追加([ticker, seed, trial])返回pd。DataFrame(试验、列= (“股票”“种子”“审判”])#并行执行蒙特卡罗mc_df = seed_sdf.groupBy()“执行人”苹果(run_trials)

我们将按天划分的试验附加到Delta Lake表上,以便分析师可以轻松访问一天的模拟价值,并通过试验Id(即种子)对个人回报进行分组,以便访问回报的每日分布及其各自的风险价值。

为了便于风险分析人员的审查,我们附上了按天划分的三角洲湖表样本。

根据我们最初将数据定义为核心资产(而不是成本)的定义,我们存储了所有丰富了我们的投资组合分类(例如行业类型和运营国家)的试验,从而能够更全面地根据需要查看我们的投资策略所面临的风险。我们将在第2部分的博文中介绍如何高效、轻松地(通过使用SQL)对有风险的数据进行切片和分割的概念,更多地关注风险分析师的角色。

从VaR和风险管理的现代方法开始

在本文中,我们展示了银行如何通过利用云计算的灵活性和Apache Spark的健壮性,有效地将Monte Carlo模拟从数万扩展到数百万,从而实现其风险管理实践的现代化。我们还演示了Databricks作为唯一的统一数据分析平台,如何通过带来实验的透明度和数据的可靠性来帮助加快模型开发生命周期,弥合科学与工程之间bob体育客户端下载的差距,并使银行拥有更强大而敏捷的风险管理方法。

看看第2部分这个系列的。

今天就在Databricks上试试下面的方法吧!如果您想了解统一数据分析如何将数据科学、业务分析和工程结合起来,以加速您的数据和机器学习工作,请查看按需研讨会统一数据管道,业务分析和机器学习与Apache Spark™

风险价值和风险管理笔记:

拿起笔记本

联系我们了解更BOB低频彩多关于我们如何协助客户处理市场风险用例的信息。

免费试用Databricks

相关的帖子

看到所有工程的博客的帖子