Code Style Guide¶
Coding standards for sigc contributions.
Rust Style¶
Formatting¶
Use rustfmt for all Rust code:
Naming Conventions¶
| Item | Convention | Example |
|---|---|---|
| Functions | snake_case | compute_signal |
| Types | PascalCase | SignalValue |
| Constants | SCREAMING_SNAKE | MAX_WORKERS |
| Modules | snake_case | sig_parser |
| Local variables | snake_case | daily_return |
Documentation¶
Document all public items:
Rust
/// Computes the signal value for a given date.
///
/// # Arguments
///
/// * `date` - The date to compute the signal for
/// * `prices` - Price data
///
/// # Returns
///
/// The computed signal value
///
/// # Errors
///
/// Returns an error if the date is not in the price data
pub fn compute_signal(date: NaiveDate, prices: &DataFrame) -> Result<f64> {
// ...
}
Error Handling¶
Use custom error types:
Rust
// Good
fn load_data(path: &str) -> Result<DataFrame, DataError> {
let file = File::open(path)
.map_err(|e| DataError::FileNotFound(path.to_string()))?;
// ...
}
// Avoid
fn load_data(path: &str) -> Result<DataFrame, Box<dyn Error>> {
// ...
}
Testing¶
Test all public functions:
Rust
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_compute_signal() {
let prices = create_test_data();
let result = compute_signal(date, &prices).unwrap();
assert_eq!(result, expected);
}
#[test]
fn test_compute_signal_missing_date() {
let prices = create_test_data();
let result = compute_signal(missing_date, &prices);
assert!(result.is_err());
}
}
sigc DSL Style¶
Signal Definitions¶
Text Only
// Good: Clear, descriptive names
signal momentum_12_1:
ret_12m = ret(prices, 252)
ret_1m = ret(prices, 21)
emit zscore(ret_12m - ret_1m)
// Avoid: Cryptic names
signal s1:
r = ret(prices, 252) - ret(prices, 21)
emit zscore(r)
Comments¶
Text Only
// Explain the "why", not the "what"
// Good: Explains rationale
// Skip last month to avoid short-term reversal contamination
ret_skip = ret(prices, 21)
// Avoid: Just restates the code
// Calculate 21-day return
ret_skip = ret(prices, 21)
Formatting¶
- Indent with 2 spaces
- One blank line between signal definitions
- Align
emitstatements
Python Style¶
Follow PEP 8 with these additions:
Type Hints¶
Use type hints for all public functions:
Python
def run(
strategy: str,
params: Optional[Dict[str, Any]] = None,
start: Optional[str] = None,
end: Optional[str] = None
) -> Results:
"""Run a backtest."""
...
Docstrings¶
Use Google-style docstrings:
Python
def compute_signal(data: pd.DataFrame, lookback: int) -> pd.Series:
"""Compute the momentum signal.
Args:
data: Price data with 'close' column
lookback: Number of days for return calculation
Returns:
Series of signal values
Raises:
ValueError: If lookback is negative
"""
...
Git Commit Messages¶
Format¶
Text Only
type(scope): short description
Longer description if needed. Wrap at 72 characters.
Fixes #123
Types¶
| Type | Use |
|---|---|
feat |
New feature |
fix |
Bug fix |
docs |
Documentation |
style |
Formatting |
refactor |
Code restructure |
test |
Tests |
chore |
Maintenance |
Examples¶
Text Only
feat(parser): add support for range() in params
fix(runtime): handle division by zero in zscore
docs(api): add Python API reference
test(signals): add tests for momentum calculation
Pull Request Guidelines¶
Title¶
Follow commit message format:
Description¶
Include: - What changed and why - How to test - Related issues
Size¶
- Prefer small, focused PRs
- Split large changes into multiple PRs
Code Review¶
For Authors¶
- Respond to all comments
- Explain your reasoning
- Be open to feedback
For Reviewers¶
- Be constructive
- Approve when satisfied
- Suggest, don't demand