├── .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 |
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 | "
"
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 | "
"
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 | "
"
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 | }
--------------------------------------------------------------------------------