ARTICLE DETAIL

资讯详情

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

深入 gs-quant SecurityMaster:多标识符时点化证券检索与标识符映射实战指南

深入 gs-quant SecurityMaster:多标识符时点化证券检索与标识符映射实战指南 深入 gs-quant SecurityMaster多标识符时点化证券检索与标识符映射实战指南【免费下载链接】gs-quantPython toolkit for quantitative finance项目地址: https://gitcode.com/GitHub_Trending/gs/gs-quant导读SecurityMaster是 gs-quantGoldman Sachs 开源的 Python 量化金融工具包中面向证券主数据的统一检索入口。它允许开发者用 Bloomberg ID、Reuters RIC、CUSIP、ISIN、SEDOL、Ticker、GSID、Marquee ID 等十余种标识符定位任意类型的资产并支持时点化point-in-time查询既能查询当前标识符也能回溯历史上任意时点的标识符与证券信息。阅读本文后你将掌握SecurityMaster的全部公共 API 用法、两种后端数据源Asset Service 与 Security Master的差异、分页与标识符映射机制以及如何借助PricingContext编写可回溯的证券查询代码。SecurityMaster 是什么定位、核心概念与数据源根据 SecurityMaster 类源码 的类文档SecurityMaster提供证券查询接口security lookup functions核心特性有三多标识符检索通过多种不同的标识符identifier查询和获取不同类型的证券资产时点化查询point-in-time标识符是时变的temporalSecurityMaster支持按特定日期解析自动类型分发根据证券的类型返回对应的Asset子类实例如Stock、Index、ETF、Future、Currency等而不是一个万能对象。该方法列表与类文档正是 Sphinx 文档页 docs/classes/gs_quant.markets.securities.SecurityMaster.rst 通过autoclass/autosummary自动生成的 11 个方法__init__、asset_type_to_str、get_all_identifiers、get_all_identifiers_gen、get_asset、get_asset_async、get_identifiers、get_many_assets、get_many_assets_async、map_identifiers、set_source。两套标识符枚举在 securities.py 中定义了两套标识符枚举分别对应两种后端数据源枚举适用数据源成员valueAssetIdentifierAsset ServiceMARQUEE_ID(MQID)、REUTERS_ID(RIC)、BLOOMBERG_ID(BBID)、BLOOMBERG_COMPOSITE_ID(BCID)、CUSIP、ISIN、SEDOL、TICKER、PLOT_ID、GSID、NAMESecurityIdentifierSecurity MasterGSID、RCIC、RIC、ID、CUSIP、CUSIP8、CINS、SEDOL、ISIN、TICKER、BBID、BCID、GSS、PRIMEID、BBG、ASSET_ID、ANY、BARRA_ID、AXIOMA_ID需要注意两套枚举的名字如BBID、CUSIP是共通的但 value 大小写不同如AssetIdentifier.CUSIP CUSIP而SecurityIdentifier.CUSIP cusip。源码通过_ASSET_TO_SECURITY_IDENTIFIER与_SECURITY_TO_ASSET_IDENTIFIER两张双向映射表securities.py在两者之间做归一化调用方无论配置哪个数据源、传入哪套枚举都能正常工作。数据源枚举与切换class SecurityMasterSource(Enum): ASSET_SERVICE auto() # 默认基于 Marquee Asset Service SECURITY_MASTER auto() # 基于 Security Master 服务/markets/securities默认数据源是ASSET_SERVICE见 securities.py通过set_source(SecurityMasterSource.SECURITY_MASTER)可切换。注意部分方法如get_identifiers、get_all_identifiers_gen仅在SECURITY_MASTER源下可用在 Asset Service 源下调用会抛出NotImplementedError这一点会在下文逐一说明。单资产检索get_asset 与 get_asset_asyncget_asset是使用频率最高的入口签名如下源码classmethod def get_asset( cls, id_value: str, id_type: Union[AssetIdentifier, SecurityIdentifier], as_of: Union[dt.date, dt.datetime] None, exchange_code: ExchangeCode None, asset_type: AssetType None, sort_by_rank: bool True, fields: Optional[list[str]] None, ) - Asset:参数说明参数含义默认值id_value标识符的值例如GS UN、GS、SPX必填id_type标识符类型AssetIdentifier或SecurityIdentifier必填as_of查询生效日期不传则使用当前PricingContext的pricing_dateNoneexchange_code交易所代码ExchangeCode.NASDAQ/ExchangeCode.NYSE用于 Ticker 消歧Noneasset_type资产类型过滤AssetType用于 Ticker 消歧Nonesort_by_rank是否按 rank 排序取第一个匹配在 Security Master 源下该参数被忽略Truefields需要返回的资产字段列表仅 Security Master 源生效None源码 docstring 提供的三个标准示例from gs_quant.markets.securities import SecurityMaster, AssetIdentifier, AssetType, ExchangeCode # 按 Bloomberg ID 查询 gs SecurityMaster.get_asset(GS UN, AssetIdentifier.BLOOMBERG_ID) # 按 Ticker 交易所代码查询消歧同名的不同交易所证券 gs SecurityMaster.get_asset(GS, AssetIdentifier.TICKER, exchange_codeExchangeCode.NYSE) # 按 Ticker 资产类型查询区分指数/股票/ETF 等同名证券 spx SecurityMaster.get_asset(SPX, AssetIdentifier.TICKER, asset_typeAssetType.INDEX)ExchangeCode枚举目前包含NASDAQ NASD纳斯达克全球市场与NYSE NYSE纽约证券交易所两个成员源码。get_asset_async是等价的异步版本用法相同仅需awaitgs await SecurityMaster.get_asset_async(GS UN, AssetIdentifier.BLOOMBERG_ID) spx await SecurityMaster.get_asset_async(SPX, AssetIdentifier.TICKER, asset_typeAssetType.INDEX)底层调用链在ASSET_SERVICE源下非 Marquee ID 的查询经由get_asset_query组装请求后调用GsAssetApi.get_many_assetssort_by_rankTrue时追加order_by[rank]返回结果再由__gs_asset_to_asset按资产类型映射为具体子类源码。从该映射实现可以看到约 30 种资产类型的分发规则例如Single Stock → Stock、Index/Access/Multi-Asset Allocation/Risk Premia/Systematic Hedging → Index、Custom Basket/Research Basket → Basket、Future → Future、Cross → Cross、Currency → Currency等无法识别的类型会抛出TypeError(funsupported asset type {asset_type})。若id_type为AssetIdentifier.MARQUEE_ID则直接调用GsAssetApi.get_asset精确获取。在SECURITY_MASTER源下则调用_get_security_master_asset请求GET /markets/securities并把effectiveDate参数格式化为YYYY-MM-DD源码此时exchange_code与asset_type参数不受支持传入会抛出NotImplementedError。批量检索get_many_assets 与 get_many_assets_async当需要一次查询多个证券时使用get_many_assets源码classmethod def get_many_assets( cls, id_values: list[str], id_type: Union[AssetIdentifier, SecurityIdentifier], limit: int 100, as_of: Union[dt.date, dt.datetime] None, exchange_code: ExchangeCode None, sort_by_rank: bool True, ) - list[Asset]:参数limit控制返回结果的最大条数默认 100其余参数语义与get_asset一致。源码示例# 按 Bloomberg ID 批量查询 assets SecurityMaster.get_many_assets([GS UN, MSFT UW], AssetIdentifier.BLOOMBERG_ID) # 按 Ticker 交易所批量查询 assets SecurityMaster.get_many_assets([GS, MSFT], AssetIdentifier.TICKER, exchange_codeExchangeCode.NYSE) # 按 Ticker 类型批量查询 assets SecurityMaster.get_many_assets([SPX], AssetIdentifier.TICKER, asset_typeAssetType.INDEX)返回值为Asset对象列表。异步版本get_many_assets_async参数与行为一致。值得注意的是该方法内部会为分布式追踪gs_quant.tracing.Tracer记录请求的标识符数量标签便于在链路追踪系统中观测调用规模源码。时点化标识符解析PricingContext 与 as_ofSecurityMaster的时点化能力体现在两处查询时的as_of参数显式指定生效日期未传as_of时自动采用当前PricingContext的pricing_date。get_asset_query的实现源码展示了这一逻辑若as_of为空则读取PricingContext.current无论当前上下文是否已进入最终都取current.pricing_date作为生效日期并将dt.date转换为 UTC 午夜时刻的dt.datetime。在测试文件 gs_quant/test/markets/test_securities.py 中test_asset_identifiers用一个跨越 2018 年底的标识符 xrefstartDate: 1952-01-01, endDate: 2018-12-31与startDate: 2019-01-01两段验证了时点行为在PricingContext(dt.date(2018, 3, 1))上下文内查询返回的是.GSTHHOLD旧标识符而查询今天则返回.GSTHHVIP新标识符。这直观说明了标识符会随时间变化as_of/PricingContext决定了命中哪一段历史。获取资产后同样可以时点化地取标识符import datetime as dt from gs_quant.markets.securities import SecurityMaster, AssetIdentifier gs SecurityMaster.get_asset(GS, AssetIdentifier.TICKER) # 当前标识符默认使用 PricingContext 的定价日 gs.get_identifiers() # 指定历史日期 gs.get_identifiers(dt.date(2018, 1, 1)) # 单个标识符带 256 条 / 600 秒 TTL 缓存 gs.get_identifier(AssetIdentifier.SEDOL) gs.get_identifier(AssetIdentifier.SEDOL, as_ofdt.date(2018, 1, 1)) # 用 PricingContext 决定 as-of 日期 with PricingContext(dt.date(2018, 1, 1)) as ctx: gs.get_identifiers()Asset.get_identifier对MARQUEE_ID做了短路处理直接返回内部 id其余标识符通过 xref 时间区间匹配start_date as_of end_date得出源码。get_identifiers内部调用GsAssetApi.get_asset_xrefs并按AssetIdentifier的合法成员过滤结果键。上述缓存机制在get_identifier上通过cachetools.TTLCache(256, 600)与线程锁实现源码。批量标识符查询get_identifiersget_identifiers源码返回一组资产在指定时点的全部标识符历史签名classmethod def get_identifiers( cls, id_values: list[str], id_type: SecurityIdentifier, as_of: dt.datetime None, start: dt.datetime None, end: dt.datetime None, ) - dictid_values输入标识符值列表如[GS UN, AAPL UW]id_type输入标识符的类型如SecurityIdentifier.BBIDas_of把输入 id 解析为资产所依据的时点默认当前时间start/end限定返回标识符的更新时间范围默认1970-01-01到2100-01-01返回{输入ID: 该资产的标识符历史列表}。该方法仅限SECURITY_MASTER源。内部先按输入 id 批量解析出资产 id再逐个请求/markets/securities/{id}/identifiers拉取时变标识符历史源码。测试 test_get_identifiers 验证了SecurityMaster.get_identifiers([GS UN, AAPL UW], SecurityIdentifier.BBID)能正确返回每个资产的 CUSIP、SEDOL 等标识符历史片段。全量标识符枚举get_all_identifiers 与 get_all_identifiers_gen当需要导出某一资产类别如全部股票的标识符全集时使用这两个方法源码classmethod def get_all_identifiers_gen( cls, class_: AssetClass None, types: Optional[list[AssetType]] None, as_of: dt.datetime None, *, id_type: SecurityIdentifier SecurityIdentifier.ID, use_offset_keyTrue, sleep0.5, ) - Generator[dict, None, None]class_按资产类别过滤如AssetClass.EquityNone表示不过滤types按资产类型列表过滤如[AssetType.STOCK]、[AssetType.STOCK, AssetType.ETF]as_of标识符生效时点默认当前时间id_type结果字典的键使用哪种标识符默认证券内部iduse_offset_key分页方式。True使用服务端offsetKey游标大数据集必需False使用offset数值偏移且当offset limit 10000时会告警并停止服务端约 1 万条上限sleep相邻两页请求之间的休眠秒数默认 0.5s用于规避服务端限流返回生成器每次next()产出一页{标识符: 该资产的 identifiers 字典}。get_all_identifiers是该生成器的聚合版内部不断next(gen)直至StopIteration一次性返回完整字典。二者均为仅 Security Master 源可用的方法。分页请求由_get_with_retries包裹源码对 429限流异常启用指数退避重试backoff.on_exception(backoff.expo, MqRequestError, giveuplambda e: e.status ! 429) def _get_with_retries(url, payload): return GsSession.current.sync.get(url, payloadpayload)测试 test_offset_key 验证了三种场景第一页请求遭遇 429 后重试成功、offsetKey游标连续翻页、以及get_all_identifiers_gen的逐页next()行为耗尽时抛StopIteration。测试 test_get_all_identifiers_with_assetTypes_not_none 则验证了types[AssetType.STOCK]、[AssetType.ETF]及组合过滤的正确性其中用到了asset_type_to_str将内部类型转为安全主数据服务的类型字符串staticmethod def asset_type_to_str(asset_class: AssetClass, asset_type: AssetType): if asset_type AssetType.STOCK: return Common Stock if asset_type AssetType.INDEX and asset_class AssetClass.Equity: return Equity Index return asset_type.value例如STOCK → Common Stock、Equity 类 INDEX → Equity Index其余类型直接返回枚举值。标识符映射map_identifiersmap_identifiers源码用于把一组输入标识符映射为其他类型的标识符签名classmethod def map_identifiers( cls, input_type: SecurityIdentifier, ids: Iterable[str], output_types: Iterable[SecurityIdentifier] frozenset([SecurityIdentifier.GSID]), start_date: dt.date None, end_date: dt.date None, as_of_date: dt.date None, ) - dict[dt.date, dict]input_type输入 id 的类型如BBID、GSID、CUSIP、ANYids输入 id 的可迭代对象不能传单个字符串会抛MqTypeErroroutput_types要映射到的目标类型集合默认{GSID}start_date/end_date映射结果覆盖的起止日期as_of_date精确的映射日期与起止日期二选一同时提供会抛MqValueError返回{日期字符串: {输入ID: {输出类型: [值...]}}}以日期为外层键。源码 docstring 示例import datetime as dt from gs_quant.markets.securities import SecurityMaster, SecurityIdentifier # 为 GS UN 获取 CUSIP result SecurityMaster.map_identifiers(SecurityIdentifier.BBID, [GS UN], [SecurityIdentifier.CUSIP]) # 为 GSID104563 获取历史时点的 Bloomberg Ticker result SecurityMaster.map_identifiers(SecurityIdentifier.GSID, [104563], [SecurityIdentifier.BBG], as_of_datedt.date(2021, 4, 19))两种源的行为差异同一方法、不同后端ASSET_SERVICE源只能指定一个输出类型多个会抛MqValueError、只能使用as_of_date传start_date/end_date会抛MqValueError、默认日期为今天底层调用GsAssetApi.map_identifiersmultimapTrue返回{日期: {输入: {输出类型名: 值}}}。SECURITY_MASTER源请求/markets/securities/map支持多输出类型与日期区间结果按天展开startDate到endDate的每一天测试 test_map_identifiers_change 展示了同一 GSID104563 在 2021-04-18 前映射为USAT、之后映射为CTLP的时变行为ric输出还会顺带附上assetIdbbg输出会拼接交易所后缀生成bbid如GS UN与bcid如GS US。测试 test_secmaster_map_identifiers_return_array_results 还验证了多值场景同一 CUSIP 可映射出多个交易所的 BBID[GS UN, GOS TH, GSCHF EU, GSUSD SE]所有输出均以列表形式组织不会互相覆盖。数据源切换与 SecMasterAssetset_source 实战set_source是全局类级开关源码SecurityMaster.set_source(SecurityMasterSource.SECURITY_MASTER) # 切换 SecurityMaster.set_source(SecurityMasterSource.ASSET_SERVICE) # 切回在测试文件中SecMasterContext与AssetContexttest_securities.py展示了推荐的上下文管理模式进入时切换、退出时恢复原数据源避免污染其他测试。切换后get_asset返回的是SecMasterAsset实例securities.py它与普通Asset子类的关键差异标识符获取走本地缓存get_identifiers首次调用时请求/markets/securities/{id}/identifiers拉取全部时变标识符历史并缓存__load_identifiers9999-99-99 的结束日期被转换为datetime.max.date()后续查询纯本地完成源码接受两套标识符枚举get_identifier会把AssetIdentifier自动转换为等价的SecurityIdentifier没有等价物的如PLOT_ID则抛MqTypeError源码Marquee ID 解析get_marquee_id从标识符缓存中取assetId并会随PricingContext日期变化而更新若当前时点资产不存在或非交易所级资产抛MqValueError源码数据序列跨多个 Marquee ID 的校验__is_validate_range会检查查询区间内 Marquee ID 是否唯一。若区间跨越公司行为corporate actions导致存在多个 Marquee ID或区间内根本没有 Marquee ID都会抛MqValueError源码对应测试 test_get_asset_get_data_series_with_range_over_many_asset_id_should_throw_mqerror 所验证的行为。测试 test_secmaster_get_asset_returning_secmasterassets 展示了在 Security Master 源下按 GSID 获取StockCommon Stock、IndexEquity Index、ETF、Currency四类资产后get_marquee_id()、get_identifier、get_identifiers()的完整返回结构可作为集成验证参考。常见错误与边界情况速查结合源码与测试以下是容易踩坑的点场景行为在ASSET_SERVICE源调用get_identifiers/get_all_identifiers_gen/get_all_identifiers抛NotImplementedError(method not available when using Asset Service)在SECURITY_MASTER源调用get_asset并传exchange_code/asset_type抛NotImplementedError(argument not implemented for Security Master (supported in Asset Service))map_identifiers的ids传入单个字符串抛MqTypeError(expected an iterable of strings e.g. list of strings)map_identifiers在 Asset Service 源传多个output_types抛MqValueError(provide exactly one output type)map_identifiers同时传as_of_date与start_date/end_date抛MqValueError两种模式互斥未匹配到任何资产get_asset返回Noneget_many_assets返回[]429 限流由backoff指数退避自动重试仅MqRequestError且 status429 时数据区间跨越多个 Marquee IDSecMasterAsset的数据查询抛MqValueError建议缩小日期范围get_all_identifiers使用use_offset_keyFalse且结果超 1 万条打日志告警并停止需改用 offset key 游标结语SecurityMaster将标识符 → 证券实体这一量化研发中最频繁的映射操作抽象成了统一、时点化的 API。通过get_asset/get_many_assets完成单点与批量检索通过get_identifier/get_identifiers/get_all_identifiers处理标识符的时变历史通过map_identifiers在不同标识符体系间转换再配合PricingContext与set_source实现可回溯、可切换后端的查询。其底层实现gs_quant/markets/securities.py与完整测试用例gs_quant/test/markets/test_securities.py为你提供了从 API 用法到底层调用链的完整参考是接入 gs-quant 证券主数据体系的最佳起点。【免费下载链接】gs-quantPython toolkit for quantitative finance项目地址: https://gitcode.com/GitHub_Trending/gs/gs-quant创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表