# VnStock Agent Guide - Comprehensive Documentation ## Introduction VnStock Agent Guide is a comprehensive documentation repository specifically designed to help AI agents and developers effectively utilize the VnStock Sponsored library ecosystem for Vietnamese stock market analysis. This guide provides detailed references, code examples, and best practices for four core libraries: vnstock_data for data retrieval, vnstock_ta for technical analysis, vnstock_news for news aggregation, and vnstock_pipeline for building automated data processing workflows. The documentation is automatically generated from source code and optimized for use with AI agents through the Context7 MCP (Model Context Protocol), ensuring agents can write accurate and efficient code when working with Vietnamese financial data. The project serves as a centralized knowledge base that combines API documentation, practical examples, and implementation patterns across the entire VnStock ecosystem. By providing clear, structured documentation with real-world code examples, it bridges the gap between raw API capabilities and practical application in trading systems, financial analysis tools, and data science workflows. The guide covers everything from basic stock price retrieval to advanced pipeline automation, enabling both novice users and experienced developers to build sophisticated financial applications for the Vietnamese market. ## APIs and Key Functions ### Retrieve Historical Stock Price Data Query historical OHLCV (Open, High, Low, Close, Volume) data for Vietnamese stocks, indices, and warrants across multiple timeframes. ```python from vnstock_data import Quote # Initialize quote object for VCB stock using VCI data source quote = Quote(source="vci", symbol="VCB") # Get daily historical data for 2024 df = quote.history( start="2024-01-01", end="2024-12-31", interval="1D" # Options: 1m, 5m, 15m, 30m, 1H, 1D, 1W, 1M ) # Validate data if df.empty: print("No data available") else: print(f"Retrieved {len(df)} records") print(df.head()) # Output: DataFrame with columns: time, open, high, low, close, volume # Example row: 2024-01-02, 89.5, 91.2, 89.0, 90.8, 2500000 # Alternative: Use VND source for faster performance quote_vnd = Quote(source="vnd", symbol="VCB") df_vnd = quote_vnd.history(start="2024-01-01", end="2024-12-31", interval="1D") # Get intraday data (1-minute bars) - max 2 years lookback df_intraday = quote.history( start="2024-11-01", end="2024-12-02", interval="1m" ) ``` ### Get Stock Listing by Industry and Exchange Retrieve comprehensive lists of stocks organized by exchange, industry sectors, and market indices. ```python from vnstock_data import Listing # Initialize listing object with VCI source (most complete data) listing = Listing(source="vci") # Get all stocks on HOSE exchange hose_stocks = listing.symbols_by_exchange("HOSE") print(f"Total HOSE stocks: {len(hose_stocks)}") # Output: DataFrame with columns: symbol, organ_name, organ_short_name, etc. # Example: VCB, Vietcombank, VCB, HOSE, ... # Get stocks by industry banking_stocks = listing.symbols_by_industries("Ngân hàng") if not banking_stocks.empty: print(banking_stocks[['symbol', 'organ_name']]) # Example: VCB, Vietcombank; ACB, ACB; TCB, Techcombank # Get all industries list industries = listing.industries() print("Available industries:") for idx, row in industries.iterrows(): print(f"{row['level1_industry']} -> {row['level2_industry']}") # Get stocks in VN30 index vn30_stocks = listing.symbols_by_group("VN30") tickers = vn30_stocks['symbol'].tolist() # ['VCB', 'VHM', 'HPG', ...] # Error handling for unsupported methods try: listing_vnd = Listing(source="vnd") industries_vnd = listing_vnd.industry() # Will fail - VND doesn't support this except AttributeError as e: print(f"Method not supported: {e}") # Always check data source matrix in 12-data-sources.md ``` ### Fetch Company Financial Statements Access comprehensive financial reports including balance sheets, income statements, cash flow statements, and financial ratios. ```python from vnstock_data import Finance # Initialize finance object for VCB finance = Finance(source="vci", symbol="VCB") # Get annual balance sheet balance_sheet = finance.balance_sheet(period="year", lang="en") print(balance_sheet.head()) # Output: DataFrame with columns: ticker, year, quarter, total_assets, total_liabilities, equity, etc. # Get quarterly income statement income_statement = finance.income_statement(period="quarter", lang="vi") print(f"Revenue (TTM): {income_statement['revenue'].iloc[0]:,.0f}") # Output: Revenue (TTM): 45,500,000,000,000 # Get cash flow statement cash_flow = finance.cash_flow(period="year", lang="en") operating_cf = cash_flow['cash_from_operating_activities'].iloc[0] print(f"Operating Cash Flow: {operating_cf:,.0f}") # Get financial ratios (P/E, P/B, ROE, ROA, etc.) ratios = finance.ratio(period="year", lang="en") pe_ratio = ratios['pe'].iloc[0] roe = ratios['roe'].iloc[0] print(f"P/E: {pe_ratio:.2f}, ROE: {roe:.2%}") # Example output: P/E: 15.30, ROE: 18.50% # Get all financial data at once with error handling try: all_reports = { 'balance_sheet': finance.balance_sheet(period="year"), 'income_statement': finance.income_statement(period="quarter"), 'cash_flow': finance.cash_flow(period="year"), 'ratio': finance.ratio(period="year") } # Validate data for report_name, df in all_reports.items(): if df.empty: print(f"Warning: {report_name} is empty") else: print(f"{report_name}: {len(df)} records") except Exception as e: print(f"Error fetching financial data: {e}") ``` ### Calculate Technical Indicators Compute 25+ technical indicators including trend, momentum, volatility, and volume indicators for stock analysis. ```python from vnstock_data import Quote from vnstock_ta import Indicator import pandas as pd # Get historical data quote = Quote(source="vnd", symbol="VCB") df = quote.history(start="2024-01-01", end="2024-12-31", interval="1D") # IMPORTANT: Set time as index for indicators df = df.set_index('time') # Initialize indicator calculator indicator = Indicator(data=df) # Calculate moving averages (Trend indicators) sma_20 = indicator.sma(length=20) sma_50 = indicator.sma(length=50) ema_12 = indicator.ema(length=12) df['SMA_20'] = sma_20 df['SMA_50'] = sma_50 df['EMA_12'] = ema_12 # Calculate RSI (Momentum indicator) rsi = indicator.rsi(length=14) df['RSI'] = rsi # Identify overbought/oversold conditions df['Signal'] = df['RSI'].apply( lambda x: 'Overbought' if x > 70 else ('Oversold' if x < 30 else 'Neutral') ) # Calculate MACD (Momentum indicator) macd_data = indicator.macd(fast=12, slow=26, signal=9) df['MACD'] = macd_data['MACD'] df['MACD_signal'] = macd_data['MACD_signal'] df['MACD_histogram'] = macd_data['MACD_histogram'] # Detect MACD crossovers df['MACD_crossover'] = ( (df['MACD'] > df['MACD_signal']) & (df['MACD'].shift(1) <= df['MACD_signal'].shift(1)) ) # Calculate Bollinger Bands (Volatility indicator) bbands = indicator.bbands(length=20, std=2) df['BB_upper'] = bbands['BBU'] df['BB_middle'] = bbands['BBM'] df['BB_lower'] = bbands['BBL'] df['BB_bandwidth'] = bbands['BBB'] df['BB_percent'] = bbands['BBP'] # Calculate ATR for position sizing (Volatility indicator) atr = indicator.atr(length=14) df['ATR'] = atr # Calculate stop loss levels df['Stop_loss'] = df['close'] - (df['ATR'] * 2) df['Take_profit'] = df['close'] + (df['ATR'] * 3) # Calculate OBV (Volume indicator) obv = indicator.obv() df['OBV'] = obv # Example: Complete trading signal df['Buy_signal'] = ( (df['RSI'] < 30) & # Oversold (df['close'] < df['BB_lower']) & # Price below lower band (df['MACD_crossover']) & # MACD bullish crossover (df['OBV'] > df['OBV'].shift(1)) # Volume confirmation ) # Print recent signals print(df[df['Buy_signal']][['close', 'RSI', 'MACD', 'BB_lower', 'OBV']].tail()) ``` ### Visualize Stock Charts with Technical Indicators Create interactive charts with multiple technical indicators and customizable themes. ```python from vnstock_data import Quote from vnstock_ta import Indicator, Plotter import pandas as pd # Get data quote = Quote(source="vnd", symbol="VCB") df = quote.history(start="2024-09-01", end="2024-12-02", interval="1D") df = df.set_index('time') # Calculate indicators first indicator = Indicator(data=df) df['SMA_20'] = indicator.sma(length=20) df['SMA_50'] = indicator.sma(length=50) df['RSI'] = indicator.rsi(length=14) macd = indicator.macd(fast=12, slow=26, signal=9) df = pd.concat([df, macd], axis=1) # Initialize plotter with light theme plotter = Plotter(data=df, theme='light') # Options: 'light' or 'dark' # Plot candlestick chart with moving averages fig1 = plotter.sma( length=[20, 50], title='VCB Price with SMA 20/50', show_volume=True ) fig1.show() # Display interactive chart in browser # Save chart as HTML fig1.write_html("vcb_sma.html") # Plot RSI in separate panel fig2 = plotter.rsi( length=14, title='VCB RSI(14)', overbought=70, oversold=30 ) fig2.show() # Plot MACD fig3 = plotter.macd( fast=12, slow=26, signal=9, title='VCB MACD' ) fig3.show() # Customize plot appearance plotter_dark = Plotter(data=df, theme='dark') fig4 = plotter_dark.bbands( length=20, std=2, title='VCB Bollinger Bands' ) # Update layout for better presentation fig4.update_layout( width=1200, height=600, font=dict(size=12), hovermode='x unified' ) # Save as PNG (requires kaleido library) try: fig4.write_image("vcb_bbands.png", width=1200, height=600) except Exception as e: print(f"PNG export failed: {e}. Install kaleido: pip install kaleido") # Example: Multi-indicator dashboard from plotly.subplots import make_subplots import plotly.graph_objects as go fig = make_subplots( rows=3, cols=1, shared_xaxes=True, vertical_spacing=0.05, row_heights=[0.5, 0.25, 0.25], subplot_titles=('Price & SMA', 'RSI', 'MACD') ) # Add candlestick fig.add_trace( go.Candlestick( x=df.index, open=df['open'], high=df['high'], low=df['low'], close=df['close'], name='Price' ), row=1, col=1 ) # Add SMAs fig.add_trace(go.Scatter(x=df.index, y=df['SMA_20'], name='SMA 20'), row=1, col=1) fig.add_trace(go.Scatter(x=df.index, y=df['SMA_50'], name='SMA 50'), row=1, col=1) # Add RSI fig.add_trace(go.Scatter(x=df.index, y=df['RSI'], name='RSI'), row=2, col=1) fig.add_hline(y=70, line_dash="dash", line_color="red", row=2, col=1) fig.add_hline(y=30, line_dash="dash", line_color="green", row=2, col=1) # Add MACD fig.add_trace(go.Scatter(x=df.index, y=df['MACD'], name='MACD'), row=3, col=1) fig.add_trace(go.Scatter(x=df.index, y=df['MACD_signal'], name='Signal'), row=3, col=1) fig.update_layout(height=900, title_text="VCB Technical Analysis Dashboard") fig.show() ``` ### Crawl Vietnamese News Articles Collect news articles from 12+ Vietnamese news sources using RSS feeds or sitemaps with caching and content cleaning. ```python from vnstock_news import Crawler, BatchCrawler, TrendingAnalyzer import pandas as pd # Method 1: Quick RSS fetch (latest news, < 30 seconds) crawler = Crawler(site_name="vnexpress") articles = crawler.get_articles_from_feed(limit_per_feed=20) print(f"Fetched {len(articles)} articles") print(articles[['title', 'publish_time', 'url']].head()) # Output: DataFrame with columns: url, title, short_description, content, # publish_time, author, category, source # Method 2: Sitemap crawl (historical data, 1-5 minutes) crawler_cafef = Crawler(site_name="cafef") historical_articles = crawler_cafef.get_articles_from_sitemap(limit=100) print(f"Date range: {historical_articles['publish_time'].min()} to {historical_articles['publish_time'].max()}") # Save to CSV historical_articles.to_csv("cafef_articles.csv", index=False, encoding='utf-8') # Method 3: Batch crawler with retry logic (recommended for production) batch_crawler = BatchCrawler( site_name="cafef", request_delay=1.0, # Delay between requests to avoid blocking max_retries=3 ) try: articles = batch_crawler.fetch_articles( limit=500, start_from=0, resume=True # Resume from last fetch if interrupted ) print(f"Successfully fetched {len(articles)} articles") # Filter by date articles['publish_time'] = pd.to_datetime(articles['publish_time']) recent = articles[articles['publish_time'] >= '2024-12-01'] print(f"Articles from December 2024: {len(recent)}") except Exception as e: print(f"Error during crawling: {e}") # Method 4: Multiple sources at once sources = ["vnexpress", "cafef", "vietstock", "tuoitre"] all_articles = [] for source in sources: try: crawler = Crawler(site_name=source) articles = crawler.get_articles_from_feed(limit_per_feed=50) articles['source'] = source all_articles.append(articles) print(f"✓ {source}: {len(articles)} articles") except Exception as e: print(f"✗ {source}: Failed - {e}") # Combine all sources if all_articles: combined = pd.concat(all_articles, ignore_index=True) combined = combined.drop_duplicates(subset=['url']) print(f"\nTotal unique articles: {len(combined)}") combined.to_csv("all_news.csv", index=False, encoding='utf-8') # Analyze trending keywords analyzer = TrendingAnalyzer() keywords = analyzer.extract_keywords( combined['title'].tolist(), top_n=20 ) print("\nTop trending keywords:") for keyword, count in keywords.items(): print(f"{keyword}: {count} mentions") ``` ### Build Automated Data Pipeline Create automated pipelines to fetch, validate, transform, and export stock data for multiple tickers in parallel. ```python from vnstock_pipeline.tasks.ohlcv import run_task as run_ohlcv from vnstock_pipeline.tasks.financial import run_financial_task from vnstock_pipeline import Scheduler from vnstock_pipeline.core.fetcher import VNFetcher from vnstock_pipeline.core.validator import VNValidator from vnstock_pipeline.core.transformer import VNTransformer from vnstock_pipeline.core.exporter import Exporter import pandas as pd # Method 1: Simple task execution (3 lines of code) tickers = ['VCB', 'ACB', 'HPG', 'VHM', 'VNM'] run_ohlcv( tickers=tickers, start="2024-01-01", end="2024-12-31", interval="1D" ) print("✓ Data saved to ./data/ohlcv/") # Output: VCB.csv, ACB.csv, HPG.csv, VHM.csv, VNM.csv # Each file contains: time, open, high, low, close, volume # Method 2: Financial reports pipeline run_financial_task( tickers=['VCB', 'ACB'], balance_sheet_period="year", income_statement_year_period="year", income_statement_quarter_period="quarter", cash_flow_period="year", ratio_period="year", lang="en", dropna=True ) print("✓ Financial reports saved to ./data/financial/") # Method 3: Custom pipeline with scheduler from vnstock_data import Quote class CustomFetcher(VNFetcher): """Custom fetcher with retry and caching""" def _vn_call(self, ticker: str, **kwargs) -> pd.DataFrame: start = kwargs.get('start') end = kwargs.get('end') interval = kwargs.get('interval', '1D') quote = Quote(source="vci", symbol=ticker) df = quote.history(start=start, end=end, interval=interval) if df.empty: raise ValueError(f"No data for {ticker}") return df class CustomValidator(VNValidator): """Validate OHLC data quality""" required_columns = ['time', 'open', 'high', 'low', 'close', 'volume'] def validate(self, data: pd.DataFrame) -> bool: # Check required columns if not all(col in data.columns for col in self.required_columns): return False # Check OHLC logic: high >= open, close, low if not ((data['high'] >= data['open']).all() and (data['high'] >= data['close']).all() and (data['high'] >= data['low']).all()): return False # Check for negative values if (data[['open', 'high', 'low', 'close', 'volume']] < 0).any().any(): return False return True class TAEnrichmentTransformer(VNTransformer): """Add technical indicators to data""" def transform(self, data: pd.DataFrame) -> pd.DataFrame: from vnstock_ta import Indicator # Remove duplicates data = data.drop_duplicates(subset=['time']) data = data.set_index('time') # Calculate indicators indicator = Indicator(data=data) data['SMA_20'] = indicator.sma(length=20) data['SMA_50'] = indicator.sma(length=50) data['RSI'] = indicator.rsi(length=14) data['ATR'] = indicator.atr(length=14) # Add signals data['trend'] = data['SMA_20'] > data['SMA_50'] data['overbought'] = data['RSI'] > 70 data['oversold'] = data['RSI'] < 30 return data.reset_index() class CSVExporter(Exporter): """Export to CSV with validation""" def export(self, data: pd.DataFrame, ticker: str, **kwargs): output_dir = kwargs.get('output_dir', './data/enriched/') import os os.makedirs(output_dir, exist_ok=True) output_path = f"{output_dir}/{ticker}.csv" data.to_csv(output_path, index=False) print(f"✓ Exported {ticker}: {len(data)} records -> {output_path}") # Initialize pipeline components fetcher = CustomFetcher() validator = CustomValidator() transformer = TAEnrichmentTransformer() exporter = CSVExporter() # Create scheduler with parallel processing scheduler = Scheduler( fetcher=fetcher, validator=validator, transformer=transformer, exporter=exporter, max_workers=10, # Process 10 stocks in parallel retry_attempts=3, backoff_factor=2.0 ) # Get VN30 tickers from vnstock_data import Listing listing = Listing(source="vci") vn30 = listing.symbols_by_group("VN30") vn30_tickers = vn30['symbol'].tolist()[:10] # First 10 stocks # Run pipeline print(f"Processing {len(vn30_tickers)} stocks...") scheduler.run( tickers=vn30_tickers, fetcher_kwargs={ 'start': '2024-01-01', 'end': '2024-12-31', 'interval': '1D' }, exporter_kwargs={ 'output_dir': './data/vn30_enriched/' } ) print("\n✓ Pipeline completed!") print("Results in ./data/vn30_enriched/") # Method 4: Scheduled daily execution import schedule import time def daily_pipeline(): """Run pipeline daily at 16:30 after market close""" from datetime import datetime, timedelta end_date = datetime.now().strftime('%Y-%m-%d') start_date = (datetime.now() - timedelta(days=1)).strftime('%Y-%m-%d') scheduler.run( tickers=vn30_tickers, fetcher_kwargs={ 'start': start_date, 'end': end_date, 'interval': '1D' } ) print(f"✓ Daily pipeline completed at {datetime.now()}") # Schedule daily execution schedule.every().day.at("16:30").do(daily_pipeline) print("Pipeline scheduler started. Running daily at 16:30...") # while True: # schedule.run_pending() # time.sleep(60) ``` ### Analyze Macroeconomic Data Access Vietnamese macroeconomic indicators including GDP, inflation, exchange rates, FDI, and interest rates. ```python from vnstock_data import Macro import pandas as pd # Initialize macro data source macro = Macro(source="vci") # Get GDP data gdp = macro.gdp() print("Vietnam GDP (Recent Quarters):") print(gdp[['year', 'quarter', 'gdp', 'gdp_growth']].tail()) # Output: DataFrame with year, quarter, gdp (billion VND), gdp_growth (%) # Get CPI and inflation data cpi = macro.cpi() print("\nConsumer Price Index:") print(cpi[['year', 'month', 'cpi', 'inflation_rate']].tail()) # Example: 2024, 12, 112.5, 3.2% (YoY inflation) # Get exchange rates (VND/USD, VND/EUR, VND/CNY, etc.) exchange_rates = macro.exchange_rate() latest_usd = exchange_rates[exchange_rates['currency'] == 'USD'].iloc[-1] print(f"\nUSD/VND Exchange Rate: {latest_usd['rate']:,.0f}") # Example: 24,500 VND per USD # Get interest rates interest_rates = macro.interest_rate() print("\nInterest Rates:") print(interest_rates[['date', 'rate_type', 'rate']].tail()) # Output: Date, Type (refinancing/discount/operating), Rate (%) # Get FDI (Foreign Direct Investment) data fdi = macro.fdi() print("\nForeign Direct Investment:") print(fdi[['year', 'quarter', 'registered_capital', 'disbursed_capital']].tail()) # Values in million USD # Get import/export data import_export = macro.import_export() print("\nTrade Balance:") print(import_export[['year', 'month', 'export', 'import', 'trade_balance']].tail()) # Values in million USD # Create macro dashboard import matplotlib.pyplot as plt fig, axes = plt.subplots(2, 2, figsize=(15, 10)) fig.suptitle('Vietnam Macroeconomic Dashboard', fontsize=16) # GDP Growth gdp_recent = gdp.tail(8) axes[0, 0].bar(range(len(gdp_recent)), gdp_recent['gdp_growth']) axes[0, 0].set_title('GDP Growth Rate (%)') axes[0, 0].set_xlabel('Quarter') axes[0, 0].set_ylabel('Growth Rate (%)') # Inflation cpi_recent = cpi.tail(12) axes[0, 1].plot(cpi_recent['month'], cpi_recent['inflation_rate'], marker='o') axes[0, 1].set_title('Inflation Rate (%)') axes[0, 1].set_xlabel('Month') axes[0, 1].set_ylabel('YoY Inflation (%)') # USD Exchange Rate usd_rates = exchange_rates[exchange_rates['currency'] == 'USD'].tail(12) axes[1, 0].plot(usd_rates['date'], usd_rates['rate'], marker='o', color='green') axes[1, 0].set_title('USD/VND Exchange Rate') axes[1, 0].set_xlabel('Date') axes[1, 0].set_ylabel('VND per USD') # Trade Balance trade_recent = import_export.tail(12) axes[1, 1].plot(trade_recent['month'], trade_recent['export'], label='Export', marker='o') axes[1, 1].plot(trade_recent['month'], trade_recent['import'], label='Import', marker='o') axes[1, 1].plot(trade_recent['month'], trade_recent['trade_balance'], label='Balance', marker='o', linestyle='--') axes[1, 1].set_title('Trade Balance (Million USD)') axes[1, 1].set_xlabel('Month') axes[1, 1].legend() plt.tight_layout() plt.savefig('macro_dashboard.png', dpi=300) print("\n✓ Dashboard saved to macro_dashboard.png") # Example: Macro screening for investment decisions latest_gdp_growth = gdp['gdp_growth'].iloc[-1] latest_inflation = cpi['inflation_rate'].iloc[-1] latest_usd_rate = exchange_rates[exchange_rates['currency'] == 'USD']['rate'].iloc[-1] print("\n=== Investment Environment Assessment ===") print(f"GDP Growth: {latest_gdp_growth:.2f}%") print(f"Inflation: {latest_inflation:.2f}%") print(f"USD/VND: {latest_usd_rate:,.0f}") if latest_gdp_growth > 6 and latest_inflation < 4: print("✓ Favorable: Strong growth with controlled inflation") elif latest_gdp_growth < 5 or latest_inflation > 5: print("⚠ Caution: Economic headwinds detected") else: print("~ Neutral: Mixed signals") ``` ### Get Top Performing Stocks Identify top gainers, losers, most active stocks, and market insights for quick market screening. ```python from vnstock_data import TopStock import pandas as pd # Initialize TopStock (only VND source supported) top_stock = TopStock() # Get top gainers (stocks with highest price increase) top_gainers = top_stock.gainer(limit=10) print("=== Top 10 Gainers ===") print(top_gainers[['symbol', 'last_price', 'price_change_pct_1d', 'accumulated_value']].head(10)) # Output: DataFrame with 15 columns including symbol, last_price, price_change_pct_1d, accumulated_value # Example: ITD, 15.3, +6.99%, 3,704,415,000 # Get top losers (stocks with highest price decrease) top_losers = top_stock.loser(limit=10) print("\n=== Top 10 Losers ===") print(top_losers[['symbol', 'last_price', 'price_change_pct_1d', 'accumulated_value']].head(10)) # Example: RYG, 10.00, -5.00%, 1,234,515,000 # Get stocks with highest trading value top_value = top_stock.value(limit=10) print("\n=== Top Value ===") print(top_value[['symbol', 'accumulated_value', 'last_price']].head(10)) # accumulated_value: total trading value in VND # Get stocks with highest volume spike top_volume = top_stock.volume(limit=10) print("\n=== Top Volume (Volume Spike) ===") print(top_volume[['symbol', 'volume_spike_20d_pct', 'last_price']].head(10)) # volume_spike_20d_pct: volume spike percentage vs 20-day average # Get stocks with most deal transactions (thỏa thuận) top_deal = top_stock.deal(limit=10) print("\n=== Most Active (Deal Transactions) ===") print(top_deal[['symbol', 'deal_volume_spike_20d_pct', 'last_price']].head(10)) # Get foreign trading activity foreign_buy = top_stock.foreign_buy(limit=10) foreign_sell = top_stock.foreign_sell(limit=10) print("\n=== Top Foreign Buying (Net) ===") print(foreign_buy[['symbol', 'date', 'net_value']].head(10)) # net_value: net buying value in VND print("\n=== Top Foreign Selling (Net) ===") print(foreign_sell[['symbol', 'date', 'net_value']].head(10)) # net_value: net selling value in VND (negative) # Example: Market sentiment analysis def analyze_market_sentiment(): """Analyze overall market sentiment from top stocks""" # Count gainers vs losers gainers = len(top_gainers) losers = len(top_losers) # Average change avg_gainer_change = top_gainers['price_change_pct_1d'].mean() avg_loser_change = top_losers['price_change_pct_1d'].mean() # Foreign net buying total_foreign_buy = foreign_buy['net_value'].sum() total_foreign_sell = foreign_sell['net_value'].sum() foreign_net = total_foreign_buy + total_foreign_sell # foreign_sell values are negative print("\n=== Market Sentiment Analysis ===") print(f"Gainers: {gainers}, Losers: {losers}") print(f"Avg Gainer Change: +{avg_gainer_change:.2f}%") print(f"Avg Loser Change: {avg_loser_change:.2f}%") print(f"Foreign Net Flow: {foreign_net:,.0f} VND") # Overall sentiment if gainers > losers * 1.5 and foreign_net > 0: sentiment = "BULLISH - Strong buying pressure" elif losers > gainers * 1.5 and foreign_net < 0: sentiment = "BEARISH - Heavy selling pressure" else: sentiment = "NEUTRAL - Mixed signals" print(f"\nOverall Sentiment: {sentiment}") return { 'gainers': gainers, 'losers': losers, 'avg_gainer_change': avg_gainer_change, 'avg_loser_change': avg_loser_change, 'foreign_net': foreign_net, 'sentiment': sentiment } # Run sentiment analysis sentiment_data = analyze_market_sentiment() # Example: Create watchlist from top performers def create_watchlist(min_change_percent=3.0, min_volume_spike=50.0): """Create watchlist from top gainers with filters""" filtered = top_gainers[ (top_gainers['price_change_pct_1d'] >= min_change_percent) & (top_gainers['volume_spike_20d_pct'] >= min_volume_spike) ].copy() # Add to watchlist watchlist = filtered[['symbol', 'last_price', 'price_change_pct_1d', 'volume_spike_20d_pct']].head(20) print("\n=== Watchlist (High momentum + High volume spike) ===") print(watchlist) # Save to file watchlist.to_csv('watchlist.csv', index=False) print("\n✓ Watchlist saved to watchlist.csv") return watchlist # Create and save watchlist my_watchlist = create_watchlist(min_change_percent=3.0, min_volume_spike=50.0) # Example: Find stocks with both price increase and foreign buying gaining_symbols = set(top_gainers['symbol']) foreign_buying_symbols = set(foreign_buy['symbol']) intersection = gaining_symbols & foreign_buying_symbols print(f"\nStocks with both price increase and foreign buying ({len(intersection)} stocks):") for symbol in sorted(intersection): gainer_pct = top_gainers[top_gainers['symbol'] == symbol]['price_change_pct_1d'].values[0] foreign_buy_val = foreign_buy[foreign_buy['symbol'] == symbol]['net_value'].values[0] print(f" {symbol}: +{gainer_pct:.2f}% | Net Buy: {foreign_buy_val:.2e} VND") ``` ## Main Use Cases and Integration Patterns The VnStock Agent Guide documentation enables a wide range of practical applications across financial analysis, trading systems, and data science workflows. The primary use cases include building technical analysis systems that combine historical price data with 25+ technical indicators for generating trading signals, fundamental analysis platforms that aggregate financial statements and ratios for valuation and screening, and news monitoring systems that track market sentiment by aggregating articles from 12+ Vietnamese news sources. Data science teams use the library for backtesting trading strategies, training machine learning models on comprehensive Vietnamese market data, and conducting quantitative research with clean, validated datasets. The pipeline automation capabilities allow for building production-grade ETL systems that continuously collect, validate, and enrich stock market data on scheduled intervals. Integration patterns emphasize flexibility and modularity across the ecosystem. The most common pattern involves using the Adapter Pattern to switch between data sources (VCI, VND, MAS) without changing application logic, enabling fallback strategies when primary sources fail. For real-time applications, developers combine the vnstock_data Quote module with vnstock_ta technical indicators in streaming pipelines, applying transformations to live price data and triggering alerts when conditions are met. The vnstock_pipeline framework provides four-stage processing (Fetcher → Validator → Transformer → Exporter) that can be customized at each stage, supporting parallel processing of 50+ stocks simultaneously with automatic retry logic and error handling. Advanced users build multi-timeframe analysis systems that fetch daily, hourly, and minute-level data in parallel, calculate indicators across timeframes, and export results to databases, CSV files, or webhooks for integration with external systems. The documentation structure supports both quick prototyping with simple three-line scripts and production deployments with Docker containerization, scheduled execution, and comprehensive monitoring.