### Example: Display Management Structure Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/profile_company.md Illustrates how to retrieve and display information about a company's management team, including their positions and start dates. The example limits output to the top 5 executives. ```python async def show_management(): profile = await get_company_profile("CPALL") print(f"Management Team ({len(profile.managements)} executives):") for mgmt in profile.managements[:5]: # Show top 5 print(f" {mgmt.position}: {mgmt.name}") print(f" Since: {mgmt.start_date.strftime('%Y-%m-%d')}") asyncio.run(show_management()) ``` -------------------------------- ### Compare Multiple Stocks Example (Python) Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/highlight_data.md An asynchronous example demonstrating the use of `StockHighlightDataService.fetch_highlight_data` to compare P/E and P/B ratios across a list of stock symbols. It formats the output for easy comparison. ```python import asyncio from settfex.services.set.stock import StockHighlightDataService async def compare_stocks(symbols: list[str]): """Compare P/E and P/B ratios across multiple stocks.""" service = StockHighlightDataService() print(f"{'Symbol':<10} {'P/E':<10} {'P/B':<10} {'Div Yield':<12}") print("-" * 50) for symbol in symbols: data = await service.fetch_highlight_data(symbol) print(f"{data.symbol:<10} {data.pe_ratio:<10.2f} {data.pb_ratio:<10.2f} {data.dividend_yield:<12.2f}%") asyncio.run(compare_stocks(["CPALL", "PTT", "KBANK", "AOT", "BBL"])) ``` -------------------------------- ### Example: Display Capital Structure Details Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/profile_company.md Provides an example of how to access and display a company's capital structure, including authorized and paid-up capital, par value for common stock, and details on voting rights. ```python async def show_capital(): profile = await get_company_profile("AOT") # Common stock print("Common Stock:") print(f" Authorized: {profile.common_capital.authorized_capital:,.2f} {profile.common_capital.currency}") print(f" Paid-up: {profile.common_capital.paidup_capital:,.2f} {profile.common_capital.currency}") print(f" Par Value: {profile.common_capital.par} {profile.common_capital.currency}") print(f" Listed Shares: {profile.commons_share.listed_share:,}") # Voting rights if profile.commons_share.voting_rights: print("\nVoting Rights:") for vr in profile.commons_share.voting_rights: print(f" {vr.symbol}: {vr.paidup_share:,} shares, Ratio: {vr.ratio}") asyncio.run(show_capital()) ``` -------------------------------- ### Install settfex Package Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/nvdr_holder.md Installs the settfex package using pip or uv. This package provides the NVDR Holder Service. ```bash pip install settfex # or uv add settfex ``` -------------------------------- ### Complete Settfex Application Example (Python) Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/list.md This comprehensive example demonstrates a complete Settfex application. It includes setting up logging, configuring custom fetcher settings, fetching stock lists asynchronously, filtering stocks by market, displaying top stocks, and searching for specific stock details. Error handling is also included. ```python import asyncio from loguru import logger from settfex.services.set import get_stock_list from settfex.utils.logging import setup_logger from settfex.utils.data_fetcher import FetcherConfig async def main(): # Setup logging setup_logger(level="INFO", log_file="logs/app.log") # Configure with custom settings config = FetcherConfig( timeout=60, max_retries=3, browser_impersonate="chrome120" ) try: # Fetch stock list logger.info("Fetching stock list...") stock_list = await get_stock_list(config=config) logger.info(f"Fetched {stock_list.count} stocks") # Analyze markets set_stocks = stock_list.filter_by_market("SET") mai_stocks = stock_list.filter_by_market("mai") print(f"\nMarket Summary:") print(f" SET: {len(set_stocks)} stocks") print(f" mai: {len(mai_stocks)} stocks") # Top 10 stocks print(f"\nFirst 10 stocks:") for stock in stock_list.security_symbols[:10]: print(f" {stock.symbol:8} {stock.name_en}") # Search for specific stock symbol = "PTT" stock = stock_list.get_symbol(symbol) if stock: print(f"\nStock Details for {symbol}:") print(f" English: {stock.name_en}") print(f" Thai: {stock.name_th}") print(f" Market: {stock.market}") print(f" Industry: {stock.industry}") except Exception as e: logger.error(f"Application failed: {e}") raise if __name__ == "__main__": asyncio.run(main()) ``` -------------------------------- ### StockListResponse Get Symbol Method Example (Python) Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/list.md Demonstrates how to use the `get_symbol` method of the `StockListResponse` object to retrieve a specific stock by its symbol. The example includes a check to see if the stock was found and prints its English name if it exists. ```python ptt = response.get_symbol("PTT") if ptt: print(ptt.name_en) else: print("Stock not found") ``` -------------------------------- ### Basic Stock Analysis Example (Python) Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/highlight_data.md An asynchronous example demonstrating how to use `get_highlight_data` to fetch and display key financial metrics for a given stock symbol. It includes printing market cap, P/E ratio, P/B ratio, dividend yield, beta, YTD change, and 52-week range. ```python import asyncio from settfex.services.set.stock import get_highlight_data async def analyze_stock(symbol: str): """Analyze key metrics for a stock.""" data = await get_highlight_data(symbol) print(f"\n{data.symbol} - Stock Analysis") print("=" * 50) print(f"Market Cap: {data.market_cap:,.0f} THB") print(f"P/E Ratio: {data.pe_ratio}") print(f"P/B Ratio: {data.pb_ratio}") print(f"Dividend Yield: {data.dividend_yield}%") print(f"Beta: {data.beta}") print(f"YTD Change: {data.ytd_percent_change:.2f}%") print(f"52-Week Range: {data.year_low_price} - {data.year_high_price}") asyncio.run(analyze_stock("CPALL")) ``` -------------------------------- ### Python Example: Real-time TFEX Data Fetching Source: https://github.com/lumduan/settfex/blob/main/CLAUDE.md This Python script demonstrates fetching real-time data from the Thailand Futures Exchange (TFEX) using the settfex library. It highlights the usage of the TFEX real-time client. Assumes settfex is installed. ```python # Example usage for fetching real-time TFEX data # Requires settfex library to be installed from settfex.services.tfex.realtime import TFEXRealtimeClient async def fetch_tfex_realtime_data(): """Fetches and prints real-time data for TFEX.""" client = TFEXRealtimeClient() try: # Example: Fetching data for a specific TFEX product (e.g., 'GF10G23') # Replace 'GF10G23' with actual TFEX product codes you want to track data = await client.get_realtime_data(['GF10G23']) print("Real-time TFEX Data:") for product, info in data.items(): print(f" {product}: Last Price = {info.get('last_price')}, Change = {info.get('change')}") except Exception as e: print(f"An error occurred: {e}") if __name__ == "__main__": import asyncio asyncio.run(fetch_tfex_realtime_data()) ``` -------------------------------- ### Python Example: Real-time SET Data Fetching Source: https://github.com/lumduan/settfex/blob/main/CLAUDE.md This Python script demonstrates how to fetch real-time data from the Stock Exchange of Thailand (SET). It utilizes the settfex library's services for real-time data retrieval. Assumes settfex is installed and configured. ```python # Example usage for fetching real-time SET data # Requires settfex library to be installed from settfex.services.set.realtime import SETRealtimeClient async def fetch_set_realtime_data(): """Fetches and prints real-time data for SET.""" client = SETRealtimeClient() try: # Example: Fetching data for a specific stock symbol (e.g., 'ADVANC') # Replace 'ADVANC' with actual stock symbols you want to track data = await client.get_realtime_data(['ADVANC']) print("Real-time SET Data:") for symbol, info in data.items(): print(f" {symbol}: Last Price = {info.get('last_price')}, Change = {info.get('change')}") except Exception as e: print(f"An error occurred: {e}") if __name__ == "__main__": import asyncio asyncio.run(fetch_set_realtime_data()) ``` -------------------------------- ### Python Example: Getting Stock List Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/corporate_action.md Shows how to import and potentially use the `get_stock_list` function, which is relevant for validating stock symbols as described in the 'Invalid Symbol' troubleshooting section. ```python from settfex.services.set import get_stock_list ``` -------------------------------- ### Install settfex Python Library Source: https://github.com/lumduan/settfex/blob/main/README.md Installs the settfex Python package using pip. This is the first step to using the library for fetching Thai stock market data. ```bash pip install settfex ``` -------------------------------- ### Python Example: Historical SET Data Fetching Source: https://github.com/lumduan/settfex/blob/main/CLAUDE.md This Python script illustrates fetching historical data for the Stock Exchange of Thailand (SET) using the settfex library. It shows how to specify date ranges and retrieve historical stock information. Requires settfex to be installed. ```python # Example usage for fetching historical SET data # Requires settfex library to be installed from settfex.services.set.historical import SETHistoricalClient from datetime import date async def fetch_set_historical_data(): """Fetches and prints historical data for SET.""" client = SETHistoricalClient() try: # Example: Fetching historical data for 'ADVANC' between two dates # Replace 'ADVANC' with actual stock symbols and adjust dates as needed symbol = 'ADVANC' start_date = date(2023, 1, 1) end_date = date(2023, 1, 5) data = await client.get_historical_data(symbol, start_date, end_date) print(f"Historical SET Data for {symbol} ({start_date} to {end_date}):") for record in data: print(f" Date: {record.get('date')}, Open: {record.get('open')}, High: {record.get('high')}, Low: {record.get('low')}, Close: {record.get('close')}") except Exception as e: print(f"An error occurred: {e}") if __name__ == "__main__": import asyncio asyncio.run(fetch_set_historical_data()) ``` -------------------------------- ### Initialize Stock with Default Caching (Python) Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/utils/session_caching.md Demonstrates initializing a `Stock` object with caching enabled by default. No specific parameters are needed to activate caching, simplifying its usage. ```python stock = Stock("PTT") # Caching enabled by default ``` -------------------------------- ### Bash Build and Publish Commands for PyPI Source: https://github.com/lumduan/settfex/blob/main/docs/guide/PYTHON_LIBRARY_BEST_PRACTICES.md Provides the command-line instructions to build Python package distributions and upload them to the Python Package Index (PyPI). It includes installing necessary tools (`build`, `twine`), creating the distributions, and performing the upload. ```bash # Install build tools uv pip install build twine # Build distribution python -m build # Upload to PyPI twine upload dist/* ``` -------------------------------- ### Python Example: Concurrent Fetching Best Practice Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/corporate_action.md Demonstrates the recommended approach for fetching data from multiple stocks concurrently using `asyncio.gather`. This pattern significantly improves performance compared to sequential fetching. ```python symbols = ["AOT", "PTT", "CPALL", "KBANK", "BBL"] tasks = [get_corporate_actions(s) for s in symbols] results = await asyncio.gather(*tasks) ``` -------------------------------- ### Python Example: Fetching Corporate Actions Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/corporate_action.md A simple Python example demonstrating how to use the convenience function `get_corporate_actions` to fetch corporate actions for a given stock symbol. This is suitable for straightforward use cases. ```python actions = await get_corporate_actions("AOT") ``` -------------------------------- ### Example: Basic Company Information Retrieval Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/profile_company.md Demonstrates how to fetch and display fundamental company details such as name, symbol, market, sector, industry, website, and establishment date using the `get_company_profile` function. ```python import asyncio from settfex.services.set import get_company_profile async def main(): profile = await get_company_profile("CPN") print(f"Company: {profile.name}") print(f"Symbol: {profile.symbol}") print(f"Market: {profile.market}") print(f"Sector: {profile.sector_name} ({profile.sector})") print(f"Industry: {profile.industry_name} ({profile.industry})") print(f"Website: {profile.url}") print(f"Established: {profile.established_date}") asyncio.run(main()) ``` -------------------------------- ### Usage Examples Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/utils/data_fetcher.md Illustrative examples demonstrating how to use the AsyncDataFetcher for various tasks including fetching web pages, JSON data with retries, and making authenticated requests. ```APIDOC ## Usage Examples ### Example 1: Fetch SET Stock Quote Page ```python import asyncio from settfex.utils.data_fetcher import AsyncDataFetcher async def fetch_set_quote(): """Fetch SET stock quote page with Thai content.""" async with AsyncDataFetcher() as fetcher: response = await fetcher.fetch( "https://www.set.or.th/th/market/product/stock/quote" ) # Check if Thai text is present if "ตลาดหลักทรัพย์" in response.text: print("✓ Thai text decoded correctly") print(f"Status: {response.status_code}") print(f"Size: {len(response.content):,} bytes") print(f"Time: {response.elapsed:.2f}s") asyncio.run(fetch_set_quote()) ``` ### Example 2: Fetch JSON Data with Retry ```python async def fetch_with_retry(): """Fetch JSON data with custom retry settings.""" from settfex.utils.data_fetcher import FetcherConfig config = FetcherConfig( max_retries=5, retry_delay=2.0, timeout=30 ) async with AsyncDataFetcher(config=config) as fetcher: try: data = await fetcher.fetch_json( "https://api.example.com/market/data" ) print(f"Received {len(data)} items") except Exception as e: print(f"Failed after retries: {e}") asyncio.run(fetch_with_retry()) ``` ### Example 3: Custom Headers and Cookies ```python async def fetch_with_auth(): """Fetch data with authentication.""" async with AsyncDataFetcher() as fetcher: response = await fetcher.fetch( "https://api.example.com/private/data", headers={ "Authorization": "Bearer token123", "X-API-Version": "v2" }, cookies="session=abc123; auth=xyz789" ) print(f"Authenticated request: {response.status_code}") asyncio.run(fetch_with_auth()) ``` ``` -------------------------------- ### Example: Show Auditor Information Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/profile_company.md Demonstrates how to fetch and display details about a company's audit, including the audit end date, opinion, and a list of auditors with their associated firms and audit periods. ```python async def show_auditors(): profile = await get_company_profile("KBANK") print(f"Audit Information:") print(f" Audit End: {profile.audit_end.strftime('%Y-%m-%d')}") print(f" Audit Opinion: {profile.audit_choice}") print(f"\nAuditors ({len(profile.auditors)}):") for auditor in profile.auditors: print(f" {auditor.name}") print(f" Firm: {auditor.company}") print(f" Period: {auditor.audit_end_date.strftime('%Y-%m-%d')}") asyncio.run(show_auditors()) ``` -------------------------------- ### Install settfex Dependencies Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/utils/data_fetcher.md Installs the necessary Python packages for AsyncDataFetcher, including curl-cffi for browser impersonation, pydantic for data validation, and loguru for logging. ```bash uv pip install curl-cffi>=0.6.0 pydantic>=2.0.0 loguru>=0.7.0 ``` -------------------------------- ### FetcherConfig Model Definition Example Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/utils/data_fetcher.md Provides an example of how to instantiate the `FetcherConfig` Pydantic model with specific parameters for `AsyncDataFetcher`. This includes setting the browser impersonation, timeout, retry logic, and user agent. ```python from settfex.utils.data_fetcher import FetcherConfig config = FetcherConfig( browser_impersonate="chrome120", timeout=30, max_retries=3, retry_delay=1.0 ) ``` -------------------------------- ### Python Example: Handling Empty Results (Troubleshooting) Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/corporate_action.md A Python snippet illustrating how to check for and handle empty results when fetching corporate actions. This is presented as a solution for the 'Empty Results' troubleshooting scenario. ```python actions = await get_corporate_actions("XYZ") if not actions: print("No corporate actions found for this stock") ``` -------------------------------- ### StockSymbol Model Example (Python) Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/list.md Provides an example of how to access the fields of a `StockSymbol` Pydantic model after retrieving a specific stock. It shows how to print the symbol, English name, Thai name, market, industry, and sector for a given stock object. ```python stock = stock_list.get_symbol("PTT") print(f"Symbol: {stock.symbol}") print(f"English: {stock.name_en}") print(f"Thai: {stock.name_th}") print(f"Market: {stock.market}") print(f"Industry: {stock.industry}") ``` -------------------------------- ### StockListResponse Filter Methods Example (Python) Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/list.md Illustrates the usage of the `filter_by_market` and `filter_by_industry` methods on a `StockListResponse` object. This example shows how to obtain lists of stocks filtered by specific market types ('SET', 'mai') and industry classifications ('BANK', 'TECH'). ```python set_stocks = response.filter_by_market("SET") mai_stocks = response.filter_by_market("mai") bank_stocks = response.filter_by_industry("BANK") tech_stocks = response.filter_by_industry("TECH") ``` -------------------------------- ### Bash Example: Running Pytest Tests Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/corporate_action.md Bash commands to execute the pytest test suite for corporate action services. It shows how to run all tests, run a specific test case by its name, and how to run tests with code coverage. ```bash # Run all corporate action tests uv pip run pytest tests/services/set/test_corporate_action.py -v # Run specific test uv pip run pytest tests/services/set/test_corporate_action.py::TestCorporateActionService::test_fetch_corporate_actions_success -v ``` -------------------------------- ### Settfex Project Structure Overview Source: https://github.com/lumduan/settfex/blob/main/CLAUDE.md This snippet details the directory structure of the settfex Python project. It shows the organization of the main package, services, tests, documentation, examples, and scripts, along with configuration files. ```tree settfex/ ├── settfex/ # Main package │ ├── __init__.py │ ├── services/ # Business logic and API integrations │ │ ├── __init__.py │ │ ├── set/ # SET-specific services │ │ │ ├── __init__.py │ │ │ ├── client.py # SET API client │ │ │ ├── realtime.py # Real-time data fetching │ │ │ └── historical.py # Historical data fetching │ │ └── tfex/ # TFEX-specific services │ │ ├── __init__.py │ │ ├── client.py # TFEX API client │ │ ├── realtime.py # Real-time data fetching │ │ └── historical.py # Historical data fetching │ └── utils/ # Helper functions and utilities │ ├── __init__.py │ ├── logging.py # Logging utilities │ ├── validation.py # Data validation │ ├── formatting.py # Data formatting │ ├── http.py # HTTP utilities │ └── data_fetcher.py # Async data fetcher with Thai/Unicode support ├── tests/ # Test suite │ ├── __init__.py │ ├── conftest.py # Pytest configuration │ ├── services/ │ │ ├── set/ │ │ └── tfex/ │ └── utils/ ├── docs/ # Documentation │ ├── index.md │ ├── installation.md │ ├── quickstart.md │ ├── api-reference.md │ └── contributing.md ├── examples/ # Usage examples │ ├── set_realtime_example.py │ ├── set_historical_example.py │ ├── tfex_realtime_example.py │ └── tfex_historical_example.py ├── scripts/ # Utility scripts │ ├── build.py │ ├── release.py │ └── test.py ├── pyproject.toml # Project configuration ├── README.md # Project overview ├── LICENSE # MIT License ├── .gitignore # Git ignore rules └── CLAUDE.md # This file ``` -------------------------------- ### Correct SessionManager Singleton Usage (Python) Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/utils/session_caching.md Demonstrates the correct method for using `SessionManager` by obtaining a single instance using `get_instance()` before a loop. This ensures that the same manager and its cache are reused for multiple requests. ```python # ✅ Good: Reuse singleton manager = await SessionManager.get_instance() for symbol in symbols: await manager.get(url) ``` -------------------------------- ### Force Cache Warmup (Python) Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/utils/session_caching.md Shows how to force a cache warmup using the `ensure_initialized` method with the `force_warmup=True` parameter. This is useful for troubleshooting when the cache might not be working as expected, ensuring a fresh session is loaded. ```python # Try force refresh: `ensure_initialized(force_warmup=True)` ``` -------------------------------- ### Compare Multiple Companies' Profiles Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/profile_company.md Compares key metrics (CG score, ESG rating, CAC flag) for multiple companies by fetching their profiles concurrently. This example showcases efficient data retrieval for a list of stock symbols. ```python async def compare_companies(): symbols = ["PTT", "KBANK", "CPALL", "AOT"] from settfex.services.set.stock import CompanyProfileService service = CompanyProfileService() tasks = [ service.fetch_company_profile(symbol) for symbol in symbols ] profiles = await asyncio.gather(*tasks) print("Company Comparison:") for profile in profiles: print(f"{profile.symbol}: CG={profile.cg_score}, ESG={profile.setesg_rating}, CAC={'✓' if profile.cac_flag else '✗'}") asyncio.run(compare_companies()) ``` -------------------------------- ### Python Package Entry Point (__init__.py) Example Source: https://github.com/lumduan/settfex/blob/main/docs/guide/PYTHON_LIBRARY_BEST_PRACTICES.md Demonstrates the best practices for a Python package's entry point file (`__init__.py`). It includes a package docstring, metadata exports (__version__, __author__, __license__), importing and re-exporting public API members, and declaring the public API using `__all__`. This ensures a clean and predictable user experience. ```python """settfex - Stock Exchange of Thailand Data Library. Usage: >>> from settfex import Stock, get_stock_list >>> stock_list = await get_stock_list() """ __version__ = "0.1.0" __author__ = "Your Name" __license__ = "MIT" # Public API exports from settfex.services.set import ( Stock, get_stock_list, ) __all__ = [ "__version__", "Stock", "get_stock_list", ] ``` -------------------------------- ### Python Example: Reusing Service Instance Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/corporate_action.md Illustrates the best practice of reusing a `CorporateActionService` instance for multiple requests to improve efficiency. This avoids the overhead of creating a new service object for each API call. ```python service = CorporateActionService() actions1 = await service.fetch_corporate_actions("AOT") actions2 = await service.fetch_corporate_actions("PTT") ``` -------------------------------- ### Bash Example: Running Pytest with Coverage Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/corporate_action.md A bash command to run the pytest test suite with code coverage enabled. It specifies the test file and requests an HTML report of the coverage results, useful for analyzing test effectiveness. ```bash # Run with coverage uv pip run pytest tests/services/set/test_corporate_action.py --cov=settfex.services.set.stock.corporate_action --cov-report=html ``` -------------------------------- ### Get Singleton SessionManager Instance (Python) Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/utils/session_caching.md Retrieves the singleton instance of `SessionManager`. Using `get_instance()` ensures that only one `SessionManager` object is active throughout the application, promoting efficient resource management and consistent state. ```python manager = await SessionManager.get_instance() ``` -------------------------------- ### Set Appropriate TTL for SessionManager (Python) Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/utils/session_caching.md Configures a `SessionManager` with a specific cache TTL of 1 hour (3600 seconds). This example highlights the best practice of balancing data freshness with performance by setting an appropriate cache duration. ```python manager = SessionManager(cache_ttl=3600) # 1 hour ``` -------------------------------- ### Initialize ShareholderService (Python) Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/shareholder.md Shows how to instantiate the `ShareholderService` class, which is the primary service for fetching shareholder data. It demonstrates initialization with default settings (which automatically use `SessionManager`) and with custom `FetcherConfig` for network parameters. ```python from settfex.services.set.stock import ShareholderService from settfex.utils.data_fetcher import FetcherConfig # Default configuration (uses SessionManager automatically) service = ShareholderService() # Custom configuration config = FetcherConfig(timeout=60, max_retries=5) service = ShareholderService(config=config) ``` -------------------------------- ### Handling Auto-Retry Errors (Python) Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/utils/session_caching.md Provides an example of how to properly handle potential errors after a request made with `SessionManager`, especially when auto-retry mechanisms might have been involved. It includes a try-except block to catch exceptions and checks the response status code. ```python # ❌ Bad: No error handling response = await manager.get(url) # ✅ Good: Handle failures after retry try: response = await manager.get(url) if response.status_code != 200: logger.error(f"Failed: {response.status_code}") except Exception as e: logger.error(f"Request failed: {e}") ``` -------------------------------- ### Initialize Stock with Default Configuration (DO) Source: https://github.com/lumduan/settfex/blob/main/docs/solution/SOLUTION_100_PERCENT.md Demonstrates the recommended way to initialize the Stock class, relying on the default FetcherConfig settings which include `use_session=True`. This ensures optimal performance and success rates without explicit configuration. ```python # Use default settings (session enabled) stock = Stock("CPALL") data = await stock.get_highlight_data() ``` -------------------------------- ### Python Example: Historical TFEX Data Fetching Source: https://github.com/lumduan/settfex/blob/main/CLAUDE.md This Python script shows how to retrieve historical data from the Thailand Futures Exchange (TFEX) using the settfex library. It covers specifying product codes and date ranges for historical queries. Requires settfex to be installed. ```python # Example usage for fetching historical TFEX data # Requires settfex library to be installed from settfex.services.tfex.historical import TFEXHistoricalClient from datetime import date async def fetch_tfex_historical_data(): """Fetches and prints historical data for TFEX.""" client = TFEXHistoricalClient() try: # Example: Fetching historical data for 'GF10G23' between two dates # Replace 'GF10G23' with actual TFEX product codes and adjust dates as needed product_code = 'GF10G23' start_date = date(2023, 1, 1) end_date = date(2023, 1, 5) data = await client.get_historical_data(product_code, start_date, end_date) print(f"Historical TFEX Data for {product_code} ({start_date} to {end_date}):") for record in data: print(f" Date: {record.get('date')}, Open: {record.get('open')}, High: {record.get('high')}, Low: {record.get('low')}, Close: {record.get('close')}") except Exception as e: print(f"An error occurred: {e}") if __name__ == "__main__": import asyncio asyncio.run(fetch_tfex_historical_data()) ``` -------------------------------- ### TOML Project Configuration (pyproject.toml) Example Source: https://github.com/lumduan/settfex/blob/main/docs/guide/PYTHON_LIBRARY_BEST_PRACTICES.md Shows a modern `pyproject.toml` file used for configuring Python projects, including metadata, build system requirements, and tool-specific configurations like pytest and ruff. This file serves as the single source of truth for project settings. ```toml [project] name = "settfex" version = "0.1.0" description = "Your description" readme = "README.md" requires-python = ">=3.11" dependencies = [ "httpx>=0.27.0", "pydantic>=2.0.0", ] [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [tool.pytest.ini_options] testpaths = ["tests"] [tool.ruff] line-length = 100 [tool.mypy] strict = true ``` -------------------------------- ### Get Corporate Actions with Custom Language and Config (Python) Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/corporate_action.md This example shows how to call the `get_corporate_actions` function with specific language settings ('th' for Thai) and a custom `FetcherConfig` to control timeout and retries. It highlights the flexibility of the function for different use cases. The function returns a list of `CorporateAction` objects. ```python from settfex.services.set import get_corporate_actions # English (default) actions = await get_corporate_actions("AOT") # Thai language actions_th = await get_corporate_actions("AOT", lang="th") # Custom configuration from settfex.utils.data_fetcher import FetcherConfig config = FetcherConfig(timeout=60, max_retries=5) actions = await get_corporate_actions("AOT", config=config) ``` -------------------------------- ### Full Stock Analysis: Profile and Highlight Data (Python) Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/profile_stock.md This Python example demonstrates how to combine profile and highlight data for a comprehensive stock analysis. It concurrently fetches both using `get_profile` and `get_highlight_data` from the SET API, then prints key details like sector, industry, market cap, P/E ratio, and dividend yield. ```python import asyncio from settfex.services.set import Stock, get_profile, get_highlight_data async def full_stock_analysis(symbol: str): # Fetch profile and highlight data concurrently profile, highlight = await asyncio.gather( get_profile(symbol), get_highlight_data(symbol) ) print(f"\n{profile.name} ({symbol})") print(f"{ '=' * 60}") print(f"\nProfile:") print(f" Sector: {profile.sector_name}") print(f" Industry: {profile.industry_name}") print(f" Listed: {profile.listed_date}") print(f" IPO: {profile.ipo} {profile.currency}") print(f"\nValuation:") print(f" Market Cap: {highlight.market_cap:,.0f}") print(f" P/E Ratio: {highlight.pe_ratio}") print(f" P/B Ratio: {highlight.pb_ratio}") print(f" Dividend Yield: {highlight.dividend_yield}%") asyncio.run(full_stock_analysis("CPALL")) ``` -------------------------------- ### Compare Multiple Stocks with Profile Data (Python) Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/profile_stock.md This Python example shows how to fetch and compare profile data for several stocks concurrently. It utilizes the asyncio library and leverages the symbol-specific referer headers to ensure reliable, concurrent data retrieval. The output includes symbol, name, sector, and IPO information. ```python import asyncio from settfex.services.set.stock import get_profile async def compare_stocks(): symbols = ["PTT", "CPALL", "KBANK", "AOT"] # Fetch profiles concurrently (works perfectly with symbol-specific referers!) profiles = await asyncio.gather(*[get_profile(symbol) for symbol in symbols]) # Display comparison print(f"\n{'Symbol':<10} {'Name':<40} {'Sector':<20} {'IPO':>10}") print("=" * 82) for profile in profiles: print(f"{profile.symbol:<10} {profile.name:<40} " f"{profile.sector_name:<20} {profile.ipo or 0:>10.2f}") asyncio.run(compare_stocks()) ``` -------------------------------- ### Initialize StockListService (Python) Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/list.md Initializes the StockListService with optional fetcher configuration. Supports default settings or custom configurations for timeout and retries. ```python from settfex.services.set import StockListService from settfex.utils.data_fetcher import FetcherConfig # Use defaults service = StockListService() # Custom configuration config = FetcherConfig(timeout=60, max_retries=5) service = StockListService(config=config) ``` -------------------------------- ### Example Board of Director Response (JSON) Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/board_of_director.md An example of the JSON response structure for the board of director API. It contains an array of objects, where each object represents a director with their name and a list of positions. ```json [ { "name": "Mr. WILLIAM ELLWOOD HEINECKE", "positions": ["CHAIRMAN"] }, { "name": "Mr. EMMANUEL JUDE DILLIPRAJ RAJAKARIER", "positions": ["GROUP CHIEF EXECUTIVE OFFICER", "DIRECTOR"] } ] ``` -------------------------------- ### Initialize CorporateActionService with Default and Custom Config (Python) Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/corporate_action.md This snippet demonstrates the instantiation of the `CorporateActionService` class. It shows how to create a service instance with default configurations (which automatically uses `SessionManager`) and how to provide a custom `FetcherConfig` to override default settings like timeout and retries. ```python from settfex.services.set.stock import CorporateActionService from settfex.utils.data_fetcher import FetcherConfig # Default configuration (uses SessionManager automatically) service = CorporateActionService() # Custom configuration config = FetcherConfig(timeout=60, max_retries=5) service = CorporateActionService(config=config) ``` -------------------------------- ### Example SET Stock List API Response Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/API_PROTECTION_NOTE.md An example of a successful JSON response from the SET API for stock symbols. This response structure is used for parsing and validation within the service implementation. ```json { "securitySymbols": [ { "symbol": "PTT", "nameTH": "บริษัท ปตท. จำกัด (มหาชน)", "nameEN": "PTT Public Company Limited", "market": "SET", "securityType": "S", "typeSequence": 1, "industry": "ENERG", "sector": "ENERGY", "querySector": "ENERGY", "isIFF": false, "isForeignListing": false, "remark": "" }, ... ] } ``` -------------------------------- ### Use Session Caching with Stock Service Source: https://github.com/lumduan/settfex/blob/main/docs/solution/SESSION_CACHE_SUMMARY.md Demonstrates how to use the enhanced SessionManager for the Stock service with session caching. The first run involves a warmup period, while subsequent runs leverage the cache for significantly faster data retrieval. ```python from settfex.services.set import Stock # First run: ~2-3s (warmup + cache) stock = Stock("PTT") data = await stock.get_highlight_data() # Subsequent runs: ~100ms (from cache) # Even after program restart! stock = Stock("CPALL") data = await stock.get_highlight_data() # 25x FASTER! ⚡ ``` -------------------------------- ### Configure Logging with Loguru (Python) Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/highlight_data.md Illustrates how to set up detailed logging using the loguru library. This includes configuring the log level (e.g., DEBUG), specifying a log file, and then using the service, ensuring that all relevant operational logs are captured for debugging and monitoring. ```python from loguru import logger from settfex.utils.logging import setup_logger # Configure logging setup_logger(level="DEBUG", log_file="logs/highlight_data.log") # Use service (logs will be captured) data = await get_highlight_data("CPALL") ``` -------------------------------- ### Running Linting with Ruff Source: https://github.com/lumduan/settfex/blob/main/README.md Illustrates the command to run linting checks using Ruff. Linting helps maintain code quality and consistency across the project. ```bash ruff check . ``` -------------------------------- ### Verify Stock Symbol and Get Corporate Actions Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/corporate_action.md This snippet demonstrates how to retrieve a stock list, get a specific stock symbol, and then fetch corporate actions for that stock. It assumes the existence of `get_stock_list` and `get_corporate_actions` functions. ```python stock_list = await get_stock_list() stock = stock_list.get_symbol("AOT") if stock: actions = await get_corporate_actions("AOT") ``` -------------------------------- ### Configure and Use StockProfileService (Python) Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/profile_stock.md Demonstrates how to configure and use the StockProfileService to fetch stock profile data. It involves setting up FetcherConfig for parameters like browser impersonation and timeout, then initializing the service and fetching a profile. The `fetch_profile` method returns a Pydantic model. ```python from settfex.utils.data_fetcher import FetcherConfig from settfex.services.set.stock import StockProfileService config = FetcherConfig( browser_impersonate="chrome120", # Browser to impersonate timeout=60, # Request timeout (seconds) max_retries=5, # Maximum retry attempts retry_delay=2.0, # Base retry delay (seconds) ) service = StockProfileService(config=config) profile = await service.fetch_profile("PTT") print(profile.symbol) ``` -------------------------------- ### Fetch SET Stock Quote Page Example Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/utils/data_fetcher.md An example demonstrating how to fetch the SET stock quote page using AsyncDataFetcher. It checks for the presence of Thai text to verify correct decoding and prints response metadata. ```python import asyncio from settfex.utils.data_fetcher import AsyncDataFetcher async def fetch_set_quote(): """Fetch SET stock quote page with Thai content.""" async with AsyncDataFetcher() as fetcher: response = await fetcher.fetch( "https://www.set.or.th/th/market/product/stock/quote" ) # Check if Thai text is present if "ตลาดหลักทรัพย์" in response.text: print("✓ Thai text decoded correctly") print(f"Status: {response.status_code}") print(f"Size: {len(response.content):,} bytes") print(f"Time: {response.elapsed:.2f}s") asyncio.run(fetch_set_quote()) ``` -------------------------------- ### Fetch Stock Profile Data (Python) Source: https://github.com/lumduan/settfex/blob/main/CLAUDE.md Demonstrates how to use the `get_profile` convenience function and the `StockProfileService` class to fetch stock profile data. Supports English and Thai languages. Requires the `settfex` library. ```python from settfex.services.set import get_profile # Using convenience function profile = await get_profile("PTT") print(f"Company: {profile.name}") print(f"Sector: {profile.sector_name}") print(f"Listed: {profile.listed_date}") print(f"IPO: {profile.ipo} {profile.currency}") # Thai language support profile_th = await get_profile("PTT", lang="th") # Using service class from settfex.services.set.stock import StockProfileService service = StockProfileService() profile = await service.fetch_profile("CPALL", lang="en") ``` -------------------------------- ### Initialize BoardOfDirectorService (Python) Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/board_of_director.md Shows how to instantiate the `BoardOfDirectorService` class, both with default settings (which automatically utilize `SessionManager`) and with custom `FetcherConfig` for specific network parameters like timeout and retry counts. ```python from settfex.services.set.stock import BoardOfDirectorService from settfex.utils.data_fetcher import FetcherConfig # Default configuration (uses SessionManager automatically) service = BoardOfDirectorService() # Custom configuration config = FetcherConfig(timeout=60, max_retries=5) service = BoardOfDirectorService(config=config) ``` -------------------------------- ### Efficient Service Instance Reuse for Stock Data Fetching in Python Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/highlight_data.md This Python code illustrates the recommended practice of reusing a service instance for multiple stock data requests to improve efficiency. It contrasts this with the less efficient approach of creating a new service instance for each individual request. This pattern is crucial for optimizing performance when dealing with numerous data fetches. ```python # Good: Reuse service instance service = StockHighlightDataService() for symbol in symbols: data = await service.fetch_highlight_data(symbol) # Avoid: Creating new service for each request for symbol in symbols: data = await get_highlight_data(symbol) # Less efficient ``` -------------------------------- ### GET /api/set/stock/{symbol}/corporate-action Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/corporate_action.md Fetches a list of corporate actions for a given stock symbol. ```APIDOC ## GET /api/set/stock/{symbol}/corporate-action ### Description Retrieves a JSON array of corporate action objects for a specified stock symbol. ### Method GET ### Endpoint `https://www.set.or.th/api/set/stock/{symbol}/corporate-action?lang={lang}` ### Parameters #### Path Parameters - **symbol** (string) - Required - The stock symbol (e.g., "AOT") #### Query Parameters - **lang** (string) - Required - The language code for the response (e.g., "en" or "th") ### Request Example ```json { "example": "GET https://www.set.or.th/api/set/stock/AOT/corporate-action?lang=en" } ``` ### Response #### Success Response (200) - **corporate_actions** (array) - An array of corporate action objects. #### Response Example ```json { "example": [ { "date": "2023-01-01", "type": "Dividend", "details": "Interim Dividend" } ] } ``` ``` -------------------------------- ### GET /api/set/stock/{symbol}/nvdr-holder Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/services/set/nvdr_holder.md Fetches NVDR holder data for a given stock symbol and language. ```APIDOC ## GET /api/set/stock/{symbol}/nvdr-holder ### Description This endpoint retrieves NVDR holder data for a specified stock symbol and language. ### Method GET ### Endpoint `https://www.set.or.th/api/set/stock/{symbol}/nvdr-holder?lang={lang}` ### Parameters #### Path Parameters - **symbol** (string) - Required - The stock symbol for which to fetch NVDR holder data. Input symbols are normalized to uppercase and will have a '-R' suffix in the response. #### Query Parameters - **lang** (string) - Required - The language code for the response (e.g., 'en', 'th'). ### Request Example No request body is required for this GET request. ### Response #### Success Response (200) - **symbol** (string) - The stock symbol with '-R' suffix. - **free_float** (number | null) - Free float statistics (often null for NVDR holder data). - **book_close_date** (string) - The date when the shareholder register was closed for a corporate action. - **ca_type** (string) - The type of corporate action (e.g., 'XD', 'XM'). #### Response Example ```json { "symbol": "MINT-R", "free_float": null, "book_close_date": "2023-10-26", "ca_type": "XD" } ``` ``` -------------------------------- ### Clear Global Cache (Python) Source: https://github.com/lumduan/settfex/blob/main/docs/settfex/utils/session_caching.md Clears all data from the global cache. This function requires access to `settfex.utils.get_global_cache`. It invalidates all stored cached data. ```python from settfex.utils import get_global_cache cache = await get_global_cache() cache.clear() # Delete all cached data ```