十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

gs-quant Report 指南:用 Python 统一管理绩效、因子风险与主题分析报告

gs-quant Report 指南:用 Python 统一管理绩效、因子风险与主题分析报告 gs-quant Report 指南用 Python 统一管理绩效、因子风险与主题分析报告【免费下载链接】gs-quantPython toolkit for quantitative finance项目地址: https://gitcode.com/GitHub_Trending/gs/gs-quant导读gs_quant.markets.report.Report是 gs-quant 中与 Marquee 报告系统交互的通用门面它把报告的创建、保存、删除、调度运行、任务状态轮询以及结果拉取封装成一组面向对象的 Python API。基于它派生的PerformanceReport绩效分析、FactorRiskReport因子风险与归因、ThematicReport主题分析覆盖了量化投研中最常见的三类报告场景。读完本文你将掌握如何用几行代码创建/获取报告、设置持仓来源、调度与异步运行报告、等待任务完成并取回 Pandas DataFrame 形式的结果以及这些调用在 REST 层GsReportApi背后的真实链路。本文以仓库中的 API 文档 Report.rst 为骨架结合其指向的 report.py 源码、API 客户端 gs/reports.py、目标对象定义 target/reports.py 以及测试用例 test_report.py 展开。一、报告体系概览一个基类、三个场景子类Report是通用报告类源码注释 General report class见 report.py所有具体报告都继承它类报告类型ReportType用途数据支撑数据集PerformanceReportPortfolio Performance Analytics组合 PnL、多空敞口、换手、持仓数量、资产数等历史绩效指标PPA/PPAAFactorRiskReportPortfolio Factor Risk/Asset Factor Risk指定风险模型下的组合或资产风险与归因PFR/PFRA/AFR/AFRAThematicReportPortfolio Thematic Analytics/Asset Thematic Analytics组合对 GS Flagship 主题篮子thematic basket的敞口与 betaPTA/PTAA/ATA/ATAA这三类类型值在 target/reports.py 的ReportType枚举中定义而ReportDataset枚举report.py把各数据集与查询字段对应起来。另外仓库还附带ReportJobFuturereport.py用于异步监控一次报告任务的生命周期其独立 API 文档见 ReportJobFuture.rst。二、Report 构造函数与核心属性Report.__init__接收报告的全部元信息report.pyReport( report_id: str None, # Marquee 报告 ID name: str None, # 报告名称 position_source_id: str None, # 持仓来源 ID如组合 MPxxx / 资产 position_source_typeNone, # Portfolio / Asset / Hedge 等 report_typeNone, # ReportType 枚举或字符串 parameters: ReportParameters None, # 报告参数风险模型、基准等 earliest_start_dateNone, # 最早起始日期 latest_end_dateNone, # 最近结束日期 latest_execution_timeNone, # 最近执行时间 statusReportStatus.new, # 默认 new percentage_completeNone, # 完成百分比 )其中position_source_type、report_type、status都做了“字符串自动转换枚举”的处理传入字符串会被转为PositionSourceType/ReportType/ReportStatus枚举实例。ReportStatus的完整状态机定义在 target/reports.py包括new、ready、executing、calculating、done、error、cancelled、waiting、queued。构造后可通过只读属性访问id、name、position_source_id、position_source_type、type、parameters、earliest_start_date、latest_end_date、latest_execution_time、status、percentage_complete其中position_source_id、position_source_type、type、parameters提供 setterreport.py。ReportParameters是定义在 target/common.py 的数据类字段极为丰富与Report强相关的核心字段包括risk_modelstr因子风险报告所用的风险模型 IDbenchmarkstr可选的基准资产 ID用于结果对照fx_hedgedbool持仓是否做 FX 对冲tagstuple[PositionTag, ...]报告标签用于把同源的绩效报告与风险报告配对transaction_cost_model/trading_cost/servicing_cost_long/servicing_cost_short成本模型相关参数asset_class、region、base_currency等用于刻画分析范围。注意直接实例化基类Report时若不传parameterssave()会默认填充一个空的ReportParameters()而FactorRiskReport会自动用risk_model、fx_hedged、benchmark、tags构造ReportParameters见下文。三、报告的获取与构造get / from_target3.1 类方法get(report_id)report Report.get(REPORTID) # 通用 perf PerformanceReport.get(PPAID) # 绩效 risk FactorRiskReport.get(PFRID) # 因子风险 thematic ThematicReport.get(PTAID) # 主题Report.get实现为一行cls.from_target(GsReportApi.get_report(report_id))report.py。它先调用 REST 客户端拉取目标报告对象再转为 Python 报告对象。子类的get行为一致但会在from_target里做类型校验PerformanceReport.from_target要求report.type ReportType.Portfolio_Performance_Analytics否则抛出MqValueError(This report is not a performance report.)report.pyFactorRiskReport.from_target只接受Portfolio Factor Risk或Asset Factor Risk两种类型report.pyThematicReport.from_target只接受Portfolio Thematic Analytics或Asset Thematic Analyticsreport.py。测试用例 test_report.py 验证了PerformanceReport.get(PPAID)后response.type ReportType.Portfolio_Performance_Analytics的行为。3.2 类方法from_target(report: TargetReport)TargetReport是 target/reports.py 中定义的 REST 传输对象dataclass字段包括position_source_id、position_source_type、type_、parameters、status、earliest_start_date、latest_end_date、latest_execution_time、percentage_complete等。from_target就是这两层对象之间的映射器所有get最终都经由它完成转换。四、报告的持久化save 与 delete# 新建报告 report FactorRiskReport( risk_model_idAXUS4M, fx_hedgedTrue, position_source_typePositionSourceType.Portfolio, position_source_idPORTFOLIOID, ) report.save() # 若 report.id 为空 - 在 Marquee 创建报告 print(report.id) # save 后回填新生成的报告 ID # 更新既有报告 report.name My Updated Risk Report report.save() # 若 report.id 存在 - 走 update_report # 删除 report.delete()save()的逻辑report.py构造TargetReportparameters为空时兜底为ReportParameters()若self.id已存在则设置target_report.id并调用GsReportApi.update_reportHTTPPUT /reports/{id}否则调用GsReportApi.create_reportHTTPPOST /reports并把返回的新id回写到self.__id。delete()则直接调用GsReportApi.delete_report(self.id)对应 HTTPDELETE /reports/{id}见 gs/reports.py。五、设置持仓来源set_position_sourceset_position_source(entity_id)根据实体 ID 前缀自动推断来源类型report.pyID 以MP开头 →position_source_type Portfolio否则 →position_source_type Asset同时写入position_source_id若对象是FactorRiskReporttype同步切换为Portfolio Factor Risk/Asset Factor Risk若对象是ThematicReporttype同步切换为Portfolio Thematic Analytics/Asset Thematic Analytics。这与子类构造函数中的推断逻辑一致FactorRiskReport与ThematicReport在未显式传position_source_type时也会用position_source_id.startswith(MP)自动判定 Portfolio 或 Asset并据此推导默认report_typereport.py 与 report.py。六、调度与运行schedule、run、get_most_recent_job6.1 schedule(start_date, end_date, backcast)schedule负责为报告安排一个日期区间report.py校验与默认逻辑要求self.id与position_source_id均有效否则抛MqValueError非 Portfolio 来源必须显式给出起止日期起止日期为空时从GsPortfolioApi.get_position_dates拉取组合持仓日期推导start_date默认取最早持仓日期若backcastTrue取最早持仓日期减一年后的前一工作日business_day_offset(..., -1, rollforward)end_date默认取前一工作日若backcastTrue取最早持仓日期最终调用GsReportApi.schedule_report(report_id, start_date, end_date, backcast)对应POST /reports/{id}/schedulegs/reports.py。6.2 run(start_date, end_date, backcastFalse, is_asyncTrue)run是“调度 取任务 等结果”的组合入口report.py# 异步立即返回 ReportJobFuture任务在后台跑 future report.run(start_datedt.date(2024, 1, 1), end_datedt.date(2024, 12, 31)) future.wait_for_completion() df future.result() # 同步阻塞直到任务完成并直接返回结果 DataFrame df report.run(start_date..., end_date..., is_asyncFalse)实现要点先调用self.schedule(...)循环最多 5 次尝试get_most_recent_job()IndexError时重试应对任务尚未生成is_asyncTrue立即返回ReportJobFutureis_asyncFalse每 6 秒轮询一次job_future.done()最长 100 次超时抛MqValueError若报告卡在waiting状态会给出明确报错提示联系 Marquee Analytics 团队。get_most_recent_job()从GsReportApi.get_report_jobs(self.id)取回任务列表按createdTime倒序取最新一条封装成ReportJobFuturereport.py。6.3 ReportJobFuture异步任务监控ReportJobFuturereport.py提供job_id/end_date属性status()查询GET /reports/jobs/{job_id}返回ReportStatusdone()状态为done/error/cancelled即为完成result()仅当状态为done时返回 Pandas DataFrame——因子风险报告Portfolio Factor Risk/Asset Factor Risk走GsReportApi.get_factor_risk_report_results绩效报告走GsDataApi.query_data(dataset_idPPA)用where{reportId: ...}过滤wait_for_completion(sleep_time10, max_retries10, error_on_timeoutTrue)周期性睡眠轮询超时默认抛错error_on_timeoutFalse时返回布尔值reschedule()对任务执行POST /reports/jobs/{job_id}/reschedule。七、PerformanceReport历史绩效指标的一站式查询PerformanceReport固定类型为Portfolio Performance Analytics构造示例源码 docstring 原样performance_report PerformanceReport( position_source_typePositionSourceType.Portfolio, position_source_idPORTFOLIOID )7.1 单指标查询get_measure / get_pnl_measureget_pnl()/get_trading_pnl()/get_trading_cost_pnl()/get_servicing_cost_long_pnl()/get_servicing_cost_short_pnl()均可选unitFactorRiskUnit.Notional或Percent默认 Notional。百分比口径下通过 AUM 换算为收益序列get_pnl_percent按“当日 PnL / 前一日 AUM”生成日收益并复利累乘见 report.pyget_long_exposure()/get_short_exposure()/get_net_exposure()/get_gross_exposure()/get_asset_count()/get_asset_count_long()/get_asset_count_short()/get_asset_count_priced()/get_turnover()直接按字段名查询 PPA 数据集。这些方法底层都汇聚到get_measure(field, start_date, end_date, return_formatReturnFormat.DATA_FRAME)构造DataQuery(where{reportId: id}, fields(field,), ...)并GsDataApi.query_data(dataset_idPPA)report.py。字段名的合法取值由ReportMeasures枚举target/reports.py约束如pnl、tradingPnl、longExposure、turnover等。7.2 多指标与持仓数据get_many_measures(measures, start_date, end_date, return_format)一次查询多个指标同样返回 DataFrame 或 JSONget_positions_data(start, enddate.today(), fields, include_all_business_daysFalse, position_typeNone)透传GsPortfolioApi.get_positions_data并携带performance_report_idself.idget_position_net_weights(start_date, end_date, asset_metadata_fields[id,name,ticker], include_all_business_daysTrue, position_typeNone)返回“日期 × 持仓”的净权重透视表自动追加netWeight字段get_portfolio_constituents(fields, start_date, end_date, prefer_rebalance_positionsFalse, return_formatDATA_FRAME)按assetCount分批每批 300 万行_get_ppaa_batches查询PORTFOLIO_CONSTITUENTS数据集prefer_rebalance_positionsTrue时优先保留 Rebalance 条目。7.3 收益归因与 AUMget_pnl_contribution(start_date, end_date, currency)按成分拆解 PnL 贡献走GsPortfolioApi.get_attributionget_brinson_attribution(benchmark, currency, include_interactionFalse, aggregation_typeArithmetic, aggregation_categoryNone, start_date, end_date, return_formatDATA_FRAME)Brinson 归因aggregation_type支持arithmetic/geometricaggregation_category支持按 Sector / Industry / Region / Country 聚合枚举见 report.pyget_aum_source()/set_aum_source()读取/设置组合的 AUM 口径RiskAumSource如 Long / Short / Gross / Net / Custom_AUMget_aum(start_date, end_date)按 AUM 口径返回{日期: AUM}字典Custom_AUM走自定义 AUMget_custom_aum(...)/upload_custom_aum(aum_data, clear_existing_dataFalse)查询/上传自定义 AUM 序列数据点用CustomAUMDataPoint(date, aum)表示report.py。八、FactorRiskReport风险模型驱动的因子风险与归因FactorRiskReport构造时自动组装ReportParameters(risk_modelrisk_model_id, fx_hedgedfx_hedged, benchmarkbenchmark_id, tagstags)report.pyrisk_report FactorRiskReport( risk_model_idAXUS4M, fx_hedgedTrue, benchmark_idbenchmark.get_marquee_id(), position_source_idPORTFOLIOID, position_source_typePositionSourceType.Portfolio, )配套辅助方法get_risk_model_id()、get_benchmark_id()直接读取parameters.risk_model、parameters.benchmark。8.1 结果查询三件套get_results(modePortfolio, factorsNone, factor_categoriesNone, start_date, end_date, currency, return_formatDATA_FRAME, unitNotional)拉取原始风险结果。mode支持Portfolio/PositionsFactorRiskResultsModeunit支持Notional/PercentFactorRiskUnit底层调用GET /risk/factors/reports/{id}/resultsgs/reports.py并对 factor 名称做 URL 编码以支持Automobiles Components这类含特殊字符的因子get_view(factorNone, factor_categoryNone, start_date, end_date, currency, unitNotional)返回与 Marquee 界面一致的视图字典如factorCategoriesTable使用 v2 APIGET /factor/risk/{id}/viewsget_table(mode, factorsNone, factor_categoriesNone, dateNone, start_date, end_date, unit, currency, return_formatDATA_FRAME)资产级表格mode支持Pnl/Exposure/ZScore/MctrFactorRiskTableModegs/reports.py。日期默认逻辑Pnl 模式默认回看一个月其他模式默认取latest_end_date快照。get_table的 docstring 给出了界面级用法pnl_table risk_report.get_table( modeFactorRiskTableMode.Pnl, start_daterisk_report.earliest_start_date, end_daterisk_report.latest_end_date, )8.2 因子维度历史序列get_factor_pnl(modePortfolio, factor_names, factor_categories, start_date, end_date, currency, unitNotional)历史因子 PnL。Percent 口径下自动补查Total因子并通过组合的绩效报告 AUM 做平滑化收益计算get_factor_pnl_percent_for_single_factor→generate_daily_returnsget_factor_exposure(...)历史因子敞口get_factor_proportion_of_risk(factor_names, factor_categories, start_date, end_date, currency)因子风险占比get_annual_risk(...)/get_daily_risk(...)年化/日度风险factor_names限定为Factor、Specific、Totalget_ex_ante_var(confidence_interval95.0, start_date, end_date, currency)前视 VaR实现上取Total的dailyRisk乘以标准正态分位st.norm.ppf(confidence_interval / 100)report.py。以上历史序列统一经_format_multiple_factor_table(factor_data, key)转成“日期 × 因子名”的长表再透视成 DataFramereport.py。8.3 平滑化的数学细节Carino 对数链接当把 PnL 拆解到多个因子时简单几何聚合会破坏可加性。源码__smooth_percent_returnsreport.py实现了 Carino 对数链接法计算总收益total_return Π(1 r_t) - 1对数缩放因子A total_return / ln(1 total_return)扰动因子α_t ln(1 r_t) / r_t基准收益按 0 处理平滑后因子日收益 cumsum(因子PnL × A × α_t × 100)。这保证了分解后的各因子收益之和与Total因子收益一致。九、ThematicReport主题篮子敞口分析ThematicReport面向 GS Flagship 主题篮子构造时可只传report_id或持仓信息thematic_report ThematicReport( report_idREPORTID, position_source_typePositionSourceType.Portfolio, position_source_idPORTFOLIOID, parametersNone, )主要方法get_thematic_data(start_date, end_date, basket_ids)返回date、thematicExposure、thematicBeta三列其中thematicBeta thematicExposure / grossExposureget_thematic_exposure(...)历史主题敞口get_thematic_betas(...)历史主题 beta内部同样用敞口/总敞口计算get_all_thematic_exposures(...)/get_top_five_thematic_exposures(...)/get_bottom_five_thematic_exposures(...)全量/前五/后五主题敞口可传basket_ids与regions过滤走GsThematicApi.get_thematicsget_thematic_breakdown(date, basket_id)某个日期下组合对某主题篮子的逐资产拆解通过模块函数get_thematic_breakdown_as_df实现report.py。数据查询内部通过_get_measures构造where{reportId: id}可选basketId过滤并按来源类型选择PTAPortfolio或ATAAsset数据集report.py。十、REST 层调用链一览所有报告操作最终都落到 gs/reports.py 的GsReportApi通过GsSession.current.sync与 Marquee 交互SDK 方法REST 端点说明Report.save()POST /reports/PUT /reports/{id}创建 / 更新报告Report.delete()DELETE /reports/{id}删除报告Report.get()/from_targetGET /reports/{id}获取报告Report.schedule()POST /reports/{id}/schedule调度报告带backcast参数get_most_recent_job()GET /reports/{id}/jobs列出任务ReportJobFuture.status()GET /reports/jobs/{job_id}查询任务状态ReportJobFuture.reschedule()POST /reports/jobs/{job_id}/reschedule重试任务get_results()GET /risk/factors/reports/{id}/results因子风险结果get_view()GET /factor/risk/{id}/viewsv2界面视图数据get_table()GET /factor/risk/{id}/tablesv2资产级表格get_brinson_attribution()GET /attribution/{portfolio_id}/brinsonBrinson 归因值得注意的实现细节schedule_report、get_factor_risk_report_results都带有backoff重试装饰器对MqTimeoutError、MqInternalServerError指数退避最多 5 次对MqRateLimitedError每 90 秒重试gs/reports.pyget_factor_risk_report_view/get_factor_risk_report_table会在请求期间临时把GsSession.current.api_version切到v2请求结束再恢复v1try/finally保证;get_reports(limit100, offset, position_source_type, position_source_id, status, report_type, order_by, tags, scroll)支持滚动分页且按tags过滤传入tags字典时按PositionTag(namekey, value...)匹配否则只返回无标签的报告。十一、从测试看典型用法仓库测试 test_report.py 给出了可信的构造范式from gs_quant.markets.report import FactorRiskReport, PerformanceReport, ThematicReport from gs_quant.target.reports import PositionSourceType, ReportStatus, ReportType fake_pfr FactorRiskReport( risk_model_idAXUS4M, fx_hedgedTrue, report_idPFRID, position_source_typePositionSourceType.Portfolio, position_source_idPORTFOLIOID, report_typeReportType.Portfolio_Factor_Risk, statusReportStatus.done, ) fake_ppa PerformanceReport( report_idPPAID, position_source_typePositionSourceType.Portfolio, position_source_idPORTFOLIOID, report_typeReportType.Portfolio_Performance_Analytics, parametersNone, statusReportStatus.done, )测试同时验证了PerformanceReport.get(PPAID)的类型校验、get_risk_model_id()返回AXUS4M以及PortfolioManager.get_reports()返回对象均为PerformanceReport/FactorRiskReport实例test_portfolio_manager.py。在PortfolioManager场景下get_reports()内部会依据目标报告的type_分发到对应的子类get方法与本文第三节的from_target类型校验逻辑闭环。十二、使用前提与限制报告 API 依赖 Marquee 服务需要先配置GsSession客户端 ID / 密钥与运行环境GsReportApi全部经由GsSession.current发起同步请求报告 ID、持仓来源 ID、风险模型 ID 均为 Marquee 侧实体标识文中示例里的PORTFOLIOID、AXUS4M等需替换为你账户下真实存在的 ID不同报告类型的可用数据集不同PPA / PFR / PTA 等查询字段请对照ReportMeasures枚举避免传不存在的字段本文所涉代码路径与 API 端点均基于当前仓库源码report.py、gs/reports.py、target/reports.py不同版本之间方法签名与端点可能有差异请以实际安装版本为准。延伸阅读报告相关 API 文档Report.rst、ReportJobFuture.rst、PerformanceReport.rst、FactorRiskReport.rst、ThematicReport.rst报告在组合管理中的使用portfolio_manager.py 及测试 test_portfolio_manager.py报告数据在时序层如何被消费timeseries/measures_reports.py【免费下载链接】gs-quantPython toolkit for quantitative finance项目地址: https://gitcode.com/GitHub_Trending/gs/gs-quant创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表