Indicator Output

There would be no fun in technical analysis if one could not access the calculated values and accessing them and reusing them if needed should be easy.

The actual outputs

Each indicator is fully documented with a proper docstring, which allows to do the following

import btalib

print(btalib.sma.__doc__)

Generating the following output

    Non-weighted average of the last n periods

    Formula:
      - movav = Sum(data, period) / period

    See also:
      - http://en.wikipedia.org/wiki/Moving_average#Simple_moving_average

    Aliases: SMA, SimpleMovingAverage
    Inputs: close
    Outputs: sma
    Params:
      - period (default: 30)
        Period for the moving average calculation

The output is named as the indicator in this case, sma.

A shorter route to get the output is also possible.

import btalib

print(btalib.sma.outputs)

And the actual outputs are printed

('sma',)

Multi-outuput indicators will simply show more items, like is the case of the stochastic

import btalib

print(btalib.stochastic.outputs)
('k', 'd')

Outputs as pandas.DataFrame

A sure winner for mostly everybody is when getting the results as a DataFrame is easy. And it is.

With a single-output indicator like the sma, with a complete script.

import btalib
import pandas as pd

# Read a csv file into a pandas dataframe
df = pd.read_csv('2006-day-001.txt', parse_dates=True, index_col='Date')
sma = btalib.sma(df, period=4)
print(sma.df)

It has not taken much to get a DataFrame, accessing sma.df has sufficed. The output (shortened) of the print statement

                  sma
Date
2006-01-02        NaN
2006-01-03        NaN
2006-01-04        NaN
2006-01-05  1815.1700
2006-01-06  1823.0050
...               ...
2006-12-21  2057.6475
...

As a single-output indicator, the resulting DataFrame contains just one column named after the output: sma

The same but for a multi-output indicator like the stochastic

import btalib
import pandas as pd

# Read a csv file into a pandas dataframe
df = pd.read_csv('2006-day-001.txt', parse_dates=True, index_col='Date')
stochastic = btalib.stochastic(df)
print(stochastic.df)

With the following result

                    k          d
Date
2006-01-02        NaN        NaN
2006-01-03        NaN        NaN
2006-01-04        NaN        NaN
2006-01-05        NaN        NaN
2006-01-06        NaN        NaN
...               ...        ...
2006-12-21  83.814859  86.781570
...

And the two outputs reported by stochastic above are mapped to the columns in the output DataFrame.

Direct Output as a pandas.DataFrame

In modern times, waiting for something, writing an extra line of code or accessing an attribute to get a DataFrame is not meant to be. Everybody is busy and things have to happen at once.

And yes, ... they can! I.e.: the output can be directly obtained as DataFrame by tweaking the configuration of bta-lib with set_return_dataframe(). An example

import btalib
import pandas as pd

btalib.config.set_return_dataframe()  # force return of a DataFrame

# Read a csv file into a pandas dataframe
df = pd.read_csv('2006-day-001.txt', parse_dates=True, index_col='Date')
print(btalib.stochastic(df))

The code has been compressed to even avoid assigning the result to a variable, because everything has to happen quickly. And the result:

                    k          d
Date
2006-01-02        NaN        NaN
2006-01-03        NaN        NaN
2006-01-04        NaN        NaN
2006-01-05        NaN        NaN
2006-01-06        NaN        NaN
...               ...        ...
2006-12-21  83.814859  86.781570
...

Access to Individual Outputs

If getting the individual columns, without going through a DataFrame is the wish, it can also be achieved.

import btalib
import pandas as pd

# Read a csv file into a pandas dataframe
df = pd.read_csv('2006-day-001.txt', parse_dates=True, index_col='Date')
stochastic = btalib.stochastic(df)

# Get an object to column `k`
stochastic_k = stochastic.k  # alias to: stochastic.outputs.k / stochastic.o.k

Note

stochastic.k is the same as doing stochastic.outputs.k or stochastic.o.k

Done. It should be taken into account that this is still an internal object to the platform, which can be reused to feed it back into an sma for example.

import btalib
import pandas as pd

# Read a csv file into a pandas dataframe
df = pd.read_csv('2006-day-001.txt', parse_dates=True, index_col='Date')
stochastic = btalib.stochastic(df)

# Get an object to column `k`
stochastic_k = stochastic.k  # alias to: stochastic.outputs.k / stochastic.o.k
sma_k = btalib.sma(stochastic_k)

Individual Outputs as pd.Series

Rather than getting an internal object, direct access to the underlying results as a pandas.Series is possible. The notation for the stochastic result above

import btalib
import pandas as pd

# Read a csv file into a pandas dataframe
df = pd.read_csv('2006-day-001.txt', parse_dates=True, index_col='Date')
stochastic = btalib.stochastic(df)

# Get an object to column `k`
stochastic_k_series = stochastic.k.series

It is also possible to invert the notation and do the following.

import btalib
import pandas as pd

# Read a csv file into a pandas dataframe
df = pd.read_csv('2006-day-001.txt', parse_dates=True, index_col='Date')
stochastic = btalib.stochastic(df)

# Get an object to column `k`
stochastic_k_series = stochastic.series.k

Although it may seem pointless to also support the inverted notation, it has one advantage, which is "output unpacking", i.e.: it is possible to recover all inputs as series in a single shot.

import btalib
import pandas as pd

# Read a csv file into a pandas dataframe
df = pd.read_csv('2006-day-001.txt', parse_dates=True, index_col='Date')
stochastic = btalib.stochastic(df)

# Get an object to column `k`
k_series, d_series = stochastic.series

Notice that same is also possible to do output unpacking of the individual outputs for internal objects

import btalib
import pandas as pd

# Read a csv file into a pandas dataframe
df = pd.read_csv('2006-day-001.txt', parse_dates=True, index_col='Date')
stochastic = btalib.stochastic(df)

# Get an object to column `k`
k, d = stochastic

Note

Yes, for both series and the regular objects, the ** keyword arguments unpacking can also be applied, or they can be passed directly for the construction of a dictionary with the output names

my_dict = dict(**stochastic)  # or dict(stochastic)
my_series_dict = dict(**stochastic.series)  # or dict(stochastic.series)