%%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
"""


