bta-lib icon indicating copy to clipboard operation
bta-lib copied to clipboard

kama, ema indicators are giving errors

Open avnsiva opened this issue 4 years ago • 2 comments

I am trying to calculate the ema with the default periods.

import btalib
import pandas as pd
df = pd.read_csv("C:\\data\\nifty2019.csv")
df['Date'] = pd.to_datetime(df['Date'])
kama = btalib.ema(df.Close)

This is giving me an error trace like below. Can you help me to see if something is wrong with the way I am using it?

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
C:\app\Anaconda3\lib\site-packages\pandas\core\series.py in __setitem__(self, key, value)
   1013         try:
-> 1014             self._set_with_engine(key, value)
   1015         except com.SettingWithCopyError:

C:\app\Anaconda3\lib\site-packages\pandas\core\series.py in _set_with_engine(self, key, value)
   1053         try:
-> 1054             self.index._engine.set_value(values, key, value)
   1055             return

pandas\_libs\index.pyx in pandas._libs.index.IndexEngine.set_value()

pandas\_libs\index.pyx in pandas._libs.index.IndexEngine.set_value()

pandas\_libs\index.pyx in pandas._libs.index.IndexEngine.get_loc()

TypeError: 'slice(29, None, None)' is an invalid key

During handling of the above exception, another exception occurred:

ValueError                                Traceback (most recent call last)
<ipython-input-3-3a859967fb56> in <module>
----> 1 kama = btalib.ema(df.Close)

C:\app\Anaconda3\lib\site-packages\btalib\indicator.py in __call__(cls, *args, **kwargs)
    150         # Auto-call base classes
    151         for b_init in reversed(list(dict.fromkeys(b.__init__ for b in bases))):
--> 152             b_init(self, *args, **kwargs)
    153 
    154         # delete old aliases only meant for operational purposes

C:\app\Anaconda3\lib\site-packages\btalib\indicators\ema.py in __init__(self, poffset)
     37     def __init__(self, poffset=0):  # see above for poffset
     38         span, seed, poff = self.p.period, self.p._seed, poffset
---> 39         self.o.ema = self.i0._ewm(span=span, _seed=seed, _poffset=poff).mean()

C:\app\Anaconda3\lib\site-packages\btalib\meta\lines.py in call_op(*args, **kwargs)
    377                     sargs.append(arg)
    378 
--> 379                 result[self._minidx:] = r = op(*sargs, **kwargs)  # run/store
    380                 result = result.astype(r.dtype, copy=False)
    381                 return self._line._clone(result, period=self._minperiod)

C:\app\Anaconda3\lib\site-packages\pandas\core\series.py in __setitem__(self, key, value)
   1040                     pass
   1041 
-> 1042             self._set_with(key, value)
   1043 
   1044         if cacher_needs_updating:

C:\app\Anaconda3\lib\site-packages\pandas\core\series.py in _set_with(self, key, value)
   1062         if isinstance(key, slice):
   1063             indexer = self.index._convert_slice_indexer(key, kind="getitem")
-> 1064             return self._set_values(indexer, value)
   1065 
   1066         elif is_scalar(key) and not is_integer(key) and key not in self.index:

C:\app\Anaconda3\lib\site-packages\pandas\core\series.py in _set_values(self, key, value)
   1109         if isinstance(key, Series):
   1110             key = key._values
-> 1111         self._data = self._data.setitem(indexer=key, value=value)
   1112         self._maybe_update_cacher()
   1113 

C:\app\Anaconda3\lib\site-packages\pandas\core\internals\managers.py in setitem(self, **kwargs)
    559 
    560     def setitem(self, **kwargs):
--> 561         return self.apply("setitem", **kwargs)
    562 
    563     def putmask(self, **kwargs):

C:\app\Anaconda3\lib\site-packages\pandas\core\internals\managers.py in apply(self, f, filter, **kwargs)
    440                 applied = b.apply(f, **kwargs)
    441             else:
--> 442                 applied = getattr(b, f)(**kwargs)
    443             result_blocks = _extend_blocks(applied, result_blocks)
    444 

C:\app\Anaconda3\lib\site-packages\pandas\core\internals\blocks.py in setitem(self, indexer, value)
    875 
    876         # length checking
--> 877         check_setitem_lengths(indexer, value, values)
    878         exact_match = (
    879             len(arr_value.shape)

C:\app\Anaconda3\lib\site-packages\pandas\core\indexers.py in check_setitem_lengths(indexer, value, values)
    121             if len(value) != length_of_indexer(indexer, values):
    122                 raise ValueError(
--> 123                     "cannot set using a slice indexer with a "
    124                     "different length than the value"
    125                 )

ValueError: cannot set using a slice indexer with a different length than the value

avnsiva avatar Mar 29 '20 20:03 avnsiva

A very fast solution for ema is to provide a _seed > 3 argument. Of course, this is a sloppy solution, the root remains. i.e

btalib.ema(df,period=30,_seed=3).df

bamartos avatar Apr 05 '20 15:04 bamartos

The seed value of the EMA is typically either the first price of the period, which in the case of close price, will look like the following:

first_close_price = df.close.iloc[0]
ema = btalib.ema(df.close, _seed=first_close_price)

Alternatively, you can use the sma of the first n-periods as the seed. Hope this helps

Calrider avatar May 19 '20 04:05 Calrider