from .cn_analyzer import CN_Analyzer import pandas as pd class VN_Analyzer(CN_Analyzer): def __init__(self): super().__init__() self.market = 'VN' self.mapping = { 'income': { 'revenue': 'revenue', 'net_income': 'net_income', 'gross_profit': 'gross_profit', 'total_profit': 'total_profit', 'sga_exp': 'sga_exp' }, 'balance': { 'total_equity': 'total_equity', 'total_assets': 'total_assets', 'total_liabilities': 'total_liabilities', 'current_assets': 'current_assets', 'current_liabilities': 'current_liabilities', 'cash': 'cash', 'receivables': 'receivables', 'inventory': 'inventory', 'fixed_assets': 'fixed_assets', 'goodwill': 'goodwill', 'short_term_debt': 'short_term_debt', 'long_term_debt': 'long_term_debt' }, 'cashflow': { 'ocf': 'ocf', 'capex': 'capex', 'dividends': 'dividends' } } def _post_process_columns(self, df, type): if market_type := self.mapping.get(type): for col in market_type.values(): if col in df.columns: df[col] = pd.to_numeric(df[col], errors='coerce') df = super()._post_process_columns(df, type) if type == 'balance': if 'long_term_investments' in df.columns: df['lt_invest'] = df['long_term_investments'] if 'long_term_debt' not in df.columns: df['long_term_debt'] = 0 if 'long_term_borrowings' in df.columns: df['long_term_debt'] = df['long_term_debt'].fillna(0) + df['long_term_borrowings'].fillna(0) return df def calculate_indicators(self, df_merged, market_metrics, historical_metrics): if 'revenue' in df_merged.columns and 'gross_profit' in df_merged.columns: df_merged['cogs'] = df_merged['revenue'] - df_merged['gross_profit'] df_merged = super().calculate_indicators(df_merged, market_metrics, historical_metrics) has_sga = False if 'sga_exp' in df_merged.columns and 'revenue' in df_merged.columns: if df_merged['sga_exp'].notna().any() and (df_merged['sga_exp'] != 0).any(): df_merged['SgaRatio'] = self._safe_div(df_merged['sga_exp'], df_merged['revenue']) has_sga = True if not has_sga: sga_sum = 0 if 'selling_exp' in df_merged.columns: sga_sum = sga_sum + df_merged['selling_exp'].fillna(0) if 'admin_exp' in df_merged.columns: sga_sum = sga_sum + df_merged['admin_exp'].fillna(0) if 'revenue' in df_merged.columns: df_merged['SgaRatio'] = self._safe_div(sga_sum, df_merged['revenue']) if 'income_tax' in df_merged.columns and 'net_income' in df_merged.columns: ebt_approx = df_merged['net_income'] + df_merged['income_tax'] df_merged['TaxRate'] = self._safe_div(df_merged['income_tax'], ebt_approx) if 'GrossMargin' in df_merged.columns and 'NetMargin' in df_merged.columns: other_ratio = df_merged['GrossMargin'] - df_merged['NetMargin'] if 'SgaRatio' in df_merged.columns: other_ratio = other_ratio - df_merged['SgaRatio'].fillna(0) if 'RDRatio' in df_merged.columns: other_ratio = other_ratio - df_merged['RDRatio'].fillna(0) df_merged['OtherExpenseRatio'] = other_ratio if 'MarketCap' in df_merged.columns: if 'net_income' in df_merged.columns: calculated_pe = self._safe_div(df_merged['MarketCap'], df_merged['net_income']) if 'PE' not in df_merged.columns: df_merged['PE'] = calculated_pe else: cond_pe = (df_merged['PE'] != 0) & df_merged['PE'].notna() df_merged['PE'] = df_merged['PE'].where(cond_pe, calculated_pe) if 'total_equity' in df_merged.columns: calculated_pb = self._safe_div(df_merged['MarketCap'], df_merged['total_equity']) if 'PB' not in df_merged.columns: df_merged['PB'] = calculated_pb else: cond_pb = (df_merged['PB'] != 0) & df_merged['PB'].notna() df_merged['PB'] = df_merged['PB'].where(cond_pb, calculated_pb) if 'dividends' in df_merged.columns: calculated_yield = self._safe_div(df_merged['dividends'], df_merged['MarketCap']) * 100 if 'DividendYield' not in df_merged.columns: df_merged['DividendYield'] = calculated_yield else: df_merged['DividendYield'] = df_merged['DividendYield'].fillna(calculated_yield) if 'employee_count' in df_merged.columns: df_merged['Employees'] = df_merged['employee_count'] if 'revenue' in df_merged.columns: df_merged['RevenuePerEmp'] = self._safe_div(df_merged['revenue'], df_merged['employee_count']) if 'net_income' in df_merged.columns: df_merged['ProfitPerEmp'] = self._safe_div(df_merged['net_income'], df_merged['employee_count']) return df_merged