A lightweight, pandas-friendly Python library for detecting candlestick patterns in financial time-series data, based on NISON book.
Project description
Py-CandleKit
A lightweight, pandas-friendly Python library for detecting candlestick patterns in financial time-series data.
✨ Features
- 20+ Classic Patterns: Detect Hammer, Engulfing, Morning Star, and more
- Pandas Integration: Works directly with pandas DataFrames (OHLC format)
- Clear Classification: Bullish/bearish/neutral signal identification
- Academic Foundation: Based on Nison's "Japanese Candlestick Charting Techniques"
- Production Ready: Comprehensive testing and type hints
- Easy Extension: Simple API for adding custom patterns
📊 Supported Patterns
Single-Candle Patterns
- Doji - Indecision (neutral)
- Hammer - Bullish reversal after downtrend
- Shooting Star - Bearish reversal after uptrend
- Bullish/Bearish Marubozu - Strong conviction with minimal shadows
- Bullish/Bearish Belt Hold - Strong opening at extreme
Two-Candle Patterns
- Bullish/Bearish Engulfing - Reversal patterns
- Piercing Line / Dark Cloud Cover - Counter-trend reversals
- Harami Cross - Reversal with doji
- Kicking - Reversal with marubozu gap
Three-Candle Patterns
- Morning/Evening Star - Classic reversal patterns
- Morning/Evening Doji Star - Reversal with doji confirmation
- Three White Soldiers - Strong bullish continuation
- Three Black Crows - Strong bearish continuation
- Three Inside/Outside Up - Bullish reversal variations
Five-Candle Patterns
- Rising/Falling Three Methods - Continuation patterns
- Mat Hold - Bullish continuation with pullback
📦 Installation
pip install py-candlekit
🚀 Quick Start
import pandas as pd
from candlekit import scan_symbol_df, CandlePatterns
# Your OHLC data (lowercase column names required)
data = {
'open': [100, 102, 101, 103, 105],
'high': [103, 104, 102, 106, 107],
'low': [99, 101, 100, 102, 104],
'close': [102, 101, 102, 105, 106]
}
df = pd.DataFrame(data)
# Scan for all patterns
results_df = scan_symbol_df(df)
print(results_df)
Output:
index pattern_name signal_type candles
0 1 Hammer bullish 1
1 3 Bullish Engulfing bullish 2
📚 Basic Usage
Detect Specific Pattern
from candlekit import detect_pattern_at_index
# Check if index 1 is a Hammer
is_hammer = detect_pattern_at_index(CandlePatterns.Hammer, df, index=1)
print(f"Hammer detected: {is_hammer}") # True
Get Results as List
from candlekit import scan_symbol
results_list = scan_symbol(df)
# Returns: [(1, 'Hammer', 'bullish'), (3, 'BullishEngulfing', 'bullish')]
Scan Specific Patterns Only
# Scan only for reversal patterns
reversal_patterns = [
CandlePatterns.Hammer,
CandlePatterns.ShootingStar,
CandlePatterns.BullishEngulfing,
CandlePatterns.MorningStar
]
results = scan_symbol_df(df, patterns=reversal_patterns)
🔧 Working with Real Data
Using yfinance (Optional)
import yfinance as yf
from candlekit import scan_symbol_df
# Download data
ticker = yf.Ticker("AAPL")
df = ticker.history(period="1mo", interval="1d")
# Ensure correct column names
df.columns = [col.lower() for col in df.columns]
# Scan for patterns
patterns = scan_symbol_df(df)
# Filter recent bullish patterns
recent_bullish = patterns[
(patterns['signal_type'] == 'bullish') &
(patterns['index'] > len(df) - 5)
]
Using CSV Data
import pandas as pd
from candlekit import scan_symbol_df
# Load from CSV (ensure column names match)
df = pd.read_csv('your_data.csv')
df.columns = ['open', 'high', 'low', 'close', 'volume'] # Rename if needed
# Scan for patterns
results = scan_symbol_df(df)
⚙️ Advanced Configuration
Custom Pattern Parameters
# Adjust sensitivity for Doji detection
detect_pattern_at_index(
CandlePatterns.Doji,
df,
index=0,
max_body_ratio=0.15 # Default: 0.1
)
# Custom Hammer parameters
detect_pattern_at_index(
CandlePatterns.Hammer,
df,
index=1,
max_body_ratio=0.3, # Default: 0.25
min_lower_wick_to_body=1.5, # Default: 2.0
max_upper_wick_ratio=0.4 # Default: 0.33
)
Pattern-Specific Parameters
Each pattern has sensible defaults, but you can adjust:
max_body_ratio: Maximum body-to-total-length ratio (for thin candles)min_body_ratio: Minimum body-to-total-length ratio (for thick candles)min_lower_wick_to_body: For Hammer patternmin_upper_wick_to_body: For Shooting Star pattern
🧠 Understanding CandleStick Objects
The library uses CandleStick objects internally. You can access their properties:
from candlekit.src.candlekit.entity import CandleStick
candle = CandleStick(df, index=0)
print(f"Body length: {candle.body_length}")
print(f"Top wick: {candle.top_wick}")
print(f"Bottom wick: {candle.bottom_wick}")
print(f"Body ratio: {candle.body_ratio:.2%}")
print(f"Is bullish: {candle.is_bullish}")
📊 Complete Pattern List
Access All Patterns
from candlekit import CandlePatterns
# List all available patterns
for pattern in CandlePatterns:
print(f"{pattern.pattern_name}: {pattern.signal_type} ({pattern.candles} candle(s))")
Pattern Categories
# Single-candle patterns
single_candle = [p for p in CandlePatterns if p.candles == 1]
# Multi-candle patterns
multi_candle = [p for p in CandlePatterns if p.candles > 1]
# Bullish patterns
bullish = [p for p in CandlePatterns if p.signal_type == 'bullish']
# Bearish patterns
bearish = [p for p in CandlePatterns if p.signal_type == 'bearish']
🧪 Testing & Quality
Run Tests
# Install test dependencies
pip install pytest
# Run all tests
python -m pytest
# Run specific test file
python -m pytest tests/test_patterns.py -v
# Run with coverage
python -m pytest --cov=candlekit tests/
Example Test
import pytest
import pandas as pd
from candlekit import detect_pattern_at_index, CandlePatterns
def test_hammer_detection():
"""Test Hammer pattern detection"""
df = pd.DataFrame({
'open': [100],
'high': [105],
'low': [95],
'close': [99]
})
# This is NOT a hammer (body too large relative to wick)
result = detect_pattern_at_index(CandlePatterns.Hammer, df, index=0)
assert result == False
# This IS a hammer
df = pd.DataFrame({
'open': [95],
'high': [98],
'low': [80],
'close': [96]
})
result = detect_pattern_at_index(CandlePatterns.Hammer, df, index=0)
assert result == True
🛠️ Development
Setup Development Environment
# Clone and install
git clone https://github.com/zhirodadkhah/candlekit.git
cd candlekit
pip install -e ".[dev]"
# Run code quality tools
flake8 src/candlekit # Linting
black src/candlekit # Formatting
mypy src/candlekit # Type checking
Adding New Patterns
- Add detection function in
patterns.py - Add to
CandlePatternsenum inutils.py - Write comprehensive tests
Example:
# In patterns.py
def is_tweezers_top(candle1: CandleStick, candle2: CandleStick) -> bool:
"""Detect Tweezer Top pattern."""
return (
candle1.high == candle2.high and
candle1.is_bullish and
not candle2.is_bullish
)
# In utils.py
CandlePatterns.TweezerTop = (2, is_tweezers_top, "bearish", "Tweezer Top")
📖 Pattern References & Methodology
All patterns are implemented according to Steve Nison's "Japanese Candlestick Charting Techniques, 2nd Edition". Each pattern function includes page references to the textbook.
Key Concepts
- Body Ratio:
body_length / total_length- measures conviction - Window Gap: Price gap between candles with no overlap
- Engulfment: Current candle's body completely contains previous
- Containment: Candle's body is within another's range
Academic Sources
- Nison, S. (2001). Japanese Candlestick Charting Techniques
- Bulkowski, T. N. (2005). Encyclopedia of Candlestick Charts
- Morris, G. L. (1995). Candlestick Charting Explained
🤝 Contributing
We welcome contributions! Please:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-pattern - Add tests for new functionality
- Ensure tests pass:
pytest - Update documentation as needed
- Submit a Pull Request
Contribution Ideas
- Add more candlestick patterns
- Improve performance for large datasets
- Add visualization helpers
- Create Jupyter notebook examples
- Add pattern combination analysis
🙏 Acknowledgments
- Steve Nison for bringing candlestick analysis to markets
- The pandas and numpy communities
- All contributors and users of this library
- Financial analysts and quants who provided feedback
⚠️ Disclaimer
IMPORTANT: This library is for educational and research purposes only.
- Trading involves substantial risk of loss
- Past performance is not indicative of future results
- Always conduct your own research and consult financial advisors
- The authors are not responsible for any trading losses
Use this tool as part of a comprehensive trading strategy, not as standalone advice.
Happy analyzing! 📈
Found a bug or have a feature request? Please open an issue on GitHub!
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file py_candlekit-1.0.1-py3-none-any.whl.
File metadata
- Download URL: py_candlekit-1.0.1-py3-none-any.whl
- Upload date:
- Size: 22.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d7497b61b367a844d3e15ce335a351460c35784c85e3c868e1e97497deb7c2b5
|
|
| MD5 |
f10ebd8805c93500290dd59c277122a2
|
|
| BLAKE2b-256 |
47aec6e0f7a6b84769a5a11c715f6187cbeae8f11052a9303d2ecff0debe67db
|