Contributing to TechKit

Thank you for your interest in contributing to TechKit! This guide will help you get started.

Code Style

C/C++ Style

  • Follow the existing code style in the codebase

  • Use 4 spaces for indentation

  • Maximum line length: 100 characters

  • Use snake_case for functions and variables

  • Use PascalCase for classes

  • Always include header guards in header files

Python Style

  • Follow PEP 8

  • Use type hints for all function signatures

  • Maximum line length: 100 characters

  • Use snake_case for functions and variables

  • Use PascalCase for classes

Adding New Indicators

Implementation Steps

  1. Create C++ implementation in src/indicators/

    • Follow the pattern of existing indicators

    • Use ring buffers for O(period) memory

    • Implement incremental update (O(1) complexity)

  2. Add C API function in include/techkit/techkit_c.h

    • Factory function: tk_<name>_new(...)

    • Update function: tk_update() or tk_<name>_update()

    • Add result type if multi-output

  3. Implement C API wrapper in src/c_api.cpp

    • Map C function to C++ implementation

    • Handle parameter validation

    • Return appropriate error codes

  4. Add tests in tests/test_<name>.cpp

    • Test incremental updates

    • Test batch calculation

    • Validate against reference implementation (TA-Lib)

  5. Add Python bindings (if applicable)

    • Add class in bindings/python/techkit/indicators.py

    • Add TA-Lib compat function in bindings/python/techkit/talib_compat.py

  6. Add Node.js bindings (if applicable)

    • Add factory function in bindings/wasm/src/

    • Export in exports_*.txt

  7. Update documentation

    • Add to API reference

    • Update indicator inventory

Indicator Template

// src/indicators/<name>.cpp
#include "techkit/internal/indicator_base.hpp"

namespace techkit {

class <Name>Indicator : public IndicatorBase {
public:
    explicit <Name>Indicator(int period) 
        : IndicatorBase(period), period_(period) {
        // Initialize state
    }
    
    void reset() override {
        IndicatorBase::reset();
        // Reset internal state
    }
    
    tk_result update(double value) override {
        // Incremental update logic
        // Return {value, valid}
    }
    
    int lookback() const override {
        return period_ - 1;  // Adjust based on algorithm
    }
    
private:
    int period_;
    // Internal state
};

} // namespace techkit

Testing

Running Tests

# C++ tests
cd build
cmake ..
make
ctest --output-on-failure

# Python tests
cd bindings/python
python -m pytest tests/

# Node.js tests
cd bindings/packages/techkit
npm test

Writing Tests

  • Test both incremental and batch modes

  • Validate against TA-Lib or other reference

  • Test edge cases (empty input, invalid parameters)

  • Test warmup period behavior

Pull Request Process

  1. Fork the repository

  2. Create a feature branch: git checkout -b feature/my-indicator

  3. Make your changes

  4. Add tests for your changes

  5. Run all tests to ensure nothing breaks

  6. Update documentation if needed

  7. Commit your changes: Follow the commit message format

  8. Push to your fork: git push origin feature/my-indicator

  9. Create a Pull Request

Commit Message Format

<type>(<scope>): <subject>

<body>

<footer>

Types:

  • feat: New indicator or feature

  • fix: Bug fix

  • docs: Documentation changes

  • test: Test additions or changes

  • refactor: Code refactoring

  • perf: Performance improvements

Example:

feat(indicators): Add XYZ indicator

Implements XYZ indicator with O(1) incremental updates.
Validated against TA-Lib with < 1e-10 error tolerance.

Closes #123

Code Review Guidelines

  • All PRs require at least one approval

  • Ensure tests pass

  • Check code style compliance

  • Verify documentation is updated

  • Confirm no memory leaks (use valgrind)

Questions?

Feel free to open an issue for questions or discussions about contributions.