<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 TA-Lib Tutorial
"TA-Lib is widely used by trading software developers requiring to perform technical analysis of financial market data."
We will show how to use them here, in the context of pinkfish.
Step1:  Some global data
Step2:  Fetch symbol data from cache, if available.
Step3:  Select timeseries between start and end.
Step4:  Get info about TA-Lib
Step5:  Here is a complete listing of the functions by group
Step6:  Get info about a specific TA-Lib function
There are 2 different API that are available with talib, namely Function API and Abstract API.  For the Function API, you pass in a price series.  For the Abstract API, you pass in a collection of named inputs
Step7:  More information is available through the 'info' property.  We observe here that the default price used is 'close'.  This can be changed by setting 'price' in the function call, e.g. price='open'.
Step8:  If we just want to see the inputs, we can print the input_names property.
Step9:  If we just want to see the parameters, we can print the paramters property.
Step10:  If we just want to see the outputs, we can print the output_names property.
Step11:  Create a technical indicator using talib
Create technical indicator
Step12:  Create technical indicator
Step13:  Create technical indicator
Step14:  Add a technical indicator to a pinkfish timeseries
Step15:  Try another one
Commodity Channel Index
Step16:  Now for something a little more difficult
Bollinger Bands
Step17:  Print the available moving average types
Step18:  Set timeperiod=20 and matype=MA_Type.EMA
<ASSISTANT_TASK:>
Python Code:
%%javascript
IPython.OutputArea.prototype._should_scroll = function(lines) {
    return false;
}
import datetime
import matplotlib.pyplot as plt
import pandas as pd
import talib
from talib.abstract import *
from talib import MA_Type
import pinkfish as pf
# Format price data
pd.options.display.float_format = '{:0.3f}'.format
%matplotlib inline
# Set size of inline plots
'''note: rcParams can't be in same cell as import matplotlib
   or %matplotlib inline
   
   %matplotlib notebook: will lead to interactive plots embedded within
   the notebook, you can zoom and resize the figure
   
   %matplotlib inline: only draw static images in the notebook
'''
plt.rcParams["figure.figsize"] = (10, 7)
Explanation: TA-Lib Tutorial
"TA-Lib is widely used by trading software developers requiring to perform technical analysis of financial market data."
We will show how to use them here, in the context of pinkfish.
End of explanation
symbol = 'SPY'
start = datetime.datetime(2018, 1, 1)
end = datetime.datetime.now()
Explanation: Some global data
End of explanation
ts = pf.fetch_timeseries(symbol)
ts.tail()
Explanation: Fetch symbol data from cache, if available.
End of explanation
ts = pf.select_tradeperiod(ts, start, end)
ts.head()
Explanation: Select timeseries between start and end.
End of explanation
print('There are {} TA-Lib functions!'.format(len(talib.get_functions())))
Explanation: Get info about TA-Lib
End of explanation
for group, funcs in talib.get_function_groups().items():
    print(group)
    print('-----------------------------------------')
    for func in funcs:
        f = Function(func)
        print('{} - {}'.format(func, f.info['display_name']))
    print()
Explanation: Here is a complete listing of the functions by group:
End of explanation
print(SMA)
Explanation: Get info about a specific TA-Lib function
There are 2 different API that are available with talib, namely Function API and Abstract API.  For the Function API, you pass in a price series.  For the Abstract API, you pass in a collection of named inputs: 'open', 'high', 'low', 'close', and 'volume'.  One or more of these may be used as defaults, but can be changed with the 'price' parameter.  
Print the function instance to get documentation.  We see that SMA has the parameter 'timeperiod' with default '30'.  The input_arrays can be a dataframe with columns named 'open', 'high', 'low', 'close', and 'volume'.
End of explanation
print(SMA.info)
Explanation: More information is available through the 'info' property.  We observe here that the default price used is 'close'.  This can be changed by setting 'price' in the function call, e.g. price='open'.
End of explanation
print(SMA.input_names)
Explanation: If we just want to see the inputs, we can print the input_names property.
End of explanation
print(SMA.parameters)
Explanation: If we just want to see the parameters, we can print the paramters property.
End of explanation
print(SMA.output_names)
Explanation: If we just want to see the outputs, we can print the output_names property.
End of explanation
sma = SMA(ts)
sma.tail()
Explanation: Create a technical indicator using talib
Create technical indicator: SMA (using defaults: timeperiod=30, price='close')
End of explanation
sma200 = SMA(ts, timeperiod=200)
sma200.tail()
Explanation: Create technical indicator: SMA (using: timeperiod=200, price='close')
End of explanation
sma200 = SMA(ts, timeperiod=200, price='open')
sma200.tail()
Explanation: Create technical indicator: SMA (using: timeperiod=200, price='open')
End of explanation
ts['sma200'] = sma200
ts.tail()
Explanation: Add a technical indicator to a pinkfish timeseries
End of explanation
print(CCI)
print(CCI.input_names)
print(CCI.parameters)
cci = CCI(ts)
ts['cci'] = cci
ts.tail()
Explanation: Try another one
Commodity Channel Index
End of explanation
print(BBANDS)
print(BBANDS.input_names)
print(BBANDS.parameters)
Explanation: Now for something a little more difficult
Bollinger Bands
End of explanation
attributes = [attr for attr in dir(MA_Type) 
              if not attr.startswith('__')]
attributes
MA_Type.__dict__
print(MA_Type[MA_Type.DEMA])
Explanation: Print the available moving average types
End of explanation
#upper, middle, lower = BBANDS(ts, timeperiod=20, matype=MA_Type.EMA)
#(for some reason, the abstract API doesn't work for BBANDS, so use the function API)
upper, middle, lower = talib.BBANDS(ts.close, timeperiod=20, matype=MA_Type.EMA)
ts['upper'] = upper; ts['middle'] = middle; ts['lower'] = lower
ts.tail()
print(MOM)
mom10 = MOM(ts, timeperiod=10)
mom10.tail()
ts['mom10'] = mom10
ts.head(50)
m1 = ts['close'].pct_change(periods=10)
ts['m1'] = m1
ts.head(50)
Explanation: Set timeperiod=20 and matype=MA_Type.EMA
End of explanation
<END_TASK>