mirror of
https://github.com/wassname/pandas-ta.git
synced 2026-08-20 12:40:09 +08:00
ENH #86 fisher indicator fix and TV correlation
This commit is contained in:
@@ -119,6 +119,7 @@ pandas_ta/_wrapper.py
|
||||
data/datas.csv
|
||||
data/SPY_5min.csv
|
||||
data/SPY_1min.csv
|
||||
data/SPY_D_adxfish.csv
|
||||
data/SPY_D_lbsz.csv
|
||||
data/TV_5min.csv
|
||||
data/similang-ch.csv
|
||||
|
||||
+95
-87
File diff suppressed because one or more lines are too long
@@ -9,7 +9,7 @@ import pandas as pd # pip install pandas
|
||||
from alphaVantageAPI.alphavantage import AlphaVantage # pip install alphaVantage-api
|
||||
import pandas_ta as ta # pip install pandas_ta
|
||||
|
||||
|
||||
AV = AlphaVantage(api_key="YOUR API KEY", premium=False, clean=True, output_size="full")
|
||||
|
||||
class Watchlist(object):
|
||||
"""Watchlist Class (** This is subject to change! **)
|
||||
@@ -44,7 +44,7 @@ class Watchlist(object):
|
||||
self.data = None
|
||||
self.kwargs = kwargs
|
||||
|
||||
self.ds = ds if ds is not None else None
|
||||
self.ds = ds if ds is not None else AV
|
||||
self.strategy = strategy
|
||||
|
||||
|
||||
@@ -105,7 +105,6 @@ class Watchlist(object):
|
||||
|
||||
if kwargs.pop("analyze", True):
|
||||
if self.debug: print(f"[+] TA[{len(self.strategy.ta)}]: {self.strategy.name}")
|
||||
# df.ta.strategy(name=self.strategy.name, ta=self.strategy.ta, **kwargs)
|
||||
df.ta.strategy(self.strategy, **kwargs)
|
||||
|
||||
df.ticker = ticker # Attach ticker to the DataFrame
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ from pandas_ta.volatility import *
|
||||
from pandas_ta.volume import *
|
||||
from pandas_ta.utils import *
|
||||
|
||||
version = ".".join(("0", "1", "92b"))
|
||||
version = ".".join(("0", "1", "93b"))
|
||||
|
||||
|
||||
def mp_worker(args):
|
||||
|
||||
@@ -3,7 +3,7 @@ from numpy import log as nplog
|
||||
from numpy import NaN as npNaN
|
||||
from pandas import DataFrame, Series
|
||||
from pandas_ta.overlap import ema, hl2
|
||||
from pandas_ta.utils import get_offset, verify_series, zero
|
||||
from pandas_ta.utils import get_offset, high_low_range, verify_series, zero
|
||||
|
||||
def fisher(high, low, length=None, signal=None, offset=None, **kwargs):
|
||||
"""Indicator: Fisher Transform (FISHT)"""
|
||||
@@ -11,30 +11,29 @@ def fisher(high, low, length=None, signal=None, offset=None, **kwargs):
|
||||
high = verify_series(high)
|
||||
low = verify_series(low)
|
||||
length = int(length) if length and length > 0 else 9
|
||||
signal = int(signal) if signal and signal > 0 else 5
|
||||
signal = int(signal) if signal and signal > 0 else 1
|
||||
offset = get_offset(offset)
|
||||
|
||||
# Calculate Result
|
||||
m = high.size
|
||||
hl2_ = hl2(high, low)
|
||||
max_high = hl2_.rolling(length).max()
|
||||
min_low = hl2_.rolling(length).min()
|
||||
hl2_range = max_high - min_low
|
||||
hl2_range[hl2_range < 1e-5] = 0.001
|
||||
position = (hl2_ - min_low) / hl2_range
|
||||
|
||||
highest_hl2 = hl2_.rolling(length).max()
|
||||
lowest_hl2 = hl2_.rolling(length).min()
|
||||
|
||||
hlr = high_low_range(highest_hl2, lowest_hl2)
|
||||
hlr[hlr < 0.001] = 0.001
|
||||
|
||||
position = ((hl2_ - lowest_hl2) / hlr) - 0.5
|
||||
|
||||
v = 0
|
||||
fish = 0
|
||||
result = [npNaN for _ in range(0, length - 1)]
|
||||
for i in range(length - 1, m):
|
||||
v = 0.66 * (position[i] - 0.5) + 0.67 * v
|
||||
if v > 0.99: v = 0.999
|
||||
m = high.size
|
||||
result = [npNaN for _ in range(0, length - 1)] + [0]
|
||||
for i in range(length, m):
|
||||
v = 0.66 * position[i] + 0.67 * v
|
||||
if v < -0.99: v = -0.999
|
||||
fish = 0.5 * (fish + nplog((1 + v) / (1 - v)))
|
||||
result.append(fish)
|
||||
|
||||
if v > 0.99: v = 0.999
|
||||
result.append(0.5 * (nplog((1 + v) / (1 - v)) + result[i - 1]))
|
||||
fisher = Series(result, index=high.index)
|
||||
signalma = ema(fisher, length=signal)
|
||||
signalma = fisher.shift(signal)
|
||||
|
||||
# Offset
|
||||
if offset != 0:
|
||||
@@ -73,37 +72,36 @@ user-specified number of periods. A reversal signal is suggested when the the
|
||||
two lines cross.
|
||||
|
||||
Sources:
|
||||
https://tulipindicators.org/fisher
|
||||
https://library.tradingtechnologies.com/trade/chrt-ti-ehler-fisher-transformation.html
|
||||
TradingView
|
||||
TradingView (Correlation >99%)
|
||||
|
||||
Calculation:
|
||||
Default Inputs:
|
||||
length=10, signal=5
|
||||
EMA = Exponential Moving Average
|
||||
HL2 = 0.5 * (high + low)
|
||||
Max_HL2 = HL2.rolling(length).max()
|
||||
Min_HL2 = HL2.rolling(length).min()
|
||||
HL2R = Max_HL2 - Min_HL2
|
||||
HL2R[HL2R < 1e-5] = 0.001 # Set small values to 0.001
|
||||
position = (HL2 - Min_HL2) / HL2R
|
||||
|
||||
FISH = 0.5 * log((1 + position) / (1 - position))
|
||||
Signal = EMA(FISH, signal)
|
||||
|
||||
# Fix
|
||||
position = position > .99 ? .999 : position < -.99 ? -.999 : position
|
||||
length=9, signal=1
|
||||
HL2 = hl2(high, low)
|
||||
HHL2 = HL2.rolling(length).max()
|
||||
LHL2 = HL2.rolling(length).min()
|
||||
|
||||
position := round_(.66 * ((hl2 - low_) / max(high_ - low_, .001) - .5) + .67 * nz(value[1]))
|
||||
HLR = HHL2 - LHL2
|
||||
HLR[HLR < 0.001] = 0.001
|
||||
|
||||
fish1 = 0.0
|
||||
fish1 := .5 * log((1 + value) / max(1 - value, .001)) + .5 * nz(fish1[1])
|
||||
position = ((HL2 - LHL2) / HLR) - 0.5
|
||||
|
||||
v = 0
|
||||
m = high.size
|
||||
FISHER = [npNaN for _ in range(0, length - 1)] + [0]
|
||||
for i in range(length, m):
|
||||
v = 0.66 * position[i] + 0.67 * v
|
||||
if v < -0.99: v = -0.999
|
||||
if v > 0.99: v = 0.999
|
||||
FISHER.append(0.5 * (nplog((1 + v) / (1 - v)) + FISHER[i - 1]))
|
||||
|
||||
SIGNAL = FISHER.shift(signal)
|
||||
|
||||
Args:
|
||||
high (pd.Series): Series of 'high's
|
||||
low (pd.Series): Series of 'low's
|
||||
length (int): Fisher period. Default: 9
|
||||
signal (int): Fisher Signal period. Default: 5
|
||||
signal (int): Fisher Signal period. Default: 1
|
||||
offset (int): How many periods to offset the result. Default: 0
|
||||
|
||||
Kwargs:
|
||||
|
||||
@@ -157,15 +157,7 @@ class TestMomentum(TestCase):
|
||||
def test_fisher(self):
|
||||
result = pandas_ta.fisher(self.high, self.low)
|
||||
self.assertIsInstance(result, DataFrame)
|
||||
self.assertEqual(result.name, "FISHERT_9_5")
|
||||
|
||||
result = pandas_ta.fisher(self.high, self.low, tt=True)
|
||||
self.assertIsInstance(result, DataFrame)
|
||||
self.assertEqual(result.name, "FISHERT_9_5")
|
||||
|
||||
result = pandas_ta.fisher(self.high, self.low, tulip=True)
|
||||
self.assertIsInstance(result, DataFrame)
|
||||
self.assertEqual(result.name, "FISHERT_9_5")
|
||||
self.assertEqual(result.name, "FISHERT_9_1")
|
||||
|
||||
def test_inertia(self):
|
||||
result = pandas_ta.inertia(self.close)
|
||||
|
||||
@@ -81,7 +81,7 @@ class TestMomentumExtension(TestCase):
|
||||
def test_fisher_ext(self):
|
||||
self.data.ta.fisher(append=True)
|
||||
self.assertIsInstance(self.data, DataFrame)
|
||||
self.assertEqual(list(self.data.columns[-2:]), ["FISHERT_9_5", "FISHERTs_9_5"])
|
||||
self.assertEqual(list(self.data.columns[-2:]), ["FISHERT_9_1", "FISHERTs_9_1"])
|
||||
|
||||
def test_inertia_ext(self):
|
||||
self.data.ta.inertia(append=True)
|
||||
|
||||
Reference in New Issue
Block a user