mirror of
https://github.com/wassname/pandas-ta.git
synced 2026-07-24 13:10:26 +08:00
added trend_return function and tests
This commit is contained in:
@@ -136,12 +136,13 @@ help(pd.DataFrame().ta.log_return)
|
||||
|:--------:|
|
||||
|  |
|
||||
|
||||
## _Performance_ (2)
|
||||
## _Performance_ (3)
|
||||
|
||||
Use parameter: cumulative=**True** for cumulative results.
|
||||
|
||||
* _Log Return_: **log_return**
|
||||
* _Percent Return_: **percent_return**
|
||||
* _Trend Return_: **trend_return**
|
||||
|
||||
| _Percent Return_ (Cumulative) with _Simple Moving Average_ (SMA) |
|
||||
|:--------:|
|
||||
|
||||
@@ -516,6 +516,12 @@ class AnalysisIndicators(BasePandasObject):
|
||||
self._append(result, **kwargs)
|
||||
return result
|
||||
|
||||
def trend_return(self, close=None, trend=None, log=True, cumulative=True, offset=None, **kwargs):
|
||||
close = self._get_column(close, 'close')
|
||||
trend = self._get_column(trend, f"{trend}")
|
||||
result = trend_return(close=close, trend=trend, log=log, cumulative=cumulative, offset=offset, **kwargs)
|
||||
self._append(result, **kwargs)
|
||||
return result
|
||||
|
||||
|
||||
# Statistics Indicators
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
from .utils import get_offset, verify_series
|
||||
from .utils import get_offset, verify_series, zero
|
||||
|
||||
|
||||
|
||||
@@ -54,6 +54,49 @@ def percent_return(close, length=None, cumulative=False, offset=None, **kwargs):
|
||||
return pct_return
|
||||
|
||||
|
||||
def trend_return(close, trend, trend_reset=0, log=True, cumulative=False, offset=None, **kwargs):
|
||||
"""Indicator: Trend Return"""
|
||||
# Validate Arguments
|
||||
close = verify_series(close)
|
||||
trend = verify_series(trend)
|
||||
offset = get_offset(offset)
|
||||
variable = kwargs.pop('variable', False)
|
||||
|
||||
# Calculate Result
|
||||
returns = log_return(close, cumulative=False) if log else percent_return(close, cumulative=False)
|
||||
m = trend.size
|
||||
tsum = 0
|
||||
result = []
|
||||
returns = (trend * returns).apply(zero)
|
||||
# trend = trend.astype(int)
|
||||
for i in range(0, m):
|
||||
if trend[i] == trend_reset:
|
||||
tsum = 0
|
||||
else:
|
||||
return_ = returns[i]
|
||||
if cumulative:
|
||||
tsum += return_
|
||||
else:
|
||||
tsum = return_
|
||||
result.append(tsum)
|
||||
|
||||
trend_return = pd.Series(result)
|
||||
|
||||
# Experimental: Add the individual return flucuations to the cumulative returns
|
||||
if variable and cumulative:
|
||||
trend_return += returns
|
||||
|
||||
# Offset
|
||||
if offset != 0:
|
||||
trend_return = trend_return.shift(offset)
|
||||
|
||||
# Name & Category
|
||||
trend_return.name = f"{'C' if cumulative else ''}{'L' if log else 'P'}TR"
|
||||
trend_return.category = 'performance'
|
||||
|
||||
return trend_return
|
||||
|
||||
|
||||
|
||||
log_return.__doc__ = \
|
||||
"""Log Return
|
||||
@@ -66,14 +109,14 @@ Sources:
|
||||
|
||||
Calculation:
|
||||
Default Inputs:
|
||||
length=1, cummulative=False
|
||||
length=1, cumulative=False
|
||||
LOGRET = log( close.diff(periods=length) )
|
||||
CUMLOGRET = LOGRET.cumsum() if cummulative
|
||||
CUMLOGRET = LOGRET.cumsum() if cumulative
|
||||
|
||||
Args:
|
||||
close (pd.Series): Series of 'close's
|
||||
length (int): It's period. Default: 20
|
||||
cummulative (bool): If True, returns the cummulative returns. Default: False
|
||||
cumulative (bool): If True, returns the cumulative returns. Default: False
|
||||
offset (int): How many periods to offset the result. Default: 0
|
||||
|
||||
Kwargs:
|
||||
@@ -96,20 +139,67 @@ Sources:
|
||||
|
||||
Calculation:
|
||||
Default Inputs:
|
||||
length=1, cummulative=False
|
||||
length=1, cumulative=False
|
||||
PCTRET = close.pct_change(length)
|
||||
CUMPCTRET = PCTRET.cumsum() if cummulative
|
||||
CUMPCTRET = PCTRET.cumsum() if cumulative
|
||||
|
||||
Args:
|
||||
close (pd.Series): Series of 'close's
|
||||
length (int): It's period. Default: 20
|
||||
cummulative (bool): If True, returns the cummulative returns. Default: False
|
||||
cumulative (bool): If True, returns the cumulative returns. Default: False
|
||||
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.Series: New feature generated.
|
||||
"""
|
||||
|
||||
|
||||
trend_return.__doc__ = \
|
||||
"""Trend Return
|
||||
|
||||
Calculates the (Cumulative) Returns of a Trend as defined by some conditional.
|
||||
By default it calculates log returns but can also use percent change.
|
||||
|
||||
Sources: Kevin Johnson
|
||||
|
||||
Calculation:
|
||||
Default Inputs:
|
||||
trend_reset=0, log=True, cumulative=False
|
||||
|
||||
sum = 0
|
||||
returns = log_return if log else percent_return # These are not cumulative
|
||||
returns = (trend * returns).apply(zero)
|
||||
for i, in range(0, trend.size):
|
||||
if item == trend_reset:
|
||||
sum = 0
|
||||
else:
|
||||
return_ = returns.iloc[i]
|
||||
if cumulative:
|
||||
sum += return_
|
||||
else:
|
||||
sum = return_
|
||||
trend_return.append(sum)
|
||||
|
||||
if cumulative and variable:
|
||||
trend_return += returns
|
||||
|
||||
Args:
|
||||
close (pd.Series): Series of 'close's
|
||||
trend (pd.Series): Series of 'trend's. Preferably 0's and 1's.
|
||||
trend_reset (value): Value used to identify if a trend has ended. Default: 0
|
||||
log (bool): Calculate logarithmic returns. Default: True
|
||||
cumulative (bool): If True, returns the cumulative returns. Default: False
|
||||
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
|
||||
variable (bool, optional): Whether to include if return fluxuations in the cumulative returns.
|
||||
|
||||
Returns:
|
||||
pd.Series: New feature generated.
|
||||
"""
|
||||
@@ -6,7 +6,7 @@ long_description = "An easy to use Python 3 Pandas Extension of Technical Analys
|
||||
setup(
|
||||
name = "pandas_ta",
|
||||
packages = ["pandas_ta"],
|
||||
version = "0.1.12a",
|
||||
version = "0.1.13a",
|
||||
description=long_description,
|
||||
long_description=long_description,
|
||||
author = "Kevin Johnson",
|
||||
|
||||
@@ -11,11 +11,13 @@ class TestPerformace(TestCase):
|
||||
def setUpClass(cls):
|
||||
cls.data = sample_data
|
||||
cls.close = cls.data['close']
|
||||
cls.islong = cls.close > pandas_ta.sma(cls.close, length=50)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
del cls.data
|
||||
del cls.close
|
||||
del cls.islong
|
||||
|
||||
|
||||
def setUp(self):
|
||||
@@ -41,4 +43,28 @@ class TestPerformace(TestCase):
|
||||
|
||||
def test_cum_percent_return(self):
|
||||
result = self.performance.percent_return(self.close, cumulative=True)
|
||||
self.assertEqual(result.name, 'CUMPCTRET_1')
|
||||
self.assertEqual(result.name, 'CUMPCTRET_1')
|
||||
|
||||
def test_log_trend_return(self):
|
||||
result = self.performance.trend_return(self.close, self.islong, log=True, cumulative=False)
|
||||
self.assertEqual(result.name, 'LTR')
|
||||
|
||||
def test_cum_log_trend_return(self):
|
||||
result = self.performance.trend_return(self.close, self.islong, log=True, cumulative=True)
|
||||
self.assertEqual(result.name, 'CLTR')
|
||||
|
||||
def test_variable_cum_log_trend_return(self):
|
||||
result = self.performance.trend_return(self.close, self.islong, log=True, cumulative=True, variable=True)
|
||||
self.assertEqual(result.name, 'CLTR')
|
||||
|
||||
def test_pct_trend_return(self):
|
||||
result = self.performance.trend_return(self.close, self.islong, log=False, cumulative=False)
|
||||
self.assertEqual(result.name, 'PTR')
|
||||
|
||||
def test_cum_pct_trend_return(self):
|
||||
result = self.performance.trend_return(self.close, self.islong, log=False, cumulative=True)
|
||||
self.assertEqual(result.name, 'CPTR')
|
||||
|
||||
def test_variable_pct_log_trend_return(self):
|
||||
result = self.performance.trend_return(self.close, self.islong, log=False, cumulative=True, variable=True)
|
||||
self.assertEqual(result.name, 'CPTR')
|
||||
@@ -12,10 +12,12 @@ class TestPerformaceExtension(TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.data = sample_data
|
||||
cls.islong = cls.data['close'] > pandas_ta.sma(cls.data['close'], length=50)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
del cls.data
|
||||
del cls.islong
|
||||
|
||||
|
||||
def setUp(self):
|
||||
@@ -30,6 +32,7 @@ class TestPerformaceExtension(TestCase):
|
||||
self.assertIsInstance(self.data, DataFrame)
|
||||
self.assertEqual(self.data.columns[-1], 'LOGRET_1')
|
||||
|
||||
def test_cum_log_return_ext(self):
|
||||
self.data.ta.log_return(append=True, cumulative=True)
|
||||
self.assertIsInstance(self.data, DataFrame)
|
||||
self.assertEqual(self.data.columns[-1], 'CUMLOGRET_1')
|
||||
@@ -39,6 +42,27 @@ class TestPerformaceExtension(TestCase):
|
||||
self.assertIsInstance(self.data, DataFrame)
|
||||
self.assertEqual(self.data.columns[-1], 'PCTRET_1')
|
||||
|
||||
def test_cum_percent_return_ext(self):
|
||||
self.data.ta.percent_return(append=True, cumulative=True)
|
||||
self.assertIsInstance(self.data, DataFrame)
|
||||
self.assertEqual(self.data.columns[-1], 'CUMPCTRET_1')
|
||||
self.assertEqual(self.data.columns[-1], 'CUMPCTRET_1')
|
||||
|
||||
def test_log_trend_return_ext(self):
|
||||
self.data.ta.trend_return(trend=self.islong, log=True, cumulative=False, append=True)
|
||||
self.assertIsInstance(self.data, DataFrame)
|
||||
self.assertEqual(self.data.columns[-1], 'LTR')
|
||||
|
||||
def test_cum_log_trend_return_ext(self):
|
||||
self.data.ta.trend_return(trend=self.islong, log=True, cumulative=True, append=True)
|
||||
self.assertIsInstance(self.data, DataFrame)
|
||||
self.assertEqual(self.data.columns[-1], 'CLTR')
|
||||
|
||||
def test_pct_trend_return_ext(self):
|
||||
self.data.ta.trend_return(trend=self.islong, log=False, cumulative=False, append=True)
|
||||
self.assertIsInstance(self.data, DataFrame)
|
||||
self.assertEqual(self.data.columns[-1], 'PTR')
|
||||
|
||||
def test_cum_pct_trend_return_ext(self):
|
||||
self.data.ta.trend_return(trend=self.islong, log=False, cumulative=True, append=True)
|
||||
self.assertIsInstance(self.data, DataFrame)
|
||||
self.assertEqual(self.data.columns[-1], 'CPTR')
|
||||
Reference in New Issue
Block a user