
gs-quant Portfolio 指南用 Python 构建、定价与风险管理投资组合【免费下载链接】gs-quantPython toolkit for quantitative finance项目地址: https://gitcode.com/GitHub_Trending/gs/gs-quantgs-quant 的Portfolio类是量化交易中处理一篮子工具的入口它允许你将多只工具如利率互换、期权聚合在一起进行批量定价、风险计算与组合管理。阅读本文后你将掌握 Portfolio 的构造方式、嵌套组合与路径寻址、定价上下文PricingContext配合使用、风险度量计算、序列化转换以及从 Marquee 平台加载与保存组合的完整实战能力。Portfolio 在 gs-quant 中的定位Portfolio是 gs-quant 中「工具的集合」其官方文档 Portfolio.rst 中通过自动生成的 API 文档列出了它的全部方法与属性。它是PriceableImpl的子类因而继承了price()、dollar_price()、calc()、resolve()等通用定价能力。从源码看其定义于 gs_quant/markets/portfolio.pydataclass class Portfolio(PriceableImpl): A collection of instruments Portfolio holds a collection of instruments in order to run pricing and risk scenarios 与单只工具不同Portfolio 可以嵌套一个组合内可以再包含子组合并且所有 pricing/risk 操作都可以一次性地作用于组合内全部工具这在批量定价和风险敞口汇总场景中非常实用。构造一个 Portfolio基本构造Portfolio的构造函数签名如下见 portfolio.pydef __init__(self, priceables(), nameNone):priceables可以是单只工具PriceableImpl、工具的迭代器list/tuple/numpy 数组等也可以是一个 dict——字典的 key 会被用作工具的名称。name组合名称用于__repr__展示、to_frame的索引等。源码中构造时的关键逻辑portfolio.py传入 dict 时会遍历{name: priceable}将每个 key 写入对应priceable.name再转换为列表存入self.priceables否则直接把传入的 priceable 或可迭代对象赋值给self.priceables内部 setter 会统一转为 tuple。from gs_quant.instrument import IRSwap from gs_quant.markets.portfolio import Portfolio swap1 IRSwap(Pay, 10y, USD, fixed_rate0.001, nameswap_10y10bp) swap2 IRSwap(Pay, 10y, USD, fixed_rate0.002, nameswap_10y20bp) swap3 IRSwap(Pay, 10y, USD, fixed_rate0.003, nameswap_10y30bp) # 传入元组 portfolio Portfolio((swap1, swap2, swap3)) print(portfolio) # Portfolio(3 instrument(s))字典构造方式key 会被用作工具名称portfolio Portfolio({swap_5: swap1, swap_6: swap2, swap_7: swap3}) assert len(portfolio) 3测试用例 test_portfolio.py 验证了 list、tuple、numpy 数组三种可迭代容器构造的结果完全等价p1 p2 p3。组合操作append / extend / pop / add文档列出的方法中组合的动态修改由以下方法完成portfolio.py# 追加单个或一批工具 portfolio.append(swap4) # 用另一个组合或工具列表扩展 portfolio.extend(new_portfolio) # 传入 Portfolio portfolio.extend([IRSwap(...), ...]) # 传入工具列表 # 按索引/名称弹出工具 extracted portfolio.pop(swap_10y20bp)此外两个 Portfolio 之间还支持运算符直接合并portfolio.py合并结果是一个新的组合。组合的遍历与查询属性文档 Attributes 中列出的属性其语义如下portfolio.py属性说明instruments组合直接持有的Instrument去重后all_instruments递归收集所有子组合的工具深度优先portfolios组合直接持有的子Portfolioall_portfolios递归收集的所有子组合priceables组合直接持有的全部元素含子组合id/quote_idMarquee 平台上的组合 ID / quote ID同时支持 Python 容器协议len(portfolio)、portfolio[i]整数索引或切片、instrument in portfolio、name in portfolio以及基于全路径的相等性比较portfolio otherportfolio.py。嵌套组合与 PortfolioPath 寻址Portfolio 允许嵌套即组合内部可以再包含子组合从而表达层级化的簿记结构。此时PortfolioPath用于定位组合内的某个工具其定义见 gs_quant/risk/results.py。路径由整数序列组成例如PortfolioPath((1, 1, 0))表示「索引 1 的子组合 → 其索引 1 的子组合 → 索引 0 的工具」。paths(key)方法可按名称或工具对象返回其在组合内的所有路径portfolio.pyswap6 IRSwap(Pay, 10y, CHF, nameCHF-swap) portfolio2_1 Portfolio((swap1, swap2, swap3), nameportfolio2_1) portfolio1_1 Portfolio((swap4, portfolio2_1), nameportfolio1_1) portfolio Portfolio((swap6, portfolio1_1), nameportfolio) assert portfolio.paths(CHF-swap) (PortfolioPath(0),)测试 test_nested_portfolios 展示了重复名称场景USD-swap在多层嵌套组合中会命中PortfolioPath(2)、PortfolioPath((1, 1, 0))、PortfolioPath((2, 1, 0))三个路径说明paths会递归搜索全部层级。其他路径相关方法/属性all_paths组合内所有工具的完整路径叶子路径见 portfolio.pysubset(paths, nameNone)按一组路径抽取工具形成新的子组合portfolio.py如果路径恰好指向单个子组合则直接返回该子组合__getitem__除了整数索引也支持用PortfolioPath、名称字符串或工具对象直接取值。在 PricingContext 中定价与风险计算定价上下文gs-quant 的定价操作通常需要配合PricingContext使用它决定定价日期、市场数据等环境。在with PricingContext(pricing_date...)代码块内调用定价方法时返回的是PricingFuture代码块结束时一次性批量提交计算在代码块外直接调用则同步返回结果。dollar_price()与price()定义在基类 gs_quant/priceable.pydef dollar_price(self): # 返回美元现值PV return self.calc(DollarPrice) def price(self, currencyNone): # 返回本币现值可选货币 return self.calc(Price(currencycurrency)) if currency else self.calc(Price)calc 与 PortfolioRiskResultPortfolio.calc(risk_measure, fnNone)是整个风险计算的核心入口portfolio.py它返回一个PortfolioRiskResultfrom gs_quant.markets import PricingContext from gs_quant import risk with PricingContext(pricing_datedt.date(2020, 10, 15)): prices portfolio.dollar_price() result portfolio.calc((risk.DollarPrice, risk.IRDelta))PortfolioRiskResultresults.py是一个可组合的结果对象支持非常灵活的切片按工具切片prices[swap2]、prices[swap_10y30bp]按风险度量切片result[risk.DollarPrice]再按工具切片result[risk.DollarPrice][swap_10y30bp]按日期切片HistoricalPricingContext 场景results[dt.date(2021, 2, 9)][risk.DollarPrice]聚合prices.aggregate()返回整个组合的汇总值。测试 test_portfolio.py 完整演示了这些用法包括result[risk.DollarPrice].aggregate()的汇总结果以及历史多日期切片在任意顺序下取值等价L141-L164。历史与情景定价HistoricalPricingContext在多个历史日期上批量定价返回按日期组织的SeriesWithInfo见 test_historical_pricingBackToTheFuturePricingContext围绕基准日前后偏移若干交易日定价test_backtothefuture_pricingresolve()在定价上下文内解析工具如根据市场数据把相对利率、到期日落实为具体数值支持in_place原地修改或返回新组合portfolio.py。测试 test_results_with_resolution 验证了 resolve 前后工具对象发生变化且解析后的结果仍然可以按原工具检索。market()Portfolio.market()返回组合内所有工具的市场数据坐标与值的映射portfolio.py。对于同一坐标出现冲突值的情况会抛出ValueError提示冲突容差 1e-6保证组合层面市场数据的一致性。序列化与转换dict / JSON / DataFrame / CSV文档列出的as_dict、to_dict、from_dict、to_json、from_json、to_frame、from_frame、to_csv、from_csv提供了组合与常见数据格式之间的双向转换。DataFrame 与 CSVto_frame(mappingsNone)将组合转为 pandas DataFrame其中mappings可用于把已有列映射成新列支持字符串取值或 callable 计算见 portfolio.py。to_csv(csv_file, mappingsNone, ignored_colsNone)则进一步写出为 CSV 文件。反向导入由类方法完成from_frame(data, mappingsNone)从 DataFrame 构造组合。它优先尝试asset_classtype组合其次尝试$type键通过Instrument.from_dict重建工具portfolio.py两者都缺失时抛出ValueError(Neither asset_class/type nor $type specified)。from_csv(csv_file, mappingsNone)读取 CSV 后调用from_frame并会校验重复列如type.1这类带数字后缀的列会触发ValueError见 portfolio.py。工具对象与其他构造函数Portfolio还提供了若干从不同数据源构建组合的类方法/静态方法方法用途from_asset_id(asset_id, dateNone)从资产 ID 加载持仓可指定日期默认取最新from_asset_name(name)从资产名称加载from_quote(quote_id)从 Marquee quote 加载工具from_eti(eti)从 ETI电子交易标识加载内部持仓from_book(book, book_typerisk, activity_typeposition)从内部簿记加载持仓get(portfolio_idNone, portfolio_nameNone, query_instrumentsFalse)从 Marquee 平台按 ID 或名称加载组合当前推荐的入口其中from_portfolio_id与from_portfolio_name自版本0.8.293起已被标记为 deprecated官方建议改用Portfolio.get(portfolio_id...)或Portfolio.get(portfolio_name...)见 portfolio.py。get还接受query_instruments参数置为True时会在加载组合的同时拉取工具详情。保存到 Marqueesave / save_as_quote / save_to_shadowbookPortfolio可以直接把工具上传到 Marquee 平台或保存为 quote / shadowbook便于后续在平台侧复用或与他人共享。save(overwriteFalse)portfolio.py若组合包含子组合抛出ValueError(Cannot save portfolios with nested portfolios)已有id且未指定overwriteTrue时抛错避免覆盖无id时要求设置name否则抛ValueError(name not set)通过GsPortfolioApi.create_portfolio创建 Marquee 组合再以当前 PositionContext 的持仓日期把工具转成Position列表上传。save_as_quote(overwriteFalse) - strportfolio.py把组合连同定价日期与市场数据封装为RiskRequest保存为 quote返回 quote ID已有 quote_id 时同样需要overwriteTrue才能覆盖。save_to_shadowbook(name)portfolio.py以给定名称保存到 shadowbook影子簿记返回保存状态并打印。这三个方法都要求组合不含嵌套子组合且都依赖PricingContext.current的定价日期与市场数据来确定保存快照的环境。相关 API 封装位于 gs_quant/api/gs/portfolios.py。其他辅助能力clone / scale / propertiesclone(clone_instrumentsFalse)portfolio.py深拷贝组合结构clone_instrumentsTrue时连同工具一起克隆同时保留id与quote_id。该能力也被calc内部使用——PortfolioRiskResult持有的是组合的克隆而非引用避免后续原地修改如 resolve污染结果对象见 portfolio.py 的注释。scale(scaling, in_placeTrue)portfolio.py对组合内所有工具按比例缩放。properties、as_dict、to_dict等来自InstrumentBase/PriceableImpl的通用协议用于把工具或组合序列化为字典结构与from_dict形成对称转换。另外同一模块还定义了Grid类portfolio.py它也是Portfolio的子类通过给定基准工具、两个参数轴x/y与各自的取值列表自动克隆并构建一个二维参数扫描网格——在敏感性分析场景如同时扫描期限与利率水平中可以直接复用 Portfolio 的定价与风险能力。组合使用模式速览把前面各节串起来一个典型的完整工作流如下import datetime as dt from gs_quant.instrument import IRSwap from gs_quant.markets import PricingContext from gs_quant.markets.portfolio import Portfolio from gs_quant import risk # 1. 构造组合 swap1 IRSwap(Pay, 10y, USD, fixed_rate0.001, nameswap_10y10bp) swap2 IRSwap(Pay, 10y, USD, fixed_rate0.002, nameswap_10y20bp) portfolio Portfolio((swap1, swap2), namemy_book) # 2. 在定价上下文中批量计算风险 with PricingContext(pricing_datedt.date(2020, 10, 15)): dollar_prices portfolio.dollar_price() deltas portfolio.calc(risk.IRDelta) # 3. 按工具与度量切片、聚合 print(dollar_prices.aggregate()) print(deltas[risk.IRDelta][swap_10y10bp]) # 4. 导出为 DataFrame / CSV再反向重建 df portfolio.to_frame() portfolio2 Portfolio.from_frame(df) portfolio.to_csv(my_book.csv)小结与进一步阅读Portfolio是 gs-quant 中聚合工具、执行批量定价与风险计算、与 Marquee 平台交互的核心容器。本文覆盖了其全部文档方法与属性构造、动态修改、嵌套寻址、定价上下文内的calc/resolve/market、dict/JSON/DataFrame/CSV 序列化、平台保存save / save_as_quote / save_to_shadowbook以及 clone / scale 等辅助能力并结合 test_portfolio.py 中的测试用例验证了各 API 的实际行为。核心实现gs_quant/markets/portfolio.py路径与结果类型gs_quant/risk/results.py定价基类gs_quant/priceable.py定价上下文PricingContext/HistoricalPricingContext参见 docs/markets.rst测试用例gs_quant/test/markets/test_portfolio.py【免费下载链接】gs-quantPython toolkit for quantitative finance项目地址: https://gitcode.com/GitHub_Trending/gs/gs-quant创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考