mirror of
https://github.com/yongghongg/stock-screener.git
synced 2022-03-09 00:26:31 +03:00
Created using Colaboratory
This commit is contained in:
153
automate_stock_screener_demo.ipynb
Normal file
153
automate_stock_screener_demo.ipynb
Normal file
@@ -0,0 +1,153 @@
|
||||
{
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"name": "automate-stock-screener-demo.ipynb",
|
||||
"provenance": [],
|
||||
"collapsed_sections": [],
|
||||
"authorship_tag": "ABX9TyOomXNYRaW/aX9XcLOD2xsa",
|
||||
"include_colab_link": true
|
||||
},
|
||||
"kernelspec": {
|
||||
"name": "python3",
|
||||
"display_name": "Python 3"
|
||||
},
|
||||
"language_info": {
|
||||
"name": "python"
|
||||
}
|
||||
},
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "view-in-github",
|
||||
"colab_type": "text"
|
||||
},
|
||||
"source": [
|
||||
"<a href=\"https://colab.research.google.com/github/yongghongg/stock-screener/blob/main/automate_stock_screener_demo.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"metadata": {
|
||||
"id": "9EmMPYxT_iXX"
|
||||
},
|
||||
"source": [
|
||||
"# install and import required libraries\n",
|
||||
"!pip install yfinance\n",
|
||||
"!pip install bs4\n",
|
||||
"!pip install requests\n",
|
||||
"import requests\n",
|
||||
"from bs4 import BeautifulSoup\n",
|
||||
"import yfinance as yf\n",
|
||||
"import email"
|
||||
],
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"metadata": {
|
||||
"id": "qG87rhOC-xih"
|
||||
},
|
||||
"source": [
|
||||
"def get_stock_list():\n",
|
||||
" # this is the website we're going to scrape from\n",
|
||||
" url = \"https://www.malaysiastock.biz/Stock-Screener.aspx\"\n",
|
||||
" response = requests.get(url, headers={'User-Agent':'test'})\n",
|
||||
" soup = BeautifulSoup(response.content, \"html.parser\")\n",
|
||||
" table = soup.find(id = \"MainContent2_tbAllStock\")\n",
|
||||
" # return the result (only ticker code) in a list\n",
|
||||
" stock_list = table.find_all('a')\n",
|
||||
" return [stock_code.get('href')[-4:] for stock_code in stock_list]\n",
|
||||
"\n",
|
||||
"def get_stock_price(code):\n",
|
||||
" # you can change the start date\n",
|
||||
" data = yf.download(code, start=\"2021-01-01\", threads= False)\n",
|
||||
" return data\n",
|
||||
"\n",
|
||||
"def add_EMA(price, day):\n",
|
||||
" return price.ewm(span=day).mean()\n",
|
||||
"\n",
|
||||
"def add_STOCH(close, low, high, period, k, d=0): \n",
|
||||
" STOCH_K = ((close - low.rolling(window=period).min()) / (high.rolling(window=period).max() - low.rolling(window=period).min())) * 100\n",
|
||||
" STOCH_K = STOCH_K.rolling(window=k).mean()\n",
|
||||
" if d == 0:\n",
|
||||
" return STOCH_K\n",
|
||||
" else:\n",
|
||||
" STOCH_D = STOCH_K.rolling(window=d).mean()\n",
|
||||
" return STOCH_D\n",
|
||||
"\n",
|
||||
"def check_bounce_EMA(df):\n",
|
||||
" candle1 = df.iloc[-1]\n",
|
||||
" candle2 = df.iloc[-2]\n",
|
||||
" cond1 = candle1['EMA18'] > candle1['EMA50'] > candle1['EMA100']\n",
|
||||
" cond2 = candle1['STOCH_%K(5,3,3)'] <= 30 or candle1['STOCH_%D(5,3,3)'] <= 30\n",
|
||||
" cond3 = candle2['Low'] < candle2['EMA50'] and \\\n",
|
||||
" candle2['Close'] > candle2['EMA50'] and \\\n",
|
||||
" candle1['Low'] > candle1 ['EMA50']\n",
|
||||
" return cond1 and cond2 and cond3\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# a list to store the screened results\n",
|
||||
"screened_list = [] \n",
|
||||
"# get the full stock list\n",
|
||||
"stock_list = get_stock_list()\n",
|
||||
"for stock_code in stock_list:\n",
|
||||
"\n",
|
||||
" print(stock_code) # remove this if you dont want the ticker to be printed\n",
|
||||
" try: \n",
|
||||
" # Step 1: get stock price for each stock\n",
|
||||
" price_chart_df = get_stock_price(stock_code + \".KL\")\n",
|
||||
"\n",
|
||||
" # Step 2: add technical indicators (in this case EMA)\n",
|
||||
" close = price_chart_df['Close']\n",
|
||||
" low = price_chart_df['Low']\n",
|
||||
" open = price_chart_df['Open']\n",
|
||||
" high = price_chart_df['High']\n",
|
||||
" price_chart_df['EMA18'] = add_EMA(close,18)\n",
|
||||
" price_chart_df['EMA50'] = add_EMA(close,50)\n",
|
||||
" price_chart_df['EMA100'] = add_EMA(close,100)\n",
|
||||
" price_chart_df['STOCH_%K(5,3,3)'] = add_STOCH(close, low, high, 5, 3)\n",
|
||||
" price_chart_df['STOCH_%D(5,3,3)'] = add_STOCH(close, low, high, 5, 3, 3)\n",
|
||||
"\n",
|
||||
" # if all 3 conditions are met, add stock into screened list\n",
|
||||
" if check_bounce_EMA(price_chart_df):\n",
|
||||
" screened_list.append(stock_code)\n",
|
||||
" print(screened_list)\n",
|
||||
" except Exception as e:\n",
|
||||
" print(e)\n",
|
||||
"\n",
|
||||
"## this cell may take a few minutes to finish"
|
||||
],
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"metadata": {
|
||||
"id": "TD3iwcVT_o19"
|
||||
},
|
||||
"source": [
|
||||
"# configure email and message\n",
|
||||
"msg = email.message_from_string(\", \".join(screened_list))\n",
|
||||
"msg['From'] = 'YOUR_EMAIL@gmail.com' # change to your email \n",
|
||||
"msg['To'] = 'YOUR_EMAIL@gmail.com'\n",
|
||||
"msg['Subject'] = \"EMA Bounce Result for Today!\"\n",
|
||||
"\n",
|
||||
"s = smtplib.SMTP(\"smtp.gmail.com\",587)\n",
|
||||
"## for yahoo mail user: s = smtplib.SMTP(\"smtp.mail.yahoo.com\",587) \n",
|
||||
"## for hotmail user: s = smtplib.SMTP(\"smtp.live.com\",587)\n",
|
||||
"s.ehlo() \n",
|
||||
"s.starttls()\n",
|
||||
"s.ehlo()\n",
|
||||
"s.login(email_from,\"YOUR_PASSWORD\") # change to your password\n",
|
||||
"s.sendmail(email_from, [email_to] + [email_cc], msg.as_string())\n",
|
||||
"s.quit()"
|
||||
],
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user