ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Nautilus Trader 编码规范完全指南:从格式、命名到提交信息的一致性工程

Nautilus Trader 编码规范完全指南:从格式、命名到提交信息的一致性工程 Nautilus Trader 编码规范完全指南从格式、命名到提交信息的一致性工程【免费下载链接】nautilus_traderProduction-grade Rust-native trading engine with deterministic event-driven architecture项目地址: https://gitcode.com/GitHub_Trending/na/nautilus_trader本篇指南以 coding_standards.md 为骨架系统梳理 Nautilus Trader 这一 Rust 原生交易引擎在代码风格、命名约定、格式化和提交信息四个维度的工程规范。读者将掌握跨语言Rust/Python/Shell的通用格式底线、面向用户 API 与内部热路径的命名分层策略、适配器门面facade的__all__约定以及项目独特的不使用 Conventional Commits 的提交信息纪律全文辅以 rustfmt.toml、.pre-commit-config.yaml、.typos.toml 与 check_commit_message.py 等仓库证据确保每条规范都可落地、可验证。规范的整体定位把现有代码库当作活文档规范的出发点非常务实当前代码库本身就是格式约定的指南。这意味着所有规则都从既有代码中提炼而来再通过工具链强制执行避免文档说一套、代码写一套的漂移。为保证规范真正被执行而不是停留在纸面仓库在 .pre-commit-config.yaml 中挂载了大量 pre-commit 钩子例如typos拼写检查来自 .typos.tomlend-of-file-fixer、trailing-whitespace、mixed-line-ending通用文本卫生check-error-conventions、check-logging-conventions、check-formatting-rs等一整套自定义脚本钩子check-commit-message校验提交信息对应 scripts/ci/check_commit_message.pycheck-links-offline用 lychee 校验仓库内 Markdown 相对链接是否可解析开发环境方面文档 environment_setup.md 说明项目使用 prek 作为 pre-commit 运行器仓库内另有prek run typos --all-files、prek run shfmt --files ...等用法并可在本地通过prek install安装钩子、用make install-tools安装被固定的开发工具。通用格式化规则适用于所有源码文件以下规则适用于仓库内全部源文件——Rust、Python、Shell 一视同仁规则要求缩进只用空格绝不使用硬 Tab行宽一般控制在100 字符以内必要时谨慎换行拼写使用美式英语color、serialize、behavior由 .typos.toml 强制校验命令运行prek run typos --all-files检查整个仓库美式拼写约束并非一刀切。typos配置通过精确标识符例外extend-identifiers保留外部 API 的原始拼写通过排除规则extend-exclude跳过逐字数据与生成文件。从 .typos.toml 可以看到典型处理方式外部 API 原拼写cummulativeBinance API 的cummulativeQuoteQty官方拼写、SETTELMENTBinance 官方 typo、MarketCatalogueBetfair API 命名等都被登记为合法标识符行业术语PnL、CMO、BSE等缩写在extend-words中显式放行生成代码与数据文件crates/adapters/binance/src/common/sbe/spot/*.rsSBE 代码生成器产物、**/test_data/**/*.json|csv|txt|xml等被整体排除。值得注意的细节[files] extend-exclude中ignore-hidden false意味着隐藏文件也要被检查而CLA.md、RELEASES.md、patches/目录属于明确豁免。Shell 脚本Bash 优先POSIX sh 仅作例外仓库的 Shell 规范在 shell.md 中有完整定义编码规范文档只给出结论性约束Bash 是仓库脚本的默认 Shell仅当调用方无法依赖 Bash 已安装时才使用 POSIXsh脚本的选择、扩展名.bashvs.sh、可移植性、结构、测试、格式化和 lint 要求均以 shell.md 为准。从 shell.md 可以提取出配套的强制手段仓库在 pre-commit 阶段同时运行shfmt参数-i 2 -ci -sr -ln bash -w与shellcheck保证脚本既有统一格式又能被静态检查。注释约定克制、一致、无 emoji注释规范共 7 条核心精神是less is more每个注释块或文档字符串上方留一个空行与代码视觉隔离使用句子大小写sentence case首字母大写其余小写除非是专有名词或缩写句号后不要跟两个空格单行注释不得以句号结尾——除非行末是 URL 或内联 Markdown 链接此时标点严格按链接需要保留多行注释句子之间用逗号分隔而不是每行一个句号最后一行以句号结尾注释保持简洁只解释非显而易见的部分文本中避免 emoji 符号。这条规则与 pre-commit 钩子check-unicode-typography形成呼应后者会拒绝非断连字符、排版破折号、弯引号以及 emoji 风格的勾选/叉号符号。此外check-non-latin-text钩子会检测 CJK、西里尔、阿拉伯等非拉丁字符以强制仓库文本保持英文en-uslocale 在 .typos.toml 中同样被设定。Rust 文档注释语气使用陈述式indicative moodRust 文档注释统一采用陈述式语气例如写Returns a cached client.而不是Return a cached client.。这一约定与 Rust 生态的主流风格一致好处是生成的 rustdoc 文档对最终用户读起来自然、平实。它直接服务于 Nautilus Trader 大量通过文档注释暴露的公共 API——例如crates/下各 crate 的公共类型与函数——确保整个文档体系语气统一。术语与措辞三个具体的硬性约定文档给出三个非常具体的措辞规则全部可以通过钩子强制执行1. 错误消息避免 , got。, got被认为不够描述性应视上下文改用, was、, received或, found差Expected string, got {type(value)}好Expected string, was {type(value)}2. 使用 hardcoded单词拼写而非hard-coded或hard coded理由是这是更现代、更被接受的拼写。3. 捕获的错误变量统一用单字母eRustErr(e)而不是Err(err)或Err(error)闭包中写|e|而不是|err|Pythonexcept SomeError as e:而不是as err:或as error:仓库中 check_error_conventions.shcheck-error-conventions钩子正是为强制错误变量命名约定而存在且pass_filenames: false、always_run组合确保每次提交都会全量检查。命名约定内部字段缩写、公共 API 全称命名规范的核心原则是按可见性分层场景策略示例私有/内部字段允许缩写保持热路径代码简洁_price_prec、_size_prec面向用户的 API使用完整、描述性名称price_precision、size_precision错误消息与日志使用完整单词price precision 而非 price prec文档特别强调缩写绝不能泄漏到仪表盘或告警中。公共属性、函数参数、返回类型、指标名/标签都要用全称因为用户最终会在监控面板、告警文本和日志里看到这些名字。Execution 术语Execution一词的用法有明确边界公共的、项目自有的 PascalCase 类型名使用完整Execution例如BinanceExecutionClientConfig内部实现类型可以保留既有的Exec命名Exec保留给ExecAlgorithmId与ExecTester家族、既有的exec_*名称以及交易所/协议术语如BitmexExecType协议专属的线上wire模型按交易所概念命名例如HyperliquidExchangeAction迁移表中要保留已确立的公共名称、历史发布条目与源码名称。Live 运行时限定词Live用于标识选择或配置实时运行时语义的类型与回测/测试形成对照LiveNodevsBacktestNodeLiveClockvsTestClockLiveDataEngineConfig、LiveRiskEngineConfig、LiveExecutionEngineConfig这一族 vs 可复用的核心引擎配置而普通的适配器客户端家族不加Live——因为已连接的客户端本身就是默认语义。备选实现按行为限定如SandboxExecutionClient、DatabentoHistoricalClient仅当存在显式的 live/historical 协议对时才保留Live以区分两个实现。适配器工厂配置数据与执行输入的命名为VenueDataClientConfig和VenueExecutionClientConfig。关键设计约束工厂直接消费客户端配置而不是再套一层独立的 factory config 包装LiveNodeConfig拥有trader_id交易所专属的account_id放在 execution client config 上。这一分层可以理解为归属清晰身份标识按所有权归位客户端配置只描述连接与行为。数据加载 API动词驱动的load_*/scan_*/stream_*词汇表数据加载 API 的形态规则是无状态数据摄入用自由函数free functions仅当实例需要跨调用保留可复用配置、缓存、worker、迭代状态或打开的资源时才使用类。禁止仅仅为了把 static/class 方法归组而使用零状态类。命名遵循语义区分参考 Polars I/O API 的精神落地为 Nautilus 既有的load_*词汇动词语义load_source_data急切读取、规范化并物化完整结果scan_source_data创建惰性查询或延迟执行计划stream_source_data增量产出记录或批次write_format急切写出内存中的结果sink_format通过惰性或流式执行路径写出摄入函数的名称从一般到具体排序动词、来源、逻辑数据、可选表示。只有当确实存在同族格式时才包含表示部分。文档给出正例load_binance_order_book_deltas优于无状态的BinanceOrderBookDeltaDataLoader.load类也优于泛化的load_binance_data函数。这一约定在仓库中有直接落地证据python/nautilus_trader/adapters/binance/init.py 的__all__中同时导出了load_binance_instruments与load_binance_order_book_deltas与动词-来源-逻辑数据的命名模式完全吻合。适配器包门面Facade__all__是公共 API 的唯一事实来源python/nautilus_trader/adapters/下的每个包都被设计为覆盖私有_libnautilus扩展的薄门面。三条核心纪律每个适配器__init__.py声明确定性的__all__它是该包公共 API 的唯一事实来源python/generate_stubs.py 把这份列表复制到对应的.pyi保证运行时导出与类型桩导出完全一致__all__的排序交给RUF022Ruff 的 pre-commit 门禁接管不要手工排序——机器排序保证跨适配器的列表风格统一。一个交易所适配器应暴露的公共表面包括规范身份常量VENUE、VENUE_CLIENT_ID、VENUE_VENUE——由 Rust 侧适配器的python/mod.rs通过m.add注册数据类型、*Config、*Factory、用户可见的枚举如*Environment、*ProductType无状态加载器load_*、stream_*、convert_*与有意暴露的工具decode_*、get_*_arrow_schema_map。同时有明确禁止项门面必须保持薄。不得仅仅为了结构对等就把原始 HTTP/WebSocket 客户端、线上模型、端点 URL 解析器get_*_url、*_HTTP_URL、缓存等内部实现塞进__all__。例外情况数据提供商如databento、tardis、blockchain数据客户端、sandbox执行客户端、多交易所的interactive_brokers券商省略交易所常量——因为对它们而言VENUE常量没有意义。以 binance/init.py 的__all__为真实样例可以观察到完整形态BINANCE、BINANCE_CLIENT_ID、BINANCE_VENUE三个常量打头随后是BinanceBar等数据类型、BinanceEnvironment/BinanceProductType/BinanceMarginType等枚举、BinanceDataClientConfig/BinanceExecutionClientConfig配置、两个Factory最后是decode_*、get_binance_arrow_schema_map与两个load_*函数——门面各层的齐全与克制一目了然。格式化细节对齐逻辑缩进而非悬挂对齐长行与多参数调用的排版有精确要求长代码行、以及传递多于两三个参数时换行并对齐到下一个逻辑缩进——不要试图在开括号后做悬挂的虚荣对齐vanity alignment。这样既节省右侧空间、让重要代码保持在视野中央也经得起函数/方法改名右括号放在新行对齐到逻辑缩进处多个悬挂参数/实参以尾随逗号结尾long_method_with_many_params( some_arg1, some_arg2, some_arg3, # -- trailing comma )Rust 侧对应的强制工具是 rustfmt.tomlmax_width 100、edition 2024、newline_style Unix、error_on_unformatted true其中error_on_unformatted意味着未格式化代码直接报错而非警告此外group_imports StdExternalCrate、imports_granularity Crate还规范了 import 的分组与粒度。配合 clippy.toml 的cognitive-complexity-threshold 10认知复杂度阈值以及allow-expect-in-tests/allow-unwrap-in-tests的测试豁免Rust 代码的格式与复杂度都有量化闸门。提交信息规范非 Conventional Commits 的提交纪律Nautilus Trader 的提交信息规范与当前编辑器/AI 助手默认的 Conventional Commits 风格刻意相反这是仓库最鲜明的工程决策之一。主题行Subject要求以大写祈使动词开头Add、Fix、Improve、Refine、Update、Remove、Refactor、Standardize覆盖了绝大部分历史提交点名受影响的面crate、适配器、子系统或类型保证日志可扫读主题至少 10 个字符以便清楚地点名受影响面目标60 字符以内。提交信息钩子对超过 60 字符只告警不失败但项目计划未来强制执行check_commit_message.py 中的SUBJECT_MAX_GUIDANCE 60印证了引导值的定位不以句号结尾主题中不得出现 issue/PR 编号。#number在任意位置都会被提交信息钩子拒绝——因为 squash merge 时 GitHub 会自动追加 PR 编号手工写号会重复或冲突。合法示例Add Decimal constructors to Instrument trait Fix non-atomic order event application Refine cross-platform wheel validation Remove stale security audit exceptions应避免的形状feat(bybit): add due_post_only flag # Conventional Commits 类型与作用域 fix: bug # 小写、无具体信息、过短 Fixed the Bybit post-only rejection flag. # 过去时、句号结尾 Update stuff # 未说明受影响面 Fix the post-only flag (#4544) # 手工添加 PR 编号 Fix PR #4544 review feedback # 主题中包含 issue/PR 编号为什么禁用 Conventional Commits文档明确提交信息与 PR 标题都不要使用 Conventional Commits 语法。原因有二仓库历史中没有任何一条提交使用该格式type 与 scope 的仪式感重复了主题行本身已经携带的信息。这一点需要特别提醒使用 AI 助手和现代编辑器的开发者——因为它们默认就会输出feat(scope): ...这类格式。PR 标题同样重要因为squash merge 会把 PR 标题变成提交主题。Body 部分Body 可选但任何超出琐碎变更的提交都应该解释为什么而不是复述 diffbody 与主题之间用空行分隔body 行宽79 字符以内对齐 PEP 8 与传统 Git 工具可用散文段落或项目符号项目符号可以沿用主题的祈使语气且不需要句号结尾可包含对后续读者有帮助的信息性超链接。Issue 引用issue 引用放在 body 中通常是最后一行Resolves #4534关闭 issue或Related to #4547部分工作squash merge 后 GitHub 会生成形如Fix TWAP child-order sizing and interval validation (#4544)的主题不要手工加后缀尽量让 PR 标题足够短使追加后缀后的 squash 合并主题仍能落在 60 字符以内。钩子落地该规范由 pre-commit 的commit-msg阶段钩子check-commit-message入口 scripts/ci/check_commit_message.py强制执行它校验待提交的主题、body 与 AI 署名always_run保证每次提交都被检查。源码中可见SUBJECT_MAX_GUIDANCE 60、主题必须以大写开头、不得过短SUBJECT_MIN_LENGTH对应文档中的 10 字符底线等具体逻辑。规范背后的工程哲学纵观整套规范可以提炼出几条贯穿始终的工程原则机器执行优先几乎所有规范都有对应的 pre-commit 钩子或配置typos、shfmt、shellcheck、RUF022、check-commit-message、check-error-conventions、rustfmt/clippy把约定变成门禁杜绝人工 review 的遗漏面向用户的表面与内部实现分层缩写属于内部热路径全称属于公共 API、日志与指标——用户永远不该看到缩写的术语单一事实来源适配器的__all__与.pyi由 python/generate_stubs.py 同步公共 API 的导出面被明确收窄为门面尊重历史与生态保留既有Exec名称、迁移表与历史发布条目Rust 文档注释采用生态主流的陈述式语气提交信息与仓库真实历史保持一致而非迎合编辑器默认为可维护性设计细节逻辑缩进对齐而非悬挂对齐、尾随逗号、主题 60 字符上限都是为了让 git 历史 diff 更干净、日志更可扫读。对于想要为 Nautilus Trader 贡献代码的开发者CONTRIBUTING.md、environment_setup.md含prek install与make install-tools与 shell.md 是配套必读而本文覆盖的 coding_standards.md 则是日常写代码时最常被引用的那本规则手册。【免费下载链接】nautilus_traderProduction-grade Rust-native trading engine with deterministic event-driven architecture项目地址: https://gitcode.com/GitHub_Trending/na/nautilus_trader创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表