First off, thank you for considering contributing to Kand! It's people like you that make Kand such a great tool.
Following these guidelines helps to communicate that you respect the time of the developers managing and developing this open source project. In return, they should reciprocate that respect in addressing your issue or assessing patches and features.
Before you start developing, you need to install several required tools:
-
Install Rust development tools:
cargo install cargo-udeps git-cliff wasm-pack
cargo-udeps: Finds unused dependenciesgit-cliff: Generates changelogswasm-pack: WebAssembly package builder
-
Install uv (Python package manager): Follow the installation guide at: https://github.com/astral-sh/uv
-
Install maturin (Python-Rust bindings):
uv tool install maturin
-
Install pre-commit (Git hooks framework):
pip install pre-commit
-
Install make (Build automation tool):
- Linux/macOS: Usually pre-installed, or install via package manager
- Windows: Install via one of the following options:
- Install Git for Windows (includes make)
- Install Chocolatey and run
choco install make - Install MSYS2 and run
pacman -S make
Make sure all these tools are properly installed before proceeding with development.
Our project is structured into three main parts:
kand: The core library written in Rust, containing all the technical indicator implementations.kand-py: The Python bindings for the core library, allowing Kand to be used in Python.kand-wasm: The WebAssembly bindings for the core library, enabling its use in JavaScript/TypeScript environments (web and Node.js).
When making changes, please follow this general workflow:
- Modify the Rust code: All logic for technical indicators resides in the
kand/directory. Make your changes or additions here first. - Ensure tests pass: Run the Rust test suite to make sure your changes haven't broken anything.
- Update bindings: If you've added a new indicator or changed a function signature, update the corresponding bindings in the
kand-py/and/orkand-wasm/directories. - Run all checks: Use the provided
Makefileto run a full suite of checks, including building, testing, linting, and formatting.
We have a Makefile that simplifies the development process. The most important command is:
makeRunning make by default executes the pre-commit target, which will:
- Build the project (
build) - Run tests (
test) - Run the linter (
clippy) - Format the code (
fmt) - Generate the changelog (
cliff) - Check for unused dependencies (
udeps-check) - Build the Wasm package (
wasm-build) - Sync the Python environment and generate stubs (
uv-sync)
Please ensure all checks pass before submitting a pull request.
To maintain consistency and readability across the codebase, adhere to the following coding guidelines when implementing or modifying technical indicators:
- Parameter Order: Function parameters for technical indicators should follow the
(input data, optimization parameters, output data)pattern:- Input Data: Includes raw input data (e.g.,
input: &[TAFloat]for a price series,input: TAFloatfor a new price,prev_input: TAFloatfor an old price) and computation state (e.g.,prev_sma: TAFloatfor the previous SMA value). Raw input data should precede state data. - Optimization Parameters: Configuration parameters like
opt_period: TAPeriodthat control the indicator's behavior. - Output Data: Typically a mutable output parameter (e.g.,
output: &mut [TAFloat]) for full calculations or the function's return value (e.g.,TAFloat) for incremental calculations. - Examples:
- For full SMA calculation: Use
(input, opt_period, output)as seen insma(input: &[TAFloat], opt_period: TAPeriod, output: &mut [TAFloat]). - For incremental SMA calculation: Use
(input, prev_input, prev_sma, opt_period)as seen insma_inc(input: TAFloat, prev_input: TAFloat, prev_sma: TAFloat, opt_period: TAPeriod).
- For full SMA calculation: Use
- Input Data: Includes raw input data (e.g.,
- Naming Conventions:
- Use descriptive names for input data, such as
input(price series or new price),prev_input(old price), orprev_sma(previous SMA value). - Use domain-specific terms with the
opt_prefix for optimization parameters, such asopt_period,opt_weight, oropt_smoothing, to clearly indicate their role as configuration parameters. - For output data, use clear names like
outputorsma_valuesto indicate the result's purpose.
- Use descriptive names for input data, such as
- Consistency: Apply this parameter order and naming style to all technical indicator functions, including full calculation functions (e.g.,
sma) and incremental calculation functions (e.g.,sma_inc), to ensure a cohesive codebase.
- Locate the indicator's code in the
kand/src/directory and apply your changes. - Run the tests to ensure correctness:
make test. - If you have changed any function signatures, update the corresponding code in
kand-pyand/orkand-wasm. - Run
maketo perform all pre-commit checks.
Adding a new indicator is exciting! To ensure quality and consistency, please follow these steps:
- Implement the new indicator in the
kand/directory. - Add a new test module for your indicator.
- Provide accurate test data: This is a critical step.
- If the indicator exists in TA-Lib, your test data must align with the output of TA-Lib. This ensures compatibility and correctness.
- If the indicator is not in TA-Lib, you must provide a reference to verify the accuracy of your implementation and test data. This can be:
- A Python implementation of the indicator.
- A link to a trading website, academic paper, or another reliable source that defines the indicator and provides example calculations.
- Add the Python bindings for your new indicator in the
kand-py/directory. - Run
maketo ensure everything is in order.
- Fork the repository and create your branch from
main. - Make your changes, adhering to the workflow described above.
- Ensure the test suite passes and that all
makechecks are green. - Issue that pull request! We'll review it as soon as we can.
Thank you for your contribution!