mirror of
https://github.com/wassname/pandas-ta.git
synced 2026-08-11 11:22:48 +08:00
ENH added Chande Kroll Stop indicator
This commit is contained in:
@@ -1,3 +1,8 @@
|
||||
[](https://pypi.org/project/pandas_ta/)
|
||||
[](https://pypi.org/project/pandas_ta/)
|
||||
[](https://pypi.org/project/pandas_ta/)
|
||||
[](https://pypistats.org/packages/pandas_ta)
|
||||
|
||||
# Technical Analysis Library in Python 3.7
|
||||

|
||||
|
||||
@@ -21,6 +26,7 @@ All the indicators return a named Series or a DataFrame in uppercase underscore
|
||||
* Added indicators:
|
||||
- __Bias__ (bias)
|
||||
- __Choppiness Index__ (chop)
|
||||
- __Chande Kroll Stop__ (cksp)
|
||||
- __KDJ__ (kdj)
|
||||
- __Parabolic Stop and Reverse__ (psar)
|
||||
- __Price Distance__ (pdist)
|
||||
@@ -212,12 +218,13 @@ Use parameter: cumulative=**True** for cumulative results.
|
||||
|:--------:|
|
||||
|  |
|
||||
|
||||
## _Trend_ (13)
|
||||
## _Trend_ (14)
|
||||
|
||||
* _Average Directional Movement Index_: **adx**
|
||||
* _Archer Moving Averages Trends_: **amat**
|
||||
* _Aroon Oscillator_: **aroon**
|
||||
* _Choppiness Index_: **chop**
|
||||
* _Chande Kroll Stop_: **cksp**
|
||||
* _Decreasing_: **decreasing**
|
||||
* _Detrended Price Oscillator_: **dpo**
|
||||
* _Increasing_: **increasing**
|
||||
|
||||
@@ -92,6 +92,7 @@ from .trend.adx import adx
|
||||
from .trend.amat import amat
|
||||
from .trend.aroon import aroon
|
||||
from .trend.chop import chop
|
||||
from .trend.cksp import cksp
|
||||
from .trend.decreasing import decreasing
|
||||
from .trend.dpo import dpo
|
||||
from .trend.increasing import increasing
|
||||
|
||||
@@ -767,6 +767,15 @@ class AnalysisIndicators(BasePandasObject):
|
||||
self._append(result, **kwargs)
|
||||
return result
|
||||
|
||||
def cksp(self, high=None, low=None, close=None, p=None, x=None, q=None, offset=None, **kwargs):
|
||||
high = self._get_column(high, 'high')
|
||||
low = self._get_column(low, 'low')
|
||||
close = self._get_column(close, 'close')
|
||||
from pandas_ta.trend.cksp import cksp
|
||||
result = cksp(high=high, low=low, close=close, p=p, x=x, q=q, offset=offset, **kwargs)
|
||||
self._append(result, **kwargs)
|
||||
return result
|
||||
|
||||
def decreasing(self, close=None, length=None, asint=True, offset=None, **kwargs):
|
||||
close = self._get_column(close, 'close')
|
||||
from pandas_ta.trend.decreasing import decreasing
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from pandas import DataFrame
|
||||
from ..volatility.atr import atr
|
||||
from ..utils import get_offset, verify_series
|
||||
|
||||
def cksp(high, low, close, p=None, x=None, q=None, offset=None, **kwargs):
|
||||
"""Indicator: Chande Kroll Stop (CKSP)"""
|
||||
# Validate Arguments
|
||||
high = verify_series(high)
|
||||
low = verify_series(low)
|
||||
close = verify_series(close)
|
||||
p = int(p) if p and p > 0 else 10
|
||||
x = float(x) if x and x > 0 else 1
|
||||
q = int(q) if q and q > 0 else 9
|
||||
offset = get_offset(offset)
|
||||
|
||||
# Calculate Result
|
||||
atr_ = atr(high=high, low=low, close=close, length=p)
|
||||
|
||||
long_stop_ = high.rolling(p).max() - x * atr_
|
||||
long_stop = long_stop_.rolling(q).max()
|
||||
|
||||
short_stop_ = high.rolling(p).min() + x * atr_
|
||||
short_stop = short_stop_.rolling(q).min()
|
||||
|
||||
# Offset
|
||||
if offset != 0:
|
||||
long_stop = long_stop.shift(offset)
|
||||
short_stop = short_stop.shift(offset)
|
||||
|
||||
# Handle fills
|
||||
if 'fillna' in kwargs:
|
||||
long_stop.fillna(kwargs['fillna'], inplace=True)
|
||||
short_stop.fillna(kwargs['fillna'], inplace=True)
|
||||
if 'fill_method' in kwargs:
|
||||
long_stop.fillna(method=kwargs['fill_method'], inplace=True)
|
||||
short_stop.fillna(method=kwargs['fill_method'], inplace=True)
|
||||
|
||||
# Name and Categorize it
|
||||
_props = f"_{p}_{x}_{q}"
|
||||
long_stop.name = f"CKSPl{_props}"
|
||||
short_stop.name = f"CKSPs{_props}"
|
||||
long_stop.category = short_stop.category = 'trend'
|
||||
|
||||
# Prepare DataFrame to return
|
||||
ckspdf = DataFrame({long_stop.name: long_stop, short_stop.name: short_stop})
|
||||
ckspdf.name = f"CKSP{_props}"
|
||||
ckspdf.category = 'trend'
|
||||
|
||||
return ckspdf
|
||||
|
||||
|
||||
|
||||
cksp.__doc__ = \
|
||||
"""Chande Kroll Stop (CKSP)
|
||||
|
||||
The Tushar Chande and Stanley Kroll in their book
|
||||
“The New Technical Trader”. It is a trend-following indicator,
|
||||
identifying your stop by calculating the average true range of
|
||||
the recent market volatility.
|
||||
|
||||
Sources:
|
||||
https://www.multicharts.com/discussion/viewtopic.php?t=48914
|
||||
|
||||
Calculation:
|
||||
Default Inputs:
|
||||
p=10, x=1, q=9
|
||||
ATR = Average True Range
|
||||
|
||||
LS0 = high.rolling(p).max() - x * ATR(length=p)
|
||||
LS = LS0.rolling(q).max()
|
||||
|
||||
SS0 = high.rolling(p).min() + x * ATR(length=p)
|
||||
SS = SS0.rolling(q).min()
|
||||
|
||||
Args:
|
||||
close (pd.Series): Series of 'close's
|
||||
p (int): ATR and first stop period. Default: 10
|
||||
x (float): ATR scalar. Default: 1
|
||||
q (int): Second stop period. Default: 9
|
||||
offset (int): How many periods to offset the result. Default: 0
|
||||
|
||||
Kwargs:
|
||||
fillna (value, optional): pd.DataFrame.fillna(value)
|
||||
fill_method (value, optional): Type of fill method
|
||||
|
||||
Returns:
|
||||
pd.DataFrame: long and short columns.
|
||||
"""
|
||||
@@ -6,7 +6,7 @@ long_description = "An easy to use Python 3 Pandas Extension with 95+ Technical
|
||||
setup(
|
||||
name ="pandas_ta",
|
||||
packages =['pandas_ta', 'pandas_ta.momentum', 'pandas_ta.overlap', 'pandas_ta.performance', 'pandas_ta.statistics', 'pandas_ta.trend', 'pandas_ta.volatility', 'pandas_ta.volume'],
|
||||
version ="0.1.45b",
|
||||
version ="0.1.46b",
|
||||
description =long_description,
|
||||
long_description =long_description,
|
||||
author ="Kevin Johnson",
|
||||
@@ -20,6 +20,7 @@ setup(
|
||||
license ="The MIT License (MIT)",
|
||||
classifiers =[
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Development Status :: 4 - Beta',
|
||||
'License :: OSI Approved :: MIT License',
|
||||
'Natural Language :: English',
|
||||
|
||||
@@ -34,7 +34,7 @@ class TestOverlap(TestCase):
|
||||
|
||||
def setUp(self): pass
|
||||
def tearDown(self): pass
|
||||
|
||||
|
||||
|
||||
def test_dema(self):
|
||||
result = pandas_ta.dema(self.close)
|
||||
|
||||
@@ -81,6 +81,11 @@ class TestTrend(TestCase):
|
||||
self.assertIsInstance(result, Series)
|
||||
self.assertEqual(result.name, 'CHOP_14_1_100')
|
||||
|
||||
def test_cksp(self):
|
||||
result = pandas_ta.cksp(self.high, self.low, self.close)
|
||||
self.assertIsInstance(result, DataFrame)
|
||||
self.assertEqual(result.name, 'CKSP_10_1_9')
|
||||
|
||||
def test_decreasing(self):
|
||||
result = pandas_ta.decreasing(self.close)
|
||||
self.assertIsInstance(result, Series)
|
||||
|
||||
@@ -43,6 +43,11 @@ class TestTrendExtension(TestCase):
|
||||
self.assertIsInstance(self.data, DataFrame)
|
||||
self.assertEqual(self.data.columns[-1], 'CHOP_14_1_100')
|
||||
|
||||
def test_cksp_ext(self):
|
||||
self.data.ta.cksp(append=True)
|
||||
self.assertIsInstance(self.data, DataFrame)
|
||||
self.assertEqual(self.data.columns[-1], 'CKSPs_10_1_9')
|
||||
|
||||
def test_decreasing_ext(self):
|
||||
self.data.ta.decreasing(append=True)
|
||||
self.assertIsInstance(self.data, DataFrame)
|
||||
|
||||
Reference in New Issue
Block a user