technical
technical copied to clipboard
Trend Step Channel - appreciate it
https://www.tradingview.com/script/nXhuJpwr-Efficient-Trend-Step-Channel/
Can anyone code this indicator in python/numba please. Seems like i am getting stuck at this line not sure what it means
abs(change(src,length))/sum(abs(change(src)),length)
the result is supposedly a series but the seems to be a ratio of two series. Appreciate any help.
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © alexgrover
//@version=4
study("Efficient Trend Step Channel",overlay=true)
length = input(100),fast = input(50),slow = input(200),src = input(close)
//----
er = abs(change(src,length))/sum(abs(change(src)),length)
dev = er*stdev(src*2,fast) + (1-er)*stdev(src*2,slow)
//----
a=0.,a := src > nz(a[1],src) + dev ? src : src < nz(a[1],src) - dev ? src : nz(a[1],src)
upper = valuewhen(change(a),a + dev,0)
lower = valuewhen(change(a),a - dev,0)
if you're stuck at some line - best share what you have so far, so we can determine where the most likely error is ?
Thanks for responding, appreciate it. I have gotten this far. Basically i have verified that deviation dev
is correct and matching trading view values. Where I am stuck is these 3 lines from the pine version
a=0.,a := src > nz(a[1],src) + dev ? src : src < nz(a[1],src) - dev ? src : nz(a[1],src)
upper = valuewhen(change(a),a + dev,0)
lower = valuewhen(change(a),a - dev,0)
Below is my python version (non optimized). I am using pandas ts for stddev
, mom
calculation which is equivalent of change
import pandas_ta as ta
## dfInd is the input dataframe that contain ohlcv data
length = 100
fast = 50
slow = 200
src = dfInd['Close'] # control src : Close, hl2, hlc3, etc
slowChange = ta.mom(src,length=length).abs()
fastChangeSum = ta.mom(src,length=1).abs().rolling(length).sum()
er = slowChange/fastChangeSum
dev = er*ta.stdev(src*2,fast) + (1-er)*ta.stdev(src*2,slow) # verified and correct
## ------------- Code below this line is where i am struggling !!
a = pd.DataFrame(0., index=dfInd.index, columns=['a'])
a=a['a']
# len(src.values)
# len(src.shift().fillna(0).values)
# # a['a'] = src.shift().fillna(0).values
value = np.where(a.shift(1).notnull(), a, src)
tsc = np.where (src > value + dev , value, src)
# tsc = np.where (src > value + dev , src, (np.where (src < value - dev , src , value)))
dfInd['TSC'] = tsc
dfInd['TSCdev'] = dev
# ----------- not reached to upper and lower bands calculations yet
# chang_a = ta.mom(dfInd['TSC'],1)
# dfInd['TSC_U'] = dfInd['TSC'] + dev
# dfInd['TSC_L'] = dfInd['TSC'] - dev
Appreciate if you can take a look at it.
a[1]
is referencing the prior row.
as this happens as part of the assignment to a - this means that you cannot really vectorize this indicator - but you'll have to loop - as the result of each row depends on the result from the calculation of the prior row.
You can find an example for this for example here:
https://github.com/freqtrade/technical/blob/7accaf535ee603c83a142e9830c775be8bf8bedb/technical/indicators/indicators.py#L1002-L1007
Obviously, this will have a quite severe performance penalty - as you'll loop through a dataframe with potentially 1000nds rows.
I understand what you are referring. Thanks for the quick response. I will try out just looping through as you suggested here and see what results i get.