Skip to main content

lukhed_stocks

A collection of stocks analysis utility functions and API wrappers. Repo is in development. Please note that you are responsible for how you access and use the data. See the responsible data usage section for more info.

Installation

pip install lukhed-stocks

TOC

No API Key Market Data
Available Wrappers
Responsible Data Usage

No API Key Market Data

Access market data without requiring API keys or authentication. This section includes utility functions for obtaining ticker lists and a unified interface for real-time quotes, price history, and fundamental data.

Available Wrappers

  • CAT Wrapper - Conolidated Audit Trail (CAT) for exchange data provided by CAT Webpage
  • Wikipedia Stocks - For obtaining various stock data from Wikipedia (various pages)
  • Schwab Wrapper - Wrapper for schwab-py wrapper. Adds key management and convenience functions to the unopinionated wrapper which provides auth, quotes, history, options, account info and more.
  • Robinhood Wrapper - Wrapper for Robinhood's public API endpoints. Provides access to stock data, fundamentals, charts, and popular stock lists without requiring authentication. Auth methods coming later.
  • Webull Wrapper - Wrapper for Webull's public API endpoints. Provides access to real-time quotes, price history, and index data without requiring authentication.
  • Polygon.io Wrapper - Wrapper for Polygon.io's API. Provides free access to market status and holiday information with up to 5 API requests per minute and 500 requests per day.
  • TradingView Wrapper - Wrapper for TradingView's stock screener. Provides access to stock lists, filters by sector/industry, and customizable screening criteria.

Ticker Functions

Tickers Import

from lukhed_stocks import tickers

Get Tickers By Exchange

Provides a list of stock data for the given exchange. Each function can optionally be called with 'tickers_only' parameter to return a list of strings only. These functions utilize CAT data by default and do not require an API key.

nasdaq = tickers.get_nasdaq_stocks()
nyse = tickers.get_nyse_stocks(tickers_only=True)
otc = tickers.get_otc_stocks()
iex = tickers.get_iex_stocks(tickers_only=True)
Function Default Source
tickers.get_nasdaq_stocks CAT
tickers.get_nyse_stocks CAT
tickers.get_otc_stocks CAT
tickers.get_iex_stocks CAT

Get Tickers By Index

Provides a list of stock data for the given index. Each function can optionally be called with 'tickers_only' parameter to return a list of strings only. The default source for each function does not require an API key.

sp500 = tickers.get_sp500_stocks()
djia = tickers.get_dow_stocks(tickers_only=True)
otc = tickers.get_russell2000_stocks()
Function Default Source
tickers.get_sp500_stocks Wikipedia
tickers.get_dow_stocks Wikipedia
tickers.get_russell2000_stocks TradingView

Get Company Logo by Ticker

logo_url = tickers.get_company_logo('ALLT')
logo_url_with_download = tickers.get_company_logo('WAY', output_file='way.png')
Function Default Source
tickers.get_company_log Synth

CAT Wrapper

Documentation coming soon.

Wikipedia Stocks

Documentation coming soon.

Schwab Wrapper

Setup

Setup the API auth once and use it across hardware. To setup, instantiate with schwab_api_setup=True. By default, your private github repo is used for key mangement (you will need a github account and token). Setup will ask for your Schwab developer app key, secret, and callback url, then take you through authenticating with Schwab.

Note: this wrapper uses schwab-py for actual Schwab auth. See the documentation there for any issues or questions in setting up your schwab account.

#Github setup
schwab = SchwabPy(schwab_api_setup=True)
#Local setup (won't work across hardware)
schwab = SchwabPy(schwab_api_setup=True, key_management='local')

Usage Examples After Setup

schwab = SchwabPy()
quotes = schwab.get_stock_quote(['allt', 'way', 'pplt', 'impuy'])
price = schwab.get_stock_price('allt')
low = schwab.get_stock_52w_low('gld')
percent_below_high = schwab.get_percent_below_52w_high('aapl')

Cache Option

If prices are stale when using this wrapper (e.g., after market) or realtime price is not needed for your analysis, you can use cache to speed up calls.

schwab = SchwabPy(use_ticker_cache=True)
quotes = schwab.get_stock_quote(['allt', 'way', 'pplt', 'impuy'])   # 'allt' in cache
price = schwab.get_stock_price('allt')  # retrieve price from cache

Utilizing schwab-py

My wrapper is built for key management, advanced analysis, and ease of use. The exposed methods are recommended when using my wrapper, but you can access any of the endpoints available from schwab-py like below.

schwab.api.get_price_history_every_minute("ALLT")

Robinhood Wrapper

Setup

No authentication required. The wrapper provides access to Robinhood's public API endpoints.

from lukhed_stocks.robinhood import Robinhood

rh = Robinhood()

Basic Usage Examples

# Get basic instrument data
basic_data = rh.get_basic_data('AAPL')
multiple_stocks = rh.get_basic_data(['AAPL', 'TSLA', 'MSFT'])

# Get fundamental data
fundamentals = rh.get_fundamentals('AAPL')

# Get chart data for different time spans
daily_chart = rh.get_basic_chart_data('AAPL', span='day')
yearly_chart = rh.get_basic_chart_data('AAPL', span='year', extended_hours=True)
# Get most held stocks on Robinhood
top_50 = rh.get_most_held_instruments(top_x=50)
symbols_only = rh.get_most_held_instruments(return_symbols_only=True)

# Search for instruments
search_results = rh.search_instruments_by_symbol_keyword('TECH')

API Rate Limiting

The wrapper includes built-in rate limiting to be respectful of Robinhood's servers.

# Adjust delay between API calls (default is 0.5 seconds)
rh = Robinhood(api_delay=1.0)

# Disable user agent randomization if needed
rh = Robinhood(random_user_agent=False)

Webull Wrapper

Setup

No authentication required. The wrapper provides access to Webull's public API endpoints.

from lukhed_stocks.webull import Webull

wb = Webull()

Basic Usage Examples

# Get real-time quote for a single stock
quote = wb.get_quote('AAPL')

# Get quotes for multiple stocks
quotes = wb.get_quote(['AAPL', 'TSLA', 'MSFT'], ids_provided=False)

# Get major indices data (DJI, NASDAQ, SPX, RUT)
indices = wb.get_indice_data()

# Get price history for a stock
history = wb.get_price_history('AAPL', interval='1d', points=800)

# Get price history for an index
index_history = wb.get_indice_price_history('spx', interval='1d', points=800)

# Get just the prices for major indices
index_prices = wb.get_indice_prices()

Cache Options

Speed up repeated calls by using cache functionality.

# Enable live cache for repeated symbol lookups
wb = Webull(keep_live_cache=True)

# Enable basics cache (saved to disk for cross-session use)
wb = Webull(use_basics_cache=True)

Note: Webull api calls require symbol id's, so the wrapper uses an API call to retrieve the proper id based on input. 
Using basics cache allows saving API calls by storing the symbol to id mapping.

# Refresh the basics cache
wb = Webull(use_basics_cache=True, refresh_basics_cache=True)

API Rate Limiting

# Adjust delay between API calls (default is 0.5 seconds)
wb = Webull(api_delay=1.0)

MarketData

Setup

The MarketData class provides a unified interface for accessing market data from multiple sources without managing individual wrapper instances. No authentication required for default sources.

from lukhed_stocks.marketdata import MarketData

md = MarketData()

Basic Usage Examples

# Get major indices prices (default: Webull)
indices = md.get_indice_prices()

# Get real-time quote
quote = md.get_quote('AAPL')
multiple_quotes = md.get_quote(['AAPL', 'TSLA', 'MSFT'])

# Get price history
history = md.get_price_history('AAPL', interval='d1', points=800)

# Get index price history
index_history = md.get_indice_price_history('spx', interval='d1', points=800)

# Get fundamental data (default: Robinhood)
fundamentals = md.get_fundamentals('AAPL')

# Get basic stock information (default: Robinhood)
basic_info = md.get_basic_info('AAPL')

Specifying Data Sources

# Specify source explicitly
quote_webull = md.get_quote('AAPL', source='webull')
fundamentals_rh = md.get_fundamentals('AAPL', source='robinhood')

Supported Sources

  • get_indice_prices(): Webull
  • get_quote(): Webull
  • get_price_history(): Webull
  • get_indice_price_history(): Webull
  • get_fundamentals(): Robinhood
  • get_basic_info(): Robinhood

Polygon.io Wrapper

Setup

Setup the API auth once and use it across hardware. To setup, instantiate the class and follow the prompts to enter your Polygon.io API key. By default, your private github repo is used for key management (you will need a github account and token).

# Github setup
from lukhed_stocks.polygon import PolygonIo

# Default instantiation uses github key_management
poly = PolygonIo()
# If you want to use local hardware key storage only
poly = PolygonIo(key_management='local')

Usage Examples After Setup

poly = PolygonIo()

# Get current market status
market_status = poly.get_market_status_now()

# Get upcoming market holidays
holidays = poly.get_upcoming_market_holidays()

# Check if market is open today
is_open = poly.is_market_open_today()

API Rate Limiting

The wrapper includes built-in rate limiting. The free tier allows 5 API requests per minute and 500 requests per day.

# Adjust delay between API calls (default is 1 second)
poly = PolygonIo(api_delay=2.0)

Skip Setup with Auth Dictionary

# Provide auth data directly to skip setup prompts
auth_data = {"key": "your_api_key_here"}
poly = PolygonIo(auth_dict=auth_data)

TradingView Wrapper

Setup

No authentication required. The wrapper provides access to TradingView's stock screener endpoints.

from lukhed_stocks.tradingview import TradingView

tv = TradingView()

# All options, with their defaults:
tv = TradingView(
    market="america",       # which scanner; see "Other markets" below
    timeout=20,             # seconds before a request is abandoned
    max_retries=3,          # retried on 429 and 5xx, honouring Retry-After
    backoff=1.5,            # exponential factor between attempts
    min_interval=0.0,       # min seconds between requests from this object
    raise_on_error=False,   # see "Error handling" below
)

Error handling

By default a failed request returns {"error": True, "statusCode": ..., "message": ..., "data": []} Check error before using the result. If you would rather it be loud, pass raise_on_error=True and a ScreenerError is raised instead:

from lukhed_stocks.tradingview import TradingView, ScreenerError

tv = TradingView(raise_on_error=True)
try:
    data = tv.screener_get_all_stocks()
except ScreenerError as exc:
    print(exc, exc.status_code, exc.attempts)

A 200 carrying a non-JSON body, or one with no data key, is treated as an error rather than as an empty result — that is what an upstream change looks like, and it should not read as "the market has no stocks today".

Other markets

market selects the scanner and derives both the URL and the payload's markets field, so TradingView(market="crypto") hits https://scanner.tradingview.com/crypto/scan. **The built-in column and filter defaults are written for america**the crypto, forex and futures scanners publish different field names, so call clear_screener_columns() and define columns explicitly after switching, or use set_market() and do the same.

Basic Usage Examples

# Get all stocks with default TradingView filters and columns
all_stocks = tv.screener_get_all_stocks()

# Get stocks by index
dow_stocks = tv.screener_get_stocks_by_index('dow')
sp500_stocks = tv.screener_get_stocks_by_index('s&p')
nasdaq_stocks = tv.screener_get_stocks_by_index('nasdaq')
russell_stocks = tv.screener_get_stocks_by_index('russel 2000')

# Get stocks at new highs or lows
new_52w_highs = tv.screener_new_highs_lows(new_high_or_low='high', month_time_frame=12)
new_3m_lows = tv.screener_new_highs_lows(new_high_or_low='low', month_time_frame=3)
all_time_highs = tv.screener_new_highs_lows(new_high_or_low='high', month_time_frame='all time')

ETFs

The default filters exclude ETFs. screener_get_all_etfs() swaps in an ETF-only filter for one request, restores your filters afterwards, and sorts by assets under management.

Every ETF reports sector "Miscellaneous" and industry "Investment Trusts/Mutual Funds", so set_etf_screener_columns() adds the fields that say what a fund holds and how it is built: asset_class.tr, category.tr, focus.tr, niche.tr, leverage.tr, strategy.tr, index_tracked, aum, expense_ratio and a few more.

tv.custom_define_columns(["close", "EMA50", "EMA150", "EMA200", "Perf.3M"])
tv.set_etf_screener_columns(add_to_current_columns=True)
etfs = tv.screener_get_all_etfs()

# Leveraged, inverse and income funds are all returned -- filter them yourself
plain = [x for x in etfs['data']
         if x['leverage.tr'] == 'Non-leveraged' and x['strategy.tr'] == 'Vanilla']
# e.g. SMH -> Equity / Sector / Information technology / Semiconductors
#      IBIT -> Currency / Pair / Long Bitcoin, short USD / In specie

Filtering Stock Lists

# Filter by sector or industry
tech_stocks = tv.filter_stock_list_by_sector('Technology', all_stocks['data'])
multiple_sectors = tv.filter_stock_list_by_sector(['Healthcare', 'Finance'], all_stocks['data'])
industry_filtered = tv.filter_stock_list_by_industry('Software', all_stocks['data'])

# Get sector/industry information
sectors = tv.get_all_sectors_in_list(all_stocks['data'])
industries = tv.get_all_industries_in_list(all_stocks['data'])
breakdown = tv.get_sector_industry_breakdown_of_list(all_stocks['data'])
tickers = tv.get_unique_stock_tickers_in_list(all_stocks['data'])

Customizing Screener Columns

# Use predefined column sets
tv.set_stock_screener_columns_overview()
tv.set_stock_screener_columns_performance()
tv.set_stock_screener_columns_valuation()
tv.set_stock_screener_columns_dividends()
tv.set_stock_screener_columns_technicals()
tv.set_stock_screener_columns_profitiability()
tv.set_stock_screener_columns_per_share()

# Add custom columns
tv.custom_define_columns(["name", "description", "Perf.W", "Perf.1M", "Perf.3M", "Perf.6M", "Perf.YTD", "exchange"])

# Add to existing columns instead of replacing
tv.set_stock_screener_columns_time_period_performance(add_to_current_columns=True)

# Reset to defaults
tv.reset_screener_columns()

Custom Filters

# Add custom filters
custom_filter = {
    "left": "market_cap_basic",
    "operation": "egreater",
    "right": 1000000000
}
tv.add_screener_filter_to_filter(custom_filter)

tv.add_screener_filter_to_filter([
    TradingView.filter_column_vs_value("close", "egreater", 15),
    TradingView.filter_column_vs_column("close", "egreater", "SMA50"),
])

# Filters accumulate on the instance -- clear or reset between screens.

# Reset filters to default
tv.reset_screener_filters()

# Clear all filters
tv.clear_screener_filters()

# Set completely custom filter
tv.set_custom_screener_filter(custom_filter)

Supported Index Filters

The wrapper supports filtering by the following indices (check tv.index_lookup for full list):

  • Dow Jones: 'dow'
  • S&P 500: 's&p'
  • Nasdaq Composite: 'nasdaq'
  • Nasdaq 100: 'nasdaq 100'
  • Russell 2000: 'russel 2000'
  • And many more sector-specific indices

Responsible Data Usage

  • Each method or wrapper in the documentation lists the source that is utilized by default
  • Below is information related to data retrieval and usage for each source

CAT Data Usage

CAT Data is pulled from this page. They provide a legal notice here.

Wikipedia Data Usage

Wikipedia content is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License. For more details on the terms of use, please refer to the Wikimedia Foundation's Terms of Use.

Synth

Full Synth terms are found here. This library provides access to synth:

  • Images, free to use if attribution is provided (please confirm with synthfinance.com or the terms above)

Robinhood Data Usage

Data is accessed through Robinhood's public API endpoints without authentication. This wrapper is intended for educational and research purposes. Please respect Robinhood's terms of service and API usage guidelines. Users are responsible for ensuring their usage complies with Robinhood's policies.

Polygon.io Data Usage

Data is accessed through Polygon.io's API. Free tier provides up to 5 API requests per minute and 500 requests per day. For higher volume usage, please visit Polygon.io's pricing page. Users are responsible for ensuring their usage complies with Polygon.io's terms of service and API usage limits.

Tradingview Data Usage

I am currently trying to remove trading view as a source, as their policy is restrictive and confusing. Please read trading view policies here

Webull Data Usage

Data is accessed through Webull's public API endpoints without authentication. This wrapper is intended for educational and research purposes. Please respect Webull's terms of service and API usage guidelines. Users are responsible for ensuring their usage complies with Webull's policies.

Metadata

Release files for lukhed-stocks 0.3.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for lukhed-stocks 0.3.3
File Size Uploaded
lukhed_stocks-0.3.3.tar.gz 44.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for lukhed-stocks 0.3.3
File Interpreter ABI Platform
lukhed_stocks-0.3.3-py3-none-any.whl Python 3 none any Details

Total release size: 86.3 kB

Release files / lukhed_stocks-0.3.3.tar.gz

Download URL lukhed_stocks-0.3.3.tar.gz
Size 44.1 kB
Tags Source
SHA-256 checksum
How to use checksums
9eda08a6a5ab87b4f14d392af655dec8e035875e8e96f056eb5495fc3700c7d9
BLAKE2b-256 checksum
How to use checksums
d69547a6674847071f6685d3e7c86d79bca1c3da3c8840772271bd7f1399c65d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.9.13

Release files / lukhed_stocks-0.3.3-py3-none-any.whl

Download URL lukhed_stocks-0.3.3-py3-none-any.whl
Size 42.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a9042d928d7c867c95547d56064fe74cf6109f2c4d87703022a3b6cf7194c5bb
BLAKE2b-256 checksum
How to use checksums
0ed362d7ad5400e94f40bdaa4e0cc40df1d3d299e4c0c96bbab4f8858c1ddd02
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.9.13

Release history Release notifications | RSS feed

0.3.4

2 release files

This release

0.3.3 This release

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page