├── .gitignore ├── 07_pandas_df_tutorial_medium.ipynb ├── 08_matplotlib_financial_chart_demo.ipynb ├── README.md ├── Squeeze_Momentum_Indicator_LazyBear_Demo.ipynb ├── automate_stock_screener_demo.ipynb ├── dataset └── symbols.csv ├── plotly_financial_chart_demo.ipynb ├── simple_technical_analysis_stock_screener_demo.ipynb ├── stock_breakout_demo.ipynb └── supertrend_demo_medium.ipynb /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # About 2 | I write about programming and stock technical analysis on [Medium](https://yonghongtan.medium.com/). 3 |
4 | Subscribe via this [link](https://yonghongtan.medium.com/membership) for unlimited access! 5 | 6 | # Support Me 7 | 8 | Buy Me A Coffee 9 | 10 | 11 | # Article List 12 | 13 | ## Stock trading related 14 | - [Backtesting All Candlestick Patterns: Which is the Best?](https://medium.com/the-investors-handbook/backtesting-all-candlestick-patterns-which-is-the-best-72a0ea8afcb4) 15 | - [A Notion Trading Journal Template](https://medium.datadriveninvestor.com/a-notion-trading-journal-template-eb01706345f9) 16 | - [The Supertrend — Implementing, Screening & Backtesting in Python](https://medium.datadriveninvestor.com/the-supertrend-implementing-screening-backtesting-in-python-70e8f88f383d) 17 | - [A Simple Guide to Plotly for Plotting Financial Chart](https://python.plainenglish.io/a-simple-guide-to-plotly-for-plotting-financial-chart-54986c996682) 18 | - [How to Detect Support & Resistance Levels and Breakout using Python](https://medium.datadriveninvestor.com/how-to-detect-support-resistance-levels-and-breakout-using-python-f8b5dac42f21) 19 | - [Implementing the Most Popular Indicator on TradingView Using Python](https://medium.com/geekculture/implementing-the-most-popular-indicator-on-tradingview-using-python-239d579412ab) 20 | - [Automate your stock screening using Python](https://levelup.gitconnected.com/automate-your-stock-screening-using-python-9107dda724c3) 21 | - [Build your own technical analysis stock screener using Python](https://medium.com/analytics-vidhya/build-your-own-technical-analysis-stock-screener-using-python-5d1bb3d091f0) 22 | 23 | ## Programming 24 | - [Resources that Helped Me Land a Developer Job Without a CS Degree](https://levelup.gitconnected.com/resources-that-helped-me-land-a-developer-job-without-a-cs-degree-d5c8a011fa90) 25 | 26 | ## Others 27 | - [Make your own Japanese dictionary and quiz app on Google Sheets](https://yonghongtan.medium.com/make-your-simple-japanese-dictionary-and-quiz-app-on-google-sheets-ed5dd2e84342) 28 | 29 | 30 | -------------------------------------------------------------------------------- /Squeeze_Momentum_Indicator_LazyBear_Demo.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "Squeeze-Momentum-Indicator-LazyBear-Demo.ipynb", 7 | "provenance": [], 8 | "collapsed_sections": [], 9 | "authorship_tag": "ABX9TyMRe72aB+EZFKys8exkJGWo", 10 | "include_colab_link": true 11 | }, 12 | "kernelspec": { 13 | "name": "python3", 14 | "display_name": "Python 3" 15 | }, 16 | "language_info": { 17 | "name": "python" 18 | } 19 | }, 20 | "cells": [ 21 | { 22 | "cell_type": "markdown", 23 | "metadata": { 24 | "id": "view-in-github", 25 | "colab_type": "text" 26 | }, 27 | "source": [ 28 | "\"Open" 29 | ] 30 | }, 31 | { 32 | "cell_type": "markdown", 33 | "metadata": { 34 | "id": "nKgeIyzc7IMw" 35 | }, 36 | "source": [ 37 | "A demo Colab Notebook for my Medium article '[Implementing the Squeeze Momentum Indicator in Python](https://medium.com/geekculture/implementing-the-most-popular-indicator-on-tradingview-using-python-239d579412ab)'" 38 | ] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "metadata": { 43 | "id": "jZjYphw06_5Y" 44 | }, 45 | "source": [ 46 | "!pip install yfinance\n", 47 | "!pip install bs4\n", 48 | "!pip install requests\n", 49 | "!pip install ta\n", 50 | "!pip install finta\n", 51 | "!pip install mplfinance\n", 52 | "import pandas as pd\n", 53 | "import requests\n", 54 | "from datetime import datetime\n", 55 | "import yfinance as yf\n", 56 | "from bs4 import BeautifulSoup\n", 57 | "import numpy as np\n", 58 | "import math\n", 59 | "import mplfinance as mpf" 60 | ], 61 | "execution_count": null, 62 | "outputs": [] 63 | }, 64 | { 65 | "cell_type": "code", 66 | "metadata": { 67 | "id": "CFmF-TFE0M3I", 68 | "colab": { 69 | "base_uri": "https://localhost:8080/" 70 | }, 71 | "outputId": "a75b30ac-6329-4260-c2cc-89f85e455a29" 72 | }, 73 | "source": [ 74 | "screened_list = []\n", 75 | "stock_list = ['AAPL','TSLA','MSFT','AMZN']\n", 76 | "for stock_code in stock_list:\n", 77 | " # get stock prices\n", 78 | " df = yf.download(stock_code, start='2020-01-01', threads= False)\n", 79 | "\n", 80 | " # parameter setup\n", 81 | " length = 20\n", 82 | " mult = 2\n", 83 | " length_KC = 20\n", 84 | " mult_KC = 1.5\n", 85 | "\n", 86 | " # calculate BB\n", 87 | " m_avg = df['Close'].rolling(window=length).mean()\n", 88 | " m_std = df['Close'].rolling(window=length).std(ddof=0)\n", 89 | " df['upper_BB'] = m_avg + mult * m_std\n", 90 | " df['lower_BB'] = m_avg - mult * m_std\n", 91 | "\n", 92 | " # calculate true range\n", 93 | " df['tr0'] = abs(df[\"High\"] - df[\"Low\"])\n", 94 | " df['tr1'] = abs(df[\"High\"] - df[\"Close\"].shift())\n", 95 | " df['tr2'] = abs(df[\"Low\"] - df[\"Close\"].shift())\n", 96 | " df['tr'] = df[['tr0', 'tr1', 'tr2']].max(axis=1)\n", 97 | "\n", 98 | " # calculate KC\n", 99 | " range_ma = df['tr'].rolling(window=length_KC).mean()\n", 100 | " df['upper_KC'] = m_avg + range_ma * mult_KC\n", 101 | " df['lower_KC'] = m_avg - range_ma * mult_KC\n", 102 | "\n", 103 | " # calculate bar value\n", 104 | " highest = df['High'].rolling(window = length_KC).max()\n", 105 | " lowest = df['Low'].rolling(window = length_KC).min()\n", 106 | " m1 = (highest + lowest)/2\n", 107 | " df['value'] = (df['Close'] - (m1 + m_avg)/2)\n", 108 | " fit_y = np.array(range(0,length_KC))\n", 109 | " df['value'] = df['value'].rolling(window = length_KC).apply(lambda x: \n", 110 | " np.polyfit(fit_y, x, 1)[0] * (length_KC-1) + \n", 111 | " np.polyfit(fit_y, x, 1)[1], raw=True)\n", 112 | "\n", 113 | " # check for 'squeeze'\n", 114 | " df['squeeze_on'] = (df['lower_BB'] > df['lower_KC']) & (df['upper_BB'] < df['upper_KC'])\n", 115 | " df['squeeze_off'] = (df['lower_BB'] < df['lower_KC']) & (df['upper_BB'] > df['upper_KC'])\n", 116 | "\n", 117 | " # buying window for long position:\n", 118 | " # 1. black cross becomes gray (the squeeze is released)\n", 119 | " long_cond1 = (df['squeeze_off'][-2] == False) & (df['squeeze_off'][-1] == True) \n", 120 | " # 2. bar value is positive => the bar is light green k\n", 121 | " long_cond2 = df['value'][-1] > 0\n", 122 | " enter_long = long_cond1 and long_cond2\n", 123 | "\n", 124 | " # buying window for short position:\n", 125 | " # 1. black cross becomes gray (the squeeze is released)\n", 126 | " short_cond1 = (df['squeeze_off'][-2] == False) & (df['squeeze_off'][-1] == True) \n", 127 | " # 2. bar value is negative => the bar is light red \n", 128 | " short_cond2 = df['value'][-1] < 0\n", 129 | " enter_short = short_cond1 and short_cond2\n", 130 | "\n", 131 | " if enter_long | enter_short:\n", 132 | " screened_list.append(stock_code)\n", 133 | "\n", 134 | "if screened_list:\n", 135 | " print(screened_list)\n", 136 | "else:\n", 137 | " print('No stock fits the Squeeze Momentum Indicator entry requirement')" 138 | ], 139 | "execution_count": 2, 140 | "outputs": [ 141 | { 142 | "output_type": "stream", 143 | "text": [ 144 | "[*********************100%***********************] 1 of 1 completed\n", 145 | "[*********************100%***********************] 1 of 1 completed\n", 146 | "[*********************100%***********************] 1 of 1 completed\n", 147 | "[*********************100%***********************] 1 of 1 completed\n", 148 | "No stock fits the Squeeze Momentum Indicator entry requirement\n" 149 | ], 150 | "name": "stdout" 151 | } 152 | ] 153 | }, 154 | { 155 | "cell_type": "code", 156 | "metadata": { 157 | "id": "ZeSijaFbbt1w", 158 | "colab": { 159 | "base_uri": "https://localhost:8080/", 160 | "height": 495 161 | }, 162 | "outputId": "5149ac0b-899f-4ff0-deea-05378f00a7dd" 163 | }, 164 | "source": [ 165 | "# to make the visualization better by only taking the last 100 rows of data\n", 166 | "df = df[-100:]\n", 167 | "\n", 168 | "# extract only ['Open', 'High', 'Close', 'Low'] from df\n", 169 | "ohcl = df[['Open', 'High', 'Close', 'Low']]\n", 170 | "\n", 171 | "# add colors for the 'value bar'\n", 172 | "colors = []\n", 173 | "for ind, val in enumerate(df['value']):\n", 174 | " if val >= 0:\n", 175 | " color = 'green'\n", 176 | " if val > df['value'][ind-1]:\n", 177 | " color = 'lime'\n", 178 | " else:\n", 179 | " color = 'maroon'\n", 180 | " if val < df['value'][ind-1]:\n", 181 | " color='red'\n", 182 | " colors.append(color)\n", 183 | " \n", 184 | "# add 2 subplots: 1. bars, 2. crosses\n", 185 | "apds = [mpf.make_addplot(df['value'], panel=1, type='bar', color=colors, alpha=0.8, secondary_y=False),\n", 186 | " mpf.make_addplot([0] * len(df), panel=1, type='scatter', marker='x', markersize=50, color=['gray' if s else 'black' for s in df['squeeze_off']], secondary_y=False)]\n", 187 | "\n", 188 | "# plot ohcl with subplots\n", 189 | "fig, axes = mpf.plot(ohcl, \n", 190 | " volume_panel = 2,\n", 191 | " figratio=(2,1),\n", 192 | " figscale=1, \n", 193 | " type='candle', \n", 194 | " addplot=apds,\n", 195 | " returnfig=True)" 196 | ], 197 | "execution_count": 3, 198 | "outputs": [ 199 | { 200 | "output_type": "display_data", 201 | "data": { 202 | "image/png": "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7ilJIiIiOp2SpLPj6cltA/RgAvCH34nkqVOnNHDgQH3rW9/qcPn48eN10UUXcZ8koMAldL0pFW81Bw4d6fI/URL/GQLQc315vghEksr5D0B/8zuRHDRokBobGztNFEtLS3X+/HmvnkogXIVSQmeGUOopBYALWSmpa1tJ9sixz/2uJgsAF/I7kczNzZVhGPrRj36kXbt2qbm5WZL09ttva9u2bbrrrrtks9l0xRVXmBYsgNDgb2IdTEPRAJiDC08AYE1+J5Lz589vHWZWVqYlS5aooaFBknTXXXdp/fr1qq2tlc1m08KFC00LFkB4s9JVfgD9gxEdX+FiGgAr8TuRnDx5slauXKnY2FgZhtHuERsbq1/84hfKy8szM14AAICwxMU0AFbi9zySknTTTTfp2muv1VtvvaWPP/5YDQ0NiouLU3Z2tqZPny673W5WnABCnN1uV01NtWdOWs4fAMKJe4oPl8ulxMShgQ4HALrVq0RSkgYPHqzZs2ebEYskyeVy6bnnntOrr76qY8eO6aKLLtKVV16pwsJCjRgxot36W7du1YYNG7RixQqvOE6dOqWVK1fqnXfeUWNjoy6//HI98MADmjBhgmcdp9Op9evXa/fu3aqrq9PIkSO1YMECffe73zXteAD0jLsARHZ6ksoqawMbDICAy8vNUn39GblcLmWnJykhYUinFZtDgfvYNm1YTc8jgKDg99BWSWpsbNSGDRu0efNmr9fvuOMOPf744/riiy983ueqVau0adMmLVy4ULt379a6detUWlqqefPmyel0eq179OhRbdu2rd0+nE6n7rjjDh0/flzbt2/XK6+8ooyMDN155506fvy4Z73HHntMO3fuVFFRkXbv3q1bb71Vjz76qEpKSnyOGwAAmKe+/oy+bHTK2dSsLxudqq8/E+iQ+gVJJIBg4Xcief78ed1666166qmndOrUKa9lZ86c0Ysvvqg5c+Z4ivD0RHNzs9544w0tWLBAN998s0aOHKlrrrlGixYt0okTJ1RWVuZZ1+Vy6ZFHHtGsWbPa7aekpETl5eVas2aNxo0bp+zsbBUXFys+Pl5PP/20JKmqqko7d+5UQUGBrrvuOqWlpem2227TjBkz9MQTT/j5qQD9L5gqGublZik7PUkul0t5uVmBDgcAwgaFegCYze9Ecvv27frb3/4mwzB00UUXeS0bNmyYDMPQ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C9t529+Dzn4HOnt904bVWv8fyztc1le/Xz3d74Vt6u/19a3bR0aqubnZlFis7KzDoYsvHuZ5fvr06Xaf1dKlS7v9XjgvfoXzFMxGm4LZrNSmGhqieryuZRPJ+fPna9asWTp8+LDWrVuniooKbdu2TQMGDPCs88knn+jOO+9USkqK1q5d26/xVZysV2xsU7++p79sttYGWnGyXoYR6Gh6r7nF5fW8vKo+QJGEr1BrU1ZjGFKLy/B6fmE7b/t70NnvQFe/G50t66vfr+72212bWrS4MCx+13vy3f+/+T/u8LPYtH61Nm1YrZaWFkVGRmrR4sIe9zyHIs5TMBttCmazYps6d66hx+taNpFMTExUYmKiRo8erYyMDN1yyy16/fXX9Z3vfEdS6xQgd999t0aPHq2tW7dq8ODBnm3tdrvXdCFu7sIE8fHxnntLzp496zVU1t0TGR8f32V8hiHLfOE9FYwx90QoHlOwCNU2ZQkXfK5dfc6dLfNnG3/X64p7ig6Xy6WIiAglJAzpMuaOlt27uDB82poP331b9y4u1L2LC5WdnqSyylqftg1lnKdgNtoUzGalNuVLHJYqtlNXV6eSkhKvaTwkacyYMZKko0ePSpL++te/auHChfrGN76h5557ziuJlKTMzEx99tlnamry7jGsrKxUVFSURo0apczMTEnSsWPHvNZx3zs5evRo8w4MAHzgLqrifpg9oX1/aztFR1llbafTdAAAgOBhqUSysbFRBQUF2rVrl9frH330kaTW6qyff/657rrrLl1zzTV64oknFB0d3W4/06ZNU2Njo959912v19966y1NmTJFUVFRmjRpkux2u6dQj9ubb76phIQET+EeAOhv7gnt3Q9/JrRHcOppZVYAAALNUkNbU1NTNXv2bG3dulWJiYmaPHmyqqqqtHz5ciUnJ+uGG27Qf/zHf8jpdOqnP/2p6urqvLaPiopSQkKCxo8fr/z8fBUXF2vFihUaPny4XnjhBR09elTLl7cWmIiOjtbdd9+t9evXa8yYMZo8ebIOHDigl156SUuWLFFUVM9vNAUAq5iYky6Ho03VT7vdKxGdmJPumdD+wmUdDUE1kxXnerQa9/exacNqS05pAgCAm6USSUkqLi5WSkqKtmzZotOnTyspKUmTJk1SQUGB4uPjtX//fjkcDn37299ut+03vvEN7dixQ5K0du1a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\n", 203 | "text/plain": [ 204 | "
" 205 | ] 206 | }, 207 | "metadata": { 208 | "tags": [] 209 | } 210 | } 211 | ] 212 | } 213 | ] 214 | } -------------------------------------------------------------------------------- /automate_stock_screener_demo.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "automate-stock-screener-demo.ipynb", 7 | "provenance": [], 8 | "collapsed_sections": [], 9 | "authorship_tag": "ABX9TyPclecTAnBBunNXKyPKq9Lh", 10 | "include_colab_link": true 11 | }, 12 | "kernelspec": { 13 | "name": "python3", 14 | "display_name": "Python 3" 15 | }, 16 | "language_info": { 17 | "name": "python" 18 | } 19 | }, 20 | "cells": [ 21 | { 22 | "cell_type": "markdown", 23 | "metadata": { 24 | "id": "view-in-github", 25 | "colab_type": "text" 26 | }, 27 | "source": [ 28 | "\"Open" 29 | ] 30 | }, 31 | { 32 | "cell_type": "markdown", 33 | "metadata": { 34 | "id": "4YGeoERrc3Lb" 35 | }, 36 | "source": [ 37 | "A demo Colab Notebook for my article: \n", 38 | "https://levelup.gitconnected.com/automate-your-stock-screening-using-python-9107dda724c3" 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "metadata": { 44 | "id": "9EmMPYxT_iXX" 45 | }, 46 | "source": [ 47 | "# install required libraries (on colab)\n", 48 | "!pip install yfinance\n", 49 | "!pip install bs4\n", 50 | "!pip install requests\n", 51 | "# import required libraries \n", 52 | "import requests\n", 53 | "from bs4 import BeautifulSoup\n", 54 | "import yfinance as yf\n", 55 | "import email\n", 56 | "import pandas as pd" 57 | ], 58 | "execution_count": null, 59 | "outputs": [] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "metadata": { 64 | "id": "qG87rhOC-xih" 65 | }, 66 | "source": [ 67 | "def get_stock_list():\n", 68 | " # this is the website we're going to scrape from\n", 69 | " url = \"https://www.malaysiastock.biz/Stock-Screener.aspx\"\n", 70 | " response = requests.get(url, headers={'User-Agent':'test'})\n", 71 | " soup = BeautifulSoup(response.content, \"html.parser\")\n", 72 | " table = soup.find(id = \"MainContent2_tbAllStock\")\n", 73 | " # return the result (only ticker code) in a list\n", 74 | " stock_list = table.find_all('a')\n", 75 | " return [stock_code.get('href')[-4:] for stock_code in stock_list]\n", 76 | "\n", 77 | "def get_stock_price(code):\n", 78 | " # you can change the start date\n", 79 | " data = yf.download(code, start=\"2021-01-01\", threads= False)\n", 80 | " return data\n", 81 | "\n", 82 | "def add_EMA(price, day):\n", 83 | " return price.ewm(span=day).mean()\n", 84 | "\n", 85 | "def add_STOCH(close, low, high, period, k, d=0): \n", 86 | " STOCH_K = ((close - low.rolling(window=period).min()) / (high.rolling(window=period).max() - low.rolling(window=period).min())) * 100\n", 87 | " STOCH_K = STOCH_K.rolling(window=k).mean()\n", 88 | " if d == 0:\n", 89 | " return STOCH_K\n", 90 | " else:\n", 91 | " STOCH_D = STOCH_K.rolling(window=d).mean()\n", 92 | " return STOCH_D\n", 93 | "\n", 94 | "def check_bounce_EMA(df):\n", 95 | " candle1 = df.iloc[-1]\n", 96 | " candle2 = df.iloc[-2]\n", 97 | " cond1 = candle1['EMA18'] > candle1['EMA50'] > candle1['EMA100']\n", 98 | " cond2 = candle1['STOCH_%K(5,3,3)'] <= 30 or candle1['STOCH_%D(5,3,3)'] <= 30\n", 99 | " cond3 = candle2['Low'] < candle2['EMA50'] and \\\n", 100 | " candle2['Close'] > candle2['EMA50'] and \\\n", 101 | " candle1['Low'] > candle1 ['EMA50']\n", 102 | " return cond1 and cond2 and cond3\n", 103 | "\n", 104 | "# a list to store the screened results\n", 105 | "screened_list = [] \n", 106 | "# get the full stock list\n", 107 | "stock_list = get_stock_list()\n", 108 | "for stock_code in stock_list:\n", 109 | "\n", 110 | " print(stock_code) # remove this if you dont want the ticker to be printed\n", 111 | " try: \n", 112 | " # Step 1: get stock price for each stock\n", 113 | " price_chart_df = get_stock_price(stock_code + \".KL\") # edit/remove \".KL\" for other exchange market\n", 114 | "\n", 115 | " # Step 2: add technical indicators (in this case EMA)\n", 116 | " close = price_chart_df['Close']\n", 117 | " low = price_chart_df['Low']\n", 118 | " open = price_chart_df['Open']\n", 119 | " high = price_chart_df['High']\n", 120 | " price_chart_df['EMA18'] = add_EMA(close,18)\n", 121 | " price_chart_df['EMA50'] = add_EMA(close,50)\n", 122 | " price_chart_df['EMA100'] = add_EMA(close,100)\n", 123 | " price_chart_df['STOCH_%K(5,3,3)'] = add_STOCH(close, low, high, 5, 3)\n", 124 | " price_chart_df['STOCH_%D(5,3,3)'] = add_STOCH(close, low, high, 5, 3, 3)\n", 125 | "\n", 126 | " # if all 3 conditions are met, add stock into screened list\n", 127 | " if check_bounce_EMA(price_chart_df):\n", 128 | " screened_list.append(stock_code)\n", 129 | " print(screened_list)\n", 130 | " except Exception as e:\n", 131 | " print(e)\n", 132 | "\n", 133 | "## this cell may take a few minutes to finish" 134 | ], 135 | "execution_count": null, 136 | "outputs": [] 137 | }, 138 | { 139 | "cell_type": "code", 140 | "metadata": { 141 | "id": "TD3iwcVT_o19" 142 | }, 143 | "source": [ 144 | "# configure email and message\n", 145 | "msg = email.message_from_string(\", \".join(screened_list))\n", 146 | "msg['From'] = 'YOUR_EMAIL@gmail.com' # change to your email \n", 147 | "msg['To'] = 'YOUR_EMAIL@gmail.com'\n", 148 | "msg['Subject'] = \"EMA Bounce Result for Today!\"\n", 149 | "\n", 150 | "s = smtplib.SMTP(\"smtp.gmail.com\",587)\n", 151 | "## for yahoo mail user: s = smtplib.SMTP(\"smtp.mail.yahoo.com\",587) \n", 152 | "## for hotmail user: s = smtplib.SMTP(\"smtp.live.com\",587)\n", 153 | "s.ehlo() \n", 154 | "s.starttls()\n", 155 | "s.ehlo()\n", 156 | "s.login(email_from,\"YOUR_PASSWORD\") # change to your password\n", 157 | "s.sendmail(email_from, [email_to] + [email_cc], msg.as_string())\n", 158 | "s.quit()" 159 | ], 160 | "execution_count": null, 161 | "outputs": [] 162 | }, 163 | { 164 | "cell_type": "code", 165 | "metadata": { 166 | "id": "vcIveOlyI3h_" 167 | }, 168 | "source": [ 169 | "# for US stock list\n", 170 | "# credit to https://github.com/shilewenuw/get_all_tickers/issues/12\n", 171 | "def get_US_stock_list(exchange):\n", 172 | " headers = {\n", 173 | " 'authority': 'api.nasdaq.com',\n", 174 | " 'accept': 'application/json, text/plain, */*',\n", 175 | " 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36',\n", 176 | " 'origin': 'https://www.nasdaq.com',\n", 177 | " 'sec-fetch-site': 'same-site',\n", 178 | " 'sec-fetch-mode': 'cors',\n", 179 | " 'sec-fetch-dest': 'empty',\n", 180 | " 'referer': 'https://www.nasdaq.com/',\n", 181 | " 'accept-language': 'en-US,en;q=0.9',\n", 182 | " }\n", 183 | "\n", 184 | " params = (\n", 185 | " ('tableonly', 'true'),\n", 186 | " ('limit', '25'),\n", 187 | " ('offset', '0'),\n", 188 | " ('download', 'true'),\n", 189 | " ('exchange', exchange)\n", 190 | " )\n", 191 | "\n", 192 | " r = requests.get('https://api.nasdaq.com/api/screener/stocks', headers=headers, params=params)\n", 193 | " data = r.json()['data']\n", 194 | " df = pd.DataFrame(data['rows'], columns=data['headers'])\n", 195 | " df_filtered = df[~df['symbol'].str.contains(\"\\.|\\^|\\s\")]\n", 196 | " return df_filtered['symbol'].tolist()\n", 197 | "\n", 198 | "stock_list = get_US_stock_list('nyse') # or 'nasdaq' or 'amex'" 199 | ], 200 | "execution_count": null, 201 | "outputs": [] 202 | } 203 | ] 204 | } -------------------------------------------------------------------------------- /dataset/symbols.csv: -------------------------------------------------------------------------------- 1 | Symbol, Company Name 2 | MMM,3M Company 3 | ABT,Abbott Laboratories 4 | ABBV,AbbVie Inc. 5 | ABMD,ABIOMED Inc 6 | ACN,Accenture plc 7 | ATVI,Activision Blizzard 8 | ADBE,Adobe Systems Inc 9 | AMD,Advanced Micro Devices Inc 10 | AAP,Advance Auto Parts 11 | AES,AES Corp 12 | AFL,AFLAC Inc 13 | A,Agilent Technologies Inc 14 | APD,Air Products & Chemicals Inc 15 | AKAM,Akamai Technologies Inc 16 | ALK,Alaska Air Group Inc 17 | ALB,Albemarle Corp 18 | ARE,Alexandria Real Estate Equities 19 | ALXN,Alexion Pharmaceuticals 20 | ALGN,Align Technology 21 | ALLE,Allegion 22 | AGN,"Allergan, plc" 23 | ADS,Alliance Data Systems 24 | LNT,Alliant Energy Corp 25 | ALL,Allstate Corp 26 | GOOGL,Alphabet Inc Class A 27 | GOOG,Alphabet Inc Class C 28 | MO,Altria Group Inc 29 | AMZN,Amazon.com Inc. 30 | AMCR,Amcor plc 31 | AEE,Ameren Corp 32 | AAL,American Airlines Group 33 | AEP,American Electric Power 34 | AXP,American Express Co 35 | AIG,American International Group 36 | AMT,American Tower Corp. 37 | AWK,American Water Works Company Inc 38 | AMP,Ameriprise Financial 39 | ABC,AmerisourceBergen Corp 40 | AME,AMETEK Inc. 41 | AMGN,Amgen Inc. 42 | APH,Amphenol Corp 43 | ADI,"Analog Devices, Inc." 44 | ANSS,ANSYS 45 | ANTM,Anthem 46 | AON,Aon plc 47 | AOS,A.O. Smith Corp 48 | APA,Apache Corporation 49 | AIV,Apartment Investment & Management 50 | AAPL,Apple Inc. 51 | AMAT,Applied Materials Inc. 52 | APTV,Aptiv PLC 53 | ADM,Archer-Daniels-Midland Co 54 | ARNC,Arconic Inc. 55 | ANET,Arista Networks 56 | AJG,Arthur J. Gallagher & Co. 57 | AIZ,Assurant 58 | ATO,Atmos Energy Corp 59 | T,AT&T Inc. 60 | ADSK,Autodesk Inc. 61 | ADP,Automatic Data Processing 62 | AZO,AutoZone Inc 63 | AVB,"AvalonBay Communities, Inc." 64 | AVY,Avery Dennison Corp 65 | BKR,Baker Hughes Co 66 | BLL,Ball Corp 67 | BAC,Bank of America Corp 68 | BK,The Bank of New York Mellon Corp. 69 | BAX,Baxter International Inc. 70 | BDX,Becton Dickinson 71 | BRK.B,Berkshire Hathaway 72 | BBY,Best Buy Co. Inc. 73 | BIIB,Biogen Inc. 74 | BLK,BlackRock 75 | BA,Boeing Company 76 | BKNG,Booking Holdings Inc 77 | BWA,BorgWarner 78 | BXP,Boston Properties 79 | BSX,Boston Scientific 80 | BMY,Bristol-Myers Squibb 81 | AVGO,Broadcom Inc. 82 | BR,Broadridge Financial Solutions 83 | BF.B,Brown-Forman Corp. 84 | CHRW,C. H. Robinson Worldwide 85 | COG,Cabot Oil & Gas 86 | CDNS,Cadence Design Systems 87 | CPB,Campbell Soup 88 | COF,Capital One Financial 89 | CPRI,Capri Holdings 90 | CAH,Cardinal Health Inc. 91 | KMX,Carmax Inc 92 | CCL,Carnival Corp. 93 | CAT,Caterpillar Inc. 94 | CBOE,Cboe Global Markets 95 | CBRE,CBRE Group 96 | CDW,CDW 97 | CE,Celanese 98 | CNC,Centene Corporation 99 | CNP,CenterPoint Energy 100 | CTL,CenturyLink Inc 101 | CERN,Cerner 102 | CF,CF Industries Holdings Inc 103 | SCHW,Charles Schwab Corporation 104 | CHTR,Charter Communications 105 | CVX,Chevron Corp. 106 | CMG,Chipotle Mexican Grill 107 | CB,Chubb Limited 108 | CHD,Church & Dwight 109 | CI,CIGNA Corp. 110 | XEC,Cimarex Energy 111 | CINF,Cincinnati Financial 112 | CTAS,Cintas Corporation 113 | CSCO,Cisco Systems 114 | C,Citigroup Inc. 115 | CFG,Citizens Financial Group 116 | CTXS,Citrix Systems 117 | CLX,The Clorox Company 118 | CME,CME Group Inc. 119 | CMS,CMS Energy 120 | KO,Coca-Cola Company 121 | CTSH,Cognizant Technology Solutions 122 | CL,Colgate-Palmolive 123 | CMCSA,Comcast Corp. 124 | CMA,Comerica Inc. 125 | CAG,Conagra Brands 126 | CXO,Concho Resources 127 | COP,ConocoPhillips 128 | ED,Consolidated Edison 129 | STZ,Constellation Brands 130 | COO,The Cooper Companies 131 | CPRT,Copart Inc 132 | GLW,Corning Inc. 133 | CTVA,Corteva 134 | COST,Costco Wholesale Corp. 135 | COTY,"Coty, Inc" 136 | CCI,Crown Castle International Corp. 137 | CSX,CSX Corp. 138 | CMI,Cummins Inc. 139 | CVS,CVS Health 140 | DHI,D. R. Horton 141 | DHR,Danaher Corp. 142 | DRI,Darden Restaurants 143 | DVA,DaVita Inc. 144 | DE,Deere & Co. 145 | DAL,Delta Air Lines Inc. 146 | XRAY,Dentsply Sirona 147 | DVN,Devon Energy 148 | FANG,Diamondback Energy 149 | DLR,Digital Realty Trust Inc 150 | DFS,Discover Financial Services 151 | DISCA,Discovery Inc. Class A 152 | DISCK,Discovery Inc. Class C 153 | DISH,Dish Network 154 | DG,Dollar General 155 | DLTR,Dollar Tree 156 | D,Dominion Energy 157 | DOV,Dover Corp. 158 | DOW,Dow Inc. 159 | DTE,DTE Energy Co. 160 | DUK,Duke Energy 161 | DRE,Duke Realty Corp 162 | DD,DuPont de Nemours Inc 163 | DXC,DXC Technology 164 | ETFC,E*Trade 165 | EMN,Eastman Chemical 166 | ETN,Eaton Corporation 167 | EBAY,eBay Inc. 168 | ECL,Ecolab Inc. 169 | EIX,Edison Int'l 170 | EW,Edwards Lifesciences 171 | EA,Electronic Arts 172 | EMR,Emerson Electric Company 173 | ETR,Entergy Corp. 174 | EOG,EOG Resources 175 | EFX,Equifax Inc. 176 | EQIX,Equinix 177 | EQR,Equity Residential 178 | ESS,"Essex Property Trust, Inc." 179 | EL,Estee Lauder Cos. 180 | EVRG,Evergy 181 | ES,Eversource Energy 182 | RE,Everest Re Group Ltd. 183 | EXC,Exelon Corp. 184 | EXPE,Expedia Group 185 | EXPD,Expeditors 186 | EXR,Extra Space Storage 187 | XOM,Exxon Mobil Corp. 188 | FFIV,F5 Networks 189 | FB,"Facebook, Inc." 190 | FAST,Fastenal Co 191 | FRT,Federal Realty Investment Trust 192 | FDX,FedEx Corporation 193 | FIS,Fidelity National Information Services 194 | FITB,Fifth Third Bancorp 195 | FE,FirstEnergy Corp 196 | FRC,First Republic Bank 197 | FISV,Fiserv Inc 198 | FLT,FleetCor Technologies Inc 199 | FLIR,FLIR Systems 200 | FLS,Flowserve Corporation 201 | FMC,FMC Corporation 202 | F,Ford Motor 203 | FTNT,Fortinet 204 | FTV,Fortive Corp 205 | FBHS,Fortune Brands Home & Security 206 | FOXA,Fox Corporation Class A 207 | FOX,Fox Corporation Class B 208 | BEN,Franklin Resources 209 | FCX,Freeport-McMoRan Inc. 210 | GPS,Gap Inc. 211 | GRMN,Garmin Ltd. 212 | IT,Gartner Inc 213 | GD,General Dynamics 214 | GE,General Electric 215 | GIS,General Mills 216 | GM,General Motors 217 | GPC,Genuine Parts 218 | GILD,Gilead Sciences 219 | GL,Globe Life Inc. 220 | GPN,Global Payments Inc. 221 | GS,Goldman Sachs Group 222 | GWW,Grainger (W.W.) Inc. 223 | HRB,H&R Block 224 | HAL,Halliburton Co. 225 | HBI,Hanesbrands Inc 226 | HOG,Harley-Davidson 227 | HIG,Hartford Financial Svc.Gp. 228 | HAS,Hasbro Inc. 229 | HCA,HCA Healthcare 230 | PEAK,Healthpeak Properties 231 | HP,Helmerich & Payne 232 | HSIC,Henry Schein 233 | HSY,The Hershey Company 234 | HES,Hess Corporation 235 | HPE,Hewlett Packard Enterprise 236 | HLT,Hilton Worldwide Holdings Inc 237 | HFC,HollyFrontier Corp 238 | HOLX,Hologic 239 | HD,Home Depot 240 | HON,Honeywell Int'l Inc. 241 | HRL,Hormel Foods Corp. 242 | HST,Host Hotels & Resorts 243 | HPQ,HP Inc. 244 | HUM,Humana Inc. 245 | HBAN,Huntington Bancshares 246 | HII,Huntington Ingalls Industries 247 | IEX,IDEX Corporation 248 | IDXX,IDEXX Laboratories 249 | INFO,IHS Markit Ltd. 250 | ITW,Illinois Tool Works 251 | ILMN,Illumina Inc 252 | IR,Ingersoll-Rand PLC 253 | INTC,Intel Corp. 254 | ICE,Intercontinental Exchange 255 | IBM,International Business Machines 256 | INCY,Incyte 257 | IP,International Paper 258 | IPG,Interpublic Group 259 | IFF,Intl Flavors & Fragrances 260 | INTU,Intuit Inc. 261 | ISRG,Intuitive Surgical Inc. 262 | IVZ,Invesco Ltd. 263 | IPGP,IPG Photonics Corp. 264 | IQV,IQVIA Holdings Inc. 265 | IRM,Iron Mountain Incorporated 266 | JKHY,Jack Henry & Associates 267 | J,Jacobs Engineering Group 268 | JBHT,J. B. Hunt Transport Services 269 | SJM,JM Smucker 270 | JNJ,Johnson & Johnson 271 | JCI,Johnson Controls International 272 | JPM,JPMorgan Chase & Co. 273 | JNPR,Juniper Networks 274 | KSU,Kansas City Southern 275 | K,Kellogg Co. 276 | KEY,KeyCorp 277 | KEYS,Keysight Technologies 278 | KMB,Kimberly-Clark 279 | KIM,Kimco Realty 280 | KMI,Kinder Morgan 281 | KLAC,KLA Corporation 282 | KSS,Kohl's Corp. 283 | KHC,Kraft Heinz Co 284 | KR,Kroger Co. 285 | LB,L Brands Inc. 286 | LHX,L3Harris Technologies 287 | LH,Laboratory Corp. of America Holding 288 | LRCX,Lam Research 289 | LW,Lamb Weston Holdings Inc 290 | LVS,Las Vegas Sands 291 | LEG,Leggett & Platt 292 | LDOS,Leidos Holdings 293 | LEN,Lennar Corp. 294 | LLY,Lilly (Eli) & Co. 295 | LNC,Lincoln National 296 | LIN,Linde plc 297 | LYV,Live Nation Entertainment 298 | LKQ,LKQ Corporation 299 | LMT,Lockheed Martin Corp. 300 | L,Loews Corp. 301 | LOW,Lowe's Cos. 302 | LYB,LyondellBasell 303 | MTB,M&T Bank Corp. 304 | M,Macy's Inc. 305 | MRO,Marathon Oil Corp. 306 | MPC,Marathon Petroleum 307 | MKTX,MarketAxess 308 | MAR,Marriott Int'l. 309 | MMC,Marsh & McLennan 310 | MLM,Martin Marietta Materials 311 | MAS,Masco Corp. 312 | MA,Mastercard Inc. 313 | MKC,McCormick & Co. 314 | MXIM,Maxim Integrated Products Inc 315 | MCD,McDonald's Corp. 316 | MCK,McKesson Corp. 317 | MDT,Medtronic plc 318 | MRK,Merck & Co. 319 | MET,MetLife Inc. 320 | MTD,Mettler Toledo 321 | MGM,MGM Resorts International 322 | MCHP,Microchip Technology 323 | MU,Micron Technology 324 | MSFT,Microsoft Corp. 325 | MAA,Mid-America Apartments 326 | MHK,Mohawk Industries 327 | TAP,Molson Coors Brewing Company 328 | MDLZ,Mondelez International 329 | MNST,Monster Beverage 330 | MCO,Moody's Corp 331 | MS,Morgan Stanley 332 | MOS,The Mosaic Company 333 | MSI,Motorola Solutions Inc. 334 | MSCI,MSCI Inc 335 | MYL,Mylan N.V. 336 | NDAQ,"Nasdaq, Inc." 337 | NOV,National Oilwell Varco Inc. 338 | NTAP,NetApp 339 | NFLX,Netflix Inc. 340 | NWL,Newell Brands 341 | NEM,Newmont Goldcorp 342 | NWSA,News Corp. Class A 343 | NWS,News Corp. Class B 344 | NEE,NextEra Energy 345 | NLSN,Nielsen Holdings 346 | NKE,Nike 347 | NI,NiSource Inc. 348 | NBL,Noble Energy Inc 349 | JWN,Nordstrom 350 | NSC,Norfolk Southern Corp. 351 | NTRS,Northern Trust Corp. 352 | NOC,Northrop Grumman 353 | NLOK,NortonLifeLock 354 | NCLH,Norwegian Cruise Line Holdings 355 | NRG,NRG Energy 356 | NUE,Nucor Corp. 357 | NVDA,Nvidia Corporation 358 | NVR,NVR Inc 359 | ORLY,O'Reilly Automotive 360 | OXY,Occidental Petroleum 361 | ODFL,Old Dominion Freight Line 362 | OMC,Omnicom Group 363 | OKE,ONEOK 364 | ORCL,Oracle Corp. 365 | PCAR,PACCAR Inc. 366 | PKG,Packaging Corporation of America 367 | PH,Parker-Hannifin 368 | PAYX,Paychex Inc. 369 | PYPL,PayPal 370 | PNR,Pentair plc 371 | PBCT,People's United Financial 372 | PEP,PepsiCo Inc. 373 | PKI,PerkinElmer 374 | PRGO,Perrigo 375 | PFE,Pfizer Inc. 376 | PM,Philip Morris International 377 | PSX,Phillips 66 378 | PNW,Pinnacle West Capital 379 | PXD,Pioneer Natural Resources 380 | PNC,PNC Financial Services 381 | PPG,PPG Industries 382 | PPL,PPL Corp. 383 | PFG,Principal Financial Group 384 | PG,Procter & Gamble 385 | PGR,Progressive Corp. 386 | PLD,Prologis 387 | PRU,Prudential Financial 388 | PEG,Public Serv. Enterprise Inc. 389 | PSA,Public Storage 390 | PHM,Pulte Homes Inc. 391 | PVH,PVH Corp. 392 | QRVO,Qorvo 393 | PWR,Quanta Services Inc. 394 | QCOM,QUALCOMM Inc. 395 | DGX,Quest Diagnostics 396 | RL,Ralph Lauren Corporation 397 | RJF,Raymond James Financial Inc. 398 | RTN,Raytheon Co. 399 | O,Realty Income Corporation 400 | REG,Regency Centers Corporation 401 | REGN,Regeneron Pharmaceuticals 402 | RF,Regions Financial Corp. 403 | RSG,Republic Services Inc 404 | RMD,ResMed 405 | RHI,Robert Half International 406 | ROK,Rockwell Automation Inc. 407 | ROL,Rollins Inc. 408 | ROP,Roper Technologies 409 | ROST,Ross Stores 410 | RCL,Royal Caribbean Cruises Ltd 411 | SPGI,"S&P Global, Inc." 412 | CRM,Salesforce.com 413 | SBAC,SBA Communications 414 | SLB,Schlumberger Ltd. 415 | STX,Seagate Technology 416 | SEE,Sealed Air 417 | SRE,Sempra Energy 418 | NOW,ServiceNow 419 | SHW,Sherwin-Williams 420 | SPG,Simon Property Group Inc 421 | SWKS,Skyworks Solutions 422 | SLG,SL Green Realty 423 | SNA,Snap-on 424 | SO,Southern Co. 425 | LUV,Southwest Airlines 426 | SWK,Stanley Black & Decker 427 | SBUX,Starbucks Corp. 428 | STT,State Street Corp. 429 | STE,STERIS plc 430 | SYK,Stryker Corp. 431 | SIVB,SVB Financial 432 | SYF,Synchrony Financial 433 | SNPS,Synopsys Inc. 434 | SYY,Sysco Corp. 435 | TMUS,T-Mobile US 436 | TROW,T. Rowe Price Group 437 | TTWO,Take-Two Interactive 438 | TPR,"Tapestry, Inc." 439 | TGT,Target Corp. 440 | TEL,TE Connectivity Ltd. 441 | FTI,TechnipFMC 442 | TFX,Teleflex 443 | TXN,Texas Instruments 444 | TXT,Textron Inc. 445 | TMO,Thermo Fisher Scientific 446 | TIF,Tiffany & Co. 447 | TJX,TJX Companies Inc. 448 | TSCO,Tractor Supply Company 449 | TDG,TransDigm Group 450 | TRV,The Travelers Companies Inc. 451 | TFC,Truist Financial 452 | TWTR,"Twitter, Inc." 453 | TSN,Tyson Foods 454 | UDR,"UDR, Inc." 455 | ULTA,Ulta Beauty 456 | USB,U.S. Bancorp 457 | UAA,Under Armour Class A 458 | UA,Under Armour Class C 459 | UNP,Union Pacific Corp 460 | UAL,United Airlines Holdings 461 | UNH,United Health Group Inc. 462 | UPS,United Parcel Service 463 | URI,"United Rentals, Inc." 464 | UTX,United Technologies 465 | UHS,"Universal Health Services, Inc." 466 | UNM,Unum Group 467 | VFC,V.F. Corp. 468 | VLO,Valero Energy 469 | VAR,Varian Medical Systems 470 | VTR,Ventas Inc 471 | VRSN,Verisign Inc. 472 | VRSK,Verisk Analytics 473 | VZ,Verizon Communications 474 | VRTX,Vertex Pharmaceuticals Inc 475 | VIAC,ViacomCBS 476 | V,Visa Inc. 477 | VNO,Vornado Realty Trust 478 | VMC,Vulcan Materials 479 | WRB,W. R. Berkley Corporation 480 | WAB,Wabtec Corporation 481 | WMT,Walmart 482 | WBA,Walgreens Boots Alliance 483 | DIS,The Walt Disney Company 484 | WM,Waste Management Inc. 485 | WAT,Waters Corporation 486 | WEC,Wec Energy Group Inc 487 | WCG,WellCare 488 | WFC,Wells Fargo 489 | WELL,Welltower Inc. 490 | WDC,Western Digital 491 | WU,Western Union Co 492 | WRK,WestRock 493 | WY,Weyerhaeuser 494 | WHR,Whirlpool Corp. 495 | WMB,Williams Cos. 496 | WLTW,Willis Towers Watson 497 | WYNN,Wynn Resorts Ltd 498 | XEL,Xcel Energy Inc 499 | XRX,Xerox 500 | XLNX,Xilinx 501 | XYL,Xylem Inc. 502 | YUM,Yum! Brands Inc 503 | ZBRA,Zebra Technologies 504 | ZBH,Zimmer Biomet Holdings 505 | ZION,Zions Bancorp 506 | ZTS,Zoetis -------------------------------------------------------------------------------- /simple_technical_analysis_stock_screener_demo.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "simple-technical-analysis-stock-screener-demo.ipynb", 7 | "provenance": [], 8 | "authorship_tag": "ABX9TyOv5Rg0eovcgPOOu//hyU/J", 9 | "include_colab_link": true 10 | }, 11 | "kernelspec": { 12 | "name": "python3", 13 | "display_name": "Python 3" 14 | }, 15 | "language_info": { 16 | "name": "python" 17 | } 18 | }, 19 | "cells": [ 20 | { 21 | "cell_type": "markdown", 22 | "metadata": { 23 | "id": "view-in-github", 24 | "colab_type": "text" 25 | }, 26 | "source": [ 27 | "\"Open" 28 | ] 29 | }, 30 | { 31 | "cell_type": "markdown", 32 | "metadata": { 33 | "id": "vnhzHjCEeKmK" 34 | }, 35 | "source": [ 36 | "A demo Colab Notebook for my article: \n", 37 | "https://levelup.gitconnected.com/automate-your-stock-screening-using-python-9107dda724c3\n" 38 | ] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "metadata": { 43 | "id": "t_3iZkcseOYp" 44 | }, 45 | "source": [ 46 | "# install required libraries (on colab)\n", 47 | "!pip install bs4\n", 48 | "!pip install requests\n", 49 | "# import required libraries \n", 50 | "from bs4 import BeautifulSoup\n", 51 | "import ast\n", 52 | "import pandas as pd\n", 53 | "import re\n", 54 | "import requests\n", 55 | "from datetime import datetime" 56 | ], 57 | "execution_count": null, 58 | "outputs": [] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "metadata": { 63 | "id": "FUUL-MhDd_xd" 64 | }, 65 | "source": [ 66 | "def get_stock_price(ticker):\n", 67 | " # pass a ticker name to i3investor website url\n", 68 | " url = \"https://klse.i3investor.com/servlets/stk/chart/{}.jsp\". format(ticker)\n", 69 | " # get response from the site and extract the price data\n", 70 | " response = requests.get(url, headers={'User-Agent':'test'})\n", 71 | " soup = BeautifulSoup(response.content, \"html.parser\")\n", 72 | " script = soup.find_all('script')\n", 73 | " data_tag = script[19].contents[0] #changed to 19 from 20\n", 74 | " chart_data = ast.literal_eval(re.findall('\\[(.*)\\]', data_tag.split(';')[0])[0])\n", 75 | " # tabulate the price data into a dataframe\n", 76 | " chart_df = pd.DataFrame(chart_data, columns = ['Date', 'Open', 'High', 'Low', 'Close', 'Volume'])\n", 77 | " # convert timestamp into readable date\n", 78 | " chart_df['Date'] = chart_df['Date'].apply(lambda x: \\\n", 79 | " datetime.utcfromtimestamp(int(x)/1000).strftime('%Y-%m-%d'))\n", 80 | " return chart_df\n", 81 | "\n", 82 | "def add_EMA(price, day):\n", 83 | " return price.ewm(span=day).mean()\n", 84 | "\n", 85 | "def get_stock_list():\n", 86 | " # this is the website we're going to scrape from\n", 87 | " url = \"https://www.malaysiastock.biz/Stock-Screener.aspx\"\n", 88 | " response = requests.get(url, headers={'User-Agent':'test'})\n", 89 | " soup = BeautifulSoup(response.content, \"html.parser\")\n", 90 | " table = soup.find(id = \"MainContent2_tbAllStock\")\n", 91 | " # return the result in a list\n", 92 | " return [stock.getText() for stock in table.find_all('a')]\n", 93 | "\n", 94 | "# function to check for EMA crossing\n", 95 | "def check_EMA_crossing(df):\n", 96 | " # condition 1: EMA18 is higher than EMA50 at the last trading day\n", 97 | " cond_1 = df.iloc[-1]['EMA18'] > df.iloc[-1]['EMA50']\n", 98 | " # condition 2: EMA18 is lower than EMA50 the previous day\n", 99 | " cond_2 = df.iloc[-2]['EMA18'] < df.iloc[-2]['EMA50']\n", 100 | " # condition 3: to filter out stocks with less than 50 candles\n", 101 | " cond_3 = len(df.index) > 50 \n", 102 | " # will return True if all 3 conditions are met\n", 103 | " return (cond_1 and cond_2 and cond_3)\n", 104 | "\n", 105 | "# main program\n", 106 | "\n", 107 | "# a list to store the screened results\n", 108 | "screened_list = [] \n", 109 | "# get the full stock list\n", 110 | "stock_list = get_stock_list()\n", 111 | "for each_stock in stock_list:\n", 112 | " print(each_stock)\n", 113 | " # Step 1: get stock price for each stock\n", 114 | " price_chart_df = get_stock_price(each_stock)\n", 115 | " # Step 2: add technical indicators (in this case EMA)\n", 116 | " price_chart_df['EMA18']=add_EMA(price_chart_df['Close'],18)\n", 117 | " price_chart_df['EMA50']=add_EMA(price_chart_df['Close'],50)\n", 118 | " price_chart_df['EMA100']=add_EMA(price_chart_df['Close'],100)\n", 119 | " # if all 3 conditions are met, add stock into screened list\n", 120 | " if check_EMA_crossing(price_chart_df):\n", 121 | " screened_list.append(each_stock)\n", 122 | "print(screened_list)" 123 | ], 124 | "execution_count": null, 125 | "outputs": [] 126 | } 127 | ] 128 | } --------------------------------------------------------------------------------