Your friendly Python library for fetching Thai stock market data πΉπ
settfex makes it super easy to get stock market data from the Stock Exchange of Thailand (SET) and Thailand Futures Exchange (TFEX). Whether you're building a trading bot, doing market analysis, or just curious about Thai stocks, we've got you covered!
pip install settfexOptional: To run the Jupyter notebook examples, install with:
pip install settfex[examples]This includes pandas, matplotlib, and jupyter notebook support.
New to settfex? Start here! We have comprehensive Jupyter notebook examples that teach you everything step-by-step:
Beginners : Start with these three notebooks to get comfortable:
- Stock List - Discover all Thai stocks
- Highlight Data - Get key metrics like P/E, market cap, dividends
- Corporate Actions - Track dividends and shareholder meetings
Fundamental Analysis : Build a complete stock analysis workflow:
Professional Trading : Master all features for institutional use:
- All 11 SET notebooks + 2 TFEX notebooks (see below)
All examples include beginner explanations, professional trading use cases, and data export examples:
- Stock List - Fetch and filter all stocks, build portfolio universes
- Highlight Data - Value screeners, dividend portfolios, risk-adjusted returns
- Stock Profile - Listing details, IPO data, foreign ownership
- Company Profile - ESG ratings, governance scores, management
- Corporate Actions - Dividend calendars, shareholder meetings
- Shareholder Data - Ownership analysis, free float monitoring
- NVDR Holders - NVDR ownership tracking and analysis
- Board of Directors - Board composition and management structure
- Trading Statistics - Multi-period performance and volatility
- Price Performance - Sector comparison and alpha calculation
- Financial Statements - Balance sheet, income, cash flow analysis
Professional derivatives trading workflows with margin calculations and risk management:
- Series List - Discover futures/options, rollover monitoring, options chains
- Trading Statistics - Margin requirements, position sizing, P/L tracking
π View All Examples - Complete index with learning guides
Want to dig deeper? Check out our detailed guides:
- Stock List Service - Get all stocks on SET/mai
- Highlight Data Service - Market metrics and valuations
- Stock Profile Service - Listing details and share structure
- Company Profile Service - Full company information
- Corporate Action Service - Dividends, meetings, and events
- Shareholder Service - Major shareholders and ownership data
- NVDR Holder Service - NVDR holder information and ownership
- Board of Director Service - Board of directors and management structure
- Trading Statistics Service - Historical trading performance and metrics
- Price Performance Service - Stock, sector, and market price performance comparison
- Financial Service - Balance sheet, income statement, and cash flow data
- TFEX Series List Service - Get all futures and options series on TFEX
- TFEX Trading Statistics Service - Trading statistics, settlement prices, and margin requirements
- AsyncDataFetcher - Low-level async HTTP client
- Session Caching - How we make things 25x faster
Want to see all stocks trading on SET? Easy!
from settfex.services.set import get_stock_list
stock_list = await get_stock_list()
print(f"Found {stock_list.count} stocks!")
# Filter by market
set_stocks = stock_list.filter_by_market("SET")
mai_stocks = stock_list.filter_by_market("mai")π Learn more about Stock Lists
Need market cap, P/E ratio, dividend yield? We got you!
from settfex.services.set import Stock
stock = Stock("CPALL")
data = await stock.get_highlight_data()
print(f"Market Cap: {data.market_cap:,.0f} THB")
print(f"P/E Ratio: {data.pe_ratio}")
print(f"Dividend Yield: {data.dividend_yield}%")π Learn more about Highlight Data
Want to know when a company was listed? Its IPO price? Foreign ownership limits?
from settfex.services.set import get_profile
profile = await get_profile("PTT")
print(f"Listed: {profile.listed_date}")
print(f"IPO Price: {profile.ipo} {profile.currency}")
print(f"Foreign Limit: {profile.percent_foreign_limit}%")π Learn more about Stock Profiles
Curious about company details, management, auditors, or ESG ratings?
from settfex.services.set import get_company_profile
company = await get_company_profile("CPN")
print(f"Company: {company.name}")
print(f"Website: {company.url}")
print(f"CG Score: {company.cg_score}/5")
print(f"ESG Rating: {company.setesg_rating}")
print(f"Executives: {len(company.managements)}")π Learn more about Company Profiles
Track dividends, shareholder meetings, and other corporate events:
from settfex.services.set import get_corporate_actions
actions = await get_corporate_actions("AOT")
for action in actions:
if action.ca_type == "XD":
print(f"Dividend: {action.dividend} {action.currency}")
print(f"XD Date: {action.x_date}")
print(f"Payment Date: {action.payment_date}")
elif action.ca_type == "XM":
print(f"Meeting: {action.meeting_type}")
print(f"Agenda: {action.agenda}")π Learn more about Corporate Actions
See who owns what! Get major shareholders, free float, and ownership distribution:
from settfex.services.set import get_shareholder_data
data = await get_shareholder_data("MINT")
print(f"Total Shareholders: {data.total_shareholder:,}")
print(f"Free Float: {data.free_float.percent_free_float:.2f}%")
for sh in data.major_shareholders[:5]:
print(f"{sh.sequence}. {sh.name}: {sh.percent_of_share:.2f}%")π Learn more about Shareholder Data
Track Non-Voting Depository Receipt (NVDR) holders and their ownership:
from settfex.services.set import get_nvdr_holder_data
data = await get_nvdr_holder_data("MINT")
print(f"Symbol: {data.symbol}") # MINT-R
print(f"Total NVDR Holders: {data.total_shareholder:,}")
for holder in data.major_shareholders[:5]:
print(f"{holder.sequence}. {holder.name}: {holder.percent_of_share:.2f}%")π Learn more about NVDR Holder Data
See who's running the show! Get board of directors and management information:
from settfex.services.set import get_board_of_directors
directors = await get_board_of_directors("MINT")
for director in directors:
positions = ", ".join(director.positions)
print(f"{director.name}: {positions}")
# Find the Chairman
chairman = next((d for d in directors if "CHAIRMAN" in d.positions), None)
if chairman:
print(f"Chairman: {chairman.name}")π Learn more about Board of Directors
Track historical trading performance with comprehensive statistics across multiple time periods:
from settfex.services.set import get_trading_stats
stats = await get_trading_stats("MINT")
# YTD performance
ytd = next(s for s in stats if s.period == "YTD")
print(f"YTD Performance: {ytd.percent_change:.2f}%")
print(f"Current Price: {ytd.close:.2f} THB")
print(f"P/E Ratio: {ytd.pe}, Market Cap: {ytd.market_cap:,.0f} THB")
# Compare different periods
for stat in stats:
print(f"{stat.period}: {stat.close:.2f} THB ({stat.percent_change:+.2f}%)")π Learn more about Trading Statistics
Compare stock performance against sector and market with comprehensive price change data:
from settfex.services.set import get_price_performance
data = await get_price_performance("MINT")
# Stock performance
print(f"Stock: {data.stock.symbol}")
print(f" YTD: {data.stock.ytd_percent_change:+.2f}%")
print(f" P/E: {data.stock.pe_ratio}, P/B: {data.stock.pb_ratio}")
# Sector comparison
print(f"Sector ({data.sector.symbol}): {data.sector.ytd_percent_change:+.2f}%")
# Market comparison
print(f"Market ({data.market.symbol}): {data.market.ytd_percent_change:+.2f}%")π Learn more about Price Performance
Fetch comprehensive financial data including balance sheet, income statement, and cash flow:
from settfex.services.set import (
get_balance_sheet,
get_income_statement,
get_cash_flow
)
# Balance sheet
balance_sheets = await get_balance_sheet("CPALL")
latest = balance_sheets[0]
print(f"Period: {latest.quarter} {latest.year}")
print(f"Total Assets: {latest.accounts[0].amount:,.0f}K")
# Income statement
income_statements = await get_income_statement("CPALL")
for stmt in income_statements[:3]:
print(f"{stmt.quarter} {stmt.year}: {stmt.status}")
# Cash flow
cash_flows = await get_cash_flow("CPALL")π Learn more about Financial Service
Want to see all futures and options trading on TFEX? Easy!
from settfex.services.tfex import get_series_list
series_list = await get_series_list()
print(f"Found {series_list.count} series!")
# Filter active futures only
active_futures = [s for s in series_list.get_futures() if s.active]
print(f"Active futures: {len(active_futures)}")
# Filter by underlying
set50_series = series_list.filter_by_underlying("SET50")
print(f"SET50 contracts: {len(set50_series)}")π Learn more about TFEX Series List
Get comprehensive trading statistics including settlement prices, margin requirements, and days to maturity!
from settfex.services.tfex import get_trading_statistics
stats = await get_trading_statistics("S50Z25")
print(f"Settlement Price: {stats.settlement_price:.5f}")
print(f"Days to Maturity: {stats.day_to_maturity}")
print(f"Initial Margin: {stats.im:,.2f} THB")
print(f"Maintenance Margin: {stats.mm:,.2f} THB")
# Calculate margin coverage
capital = 500000
max_contracts = int(capital / stats.im)
print(f"Can trade {max_contracts} contracts with {capital:,.0f} THB")π Learn more about TFEX Trading Statistics
First request takes ~2 seconds (warming up). After that? 100ms! That's 25x faster thanks to smart session caching.
Dual-Site Support: Separate cached sessions for SET and TFEX - each optimized for its own API!
π Learn about Session Caching
Full UTF-8 support for Thai characters. Company names, sectors, everything just works!
Everything is type-hinted and validated with Pydantic. Your IDE will love it!
Beautiful logs with loguru. Debug issues easily or turn them off in production.
Here's everything in action:
import asyncio
from settfex.services.set import (
get_stock_list,
get_profile,
get_company_profile,
get_corporate_actions,
get_board_of_directors,
get_trading_stats,
Stock
)
async def analyze_stock(symbol: str):
# Get basic info from stock list
stock_list = await get_stock_list()
stock_info = stock_list.get_symbol(symbol)
if not stock_info:
print(f"Stock {symbol} not found!")
return
print(f"π {stock_info.name_en} ({symbol})")
print(f"Market: {stock_info.market}")
print(f"Sector: {stock_info.sector}")
# Get detailed metrics
stock = Stock(symbol)
highlight = await stock.get_highlight_data()
print(f"\nπ° Valuation:")
print(f"Market Cap: {highlight.market_cap:,.0f} THB")
print(f"P/E Ratio: {highlight.pe_ratio}")
print(f"Dividend Yield: {highlight.dividend_yield}%")
# Get listing details
profile = await get_profile(symbol)
print(f"\nπ
Listed: {profile.listed_date}")
print(f"IPO: {profile.ipo} {profile.currency}")
# Get company info
company = await get_company_profile(symbol)
print(f"\nπ’ {company.name}")
print(f"Website: {company.url}")
print(f"ESG Rating: {company.setesg_rating}")
# Get corporate actions
actions = await get_corporate_actions(symbol)
print(f"\nπ
Corporate Actions: {len(actions)}")
for action in actions[:3]: # Show first 3
if action.ca_type == "XD":
print(f" Dividend: {action.dividend} {action.currency}")
elif action.ca_type == "XM":
print(f" Meeting: {action.meeting_type}")
# Get board of directors
directors = await get_board_of_directors(symbol)
print(f"\nπ Board of Directors: {len(directors)}")
chairman = next((d for d in directors if "CHAIRMAN" in d.positions), None)
if chairman:
print(f" Chairman: {chairman.name}")
# Get trading statistics
stats = await get_trading_stats(symbol)
ytd = next((s for s in stats if s.period == "YTD"), None)
if ytd:
print(f"\nπ Trading Statistics (YTD):")
print(f" Performance: {ytd.percent_change:+.2f}%")
print(f" Volume: {ytd.total_volume:,.0f} shares")
print(f" Turnover: {ytd.turnover_ratio:.2f}%")
# Run it!
asyncio.run(analyze_stock("PTT"))Need more control? We've got you covered!
from settfex.utils.data_fetcher import AsyncDataFetcher, FetcherConfig
# Custom configuration
config = FetcherConfig(
timeout=60, # Longer timeout
max_retries=5, # More retries
browser_impersonate="safari17_0" # Different browser
)
# Use with any service
from settfex.services.set.stock import StockHighlightDataService
service = StockHighlightDataService(config=config)
data = await service.fetch_highlight_data("CPALL")π Learn more about AsyncDataFetcher
By default, settfex only shows ERROR-level logs to keep your terminal clean. Want to see more?
from settfex.utils.logging import setup_logger
# Turn on detailed logs for debugging
setup_logger(level="DEBUG", log_file="logs/settfex.log")
# Or just INFO level for general monitoring
setup_logger(level="INFO")
# Now run your code - you'll see what's happening!
stock_list = await get_stock_list()Great for debugging or monitoring in production. Default is ERROR level for clean output.
We'd love your help making settfex better! Here's how:
- Fork the repo
- Create a feature branch:
git checkout -b feature/cool-new-thing - Make your changes with proper type hints and tests
- Run tests:
pytest - Run linting:
ruff check . - Commit:
git commit -m 'Add cool new thing' - Push:
git push origin feature/cool-new-thing - Open a Pull Request
MIT License - feel free to use this in your projects!
This library is not officially affiliated with the Stock Exchange of Thailand or Thailand Futures Exchange. Use at your own risk for educational and informational purposes.
- π Check the detailed documentation
- π Found a bug? Open an issue