diff --git a/cli/openbb_cli/argparse_translator/argparse_translator.py b/cli/openbb_cli/argparse_translator/argparse_translator.py index 2715f2b39016..6ddbbf90740d 100644 --- a/cli/openbb_cli/argparse_translator/argparse_translator.py +++ b/cli/openbb_cli/argparse_translator/argparse_translator.py @@ -400,22 +400,23 @@ def execute_func( """ kwargs = self._unflatten_args(vars(parsed_args)) kwargs = self._update_with_custom_types(kwargs) - provider = kwargs.get("provider") - provider_args = [] + provider_args: List = [] if provider and provider in self.provider_parameters: provider_args = self.provider_parameters[provider] else: for args in self.provider_parameters.values(): provider_args.extend(args) - # remove kwargs that doesn't match the signature or provider parameters + # remove kwargs not matching the signature, provider parameters, or are empty. kwargs = { key: value for key, value in kwargs.items() - if key in self.signature.parameters or key in provider_args + if ( + (key in self.signature.parameters or key in provider_args) + and (value or value is False) + ) } - return self.func(**kwargs) def parse_args_and_execute(self) -> Any: @@ -426,6 +427,7 @@ def parse_args_and_execute(self) -> Any: Any: The return value of the original function. """ parsed_args = self._parser.parse_args() + return self.execute_func(parsed_args) def translate(self) -> Callable: diff --git a/openbb_platform/core/openbb_core/provider/standard_models/equity_screener.py b/openbb_platform/core/openbb_core/provider/standard_models/equity_screener.py index 97c5c10afa95..486eaa004208 100644 --- a/openbb_platform/core/openbb_core/provider/standard_models/equity_screener.py +++ b/openbb_platform/core/openbb_core/provider/standard_models/equity_screener.py @@ -1,8 +1,8 @@ """Equity Screener Standard Model.""" -from typing import List, Set, Union +from typing import Optional -from pydantic import Field, field_validator +from pydantic import Field from openbb_core.provider.abstract.data import Data from openbb_core.provider.abstract.query_params import QueryParams @@ -17,12 +17,4 @@ class EquityScreenerData(Data): """Equity Screener Data.""" symbol: str = Field(description=DATA_DESCRIPTIONS.get("symbol", "")) - name: str = Field(description="Name of the company.") - - @field_validator("symbol", mode="before", check_fields=False) - @classmethod - def to_upper(cls, v: Union[str, List[str], Set[str]]): - """Convert field to uppercase.""" - if isinstance(v, str): - return v.upper() - return ",".join([symbol.upper() for symbol in list(v)]) + name: Optional[str] = Field(default=None, description="Name of the company.") diff --git a/openbb_platform/extensions/equity/integration/test_equity_api.py b/openbb_platform/extensions/equity/integration/test_equity_api.py index b4ec503a4d4a..176106f89b08 100644 --- a/openbb_platform/extensions/equity/integration/test_equity_api.py +++ b/openbb_platform/extensions/equity/integration/test_equity_api.py @@ -1455,6 +1455,22 @@ def test_equity_search(params, headers): "provider": "nasdaq", } ), + ( + { + "metric": "overview", + "signal": None, + "preset": None, + "filters_dict": None, + "sector": "consumer_defensive", + "industry": "grocery_stores", + "index": "all", + "exchange": "all", + "mktcap": "all", + "recommendation": "all", + "limit": None, + "provider": "finviz", + } + ), ], ) @pytest.mark.integration diff --git a/openbb_platform/extensions/equity/integration/test_equity_python.py b/openbb_platform/extensions/equity/integration/test_equity_python.py index b7c33b102374..85405df2f2a4 100644 --- a/openbb_platform/extensions/equity/integration/test_equity_python.py +++ b/openbb_platform/extensions/equity/integration/test_equity_python.py @@ -1390,6 +1390,22 @@ def test_equity_search(params, obb): "provider": "nasdaq", } ), + ( + { + "metric": "overview", + "signal": None, + "preset": None, + "filters_dict": None, + "sector": "consumer_defensive", + "industry": "grocery_stores", + "index": "all", + "exchange": "all", + "mktcap": "all", + "recommendation": "all", + "limit": None, + "provider": "finviz", + } + ), ], ) @pytest.mark.integration diff --git a/openbb_platform/providers/finviz/README.md b/openbb_platform/providers/finviz/README.md index 6aecc472a454..6d31322955eb 100644 --- a/openbb_platform/providers/finviz/README.md +++ b/openbb_platform/providers/finviz/README.md @@ -2,6 +2,8 @@ This extension integrates the [Finviz](https://finviz.com/) data provider into the OpenBB Platform. +It will install, [finvizfinance](https://github.com/lit26/finvizfinance/), to power the functions. + ## Installation To install the extension: @@ -10,4 +12,100 @@ To install the extension: pip install openbb-finviz ``` -Documentation available [here](https://docs.openbb.co/platform/developer_guide/contributing). +## Endpoints + +- obb.equity.compare.groups +- obb.equity.estimates.price_target +- obb.equity.fundamental.metrics +- obb.equity.profile +- obb.equity.price.performance +- obb.equity.screener + +## Screener + +The screener is a faithful replication of the public-facing stock screener - https://finviz.com/screener.ashx? + +Some options are directly accessible through the function parameters, all others are exposed via `presets` or `filters_dict`. +The filters list below are exposed in the function, with choices visible in the docstring: + +- `exchange` +- `index` +- `sector` +- `industry` +- `mktcap` +- `recommendation` (analyst's mean score from 1-5) +- `signal` (same as the "Signal" on the Finviz page) + +When the function is run without any parameters, it will default to the "top_gainers" signal. + +```python +res = obb.equity.screener(provider="finviz") +``` + +### Metric + +The `metric` parameter defines the type of data fields to return. Choices are: + +- `overview` +- `ownership` +- `performance` +- `technical` +- `valuation` + +Default is, "overview". + +``` +res = obb.equity.screener(provider="finviz", metric="performance") +``` + +### Preset Files + +Presets can be created and customized in the "OpenBBUserData" folder. Template and default presets are created on the first run of the function. + +Files are loaded on runtime, changes are effective without restarting the Python interpreter. + +The `preset` parameter will override all others, except `metric` and `limit`. + +Run the function to create the template and default presets in your `OpenBBUserData` folder. + +Presets from the legacy OpenBB Terminal will continue to work, simply move your presets into the folder below. + +```python +res = obb.equity.screener(provider="finviz", index="nasdaq") +``` + +Then find the presets here: `$HOME/OpenBBUserData/presets/finviz` + +```python +res = obb.equity.screener(provider="finviz", preset="short_squeeze") +``` + +### Filters Dict + +The `filters_dict` parameter acts as an alternative to `preset`, accepting a dictionary or JSON encoded string. + +```python +res = obb.equity.screener(provider="finviz", filters_dict={"Index": "NASDAQ 100"}) +``` + +Or as a JSON: + +```python +res = obb.equity.screener(provider="finviz", filters_dict='{"Index": "NASDAQ 100"}') +``` + +When using the Fast API, this is sent in the request body. + +### Error Messages + +All parameters are validated, incorrect keys and choices will raise an error with information to help correct. For example: + +```python +obb.equity.screener(provider="finviz", filters_dict='{"Index": "NASDAQ"}') +``` + +```console +Invalid filter option 'NASDAQ'. Possible filter options: ['Any', 'S&P 500', 'NASDAQ 100', 'DJIA', 'RUSSELL 2000'] +``` + +Read the OpenBB Platform documentation [here](https://docs.openbb.co) diff --git a/openbb_platform/providers/finviz/openbb_finviz/__init__.py b/openbb_platform/providers/finviz/openbb_finviz/__init__.py index 8862746c64bb..7368e032f0a8 100644 --- a/openbb_platform/providers/finviz/openbb_finviz/__init__.py +++ b/openbb_platform/providers/finviz/openbb_finviz/__init__.py @@ -3,6 +3,7 @@ from openbb_core.provider.abstract.provider import Provider from openbb_finviz.models.compare_groups import FinvizCompareGroupsFetcher from openbb_finviz.models.equity_profile import FinvizEquityProfileFetcher +from openbb_finviz.models.equity_screener import FinvizEquityScreenerFetcher from openbb_finviz.models.key_metrics import FinvizKeyMetricsFetcher from openbb_finviz.models.price_performance import FinvizPricePerformanceFetcher from openbb_finviz.models.price_target import FinvizPriceTargetFetcher @@ -16,6 +17,7 @@ "CompareGroups": FinvizCompareGroupsFetcher, "EtfPricePerformance": FinvizPricePerformanceFetcher, "EquityInfo": FinvizEquityProfileFetcher, + "EquityScreener": FinvizEquityScreenerFetcher, "KeyMetrics": FinvizKeyMetricsFetcher, "PricePerformance": FinvizPricePerformanceFetcher, "PriceTarget": FinvizPriceTargetFetcher, diff --git a/openbb_platform/providers/finviz/openbb_finviz/models/equity_screener.py b/openbb_platform/providers/finviz/openbb_finviz/models/equity_screener.py new file mode 100644 index 000000000000..762cc492841c --- /dev/null +++ b/openbb_platform/providers/finviz/openbb_finviz/models/equity_screener.py @@ -0,0 +1,725 @@ +"""Finviz Equity Screener Model.""" + +# pylint: disable=unused-argument,too-many-statements,too-many-branches,too-many-locals + +from typing import Any, Dict, List, Literal, Optional, Union +from warnings import warn + +from openbb_core.app.model.abstract.error import OpenBBError +from openbb_core.provider.abstract.fetcher import Fetcher +from openbb_core.provider.standard_models.equity_screener import ( + EquityScreenerData, + EquityScreenerQueryParams, +) +from openbb_core.provider.utils.descriptions import ( + DATA_DESCRIPTIONS, + QUERY_DESCRIPTIONS, +) +from openbb_core.provider.utils.errors import EmptyDataError +from openbb_finviz.utils.screener_helper import ( + EXCHANGE_MAP, + INDEX_MAP, + INDUSTRY_MAP, + MARKET_CAP_MAP, + RECOMMENDATION_MAP, + SECTOR_MAP, + SIGNALS, + SIGNALS_DESC_STR, + MarketCap, + Recommendation, + Sectors, +) +from pydantic import Field, field_validator + + +class FinvizEquityScreenerQueryParams(EquityScreenerQueryParams): + """Finviz Equity Screener Query Params.""" + + __json_schema_extra__ = { + "metric": { + "choices": [ + "overview", + "valuation", + "financial", + "ownership", + "performance", + "technical", + ], + }, + "signal": {"choices": SIGNALS}, + "exchange": {"choices": list(EXCHANGE_MAP)}, + "index": {"choices": list(INDEX_MAP)}, + "sector": {"choices": list(SECTOR_MAP)}, + "industry": {"choices": list(INDUSTRY_MAP)}, + "market_cap": {"choices": list(MARKET_CAP_MAP)}, + "recommendation": {"choices": list(RECOMMENDATION_MAP)}, + } + + metric: Literal[ + "overview", + "valuation", + "financial", + "ownership", + "performance", + "technical", + ] = Field( + default="overview", + description="The data group to return, default is 'overview'.", + ) + exchange: Literal["all", "amex", "nasdaq", "nyse"] = Field( + default="all", description="Filter by exchange." + ) + index: Literal["all", "dow", "nasdaq", "sp500", "russell"] = Field( + default="all", + description="Filter by index.", + ) + sector: Sectors = Field( + default="all", + description="Filter by sector.", + ) + industry: Optional[str] = Field( + default="all", + description="Filter by industry.", + ) + mktcap: MarketCap = Field( + default="all", + description="Filter by market cap." + + "\n Mega - > 200B" + + "\n Large - 10B - 200B" + + "\n Mid - 2B - 10B" + + "\n Small - 300M - 2B" + + "\n Micro - 50M - 300M" + + "\n Nano - < 50M", + ) + recommendation: Recommendation = Field( + default="all", description="Filter by analyst recommendation." + ) + signal: Optional[str] = Field( + default=None, + description="The Finviz screener signal to use." + + " When no parameters are provided, the screener defaults to 'top_gainers'." + + f" Available signals are:{SIGNALS_DESC_STR}", + ) + preset: Optional[str] = Field( + default=None, + description="A configured preset file to use for the query." + + " This overrides all other query parameters except 'metric', and 'limit'." + + " Presets (.ini text files) can be created and modified in the '~/OpenBBUserData/finviz/presets' directory." + + " If the path does not exist, it will be created and populated with the default presets on the first run." + + " Refer to the file, 'screener_template.ini', for the format and options." + + "\n\nNote: Syntax of parameters in preset files must follow the template file exactly " + + " - i.e, Analyst Recom. = Strong Buy (1)", + ) + filters_dict: Optional[Union[Dict, str]] = Field( + default=None, + kw_only=True, + description="A formatted dictionary, or serialized JSON string, of additional filters to apply to the query." + + " This parameter can be used as an alternative to preset files, and is ignored when a preset is supplied." + + " Invalid entries will raise an error. Syntax should follow the 'screener_template.ini' file.", + ) + limit: Optional[int] = Field( + default=None, + description=QUERY_DESCRIPTIONS.get("limit", ""), + ) + + @field_validator("signal", mode="before", check_fields=False) + @classmethod + def validate_signal(cls, v): + """Validate the signal.""" + if v is not None and v not in SIGNALS: + raise OpenBBError( + f"Invalid signal '{v}'. Available signals are:\n{SIGNALS_DESC_STR}" + ) + return v if v else None + + @field_validator("industry", mode="before", check_fields=False) + @classmethod + def validate_industry(cls, v): + """Validate the industry.""" + if v is not None and v not in INDUSTRY_MAP: + raise OpenBBError( + f"Invalid industry '{v}'. Available industries are:\n{', '.join(INDUSTRY_MAP)}" + ) + return v if v else None + + @field_validator("preset", mode="before", check_fields=False) + @classmethod + def validate_preset(cls, v): + """Check to reject running template file.""" + if v is not None and v == "screener_template": + raise OpenBBError( + f"Invalid preset '{v}'. Please rename the file to use as a preset." + ) + return v if v else None + + @field_validator("filters_dict", mode="before", check_fields=False) + @classmethod + def validate_filters_dict(cls, v): + """Validate the filters_dict.""" + if isinstance(v, str): + # pylint: disable=import-outside-toplevel + import json + + try: + v = json.loads(v) + except json.JSONDecodeError as e: + raise OpenBBError(f"Invalid JSON format for 'filters_dict': {e}") from e + if v is not None and not isinstance(v, dict): + raise OpenBBError( + "Invalid 'filters_dict' format. Must be a dictionary or serialized JSON string." + ) + + return v + + +class FinvizEquityScreenerData(EquityScreenerData): + """Finviz Equity Screener Data. Actual returned data varies by the 'metric' parameter.""" + + __alias_dict__ = { + "symbol": "Ticker", + "name": "Company", + "earnings_date": "Earnings", + "sector": "Sector", + "industry": "Industry", + "country": "Country", + "shares_outstanding": "Outstanding", + "shares_float": "Float", + "short_interest": "Float Short", + "short_ratio": "Short Ratio", + "insider_ownership": "Insider Own", + "insider_ownership_change": "Insider Trans", + "institutional_ownership": "Inst Own", + "institutional_ownership_change": "Inst Trans", + "analyst_recommendation": "Recom", + "beta": "Beta", + "market_cap": "Market Cap", + "price": "Price", + "change_percent": "Change", + "change_from_open": "from Open", + "gap": "Gap", + "year_high_percent": "52W High", + "year_low_percent": "52W Low", + "sma20_percent": "SMA20", + "sma50_percent": "SMA50", + "sma200_percent": "SMA200", + "rsi": "RSI", + "volume": "Volume", + "volume_avg": "Avg Volume", + "volume_relative": "Rel Volume", + "average_true_range": "ATR", + "price_change_1W": "Perf Week", + "price_change_1M": "Perf Month", + "price_change_3M": "Perf Quart", + "price_change_6M": "Perf Half", + "price_change_1Y": "Perf Year", + "price_change_YTD": "Perf YTD", + "volatility_1W": "Volatility W", + "volatility_1M": "Volatility M", + "price_to_earnings": "P/E", + "forward_pe": "Fwd P/E", + "peg_ratio": "PEG", + "price_to_sales": "P/S", + "price_to_book": "P/B", + "price_to_cash": "P/C", + "price_to_free_cash_flow": "P/FCF", + "eps_growth_past_1Y": "EPS this Y", + "eps_growth_next_1Y": "EPS next Y", + "eps_growth_past_5Y": "EPS past 5Y", + "eps_growth_next_5Y": "EPS next 5Y", + "sales_growth_past_5Y": "Sales past 5Y", + "dividend_yield": "Dividend", + "return_on_assets": "ROA", + "return_on_equity": "ROE", + "return_on_investment": "ROI", + "current_ratio": "Curr R", + "quick_ratio": "Quick R", + "long_term_debt_to_equity": "LTDebt/Eq", + "debt_to_equity": "Debt/Eq", + "gross_margin": "Gross M", + "operating_margin": "Oper M", + "profit_margin": "Profit M", + } + + earnings_date: Optional[str] = Field( + default=None, + description="Earnings date, where 'a' and 'b' mean after and before market close, respectively.", + ) + country: Optional[str] = Field( + default=None, + description="Country of the company.", + ) + sector: Optional[str] = Field( + default=None, + description="Sector of the company.", + ) + industry: Optional[str] = Field( + default=None, + description="Industry of the company.", + ) + beta: Optional[float] = Field( + default=None, + description="Beta of the stock.", + ) + analyst_recommendation: Optional[float] = Field( + default=None, + description="Analyst's mean recommendation. (1=Buy 5=Sell).", + ) + market_cap: Optional[float] = Field( + default=None, + description="Market capitalization of the company.", + json_schema_extra={"x-unit_measurement": "currency"}, + ) + price: Optional[float] = Field( + default=None, + description="Price of a share.", + json_schema_extra={"x-unit_measurement": "currency"}, + ) + change_percent: Optional[float] = Field( + default=None, + description="Price change percentage.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + change_from_open: Optional[float] = Field( + default=None, + description="Price change percentage, from the opening price.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + gap: Optional[float] = Field( + default=None, + description="Price gap percentage, from the previous close.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + volume: Optional[Union[int, float]] = Field( + default=None, + description=DATA_DESCRIPTIONS.get("volume", ""), + ) + volume_avg: Optional[Union[int, float]] = Field( + default=None, + description="3-month average daily volume.", + ) + volume_relative: Optional[float] = Field( + default=None, + description="Current volume relative to the average.", + ) + average_true_range: Optional[float] = Field( + default=None, + description="Average true range (14).", + json_schema_extra={"x-unit_measurement:": "currency"}, + ) + price_change_1W: Optional[float] = Field( + default=None, + description="One-week price return.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + price_change_1M: Optional[float] = Field( + default=None, + description="One-month price return.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + price_change_3M: Optional[float] = Field( + default=None, + description="Three-month price return.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + price_change_6M: Optional[float] = Field( + default=None, + description="Six-month price return.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + price_change_1Y: Optional[float] = Field( + default=None, + description="One-year price return.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + price_change_YTD: Optional[float] = Field( + default=None, + description="Year-to-date price return.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + volatility_1W: Optional[float] = Field( + default=None, + description="One-week volatility.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + volatility_1M: Optional[float] = Field( + default=None, + description="One-month volatility.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + year_high_percent: Optional[float] = Field( + default=None, + description="Percent difference from current price to the 52-week high.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + year_low_percent: Optional[float] = Field( + default=None, + description="Percent difference from current price to the 52-week low.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + sma20_percent: Optional[float] = Field( + default=None, + description="Percent difference from current price to the 20-day simple moving average.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + sma50_percent: Optional[float] = Field( + default=None, + description="Percent difference from current price to the 50-day simple moving average.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + sma200_percent: Optional[float] = Field( + default=None, + description="Percent difference from current price to the 200-day simple moving average.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + rsi: Optional[float] = Field( + default=None, + description="Relative strength index (14).", + ) + shares_outstanding: Optional[Union[int, float]] = Field( + default=None, + description="Number of shares outstanding.", + ) + shares_float: Optional[Union[int, float]] = Field( + default=None, + description="Number of shares available to trade.", + ) + short_interest: Optional[float] = Field( + default=None, + description="Percent of float reported as short.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + short_ratio: Optional[float] = Field( + default=None, + description="Short interest ratio", + ) + insider_ownership: Optional[float] = Field( + default=None, + description="Insider ownership as a percentage.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + insider_ownership_change: Optional[float] = Field( + default=None, + description="6-month change in insider ownership percentage.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + institutional_ownership: Optional[float] = Field( + default=None, + description="Institutional ownership as a percentage.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + institutional_ownership_change: Optional[float] = Field( + default=None, + description="3-month change in institutional ownership percentage.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + price_to_earnings: Optional[float] = Field( + default=None, + description="Price to earnings ratio.", + ) + forward_pe: Optional[float] = Field( + default=None, + description="Forward price to earnings ratio.", + ) + peg_ratio: Optional[float] = Field( + default=None, + description="Price/Earnings-To-Growth (PEG) ratio.", + ) + price_to_sales: Optional[float] = Field( + default=None, + description="Price to sales ratio.", + ) + price_to_book: Optional[float] = Field( + default=None, + description="Price to book ratio.", + ) + price_to_cash: Optional[float] = Field( + default=None, + description="Price to cash ratio.", + ) + price_to_fcf: Optional[float] = Field( + default=None, + description="Price to free cash flow ratio.", + ) + eps_growth_past_1Y: Optional[float] = Field( + default=None, + description="EPS growth for this year.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + eps_growth_next_1Y: Optional[float] = Field( + default=None, + description="EPS growth next year.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + eps_growth_past_5Y: Optional[float] = Field( + default=None, + description="EPS growth for the previous 5 years.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + eps_growth_next_5Y: Optional[float] = Field( + default=None, + description="EPS growth for the next 5 years.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + sales_growth_past_5Y: Optional[float] = Field( + default=None, + description="Sales growth for the previous 5 years.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + dividend_yield: Optional[float] = Field( + default=None, + description="Annualized dividend yield.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + return_on_assets: Optional[float] = Field( + default=None, + description="Return on assets.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + return_on_equity: Optional[float] = Field( + default=None, + description="Return on equity.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + return_on_investment: Optional[float] = Field( + default=None, + description="Return on investment.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + current_ratio: Optional[float] = Field( + default=None, + description="Current ratio.", + ) + quick_ratio: Optional[float] = Field( + default=None, + description="Quick ratio.", + ) + long_term_debt_to_equity: Optional[float] = Field( + default=None, + description="Long term debt to equity ratio.", + ) + debt_to_equity: Optional[float] = Field( + default=None, + description="Total debt to equity ratio.", + ) + gross_margin: Optional[float] = Field( + default=None, + description="Gross margin.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + operating_margin: Optional[float] = Field( + default=None, + description="Operating margin.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + profit_margin: Optional[float] = Field( + default=None, + description="Profit margin.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + + +class FinvizEquityScreenerFetcher( + Fetcher[FinvizEquityScreenerQueryParams, List[FinvizEquityScreenerData]] +): + """Finviz Equity Screener Fetcher.""" + + @staticmethod + def transform_query(params: Dict[str, Any]) -> FinvizEquityScreenerQueryParams: + """Transform query parameters.""" + transformed_params = params.copy() + if not transformed_params.get("filters_dict"): + transformed_params["filters_dict"] = {} + return FinvizEquityScreenerQueryParams(**transformed_params) + + @staticmethod + def extract_data( # noqa = PRL0912 + query: FinvizEquityScreenerQueryParams, + credentials: Optional[Dict[str, str]], + **kwargs: Any, + ) -> List[Dict]: + """Extract data from Finviz.""" + # pylint: disable=import-outside-toplevel + import configparser # noqa + from finvizfinance.screener import ( + financial, + overview, + ownership, + performance, + technical, + valuation, + ) + from numpy import nan + from openbb_finviz.utils.screener_helper import ( + get_preset_choices, + d_check_screener, + d_signals, + ) + from pandas import DataFrame + + preset = None + + try: + data_dir = kwargs.get("preferences", {}).get("data_directory") + preset_choices = get_preset_choices(data_dir) + preset = query.preset + if preset is not None and preset not in preset_choices: + raise OpenBBError( + f"Invalid preset '{preset}'. Available presets are:\n{list(preset_choices)}" + ) + except Exception as e: + if preset is not None: + raise e from e + warn(f"Error loading presets: {e}") + preset = None + + data_type = query.metric + ascend = False + limit = query.limit + sleep = 0.1 # For optimized pagination speed without creating too many requests error from Finviz. + sort_by = "Change" + df_screen = DataFrame() + screen_type = { + "overview": overview.Overview, + "valuation": valuation.Valuation, + "financial": financial.Financial, + "ownership": ownership.Ownership, + "performance": performance.Performance, + "technical": technical.Technical, + } + + if data_type in screen_type: + screen = screen_type[data_type]() + + if preset is not None: + preset_filter = configparser.RawConfigParser() + preset_filter.optionxform = str # type: ignore + preset_filter.read(preset_choices[preset]) + d_general = preset_filter["General"] + d_filters = { + **preset_filter["Descriptive"], + **preset_filter["Fundamental"], + **preset_filter["Technical"], + } + for section in ["General", "Descriptive", "Fundamental", "Technical"]: + for key, val in {**preset_filter[section]}.items(): + if key not in d_check_screener: + raise OpenBBError( + f"The screener variable {section}.{key} shouldn't exist!\n" + ) + + if val not in d_check_screener[key]: + raise OpenBBError( + f"Invalid [{section}] {key}={val}. " + f"Choose one of the following options:\n{', '.join(d_check_screener[key])}.\n" + ) + + d_filters = {k: v for k, v in d_filters.items() if v is not None} + screen.set_filter(filters_dict=d_filters) + asc = None + + asc = d_general.get("Ascend") + + if asc is not None: + ascend = asc == "true" + + df_screen = screen.screener_view( + order=d_general.get("Order", "Change"), + limit=limit if limit else 100000, + ascend=ascend, + sleep_sec=sleep, + verbose=0, + ) + # If no preset is supplied, then set the filters based on the query parameters. + else: + if query.signal is not None: + screen.set_filter(signal=d_signals[query.signal]) + if query.signal in ["unusual_volume", "most_active"]: + sort_by = "Relative Volume" + elif query.signal == "top_losers": + ascend = True + elif query.signal in ["new_low", "multiple_bottom", "double_bottom"]: + sort_by = "52-Week Low (Relative)" + ascend = True + elif query.signal in ["new_high", "multiple_top", "double_top"]: + sort_by = "52-Week High (Relative)" + elif query.signal == "oversold": + sort_by = "Relative Strength Index (14)" + ascend = True + elif query.signal == "overbought": + sort_by = "Relative Strength Index (14)" + elif query.signal == "most_volatile": + sort_by = "Volatility (Week)" + else: + pass + + filters_dict: Dict = {} + + if query.sector != "all": + filters_dict["Sector"] = SECTOR_MAP[query.sector] + + if query.industry != "all": + filters_dict["Industry"] = INDUSTRY_MAP[query.industry] # type: ignore + + if query.exchange != "all": + filters_dict["Exchange"] = EXCHANGE_MAP[query.exchange] + + if query.index != "all": + filters_dict["Index"] = INDEX_MAP[query.index] + + if query.recommendation != "all": + filters_dict["Analyst Recom."] = RECOMMENDATION_MAP[ + query.recommendation + ] + + if query.mktcap != "all": + filters_dict["Market Cap."] = MARKET_CAP_MAP[query.mktcap] + + if query.filters_dict is not None: + _filters_dict = query.filters_dict.copy() # type: ignore + order = _filters_dict.pop("Order", None) + asc = _filters_dict.pop("Ascend", None) + if asc: + ascend = asc == "true" + if order: + sort_by = order + filters_dict.update(_filters_dict) + + if filters_dict: + screen.set_filter(filters_dict=filters_dict) + + if not filters_dict and query.signal is None: + screen.set_filter(signal=d_signals["top_gainers"]) + warn( + "No filters or signal provided. Defaulting to 'top_gainers' signal." + + " Use the preset, 'all_stocks', to explicitly return every stock on Finviz." + + " Returning 10K symbols can take several minutes." + ) + + df_screen = screen.screener_view( + order=sort_by, + limit=limit if limit else 100000, + ascend=ascend, + sleep_sec=sleep, + verbose=0, + ) + + if df_screen is None or df_screen.empty: + raise EmptyDataError( + "No tickers found for the supplied parameters. Try relaxing the constraints." + ) + + df_screen.columns = [val.strip("\n") for val in df_screen.columns] + # Commas in the company name can cause issues with delimiters. + if "Company" in df_screen.columns: + df_screen["Company"] = df_screen["Company"].str.replace(",", "") + + return df_screen.convert_dtypes().replace({nan: None}).to_dict(orient="records") + + @staticmethod + def transform_data( + query: FinvizEquityScreenerQueryParams, + data: List[Dict], + **kwargs: Any, + ) -> List[FinvizEquityScreenerData]: + """Transform data.""" + return [FinvizEquityScreenerData.model_validate(d) for d in data] diff --git a/openbb_platform/providers/finviz/openbb_finviz/utils/presets/__init__.py b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/__init__.py new file mode 100644 index 000000000000..ab1edf111b5b --- /dev/null +++ b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/__init__.py @@ -0,0 +1 @@ +"""Finviz Screener Presets.""" diff --git a/openbb_platform/providers/finviz/openbb_finviz/utils/presets/all_stocks.ini b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/all_stocks.ini new file mode 100644 index 000000000000..aa935e573263 --- /dev/null +++ b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/all_stocks.ini @@ -0,0 +1,12 @@ +# Author of preset: OpenBB +# Description: All stocks available from Finviz, with no filters. This preset will take a couple of minutes to execute, and may not be useful for most users. + +[General] + +Order = Market Cap. + +[Descriptive] + +[Fundamental] + +[Technical] diff --git a/openbb_platform/providers/finviz/openbb_finviz/utils/presets/analyst_strong_buy.ini b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/analyst_strong_buy.ini new file mode 100644 index 000000000000..b3220f2a66c7 --- /dev/null +++ b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/analyst_strong_buy.ini @@ -0,0 +1,17 @@ +# Author of preset: JohnnyDankseed +# Description: Analyst Strong Buy + +[General] + +Order = Change +Signal = Top Gainers + +[Descriptive] +Analyst Recom. = Strong Buy (1) + +[Fundamental] +Debt/Equity = Under 0.6 + +[Technical] +50-Day Simple Moving Average = Price above SMA50 +200-Day Simple Moving Average = Price above SMA200 diff --git a/openbb_platform/providers/finviz/openbb_finviz/utils/presets/buffet_like.ini b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/buffet_like.ini new file mode 100644 index 000000000000..6b06052985b1 --- /dev/null +++ b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/buffet_like.ini @@ -0,0 +1,18 @@ +# Author of preset: Traceabl3 +# Description: Buffet like value screener (Value invsting for long term growth) + +[General] + +[Descriptive] +Market Cap. = +Mid (over $2bln) +Dividend Yield = Positive (>0%) + +[Fundamental] +EPS growthnext 5 years = Positive (>0%) +Debt/Equity = Under 0.5 +Price/Free Cash Flow = Under 50 +Sales growthpast 5 years = Positive (>0%) +Return on Investment = Over +15% +P/B = Under 3 + +[Technical] \ No newline at end of file diff --git a/openbb_platform/providers/finviz/openbb_finviz/utils/presets/bull_runs_over_10pct.ini b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/bull_runs_over_10pct.ini new file mode 100644 index 000000000000..85f8d2fcfd1e --- /dev/null +++ b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/bull_runs_over_10pct.ini @@ -0,0 +1,13 @@ +# Author of preset: OpenBB +# Description: Bull runs over 10% + +[General] +Order = Change +Signal = Top Gainers + +[Descriptive] + +[Fundamental] + +[Technical] +Performance = Today +10% \ No newline at end of file diff --git a/openbb_platform/providers/finviz/openbb_finviz/utils/presets/cheap_dividend.ini b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/cheap_dividend.ini new file mode 100644 index 000000000000..ee2835209f72 --- /dev/null +++ b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/cheap_dividend.ini @@ -0,0 +1,14 @@ +# Author of preset: Traceabl3 +# Description: Cheap dividend stocks + +[General] +Signal = Oversold + +[Descriptive] +Dividend Yield = Over 1% + +[Fundamental] +P/E = Under 15 +P/B = Under 1 + +[Technical] \ No newline at end of file diff --git a/openbb_platform/providers/finviz/openbb_finviz/utils/presets/cheap_oversold.ini b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/cheap_oversold.ini new file mode 100644 index 000000000000..8eab824c36bc --- /dev/null +++ b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/cheap_oversold.ini @@ -0,0 +1,12 @@ +# Author of preset: Traceabl3 +# Description: Cheap stonks that are oversold: under 10% above the low, and oversold on the RSI. + +[General] + +[Descriptive] + +[Fundamental] + +[Technical] +52-Week High/Low = 0-10% above Low +RSI (14) = Oversold (20) \ No newline at end of file diff --git a/openbb_platform/providers/finviz/openbb_finviz/utils/presets/continued_momentum.ini b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/continued_momentum.ini new file mode 100644 index 000000000000..af73a8ecfc17 --- /dev/null +++ b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/continued_momentum.ini @@ -0,0 +1,20 @@ +# Author of preset: JohnnyDankseed +# Description: Continued Momentum Scan + +[General] +Order = Change +Signal = Top Gainers + +[Descriptive] +Market Cap. = -Mid (under $10bln) +Average Volume = Over 50K +Relative Volume = Over 2 +Current Volume = Over 1M +Price = Under $30 + +[Fundamental] + +[Technical] + +Beta = Over 1 +Volatility = Week - Over 3% \ No newline at end of file diff --git a/openbb_platform/providers/finviz/openbb_finviz/utils/presets/death_cross.ini b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/death_cross.ini new file mode 100644 index 000000000000..c57cefb7e5be --- /dev/null +++ b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/death_cross.ini @@ -0,0 +1,11 @@ +# Author of preset: Traceabl3 +# Description: When the 50 sma crosses below the 200 sma. More information can be found in https://www.investopedia.com/terms/d/deathcross.asp + +[General] + +[Descriptive] + +[Fundamental] + +[Technical] +200-Day Simple Moving Average = SMA200 crossed SMA50 above \ No newline at end of file diff --git a/openbb_platform/providers/finviz/openbb_finviz/utils/presets/golden_cross.ini b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/golden_cross.ini new file mode 100644 index 000000000000..8fb05cd1c1c4 --- /dev/null +++ b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/golden_cross.ini @@ -0,0 +1,11 @@ +# Author of preset: Traceabl3 +# Description: Golden Cross when the 50 day moves above the200 day from below. + +[General] + +[Descriptive] + +[Fundamental] + +[Technical] +50-Day Simple Moving Average = SMA50 crossed SMA200 above \ No newline at end of file diff --git a/openbb_platform/providers/finviz/openbb_finviz/utils/presets/growth_stocks.ini b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/growth_stocks.ini new file mode 100644 index 000000000000..c9ef7f28e3a6 --- /dev/null +++ b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/growth_stocks.ini @@ -0,0 +1,24 @@ +# Author of preset: JohnnyDankseed +# Description: Growth Stocks + +[General] +Order = PEG (Price/Earnings/Growth) +Signal = Top Gainers + +[Descriptive] +Market Cap. = +Micro (over $50mln) +Average Volume = Over 300K +Country = USA +Price = Over $10 + +[Fundamental] +EPS growthnext 5 years = Over 15% +Debt/Equity = Under 0.5 +PEG = Under 2 +EPS growththis year = Over 15% +EPS growthqtr over qtr = Over 15% +EPS growthpast 5 years = Over 15% + +[Technical] +20-Day Simple Moving Average = SMA20 above SMA200 +50-Day Simple Moving Average = SMA50 above SMA200 \ No newline at end of file diff --git a/openbb_platform/providers/finviz/openbb_finviz/utils/presets/heavy_inst_ins.ini b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/heavy_inst_ins.ini new file mode 100644 index 000000000000..07f9b9a8dfd7 --- /dev/null +++ b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/heavy_inst_ins.ini @@ -0,0 +1,15 @@ +# Author of preset: Traceabl3 +# Description: Heavily owned by institutions and insiders (>30% each) + +[General] + +[Descriptive] +Analyst Recom. = Hold or better + +[Fundamental] +InsiderOwnership = High (>30%) +InsiderTransactions = Positive (>0%) +PEG = Under 1 +InstitutionalOwnership = Over 30% + +[Technical] \ No newline at end of file diff --git a/openbb_platform/providers/finviz/openbb_finviz/utils/presets/large_cap_rsi20.ini b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/large_cap_rsi20.ini new file mode 100644 index 000000000000..605b49e67031 --- /dev/null +++ b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/large_cap_rsi20.ini @@ -0,0 +1,17 @@ +# Author of preset: OpenBB +# Description: Large caps with RSI under 20 + +[General] + +Order = Relative Strength Index (14) +Ascend = true + +[Descriptive] + +Market Cap. = +Large (over $10bln) + +[Fundamental] + +[Technical] + +RSI (14) = Oversold (20) diff --git a/openbb_platform/providers/finviz/openbb_finviz/utils/presets/large_cap_rsi80.ini b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/large_cap_rsi80.ini new file mode 100755 index 000000000000..95b6b4d4cf59 --- /dev/null +++ b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/large_cap_rsi80.ini @@ -0,0 +1,17 @@ +# Author of preset: OpenBB +# Description: Large caps with RSI over 80 + +[General] + +Order = Relative Strength Index (14) +Ascend = false + +[Descriptive] + +Market Cap. = +Large (over $10bln) + +[Fundamental] + +[Technical] + +RSI (14) = Overbought (80) diff --git a/openbb_platform/providers/finviz/openbb_finviz/utils/presets/modified_dreman.ini b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/modified_dreman.ini new file mode 100644 index 000000000000..81b77de635db --- /dev/null +++ b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/modified_dreman.ini @@ -0,0 +1,17 @@ +# Author of preset: Traceabl3 +# Description: Modified Version of the Dreman Screener. + +[General] + +Order = Dividend Yield + +[Descriptive] +Dividend Yield = Over 1% + +[Fundamental] +P/E = Under 20 +EPS growthnext 5 years = Positive Low (<10%) +Sales growthpast 5 years = Positive Low (0-10%) +EPS growththis year = Positive Low (0-10%) + +[Technical] \ No newline at end of file diff --git a/openbb_platform/providers/finviz/openbb_finviz/utils/presets/modified_neff.ini b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/modified_neff.ini new file mode 100644 index 000000000000..d634484b825a --- /dev/null +++ b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/modified_neff.ini @@ -0,0 +1,16 @@ +# Author of preset: Traceabl3 +# Description: Neff Screener with modifications // operational margin <50%. More information can be found in https://marketxls.com/template/neff-screen/ + +[General] + +Order = Sales growth past 5 years + +[Descriptive] + +[Fundamental] +Sales growthpast 5 years = Under 20% +PEG = Under 2 +EPS growththis year = Under 20% +Operating Margin = Under 50% + +[Technical] \ No newline at end of file diff --git a/openbb_platform/providers/finviz/openbb_finviz/utils/presets/profitable_low_price_sales.ini b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/profitable_low_price_sales.ini new file mode 100644 index 000000000000..4e96fa925802 --- /dev/null +++ b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/profitable_low_price_sales.ini @@ -0,0 +1,21 @@ +# Author of preset: OpenBB +# Description: Profitable companies with high sales growth, low P/S, and decent trading volume. + +[General] + +Order = Price/Sales +Ascend = true + +[Descriptive] + +Market Cap. = +Mid (over $2bln) +Average Volume = Over 1M + +[Fundamental] + +P/S = Under 10 +Sales growthqtr over qtr = High (>25%) +Sales growthpast 5 years = Over 30% +Net Profit Margin = Positive (>0%) + +[Technical] diff --git a/openbb_platform/providers/finviz/openbb_finviz/utils/presets/recent_growth_support.ini b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/recent_growth_support.ini new file mode 100644 index 000000000000..9f57f32fe86d --- /dev/null +++ b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/recent_growth_support.ini @@ -0,0 +1,19 @@ +# Author of preset: OpenBB +# Description: Recent Growth, Support + +[General] +Order = 200-Day SMA (Relative) +Signal = Top Gainers +Ascend = false + +[Descriptive] +Average Volume = Over 500K +Country = USA +Price = Over $10 + +[Fundamental] + +[Technical] +Performance = Quarter +20% +Performance 2 = Month +10% +Pattern = TL Support \ No newline at end of file diff --git a/openbb_platform/providers/finviz/openbb_finviz/utils/presets/screener_template.ini b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/screener_template.ini new file mode 100644 index 000000000000..5e9092479e7c --- /dev/null +++ b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/screener_template.ini @@ -0,0 +1,353 @@ +# Author of preset: OpenBBTerminal (https://github.com/OpenBB-finance/OpenBB) +# Description: Template with all available filters, with choices for each. +# More information can be found in https://finviz.com/help/screener.ashx +# and https://finviz.com/help/technical-analysis/charts-patterns.ashx + +# To use this template, place the file in your OpenBBUserData folder, `~/OpenBBUserData/presets/finviz` and then launch the program. +# Uncomment (remomve the "#") the lines below, containing,"=", corresponding with the filter you want to use. +# Valid choices for each filter are listed directly above the corresponding line to un-comment, i.e. "Order = Ticker". +# It is recommended to modify filters one-at-a-time. +# Presets are loaded on runtime, there is no need to restart the program after modifying a file. +# This file must be renamed in order to use it. + +[General] +# Ticker, Company, Sector, Industry, Country, Market Cap., Price/Earnings, Forward Price/Earnings, PEG (Price/Earnings/Growth), Price/Sales, Price/Book, Price/Cash, Price/Free Cash Flow, Dividend Yield, Payout Ratio, EPS (ttm), EPS growth this year, EPS growth next year, EPS growth past 5 years, EPS growth next 5 years, Sales growth past 5 years, EPS growth qtr over qtr, Sales growth qtr over qtr, Shares Outstanding, Shares Float, Insider Ownership, Insider Transactions, Institutional Ownership, Institutional Transactions, Short Interest Share, Short Interest Ratio, Earnings Date, Return on Assets, Return on Equity, Return on Investment, Current Ratio, Quick Ratio, LT Debt/Equity, Total Debt/Equity, Gross Margin, Operating Margin, Net Profit Margin, Analyst Recommendation, Performance (Week), Performance (Month), Performance (Quarter), Performance (Half Year), Performance (Year), Performance (Year To Date), Beta, Average True Range, Volatility (Week), Volatility (Month), 20-Day SMA (Relative), 50-Day SMA (Relative), 200-Day SMA (Relative), 50-Day High (Relative), 50-Day Low (Relative), 52-Week High (Relative), 52-Week Low (Relative), Relative Strength Index (14), Average Volume (3 Month), Relative Volume, Change, Change from Open, Gap, Volume, Price, Target Price, IPO Date + +#Order = Ticker + + +# true, false + +#Ascend = false + +# None (all stocks), 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 + +#Signal = Top Gainers + + +[Descriptive] +# Any, AMEX, NASDAQ, NYSE + +#Exchange = NASDAQ + + +# Any, Mega ($200bln and more), Large ($10bln to $200bln), Mid ($2bl to $10bln), Small ($300mln to $2bln), Micro ($50mln to $300mln), Nano (under $50mln), +Large (over $10bln), +Mid (over $2bln), +Small (over $300mln), +Micro (over $50mln), -Large (under $200bln), -Mid (under $10bln), -Small (under $2bln), -Micro (under $300mln) + +#Market Cap. = Large ($10bln to $200bln) + + +# Any, Today, Today Before Market Open, Today Before Market Close, Tomorrow, Tomorrow Before Market Open, Tomorrow Before Market Close, Yesterday, Yesterday Before Market Open, Yesterday Before Market Close, Next 5 Days, Previous 5 Days, This Week, Next Week, Previous Week, This Month + +#Earnings Date = Any + + +# Any, 50% Above Price, 40% Above Price, 30% Above Price, 20% Above Price, 10% Above Price, 5% Above Price, Above Price, Below Price, 5% Below Price, 10% Below Price, 20% Below Price, 30% Below Price, 40% Below Price, 50% Below Price + +#Target Price = Any + + +# Any, S&P 500, DJIA + +#Index = Any + + +# Any, None (0%), Positive (>0%), High (>5%), Very High (>10%), Over 1%, Over 2%, Over 3%, Over 4%, Over 5%, Over 6%, Over 7%, Over 8%, Over 9%, Over 10% + +#Dividend Yield = Over 5% + + +# Any, Under 50K, Under 100K, Under 500K, Under 750K, Under 1M, Over 50K, Over 100K, Over 300K, Over 400K, Over 500K, Over 750K, Over 1M, Over 2M, 100K to 500K, 100K to 1M, 500K to 1M, 500K to 10M + +#Average Volume = Over 1M + + +# Any, Today, Yesterday, In the last week, In the last month, In the last quarter, In the last year, In the last 2 years, In the last 3 years, In the last 5 years, More than a year ago, More that 5 years ago, More than 10 years ago, More than 15 years ago, More than 20 years ago, More than 25 years ago + +#IPO Date = Any + + +# Any, Basic Materials, Communication Services, Consumer Cyclical, Consumer Defensive, Energy, Financial, Healthcare, Industrials, Real Estate, Technology, Utilities + +#Sector = Technology + + +# Any, Low (<5%), High (>20%), Under 5%, Under 10%, Under 15%, Under 20%, Under 25%, Under 30%, Over 5%, Over 10%, Over 15%, Over 20%, Over 25%, Over 30% + +#Float Short = Any + + +# Any, Over 10, Over 5, Over 3, Over 2, Over 1.5, Over 1, Over 0.75, Over 0.5, Over 0.25, Under 2, Under 1, Under 1.5, Under 1, Under 0.75, Under 0.5, Under 0.25, Under 0.1 + +#Relative Volume = Over 1.5 + + +# Any, Under 1M, Under 5M, Under 10M, Under 20M, Under 50M, Under 100M, Over 1M, Over 2M, Over 5M, Over 10M, Over 20M, Over 50M, Over 100M, Over 200M, Over 500M, Over 1000M + +#Shares Outstanding = Any + + +# Any, Stocks only (ex-Funds), Exchange Traded Fund, Advertising Agencies, Aerospace & Defense, Agricultural Inputs, Airlines, Airports & Air Services, Aluminum, Apparel Manufacturing, Apparel Retail, Asset Management, Auto Manufacturers, Auto Parts, Auto & Truck Dealerships, Banks - Diversified, Banks - Regional, Beverages - Brewers, Beverages - Non-Alcoholic, Beverages - Wineries & Distilleries, Biotechnology, Broadcasting, Building Materials, Building Products & Equipment, Business Equipment & Supplies, Capital Markets, Chemicals, Closed-End Fund - Debt, Closed-End Fund - Equity, Closed-End Fund - Foreign, Coking Coal, Communication Equipment, Computer Hardware, Confectioners, Conglomerates, Consulting Services, Consumer Electronics, Copper, Credit Services, Department Stores, Diagnostics & Research, Discount Stores, Drug Manufacturers - General, Drug Manufacturers - Specialty & Generic, Education & Training Services, Electrical Equipment & Parts, Electronic Components, Electronic Gaming & Multimedia, Electronics & Computer Distribution, Engineering & Construction, Entertainment, Farm & Heavy Construction Machinery, Farm Products, Financial Conglomerates, Financial Data & Stock Exchanges, Food Distribution, Footwear & Accessories, Furnishings, Fixtures & Appliances, Gambling, Gold, Grocery Stores, Healthcare Plans, Health Information Services, Home Improvement Retail, Household & Personal Products, Industrial Distribution, Information Technology Services, Infrastructure Operations, Insurance Brokers, Insurance - Diversified, Insurance - Life, Insurance - Property & Casualty, Insurance - Reinsurance, Insurance - Specialty, Integrated Freight & Logistics, Internet Content & Information, Internet Retail, Leisure, Lodging, Lumber & Wood Production, Luxury Goods, Marine Shipping, Medical Care Facilities, Medical Devices, Medical Distribution, Medical Instruments & Supplies, Metal Fabrication, Mortgage Finance, Oil & Gas Drilling, Oil & Gas E&P, Oil & Gas Equipment & Services, Oil & Gas Integrated, Oil & Gas Midstream, Oil & Gas Refining & Marketing, Other Industrial Metals & Mining, Other Precious Metals & Mining, Packaged Foods, Packaging & Containers, Paper & Paper Products, Personal Services, Pharmaceutical Retailers, Pollution & Treatment Controls, Publishing, Railroads, Real Estate - Development, Real Estate - Diversified, Real Estate Services, Recreational Vehicles, REIT - Diversified, REIT - Healthcare Facilities, REIT - Hotel & Motel, REIT - Industrial, REIT - Mortgage, REIT - Office, REIT - Residential, REIT - Retail, REIT - Specialty, Rental & Leasing Services, Residential Construction, Resorts & Casinos, Restaurants, Scientific & Technical Instruments, Security & Protection Services, Semiconductor Equipment & Materials, Semiconductors, Shell Companies, Silver, Software - Application, Software - Infrastructure, Solar, Specialty Business Services, Specialty Chemicals, Specialty Industrial Machinery, Specialty Retail, Staffing & Employment Services, Steel, Telecom Services, Textile Manufacturing, Thermal Coal, Tobacco, Tools & Accessories, Travel Services, Trucking, Uranium, Utilities - Diversified, Utilities - Independent Power Producers, Utilities - Regulated Electric, Utilities - Regulated Gas, Utilities - Regulated Water, Utilities - Renewable, Waste Management + +#Industry = Any + + +# Any, Strong Buy (1), Buy or better, Buy, Hold or better, Hold, Hold or worse, Sell, Sell or worse, Strong Sell (5) + +#Analyst Recom. = Any + + +# Any, Under 100K, Under 500K, Under 750K, Under 1M, Over 0, Over 50K, Over 100K, Over 200K, Over 300K, Over 400K, Over 500K, Over 750K, Over 1M, Over 2M, Over 5M, Over 10M, Over 20M + +#Current Volume = Any + + +# Any, Under 1M, Under 5M, Under 10M, Under 20M, Under 50M, Under 100M, Over 1M, Over 2M, Over 5M, Over 10M, Over 20M, Over 50M, Over 100M, Over 200M, Over 500M, Over 1000M + +#Float = Any + + +# Any, Asia, Europe, Latin America, BRIC, Argentina, Australia, Bahamas, Belgium, BeNeLux, Bermuda, Brazil, Canada, Cayman Islands, Chile, China, China & Hong Kong, Colombia, Cyprus, Denmark, Finland, France, Germany, Greece, Hong Kong, Hungary, Iceland, India, Indonesia, Ireland, Israel, Italy, Japan, Kazakhstan, Luxembourg, Malaysia, Malta, Mexico, Monaco, Netherlands, New Zealand, Norway, Panama, Peru, Philippines, Portugal, Russia, Singapore, South Africa, South Korea, Spain, Sweden, Switzerland, Taiwan, Turkey, United Arab Emirates, United Kingdom, Uruguay + +#Country = Any + + +# Any, Optionable, Shortable, Optionable and shortable + +#Option/Short = Any + + +# Any, Under $1, Under $2, Under $3, Under $4, Under $5, Under $7, Under $10, Under $15, Under $20, Under $30, Under $40, Under $50, Over $1, Over $2, Over $3, Over $4, Over $5 ,Over $7, Over $10, Over $15, Over $20, Over $30, Over $40, Over $50, Over $60, Over $70, Over $80, Over $90, Over $100, $1 to $5, $1 to $10, $1 to $20, $5 to $10, $5 to $20, $5 to $50, $10 to $20, $10 to $50, $20 to $50, $50 to $100 + +#Price = Any + + +[Fundamental] +# Any, Low (<15), Profitable (>0), High (>50), Under 5, Under 10, Under 15, Under 20, Under 25, Under 30, Under 35, Under 40, Under 45, Under 50, Over 5, Over 10, Over 15, Over 25, Over 30, Over 35, Over 40, Over 45, Over 50 + +#P/E = Any + + +# Any, Low (<3), High (>50), Under 1, Under 2, Under 3, Under 4, Under 5, Under 6, Under 7, Under 8, Under 9, Under 10, Over 1, Over 2, Over 3, Over 4, Over 5, Over 6, Over 7, Over 8, Over 9, Over 10, Over 20, Over 30, Over 40, Over 50 + +#Price/Cash = Any + + +# Any, Negative (<0%), Positive (>0%), Positive Low (<10%), High (>25%), Under 5%, Under 10%, Under 15%, Under 20%, Under 25%, Under 30%, Over 5%, Over 10%, Over 15%, Over 20%, Over 25%, Over 30% + +#EPS growthnext 5 years = Any + + +# Any, Positive (>0%), Negative (<0%), Very Positive (>30%), Very Negative (<-15%), Under -50%, Under -40%, Under -35%, Under -30%, Under -25%, Under -20%, Under -15%, Under -10%, Under -5%, Over +50%, Over +45%, Over +40%, Over +35%, Over +30%, Over +25%, Over +20%, Over +15%, Over +10%, Over +5% + +#Return on Equity = Any + + +# Any, High (>0.5), Low (<0.1), Under 1, Under 0.9, Under 0.8, Under 0.7, Under 0.6, Under 0.5, Under 0.4, Under 0.3, Under 0.2, Under 0.1, Over 0.1, Over 0.2, Over 0.3, Over 0.4, Over 0.5, Over 0.6, Over 0.7, Over 0.8, Over 0.9, Over 1 + +#Debt/Equity = Any + + +# Any, Low (<5%), High (>30%), Very High (>50%), Over 10%, Over 20%, Over 30%, Over 40%, Over 50%, Over 60%, Over 70%, Over 80%, Over 90% + +#InsiderOwnership = Any + + +# Any, Low (<15), Profitable (>0), High (>50), Under 5, Under 10, Under 15, Under 20, Under 25, Under 30, Under 35, Under 40, Under 45, Under 50, Over 5, Over 10, Over 15, Over 20, Over 25, Over 30, Over 35, Over 40, Over 45, Over 50 + +#Forward P/E = Any + + +# Any, Low (<15), High (>50), Under 5, Under 10, Under 15, Under 20, Under 25, Under 30, Under 35, Under 40, Under 45, Under 50, Under 60, Under 70, Under 80, Under 90, Under 100, Over 5, Over 10, Over 15, Over 20, Over 25, Over 30, Over 35, Over 40, Over 45, Over 50, Over 60, Over 70, Over 80, Over 90, Over 100 + +#Price/Free Cash Flow = Any + + +# Any, Negative (<0%), Positive (>0%), Positive Low (0-10%), High (>25%), Under 5%, Under 10%, Under 15%, Under 20%, Under 25%, Under 30%, Over 5%, Over 10%, Over 15%, Over 20%, Over 25%, Over 30% + +#Sales growthpast 5 years = Any + + +# Any, Positive (>0%), Negative (<0%), Very Positive (>25%), Very Negative (<-10%), Under -50%, Under -45%, Under -40%, Under -35%, Under -30%, Under -25%, Under -20%, Under -15%, Under -10%, Under -5%, Over +5%, Over +10%, Over +15%, Over +20%, Over +25%, Over +30%, Over +35%, Over +40%, Over +45%, Over +50% + +#Return on Investment = Any + + +# Any, Positive (>0%), Negative (<0%), High (>50%), Under 90%, Under 80%, Under 70%, Under 60%, Under 50%, Under 45%, Under 40%, Under 35%, Under 30%, Under 25%, Under 20%, Under 15%, Under 10%, Under 5%, Under 0%, Under -10%, Under -20%, Under -30%, Under -50%, Under -70%, Under -100%, Over 0%, Over 5%, Over 10%, Over 15%, Over 20%, Over 25%, Over 30%, Over 40%, Over 45%, Over 50%, Over 60%, Over 70%, Over 80%, Over 90% + +#Gross Margin = Any + + +# Any, Very Negative (<20%), Negative (<0%), Positive (>0%), Very Positive (>20%), Under -90%, Under -80%, Under -70%, Under -60%, Under -50%, Under -45%, Under -40%, Under -35%, Under -30%, Under -25%, Under -20%, Under -15%, Under -10%, Under -5%, Over +5%, Over +10%, Over +15%, Over +20%, Over +25%, Over +30%, Over +35%, Over +40%, Over +45%, Over +50%, Over +60%, Over +70%, Over +80%, Over +90% + +#InsiderTransactions = Any + + +# Any, Low (<1), High (>2), Under 1, Under 2, Under 3, Over 1, Over 2, Over 3 + +#PEG = Any + + +# Any, Negative (<0%), Positive (>0%), Positive Low (0-10%), High (>25%), Under 5%, Under 10%, Under 15%, Under 20%, Under 25%, Under 30%, Over 5%, Over 10%, Over 15%, Over 20%, Over 25%, Over 30% + +#EPS growththis year = Any + + +# Any, Negative (<0%), Positive (>0%), Positive Low (0-10%), High (>25%), Under 5%, Under 10%, Under 15%, Under 20%, Under 25%, Under 30%, Over 5%, Over 10%, Over 15%, Over 20%, Over 25%, Over 30% + +#EPS growthqtr over qtr = Any + + +# Any, High (>3), Low (<1), Under 1, Under 0.5, Over 0.5, Over 1, Over 1.5, Over 2, Over 3, Over 4, Over 5, Over 10 + +#Current Ratio = Any + + +# Any, Negative (<0%), Positive (>0%), Very Negative (<-20%), High (>25%), Under 90%, Under 80%, Under 70%, Under 60%, Under 50%, Under 45%, Under 40%, Under 35%, Under 30%, Under 25%, Under 20%, Under 15%, Under 10%, Under 5%, Under 0%, Under -10%, Under -20%, Under -30%, Under -50%, Under -70%, Under -100%, Over 0%, Over 10%, Under 15%, Over 20%, Over 25%, Over 30%, Over 35%, Over 40%, Over 45%, Over 50%, Over 60%, Over 70%, Over 80%, Over 90% + +#Operating Margin = Any + + +# Any, Low (<5%), High (>90%), Under 90%, Under 80%, Under 70%, Under 60%, Under 50%, Under 40%, Under 30%, Under 20%, Under 10%, Over 10%, Over 20%, Over 30%, Over 40%, Over 50%, Over 60%, Over 70%, Over 80%, Over 90% + +#InstitutionalOwnership = Any + + +# Any, Low (<1), High (>10), Under 1, Under 2, Under 3, Under 4, Under 5, Under 6, Under 7, Under 8, Under 9, Under 10, Over 1, Over 2, Over 3, Over 4, Over 5, Over 6, Over 6, Over 7, Over 8, Over 9, Over 10 + +#P/S = Any + + +# Any, Negative (<0%), Positive (>0%), Positive Low (0-10%), High (>25%), Under 5%, Under 10%, Under 15%, Under 20%, Under 25%, Under 30%, Over 5%, Over 10%, Over 15%, Over 20%, Over 25%, Over 30% + +#EPS growthnext year = Any + + +# Any, Negative (<0%), Positive (>0%), Positive Low (0-10%), High (>25%), Under 5%, Under 10%, Under 15%, Under 20%, Under 25%, Under 30%, Over 5%, Over 10%, Over 15%, Over 20%, Over 25%, Over 30% + +#Sales growthqtr over qtr = Any + + +# Any, High (>3), Low (<0.5), Under 1, Under 0.5, Over 0.5, Over 1, Over 1.5, Over 2, Over 3, Over 4, Over 5, Over 10 + +#Quick Ratio = Any + + +# Any, Positive (>0%), Negative (<0%), Very Negative (<-20%), High (>20%), Under 90%, Under 80%, Under 70%, Under 60%, Under 50%, Under 45%, Under 40%, Under 35%, Under 30%, Under 25%, Under 20%, Under 15%, Under 10%, Under 5%, Under 0%, Under -10%, Under -20%, Under -30%, Under -50%, Under -70%, Under -100%, Over 0%, Over 5%, Over 10%, Over 15%, Over 20%, Over 25%, Over 30%, Over 35%, Over 40%, Over 45%, Over 50%, Over 60%, Over 70%, Over 80%, Over 90% + +#Net Profit Margin = Any + + +# Any, Very Negative (<20%), Negative (<0%), Positive (>0%), Very Positive (>20%), Under -50%, Under -45%, Under -40%, Under -35%, Under -30%, Under -25%, Under -20%, Under -15%, Under -10%, Under -5%, Over +5%, Over +10%, Over +15%, Over +20%, Over +25%, Over +30%, Over +35%, Over +40%, Over +45%, Over +50% + +#InstitutionalTransactions = Any + + +# Any, Low (<1), High (>5), Under 1, Under 2, Under 3, Under 4, Under 5, Under 6, Under 7, Under 8, Under 9, Under 10, Over 1, Over 2, Over 3, Over 4, Over 5, Over 6, Over 7, Over 8, Over 9, Over 10 + +#P/B = Any + + +# Any, Negative (<0%), Positive (>0%), Positive Low (0-10%), High (>25%), Under 5%, Under 10%, Under 15%, Under 20%, Under 25%, Under 30%, Over 5%, Over 10%, Over 15%, Over 20%, Over 25%, Over 30% + +#EPS growthpast 5 years = Any + + +# Any, Positive (>0%), Negative (<0%), Very Positive (>15%), Very Negative (<-15%), Under -50%, Under -45%, Under -40%, Under -35%, Under -30%, Under -25%, Under -20%, Under -15%, Under -10%, Under -5%, Over +5%, Over +10%, Over +15%, Over +20%, Over +25%, Over +30%, Over +35%, Over +40%, Over +45%, Over +50% + +#Return on Assets = Any + + +# Any, High (>0.5), Low (<0.1), Under 1, Under 0.9, Under 0.8, Under 0.7, Under 0.6, Under 0.5, Under 0.4, Under 0.3, Under 0.2, Under 0.1, Over 0.1, Over 0.2, Over 0.3, Over 0.4, Over.5, Over 0.6, Over 0.7, Over 0.8, Over 0.9, Over 1 + +#LT Debt/Equity = Any + + +# Any, None (0%), Positive (>0%), Low (<20%), High (>50%), Over 0%, Over 10%, Over 20%, Over 30%, Over 40%, Over 50%, Over 60%, Over 70%, Over 80%, Over 90%, Over 100%, Under 10%, Under 20%, Under 30%, Under 40%, Under 50%, Under 60%, Under 70%, Under 80%, Under 90%, Under 100% + +#Payout Ratio = Any + + +[Technical] +# Any, Today Up, Today Down, Today -15%, Today -10%, Today -5%, Today +5%, Today +10%, Today +15%, Week -30%, Week -20%, Week -10%, Week Down, Week Up, Week +10%, Week +20%, Week +30%, Month -50%, Month -30%, Month -20%, Month -10%, Month Down, Month Up, Month +10%, Month +20%, Month +30%, Month +50%, Quarter -50%, Quarter -30%, Quarter -20%, Quarter -10%, Quarter Down, Quarter Up, Quarter +10%, Quarter +20%, Quarter +30%, Quarter +50%, Half -75%, Half -50%, Half -30%, Half -20%, Half -10%, Half Down, Half Up, Half +10%, Half +20%, Half +30%, Half +50%, Half +100%, Year -75%, Year -50%, Year -30%, Year -20%, Year -10%, Year Down, Year Up, Year +10%, Year +20%, Year +30%, Year +50%, Year +100%, Year +200%, Year +300%, Year +500%, YTD -75%, YTD -50%, YTD -30%, YTD -20%, YTD -10%, YTD -5%, YTD Down, YTD Up, YTD +5%, YTD +10%, YTD +20%, YTD +30, YTD +50%, YTD +100% + +#Performance = Any + + +# Any, Price below SMA20, Price 10% below SMA20, Price 20% below SMA20, Price 30% below SMA20, Price 40% below SMA20, Price 50% below SMA20, Price above SMA20, Price 10% above SMA20, Price 20% above SMA20, Price 30% above SMA20, Price 40% above SMA20, Price 50% above SMA20, Price crossed SMA20, Price crossed SMA20 above, Price crossed SMA20 below, SMA20 crossed SMA50, SMA20 crossed SMA50 above, SMA20 crossed SMA50 below, SMA20 cross SMA200, SMA20 crossed SMA200 below, SMA20 crossed SMA200 above, SMA20 above SMA50, SMA20 below SMA50, SMA20 above SMA200, SMA20 below SMA200 + +#20-Day Simple Moving Average = Any + + +# Any, New High, New Low, 5% or more below High, 10% or more below High, 15% or more below High, 20% or more below High, 30% or more below High, 40% or more below High, 50% or more below High, 0-3% below High, 0-5% below High, 0-10% below High, 5% or more above Low, 10% or more above Low, 15% or more above Low, 20% or more above Low, 30% or more above Low, 40% or more above Low, 50% or more above Low, 0-3% above Low, 0-5% above Low, 0-10% above Low + +#20-Day High/Low = Any + + +# Any, Under 0, Under 0.5, Under 1, Under 1.5, Under 2, Over 0, Over 0.5, Over 1, Over 1.5, Over 2, Over 2.5, Over 3, Over 4, 0 to 0.5, 0 to 1, 0.5 to 1, 0.5 to 1.5, 1 to 1.5, 1 to 2 + +#Beta = Any + + +# Any, Today Up, Today Down, Today -15%, Today -10%, Today -5%, Today +5%, Today +10%, Today +15%, Week -30%, Week -20%, Week -10%, Week Down, Week Up, Week +10%, Week +20%, Week +30%, Month -50%, Month -30%, Month -20%, Month -10%, Month Down, Month Up, Month +10%, Month +20%, Month +30%, Month +50%, Quarter -50%, Quarter -30%, Quarter -20%, Quarter -10%, Quarter Down, Quarter Up, Quarter +10%, Quarter +20%, Quarter +30%, Quarter +50%, Half -75%, Half -50%, Half -30%, Half -20%, Half -10%, Half Down, Half Up, Half +10%, Half +20%, Half +30%, Half +50%, Half +100%, Year -75%, Year -50%, Year -30%, Year -20%, Year -10%, Year Down, Year Up, Year +10%, Year +20%, Year +30%, Year +50%, Year +100%, Year +200%, Year +300%, Year +500%, YTD -75%, YTD -50%, YTD -30%, YTD -20%, YTD -10%, YTD -5%, YTD Down, YTD Up, YTD +5%, YTD +10%, YTD +20%, YTD +30, YTD +50%, YTD +100% + +#Performance 2 = Any + + +# Any, Price below SMA50, Price 10% below SMA50, Price 20% below SMA50, Price 30% below SMA50, Price 40% below SMA50, Price 50% below SMA50, Price above SMA50, Price 10% above SMA50, Price 20% above SMA50, Price 30% above SMA50, Price 40% above SMA50, Price 50% above SMA50, Price crossed SMA50, Price crossed SMA50 above, Price crossed SMA50 below, SMA50 crossed SMA20, SMA50 crossed SMA20 above, SMA50 crossed SMA20 below, SMA50 cross SMA200, SMA50 crossed SMA200 below, SMA50 crossed SMA200 above, SMA50 above SMA20, SMA50 below SMA20, SMA50 above SMA200, SMA50 below SMA200 + +#50-Day Simple Moving Average = Any + + +# Any, New High, New Low, 5% or more below High, 10% or more below High, 15% or more below High, 20% or more below High, 30% or more below High, 40% or more below High, 50% or more below High, 0-3% below High, 0-5% below High, 0-10% below High, 5% or more above Low, 10% or more above Low, 15% or more above Low, 20% or more above Low, 30% or more above Low, 40% or more above Low, 50% or more above Low, 0-3% above Low, 0-5% above Low, 0-10% above Low + +#50-Day High/Low = Any + + +# Any, Over 0.25, Over 0.5, Over 0.75, Over 1, Over 1.5, Over 2. Over 2.5, Over 3, Over 3.5, Over 4, Over 4.5, Over 5, Under 0.25, Under 0.5, Under 0.75, Under 1, Under 1.5, Under 2, Under 2.5, Under 3, Under 3.5, Under 4, Under 4.5, Under 5 + +#Average True Range = Any + + +# Any, Week - Over 3%, Week - Over 4%, Week - Over 5%, Week - Over 6%, Week - Over 7%, Week - Over 8%, Week - Over 9%, Week - Over 10%, Week - Over 12%, Week - Over 15%, Month - Over2%, Month - Over3%, Month - Over4%, Month - Over 5%, Month - Over 5%, Month - Over 6%, Month - Over 7%, Month - Over 8%, Month - Over 9%, Month - Over 10%, Month - Over 12%, Month - Over 15% + +#Volatility = Any + + +# Any, Price below SMA200, Price 10% below SMA200, Price 20% below SMA200, Price 30% below SMA200, Price 40% below SMA200, Price 50% below SMA200, Price above SMA200, Price 10% above SMA200, Price 20% above SMA200, Price 30% above SMA200, Price 40% above SMA200, Price 50% above SMA200, Price crossed SMA200, Price crossed SMA200 above, Price crossed SMA200 below, SMA200 crossed SMA20, SMA20 crossed SMA20 above, SMA20 crossed SMA20 below, SMA200 cross SMA50, SMA200 crossed SMA50 below, SMA200 crossed SMA50 above, SMA200 above SMA20, SMA200 below SMA20, SMA200 above SMA50, SMA200 below SMA50 + +#200-Day Simple Moving Average = Any + + +# Any, New High, New Low, 5% or more below High, 10% or more below High, 15% or more below High, 20% or more below High, 30% or more below High, 40% or more below High, 50% or more below High, 0-3% below High, 0-5% below High, 0-10% below High, 5% or more above Low, 10% or more above Low, 15% or more above Low, 20% or more above Low, 30% or more above Low, 40% or more above Low, 50% or more above Low, 0-3% above Low, 0-5% above Low, 0-10% above Low + +#52-Week High/Low = Any + + +# Any, Overbought (90), Overbought (80), Overbought (70), Overbought (60), Oversold (40), Oversold (30), Oversold (20), Oversold (10), Not Overbought (<60), Not Overbought (<50), Not Oversold (>50), Not Oversold (>40) + +#RSI (14) = Any + + +# Any, Up, Up 1%, Up 2%, Up 3%, Up 4%, Up 5%, Up 6%, Up 7%, Up 8%, Up 9%, Up 10%, Up 15%, Up 20%, Down, Down 1%, Down 2%, Down 3%, Down 4%, Down 5%, Down 6%, Down 7%, Down 8%, Down 9%, Down 10%, Down 15%, Down 20% + +#Change = Any + + +# Any, Horizontal S/R, Horizontal S/R (Strong), TL Resistance, TL Resistance (Strong), TL Support, TL Support (Strong), Wedge Up, Wedge Up (Strong), Wedge Down, Wedge Down (Strong), Triangle Ascending, Triangle Ascending (Strong), Triangle Descending, Triangle Descending (Strong), Wedge, Wedge (Strong), Channel Up, Channel Up (Strong), Channel Down, Channel Down (Strong), Channel, Channel (Strong), Double Top, Double Bottom, Multiple Top, Multiple Bottom, Head & Shoulders, Head & Shoulders Inverse + +#Pattern = Any + + +# Any, Up, Up 1%, Up 2%, Up 3%, Up 4%, Up 5%, Up 6%, Up 7%, Up 8%, Up 9%, Up 10%, Up 15%, Up 20%, Down, Down 1%, Down 2%, Down 3%, Down 4%, Down 5%, Down 6%, Down 7%, Down 8%, Down 9%, Down 10%, Down 15%, Down 20% + +#Gap = Any + + +# Any, Up, Up 1%, Up 2%, Up 3%, Up 4%, Up 5%, Up 6%, Up 7%, Up 8%, Up 9%, Up 10%, Up 15%, Up 20%, Down, Down 1%, Down 2%, Down 3%, Down 4%, Down 5%, Down 6%, Down 7%, Down 8%, Down 9%, Down 10%, Down 15%, Down 20% + +#Change from Open = Any + + +# Any, Long Lower Shadow, Long Upper Shadow, Hammer, Inverted Hammer, Spinning Top White, Spinning Top Black, Doji, Dragonfly Doji, Gravestone Doji, Marubozu White, Marubozu Black + +#Candlestick = Any diff --git a/openbb_platform/providers/finviz/openbb_finviz/utils/presets/short_squeeze.ini b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/short_squeeze.ini new file mode 100644 index 000000000000..04d219857059 --- /dev/null +++ b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/short_squeeze.ini @@ -0,0 +1,20 @@ +# Author of preset: OpenBB +# Description: Short Squeeze Candidates + +[General] +Order = Relative Volume +Ascend = false +Signal = Top Gainers + +[Descriptive] + +Float Short = Over 20% +Relative Volume = Over 1 + +[Fundamental] + + +[Technical] + +Performance = Week Up +Beta = Over 1 \ No newline at end of file diff --git a/openbb_platform/providers/finviz/openbb_finviz/utils/presets/undervalue.ini b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/undervalue.ini new file mode 100644 index 000000000000..d92d148194d8 --- /dev/null +++ b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/undervalue.ini @@ -0,0 +1,16 @@ +# Author of preset: Traceabl3 +# Description: Potential Undervalued stocks + +[General] +Signal = Upgrades +Order = Market Cap. +Ascend = false + +[Descriptive] + +[Fundamental] +PEG = Low (<1) +P/B = Under 3 +EPS growthpast 5 years = Over 15% + +[Technical] \ No newline at end of file diff --git a/openbb_platform/providers/finviz/openbb_finviz/utils/presets/weak_support_top_performers.ini b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/weak_support_top_performers.ini new file mode 100644 index 000000000000..05ead450bf16 --- /dev/null +++ b/openbb_platform/providers/finviz/openbb_finviz/utils/presets/weak_support_top_performers.ini @@ -0,0 +1,20 @@ +# Author of preset: OpenBB +# Description: Weak support trendlines among top performers + +[General] + +Signal = Top Gainers + +[Descriptive] + +Option/Short = Optionable and shortable +Average Volume = Over 500K +Country = USA +Price = Over $20 + +[Fundamental] + +[Technical] +Performance = Quarter +20% +Performance 2 = Month +10% +Pattern = TL Support \ No newline at end of file diff --git a/openbb_platform/providers/finviz/openbb_finviz/utils/screener_helper.py b/openbb_platform/providers/finviz/openbb_finviz/utils/screener_helper.py new file mode 100644 index 000000000000..544df95015db --- /dev/null +++ b/openbb_platform/providers/finviz/openbb_finviz/utils/screener_helper.py @@ -0,0 +1,2112 @@ +"""Screener Helpers """ + +# pylint: disable=too-many-lines + +from typing import Dict, Literal + +MARKET_CAP_MAP = { + "all": "Any", + "mega": "Mega ($200bln and more)", + "large": "Large ($10bln to $200bln)", + "large_over": "+Large (over $10bln)", + "large_under": "-Large (under $200bln)", + "mid": "Mid ($2bl to $10bln)", + "mid_over": "+Mid (over $2bln)", + "mid_under": "-Mid (under $10bln)", + "small": "Small ($300mln to $2bln)", + "small_over": "+Small (over $300mln)", + "small_under": "-Small (under $2bln)", + "micro": "Micro ($50mln to $300mln)", + "micro_over": "+Micro (over $50mln)", + "micro_under": "-Micro (under $300mln)", + "nano": "Nano (under $50mln)", +} + +MarketCap = Literal[ + "all", + "mega", + "large", + "large_over", + "large_under", + "mid", + "mid_over", + "mid_under", + "small", + "small_over", + "small_under", + "micro", + "micro_over", + "micro_under", + "nano", +] + +INDUSTRY_MAP = { + "all": "Any", + "stocks_only": "Stocks only (ex-Funds)", + "etf": "Exchange Traded Fund", + "advertising_agencies": "Advertising Agencies", + "aerospace_defense": "Aerospace & Defense", + "agricultural_inputs": "Agricultural Inputs", + "airlines": "Airlines", + "airports_airservices": "Airports & Air Services", + "aluminum": "Aluminum", + "apparel_manufacturing": "Apparel Manufacturing", + "apparel_retail": "Apparel Retail", + "asset_management": "Asset Management", + "auto_manufacturers": "Auto Manufacturers", + "auto_parts": "Auto Parts", + "auto_dealerships": "Auto & Truck Dealerships", + "banks_diversified": "Banks - Diversified", + "banks_regional": "Banks - Regional", + "beverages_brewers": "Beverages - Brewers", + "beverages_nonalcoholic": "Beverages - Non-Alcoholic", + "beverages_wineries_distilleries": "Beverages - Wineries & Distilleries", + "biotechnology": "Biotechnology", + "broadcasting": "Broadcasting", + "building_materials": "Building Materials", + "building_products_equipment": "Building Products & Equipment", + "business_equipment_supplies": "Business Equipment & Supplies", + "capital_markets": "Capital Markets", + "chemicals": "Chemicals", + "closed_end_fund_debt": "Closed-End Fund - Debt", + "closed_end_fund_equity": "Closed-End Fund - Equity", + "closed_end_fund_foreign": "Closed-End Fund - Foreign", + "coking_coal": "Coking Coal", + "communication_equipment": "Communication Equipment", + "computer_hardware": "Computer Hardware", + "confectioners": "Confectioners", + "conglomerates": "Conglomerates", + "consulting_services": "Consulting Services", + "consumer_electronics": "Consumer Electronics", + "copper": "Copper", + "credit_services": "Credit Services", + "department_stores": "Department Stores", + "diagnostics_research": "Diagnostics & Research", + "discount_stores": "Discount Stores", + "drug_manufacturers_general": "Drug Manufacturers - General", + "drug_manufacturers_specialty_generic": "Drug Manufacturers - Specialty & Generic", + "education_training_services": "Education & Training Services", + "electrical_equipment_parts": "Electrical Equipment & Parts", + "electronic_components": "Electronic Components", + "electronic_gaming_multimedia": "Electronic Gaming & Multimedia", + "electronics_computer_distribution": "Electronics & Computer Distribution", + "engineering_construction": "Engineering & Construction", + "entertainment": "Entertainment", + "farm_heavy_construction_machinery": "Farm & Heavy Construction Machinery", + "farm_products": "Farm Products", + "financial_conglomerates": "Financial Conglomerates", + "financial_data_stock_exchanges": "Financial Data & Stock Exchanges", + "food_distribution": "Food Distribution", + "footwear_accessories": "Footwear & Accessories", + "furnishings_fixtures_appliances": "Furnishings, Fixtures & Appliances", + "gambling": "Gambling", + "gold": "Gold", + "grocery_stores": "Grocery Stores", + "health_care_plans": "Healthcare Plans", + "health_information_services": "Health Information Services", + "home_improvement_retail": "Home Improvement Retail", + "household_personal_products": "Household & Personal Products", + "industrial_distribution": "Industrial Distribution", + "information_technology_services": "Information Technology Services", + "infrastructure_operations": "Infrastructure Operations", + "insurance_brokers": "Insurance Brokers", + "insurance_diversified": "Insurance - Diversified", + "insurance_life": "Insurance - Life", + "insurance_property_casualty": "Insurance - Property & Casualty", + "insurance_reinsurance": "Insurance - Reinsurance", + "insurance_specialty": "Insurance - Specialty", + "integrated_freight_logistics": "Integrated Freight & Logistics", + "internet_content_information": "Internet Content & Information", + "internet_retail": "Internet Retail", + "leisure": "Leisure", + "lodging": "Lodging", + "lumber_wood_production": "Lumber & Wood Production", + "luxury_goods": "Luxury Goods", + "marine_shipping": "Marine Shipping", + "medical_care_facilities": "Medical Care Facilities", + "medical_devices": "Medical Devices", + "medical_distribution": "Medical Distribution", + "medical_instruments_supplies": "Medical Instruments & Supplies", + "metal_fabrication": "Metal Fabrication", + "mortgage_finance": "Mortgage Finance", + "oil_gas_drilling": "Oil & Gas Drilling", + "oil_gas_ep": "Oil & Gas E&P", + "oil_gas_equipment_services": "Oil & Gas Equipment & Services", + "oil_gas_integrated": "Oil & Gas Integrated", + "oil_gas_midstream": "Oil & Gas Midstream", + "oil_gas_refining_marketing": "Oil & Gas Refining & Marketing", + "other_industrial_metals_mining": "Other Industrial Metals & Mining", + "other_precious_metals_mining": "Other Precious Metals & Mining", + "packaged_foods": "Packaged Foods", + "packaging_containers": "Packaging & Containers", + "paper_paper_products": "Paper & Paper Products", + "personal_services": "Personal Services", + "pharmaceutical_retailers": "Pharmaceutical Retailers", + "pollution_treatment_controls": "Pollution & Treatment Controls", + "publishing": "Publishing", + "railroads": "Railroads", + "real_estate_development": "Real Estate - Development", + "real_estate_diversified": "Real Estate - Diversified", + "real_estate_services": "Real Estate Services", + "recreational_vehicles": "Recreational Vehicles", + "reit_diversified": "REIT - Diversified", + "reit_health_care_facilities": "REIT - Healthcare Facilities", + "reit_hotel_motel": "REIT - Hotel & Motel", + "reit_industrial": "REIT - Industrial", + "reit_mortgage": "REIT - Mortgage", + "reit_office": "REIT - Office", + "reit_residential": "REIT - Residential", + "reit_retail": "REIT - Retail", + "reit_specialty": "REIT - Specialty", + "rental_leasing_services": "Rental & Leasing Services", + "residential_construction": "Residential Construction", + "resorts_casinos": "Resorts & Casinos", + "restaurants": "Restaurants", + "scientific_technical_instruments": "Scientific & Technical Instruments", + "security_protection_services": "Security & Protection Services", + "semiconductor_equipment_materials": "Semiconductor Equipment & Materials", + "semiconductors": "Semiconductors", + "shell_companies": "Shell Companies", + "silver": "Silver", + "software_application": "Software - Application", + "software_infrastructure": "Software - Infrastructure", + "solar": "Solar", + "specialty_business_services": "Specialty Business Services", + "specialty_chemicals": "Specialty Chemicals", + "specialty_industrial_machinery": "Specialty Industrial Machinery", + "specialty_retail": "Specialty Retail", + "staffing_employment_services": "Staffing & Employment Services", + "steel": "Steel", + "telecom_services": "Telecom Services", + "textile_manufacturing": "Textile Manufacturing", + "thermal_coal": "Thermal Coal", + "tobacco": "Tobacco", + "tools_accessories": "Tools & Accessories", + "travel_services": "Travel Services", + "trucking": "Trucking", + "uranium": "Uranium", + "utilities_diversified": "Utilities - Diversified", + "utilities_independent_power_producers": "Utilities - Independent Power Producers", + "utilities_regulated_electric": "Utilities - Regulated Electric", + "utilities_regulated_gas": "Utilities - Regulated Gas", + "utilities_regulated_water": "Utilities - Regulated Water", + "utilities_renewable": "Utilities - Renewable", + "waste_management": "Waste Management", +} + +d_signals = { + "top_gainers": "Top Gainers", + "top_losers": "Top Losers", + "new_high": "New High", + "new_low": "New Low", + "most_volatile": "Most Volatile", + "most_active": "Most Active", + "unusual_volume": "Unusual Volume", + "overbought": "Overbought", + "oversold": "Oversold", + "downgrades": "Downgrades", + "upgrades": "Upgrades", + "earnings_before": "Earnings Before", + "earnings_after": "Earnings After", + "recent_insider_buying": "Recent Insider Buying", + "recent_insider_selling": "Recent Insider Selling", + "major_news": "Major News", + "horizontal_sr": "Horizontal S/R", + "tl_resistance": "TL Resistance", + "tl_support": "TL Support", + "wedge_up": "Wedge Up", + "wedge_down": "Wedge Down", + "wedge": "Wedge", + "triangle_ascending": "Triangle Ascending", + "triangle_descending": "Triangle Descending", + "channel_up": "Channel Up", + "channel_down": "Channel Down", + "channel": "Channel", + "double_top": "Double Top", + "double_bottom": "Double Bottom", + "multiple_top": "Multiple Top", + "multiple_bottom": "Multiple Bottom", + "head_shoulders": "Head & Shoulders", + "head_shoulders_inverse": "Head & Shoulders Inverse", +} + + +d_signals_desc = { + "top_gainers": "stocks with the highest price gain percent today", + "top_losers": "stocks with the highest price percent loss today", + "new_high": "stocks making 52-week high today", + "new_low": "stocks making 52-week low today", + "most_volatile": "stocks with the highest widest high/low trading range today", + "most_active": "stocks with the highest trading volume today", + "unusual_volume": "stocks with unusually high volume today - the highest relative volume ratio", + "overbought": "stock is becoming overvalued and may experience a pullback.", + "oversold": "oversold stocks may represent a buying opportunity for investors", + "downgrades": "stocks downgraded by analysts today", + "upgrades": "stocks upgraded by analysts today", + "earnings_before": "companies reporting earnings today, before market open", + "earnings_after": "companies reporting earnings today, after market close", + "recent_insider_buying": "stocks with recent insider buying activity", + "recent_insider_selling": "stocks with recent insider selling activity", + "major_news": "stocks with the highest news coverage today", + "horizontal_sr": "horizontal channel of price range between support and resistance trendlines", + "tl_resistance": "once a rising trendline is broken", + "tl_support": "once a falling trendline is broken", + "wedge_up": "upward trendline support and upward trendline resistance (reversal)", + "wedge_down": "downward trendline support and downward trendline resistance (reversal)", + "wedge": "upward trendline support, downward trendline resistance (contiunation)", + "triangle_ascending": "upward trendline support and horizontal trendline resistance", + "triangle_descending": "horizontal trendline support and downward trendline resistance", + "channel_up": "both support and resistance trendlines slope upward", + "channel_down": "both support and resistance trendlines slope downward", + "channel": "both support and resistance trendlines are horizontal", + "double_top": "stock with 'M' shape that indicates a bearish reversal in trend", + "double_bottom": "stock with 'W' shape that indicates a bullish reversal in trend", + "multiple_top": "same as double_top hitting more highs", + "multiple_bottom": "same as double_bottom hitting more lows", + "head_shoulders": "chart formation that predicts a bullish-to-bearish trend reversal", + "head_shoulders_inverse": "chart formation that predicts a bearish-to-bullish trend reversal", +} + +Recommendation = Literal[ + "all", + "strong_buy", + "buy+", + "buy", + "hold+", + "hold", + "hold-", + "sell", + "sell-", + "strong_sell", +] + +RECOMMENDATION_MAP = { + "all": "Any", + "strong_buy": "Strong Buy (1)", + "buy+": "Buy or better", + "buy": "Buy", + "hold+": "Hold or better", + "hold": "Hold", + "hold-": "Hold or worse", + "sell": "Sell", + "sell-": "Sell or worse", + "strong_sell": "Strong Sell (5)", +} + +d_check_screener = { + "Order": [ + "Any", + "Signal", + "Ticker", + "Company", + "Sector", + "Industry", + "Country", + "Market Cap.", + "Price/Earnings", + "Forward Price/Earnings", + "PEG (Price/Earnings/Growth)", + "Price/Sales", + "Price/Book", + "Price/Cash", + "Price/Free Cash Flow", + "Dividend Yield", + "Payout Ratio", + "EPS(ttm)", + "EPS growth this year", + "EPS growth next year", + "EPS growth past 5 years", + "EPS growth next 5 years", + "Sales growth past 5 years", + "EPS growth qtr over qtr", + "Sales growth qtr over qtr", + "Shares Outstanding", + "Shares Float", + "Insider Ownership", + "Insider Transactions", + "Institutional Ownership", + "Institutional Transactions", + "Short Interest Share", + "Short Interest Ratio", + "Earnings Date", + "Return on Assets", + "Return on Equity", + "Return on Investment", + "Current Ratio", + "Quick Ratio", + "LT Debt/Equity", + "Total Debt/Equity", + "Gross Margin", + "Operating Margin", + "Net Profit Margin", + "Analyst Recommendation", + "Performance (Week)", + "Performance (Month)", + "Performance (Quarter)", + "Performance (Half Year)", + "Performance (Year)", + "Performance (Year To Date)", + "Beta", + "Average True Range", + "Volatility (Week)", + "Volatility (Month)", + "20-Day SMA (Relative)", + "50-Day SMA (Relative)", + "200-Day SMA (Relative)", + "50-Day High (Relative)", + "50-Day Low (Relative)", + "52-Week High (Relative)", + "52-Week Low (Relative)", + "Relative Strength Index (14)", + "Average Volume (3 Month)", + "Relative Volume", + "Change", + "Change from Open", + "Gap", + "Volume", + "Price", + "Target Price", + "IPO Date", + ], + "Ascend": ["true", "false"], + "Signal": [ + "Any", + "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", + ], + "Exchange": ["Any", "AMEX", "NASDAQ", "NYSE"], + "Market Cap.": [ + "Any", + "Mega ($200bln and more)", + "Large ($10bln to $200bln)", + "Mid ($2bln to $10bln)", + "Small ($300mln to $2bln)", + "Micro ($50mln to $300mln)", + "Nano (under $50mln)", + "+Large (over $10bln)", + "+Mid (over $2bln)", + "+Small (over $300mln)", + "+Micro (over $50mln)", + "-Large (under $200bln)", + "-Mid (under $10bln)", + "-Small (under $2bln)", + "-Micro (under $300mln)", + ], + "Earnings Date": [ + "Any", + "Today", + "Today Before Market Open", + "Today Before Market Close", + "Tomorrow", + "Tomorrow Before Market Open", + "Tomorrow Before Market Close", + "Yesterday", + "Yesterday Before Market Open", + "Yesterday Before Market Close", + "Next 5 Days", + "Previous 5 Days", + "This Week", + "Next Week", + "Previous Week", + "This Month", + ], + "Target Price": [ + "Any", + "50% Above Price", + "40% Above Price", + "30% Above Price", + "20% Above Price", + "10% Above Price", + "5% Above Price", + "Above Price", + "Below Price", + "5% Below Price", + "10% Below Price", + "20% Below Price", + "30% Below Price", + "40% Below Price", + "50% Below Price", + ], + "Index": ["Any", "S&P 500", "DJIA", "NASDAQ 100", "Russell 2000"], + "Dividend Yield": [ + "Any", + "None (0%)", + "Positive (>0%)", + "High (>5%)", + "Very High (>10%)", + "Over 1%", + "Over 2%", + "Over 3%", + "Over 4%", + "Over 5%", + "Over 6%", + "Over 7%", + "Over 8%", + "Over 9%", + "Over 10%", + ], + "Average Volume": [ + "Any", + "Under 50K", + "Under 100K", + "Under 500K", + "Under 750K", + "Under 1M", + "Over 50K", + "Over 100K", + "Over 200K", + "Over 300K", + "Over 400K", + "Over 500K", + "Over 750K", + "Over 1M", + "Over 2M", + "100K to 500K", + "100K to 1M", + "500K to 1M", + "500K to 10M", + ], + "IPO Date": [ + "Any", + "Today", + "Yesterday", + "In the last week", + "In the last month", + "In the last quarter", + "In the last year", + "In the last 2 years", + "In the last 3 years", + "In the last 5 years", + "More than a year ago", + "More that 5 years ago", + "More than 10 years ago", + "More than 15 years ago", + "More than 20 years ago", + "More than 25 years ago", + ], + "Sector": [ + "Any", + "Basic Materials", + "Communication Services", + "Consumer Cyclical", + "Consumer Defensive", + "Energy", + "Financial", + "Healthcare", + "Industrials", + "Real Estate", + "Technology", + "Utilities", + ], + "Float Short": [ + "Any", + "Low (<5%)", + "High(>20%)", + "Under 5%", + "Under 10%", + "Under 15%", + "Under 20%", + "Under 25%", + "Under 30%", + "Over 5%", + "Over 10%", + "Over 15%", + "Over 20%", + "Over 25%", + "Over 30%", + ], + "Relative Volume": [ + "Any", + "Over 10", + "Over 5", + "Over 3", + "Over 2", + "Over 1.5", + "Over 1", + "Over 0.75", + "Over 0.5", + "Over 0.25", + "Under 2", + "Under 1", + "Under 1.5", + "Under 1", + "Under 0.75", + "Under 0.5", + "Under 0.25", + "Under 0.1", + ], + "Shares Outstanding": [ + "Any", + "Under 1M", + "Under 5M", + "Under 10M", + "Under 20M", + "Under 50M", + "Under 100M", + "Over 1M", + "Over 2M", + "Over 5M", + "Over 10M", + "Over 20M", + "Over 50M", + "Over 100M", + "Over 200M", + "Over 500M", + "Over 1000M", + ], + "Industry": list(INDUSTRY_MAP.values()), + "Analyst Recom.": [ + "Any", + "Strong Buy (1)", + "Buy or better", + "Buy", + "Hold or better", + "Hold", + "Hold or worse", + "Sell", + "Sell or worse", + "Strong Sell (5)", + ], + "Current Volume": [ + "Any", + "Under 100K", + "Under 500K", + "Under 750K", + "Under 1M", + "Over 0", + "Over 50K", + "Over 100K", + "Over 200K", + "Over 300K", + "Over 400K", + "Over 500K", + "Over 750K", + "Over 1M", + "Over 2M", + "Over 5M", + "Over 10M", + "Over 20M", + ], + "Float": [ + "Any", + "Under 1M", + "Under 5M", + "Under 10M", + "Under 20M", + "Under 50M", + "Under 100M", + "Over 1M", + "Over 2M", + "Over 5M", + "Over 10M", + "Over 20M", + "Over 50M", + "Over 100M", + "Over 200M", + "Over 500M", + "Over 1000M", + ], + "Country": [ + "Any", + "Asia", + "Europe", + "Latin America", + "BRIC", + "Argentina", + "Australia", + "Bahamas", + "Belgium", + "BeNeLux", + "Bermuda", + "Brazil", + "Canada", + "Cayman Islands", + "Chile", + "China", + "China & Hong Kong", + "Colombia", + "Cyprus", + "Denmark", + "Finland", + "France", + "Germany", + "Greece", + "Hong Kong", + "Hungary", + "Iceland", + "Iceland", + "India", + "Indonesia", + "Ireland", + "Israel", + "Italy", + "Japan", + "Kazakhstan", + "Luxembourg", + "Malaysia", + "Malta", + "Mexico", + "Monaco", + "Netherlands", + "New Zealand", + "Norway", + "Panama", + "Peru", + "Philippines", + "Portugal", + "Russia", + "Singapore", + "South Africa", + "South Korea", + "Spain", + "Sweden", + "Switzerland", + "Taiwan", + "Turkey", + "United Arab Emirates", + "United Kingdom", + "Uruguay", + "USA", + "Foreign (ex-USA)", + ], + "Option/Short": ["Any", "Optionable", "Shortable", "Optionable and shortable"], + "Price": [ + "Any", + "Under $1", + "Under $2", + "Under $3", + "Under $4", + "Under $5", + "Under $7", + "Under $10", + "Under $15", + "Under $20", + "Under $30", + "Under $40", + "Under $50", + "Over $1", + "Over $2", + "Over $3", + "Over $4", + "Over $5", + "Over $7", + "Over $10", + "Over $15", + "Over $20", + "Over $30", + "Over $40", + "Over $50", + "Over $60", + "Over $70", + "Over $80", + "Over $90", + "Over $100", + "$1 to $5", + "$1 to $10", + "$1 to $20", + "$5 to %10", + "$5 to $20", + "$5 to $50", + "$10 to $20", + "$10 to $50", + "$20 to $50", + "$50 to $100", + ], + "P/E": [ + "Any", + "Low (<15)", + "Profitable (>0)", + "High (>50)", + "Under 5", + "Under 10", + "Under 15", + "Under 20", + "Under 25", + "Under 30", + "Under 35", + "Under 40", + "Under 45", + "Under 50", + "Over 5", + "Over 10", + "Over 15", + "Over 25", + "Over 30", + "Over 35", + "Over 40", + "Over 45", + "Over 50", + ], + "Price/Cash": [ + "Any", + "Low (<3)", + "High (>50)", + "Under 1", + "Under 2", + "Under 3", + "Under 4", + "Under 5", + "Under 6", + "Under 7", + "Under 8", + "Under 9", + "Under 10", + "Over 1", + "Over 2", + "Over 3", + "Over 4", + "Over 5", + "Over 6", + "Over 7", + "Over 8", + "Over 9", + "Over 10", + "Over 20", + "Over 30", + "Over 40", + "Over 50", + ], + "EPS growthnext 5 years": [ + "Any", + "Negative (<0%)", + "Positive (>0%)", + "Positive Low (<10%)", + "High (>25%)", + "Under 5%", + "Under 10%", + "Under 15%", + "Under 20%", + "Under 25%", + "Under 30%", + "Over 5%", + "Over 10%", + "Over 15%", + "Over 20%", + "Over 25%", + "Over 30%", + ], + "Return on Equity": [ + "Any", + "Positive (>0%)", + "Negative (<0%)", + "Very Positive (>30%)", + "Very Negative (<-15%)", + "Under -50%", + "Under -40%", + "Under -35%", + "Under -30%", + "Under -25%", + "Under -20%", + "Under -15%", + "Under -10%", + "Under -5%", + "Over +50%", + "Over +45%", + "Over +40%", + "Over +35%", + "Over +30%", + "Over +25%", + "Over +20%", + "Over +15%", + "Over +10%", + "Over +5%", + ], + "Debt/Equity": [ + "Any", + "High (>0.5)", + "Low (<0.1)", + "Under 1", + "Under 0.9", + "Under 0.8", + "Under 0.7", + "Under 0.6", + "Under 0.5", + "Under 0.4", + "Under 0.3", + "Under 0.2", + "Under 0.1", + "Over 0.1", + "Over 0.2", + "Over 0.3", + "Over 0.4", + "Over 0.5", + "Over 0.6", + "Over 0.7", + "Over 0.8", + "Over 0.9", + "Over 1", + ], + "InsiderOwnership": [ + "Any", + "Low (<5%)", + "High (>30%)", + "Very High (>50%)", + "Over 10%", + "Over 20%", + "Over 30%", + "Over 40%", + "Over 50%", + "Over 60%", + "Over 70%", + "Over 80%", + "Over 90%", + ], + "Forward P/E": [ + "Any", + "Low (<15)", + "Profitable (>0)", + "High (>50)", + "Under 5", + "Under 10", + "Under 15", + "Under 20", + "Under 25", + "Under 30", + "Under 35", + "Under 40", + "Under 45", + "Under 50", + "Over 5", + "Over 10", + "Over 15", + "Over 20", + "Over 25", + "Over 30", + "Over 35", + "Over 40", + "Over 45", + "Over 50", + ], + "Price/Free Cash Flow": [ + "Any", + "Low (<15)", + "High (>50)", + "Under 5", + "Under 10", + "Under 15", + "Under 20", + "Under 25", + "Under 30", + "Under 35", + "Under 40", + "Under 45", + "Under 50", + "Under 60", + "Under 70", + "Under 80", + "Under 90", + "Under 100", + "Over 5", + "Over 10", + "Over 15", + "Over 20", + "Over 25", + "Over 30", + "Over 35", + "Over 40", + "Over 45", + "Over 50", + "Over 60", + "Over 70", + "Over 80", + "Over 90", + "Over 100", + ], + "Sales growthpast 5 years": [ + "Any", + "Negative (<0%)", + "Positive (>0%)", + "Positive Low (0-10%)", + "High (>25%)", + "Under 5%", + "Under 10%", + "Under 15%", + "Under 20%", + "Under 25%", + "Under 30%", + "Over 5%", + "Over 10%", + "Over 15%", + "Over 20%", + "Over 25%", + "Over 30%", + ], + "Return on Investment": [ + "Any", + "Positive (>0%)", + "Negative (<0%)", + "Very Positive (>25%)", + "Very Negative (<-10%)", + "Under -50%", + "Under -45%", + "Under -40%", + "Under -35%", + "Under -30%", + "Under -25%", + "Under -20%", + "Under -15%", + "Under -10%", + "Under -5%", + "Over +5%", + "Over +10%", + "Over +15%", + "Over +20%", + "Over +25%", + "Over +30%", + "Over +35%", + "Over +40%", + "Over +45%", + "Over +50%", + ], + "Gross Margin": [ + "Any", + "Positive (>0%)", + "Negative (<0%)", + "High (>50%)", + "Under 90%", + "Under 80%", + "Under 70%", + "Under 60%", + "Under 50%", + "Under 45%", + "Under 40%", + "Under 35%", + "Under 30%", + "Under 25%", + "Under 20%", + "Under 15%", + "Under 10%", + "Under 5%", + "Under 0%", + "Under -10%", + "Under -20%", + "Under -30%", + "Under -50%", + "Under -70%", + "Under -100%", + "Over 0%", + "Over 5%", + "Over 10%", + "Over 15%", + "Over 20%", + "Over 25%", + "Over 30%", + "Over 40%", + "Over 45%", + "Over 50%", + "Over 60%", + "Over 70%", + "Over 80%", + "Over 90%", + ], + "InsiderTransactions": [ + "Any", + "Very Negative (<20%)", + "Negative (<0%)", + "Positive (>0%)", + "Very Positive (>20%)", + "Under -90%", + "Under 80%", + "Under 70%", + "Under -60%", + "Under -50%", + "Under -45%", + "Under 40%", + "Under -35%", + "Under -30%", + "Under -25%", + "Under -20%", + "Under -15%", + "Under -10%", + "Under -5%", + "Over +5%", + "Over +10%", + "Over +15%", + "Over +20%", + "Over +25%", + "Over +30%", + "Over +35%", + "Over +40%", + "Over +45%", + "Over +50%", + "Over +60%", + "Over +70%", + "Over +80%", + "Over +90%", + ], + "PEG": [ + "Any", + "Low (<1)", + "High (>2)", + "Under 1", + "Under 2", + "Under 3", + "Over 1", + "Over 2", + "Over 3", + ], + "EPS growththis year": [ + "Any", + "Negative (<0%)", + "Positive (>0%)", + "Positive Low (0-10%)", + "High (>25%)", + "Under 5%", + "Under 10%", + "Under 15%", + "Under 20%", + "Under 25%", + "Under 30%", + "Over 5%", + "Over 10%", + "Over 15%", + "Over 20%", + "Over 25%", + "Over 30%", + ], + "EPS growthqtr over qtr": [ + "Any", + "Negative (<0%)", + "Positive (>0%)", + "Positive Low (0-10%)", + "High (>25%)", + "Under 5%", + "Under 10%", + "Under 15%", + "Under 20%", + "Under 25%", + "Under 30%", + "Over 5%", + "Over 10%", + "Over 15%", + "Over 20%", + "Over 25%", + "Over 30%", + ], + "Current Ratio": [ + "Any", + "High (>3)", + "Low (<1)", + "Under 1", + "Under 0.5", + "Over 0.5", + "Over 1", + "Over 1.5", + "Over 2", + "Over 3", + "Over 4", + "Over 5", + "Over 10", + ], + "Operating Margin": [ + "Any", + "Negative (<0%)", + "Positive (>0%)", + "Very Negative (<-20%)", + "High (>25%)", + "Under 90%", + "Under 80%", + "Under 70%", + "Under 60%", + "Under 50%", + "Under 45%", + "Under 40%", + "Under 35%", + "Under 30%", + "Under 25%", + "Under 20%", + "Under 15%", + "Under 10%", + "Under 5%", + "Under 0%", + "Under -10%", + "Under -20%", + "Under -30%", + "Under -50%", + "Under -70%", + "Under -100%", + "Over 0%", + "Over 10%", + "Under 15%", + "Over 20%", + "Over 25%", + "Over 30%", + "Over 35%", + "Over 40%", + "Over 45%", + "Over 50%", + "Over 60%", + "Over 70%", + "Over 80%", + "Over 90%", + ], + "InstitutionalOwnership": [ + "Any", + "Low (<5%)", + "High (>90%)", + "Under 90%", + "Under 80%", + "Under 70%", + "Under 60%", + "Under 50%", + "Under 40%", + "Under 30%", + "Under 20%", + "Under 10%", + "Over 10%", + "Over 20%", + "Over 30%", + "Over 40%", + "Over 50%", + "Over 60%", + "Over 70%", + "Over 80%", + "Over 90%", + ], + "P/S": [ + "Any", + "Low (<1)", + "High (>10)", + "Under 1", + "Under 2", + "Under 3", + "Under 4", + "Under 5", + "Under 6", + "Under 7", + "Under 8", + "Under 9", + "Under 10", + "Over 1", + "Over 2", + "Over 3", + "Over 4", + "Over 5", + "Over 6", + "Over 6", + "Over 7", + "Over 8", + "Over 9", + "Over 10", + ], + "EPS growthnext year": [ + "Any", + "Negative (<0%)", + "Positive (>0%)", + "Positive Low (0-10%)", + "High (>25%)", + "Under 5%", + "Under 10%", + "Under 15%", + "Under 20%", + "Under 25%", + "Under 30%", + "Over 5%", + "Over 10%", + "Over 15%", + "Over 20%", + "Over 25%", + "Over 30%", + ], + "Sales growthqtr over qtr": [ + "Any", + "Negative (<0%)", + "Positive (>0%)", + "Positive Low (0-10%)", + "High (>25%)", + "Under 5%", + "Under 10%", + "Under 15%", + "Under 20%", + "Under 25%", + "Under 30%", + "Over 5%", + "Over 10%", + "Over 15%", + "Over 20%", + "Over 25%", + "Over 30%", + ], + "Quick Ratio": [ + "Any", + "High (>3)", + "Low (<0.5)", + "Under 1", + "Under 0.5", + "Over 0.5", + "Over 1", + "Over 1.5", + "Over 2", + "Over 3", + "Over 4", + "Over 5", + "Over 10", + ], + "Net Profit Margin": [ + "Any", + "Positive (>0%)", + "Negative (<0%)", + "Very Negative (<-20%)", + "High (>20%)", + "Under 90%", + "Under 80%", + "Under 70%", + "Under 60%", + "Under 50%", + "Under 45%", + "Under 40%", + "Under 35%", + "Under 30%", + "Under 25%", + "Under 20%", + "Under 15%", + "Under 10%", + "Under 5%", + "Under 0%", + "Under -10%", + "Under -20%", + "Under -30%", + "Under -50%", + "Under -70%", + "Under -100%", + "Over 0%", + "Over 5%", + "Over 10%", + "Over 15%", + "Over 20%", + "Over 25%", + "Over 30%", + "Over 35%", + "Over 40%", + "Over 45%", + "Over 50%", + "Over 60%", + "Over 70%", + "Over 80%", + "Over 90%", + ], + "InstitutionalTransactions": [ + "Any", + "Very Negative (<20%)", + "Negative (<0%)", + "Positive (>0%)", + "Very Positive (>20%)", + "Under -50%", + "Under -45%", + "Under -40%", + "Under -35%", + "Under -30%", + "Under -25%", + "Under -20%", + "Under -15%", + "Under -10%", + "Under -5%", + "Over +5%", + "Over +10%", + "Over +15%", + "Over +20%", + "Over +25%", + "Over +30%", + "Over +35%", + "Over +40%", + "Over +45%", + "Over +50%", + ], + "P/B": [ + "Any", + "Low (<1)", + "High (>5)", + "Under 1", + "Under 2", + "Under 3", + "Under 4", + "Under 5", + "Under 6", + "Under 7", + "Under 8", + "Under 9", + "Under 10", + "Over 1", + "Over 2", + "Over 3", + "Over 4", + "Over 5", + "Over 6", + "Over 7", + "Over 8", + "Over 9", + "Over 10", + ], + "EPS growthpast 5 years": [ + "Any", + "Negative (<0%)", + "Positive (>0%)", + "Positive Low (0-10%)", + "High (>25%)", + "Under 5%", + "Under 10%", + "Under 15%", + "Under 20%", + "Under 25%", + "Under 30%", + "Over 5%", + "Over 10%", + "Over 15%", + "Over 20%", + "Over 25%", + "Over 30%", + ], + "Return on Assets": [ + "Any", + "Positive (>0%)", + "Negative (<0%)", + "Very Positive (>15%)", + "Very Negative (<-15%)", + "Under -50%", + "Under -45%", + "Under -40%", + "Under -35%", + "Under -30%", + "Under -25%", + "Under -20%", + "Under -15%", + "Under -10%", + "Under -5%", + "Over +5%", + "Over +10%", + "Over +15%", + "Over +20%", + "Over +25%", + "Over +30%", + "Over +35%", + "Over +40%", + "Over +45%", + "Over +50%", + ], + "LT Debt/Equity": [ + "Any", + "High (>0.5)", + "Low (<0.1)", + "Under 1", + "Under 0.9", + "Under 0.8", + "Under 0.7", + "Under 0.6", + "Under 0.5", + "Under 0.4", + "Under 0.3", + "Under 0.2", + "Under 0.1", + "Over 0.1", + "Over 0.2", + "Over 0.3", + "Over 0.4", + "Over.5", + "Over 0.6", + "Over 0.7", + "Over 0.8", + "Over 0.9", + "Over 1", + ], + "Payout Ratio": [ + "Any", + "None (0%)", + "Positive (>0%)", + "Low (<20%)", + "High (>50%)", + "Over 0%", + "Over 10%", + "Over 20%", + "Over 30%", + "Over 40%", + "Over 50%", + "Over 60%", + "Over 70%", + "Over 80%", + "Over 90%", + "Over 100%", + "Under 10%", + "Under 20%", + "Under 30%", + "Under 40%", + "Under 50%", + "Under 60%", + "Under 70%", + "Under 80%", + "Under 90%", + "Under 100%", + ], + "Performance": [ + "Any", + "Today Up", + "Today Down", + "Today -15%", + "Today -10%", + "Today -5%", + "Today +5%", + "Today +10%", + "Today +15%", + "Week -30%", + "Week -20%", + "Week -10%", + "Week Down", + "Week Up", + "Week +10%", + "Week +20%", + "Week +30%", + "Month -50%", + "Month -30%", + "Month -20%", + "Month -10%", + "Month Down", + "Month Up", + "Month +10%", + "Month +20%", + "Month +30%", + "Month +50%", + "Quarter -50%", + "Quarter -30%", + "Quarter -20%", + "Quarter -10%", + "Quarter Down", + "Quarter Up", + "Quarter +10%", + "Quarter +20%", + "Quarter +30%", + "Quarter +50%", + "Half -75%", + "Half -50%", + "Half -30%", + "Half -20%", + "Half -10%", + "Half Down", + "Half Up", + "Half +10%", + "Half +20%", + "Half +30%", + "Half +50%", + "Half +100%", + "Year -75%", + "Year -50%", + "Year -30%", + "Year -20%", + "Year -10%", + "Year Down", + "Year Up", + "Year +10%", + "Year +20%", + "Year +30%", + "Year +50%", + "Year +100%", + "Year +200%", + "Year +300%", + "Year +500%", + "YTD -75%", + "YTD -50%", + "YTD -30%", + "YTD -20%", + "YTD -10%", + "YTD -5%", + "YTD Down", + "YTD Up", + "YTD +5%", + "YTD +10%", + "YTD +20%", + "YTD +30", + "YTD +50%", + "YTD +100%", + ], + "20-Day Simple Moving Average": [ + "Any", + "Price below SMA20", + "Price 10% below SMA20", + "Price 20% below SMA20", + "Price 30% below SMA20", + "Price 40% below SMA20", + "Price 50% below SMA20", + "Price above SMA20", + "Price 10% above SMA20", + "Price 20% above SMA20", + "Price 30% above SMA20", + "Price 40% above SMA20", + "Price 50% above SMA20", + "Price crossed SMA20", + "Price crossed SMA20 above", + "Price crossed SMA20 below", + "SMA20 crossed SMA50", + "SMA20 crossed SMA50 above", + "SMA20 crossed SMA50 below", + "SMA20 cross SMA200", + "SMA20 crossed SMA200 below", + "SMA20 crossed SMA200 above", + "SMA20 above SMA50", + "SMA20 below SMA50", + "SMA20 above SMA200", + "SMA20 below SMA200", + ], + "20-Day High/Low": [ + "Any", + "New High", + "New Low", + "5% or more below High", + "10% or more below High", + "15% or more below High", + "20% or more below High", + "30% or more below High", + "40% or more below High", + "50% or more below High", + "0-3% below High", + "0-5% below High", + "0-10% below High", + "5% or more above Low", + "10% or more above Low", + "15% or more above Low", + "20% or more above Low", + "30% or more above Low", + "40% or more above Low", + "50% or more above Low", + "0-3% above Low", + "0-5% above Low", + "0-10% above Low", + ], + "Beta": [ + "Any", + "Under 0", + "Under 0.5", + "Under 1", + "Under 1.5", + "Under 2", + "Over 0", + "Over 0.5", + "Over 1", + "Over 1.5", + "Over 2", + "Over 2.5", + "Over 3", + "Over 4", + "0 to 0.5", + "0 to 1", + "0.5 to 1", + "0.5 to 1.5", + "1 to 1.5", + "1 to 2", + ], + "Performance 2": [ + "Any", + "Today Up", + "Today Down", + "Today -15%", + "Today -10%", + "Today -5%", + "Today +5%", + "Today +10%", + "Today +15%", + "Week -30%", + "Week -20%", + "Week -10%", + "Week Down", + "Week Up", + "Week +10%", + "Week +20%", + "Week +30%", + "Month -50%", + "Month -30%", + "Month -20%", + "Month -10%", + "Month Down", + "Month Up", + "Month +10%", + "Month +20%", + "Month +30%", + "Month +50%", + "Quarter -50%", + "Quarter -30%", + "Quarter -20%", + "Quarter -10%", + "Quarter Down", + "Quarter Up", + "Quarter +10%", + "Quarter +20%", + "Quarter +30%", + "Quarter +50%", + "Half -75%", + "Half -50%", + "Half -30%", + "Half -20%", + "Half -10%", + "Half Down", + "Half Up", + "Half +10%", + "Half +20%", + "Half +30%", + "Half +50%", + "Half +100%", + "Year -75%", + "Year -50%", + "Year -30%", + "Year -20%", + "Year -10%", + "Year Down", + "Year Up", + "Year +10%", + "Year +20%", + "Year +30%", + "Year +50%", + "Year +100%", + "Year +200%", + "Year +300%", + "Year +500%", + "YTD -75%", + "YTD -50%", + "YTD -30%", + "YTD -20%", + "YTD -10%", + "YTD -5%", + "YTD Down", + "YTD Up", + "YTD +5%", + "YTD +10%", + "YTD +20%", + "YTD +30", + "YTD +50%", + "YTD +100%", + ], + "50-Day Simple Moving Average": [ + "Any", + "Price below SMA50", + "Price 10% below SMA50", + "Price 20% below SMA50", + "Price 30% below SMA50", + "Price 40% below SMA50", + "Price 50% below SMA50", + "Price above SMA50", + "Price 10% above SMA50", + "Price 20% above SMA50", + "Price 30% above SMA50", + "Price 40% above SMA50", + "Price 50% above SMA50", + "Price crossed SMA50", + "Price crossed SMA50 above", + "Price crossed SMA50 below", + "SMA50 crossed SMA20", + "SMA50 crossed SMA20 above", + "SMA50 crossed SMA20 below", + "SMA50 cross SMA200", + "SMA50 crossed SMA200 below", + "SMA50 crossed SMA200 above", + "SMA50 above SMA20", + "SMA50 below SMA20", + "SMA50 above SMA200", + "SMA50 below SMA200", + ], + "50-Day High/Low": [ + "Any", + "New High", + "New Low", + "5% or more below High", + "10% or more below High", + "15% or more below High", + "20% or more below High", + "30% or more below High", + "40% or more below High", + "50% or more below High", + "0-3% below High", + "0-5% below High", + "0-10% below High", + "5% or more above Low", + "10% or more above Low", + "15% or more above Low", + "20% or more above Low", + "30% or more above Low", + "40% or more above Low", + "50% or more above Low", + "0-3% above Low", + "0-5% above Low", + "0-10% above Low", + ], + "Average True Range": [ + "Any", + "Over 0.25", + "Over 0.5", + "Over 0.75", + "Over 1", + "Over 1.5", + "Over 2. Over 2.5", + "Over 3", + "Over 3.5", + "Over 4", + "Over 4.5", + "Over 5", + "Under 0.25", + "Under 0.5", + "Under 0.75", + "Under 1", + "Under 1.5", + "Under 2", + "Under 2.5", + "Under 3", + "Under 3.5", + "Under 4", + "Under 4.5", + "Under 5", + ], + "Volatility": [ + "Any", + "Week - Over 3%", + "Week - Over 4%", + "Week - Over 5%", + "Week - 6%", + "Week - 7%", + "Week - 8%", + "Week - 9%", + "Week - 10%", + "Week - 12%", + "Week - 15%", + "Month - 2%", + "Month - 3%", + "Month - 4%", + "Month 5%", + "Month 5%", + "Month 6%", + "Month 7%", + "Month 8%", + "Month 9%", + "Month 10%", + "Month 12%", + "Month 15%", + ], + "200-Day Simple Moving Average": [ + "Any", + "Price below SMA200", + "Price 10% below SMA200", + "Price 20% below SMA200", + "Price 30% below SMA200", + "Price 40% below SMA200", + "Price 50% below SMA200", + "Price above SMA200", + "Price 10% above SMA200", + "Price 20% above SMA200", + "Price 30% above SMA200", + "Price 40% above SMA200", + "Price 50% above SMA200", + "Price crossed SMA200", + "Price crossed SMA200 above", + "Price crossed SMA200 below", + "SMA200 crossed SMA20", + "SMA20 crossed SMA20 above", + "SMA20 crossed SMA20 below", + "SMA200 cross SMA50", + "SMA200 crossed SMA50 below", + "SMA200 crossed SMA50 above", + "SMA200 above SMA20", + "SMA200 below SMA20", + "SMA200 above SMA50", + "SMA200 below SMA50", + ], + "52-Week High/Low": [ + "Any", + "New High", + "New Low", + "5% or more below High", + "10% or more below High", + "15% or more below High", + "20% or more below High", + "30% or more below High", + "40% or more below High", + "50% or more below High", + "0-3% below High", + "0-5% below High", + "0-10% below High", + "5% or more above Low", + "10% or more above Low", + "15% or more above Low", + "20% or more above Low", + "30% or more above Low", + "40% or more above Low", + "50% or more above Low", + "0-3% above Low", + "0-5% above Low", + "0-10% above Low", + ], + "RSI (14)": [ + "Any", + "Overbought (90)", + "Overbought (80)", + "Overbought (70)", + "Overbought (6)", + "Oversold (40)", + "Oversold (30)", + "Oversold (20)", + "Oversold (10)", + "Not Overbought (<60)", + "Not Overbought (<50)", + "Not Oversold (>50)", + "Not Oversold (>40)", + ], + "Change": [ + "Any", + "Up", + "Up 1%", + "Up 2%", + "Up 3%", + "Up 4%", + "Up 5%", + "Up 6%", + "Up 7%", + "Up 8%", + "Up 9%", + "Up 10%", + "Up 15%", + "Up 20%", + "Down", + "Down 1%", + "Down 2%", + "Down 3%", + "Down 4%", + "Down 5%", + "Down 6%", + "Down 7%", + "Down 8%", + "Down 9%", + "Down 10%", + "Down 15%", + "Down 20%", + ], + "Pattern": [ + "Any", + "Horizontal S/R", + "Horizontal S/R (Strong)", + "TL Resistance", + "TL Resistance (Strong)", + "TL Support", + "TL Support (Strong)", + "Wedge Up", + "Wedge Up (Strong)", + "Wedge Down", + "Wedge Down (Strong)", + "Triangle Ascending", + "Triangle Ascending (Strong)", + "Triangle Descending", + "Triangle Descending (Strong)", + "Wedge", + "Wedge (Strong)", + "Channel Up", + "Channel Up (Strong)", + "Channel Down", + "Channel Down (Strong)", + "Channel", + "Channel (Strong)", + "Double Top", + "Double Bottom", + "Multiple Top", + "Multiple Bottom", + "Head & Shoulders", + "Head & Shoulders Inverse", + ], + "Gap": [ + "Any", + "Up", + "Up 1%", + "Up 2%", + "Up 3%", + "Up 4%", + "Up 5%", + "Up 6%", + "Up 7%", + "Up 8%", + "Up 9%", + "Up 10%", + "Up 15%", + "Up 20%", + "Down", + "Down 1%", + "Down 2%", + "Down 3%", + "Down 4%", + "Down 5%", + "Down 6%", + "Down 7%", + "Down 8%", + "Down 9%", + "Down 10%", + "Down 15%", + "Down 20%", + ], + "Change from Open": [ + "Any", + "Up", + "Up 1%", + "Up 2%", + "Up 3%", + "Up 4%", + "Up 5%", + "Up 6%", + "Up 7%", + "Up 8%", + "Up 9%", + "Up 10%", + "Up 15%", + "Up 20%", + "Down", + "Down 1%", + "Down 2%", + "Down 3%", + "Down 4%", + "Down 5%", + "Down 6%", + "Down 7%", + "Down 8%", + "Down 9%", + "Down 10%", + "Down 15%", + "Down 20%", + ], + "Candlestick": [ + "Any", + "Long Lower Shadow", + "Long Upper Shadow", + "Hammer", + "Inverted Hammer", + "Spinning Top White", + "Spinning Top Black", + "Doji", + "Dragonfly Doji", + "Gravestone Doji", + "Marubozu White", + "Marubozu Black", + ], +} + +SIGNALS = sorted(list(d_signals)) + +SIGNALS_DESC_STR = "" +for k, v in sorted(d_signals_desc.items()): + SIGNALS_DESC_STR += f"\n {k}: {v}" + + +SECTOR_MAP = { + "all": "Any", + "energy": "Energy", + "materials": "Basic Materials", + "industrials": "Industrials", + "consumer_cyclical": "Consumer Cyclical", + "consumer_defensive": "Consumer Defensive", + "financial": "Financial", + "healthcare": "Healthcare", + "technology": "Technology", + "communication_services": "Communication Services", + "utilities": "Utilities", + "real_estate": "Real Estate", +} + +Sectors = Literal[ + "all", + "energy", + "materials", + "industrials", + "consumer_cyclical", + "consumer_defensive", + "financial", + "healthcare", + "technology", + "communication_services", + "utilities", + "real_estate", +] + +EXCHANGE_MAP = { + "all": "Any", + "amex": "AMEX", + "nasdaq": "NASDAQ", + "nyse": "NYSE", +} + +INDEX_MAP = { + "all": "Any", + "dow": "DJIA", + "sp500": "S&P 500", + "nasdaq": "NASDAQ 100", + "russell": "RUSSELL 2000", +} + + +def get_preset_choices(user_data_path) -> Dict: + """Get a combined map of default and user screener presets.""" + # pylint: disable=import-outside-toplevel + import shutil + from pathlib import Path + from warnings import warn + + PRESETS_PATH = Path(user_data_path) / "presets" / "finviz" + PRESETS_PATH_DEFAULT = Path(__file__).parent.resolve() / "presets" + preset_choices: Dict = {} + + if PRESETS_PATH_DEFAULT.exists(): + preset_choices.update( + { + filepath.name.replace(".ini", ""): filepath + for filepath in PRESETS_PATH_DEFAULT.iterdir() + if filepath.suffix == ".ini" + } + ) + + try: + # Create the user presets directory if it doesn't exist. + if not PRESETS_PATH.exists(): + PRESETS_PATH.mkdir(parents=True, exist_ok=True) + + # Copy any missing default presets to the user presets directory. + for filepath in PRESETS_PATH_DEFAULT.iterdir(): + if filepath.suffix == ".ini": + target_path = PRESETS_PATH / filepath.name + if not target_path.exists(): + shutil.copy(filepath, target_path) + + # Override any default paths to the user path, if they exist. + if PRESETS_PATH.exists(): + preset_choices.update( + { + filepath.name.replace(".ini", ""): filepath + for filepath in PRESETS_PATH.iterdir() + if filepath.suffix == ".ini" + } + ) + except Exception as e: + warn(f"Error loading user presets: {e}") + + preset_choices = { + k: v for k, v in sorted(preset_choices.items()) if k != "screener_template" + } + + return preset_choices diff --git a/openbb_platform/providers/finviz/tests/record/http/test_finviz_fetchers/test_finviz_equity_screener_fetcher_urllib3_v1.yaml b/openbb_platform/providers/finviz/tests/record/http/test_finviz_fetchers/test_finviz_equity_screener_fetcher_urllib3_v1.yaml new file mode 100644 index 000000000000..84c1d09aea28 --- /dev/null +++ b/openbb_platform/providers/finviz/tests/record/http/test_finviz_fetchers/test_finviz_equity_screener_fetcher_urllib3_v1.yaml @@ -0,0 +1,492 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Cookie: + - MOCK_COOKIE + method: GET + uri: https://finviz.com/screener.ashx?o=-relativevolume&s=ta_mostactive&v=111 + response: + body: + string: !!binary | + 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 + 4wIAoDtBkDiEAgA= + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8aae0774ef9f8438-YVR + Cache-Control: + - no-cache + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - text/html; charset=utf-8 + Date: + - Mon, 29 Jul 2024 15:09:17 GMT + Request-Context: + - appId=cid-v1:bdd405ef-7a83-4f9a-9228-0107d7f4bc90 + Server: + - cloudflare + Set-Cookie: + - notice-newsletter=show; expires=Tue, 30 Jul 2024 15:09:16 GMT; domain=.finviz.com; + path=/; samesite=lax + - screenerUrl=v%3D111%26s%3Dta_mostactive%26o%3D-relativevolume; expires=Tue, + 29 Jul 2025 15:09:16 GMT; domain=.finviz.com; path=/; samesite=lax + Transfer-Encoding: + - chunked + Vary: + - Accept-Encoding + X-Frame-Options: + - SAMEORIGIN + X-Powered-By: + - ASP.NET + - ARR/3.0 + - ASP.NET + status: + code: 200 + message: OK +version: 1 diff --git a/openbb_platform/providers/finviz/tests/record/http/test_finviz_fetchers/test_finviz_equity_screener_fetcher_urllib3_v2.yaml b/openbb_platform/providers/finviz/tests/record/http/test_finviz_fetchers/test_finviz_equity_screener_fetcher_urllib3_v2.yaml new file mode 100644 index 000000000000..75afc6d3ecde --- /dev/null +++ b/openbb_platform/providers/finviz/tests/record/http/test_finviz_fetchers/test_finviz_equity_screener_fetcher_urllib3_v2.yaml @@ -0,0 +1,1957 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Cookie: + - MOCK_COOKIE + method: GET + uri: https://finviz.com/screener.ashx?o=-relativevolume&s=ta_mostactive&v=111 + response: + body: + string: "\n\n\nMost + Active - Stock Screener - Overview relativevolume\n\n\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \n\n\n\n \n\n\n\n\r\n + \ \r\n \r\n \r\n
\r\n
\r\n + \
\r\n
\r\n
\r\n
\r\n
\r\n\r\n + \

\r\n Subscribe + to our newsletter to receive the latest product updates and special offers\r\n + \

\r\n
\r\n + \
\r\n \r\n + \
\r\n \r\n
\r\n\r\n \r\n + \
\r\n \r\n
\r\n \r\n \r\n \r\n \r\n \r\n + \ \r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n + \
\r\n \r\n + \ \r\n \r\n + \ \r\n \r\n + \ \r\n + \ \r\n
\r\n \r\n \r\n \r\n\r\n
\r\n + \
\r\n + \ \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n + \
\r\n
\r\n
\r\n + \
\r\n
\r\n
\r\n
\r\n + \
\r\n
\r\n
\r\n \"\"\r\n
\r\n \r\n \r\n + \ \r\n \r\n
\r\n \r\n \r\n \r\n \r\n \r\n + \ \r\n + \ \r\n + \ \r\n \r\n
HomeNewsScreenerMapsGroupsPortfolioInsiderFuturesForexCryptoBacktestsElite
\r\n + \ \r\n
\r\n
\r\n \r\n \r\n\r\n + \
\r\n
\r\n Theme\r\n
\r\n + \
\r\n Help\r\n LoginRegister
\r\n + \
\r\n + \ \r\n
\n\n\n\n
\n
\n\n\n\n\n
\"\"\n\n\n
Select the criteria + by which the output information will be sorted. The order settings apply to + all views. Use the ascending and descending option to invert + the current order.

TIP: In table views you can click on top of a column + to sort the table by the underlying values.
] delay=[500]\">Order + by
\n\n\n\n\n
You can + screen the stocks by signal - an event, by which traders usually enter or + exit positions.

Most Active: Stocks with highest trading volume + today.
] delay=[500]\">Signal\n\n\n\n\nTo screen through a selected + set of stocks, you can enter one or more tickers directly, such as 'MSFT,GOOG,AAPL'. + The screening process will run only on the specified stocks. No input ticker(s) + equals all stocks. The open in screener option in the Search, + will copy the listed tickers to the screener's ticker box automatically.] + offsetx=[-100] delay=[500]\">Tickers\n\n\n\n\n\n
\n\n
\n\n\n\nTo optimize the screening + by various stock-related criteria, you can use one or more Filters.] + offsetx=[-305] delay=[500]\">Filters \r\n \r\n\n\n\n\n\n\n
\r\n
\r\n + \ \r\n \r\n
\r\n + \
\r\n
Descriptive
\n
Fundamental
\n
Technical
\n
News
\n
ETF
\n
All
\n + \
\r\n
\r\n
\n\n\n\n
\n
\n\n\n
\n
Stock + Exchange at which a stock is listed.
] delay=[500]\">Exchange\n\n\r\n
\r\n \r\n \r\n + \ \r\n + \ \r\n + \ \r\n
\r\n \r\n \r\n \r\n \r\n\r\n + \ \r\n \r\n \r\n \r\n \r\n\r\n + \ \r\n
\r\n
\n\n\nA major + index membership of a stock.] delay=[500]\">Index\n\n\r\n
\r\n \r\n \r\n + \ \r\n + \ \r\n + \ \r\n
\r\n \r\n \r\n \r\n \r\n\r\n + \ \r\n \r\n \r\n \r\n \r\n\r\n + \ \r\n
\r\n
\n\n\nThe sector + which a stock belongs to.] delay=[500]\">Sector\n\n\r\n
\r\n \r\n \r\n + \ \r\n + \ \r\n + \ \r\n
\r\n \r\n \r\n \r\n \r\n\r\n + \ \r\n \r\n \r\n \r\n \r\n\r\n + \ \r\n
\r\n
\n\n\nThe industry + which a stock belongs to.] delay=[500]\">Industry\n\n\r\n
\r\n \r\n \r\n + \ \r\n + \ \r\n + \ \r\n
\r\n \r\n \r\n \r\n \r\n\r\n + \ \r\n \r\n \r\n \r\n \r\n\r\n + \ \r\n
\r\n
\n\n\nThe country + where company of selected stock is based.] offsetx=[-305] + delay=[500]\">Country\n\n\r\n
\r\n \r\n + \ \r\n \r\n + \ \r\n + \ \r\n
\r\n \r\n \r\n \r\n \r\n\r\n + \ \r\n \r\n \r\n \r\n \r\n\r\n + \ \r\n
\r\n
\n\n\n\nEquals + The total dollar market value of all of a company's outstanding shares.] + delay=[500]\">Market Cap.\n\n\n\n\nThe dividend yield equals the annual dividend per share + divided by the stock\u2019s price. This measurement tells what percentage + return a company pays out to shareholders in the form of dividends.

If + there is no forward dividend estimate available, trailing twelve month (TTM) + value is used.
] delay=[500]\">Dividend Yield
\n\n\n\n\nThe + amount of short-selling transactions of given stock.] delay=[500]\">Float + Short\n\n\n\n\nAn + outlook of a stock-market analyst on a stock.] delay=[500]\">Analyst + Recom.\n\n\r\n + \
\r\n \r\n + \ \r\n \r\n \r\n \r\n
\r\n \r\n \r\n + \ \r\n \r\n\r\n \r\n + \ \r\n + \ \r\n + \ \r\n \r\n\r\n \r\n + \
\r\n + \
\n\n\nStocks + with options and/or available to sell short.] delay=[500]\">Option/Short\n\n\r\n
\r\n \r\n \r\n + \ \r\n + \ \r\n + \ \r\n
\r\n \r\n \r\n \r\n \r\n\r\n + \ \r\n \r\n \r\n \r\n \r\n\r\n + \ \r\n
\r\n
\n\n\n\nDate + when company reports earnings.] delay=[500]\">Earnings Date\n\n\r\n
\r\n + \ \r\n + \ \r\n \r\n \r\n \r\n
\r\n \r\n \r\n + \ \r\n \r\n\r\n \r\n + \ \r\n + \ \r\n + \ \r\n \r\n\r\n \r\n + \
\r\n + \
\n\n\nThe average number + of shares traded in a security per day.] offsetx=[-305] + delay=[500]\">Average Volume\n\n\n\n\nRatio + between current volume and 3-month average, intraday adjusted.] + offsetx=[-305] delay=[500]\">Relative Volume\n\n\n\n\nNumber of shares + traded today.] offsetx=[-305] delay=[500]\">Current Volume\n\n\r\n
\r\n + \ \r\n + \ \r\n \r\n \r\n \r\n
\r\n \r\n \r\n + \ \r\n \r\n\r\n \r\n + \ \r\n + \ \r\n + \ \r\n \r\n\r\n \r\n + \
\r\n + \
\n\n\nNumber + of trades today.] delay=[500]\">Trades\n\n
\n\n\n\nThe current + stock price.] delay=[500]\">Price\n\n\n\n\nAnalysts' mean target + price.] delay=[500]\">Target Price\n\n\n\n\nDate + when company had an IPO.] delay=[500]\">IPO Date\n\n\n\n\nShares outstanding + represent the total number of shares issued by a corporation and held by its + shareholders.] delay=[500]\">Shares Outstanding\n\n\n\n\nFloat is + the number of stock shares that are available for trading to the public. This + doesn't include shares held by insiders.] delay=[500]\">Float\n\n\n\n\n\n
\n
\n\n\n\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
OverviewValuationFinancialOwnershipPerformanceTechnicalETFETF + PerfCustomChartsTickersBasicTANewsSnapshotMapsStats
\n
\"\"
\n
\n
#1 / 200 Total
\n
\r\n + \ \r\n\n\r\n \r\n
\n
\n
\"\"
\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
No.TickerCompanySectorIndustryCountryMarket + CapP/EPriceChangeVolume
1
Lipella Pharmaceuticals IncBiotechnology \u2022 + USA \u2022 7.27M
] offsetx=[100] offsety=[0] delay=[0]\">LIPO
Lipella + Pharmaceuticals IncHealthcareBiotechnologyUSA7.27M-
Lipella Pharmaceuticals IncBiotechnology \u2022 + USA \u2022 7.27M
] offsetx=[-324] offsety=[20] delay=[0]\">0.96
136.54%149,626,879
2
Planet Image International LtdComputer Hardware + \u2022 China \u2022 273.17M
] offsetx=[100] + offsety=[0] delay=[0]\">YIBO
Planet + Image International LtdTechnologyComputer HardwareChina273.17M35.14
Planet Image International LtdComputer Hardware + \u2022 China \u2022 273.17M
] offsetx=[-324] + offsety=[20] delay=[0]\">5.07
73.93%24,431,680
3
2U IncEducation & Training Services \u2022 + USA \u2022 7.11M
] offsetx=[100] offsety=[0] delay=[0]\">TWOU
2U + IncConsumer DefensiveEducation & Training ServicesUSA7.11M-
2U IncEducation & Training Services \u2022 + USA \u2022 7.11M
] offsetx=[-324] offsety=[20] delay=[0]\">2.53
102.40%51,306,348
4
Cognition Therapeutics IncBiotechnology \u2022 + USA \u2022 63.69M
] offsetx=[100] offsety=[0] delay=[0]\">CGTX
Cognition + Therapeutics IncHealthcareBiotechnologyUSA63.69M-
Cognition Therapeutics IncBiotechnology \u2022 + USA \u2022 63.69M
] offsetx=[-324] offsety=[20] delay=[0]\">1.59
-32.92%18,698,869
5
Tivic Health Systems IncMedical Devices \u2022 + USA \u2022 3.87M
] offsetx=[100] offsety=[0] delay=[0]\">TIVC
Tivic + Health Systems IncHealthcareMedical DevicesUSA3.87M-
Tivic Health Systems IncMedical Devices \u2022 + USA \u2022 3.87M
] offsetx=[-324] offsety=[20] delay=[0]\">0.63
38.53%60,226,282
6
NLS Pharmaceutics LtdBiotechnology \u2022 + Switzerland \u2022 12.34M
] offsetx=[100] offsety=[0] delay=[0]\">NLSP
NLS + Pharmaceutics LtdHealthcareBiotechnologySwitzerland12.34M-
NLS Pharmaceutics LtdBiotechnology \u2022 + Switzerland \u2022 12.34M
] offsetx=[-324] offsety=[20] + delay=[0]\">0.26
39.21%95,707,493
7
Loop Media IncBroadcasting \u2022 + USA \u2022 10.51M
] offsetx=[100] offsety=[0] delay=[0]\">LPTV
Loop + Media IncCommunication ServicesBroadcastingUSA10.51M-
Loop Media IncBroadcasting \u2022 + USA \u2022 10.51M
] offsetx=[-324] offsety=[20] delay=[0]\">0.13
12.82%36,700,003
8
Beamr Imaging LtdSoftware - Application \u2022 + Israel \u2022 73.94M
] offsetx=[100] offsety=[0] delay=[0]\">BMR
Beamr + Imaging LtdTechnologySoftware - ApplicationIsrael73.94M-
Beamr Imaging LtdSoftware - Application \u2022 + Israel \u2022 73.94M
] offsetx=[-324] offsety=[20] delay=[0]\">4.90
1.03%6,788,567
9
BurgerFi International IncRestaurants \u2022 + USA \u2022 12.82M
] offsetx=[100] offsety=[0] delay=[0]\">BFI
BurgerFi + International IncConsumer CyclicalRestaurantsUSA12.82M-
BurgerFi International IncRestaurants \u2022 + USA \u2022 12.82M
] offsetx=[-324] offsety=[20] delay=[0]\">0.47
11.29%27,843,015
10
TransCode Therapeutics IncBiotechnology \u2022 + USA \u2022 2.12M
] offsetx=[100] offsety=[0] delay=[0]\">RNAZ
TransCode + Therapeutics IncHealthcareBiotechnologyUSA2.12M-
TransCode Therapeutics IncBiotechnology \u2022 + USA \u2022 2.12M
] offsetx=[-324] offsety=[20] delay=[0]\">0.29
-1.22%6,760,969
11
Sangamo Therapeutics IncBiotechnology \u2022 + USA \u2022 196.10M
] offsetx=[100] offsety=[-220] delay=[0]\">SGMO
Sangamo + Therapeutics IncHealthcareBiotechnologyUSA196.10M-
Sangamo Therapeutics IncBiotechnology \u2022 + USA \u2022 196.10M
] offsetx=[-324] offsety=[-264] delay=[0]\">0.94
9.26%32,774,017
12
Nasdaq IncFinancial Data & Stock Exchanges \u2022 + USA \u2022 38.94B
] offsetx=[100] offsety=[-220] delay=[0]\">NDAQ
Nasdaq + IncFinancialFinancial Data & Stock ExchangesUSA38.94B38.81
Nasdaq IncFinancial Data & Stock Exchanges \u2022 + USA \u2022 38.94B
] offsetx=[-324] offsety=[-264] delay=[0]\">67.54
0.87%6,803,927
13
Vintage Wine Estates IncBeverages - Wineries & + Distilleries \u2022 USA \u2022 4.37M
] offsetx=[100] + offsety=[-220] delay=[0]\">VWE
Vintage + Wine Estates IncConsumer DefensiveBeverages - Wineries & DistilleriesUSA4.37M-
Vintage Wine Estates IncBeverages - Wineries & + Distilleries \u2022 USA \u2022 4.37M
] offsetx=[-324] + offsety=[-264] delay=[0]\">0.07
4.50%8,299,280
14
Serve Robotics IncSpecialty Industrial Machinery + \u2022 USA \u2022 555.02M
] offsetx=[100] + offsety=[-220] delay=[0]\">SERV
Serve + Robotics IncIndustrialsSpecialty Industrial MachineryUSA555.02M-
Serve Robotics IncSpecialty Industrial Machinery + \u2022 USA \u2022 555.02M
] offsetx=[-324] + offsety=[-264] delay=[0]\">14.96
13.16%29,509,417
15
Hyzon Motors IncAuto Parts \u2022 + USA \u2022 40.35M
] offsetx=[100] offsety=[-220] delay=[0]\">HYZN
Hyzon + Motors IncConsumer CyclicalAuto PartsUSA40.35M-
Hyzon Motors IncAuto Parts \u2022 + USA \u2022 40.35M
] offsetx=[-324] offsety=[-264] delay=[0]\">0.15
-6.80%3,246,602
16
Dexcom IncMedical Devices \u2022 USA + \u2022 27.27B
] offsetx=[100] offsety=[-220] delay=[0]\">DXCM
Dexcom + IncHealthcareMedical DevicesUSA27.27B41.93
Dexcom IncMedical Devices \u2022 USA + \u2022 27.27B
] offsetx=[-324] offsety=[-264] delay=[0]\">68.05
6.32%7,409,184
17
Agape ATP CorpPackaged Foods \u2022 + Malaysia \u2022 7.37M
] offsetx=[100] offsety=[-220] delay=[0]\">ATPC
Agape + ATP CorpConsumer DefensivePackaged FoodsMalaysia7.37M-
Agape ATP CorpPackaged Foods \u2022 + Malaysia \u2022 7.37M
] offsetx=[-324] offsety=[-264] delay=[0]\">0.10
-11.30%4,853,902
18
Salarius Pharmaceuticals IncBiotechnology \u2022 + USA \u2022 2.21M
] offsetx=[100] offsety=[-220] delay=[0]\">SLRX
Salarius + Pharmaceuticals IncHealthcareBiotechnologyUSA2.21M-
Salarius Pharmaceuticals IncBiotechnology \u2022 + USA \u2022 2.21M
] offsetx=[-324] offsety=[-264] delay=[0]\">3.69
15.67%3,927,786
19
Longeveron IncBiotechnology \u2022 + USA \u2022 25.27M
] offsetx=[100] offsety=[-220] delay=[0]\">LGVN
Longeveron + IncHealthcareBiotechnologyUSA25.27M-
Longeveron IncBiotechnology \u2022 + USA \u2022 25.27M
] offsetx=[-324] offsety=[-264] delay=[0]\">3.98
15.69%18,922,060
20
Integra Lifesciences Holdings CorpMedical Devices + \u2022 USA \u2022 2.11B
] offsetx=[100] offsety=[-220] + delay=[0]\">IART
Integra + Lifesciences Holdings CorpHealthcareMedical DevicesUSA2.11B52.86
Integra Lifesciences Holdings CorpMedical Devices + \u2022 USA \u2022 2.11B
] offsetx=[-324] offsety=[-264] + delay=[0]\">26.80
-14.75%2,681,416
\n
\n\n\n\n
Signal: ta_mostactiveexport
\n
\"\"
\n12345678910\r\n \r\n\n
\"\"
\n
\n\n\r\n \r\n
\r\n
\r\n
\r\n affiliate\r\n + \ \u2022 \r\n advertise\r\n \r\n + \ \u2022 toggle light mode\r\n + \ \u2022 \r\n contact\r\n \u2022 \r\n help\r\n + \u2022 \r\n privacy + \
\r\n Quotes delayed 15 minutes for NASDAQ, NYSE and AMEX.\r\n + \
\r\n Copyright \xA9 2007-2024 FINVIZ.com. All Rights Reserved.\r\n + \ \r\n
\r\n \r\n + \ \r\n \r\n
\r\n
\r\n\t\t\t \r\n\r\n \r\n\r\n
\r\n\t\t\t

Upgrade + your FINVIZ experience

\r\n

\r\n + \ Join thousands of traders who make + more informed decisions with our premium features.\r\n Real-time + quotes, advanced visualizations, backtesting, and much more.\r\n

\r\n + \ Learn + more about FINVIZ*Elite\r\n
\r\n + \
\r\n
\n\n\n" + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8aae05b6c8d58450-YVR + Cache-Control: + - no-cache + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - text/html; charset=utf-8 + Date: + - Mon, 29 Jul 2024 15:08:05 GMT + Request-Context: + - appId=cid-v1:bdd405ef-7a83-4f9a-9228-0107d7f4bc90 + Server: + - cloudflare + Set-Cookie: + - notice-newsletter=show; expires=Tue, 30 Jul 2024 15:08:05 GMT; domain=.finviz.com; + path=/; samesite=lax + - screenerUrl=v%3D111%26s%3Dta_mostactive%26o%3D-relativevolume; expires=Tue, + 29 Jul 2025 15:08:05 GMT; domain=.finviz.com; path=/; samesite=lax + Transfer-Encoding: + - chunked + Vary: + - Accept-Encoding + X-Frame-Options: + - SAMEORIGIN + X-Powered-By: + - ASP.NET + - ARR/3.0 + - ASP.NET + status: + code: 200 + message: OK +version: 1 diff --git a/openbb_platform/providers/finviz/tests/test_finviz_fetchers.py b/openbb_platform/providers/finviz/tests/test_finviz_fetchers.py index 02b935c9c3a9..4e05252aed9d 100644 --- a/openbb_platform/providers/finviz/tests/test_finviz_fetchers.py +++ b/openbb_platform/providers/finviz/tests/test_finviz_fetchers.py @@ -4,6 +4,7 @@ from openbb_core.app.service.user_service import UserService from openbb_finviz.models.compare_groups import FinvizCompareGroupsFetcher from openbb_finviz.models.equity_profile import FinvizEquityProfileFetcher +from openbb_finviz.models.equity_screener import FinvizEquityScreenerFetcher from openbb_finviz.models.key_metrics import FinvizKeyMetricsFetcher from openbb_finviz.models.price_performance import FinvizPricePerformanceFetcher from openbb_finviz.models.price_target import FinvizPriceTargetFetcher @@ -77,3 +78,13 @@ def test_finviz_compare_groups_fetcher(credentials=test_credentials): fetcher = FinvizCompareGroupsFetcher() result = fetcher.test(params, credentials) assert result is None + + +@pytest.mark.record_http +def test_finviz_equity_screener_fetcher(credentials=test_credentials): + """Test Finviz Equity Screener Fetcher.""" + params = {"signal": "most_active", "limit": 20} + + fetcher = FinvizEquityScreenerFetcher() + result = fetcher.test(params, credentials) + assert result is None