A beginner-friendly yet powerful Python toolkit for financial analysis and automation — built to make modern investing accessible to everyone
The Finance class provides access to comprehensive financial reporting data including balance sheets, income statements, cash flow statements, and financial ratios. It supports quarterly and annual reporting periods with multi-year historical data for Vietnamese listed companies.
Adapter for financial reports and ratios with support for both quarterly and annual reporting periods. Provides standardized financial data across Vietnamese data sources.
class Finance:
"""
Financial data adapter for corporate financial statements and ratios.
Supported sources: VCI, TCBS
"""
def __init__(self, source: str, symbol: str, period: str = "quarter", get_all: bool = True, show_log: bool = False):
"""
Initialize Finance data adapter.
Args:
source (str): Data source ("vci", "tcbs")
symbol (str): Company symbol
period (str): Reporting period ("quarter", "year"), defaults to "quarter"
get_all (bool): Get all available periods, defaults to True
show_log (bool): Enable logging, defaults to False
"""Comprehensive balance sheet information including assets, liabilities, and shareholders' equity with detailed line items and multi-period comparisons.
def balance_sheet(self, *args, **kwargs) -> pd.DataFrame:
"""
Get balance sheet data with assets, liabilities, and equity information.
Common parameters (vary by source):
symbol (str): Company symbol
period (str): Reporting period ("quarter", "year")
lang (str): Language ("vi", "en"), defaults to "vi"
dropna (bool): Drop rows with all NaN values, defaults to True
show_log (bool): Enable detailed logging, defaults to False
Returns:
pd.DataFrame: Balance sheet data including:
- total_assets: Total assets
- current_assets: Current assets
- cash_and_equivalents: Cash and cash equivalents
- short_term_investments: Short-term investments
- accounts_receivable: Accounts receivable
- inventory: Inventory
- prepaid_expenses: Prepaid expenses
- other_current_assets: Other current assets
- non_current_assets: Non-current assets
- property_plant_equipment: Property, plant & equipment
- intangible_assets: Intangible assets
- long_term_investments: Long-term investments
- other_non_current_assets: Other non-current assets
- total_liabilities: Total liabilities
- current_liabilities: Current liabilities
- accounts_payable: Accounts payable
- short_term_debt: Short-term debt
- accrued_expenses: Accrued expenses
- other_current_liabilities: Other current liabilities
- non_current_liabilities: Non-current liabilities
- long_term_debt: Long-term debt
- other_non_current_liabilities: Other non-current liabilities
- total_equity: Total shareholders' equity
- share_capital: Share capital
- retained_earnings: Retained earnings
- other_equity: Other equity components
"""from vnstock import Finance
# Initialize Finance adapter for quarterly data
finance = Finance(source="vci", symbol="TCB", period="quarter")
# Get quarterly balance sheet
quarterly_bs = finance.balance_sheet(
symbol="TCB",
period="quarter",
lang="vi"
)
# Get annual balance sheet
annual_bs = finance.balance_sheet(
symbol="VCB",
period="year",
lang="en"
)
# Get balance sheet without NaN cleanup
raw_bs = finance.balance_sheet(
symbol="HPG",
period="quarter",
dropna=False
)Detailed income statement including revenues, expenses, and profitability metrics with operating and non-operating components.
def income_statement(self, *args, **kwargs) -> pd.DataFrame:
"""
Get income statement data with revenue, expenses, and profit information.
Common parameters (vary by source):
symbol (str): Company symbol
period (str): Reporting period ("quarter", "year")
lang (str): Language ("vi", "en"), defaults to "vi"
dropna (bool): Drop rows with all NaN values, defaults to True
Returns:
pd.DataFrame: Income statement data including:
- total_revenue: Total revenue/net sales
- cost_of_goods_sold: Cost of goods sold
- gross_profit: Gross profit
- operating_expenses: Total operating expenses
- selling_expenses: Selling and marketing expenses
- administrative_expenses: General and administrative expenses
- research_development: Research and development expenses
- other_operating_expenses: Other operating expenses
- operating_income: Operating income/EBIT
- financial_income: Financial income
- financial_expenses: Financial expenses
- other_income: Other non-operating income
- other_expenses: Other non-operating expenses
- pre_tax_income: Income before tax
- tax_expense: Income tax expense
- net_income: Net income after tax
- earnings_per_share: Earnings per share (EPS)
- diluted_eps: Diluted earnings per share
"""# Get quarterly income statement
quarterly_is = finance.income_statement(
symbol="TCB",
period="quarter",
lang="vi"
)
# Get annual income statement
annual_is = finance.income_statement(
symbol="VCB",
period="year"
)
# Multi-company income statement comparison
symbols = ["TCB", "VCB", "BID"]
income_data = {}
for symbol in symbols:
company_finance = Finance(source="vci", symbol=symbol, period="year")
income_data[symbol] = company_finance.income_statement(symbol=symbol, period="year")Cash flow statement data including operating, investing, and financing activities with detailed cash flow components.
def cash_flow(self, *args, **kwargs) -> pd.DataFrame:
"""
Get cash flow statement data with operating, investing, and financing activities.
Common parameters (vary by source):
symbol (str): Company symbol
period (str): Reporting period ("quarter", "year")
lang (str): Language ("vi", "en"), defaults to "vi"
dropna (bool): Drop rows with all NaN values, defaults to True
Returns:
pd.DataFrame: Cash flow statement data including:
- operating_cash_flow: Net cash from operating activities
- net_income_adjusted: Net income adjusted for non-cash items
- depreciation_amortization: Depreciation and amortization
- working_capital_changes: Changes in working capital
- accounts_receivable_changes: Changes in accounts receivable
- inventory_changes: Changes in inventory
- accounts_payable_changes: Changes in accounts payable
- other_operating_changes: Other operating cash flow changes
- investing_cash_flow: Net cash from investing activities
- capital_expenditures: Capital expenditures
- acquisitions: Acquisitions and investments
- asset_sales: Proceeds from asset sales
- other_investing_activities: Other investing activities
- financing_cash_flow: Net cash from financing activities
- debt_issuance: Debt issuance proceeds
- debt_repayment: Debt repayments
- equity_issuance: Equity issuance proceeds
- dividend_payments: Dividend payments
- share_repurchases: Share repurchases
- other_financing_activities: Other financing activities
- net_cash_flow: Net change in cash
- beginning_cash: Beginning cash balance
- ending_cash: Ending cash balance
"""# Get quarterly cash flow statement
quarterly_cf = finance.cash_flow(
symbol="TCB",
period="quarter"
)
# Get annual cash flow with English labels
annual_cf = finance.cash_flow(
symbol="VCB",
period="year",
lang="en"
)
# Analyze cash flow trends
hpg_cf = finance.cash_flow(symbol="HPG", period="quarter")Comprehensive financial ratios including profitability, liquidity, efficiency, and leverage ratios with multi-period analysis.
def ratio(self, *args, **kwargs) -> pd.DataFrame:
"""
Get financial ratios and performance metrics.
Common parameters (vary by source):
symbol (str): Company symbol
period (str): Reporting period ("quarter", "year")
flatten_columns (bool): Flatten multi-level column headers
separator (str): Column name separator for flattened columns
drop_levels (list): Column levels to drop in multi-index
Returns:
pd.DataFrame: Financial ratios including:
# Profitability Ratios
- gross_profit_margin: Gross profit margin (%)
- operating_profit_margin: Operating profit margin (%)
- net_profit_margin: Net profit margin (%)
- return_on_assets: Return on assets (ROA) (%)
- return_on_equity: Return on equity (ROE) (%)
- return_on_invested_capital: Return on invested capital (ROIC) (%)
# Liquidity Ratios
- current_ratio: Current ratio
- quick_ratio: Quick ratio (acid test)
- cash_ratio: Cash ratio
- working_capital: Working capital
# Efficiency Ratios
- asset_turnover: Asset turnover ratio
- inventory_turnover: Inventory turnover ratio
- receivables_turnover: Accounts receivable turnover
- days_sales_outstanding: Days sales outstanding (DSO)
- days_inventory_outstanding: Days inventory outstanding (DIO)
- days_payable_outstanding: Days payable outstanding (DPO)
- cash_conversion_cycle: Cash conversion cycle
# Leverage Ratios
- debt_to_equity: Debt-to-equity ratio
- debt_to_assets: Debt-to-assets ratio
- interest_coverage: Interest coverage ratio
- debt_service_coverage: Debt service coverage ratio
# Market Ratios
- price_to_earnings: Price-to-earnings (P/E) ratio
- price_to_book: Price-to-book (P/B) ratio
- price_to_sales: Price-to-sales (P/S) ratio
- enterprise_value_ebitda: EV/EBITDA ratio
- dividend_yield: Dividend yield (%)
- dividend_payout_ratio: Dividend payout ratio (%)
"""# Get comprehensive financial ratios
ratios = finance.ratio(
symbol="TCB",
period="quarter"
)
# Get ratios with flattened column names
flat_ratios = finance.ratio(
symbol="VCB",
period="year",
flatten_columns=True,
separator="_"
)
# Get ratios with specific column levels
custom_ratios = finance.ratio(
symbol="HPG",
period="quarter",
drop_levels=[0] # Drop first level of multi-index
)from vnstock import Finance
import pandas as pd
# Initialize finance adapter
finance = Finance(source="vci", symbol="TCB", period="quarter")
# Get multi-year quarterly data
symbol = "TCB"
quarterly_bs = finance.balance_sheet(symbol=symbol, period="quarter")
quarterly_is = finance.income_statement(symbol=symbol, period="quarter")
quarterly_cf = finance.cash_flow(symbol=symbol, period="quarter")
quarterly_ratios = finance.ratio(symbol=symbol, period="quarter")
# Combine for comprehensive analysis
financial_data = {
'balance_sheet': quarterly_bs,
'income_statement': quarterly_is,
'cash_flow': quarterly_cf,
'ratios': quarterly_ratios
}
# Analyze trends
print("Revenue Growth (QoQ):")
revenue_growth = quarterly_is['total_revenue'].pct_change()
print(revenue_growth)
print("ROE Trend:")
roe_trend = quarterly_ratios['return_on_equity']
print(roe_trend)# Compare financial performance across companies
symbols = ["TCB", "VCB", "BID"]
comparison_metrics = {}
for symbol in symbols:
company_finance = Finance(source="vci", symbol=symbol, period="year")
# Get latest annual data
ratios = company_finance.ratio(symbol=symbol, period="year")
income = company_finance.income_statement(symbol=symbol, period="year")
# Extract key metrics (latest period)
latest_ratios = ratios.iloc[:, -1] # Last column (most recent)
latest_income = income.iloc[:, -1]
comparison_metrics[symbol] = {
'roe': latest_ratios.get('return_on_equity', 0),
'roa': latest_ratios.get('return_on_assets', 0),
'net_margin': latest_ratios.get('net_profit_margin', 0),
'revenue': latest_income.get('total_revenue', 0),
'net_income': latest_income.get('net_income', 0)
}
# Create comparison DataFrame
comparison_df = pd.DataFrame(comparison_metrics).T
print("Financial Comparison:")
print(comparison_df)def assess_financial_health(symbol, source="vci"):
"""Assess company financial health using key ratios."""
finance = Finance(source=source, symbol=symbol, period="quarter")
# Get latest financial data
ratios = finance.ratio(symbol=symbol, period="quarter")
balance_sheet = finance.balance_sheet(symbol=symbol, period="quarter")
# Extract latest period data
latest_ratios = ratios.iloc[:, -1]
latest_bs = balance_sheet.iloc[:, -1]
# Calculate health score components
health_indicators = {
'liquidity': {
'current_ratio': latest_ratios.get('current_ratio', 0),
'quick_ratio': latest_ratios.get('quick_ratio', 0),
'cash_ratio': latest_ratios.get('cash_ratio', 0)
},
'profitability': {
'roe': latest_ratios.get('return_on_equity', 0),
'roa': latest_ratios.get('return_on_assets', 0),
'net_margin': latest_ratios.get('net_profit_margin', 0)
},
'leverage': {
'debt_to_equity': latest_ratios.get('debt_to_equity', 0),
'debt_to_assets': latest_ratios.get('debt_to_assets', 0),
'interest_coverage': latest_ratios.get('interest_coverage', 0)
}
}
return health_indicators
# Assess multiple companies
symbols = ["TCB", "VCB", "HPG"]
health_assessments = {}
for symbol in symbols:
health_assessments[symbol] = assess_financial_health(symbol)
print("Financial Health Assessment:")
for symbol, health in health_assessments.items():
print(f"\n{symbol}:")
for category, metrics in health.items():
print(f" {category.title()}:")
for metric, value in metrics.items():
print(f" {metric}: {value:.2f}")Install with Tessl CLI
npx tessl i tessl/pypi-vnstock