<jupyter_start><jupyter_text>Strategy Analysis with **Pandas TA** and AI/ML* This is a **Work in Progress** and subject to change!* Contributions are welcome and accepted!* Examples below are for **educational purposes only**.* **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.  Required Packages Uncomment the packages you need to install or are missing<jupyter_code>#!pip install numpy
#!pip install pandas
#!pip install mplfinance
#!pip install pandas-datareader
#!pip install requests_cache
#!pip install alphaVantage-api # Required for Watchlist
%pylab inline
import datetime as dt
import random as rnd
from sys import float_info as sflt

import numpy as np
import pandas as pd
pd.set_option('max_rows', 100)
pd.set_option('max_columns', 20)

import mplfinance as mpf
import pandas_ta as ta

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

print(f"Numpy v{np.__version__}")
print(f"Pandas v{pd.__version__}")
print(f"mplfinance v{mpf.__version__}")
print(f"Pandas TA v{ta.version}")
%matplotlib inline<jupyter_output>Populating the interactive namespace from numpy and matplotlib
Numpy v1.19.5
Pandas v1.2.0
mplfinance v0.12.7a4
Pandas TA v0.2.40b0<jupyter_text>MISC Functions<jupyter_code>def recent_bars(df, tf: str = "1y"):
    # All Data: 0, Last Four Years: 0.25, Last Two Years: 0.5, This Year: 1, Last Half Year: 2, Last Quarter: 4
    yearly_divisor = {"all": 0, "10y": 0.1, "5y": 0.2, "4y": 0.25, "3y": 1./3, "2y": 0.5, "1y": 1, "6mo": 2, "3mo": 4}
    yd = yearly_divisor[tf] if tf in yearly_divisor.keys() else 0
    return int(ta.RATE["TRADING_DAYS_PER_YEAR"] / yd) if yd > 0 else df.shape[0]<jupyter_output><empty_output><jupyter_text>Collect some Data<jupyter_code>tf = "D"
tickers = ["SPY", "QQQ", "AAPL", "TSLA"]
watch = Watchlist(tickers, tf=tf, timed=True)
watch.strategy = ta.CommonStrategy
watch.load(tickers, analyze=True, verbose=False)<jupyter_output>[!] Loading All: SPY, QQQ, AAPL, TSLA
[i] Loaded['D']: SPY_D.csv
[i] Runtime: 360.4083 ms (0.3604 s)
[i] Loaded['D']: QQQ_D.csv
[i] Runtime: 388.5823 ms (0.3886 s)
[i] Loaded['D']: AAPL_D.csv
[i] Runtime: 351.0826 ms (0.3511 s)
[i] Loaded['D']: TSLA_D.csv
[i] Runtime: 350.7362 ms (0.3507 s)<jupyter_text>Select an Asset<jupyter_code>ticker = tickers[0]
print(f"{ticker} {watch.data[ticker].shape}\nColumns: {', '.join(list(watch.data[ticker].columns))}")<jupyter_output>SPY (5265, 10)
Columns: open, high, low, close, volume, SMA_10, SMA_20, SMA_50, SMA_200, VOL_SMA_20<jupyter_text>Trim it<jupyter_code>duration = "1y"
recent = recent_bars(watch.data[ticker], duration)
asset = watch.data[ticker].copy().tail(recent)<jupyter_output><empty_output><jupyter_text>Create a Trend<jupyter_code># Example Long Trends
# long = ta.sma(asset.close, 10) < ta.sma(asset.close, 20) # SMA(10) > SMA(20)
long = ta.ema(asset.close, 8) > ta.ema(asset.close, 21) # EMA(8) > EMA(21)
# long = ta.increasing(ta.ema(asset.close, 50))
# long = ta.macd(asset.close).iloc[:,1] > 0 # MACD Histogram is positive

asset.ta.ema(length=8, append=True)
asset.ta.ema(length=21, append=True)
asset.ta.ema(length=50, append=True)
asset[asset.columns[5:]].tail()<jupyter_output><empty_output><jupyter_text>Calculate Trend Returns from the long trend<jupyter_code>trendy = asset.ta.trend_return(trend=long, cumulative=True, trade_offset=-1, append=True)
trendy.tail() # Third Column is the long trend; binary sequences<jupyter_output><empty_output><jupyter_text>Simple Price Chart<jupyter_code>extime = ta.get_time(to_string=True)
chart_ = asset[["close", "EMA_8", "EMA_21", "EMA_50"]]
chart_.plot(figsize=(16, 10), color=colors("BkGrOrRd"), title=f"{ticker} {extime}", grid=True)<jupyter_output><empty_output><jupyter_text>Trend Returns and Cumulative Trend Returns<jupyter_code>cltr = trendy.iloc[:,0]
tr = trendy.iloc[:,1]

trendy.iloc[:,:2].plot(figsize=(16, 3), color=colors("BkBl"))
cltr.plot(figsize=(16, 3), kind="area", stacked=False, color=colors("SvGy")[0], alpha=0.25, grid=True)<jupyter_output><empty_output><jupyter_text>Total Return<jupyter_code>capital = 10000

total_return = cltr.cumsum() * capital
positive_return = total_return[total_return > 0]
negative_return = total_return[total_return <= 0]
trdf = pd.DataFrame({"tr+": positive_return, "tr-": negative_return})
trdf.plot(figsize=(16, 5), color=colors(), kind="area", stacked=False, alpha=0.25, grid=True)<jupyter_output><empty_output><jupyter_text>Long and Short Trends<jupyter_code>long_trend = (trendy.iloc[:,-2] > 0).astype(int)
short_trend = (1 - long_trend).astype(int)

long_trend.plot(figsize=(16, 0.85), kind="area", stacked=True, color=colors()[0], alpha=0.25)
short_trend.plot(figsize=(16, 0.85), kind="area", stacked=True, color=colors()[1], alpha=0.25)<jupyter_output><empty_output><jupyter_text>Entries & Exits<jupyter_code>entries = (trendy.iloc[:,-1] > 0).astype(int) * asset.close
entries[entries < 0.0001] = np.nan
entries.name = "Entry"


exits = (trendy.iloc[:,-1] < 0).astype(int) * asset.close
exits[exits < 0.0001] = np.nan
exits.name = "Exit"

total_trades = trendy.iloc[:,-1].abs().sum()
print(f"Total Trades: {total_trades}")

all_trades = trendy.iloc[:,-1].copy().fillna(0)
all_trades = all_trades[all_trades != 0]

trades = pd.DataFrame({"Signal": all_trades, entries.name: entries.dropna(), exits.name: exits.dropna()})
trades<jupyter_output>Total Trades: 6<jupyter_text>Chart Display Strings<jupyter_code>first_date, last_date = asset.index[0], asset.index[-1]
f_date = f"{first_date.day_name()} {first_date.month}-{first_date.day}-{first_date.year}"
l_date = f"{last_date.day_name()} {last_date.month}-{last_date.day}-{last_date.year}"
last_ohlcv = f"Last OHLCV: ({asset.iloc[-1].open}, {asset.iloc[-1].high}, {asset.iloc[-1].low}, {asset.iloc[-1].close}, {int(asset.iloc[-1].volume)})"
ptitle = f"\n{ticker} [{tf} for {duration}({recent} bars)] from {f_date} to {l_date}\n{last_ohlcv}\n{extime}"<jupyter_output><empty_output><jupyter_text>Trade Chart<jupyter_code># chart = asset["close"] #asset[["close", "SMA_10", "SMA_20", "SMA_50", "SMA_200"]]
# chart = asset[["close", "SMA_10", "SMA_20"]]
chart = asset[["close", "EMA_8", "EMA_21", "EMA_50"]]
chart.plot(figsize=(16, 10), color=colors("BkGrOrRd"), title=ptitle, grid=True)
entries.plot(figsize=(16, 10), color=colors("FcLi")[1], marker="^", markersize=12, alpha=0.8)
exits.plot(figsize=(16, 10), color=colors("FcLi")[0], marker="v", markersize=12, alpha=0.8, grid=True)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.17364175924516817, 'fraction_numerical': 0.041546187794856186, 'mean_word_length': 6.985419198055893, 'pattern_counts': {'":': 12, '<': 58, '<?xml version=': 0, '>': 61, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '14', 'dir': 'jupyter-structured-clean-dedup', 'id': '57902', 'license': 'MIT', 'n_tokens_mistral': 2808, 'n_tokens_neox': 2600, 'n_words': 542, 'path': 'examples/AIExample.ipynb', 'repo_name': 'MyBourse/pandas-ta', 'size': '6571'}