diff --git a/.circleci/config.yml b/.circleci/config.yml index 8b84a71..ae171d0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -66,28 +66,30 @@ workflows: branches: only: - master + - before-release - test_py37 - test_py38: filters: branches: only: - master + - before-release - test_py39: filters: branches: only: - master + - before-release - coverage: filters: branches: only: - master - # - doc + - before-release ########################################### # Testing CircleCI in local ########################################### # circleci local execute --job test_py37 -# circleci local execute --job coverage -# circleci local execute --job doc \ No newline at end of file +# circleci local execute --job coverage \ No newline at end of file diff --git a/README.md b/README.md index 6f11d53..cc9c8e6 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,13 @@ ![PyPI](https://img.shields.io/pypi/v/finvizfinance) ![PyPI - Wheel](https://img.shields.io/pypi/wheel/finvizfinance) ![PyPI - License](https://img.shields.io/pypi/l/finvizfinance?color=gre) +[![Coverage Status](https://coveralls.io/repos/github/lit26/finvizfinance/badge.svg)](https://coveralls.io/github/lit26/finvizfinance) ![Travis (.org)](https://img.shields.io/travis/lit26/finvizfinance) ![Read the Docs](https://img.shields.io/readthedocs/finvizfinance) [![Downloads](https://pepy.tech/badge/finvizfinance)](https://pepy.tech/project/finvizfinance) [![CodeFactor](https://www.codefactor.io/repository/github/lit26/finvizfinance/badge/master)](https://www.codefactor.io/repository/github/lit26/finvizfinance/overview/master) [![Donate PayPal](https://img.shields.io/badge/Donate%20%24-PayPal-brightgreen.svg)](https://www.paypal.me/TIANNINGL/) +[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) # finvizfinance @@ -38,7 +40,6 @@ $ pip install finvizfinance Getting information (fundament, description, outer rating, stock news, inside trader) of an individual stock. ```python -import pandas as pd from finvizfinance.quote import finvizfinance stock = finvizfinance('tsla') @@ -46,12 +47,12 @@ stock = finvizfinance('tsla') #### Chart ```python -stock.TickerCharts() +stock.ticker_charts() ``` #### Fundament ```python -stock_fundament = stock.TickerFundament() +stock_fundament = stock.ticker_fundament() # result # stock_fundament = {'Company': 'Tesla, Inc.', 'Sector': 'Consumer Cyclical', @@ -63,7 +64,7 @@ stock_fundament = stock.TickerFundament() #### Description ```python -stock_description = stock.TickerDescription() +stock_description = stock.ticker_description() # stock_description # stock_description = 'Tesla, Inc. designs, develops, manufactures, ...' @@ -71,18 +72,18 @@ stock_description = stock.TickerDescription() #### Outer Ratings ```python -outer_ratings_df = stock.TickerOuterRatings() +outer_ratings_df = stock.ticker_outer_ratings() ``` ![Outer Ratings example](asset/outer_rating.png) #### Stock News ```python -news_df = stock.TickerNews() +news_df = stock.ticker_news() ``` ![stock news example](asset/stock_news.png) #### Inside Trader ```python -inside_trader_df = stock.TickerInsideTrader() +inside_trader_df = stock.ticker_inside_trader() ``` ![insider trader example](asset/insider_trader.png) @@ -94,7 +95,7 @@ Getting recent financial news from finviz. from finvizfinance.news import News fnews = News() -all_news = fnews.getNews() +all_news = fnews.get_news() ``` Finviz News include 'news' and 'blogs'. ```python @@ -117,7 +118,7 @@ finsider = Insider(option='top owner trade') # option: latest, top week, top owner trade # default: latest -insider_trader = finsider.getInsider() +insider_trader = finsider.get_insider() ``` ![insider example](asset/insider.png) @@ -133,7 +134,7 @@ from finvizfinance.screener.overview import Overview foverview = Overview() filters_dict = {'Index':'S&P 500','Sector':'Basic Materials'} foverview.set_filter(filters_dict=filters_dict) -df = foverview.ScreenerView() +df = foverview.screener_view() df.head() ``` ![insider example](asset/screen_overview.png) diff --git a/docs/conf.py b/docs/conf.py index 755e7b0..57a25fb 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -22,7 +22,7 @@ author = 'Tianning Li' # The full version, including alpha/beta/rc tags -release = '0.10.1' +release = '0.11.0' # -- General configuration --------------------------------------------------- diff --git a/docs/index.rst b/docs/index.rst index 066f796..ead08a5 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -37,11 +37,11 @@ Example getting individual ticker information .. code-block:: python - stock_fundament = stock.TickerFundament() - stock_description = stock.TickerDescription() - outer_ratings_df = stock.TickerOuterRatings() - news_df = stock.TickerNews() - inside_trader_df = stock.TickerInsideTrader() + stock_fundament = stock.ticker_fundament() + stock_description = stock.ticker_description() + outer_ratings_df = stock.ticker_outer_ratings() + news_df = stock.ticker_news() + inside_trader_df = stock.ticker_inside_trader() Screener Example ================ @@ -52,7 +52,7 @@ Screener Example foverview = Overview() filters_dict = {'Exchange':'AMEX','Sector':'Basic Materials'} foverview.set_filter(filters_dict=filters_dict) - df = foverview.ScreenerView() + df = foverview.screener_view() df.head() News Example @@ -62,7 +62,7 @@ News Example from finvizfinance.news import News fnews = News() - all_news = fnews.getNews() + all_news = fnews.get_news() # all_news['news'].head() # all_news['blogs'].head() @@ -73,7 +73,7 @@ Insider Example from finvizfinance.insider import Insider finsider = Insider(option='top owner trade') - finsider.getInsider().head() + finsider.get_insider().head() Contents ================== diff --git a/example/example.ipynb b/example/example.ipynb index d580b26..f0b6877 100644 --- a/example/example.ipynb +++ b/example/example.ipynb @@ -28,26 +28,37 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "'https://finviz.com/chart.ashx?t=tsla&ty=c&ta=1&p=d'" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "stock.TickerCharts()" + "stock.ticker_charts()" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": {}, "outputs": [ { "data": { - "image/jpeg": "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\n", + "image/jpeg": "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\n", "text/plain": [ "" ] }, - "execution_count": 3, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -59,27 +70,27 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ - "stock_fundament = stock.TickerFundament()\n", - "stock_description = stock.TickerDescription()\n", - "outer_ratings_df = stock.TickerOuterRatings()\n", - "news_df = stock.TickerNews()\n", - "inside_trader_df = stock.TickerInsideTrader()" + "stock_fundament = stock.ticker_fundament()\n", + "stock_description = stock.ticker_description()\n", + "outer_ratings_df = stock.ticker_outer_ratings()\n", + "news_df = stock.ticker_news()\n", + "inside_trader_df = stock.ticker_inside_trader()" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "{'Company': 'Tesla, Inc.', 'Sector': 'Consumer Cyclical', 'Industry': 'Auto Manufacturers', 'Country': 'USA', 'Index': '-', 'P/E': '1041.35', 'EPS (ttm)': '1.94', 'Insider Own': '0.10%', 'Shs Outstand': '186.00M', 'Perf Week': '7.22%', 'Market Cap': '368.21B', 'Forward P/E': '130.14', 'EPS next Y': '78.63%', 'Insider Trans': '-28.07%', 'Shs Float': '148.29M', 'Perf Month': '31.42%', 'Income': '368.00M', 'PEG': '-', 'EPS next Q': '2.67', 'Inst Own': '49.20%', 'Short Float': '8.06%', 'Perf Quarter': '146.68%', 'Sales': '25.71B', 'P/S': '14.32', 'EPS this Y': '14.90%', 'Inst Trans': '-1.68%', 'Short Ratio': '0.86', 'Perf Half Y': '159.80%', 'Book/sh': '52.98', 'P/B': '38.19', 'ROA': '1.00%', 'Target Price': '1293.75', 'Perf Year': '841.09%', 'Cash/sh': '47.34', 'P/C': '42.74', 'EPS next 5Y': '-', 'ROE': '4.60%', '52W Range': '211.54 - 2129.00', 'Perf YTD': '383.67%', 'Dividend': '-', 'P/FCF': '141.75', 'EPS past 5Y': '-15.60%', 'ROI': '-0.90%', '52W High': '-4.96%', 'Beta': '1.37', 'Dividend %': '-', 'Quick Ratio': '0.90', 'Sales past 5Y': '50.40%', 'Gross Margin': '19.80%', '52W Low': '856.48%', 'ATR': '105.12', 'Employees': '48016', 'Current Ratio': '1.20', 'Sales Q/Q': '-4.90%', 'Oper. Margin': '4.80%', 'RSI (14)': '76.78', 'Volatility': '5.93% 5.27%', 'Optionable': 'Yes', 'Debt/Eq': '1.43', 'EPS Q/Q': '121.70%', 'Profit Margin': '1.40%', 'Rel Volume': '0.76', 'Prev Close': '2014.20', 'Shortable': 'Yes', 'LT Debt/Eq': '1.06', 'Earnings': 'Jul 22 AMC', 'Payout': '0.00%', 'Avg Volume': '13.95M', 'Price': '2023.34', 'Recom': '3.00', 'SMA20': '24.21%', 'SMA50': '42.95%', 'SMA200': '149.94%', 'Volume': '10,549,296', 'Change': '0.45%'}\n" + "{'Company': 'Tesla, Inc.', 'Sector': 'Consumer Cyclical', 'Industry': 'Auto Manufacturers', 'Country': 'USA', 'Index': 'S&P 500', 'P/E': '329.99', 'EPS (ttm)': '3.08', 'Insider Own': '0.20%', 'Shs Outstand': '963.33M', 'Perf Week': '0.20%', 'Market Cap': '979.74B', 'Forward P/E': '124.45', 'EPS next Y': '34.87%', 'Insider Trans': '-85.61%', 'Shs Float': '811.86M', 'Perf Month': '-4.77%', 'Income': '3.47B', 'PEG': '4.52', 'EPS next Q': '2.25', 'Inst Own': '42.50%', 'Short Float': '3.17%', 'Perf Quarter': '36.88%', 'Sales': '46.85B', 'P/S': '20.91', 'EPS this Y': '165.00%', 'Inst Trans': '4.67%', 'Short Ratio': '1.01', 'Perf Half Y': '64.65%', 'Book/sh': '27.11', 'P/B': '37.51', 'ROA': '6.40%', 'Target Price': '836.72', 'Perf Year': '62.19%', 'Cash/sh': '16.71', 'P/C': '60.87', 'EPS next 5Y': '73.06%', 'ROE': '14.30%', '52W Range From': '539.49', '52W Range To': '1243.49', 'Perf YTD': '44.12%', 'Dividend': '-', 'P/FCF': '99.06', 'EPS past 5Y': '19.70%', 'ROI': '5.00%', '52W High': '-18.21%', 'Beta': '2.05', 'Dividend %': '-', 'Quick Ratio': '1.10', 'Sales past 5Y': '50.80%', 'Gross Margin': '23.10%', '52W Low': '88.52%', 'ATR': '61.98', 'Employees': '70757', 'Current Ratio': '1.40', 'Sales Q/Q': '56.80%', 'Oper. Margin': '9.60%', 'RSI (14)': '45.54', 'Volatility W': '4.84%', 'Volatility M': '5.42%', 'Optionable': 'Yes', 'Debt/Eq': '0.30', 'EPS Q/Q': '430.70%', 'Profit Margin': '7.40%', 'Rel Volume': '0.77', 'Prev Close': '1003.80', 'Shortable': 'Yes', 'LT Debt/Eq': '0.24', 'Earnings': 'Oct 20 AMC', 'Payout': '0.00%', 'Avg Volume': '25.50M', 'Price': '1017.03', 'Recom': '2.60', 'SMA20': '-5.66%', 'SMA50': '1.53%', 'SMA200': '34.43%', 'Volume': '19,708,422', 'Change': '1.32%'}\n" ] } ], @@ -89,14 +100,14 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Tesla, Inc. designs, develops, manufactures, leases, and sells electric vehicles, and energy generation and storage systems in the United States, China, Netherlands, Norway, and internationally. The company operates in two segments, Automotive; and Energy Generation and Storage. The Automotive segment offers sedans and sport utility vehicles. It also provides electric powertrain components and systems; and services for electric vehicles through its company-owned service locations, and Tesla mobile service technicians, as well as sells used vehicles. This segment markets and sells its products through a network of company-owned stores and galleries, as well as through its own Website. The Energy Generation and Storage segment offers energy storage products, such as rechargeable lithium-ion battery systems for use in homes, industrial, commercial facilities, and utility grids; and designs, manufactures, installs, maintains, leases, and sells solar energy generation and energy storage products to residential and commercial customers. It also provides vehicle insurance services, as well as renewable energy. The company was formerly known as Tesla Motors, Inc. and changed its name to Tesla, Inc. in February 2017. Tesla, Inc. was founded in 2003 and is headquartered in Palo Alto, California.\n" + "Tesla, Inc. designs, develops, manufactures, leases, and sells electric vehicles, and energy generation and storage systems in the United States, China, and internationally. The company operates in two segments, Automotive, and Energy Generation and Storage. The Automotive segment offers electric vehicles, as well as sells automotive regulatory credits. It provides sedans and sport utility vehicles through direct and used vehicle sales, a network of Tesla Superchargers, and in-app upgrades; and purchase financing and leasing services. This segment is also involved in the provision of non-warranty after-sales vehicle services, sale of used vehicles, retail merchandise, and vehicle insurance, as well as sale of products through its subsidiaries to third party customers; services for electric vehicles through its company-owned service locations, and Tesla mobile service technicians; and vehicle limited warranties and extended service plans. The Energy Generation and Storage segment engages in the design, manufacture, installation, sale, and leasing of solar energy generation and energy storage products, and related services to residential, commercial, and industrial customers and utilities through its website, stores, and galleries, as well as through a network of channel partners. This segment also offers service and repairs to its energy product customers, including under warranty; and various financing options to its solar customers. The company was formerly known as Tesla Motors, Inc. and changed its name to Tesla, Inc. in February 2017. Tesla, Inc. was founded in 2003 and is headquartered in Palo Alto, California.\n" ] } ], @@ -106,7 +117,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -140,65 +151,58 @@ " \n", " \n", " 0\n", - " 2020-08-14\n", - " Upgrade\n", - " Morgan Stanley\n", - " Underweight → Equal-Weight\n", - " $1050 → $1360\n", + " 2021-12-07\n", + " Reiterated\n", + " UBS\n", + " Neutral\n", + " $725 → $1000\n", " \n", " \n", " 1\n", - " 2020-08-14\n", - " Upgrade\n", - " BofA Securities\n", - " Underperform → Neutral\n", - " $800 → $1750\n", + " 2021-11-08\n", + " Reiterated\n", + " Jefferies\n", + " Buy\n", + " $950 → $1400\n", " \n", " \n", " 2\n", - " 2020-07-29\n", + " 2021-10-25\n", " Reiterated\n", " Morgan Stanley\n", - " Underweight\n", - " $740 → $1050\n", + " Overweight\n", + " $900 → $1200\n", " \n", " \n", " 3\n", - " 2020-07-28\n", - " Downgrade\n", - " Bernstein\n", - " Mkt Perform → Underperform\n", - " $900\n", + " 2021-10-21\n", + " Reiterated\n", + " Wells Fargo\n", + " Equal Weight\n", + " $660 → $860\n", " \n", " \n", " 4\n", - " 2020-07-24\n", - " Upgrade\n", - " Argus\n", - " Hold → Buy\n", - " \n", + " 2021-10-21\n", + " Reiterated\n", + " Wedbush\n", + " Outperform\n", + " $1000 → $1100\n", " \n", " \n", "\n", "" ], "text/plain": [ - " Date Status Outer Rating \\\n", - "0 2020-08-14 Upgrade Morgan Stanley Underweight → Equal-Weight \n", - "1 2020-08-14 Upgrade BofA Securities Underperform → Neutral \n", - "2 2020-07-29 Reiterated Morgan Stanley Underweight \n", - "3 2020-07-28 Downgrade Bernstein Mkt Perform → Underperform \n", - "4 2020-07-24 Upgrade Argus Hold → Buy \n", - "\n", - " Price \n", - "0 $1050 → $1360 \n", - "1 $800 → $1750 \n", - "2 $740 → $1050 \n", - "3 $900 \n", - "4 " + " Date Status Outer Rating Price\n", + "0 2021-12-07 Reiterated UBS Neutral $725 → $1000\n", + "1 2021-11-08 Reiterated Jefferies Buy $950 → $1400\n", + "2 2021-10-25 Reiterated Morgan Stanley Overweight $900 → $1200\n", + "3 2021-10-21 Reiterated Wells Fargo Equal Weight $660 → $860\n", + "4 2021-10-21 Reiterated Wedbush Outperform $1000 → $1100" ] }, - "execution_count": 7, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -209,7 +213,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -241,33 +245,33 @@ " \n", " \n", " 0\n", - " 2020-08-25 22:28:00\n", - " Dow Jones Futures: After Solid Stock Market Ra...\n", + " 2021-12-11 18:36:00\n", + " Dow Jones Futures: Bulls Still Penned In With ...\n", " https://www.investors.com/market-trend/stock-m...\n", " \n", " \n", " 1\n", - " 2020-08-25 18:23:00\n", - " Another Analyst Weighs in on Nikola Stock. Why...\n", - " https://www.barrons.com/articles/nikola-stocks...\n", + " 2021-12-11 15:17:00\n", + " Is Lucid Motors a Buy Right Now?\n", + " https://www.fool.com/investing/2021/12/11/is-l...\n", " \n", " \n", " 2\n", - " 2020-08-25 18:00:00\n", - " FANGMAN Is No Match for These 'Seven Princesses'\n", - " https://finance.yahoo.com/news/fangman-no-matc...\n", + " 2021-12-11 13:43:00\n", + " Jim Cramer likes these 3 'junior' growth stock...\n", + " https://finance.yahoo.com/news/jim-cramer-like...\n", " \n", " \n", " 3\n", - " 2020-08-25 16:57:00\n", - " Forget the Dow Shake-Up. A Tesla Addition to t...\n", - " https://www.barrons.com/articles/the-dow-shake...\n", + " 2021-12-11 10:33:00\n", + " Want to Bet on China's EV Growth? Here Are 6 S...\n", + " https://www.fool.com/investing/2021/12/11/want...\n", " \n", " \n", " 4\n", - " 2020-08-25 16:25:00\n", - " Tesla Inc. stock rises Tuesday, still underper...\n", - " https://www.marketwatch.com/story/tesla-inc-st...\n", + " 2021-12-11 09:00:00\n", + " Dorsey's exit from Twitter reveals shortening ...\n", + " https://finance.yahoo.com/news/twitter-salesfo...\n", " \n", " \n", "\n", @@ -275,21 +279,21 @@ ], "text/plain": [ " Date Title \\\n", - "0 2020-08-25 22:28:00 Dow Jones Futures: After Solid Stock Market Ra... \n", - "1 2020-08-25 18:23:00 Another Analyst Weighs in on Nikola Stock. Why... \n", - "2 2020-08-25 18:00:00 FANGMAN Is No Match for These 'Seven Princesses' \n", - "3 2020-08-25 16:57:00 Forget the Dow Shake-Up. A Tesla Addition to t... \n", - "4 2020-08-25 16:25:00 Tesla Inc. stock rises Tuesday, still underper... \n", + "0 2021-12-11 18:36:00 Dow Jones Futures: Bulls Still Penned In With ... \n", + "1 2021-12-11 15:17:00 Is Lucid Motors a Buy Right Now? \n", + "2 2021-12-11 13:43:00 Jim Cramer likes these 3 'junior' growth stock... \n", + "3 2021-12-11 10:33:00 Want to Bet on China's EV Growth? Here Are 6 S... \n", + "4 2021-12-11 09:00:00 Dorsey's exit from Twitter reveals shortening ... \n", "\n", " Link \n", "0 https://www.investors.com/market-trend/stock-m... \n", - "1 https://www.barrons.com/articles/nikola-stocks... \n", - "2 https://finance.yahoo.com/news/fangman-no-matc... \n", - "3 https://www.barrons.com/articles/the-dow-shake... \n", - "4 https://www.marketwatch.com/story/tesla-inc-st... " + "1 https://www.fool.com/investing/2021/12/11/is-l... \n", + "2 https://finance.yahoo.com/news/jim-cramer-like... \n", + "3 https://www.fool.com/investing/2021/12/11/want... \n", + "4 https://finance.yahoo.com/news/twitter-salesfo... " ] }, - "execution_count": 8, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -300,7 +304,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -333,96 +337,109 @@ " Value ($)\n", " #Shares Total\n", " SEC Form 4\n", + " SEC Form 4 Link\n", " Insider_id\n", " \n", " \n", " \n", " \n", " 0\n", - " Kirkhorn Zachary\n", - " Chief Financial Officer\n", - " Aug 17\n", - " Sale\n", - " 1677.86\n", - " 250.0\n", - " 419465.0\n", - " 11331.0\n", - " Aug 19 09:43 PM\n", - " 1771364\n", + " Musk Elon\n", + " CEO\n", + " Dec 09\n", + " Option Exercise\n", + " 6.24\n", + " 2165241.0\n", + " 13511104.0\n", + " 2165241.0\n", + " Dec 09 08:19 PM\n", + " http://www.sec.gov/Archives/edgar/data/1318605...\n", + " 1494730\n", " \n", " \n", " 1\n", - " Baglino Andrew D\n", - " SVP Powertrain and Energy Eng.\n", - " Aug 10\n", - " Option Exercise\n", - " 241.93\n", - " 200.0\n", - " 48386.0\n", - " 4322.0\n", - " Aug 12 08:43 PM\n", - " 1790565\n", + " Musk Elon\n", + " CEO\n", + " Dec 09\n", + " Sale\n", + " 1044.54\n", + " 390639.0\n", + " 408039939.0\n", + " 1231150.0\n", + " Dec 09 08:21 PM\n", + " http://www.sec.gov/Archives/edgar/data/1318605...\n", + " 1494730\n", " \n", " \n", " 2\n", - " Baglino Andrew D\n", - " SVP Powertrain and Energy Eng.\n", - " Aug 10\n", + " Musk Elon\n", + " CEO\n", + " Dec 09\n", " Sale\n", - " 1445.25\n", - " 300.0\n", - " 433575.0\n", - " 4022.0\n", - " Aug 12 08:43 PM\n", - " 1790565\n", + " 1021.56\n", + " 543452.0\n", + " 555171415.0\n", + " 1621789.0\n", + " Dec 09 08:19 PM\n", + " http://www.sec.gov/Archives/edgar/data/1318605...\n", + " 1494730\n", " \n", " \n", " 3\n", - " Guillen Jerome M\n", - " President, Automotive\n", - " Aug 03\n", - " Option Exercise\n", - " 258.18\n", - " 3000.0\n", - " 774540.0\n", - " 12752.0\n", - " Aug 05 08:48 PM\n", - " 1584518\n", + " Taneja Vaibhav\n", + " Chief Accounting Officer\n", + " Dec 06\n", + " Sale\n", + " 980.41\n", + " 1590.0\n", + " 1559339.0\n", + " 22905.0\n", + " Dec 07 09:11 PM\n", + " http://www.sec.gov/Archives/edgar/data/1318605...\n", + " 1771340\n", " \n", " \n", " 4\n", - " Guillen Jerome M\n", - " President, Automotive\n", - " Aug 03\n", + " Kirkhorn Zachary\n", + " Chief Financial Officer\n", + " Dec 06\n", " Sale\n", - " 1450.21\n", - " 3000.0\n", - " 4350630.0\n", - " 9752.0\n", - " Aug 05 08:48 PM\n", - " 1584518\n", + " 980.43\n", + " 2652.0\n", + " 2600345.0\n", + " 56634.0\n", + " Dec 07 09:02 PM\n", + " http://www.sec.gov/Archives/edgar/data/1318605...\n", + " 1771364\n", " \n", " \n", "\n", "" ], "text/plain": [ - " Insider Trading Relationship Date Transaction \\\n", - "0 Kirkhorn Zachary Chief Financial Officer Aug 17 Sale \n", - "1 Baglino Andrew D SVP Powertrain and Energy Eng. Aug 10 Option Exercise \n", - "2 Baglino Andrew D SVP Powertrain and Energy Eng. Aug 10 Sale \n", - "3 Guillen Jerome M President, Automotive Aug 03 Option Exercise \n", - "4 Guillen Jerome M President, Automotive Aug 03 Sale \n", + " Insider Trading Relationship Date Transaction \\\n", + "0 Musk Elon CEO Dec 09 Option Exercise \n", + "1 Musk Elon CEO Dec 09 Sale \n", + "2 Musk Elon CEO Dec 09 Sale \n", + "3 Taneja Vaibhav Chief Accounting Officer Dec 06 Sale \n", + "4 Kirkhorn Zachary Chief Financial Officer Dec 06 Sale \n", + "\n", + " Cost #Shares Value ($) #Shares Total SEC Form 4 \\\n", + "0 6.24 2165241.0 13511104.0 2165241.0 Dec 09 08:19 PM \n", + "1 1044.54 390639.0 408039939.0 1231150.0 Dec 09 08:21 PM \n", + "2 1021.56 543452.0 555171415.0 1621789.0 Dec 09 08:19 PM \n", + "3 980.41 1590.0 1559339.0 22905.0 Dec 07 09:11 PM \n", + "4 980.43 2652.0 2600345.0 56634.0 Dec 07 09:02 PM \n", "\n", - " Cost #Shares Value ($) #Shares Total SEC Form 4 Insider_id \n", - "0 1677.86 250.0 419465.0 11331.0 Aug 19 09:43 PM 1771364 \n", - "1 241.93 200.0 48386.0 4322.0 Aug 12 08:43 PM 1790565 \n", - "2 1445.25 300.0 433575.0 4022.0 Aug 12 08:43 PM 1790565 \n", - "3 258.18 3000.0 774540.0 12752.0 Aug 05 08:48 PM 1584518 \n", - "4 1450.21 3000.0 4350630.0 9752.0 Aug 05 08:48 PM 1584518 " + " SEC Form 4 Link Insider_id \n", + "0 http://www.sec.gov/Archives/edgar/data/1318605... 1494730 \n", + "1 http://www.sec.gov/Archives/edgar/data/1318605... 1494730 \n", + "2 http://www.sec.gov/Archives/edgar/data/1318605... 1494730 \n", + "3 http://www.sec.gov/Archives/edgar/data/1318605... 1771340 \n", + "4 http://www.sec.gov/Archives/edgar/data/1318605... 1771364 " ] }, - "execution_count": 9, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -431,6 +448,157 @@ "inside_trader_df.head()" ] }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['Most Active', 'Major News']" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "stock.ticker_signal()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Statements" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
01234567
Period End Date9/25/20216/26/20213/27/202112/26/20209/26/20206/27/20203/28/202012/28/2019
Cash and Equivalents17,635.0019,197.0019,022.0017,281.0020,243.0013,130.0015,769.0028,388.00
Short Term Investments27,699.0027,646.0031,368.0040,816.0052,927.0059,642.0053,877.0067,391.00
Cash and Short Term Investments62,639.0061,696.0069,834.0076,826.0090,943.0093,025.0094,051.00107,162.00
Accounts Receivable - Trade, Net26,278.0017,475.0018,503.0027,101.0016,120.0017,882.0015,722.0020,970.00
\n", + "
" + ], + "text/plain": [ + " 0 1 2 3 \\\n", + "Period End Date 9/25/2021 6/26/2021 3/27/2021 12/26/2020 \n", + "Cash and Equivalents 17,635.00 19,197.00 19,022.00 17,281.00 \n", + "Short Term Investments 27,699.00 27,646.00 31,368.00 40,816.00 \n", + "Cash and Short Term Investments 62,639.00 61,696.00 69,834.00 76,826.00 \n", + "Accounts Receivable - Trade, Net 26,278.00 17,475.00 18,503.00 27,101.00 \n", + "\n", + " 4 5 6 7 \n", + "Period End Date 9/26/2020 6/27/2020 3/28/2020 12/28/2019 \n", + "Cash and Equivalents 20,243.00 13,130.00 15,769.00 28,388.00 \n", + "Short Term Investments 52,927.00 59,642.00 53,877.00 67,391.00 \n", + "Cash and Short Term Investments 90,943.00 93,025.00 94,051.00 107,162.00 \n", + "Accounts Receivable - Trade, Net 16,120.00 17,882.00 15,722.00 20,970.00 " + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from finvizfinance.quote import Statements\n", + "statement = Statements()\n", + "df = statement.get_statements('AAPL', statement=\"B\", timeframe=\"Q\")\n", + "df.head()" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -440,18 +608,18 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "from finvizfinance.news import News\n", "fnews = News()\n", - "all_news = fnews.getNews()" + "all_news = fnews.get_news()" ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 13, "metadata": {}, "outputs": [ { @@ -484,38 +652,38 @@ " \n", " \n", " 0\n", - " 12:03AM\n", - " China's mighty Ant heads for a mega market debut\n", - " www.bbc.co.uk\n", - " https://www.bbc.co.uk/news/business-53915531\n", + " 05:57PM\n", + " Can Peloton Sue Over Its ‘And Just Like That’ ...\n", + " www.nytimes.com\n", + " https://www.nytimes.com/2021/12/11/arts/televi...\n", " \n", " \n", " 1\n", - " Aug-25\n", - " In RNC speech, Pompeo previews Trump's China e...\n", - " www.cnn.com\n", - " https://www.cnn.com/2020/08/25/politics/pompeo...\n", + " 05:26PM\n", + " Armenia will allow employers to fire unvaccina...\n", + " www.foxbusiness.com\n", + " https://www.foxbusiness.com/economy/armenia-al...\n", " \n", " \n", " 2\n", - " Aug-25\n", - " Australia to Sell A$21 Billion of Bonds, Smash...\n", + " 04:00PM\n", + " Fed Hikes Seen Starting With Yield Curve Flatt...\n", " www.bloomberg.com\n", - " https://www.bloomberg.com/news/articles/2020-0...\n", + " https://www.bloomberg.com/news/articles/2021-1...\n", " \n", " \n", " 3\n", - " Aug-25\n", - " Harley-Davidson puts motorcycle launch on back...\n", - " www.foxbusiness.com\n", - " https://www.foxbusiness.com/markets/harley-dav...\n", + " 04:00PM\n", + " Omicron Forces Central Bankers to Look Back at...\n", + " www.bloomberg.com\n", + " https://www.bloomberg.com/news/articles/2021-1...\n", " \n", " \n", " 4\n", - " Aug-25\n", - " Japanese shares ease after prior session rally\n", - " www.reuters.com\n", - " https://www.reuters.com/article/japan-stocks-m...\n", + " 04:00PM\n", + " U.S. Corporate Bond Primary Markets Finally En...\n", + " www.bloomberg.com\n", + " https://www.bloomberg.com/news/articles/2021-1...\n", " \n", " \n", "\n", @@ -523,21 +691,21 @@ ], "text/plain": [ " Date Title \\\n", - "0 12:03AM China's mighty Ant heads for a mega market debut \n", - "1 Aug-25 In RNC speech, Pompeo previews Trump's China e... \n", - "2 Aug-25 Australia to Sell A$21 Billion of Bonds, Smash... \n", - "3 Aug-25 Harley-Davidson puts motorcycle launch on back... \n", - "4 Aug-25 Japanese shares ease after prior session rally \n", + "0 05:57PM Can Peloton Sue Over Its ‘And Just Like That’ ... \n", + "1 05:26PM Armenia will allow employers to fire unvaccina... \n", + "2 04:00PM Fed Hikes Seen Starting With Yield Curve Flatt... \n", + "3 04:00PM Omicron Forces Central Bankers to Look Back at... \n", + "4 04:00PM U.S. Corporate Bond Primary Markets Finally En... \n", "\n", " Source Link \n", - "0 www.bbc.co.uk https://www.bbc.co.uk/news/business-53915531 \n", - "1 www.cnn.com https://www.cnn.com/2020/08/25/politics/pompeo... \n", - "2 www.bloomberg.com https://www.bloomberg.com/news/articles/2020-0... \n", - "3 www.foxbusiness.com https://www.foxbusiness.com/markets/harley-dav... \n", - "4 www.reuters.com https://www.reuters.com/article/japan-stocks-m... " + "0 www.nytimes.com https://www.nytimes.com/2021/12/11/arts/televi... \n", + "1 www.foxbusiness.com https://www.foxbusiness.com/economy/armenia-al... \n", + "2 www.bloomberg.com https://www.bloomberg.com/news/articles/2021-1... \n", + "3 www.bloomberg.com https://www.bloomberg.com/news/articles/2021-1... \n", + "4 www.bloomberg.com https://www.bloomberg.com/news/articles/2021-1... " ] }, - "execution_count": 11, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -548,7 +716,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 14, "metadata": {}, "outputs": [ { @@ -581,60 +749,60 @@ " \n", " \n", " 0\n", - " 12:05AM\n", - " Escobar: For China, Everything Is Proceeding A...\n", - " zerohedge\n", - " http://feedproxy.google.com/~r/zerohedge/feed/...\n", + " 07:30PM\n", + " California Is Hiding $300 Billion A Year In Sp...\n", + " www.zerohedge.com\n", + " https://www.zerohedge.com/political/california...\n", " \n", " \n", " 1\n", - " Aug-25\n", - " Photos Emerge Of 'Secret' Stealth Drone Made B...\n", - " zerohedge\n", - " http://feedproxy.google.com/~r/zerohedge/feed/...\n", + " 07:00PM\n", + " Pfizer Jab Is Only 23% Effective Against Omicr...\n", + " www.zerohedge.com\n", + " https://www.zerohedge.com/covid-19/pfizer-jab-...\n", " \n", " \n", " 2\n", - " Aug-25\n", - " Attack Of The Tomato Killers: The Police State...\n", - " zerohedge\n", - " http://feedproxy.google.com/~r/zerohedge/feed/...\n", + " 06:30PM\n", + " US Shale Slams Biden's Oil Policies\n", + " www.zerohedge.com\n", + " https://www.zerohedge.com/energy/us-shale-slam...\n", " \n", " \n", " 3\n", - " Aug-25\n", - " Portland Businesses Leave Due To 'Lawlessness ...\n", - " zerohedge\n", - " http://feedproxy.google.com/~r/zerohedge/feed/...\n", + " 06:12PM\n", + " 70 Dead In Kentucky As Biden Calls Tornado Out...\n", + " www.zerohedge.com\n", + " https://www.zerohedge.com/weather/mass-casualt...\n", " \n", " \n", " 4\n", - " Aug-25\n", - " GOP Senators Demand FDA Explain Hydroxychloroq...\n", - " zerohedge\n", - " http://feedproxy.google.com/~r/zerohedge/feed/...\n", + " 06:00PM\n", + " Stung By The Semi Shortage, Chinese Auto Sales...\n", + " www.zerohedge.com\n", + " https://www.zerohedge.com/markets/stung-semi-s...\n", " \n", " \n", "\n", "" ], "text/plain": [ - " Date Title Source \\\n", - "0 12:05AM Escobar: For China, Everything Is Proceeding A... zerohedge \n", - "1 Aug-25 Photos Emerge Of 'Secret' Stealth Drone Made B... zerohedge \n", - "2 Aug-25 Attack Of The Tomato Killers: The Police State... zerohedge \n", - "3 Aug-25 Portland Businesses Leave Due To 'Lawlessness ... zerohedge \n", - "4 Aug-25 GOP Senators Demand FDA Explain Hydroxychloroq... zerohedge \n", + " Date Title \\\n", + "0 07:30PM California Is Hiding $300 Billion A Year In Sp... \n", + "1 07:00PM Pfizer Jab Is Only 23% Effective Against Omicr... \n", + "2 06:30PM US Shale Slams Biden's Oil Policies \n", + "3 06:12PM 70 Dead In Kentucky As Biden Calls Tornado Out... \n", + "4 06:00PM Stung By The Semi Shortage, Chinese Auto Sales... \n", "\n", - " Link \n", - "0 http://feedproxy.google.com/~r/zerohedge/feed/... \n", - "1 http://feedproxy.google.com/~r/zerohedge/feed/... \n", - "2 http://feedproxy.google.com/~r/zerohedge/feed/... \n", - "3 http://feedproxy.google.com/~r/zerohedge/feed/... \n", - "4 http://feedproxy.google.com/~r/zerohedge/feed/... " + " Source Link \n", + "0 www.zerohedge.com https://www.zerohedge.com/political/california... \n", + "1 www.zerohedge.com https://www.zerohedge.com/covid-19/pfizer-jab-... \n", + "2 www.zerohedge.com https://www.zerohedge.com/energy/us-shale-slam... \n", + "3 www.zerohedge.com https://www.zerohedge.com/weather/mass-casualt... \n", + "4 www.zerohedge.com https://www.zerohedge.com/markets/stung-semi-s... " ] }, - "execution_count": 12, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } @@ -652,7 +820,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 15, "metadata": {}, "outputs": [ { @@ -686,73 +854,79 @@ " Value ($)\n", " #Shares Total\n", " SEC Form 4\n", + " SEC Form 4 Link\n", " \n", " \n", " \n", " \n", " 0\n", - " KDP\n", - " Maple Holdings B.V.\n", + " PPD\n", + " H&F Corporate Investors VII, L\n", " 10% Owner\n", - " Aug 17\n", + " Dec 08\n", " Sale\n", - " 29.00\n", - " 45000000.0\n", - " 1.305000e+09\n", - " 681084122.0\n", - " Aug 19 05:15 PM\n", + " 47.50\n", + " 132841266.0\n", + " 6.309960e+09\n", + " 0.0\n", + " Dec 08 04:53 PM\n", + " http://www.sec.gov/Archives/edgar/data/1405076...\n", " \n", " \n", " 1\n", - " KDP\n", - " JAB Holdings B.V.\n", + " PPD\n", + " H&F Corporate Investors VIII,\n", " 10% Owner\n", - " Aug 17\n", + " Dec 08\n", " Sale\n", - " 29.00\n", - " 45000000.0\n", - " 1.305000e+09\n", - " 681084122.0\n", - " Aug 19 05:15 PM\n", + " 47.50\n", + " 132841266.0\n", + " 6.309960e+09\n", + " 0.0\n", + " Dec 08 05:05 PM\n", + " http://www.sec.gov/Archives/edgar/data/1618902...\n", " \n", " \n", " 2\n", - " AVTR\n", - " New Mountain Investments III,\n", + " APP\n", + " KKR Group Partnership L.P.\n", " 10% Owner\n", - " Aug 21\n", + " Dec 07\n", " Sale\n", - " 19.51\n", - " 25575472.0\n", - " 4.988879e+08\n", - " 64016093.0\n", - " Aug 25 05:08 PM\n", + " 80.51\n", + " 8410000.0\n", + " 6.770891e+08\n", + " 60735000.0\n", + " Dec 09 05:31 PM\n", + " http://www.sec.gov/Archives/edgar/data/1081714...\n", " \n", " \n", " 3\n", - " FISV\n", - " New Omaha Holdings L.P.\n", + " APP\n", + " KKR Denali Holdings L.P.\n", " 10% Owner\n", - " Aug 21\n", + " Dec 07\n", " Sale\n", - " 98.00\n", - " 5000000.0\n", - " 4.900000e+08\n", - " 105425667.0\n", - " Aug 21 05:00 PM\n", + " 80.51\n", + " 8410000.0\n", + " 6.770891e+08\n", + " 60735000.0\n", + " Dec 09 05:31 PM\n", + " http://www.sec.gov/Archives/edgar/data/1666676...\n", " \n", " \n", " 4\n", - " KKR\n", - " KKR Group Partnership L.P.\n", + " BSA\n", + " PAULSON & CO. INC.\n", " 10% Owner\n", - " Aug 21\n", + " Dec 08\n", " Sale\n", - " 98.00\n", - " 5000000.0\n", - " 4.900000e+08\n", - " 105425667.0\n", - " Aug 21 05:01 PM\n", + " 31.50\n", + " 10260431.0\n", + " 3.232036e+08\n", + " 9740121.0\n", + " Dec 10 04:38 PM\n", + " http://www.sec.gov/Archives/edgar/data/1035674...\n", " \n", " \n", "\n", @@ -760,21 +934,28 @@ ], "text/plain": [ " Ticker Owner Relationship Date Transaction \\\n", - "0 KDP Maple Holdings B.V. 10% Owner Aug 17 Sale \n", - "1 KDP JAB Holdings B.V. 10% Owner Aug 17 Sale \n", - "2 AVTR New Mountain Investments III, 10% Owner Aug 21 Sale \n", - "3 FISV New Omaha Holdings L.P. 10% Owner Aug 21 Sale \n", - "4 KKR KKR Group Partnership L.P. 10% Owner Aug 21 Sale \n", + "0 PPD H&F Corporate Investors VII, L 10% Owner Dec 08 Sale \n", + "1 PPD H&F Corporate Investors VIII, 10% Owner Dec 08 Sale \n", + "2 APP KKR Group Partnership L.P. 10% Owner Dec 07 Sale \n", + "3 APP KKR Denali Holdings L.P. 10% Owner Dec 07 Sale \n", + "4 BSA PAULSON & CO. INC. 10% Owner Dec 08 Sale \n", + "\n", + " Cost #Shares Value ($) #Shares Total SEC Form 4 \\\n", + "0 47.50 132841266.0 6.309960e+09 0.0 Dec 08 04:53 PM \n", + "1 47.50 132841266.0 6.309960e+09 0.0 Dec 08 05:05 PM \n", + "2 80.51 8410000.0 6.770891e+08 60735000.0 Dec 09 05:31 PM \n", + "3 80.51 8410000.0 6.770891e+08 60735000.0 Dec 09 05:31 PM \n", + "4 31.50 10260431.0 3.232036e+08 9740121.0 Dec 10 04:38 PM \n", "\n", - " Cost #Shares Value ($) #Shares Total SEC Form 4 \n", - "0 29.00 45000000.0 1.305000e+09 681084122.0 Aug 19 05:15 PM \n", - "1 29.00 45000000.0 1.305000e+09 681084122.0 Aug 19 05:15 PM \n", - "2 19.51 25575472.0 4.988879e+08 64016093.0 Aug 25 05:08 PM \n", - "3 98.00 5000000.0 4.900000e+08 105425667.0 Aug 21 05:00 PM \n", - "4 98.00 5000000.0 4.900000e+08 105425667.0 Aug 21 05:01 PM " + " SEC Form 4 Link \n", + "0 http://www.sec.gov/Archives/edgar/data/1405076... \n", + "1 http://www.sec.gov/Archives/edgar/data/1618902... \n", + "2 http://www.sec.gov/Archives/edgar/data/1081714... \n", + "3 http://www.sec.gov/Archives/edgar/data/1666676... \n", + "4 http://www.sec.gov/Archives/edgar/data/1035674... " ] }, - "execution_count": 13, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } @@ -782,7 +963,7 @@ "source": [ "from finvizfinance.insider import Insider\n", "finsider = Insider(option='top owner trade')\n", - "finsider.getInsider().head()" + "finsider.get_insider().head()" ] }, { @@ -794,7 +975,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 16, "metadata": {}, "outputs": [ { @@ -828,6 +1009,7 @@ " Value ($)\n", " #Shares Total\n", " SEC Form 4\n", + " SEC Form 4 Link\n", " \n", " \n", " \n", @@ -836,65 +1018,70 @@ " TSLA\n", " Taneja Vaibhav\n", " Chief Accounting Officer\n", - " Jul 20\n", + " Dec 05\n", " Option Exercise\n", - " 273.29\n", - " 817.0\n", - " 223277.0\n", - " 3616.0\n", - " Jul 22 09:50 PM\n", + " 0.00\n", + " 3283.0\n", + " 0.0\n", + " 24495.0\n", + " Dec 07 09:11 PM\n", + " http://www.sec.gov/Archives/edgar/data/1318605...\n", " \n", " \n", " 1\n", " TSLA\n", " Taneja Vaibhav\n", " Chief Accounting Officer\n", - " Jul 20\n", + " Dec 06\n", " Sale\n", - " 1558.75\n", - " 887.0\n", - " 1382608.0\n", - " 2729.0\n", - " Jul 22 09:50 PM\n", + " 980.41\n", + " 1590.0\n", + " 1559339.0\n", + " 22905.0\n", + " Dec 07 09:11 PM\n", + " http://www.sec.gov/Archives/edgar/data/1318605...\n", " \n", " \n", " 2\n", " TSLA\n", " Taneja Vaibhav\n", " Chief Accounting Officer\n", - " Jun 05\n", + " Oct 18\n", " Option Exercise\n", - " 0.00\n", - " 733.0\n", - " 0.0\n", - " 3170.0\n", - " Jun 09 09:05 PM\n", + " 54.66\n", + " 7000.0\n", + " 382620.0\n", + " 28212.0\n", + " Oct 20 08:39 PM\n", + " http://www.sec.gov/Archives/edgar/data/1318605...\n", " \n", " \n", " 3\n", " TSLA\n", " Taneja Vaibhav\n", " Chief Accounting Officer\n", - " Jun 08\n", - " Option Exercise\n", - " 273.26\n", - " 500.0\n", - " 136630.0\n", - " 3299.0\n", - " Jun 09 09:05 PM\n", + " Oct 18\n", + " Sale\n", + " 864.31\n", + " 7000.0\n", + " 6050148.0\n", + " 21212.0\n", + " Oct 20 08:39 PM\n", + " http://www.sec.gov/Archives/edgar/data/1318605...\n", " \n", " \n", " 4\n", " TSLA\n", " Taneja Vaibhav\n", " Chief Accounting Officer\n", - " Jun 08\n", - " Sale\n", - " 949.76\n", - " 500.0\n", - " 474880.0\n", - " 2799.0\n", - " Jun 09 09:05 PM\n", + " Sep 05\n", + " Option Exercise\n", + " 0.00\n", + " 3666.0\n", + " 0.0\n", + " 22979.0\n", + " Sep 08 08:25 PM\n", + " http://www.sec.gov/Archives/edgar/data/1318605...\n", " \n", " \n", "\n", @@ -902,21 +1089,28 @@ ], "text/plain": [ " Ticker Owner Relationship Date Transaction \\\n", - "0 TSLA Taneja Vaibhav Chief Accounting Officer Jul 20 Option Exercise \n", - "1 TSLA Taneja Vaibhav Chief Accounting Officer Jul 20 Sale \n", - "2 TSLA Taneja Vaibhav Chief Accounting Officer Jun 05 Option Exercise \n", - "3 TSLA Taneja Vaibhav Chief Accounting Officer Jun 08 Option Exercise \n", - "4 TSLA Taneja Vaibhav Chief Accounting Officer Jun 08 Sale \n", + "0 TSLA Taneja Vaibhav Chief Accounting Officer Dec 05 Option Exercise \n", + "1 TSLA Taneja Vaibhav Chief Accounting Officer Dec 06 Sale \n", + "2 TSLA Taneja Vaibhav Chief Accounting Officer Oct 18 Option Exercise \n", + "3 TSLA Taneja Vaibhav Chief Accounting Officer Oct 18 Sale \n", + "4 TSLA Taneja Vaibhav Chief Accounting Officer Sep 05 Option Exercise \n", "\n", - " Cost #Shares Value ($) #Shares Total SEC Form 4 \n", - "0 273.29 817.0 223277.0 3616.0 Jul 22 09:50 PM \n", - "1 1558.75 887.0 1382608.0 2729.0 Jul 22 09:50 PM \n", - "2 0.00 733.0 0.0 3170.0 Jun 09 09:05 PM \n", - "3 273.26 500.0 136630.0 3299.0 Jun 09 09:05 PM \n", - "4 949.76 500.0 474880.0 2799.0 Jun 09 09:05 PM " + " Cost #Shares Value ($) #Shares Total SEC Form 4 \\\n", + "0 0.00 3283.0 0.0 24495.0 Dec 07 09:11 PM \n", + "1 980.41 1590.0 1559339.0 22905.0 Dec 07 09:11 PM \n", + "2 54.66 7000.0 382620.0 28212.0 Oct 20 08:39 PM \n", + "3 864.31 7000.0 6050148.0 21212.0 Oct 20 08:39 PM \n", + "4 0.00 3666.0 0.0 22979.0 Sep 08 08:25 PM \n", + "\n", + " SEC Form 4 Link \n", + "0 http://www.sec.gov/Archives/edgar/data/1318605... \n", + "1 http://www.sec.gov/Archives/edgar/data/1318605... \n", + "2 http://www.sec.gov/Archives/edgar/data/1318605... \n", + "3 http://www.sec.gov/Archives/edgar/data/1318605... \n", + "4 http://www.sec.gov/Archives/edgar/data/1318605... " ] }, - "execution_count": 14, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" } @@ -924,7 +1118,7 @@ "source": [ "from finvizfinance.insider import Insider\n", "finsider = Insider(option='1771340')\n", - "finsider.getInsider().head()" + "finsider.get_insider().head()" ] }, { @@ -943,16 +1137,14 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "[Info] loading page 1/3 ...\n", - "[Info] loading page 2/3 ...\n", - "[Info] loading page 3/3 ...\n" + "[Info] loading page [##############################] 3/3 \r" ] }, { @@ -991,42 +1183,42 @@ " \n", " \n", " 0\n", - " AAU\n", - " Almaden Minerals Ltd.\n", + " AXU\n", + " Alexco Resource Corp.\n", " Basic Materials\n", - " Gold\n", + " Other Precious Metals & Mining\n", " Canada\n", - " 7.395000e+07\n", + " 3.267500e+08\n", " None\n", - " 0.63\n", - " -0.0721\n", - " 946411.0\n", + " 1.63\n", + " -0.0523\n", + " 716333.0\n", " \n", " \n", " 1\n", - " USAS\n", - " Americas Gold and Silver Corporation\n", + " AAU\n", + " Almaden Minerals Ltd.\n", " Basic Materials\n", - " Other Industrial Metals & Mining\n", + " Gold\n", " Canada\n", - " 2.883500e+08\n", + " 4.171000e+07\n", " None\n", - " 2.72\n", - " -0.0109\n", - " 888371.0\n", + " 0.31\n", + " -0.0442\n", + " 271102.0\n", " \n", " \n", " 2\n", - " AUG\n", - " Auryn Resources Inc.\n", + " USAS\n", + " Americas Gold and Silver Corporation\n", " Basic Materials\n", " Other Industrial Metals & Mining\n", " Canada\n", - " 2.313700e+08\n", - " 14.73\n", - " 2.15\n", - " -0.0092\n", - " 242322.0\n", + " 1.011400e+08\n", + " None\n", + " 0.76\n", + " -0.0332\n", + " 218021.0\n", " \n", " \n", " 3\n", @@ -1035,11 +1227,11 @@ " Basic Materials\n", " Silver\n", " Canada\n", - " 9.723000e+07\n", + " 8.133000e+07\n", " None\n", - " 1.10\n", - " -0.0179\n", - " 1706478.0\n", + " 0.80\n", + " -0.0213\n", + " 233972.0\n", " \n", " \n", " 4\n", @@ -1048,11 +1240,11 @@ " Basic Materials\n", " Gold\n", " Canada\n", - " 6.510000e+09\n", - " 14.94\n", - " 6.23\n", - " -0.0016\n", - " 6132577.0\n", + " 3.910000e+09\n", + " 6.11\n", + " 3.72\n", + " -0.0027\n", + " 11231480.0\n", " \n", " \n", "\n", @@ -1060,28 +1252,28 @@ ], "text/plain": [ " Ticker Company Sector \\\n", - "0 AAU Almaden Minerals Ltd. Basic Materials \n", - "1 USAS Americas Gold and Silver Corporation Basic Materials \n", - "2 AUG Auryn Resources Inc. Basic Materials \n", + "0 AXU Alexco Resource Corp. Basic Materials \n", + "1 AAU Almaden Minerals Ltd. Basic Materials \n", + "2 USAS Americas Gold and Silver Corporation Basic Materials \n", "3 ASM Avino Silver & Gold Mines Ltd. Basic Materials \n", "4 BTG B2Gold Corp. Basic Materials \n", "\n", - " Industry Country Market Cap P/E Price \\\n", - "0 Gold Canada 7.395000e+07 None 0.63 \n", - "1 Other Industrial Metals & Mining Canada 2.883500e+08 None 2.72 \n", - "2 Other Industrial Metals & Mining Canada 2.313700e+08 14.73 2.15 \n", - "3 Silver Canada 9.723000e+07 None 1.10 \n", - "4 Gold Canada 6.510000e+09 14.94 6.23 \n", + " Industry Country Market Cap P/E Price \\\n", + "0 Other Precious Metals & Mining Canada 3.267500e+08 None 1.63 \n", + "1 Gold Canada 4.171000e+07 None 0.31 \n", + "2 Other Industrial Metals & Mining Canada 1.011400e+08 None 0.76 \n", + "3 Silver Canada 8.133000e+07 None 0.80 \n", + "4 Gold Canada 3.910000e+09 6.11 3.72 \n", "\n", - " Change Volume \n", - "0 -0.0721 946411.0 \n", - "1 -0.0109 888371.0 \n", - "2 -0.0092 242322.0 \n", - "3 -0.0179 1706478.0 \n", - "4 -0.0016 6132577.0 " + " Change Volume \n", + "0 -0.0523 716333.0 \n", + "1 -0.0442 271102.0 \n", + "2 -0.0332 218021.0 \n", + "3 -0.0213 233972.0 \n", + "4 -0.0027 11231480.0 " ] }, - "execution_count": 15, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } @@ -1091,7 +1283,7 @@ "foverview = Overview()\n", "filters_dict = {'Exchange':'AMEX','Sector':'Basic Materials'}\n", "foverview.set_filter(filters_dict=filters_dict)\n", - "df = foverview.ScreenerView(order='Company')\n", + "df = foverview.screener_view(order='Company')\n", "df.head()" ] }, @@ -1104,7 +1296,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 19, "metadata": {}, "outputs": [ { @@ -1151,168 +1343,453 @@ " \n", " 0\n", " AYRO\n", - " 7.893000e+07\n", - " None\n", - " -1.104\n", - " -2.219\n", + " 8.094000e+07\n", " None\n", - " 1.6\n", - " 1.6\n", - " 0\n", - " 0\n", + " -0.378\n", + " -0.4\n", " None\n", + " 14.2\n", + " 13.7\n", + " 0.0\n", + " 0.0\n", + " -0.189\n", " None\n", " None\n", - " -\n", - " 3.21\n", - " 0.0559\n", - " 1012533.0\n", + " Nov 15/b\n", + " 2.06\n", + " 0.0098\n", + " 402231.0\n", " \n", " \n", " 1\n", " BLBD\n", - " 3.159000e+08\n", + " 4.879900e+08\n", " None\n", - " 0.031\n", - " -0.180\n", - " 0.302\n", - " 1.3\n", + " 0.043\n", + " -0.271\n", + " 0.16\n", + " 0.9\n", " 0.2\n", " None\n", " None\n", - " 0.12\n", + " 0.115\n", " 0.028\n", - " 0.013\n", - " Aug 12/a\n", - " 11.70\n", - " 0.0009\n", - " 145036.0\n", + " 0.018\n", + " Dec 15/a\n", + " 17.36\n", + " -0.0203\n", + " 129770.0\n", " \n", " \n", " 2\n", - " F\n", - " 2.785000e+10\n", + " ELMS\n", + " 9.265000e+08\n", " None\n", - " -0.008\n", - " -0.066\n", - " 0.007\n", - " 1.3\n", - " 1.2\n", - " 3.89\n", - " 5.68\n", - " 0.044\n", - " -0.039\n", - " -0.016\n", - " Jul 30/a\n", - " 6.94\n", - " -0.0057\n", - " 49043083.0\n", + " None\n", + " None\n", + " None\n", + " 2.6\n", + " 2.5\n", + " 0.11\n", + " 0.31\n", + " None\n", + " None\n", + " None\n", + " Nov 10/a\n", + " 7.20\n", + " -0.0041\n", + " 253061.0\n", " \n", " \n", " 3\n", - " GM\n", - " 4.289000e+10\n", - " None\n", - " 0.006\n", - " 0.037\n", - " 0.032\n", - " 1.1\n", - " 1\n", - " 2.22\n", - " 3.24\n", - " 0.083\n", + " F\n", + " 8.899000e+10\n", + " 0.0186\n", + " 0.011\n", + " 0.084\n", + " -0.024\n", + " 1.2\n", + " 1.0\n", + " 2.66\n", + " 3.95\n", + " 0.101\n", " 0.01\n", - " 0.013\n", - " Jul 29/b\n", - " 29.69\n", - " -0.0205\n", - " 12985365.0\n", + " 0.021\n", + " Oct 27/a\n", + " 21.45\n", + " 0.0961\n", + " 168050902.0\n", " \n", " \n", " 4\n", - " NKLA\n", - " 1.544000e+10\n", + " FFIE\n", + " 2.020000e+09\n", " None\n", - " -0.324\n", - " -0.340\n", + " -0.044\n", + " -0.045\n", " None\n", + " 0.1\n", + " 0.1\n", + " 0.0\n", + " 0.0\n", " None\n", " None\n", - " 0\n", - " 0.01\n", + " None\n", + " -\n", + " 5.41\n", + " -0.0181\n", + " 1162044.0\n", + " \n", + " \n", + " 5\n", + " FSR\n", + " 5.690000e+09\n", + " None\n", + " -0.334\n", + " -0.421\n", + " None\n", + " 18.4\n", + " 18.4\n", + " 0.73\n", + " 0.0\n", " None\n", " None\n", " None\n", - " Aug 04/a\n", - " 39.18\n", - " 0.0127\n", - " 5460998.0\n", + " Nov 03/a\n", + " 17.83\n", + " -0.0017\n", + " 4227609.0\n", " \n", " \n", - " 5\n", - " TSLA\n", - " 3.682100e+11\n", + " 6\n", + " GM\n", + " 9.379000e+10\n", " None\n", - " 0.010\n", " 0.046\n", - " -0.009\n", - " 1.2\n", + " 0.22\n", + " 0.031\n", + " 1.1\n", " 0.9\n", - " 1.06\n", - " 1.43\n", - " 0.198\n", - " 0.048\n", - " 0.014\n", - " Jul 22/a\n", - " 2023.34\n", - " 0.0045\n", - " 10549296.0\n", + " 1.37\n", + " 2.01\n", + " 0.143\n", + " 0.081\n", + " 0.084\n", + " Oct 27/b\n", + " 63.21\n", + " 0.0602\n", + " 22569629.0\n", + " \n", + " \n", + " 7\n", + " GOEV\n", + " 2.500000e+09\n", + " None\n", + " -0.424\n", + " -0.549\n", + " -0.34\n", + " 4.0\n", + " 4.0\n", + " 0.0\n", + " 0.0\n", + " 0.737\n", + " None\n", + " None\n", + " Nov 15/a\n", + " 9.36\n", + " -0.0085\n", + " 2822866.0\n", " \n", " \n", - " 6\n", - " WKHS\n", - " 1.930000e+09\n", + " 8\n", + " HYZN\n", + " 1.840000e+09\n", " None\n", - " -3.081\n", - " 3.316\n", - " -1.029\n", - " 0.3\n", - " 0.3\n", + " 0.044\n", + " 0.059\n", + " None\n", + " 16.3\n", + " 15.9\n", + " 0.0\n", + " 0.0\n", + " -0.006\n", + " None\n", + " None\n", + " Nov 12/b\n", + " 6.72\n", + " -0.0132\n", + " 1099254.0\n", + " \n", + " \n", + " 9\n", + " LCID\n", + " 6.350000e+10\n", " None\n", + " -1.48\n", + " -2.262\n", " None\n", + " 18.5\n", + " 18.3\n", + " 0.0\n", + " 0.01\n", " None\n", " None\n", " None\n", - " Aug 10/b\n", - " 18.20\n", - " 0.1081\n", - " 29521025.0\n", + " Nov 15/a\n", + " 37.66\n", + " 0.0312\n", + " 91378217.0\n", " \n", - " \n", + " \n", + " 10\n", + " MULN\n", + " 1.407000e+08\n", + " None\n", + " -0.099\n", + " -0.616\n", + " -0.357\n", + " 1.2\n", + " 1.2\n", + " 1.29\n", + " 1.37\n", + " 0.127\n", + " -0.013\n", + " -0.029\n", + " -\n", + " 6.41\n", + " -0.0077\n", + " 605228.0\n", + " \n", + " \n", + " 11\n", + " NKLA\n", + " 4.130000e+09\n", + " None\n", + " -0.669\n", + " -0.779\n", + " None\n", + " None\n", + " None\n", + " 0.0\n", + " 0.04\n", + " None\n", + " None\n", + " None\n", + " Nov 04/b\n", + " 9.72\n", + " -0.0221\n", + " 7283083.0\n", + " \n", + " \n", + " 12\n", + " PTRA\n", + " 2.240000e+09\n", + " None\n", + " None\n", + " None\n", + " None\n", + " 10.9\n", + " 9.8\n", + " 0.14\n", + " 0.16\n", + " None\n", + " None\n", + " None\n", + " Nov 10/a\n", + " 9.14\n", + " -0.0577\n", + " 2122142.0\n", + " \n", + " \n", + " 13\n", + " RIDE\n", + " 8.276300e+08\n", + " None\n", + " -0.547\n", + " -0.634\n", + " None\n", + " 2.9\n", + " 2.9\n", + " 0.0\n", + " 0.0\n", + " None\n", + " None\n", + " None\n", + " Nov 11/a\n", + " 4.16\n", + " -0.0119\n", + " 3435230.0\n", + " \n", + " \n", + " 14\n", + " RIVN\n", + " 1.034900e+11\n", + " None\n", + " None\n", + " None\n", + " None\n", + " 4.7\n", + " 4.7\n", + " None\n", + " None\n", + " None\n", + " None\n", + " None\n", + " -\n", + " 114.66\n", + " -0.0064\n", + " 8328876.0\n", + " \n", + " \n", + " 15\n", + " SEV\n", + " NaN\n", + " None\n", + " None\n", + " None\n", + " None\n", + " None\n", + " None\n", + " None\n", + " None\n", + " None\n", + " None\n", + " None\n", + " -\n", + " 14.26\n", + " 0.0341\n", + " 518902.0\n", + " \n", + " \n", + " 16\n", + " TSLA\n", + " 9.797400e+11\n", + " None\n", + " 0.064\n", + " 0.143\n", + " 0.05\n", + " 1.4\n", + " 1.1\n", + " 0.24\n", + " 0.3\n", + " 0.231\n", + " 0.096\n", + " 0.074\n", + " Oct 20/a\n", + " 1017.03\n", + " 0.0132\n", + " 19708422.0\n", + " \n", + " \n", + " 17\n", + " VLCN\n", + " 1.420600e+08\n", + " None\n", + " None\n", + " None\n", + " None\n", + " 1.6\n", + " 1.1\n", + " 0.02\n", + " 0.27\n", + " None\n", + " None\n", + " None\n", + " -\n", + " 11.42\n", + " 0.0683\n", + " 81423.0\n", + " \n", + " \n", + " 18\n", + " WKHS\n", + " 8.187100e+08\n", + " None\n", + " 0.074\n", + " 0.136\n", + " -0.114\n", + " 1.9\n", + " 1.5\n", + " 0.18\n", + " 1.28\n", + " None\n", + " None\n", + " None\n", + " Nov 09/b\n", + " 4.99\n", + " -0.0235\n", + " 5470937.0\n", + " \n", + " \n", "\n", "" ], "text/plain": [ - " Ticker Market Cap Dividend ROA ROE ROI Curr R Quick R LTDebt/Eq \\\n", - "0 AYRO 7.893000e+07 None -1.104 -2.219 None 1.6 1.6 0 \n", - "1 BLBD 3.159000e+08 None 0.031 -0.180 0.302 1.3 0.2 None \n", - "2 F 2.785000e+10 None -0.008 -0.066 0.007 1.3 1.2 3.89 \n", - "3 GM 4.289000e+10 None 0.006 0.037 0.032 1.1 1 2.22 \n", - "4 NKLA 1.544000e+10 None -0.324 -0.340 None None None 0 \n", - "5 TSLA 3.682100e+11 None 0.010 0.046 -0.009 1.2 0.9 1.06 \n", - "6 WKHS 1.930000e+09 None -3.081 3.316 -1.029 0.3 0.3 None \n", + " Ticker Market Cap Dividend ROA ROE ROI Curr R Quick R \\\n", + "0 AYRO 8.094000e+07 None -0.378 -0.4 None 14.2 13.7 \n", + "1 BLBD 4.879900e+08 None 0.043 -0.271 0.16 0.9 0.2 \n", + "2 ELMS 9.265000e+08 None None None None 2.6 2.5 \n", + "3 F 8.899000e+10 0.0186 0.011 0.084 -0.024 1.2 1.0 \n", + "4 FFIE 2.020000e+09 None -0.044 -0.045 None 0.1 0.1 \n", + "5 FSR 5.690000e+09 None -0.334 -0.421 None 18.4 18.4 \n", + "6 GM 9.379000e+10 None 0.046 0.22 0.031 1.1 0.9 \n", + "7 GOEV 2.500000e+09 None -0.424 -0.549 -0.34 4.0 4.0 \n", + "8 HYZN 1.840000e+09 None 0.044 0.059 None 16.3 15.9 \n", + "9 LCID 6.350000e+10 None -1.48 -2.262 None 18.5 18.3 \n", + "10 MULN 1.407000e+08 None -0.099 -0.616 -0.357 1.2 1.2 \n", + "11 NKLA 4.130000e+09 None -0.669 -0.779 None None None \n", + "12 PTRA 2.240000e+09 None None None None 10.9 9.8 \n", + "13 RIDE 8.276300e+08 None -0.547 -0.634 None 2.9 2.9 \n", + "14 RIVN 1.034900e+11 None None None None 4.7 4.7 \n", + "15 SEV NaN None None None None None None \n", + "16 TSLA 9.797400e+11 None 0.064 0.143 0.05 1.4 1.1 \n", + "17 VLCN 1.420600e+08 None None None None 1.6 1.1 \n", + "18 WKHS 8.187100e+08 None 0.074 0.136 -0.114 1.9 1.5 \n", "\n", - " Debt/Eq Gross M Oper M Profit M Earnings Price Change Volume \n", - "0 0 None None None - 3.21 0.0559 1012533.0 \n", - "1 None 0.12 0.028 0.013 Aug 12/a 11.70 0.0009 145036.0 \n", - "2 5.68 0.044 -0.039 -0.016 Jul 30/a 6.94 -0.0057 49043083.0 \n", - "3 3.24 0.083 0.01 0.013 Jul 29/b 29.69 -0.0205 12985365.0 \n", - "4 0.01 None None None Aug 04/a 39.18 0.0127 5460998.0 \n", - "5 1.43 0.198 0.048 0.014 Jul 22/a 2023.34 0.0045 10549296.0 \n", - "6 None None None None Aug 10/b 18.20 0.1081 29521025.0 " + " LTDebt/Eq Debt/Eq Gross M Oper M Profit M Earnings Price Change \\\n", + "0 0.0 0.0 -0.189 None None Nov 15/b 2.06 0.0098 \n", + "1 None None 0.115 0.028 0.018 Dec 15/a 17.36 -0.0203 \n", + "2 0.11 0.31 None None None Nov 10/a 7.20 -0.0041 \n", + "3 2.66 3.95 0.101 0.01 0.021 Oct 27/a 21.45 0.0961 \n", + "4 0.0 0.0 None None None - 5.41 -0.0181 \n", + "5 0.73 0.0 None None None Nov 03/a 17.83 -0.0017 \n", + "6 1.37 2.01 0.143 0.081 0.084 Oct 27/b 63.21 0.0602 \n", + "7 0.0 0.0 0.737 None None Nov 15/a 9.36 -0.0085 \n", + "8 0.0 0.0 -0.006 None None Nov 12/b 6.72 -0.0132 \n", + "9 0.0 0.01 None None None Nov 15/a 37.66 0.0312 \n", + "10 1.29 1.37 0.127 -0.013 -0.029 - 6.41 -0.0077 \n", + "11 0.0 0.04 None None None Nov 04/b 9.72 -0.0221 \n", + "12 0.14 0.16 None None None Nov 10/a 9.14 -0.0577 \n", + "13 0.0 0.0 None None None Nov 11/a 4.16 -0.0119 \n", + "14 None None None None None - 114.66 -0.0064 \n", + "15 None None None None None - 14.26 0.0341 \n", + "16 0.24 0.3 0.231 0.096 0.074 Oct 20/a 1017.03 0.0132 \n", + "17 0.02 0.27 None None None - 11.42 0.0683 \n", + "18 0.18 1.28 None None None Nov 09/b 4.99 -0.0235 \n", + "\n", + " Volume \n", + "0 402231.0 \n", + "1 129770.0 \n", + "2 253061.0 \n", + "3 168050902.0 \n", + "4 1162044.0 \n", + "5 4227609.0 \n", + "6 22569629.0 \n", + "7 2822866.0 \n", + "8 1099254.0 \n", + "9 91378217.0 \n", + "10 605228.0 \n", + "11 7283083.0 \n", + "12 2122142.0 \n", + "13 3435230.0 \n", + "14 8328876.0 \n", + "15 518902.0 \n", + "16 19708422.0 \n", + "17 81423.0 \n", + "18 5470937.0 " ] }, - "execution_count": 16, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } @@ -1336,15 +1813,14 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "[Info] loading page 1/2 ...\n", - "[Info] loading page 2/2 ...\n" + "[Info] loading page [##############################] 2/2 \r" ] }, { @@ -1383,90 +1859,97 @@ " \n", " \n", " 0\n", - " TOWN\n", - " TowneBank\n", + " SMCP\n", + " AlphaMark Actively Managed Small Cap ETF\n", " Financial\n", - " Banks - Regional\n", + " Exchange Traded Fund\n", " USA\n", - " 1.380000e+09\n", - " 9.7\n", - " 18.70\n", - " 0.0180\n", - " 206678.0\n", + " NaN\n", + " NaN\n", + " 30.96\n", + " 0.0098\n", + " 8.0\n", " \n", " \n", " 1\n", - " RBCAA\n", - " Republic Bancorp, Inc.\n", - " Financial\n", - " Banks - Regional\n", - " USA\n", - " 6.818700e+08\n", - " 7.72\n", - " 31.70\n", - " 0.0141\n", - " 15481.0\n", + " TM\n", + " Toyota Motor Corporation\n", + " Consumer Cyclical\n", + " Auto Manufacturers\n", + " Japan\n", + " 2.958100e+11\n", + " 9.24\n", + " 182.35\n", + " 0.0087\n", + " 124651.0\n", " \n", " \n", " 2\n", - " MO\n", - " Altria Group, Inc.\n", - " Consumer Defensive\n", - " Tobacco\n", + " CSWC\n", + " Capital Southwest Corporation\n", + " Financial\n", + " Asset Management\n", " USA\n", - " 8.095000e+10\n", - " None\n", - " 43.52\n", - " -0.0118\n", - " 6111766.0\n", + " 6.257700e+08\n", + " 10.29\n", + " 26.88\n", + " 0.0011\n", + " 123642.0\n", " \n", " \n", " 3\n", - " AMNB\n", - " American National Bankshares Inc.\n", + " PMGMU\n", + " Priveterra Acquisition Corp.\n", " Financial\n", - " Banks - Regional\n", + " Shell Companies\n", " USA\n", - " 2.680100e+08\n", - " 8.63\n", - " 23.51\n", - " 0.0129\n", - " 7659.0\n", + " NaN\n", + " NaN\n", + " 9.98\n", + " 0.0010\n", + " 56142.0\n", " \n", " \n", " 4\n", - " KSCD\n", - " KFA Small Cap Quality Dividend Index ETF\n", + " BRK-A\n", + " Berkshire Hathaway Inc.\n", " Financial\n", - " Exchange Traded Fund\n", + " Insurance - Diversified\n", " USA\n", - " NaN\n", - " None\n", - " 23.21\n", - " -0.0018\n", - " 1076.0\n", + " 6.481500e+11\n", + " 7.76\n", + " 435000.00\n", + " 0.0154\n", + " 1569.0\n", " \n", " \n", "\n", "" ], "text/plain": [ - " Ticker Company Sector \\\n", - "0 TOWN TowneBank Financial \n", - "1 RBCAA Republic Bancorp, Inc. Financial \n", - "2 MO Altria Group, Inc. Consumer Defensive \n", - "3 AMNB American National Bankshares Inc. Financial \n", - "4 KSCD KFA Small Cap Quality Dividend Index ETF Financial \n", + " Ticker Company Sector \\\n", + "0 SMCP AlphaMark Actively Managed Small Cap ETF Financial \n", + "1 TM Toyota Motor Corporation Consumer Cyclical \n", + "2 CSWC Capital Southwest Corporation Financial \n", + "3 PMGMU Priveterra Acquisition Corp. Financial \n", + "4 BRK-A Berkshire Hathaway Inc. Financial \n", + "\n", + " Industry Country Market Cap P/E Price Change \\\n", + "0 Exchange Traded Fund USA NaN NaN 30.96 0.0098 \n", + "1 Auto Manufacturers Japan 2.958100e+11 9.24 182.35 0.0087 \n", + "2 Asset Management USA 6.257700e+08 10.29 26.88 0.0011 \n", + "3 Shell Companies USA NaN NaN 9.98 0.0010 \n", + "4 Insurance - Diversified USA 6.481500e+11 7.76 435000.00 0.0154 \n", "\n", - " Industry Country Market Cap P/E Price Change Volume \n", - "0 Banks - Regional USA 1.380000e+09 9.7 18.70 0.0180 206678.0 \n", - "1 Banks - Regional USA 6.818700e+08 7.72 31.70 0.0141 15481.0 \n", - "2 Tobacco USA 8.095000e+10 None 43.52 -0.0118 6111766.0 \n", - "3 Banks - Regional USA 2.680100e+08 8.63 23.51 0.0129 7659.0 \n", - "4 Exchange Traded Fund USA NaN None 23.21 -0.0018 1076.0 " + " Volume \n", + "0 8.0 \n", + "1 124651.0 \n", + "2 123642.0 \n", + "3 56142.0 \n", + "4 1569.0 " ] }, - "execution_count": 17, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } @@ -1474,7 +1957,7 @@ "source": [ "signal = 'Triangle Ascending'\n", "foverview.set_filter(signal=signal)\n", - "df = foverview.ScreenerView()\n", + "df = foverview.screener_view()\n", "df.head()" ] }, @@ -1487,14 +1970,14 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "[Info] loading page 1/1 ...\n" + "[Info] loading page [##############################] 1/1 \r" ] }, { @@ -1538,11 +2021,11 @@ " Consumer Cyclical\n", " Auto Manufacturers\n", " USA\n", - " 3.682100e+11\n", - " 1041.35\n", - " 2023.34\n", - " 0.0045\n", - " 10549296.0\n", + " 9.797400e+11\n", + " 329.99\n", + " 1017.03\n", + " 0.0132\n", + " 19708422.0\n", " \n", " \n", "\n", @@ -1552,11 +2035,11 @@ " Ticker Company Sector Industry Country \\\n", "0 TSLA Tesla, Inc. Consumer Cyclical Auto Manufacturers USA \n", "\n", - " Market Cap P/E Price Change Volume \n", - "0 3.682100e+11 1041.35 2023.34 0.0045 10549296.0 " + " Market Cap P/E Price Change Volume \n", + "0 9.797400e+11 329.99 1017.03 0.0132 19708422.0 " ] }, - "execution_count": 18, + "execution_count": 21, "metadata": {}, "output_type": "execute_result" } @@ -1564,7 +2047,7 @@ "source": [ "ticker='TSLA'\n", "foverview.set_filter(signal='', filters_dict={}, ticker=ticker)\n", - "df = foverview.ScreenerView()\n", + "df = foverview.screener_view()\n", "df.head()" ] }, @@ -1577,18 +2060,229 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 23, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
TickerPricePerf 5MinPerf HourPerf DayPerf WeekPerf MonthPerf QuartPerf HalfPerf YearPerf YTD
0BTCUSD49390.7500-0.00310.01070.01600.0078-0.23590.09310.34271.74950.6862
1GBPUSD1.32680.0004-0.00010.00370.0027-0.0100-0.0403-0.0641-0.0015-0.0285
2AUDUSD0.7169-0.0004-0.00050.00300.0249-0.0215-0.0245-0.0748-0.0483-0.0690
3GBPJPY150.400.0001-0.00060.00300.0083-0.0147-0.0102-0.02940.08600.0667
4EURUSD1.1316-0.0000-0.00010.00210.0009-0.0141-0.0417-0.0700-0.0674-0.0737
5USDCAD1.2722-0.00020.00010.0008-0.00870.01890.00280.0520-0.0010-0.0026
6NZDUSD0.6792-0.0007-0.0008-0.00010.0071-0.0378-0.0443-0.0557-0.0427-0.0550
7USDJPY113.33-0.0005-0.0008-0.00110.0050-0.00500.03140.03670.08730.0976
8EURGBP0.8528-0.0003-0.0001-0.0014-0.0007-0.0038-0.0010-0.0064-0.0655-0.0465
9USDCHF0.9206-0.0000-0.0001-0.00280.00320.00270.00360.02930.03890.0395
\n", + "
" + ], + "text/plain": [ + " Ticker Price Perf 5Min Perf Hour Perf Day Perf Week Perf Month \\\n", + "0 BTCUSD 49390.7500 -0.0031 0.0107 0.0160 0.0078 -0.2359 \n", + "1 GBPUSD 1.3268 0.0004 -0.0001 0.0037 0.0027 -0.0100 \n", + "2 AUDUSD 0.7169 -0.0004 -0.0005 0.0030 0.0249 -0.0215 \n", + "3 GBPJPY 150.40 0.0001 -0.0006 0.0030 0.0083 -0.0147 \n", + "4 EURUSD 1.1316 -0.0000 -0.0001 0.0021 0.0009 -0.0141 \n", + "5 USDCAD 1.2722 -0.0002 0.0001 0.0008 -0.0087 0.0189 \n", + "6 NZDUSD 0.6792 -0.0007 -0.0008 -0.0001 0.0071 -0.0378 \n", + "7 USDJPY 113.33 -0.0005 -0.0008 -0.0011 0.0050 -0.0050 \n", + "8 EURGBP 0.8528 -0.0003 -0.0001 -0.0014 -0.0007 -0.0038 \n", + "9 USDCHF 0.9206 -0.0000 -0.0001 -0.0028 0.0032 0.0027 \n", + "\n", + " Perf Quart Perf Half Perf Year Perf YTD \n", + "0 0.0931 0.3427 1.7495 0.6862 \n", + "1 -0.0403 -0.0641 -0.0015 -0.0285 \n", + "2 -0.0245 -0.0748 -0.0483 -0.0690 \n", + "3 -0.0102 -0.0294 0.0860 0.0667 \n", + "4 -0.0417 -0.0700 -0.0674 -0.0737 \n", + "5 0.0028 0.0520 -0.0010 -0.0026 \n", + "6 -0.0443 -0.0557 -0.0427 -0.0550 \n", + "7 0.0314 0.0367 0.0873 0.0976 \n", + "8 -0.0010 -0.0064 -0.0655 -0.0465 \n", + "9 0.0036 0.0293 0.0389 0.0395 " + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "from finvizfinance.forex import Forex\n", "fforex = Forex()\n", - "df = fforex.performance()" + "df = fforex.performance()\n", + "df" ] }, { "cell_type": "code", - "execution_count": 20, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -1604,14 +2298,288 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 27, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
TickerPricePerf 5MinPerf HourPerf DayPerf WeekPerf MonthPerf QuartPerf HalfPerf YearPerf YTD
0LTCEUR138.7400-0.0037-0.00320.0266-0.0144-0.3781-0.0635-0.01321.34750.3004
1LTCUSD156.8800-0.0017-0.00100.0261-0.0131-0.3866-0.1010-0.08401.18340.1988
2BTCEUR43668.9000-0.00390.00970.01660.0076-0.22510.14190.44661.95240.8281
3BTCUSD49411.7400-0.00270.01120.01650.0082-0.23560.09360.34331.75070.6870
4BCHEUR404.5700-0.0061-0.00340.0094-0.0228-0.3066-0.2410-0.17510.88850.4203
5LTCBTC0.0032-0.0031-0.01090.0093-0.0226-0.1979-0.1793-0.3193-0.2063-0.2904
6ETHEUR3600.9600-0.00380.01040.0084-0.0230-0.10890.31300.77797.01714.9278
7ETHUSD4065.0000-0.00240.00960.0073-0.0238-0.12300.25610.64796.45164.4662
8BCHUSD456.50000.00010.00090.0066-0.0225-0.3184-0.2757-0.23790.75680.3075
9XRPUSD0.8317-0.0040-0.00070.00390.0082-0.3106-0.2162-0.04230.49302.4708
10XRPEUR0.7348-0.0023-0.00300.00120.0070-0.3011-0.18140.03140.60392.7778
11ETHBTC0.08230.0009-0.0011-0.0102-0.03080.14840.14750.22691.70832.2347
12BCHBTC0.0092-0.0104-0.0087-0.0113-0.0328-0.1087-0.3401-0.4319-0.3609-0.2264
13XRPBTC0.0000-0.0036-0.0100-0.0146-0.0036-0.0961-0.2834-0.2873-0.45801.0587
\n", + "
" + ], + "text/plain": [ + " Ticker Price Perf 5Min Perf Hour Perf Day Perf Week Perf Month \\\n", + "0 LTCEUR 138.7400 -0.0037 -0.0032 0.0266 -0.0144 -0.3781 \n", + "1 LTCUSD 156.8800 -0.0017 -0.0010 0.0261 -0.0131 -0.3866 \n", + "2 BTCEUR 43668.9000 -0.0039 0.0097 0.0166 0.0076 -0.2251 \n", + "3 BTCUSD 49411.7400 -0.0027 0.0112 0.0165 0.0082 -0.2356 \n", + "4 BCHEUR 404.5700 -0.0061 -0.0034 0.0094 -0.0228 -0.3066 \n", + "5 LTCBTC 0.0032 -0.0031 -0.0109 0.0093 -0.0226 -0.1979 \n", + "6 ETHEUR 3600.9600 -0.0038 0.0104 0.0084 -0.0230 -0.1089 \n", + "7 ETHUSD 4065.0000 -0.0024 0.0096 0.0073 -0.0238 -0.1230 \n", + "8 BCHUSD 456.5000 0.0001 0.0009 0.0066 -0.0225 -0.3184 \n", + "9 XRPUSD 0.8317 -0.0040 -0.0007 0.0039 0.0082 -0.3106 \n", + "10 XRPEUR 0.7348 -0.0023 -0.0030 0.0012 0.0070 -0.3011 \n", + "11 ETHBTC 0.0823 0.0009 -0.0011 -0.0102 -0.0308 0.1484 \n", + "12 BCHBTC 0.0092 -0.0104 -0.0087 -0.0113 -0.0328 -0.1087 \n", + "13 XRPBTC 0.0000 -0.0036 -0.0100 -0.0146 -0.0036 -0.0961 \n", + "\n", + " Perf Quart Perf Half Perf Year Perf YTD \n", + "0 -0.0635 -0.0132 1.3475 0.3004 \n", + "1 -0.1010 -0.0840 1.1834 0.1988 \n", + "2 0.1419 0.4466 1.9524 0.8281 \n", + "3 0.0936 0.3433 1.7507 0.6870 \n", + "4 -0.2410 -0.1751 0.8885 0.4203 \n", + "5 -0.1793 -0.3193 -0.2063 -0.2904 \n", + "6 0.3130 0.7779 7.0171 4.9278 \n", + "7 0.2561 0.6479 6.4516 4.4662 \n", + "8 -0.2757 -0.2379 0.7568 0.3075 \n", + "9 -0.2162 -0.0423 0.4930 2.4708 \n", + "10 -0.1814 0.0314 0.6039 2.7778 \n", + "11 0.1475 0.2269 1.7083 2.2347 \n", + "12 -0.3401 -0.4319 -0.3609 -0.2264 \n", + "13 -0.2834 -0.2873 -0.4580 1.0587 " + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "from finvizfinance.crypto import Crypto\n", "fcrypto = Crypto()\n", - "fcrypto.performance()\n", - "fcrypto.chart('btcusd',timeframe='5M')" + "df = fcrypto.performance()\n", + "df" ] }, { @@ -1623,7 +2591,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 28, "metadata": {}, "outputs": [ { @@ -1663,67 +2631,67 @@ " \n", " 139\n", " Utilities - Regulated Electric\n", - " 37\n", - " 6.705700e+11\n", - " 0.0331\n", - " 23.03\n", - " 17.75\n", - " 3.9\n", - " 0.0162\n", - " -0.0060\n", - " 52580000.0\n", + " 38\n", + " 7.819700e+11\n", + " 0.0326\n", + " 25.24\n", + " 1.91\n", + " 3.59\n", + " 0.0149\n", + " 0.0050\n", + " 48220000.0\n", " \n", " \n", " 140\n", " Utilities - Regulated Gas\n", - " 12\n", - " 6.018000e+10\n", - " 0.0307\n", - " 33.01\n", - " 16.33\n", - " 8.94\n", - " 0.0256\n", - " -0.0118\n", - " 7990000.0\n", + " 15\n", + " 7.858000e+10\n", + " 0.0294\n", + " 17.56\n", + " 17.74\n", + " 3.76\n", + " 0.0299\n", + " 0.0099\n", + " 13070000.0\n", " \n", " \n", " 141\n", " Utilities - Regulated Water\n", - " 15\n", - " 5.362000e+10\n", - " 0.0186\n", - " 36.21\n", - " 35.5\n", - " 4.39\n", - " 0.0181\n", - " 0.0004\n", - " 3630000.0\n", + " 18\n", + " 6.778000e+10\n", + " 0.0145\n", + " 32.64\n", + " 38.46\n", + " 4.02\n", + " 0.0146\n", + " 0.0032\n", + " 6670000.0\n", " \n", " \n", " 142\n", " Utilities - Renewable\n", - " 11\n", - " 4.180000e+10\n", - " 0.0291\n", - " 41.76\n", - " 68.31\n", - " 3.42\n", - " 0.0193\n", - " -0.0028\n", - " 4000000.0\n", + " 16\n", + " 7.277000e+10\n", + " 0.0302\n", + " 45.18\n", + " 74.83\n", + " 1.45\n", + " 0.0222\n", + " -0.0072\n", + " 8520000.0\n", " \n", " \n", " 143\n", " Waste Management\n", - " 23\n", - " 1.277200e+11\n", - " 0.0133\n", - " 42.81\n", - " 30.24\n", - " 9.85\n", - " 0.0213\n", - " 0.0049\n", - " 10350000.0\n", + " 21\n", + " 1.882400e+11\n", + " 0.0097\n", + " 47.58\n", + " 34.90\n", + " 3.39\n", + " 0.0212\n", + " 0.0044\n", + " 7620000.0\n", " \n", " \n", "\n", @@ -1731,21 +2699,21 @@ ], "text/plain": [ " Name Stocks Market Cap Dividend P/E \\\n", - "139 Utilities - Regulated Electric 37 6.705700e+11 0.0331 23.03 \n", - "140 Utilities - Regulated Gas 12 6.018000e+10 0.0307 33.01 \n", - "141 Utilities - Regulated Water 15 5.362000e+10 0.0186 36.21 \n", - "142 Utilities - Renewable 11 4.180000e+10 0.0291 41.76 \n", - "143 Waste Management 23 1.277200e+11 0.0133 42.81 \n", + "139 Utilities - Regulated Electric 38 7.819700e+11 0.0326 25.24 \n", + "140 Utilities - Regulated Gas 15 7.858000e+10 0.0294 17.56 \n", + "141 Utilities - Regulated Water 18 6.778000e+10 0.0145 32.64 \n", + "142 Utilities - Renewable 16 7.277000e+10 0.0302 45.18 \n", + "143 Waste Management 21 1.882400e+11 0.0097 47.58 \n", "\n", - " Fwd P/E PEG Float Short Change Volume \n", - "139 17.75 3.9 0.0162 -0.0060 52580000.0 \n", - "140 16.33 8.94 0.0256 -0.0118 7990000.0 \n", - "141 35.5 4.39 0.0181 0.0004 3630000.0 \n", - "142 68.31 3.42 0.0193 -0.0028 4000000.0 \n", - "143 30.24 9.85 0.0213 0.0049 10350000.0 " + " Fwd P/E PEG Float Short Change Volume \n", + "139 1.91 3.59 0.0149 0.0050 48220000.0 \n", + "140 17.74 3.76 0.0299 0.0099 13070000.0 \n", + "141 38.46 4.02 0.0146 0.0032 6670000.0 \n", + "142 74.83 1.45 0.0222 -0.0072 8520000.0 \n", + "143 34.90 3.39 0.0212 0.0044 7620000.0 " ] }, - "execution_count": 22, + "execution_count": 28, "metadata": {}, "output_type": "execute_result" } @@ -1753,13 +2721,13 @@ "source": [ "from finvizfinance.group.overview import Overview\n", "fgoverview = Overview()\n", - "df = fgoverview.ScreenerView(group='Industry')\n", + "df = fgoverview.screener_view(group='Industry')\n", "df.tail()" ] }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 29, "metadata": {}, "outputs": [ { @@ -1803,87 +2771,87 @@ " \n", " 139\n", " Utilities - Regulated Electric\n", - " 670.57B\n", - " 23.03\n", - " 17.75\n", - " 3.9\n", - " 2.38\n", - " 1.62\n", - " 33.41\n", - " 45.21\n", - " 0.0232\n", - " 0.0590\n", - " 0.0202\n", - " -0.0060\n", - " 52580000.0\n", + " 781.97B\n", + " 25.24\n", + " 1.91\n", + " 3.59\n", + " 1.91\n", + " 1.17\n", + " 35.81\n", + " 64.73\n", + " -0.0089\n", + " 0.0702\n", + " 0.0196\n", + " 0.0050\n", + " 48220000.0\n", " \n", " \n", " 140\n", " Utilities - Regulated Gas\n", - " 60.18B\n", - " 33.01\n", - " 16.33\n", - " 8.94\n", - " 1.73\n", - " 1.85\n", - " 28.26\n", - " 48.94\n", - " 0.0274\n", - " 0.0369\n", - " -0.0137\n", - " -0.0118\n", - " 7990000.0\n", + " 78.58B\n", + " 17.56\n", + " 17.74\n", + " 3.76\n", + " 2.05\n", + " 2.02\n", + " 28.75\n", + " 42.14\n", + " 0.0548\n", + " 0.0467\n", + " 0.0303\n", + " 0.0099\n", + " 13070000.0\n", " \n", " \n", " 141\n", " Utilities - Regulated Water\n", - " 53.62B\n", - " 36.21\n", - " 35.50\n", - " 4.39\n", - " 5.22\n", - " 2.95\n", - " 37.65\n", - " 61.32\n", - " 0.0576\n", - " 0.0825\n", - " 0.0415\n", - " 0.0004\n", - " 3630000.0\n", + " 67.78B\n", + " 32.64\n", + " 38.46\n", + " 4.02\n", + " 4.92\n", + " 3.12\n", + " 42.91\n", + " 61.9\n", + " 0.0521\n", + " 0.0812\n", + " 0.0581\n", + " 0.0032\n", + " 6670000.0\n", " \n", " \n", " 142\n", " Utilities - Renewable\n", - " 41.80B\n", - " 41.76\n", - " 68.31\n", - " 3.42\n", - " 3.56\n", - " 2.33\n", - " 23.16\n", - " 109.92\n", - " -0.3193\n", - " 0.1221\n", - " 0.1531\n", - " -0.0028\n", - " 4000000.0\n", + " 72.77B\n", + " 45.18\n", + " 74.83\n", + " 1.45\n", + " 4.37\n", + " 2.60\n", + " 18.93\n", + " 119.43\n", + " -0.1608\n", + " 0.3117\n", + " 0.0883\n", + " -0.0072\n", + " 8520000.0\n", " \n", " \n", " 143\n", " Waste Management\n", - " 127.72B\n", - " 42.81\n", - " 30.24\n", - " 9.85\n", - " 2.90\n", - " 4.52\n", - " 29.42\n", - " 31.41\n", - " 0.1037\n", - " 0.0435\n", - " 0.0722\n", - " 0.0049\n", - " 10350000.0\n", + " 188.24B\n", + " 47.58\n", + " 34.90\n", + " 3.39\n", + " 3.69\n", + " 5.09\n", + " 65.61\n", + " 42.26\n", + " 0.0724\n", + " 0.1402\n", + " 0.0698\n", + " 0.0044\n", + " 7620000.0\n", " \n", " \n", "\n", @@ -1891,28 +2859,28 @@ ], "text/plain": [ " Name Market Cap P/E Fwd P/E PEG P/S \\\n", - "139 Utilities - Regulated Electric 670.57B 23.03 17.75 3.9 2.38 \n", - "140 Utilities - Regulated Gas 60.18B 33.01 16.33 8.94 1.73 \n", - "141 Utilities - Regulated Water 53.62B 36.21 35.50 4.39 5.22 \n", - "142 Utilities - Renewable 41.80B 41.76 68.31 3.42 3.56 \n", - "143 Waste Management 127.72B 42.81 30.24 9.85 2.90 \n", + "139 Utilities - Regulated Electric 781.97B 25.24 1.91 3.59 1.91 \n", + "140 Utilities - Regulated Gas 78.58B 17.56 17.74 3.76 2.05 \n", + "141 Utilities - Regulated Water 67.78B 32.64 38.46 4.02 4.92 \n", + "142 Utilities - Renewable 72.77B 45.18 74.83 1.45 4.37 \n", + "143 Waste Management 188.24B 47.58 34.90 3.39 3.69 \n", "\n", " P/B P/C P/FCF EPS past 5Y EPS next 5Y Sales past 5Y Change \\\n", - "139 1.62 33.41 45.21 0.0232 0.0590 0.0202 -0.0060 \n", - "140 1.85 28.26 48.94 0.0274 0.0369 -0.0137 -0.0118 \n", - "141 2.95 37.65 61.32 0.0576 0.0825 0.0415 0.0004 \n", - "142 2.33 23.16 109.92 -0.3193 0.1221 0.1531 -0.0028 \n", - "143 4.52 29.42 31.41 0.1037 0.0435 0.0722 0.0049 \n", + "139 1.17 35.81 64.73 -0.0089 0.0702 0.0196 0.0050 \n", + "140 2.02 28.75 42.14 0.0548 0.0467 0.0303 0.0099 \n", + "141 3.12 42.91 61.9 0.0521 0.0812 0.0581 0.0032 \n", + "142 2.60 18.93 119.43 -0.1608 0.3117 0.0883 -0.0072 \n", + "143 5.09 65.61 42.26 0.0724 0.1402 0.0698 0.0044 \n", "\n", " Volume \n", - "139 52580000.0 \n", - "140 7990000.0 \n", - "141 3630000.0 \n", - "142 4000000.0 \n", - "143 10350000.0 " + "139 48220000.0 \n", + "140 13070000.0 \n", + "141 6670000.0 \n", + "142 8520000.0 \n", + "143 7620000.0 " ] }, - "execution_count": 23, + "execution_count": 29, "metadata": {}, "output_type": "execute_result" } @@ -1920,13 +2888,13 @@ "source": [ "from finvizfinance.group.valuation import Valuation\n", "fgvaluation = Valuation()\n", - "df = fgvaluation.ScreenerView(group='Industry')\n", + "df = fgvaluation.screener_view(group='Industry')\n", "df.tail()" ] }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 30, "metadata": {}, "outputs": [ { @@ -1968,77 +2936,77 @@ " \n", " 139\n", " Utilities - Regulated Electric\n", - " -0.32%\n", - " -0.0104\n", - " 0.0468\n", - " -0.1273\n", - " -0.0514\n", - " -0.0874\n", - " 2.47\n", - " 70440000.0\n", - " 0.75\n", - " -0.0060\n", - " 52580000.0\n", + " 2.23%\n", + " 0.0232\n", + " 0.0109\n", + " 0.0318\n", + " 0.0819\n", + " 0.0632\n", + " 2.38\n", + " 65030000.0\n", + " 0.74\n", + " 0.0050\n", + " 48220000.0\n", " \n", " \n", " 140\n", " Utilities - Regulated Gas\n", - " -1.84%\n", - " 0.0134\n", - " 0.0186\n", - " -0.1300\n", - " -0.1964\n", - " -0.1807\n", - " 2.31\n", - " 15340000.0\n", - " 0.52\n", - " -0.0118\n", - " 7990000.0\n", + " 3.84%\n", + " 0.0131\n", + " 0.0246\n", + " -0.0546\n", + " 0.0249\n", + " 0.0241\n", + " 2.12\n", + " 14100000.0\n", + " 0.93\n", + " 0.0099\n", + " 13070000.0\n", " \n", " \n", " 141\n", " Utilities - Regulated Water\n", - " -2.65%\n", - " -0.0436\n", - " 0.0830\n", - " -0.0598\n", - " 0.0110\n", - " -0.0309\n", - " 2.24\n", - " 4720000.0\n", - " 0.77\n", - " 0.0004\n", - " 3630000.0\n", + " 2.85%\n", + " 0.0283\n", + " 0.0081\n", + " 0.0799\n", + " 0.1448\n", + " 0.1300\n", + " 2.47\n", + " 6950000.0\n", + " 0.96\n", + " 0.0032\n", + " 6670000.0\n", " \n", " \n", " 142\n", " Utilities - Renewable\n", - " 3.06%\n", - " 0.0856\n", - " 0.1434\n", - " 0.0378\n", - " 0.3013\n", - " 0.1548\n", - " 2.16\n", - " 4440000.0\n", - " 0.90\n", - " -0.0028\n", - " 4000000.0\n", + " 0.29%\n", + " -0.0786\n", + " -0.0665\n", + " -0.0673\n", + " -0.0694\n", + " -0.1740\n", + " 2.09\n", + " 8040000.0\n", + " 1.06\n", + " -0.0072\n", + " 8520000.0\n", " \n", " \n", " 143\n", " Waste Management\n", - " 1.29%\n", - " 0.0384\n", - " 0.0850\n", - " -0.0457\n", - " 0.0226\n", - " 0.0076\n", - " 2.14\n", - " 13250000.0\n", - " 0.78\n", - " 0.0049\n", - " 10350000.0\n", + " 0.23%\n", + " -0.0104\n", + " 0.0436\n", + " 0.1422\n", + " 0.3677\n", + " 0.3338\n", + " 2.15\n", + " 9570000.0\n", + " 0.80\n", + " 0.0044\n", + " 7620000.0\n", " \n", " \n", "\n", @@ -2046,28 +3014,28 @@ ], "text/plain": [ " Name Perf Week Perf Month Perf Quart \\\n", - "139 Utilities - Regulated Electric -0.32% -0.0104 0.0468 \n", - "140 Utilities - Regulated Gas -1.84% 0.0134 0.0186 \n", - "141 Utilities - Regulated Water -2.65% -0.0436 0.0830 \n", - "142 Utilities - Renewable 3.06% 0.0856 0.1434 \n", - "143 Waste Management 1.29% 0.0384 0.0850 \n", + "139 Utilities - Regulated Electric 2.23% 0.0232 0.0109 \n", + "140 Utilities - Regulated Gas 3.84% 0.0131 0.0246 \n", + "141 Utilities - Regulated Water 2.85% 0.0283 0.0081 \n", + "142 Utilities - Renewable 0.29% -0.0786 -0.0665 \n", + "143 Waste Management 0.23% -0.0104 0.0436 \n", "\n", " Perf Half Perf Year Perf YTD Recom Avg Volume Rel Volume Change \\\n", - "139 -0.1273 -0.0514 -0.0874 2.47 70440000.0 0.75 -0.0060 \n", - "140 -0.1300 -0.1964 -0.1807 2.31 15340000.0 0.52 -0.0118 \n", - "141 -0.0598 0.0110 -0.0309 2.24 4720000.0 0.77 0.0004 \n", - "142 0.0378 0.3013 0.1548 2.16 4440000.0 0.90 -0.0028 \n", - "143 -0.0457 0.0226 0.0076 2.14 13250000.0 0.78 0.0049 \n", + "139 0.0318 0.0819 0.0632 2.38 65030000.0 0.74 0.0050 \n", + "140 -0.0546 0.0249 0.0241 2.12 14100000.0 0.93 0.0099 \n", + "141 0.0799 0.1448 0.1300 2.47 6950000.0 0.96 0.0032 \n", + "142 -0.0673 -0.0694 -0.1740 2.09 8040000.0 1.06 -0.0072 \n", + "143 0.1422 0.3677 0.3338 2.15 9570000.0 0.80 0.0044 \n", "\n", " Volume \n", - "139 52580000.0 \n", - "140 7990000.0 \n", - "141 3630000.0 \n", - "142 4000000.0 \n", - "143 10350000.0 " + "139 48220000.0 \n", + "140 13070000.0 \n", + "141 6670000.0 \n", + "142 8520000.0 \n", + "143 7620000.0 " ] }, - "execution_count": 24, + "execution_count": 30, "metadata": {}, "output_type": "execute_result" } @@ -2075,7 +3043,7 @@ "source": [ "from finvizfinance.group.performance import Performance\n", "fgperformance = Performance()\n", - "df = fgperformance.ScreenerView(group='Industry')\n", + "df = fgperformance.screener_view(group='Industry')\n", "df.tail()" ] }, @@ -2088,27 +3056,189 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 32, + "metadata": {}, + "outputs": [], + "source": [ + "from finvizfinance.earnings import Earnings\n", + "\n", + "fEarnings = Earnings()\n", + "df_days = fEarnings.partition_days(mode='financial')" + ] + }, + { + "cell_type": "code", + "execution_count": 34, "metadata": {}, "outputs": [ { - "ename": "AttributeError", - "evalue": "'Earnings' object has no attribute 'setPeriod'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0mfEarnings\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mEarnings\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0mfEarnings\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msetPeriod\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 5\u001b[0m \u001b[0mdf_days\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfEarnings\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpartitionDays\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmode\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'financial'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mAttributeError\u001b[0m: 'Earnings' object has no attribute 'setPeriod'" - ] + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
TickerMarket CapDividendROAROEROICurr RQuick RLTDebt/EqDebt/EqGross MOper MProfit MEarningsPriceChangeVolume
0COUP1.196000e+10None-0.109-0.368-0.040.80.80.971.630.55-0.4-0.489Dec 06/a155.49-0.04441900530.0
1GTLB1.116000e+10NoneNoneNone0.9372.32.3NoneNone0.875NoneNoneDec 06/a75.00-0.02501642684.0
2HQY3.560000e+09None0.00.00.0164.64.60.480.520.5680.0060.001Dec 06/a40.85-0.02901428330.0
3MDB3.595000e+10None-0.18-2.714-0.2145.75.71.761.770.698-0.358-0.412Dec 06/a507.73-0.0108763871.0
4SUMO1.590000e+09None-0.179-0.238-0.1842.52.50.00.00.712-0.465-0.472Dec 06/a13.74-0.03581304922.0
\n", + "
" + ], + "text/plain": [ + " Ticker Market Cap Dividend ROA ROE ROI Curr R Quick R LTDebt/Eq \\\n", + "0 COUP 1.196000e+10 None -0.109 -0.368 -0.04 0.8 0.8 0.97 \n", + "1 GTLB 1.116000e+10 None None None 0.937 2.3 2.3 None \n", + "2 HQY 3.560000e+09 None 0.0 0.0 0.016 4.6 4.6 0.48 \n", + "3 MDB 3.595000e+10 None -0.18 -2.714 -0.214 5.7 5.7 1.76 \n", + "4 SUMO 1.590000e+09 None -0.179 -0.238 -0.184 2.5 2.5 0.0 \n", + "\n", + " Debt/Eq Gross M Oper M Profit M Earnings Price Change Volume \n", + "0 1.63 0.55 -0.4 -0.489 Dec 06/a 155.49 -0.0444 1900530.0 \n", + "1 None 0.875 None None Dec 06/a 75.00 -0.0250 1642684.0 \n", + "2 0.52 0.568 0.006 0.001 Dec 06/a 40.85 -0.0290 1428330.0 \n", + "3 1.77 0.698 -0.358 -0.412 Dec 06/a 507.73 -0.0108 763871.0 \n", + "4 0.0 0.712 -0.465 -0.472 Dec 06/a 13.74 -0.0358 1304922.0 " + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "from finvizfinance.earnings import Earnings\n", - "\n", - "fEarnings = Earnings()\n", - "fEarnings.setPeriod()\n", - "df_days = fEarnings.partitionDays(mode='financial')" + "df_days['Dec 06/a']" ] }, { @@ -2136,7 +3266,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.5" + "version": "3.7.8" }, "toc": { "base_numbering": 1, @@ -2154,7 +3284,7 @@ "width": "189.219px" }, "toc_section_display": true, - "toc_window_display": false + "toc_window_display": true }, "varInspector": { "cols": { diff --git a/finvizfinance/__init__.py b/finvizfinance/__init__.py index 5dc1196..0858124 100644 --- a/finvizfinance/__init__.py +++ b/finvizfinance/__init__.py @@ -5,5 +5,5 @@ .. moduleauthor:: Tianning Li """ -__version__ = "0.10" +__version__ = "0.11.0" __author__ = "Tianning Li" diff --git a/finvizfinance/calendar.py b/finvizfinance/calendar.py index ca37c40..5307cec 100644 --- a/finvizfinance/calendar.py +++ b/finvizfinance/calendar.py @@ -1,6 +1,7 @@ import re import pandas as pd -from finvizfinance.util import webScrap +from finvizfinance.util import web_scrap + """ .. module:: calendar :synopsis: calendar. @@ -13,9 +14,9 @@ class Calendar: """Calendar Getting information from the finviz calendar page. """ + def __init__(self): - """initiate module - """ + """initiate module""" pass def calendar(self): @@ -24,28 +25,37 @@ def calendar(self): Returns: df(pandas.DataFrame): economic calendar table """ - soup = webScrap("https://finviz.com/calendar.ashx") - tables = soup.findAll('table', class_='calendar') - columns = ['Datetime', 'Release', 'Impact', 'For', 'Actual', 'Expected', 'Prior'] + soup = web_scrap("https://finviz.com/calendar.ashx") + tables = soup.findAll("table", class_="calendar") + columns = [ + "Datetime", + "Release", + "Impact", + "For", + "Actual", + "Expected", + "Prior", + ] df = pd.DataFrame([], columns=columns) for table in tables: - rows = table.findAll('tr') + rows = table.findAll("tr") # check row - if rows[1].findAll('td')[2].text != 'No economic releases': + if rows[1].findAll("td")[2].text != "No economic releases": # parse date - date = rows[0].find('td').text + date = rows[0].find("td").text for row in rows[1:]: - cols = row.findAll('td') + cols = row.findAll("td") info_dict = { - 'Datetime': '{}, {}'.format(date, cols[0].text), - 'Release': cols[2].text, - 'Impact': re.findall('gfx/calendar/impact_(.*).gif', - cols[3].find('img')['src'])[0], - 'For': cols[4].text, - 'Actual': cols[5].text, - 'Expected': cols[6].text, - 'Prior': cols[7].text + "Datetime": "{}, {}".format(date, cols[0].text), + "Release": cols[2].text, + "Impact": re.findall( + "gfx/calendar/impact_(.*).gif", cols[3].find("img")["src"] + )[0], + "For": cols[4].text, + "Actual": cols[5].text, + "Expected": cols[6].text, + "Prior": cols[7].text, } df = df.append(info_dict, ignore_index=True) return df diff --git a/finvizfinance/crypto.py b/finvizfinance/crypto.py index 829204a..e0cfb39 100644 --- a/finvizfinance/crypto.py +++ b/finvizfinance/crypto.py @@ -1,4 +1,5 @@ -from finvizfinance.util import scrapFunction, imageScrapFunction +from finvizfinance.util import scrap_function, image_scrap_function + """ .. module:: crypto :synopsis: crypto information @@ -12,9 +13,9 @@ class Crypto: Getting information from the finviz crypto page. """ + def __init__(self): - """initiate module - """ + """initiate module""" pass def performance(self): @@ -23,11 +24,11 @@ def performance(self): Returns: df(pandas.DataFrame): crypto performance table """ - url = 'https://finviz.com/crypto_performance.ashx' - df = scrapFunction(url) + url = "https://finviz.com/crypto_performance.ashx" + df = scrap_function(url) return df - def chart(self, crypto, timeframe='D', urlonly=False): + def chart(self, crypto, timeframe="D", urlonly=False): """Get crypto chart. Args: @@ -38,6 +39,6 @@ def chart(self, crypto, timeframe='D', urlonly=False): charturl(str): url for the chart """ - url = 'https://finviz.com/crypto_charts.ashx?t=ALL&tf=' - charturl = imageScrapFunction(url, crypto, timeframe, urlonly) - return charturl \ No newline at end of file + url = "https://finviz.com/crypto_charts.ashx?t=ALL&tf=" + charturl = image_scrap_function(url, crypto, timeframe, urlonly) + return charturl diff --git a/finvizfinance/earnings.py b/finvizfinance/earnings.py index 838f0b1..cb49197 100644 --- a/finvizfinance/earnings.py +++ b/finvizfinance/earnings.py @@ -6,6 +6,7 @@ from finvizfinance.screener.ownership import Ownership from finvizfinance.screener.performance import Performance from finvizfinance.screener.technical import Technical + """ .. module:: earnings :synopsis: earnings. @@ -18,103 +19,120 @@ class Earnings: """Earnings Partition dataframe of ticker information of period of earning dates(This Week, Next Week, Previous Week, This Month) into dates - + Args: period(str): choose an option of period(This Week, Next Week, Previous Week, This Month). """ - def __init__(self, period='This Week'): - """initiate module - """ + + def __init__(self, period="This Week"): + """initiate module""" self.earning_days = [] self.df_days = {} self.df = None self.period = period - self._setPeriod(period) + self._set_period(period) - def _setPeriod(self, period): + def _set_period(self, period): """Set the period. Args: period(str): choose an option of period(This Week, Next Week, Previous Week, This Month). """ - check_list = ['This Week', 'Next Week', 'Previous Week', 'This Month'] + check_list = ["This Week", "Next Week", "Previous Week", "This Month"] if period not in check_list: - raise ValueError("Invalid period '{}'. Available period: {}".format(period, check_list)) + raise ValueError( + "Invalid period '{}'. Available period: {}".format(period, check_list) + ) self.period = period ffinancial = Financial() - filters_dict = {'Earnings Date': period} + filters_dict = {"Earnings Date": period} ffinancial.set_filter(filters_dict=filters_dict) - self.df = ffinancial.ScreenerView(order='Earnings Date', verbose=0) - self.earning_days = list(set(self.df['Earnings'].to_list())) + self.df = ffinancial.screener_view(order="Earnings Date", verbose=0) + self.earning_days = list(set(self.df["Earnings"].to_list())) self.earning_days.sort() - def partitionDays(self, mode='financial'): + def partition_days(self, mode="financial"): """Partition dataframe to separate dataframes according to the dates. Args: mode(str): choose an option of period(financial, overview, valuation, ownership, performance, technical). """ - check_list = ['financial', 'overview', 'valuation', 'ownership', 'performance', 'technical'] + check_list = [ + "financial", + "overview", + "valuation", + "ownership", + "performance", + "technical", + ] if mode not in check_list: - raise ValueError("Invalid mode '{}'. Available mode: {}".format(mode, check_list)) + raise ValueError( + "Invalid mode '{}'. Available mode: {}".format(mode, check_list) + ) for earning_day in self.earning_days: - if mode == 'financial': - self.df_days[earning_day] = self.df[self.df['Earnings'] == earning_day].reset_index(drop=True) + if mode == "financial": + self.df_days[earning_day] = self.df[ + self.df["Earnings"] == earning_day + ].reset_index(drop=True) else: - self.df_days[earning_day] = self.df[self.df['Earnings'] == earning_day]['Ticker'].to_list() + self.df_days[earning_day] = self.df[self.df["Earnings"] == earning_day][ + "Ticker" + ].to_list() fearnings = None - if mode == 'financial': + if mode == "financial": return self.df_days - elif mode == 'overview': + elif mode == "overview": fearnings = Overview() - elif mode == 'valuation': + elif mode == "valuation": fearnings = Valuation() - elif mode == 'ownership': + elif mode == "ownership": fearnings = Ownership() - elif mode == 'performance': + elif mode == "performance": fearnings = Performance() - elif mode == 'technical': + elif mode == "technical": fearnings = Technical() - filters_dict = {'Earnings Date': self.period} + filters_dict = {"Earnings Date": self.period} fearnings.set_filter(filters_dict=filters_dict) - df2 = fearnings.ScreenerView(order='Earnings Date', verbose=0) + df2 = fearnings.screener_view(order="Earnings Date", verbose=0) df2_days = {} for earning_day in self.earning_days: tickers = self.df_days[earning_day] - df2_days[earning_day] = df2[df2['Ticker'].isin(tickers)].reset_index(drop=True) + df2_days[earning_day] = df2[df2["Ticker"].isin(tickers)].reset_index( + drop=True + ) self.df_days = df2_days return self.df_days - def outputExcel(self, output_file='earning_days.xlsx'): + def output_excel(self, output_file="earning_days.xlsx"): """Output dataframes to single Excel file. Args: output_file(str): name of the output excel file. """ - print('Print to Excel...') - with pd.ExcelWriter(output_file, - datetime_format='YYYY-MM-DD', - engine='xlsxwriter') as writer: + print("Print to Excel...") + with pd.ExcelWriter( + output_file, datetime_format="YYYY-MM-DD", engine="xlsxwriter" + ) as writer: for name, df in self.df_days.items(): - sheet_name = '_'.join(name.split('/')) + sheet_name = "_".join(name.split("/")) df.to_excel(writer, sheet_name=sheet_name, index=False) - def outputCSV(self, output_dir='earning_days'): + def output_csv(self, output_dir="earning_days"): """Output dataframes to csv files. Args: output_dir(str): name of the output directory. """ - print('Print to CSV...') + print("Print to CSV...") isdir = os.path.isdir(output_dir) if not isdir: os.mkdir(output_dir) for name, df in self.df_days.items(): - file_name = '_'.join(name.split('/')) - df.to_csv(output_dir+'/'+file_name+'.csv', index=False) + file_name = "_".join(name.split("/")) + df.to_csv(output_dir + "/" + file_name + ".csv", index=False) diff --git a/finvizfinance/forex.py b/finvizfinance/forex.py index 6bb914f..5994737 100644 --- a/finvizfinance/forex.py +++ b/finvizfinance/forex.py @@ -1,4 +1,5 @@ -from finvizfinance.util import scrapFunction, imageScrapFunction +from finvizfinance.util import scrap_function, image_scrap_function + """ .. module:: forex :synopsis: forex. @@ -11,12 +12,12 @@ class Forex: """Forex Getting information from the finviz forex page. """ + def __init__(self): - """initiate module - """ + """initiate module""" pass - def performance(self, change='percent'): + def performance(self, change="percent"): """Get forex performance table. Args: @@ -26,16 +27,16 @@ def performance(self, change='percent'): df(pandas.DataFrame): forex performance table """ url = None - if change == 'percent': - url = 'https://finviz.com/forex_performance.ashx' - elif change == 'PIPS': - url = 'https://finviz.com/forex_performance.ashx?v=1&tv=2&o=-perfdaypct' + if change == "percent": + url = "https://finviz.com/forex_performance.ashx" + elif change == "PIPS": + url = "https://finviz.com/forex_performance.ashx?v=1&tv=2&o=-perfdaypct" else: - raise ValueError('Options of change: percent(default), PIPS') - df = scrapFunction(url) + raise ValueError("Options of change: percent(default), PIPS") + df = scrap_function(url) return df - def chart(self, forex, timeframe='D', urlonly=False): + def chart(self, forex, timeframe="D", urlonly=False): """Get forex chart. Args: @@ -45,9 +46,9 @@ def chart(self, forex, timeframe='D', urlonly=False): Returns: charturl(str): url for the chart """ - if forex == '': + if forex == "": return None - url = 'https://finviz.com/forex_charts.ashx?t=ALL&tf=' - charturl = imageScrapFunction(url, forex, timeframe, urlonly) - return charturl \ No newline at end of file + url = "https://finviz.com/forex_charts.ashx?t=ALL&tf=" + charturl = image_scrap_function(url, forex, timeframe, urlonly) + return charturl diff --git a/finvizfinance/future.py b/finvizfinance/future.py index 5710851..c7753be 100644 --- a/finvizfinance/future.py +++ b/finvizfinance/future.py @@ -1,6 +1,6 @@ import json import pandas as pd -from finvizfinance.util import webScrap +from finvizfinance.util import web_scrap """ .. module:: future @@ -14,12 +14,12 @@ class Future: """Future Getting information from the finviz future page. """ + def __init__(self): - """initiate module - """ + """initiate module""" pass - def performance(self, timeframe='D'): + def performance(self, timeframe="D"): """Get forex performance table. Args: @@ -29,23 +29,26 @@ def performance(self, timeframe='D'): df(pandas.DataFrame): forex performance table """ params = None - if timeframe == 'D': - params = '' - elif timeframe == 'W': - params = '?v=12' - elif timeframe == 'M': - params = '?v=13' - elif timeframe == 'Q': - params = '?v=14' - elif timeframe == 'HY': - params = '?v=15' - elif timeframe == 'Y': - params = '?v=16' + if timeframe == "D": + params = "" + elif timeframe == "W": + params = "?v=12" + elif timeframe == "M": + params = "?v=13" + elif timeframe == "Q": + params = "?v=14" + elif timeframe == "HY": + params = "?v=15" + elif timeframe == "Y": + params = "?v=16" else: raise ValueError("Invalid timeframe '{}'".format(timeframe)) - soup = webScrap('https://finviz.com/futures_performance.ashx'+params) - data = soup.text[soup.text.find('var rows = ')+11:soup.text.find('FinvizInitFuturesPerformance(rows);')] + soup = web_scrap("https://finviz.com/futures_performance.ashx" + params) + data = soup.text[ + soup.text.find("var rows = ") + + 11 : soup.text.find("FinvizInitFuturesPerformance(rows);") + ] data = json.loads(data.strip()[:-1]) df = pd.DataFrame(data) return df diff --git a/finvizfinance/group/custom.py b/finvizfinance/group/custom.py index 4a58662..25d427c 100644 --- a/finvizfinance/group/custom.py +++ b/finvizfinance/group/custom.py @@ -1,6 +1,7 @@ import pandas as pd -from finvizfinance.util import webScrap, numberCovert +from finvizfinance.util import web_scrap, number_covert from finvizfinance.group.overview import Overview + """ .. module:: group.custom :synopsis: group custom table. @@ -10,33 +11,33 @@ COLUMNS = { - 0: 'No.', - 1: 'Name', - 2: 'Market Cap.', - 3: 'P/E', - 4: 'Forward P/E', - 5: 'PEG', - 6: 'P/S', - 7: 'P/B', - 8: 'P/Cash', - 9: 'P/Free Cash Flow', - 10: 'Dividend Yield', - 11: 'EPS growth past 5 years', - 12: 'EPS growth next 5 years', - 13: 'Sales growth past 5 years', - 14: 'Shares Float', - 15: 'Performance (Week)', - 16: 'Performance (Month)', - 17: 'Performance (Quarter)', - 18: 'Performance (Half Year)', - 19: 'Performance (Year)', - 20: 'Performance (YearToDate)', - 21: 'Analyst Recom.', - 22: 'Average Volume', - 23: 'Relative Volume', - 24: 'Change', - 25: 'Volume', - 26: 'Number of Stocks' + 0: "No.", + 1: "Name", + 2: "Market Cap.", + 3: "P/E", + 4: "Forward P/E", + 5: "PEG", + 6: "P/S", + 7: "P/B", + 8: "P/Cash", + 9: "P/Free Cash Flow", + 10: "Dividend Yield", + 11: "EPS growth past 5 years", + 12: "EPS growth next 5 years", + 13: "Sales growth past 5 years", + 14: "Shares Float", + 15: "Performance (Week)", + 16: "Performance (Month)", + 17: "Performance (Quarter)", + 18: "Performance (Half Year)", + 19: "Performance (Year)", + 20: "Performance (YearToDate)", + 21: "Analyst Recom.", + 22: "Average Volume", + 23: "Relative Volume", + 24: "Change", + 25: "Volume", + 26: "Number of Stocks", } @@ -44,14 +45,14 @@ class Custom(Overview): """Custom inherit from overview module. Getting information from the finviz group custom page. """ + def __init__(self): - """initiate module - """ - self.BASE_URL = 'https://finviz.com/groups.ashx?{group}&v=152' - self.url = self.BASE_URL.format(group='g=sector') - Overview._loadSetting(self) + """initiate module""" + self.BASE_URL = "https://finviz.com/groups.ashx?{group}&v=152" + self.url = self.BASE_URL.format(group="g=sector") + Overview._load_setting(self) - def getColumns(self): + def get_columns(self): """Get information about the columns Returns: @@ -59,7 +60,9 @@ def getColumns(self): """ return COLUMNS - def ScreenerView(self, group='Sector', order='Name', columns=[0, 1, 2, 3, 10, 22, 24, 25, 26]): + def screener_view( + self, group="Sector", order="Name", columns=[0, 1, 2, 3, 10, 22, 24, 25, 26] + ): """Get screener table. Args: @@ -73,26 +76,30 @@ def ScreenerView(self, group='Sector', order='Name', columns=[0, 1, 2, 3, 10, 22 raise ValueError() if order not in self.order_dict: raise ValueError() - self.url = self.BASE_URL.format(group=self.group_dict[group])+'&'+self.order_dict[order] + self.url = ( + self.BASE_URL.format(group=self.group_dict[group]) + + "&" + + self.order_dict[order] + ) columns = [str(i) for i in columns] - self.url += '&c=' + ','.join(columns) + self.url += "&c=" + ",".join(columns) - soup = webScrap(self.url) - table = soup.findAll('table')[6] - rows = table.findAll('tr') - table_header = [i.text for i in rows[0].findAll('td')][1:] + soup = web_scrap(self.url) + table = soup.findAll("table")[6] + rows = table.findAll("tr") + table_header = [i.text for i in rows[0].findAll("td")][1:] df = pd.DataFrame([], columns=table_header) rows = rows[1:] - num_col_index = [i for i in range(2, len(table_header))] + num_col_index = list(range(2, len(table_header))) for row in rows: - cols = row.findAll('td')[1:] + cols = row.findAll("td")[1:] info_dict = {} for i, col in enumerate(cols): # check if the col is number if i not in num_col_index: info_dict[table_header[i]] = col.text else: - info_dict[table_header[i]] = numberCovert(col.text) + info_dict[table_header[i]] = number_covert(col.text) df = df.append(info_dict, ignore_index=True) - return df \ No newline at end of file + return df diff --git a/finvizfinance/group/overview.py b/finvizfinance/group/overview.py index c83496e..699bb5d 100644 --- a/finvizfinance/group/overview.py +++ b/finvizfinance/group/overview.py @@ -1,5 +1,6 @@ -from finvizfinance.util import webScrap, numberCovert import pandas as pd +from finvizfinance.util import web_scrap, number_covert + """ .. module:: group.overview :synopsis: group overview table. @@ -13,37 +14,38 @@ class Overview: """Overview Getting information from the finviz group overview page. """ + def __init__(self): """initiate module""" - self.BASE_URL = 'https://finviz.com/groups.ashx?{group}&v=110' - self.url = self.BASE_URL.format(group='g=sector') - self._loadSetting() + self.BASE_URL = "https://finviz.com/groups.ashx?{group}&v=110" + self.url = self.BASE_URL.format(group="g=sector") + self._load_setting() - def _loadSetting(self): + def _load_setting(self): """load all the groups.""" - soup = webScrap(self.url) - selects = soup.findAll('select') + soup = web_scrap(self.url) + selects = soup.findAll("select") # group - options = selects[0].findAll('option') + options = selects[0].findAll("option") key = [i.text for i in options] value = [] for option in options: - temp = option['value'].split('?')[1].split('&') + temp = option["value"].split("?")[1].split("&") if len(temp) == 4: - temp = '&'.join(temp[:2]) + temp = "&".join(temp[:2]) else: temp = temp[0] value.append(temp) self.group_dict = dict(zip(key, value)) # order - options = selects[1].findAll('option') + options = selects[1].findAll("option") key = [i.text for i in options] - value = [i['value'].split('&')[-1] for i in options] + value = [i["value"].split("&")[-1] for i in options] self.order_dict = dict(zip(key, value)) - def getGroup(self): + def get_group(self): """Get groups. Returns: @@ -51,7 +53,7 @@ def getGroup(self): """ return list(self.group_dict.keys()) - def getOrders(self): + def get_orders(self): """Get orders. Returns: @@ -59,7 +61,7 @@ def getOrders(self): """ return list(self.order_dict.keys()) - def ScreenerView(self, group='Sector', order='Name'): + def screener_view(self, group="Sector", order="Name"): """Get screener table. Args: @@ -73,24 +75,28 @@ def ScreenerView(self, group='Sector', order='Name'): raise ValueError() if order not in self.order_dict: raise ValueError() - self.url = self.BASE_URL.format(group=self.group_dict[group])+'&'+self.order_dict[order] - - soup = webScrap(self.url) - table = soup.findAll('table')[5] - rows = table.findAll('tr') - table_header = [i.text for i in rows[0].findAll('td')][1:] + self.url = ( + self.BASE_URL.format(group=self.group_dict[group]) + + "&" + + self.order_dict[order] + ) + + soup = web_scrap(self.url) + table = soup.findAll("table")[5] + rows = table.findAll("tr") + table_header = [i.text for i in rows[0].findAll("td")][1:] df = pd.DataFrame([], columns=table_header) rows = rows[1:] - num_col_index = [i for i in range(2, len(table_header))] + num_col_index = list(range(2, len(table_header))) for row in rows: - cols = row.findAll('td')[1:] + cols = row.findAll("td")[1:] info_dict = {} for i, col in enumerate(cols): # check if the col is number if i not in num_col_index: info_dict[table_header[i]] = col.text else: - info_dict[table_header[i]] = numberCovert(col.text) + info_dict[table_header[i]] = number_covert(col.text) df = df.append(info_dict, ignore_index=True) return df diff --git a/finvizfinance/group/performance.py b/finvizfinance/group/performance.py index 396791e..5da9aed 100644 --- a/finvizfinance/group/performance.py +++ b/finvizfinance/group/performance.py @@ -1,4 +1,5 @@ from finvizfinance.group.overview import Overview + """ .. module:: group.performance :synopsis: group performance table. @@ -11,9 +12,9 @@ class Performance(Overview): """Performance inherit from overview module. Getting information from the finviz group performance page. """ + def __init__(self): - """initiate module - """ - self.BASE_URL = 'https://finviz.com/groups.ashx?{group}&v=140' - self.url = self.BASE_URL.format(group='g=sector') - Overview._loadSetting(self) \ No newline at end of file + """initiate module""" + self.BASE_URL = "https://finviz.com/groups.ashx?{group}&v=140" + self.url = self.BASE_URL.format(group="g=sector") + Overview._load_setting(self) diff --git a/finvizfinance/group/spectrum.py b/finvizfinance/group/spectrum.py index 678c55f..2de45ae 100644 --- a/finvizfinance/group/spectrum.py +++ b/finvizfinance/group/spectrum.py @@ -1,5 +1,5 @@ from finvizfinance.group.overview import Overview -from finvizfinance.util import webScrap, imageScrap +from finvizfinance.util import web_scrap, image_scrap """ .. module:: group.spectrum @@ -13,14 +13,14 @@ class Spectrum(Overview): """Spectrum inherit from overview module. Getting information from the finviz group spectrum page. """ + def __init__(self): - """initiate module - """ - self.BASE_URL = 'https://finviz.com/groups.ashx?{group}&v=310' - self.url = self.BASE_URL.format(group='g=sector') - Overview._loadSetting(self) + """initiate module""" + self.BASE_URL = "https://finviz.com/groups.ashx?{group}&v=310" + self.url = self.BASE_URL.format(group="g=sector") + Overview._load_setting(self) - def ScreenerView(self, group='Sector', order='Name', out_dir=''): + def screener_view(self, group="Sector", order="Name", out_dir=""): """Get screener table. Args: @@ -31,8 +31,12 @@ def ScreenerView(self, group='Sector', order='Name', out_dir=''): raise ValueError() if order not in self.order_dict: raise ValueError() - self.url = self.BASE_URL.format(group=self.group_dict[group])+'&'+self.order_dict[order] + self.url = ( + self.BASE_URL.format(group=self.group_dict[group]) + + "&" + + self.order_dict[order] + ) - soup = webScrap(self.url) - url = 'https://finviz.com/' + soup.findAll('img')[5]['src'] - imageScrap(url, group, '') \ No newline at end of file + soup = web_scrap(self.url) + url = "https://finviz.com/" + soup.findAll("img")[5]["src"] + image_scrap(url, group, "") diff --git a/finvizfinance/group/valuation.py b/finvizfinance/group/valuation.py index 86f03a7..fb31233 100644 --- a/finvizfinance/group/valuation.py +++ b/finvizfinance/group/valuation.py @@ -1,4 +1,5 @@ from finvizfinance.group.overview import Overview + """ .. module:: group.valuation :synopsis: group valuation table. @@ -11,9 +12,9 @@ class Valuation(Overview): """Valuation inherit from overview module. Getting information from the finviz group valuation page. """ + def __init__(self): - """initiate module - """ - self.BASE_URL = 'https://finviz.com/groups.ashx?{group}&v=120' - self.url = self.BASE_URL.format(group='g=sector') - Overview._loadSetting(self) \ No newline at end of file + """initiate module""" + self.BASE_URL = "https://finviz.com/groups.ashx?{group}&v=120" + self.url = self.BASE_URL.format(group="g=sector") + Overview._load_setting(self) diff --git a/finvizfinance/insider.py b/finvizfinance/insider.py index e67b96c..6056c04 100644 --- a/finvizfinance/insider.py +++ b/finvizfinance/insider.py @@ -1,5 +1,6 @@ import pandas as pd -from finvizfinance.util import webScrap, numberCovert +from finvizfinance.util import web_scrap, number_covert + """ .. module:: insider :synopsis: insider table. @@ -7,7 +8,7 @@ .. moduleauthor:: Tianning Li """ -INSIDER_URL = 'https://finviz.com/insidertrading.ashx' +INSIDER_URL = "https://finviz.com/insidertrading.ashx" class Insider: @@ -19,55 +20,69 @@ class Insider: top week buys, top week sales, top owner trade, top owner buys, top owner sales, insider_id) """ - def __init__(self, option='latest'): - """initiate module - """ - if option == 'latest': - self.soup = webScrap(INSIDER_URL) - elif option == 'latest buys': - self.soup = webScrap(INSIDER_URL+'?tc=1') - elif option == 'latest sales': - self.soup = webScrap(INSIDER_URL+'?tc=2') - elif option == 'top week': - self.soup = webScrap(INSIDER_URL+'?or=-10&tv=100000&tc=7&o=-transactionValue') - elif option == 'top week buys': - self.soup = webScrap(INSIDER_URL+'?or=-10&tv=100000&tc=1&o=-transactionValue') - elif option == 'top week sales': - self.soup = webScrap(INSIDER_URL+'?or=-10&tv=100000&tc=2&o=-transactionValue') - elif option == 'top owner trade': - self.soup = webScrap(INSIDER_URL+'?or=10&tv=1000000&tc=7&o=-transactionValue') - elif option == 'top owner buys': - self.soup = webScrap(INSIDER_URL+'?or=10&tv=1000000&tc=1&o=-transactionValue') - elif option == 'top owner sales': - self.soup = webScrap(INSIDER_URL+'?or=10&tv=1000000&tc=2&o=-transactionValue') + + def __init__(self, option="latest"): + """initiate module""" + if option == "latest": + self.soup = web_scrap(INSIDER_URL) + elif option == "latest buys": + self.soup = web_scrap(INSIDER_URL + "?tc=1") + elif option == "latest sales": + self.soup = web_scrap(INSIDER_URL + "?tc=2") + elif option == "top week": + self.soup = web_scrap( + INSIDER_URL + "?or=-10&tv=100000&tc=7&o=-transactionValue" + ) + elif option == "top week buys": + self.soup = web_scrap( + INSIDER_URL + "?or=-10&tv=100000&tc=1&o=-transactionValue" + ) + elif option == "top week sales": + self.soup = web_scrap( + INSIDER_URL + "?or=-10&tv=100000&tc=2&o=-transactionValue" + ) + elif option == "top owner trade": + self.soup = web_scrap( + INSIDER_URL + "?or=10&tv=1000000&tc=7&o=-transactionValue" + ) + elif option == "top owner buys": + self.soup = web_scrap( + INSIDER_URL + "?or=10&tv=1000000&tc=1&o=-transactionValue" + ) + elif option == "top owner sales": + self.soup = web_scrap( + INSIDER_URL + "?or=10&tv=1000000&tc=2&o=-transactionValue" + ) elif option.isdigit(): - self.soup = webScrap(INSIDER_URL+'?oc='+option+'&tc=7') + self.soup = web_scrap(INSIDER_URL + "?oc=" + option + "&tc=7") self.df = None - def getInsider(self): + def get_insider(self): """Get insider information table. Returns: df(pandas.DataFrame): insider information table """ - insider_trader = self.soup.findAll('table')[5] - rows = insider_trader.findAll('tr') - table_header = [i.text.strip() for i in rows[0].findAll('td')] + ['SEC Form 4 Link'] + insider_trader = self.soup.findAll("table")[5] + rows = insider_trader.findAll("tr") + table_header = [i.text.strip() for i in rows[0].findAll("td")] + [ + "SEC Form 4 Link" + ] df = pd.DataFrame([], columns=table_header) rows = rows[1:] - num_col = ['Cost', '#Shares', 'Value ($)', '#Shares Total'] + num_col = ["Cost", "#Shares", "Value ($)", "#Shares Total"] num_col_index = [table_header.index(i) for i in table_header if i in num_col] for row in rows: - cols = row.findAll('td') + cols = row.findAll("td") info_dict = {} for i, col in enumerate(cols): if i not in num_col_index: info_dict[table_header[i]] = col.text if i == len(cols) - 1: - info_dict['SEC Form 4 Link'] = col.find('a').attrs['href'] + info_dict["SEC Form 4 Link"] = col.find("a").attrs["href"] else: - info_dict[table_header[i]] = numberCovert(col.text) - info_dict['SEC Form 4 Link'] = cols[-1].find('a').attrs['href'] + info_dict[table_header[i]] = number_covert(col.text) + info_dict["SEC Form 4 Link"] = cols[-1].find("a").attrs["href"] df = df.append(info_dict, ignore_index=True) self.df = df - return df \ No newline at end of file + return df diff --git a/finvizfinance/news.py b/finvizfinance/news.py index 2cbfd9e..b1fe171 100644 --- a/finvizfinance/news.py +++ b/finvizfinance/news.py @@ -1,5 +1,6 @@ import pandas as pd -from finvizfinance.util import webScrap +from finvizfinance.util import web_scrap + """ .. module:: news :synopsis: news table. @@ -7,7 +8,7 @@ .. moduleauthor:: Tianning Li """ -NEWS_URL = 'https://finviz.com/news.ashx' +NEWS_URL = "https://finviz.com/news.ashx" class News: @@ -15,14 +16,14 @@ class News: Getting information from the finviz news page. """ + def __init__(self): - """initiate module - """ + """initiate module""" self.all_news = {} - self.soup = webScrap(NEWS_URL) + self.soup = web_scrap(NEWS_URL) self.news = {} - def getNews(self): + def get_news(self): """Get insider information table. Retrieves table information from finviz finance news. @@ -31,15 +32,15 @@ def getNews(self): news(dict): news table """ - tables = self.soup.findAll('table') + tables = self.soup.findAll("table") news = tables[6] - news_df = self._getNewsHelper(news) + news_df = self._get_news_helper(news) blog = tables[7] - blog_df = self._getNewsHelper(blog) - self.news = {'news': news_df, 'blogs': blog_df} + blog_df = self._get_news_helper(blog) + self.news = {"news": news_df, "blogs": blog_df} return self.news - def _getNewsHelper(self, rows): + def _get_news_helper(self, rows): """Get insider information table helper function. Args: @@ -49,16 +50,18 @@ def _getNewsHelper(self, rows): df(pandas.DataFrame): news information table """ - df = pd.DataFrame([], columns=['Date', 'Title', 'Source', 'Link']) - rows = rows.findAll('tr') + df = pd.DataFrame([], columns=["Date", "Title", "Source", "Link"]) + rows = rows.findAll("tr") for row in rows: - cols = row.findAll('td') + cols = row.findAll("td") date = cols[1].text title = cols[2].text - link = cols[2].a['href'] - source = link.split('/')[2] - if source == 'feedproxy.google.com': - source = link.split('/')[4] - df = df.append({'Date': date, 'Title': title, 'Source': source, 'Link': link}, - ignore_index=True) - return df \ No newline at end of file + link = cols[2].a["href"] + source = link.split("/")[2] + if source == "feedproxy.google.com": + source = link.split("/")[4] + df = df.append( + {"Date": date, "Title": title, "Source": source, "Link": link}, + ignore_index=True, + ) + return df diff --git a/finvizfinance/quote.py b/finvizfinance/quote.py index a355988..67d3da9 100644 --- a/finvizfinance/quote.py +++ b/finvizfinance/quote.py @@ -2,16 +2,25 @@ import json import pandas as pd import requests -from finvizfinance.util import webScrap, imageScrap, numberCovert, headers +from finvizfinance.util import web_scrap, image_scrap, number_covert, headers + """ .. module:: finvizfinance :synopsis: individual ticker. .. moduleauthor:: Tianning Li """ -QUOTE_URL = 'https://finviz.com/quote.ashx?t={ticker}' -NUM_COL = ['P/E', 'EPS (ttm)', 'Insider Own', 'Shs Outstand', 'Market Cap', 'Forward P/E', - 'EPS nest Y', 'Insider '] +QUOTE_URL = "https://finviz.com/quote.ashx?t={ticker}" +NUM_COL = [ + "P/E", + "EPS (ttm)", + "Insider Own", + "Shs Outstand", + "Market Cap", + "Forward P/E", + "EPS nest Y", + "Insider ", +] class Quote: @@ -19,13 +28,14 @@ class Quote: Getting current price of the ticker """ - def getCurrent(self, ticker): + + def get_current(self, ticker): """Getting current price of the ticker. Returns: price(float): price of the ticker """ - soup = webScrap("https://finviz.com/request_quote.ashx?t={}".format(ticker)) + soup = web_scrap("https://finviz.com/request_quote.ashx?t={}".format(ticker)) return soup.text @@ -37,28 +47,30 @@ class finvizfinance: ticker(str): ticker string verbose(int): choice of visual the progress. 1 for visualize progress. """ + def __init__(self, ticker, verbose=0): - """initiate module - """ + """initiate module""" self.ticker = ticker self.flag = False self.quote_url = QUOTE_URL.format(ticker=ticker) - self.soup = webScrap(self.quote_url) + self.soup = web_scrap(self.quote_url) if self._checkexist(verbose): self.flag = True self.info = {} def _checkexist(self, verbose): try: - if 'not found' in self.soup.find('td', class_='body-text').text: - print('Ticker not found.') + if "not found" in self.soup.find("td", class_="body-text").text: + print("Ticker not found.") return False except: if verbose == 1: - print('Ticker exists.') + print("Ticker exists.") return True - def TickerCharts(self, timeframe='daily', charttype='advanced', out_dir='', urlonly=False): + def ticker_charts( + self, timeframe="daily", charttype="advanced", out_dir="", urlonly=False + ): """Download ticker charts. Args: @@ -70,29 +82,32 @@ def TickerCharts(self, timeframe='daily', charttype='advanced', out_dir='', urlo Returns: charturl(str): url for the chart """ - if timeframe not in ['daily', 'weekly', 'monthly']: + if timeframe not in ["daily", "weekly", "monthly"]: raise ValueError("Invalid timeframe '{}'".format(timeframe)) - if charttype not in ['candle', 'line', 'advanced']: + if charttype not in ["candle", "line", "advanced"]: raise ValueError("Invalid chart type '{}'".format(charttype)) - url_type = 'c' - url_ta = '0' - if charttype == 'line': - url_type = 'l' - elif charttype == 'advanced' and timeframe != 'weekly' and timeframe != 'monthly': - url_ta = '1' - - url_timeframe = 'd' - if timeframe == 'weekly': - url_timeframe = 'w' - elif timeframe == 'monthly': - url_timeframe = 'm' - chart_url = 'https://finviz.com/chart.ashx?t={ticker}&ty={type}&ta={ta}&p={timeframe}'.format(ticker=self.ticker, - type=url_type, ta=url_ta, timeframe=url_timeframe) + url_type = "c" + url_ta = "0" + if charttype == "line": + url_type = "l" + elif ( + charttype == "advanced" and timeframe != "weekly" and timeframe != "monthly" + ): + url_ta = "1" + + url_timeframe = "d" + if timeframe == "weekly": + url_timeframe = "w" + elif timeframe == "monthly": + url_timeframe = "m" + chart_url = "https://finviz.com/chart.ashx?t={ticker}&ty={type}&ta={ta}&p={timeframe}".format( + ticker=self.ticker, type=url_type, ta=url_ta, timeframe=url_timeframe + ) if not urlonly: - imageScrap(chart_url, self.ticker, out_dir) + image_scrap(chart_url, self.ticker, out_dir) return chart_url - def TickerFundament(self, raw=True): + def ticker_fundament(self, raw=True): """Get ticker fundament. Args: @@ -103,31 +118,39 @@ def TickerFundament(self, raw=True): """ fundament_info = {} - table = self.soup.findAll('table')[5] - rows = table.findAll('tr') + table = self.soup.findAll("table")[5] + rows = table.findAll("tr") - fundament_info['Company'] = rows[1].text - fundament_info['Sector'], fundament_info['Industry'], fundament_info['Country'] = rows[2].text.split(' | ') + fundament_info["Company"] = rows[1].text + ( + fundament_info["Sector"], + fundament_info["Industry"], + fundament_info["Country"], + ) = rows[2].text.split(" | ") - fundament_table = self.soup.find('table', class_='snapshot-table2') - rows = fundament_table.findAll('tr') + fundament_table = self.soup.find("table", class_="snapshot-table2") + rows = fundament_table.findAll("tr") for row in rows: - cols = row.findAll('td') + cols = row.findAll("td") cols = [i.text for i in cols] - header = '' + header = "" for i, value in enumerate(cols): if i % 2 == 0: header = value else: - if header == 'Volatility': - fundament_info = self._parse_volatility(header, fundament_info, value, raw) - elif header == '52W Range': - fundament_info = self._parse_52w_range(header, fundament_info, value, raw) - elif header == 'Optionable' or header == 'Shortable': + if header == "Volatility": + fundament_info = self._parse_volatility( + header, fundament_info, value, raw + ) + elif header == "52W Range": + fundament_info = self._parse_52w_range( + header, fundament_info, value, raw + ) + elif header == "Optionable" or header == "Shortable": if raw: fundament_info[header] = value - elif value == 'Yes': + elif value == "Yes": fundament_info[header] = True else: fundament_info[header] = False @@ -136,20 +159,20 @@ def TickerFundament(self, raw=True): fundament_info[header] = value else: try: - fundament_info[header] = numberCovert(value) + fundament_info[header] = number_covert(value) except ValueError: fundament_info[header] = value - self.info['fundament'] = fundament_info + self.info["fundament"] = fundament_info return fundament_info def _parse_52w_range(self, header, fundament_info, value, raw): - info_header = ['52W Range From', '52W Range To'] + info_header = ["52W Range From", "52W Range To"] info_value = [0, 2] self._parse_value(header, fundament_info, value, raw, info_header, info_value) return fundament_info def _parse_volatility(self, header, fundament_info, value, raw): - info_header = ['Volatility W', 'Volatility M'] + info_header = ["Volatility W", "Volatility M"] info_value = [0, 1] self._parse_value(header, fundament_info, value, raw, info_header, info_value) return fundament_info @@ -162,132 +185,170 @@ def _parse_value(self, header, fundament_info, value, raw, info_header, info_val fundament_info[info_header[i]] = value[value_index] else: for i, value_index in enumerate(info_value): - fundament_info[info_header[i]] = numberCovert(value[value_index]) + fundament_info[info_header[i]] = number_covert(value[value_index]) except: fundament_info[header] = value return fundament_info - def TickerDescription(self): + def ticker_description(self): """Get ticker description. Returns: description(str): ticker description. """ - return self.soup.find('td', class_='fullview-profile').text + return self.soup.find("td", class_="fullview-profile").text - def TickerOuterRatings(self): + def ticker_outer_ratings(self): """Get outer ratings table. Returns: df(pandas.DataFrame): outer ratings table """ - fullview_ratings_outer = self.soup.find('table', class_="fullview-ratings-outer") - df = pd.DataFrame([], columns=['Date', 'Status', 'Outer', 'Rating', 'Price']) - rows = fullview_ratings_outer.findAll('td', class_="fullview-ratings-inner") + fullview_ratings_outer = self.soup.find( + "table", class_="fullview-ratings-outer" + ) + df = pd.DataFrame([], columns=["Date", "Status", "Outer", "Rating", "Price"]) + rows = fullview_ratings_outer.findAll("td", class_="fullview-ratings-inner") for row in rows: - each_row = row.find('tr') - cols = each_row.findAll('td') + each_row = row.find("tr") + cols = each_row.findAll("td") date = cols[0].text - date = datetime.strptime(date, '%b-%d-%y') + date = datetime.strptime(date, "%b-%d-%y") status = cols[1].text outer = cols[2].text rating = cols[3].text price = cols[4].text - df = df.append({'Date': date, 'Status': status, 'Outer': outer, 'Rating': rating, 'Price': price}, - ignore_index=True) - self.info['ratings_outer'] = df + df = df.append( + { + "Date": date, + "Status": status, + "Outer": outer, + "Rating": rating, + "Price": price, + }, + ignore_index=True, + ) + self.info["ratings_outer"] = df return df - def TickerNews(self): + def ticker_news(self): """Get news information table. Returns: df(pandas.DataFrame): news information table """ - fullview_news_outer = self.soup.find('table', class_='fullview-news-outer') - rows = fullview_news_outer.findAll('tr') + fullview_news_outer = self.soup.find("table", class_="fullview-news-outer") + rows = fullview_news_outer.findAll("tr") - last_date = '' - df = pd.DataFrame([], columns=['Date', 'Title', 'Link']) + last_date = "" + df = pd.DataFrame([], columns=["Date", "Title", "Link"]) for row in rows: - cols = row.findAll('td') + cols = row.findAll("td") date = cols[0].text title = cols[1].a.text - link = cols[1].a['href'] - newsTime = date.split() - if len(newsTime) == 2: - last_date = newsTime[0] - newsTime = ' '.join(newsTime) + link = cols[1].a["href"] + news_time = date.split() + if len(news_time) == 2: + last_date = news_time[0] + news_time = " ".join(news_time) else: - newsTime = last_date + ' ' + newsTime[0] - newsTime = datetime.strptime(newsTime, '%b-%d-%y %I:%M%p') - df = df.append({'Date': newsTime, 'Title': title, 'Link': link}, ignore_index=True) - self.info['news'] = df + news_time = last_date + " " + news_time[0] + news_time = datetime.strptime(news_time, "%b-%d-%y %I:%M%p") + df = df.append( + {"Date": news_time, "Title": title, "Link": link}, ignore_index=True + ) + self.info["news"] = df return df - def TickerInsideTrader(self): + def ticker_inside_trader(self): """Get insider information table. Returns: df(pandas.DataFrame): insider information table """ - inside_trader = self.soup.find('table', class_='body-table') - rows = inside_trader.findAll('tr') - table_header = [i.text for i in rows[0].findAll('td')] - table_header += ['SEC Form 4 Link', 'Insider_id'] + inside_trader = self.soup.find("table", class_="body-table") + rows = inside_trader.findAll("tr") + table_header = [i.text for i in rows[0].findAll("td")] + table_header += ["SEC Form 4 Link", "Insider_id"] df = pd.DataFrame([], columns=table_header) rows = rows[1:] - num_col = ['Cost', '#Shares', 'Value ($)', '#Shares Total'] + num_col = ["Cost", "#Shares", "Value ($)", "#Shares Total"] num_col_index = [table_header.index(i) for i in table_header if i in num_col] for row in rows: - cols = row.findAll('td') + cols = row.findAll("td") info_dict = {} for i, col in enumerate(cols): if i not in num_col_index: info_dict[table_header[i]] = col.text else: - info_dict[table_header[i]] = numberCovert(col.text) - info_dict['SEC Form 4 Link'] = cols[-1].find('a').attrs['href'] - info_dict['Insider_id'] = cols[0].a['href'].split('oc=')[1].split('&tc=')[0] + info_dict[table_header[i]] = number_covert(col.text) + info_dict["SEC Form 4 Link"] = cols[-1].find("a").attrs["href"] + info_dict["Insider_id"] = cols[0].a["href"].split("oc=")[1].split("&tc=")[0] df = df.append(info_dict, ignore_index=True) - self.info['inside trader'] = df + self.info["inside trader"] = df return df - def TickerSignal(self): + def ticker_signal(self): """Get all the trading signals from finviz. Returns: ticker_signals(list): get all the ticker signals as list. """ from finvizfinance.screener.ticker import Ticker + fticker = Ticker() - signals = ['Top Gainers', 'Top Losers', 'New High', 'New Low', - 'Most Volatile', 'Most Active', 'Unusual Volume', - 'Overbought', 'Oversold', 'Downgrades', 'Upgrades', - 'Earnings Before', 'Earnings After', 'Recent Insider Buying', - 'Recent Insider Selling', 'Major News', 'Horizontal S/R', - 'TL Resistance', 'TL Support', 'Wedge Up', 'Wedge Down', - 'Triangle Ascending', 'Triangle Descending', 'Wedge', - 'Channel Up', 'Channel Down', 'Channel', 'Double Top', - 'Double Bottom', 'Multiple Top', 'Multiple Bottom', - 'Head & Shoulders', 'Head & Shoulders Inverse'] + signals = [ + "Top Gainers", + "Top Losers", + "New High", + "New Low", + "Most Volatile", + "Most Active", + "Unusual Volume", + "Overbought", + "Oversold", + "Downgrades", + "Upgrades", + "Earnings Before", + "Earnings After", + "Recent Insider Buying", + "Recent Insider Selling", + "Major News", + "Horizontal S/R", + "TL Resistance", + "TL Support", + "Wedge Up", + "Wedge Down", + "Triangle Ascending", + "Triangle Descending", + "Wedge", + "Channel Up", + "Channel Down", + "Channel", + "Double Top", + "Double Bottom", + "Multiple Top", + "Multiple Bottom", + "Head & Shoulders", + "Head & Shoulders Inverse", + ] ticker_signal = [] for signal in signals: fticker.set_filter(signal=signal, ticker=self.ticker.upper()) - if fticker.ScreenerView(verbose=0) == [self.ticker.upper()]: + if fticker.screener_view(verbose=0) == [self.ticker.upper()]: ticker_signal.append(signal) return ticker_signal - def TickerFullInfo(self): + def ticker_full_info(self): """Get all the ticker information. Returns: df(pandas.DataFrame): insider information table """ - self.TickerFundament() - self.TickerOuterRatings() - self.TickerNews() - self.TickerInsideTrader() + self.ticker_fundament() + self.ticker_outer_ratings() + self.ticker_news() + self.ticker_inside_trader() return self.info @@ -296,7 +357,8 @@ class Statements: Getting statements of ticker """ - def getStatements(self, ticker, statement="I", timeframe="A"): + + def get_statements(self, ticker, statement="I", timeframe="A"): """Getting statements of ticker. Args: @@ -306,14 +368,14 @@ def getStatements(self, ticker, statement="I", timeframe="A"): Returns: df(pandas.DataFrame): statements table """ - url = 'https://finviz.com/api/statement.ashx?t={ticker}&s={statement}{timeframe}'.format(ticker=ticker, - statement=statement, - timeframe=timeframe) + url = "https://finviz.com/api/statement.ashx?t={ticker}&s={statement}{timeframe}".format( + ticker=ticker, statement=statement, timeframe=timeframe + ) try: website = requests.get(url, headers=headers) website.raise_for_status() response = json.loads(website.content) - df = pd.DataFrame.from_dict(response['data'], orient='index') + df = pd.DataFrame.from_dict(response["data"], orient="index") return df except requests.exceptions.HTTPError as err: - raise Exception(err) \ No newline at end of file + raise Exception(err) diff --git a/finvizfinance/screener/custom.py b/finvizfinance/screener/custom.py index 993fb35..7f3249f 100644 --- a/finvizfinance/screener/custom.py +++ b/finvizfinance/screener/custom.py @@ -1,7 +1,8 @@ import warnings import pandas as pd from finvizfinance.screener.overview import Overview -from finvizfinance.util import webScrap, progressBar, NUMBER_COL +from finvizfinance.util import web_scrap, progress_bar, NUMBER_COL + """ .. module:: screen.custom :synopsis: screen custom table. @@ -10,77 +11,77 @@ """ COLUMNS = { - 0: 'No.', - 1: 'Ticker', - 2: 'Company', - 3: 'Sector', - 4: 'Industry', - 5: 'Country', - 6: 'Market Cap.', - 7: 'P/E', - 8: 'Forward P/E', - 9: 'PEG', - 10: 'P/S', - 11: 'P/B', - 12: 'P/Cash', - 13: 'P/Free Cash Flow', - 14: 'Dividend Yield', - 15: 'Payout Ratio', - 16: 'EPS', - 17: 'EPS growth this year', - 18: 'EPS growth next year', - 19: 'EPS growth past 5 years', - 20: 'EPS growth next 5 years', - 21: 'Sales growth past 5 years', - 22: 'EPS growth qtr over qtr', - 23: 'Sales growth qtr over qtr', - 24: 'Shares Outstanding', - 25: 'Shares Float', - 26: 'Insider Ownership', - 27: 'Insider Transactions', - 28: 'Institutional Ownership', - 29: 'Institutional Transactions', - 30: 'Float Short', - 31: 'Short Ratio', - 32: 'Return on Assets', - 33: 'Return on Equity', - 34: 'Return on Investments', - 35: 'Current Ratio', - 36: 'Quick Ratio', - 37: 'Long Term Debt/Equity', - 38: 'Total Debt/Equity', - 39: 'Gross Margin', - 40: 'Operating Margin', - 41: 'Net Profit Margin', - 42: 'Performance (Week)', - 43: 'Performance (Month)', - 44: 'Performance (Quarter)', - 45: 'Performance (Half Year)', - 46: 'Performance (Year)', - 47: 'Performance (YearToDate)', - 48: 'Beta', - 49: 'Average True Range', - 50: 'Volatility (Week)', - 51: 'Volatility (Month)', - 52: '20-Day Simple Moving Average', - 53: '50-Day Simple Moving Average', - 54: '200-Day Simple Moving Average', - 55: '50-Day High', - 56: '50-Day Low', - 57: '52-Week High', - 58: '52-Week Low', - 59: 'RSI', - 60: 'Change from Open', - 61: 'Gap', - 62: 'Analyst Recom.', - 63: 'Average Volume', - 64: 'Relative Volume', - 65: 'Price', - 66: 'Change', - 67: 'Volume', - 68: 'Earnings Date', - 69: 'Target Price', - 70: 'IPO Date' + 0: "No.", + 1: "Ticker", + 2: "Company", + 3: "Sector", + 4: "Industry", + 5: "Country", + 6: "Market Cap.", + 7: "P/E", + 8: "Forward P/E", + 9: "PEG", + 10: "P/S", + 11: "P/B", + 12: "P/Cash", + 13: "P/Free Cash Flow", + 14: "Dividend Yield", + 15: "Payout Ratio", + 16: "EPS", + 17: "EPS growth this year", + 18: "EPS growth next year", + 19: "EPS growth past 5 years", + 20: "EPS growth next 5 years", + 21: "Sales growth past 5 years", + 22: "EPS growth qtr over qtr", + 23: "Sales growth qtr over qtr", + 24: "Shares Outstanding", + 25: "Shares Float", + 26: "Insider Ownership", + 27: "Insider Transactions", + 28: "Institutional Ownership", + 29: "Institutional Transactions", + 30: "Float Short", + 31: "Short Ratio", + 32: "Return on Assets", + 33: "Return on Equity", + 34: "Return on Investments", + 35: "Current Ratio", + 36: "Quick Ratio", + 37: "Long Term Debt/Equity", + 38: "Total Debt/Equity", + 39: "Gross Margin", + 40: "Operating Margin", + 41: "Net Profit Margin", + 42: "Performance (Week)", + 43: "Performance (Month)", + 44: "Performance (Quarter)", + 45: "Performance (Half Year)", + 46: "Performance (Year)", + 47: "Performance (YearToDate)", + 48: "Beta", + 49: "Average True Range", + 50: "Volatility (Week)", + 51: "Volatility (Month)", + 52: "20-Day Simple Moving Average", + 53: "50-Day Simple Moving Average", + 54: "200-Day Simple Moving Average", + 55: "50-Day High", + 56: "50-Day Low", + 57: "52-Week High", + 58: "52-Week Low", + 59: "RSI", + 60: "Change from Open", + 61: "Gap", + 62: "Analyst Recom.", + 63: "Average Volume", + 64: "Relative Volume", + 65: "Price", + 66: "Change", + 67: "Volume", + 68: "Earnings Date", + 69: "Target Price", + 70: "IPO Date", } @@ -88,14 +89,16 @@ class Custom(Overview): """Custom inherit from overview module. Getting information from the finviz screener custom page. """ - def __init__(self): - """initiate module - """ - self.BASE_URL = 'https://finviz.com/screener.ashx?v=151{signal}{filter}&ft=4{ticker}' - self.url = self.BASE_URL.format(signal='', filter='', ticker='') - Overview._loadSetting(self) - def getColumns(self): + def __init__(self): + """initiate module""" + self.BASE_URL = ( + "https://finviz.com/screener.ashx?v=151{signal}{filter}&ft=4{ticker}" + ) + self.url = self.BASE_URL.format(signal="", filter="", ticker="") + Overview._load_setting(self) + + def get_columns(self): """Get information about the columns Returns: @@ -110,18 +113,22 @@ def _screener_helper(self, i, page, rows, df, num_col_index, table_header, limit df(pandas.DataFrame): screener information table """ if i == page - 1: - df = self._get_table(rows, df, num_col_index, table_header, limit=((limit - 1) % 20 + 1)) + df = self._get_table( + rows, df, num_col_index, table_header, limit=((limit - 1) % 20 + 1) + ) else: df = self._get_table(rows, df, num_col_index, table_header) return df - def ScreenerView(self, - order='ticker', - limit=-1, - select_page=None, - verbose=1, - ascend=True, - columns=[0, 1, 2, 3, 4, 5, 6, 7, 65, 66, 67]): + def screener_view( + self, + order="ticker", + limit=-1, + select_page=None, + verbose=1, + ascend=True, + columns=[0, 1, 2, 3, 4, 5, 6, 7, 65, 66, 67], + ): """Get screener table. Args: @@ -135,20 +142,22 @@ def ScreenerView(self, df(pandas.DataFrame): screener information table """ url = self.url - if order != 'ticker': + if order != "ticker": if order not in self.order_dict: order_keys = list(self.order_dict.keys()) - raise ValueError("Invalid order '{}'. Possible order: {}".format(order, order_keys)) - url = self.url+'&'+self.order_dict[order] + raise ValueError( + "Invalid order '{}'. Possible order: {}".format(order, order_keys) + ) + url = self.url + "&" + self.order_dict[order] if not ascend: - url = url.replace('o=', 'o=-') + url = url.replace("o=", "o=-") columns = [str(i) for i in columns] - url += '&c=' + ','.join(columns) - soup = webScrap(url) + url += "&c=" + ",".join(columns) + soup = web_scrap(url) page = self._get_page(soup) if page == 0: - print('No ticker found.') + print("No ticker found.") return None start_page = 1 @@ -169,36 +178,40 @@ def ScreenerView(self, if verbose == 1: if not select_page: - progressBar(start_page, end_page) + progress_bar(start_page, end_page) else: - progressBar(1, 1) + progress_bar(1, 1) - table = soup.findAll('table')[18] - rows = table.findAll('tr') - table_header = [i.text for i in rows[0].findAll('td')][1:] + table = soup.findAll("table")[18] + rows = table.findAll("tr") + table_header = [i.text for i in rows[0].findAll("td")][1:] num_col_index = [table_header.index(i) for i in table_header if i in NUMBER_COL] df = pd.DataFrame([], columns=table_header) if not select_page or select_page == 1: - df = self._screener_helper(0, page, rows, df, num_col_index, table_header, limit) + df = self._screener_helper( + 0, page, rows, df, num_col_index, table_header, limit + ) if select_page != 1: for i in range(start_page, end_page): if verbose == 1: if not select_page: - progressBar(i + 1, page) + progress_bar(i + 1, page) else: - progressBar(1, 1) + progress_bar(1, 1) url = self.url - if order == 'ticker': - url += '&r={}'.format(i * 20 + 1) + if order == "ticker": + url += "&r={}".format(i * 20 + 1) else: - url += '&r={}'.format(i * 20 + 1) + '&' + self.order_dict[order] + url += "&r={}".format(i * 20 + 1) + "&" + self.order_dict[order] if not ascend: - url = url.replace('o=', 'o=-') - url += '&c=' + ','.join(columns) - soup = webScrap(url) - table = soup.findAll('table')[18] - rows = table.findAll('tr') - df = self._screener_helper(i, page, rows, df, num_col_index, table_header, limit) + url = url.replace("o=", "o=-") + url += "&c=" + ",".join(columns) + soup = web_scrap(url) + table = soup.findAll("table")[18] + rows = table.findAll("tr") + df = self._screener_helper( + i, page, rows, df, num_col_index, table_header, limit + ) return df diff --git a/finvizfinance/screener/financial.py b/finvizfinance/screener/financial.py index 96d8b30..3a54294 100644 --- a/finvizfinance/screener/financial.py +++ b/finvizfinance/screener/financial.py @@ -1,4 +1,5 @@ from finvizfinance.screener.overview import Overview + """ .. module:: screen.financial :synopsis: screen financial table. @@ -11,9 +12,11 @@ class Financial(Overview): """Financial inherit from overview module. Getting information from the finviz screener financial page. """ + def __init__(self): - """initiate module - """ - self.BASE_URL = 'https://finviz.com/screener.ashx?v=161{signal}{filter}&ft=4{ticker}' - self.url = self.BASE_URL.format(signal='', filter='', ticker='') - Overview._loadSetting(self) \ No newline at end of file + """initiate module""" + self.BASE_URL = ( + "https://finviz.com/screener.ashx?v=161{signal}{filter}&ft=4{ticker}" + ) + self.url = self.BASE_URL.format(signal="", filter="", ticker="") + Overview._load_setting(self) diff --git a/finvizfinance/screener/overview.py b/finvizfinance/screener/overview.py index 44a3ca3..fcc876e 100644 --- a/finvizfinance/screener/overview.py +++ b/finvizfinance/screener/overview.py @@ -1,7 +1,14 @@ import warnings import pandas as pd from finvizfinance.quote import finvizfinance -from finvizfinance.util import webScrap, numberCovert, progressBar, NUMBER_COL, util_dict +from finvizfinance.util import ( + web_scrap, + number_covert, + progress_bar, + NUMBER_COL, + util_dict, +) + """ .. module:: screen.overview :synopsis: screen overview table. @@ -15,18 +22,21 @@ class Overview: """Overview Getting information from the finviz screener overview page. """ + def __init__(self): """initiate module""" - self.BASE_URL = 'https://finviz.com/screener.ashx?v=111{signal}{filter}&ft=4{ticker}' - self.url = self.BASE_URL.format(signal='', filter='', ticker='') - self._loadSetting() + self.BASE_URL = ( + "https://finviz.com/screener.ashx?v=111{signal}{filter}&ft=4{ticker}" + ) + self.url = self.BASE_URL.format(signal="", filter="", ticker="") + self._load_setting() - def _loadSetting(self): + def _load_setting(self): """load all the signals and filters.""" data = util_dict - self.signal_dict = data['signal'] - self.filter_dict = data['filter'] - self.order_dict = data['order'] + self.signal_dict = data["signal"] + self.filter_dict = data["filter"] + self.order_dict = data["order"] def _set_signal(self, signal): """set signal. @@ -36,15 +46,17 @@ def _set_signal(self, signal): Returns: url_signal(str): signal string for url """ - url_signal = '' - if signal not in self.signal_dict and signal != '': + url_signal = "" + if signal not in self.signal_dict and signal != "": signal_keys = list(self.signal_dict.keys()) - raise ValueError("Invalid signal '{}'. Possible signal: {}".format(signal, signal_keys)) - elif signal != '': - url_signal = '&s=' + self.signal_dict[signal] + raise ValueError( + "Invalid signal '{}'. Possible signal: {}".format(signal, signal_keys) + ) + elif signal != "": + url_signal = "&s=" + self.signal_dict[signal] return url_signal - def getSignal(self): + def get_signal(self): """Get signals. Returns: @@ -52,7 +64,7 @@ def getSignal(self): """ return list(self.signal_dict.keys()) - def getFilters(self): + def get_filters(self): """Get filters. Returns: @@ -60,7 +72,7 @@ def getFilters(self): """ return list(self.filter_dict.keys()) - def getFilterOptions(self, screen_filter): + def get_filter_options(self, screen_filter): """Get filters options. Args: @@ -71,10 +83,14 @@ def getFilterOptions(self, screen_filter): """ if screen_filter not in self.filter_dict: filter_keys = list(self.filter_dict.keys()) - raise ValueError("Invalid filter '{}'. Possible filter: {}".format(screen_filter, filter_keys)) - return list(self.filter_dict[screen_filter]['option']) - - def getOrders(self): + raise ValueError( + "Invalid filter '{}'. Possible filter: {}".format( + screen_filter, filter_keys + ) + ) + return list(self.filter_dict[screen_filter]["option"]) + + def get_orders(self): """Get orders. Returns: @@ -95,18 +111,23 @@ def _set_filters(self, filters_dict): for key, value in filters_dict.items(): if key not in self.filter_dict: filter_keys = list(self.filter_dict.keys()) - raise ValueError("Invalid filter '{}'. Possible filter: {}".format(key, filter_keys)) - if value not in self.filter_dict[key]['option']: - filter_options = list(self.filter_dict[key]['option'].keys()) - raise ValueError("Invalid filter option '{}'. Possible filter options: {}".format(value, - filter_options)) - prefix = self.filter_dict[key]['prefix'] - urlcode = self.filter_dict[key]['option'][value] - if urlcode != '': - filters.append('{}_{}'.format(prefix, urlcode)) - url_filter = '' + raise ValueError( + "Invalid filter '{}'. Possible filter: {}".format(key, filter_keys) + ) + if value not in self.filter_dict[key]["option"]: + filter_options = list(self.filter_dict[key]["option"].keys()) + raise ValueError( + "Invalid filter option '{}'. Possible filter options: {}".format( + value, filter_options + ) + ) + prefix = self.filter_dict[key]["prefix"] + urlcode = self.filter_dict[key]["option"][value] + if urlcode != "": + filters.append("{}_{}".format(prefix, urlcode)) + url_filter = "" if len(filters) != 0: - url_filter = '&f=' + ','.join(filters) + url_filter = "&f=" + ",".join(filters) return url_filter def _set_ticker(self, ticker): @@ -117,11 +138,11 @@ def _set_ticker(self, ticker): Returns: url_ticker(str): ticker string for url """ - if ticker == '': - return '' - return '&t='+ticker + if ticker == "": + return "" + return "&t=" + ticker - def set_filter(self, signal='', filters_dict={}, ticker=''): + def set_filter(self, signal="", filters_dict={}, ticker=""): """Update the settings. Args: @@ -129,18 +150,19 @@ def set_filter(self, signal='', filters_dict={}, ticker=''): filters_dict(dict): dictionary of filters ticker(str): ticker string """ - if signal == '' and filters_dict == {} and ticker == '': - self.url = self.BASE_URL.format(signal='', filter='', ticker='') + if signal == "" and filters_dict == {} and ticker == "": + self.url = self.BASE_URL.format(signal="", filter="", ticker="") else: url_signal = self._set_signal(signal) url_filter = self._set_filters(filters_dict) url_ticker = self._set_ticker(ticker) - self.url = self.BASE_URL.format(signal=url_signal, filter=url_filter, ticker=url_ticker) + self.url = self.BASE_URL.format( + signal=url_signal, filter=url_filter, ticker=url_ticker + ) def _get_page(self, soup): - """Check the page number - """ - options = soup.findAll('table')[17].findAll('option') + """Check the page number""" + options = soup.findAll("table")[17].findAll("option") return len(options) def _get_table(self, rows, df, num_col_index, table_header, limit=-1): @@ -153,15 +175,15 @@ def _get_table(self, rows, df, num_col_index, table_header, limit=-1): if limit != -1: rows = rows[0:limit] - for index, row in enumerate(rows): - cols = row.findAll('td')[1:] + for row in rows: + cols = row.findAll("td")[1:] info_dict = {} for i, col in enumerate(cols): # check if the col is number if i not in num_col_index: info_dict[table_header[i]] = col.text else: - info_dict[table_header[i]] = numberCovert(col.text) + info_dict[table_header[i]] = number_covert(col.text) df = df.append(info_dict, ignore_index=True) return df @@ -172,12 +194,16 @@ def _screener_helper(self, i, page, rows, df, num_col_index, table_header, limit df(pandas.DataFrame): screener information table """ if i == page - 1: - df = self._get_table(rows, df, num_col_index, table_header, limit=((limit - 1) % 20 + 1)) + df = self._get_table( + rows, df, num_col_index, table_header, limit=((limit - 1) % 20 + 1) + ) else: df = self._get_table(rows, df, num_col_index, table_header) return df - def ScreenerView(self, order='ticker', limit=-1, select_page=None, verbose=1, ascend=True): + def screener_view( + self, order="ticker", limit=-1, select_page=None, verbose=1, ascend=True + ): """Get screener table. Args: @@ -190,18 +216,20 @@ def ScreenerView(self, order='ticker', limit=-1, select_page=None, verbose=1, as df(pandas.DataFrame): screener information table """ url = self.url - if order != 'ticker': + if order != "ticker": if order not in self.order_dict: order_keys = list(self.order_dict.keys()) - raise ValueError("Invalid order '{}'. Possible order: {}".format(order, order_keys)) - url = self.url+'&'+self.order_dict[order] + raise ValueError( + "Invalid order '{}'. Possible order: {}".format(order, order_keys) + ) + url = self.url + "&" + self.order_dict[order] if not ascend: - url = url.replace('o=', 'o=-') - soup = webScrap(url) + url = url.replace("o=", "o=-") + soup = web_scrap(url) page = self._get_page(soup) if page == 0: - print('No ticker found.') + print("No ticker found.") return None start_page = 1 @@ -222,40 +250,44 @@ def ScreenerView(self, order='ticker', limit=-1, select_page=None, verbose=1, as if verbose == 1: if not select_page: - progressBar(start_page, end_page) + progress_bar(start_page, end_page) else: - progressBar(1, 1) + progress_bar(1, 1) - table = soup.findAll('table')[18] - rows = table.findAll('tr') - table_header = [i.text for i in rows[0].findAll('td')][1:] + table = soup.findAll("table")[18] + rows = table.findAll("tr") + table_header = [i.text for i in rows[0].findAll("td")][1:] num_col_index = [table_header.index(i) for i in table_header if i in NUMBER_COL] df = pd.DataFrame([], columns=table_header) if not select_page or select_page == 1: - df = self._screener_helper(0, page, rows, df, num_col_index, table_header, limit) + df = self._screener_helper( + 0, page, rows, df, num_col_index, table_header, limit + ) if select_page != 1: for i in range(start_page, end_page): if verbose == 1: if not select_page: - progressBar(i+1, page) + progress_bar(i + 1, page) else: - progressBar(1, 1) + progress_bar(1, 1) url = self.url - if order == 'ticker': - url += '&r={}'.format(i * 20 + 1) + if order == "ticker": + url += "&r={}".format(i * 20 + 1) else: - url += '&r={}'.format(i * 20 + 1) + '&' + self.order_dict[order] + url += "&r={}".format(i * 20 + 1) + "&" + self.order_dict[order] if not ascend: - url = url.replace('o=', 'o=-') - soup = webScrap(url) - table = soup.findAll('table')[18] - rows = table.findAll('tr') - df = self._screener_helper(i, page, rows, df, num_col_index, table_header, limit) + url = url.replace("o=", "o=-") + soup = web_scrap(url) + table = soup.findAll("table")[18] + rows = table.findAll("tr") + df = self._screener_helper( + i, page, rows, df, num_col_index, table_header, limit + ) return df - def compare(self, ticker, compare_list, order='ticker', verbose=1): + def compare(self, ticker, compare_list, order="ticker", verbose=1): """Get screener table of similar property (Sector, Industry, Country) Args: @@ -266,17 +298,17 @@ def compare(self, ticker, compare_list, order='ticker', verbose=1): Returns: df(pandas.DataFrame): screener information table """ - check_list = ['Sector', 'Industry', 'Country'] + check_list = ["Sector", "Industry", "Country"] error_list = [i for i in compare_list if i not in check_list] if len(error_list) != 0: - raise ValueError('Please check: {}'.format(error_list)) + raise ValueError("Please check: {}".format(error_list)) stock = finvizfinance(ticker) - stock_fundament = stock.TickerFundament() + stock_fundament = stock.ticker_fundament() filters_dict = {} for compare in compare_list: filters_dict[compare] = stock_fundament[compare] self.set_filter(filters_dict=filters_dict) - df = self.ScreenerView(order=order, verbose=verbose) + df = self.screener_view(order=order, verbose=verbose) return df diff --git a/finvizfinance/screener/ownership.py b/finvizfinance/screener/ownership.py index 11d2a76..6db558d 100644 --- a/finvizfinance/screener/ownership.py +++ b/finvizfinance/screener/ownership.py @@ -1,4 +1,5 @@ from finvizfinance.screener.overview import Overview + """ .. module:: screen.ownership :synopsis: screen ownership table. @@ -11,9 +12,11 @@ class Ownership(Overview): """Ownership inherit from overview module. Getting information from the finviz screener ownership page. """ + def __init__(self): - """initiate module - """ - self.BASE_URL = 'https://finviz.com/screener.ashx?v=131{signal}{filter}&ft=4{ticker}' - self.url = self.BASE_URL.format(signal='', filter='', ticker='') - Overview._loadSetting(self) \ No newline at end of file + """initiate module""" + self.BASE_URL = ( + "https://finviz.com/screener.ashx?v=131{signal}{filter}&ft=4{ticker}" + ) + self.url = self.BASE_URL.format(signal="", filter="", ticker="") + Overview._load_setting(self) diff --git a/finvizfinance/screener/performance.py b/finvizfinance/screener/performance.py index 867d256..df5ec86 100644 --- a/finvizfinance/screener/performance.py +++ b/finvizfinance/screener/performance.py @@ -1,4 +1,5 @@ from finvizfinance.screener.overview import Overview + """ .. module:: screen.performance :synopsis: screen performance table. @@ -11,9 +12,11 @@ class Performance(Overview): """Performance inherit from overview module. Getting information from the finviz screener performance page. """ + def __init__(self): - """initiate module - """ - self.BASE_URL = 'https://finviz.com/screener.ashx?v=141{signal}{filter}&ft=4{ticker}' - self.url = self.BASE_URL.format(signal='', filter='', ticker='') - Overview._loadSetting(self) \ No newline at end of file + """initiate module""" + self.BASE_URL = ( + "https://finviz.com/screener.ashx?v=141{signal}{filter}&ft=4{ticker}" + ) + self.url = self.BASE_URL.format(signal="", filter="", ticker="") + Overview._load_setting(self) diff --git a/finvizfinance/screener/technical.py b/finvizfinance/screener/technical.py index df7921d..0d005e3 100644 --- a/finvizfinance/screener/technical.py +++ b/finvizfinance/screener/technical.py @@ -1,4 +1,5 @@ from finvizfinance.screener.overview import Overview + """ .. module:: screen.technical :synopsis: screen technical table. @@ -11,9 +12,11 @@ class Technical(Overview): """Technical inherit from overview module. Getting information from the finviz screener technical page. """ + def __init__(self): - """initiate module - """ - self.BASE_URL = 'https://finviz.com/screener.ashx?v=171{signal}{filter}&ft=4{ticker}' - self.url = self.BASE_URL.format(signal='', filter='', ticker='') - Overview._loadSetting(self) \ No newline at end of file + """initiate module""" + self.BASE_URL = ( + "https://finviz.com/screener.ashx?v=171{signal}{filter}&ft=4{ticker}" + ) + self.url = self.BASE_URL.format(signal="", filter="", ticker="") + Overview._load_setting(self) diff --git a/finvizfinance/screener/ticker.py b/finvizfinance/screener/ticker.py index c34170a..88d0d44 100644 --- a/finvizfinance/screener/ticker.py +++ b/finvizfinance/screener/ticker.py @@ -1,5 +1,6 @@ from finvizfinance.screener.overview import Overview -from finvizfinance.util import webScrap, progressBar +from finvizfinance.util import web_scrap, progress_bar + """ .. module:: screen.ticker :synopsis: screen ticker table. @@ -12,22 +13,24 @@ class Ticker(Overview): """Financial inherit from overview module. Getting information from the finviz screener ticker page. """ + def __init__(self): - """initiate module - """ - self.BASE_URL = 'https://finviz.com/screener.ashx?v=411{signal}{filter}&ft=4{ticker}' - self.url = self.BASE_URL.format(signal='', filter='', ticker='') - Overview._loadSetting(self) + """initiate module""" + self.BASE_URL = ( + "https://finviz.com/screener.ashx?v=411{signal}{filter}&ft=4{ticker}" + ) + self.url = self.BASE_URL.format(signal="", filter="", ticker="") + Overview._load_setting(self) def _screener_helper(self, i, page, soup, tickers, limit): - table = soup.findAll('table')[18] - page_tickers = table.findAll('span') + table = soup.findAll("table")[18] + page_tickers = table.findAll("span") if i == page - 1: - page_tickers = page_tickers[:((limit - 1) % 1000 + 1)] - tickers = tickers + [i.text.split('\xa0')[1] for i in page_tickers] + page_tickers = page_tickers[: ((limit - 1) % 1000 + 1)] + tickers = tickers + [i.text.split("\xa0")[1] for i in page_tickers] return tickers - def ScreenerView(self, limit=-1, verbose=1): + def screener_view(self, limit=-1, verbose=1): """Get screener table. Args: @@ -35,26 +38,26 @@ def ScreenerView(self, limit=-1, verbose=1): Returns: tickers(list): get all the tickers as list. """ - soup = webScrap(self.url) + soup = web_scrap(self.url) page = self._get_page(soup) if page == 0: if verbose == 1: - print('No ticker found.') + print("No ticker found.") return None if limit != -1: - if page > (limit-1)//1000+1: - page = (limit-1)//1000+1 + if page > (limit - 1) // 1000 + 1: + page = (limit - 1) // 1000 + 1 if verbose == 1: - progressBar(1, page) + progress_bar(1, page) tickers = [] tickers = self._screener_helper(0, page, soup, tickers, limit) for i in range(1, page): if verbose == 1: - progressBar(i+1, page) - soup = webScrap(self.url + '&r={}'.format(i * 1000 + 1)) + progress_bar(i + 1, page) + soup = web_scrap(self.url + "&r={}".format(i * 1000 + 1)) tickers = self._screener_helper(i, page, soup, tickers, limit) - return tickers \ No newline at end of file + return tickers diff --git a/finvizfinance/screener/valuation.py b/finvizfinance/screener/valuation.py index 672a0b8..0709f45 100644 --- a/finvizfinance/screener/valuation.py +++ b/finvizfinance/screener/valuation.py @@ -1,4 +1,5 @@ from finvizfinance.screener.overview import Overview + """ .. module:: screen.valuation :synopsis: screen valuation table. @@ -9,11 +10,13 @@ class Valuation(Overview): """Valuation inherit from overview module. - Getting information from the finviz screener valuation page. + Getting information from the finviz screener valuation page. """ + def __init__(self): - """initiate module - """ - self.BASE_URL = 'https://finviz.com/screener.ashx?v=121{signal}{filter}&ft=4{ticker}' - self.url = self.BASE_URL.format(signal='', filter='', ticker='') - Overview._loadSetting(self) \ No newline at end of file + """initiate module""" + self.BASE_URL = ( + "https://finviz.com/screener.ashx?v=121{signal}{filter}&ft=4{ticker}" + ) + self.url = self.BASE_URL.format(signal="", filter="", ticker="") + Overview._load_setting(self) diff --git a/finvizfinance/util.py b/finvizfinance/util.py index 0a50835..820b879 100644 --- a/finvizfinance/util.py +++ b/finvizfinance/util.py @@ -10,24 +10,81 @@ .. moduleauthor:: Tianning Li """ -headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) \ - AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36'} - -NUMBER_COL = ['Market Cap', 'P/E', 'Fwd P/E', 'PEG', 'P/S', 'P/B', 'P/C', - 'P/FCF', 'Dividend', 'Payout Ratio', 'EPS', 'EPS this Y', 'EPS next Y', - 'EPS past 5Y', 'EPS next 5Y', 'Sales past 5Y', 'EPS Q/Q', 'Sales Q/Q', - 'Outstanding', 'Float', 'Insider Own', 'Insider Trans', 'Inst Own', 'Inst Trans', - 'Float Short', 'Short Ratio', 'ROA', 'ROE', 'ROI', 'Curr R', 'Quick R', 'LTDebt/Eq', - 'Debt/Eq', 'Gross M', 'Oper M', 'Profit M', 'Perf Week', 'Perf Month', 'Perf Quart', - 'Perf Half', 'Perf Year', 'Perf YTD', 'Beta', 'ATR', 'Volatility W', 'Volatility M', - 'SMA20', 'SMA50', 'SMA200', '50D High', '50D Low', '52W High', '52W Low', 'RSI', - 'from Open', 'Gap', 'Recom', 'Avg Volume', 'Rel Volume', 'Price', 'Change', 'Volume', - 'Target Price'] +headers = { + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) \ + AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36" +} + +NUMBER_COL = [ + "Market Cap", + "P/E", + "Fwd P/E", + "PEG", + "P/S", + "P/B", + "P/C", + "P/FCF", + "Dividend", + "Payout Ratio", + "EPS", + "EPS this Y", + "EPS next Y", + "EPS past 5Y", + "EPS next 5Y", + "Sales past 5Y", + "EPS Q/Q", + "Sales Q/Q", + "Outstanding", + "Float", + "Insider Own", + "Insider Trans", + "Inst Own", + "Inst Trans", + "Float Short", + "Short Ratio", + "ROA", + "ROE", + "ROI", + "Curr R", + "Quick R", + "LTDebt/Eq", + "Debt/Eq", + "Gross M", + "Oper M", + "Profit M", + "Perf Week", + "Perf Month", + "Perf Quart", + "Perf Half", + "Perf Year", + "Perf YTD", + "Beta", + "ATR", + "Volatility W", + "Volatility M", + "SMA20", + "SMA50", + "SMA200", + "50D High", + "50D Low", + "52W High", + "52W Low", + "RSI", + "from Open", + "Gap", + "Recom", + "Avg Volume", + "Rel Volume", + "Price", + "Change", + "Volume", + "Target Price", +] session = requests.Session() -def webScrap(url): +def web_scrap(url): """Scrap website. Args: @@ -38,7 +95,7 @@ def webScrap(url): try: website = session.get(url, headers=headers, timeout=10) website.raise_for_status() - soup = BeautifulSoup(website.text, 'lxml') + soup = BeautifulSoup(website.text, "lxml") except requests.exceptions.HTTPError as err: raise Exception(err) except requests.exceptions.Timeout as err: @@ -46,7 +103,7 @@ def webScrap(url): return soup -def imageScrap(url, ticker, out_dir): +def image_scrap(url, ticker, out_dir): """scrap website and download image Args: @@ -59,8 +116,8 @@ def imageScrap(url, ticker, out_dir): r.raise_for_status() r.raw.decode_content = True if len(out_dir) != 0: - out_dir += '/' - f = open('{}{}.jpg'.format(out_dir, ticker), "wb") + out_dir += "/" + f = open("{}{}.jpg".format(out_dir, ticker), "wb") f.write(r.content) f.close() except requests.exceptions.HTTPError as err: @@ -69,7 +126,7 @@ def imageScrap(url, ticker, out_dir): raise Exception(err) -def scrapFunction(url): +def scrap_function(url): """Scrap forex, crypto information. Args: @@ -77,26 +134,26 @@ def scrapFunction(url): Returns: df(pandas.DataFrame): performance table """ - soup = webScrap(url) - table = soup.findAll('table')[3] - rows = table.findAll('tr') - table_header = [i.text.strip() for i in rows[0].findAll('td')][1:] + soup = web_scrap(url) + table = soup.findAll("table")[3] + rows = table.findAll("tr") + table_header = [i.text.strip() for i in rows[0].findAll("td")][1:] df = pd.DataFrame([], columns=table_header) rows = rows[1:] num_col_index = [i for i in range(2, len(table_header))] for row in rows: - cols = row.findAll('td')[1:] + cols = row.findAll("td")[1:] info_dict = {} for i, col in enumerate(cols): if i not in num_col_index: info_dict[table_header[i]] = col.text else: - info_dict[table_header[i]] = numberCovert(col.text) + info_dict[table_header[i]] = number_covert(col.text) df = df.append(info_dict, ignore_index=True) return df -def imageScrapFunction(url, chart, timeframe, urlonly): +def image_scrap_function(url, chart, timeframe, urlonly): """Scrap forex, crypto information. Args: @@ -105,36 +162,36 @@ def imageScrapFunction(url, chart, timeframe, urlonly): timeframe (str): choice of timeframe(5M, H, D, W, M) urlonly (boolean): choice of downloading chart """ - if timeframe == '5M': - url += 'm5' - elif timeframe == 'H': - url += 'h1' - elif timeframe == 'D': - url += 'd1' - elif timeframe == 'W': - url += 'w1' - elif timeframe == 'M': - url += 'mo' + if timeframe == "5M": + url += "m5" + elif timeframe == "H": + url += "h1" + elif timeframe == "D": + url += "d1" + elif timeframe == "W": + url += "w1" + elif timeframe == "M": + url += "mo" else: - raise ValueError('Invalid timeframe.') + raise ValueError("Invalid timeframe.") - soup = webScrap(url) - content = soup.find('div', class_='container') - imgs = content.findAll('img') + soup = web_scrap(url) + content = soup.find("div", class_="container") + imgs = content.findAll("img") for img in imgs: - website = img['src'] - name = website.split('?')[1].split('&')[0].split('.')[0] - chart_name = name.split('_')[0] + website = img["src"] + name = website.split("?")[1].split("&")[0].split(".")[0] + chart_name = name.split("_")[0] if chart.lower() == chart_name: - charturl = 'https://finviz.com/' + website + charturl = "https://finviz.com/" + website if not urlonly: - imageScrap(charturl, name, '') + image_scrap(charturl, name, "") return charturl else: continue -def numberCovert(num): +def number_covert(num): """covert number(str) to number(float) Args: @@ -142,26 +199,2116 @@ def numberCovert(num): Return: num(float): number of string """ - if num == '-': + if num == "-": return None - elif num[-1] == '%': + elif num[-1] == "%": return float(num[:-1]) / 100 - elif num[-1] == 'B': + elif num[-1] == "B": return float(num[:-1]) * 1000000000 - elif num[-1] == 'M': + elif num[-1] == "M": return float(num[:-1]) * 1000000 - elif num[-1] == 'K': + elif num[-1] == "K": return float(num[:-1]) * 1000 else: - return float(''.join(num.split(','))) + return float("".join(num.split(","))) -def progressBar(page, total): +def progress_bar(page, total): bar_len = 30 filled_len = int(round(bar_len * page / float(total))) - bar = '#' * filled_len + '-' * (bar_len - filled_len) - sys.stdout.write('[Info] loading page [{}] {}/{} \r'.format(bar, page, total)) + bar = "#" * filled_len + "-" * (bar_len - filled_len) + sys.stdout.write("[Info] loading page [{}] {}/{} \r".format(bar, page, total)) sys.stdout.flush() -util_dict = {"signal": {"Top Gainers": "ta_topgainers", "Top Losers": "ta_toplosers", "New High": "ta_newhigh", "New Low": "ta_newlow", "Most Volatile": "ta_mostvolatile", "Most Active": "ta_mostactive", "Unusual Volume": "ta_unusualvolume", "Overbought": "ta_overbought", "Oversold": "ta_oversold", "Downgrades": "n_downgrades", "Upgrades": "n_upgrades", "Earnings Before": "n_earningsbefore", "Earnings After": "n_earningsafter", "Recent Insider Buying": "it_latestbuys", "Recent Insider Selling": "it_latestsales", "Major News": "n_majornews", "Horizontal S/R": "ta_p_horizontal", "TL Resistance": "ta_p_tlresistance", "TL Support": "ta_p_tlsupport", "Wedge Up": "ta_p_wedgeup", "Wedge Down": "ta_p_wedgedown", "Triangle Ascending": "ta_p_wedgeresistance", "Triangle Descending": "ta_p_wedgesupport", "Wedge": "ta_p_wedge", "Channel Up": "ta_p_channelup", "Channel Down": "ta_p_channeldown", "Channel": "ta_p_channel", "Double Top": "ta_p_doubletop", "Double Bottom": "ta_p_doublebottom", "Multiple Top": "ta_p_multipletop", "Multiple Bottom": "ta_p_multiplebottom", "Head & Shoulders": "ta_p_headandshoulders", "Head & Shoulders Inverse": "ta_p_headandshouldersinv"}, "filter": {"Exchange": {"prefix": "exch", "option": {"Any": "", "AMEX": "amex", "NASDAQ": "nasd", "NYSE": "nyse"}}, "Index": {"prefix": "idx", "option": {"Any": "", "S&P 500": "sp500", "DJIA": "dji"}}, "Sector": {"prefix": "sec", "option": {"Any": "", "Basic Materials": "basicmaterials", "Communication Services": "communicationservices", "Consumer Cyclical": "consumercyclical", "Consumer Defensive": "consumerdefensive", "Energy": "energy", "Financial": "financial", "Healthcare": "healthcare", "Industrials": "industrials", "Real Estate": "realestate", "Technology": "technology", "Utilities": "utilities"}}, "Industry": {"prefix": "ind", "option": {"Any": "", "Stocks only (ex-Funds)": "stocksonly", "Exchange Traded Fund": "exchangetradedfund", "Advertising Agencies": "advertisingagencies", "Aerospace & Defense": "aerospacedefense", "Agricultural Inputs": "agriculturalinputs", "Airlines": "airlines", "Airports & Air Services": "airportsairservices", "Aluminum": "aluminum", "Apparel Manufacturing": "apparelmanufacturing", "Apparel Retail": "apparelretail", "Asset Management": "assetmanagement", "Auto Manufacturers": "automanufacturers", "Auto Parts": "autoparts", "Auto & Truck Dealerships": "autotruckdealerships", "Banks - Diversified": "banksdiversified", "Banks - Regional": "banksregional", "Beverages - Brewers": "beveragesbrewers", "Beverages - Non-Alcoholic": "beveragesnonalcoholic", "Beverages - Wineries & Distilleries": "beverageswineriesdistilleries", "Biotechnology": "biotechnology", "Broadcasting": "broadcasting", "Building Materials": "buildingmaterials", "Building Products & Equipment": "buildingproductsequipment", "Business Equipment & Supplies": "businessequipmentsupplies", "Capital Markets": "capitalmarkets", "Chemicals": "chemicals", "Closed-End Fund - Debt": "closedendfunddebt", "Closed-End Fund - Equity": "closedendfundequity", "Closed-End Fund - Foreign": "closedendfundforeign", "Coking Coal": "cokingcoal", "Communication Equipment": "communicationequipment", "Computer Hardware": "computerhardware", "Confectioners": "confectioners", "Conglomerates": "conglomerates", "Consulting Services": "consultingservices", "Consumer Electronics": "consumerelectronics", "Copper": "copper", "Credit Services": "creditservices", "Department Stores": "departmentstores", "Diagnostics & Research": "diagnosticsresearch", "Discount Stores": "discountstores", "Drug Manufacturers - General": "drugmanufacturersgeneral", "Drug Manufacturers - Specialty & Generic": "drugmanufacturersspecialtygeneric", "Education & Training Services": "educationtrainingservices", "Electrical Equipment & Parts": "electricalequipmentparts", "Electronic Components": "electroniccomponents", "Electronic Gaming & Multimedia": "electronicgamingmultimedia", "Electronics & Computer Distribution": "electronicscomputerdistribution", "Engineering & Construction": "engineeringconstruction", "Entertainment": "entertainment", "Farm & Heavy Construction Machinery": "farmheavyconstructionmachinery", "Farm Products": "farmproducts", "Financial Conglomerates": "financialconglomerates", "Financial Data & Stock Exchanges": "financialdatastockexchanges", "Food Distribution": "fooddistribution", "Footwear & Accessories": "footwearaccessories", "Furnishings, Fixtures & Appliances": "furnishingsfixturesappliances", "Gambling": "gambling", "Gold": "gold", "Grocery Stores": "grocerystores", "Healthcare Plans": "healthcareplans", "Health Information Services": "healthinformationservices", "Home Improvement Retail": "homeimprovementretail", "Household & Personal Products": "householdpersonalproducts", "Industrial Distribution": "industrialdistribution", "Information Technology Services": "informationtechnologyservices", "Infrastructure Operations": "infrastructureoperations", "Insurance Brokers": "insurancebrokers", "Insurance - Diversified": "insurancediversified", "Insurance - Life": "insurancelife", "Insurance - Property & Casualty": "insurancepropertycasualty", "Insurance - Reinsurance": "insurancereinsurance", "Insurance - Specialty": "insurancespecialty", "Integrated Freight & Logistics": "integratedfreightlogistics", "Internet Content & Information": "internetcontentinformation", "Internet Retail": "internetretail", "Leisure": "leisure", "Lodging": "lodging", "Lumber & Wood Production": "lumberwoodproduction", "Luxury Goods": "luxurygoods", "Marine Shipping": "marineshipping", "Medical Care Facilities": "medicalcarefacilities", "Medical Devices": "medicaldevices", "Medical Distribution": "medicaldistribution", "Medical Instruments & Supplies": "medicalinstrumentssupplies", "Metal Fabrication": "metalfabrication", "Mortgage Finance": "mortgagefinance", "Oil & Gas Drilling": "oilgasdrilling", "Oil & Gas E&P": "oilgasep", "Oil & Gas Equipment & Services": "oilgasequipmentservices", "Oil & Gas Integrated": "oilgasintegrated", "Oil & Gas Midstream": "oilgasmidstream", "Oil & Gas Refining & Marketing": "oilgasrefiningmarketing", "Other Industrial Metals & Mining": "otherindustrialmetalsmining", "Other Precious Metals & Mining": "otherpreciousmetalsmining", "Packaged Foods": "packagedfoods", "Packaging & Containers": "packagingcontainers", "Paper & Paper Products": "paperpaperproducts", "Personal Services": "personalservices", "Pharmaceutical Retailers": "pharmaceuticalretailers", "Pollution & Treatment Controls": "pollutiontreatmentcontrols", "Publishing": "publishing", "Railroads": "railroads", "Real Estate - Development": "realestatedevelopment", "Real Estate - Diversified": "realestatediversified", "Real Estate Services": "realestateservices", "Recreational Vehicles": "recreationalvehicles", "REIT - Diversified": "reitdiversified", "REIT - Healthcare Facilities": "reithealthcarefacilities", "REIT - Hotel & Motel": "reithotelmotel", "REIT - Industrial": "reitindustrial", "REIT - Mortgage": "reitmortgage", "REIT - Office": "reitoffice", "REIT - Residential": "reitresidential", "REIT - Retail": "reitretail", "REIT - Specialty": "reitspecialty", "Rental & Leasing Services": "rentalleasingservices", "Residential Construction": "residentialconstruction", "Resorts & Casinos": "resortscasinos", "Restaurants": "restaurants", "Scientific & Technical Instruments": "scientifictechnicalinstruments", "Security & Protection Services": "securityprotectionservices", "Semiconductor Equipment & Materials": "semiconductorequipmentmaterials", "Semiconductors": "semiconductors", "Shell Companies": "shellcompanies", "Silver": "silver", "Software - Application": "softwareapplication", "Software - Infrastructure": "softwareinfrastructure", "Solar": "solar", "Specialty Business Services": "specialtybusinessservices", "Specialty Chemicals": "specialtychemicals", "Specialty Industrial Machinery": "specialtyindustrialmachinery", "Specialty Retail": "specialtyretail", "Staffing & Employment Services": "staffingemploymentservices", "Steel": "steel", "Telecom Services": "telecomservices", "Textile Manufacturing": "textilemanufacturing", "Thermal Coal": "thermalcoal", "Tobacco": "tobacco", "Tools & Accessories": "toolsaccessories", "Travel Services": "travelservices", "Trucking": "trucking", "Uranium": "uranium", "Utilities - Diversified": "utilitiesdiversified", "Utilities - Independent Power Producers": "utilitiesindependentpowerproducers", "Utilities - Regulated Electric": "utilitiesregulatedelectric", "Utilities - Regulated Gas": "utilitiesregulatedgas", "Utilities - Regulated Water": "utilitiesregulatedwater", "Utilities - Renewable": "utilitiesrenewable", "Waste Management": "wastemanagement"}}, "Country": {"prefix": "geo", "option": {"Any": "", "USA": "usa", "Foreign (ex-USA)": "notusa", "Asia": "asia", "Europe": "europe", "Latin America": "latinamerica", "BRIC": "bric", "Argentina": "argentina", "Australia": "australia", "Bahamas": "bahamas", "Belgium": "belgium", "BeNeLux": "benelux", "Bermuda": "bermuda", "Brazil": "brazil", "Canada": "canada", "Cayman Islands": "caymanislands", "Chile": "chile", "China": "china", "China & Hong Kong": "chinahongkong", "Colombia": "colombia", "Cyprus": "cyprus", "Denmark": "denmark", "Finland": "finland", "France": "france", "Germany": "germany", "Greece": "greece", "Hong Kong": "hongkong", "Hungary": "hungary", "Iceland": "iceland", "India": "india", "Indonesia": "indonesia", "Ireland": "ireland", "Israel": "israel", "Italy": "italy", "Japan": "japan", "Kazakhstan": "kazakhstan", "Luxembourg": "luxembourg", "Malaysia": "malaysia", "Malta": "malta", "Mexico": "mexico", "Monaco": "monaco", "Netherlands": "netherlands", "New Zealand": "newzealand", "Norway": "norway", "Panama": "panama", "Peru": "peru", "Philippines": "philippines", "Portugal": "portugal", "Russia": "russia", "Singapore": "singapore", "South Africa": "southafrica", "South Korea": "southkorea", "Spain": "spain", "Sweden": "sweden", "Switzerland": "switzerland", "Taiwan": "taiwan", "Turkey": "turkey", "United Arab Emirates": "unitedarabemirates", "United Kingdom": "unitedkingdom", "Uruguay": "uruguay"}}, "Market Cap.": {"prefix": "cap", "option": {"Any": "", "Mega ($200bln and more)": "mega", "Large ($10bln to $200bln)": "large", "Mid ($2bln to $10bln)": "mid", "Small ($300mln to $2bln)": "small", "Micro ($50mln to $300mln)": "micro", "Nano (under $50mln)": "nano", "+Large (over $10bln)": "largeover", "+Mid (over $2bln)": "midover", "+Small (over $300mln)": "smallover", "+Micro (over $50mln)": "microover", "-Large (under $200bln)": "largeunder", "-Mid (under $10bln)": "midunder", "-Small (under $2bln)": "smallunder", "-Micro (under $300mln)": "microunder"}}, "P/E": {"prefix": "fa_pe", "option": {"Any": "", "Low (<15)": "low", "Profitable (>0)": "profitable", "High (>50)": "high", "Under 5": "u5", "Under 10": "u10", "Under 15": "u15", "Under 20": "u20", "Under 25": "u25", "Under 30": "u30", "Under 35": "u35", "Under 40": "u40", "Under 45": "u45", "Under 50": "u50", "Over 5": "o5", "Over 10": "o10", "Over 15": "o15", "Over 20": "o20", "Over 25": "o25", "Over 30": "o30", "Over 35": "o35", "Over 40": "o40", "Over 45": "o45", "Over 50": "o50"}}, "Forward P/E": {"prefix": "fa_fpe", "option": {"Any": "", "Low (<15)": "low", "Profitable (>0)": "profitable", "High (>50)": "high", "Under 5": "u5", "Under 10": "u10", "Under 15": "u15", "Under 20": "u20", "Under 25": "u25", "Under 30": "u30", "Under 35": "u35", "Under 40": "u40", "Under 45": "u45", "Under 50": "u50", "Over 5": "o5", "Over 10": "o10", "Over 15": "o15", "Over 20": "o20", "Over 25": "o25", "Over 30": "o30", "Over 35": "o35", "Over 40": "o40", "Over 45": "o45", "Over 50": "o50"}}, "PEG": {"prefix": "fa_peg", "option": {"Any": "", "Low (<1)": "low", "High (>2)": "high", "Under 1": "u1", "Under 2": "u2", "Under 3": "u3", "Over 1": "o1", "Over 2": "o2", "Over 3": "o3"}}, "P/S": {"prefix": "fa_ps", "option": {"Any": "", "Low (<1)": "low", "High (>10)": "high", "Under 1": "u1", "Under 2": "u2", "Under 3": "u3", "Under 4": "u4", "Under 5": "u5", "Under 6": "u6", "Under 7": "u7", "Under 8": "u8", "Under 9": "u9", "Under 10": "u10", "Over 1": "o1", "Over 2": "o2", "Over 3": "o3", "Over 4": "o4", "Over 5": "o5", "Over 6": "o6", "Over 7": "o7", "Over 8": "o8", "Over 9": "o9", "Over 10": "o10"}}, "P/B": {"prefix": "fa_pb", "option": {"Any": "", "Low (<1)": "low", "High (>5)": "high", "Under 1": "u1", "Under 2": "u2", "Under 3": "u3", "Under 4": "u4", "Under 5": "u5", "Under 6": "u6", "Under 7": "u7", "Under 8": "u8", "Under 9": "u9", "Under 10": "u10", "Over 1": "o1", "Over 2": "o2", "Over 3": "o3", "Over 4": "o4", "Over 5": "o5", "Over 6": "o6", "Over 7": "o7", "Over 8": "o8", "Over 9": "o9", "Over 10": "o10"}}, "Price/Cash": {"prefix": "fa_pc", "option": {"Any": "", "Low (<3)": "low", "High (>50)": "high", "Under 1": "u1", "Under 2": "u2", "Under 3": "u3", "Under 4": "u4", "Under 5": "u5", "Under 6": "u6", "Under 7": "u7", "Under 8": "u8", "Under 9": "u9", "Under 10": "u10", "Over 1": "o1", "Over 2": "o2", "Over 3": "o3", "Over 4": "o4", "Over 5": "o5", "Over 6": "o6", "Over 7": "o7", "Over 8": "o8", "Over 9": "o9", "Over 10": "o10", "Over 20": "o20", "Over 30": "o30", "Over 40": "o40", "Over 50": "o50"}}, "Price/Free Cash Flow": {"prefix": "fa_pfcf", "option": {"Any": "", "Low (<15)": "low", "High (>50)": "high", "Under 5": "u5", "Under 10": "u10", "Under 15": "u15", "Under 20": "u20", "Under 25": "u25", "Under 30": "u30", "Under 35": "u35", "Under 40": "u40", "Under 45": "u45", "Under 50": "u50", "Under 60": "u60", "Under 70": "u70", "Under 80": "u80", "Under 90": "u90", "Under 100": "u100", "Over 5": "o5", "Over 10": "o10", "Over 15": "o15", "Over 20": "o20", "Over 25": "o25", "Over 30": "o30", "Over 35": "o35", "Over 40": "o40", "Over 45": "o45", "Over 50": "o50", "Over 60": "o60", "Over 70": "o70", "Over 80": "o80", "Over 90": "o90", "Over 100": "o100"}}, "EPS growththis year": {"prefix": "fa_epsyoy", "option": {"Any": "", "Negative (<0%)": "neg", "Positive (>0%)": "pos", "Positive Low (0-10%)": "poslow", "High (>25%)": "high", "Under 5%": "u5", "Under 10%": "u10", "Under 15%": "u15", "Under 20%": "u20", "Under 25%": "u25", "Under 30%": "u30", "Over 5%": "o5", "Over 10%": "o10", "Over 15%": "o15", "Over 20%": "o20", "Over 25%": "o25", "Over 30%": "o30"}}, "EPS growthnext year": {"prefix": "fa_epsyoy1", "option": {"Any": "", "Negative (<0%)": "neg", "Positive (>0%)": "pos", "Positive Low (0-10%)": "poslow", "High (>25%)": "high", "Under 5%": "u5", "Under 10%": "u10", "Under 15%": "u15", "Under 20%": "u20", "Under 25%": "u25", "Under 30%": "u30", "Over 5%": "o5", "Over 10%": "o10", "Over 15%": "o15", "Over 20%": "o20", "Over 25%": "o25", "Over 30%": "o30"}}, "EPS growthpast 5 years": {"prefix": "fa_eps5years", "option": {"Any": "", "Negative (<0%)": "neg", "Positive (>0%)": "pos", "Positive Low (0-10%)": "poslow", "High (>25%)": "high", "Under 5%": "u5", "Under 10%": "u10", "Under 15%": "u15", "Under 20%": "u20", "Under 25%": "u25", "Under 30%": "u30", "Over 5%": "o5", "Over 10%": "o10", "Over 15%": "o15", "Over 20%": "o20", "Over 25%": "o25", "Over 30%": "o30"}}, "EPS growthnext 5 years": {"prefix": "fa_estltgrowth", "option": {"Any": "", "Negative (<0%)": "neg", "Positive (>0%)": "pos", "Positive Low (<10%)": "poslow", "High (>25%)": "high", "Under 5%": "u5", "Under 10%": "u10", "Under 15%": "u15", "Under 20%": "u20", "Under 25%": "u25", "Under 30%": "u30", "Over 5%": "o5", "Over 10%": "o10", "Over 15%": "o15", "Over 20%": "o20", "Over 25%": "o25", "Over 30%": "o30"}}, "Sales growthpast 5 years": {"prefix": "fa_sales5years", "option": {"Any": "", "Negative (<0%)": "neg", "Positive (>0%)": "pos", "Positive Low (0-10%)": "poslow", "High (>25%)": "high", "Under 5%": "u5", "Under 10%": "u10", "Under 15%": "u15", "Under 20%": "u20", "Under 25%": "u25", "Under 30%": "u30", "Over 5%": "o5", "Over 10%": "o10", "Over 15%": "o15", "Over 20%": "o20", "Over 25%": "o25", "Over 30%": "o30"}}, "EPS growthqtr over qtr": {"prefix": "fa_epsqoq", "option": {"Any": "", "Negative (<0%)": "neg", "Positive (>0%)": "pos", "Positive Low (0-10%)": "poslow", "High (>25%)": "high", "Under 5%": "u5", "Under 10%": "u10", "Under 15%": "u15", "Under 20%": "u20", "Under 25%": "u25", "Under 30%": "u30", "Over 5%": "o5", "Over 10%": "o10", "Over 15%": "o15", "Over 20%": "o20", "Over 25%": "o25", "Over 30%": "o30"}}, "Sales growthqtr over qtr": {"prefix": "fa_salesqoq", "option": {"Any": "", "Negative (<0%)": "neg", "Positive (>0%)": "pos", "Positive Low (0-10%)": "poslow", "High (>25%)": "high", "Under 5%": "u5", "Under 10%": "u10", "Under 15%": "u15", "Under 20%": "u20", "Under 25%": "u25", "Under 30%": "u30", "Over 5%": "o5", "Over 10%": "o10", "Over 15%": "o15", "Over 20%": "o20", "Over 25%": "o25", "Over 30%": "o30"}}, "Dividend Yield": {"prefix": "fa_div", "option": {"Any": "", "None (0%)": "none", "Positive (>0%)": "pos", "High (>5%)": "high", "Very High (>10%)": "veryhigh", "Over 1%": "o1", "Over 2%": "o2", "Over 3%": "o3", "Over 4%": "o4", "Over 5%": "o5", "Over 6%": "o6", "Over 7%": "o7", "Over 8%": "o8", "Over 9%": "o9", "Over 10%": "o10"}}, "Return on Assets": {"prefix": "fa_roa", "option": {"Any": "", "Positive (>0%)": "pos", "Negative (<0%)": "neg", "Very Positive (>15%)": "verypos", "Very Negative (": "veryneg", "Under -50%": "u-50", "Under -45%": "u-45", "Under -40%": "u-40", "Under -35%": "u-35", "Under -30%": "u-30", "Under -25%": "u-25", "Under -20%": "u-20", "Under -15%": "u-15", "Under -10%": "u-10", "Under -5%": "u-5", "Over +5%": "o5", "Over +10%": "o10", "Over +15%": "o15", "Over +20%": "o20", "Over +25%": "o25", "Over +30%": "o30", "Over +35%": "o35", "Over +40%": "o40", "Over +45%": "o45", "Over +50%": "o50"}}, "Return on Equity": {"prefix": "fa_roe", "option": {"Any": "", "Positive (>0%)": "pos", "Negative (<0%)": "neg", "Very Positive (>30%)": "verypos", "Very Negative (": "veryneg", "Under -50%": "u-50", "Under -45%": "u-45", "Under -40%": "u-40", "Under -35%": "u-35", "Under -30%": "u-30", "Under -25%": "u-25", "Under -20%": "u-20", "Under -15%": "u-15", "Under -10%": "u-10", "Under -5%": "u-5", "Over +5%": "o5", "Over +10%": "o10", "Over +15%": "o15", "Over +20%": "o20", "Over +25%": "o25", "Over +30%": "o30", "Over +35%": "o35", "Over +40%": "o40", "Over +45%": "o45", "Over +50%": "o50"}}, "Return on Investment": {"prefix": "fa_roi", "option": {"Any": "", "Positive (>0%)": "pos", "Negative (<0%)": "neg", "Very Positive (>25%)": "verypos", "Very Negative (": "veryneg", "Under -50%": "u-50", "Under -45%": "u-45", "Under -40%": "u-40", "Under -35%": "u-35", "Under -30%": "u-30", "Under -25%": "u-25", "Under -20%": "u-20", "Under -15%": "u-15", "Under -10%": "u-10", "Under -5%": "u-5", "Over +5%": "o5", "Over +10%": "o10", "Over +15%": "o15", "Over +20%": "o20", "Over +25%": "o25", "Over +30%": "o30", "Over +35%": "o35", "Over +40%": "o40", "Over +45%": "o45", "Over +50%": "o50"}}, "Current Ratio": {"prefix": "fa_curratio", "option": {"Any": "", "High (>3)": "high", "Low (<1)": "low", "Under 1": "u1", "Under 0.5": "u0.5", "Over 0.5": "o0.5", "Over 1": "o1", "Over 1.5": "o1.5", "Over 2": "o2", "Over 3": "o3", "Over 4": "o4", "Over 5": "o5", "Over 10": "o10"}}, "Quick Ratio": {"prefix": "fa_quickratio", "option": {"Any": "", "High (>3)": "high", "Low (<0.5)": "low", "Under 1": "u1", "Under 0.5": "u0.5", "Over 0.5": "o0.5", "Over 1": "o1", "Over 1.5": "o1.5", "Over 2": "o2", "Over 3": "o3", "Over 4": "o4", "Over 5": "o5", "Over 10": "o10"}}, "LT Debt/Equity": {"prefix": "fa_ltdebteq", "option": {"Any": "", "High (>0.5)": "high", "Low (<0.1)": "low", "Under 1": "u1", "Under 0.9": "u0.9", "Under 0.8": "u0.8", "Under 0.7": "u0.7", "Under 0.6": "u0.6", "Under 0.5": "u0.5", "Under 0.4": "u0.4", "Under 0.3": "u0.3", "Under 0.2": "u0.2", "Under 0.1": "u0.1", "Over 0.1": "o0.1", "Over 0.2": "o0.2", "Over 0.3": "o0.3", "Over 0.4": "o0.4", "Over 0.5": "o0.5", "Over 0.6": "o0.6", "Over 0.7": "o0.7", "Over 0.8": "o0.8", "Over 0.9": "o0.9", "Over 1": "o1"}}, "Debt/Equity": {"prefix": "fa_debteq", "option": {"Any": "", "High (>0.5)": "high", "Low (<0.1)": "low", "Under 1": "u1", "Under 0.9": "u0.9", "Under 0.8": "u0.8", "Under 0.7": "u0.7", "Under 0.6": "u0.6", "Under 0.5": "u0.5", "Under 0.4": "u0.4", "Under 0.3": "u0.3", "Under 0.2": "u0.2", "Under 0.1": "u0.1", "Over 0.1": "o0.1", "Over 0.2": "o0.2", "Over 0.3": "o0.3", "Over 0.4": "o0.4", "Over 0.5": "o0.5", "Over 0.6": "o0.6", "Over 0.7": "o0.7", "Over 0.8": "o0.8", "Over 0.9": "o0.9", "Over 1": "o1"}}, "Gross Margin": {"prefix": "fa_grossmargin", "option": {"Any": "", "Positive (>0%)": "pos", "Negative (<0%)": "neg", "High (>50%)": "high", "Under 90%": "u90", "Under 80%": "u80", "Under 70%": "u70", "Under 60%": "u60", "Under 50%": "u50", "Under 45%": "u45", "Under 40%": "u40", "Under 35%": "u35", "Under 30%": "u30", "Under 25%": "u25", "Under 20%": "u20", "Under 15%": "u15", "Under 10%": "u10", "Under 5%": "u5", "Under 0%": "u0", "Under -10%": "u-10", "Under -20%": "u-20", "Under -30%": "u-30", "Under -50%": "u-50", "Under -70%": "u-70", "Under -100%": "u-100", "Over 0%": "o0", "Over 5%": "o5", "Over 10%": "o10", "Over 15%": "o15", "Over 20%": "o20", "Over 25%": "o25", "Over 30%": "o30", "Over 35%": "o35", "Over 40%": "o40", "Over 45%": "o45", "Over 50%": "o50", "Over 60%": "o60", "Over 70%": "o70", "Over 80%": "o80", "Over 90%": "o90"}}, "Operating Margin": {"prefix": "fa_opermargin", "option": {"Any": "", "Positive (>0%)": "pos", "Negative (<0%)": "neg", "Very Negative (": "veryneg", "High (>25%)": "high", "Under 90%": "u90", "Under 80%": "u80", "Under 70%": "u70", "Under 60%": "u60", "Under 50%": "u50", "Under 45%": "u45", "Under 40%": "u40", "Under 35%": "u35", "Under 30%": "u30", "Under 25%": "u25", "Under 20%": "u20", "Under 15%": "u15", "Under 10%": "u10", "Under 5%": "u5", "Under 0%": "u0", "Under -10%": "u-10", "Under -20%": "u-20", "Under -30%": "u-30", "Under -50%": "u-50", "Under -70%": "u-70", "Under -100%": "u-100", "Over 0%": "o0", "Over 5%": "o5", "Over 10%": "o10", "Over 15%": "o15", "Over 20%": "o20", "Over 25%": "o25", "Over 30%": "o30", "Over 35%": "o35", "Over 40%": "o40", "Over 45%": "o45", "Over 50%": "o50", "Over 60%": "o60", "Over 70%": "o70", "Over 80%": "o80", "Over 90%": "o90"}}, "Net Profit Margin": {"prefix": "fa_netmargin", "option": {"Any": "", "Positive (>0%)": "pos", "Negative (<0%)": "neg", "Very Negative (": "veryneg", "High (>20%)": "high", "Under 90%": "u90", "Under 80%": "u80", "Under 70%": "u70", "Under 60%": "u60", "Under 50%": "u50", "Under 45%": "u45", "Under 40%": "u40", "Under 35%": "u35", "Under 30%": "u30", "Under 25%": "u25", "Under 20%": "u20", "Under 15%": "u15", "Under 10%": "u10", "Under 5%": "u5", "Under 0%": "u0", "Under -10%": "u-10", "Under -20%": "u-20", "Under -30%": "u-30", "Under -50%": "u-50", "Under -70%": "u-70", "Under -100%": "u-100", "Over 0%": "o0", "Over 5%": "o5", "Over 10%": "o10", "Over 15%": "o15", "Over 20%": "o20", "Over 25%": "o25", "Over 30%": "o30", "Over 35%": "o35", "Over 40%": "o40", "Over 45%": "o45", "Over 50%": "o50", "Over 60%": "o60", "Over 70%": "o70", "Over 80%": "o80", "Over 90%": "o90"}}, "Payout Ratio": {"prefix": "fa_payoutratio", "option": {"Any": "", "None (0%)": "none", "Positive (>0%)": "pos", "Low (<20%)": "low", "High (>50%)": "high", "Over 0%": "o0", "Over 10%": "o10", "Over 20%": "o20", "Over 30%": "o30", "Over 40%": "o40", "Over 50%": "o50", "Over 60%": "o60", "Over 70%": "o70", "Over 80%": "o80", "Over 90%": "o90", "Over 100%": "o100", "Under 10%": "u10", "Under 20%": "u20", "Under 30%": "u30", "Under 40%": "u40", "Under 50%": "u50", "Under 60%": "u60", "Under 70%": "u70", "Under 80%": "u80", "Under 90%": "u90", "Under 100%": "u100"}}, "InsiderOwnership": {"prefix": "sh_insiderown", "option": {"Any": "", "Low (<5%)": "low", "High (>30%)": "high", "Very High (>50%)": "veryhigh", "Over 10%": "o10", "Over 20%": "o20", "Over 30%": "o30", "Over 40%": "o40", "Over 50%": "o50", "Over 60%": "o60", "Over 70%": "o70", "Over 80%": "o80", "Over 90%": "o90"}}, "InsiderTransactions": {"prefix": "sh_insidertrans", "option": {"Any": "", "Very Negative (<20%)": "veryneg", "Negative (<0%)": "neg", "Positive (>0%)": "pos", "Very Positive (>20%)": "verypos", "Under -90%": "u-90", "Under -80%": "u-80", "Under -70%": "u-70", "Under -60%": "u-60", "Under -50%": "u-50", "Under -45%": "u-45", "Under -40%": "u-40", "Under -35%": "u-35", "Under -30%": "u-30", "Under -25%": "u-25", "Under -20%": "u-20", "Under -15%": "u-15", "Under -10%": "u-10", "Under -5%": "u-5", "Over +5%": "o5", "Over +10%": "o10", "Over +15%": "o15", "Over +20%": "o20", "Over +25%": "o25", "Over +30%": "o30", "Over +35%": "o35", "Over +40%": "o40", "Over +45%": "o45", "Over +50%": "o50", "Over +60%": "o60", "Over +70%": "o70", "Over +80%": "o80", "Over +90%": "o90"}}, "InstitutionalOwnership": {"prefix": "sh_instown", "option": {"Any": "", "Low (<5%)": "low", "High (>90%)": "high", "Under 90%": "u90", "Under 80%": "u80", "Under 70%": "u70", "Under 60%": "u60", "Under 50%": "u50", "Under 40%": "u40", "Under 30%": "u30", "Under 20%": "u20", "Under 10%": "u10", "Over 10%": "o10", "Over 20%": "o20", "Over 30%": "o30", "Over 40%": "o40", "Over 50%": "o50", "Over 60%": "o60", "Over 70%": "o70", "Over 80%": "o80", "Over 90%": "o90"}}, "InstitutionalTransactions": {"prefix": "sh_insttrans", "option": {"Any": "", "Very Negative (<20%)": "veryneg", "Negative (<0%)": "neg", "Positive (>0%)": "pos", "Very Positive (>20%)": "verypos", "Under -50%": "u-50", "Under -45%": "u-45", "Under -40%": "u-40", "Under -35%": "u-35", "Under -30%": "u-30", "Under -25%": "u-25", "Under -20%": "u-20", "Under -15%": "u-15", "Under -10%": "u-10", "Under -5%": "u-5", "Over +5%": "o5", "Over +10%": "o10", "Over +15%": "o15", "Over +20%": "o20", "Over +25%": "o25", "Over +30%": "o30", "Over +35%": "o35", "Over +40%": "o40", "Over +45%": "o45", "Over +50%": "o50"}}, "Float Short": {"prefix": "sh_short", "option": {"Any": "", "Low (<5%)": "low", "High (>20%)": "high", "Under 5%": "u5", "Under 10%": "u10", "Under 15%": "u15", "Under 20%": "u20", "Under 25%": "u25", "Under 30%": "u30", "Over 5%": "o5", "Over 10%": "o10", "Over 15%": "o15", "Over 20%": "o20", "Over 25%": "o25", "Over 30%": "o30"}}, "Analyst Recom.": {"prefix": "an_recom", "option": {"Any": "", "Strong Buy (1)": "strongbuy", "Buy or better": "buybetter", "Buy": "buy", "Hold or better": "holdbetter", "Hold": "hold", "Hold or worse": "holdworse", "Sell": "sell", "Sell or worse": "sellworse", "Strong Sell (5)": "strongsell"}}, "Option/Short": {"prefix": "sh_opt", "option": {"Any": "", "Optionable": "option", "Shortable": "short", "Optionable and shortable": "optionshort"}}, "Earnings Date": {"prefix": "earningsdate", "option": {"Any": "", "Today": "today", "Today Before Market Open": "todaybefore", "Today After Market Close": "todayafter", "Tomorrow": "tomorrow", "Tomorrow Before Market Open": "tomorrowbefore", "Tomorrow After Market Close": "tomorrowafter", "Yesterday": "yesterday", "Yesterday Before Market Open": "yesterdaybefore", "Yesterday After Market Close": "yesterdayafter", "Next 5 Days": "nextdays5", "Previous 5 Days": "prevdays5", "This Week": "thisweek", "Next Week": "nextweek", "Previous Week": "prevweek", "This Month": "thismonth"}}, "Performance": {"prefix": "ta_perf", "option": {"Any": "", "Today Up": "dup", "Today Down": "ddown", "Today -15%": "d15u", "Today -10%": "d10u", "Today -5%": "d5u", "Today +5%": "d5o", "Today +10%": "d10o", "Today +15%": "d15o", "Week -30%": "1w30u", "Week -20%": "1w20u", "Week -10%": "1w10u", "Week Down": "1wdown", "Week Up": "1wup", "Week +10%": "1w10o", "Week +20%": "1w20o", "Week +30%": "1w30o", "Month -50%": "4w50u", "Month -30%": "4w30u", "Month -20%": "4w20u", "Month -10%": "4w10u", "Month Down": "4wdown", "Month Up": "4wup", "Month +10%": "4w10o", "Month +20%": "4w20o", "Month +30%": "4w30o", "Month +50%": "4w50o", "Quarter -50%": "13w50u", "Quarter -30%": "13w30u", "Quarter -20%": "13w20u", "Quarter -10%": "13w10u", "Quarter Down": "13wdown", "Quarter Up": "13wup", "Quarter +10%": "13w10o", "Quarter +20%": "13w20o", "Quarter +30%": "13w30o", "Quarter +50%": "13w50o", "Half -75%": "26w75u", "Half -50%": "26w50u", "Half -30%": "26w30u", "Half -20%": "26w20u", "Half -10%": "26w10u", "Half Down": "26wdown", "Half Up": "26wup", "Half +10%": "26w10o", "Half +20%": "26w20o", "Half +30%": "26w30o", "Half +50%": "26w50o", "Half +100%": "26w100o", "Year -75%": "52w75u", "Year -50%": "52w50u", "Year -30%": "52w30u", "Year -20%": "52w20u", "Year -10%": "52w10u", "Year Down": "52wdown", "Year Up": "52wup", "Year +10%": "52w10o", "Year +20%": "52w20o", "Year +30%": "52w30o", "Year +50%": "52w50o", "Year +100%": "52w100o", "Year +200%": "52w200o", "Year +300%": "52w300o", "Year +500%": "52w500o", "YTD -75%": "ytd75u", "YTD -50%": "ytd50u", "YTD -30%": "ytd30u", "YTD -20%": "ytd20u", "YTD -10%": "ytd10u", "YTD -5%": "ytd5u", "YTD Down": "ytddown", "YTD Up": "ytdup", "YTD +5%": "ytd5o", "YTD +10%": "ytd10o", "YTD +20%": "ytd20o", "YTD +30%": "ytd30o", "YTD +50%": "ytd50o", "YTD +100%": "ytd100o"}}, "Performance 2": {"prefix": "ta_perf2", "option": {"Any": "", "Today Up": "dup", "Today Down": "ddown", "Today -15%": "d15u", "Today -10%": "d10u", "Today -5%": "d5u", "Today +5%": "d5o", "Today +10%": "d10o", "Today +15%": "d15o", "Week -30%": "1w30u", "Week -20%": "1w20u", "Week -10%": "1w10u", "Week Down": "1wdown", "Week Up": "1wup", "Week +10%": "1w10o", "Week +20%": "1w20o", "Week +30%": "1w30o", "Month -50%": "4w50u", "Month -30%": "4w30u", "Month -20%": "4w20u", "Month -10%": "4w10u", "Month Down": "4wdown", "Month Up": "4wup", "Month +10%": "4w10o", "Month +20%": "4w20o", "Month +30%": "4w30o", "Month +50%": "4w50o", "Quarter -50%": "13w50u", "Quarter -30%": "13w30u", "Quarter -20%": "13w20u", "Quarter -10%": "13w10u", "Quarter Down": "13wdown", "Quarter Up": "13wup", "Quarter +10%": "13w10o", "Quarter +20%": "13w20o", "Quarter +30%": "13w30o", "Quarter +50%": "13w50o", "Half -75%": "26w75u", "Half -50%": "26w50u", "Half -30%": "26w30u", "Half -20%": "26w20u", "Half -10%": "26w10u", "Half Down": "26wdown", "Half Up": "26wup", "Half +10%": "26w10o", "Half +20%": "26w20o", "Half +30%": "26w30o", "Half +50%": "26w50o", "Half +100%": "26w100o", "Year -75%": "52w75u", "Year -50%": "52w50u", "Year -30%": "52w30u", "Year -20%": "52w20u", "Year -10%": "52w10u", "Year Down": "52wdown", "Year Up": "52wup", "Year +10%": "52w10o", "Year +20%": "52w20o", "Year +30%": "52w30o", "Year +50%": "52w50o", "Year +100%": "52w100o", "Year +200%": "52w200o", "Year +300%": "52w300o", "Year +500%": "52w500o", "YTD -75%": "ytd75u", "YTD -50%": "ytd50u", "YTD -30%": "ytd30u", "YTD -20%": "ytd20u", "YTD -10%": "ytd10u", "YTD -5%": "ytd5u", "YTD Down": "ytddown", "YTD Up": "ytdup", "YTD +5%": "ytd5o", "YTD +10%": "ytd10o", "YTD +20%": "ytd20o", "YTD +30%": "ytd30o", "YTD +50%": "ytd50o", "YTD +100%": "ytd100o"}}, "Volatility": {"prefix": "ta_volatility", "option": {"Any": "", "Week - Over 3%": "wo3", "Week - Over 4%": "wo4", "Week - Over 5%": "wo5", "Week - Over 6%": "wo6", "Week - Over 7%": "wo7", "Week - Over 8%": "wo8", "Week - Over 9%": "wo9", "Week - Over 10%": "wo10", "Week - Over 12%": "wo12", "Week - Over 15%": "wo15", "Month - Over 2%": "mo2", "Month - Over 3%": "mo3", "Month - Over 4%": "mo4", "Month - Over 5%": "mo5", "Month - Over 6%": "mo6", "Month - Over 7%": "mo7", "Month - Over 8%": "mo8", "Month - Over 9%": "mo9", "Month - Over 10%": "mo10", "Month - Over 12%": "mo12", "Month - Over 15%": "mo15"}}, "RSI (14)": {"prefix": "ta_rsi", "option": {"Any": "", "Overbought (90)": "ob90", "Overbought (80)": "ob80", "Overbought (70)": "ob70", "Overbought (60)": "ob60", "Oversold (40)": "os40", "Oversold (30)": "os30", "Oversold (20)": "os20", "Oversold (10)": "os10", "Not Overbought (<60)": "nob60", "Not Overbought (<50)": "nob50", "Not Oversold (>50)": "nos50", "Not Oversold (>40)": "nos40"}}, "Gap": {"prefix": "ta_gap", "option": {"Any": "", "Up": "u", "Up 0%": "u0", "Up 1%": "u1", "Up 2%": "u2", "Up 3%": "u3", "Up 4%": "u4", "Up 5%": "u5", "Up 6%": "u6", "Up 7%": "u7", "Up 8%": "u8", "Up 9%": "u9", "Up 10%": "u10", "Up 15%": "u15", "Up 20%": "u20", "Down": "d", "Down 0%": "d0", "Down 1%": "d1", "Down 2%": "d2", "Down 3%": "d3", "Down 4%": "d4", "Down 5%": "d5", "Down 6%": "d6", "Down 7%": "d7", "Down 8%": "d8", "Down 9%": "d9", "Down 10%": "d10", "Down 15%": "d15", "Down 20%": "d20"}}, "20-Day Simple Moving Average": {"prefix": "ta_sma20", "option": {"Any": "", "Price below SMA20": "pb", "Price 10% below SMA20": "pb10", "Price 20% below SMA20": "pb20", "Price 30% below SMA20": "pb30", "Price 40% below SMA20": "pb40", "Price 50% below SMA20": "pb50", "Price above SMA20": "pa", "Price 10% above SMA20": "pa10", "Price 20% above SMA20": "pa20", "Price 30% above SMA20": "pa30", "Price 40% above SMA20": "pa40", "Price 50% above SMA20": "pa50", "Price crossed SMA20": "pc", "Price crossed SMA20 above": "pca", "Price crossed SMA20 below": "pcb", "SMA20 crossed SMA50": "cross50", "SMA20 crossed SMA50 above": "cross50a", "SMA20 crossed SMA50 below": "cross50b", "SMA20 crossed SMA200": "cross200", "SMA20 crossed SMA200 above": "cross200a", "SMA20 crossed SMA200 below": "cross200b", "SMA20 above SMA50": "sa50", "SMA20 below SMA50": "sb50", "SMA20 above SMA200": "sa200", "SMA20 below SMA200": "sb200"}}, "50-Day Simple Moving Average": {"prefix": "ta_sma50", "option": {"Any": "", "Price below SMA50": "pb", "Price 10% below SMA50": "pb10", "Price 20% below SMA50": "pb20", "Price 30% below SMA50": "pb30", "Price 40% below SMA50": "pb40", "Price 50% below SMA50": "pb50", "Price above SMA50": "pa", "Price 10% above SMA50": "pa10", "Price 20% above SMA50": "pa20", "Price 30% above SMA50": "pa30", "Price 40% above SMA50": "pa40", "Price 50% above SMA50": "pa50", "Price crossed SMA50": "pc", "Price crossed SMA50 above": "pca", "Price crossed SMA50 below": "pcb", "SMA50 crossed SMA20": "cross20", "SMA50 crossed SMA20 above": "cross20a", "SMA50 crossed SMA20 below": "cross20b", "SMA50 crossed SMA200": "cross200", "SMA50 crossed SMA200 above": "cross200a", "SMA50 crossed SMA200 below": "cross200b", "SMA50 above SMA20": "sa20", "SMA50 below SMA20": "sb20", "SMA50 above SMA200": "sa200", "SMA50 below SMA200": "sb200"}}, "200-Day Simple Moving Average": {"prefix": "ta_sma200", "option": {"Any": "", "Price below SMA200": "pb", "Price 10% below SMA200": "pb10", "Price 20% below SMA200": "pb20", "Price 30% below SMA200": "pb30", "Price 40% below SMA200": "pb40", "Price 50% below SMA200": "pb50", "Price 60% below SMA200": "pb60", "Price 70% below SMA200": "pb70", "Price 80% below SMA200": "pb80", "Price 90% below SMA200": "pb90", "Price above SMA200": "pa", "Price 10% above SMA200": "pa10", "Price 20% above SMA200": "pa20", "Price 30% above SMA200": "pa30", "Price 40% above SMA200": "pa40", "Price 50% above SMA200": "pa50", "Price 60% above SMA200": "pa60", "Price 70% above SMA200": "pa70", "Price 80% above SMA200": "pa80", "Price 90% above SMA200": "pa90", "Price 100% above SMA200": "pa100", "Price crossed SMA200": "pc", "Price crossed SMA200 above": "pca", "Price crossed SMA200 below": "pcb", "SMA200 crossed SMA20": "cross20", "SMA200 crossed SMA20 above": "cross20a", "SMA200 crossed SMA20 below": "cross20b", "SMA200 crossed SMA50": "cross50", "SMA200 crossed SMA50 above": "cross50a", "SMA200 crossed SMA50 below": "cross50b", "SMA200 above SMA20": "sa20", "SMA200 below SMA20": "sb20", "SMA200 above SMA50": "sa50", "SMA200 below SMA50": "sb50"}}, "Change": {"prefix": "ta_change", "option": {"Any": "", "Up": "u", "Up 1%": "u1", "Up 2%": "u2", "Up 3%": "u3", "Up 4%": "u4", "Up 5%": "u5", "Up 6%": "u6", "Up 7%": "u7", "Up 8%": "u8", "Up 9%": "u9", "Up 10%": "u10", "Up 15%": "u15", "Up 20%": "u20", "Down": "d", "Down 1%": "d1", "Down 2%": "d2", "Down 3%": "d3", "Down 4%": "d4", "Down 5%": "d5", "Down 6%": "d6", "Down 7%": "d7", "Down 8%": "d8", "Down 9%": "d9", "Down 10%": "d10", "Down 15%": "d15", "Down 20%": "d20"}}, "Change from Open": {"prefix": "ta_changeopen", "option": {"Any": "", "Up": "u", "Up 1%": "u1", "Up 2%": "u2", "Up 3%": "u3", "Up 4%": "u4", "Up 5%": "u5", "Up 6%": "u6", "Up 7%": "u7", "Up 8%": "u8", "Up 9%": "u9", "Up 10%": "u10", "Up 15%": "u15", "Up 20%": "u20", "Down": "d", "Down 1%": "d1", "Down 2%": "d2", "Down 3%": "d3", "Down 4%": "d4", "Down 5%": "d5", "Down 6%": "d6", "Down 7%": "d7", "Down 8%": "d8", "Down 9%": "d9", "Down 10%": "d10", "Down 15%": "d15", "Down 20%": "d20"}}, "20-Day High/Low": {"prefix": "ta_highlow20d", "option": {"Any": "", "New High": "nh", "New Low": "nl", "5% or more below High": "b5h", "10% or more below High": "b10h", "15% or more below High": "b15h", "20% or more below High": "b20h", "30% or more below High": "b30h", "40% or more below High": "b40h", "50% or more below High": "b50h", "0-3% below High": "b0to3h", "0-5% below High": "b0to5h", "0-10% below High": "b0to10h", "5% or more above Low": "a5h", "10% or more above Low": "a10h", "15% or more above Low": "a15h", "20% or more above Low": "a20h", "30% or more above Low": "a30h", "40% or more above Low": "a40h", "50% or more above Low": "a50h", "0-3% above Low": "a0to3h", "0-5% above Low": "a0to5h", "0-10% above Low": "a0to10h"}}, "50-Day High/Low": {"prefix": "ta_highlow50d", "option": {"Any": "", "New High": "nh", "New Low": "nl", "5% or more below High": "b5h", "10% or more below High": "b10h", "15% or more below High": "b15h", "20% or more below High": "b20h", "30% or more below High": "b30h", "40% or more below High": "b40h", "50% or more below High": "b50h", "0-3% below High": "b0to3h", "0-5% below High": "b0to5h", "0-10% below High": "b0to10h", "5% or more above Low": "a5h", "10% or more above Low": "a10h", "15% or more above Low": "a15h", "20% or more above Low": "a20h", "30% or more above Low": "a30h", "40% or more above Low": "a40h", "50% or more above Low": "a50h", "0-3% above Low": "a0to3h", "0-5% above Low": "a0to5h", "0-10% above Low": "a0to10h"}}, "52-Week High/Low": {"prefix": "ta_highlow52w", "option": {"Any": "", "New High": "nh", "New Low": "nl", "5% or more below High": "b5h", "10% or more below High": "b10h", "15% or more below High": "b15h", "20% or more below High": "b20h", "30% or more below High": "b30h", "40% or more below High": "b40h", "50% or more below High": "b50h", "60% or more below High": "b60h", "70% or more below High": "b70h", "80% or more below High": "b80h", "90% or more below High": "b90h", "0-3% below High": "b0to3h", "0-5% below High": "b0to5h", "0-10% below High": "b0to10h", "5% or more above Low": "a5h", "10% or more above Low": "a10h", "15% or more above Low": "a15h", "20% or more above Low": "a20h", "30% or more above Low": "a30h", "40% or more above Low": "a40h", "50% or more above Low": "a50h", "60% or more above Low": "a60h", "70% or more above Low": "a70h", "80% or more above Low": "a80h", "90% or more above Low": "a90h", "100% or more above Low": "a100h", "120% or more above Low": "a120h", "150% or more above Low": "a150h", "200% or more above Low": "a200h", "300% or more above Low": "a300h", "500% or more above Low": "a500h", "0-3% above Low": "a0to3h", "0-5% above Low": "a0to5h", "0-10% above Low": "a0to10h"}}, "Pattern": {"prefix": "ta_pattern", "option": {"Any": "", "Horizontal S/R": "horizontal", "Horizontal S/R (Strong)": "horizontal2", "TL Resistance": "tlresistance", "TL Resistance (Strong)": "tlresistance2", "TL Support": "tlsupport", "TL Support (Strong)": "tlsupport2", "Wedge Up": "wedgeup", "Wedge Up (Strong)": "wedgeup2", "Wedge Down": "wedgedown", "Wedge Down (Strong)": "wedgedown2", "Triangle Ascending": "wedgeresistance", "Triangle Ascending (Strong)": "wedgeresistance2", "Triangle Descending": "wedgesupport", "Triangle Descending (Strong)": "wedgesupport2", "Wedge": "wedge", "Wedge (Strong)": "wedge2", "Channel Up": "channelup", "Channel Up (Strong)": "channelup2", "Channel Down": "channeldown", "Channel Down (Strong)": "channeldown2", "Channel": "channel", "Channel (Strong)": "channel2", "Double Top": "doubletop", "Double Bottom": "doublebottom", "Multiple Top": "multipletop", "Multiple Bottom": "multiplebottom", "Head & Shoulders": "headandshoulders", "Head & Shoulders Inverse": "headandshouldersinv"}}, "Candlestick": {"prefix": "ta_candlestick", "option": {"Any": "", "Long Lower Shadow": "lls", "Long Upper Shadow": "lus", "Hammer": "h", "Inverted Hammer": "ih", "Spinning Top White": "stw", "Spinning Top Black": "stb", "Doji": "d", "Dragonfly Doji": "dd", "Gravestone Doji": "gd", "Marubozu White": "mw", "Marubozu Black": "mb"}}, "Beta": {"prefix": "ta_beta", "option": {"Any": "", "Under 0": "u0", "Under 0.5": "u0.5", "Under 1": "u1", "Under 1.5": "u1.5", "Under 2": "u2", "Over 0": "o0", "Over 0.5": "o0.5", "Over 1": "o1", "Over 1.5": "o1.5", "Over 2": "o2", "Over 2.5": "o2.5", "Over 3": "o3", "Over 4": "o4", "0 to 0.5": "0to0.5", "0 to 1": "0to1", "0.5 to 1": "0.5to1", "0.5 to 1.5": "0.5to1.5", "1 to 1.5": "1to1.5", "1 to 2": "1to2"}}, "Average True Range": {"prefix": "ta_averagetruerange", "option": {"Any": "", "Over 0.25": "o0.25", "Over 0.5": "o0.5", "Over 0.75": "o0.75", "Over 1": "o1", "Over 1.5": "o1.5", "Over 2": "o2", "Over 2.5": "o2.5", "Over 3": "o3", "Over 3.5": "o3.5", "Over 4": "o4", "Over 4.5": "o4.5", "Over 5": "o5", "Under 0.25": "u0.25", "Under 0.5": "u0.5", "Under 0.75": "u0.75", "Under 1": "u1", "Under 1.5": "u1.5", "Under 2": "u2", "Under 2.5": "u2.5", "Under 3": "u3", "Under 3.5": "u3.5", "Under 4": "u4", "Under 4.5": "u4.5", "Under 5": "u5"}}, "Average Volume": {"prefix": "sh_avgvol", "option": {"Any": "", "Under 50K": "u50", "Under 100K": "u100", "Under 500K": "u500", "Under 750K": "u750", "Under 1M": "u1000", "Over 50K": "o50", "Over 100K": "o100", "Over 200K": "o200", "Over 300K": "o300", "Over 400K": "o400", "Over 500K": "o500", "Over 750K": "o750", "Over 1M": "o1000", "Over 2M": "o2000", "100K to 500K": "100to500", "100K to 1M": "100to1000", "500K to 1M": "500to1000", "500K to 10M": "500to10000"}}, "Relative Volume": {"prefix": "sh_relvol", "option": {"Any": "", "Over 10": "o10", "Over 5": "o5", "Over 3": "o3", "Over 2": "o2", "Over 1.5": "o1.5", "Over 1": "o1", "Over 0.75": "o0.75", "Over 0.5": "o0.5", "Over 0.25": "o0.25", "Under 2": "u2", "Under 1.5": "u1.5", "Under 1": "u1", "Under 0.75": "u0.75", "Under 0.5": "u0.5", "Under 0.25": "u0.25", "Under 0.1": "u0.1"}}, "Current Volume": {"prefix": "sh_curvol", "option": {"Any": "", "Under 50K": "u50", "Under 100K": "u100", "Under 500K": "u500", "Under 750K": "u750", "Under 1M": "u1000", "Over 0": "o0", "Over 50K": "o50", "Over 100K": "o100", "Over 200K": "o200", "Over 300K": "o300", "Over 400K": "o400", "Over 500K": "o500", "Over 750K": "o750", "Over 1M": "o1000", "Over 2M": "o2000", "Over 5M": "o5000", "Over 10M": "o10000", "Over 20M": "o20000"}}, "Price": {"prefix": "sh_price", "option": {"Any": "", "Under $1": "u1", "Under $2": "u2", "Under $3": "u3", "Under $4": "u4", "Under $5": "u5", "Under $7": "u7", "Under $10": "u10", "Under $15": "u15", "Under $20": "u20", "Under $30": "u30", "Under $40": "u40", "Under $50": "u50", "Over $1": "o1", "Over $2": "o2", "Over $3": "o3", "Over $4": "o4", "Over $5": "o5", "Over $7": "o7", "Over $10": "o10", "Over $15": "o15", "Over $20": "o20", "Over $30": "o30", "Over $40": "o40", "Over $50": "o50", "Over $60": "o60", "Over $70": "o70", "Over $80": "o80", "Over $90": "o90", "Over $100": "o100", "$1 to $5": "1to5", "$1 to $10": "1to10", "$1 to $20": "1to20", "$5 to $10": "5to10", "$5 to $20": "5to20", "$5 to $50": "5to50", "$10 to $20": "10to20", "$10 to $50": "10to50", "$20 to $50": "20to50", "$50 to $100": "50to100"}}, "Target Price": {"prefix": "targetprice", "option": {"Any": "", "50% Above Price": "a50", "40% Above Price": "a40", "30% Above Price": "a30", "20% Above Price": "a20", "10% Above Price": "a10", "5% Above Price": "a5", "Above Price": "above", "Below Price": "below", "5% Below Price": "b5", "10% Below Price": "b10", "20% Below Price": "b20", "30% Below Price": "b30", "40% Below Price": "b40", "50% Below Price": "b50"}}, "IPO Date": {"prefix": "ipodate", "option": {"Any": "", "Today": "today", "Yesterday": "yesterday", "In the last week": "prevweek", "In the last month": "prevmonth", "In the last quarter": "prevquarter", "In the last year": "prevyear", "In the last 2 years": "prev2yrs", "In the last 3 years": "prev3yrs", "In the last 5 years": "prev5yrs", "More than a year ago": "more1", "More than 5 years ago": "more5", "More than 10 years ago": "more10", "More than 15 years ago": "more15", "More than 20 years ago": "more20", "More than 25 years ago": "more25"}}, "Shares Outstanding": {"prefix": "sh_outstanding", "option": {"Any": "", "Under 1M": "u1", "Under 5M": "u5", "Under 10M": "u10", "Under 20M": "u20", "Under 50M": "u50", "Under 100M": "u100", "Over 1M": "o1", "Over 2M": "o2", "Over 5M": "o5", "Over 10M": "o10", "Over 20M": "o20", "Over 50M": "o50", "Over 100M": "o100", "Over 200M": "o200", "Over 500M": "o500", "Over 1000M": "o1000"}}, "Float": {"prefix": "sh_float", "option": {"Any": "", "Under 1M": "u1", "Under 5M": "u5", "Under 10M": "u10", "Under 20M": "u20", "Under 50M": "u50", "Under 100M": "u100", "Over 1M": "o1", "Over 2M": "o2", "Over 5M": "o5", "Over 10M": "o10", "Over 20M": "o20", "Over 50M": "o50", "Over 100M": "o100", "Over 200M": "o200", "Over 500M": "o500", "Over 1000M": "o1000"}}}, "order": {"Ticker": "o=ticker", "Company": "o=company", "Sector": "o=sector", "Industry": "o=industry", "Country": "o=country", "Market Cap.": "o=marketcap", "Price/Earnings": "o=pe", "Forward Price/Earnings": "o=forwardpe", "PEG (Price/Earnings/Growth)": "o=peg", "Price/Sales": "o=ps", "Price/Book": "o=pb", "Price/Cash": "o=pc", "Price/Free Cash Flow": "o=pfcf", "Dividend Yield": "o=dividendyield", "Payout Ratio": "o=payoutratio", "EPS (ttm)": "o=eps", "EPS growth this year": "o=epsyoy", "EPS growth next year": "o=epsyoy1", "EPS growth past 5 years": "o=eps5years", "EPS growth next 5 years": "o=estltgrowth", "Sales growth past 5 years": "o=sales5years", "EPS growth qtr over qtr": "o=epsqoq", "Sales growth qtr over qtr": "o=salesqoq", "Shares Outstanding": "o=sharesoutstanding2", "Shares Float": "o=sharesfloat", "Insider Ownership": "o=insiderown", "Insider Transactions": "o=insidertrans", "Institutional Ownership": "o=instown", "Institutional Transactions": "o=insttrans", "Short Interest Share": "o=shortinterestshare", "Short Interest Ratio": "o=shortinterestratio", "Earnings Date": "o=earningsdate", "Return on Assets": "o=roa", "Return on Equity": "o=roe", "Return on Investment": "o=roi", "Current Ratio": "o=curratio", "Quick Ratio": "o=quickratio", "LT Debt/Equity": "o=ltdebteq", "Total Debt/Equity": "o=debteq", "Gross Margin": "o=grossmargin", "Operating Margin": "o=opermargin", "Net Profit Margin": "o=netmargin", "Analyst Recommendation": "o=recom", "Performance (Week)": "o=perf1w", "Performance (Month)": "o=perf4w", "Performance (Quarter)": "o=perf13w", "Performance (Half Year)": "o=perf26w", "Performance (Year)": "o=perf52w", "Performance (Year To Date)": "o=perfytd", "Beta": "o=beta", "Average True Range": "o=averagetruerange", "Volatility (Week)": "o=volatility1w", "Volatility (Month)": "o=volatility4w", "20-Day SMA (Relative)": "o=sma20", "50-Day SMA (Relative)": "o=sma50", "200-Day SMA (Relative)": "o=sma200", "50-Day High (Relative)": "o=high50d", "50-Day Low (Relative)": "o=low50d", "52-Week High (Relative)": "o=high52w", "52-Week Low (Relative)": "o=low52w", "Relative Strength Index (14)": "o=rsi", "Average Volume (3 Month)": "o=averagevolume", "Relative Volume": "o=relativevolume", "Change": "o=change", "Change from Open": "o=changeopen", "Gap": "o=gap", "Volume": "o=volume", "Price": "o=price", "Target Price": "o=targetprice", "IPO Date": "o=ipodate"}} \ No newline at end of file +util_dict = { + "signal": { + "Top Gainers": "ta_topgainers", + "Top Losers": "ta_toplosers", + "New High": "ta_newhigh", + "New Low": "ta_newlow", + "Most Volatile": "ta_mostvolatile", + "Most Active": "ta_mostactive", + "Unusual Volume": "ta_unusualvolume", + "Overbought": "ta_overbought", + "Oversold": "ta_oversold", + "Downgrades": "n_downgrades", + "Upgrades": "n_upgrades", + "Earnings Before": "n_earningsbefore", + "Earnings After": "n_earningsafter", + "Recent Insider Buying": "it_latestbuys", + "Recent Insider Selling": "it_latestsales", + "Major News": "n_majornews", + "Horizontal S/R": "ta_p_horizontal", + "TL Resistance": "ta_p_tlresistance", + "TL Support": "ta_p_tlsupport", + "Wedge Up": "ta_p_wedgeup", + "Wedge Down": "ta_p_wedgedown", + "Triangle Ascending": "ta_p_wedgeresistance", + "Triangle Descending": "ta_p_wedgesupport", + "Wedge": "ta_p_wedge", + "Channel Up": "ta_p_channelup", + "Channel Down": "ta_p_channeldown", + "Channel": "ta_p_channel", + "Double Top": "ta_p_doubletop", + "Double Bottom": "ta_p_doublebottom", + "Multiple Top": "ta_p_multipletop", + "Multiple Bottom": "ta_p_multiplebottom", + "Head & Shoulders": "ta_p_headandshoulders", + "Head & Shoulders Inverse": "ta_p_headandshouldersinv", + }, + "filter": { + "Exchange": { + "prefix": "exch", + "option": {"Any": "", "AMEX": "amex", "NASDAQ": "nasd", "NYSE": "nyse"}, + }, + "Index": { + "prefix": "idx", + "option": {"Any": "", "S&P 500": "sp500", "DJIA": "dji"}, + }, + "Sector": { + "prefix": "sec", + "option": { + "Any": "", + "Basic Materials": "basicmaterials", + "Communication Services": "communicationservices", + "Consumer Cyclical": "consumercyclical", + "Consumer Defensive": "consumerdefensive", + "Energy": "energy", + "Financial": "financial", + "Healthcare": "healthcare", + "Industrials": "industrials", + "Real Estate": "realestate", + "Technology": "technology", + "Utilities": "utilities", + }, + }, + "Industry": { + "prefix": "ind", + "option": { + "Any": "", + "Stocks only (ex-Funds)": "stocksonly", + "Exchange Traded Fund": "exchangetradedfund", + "Advertising Agencies": "advertisingagencies", + "Aerospace & Defense": "aerospacedefense", + "Agricultural Inputs": "agriculturalinputs", + "Airlines": "airlines", + "Airports & Air Services": "airportsairservices", + "Aluminum": "aluminum", + "Apparel Manufacturing": "apparelmanufacturing", + "Apparel Retail": "apparelretail", + "Asset Management": "assetmanagement", + "Auto Manufacturers": "automanufacturers", + "Auto Parts": "autoparts", + "Auto & Truck Dealerships": "autotruckdealerships", + "Banks - Diversified": "banksdiversified", + "Banks - Regional": "banksregional", + "Beverages - Brewers": "beveragesbrewers", + "Beverages - Non-Alcoholic": "beveragesnonalcoholic", + "Beverages - Wineries & Distilleries": "beverageswineriesdistilleries", + "Biotechnology": "biotechnology", + "Broadcasting": "broadcasting", + "Building Materials": "buildingmaterials", + "Building Products & Equipment": "buildingproductsequipment", + "Business Equipment & Supplies": "businessequipmentsupplies", + "Capital Markets": "capitalmarkets", + "Chemicals": "chemicals", + "Closed-End Fund - Debt": "closedendfunddebt", + "Closed-End Fund - Equity": "closedendfundequity", + "Closed-End Fund - Foreign": "closedendfundforeign", + "Coking Coal": "cokingcoal", + "Communication Equipment": "communicationequipment", + "Computer Hardware": "computerhardware", + "Confectioners": "confectioners", + "Conglomerates": "conglomerates", + "Consulting Services": "consultingservices", + "Consumer Electronics": "consumerelectronics", + "Copper": "copper", + "Credit Services": "creditservices", + "Department Stores": "departmentstores", + "Diagnostics & Research": "diagnosticsresearch", + "Discount Stores": "discountstores", + "Drug Manufacturers - General": "drugmanufacturersgeneral", + "Drug Manufacturers - Specialty & Generic": "drugmanufacturersspecialtygeneric", + "Education & Training Services": "educationtrainingservices", + "Electrical Equipment & Parts": "electricalequipmentparts", + "Electronic Components": "electroniccomponents", + "Electronic Gaming & Multimedia": "electronicgamingmultimedia", + "Electronics & Computer Distribution": "electronicscomputerdistribution", + "Engineering & Construction": "engineeringconstruction", + "Entertainment": "entertainment", + "Farm & Heavy Construction Machinery": "farmheavyconstructionmachinery", + "Farm Products": "farmproducts", + "Financial Conglomerates": "financialconglomerates", + "Financial Data & Stock Exchanges": "financialdatastockexchanges", + "Food Distribution": "fooddistribution", + "Footwear & Accessories": "footwearaccessories", + "Furnishings, Fixtures & Appliances": "furnishingsfixturesappliances", + "Gambling": "gambling", + "Gold": "gold", + "Grocery Stores": "grocerystores", + "Healthcare Plans": "healthcareplans", + "Health Information Services": "healthinformationservices", + "Home Improvement Retail": "homeimprovementretail", + "Household & Personal Products": "householdpersonalproducts", + "Industrial Distribution": "industrialdistribution", + "Information Technology Services": "informationtechnologyservices", + "Infrastructure Operations": "infrastructureoperations", + "Insurance Brokers": "insurancebrokers", + "Insurance - Diversified": "insurancediversified", + "Insurance - Life": "insurancelife", + "Insurance - Property & Casualty": "insurancepropertycasualty", + "Insurance - Reinsurance": "insurancereinsurance", + "Insurance - Specialty": "insurancespecialty", + "Integrated Freight & Logistics": "integratedfreightlogistics", + "Internet Content & Information": "internetcontentinformation", + "Internet Retail": "internetretail", + "Leisure": "leisure", + "Lodging": "lodging", + "Lumber & Wood Production": "lumberwoodproduction", + "Luxury Goods": "luxurygoods", + "Marine Shipping": "marineshipping", + "Medical Care Facilities": "medicalcarefacilities", + "Medical Devices": "medicaldevices", + "Medical Distribution": "medicaldistribution", + "Medical Instruments & Supplies": "medicalinstrumentssupplies", + "Metal Fabrication": "metalfabrication", + "Mortgage Finance": "mortgagefinance", + "Oil & Gas Drilling": "oilgasdrilling", + "Oil & Gas E&P": "oilgasep", + "Oil & Gas Equipment & Services": "oilgasequipmentservices", + "Oil & Gas Integrated": "oilgasintegrated", + "Oil & Gas Midstream": "oilgasmidstream", + "Oil & Gas Refining & Marketing": "oilgasrefiningmarketing", + "Other Industrial Metals & Mining": "otherindustrialmetalsmining", + "Other Precious Metals & Mining": "otherpreciousmetalsmining", + "Packaged Foods": "packagedfoods", + "Packaging & Containers": "packagingcontainers", + "Paper & Paper Products": "paperpaperproducts", + "Personal Services": "personalservices", + "Pharmaceutical Retailers": "pharmaceuticalretailers", + "Pollution & Treatment Controls": "pollutiontreatmentcontrols", + "Publishing": "publishing", + "Railroads": "railroads", + "Real Estate - Development": "realestatedevelopment", + "Real Estate - Diversified": "realestatediversified", + "Real Estate Services": "realestateservices", + "Recreational Vehicles": "recreationalvehicles", + "REIT - Diversified": "reitdiversified", + "REIT - Healthcare Facilities": "reithealthcarefacilities", + "REIT - Hotel & Motel": "reithotelmotel", + "REIT - Industrial": "reitindustrial", + "REIT - Mortgage": "reitmortgage", + "REIT - Office": "reitoffice", + "REIT - Residential": "reitresidential", + "REIT - Retail": "reitretail", + "REIT - Specialty": "reitspecialty", + "Rental & Leasing Services": "rentalleasingservices", + "Residential Construction": "residentialconstruction", + "Resorts & Casinos": "resortscasinos", + "Restaurants": "restaurants", + "Scientific & Technical Instruments": "scientifictechnicalinstruments", + "Security & Protection Services": "securityprotectionservices", + "Semiconductor Equipment & Materials": "semiconductorequipmentmaterials", + "Semiconductors": "semiconductors", + "Shell Companies": "shellcompanies", + "Silver": "silver", + "Software - Application": "softwareapplication", + "Software - Infrastructure": "softwareinfrastructure", + "Solar": "solar", + "Specialty Business Services": "specialtybusinessservices", + "Specialty Chemicals": "specialtychemicals", + "Specialty Industrial Machinery": "specialtyindustrialmachinery", + "Specialty Retail": "specialtyretail", + "Staffing & Employment Services": "staffingemploymentservices", + "Steel": "steel", + "Telecom Services": "telecomservices", + "Textile Manufacturing": "textilemanufacturing", + "Thermal Coal": "thermalcoal", + "Tobacco": "tobacco", + "Tools & Accessories": "toolsaccessories", + "Travel Services": "travelservices", + "Trucking": "trucking", + "Uranium": "uranium", + "Utilities - Diversified": "utilitiesdiversified", + "Utilities - Independent Power Producers": "utilitiesindependentpowerproducers", + "Utilities - Regulated Electric": "utilitiesregulatedelectric", + "Utilities - Regulated Gas": "utilitiesregulatedgas", + "Utilities - Regulated Water": "utilitiesregulatedwater", + "Utilities - Renewable": "utilitiesrenewable", + "Waste Management": "wastemanagement", + }, + }, + "Country": { + "prefix": "geo", + "option": { + "Any": "", + "USA": "usa", + "Foreign (ex-USA)": "notusa", + "Asia": "asia", + "Europe": "europe", + "Latin America": "latinamerica", + "BRIC": "bric", + "Argentina": "argentina", + "Australia": "australia", + "Bahamas": "bahamas", + "Belgium": "belgium", + "BeNeLux": "benelux", + "Bermuda": "bermuda", + "Brazil": "brazil", + "Canada": "canada", + "Cayman Islands": "caymanislands", + "Chile": "chile", + "China": "china", + "China & Hong Kong": "chinahongkong", + "Colombia": "colombia", + "Cyprus": "cyprus", + "Denmark": "denmark", + "Finland": "finland", + "France": "france", + "Germany": "germany", + "Greece": "greece", + "Hong Kong": "hongkong", + "Hungary": "hungary", + "Iceland": "iceland", + "India": "india", + "Indonesia": "indonesia", + "Ireland": "ireland", + "Israel": "israel", + "Italy": "italy", + "Japan": "japan", + "Kazakhstan": "kazakhstan", + "Luxembourg": "luxembourg", + "Malaysia": "malaysia", + "Malta": "malta", + "Mexico": "mexico", + "Monaco": "monaco", + "Netherlands": "netherlands", + "New Zealand": "newzealand", + "Norway": "norway", + "Panama": "panama", + "Peru": "peru", + "Philippines": "philippines", + "Portugal": "portugal", + "Russia": "russia", + "Singapore": "singapore", + "South Africa": "southafrica", + "South Korea": "southkorea", + "Spain": "spain", + "Sweden": "sweden", + "Switzerland": "switzerland", + "Taiwan": "taiwan", + "Turkey": "turkey", + "United Arab Emirates": "unitedarabemirates", + "United Kingdom": "unitedkingdom", + "Uruguay": "uruguay", + }, + }, + "Market Cap.": { + "prefix": "cap", + "option": { + "Any": "", + "Mega ($200bln and more)": "mega", + "Large ($10bln to $200bln)": "large", + "Mid ($2bln to $10bln)": "mid", + "Small ($300mln to $2bln)": "small", + "Micro ($50mln to $300mln)": "micro", + "Nano (under $50mln)": "nano", + "+Large (over $10bln)": "largeover", + "+Mid (over $2bln)": "midover", + "+Small (over $300mln)": "smallover", + "+Micro (over $50mln)": "microover", + "-Large (under $200bln)": "largeunder", + "-Mid (under $10bln)": "midunder", + "-Small (under $2bln)": "smallunder", + "-Micro (under $300mln)": "microunder", + }, + }, + "P/E": { + "prefix": "fa_pe", + "option": { + "Any": "", + "Low (<15)": "low", + "Profitable (>0)": "profitable", + "High (>50)": "high", + "Under 5": "u5", + "Under 10": "u10", + "Under 15": "u15", + "Under 20": "u20", + "Under 25": "u25", + "Under 30": "u30", + "Under 35": "u35", + "Under 40": "u40", + "Under 45": "u45", + "Under 50": "u50", + "Over 5": "o5", + "Over 10": "o10", + "Over 15": "o15", + "Over 20": "o20", + "Over 25": "o25", + "Over 30": "o30", + "Over 35": "o35", + "Over 40": "o40", + "Over 45": "o45", + "Over 50": "o50", + }, + }, + "Forward P/E": { + "prefix": "fa_fpe", + "option": { + "Any": "", + "Low (<15)": "low", + "Profitable (>0)": "profitable", + "High (>50)": "high", + "Under 5": "u5", + "Under 10": "u10", + "Under 15": "u15", + "Under 20": "u20", + "Under 25": "u25", + "Under 30": "u30", + "Under 35": "u35", + "Under 40": "u40", + "Under 45": "u45", + "Under 50": "u50", + "Over 5": "o5", + "Over 10": "o10", + "Over 15": "o15", + "Over 20": "o20", + "Over 25": "o25", + "Over 30": "o30", + "Over 35": "o35", + "Over 40": "o40", + "Over 45": "o45", + "Over 50": "o50", + }, + }, + "PEG": { + "prefix": "fa_peg", + "option": { + "Any": "", + "Low (<1)": "low", + "High (>2)": "high", + "Under 1": "u1", + "Under 2": "u2", + "Under 3": "u3", + "Over 1": "o1", + "Over 2": "o2", + "Over 3": "o3", + }, + }, + "P/S": { + "prefix": "fa_ps", + "option": { + "Any": "", + "Low (<1)": "low", + "High (>10)": "high", + "Under 1": "u1", + "Under 2": "u2", + "Under 3": "u3", + "Under 4": "u4", + "Under 5": "u5", + "Under 6": "u6", + "Under 7": "u7", + "Under 8": "u8", + "Under 9": "u9", + "Under 10": "u10", + "Over 1": "o1", + "Over 2": "o2", + "Over 3": "o3", + "Over 4": "o4", + "Over 5": "o5", + "Over 6": "o6", + "Over 7": "o7", + "Over 8": "o8", + "Over 9": "o9", + "Over 10": "o10", + }, + }, + "P/B": { + "prefix": "fa_pb", + "option": { + "Any": "", + "Low (<1)": "low", + "High (>5)": "high", + "Under 1": "u1", + "Under 2": "u2", + "Under 3": "u3", + "Under 4": "u4", + "Under 5": "u5", + "Under 6": "u6", + "Under 7": "u7", + "Under 8": "u8", + "Under 9": "u9", + "Under 10": "u10", + "Over 1": "o1", + "Over 2": "o2", + "Over 3": "o3", + "Over 4": "o4", + "Over 5": "o5", + "Over 6": "o6", + "Over 7": "o7", + "Over 8": "o8", + "Over 9": "o9", + "Over 10": "o10", + }, + }, + "Price/Cash": { + "prefix": "fa_pc", + "option": { + "Any": "", + "Low (<3)": "low", + "High (>50)": "high", + "Under 1": "u1", + "Under 2": "u2", + "Under 3": "u3", + "Under 4": "u4", + "Under 5": "u5", + "Under 6": "u6", + "Under 7": "u7", + "Under 8": "u8", + "Under 9": "u9", + "Under 10": "u10", + "Over 1": "o1", + "Over 2": "o2", + "Over 3": "o3", + "Over 4": "o4", + "Over 5": "o5", + "Over 6": "o6", + "Over 7": "o7", + "Over 8": "o8", + "Over 9": "o9", + "Over 10": "o10", + "Over 20": "o20", + "Over 30": "o30", + "Over 40": "o40", + "Over 50": "o50", + }, + }, + "Price/Free Cash Flow": { + "prefix": "fa_pfcf", + "option": { + "Any": "", + "Low (<15)": "low", + "High (>50)": "high", + "Under 5": "u5", + "Under 10": "u10", + "Under 15": "u15", + "Under 20": "u20", + "Under 25": "u25", + "Under 30": "u30", + "Under 35": "u35", + "Under 40": "u40", + "Under 45": "u45", + "Under 50": "u50", + "Under 60": "u60", + "Under 70": "u70", + "Under 80": "u80", + "Under 90": "u90", + "Under 100": "u100", + "Over 5": "o5", + "Over 10": "o10", + "Over 15": "o15", + "Over 20": "o20", + "Over 25": "o25", + "Over 30": "o30", + "Over 35": "o35", + "Over 40": "o40", + "Over 45": "o45", + "Over 50": "o50", + "Over 60": "o60", + "Over 70": "o70", + "Over 80": "o80", + "Over 90": "o90", + "Over 100": "o100", + }, + }, + "EPS growththis year": { + "prefix": "fa_epsyoy", + "option": { + "Any": "", + "Negative (<0%)": "neg", + "Positive (>0%)": "pos", + "Positive Low (0-10%)": "poslow", + "High (>25%)": "high", + "Under 5%": "u5", + "Under 10%": "u10", + "Under 15%": "u15", + "Under 20%": "u20", + "Under 25%": "u25", + "Under 30%": "u30", + "Over 5%": "o5", + "Over 10%": "o10", + "Over 15%": "o15", + "Over 20%": "o20", + "Over 25%": "o25", + "Over 30%": "o30", + }, + }, + "EPS growthnext year": { + "prefix": "fa_epsyoy1", + "option": { + "Any": "", + "Negative (<0%)": "neg", + "Positive (>0%)": "pos", + "Positive Low (0-10%)": "poslow", + "High (>25%)": "high", + "Under 5%": "u5", + "Under 10%": "u10", + "Under 15%": "u15", + "Under 20%": "u20", + "Under 25%": "u25", + "Under 30%": "u30", + "Over 5%": "o5", + "Over 10%": "o10", + "Over 15%": "o15", + "Over 20%": "o20", + "Over 25%": "o25", + "Over 30%": "o30", + }, + }, + "EPS growthpast 5 years": { + "prefix": "fa_eps5years", + "option": { + "Any": "", + "Negative (<0%)": "neg", + "Positive (>0%)": "pos", + "Positive Low (0-10%)": "poslow", + "High (>25%)": "high", + "Under 5%": "u5", + "Under 10%": "u10", + "Under 15%": "u15", + "Under 20%": "u20", + "Under 25%": "u25", + "Under 30%": "u30", + "Over 5%": "o5", + "Over 10%": "o10", + "Over 15%": "o15", + "Over 20%": "o20", + "Over 25%": "o25", + "Over 30%": "o30", + }, + }, + "EPS growthnext 5 years": { + "prefix": "fa_estltgrowth", + "option": { + "Any": "", + "Negative (<0%)": "neg", + "Positive (>0%)": "pos", + "Positive Low (<10%)": "poslow", + "High (>25%)": "high", + "Under 5%": "u5", + "Under 10%": "u10", + "Under 15%": "u15", + "Under 20%": "u20", + "Under 25%": "u25", + "Under 30%": "u30", + "Over 5%": "o5", + "Over 10%": "o10", + "Over 15%": "o15", + "Over 20%": "o20", + "Over 25%": "o25", + "Over 30%": "o30", + }, + }, + "Sales growthpast 5 years": { + "prefix": "fa_sales5years", + "option": { + "Any": "", + "Negative (<0%)": "neg", + "Positive (>0%)": "pos", + "Positive Low (0-10%)": "poslow", + "High (>25%)": "high", + "Under 5%": "u5", + "Under 10%": "u10", + "Under 15%": "u15", + "Under 20%": "u20", + "Under 25%": "u25", + "Under 30%": "u30", + "Over 5%": "o5", + "Over 10%": "o10", + "Over 15%": "o15", + "Over 20%": "o20", + "Over 25%": "o25", + "Over 30%": "o30", + }, + }, + "EPS growthqtr over qtr": { + "prefix": "fa_epsqoq", + "option": { + "Any": "", + "Negative (<0%)": "neg", + "Positive (>0%)": "pos", + "Positive Low (0-10%)": "poslow", + "High (>25%)": "high", + "Under 5%": "u5", + "Under 10%": "u10", + "Under 15%": "u15", + "Under 20%": "u20", + "Under 25%": "u25", + "Under 30%": "u30", + "Over 5%": "o5", + "Over 10%": "o10", + "Over 15%": "o15", + "Over 20%": "o20", + "Over 25%": "o25", + "Over 30%": "o30", + }, + }, + "Sales growthqtr over qtr": { + "prefix": "fa_salesqoq", + "option": { + "Any": "", + "Negative (<0%)": "neg", + "Positive (>0%)": "pos", + "Positive Low (0-10%)": "poslow", + "High (>25%)": "high", + "Under 5%": "u5", + "Under 10%": "u10", + "Under 15%": "u15", + "Under 20%": "u20", + "Under 25%": "u25", + "Under 30%": "u30", + "Over 5%": "o5", + "Over 10%": "o10", + "Over 15%": "o15", + "Over 20%": "o20", + "Over 25%": "o25", + "Over 30%": "o30", + }, + }, + "Dividend Yield": { + "prefix": "fa_div", + "option": { + "Any": "", + "None (0%)": "none", + "Positive (>0%)": "pos", + "High (>5%)": "high", + "Very High (>10%)": "veryhigh", + "Over 1%": "o1", + "Over 2%": "o2", + "Over 3%": "o3", + "Over 4%": "o4", + "Over 5%": "o5", + "Over 6%": "o6", + "Over 7%": "o7", + "Over 8%": "o8", + "Over 9%": "o9", + "Over 10%": "o10", + }, + }, + "Return on Assets": { + "prefix": "fa_roa", + "option": { + "Any": "", + "Positive (>0%)": "pos", + "Negative (<0%)": "neg", + "Very Positive (>15%)": "verypos", + "Very Negative (": "veryneg", + "Under -50%": "u-50", + "Under -45%": "u-45", + "Under -40%": "u-40", + "Under -35%": "u-35", + "Under -30%": "u-30", + "Under -25%": "u-25", + "Under -20%": "u-20", + "Under -15%": "u-15", + "Under -10%": "u-10", + "Under -5%": "u-5", + "Over +5%": "o5", + "Over +10%": "o10", + "Over +15%": "o15", + "Over +20%": "o20", + "Over +25%": "o25", + "Over +30%": "o30", + "Over +35%": "o35", + "Over +40%": "o40", + "Over +45%": "o45", + "Over +50%": "o50", + }, + }, + "Return on Equity": { + "prefix": "fa_roe", + "option": { + "Any": "", + "Positive (>0%)": "pos", + "Negative (<0%)": "neg", + "Very Positive (>30%)": "verypos", + "Very Negative (": "veryneg", + "Under -50%": "u-50", + "Under -45%": "u-45", + "Under -40%": "u-40", + "Under -35%": "u-35", + "Under -30%": "u-30", + "Under -25%": "u-25", + "Under -20%": "u-20", + "Under -15%": "u-15", + "Under -10%": "u-10", + "Under -5%": "u-5", + "Over +5%": "o5", + "Over +10%": "o10", + "Over +15%": "o15", + "Over +20%": "o20", + "Over +25%": "o25", + "Over +30%": "o30", + "Over +35%": "o35", + "Over +40%": "o40", + "Over +45%": "o45", + "Over +50%": "o50", + }, + }, + "Return on Investment": { + "prefix": "fa_roi", + "option": { + "Any": "", + "Positive (>0%)": "pos", + "Negative (<0%)": "neg", + "Very Positive (>25%)": "verypos", + "Very Negative (": "veryneg", + "Under -50%": "u-50", + "Under -45%": "u-45", + "Under -40%": "u-40", + "Under -35%": "u-35", + "Under -30%": "u-30", + "Under -25%": "u-25", + "Under -20%": "u-20", + "Under -15%": "u-15", + "Under -10%": "u-10", + "Under -5%": "u-5", + "Over +5%": "o5", + "Over +10%": "o10", + "Over +15%": "o15", + "Over +20%": "o20", + "Over +25%": "o25", + "Over +30%": "o30", + "Over +35%": "o35", + "Over +40%": "o40", + "Over +45%": "o45", + "Over +50%": "o50", + }, + }, + "Current Ratio": { + "prefix": "fa_curratio", + "option": { + "Any": "", + "High (>3)": "high", + "Low (<1)": "low", + "Under 1": "u1", + "Under 0.5": "u0.5", + "Over 0.5": "o0.5", + "Over 1": "o1", + "Over 1.5": "o1.5", + "Over 2": "o2", + "Over 3": "o3", + "Over 4": "o4", + "Over 5": "o5", + "Over 10": "o10", + }, + }, + "Quick Ratio": { + "prefix": "fa_quickratio", + "option": { + "Any": "", + "High (>3)": "high", + "Low (<0.5)": "low", + "Under 1": "u1", + "Under 0.5": "u0.5", + "Over 0.5": "o0.5", + "Over 1": "o1", + "Over 1.5": "o1.5", + "Over 2": "o2", + "Over 3": "o3", + "Over 4": "o4", + "Over 5": "o5", + "Over 10": "o10", + }, + }, + "LT Debt/Equity": { + "prefix": "fa_ltdebteq", + "option": { + "Any": "", + "High (>0.5)": "high", + "Low (<0.1)": "low", + "Under 1": "u1", + "Under 0.9": "u0.9", + "Under 0.8": "u0.8", + "Under 0.7": "u0.7", + "Under 0.6": "u0.6", + "Under 0.5": "u0.5", + "Under 0.4": "u0.4", + "Under 0.3": "u0.3", + "Under 0.2": "u0.2", + "Under 0.1": "u0.1", + "Over 0.1": "o0.1", + "Over 0.2": "o0.2", + "Over 0.3": "o0.3", + "Over 0.4": "o0.4", + "Over 0.5": "o0.5", + "Over 0.6": "o0.6", + "Over 0.7": "o0.7", + "Over 0.8": "o0.8", + "Over 0.9": "o0.9", + "Over 1": "o1", + }, + }, + "Debt/Equity": { + "prefix": "fa_debteq", + "option": { + "Any": "", + "High (>0.5)": "high", + "Low (<0.1)": "low", + "Under 1": "u1", + "Under 0.9": "u0.9", + "Under 0.8": "u0.8", + "Under 0.7": "u0.7", + "Under 0.6": "u0.6", + "Under 0.5": "u0.5", + "Under 0.4": "u0.4", + "Under 0.3": "u0.3", + "Under 0.2": "u0.2", + "Under 0.1": "u0.1", + "Over 0.1": "o0.1", + "Over 0.2": "o0.2", + "Over 0.3": "o0.3", + "Over 0.4": "o0.4", + "Over 0.5": "o0.5", + "Over 0.6": "o0.6", + "Over 0.7": "o0.7", + "Over 0.8": "o0.8", + "Over 0.9": "o0.9", + "Over 1": "o1", + }, + }, + "Gross Margin": { + "prefix": "fa_grossmargin", + "option": { + "Any": "", + "Positive (>0%)": "pos", + "Negative (<0%)": "neg", + "High (>50%)": "high", + "Under 90%": "u90", + "Under 80%": "u80", + "Under 70%": "u70", + "Under 60%": "u60", + "Under 50%": "u50", + "Under 45%": "u45", + "Under 40%": "u40", + "Under 35%": "u35", + "Under 30%": "u30", + "Under 25%": "u25", + "Under 20%": "u20", + "Under 15%": "u15", + "Under 10%": "u10", + "Under 5%": "u5", + "Under 0%": "u0", + "Under -10%": "u-10", + "Under -20%": "u-20", + "Under -30%": "u-30", + "Under -50%": "u-50", + "Under -70%": "u-70", + "Under -100%": "u-100", + "Over 0%": "o0", + "Over 5%": "o5", + "Over 10%": "o10", + "Over 15%": "o15", + "Over 20%": "o20", + "Over 25%": "o25", + "Over 30%": "o30", + "Over 35%": "o35", + "Over 40%": "o40", + "Over 45%": "o45", + "Over 50%": "o50", + "Over 60%": "o60", + "Over 70%": "o70", + "Over 80%": "o80", + "Over 90%": "o90", + }, + }, + "Operating Margin": { + "prefix": "fa_opermargin", + "option": { + "Any": "", + "Positive (>0%)": "pos", + "Negative (<0%)": "neg", + "Very Negative (": "veryneg", + "High (>25%)": "high", + "Under 90%": "u90", + "Under 80%": "u80", + "Under 70%": "u70", + "Under 60%": "u60", + "Under 50%": "u50", + "Under 45%": "u45", + "Under 40%": "u40", + "Under 35%": "u35", + "Under 30%": "u30", + "Under 25%": "u25", + "Under 20%": "u20", + "Under 15%": "u15", + "Under 10%": "u10", + "Under 5%": "u5", + "Under 0%": "u0", + "Under -10%": "u-10", + "Under -20%": "u-20", + "Under -30%": "u-30", + "Under -50%": "u-50", + "Under -70%": "u-70", + "Under -100%": "u-100", + "Over 0%": "o0", + "Over 5%": "o5", + "Over 10%": "o10", + "Over 15%": "o15", + "Over 20%": "o20", + "Over 25%": "o25", + "Over 30%": "o30", + "Over 35%": "o35", + "Over 40%": "o40", + "Over 45%": "o45", + "Over 50%": "o50", + "Over 60%": "o60", + "Over 70%": "o70", + "Over 80%": "o80", + "Over 90%": "o90", + }, + }, + "Net Profit Margin": { + "prefix": "fa_netmargin", + "option": { + "Any": "", + "Positive (>0%)": "pos", + "Negative (<0%)": "neg", + "Very Negative (": "veryneg", + "High (>20%)": "high", + "Under 90%": "u90", + "Under 80%": "u80", + "Under 70%": "u70", + "Under 60%": "u60", + "Under 50%": "u50", + "Under 45%": "u45", + "Under 40%": "u40", + "Under 35%": "u35", + "Under 30%": "u30", + "Under 25%": "u25", + "Under 20%": "u20", + "Under 15%": "u15", + "Under 10%": "u10", + "Under 5%": "u5", + "Under 0%": "u0", + "Under -10%": "u-10", + "Under -20%": "u-20", + "Under -30%": "u-30", + "Under -50%": "u-50", + "Under -70%": "u-70", + "Under -100%": "u-100", + "Over 0%": "o0", + "Over 5%": "o5", + "Over 10%": "o10", + "Over 15%": "o15", + "Over 20%": "o20", + "Over 25%": "o25", + "Over 30%": "o30", + "Over 35%": "o35", + "Over 40%": "o40", + "Over 45%": "o45", + "Over 50%": "o50", + "Over 60%": "o60", + "Over 70%": "o70", + "Over 80%": "o80", + "Over 90%": "o90", + }, + }, + "Payout Ratio": { + "prefix": "fa_payoutratio", + "option": { + "Any": "", + "None (0%)": "none", + "Positive (>0%)": "pos", + "Low (<20%)": "low", + "High (>50%)": "high", + "Over 0%": "o0", + "Over 10%": "o10", + "Over 20%": "o20", + "Over 30%": "o30", + "Over 40%": "o40", + "Over 50%": "o50", + "Over 60%": "o60", + "Over 70%": "o70", + "Over 80%": "o80", + "Over 90%": "o90", + "Over 100%": "o100", + "Under 10%": "u10", + "Under 20%": "u20", + "Under 30%": "u30", + "Under 40%": "u40", + "Under 50%": "u50", + "Under 60%": "u60", + "Under 70%": "u70", + "Under 80%": "u80", + "Under 90%": "u90", + "Under 100%": "u100", + }, + }, + "InsiderOwnership": { + "prefix": "sh_insiderown", + "option": { + "Any": "", + "Low (<5%)": "low", + "High (>30%)": "high", + "Very High (>50%)": "veryhigh", + "Over 10%": "o10", + "Over 20%": "o20", + "Over 30%": "o30", + "Over 40%": "o40", + "Over 50%": "o50", + "Over 60%": "o60", + "Over 70%": "o70", + "Over 80%": "o80", + "Over 90%": "o90", + }, + }, + "InsiderTransactions": { + "prefix": "sh_insidertrans", + "option": { + "Any": "", + "Very Negative (<20%)": "veryneg", + "Negative (<0%)": "neg", + "Positive (>0%)": "pos", + "Very Positive (>20%)": "verypos", + "Under -90%": "u-90", + "Under -80%": "u-80", + "Under -70%": "u-70", + "Under -60%": "u-60", + "Under -50%": "u-50", + "Under -45%": "u-45", + "Under -40%": "u-40", + "Under -35%": "u-35", + "Under -30%": "u-30", + "Under -25%": "u-25", + "Under -20%": "u-20", + "Under -15%": "u-15", + "Under -10%": "u-10", + "Under -5%": "u-5", + "Over +5%": "o5", + "Over +10%": "o10", + "Over +15%": "o15", + "Over +20%": "o20", + "Over +25%": "o25", + "Over +30%": "o30", + "Over +35%": "o35", + "Over +40%": "o40", + "Over +45%": "o45", + "Over +50%": "o50", + "Over +60%": "o60", + "Over +70%": "o70", + "Over +80%": "o80", + "Over +90%": "o90", + }, + }, + "InstitutionalOwnership": { + "prefix": "sh_instown", + "option": { + "Any": "", + "Low (<5%)": "low", + "High (>90%)": "high", + "Under 90%": "u90", + "Under 80%": "u80", + "Under 70%": "u70", + "Under 60%": "u60", + "Under 50%": "u50", + "Under 40%": "u40", + "Under 30%": "u30", + "Under 20%": "u20", + "Under 10%": "u10", + "Over 10%": "o10", + "Over 20%": "o20", + "Over 30%": "o30", + "Over 40%": "o40", + "Over 50%": "o50", + "Over 60%": "o60", + "Over 70%": "o70", + "Over 80%": "o80", + "Over 90%": "o90", + }, + }, + "InstitutionalTransactions": { + "prefix": "sh_insttrans", + "option": { + "Any": "", + "Very Negative (<20%)": "veryneg", + "Negative (<0%)": "neg", + "Positive (>0%)": "pos", + "Very Positive (>20%)": "verypos", + "Under -50%": "u-50", + "Under -45%": "u-45", + "Under -40%": "u-40", + "Under -35%": "u-35", + "Under -30%": "u-30", + "Under -25%": "u-25", + "Under -20%": "u-20", + "Under -15%": "u-15", + "Under -10%": "u-10", + "Under -5%": "u-5", + "Over +5%": "o5", + "Over +10%": "o10", + "Over +15%": "o15", + "Over +20%": "o20", + "Over +25%": "o25", + "Over +30%": "o30", + "Over +35%": "o35", + "Over +40%": "o40", + "Over +45%": "o45", + "Over +50%": "o50", + }, + }, + "Float Short": { + "prefix": "sh_short", + "option": { + "Any": "", + "Low (<5%)": "low", + "High (>20%)": "high", + "Under 5%": "u5", + "Under 10%": "u10", + "Under 15%": "u15", + "Under 20%": "u20", + "Under 25%": "u25", + "Under 30%": "u30", + "Over 5%": "o5", + "Over 10%": "o10", + "Over 15%": "o15", + "Over 20%": "o20", + "Over 25%": "o25", + "Over 30%": "o30", + }, + }, + "Analyst Recom.": { + "prefix": "an_recom", + "option": { + "Any": "", + "Strong Buy (1)": "strongbuy", + "Buy or better": "buybetter", + "Buy": "buy", + "Hold or better": "holdbetter", + "Hold": "hold", + "Hold or worse": "holdworse", + "Sell": "sell", + "Sell or worse": "sellworse", + "Strong Sell (5)": "strongsell", + }, + }, + "Option/Short": { + "prefix": "sh_opt", + "option": { + "Any": "", + "Optionable": "option", + "Shortable": "short", + "Optionable and shortable": "optionshort", + }, + }, + "Earnings Date": { + "prefix": "earningsdate", + "option": { + "Any": "", + "Today": "today", + "Today Before Market Open": "todaybefore", + "Today After Market Close": "todayafter", + "Tomorrow": "tomorrow", + "Tomorrow Before Market Open": "tomorrowbefore", + "Tomorrow After Market Close": "tomorrowafter", + "Yesterday": "yesterday", + "Yesterday Before Market Open": "yesterdaybefore", + "Yesterday After Market Close": "yesterdayafter", + "Next 5 Days": "nextdays5", + "Previous 5 Days": "prevdays5", + "This Week": "thisweek", + "Next Week": "nextweek", + "Previous Week": "prevweek", + "This Month": "thismonth", + }, + }, + "Performance": { + "prefix": "ta_perf", + "option": { + "Any": "", + "Today Up": "dup", + "Today Down": "ddown", + "Today -15%": "d15u", + "Today -10%": "d10u", + "Today -5%": "d5u", + "Today +5%": "d5o", + "Today +10%": "d10o", + "Today +15%": "d15o", + "Week -30%": "1w30u", + "Week -20%": "1w20u", + "Week -10%": "1w10u", + "Week Down": "1wdown", + "Week Up": "1wup", + "Week +10%": "1w10o", + "Week +20%": "1w20o", + "Week +30%": "1w30o", + "Month -50%": "4w50u", + "Month -30%": "4w30u", + "Month -20%": "4w20u", + "Month -10%": "4w10u", + "Month Down": "4wdown", + "Month Up": "4wup", + "Month +10%": "4w10o", + "Month +20%": "4w20o", + "Month +30%": "4w30o", + "Month +50%": "4w50o", + "Quarter -50%": "13w50u", + "Quarter -30%": "13w30u", + "Quarter -20%": "13w20u", + "Quarter -10%": "13w10u", + "Quarter Down": "13wdown", + "Quarter Up": "13wup", + "Quarter +10%": "13w10o", + "Quarter +20%": "13w20o", + "Quarter +30%": "13w30o", + "Quarter +50%": "13w50o", + "Half -75%": "26w75u", + "Half -50%": "26w50u", + "Half -30%": "26w30u", + "Half -20%": "26w20u", + "Half -10%": "26w10u", + "Half Down": "26wdown", + "Half Up": "26wup", + "Half +10%": "26w10o", + "Half +20%": "26w20o", + "Half +30%": "26w30o", + "Half +50%": "26w50o", + "Half +100%": "26w100o", + "Year -75%": "52w75u", + "Year -50%": "52w50u", + "Year -30%": "52w30u", + "Year -20%": "52w20u", + "Year -10%": "52w10u", + "Year Down": "52wdown", + "Year Up": "52wup", + "Year +10%": "52w10o", + "Year +20%": "52w20o", + "Year +30%": "52w30o", + "Year +50%": "52w50o", + "Year +100%": "52w100o", + "Year +200%": "52w200o", + "Year +300%": "52w300o", + "Year +500%": "52w500o", + "YTD -75%": "ytd75u", + "YTD -50%": "ytd50u", + "YTD -30%": "ytd30u", + "YTD -20%": "ytd20u", + "YTD -10%": "ytd10u", + "YTD -5%": "ytd5u", + "YTD Down": "ytddown", + "YTD Up": "ytdup", + "YTD +5%": "ytd5o", + "YTD +10%": "ytd10o", + "YTD +20%": "ytd20o", + "YTD +30%": "ytd30o", + "YTD +50%": "ytd50o", + "YTD +100%": "ytd100o", + }, + }, + "Performance 2": { + "prefix": "ta_perf2", + "option": { + "Any": "", + "Today Up": "dup", + "Today Down": "ddown", + "Today -15%": "d15u", + "Today -10%": "d10u", + "Today -5%": "d5u", + "Today +5%": "d5o", + "Today +10%": "d10o", + "Today +15%": "d15o", + "Week -30%": "1w30u", + "Week -20%": "1w20u", + "Week -10%": "1w10u", + "Week Down": "1wdown", + "Week Up": "1wup", + "Week +10%": "1w10o", + "Week +20%": "1w20o", + "Week +30%": "1w30o", + "Month -50%": "4w50u", + "Month -30%": "4w30u", + "Month -20%": "4w20u", + "Month -10%": "4w10u", + "Month Down": "4wdown", + "Month Up": "4wup", + "Month +10%": "4w10o", + "Month +20%": "4w20o", + "Month +30%": "4w30o", + "Month +50%": "4w50o", + "Quarter -50%": "13w50u", + "Quarter -30%": "13w30u", + "Quarter -20%": "13w20u", + "Quarter -10%": "13w10u", + "Quarter Down": "13wdown", + "Quarter Up": "13wup", + "Quarter +10%": "13w10o", + "Quarter +20%": "13w20o", + "Quarter +30%": "13w30o", + "Quarter +50%": "13w50o", + "Half -75%": "26w75u", + "Half -50%": "26w50u", + "Half -30%": "26w30u", + "Half -20%": "26w20u", + "Half -10%": "26w10u", + "Half Down": "26wdown", + "Half Up": "26wup", + "Half +10%": "26w10o", + "Half +20%": "26w20o", + "Half +30%": "26w30o", + "Half +50%": "26w50o", + "Half +100%": "26w100o", + "Year -75%": "52w75u", + "Year -50%": "52w50u", + "Year -30%": "52w30u", + "Year -20%": "52w20u", + "Year -10%": "52w10u", + "Year Down": "52wdown", + "Year Up": "52wup", + "Year +10%": "52w10o", + "Year +20%": "52w20o", + "Year +30%": "52w30o", + "Year +50%": "52w50o", + "Year +100%": "52w100o", + "Year +200%": "52w200o", + "Year +300%": "52w300o", + "Year +500%": "52w500o", + "YTD -75%": "ytd75u", + "YTD -50%": "ytd50u", + "YTD -30%": "ytd30u", + "YTD -20%": "ytd20u", + "YTD -10%": "ytd10u", + "YTD -5%": "ytd5u", + "YTD Down": "ytddown", + "YTD Up": "ytdup", + "YTD +5%": "ytd5o", + "YTD +10%": "ytd10o", + "YTD +20%": "ytd20o", + "YTD +30%": "ytd30o", + "YTD +50%": "ytd50o", + "YTD +100%": "ytd100o", + }, + }, + "Volatility": { + "prefix": "ta_volatility", + "option": { + "Any": "", + "Week - Over 3%": "wo3", + "Week - Over 4%": "wo4", + "Week - Over 5%": "wo5", + "Week - Over 6%": "wo6", + "Week - Over 7%": "wo7", + "Week - Over 8%": "wo8", + "Week - Over 9%": "wo9", + "Week - Over 10%": "wo10", + "Week - Over 12%": "wo12", + "Week - Over 15%": "wo15", + "Month - Over 2%": "mo2", + "Month - Over 3%": "mo3", + "Month - Over 4%": "mo4", + "Month - Over 5%": "mo5", + "Month - Over 6%": "mo6", + "Month - Over 7%": "mo7", + "Month - Over 8%": "mo8", + "Month - Over 9%": "mo9", + "Month - Over 10%": "mo10", + "Month - Over 12%": "mo12", + "Month - Over 15%": "mo15", + }, + }, + "RSI (14)": { + "prefix": "ta_rsi", + "option": { + "Any": "", + "Overbought (90)": "ob90", + "Overbought (80)": "ob80", + "Overbought (70)": "ob70", + "Overbought (60)": "ob60", + "Oversold (40)": "os40", + "Oversold (30)": "os30", + "Oversold (20)": "os20", + "Oversold (10)": "os10", + "Not Overbought (<60)": "nob60", + "Not Overbought (<50)": "nob50", + "Not Oversold (>50)": "nos50", + "Not Oversold (>40)": "nos40", + }, + }, + "Gap": { + "prefix": "ta_gap", + "option": { + "Any": "", + "Up": "u", + "Up 0%": "u0", + "Up 1%": "u1", + "Up 2%": "u2", + "Up 3%": "u3", + "Up 4%": "u4", + "Up 5%": "u5", + "Up 6%": "u6", + "Up 7%": "u7", + "Up 8%": "u8", + "Up 9%": "u9", + "Up 10%": "u10", + "Up 15%": "u15", + "Up 20%": "u20", + "Down": "d", + "Down 0%": "d0", + "Down 1%": "d1", + "Down 2%": "d2", + "Down 3%": "d3", + "Down 4%": "d4", + "Down 5%": "d5", + "Down 6%": "d6", + "Down 7%": "d7", + "Down 8%": "d8", + "Down 9%": "d9", + "Down 10%": "d10", + "Down 15%": "d15", + "Down 20%": "d20", + }, + }, + "20-Day Simple Moving Average": { + "prefix": "ta_sma20", + "option": { + "Any": "", + "Price below SMA20": "pb", + "Price 10% below SMA20": "pb10", + "Price 20% below SMA20": "pb20", + "Price 30% below SMA20": "pb30", + "Price 40% below SMA20": "pb40", + "Price 50% below SMA20": "pb50", + "Price above SMA20": "pa", + "Price 10% above SMA20": "pa10", + "Price 20% above SMA20": "pa20", + "Price 30% above SMA20": "pa30", + "Price 40% above SMA20": "pa40", + "Price 50% above SMA20": "pa50", + "Price crossed SMA20": "pc", + "Price crossed SMA20 above": "pca", + "Price crossed SMA20 below": "pcb", + "SMA20 crossed SMA50": "cross50", + "SMA20 crossed SMA50 above": "cross50a", + "SMA20 crossed SMA50 below": "cross50b", + "SMA20 crossed SMA200": "cross200", + "SMA20 crossed SMA200 above": "cross200a", + "SMA20 crossed SMA200 below": "cross200b", + "SMA20 above SMA50": "sa50", + "SMA20 below SMA50": "sb50", + "SMA20 above SMA200": "sa200", + "SMA20 below SMA200": "sb200", + }, + }, + "50-Day Simple Moving Average": { + "prefix": "ta_sma50", + "option": { + "Any": "", + "Price below SMA50": "pb", + "Price 10% below SMA50": "pb10", + "Price 20% below SMA50": "pb20", + "Price 30% below SMA50": "pb30", + "Price 40% below SMA50": "pb40", + "Price 50% below SMA50": "pb50", + "Price above SMA50": "pa", + "Price 10% above SMA50": "pa10", + "Price 20% above SMA50": "pa20", + "Price 30% above SMA50": "pa30", + "Price 40% above SMA50": "pa40", + "Price 50% above SMA50": "pa50", + "Price crossed SMA50": "pc", + "Price crossed SMA50 above": "pca", + "Price crossed SMA50 below": "pcb", + "SMA50 crossed SMA20": "cross20", + "SMA50 crossed SMA20 above": "cross20a", + "SMA50 crossed SMA20 below": "cross20b", + "SMA50 crossed SMA200": "cross200", + "SMA50 crossed SMA200 above": "cross200a", + "SMA50 crossed SMA200 below": "cross200b", + "SMA50 above SMA20": "sa20", + "SMA50 below SMA20": "sb20", + "SMA50 above SMA200": "sa200", + "SMA50 below SMA200": "sb200", + }, + }, + "200-Day Simple Moving Average": { + "prefix": "ta_sma200", + "option": { + "Any": "", + "Price below SMA200": "pb", + "Price 10% below SMA200": "pb10", + "Price 20% below SMA200": "pb20", + "Price 30% below SMA200": "pb30", + "Price 40% below SMA200": "pb40", + "Price 50% below SMA200": "pb50", + "Price 60% below SMA200": "pb60", + "Price 70% below SMA200": "pb70", + "Price 80% below SMA200": "pb80", + "Price 90% below SMA200": "pb90", + "Price above SMA200": "pa", + "Price 10% above SMA200": "pa10", + "Price 20% above SMA200": "pa20", + "Price 30% above SMA200": "pa30", + "Price 40% above SMA200": "pa40", + "Price 50% above SMA200": "pa50", + "Price 60% above SMA200": "pa60", + "Price 70% above SMA200": "pa70", + "Price 80% above SMA200": "pa80", + "Price 90% above SMA200": "pa90", + "Price 100% above SMA200": "pa100", + "Price crossed SMA200": "pc", + "Price crossed SMA200 above": "pca", + "Price crossed SMA200 below": "pcb", + "SMA200 crossed SMA20": "cross20", + "SMA200 crossed SMA20 above": "cross20a", + "SMA200 crossed SMA20 below": "cross20b", + "SMA200 crossed SMA50": "cross50", + "SMA200 crossed SMA50 above": "cross50a", + "SMA200 crossed SMA50 below": "cross50b", + "SMA200 above SMA20": "sa20", + "SMA200 below SMA20": "sb20", + "SMA200 above SMA50": "sa50", + "SMA200 below SMA50": "sb50", + }, + }, + "Change": { + "prefix": "ta_change", + "option": { + "Any": "", + "Up": "u", + "Up 1%": "u1", + "Up 2%": "u2", + "Up 3%": "u3", + "Up 4%": "u4", + "Up 5%": "u5", + "Up 6%": "u6", + "Up 7%": "u7", + "Up 8%": "u8", + "Up 9%": "u9", + "Up 10%": "u10", + "Up 15%": "u15", + "Up 20%": "u20", + "Down": "d", + "Down 1%": "d1", + "Down 2%": "d2", + "Down 3%": "d3", + "Down 4%": "d4", + "Down 5%": "d5", + "Down 6%": "d6", + "Down 7%": "d7", + "Down 8%": "d8", + "Down 9%": "d9", + "Down 10%": "d10", + "Down 15%": "d15", + "Down 20%": "d20", + }, + }, + "Change from Open": { + "prefix": "ta_changeopen", + "option": { + "Any": "", + "Up": "u", + "Up 1%": "u1", + "Up 2%": "u2", + "Up 3%": "u3", + "Up 4%": "u4", + "Up 5%": "u5", + "Up 6%": "u6", + "Up 7%": "u7", + "Up 8%": "u8", + "Up 9%": "u9", + "Up 10%": "u10", + "Up 15%": "u15", + "Up 20%": "u20", + "Down": "d", + "Down 1%": "d1", + "Down 2%": "d2", + "Down 3%": "d3", + "Down 4%": "d4", + "Down 5%": "d5", + "Down 6%": "d6", + "Down 7%": "d7", + "Down 8%": "d8", + "Down 9%": "d9", + "Down 10%": "d10", + "Down 15%": "d15", + "Down 20%": "d20", + }, + }, + "20-Day High/Low": { + "prefix": "ta_highlow20d", + "option": { + "Any": "", + "New High": "nh", + "New Low": "nl", + "5% or more below High": "b5h", + "10% or more below High": "b10h", + "15% or more below High": "b15h", + "20% or more below High": "b20h", + "30% or more below High": "b30h", + "40% or more below High": "b40h", + "50% or more below High": "b50h", + "0-3% below High": "b0to3h", + "0-5% below High": "b0to5h", + "0-10% below High": "b0to10h", + "5% or more above Low": "a5h", + "10% or more above Low": "a10h", + "15% or more above Low": "a15h", + "20% or more above Low": "a20h", + "30% or more above Low": "a30h", + "40% or more above Low": "a40h", + "50% or more above Low": "a50h", + "0-3% above Low": "a0to3h", + "0-5% above Low": "a0to5h", + "0-10% above Low": "a0to10h", + }, + }, + "50-Day High/Low": { + "prefix": "ta_highlow50d", + "option": { + "Any": "", + "New High": "nh", + "New Low": "nl", + "5% or more below High": "b5h", + "10% or more below High": "b10h", + "15% or more below High": "b15h", + "20% or more below High": "b20h", + "30% or more below High": "b30h", + "40% or more below High": "b40h", + "50% or more below High": "b50h", + "0-3% below High": "b0to3h", + "0-5% below High": "b0to5h", + "0-10% below High": "b0to10h", + "5% or more above Low": "a5h", + "10% or more above Low": "a10h", + "15% or more above Low": "a15h", + "20% or more above Low": "a20h", + "30% or more above Low": "a30h", + "40% or more above Low": "a40h", + "50% or more above Low": "a50h", + "0-3% above Low": "a0to3h", + "0-5% above Low": "a0to5h", + "0-10% above Low": "a0to10h", + }, + }, + "52-Week High/Low": { + "prefix": "ta_highlow52w", + "option": { + "Any": "", + "New High": "nh", + "New Low": "nl", + "5% or more below High": "b5h", + "10% or more below High": "b10h", + "15% or more below High": "b15h", + "20% or more below High": "b20h", + "30% or more below High": "b30h", + "40% or more below High": "b40h", + "50% or more below High": "b50h", + "60% or more below High": "b60h", + "70% or more below High": "b70h", + "80% or more below High": "b80h", + "90% or more below High": "b90h", + "0-3% below High": "b0to3h", + "0-5% below High": "b0to5h", + "0-10% below High": "b0to10h", + "5% or more above Low": "a5h", + "10% or more above Low": "a10h", + "15% or more above Low": "a15h", + "20% or more above Low": "a20h", + "30% or more above Low": "a30h", + "40% or more above Low": "a40h", + "50% or more above Low": "a50h", + "60% or more above Low": "a60h", + "70% or more above Low": "a70h", + "80% or more above Low": "a80h", + "90% or more above Low": "a90h", + "100% or more above Low": "a100h", + "120% or more above Low": "a120h", + "150% or more above Low": "a150h", + "200% or more above Low": "a200h", + "300% or more above Low": "a300h", + "500% or more above Low": "a500h", + "0-3% above Low": "a0to3h", + "0-5% above Low": "a0to5h", + "0-10% above Low": "a0to10h", + }, + }, + "Pattern": { + "prefix": "ta_pattern", + "option": { + "Any": "", + "Horizontal S/R": "horizontal", + "Horizontal S/R (Strong)": "horizontal2", + "TL Resistance": "tlresistance", + "TL Resistance (Strong)": "tlresistance2", + "TL Support": "tlsupport", + "TL Support (Strong)": "tlsupport2", + "Wedge Up": "wedgeup", + "Wedge Up (Strong)": "wedgeup2", + "Wedge Down": "wedgedown", + "Wedge Down (Strong)": "wedgedown2", + "Triangle Ascending": "wedgeresistance", + "Triangle Ascending (Strong)": "wedgeresistance2", + "Triangle Descending": "wedgesupport", + "Triangle Descending (Strong)": "wedgesupport2", + "Wedge": "wedge", + "Wedge (Strong)": "wedge2", + "Channel Up": "channelup", + "Channel Up (Strong)": "channelup2", + "Channel Down": "channeldown", + "Channel Down (Strong)": "channeldown2", + "Channel": "channel", + "Channel (Strong)": "channel2", + "Double Top": "doubletop", + "Double Bottom": "doublebottom", + "Multiple Top": "multipletop", + "Multiple Bottom": "multiplebottom", + "Head & Shoulders": "headandshoulders", + "Head & Shoulders Inverse": "headandshouldersinv", + }, + }, + "Candlestick": { + "prefix": "ta_candlestick", + "option": { + "Any": "", + "Long Lower Shadow": "lls", + "Long Upper Shadow": "lus", + "Hammer": "h", + "Inverted Hammer": "ih", + "Spinning Top White": "stw", + "Spinning Top Black": "stb", + "Doji": "d", + "Dragonfly Doji": "dd", + "Gravestone Doji": "gd", + "Marubozu White": "mw", + "Marubozu Black": "mb", + }, + }, + "Beta": { + "prefix": "ta_beta", + "option": { + "Any": "", + "Under 0": "u0", + "Under 0.5": "u0.5", + "Under 1": "u1", + "Under 1.5": "u1.5", + "Under 2": "u2", + "Over 0": "o0", + "Over 0.5": "o0.5", + "Over 1": "o1", + "Over 1.5": "o1.5", + "Over 2": "o2", + "Over 2.5": "o2.5", + "Over 3": "o3", + "Over 4": "o4", + "0 to 0.5": "0to0.5", + "0 to 1": "0to1", + "0.5 to 1": "0.5to1", + "0.5 to 1.5": "0.5to1.5", + "1 to 1.5": "1to1.5", + "1 to 2": "1to2", + }, + }, + "Average True Range": { + "prefix": "ta_averagetruerange", + "option": { + "Any": "", + "Over 0.25": "o0.25", + "Over 0.5": "o0.5", + "Over 0.75": "o0.75", + "Over 1": "o1", + "Over 1.5": "o1.5", + "Over 2": "o2", + "Over 2.5": "o2.5", + "Over 3": "o3", + "Over 3.5": "o3.5", + "Over 4": "o4", + "Over 4.5": "o4.5", + "Over 5": "o5", + "Under 0.25": "u0.25", + "Under 0.5": "u0.5", + "Under 0.75": "u0.75", + "Under 1": "u1", + "Under 1.5": "u1.5", + "Under 2": "u2", + "Under 2.5": "u2.5", + "Under 3": "u3", + "Under 3.5": "u3.5", + "Under 4": "u4", + "Under 4.5": "u4.5", + "Under 5": "u5", + }, + }, + "Average Volume": { + "prefix": "sh_avgvol", + "option": { + "Any": "", + "Under 50K": "u50", + "Under 100K": "u100", + "Under 500K": "u500", + "Under 750K": "u750", + "Under 1M": "u1000", + "Over 50K": "o50", + "Over 100K": "o100", + "Over 200K": "o200", + "Over 300K": "o300", + "Over 400K": "o400", + "Over 500K": "o500", + "Over 750K": "o750", + "Over 1M": "o1000", + "Over 2M": "o2000", + "100K to 500K": "100to500", + "100K to 1M": "100to1000", + "500K to 1M": "500to1000", + "500K to 10M": "500to10000", + }, + }, + "Relative Volume": { + "prefix": "sh_relvol", + "option": { + "Any": "", + "Over 10": "o10", + "Over 5": "o5", + "Over 3": "o3", + "Over 2": "o2", + "Over 1.5": "o1.5", + "Over 1": "o1", + "Over 0.75": "o0.75", + "Over 0.5": "o0.5", + "Over 0.25": "o0.25", + "Under 2": "u2", + "Under 1.5": "u1.5", + "Under 1": "u1", + "Under 0.75": "u0.75", + "Under 0.5": "u0.5", + "Under 0.25": "u0.25", + "Under 0.1": "u0.1", + }, + }, + "Current Volume": { + "prefix": "sh_curvol", + "option": { + "Any": "", + "Under 50K": "u50", + "Under 100K": "u100", + "Under 500K": "u500", + "Under 750K": "u750", + "Under 1M": "u1000", + "Over 0": "o0", + "Over 50K": "o50", + "Over 100K": "o100", + "Over 200K": "o200", + "Over 300K": "o300", + "Over 400K": "o400", + "Over 500K": "o500", + "Over 750K": "o750", + "Over 1M": "o1000", + "Over 2M": "o2000", + "Over 5M": "o5000", + "Over 10M": "o10000", + "Over 20M": "o20000", + }, + }, + "Price": { + "prefix": "sh_price", + "option": { + "Any": "", + "Under $1": "u1", + "Under $2": "u2", + "Under $3": "u3", + "Under $4": "u4", + "Under $5": "u5", + "Under $7": "u7", + "Under $10": "u10", + "Under $15": "u15", + "Under $20": "u20", + "Under $30": "u30", + "Under $40": "u40", + "Under $50": "u50", + "Over $1": "o1", + "Over $2": "o2", + "Over $3": "o3", + "Over $4": "o4", + "Over $5": "o5", + "Over $7": "o7", + "Over $10": "o10", + "Over $15": "o15", + "Over $20": "o20", + "Over $30": "o30", + "Over $40": "o40", + "Over $50": "o50", + "Over $60": "o60", + "Over $70": "o70", + "Over $80": "o80", + "Over $90": "o90", + "Over $100": "o100", + "$1 to $5": "1to5", + "$1 to $10": "1to10", + "$1 to $20": "1to20", + "$5 to $10": "5to10", + "$5 to $20": "5to20", + "$5 to $50": "5to50", + "$10 to $20": "10to20", + "$10 to $50": "10to50", + "$20 to $50": "20to50", + "$50 to $100": "50to100", + }, + }, + "Target Price": { + "prefix": "targetprice", + "option": { + "Any": "", + "50% Above Price": "a50", + "40% Above Price": "a40", + "30% Above Price": "a30", + "20% Above Price": "a20", + "10% Above Price": "a10", + "5% Above Price": "a5", + "Above Price": "above", + "Below Price": "below", + "5% Below Price": "b5", + "10% Below Price": "b10", + "20% Below Price": "b20", + "30% Below Price": "b30", + "40% Below Price": "b40", + "50% Below Price": "b50", + }, + }, + "IPO Date": { + "prefix": "ipodate", + "option": { + "Any": "", + "Today": "today", + "Yesterday": "yesterday", + "In the last week": "prevweek", + "In the last month": "prevmonth", + "In the last quarter": "prevquarter", + "In the last year": "prevyear", + "In the last 2 years": "prev2yrs", + "In the last 3 years": "prev3yrs", + "In the last 5 years": "prev5yrs", + "More than a year ago": "more1", + "More than 5 years ago": "more5", + "More than 10 years ago": "more10", + "More than 15 years ago": "more15", + "More than 20 years ago": "more20", + "More than 25 years ago": "more25", + }, + }, + "Shares Outstanding": { + "prefix": "sh_outstanding", + "option": { + "Any": "", + "Under 1M": "u1", + "Under 5M": "u5", + "Under 10M": "u10", + "Under 20M": "u20", + "Under 50M": "u50", + "Under 100M": "u100", + "Over 1M": "o1", + "Over 2M": "o2", + "Over 5M": "o5", + "Over 10M": "o10", + "Over 20M": "o20", + "Over 50M": "o50", + "Over 100M": "o100", + "Over 200M": "o200", + "Over 500M": "o500", + "Over 1000M": "o1000", + }, + }, + "Float": { + "prefix": "sh_float", + "option": { + "Any": "", + "Under 1M": "u1", + "Under 5M": "u5", + "Under 10M": "u10", + "Under 20M": "u20", + "Under 50M": "u50", + "Under 100M": "u100", + "Over 1M": "o1", + "Over 2M": "o2", + "Over 5M": "o5", + "Over 10M": "o10", + "Over 20M": "o20", + "Over 50M": "o50", + "Over 100M": "o100", + "Over 200M": "o200", + "Over 500M": "o500", + "Over 1000M": "o1000", + }, + }, + }, + "order": { + "Ticker": "o=ticker", + "Company": "o=company", + "Sector": "o=sector", + "Industry": "o=industry", + "Country": "o=country", + "Market Cap.": "o=marketcap", + "Price/Earnings": "o=pe", + "Forward Price/Earnings": "o=forwardpe", + "PEG (Price/Earnings/Growth)": "o=peg", + "Price/Sales": "o=ps", + "Price/Book": "o=pb", + "Price/Cash": "o=pc", + "Price/Free Cash Flow": "o=pfcf", + "Dividend Yield": "o=dividendyield", + "Payout Ratio": "o=payoutratio", + "EPS (ttm)": "o=eps", + "EPS growth this year": "o=epsyoy", + "EPS growth next year": "o=epsyoy1", + "EPS growth past 5 years": "o=eps5years", + "EPS growth next 5 years": "o=estltgrowth", + "Sales growth past 5 years": "o=sales5years", + "EPS growth qtr over qtr": "o=epsqoq", + "Sales growth qtr over qtr": "o=salesqoq", + "Shares Outstanding": "o=sharesoutstanding2", + "Shares Float": "o=sharesfloat", + "Insider Ownership": "o=insiderown", + "Insider Transactions": "o=insidertrans", + "Institutional Ownership": "o=instown", + "Institutional Transactions": "o=insttrans", + "Short Interest Share": "o=shortinterestshare", + "Short Interest Ratio": "o=shortinterestratio", + "Earnings Date": "o=earningsdate", + "Return on Assets": "o=roa", + "Return on Equity": "o=roe", + "Return on Investment": "o=roi", + "Current Ratio": "o=curratio", + "Quick Ratio": "o=quickratio", + "LT Debt/Equity": "o=ltdebteq", + "Total Debt/Equity": "o=debteq", + "Gross Margin": "o=grossmargin", + "Operating Margin": "o=opermargin", + "Net Profit Margin": "o=netmargin", + "Analyst Recommendation": "o=recom", + "Performance (Week)": "o=perf1w", + "Performance (Month)": "o=perf4w", + "Performance (Quarter)": "o=perf13w", + "Performance (Half Year)": "o=perf26w", + "Performance (Year)": "o=perf52w", + "Performance (Year To Date)": "o=perfytd", + "Beta": "o=beta", + "Average True Range": "o=averagetruerange", + "Volatility (Week)": "o=volatility1w", + "Volatility (Month)": "o=volatility4w", + "20-Day SMA (Relative)": "o=sma20", + "50-Day SMA (Relative)": "o=sma50", + "200-Day SMA (Relative)": "o=sma200", + "50-Day High (Relative)": "o=high50d", + "50-Day Low (Relative)": "o=low50d", + "52-Week High (Relative)": "o=high52w", + "52-Week Low (Relative)": "o=low52w", + "Relative Strength Index (14)": "o=rsi", + "Average Volume (3 Month)": "o=averagevolume", + "Relative Volume": "o=relativevolume", + "Change": "o=change", + "Change from Open": "o=changeopen", + "Gap": "o=gap", + "Volume": "o=volume", + "Price": "o=price", + "Target Price": "o=targetprice", + "IPO Date": "o=ipodate", + }, +} diff --git a/setup.py b/setup.py index 65a830c..6f4fe8e 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ HERE = pathlib.Path(__file__).parent -VERSION = '0.10.1' +VERSION = '0.11' PACKAGE_NAME = 'finvizfinance' AUTHOR = 'Tianning Li' AUTHOR_EMAIL = 'ltianningli@gmail.com' @@ -22,9 +22,10 @@ 'lxml' ] CLASSIFIERS = [ - 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', 'License :: OSI Approved :: MIT License' ] PYTHON_REQUIRES='>=3.5' diff --git a/test/test_crypto.py b/test/test_crypto.py index 2d44ca8..b0630e7 100644 --- a/test/test_crypto.py +++ b/test/test_crypto.py @@ -7,8 +7,8 @@ def test_finvizfinance_crypto(): def test_finvizfinance_crypto_mock(mocker): - mocker.patch('finvizfinance.crypto.imageScrapFunction', return_value="imagescrapfunctionurl") + mocker.patch('finvizfinance.crypto.image_scrap_function', return_value="image_scrap_functionurl") fcrypto = Crypto() url = fcrypto.chart(crypto='test') - assert url == "imagescrapfunctionurl" + assert url == "image_scrap_functionurl" diff --git a/test/test_forex.py b/test/test_forex.py index b5ff79a..e088366 100644 --- a/test/test_forex.py +++ b/test/test_forex.py @@ -9,18 +9,18 @@ def test_forex_performance_percentage(): def test_forex_performance_pips(mocker): - mocker.patch('finvizfinance.forex.scrapFunction', return_value="df") + mocker.patch('finvizfinance.forex.scrap_function', return_value="df") fforex = Forex() df = fforex.performance(change='PIPS') assert (df is not None) def test_finvizfinance_crypto_mock(mocker): - mocker.patch('finvizfinance.forex.imageScrapFunction', return_value="imagescrapfunctionurl") + mocker.patch('finvizfinance.forex.image_scrap_function', return_value="image_scrap_functionurl") fforex = Forex() url = fforex.chart(forex='test') - assert url == "imagescrapfunctionurl" + assert url == "image_scrap_functionurl" def test_forex_performance_error(): diff --git a/test/test_group.py b/test/test_group.py index 79af6b7..d3120e6 100644 --- a/test/test_group.py +++ b/test/test_group.py @@ -1,5 +1,5 @@ def test_group_overview(): from finvizfinance.group.overview import Overview fgoverview = Overview() - df = fgoverview.ScreenerView(group='Industry') + df = fgoverview.screener_view(group='Industry') assert (df is not None) \ No newline at end of file diff --git a/test/test_insider.py b/test/test_insider.py index 71a8eac..f589785 100644 --- a/test/test_insider.py +++ b/test/test_insider.py @@ -3,12 +3,12 @@ def test_finvizfinance_insider(): finsider = Insider() - insider = finsider.getInsider() + insider = finsider.get_insider() assert(insider is not None) def test_finvizfinance_insider_option(mocker): - web_scrap_mock = mocker.patch('finvizfinance.insider.webScrap', return_value="dummy web scrap") + web_scrap_mock = mocker.patch('finvizfinance.insider.web_scrap', return_value="dummy web scrap") Insider() web_scrap_mock.assert_called_with('https://finviz.com/insidertrading.ashx') Insider('latest buys') diff --git a/test/test_news.py b/test/test_news.py index 29365b6..a668e42 100644 --- a/test/test_news.py +++ b/test/test_news.py @@ -1,7 +1,7 @@ def test_finvizfinance_news(): from finvizfinance.news import News fnews = News() - all_news = fnews.getNews() + all_news = fnews.get_news() news = all_news['news'] blogs = all_news['blogs'] assert(news is not None) diff --git a/test/test_quote.py b/test/test_quote.py index 3d5221d..d284e21 100644 --- a/test/test_quote.py +++ b/test/test_quote.py @@ -3,37 +3,37 @@ # def test_finvizfinance_quote(mocker): -# web_scrap_mock = mocker.patch('finvizfinance.quote.webScrap', return_value={"text": 'webScrap'}) +# web_scrap_mock = mocker.patch('finvizfinance.quote.web_scrap', return_value={"text": 'web_scrap'}) # Quote().getCurrent('ticker') # web_scrap_mock.assert_called_with('https://finviz.com/request_quote.ashx?t=ticker') def test_finvizfinance_finvizfinance(): stock = finvizfinance('tsla') - stock_info = stock.TickerFullInfo() + stock_info = stock.ticker_full_info() assert(stock_info is not None) def test_finvizfinance_finvizfinance_chart_invalid(mocker): mocker.patch('finvizfinance.quote.finvizfinance._checkexist', return_value=True) - mocker.patch('finvizfinance.quote.webScrap', return_value="") + mocker.patch('finvizfinance.quote.web_scrap', return_value="") with pytest.raises(ValueError, match=r"Invalid timeframe 'dummy'"): - finvizfinance('tsla').TickerCharts(timeframe='dummy') + finvizfinance('tsla').ticker_charts(timeframe='dummy') def test_statements(): fstatments = Statements() - df = fstatments.getStatements('tsla') + df = fstatments.get_statements('tsla') assert (df is not None) with pytest.raises(ValueError, match=r"Invalid chart type 'dummy'"): - finvizfinance('tsla').TickerCharts(charttype='dummy') + finvizfinance('tsla').ticker_charts(charttype='dummy') def test_finvizfinance_finvizfinance_chart(mocker): mocker.patch('finvizfinance.quote.finvizfinance._checkexist', return_value=True) - mocker.patch('finvizfinance.quote.webScrap', return_value="") - image_scrap_mock = mocker.patch('finvizfinance.quote.imageScrap') - finvizfinance('dummy').TickerCharts() + mocker.patch('finvizfinance.quote.web_scrap', return_value="") + image_scrap_mock = mocker.patch('finvizfinance.quote.image_scrap') + finvizfinance('dummy').ticker_charts() image_scrap_mock.assert_called_with( 'https://finviz.com/chart.ashx?t=dummy&ty=c&ta=1&p=d', 'dummy', '') diff --git a/test/test_screener.py b/test/test_screener.py index 730f790..97561dc 100644 --- a/test/test_screener.py +++ b/test/test_screener.py @@ -5,25 +5,25 @@ def test_screener_overview(): foverview = Overview() filters_dict = {'Exchange': 'AMEX', 'Sector': 'Basic Materials'} foverview.set_filter(filters_dict=filters_dict) - df = foverview.ScreenerView() + df = foverview.screener_view() assert(df is not None) ticker = 'TSLA' foverview.set_filter(signal='', filters_dict={}, ticker=ticker) - df = foverview.ScreenerView() + df = foverview.screener_view() assert(df is not None) def test_screener_get_settings(): foverview = Overview() - signals = foverview.getSignal() + signals = foverview.get_signal() assert type(signals) is list - filters = foverview.getFilters() + filters = foverview.get_filters() assert type(filters) is list - filter_options = foverview.getFilterOptions('Exchange') + filter_options = foverview.get_filter_options('Exchange') assert type(filter_options) is list with pytest.raises(ValueError): - foverview.getFilterOptions('Dummy') + foverview.get_filter_options('Dummy')