Files
pandas-ta/examples/PandasTA_Strategy_Examples.ipynb
T

210 KiB
Raw Blame History

Pandas TA (pandas_ta) Strategies for Custom Technical Analysis

Topics

  • What is a Pandas TA Strategy?
    • Builtin Strategies: AllStrategy and CommonStrategy
    • Creating Strategies
  • Watchlist Class
    • Strategy 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 Strategies
    • 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.17b0
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 Strategy?

A Strategy is a simple way to name and group your favorite TA indicators. Technically, a Strategy is a simple Data Class to contain list of indicators and their parameters. Note: Strategy is experimental and subject to change. Pandas TA comes with two basic Strategies: AllStrategy and CommonStrategy.

Strategy 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 Strategy tries to capture. Default: None
  • created: At datetime string of when it was created. Default: Automatically generated.

Things to note:

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

Builtin Examples

All

Default Values

In [2]:
AllStrategy = ta.AllStrategy
print("name =", AllStrategy.name)
print("description =", AllStrategy.description)
print("created =", AllStrategy.created)
print("ta =", AllStrategy.ta)
name = All
description = All the indicators with their default settings. Pandas TA default.
created = Wednesday August 4, 2021, NYSE: 9:51:45, Local: 13:51:45 PDT, Day 216/365 (59.00%)
ta = None

Common

Default Values

In [3]:
CommonStrategy = ta.CommonStrategy
print("name =", CommonStrategy.name)
print("description =", CommonStrategy.description)
print("created =", CommonStrategy.created)
print("ta =", CommonStrategy.ta)
name = Common Price and Volume SMAs
description = Common Price SMAs: 10, 20, 50, 200 and Volume SMA: 20.
created = Wednesday August 4, 2021, NYSE: 9:51:45, Local: 13:51:45 PDT, Day 216/365 (59.00%)
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'}]
In [ ]:

Creating Strategies

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

Simple Strategy A

In [4]:
custom_a = ta.Strategy(name="A", ta=[{"kind": "sma", "length": 50}, {"kind": "sma", "length": 200}])
custom_a
Out [4]:
Strategy(name='A', ta=[{'kind': 'sma', 'length': 50}, {'kind': 'sma', 'length': 200}], description='TA Description', created='Wednesday August 4, 2021, NYSE: 9:51:45, Local: 13:51:45 PDT, Day 216/365 (59.00%)')

Simple Strategy B

In [5]:
custom_b = ta.Strategy(name="B", ta=[{"kind": "ema", "length": 8}, {"kind": "ema", "length": 21}, {"kind": "log_return", "cumulative": True}, {"kind": "rsi"}, {"kind": "supertrend"}])
custom_b
Out [5]:
Strategy(name='B', ta=[{'kind': 'ema', 'length': 8}, {'kind': 'ema', 'length': 21}, {'kind': 'log_return', 'cumulative': True}, {'kind': 'rsi'}, {'kind': 'supertrend'}], description='TA Description', created='Wednesday August 4, 2021, NYSE: 9:51:45, Local: 13:51:45 PDT, Day 216/365 (59.00%)')

Bad Strategy. (Misspelled Indicator)

In [6]:
# Misspelled indicator, will fail later when ran with Pandas TA
custom_run_failure = ta.Strategy(name="Runtime Failure", ta=[{"kind": "percet_return"}])
custom_run_failure
Out [6]:
Strategy(name='Runtime Failure', ta=[{'kind': 'percet_return'}], description='TA Description', created='Wednesday August 4, 2021, NYSE: 9:51:45, Local: 13:51:45 PDT, Day 216/365 (59.00%)')
In [ ]:

Strategy 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=False)

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

In [9]:
watch
Out [9]:
Watch(name='Watch: SPY, IWM', ds_name='av', tickers[2]='SPY, IWM', tf='D', strategy[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, strategy: pandas_ta.core.Strategy = 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 Strategy.
 |  
 |  Default Strategy: pandas_ta.CommonStrategy
 |  
 |  ## 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, strategy: pandas_ta.core.Strategy = 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
 |  
 |  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 Strategy is "Common"

In [11]:
# No arguments loads all the tickers and applies the Strategy 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[av]: SPY[D]
[+] Strategy: Common Price and Volume SMAs
[i] Indicator arguments: {'timed': False, 'append': True}
[i] Multiprocessing 5 indicators with 7 chunks and 8/8 cpus.
[i] Total indicators: 5
[i] Columns added: 5
[i] Last Run: Wednesday August 4, 2021, NYSE: 9:51:48, Local: 13:51:48 PDT, Day 216/365 (59.00%)
[+] Downloading[av]: IWM[D]
[+] Strategy: Common Price and Volume SMAs
[i] Indicator arguments: {'timed': False, 'append': True}
[i] Multiprocessing 5 indicators with 7 chunks and 8/8 cpus.
[i] Total indicators: 5
[i] Columns added: 5
[i] Last Run: Wednesday August 4, 2021, NYSE: 9:52:09, Local: 13:52:09 PDT, Day 216/365 (59.00%)
In [12]:
", ".join([f"{t}: {d.shape}" for t,d in watch.data.items()])
Out [12]:
'SPY: (5475, 10), IWM: (5331, 10)'
In [13]:
watch.data["SPY"]
Out [13]:
open high low close volume SMA_10 SMA_20 SMA_50 SMA_200 VOL_SMA_20
date
1999-11-01 136.5000 137.0000 135.5625 135.5625 4006500.0 NaN NaN NaN NaN NaN
1999-11-02 135.9687 137.2500 134.5937 134.5937 6516900.0 NaN NaN NaN NaN NaN
1999-11-03 136.0000 136.3750 135.1250 135.5000 7222300.0 NaN NaN NaN NaN NaN
1999-11-04 136.7500 137.3593 135.7656 136.5312 7907500.0 NaN NaN NaN NaN NaN
1999-11-05 138.6250 139.1093 136.7812 137.8750 7431500.0 NaN NaN NaN NaN NaN
... ... ... ... ... ... ... ... ... ... ...
2021-07-29 439.8150 441.8000 439.8100 440.6500 45910298.0 435.683 434.9235 426.8204 392.47485 67581418.80
2021-07-30 437.9100 440.0600 437.7700 438.5100 68951202.0 436.400 435.3275 427.3734 392.91675 68356927.55
2021-08-02 440.3400 440.9300 437.2100 437.5900 58783297.0 437.662 435.5210 427.8196 393.36505 68411209.00
2021-08-03 438.4400 441.2800 436.1000 441.1500 58053896.0 438.671 435.9320 428.3438 393.83330 67878382.85
2021-08-04 439.7800 441.1200 438.7300 438.9800 45933859.0 439.114 436.1580 428.7400 394.29175 66997603.00

5475 rows × 10 columns

In [ ]:
In [14]:
watch.load("SPY", plot=True, mas=True)
Out [14]:
[i] Loaded SPY[D]: SPY_D.csv
open high low close volume SMA_10 SMA_20 SMA_50 SMA_200 VOL_SMA_20
date
1999-11-01 136.5000 137.0000 135.5625 135.5625 4006500.0 NaN NaN NaN NaN NaN
1999-11-02 135.9687 137.2500 134.5937 134.5937 6516900.0 NaN NaN NaN NaN NaN
1999-11-03 136.0000 136.3750 135.1250 135.5000 7222300.0 NaN NaN NaN NaN NaN
1999-11-04 136.7500 137.3593 135.7656 136.5312 7907500.0 NaN NaN NaN NaN NaN
1999-11-05 138.6250 139.1093 136.7812 137.8750 7431500.0 NaN NaN NaN NaN NaN
... ... ... ... ... ... ... ... ... ... ...
2021-07-29 439.8150 441.8000 439.8100 440.6500 45910298.0 435.683 434.9235 426.8204 392.47485 67581418.80
2021-07-30 437.9100 440.0600 437.7700 438.5100 68951202.0 436.400 435.3275 427.3734 392.91675 68356927.55
2021-08-02 440.3400 440.9300 437.2100 437.5900 58783297.0 437.662 435.5210 427.8196 393.36505 68411209.00
2021-08-03 438.4400 441.2800 436.1000 441.1500 58053896.0 438.671 435.9320 428.3438 393.83330 67878382.85
2021-08-04 439.7800 441.1200 438.7300 438.9800 45933859.0 439.114 436.1580 428.7400 394.29175 66997603.00

5475 rows × 10 columns

In [ ]:

Easy to swap Strategies and run them

Running Simple Strategy A

In [15]:
# Load custom_a into Watchlist and verify
watch.strategy = custom_a
# watch.debug = True
watch.strategy
Out [15]:
Strategy(name='A', ta=[{'kind': 'sma', 'length': 50}, {'kind': 'sma', 'length': 200}], description='TA Description', created='Wednesday August 4, 2021, NYSE: 9:51:45, Local: 13:51:45 PDT, Day 216/365 (59.00%)')
In [16]:
watch.load("IWM")
Out [16]:
[i] Loaded IWM[D]: IWM_D.csv
open high low close volume SMA_50 SMA_200
date
2000-05-26 91.06 91.440 90.630 91.44 37400.0 NaN NaN
2000-05-30 92.75 94.810 92.750 94.81 28800.0 NaN NaN
2000-05-31 95.13 96.380 95.130 95.75 18000.0 NaN NaN
2000-06-01 97.11 97.310 97.110 97.31 3500.0 NaN NaN
2000-06-02 101.70 102.400 101.700 102.40 14700.0 NaN NaN
... ... ... ... ... ... ... ...
2021-07-29 222.79 224.435 222.140 222.52 22112239.0 224.9142 209.22680
2021-07-30 221.65 224.050 220.275 221.05 28473020.0 224.9762 209.51855
2021-08-02 222.47 224.550 219.640 219.95 24192605.0 224.9872 209.81285
2021-08-03 220.62 221.120 217.100 220.86 27798643.0 225.0050 210.10340
2021-08-04 219.10 221.200 217.890 218.11 25257969.0 224.9392 210.38220

5331 rows × 7 columns

Running Simple Strategy B

In [17]:
# Load custom_b into Watchlist and verify
watch.strategy = custom_b
watch.strategy
Out [17]:
Strategy(name='B', ta=[{'kind': 'ema', 'length': 8}, {'kind': 'ema', 'length': 21}, {'kind': 'log_return', 'cumulative': True}, {'kind': 'rsi'}, {'kind': 'supertrend'}], description='TA Description', created='Wednesday August 4, 2021, NYSE: 9:51:45, Local: 13:51:45 PDT, Day 216/365 (59.00%)')
In [18]:
watch.load("SPY")
Out [18]:
[i] Loaded SPY[D]: SPY_D.csv
open high low close volume 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
1999-11-01 136.5000 137.0000 135.5625 135.5625 4006500.0 NaN NaN 0.000000 NaN 0.000000 1 NaN NaN
1999-11-02 135.9687 137.2500 134.5937 134.5937 6516900.0 NaN NaN -0.007172 NaN NaN 1 NaN NaN
1999-11-03 136.0000 136.3750 135.1250 135.5000 7222300.0 NaN NaN -0.000461 NaN NaN 1 NaN NaN
1999-11-04 136.7500 137.3593 135.7656 136.5312 7907500.0 NaN NaN 0.007120 NaN NaN 1 NaN NaN
1999-11-05 138.6250 139.1093 136.7812 137.8750 7431500.0 NaN NaN 0.016915 NaN NaN 1 NaN NaN
... ... ... ... ... ... ... ... ... ... ... ... ... ...
2021-07-29 439.8150 441.8000 439.8100 440.6500 45910298.0 437.899020 434.223638 1.178818 63.083431 429.203232 1 429.203232 NaN
2021-07-30 437.9100 440.0600 437.7700 438.5100 68951202.0 438.034793 434.613307 1.173950 58.908437 429.203232 1 429.203232 NaN
2021-08-02 440.3400 440.9300 437.2100 437.5900 58783297.0 437.935950 434.883915 1.171850 57.157102 429.203232 1 429.203232 NaN
2021-08-03 438.4400 441.2800 436.1000 441.1500 58053896.0 438.650184 435.453560 1.179952 61.879836 429.203232 1 429.203232 NaN
2021-08-04 439.7800 441.1200 438.7300 438.9800 45933859.0 438.723476 435.774145 1.175021 57.704255 429.203232 1 429.203232 NaN

5475 rows × 13 columns

Running Bad Strategy. (Misspelled indicator)

In [19]:
# Load custom_run_failure into Watchlist and verify
watch.strategy = custom_run_failure
watch.strategy
Out [19]:
Strategy(name='Runtime Failure', ta=[{'kind': 'percet_return'}], description='TA Description', created='Wednesday August 4, 2021, NYSE: 9:51:45, Local: 13:51:45 PDT, Day 216/365 (59.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 'percet_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.

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.Strategy("Volume MAs and Price MA chain", volmas_price_ma_chain)
vp_ma_chain_ta
Out [21]:
Strategy(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'}], description='TA Description', created='Wednesday August 4, 2021, NYSE: 9:51:45, Local: 13:51:45 PDT, Day 216/365 (59.00%)')
In [22]:
# Update the Watchlist
watch.strategy = vp_ma_chain_ta
watch.strategy.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
open high low close volume VOLUME_EMA_10 VOLUME_SMA_20 EMA_5 EMA_5_LR_8
date
1999-11-01 136.5000 137.0000 135.5625 135.5625 4006500.0 NaN NaN NaN NaN
1999-11-02 135.9687 137.2500 134.5937 134.5937 6516900.0 NaN NaN NaN NaN
1999-11-03 136.0000 136.3750 135.1250 135.5000 7222300.0 NaN NaN NaN NaN
1999-11-04 136.7500 137.3593 135.7656 136.5312 7907500.0 NaN NaN NaN NaN
1999-11-05 138.6250 139.1093 136.7812 137.8750 7431500.0 NaN NaN 136.012480 NaN
... ... ... ... ... ... ... ... ... ...
2021-07-29 439.8150 441.8000 439.8100 440.6500 45910298.0 6.106783e+07 67581418.80 439.017785 439.805454
2021-07-30 437.9100 440.0600 437.7700 438.5100 68951202.0 6.250117e+07 68356927.55 438.848523 440.040302
2021-08-02 440.3400 440.9300 437.2100 437.5900 58783297.0 6.182519e+07 68411209.00 438.429015 439.742146
2021-08-03 438.4400 441.2800 436.1000 441.1500 58053896.0 6.113950e+07 67878382.85 439.336010 439.574486
2021-08-04 439.7800 441.1200 438.7300 438.9800 45933859.0 5.837484e+07 66997603.00 439.217340 439.407713

5475 rows × 9 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.Strategy("MACD BBands", macd_bands_ta, f"BBANDS_{macd_bands_ta[1]['length']} applied to MACD")
macd_bands_ta
Out [24]:
Strategy(name='MACD BBands', ta=[{'kind': 'macd'}, {'kind': 'bbands', 'close': 'MACD_12_26_9', 'length': 20, 'ddof': 0, 'prefix': 'MACD'}], description='BBANDS_20 applied to MACD', created='Wednesday August 4, 2021, NYSE: 9:51:45, Local: 13:51:45 PDT, Day 216/365 (59.00%)')
In [25]:
# Update the Watchlist
watch.strategy = macd_bands_ta
watch.strategy.name
Out [25]:
'MACD BBands'
In [26]:
spy = watch.load("SPY")
spy
Out [26]:
[i] Loaded SPY[D]: SPY_D.csv
open high low close volume 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
1999-11-01 136.5000 137.0000 135.5625 135.5625 4006500.0 NaN NaN NaN NaN NaN NaN NaN NaN
1999-11-02 135.9687 137.2500 134.5937 134.5937 6516900.0 NaN NaN NaN NaN NaN NaN NaN NaN
1999-11-03 136.0000 136.3750 135.1250 135.5000 7222300.0 NaN NaN NaN NaN NaN NaN NaN NaN
1999-11-04 136.7500 137.3593 135.7656 136.5312 7907500.0 NaN NaN NaN NaN NaN NaN NaN NaN
1999-11-05 138.6250 139.1093 136.7812 137.8750 7431500.0 NaN NaN NaN NaN NaN NaN NaN NaN
... ... ... ... ... ... ... ... ... ... ... ... ... ...
2021-07-29 439.8150 441.8000 439.8100 440.6500 45910298.0 3.659359 0.293348 3.366011 2.370151 3.428878 4.487606 61.753577 0.608848
2021-07-30 437.9100 440.0600 437.7700 438.5100 68951202.0 3.536797 0.136628 3.400168 2.455793 3.468200 4.480608 58.382302 0.533878
2021-08-02 440.3400 440.9300 437.2100 437.5900 58783297.0 3.327076 -0.058474 3.385550 2.468149 3.474921 4.481692 57.945001 0.426575
2021-08-03 438.4400 441.2800 436.1000 441.1500 58053896.0 3.408839 0.018631 3.390208 2.466294 3.473372 4.480450 57.988489 0.467960
2021-08-04 439.7800 441.1200 438.7300 438.9800 45933859.0 3.260945 -0.103410 3.364355 2.445938 3.450604 4.455271 58.231346 0.405611

5475 rows × 13 columns

In [ ]:

Comprehensive Strategy

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_strategy = ta.Strategy(
    "Momo, Bands and SMAs and Cumulative Log Returns", # name
    momo_bands_sma_ta, # ta
    "MACD and RSI Momo with BBANDS and SMAs 50 & 200 and Cumulative Log Returns" # description
)
momo_bands_sma_strategy
Out [27]:
Strategy(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'}], description='MACD and RSI Momo with BBANDS and SMAs 50 & 200 and Cumulative Log Returns', created='Wednesday August 4, 2021, NYSE: 9:51:45, Local: 13:51:45 PDT, Day 216/365 (59.00%)')
In [28]:
# Update the Watchlist
watch.strategy = momo_bands_sma_strategy
watch.strategy.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
open high low close volume SMA_50 SMA_200 BBL_20_2.0 BBM_20_2.0 BBU_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
2021-07-29 439.815 441.80 439.81 440.65 45910298.0 426.8204 392.47485 427.133457 434.9235 442.713543 ... 0.867553 3.659359 0.293348 3.366011 63.083431 1.178818 1.177090 0 30 70
2021-07-30 437.910 440.06 437.77 438.51 68951202.0 427.3734 392.91675 427.674645 435.3275 442.980355 ... 0.707929 3.536797 0.136628 3.400168 58.908437 1.173950 1.176439 0 30 70
2021-08-02 440.340 440.93 437.21 437.59 58783297.0 427.8196 393.36505 427.844842 435.5210 443.197158 ... 0.634768 3.327076 -0.058474 3.385550 57.157102 1.171850 1.174877 0 30 70
2021-08-03 438.440 441.28 436.10 441.15 58053896.0 428.3438 393.83330 427.979505 435.9320 443.884495 ... 0.828073 3.408839 0.018631 3.390208 61.879836 1.179952 1.175850 0 30 70
2021-08-04 439.780 441.12 438.73 438.98 45933859.0 428.7400 394.29175 428.129141 436.1580 444.186859 ... 0.675741 3.260945 -0.103410 3.364355 57.704255 1.175021 1.175918 0 30 70

5 rows × 21 columns

In [ ]:

Additional Strategy 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_strategy = ta.Strategy(
    "EMA, MACD History, Outter BBands, Log Returns", # name
    params_ta, # ta
    "EMA, MACD History, BBands(LB, UB), and Log Returns Strategy" # description
)
params_ta_strategy
Out [30]:
Strategy(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)}], description='EMA, MACD History, BBands(LB, UB), and Log Returns Strategy', created='Wednesday August 4, 2021, NYSE: 9:51:45, Local: 13:51:45 PDT, Day 216/365 (59.00%)')
In [31]:
# Update the Watchlist
watch.strategy = params_ta_strategy
watch.strategy.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
open high low close volume EMA_10 MACDh_9_19_10 LB UB LOGRET_5
date
2021-07-29 439.815 441.80 439.81 440.65 45910298.0 437.248923 0.342445 438.156795 441.623205 0.011848
2021-07-30 437.910 440.06 437.77 438.51 68951202.0 437.478210 0.125869 437.555016 441.652984 -0.003256
2021-08-02 440.340 440.93 437.21 437.59 58783297.0 437.498535 -0.126616 436.928813 440.907187 -0.007808
2021-08-03 438.440 441.28 436.10 441.15 58053896.0 438.162438 -0.016262 436.662194 442.029806 0.004863
2021-08-04 439.780 441.12 438.73 438.98 45933859.0 438.311086 -0.168348 436.712661 442.039339 0.000342
In [ ]:

Disclaimer

  • All investments involve risk, and the past performance of a security, industry, sector, market, financial product, trading strategy, 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.