Contributing Guidelines
Contributions are useful when they sharpen one of three things: correctness, throughput, or clarity. The codebase gets little value from decorative abstractions or generic examples. It benefits from changes that make the numeric contract clearer, the execution path tighter, or the documentation more honest about how the system actually behaves.
That means the quality bar is higher than “it builds” and narrower than “it adds a lot.” Small changes are welcome if they resolve a real ambiguity, remove waste from a hot path, or make an implementation easier to trust. Large changes are only worth it when the contract stays legible after the refactor.
What is worth contributing
Good contributions usually fall into a few categories: indicator implementations with a clear scalar reference, measured performance improvements, better parity tests across scalar and accelerated paths, tighter documentation, and bug reports that reduce a real failure to a reproducible case. All of those improve the stack in a way that survives review.
The least helpful contributions are speculative architecture changes, broad rewrites that erase useful history, and feature additions that fail to explain their numerical contract. In this domain, ambiguity is often more expensive than missing functionality.
If you are adding indicator work
Start with the scalar implementation and make it easy to read. The optimized path only matters after the reference behavior is clear. Define warmup handling, NaN treatment, parameter validation, and expected output shape before reaching for SIMD or GPU kernels. A fast implementation with a fuzzy contract fails review.
If the change includes acceleration, keep the reference path intact and prove parity against it. The review burden goes up sharply once the implementation uses intrinsics, unsafe blocks, or device code, so the tests need to get stronger as the implementation gets lower-level.
If you are changing performance-sensitive code
Measure first. A credible performance contribution states the workload, the hardware, and the exact change in behavior. If the benchmark excludes setup cost, say so. If the optimization depends on a specific instruction set or device feature, say that too. Aim for a gain that still holds up when someone reads the diff and the benchmark notes.
Keep the fast path narrow. It is better to merge one explicit optimization with a clear fallback than a broad rewrite that is difficult to test and difficult to explain.
If you are changing documentation
Write like the maintainer of the system. That means fewer generic introductions, fewer empty checklists, and more direct statements about what the code does, what boundary matters, and where the reader should go next. Documentation is strongest when it explains the constraint, not when it stretches a topic into a template.
Pull request expectations
- Keep the scope focused enough that the change can be reviewed as one argument.
- Explain the contract you changed, along with the files you touched.
- Include tests or benchmark evidence when the change affects behavior or speed.
- Keep reference paths unless the replacement is easier to verify.
- Prefer clarity over cleverness in both code and prose.
Where to get context first
Read Architecture Overview before making broad design changes. Read Testing Best Practices before touching hot numeric paths. For product boundaries and implementation context, the most useful pages are Technical Analysis Library, Backtesting Engine, and the technical insights section.