{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Technical Analysis with Pandas ([pandas_ta](https://github.com/twopirllc/pandas-ta))\n", "* Below contains examples of simple charts that can be made from pandas_ta indicators\n", "* Examples below are for **educational purposes only**\n", "* **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." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Pandas TA v0.2.89b0\n", "To install the Latest Version:\n", "$ pip install -U git+https://github.com/twopirllc/pandas-ta\n", "\n", "Populating the interactive namespace from numpy and matplotlib\n" ] } ], "source": [ "%matplotlib inline\n", "import datetime as dt\n", "import random as rnd\n", "\n", "from tqdm import tqdm\n", "import numpy as np\n", "import pandas as pd\n", "import matplotlib.ticker as ticker\n", "import mplfinance as mpf\n", "\n", "from alphaVantageAPI.alphavantage import AlphaVantage\n", "import pandas_ta as ta\n", "\n", "from watchlist import colors # Is this failing? If so, copy it locally. See above.\n", "\n", "print(f\"\\nPandas TA v{ta.version}\\nTo install the Latest Version:\\n$ pip install -U git+https://github.com/twopirllc/pandas-ta\\n\")\n", "\n", "%pylab inline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### List of Indicators (post an [issue](https://github.com/twopirllc/pandas-ta/issues) if the indicator doc needs updating)" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Pandas TA - Technical Analysis Indicators - v0.2.89b0\n", "Total Indicators & Utilities: 202\n", "Abbreviations:\n", " aberration, above, above_value, accbands, ad, adosc, adx, alma, amat, ao, aobv, apo, aroon, atr, bbands, below, below_value, bias, bop, brar, cci, cdl_pattern, cdl_z, cfo, cg, chop, cksp, cmf, cmo, coppock, cross, cross_value, cti, decay, decreasing, dema, dm, donchian, dpo, ebsw, efi, ema, entropy, eom, er, eri, fisher, fwma, ha, hilo, hl2, hlc3, hma, hwc, hwma, ichimoku, increasing, inertia, kama, kc, kdj, kst, kurtosis, kvo, linreg, log_return, long_run, macd, mad, massi, mcgd, median, mfi, midpoint, midprice, mom, natr, nvi, obv, ohlc4, pdist, percent_return, pgo, ppo, psar, psl, pvi, pvo, pvol, pvr, pvt, pwma, qqe, qstick, quantile, rma, roc, rsi, rsx, rvgi, rvi, short_run, sinwma, skew, slope, sma, smi, squeeze, ssf, stc, stdev, stoch, stochrsi, supertrend, swma, t3, td_seq, tema, thermo, trima, trix, true_range, tsi, tsignals, ttm_trend, ui, uo, variance, vhf, vidya, vortex, vp, vwap, vwma, wcp, willr, wma, xsignals, zlma, zscore\n", "\n", "Candle Patterns:\n", " 2crows, 3blackcrows, 3inside, 3linestrike, 3outside, 3starsinsouth, 3whitesoldiers, abandonedbaby, advanceblock, belthold, breakaway, closingmarubozu, concealbabyswall, counterattack, darkcloudcover, doji, dojistar, dragonflydoji, engulfing, eveningdojistar, eveningstar, gapsidesidewhite, gravestonedoji, hammer, hangingman, harami, haramicross, highwave, hikkake, hikkakemod, homingpigeon, identical3crows, inneck, inside, invertedhammer, kicking, kickingbylength, ladderbottom, longleggeddoji, longline, marubozu, matchinglow, mathold, morningdojistar, morningstar, onneck, piercing, rickshawman, risefall3methods, separatinglines, shootingstar, shortline, spinningtop, stalledpattern, sticksandwich, takuri, tasukigap, thrusting, tristar, unique3river, upsidegap2crows, xsidegap3methods\n" ] } ], "source": [ "e = pd.DataFrame()\n", "e.ta.indicators()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Individual Indicator help" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on function ema in module pandas_ta.overlap.ema:\n", "\n", "ema(close, length=None, offset=None, **kwargs)\n", " Exponential Moving Average (EMA)\n", " \n", " The Exponential Moving Average is more responsive moving average compared to the\n", " Simple Moving Average (SMA). The weights are determined by alpha which is\n", " proportional to it's length. There are several different methods of calculating\n", " EMA. One method uses just the standard definition of EMA and another uses the\n", " SMA to generate the initial value for the rest of the calculation.\n", " \n", " Sources:\n", " https://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:moving_averages\n", " https://www.investopedia.com/ask/answers/122314/what-exponential-moving-average-ema-formula-and-how-ema-calculated.asp\n", " \n", " Calculation:\n", " Default Inputs:\n", " length=10, adjust=False, sma=True\n", " if sma:\n", " sma_nth = close[0:length].sum() / length\n", " close[:length - 1] = np.NaN\n", " close.iloc[length - 1] = sma_nth\n", " EMA = close.ewm(span=length, adjust=adjust).mean()\n", " \n", " Args:\n", " close (pd.Series): Series of 'close's\n", " length (int): It's period. Default: 10\n", " offset (int): How many periods to offset the result. Default: 0\n", " \n", " Kwargs:\n", " adjust (bool, optional): Default: False\n", " sma (bool, optional): If True, uses SMA for initial value. Default: True\n", " fillna (value, optional): pd.DataFrame.fillna(value)\n", " fill_method (value, optional): Type of fill method\n", " \n", " Returns:\n", " pd.Series: New feature generated.\n", "\n" ] } ], "source": [ "help(ta.ema)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "# Function to format Millions\n", "def format_millions(x, pos):\n", " \"The two args are the value and tick position\"\n", " return \"%1.1fM\" % (x * 1e-6)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "def ctitle(indicator_name, ticker=\"SPY\", length=100):\n", " return f\"{ticker}: {indicator_name} from {recent_startdate} to {recent_enddate} ({length})\"\n", "\n", "# # All Data: 0, Last Four Years: 0.25, Last Two Years: 0.5, This Year: 1, Last Half Year: 2, Last Quarter: 3\n", "# yearly_divisor = 1\n", "# recent = int(ta.RATE[\"TRADING_DAYS_PER_YEAR\"] / yearly_divisor) if yearly_divisor > 0 else df.shape[0]\n", "# print(recent)\n", "def recent_bars(df, tf: str = \"1y\"):\n", " # All Data: 0, Last Four Years: 0.25, Last Two Years: 0.5, This Year: 1, Last Half Year: 2, Last Quarter: 4\n", " 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}\n", " yd = yearly_divisor[tf] if tf in yearly_divisor.keys() else 0\n", " return int(ta.RATE[\"TRADING_DAYS_PER_YEAR\"] / yd) if yd > 0 else df.shape[0]\n", "\n", "def ta_ylim(series: pd.Series, percent: float = 0.1):\n", " smin, smax = series.min(), series.max()\n", " if isinstance(percent, float) and 0 <= float(percent) <= 1:\n", " y_min = (1 + percent) * smin if smin < 0 else (1 - percent) * smin\n", " y_max = (1 - percent) * smax if smax < 0 else (1 + percent) * smax\n", " return (y_min, y_max)\n", " return (smin, smax)\n", "\n", "price_size = (16, 8)\n", "ind_size = (16, 3.25)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Load Daily Ticker Data using yfinance and clean it" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "# help(e.ta.ticker)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "==== Company Information =====================================================\n", "SPDR S&P 500 ETF Trust(SPDR S&P 500) [SPY]\n", "\n", "==== Market Information =====================================================\n", "Market | Exchange | Symbol | Category US | PCX | SPY | Large Blend\n", "\n", "NAV | Yield 415.05 | 1.3300%\n", "\n", "\n", "\n", "==== Price Information =====================================================\n", "Open High Low | Close 417.0900 417.0900 414.7000 | 414.9200\n", "HL2 | HLC3 | OHLC4 | C - OHLC4 416.2640, 415.8160, 416.1345, -1.2145\n", "Change (%) -5.6741 (-1.3491%)\n", "Bid | Ask | Spread 413.56 x 900 | 413.68 x 900 | 0.1200\n", "Volume | Market | Avg Vol (10Day) \n", " 118,676,302 | 118,676,302 | 74,021,017 (66,100,437)\n", "\n", "52Wk Range (% from 52Wk Low) 298.93 - 425.46 : 126.5300 (38.8017%)\n", "SMA 50 | SMA 200 418.3137 | 395.1771\n", "Avg. Return 3Yr | 5Yr 16.9700% | 17.4100%\n", "\n", "==== Dividends / Splits =====================================================\n", "\n", "Stock Splits (Last 5 of 114):\n", "Date 2021-03-19 2020-12-18 2020-09-18 2020-06-19 2020-03-20\n", "Ratio 1.278 1.58 1.339 1.366 1.406\n", "SPY(252, 7) from 2020-06-19 00:00:00 to 2021-06-18 00:00:00\n" ] }, { "data": { "text/html": [ "
| \n", " | open | \n", "high | \n", "low | \n", "close | \n", "volume | \n", "dividends | \n", "stock splits | \n", "
|---|---|---|---|---|---|---|---|
| date | \n", "\n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " |
| 2020-06-19 | \n", "310.572014 | \n", "310.779600 | \n", "303.019496 | \n", "305.105347 | \n", "135549600 | \n", "1.366 | \n", "0 | \n", "
| 2020-06-22 | \n", "304.462768 | \n", "307.487721 | \n", "303.236978 | \n", "307.062653 | \n", "74649400 | \n", "0.000 | \n", "0 | \n", "
| 2020-06-23 | \n", "309.899768 | \n", "310.898211 | \n", "308.041294 | \n", "308.476257 | \n", "68471200 | \n", "0.000 | \n", "0 | \n", "
| 2020-06-24 | \n", "306.291601 | \n", "306.953942 | \n", "298.640252 | \n", "300.607452 | \n", "132813500 | \n", "0.000 | \n", "0 | \n", "
| 2020-06-25 | \n", "299.994539 | \n", "304.116796 | \n", "297.829618 | \n", "303.830109 | \n", "89468000 | \n", "0.000 | \n", "0 | \n", "