Files
pandas-ta/examples/PandasTA_Study_Examples.ipynb
T

232 KiB
Raw Blame History

Pandas TA (pandas_ta) Studies for Custom Technical Analysis

Topics

  • What is a Pandas TA Study?
    • Builtin Studies: AllStudy and CommonStudy
    • Creating Studies
  • Watchlist Class
    • Study Management and Execution
    • NOTE: The watchlist module is independent of Pandas TA. To easily use it, copy it from your local pandas_ta installation directory into your project directory.
  • Indicator Composition/Chaining for more Complex Studies
    • Comprehensive Example: MACD and RSI Momo with BBANDS and SMAs 50 & 200 and Cumulative Log Returns
In [1]:
%matplotlib inline
import datetime as dt

from tqdm import tqdm

import pandas as pd
import pandas_ta as ta
from alphaVantageAPI.alphavantage import AlphaVantage  # pip install alphaVantage-api

from watchlist import Watchlist # Is this failing? If so, copy it locally. See above.

print(f"\nPandas TA v{ta.version}\nTo install the Latest Version:\n$ pip install -U git+https://github.com/twopirllc/pandas-ta\n")
%pylab inline
Pandas TA v0.3.54b0
To install the Latest Version:
$ pip install -U git+https://github.com/twopirllc/pandas-ta

Populating the interactive namespace from numpy and matplotlib

What is a Pandas TA Study?

A Study is a simple way to name and group TA indicators. Technically, a Study is a simple Data Class to contain list of indicators and their parameters. Note: Study is experimental and subject to change. Pandas TA comes with two basic Studies: AllStudy and CommonStudy.

Study Requirements:

  • name: Some short memorable string. Note: Case-insensitive "All" is reserved.
  • ta: A list of dicts containing keyword arguments to identify the indicator and the indicator's arguments

Optional Requirements:

  • description: A more detailed description of what the Study tries to capture. Default: None
  • created: At datetime string of when it was created. Default: Automatically generated.

Things to note:

  • A Study will fail when consumed by Pandas TA if there is no {"kind": "indicator name"} attribute.

Builtin Examples

All

Default Values

In [2]:
AllStudy = ta.AllStudy
print(f"{AllStudy.name = }")
print(f"{AllStudy.description = }")
print(f"{AllStudy.created = }")
print(f"{AllStudy.ta = }")
print(f"{AllStudy.cores = }")
AllStudy.name = 'All'
AllStudy.description = 'All the indicators with their default settings. Pandas TA default.'
AllStudy.created = 'Friday March 4, 2022, NYSE: 4:10:37, Local: 8:10:37 PST, Day 63/365 (17.00%)'
AllStudy.ta = None
AllStudy.cores = 8

Common

Default Values

In [3]:
CommonStudy = ta.CommonStudy
print(f"{CommonStudy.name = }")
print(f"{CommonStudy.description = }")
print(f"{CommonStudy.created = }")
print(f"{CommonStudy.ta = }")
print(f"{CommonStudy.cores = }")
CommonStudy.name = 'Common Price and Volume SMAs'
CommonStudy.description = 'Common Price SMAs: 10, 20, 50, 200 and Volume SMA: 20.'
CommonStudy.created = 'Friday March 4, 2022, NYSE: 4:10:37, Local: 8:10:37 PST, Day 63/365 (17.00%)'
CommonStudy.ta = [{'kind': 'sma', 'length': 10}, {'kind': 'sma', 'length': 20}, {'kind': 'sma', 'length': 50}, {'kind': 'sma', 'length': 200}, {'kind': 'sma', 'close': 'volume', 'length': 20, 'prefix': 'VOL'}]
CommonStudy.cores = 0
In [ ]:

Creating Studies

Studies require a name and an array of dicts containing the "kind" of indicator ("sma") and other potential parameters for ta.

Simple Study A

In [4]:
custom_a = ta.Study(name="A", cores=0, ta=[{"kind": "sma", "length": 50}, {"kind": "sma", "length": 200}])
custom_a
Out [4]:
Study(name='A', ta=[{'kind': 'sma', 'length': 50}, {'kind': 'sma', 'length': 200}], cores=0, description='', created='Friday March 4, 2022, NYSE: 4:10:37, Local: 8:10:37 PST, Day 63/365 (17.00%)')

Simple Study B

In [5]:
custom_b = ta.Study(name="B", cores=0, ta=[{"kind": "ema", "length": 8}, {"kind": "ema", "length": 21}, {"kind": "log_return", "cumulative": True}, {"kind": "rsi"}, {"kind": "supertrend"}])
custom_b
Out [5]:
Study(name='B', ta=[{'kind': 'ema', 'length': 8}, {'kind': 'ema', 'length': 21}, {'kind': 'log_return', 'cumulative': True}, {'kind': 'rsi'}, {'kind': 'supertrend'}], cores=0, description='', created='Friday March 4, 2022, NYSE: 4:10:37, Local: 8:10:37 PST, Day 63/365 (17.00%)')

Bad Study. (Misspelled Indicator)

In [6]:
# Misspelled indicator, will fail later when ran with Pandas TA
custom_run_failure = ta.Study(name="Runtime Failure", cores=0, ta=[{"kind": "peret_return"}])
custom_run_failure
Out [6]:
Study(name='Runtime Failure', ta=[{'kind': 'peret_return'}], cores=0, description='', created='Friday March 4, 2022, NYSE: 4:10:37, Local: 8:10:37 PST, Day 63/365 (17.00%)')
In [ ]:

Study Management and Execution with Watchlist

Initialize AlphaVantage Data Source

In [7]:
AV = AlphaVantage(
    api_key="YOUR API KEY", premium=False,
    output_size='full', clean=True,
    export_path=".", export=True
)
AV
Out [7]:
AlphaVantage(
  end_point:str = https://www.alphavantage.co/query,
  api_key:str = YOUR API KEY,
  export:bool = True,
  export_path:str = .,
  output_size:str = full,
  output:str = csv,
  datatype:str = json,
  clean:bool = True,
  proxy:dict = {}
)

Create Watchlist and set it's 'ds' to AlphaVantage

In [8]:
data_source = "av" # Default
data_source = "yahoo"
watch = Watchlist(["SPY", "IWM"], ds_name=data_source, timed=True)

Info about the Watchlist. Note, the default Study is "All"

In [9]:
watch
Out [9]:
Watch(name='Watch: SPY, IWM', ds_name='yahoo', tickers[2]='SPY, IWM', tf='D', study[5]='Common Price and Volume SMAs')

Help about Watchlist

In [10]:
help(Watchlist)
Help on class Watchlist in module watchlist:

class Watchlist(builtins.object)
 |  Watchlist(tickers: list, tf: str = None, name: str = None, study: pandas_ta.utils._study.Study = None, ds_name: str = 'av', **kwargs)
 |  
 |  # Watchlist Class (** This is subject to change! **)
 |  A simple Class to load/download financial market data and automatically
 |  apply Technical Analysis indicators with a Pandas TA Study.
 |  
 |  Default Study: pandas_ta.CommonStudy
 |  
 |  ## Package Support:
 |  ### Data Source (Default: AlphaVantage)
 |  - AlphaVantage (pip install alphaVantage-api).
 |  - Python Binance (pip install python-binance). # Future Support
 |  - Yahoo Finance (pip install yfinance). # Almost Supported
 |  
 |  # Technical Analysis:
 |  - Pandas TA (pip install pandas_ta)
 |  
 |  ## Required Arguments:
 |  - tickers: A list of strings containing tickers. Example: ["SPY", "AAPL"]
 |  
 |  Methods defined here:
 |  
 |  __init__(self, tickers: list, tf: str = None, name: str = None, study: pandas_ta.utils._study.Study = None, ds_name: str = 'av', **kwargs)
 |      Initialize self.  See help(type(self)) for accurate signature.
 |  
 |  __repr__(self) -> str
 |      Return repr(self).
 |  
 |  indicators(self, *args, **kwargs) -> <built-in function any>
 |      Returns the list of indicators that are available with Pandas Ta.
 |  
 |  load(self, ticker: str = None, tf: str = None, index: str = 'date', drop: list = [], plot: bool = False, **kwargs) -> pandas.core.frame.DataFrame
 |      Loads or Downloads (if a local csv does not exist) the data from the
 |      Data Source. When successful, it returns a Data Frame for the requested
 |      ticker. If no tickers are given, it loads all the tickers.
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |  
 |  __dict__
 |      dictionary for instance variables (if defined)
 |  
 |  __weakref__
 |      list of weak references to the object (if defined)
 |  
 |  data
 |      When not None, it contains a dictionary of DataFrames keyed by ticker. data = {"SPY": pd.DataFrame, ...}
 |  
 |  name
 |      The name of the Watchlist. Default: "Watchlist: {Watchlist.tickers}".
 |  
 |  strategy
 |      Sets a valid Strategy. Default: pandas_ta.CommonStrategy
 |  
 |  study
 |      Sets a valid Study. Default: pandas_ta.CommonStudy
 |  
 |  tf
 |      Alias for timeframe. Default: 'D'
 |  
 |  tickers
 |      tickers
 |      
 |      If a string, it it converted to a list. Example: "AAPL" -> ["AAPL"]
 |          * Does not accept, comma seperated strings.
 |      If a list, checks if it is a list of strings.
 |  
 |  verbose
 |      Toggle the verbose property. Default: False

Default Study is "Common"

In [11]:
# No arguments loads all the tickers and applies the Study to each ticker.
# The result can be accessed with Watchlist's 'data' property which returns a 
# dictionary keyed by ticker and DataFrames as values 
watch.load(verbose=True)
[!] Loading All: SPY, IWM
[+] Downloading[yahoo]: SPY[D]
[+] yf | SPY(7328, 7): 3410.8553 ms (3.4109 s)
[+] Saving: /Users/kj/av_data/SPY_D.csv
[+] Study: Common Price and Volume SMAs
[i] Indicator arguments: {'timed': True, 'append': True}
[i] No mulitproccessing (cores = 0).
[i] Progress: 100%|███████████████████████████████████████████████| 5/5 [00:00<00:00, 118.73it/s]
[i] Total indicators: 5
[i] Columns added: 5
[i] Last Run: Friday March 4, 2022, NYSE: 4:10:40, Local: 8:10:40 PST, Day 63/365 (17.00%)
[i] Analysis Time: 59.7448 ms (0.0597 s) for 5 columns (avg 11.9521 ms / col).
[+] Downloading[yahoo]: IWM[D]
[+] yf | IWM(5478, 7): 3192.7451 ms (3.1927 s)
[+] Saving: /Users/kj/av_data/IWM_D.csv
[+] Study: Common Price and Volume SMAs
[i] Indicator arguments: {'timed': True, 'append': True}
[i] No mulitproccessing (cores = 0).
[i] Progress: 100%|██████████████████████████████████████████████| 5/5 [00:00<00:00, 1062.44it/s]
[i] Total indicators: 5
[i] Columns added: 5
[i] Last Run: Friday March 4, 2022, NYSE: 4:10:44, Local: 8:10:44 PST, Day 63/365 (17.00%)
[i] Analysis Time: 6.1147 ms (0.0061 s) for 5 columns (avg 1.2238 ms / col).
In [12]:
", ".join([f"{t}: {d.shape}" for t,d in watch.data.items()])
Out [12]:
'SPY: (7328, 12), IWM: (5478, 12)'
In [13]:
watch.data["SPY"]
Out [13]:
Open High Low Close Volume Dividends Stock Splits SMA_10 SMA_20 SMA_50 SMA_200 VOL_SMA_20
Date
1993-01-29 25.645575 25.645575 25.517985 25.627348 1003200 0.0 0 NaN NaN NaN NaN NaN
1993-02-01 25.645572 25.809616 25.645572 25.809616 480500 0.0 0 NaN NaN NaN NaN NaN
1993-02-02 25.791401 25.882536 25.736719 25.864309 201300 0.0 0 NaN NaN NaN NaN NaN
1993-02-03 25.900760 26.155940 25.882533 26.137712 529400 0.0 0 NaN NaN NaN NaN NaN
1993-02-04 26.228843 26.301752 25.937209 26.247070 531500 0.0 0 NaN NaN NaN NaN NaN
... ... ... ... ... ... ... ... ... ... ... ... ...
2022-02-28 432.029999 438.200012 430.700012 436.630005 145347600 0.0 0 435.721002 442.912004 453.780742 443.186750 122484490.0
2022-03-01 435.040009 437.170013 427.109985 429.980011 137785900 0.0 0 434.817004 441.915504 453.084002 443.274417 121761215.0
2022-03-02 432.369995 439.720001 431.570007 437.890015 117726500 0.0 0 433.996005 441.162505 452.644402 443.406882 121489770.0
2022-03-03 440.470001 441.109985 433.799988 435.709991 104097600 0.0 0 432.907004 440.080504 452.259002 443.546169 120826600.0
2022-03-04 431.750000 432.489990 428.109985 428.225006 35680916 0.0 0 432.023505 439.161754 451.562302 443.653377 116709425.8

7328 rows × 12 columns

In [ ]:
In [14]:
watch.load("SPY", plot=True, mas=True)
Out [14]:
[i] Loaded SPY[D]: SPY_D.csv
[i] Analysis Time: 3.4316 ms (0.0034 s) for 5 columns (avg 0.6878 ms / col).
Open High Low Close Volume Dividends Stock Splits SMA_10 SMA_20 SMA_50 SMA_200 VOL_SMA_20
Date
1993-01-29 25.645575 25.645575 25.517985 25.627348 1003200 0.0 0 NaN NaN NaN NaN NaN
1993-02-01 25.645572 25.809616 25.645572 25.809616 480500 0.0 0 NaN NaN NaN NaN NaN
1993-02-02 25.791401 25.882536 25.736719 25.864309 201300 0.0 0 NaN NaN NaN NaN NaN
1993-02-03 25.900760 26.155940 25.882533 26.137712 529400 0.0 0 NaN NaN NaN NaN NaN
1993-02-04 26.228843 26.301752 25.937209 26.247070 531500 0.0 0 NaN NaN NaN NaN NaN
... ... ... ... ... ... ... ... ... ... ... ... ...
2022-02-28 432.029999 438.200012 430.700012 436.630005 145347600 0.0 0 435.721002 442.912004 453.780742 443.186750 122484490.0
2022-03-01 435.040009 437.170013 427.109985 429.980011 137785900 0.0 0 434.817004 441.915504 453.084002 443.274417 121761215.0
2022-03-02 432.369995 439.720001 431.570007 437.890015 117726500 0.0 0 433.996005 441.162505 452.644402 443.406882 121489770.0
2022-03-03 440.470001 441.109985 433.799988 435.709991 104097600 0.0 0 432.907004 440.080504 452.259002 443.546169 120826600.0
2022-03-04 431.750000 432.489990 428.109985 428.225006 35680916 0.0 0 432.023505 439.161754 451.562302 443.653377 116709425.8

7328 rows × 12 columns

In [ ]:

Easy to swap Studies and run them

Running Simple Study A

In [15]:
# Load custom_a into Watchlist and verify
watch.study = custom_a
watch.study
Out [15]:
Study(name='A', ta=[{'kind': 'sma', 'length': 50}, {'kind': 'sma', 'length': 200}], cores=0, description='', created='Friday March 4, 2022, NYSE: 4:10:37, Local: 8:10:37 PST, Day 63/365 (17.00%)')
In [16]:
watch.load("IWM")
Out [16]:
[i] Loaded IWM[D]: IWM_D.csv
[i] Analysis Time: 1.9032 ms (0.0019 s) for 2 columns (avg 0.9548 ms / col).
Open High Low Close Volume Dividends Stock Splits SMA_50 SMA_200
Date
2000-05-26 34.332574 34.473957 34.167627 34.473957 74800 0.0 0.0 NaN NaN
2000-05-30 34.968799 35.746407 34.968799 35.746407 57600 0.0 0.0 NaN NaN
2000-05-31 35.864237 36.335514 35.864237 35.876019 36000 0.0 0.0 NaN NaN
2000-06-01 36.612390 36.688972 36.612390 36.688972 7000 0.0 0.0 NaN NaN
2000-06-02 38.350220 38.597641 38.350220 38.597641 29400 0.0 0.0 NaN NaN
... ... ... ... ... ... ... ... ... ...
2022-02-28 200.470001 204.600006 200.460007 203.320007 34893800 0.0 0.0 208.233600 219.773493
2022-03-01 202.660004 203.789993 197.800003 199.490005 40638900 0.0 0.0 207.959800 219.674165
2022-03-02 200.839996 205.300003 200.690002 204.240005 29978600 0.0 0.0 207.741800 219.597099
2022-03-03 205.089996 205.110001 200.289993 201.820007 29828500 0.0 0.0 207.535800 219.516269
2022-03-04 199.699997 200.860001 197.320007 197.380005 10547256 0.0 0.0 207.119801 219.421625

5478 rows × 9 columns

Running Simple Study B

In [17]:
# Load custom_b into Watchlist and verify
watch.study = custom_b
watch.study
Out [17]:
Study(name='B', ta=[{'kind': 'ema', 'length': 8}, {'kind': 'ema', 'length': 21}, {'kind': 'log_return', 'cumulative': True}, {'kind': 'rsi'}, {'kind': 'supertrend'}], cores=0, description='', created='Friday March 4, 2022, NYSE: 4:10:37, Local: 8:10:37 PST, Day 63/365 (17.00%)')
In [18]:
watch.load("IWM")
Out [18]:
[i] Loaded IWM[D]: IWM_D.csv
[i] Analysis Time: 262.2929 ms (0.2623 s) for 8 columns (avg 32.7873 ms / col).
Open High Low Close Volume Dividends Stock Splits EMA_8 EMA_21 CUMLOGRET_1 RSI_14 SUPERT_7_3.0 SUPERTd_7_3.0 SUPERTl_7_3.0 SUPERTs_7_3.0
Date
2000-05-26 34.332574 34.473957 34.167627 34.473957 74800 0.0 0.0 NaN NaN 0.000000 NaN 0.000000 1 NaN NaN
2000-05-30 34.968799 35.746407 34.968799 35.746407 57600 0.0 0.0 NaN NaN 0.036246 NaN NaN 1 NaN NaN
2000-05-31 35.864237 36.335514 35.864237 35.876019 36000 0.0 0.0 NaN NaN 0.039865 NaN NaN 1 NaN NaN
2000-06-01 36.612390 36.688972 36.612390 36.688972 7000 0.0 0.0 NaN NaN 0.062272 NaN NaN 1 NaN NaN
2000-06-02 38.350220 38.597641 38.350220 38.597641 29400 0.0 0.0 NaN NaN 0.112987 NaN NaN 1 NaN NaN
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
2022-02-28 200.470001 204.600006 200.460007 203.320007 34893800 0.0 0.0 200.524146 201.740315 1.774577 50.680772 211.164767 -1 NaN 211.164767
2022-03-01 202.660004 203.789993 197.800003 199.490005 40638900 0.0 0.0 200.294337 201.535742 1.755560 46.117134 211.164767 -1 NaN 211.164767
2022-03-02 200.839996 205.300003 200.690002 204.240005 29978600 0.0 0.0 201.171152 201.781584 1.779092 51.901774 211.164767 -1 NaN 211.164767
2022-03-03 205.089996 205.110001 200.289993 201.820007 29828500 0.0 0.0 201.315342 201.785077 1.767172 49.014699 211.164767 -1 NaN 211.164767
2022-03-04 199.699997 200.860001 197.320007 197.380005 10547256 0.0 0.0 200.440823 201.384616 1.744927 44.161052 211.164767 -1 NaN 211.164767

5478 rows × 15 columns

Running Bad Study. (Misspelled indicator)

In [19]:
# Load custom_run_failure into Watchlist and verify
watch.study = custom_run_failure
watch.study
Out [19]:
Study(name='Runtime Failure', ta=[{'kind': 'peret_return'}], cores=0, description='', created='Friday March 4, 2022, NYSE: 4:10:37, Local: 8:10:37 PST, Day 63/365 (17.00%)')
In [20]:
try:
    iwm = watch.load("IWM")
except AttributeError as error:
    print(f"[X] Oops! {error}")
[i] Loaded IWM[D]: IWM_D.csv
[X] Oops! 'AnalysisIndicators' object has no attribute 'peret_return'
In [ ]:

Indicator Composition/Chaining

  • When you need an indicator to depend on the value of a prior indicator
  • Utilitze prefix or suffix to help identify unique columns or avoid column name clashes.
  • Set cores=0 for better performance when few indicators

Volume MAs and MA chains

In [21]:
# Set EMA's and SMA's 'close' to 'volume' to create Volume MAs, prefix 'volume' MAs with 'VOLUME' so easy to identify the column
# Take a price EMA and apply LINREG from EMA's output
volmas_price_ma_chain = [
    {"kind":"ema", "close": "volume", "length": 10, "prefix": "VOLUME"},
    {"kind":"sma", "close": "volume", "length": 20, "prefix": "VOLUME"},
    {"kind":"ema", "length": 5},
    {"kind":"linreg", "close": "EMA_5", "length": 8, "prefix": "EMA_5"},
]
vp_ma_chain_ta = ta.Study("Volume MAs and Price MA chain", cores=0, ta=volmas_price_ma_chain)
vp_ma_chain_ta
Out [21]:
Study(name='Volume MAs and Price MA chain', ta=[{'kind': 'ema', 'close': 'volume', 'length': 10, 'prefix': 'VOLUME'}, {'kind': 'sma', 'close': 'volume', 'length': 20, 'prefix': 'VOLUME'}, {'kind': 'ema', 'length': 5}, {'kind': 'linreg', 'close': 'EMA_5', 'length': 8, 'prefix': 'EMA_5'}], cores=0, description='', created='Friday March 4, 2022, NYSE: 4:10:37, Local: 8:10:37 PST, Day 63/365 (17.00%)')
In [22]:
# Update the Watchlist
watch.study = vp_ma_chain_ta
watch.study.name
Out [22]:
'Volume MAs and Price MA chain'
In [23]:
spy = watch.load("SPY")
spy
Out [23]:
[i] Loaded SPY[D]: SPY_D.csv
[i] Analysis Time: 2.4727 ms (0.0025 s) for 4 columns (avg 0.6194 ms / col).
Open High Low Close Volume Dividends Stock Splits VOLUME_EMA_10 VOLUME_SMA_20 EMA_5 EMA_5_LR_8
Date
1993-01-29 25.645575 25.645575 25.517985 25.627348 1003200 0.0 0 NaN NaN NaN NaN
1993-02-01 25.645572 25.809616 25.645572 25.809616 480500 0.0 0 NaN NaN NaN NaN
1993-02-02 25.791401 25.882536 25.736719 25.864309 201300 0.0 0 NaN NaN NaN NaN
1993-02-03 25.900760 26.155940 25.882533 26.137712 529400 0.0 0 NaN NaN NaN NaN
1993-02-04 26.228843 26.301752 25.937209 26.247070 531500 0.0 0 NaN NaN 25.937211 NaN
... ... ... ... ... ... ... ... ... ... ... ...
2022-02-28 432.029999 438.200012 430.700012 436.630005 145347600 0.0 0 1.357540e+08 122484490.0 434.164598 429.983874
2022-03-01 435.040009 437.170013 427.109985 429.980011 137785900 0.0 0 1.361234e+08 121761215.0 432.769736 430.541195
2022-03-02 432.369995 439.720001 431.570007 437.890015 117726500 0.0 0 1.327785e+08 121489770.0 434.476496 432.167188
2022-03-03 440.470001 441.109985 433.799988 435.709991 104097600 0.0 0 1.275638e+08 120826600.0 434.887661 433.943960
2022-03-04 431.750000 432.489990 428.109985 428.225006 35680916 0.0 0 1.108578e+08 116709425.8 432.666776 434.352225

7328 rows × 11 columns

In [ ]:

MACD BBANDS

In [24]:
# MACD is the initial indicator that BBANDS depends on.
# Set BBANDS's 'close' to MACD's main signal, in this case 'MACD_12_26_9' and add a prefix (or suffix) so it's easier to identify
macd_bands_ta = [
    {"kind":"macd"},
    {"kind":"bbands", "close": "MACD_12_26_9", "length": 20, "ddof": 0, "prefix": "MACD"}
]
macd_bands_ta = ta.Study("MACD BBands", cores=0, ta=macd_bands_ta, description=f"BBANDS_{macd_bands_ta[1]['length']} applied to MACD")
macd_bands_ta
Out [24]:
Study(name='MACD BBands', ta=[{'kind': 'macd'}, {'kind': 'bbands', 'close': 'MACD_12_26_9', 'length': 20, 'ddof': 0, 'prefix': 'MACD'}], cores=0, description='BBANDS_20 applied to MACD', created='Friday March 4, 2022, NYSE: 4:10:37, Local: 8:10:37 PST, Day 63/365 (17.00%)')
In [25]:
# Update the Watchlist
watch.study = macd_bands_ta
watch.study.name
Out [25]:
'MACD BBands'
In [26]:
spy = watch.load("SPY")
spy
Out [26]:
[i] Loaded SPY[D]: SPY_D.csv
[i] Analysis Time: 5.5015 ms (0.0055 s) for 8 columns (avg 0.6883 ms / col).
Open High Low Close Volume Dividends Stock Splits MACD_12_26_9 MACDh_12_26_9 MACDs_12_26_9 MACD_BBL_20_2.0 MACD_BBM_20_2.0 MACD_BBU_20_2.0 MACD_BBB_20_2.0 MACD_BBP_20_2.0
Date
1993-01-29 25.645575 25.645575 25.517985 25.627348 1003200 0.0 0 NaN NaN NaN NaN NaN NaN NaN NaN
1993-02-01 25.645572 25.809616 25.645572 25.809616 480500 0.0 0 NaN NaN NaN NaN NaN NaN NaN NaN
1993-02-02 25.791401 25.882536 25.736719 25.864309 201300 0.0 0 NaN NaN NaN NaN NaN NaN NaN NaN
1993-02-03 25.900760 26.155940 25.882533 26.137712 529400 0.0 0 NaN NaN NaN NaN NaN NaN NaN NaN
1993-02-04 26.228843 26.301752 25.937209 26.247070 531500 0.0 0 NaN NaN NaN NaN NaN NaN NaN NaN
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
2022-02-28 432.029999 438.200012 430.700012 436.630005 145347600 0.0 0 -5.750580 -0.393816 -5.356764 -7.436681 -4.708023 -1.979365 -115.915231 0.308962
2022-03-01 435.040009 437.170013 427.109985 429.980011 137785900 0.0 0 -5.882783 -0.420815 -5.461968 -7.123321 -4.630572 -2.137823 -107.664858 0.248829
2022-03-02 432.369995 439.720001 431.570007 437.890015 117726500 0.0 0 -5.288323 0.138916 -5.427239 -6.963301 -4.577189 -2.191078 -104.260969 0.350985
2022-03-03 440.470001 441.109985 433.799988 435.709991 104097600 0.0 0 -4.936218 0.392817 -5.329035 -6.949968 -4.569517 -2.189067 -104.188276 0.422977
2022-03-04 431.750000 432.489990 428.109985 428.225006 35680916 0.0 0 -5.201191 0.102275 -5.303466 -6.977203 -4.584723 -2.192242 -104.367512 0.371165

7328 rows × 15 columns

In [ ]:

Comprehensive Study

MACD and RSI Momentum with BBANDS and SMAs and Cumulative Log Returns

In [27]:
momo_bands_sma_ta = [
    {"kind":"sma", "length": 50},
    {"kind":"sma", "length": 200},
    {"kind":"bbands", "length": 20, "ddof": 0},
    {"kind":"macd"},
    {"kind":"rsi"},
    {"kind":"log_return", "cumulative": True},
    {"kind":"sma", "close": "CUMLOGRET_1", "length": 5, "suffix": "CUMLOGRET"},
]
momo_bands_sma_Study = ta.Study(
    name="Momo, Bands and SMAs and Cumulative Log Returns", # name
    ta=momo_bands_sma_ta, # ta
    description="MACD and RSI Momo with BBANDS and SMAs 50 & 200 and Cumulative Log Returns", # description
    cores=0
)
momo_bands_sma_Study
Out [27]:
Study(name='Momo, Bands and SMAs and Cumulative Log Returns', ta=[{'kind': 'sma', 'length': 50}, {'kind': 'sma', 'length': 200}, {'kind': 'bbands', 'length': 20, 'ddof': 0}, {'kind': 'macd'}, {'kind': 'rsi'}, {'kind': 'log_return', 'cumulative': True}, {'kind': 'sma', 'close': 'CUMLOGRET_1', 'length': 5, 'suffix': 'CUMLOGRET'}], cores=0, description='MACD and RSI Momo with BBANDS and SMAs 50 & 200 and Cumulative Log Returns', created='Friday March 4, 2022, NYSE: 4:10:37, Local: 8:10:37 PST, Day 63/365 (17.00%)')
In [28]:
# Update the Watchlist
watch.study = momo_bands_sma_Study
watch.study.name
Out [28]:
'Momo, Bands and SMAs and Cumulative Log Returns'
In [29]:
spy = watch.load("SPY")
# Apply constants to the DataFrame for indicators
spy.ta.constants(True, [0, 30, 70])
spy.tail()
Out [29]:
[i] Loaded SPY[D]: SPY_D.csv
[i] Analysis Time: 6.8512 ms (0.0069 s) for 13 columns (avg 0.5275 ms / col).
Open High Low Close Volume Dividends Stock Splits SMA_50 SMA_200 BBL_20_2.0 ... BBP_20_2.0 MACD_12_26_9 MACDh_12_26_9 MACDs_12_26_9 RSI_14 CUMLOGRET_1 SMA_5_CUMLOGRET 0 30 70
Date
2022-02-28 432.029999 438.200012 430.700012 436.630005 145347600 0.0 0 453.780742 443.186750 423.963287 ... 0.334237 -5.750580 -0.393816 -5.356764 45.161043 2.835426 2.821986 0 30 70
2022-03-01 435.040009 437.170013 427.109985 429.980011 137785900 0.0 0 453.084002 443.274417 422.454396 ... 0.193350 -5.882783 -0.420815 -5.461968 41.057957 2.820079 2.822177 0 30 70
2022-03-02 432.369995 439.720001 431.570007 437.890015 117726500 0.0 0 452.644402 443.406882 422.311628 ... 0.413201 -5.288323 0.138916 -5.427239 47.202634 2.838308 2.829593 0 30 70
2022-03-03 440.470001 441.109985 433.799988 435.709991 104097600 0.0 0 452.259002 443.546169 422.638842 ... 0.374711 -4.936218 0.392817 -5.329035 45.785943 2.833317 2.833023 0 30 70
2022-03-04 431.750000 432.489990 428.109985 428.225006 35680916 0.0 0 451.562302 443.653377 421.260777 ... 0.194521 -5.201191 0.102275 -5.303466 41.212414 2.815989 2.828624 0 30 70

5 rows × 23 columns

In [ ]:

Additional Study Options

The params keyword takes a tuple as a shorthand to the parameter arguments in order.

  • Note: If the indicator arguments change, so will results. Breaking Changes will always be posted on the README.

The col_numbers keyword takes a tuple specifying which column to return if the result is a DataFrame.

In [30]:
params_ta = [
    {"kind":"ema", "params": (10,)},
    # params sets MACD's keyword arguments: fast=9, slow=19, signal=10
    # and returning the 2nd column: histogram
    {"kind":"macd", "params": (9, 19, 10), "col_numbers": (1,)},
    # Selects the Lower and Upper Bands and renames them LB and UB, ignoring the MB
    {"kind":"bbands", "col_numbers": (0,2), "col_names": ("LB", "UB")},
    {"kind":"log_return", "params": (5, False)},
]
params_ta_Study = ta.Study(
    name="EMA, MACD History, Outter BBands, Log Returns", # name
    ta=params_ta, # ta
    description="EMA, MACD History, BBands(LB, UB), and Log Returns Study", # description
    cores=0
)
params_ta_Study
Out [30]:
Study(name='EMA, MACD History, Outter BBands, Log Returns', ta=[{'kind': 'ema', 'params': (10,)}, {'kind': 'macd', 'params': (9, 19, 10), 'col_numbers': (1,)}, {'kind': 'bbands', 'col_numbers': (0, 2), 'col_names': ('LB', 'UB')}, {'kind': 'log_return', 'params': (5, False)}], cores=0, description='EMA, MACD History, BBands(LB, UB), and Log Returns Study', created='Friday March 4, 2022, NYSE: 4:10:37, Local: 8:10:37 PST, Day 63/365 (17.00%)')
In [31]:
# Update the Watchlist
watch.study = params_ta_Study
watch.study.name
Out [31]:
'EMA, MACD History, Outter BBands, Log Returns'
In [32]:
spy = watch.load("SPY")
spy.tail()
Out [32]:
[i] Loaded SPY[D]: SPY_D.csv
[i] Analysis Time: 5.4602 ms (0.0055 s) for 5 columns (avg 1.0929 ms / col).
Open High Low Close Volume Dividends Stock Splits EMA_10 MACDh_9_19_10 LB UB LOGRET_5
Date
2022-02-28 432.029999 438.200012 430.700012 436.630005 145347600 0.0 0 436.035275 -0.201140 419.234187 442.445818 0.005512
2022-03-01 435.040009 437.170013 427.109985 429.980011 137785900 0.0 0 434.934318 -0.253662 419.347488 442.496519 0.000954
2022-03-02 432.369995 439.720001 431.570007 437.890015 117726500 0.0 0 435.471717 0.450856 425.878280 442.341727 0.037081
2022-03-03 440.470001 441.109985 433.799988 435.709991 104097600 0.0 0 435.515040 0.726757 429.759432 441.424577 0.017153
2022-03-04 431.750000 432.489990 428.109985 428.225006 35680916 0.0 0 434.189579 0.294918 425.993151 441.380860 -0.021999
In [ ]:

Disclaimer

  • All investments involve risk, and the past performance of a security, industry, sector, market, financial product, trading Study, or individuals trading does not guarantee future results or returns. Investors are fully responsible for any investment decisions they make. Such decisions should be based solely on an evaluation of their financial circumstances, investment objectives, risk tolerance, and liquidity needs.

  • Any opinions, news, research, analyses, prices, or other information offered is provided as general market commentary, and does not constitute investment advice. I will not accept liability for any loss or damage, including without limitation any loss of profit, which may arise directly or indirectly from use of or reliance on such information.