From 282cec080b22fec2169f1137f59ca1caf4202d6f Mon Sep 17 00:00:00 2001 From: xucheng Date: Mon, 12 Jan 2026 19:20:18 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E4=BA=86=E4=B8=80=E4=BA=9B?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E8=8E=B7=E5=8F=96=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/clients/bloomberg_client.py | 308 +++--- backend/app/services/bloomberg_service.py | 15 +- backend/debug_bdh.py | 70 ++ backend/debug_bdp_currency.py | 67 ++ backend/debug_revenue_dates.py | 94 ++ backend/inspect_db.py | 42 + backend/inspect_market_cap.py | 39 + backend/server.log | 979 +++++++++++++++++++ backend/test_bloomberg_market_cap.py | 61 ++ backend/test_bloomberg_series.py | 66 ++ backend/verify_currency.py | 57 ++ backend/verify_historical_currency.py | 41 + frontend/src/app/page.tsx | 331 ++++--- frontend/src/components/app-sidebar.tsx | 41 + frontend/src/components/bloomberg-view.tsx | 182 +++- frontend/src/components/financial-tables.tsx | 4 +- frontend/src/components/history-list.tsx | 78 +- frontend/src/components/nav-header.tsx | 10 +- frontend/src/components/stock-chart.tsx | 83 ++ 19 files changed, 2256 insertions(+), 312 deletions(-) create mode 100644 backend/debug_bdh.py create mode 100644 backend/debug_bdp_currency.py create mode 100644 backend/debug_revenue_dates.py create mode 100644 backend/inspect_db.py create mode 100644 backend/inspect_market_cap.py create mode 100644 backend/test_bloomberg_market_cap.py create mode 100644 backend/test_bloomberg_series.py create mode 100644 backend/verify_currency.py create mode 100644 backend/verify_historical_currency.py create mode 100644 frontend/src/components/app-sidebar.tsx create mode 100644 frontend/src/components/stock-chart.tsx diff --git a/backend/app/clients/bloomberg_client.py b/backend/app/clients/bloomberg_client.py index ef067fe..e88d552 100644 --- a/backend/app/clients/bloomberg_client.py +++ b/backend/app/clients/bloomberg_client.py @@ -9,7 +9,7 @@ import websocket import psycopg2 import pandas as pd from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT -from datetime import datetime +from datetime import datetime, timedelta from dotenv import load_dotenv from pathlib import Path import logging @@ -81,7 +81,7 @@ PRICE_CONFIG = { } STOCKCARD_CONFIG = { - "period": 15, + "period": 10, "unit": 100000000 } @@ -300,12 +300,22 @@ class BloombergClient: except Exception: conn.rollback() # Should not happen with IF NOT EXISTS but good practice + # Migrate update_date to TIMESTAMP + try: + cur.execute("ALTER TABLE stockcard ALTER COLUMN update_date TYPE TIMESTAMP USING update_date::timestamp;") + except Exception as e: + # Likely already converted or failed, log but don't crash + logger.info(f"Schema migration note (update_date): {e}") + conn.rollback() + conn.commit() def save_data(self, data_list): """Insert a list of data dictionaries into the database.""" if not data_list: return + + conn = self._get_db_connection() if not conn: return @@ -354,7 +364,7 @@ class BloombergClient: id, ROW_NUMBER() OVER( PARTITION BY company_code, currency, indicator, value_date - ORDER BY update_date DESC + ORDER BY update_date DESC, id DESC ) as rn FROM stockcard @@ -407,12 +417,28 @@ class BloombergClient: # If symbol already has Equity, use it. Else append. if "Equity" in symbol: company_code = symbol + bucket_code = symbol # Usage for bucket? + # If symbol comes in as '631 HK Equity', we might want to standardize? + # Assuming symbol is correct input. else: # Special case for China market: use 'CH Equity' instead of 'CN Equity' mapped_market = "CH" if market == "CN" else market + + # Canonical Code (Store in DB): Keep explicit zeros if provided in symbol company_code = f"{symbol} {mapped_market} Equity" - today_str = datetime.now().strftime('%Y-%m-%d') + # Query Ticker (Send to Bloomberg): Handle HK special case + query_ticker = company_code + if market == "HK" or (len(company_code.split()) > 1 and company_code.split()[1] == "HK"): + # Extract number part + parts = company_code.split() + ticker_part = parts[0] + if ticker_part.isdigit(): + short_ticker = str(int(ticker_part)) + # Reconstruct: 631 HK Equity + query_ticker = f"{short_ticker} {' '.join(parts[1:])}" + + today_str = datetime.now().strftime('%Y-%m-%d %H:%M:%S') logger.info(f"🚀 Starting fetch for: {company_code}") if progress_callback: progress_callback("Starting Bloomberg session...", 0) @@ -438,12 +464,8 @@ if 'bquery' not in globals(): try: self.execute_remote_code(init_code) - # 1. Fetch Basic Info - logger.info("Fetching Basic Data...") - if progress_callback: progress_callback("Fetching Company Basic Info...", 10) - basic_data = self._fetch_basic_remote(company_code, "USD") - self.save_data(basic_data) - + + # 1. Fetch Basic Info # Determine currency if force_currency and force_currency != "Auto": currency = force_currency @@ -456,46 +478,71 @@ if 'bquery' not in globals(): elif "HK" in market.upper(): currency = "HKD" logger.info(f"Using auto-detected currency: {currency}") - # 2. Fetch Currency Data + # 2. Fetch Basic Info + logger.info("Fetching Basic Data...") + if progress_callback: progress_callback("Fetching Company Basic Info...", 10) + try: + basic_data = self._fetch_basic_remote(company_code, currency, query_ticker=query_ticker) + logger.info(f"DEBUG: basic_data before save: {basic_data}") + self.save_data(basic_data) + except Exception as e: + logger.error(f"Error fetching basic data: {e}") + + # 3. Fetch Currency Data logger.info("Fetching Currency Data...") if progress_callback: progress_callback(f"正在获取货币指标 ({currency})...", 30) - curr_data = self._fetch_series_remote(company_code, currency, CURRENCY_CONFIG, "currency") - self.save_data(curr_data) + curr_data = [] + try: + curr_data = self._fetch_series_remote(company_code, currency, CURRENCY_CONFIG, "currency", query_ticker=query_ticker) + self.save_data(curr_data) + except Exception as e: + logger.error(f"Error fetching currency series: {e}") - # 3. Fetch Non-Currency Data + # 4. Fetch Non-Currency Data logger.info("Fetching Non-Currency Data...") if progress_callback: progress_callback("正在获取非货币指标...", 50) - non_curr_data = self._fetch_series_remote(company_code, currency, NON_CURRENCY_CONFIG, "non_currency") - self.save_data(non_curr_data) - - # 4. Fetch Price Data (Aligned with Revenue Dates) + try: + non_curr_data = self._fetch_series_remote(company_code, currency, NON_CURRENCY_CONFIG, "non_currency", query_ticker=query_ticker) + self.save_data(non_curr_data) + except Exception as e: + logger.error(f"Error fetching non-currency series: {e}") + + # 5. Fetch Price Data (Aligned with Revenue Dates) logger.info("Fetching Price Data (Aligned)...") if progress_callback: progress_callback("正在获取价格指标...", 70) # Extract Revenue dates revenue_dates = [] - rev_key = CURRENCY_CONFIG.get("Revenue", "SALES_REV_TURN") - # The saved data uses indicator name from config keys (e.g. "Revenue") - # So looking for "Revenue" in saved entries + if curr_data: + for item in curr_data: + # Check for "Revenue" + if item['indicator'].lower() == "revenue": # Robust case-insensitive check + if item['value_date']: + revenue_dates.append(item['value_date']) - for item in curr_data: - # Check for "Revenue" (case insensitive match if needed) - if item['indicator'].lower() == 'revenue': - if item['value_date']: - # Ensure YYYY-MM-DD - revenue_dates.append(item['value_date']) - - # Remove specs, duplicates, sort + # Remove duplicates, sort revenue_dates = sorted(list(set(revenue_dates)), reverse=True) if revenue_dates: logger.info(f"Found {len(revenue_dates)} revenue reporting dates. Fetching aligned price data...") - price_data = self._fetch_price_by_dates_remote(company_code, currency, revenue_dates) - self.save_data(price_data) + try: + price_data = self._fetch_price_by_dates_remote(company_code, currency, revenue_dates, query_ticker=query_ticker) + self.save_data(price_data) + except Exception as e: + logger.error(f"Error fetching aligned price data: {e}") else: - logger.warning("No revenue dates found. Falling back to yearly price fetch.") - price_data = self._fetch_series_remote(company_code, currency, PRICE_CONFIG, "price") - self.save_data(price_data) + logger.warning("No revenue dates found. Falling back to yearly price fetch (Dec 31).") + # Generate last 10 years Dec 31 + fallback_dates = [] + current_year = datetime.now().year + for i in range(1, 11): + fallback_dates.append(f"{current_year - i}-12-31") + + try: + price_data = self._fetch_price_by_dates_remote(company_code, currency, fallback_dates, query_ticker=query_ticker) + self.save_data(price_data) + except Exception as e: + logger.error(f"Error fetching fallback price data: {e}") # 5. Cleanup if progress_callback: progress_callback("Finalizing data...", 90) @@ -508,74 +555,80 @@ if 'bquery' not in globals(): if progress_callback: progress_callback(f"Error: {e}", 0) raise e - def _fetch_basic_remote(self, company_code, currency): + def _fetch_basic_remote(self, company_code, currency, query_ticker=None): """Generates code to fetch basic data""" + target_ticker = query_ticker if query_ticker else company_code + code = f""" def get_basic(): company = "{company_code}" + query_ticker = "{target_ticker}" curr = "{currency}" res_list = [] - # 1. BQL query - q = f"for(['{{company}}']) get(name,listing_date,pe_ratio,px_to_book_ratio,cur_mkt_cap(currency={{curr}}),PCT_REVENUE_FROM_FOREIGN_SOURCES)" + # 1. BDP Query for most fields (except Market Cap) + fields = ["NAME", "PE_RATIO", "PX_TO_BOOK_RATIO", "PCT_REVENUE_FROM_FOREIGN_SOURCES", "DIVIDEND_12_MONTH_YIELD", "EQY_INIT_PO_DT"] + try: - df = bquery.bql(q) + # Use overrides for currency. Expects list of tuples. + # Try both CURRENCY (for price) and EQY_FUND_CRNCY (for fundamentals) + df = bquery.bdp([query_ticker], fields, overrides=[('CURRENCY', curr), ('EQY_FUND_CRNCY', curr)]) + if not df.empty: - def get_val(df, field_name): - if field_name == 'name': - rows = df[df['field'] == 'name'] - elif 'cur_mkt_cap' in field_name: - rows = df[df['field'].str.contains('cur_mkt_cap')] - elif 'FOREIGN' in field_name: - rows = df[df['field'].str.contains('FOREIGN')] - else: - rows = df[df['field'] == field_name] - - if not rows.empty: - val = rows['value'].iloc[0] - # Handle Timestamp object from remote pandas - if hasattr(val, 'strftime'): - return val.strftime('%Y-%m-%d') - return str(val) if val is not None else None + def safe_get(df, col): + if col in df.columns: + val = df[col].iloc[0] + if val is None: return None + if hasattr(val, 'strftime'): return val.strftime('%Y-%m-%d') + return str(val) return None - res_list.append({{"indicator": "company_name", "value": get_val(df, 'name')}}) - res_list.append({{"indicator": "pe_ratio", "value": get_val(df, 'pe_ratio')}}) - res_list.append({{"indicator": "pb_ratio", "value": get_val(df, 'pb_ratio')}}) - res_list.append({{"indicator": "market_cap", "value": get_val(df, 'cur_mkt_cap')}}) - res_list.append({{"indicator": "Rev_Abroad", "value": get_val(df, 'FOREIGN')}}) - except Exception as e: - print(f"Basic BQL Error: {{e}}") + res_list.append({{"indicator": "company_name", "value": safe_get(df, 'NAME')}}) + res_list.append({{"indicator": "pe_ratio", "value": safe_get(df, 'PE_RATIO')}}) + res_list.append({{"indicator": "pb_ratio", "value": safe_get(df, 'PX_TO_BOOK_RATIO')}}) + # res_list.append({{"indicator": "market_cap", "value": safe_get(df, 'CUR_MKT_CAP')}}) # Moved to BDH + res_list.append({{"indicator": "Rev_Abroad", "value": safe_get(df, 'PCT_REVENUE_FROM_FOREIGN_SOURCES')}}) + res_list.append({{"indicator": "dividend_yield", "value": safe_get(df, 'DIVIDEND_12_MONTH_YIELD')}}) + res_list.append({{"indicator": "IPO_date", "value": safe_get(df, 'EQY_INIT_PO_DT')}}) - # 2. BDP for IPO and Dividend - try: - did = bquery.bdp([company], ["DIVIDEND_12_MONTH_YIELD"]) - if not did.empty and 'DIVIDEND_12_MONTH_YIELD' in did.columns: - res_list.append({{"indicator": "dividend_yield", "value": str(did['DIVIDEND_12_MONTH_YIELD'][0])}}) - - ipo = bquery.bdp([company], ["EQY_INIT_PO_DT"]) - if not ipo.empty and 'EQY_INIT_PO_DT' in ipo.columns: - val = ipo['EQY_INIT_PO_DT'][0] - val_str = str(val) - if hasattr(val, 'strftime'): - val_str = val.strftime('%Y-%m-%d') - res_list.append({{"indicator": "IPO_date", "value": val_str}}) - except Exception as e: print(f"Basic BDP Error: {{e}}") + # 2. BDH Query for Market Cap (To enforce Currency) + try: + import datetime + end_date = datetime.datetime.now().strftime('%Y%m%d') + start_date = (datetime.datetime.now() - datetime.timedelta(days=10)).strftime('%Y%m%d') + + # Fetch CUR_MKT_CAP via BDH to respect currency option + df_cap = bquery.bdh([query_ticker], ['CUR_MKT_CAP'], start_date=start_date, end_date=end_date, options={{'currency': curr}}) + + if not df_cap.empty: + # BDH usually returns Market Cap in Millions. + # User simplified requirement: Keep it in Millions. + # Frontend will divide by 100 to get "Yi". + val_millions = df_cap.iloc[-1]['CUR_MKT_CAP'] + res_list.append({{"indicator": "market_cap", "value": str(val_millions)}}) + + except Exception as e: + print(f"Basic BDH Market Cap Error: {{e}}") + # Format result final_res = [] - today = datetime.now().strftime('%Y-%m-%d') + + import datetime + today_dt = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') + for item in res_list: - if item['value']: + # Check against None string too if needed + if item['value'] and str(item['value']) != 'None': final_res.append({{ "Company_code": company, - "update_date": today, + "update_date": today_dt, "currency": curr, "indicator": item['indicator'], "value": item['value'], - "value_date": today + "value_date": today_dt }}) print("JSON_START") @@ -586,27 +639,35 @@ get_basic() """ return self._execute_and_parse(code) - def _fetch_series_remote(self, company_code, currency, config_dict, result_type): + def _fetch_series_remote(self, company_code, currency, config_dict, result_type, query_ticker=None): """Generates code to fetch series data using BDH""" + target_ticker = query_ticker if query_ticker else company_code config_json = json.dumps(config_dict) period_years = STOCKCARD_CONFIG['period'] - start_year = datetime.now().year - period_years - start_date = f"{start_year}0101" - end_date = datetime.now().strftime('%Y%m%d') - + # Calculate start date + end_date = datetime.now() + start_date = end_date - timedelta(days=period_years*365) + + # Format dates for BDH (YYYYMMDD) + start_date_str = start_date.strftime('%Y%m%d') + end_date_str = end_date.strftime('%Y%m%d') + + # BDH Options bdh_options = { - 'periodicitySelection': 'YEARLY', - 'currency': currency, - 'nonTradingDayFillOption': 'ALL_CALENDAR_DAYS', - 'nonTradingDayFillMethod': 'PREVIOUS_VALUE' + "periodicityAdjustment": "FISCAL", + "periodicitySelection": "YEARLY", + "currency": currency, + # "nonTradingDayFillOption": "NON_TRADING_WEEKDAYS", + # "nonTradingDayFillMethod": "PREVIOUS_VALUE" } bdh_opts_json = json.dumps(bdh_options) code = f""" def get_series(): company = "{company_code}" + query_ticker = "{target_ticker}" curr = "{currency}" config = {config_json} @@ -617,10 +678,10 @@ def get_series(): try: df = bquery.bdh( - [company], + [query_ticker], fields, - start_date='{start_date}', - end_date='{end_date}', + start_date='{start_date_str}', + end_date='{end_date_str}', options={bdh_opts_json} ) @@ -659,7 +720,7 @@ def get_series(): res_list.append({{ "Company_code": company, - "update_date": "{datetime.now().strftime('%Y-%m-%d')}", + "update_date": "{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}", "currency": curr, "indicator": indicator_name, "value": val_str, @@ -677,11 +738,12 @@ get_series() """ return self._execute_and_parse(code) - def _fetch_price_by_dates_remote(self, company_code, currency, dates): + def _fetch_price_by_dates_remote(self, company_code, currency, dates, query_ticker=None): """Generates code to fetch price/mkt_cap for specific dates""" if not dates: return [] + target_ticker = query_ticker if query_ticker else company_code dates_json = json.dumps(dates) config_json = json.dumps(PRICE_CONFIG) @@ -695,6 +757,7 @@ get_series() code = f""" def get_price_by_dates(): company = "{company_code}" + query_ticker = "{target_ticker}" curr = "{currency}" dates = {dates_json} config = {config_json} @@ -708,27 +771,30 @@ def get_price_by_dates(): # d_str is 'YYYY-MM-DD', bdh needs 'YYYYMMDD' d_param = d_str.replace('-', '') - try: - df = bquery.bdh( - [company], - fields, - start_date=d_param, - end_date=d_param, - options={bdh_opts_json} - ) - - if not df.empty: - for _, row in df.iterrows(): - # value_date is d_str - - for mnemonic, indicator_name in mnemonic_map.items(): - col_name = mnemonic - # bdh columns might be tuple or just string depending on request - # usually 'PX_LAST' - + for mnemonic, indicator_name in mnemonic_map.items(): + field = mnemonic + try: + df = bquery.bdh( + [query_ticker], + [field], + start_date=d_param, + end_date=d_param, + options={bdh_opts_json} + ) + + if not df.empty: + for _, row in df.iterrows(): val = None - if col_name in df.columns: - val = row[col_name] + if field in df.columns: + val = row[field] + elif field in row: + val = row[field] + else: + # Try case insensitive + for c in df.columns: + if c.upper() == field: + val = row[c] + break if pd.isna(val) or val is None: continue @@ -737,14 +803,16 @@ def get_price_by_dates(): res_list.append({{ "Company_code": company, - "update_date": "{datetime.now().strftime('%Y-%m-%d')}", + "update_date": "{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}", "currency": curr, "indicator": indicator_name, "value": val_str, - "value_date": d_str + "value_date": d_str }}) - except Exception as e: - print(f"Error fetching price for {{d_str}}: {{e}}") + + except Exception as e: + # print(f"BDH Error for {{field}}: {{e}}") + pass print("JSON_START") print(json.dumps(res_list)) @@ -758,7 +826,9 @@ get_price_by_dates() """Execute code and parse [JSON_START]...[JSON_END]""" raw_output_list = self.execute_remote_code(code) raw_output = "".join(raw_output_list) if isinstance(raw_output_list, list) else str(raw_output_list) - # logger.debug(f"Remote execution returned {len(raw_output)} chars.") # Optional debug + # Always log raw output first few chars for debug + logger.info(f"REMOTE RAW OUTPUT: {raw_output[:1000]}") + # Actually let's log everything if it fails to find JSON # Simple parser try: @@ -771,7 +841,7 @@ get_price_by_dates() logger.info(f"✅ Parsed {len(data) if isinstance(data, list) else 1} items from remote.") return data else: - logger.warning(f"⚠️ No JSON output found in remote response.") + logger.warning(f"⚠️ No JSON output found in remote response. Raw: {raw_output}") return [] except Exception as e: logger.error(f"❌ Error parsing JSON from remote: {e}") diff --git a/backend/app/services/bloomberg_service.py b/backend/app/services/bloomberg_service.py index 2b4b55d..5db75c7 100644 --- a/backend/app/services/bloomberg_service.py +++ b/backend/app/services/bloomberg_service.py @@ -58,8 +58,9 @@ async def get_bloomberg_data( # 2. 获取该公司的所有数据 # schema: indicator, value, value_date (作为报告期) + # Added update_date query = text(""" - SELECT indicator, value, value_date, currency + SELECT indicator, value, value_date, currency, update_date FROM stockcard WHERE Company_code = :code """) @@ -73,11 +74,16 @@ async def get_bloomberg_data( val = row.value v_date = row.value_date curr = row.currency + u_date = row.update_date if not v_date: continue date_str = v_date.isoformat() if hasattr(v_date, 'isoformat') else str(v_date) + # Handle update_date formatting + update_date_str = "" + if u_date: + update_date_str = u_date.isoformat() if hasattr(u_date, 'isoformat') else str(u_date) # Key by (date, currency) to support multiple currencies for the same date unique_key = f"{date_str}_{curr}" @@ -85,9 +91,14 @@ async def get_bloomberg_data( if unique_key not in data_by_date: data_by_date[unique_key] = { "end_date": date_str, - "currency": curr + "currency": curr, + "update_date": "" } + # Update the group's update_date if we find a newer one in this batch + if update_date_str > data_by_date[unique_key]["update_date"]: + data_by_date[unique_key]["update_date"] = update_date_str + # Normalize key to match frontend expectation (mostly lowercase) # e.g. "ROE" -> "roe", "PE" -> "pe" norm_indicator = indicator.lower() diff --git a/backend/debug_bdh.py b/backend/debug_bdh.py new file mode 100644 index 0000000..e3da856 --- /dev/null +++ b/backend/debug_bdh.py @@ -0,0 +1,70 @@ + +import sys +import os +import time +import logging + +# Ensure we can import from backend +sys.path.append(os.path.join(os.getcwd(), 'backend')) + +# Setup logging +logging.basicConfig(level=logging.INFO) + +from app.clients.bloomberg_client import BloombergClient + +def test_bdh_currency(): + print("Initializing BloombergClient...") + client = BloombergClient() + + ticker = "6301 JP Equity" + + code = """ +import sys +import datetime +try: + if 'bquery' not in globals(): + import bquery +except ImportError: + pass + +ticker = "{ticker}" +fields = ["CUR_MKT_CAP", "PX_LAST"] + +print(f"--- BDH Currency Test for {{ticker}} ---") + +def get_bdh_val(curr, desc): + try: + # BDH request for last 5 days to ensure we hit a trading day + end_date = datetime.datetime.now().strftime('%Y%m%d') + start_date = (datetime.datetime.now() - datetime.timedelta(days=10)).strftime('%Y%m%d') + + # Pass currency in options + df = bquery.bdh([ticker], fields, start_date=start_date, end_date=end_date, options={{'currency': curr}}) + + if not df.empty: + print(f"--- {{desc}} (Currency: {{curr}}) ---") + # Get last row + last_row = df.iloc[-1] + for col in df.columns: + print(f" {{col}}: {{last_row[col]}}") + else: + print(f"{{desc}} Empty") + except Exception as e: + print(f"{{desc}} Error: {{e}}") + +# 1. JPY +get_bdh_val('JPY', "BDH_JPY") + +# 2. USD +get_bdh_val('USD', "BDH_USD") + +""" + formatted_code = code.format(ticker=ticker) + + print(f"Executing remote logic for {ticker}...") + output = client.execute_remote_code(formatted_code) + print("Remote Output:") + print(output) + +if __name__ == "__main__": + test_bdh_currency() diff --git a/backend/debug_bdp_currency.py b/backend/debug_bdp_currency.py new file mode 100644 index 0000000..4c65331 --- /dev/null +++ b/backend/debug_bdp_currency.py @@ -0,0 +1,67 @@ + +import sys +import os +import time +import logging + +# Ensure we can import from backend +sys.path.append(os.path.join(os.getcwd(), 'backend')) + +# Setup logging +logging.basicConfig(level=logging.INFO) + +from app.clients.bloomberg_client import BloombergClient + +def test_bdp_options_injection(): + print("Initializing BloombergClient...") + client = BloombergClient() + + ticker = "6301 JP Equity" + + code = """ +import sys +try: + if 'bquery' not in globals(): + import bquery +except ImportError: + pass + +ticker = "{ticker}" +fields = ["CUR_MKT_CAP", "PX_LAST"] + +print(f"--- Option Injection Test for {{ticker}} ---") + +def get_val_via_options(custom_overrides, desc): + try: + # Pass overrides=None, pass custom overrides via options + # Escape braces for format string by doubling them + df = bquery.bdp([ticker], fields, overrides=None, options={{'overrides': custom_overrides}}) + if not df.empty: + print(f"--- {{desc}} ---") + for col in df.columns: + print(f" {{col}}: {{df.iloc[0][col]}}") + print(f" Sent: {{custom_overrides}}") + else: + print(f"{{desc}} Empty") + except Exception as e: + print(f"{{desc}} Error: {{e}}") + +# 1. Direct fieldId (No wrapper) +get_val_via_options([{{'fieldId': 'CURRENCY', 'value': 'USD'}}], "Try1_Direct_Dict") + +# 2. Wrapped in 'overrides' (Same as current impl) +get_val_via_options([{{'overrides': {{'fieldId': 'CURRENCY', 'value': 'USD'}}}}], "Try2_Wrapped_Overrides") + +# 3. Wrapped in 'override' (Singular) +get_val_via_options([{{'override': {{'fieldId': 'CURRENCY', 'value': 'USD'}}}}], "Try3_Wrapped_Override") + +""" + formatted_code = code.format(ticker=ticker) + + print(f"Executing remote logic for {ticker}...") + output = client.execute_remote_code(formatted_code) + print("Remote Output:") + print(output) + +if __name__ == "__main__": + test_bdp_options_injection() diff --git a/backend/debug_revenue_dates.py b/backend/debug_revenue_dates.py new file mode 100644 index 0000000..b1155e9 --- /dev/null +++ b/backend/debug_revenue_dates.py @@ -0,0 +1,94 @@ + +import asyncio +from app.clients.bloomberg_client import BloombergClient, CURRENCY_CONFIG + +async def run(): + client = BloombergClient() + company = "2503 JP Equity" + + # Simulate fetch of currency data (which includes Revenue) + # CURRENCY_CONFIG key "Revenue" is "SALES_REV_TURN" + + print(f"Debugging Revenue Dates for {company} (CNY)...") + + # We'll use the exact simulating logic of _fetch_series_remote but print the dates + + config = {"Revenue": CURRENCY_CONFIG["Revenue"]} + # Force CNY + currency = "CNY" + + # Generate the code that _fetch_series_remote generates + # We need to replicate the remote code construction roughly or call execute_remote_code + + import json + from datetime import datetime + + STOCKCARD_CONFIG = { "period": 10 } + period_years = STOCKCARD_CONFIG['period'] + start_year = datetime.now().year - period_years + start_date = f"{start_year}0101" + end_date = datetime.now().strftime('%Y%m%d') + + bdh_options = { + 'periodicitySelection': 'YEARLY', + 'currency': currency, + 'nonTradingDayFillOption': 'ALL_CALENDAR_DAYS', + 'nonTradingDayFillMethod': 'PREVIOUS_VALUE' + } + + config_json = json.dumps(config) + bdh_opts_json = json.dumps(bdh_options) + + remote_code = f""" +def debug_series(): + company = "{company}" + curr = "{currency}" + config = {config_json} + + mnemonic_map = {{v.upper(): k for k, v in config.items()}} + fields = list(mnemonic_map.keys()) + + try: + df = bquery.bdh( + [company], + fields, + start_date='{start_date}', + end_date='{end_date}', + options={bdh_opts_json} + ) + + print(f"--- Raw Revenue Data (CNY) ---") + if not df.empty: + print(df) + + revenue_dates = [] + for _, row in df.iterrows(): + # Extract date + date_val = None + if 'date' in df.columns: date_val = row['date'] + elif 'DATE' in df.columns: date_val = row['DATE'] + + if date_val: + d_str = str(date_val)[:10] + # Check for value + val = None + if fields[0] in row: val = row[fields[0]] + elif fields[0] in df.columns: val = row[fields[0]] + + if val is not None: + revenue_dates.append(d_str) + + print(f"\\nExtracted Revenue Dates: {{sorted(revenue_dates, reverse=True)}}") + else: + print("DataFrame is empty.") + + except Exception as e: + print(f"Error: {{e}}") + +debug_series() +""" + result = client.execute_remote_code(remote_code) + print(result) + +if __name__ == "__main__": + asyncio.run(run()) diff --git a/backend/inspect_db.py b/backend/inspect_db.py new file mode 100644 index 0000000..30dfdfb --- /dev/null +++ b/backend/inspect_db.py @@ -0,0 +1,42 @@ +import os +import psycopg2 +from dotenv import load_dotenv + +load_dotenv() + +def inspect_schema(): + db_host = os.getenv("DB_HOST", "192.168.3.195") + db_user = os.getenv("DB_USER", "value") + db_pass = os.getenv("DB_PASSWORD", "Value609!") + db_name = os.getenv("DB_NAME", "fa3") + db_port = os.getenv("DB_PORT", "5432") + + try: + conn = psycopg2.connect( + host=db_host, user=db_user, password=db_pass, dbname=db_name, port=db_port + ) + cur = conn.cursor() + + print("--- Table Columns ---") + cur.execute(""" + SELECT column_name, data_type + FROM information_schema.columns + WHERE table_name = 'stockcard'; + """) + rows = cur.fetchall() + for row in rows: + print(f"{row[0]}: {row[1]}") + + print("\n--- Recent Records update_date ---") + cur.execute("SELECT update_date FROM stockcard ORDER BY id DESC LIMIT 5") + rows = cur.fetchall() + for row in rows: + print(f"{row[0]} (Type: {type(row[0])})") + + conn.close() + + except Exception as e: + print(f"Error: {e}") + +if __name__ == "__main__": + inspect_schema() diff --git a/backend/inspect_market_cap.py b/backend/inspect_market_cap.py new file mode 100644 index 0000000..c00447f --- /dev/null +++ b/backend/inspect_market_cap.py @@ -0,0 +1,39 @@ + +import os +import psycopg2 +import logging +from datetime import datetime + +# Config logging +logging.basicConfig(level=logging.INFO) + +def inspect_db(): + db_host = os.getenv("DB_HOST", "192.168.3.195") + db_user = os.getenv("DB_USER", "value") + db_pass = os.getenv("DB_PASSWORD", "Value609!") + db_name = os.getenv("DB_NAME", "fa3") + + conn = psycopg2.connect( + host=db_host, user=db_user, password=db_pass, dbname=db_name + ) + + with conn.cursor() as cur: + # Check basic data market cap + cur.execute(""" + SELECT update_date, indicator, value, value_date, currency, source + FROM stockcard + WHERE Company_code LIKE '6301 JP%' + AND (indicator = 'market_cap' OR indicator = 'Market_Cap') + ORDER BY update_date DESC, value_date DESC + LIMIT 20; + """) + rows = cur.fetchall() + print(f"{'Update Date':<20} | {'Indicator':<15} | {'Currency':<5} | {'Value Date':<12} | {'Value (Raw)':<20} | {'Source'}") + print("-" * 100) + for row in rows: + print(f"{str(row[0]):<20} | {row[1]:<15} | {row[4]:<5} | {str(row[3]):<12} | {row[2]:<20} | {row[5]}") + + conn.close() + +if __name__ == "__main__": + inspect_db() diff --git a/backend/server.log b/backend/server.log index ee210b9..a5c2812 100644 --- a/backend/server.log +++ b/backend/server.log @@ -1556,3 +1556,982 @@ sqlalchemy.exc.ProgrammingError: (sqlalchemy.dialects.postgresql.asyncpg.Program 2026-01-12 09:31:26,489 - app.clients.bloomberg_client - INFO - ✅ Completed processing for 2503 JP Equity 2026-01-12 09:31:26,490 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=54, Msg=Bloomberg data sync complete, Progress=90% 2026-01-12 09:31:26,791 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=54, Msg=Bloomberg 数据同步完成, Progress=100% +2026-01-12 10:15:52,800 - app.main - INFO - 🔍 [搜索] 开始搜索股票: 三一国际 +2026-01-12 10:15:53,105 - app.main - INFO - 🤖 [搜索-LLM] 调用 gemini-2.5-flash 进行股票搜索 +2026-01-12 10:15:53,112 - google_genai.models - INFO - AFC is enabled with max remote calls: 10. +2026-01-12 10:15:57,833 - httpx - INFO - HTTP Request: POST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent "HTTP/1.1 200 OK" +2026-01-12 10:15:57,856 - app.main - INFO - ✅ [搜索-LLM] 模型响应完成, 耗时: 4.75秒, Tokens: prompt=166, completion=78, total=244 +2026-01-12 10:15:57,857 - app.main - INFO - ✅ [搜索] 搜索完成, 找到 1 个结果, 总耗时: 5.05秒 +2026-01-12 10:16:22,607 - app.main - INFO - 🔍 [搜索] 开始搜索股票: 三一国际 +2026-01-12 10:16:22,609 - app.main - INFO - 🤖 [搜索-LLM] 调用 gemini-2.5-flash 进行股票搜索 +2026-01-12 10:16:22,611 - google_genai.models - INFO - AFC is enabled with max remote calls: 10. +2026-01-12 10:16:26,693 - httpx - INFO - HTTP Request: POST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent "HTTP/1.1 200 OK" +2026-01-12 10:16:26,716 - app.main - INFO - ✅ [搜索-LLM] 模型响应完成, 耗时: 4.11秒, Tokens: prompt=166, completion=78, total=244 +2026-01-12 10:16:26,717 - app.main - INFO - ✅ [搜索] 搜索完成, 找到 1 个结果, 总耗时: 4.11秒 +2026-01-12 10:39:45,586 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=55, Msg=正在初始化数据获取..., Progress=0% +2026-01-12 10:39:46,580 - app.clients.bloomberg_client - INFO - Connecting to Jupyter at http://192.168.3.161:8888... +2026-01-12 10:39:47,135 - app.clients.bloomberg_client - INFO - ✅ Authentication successful. +2026-01-12 10:39:47,166 - app.clients.bloomberg_client - INFO - ✅ Found existing kernel: bc27f3b1-b028-434a-99fa-c1cad4495a87 (remote_env) +2026-01-12 10:39:47,228 - app.clients.bloomberg_client - INFO - ✅ WebSocket connected. +2026-01-12 10:39:47,228 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=55, Msg=数据源连接成功, Progress=10% +2026-01-12 10:39:47,502 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=55, Msg=正在连接 Bloomberg 终端..., Progress=20% +2026-01-12 10:39:47,936 - app.clients.bloomberg_client - INFO - 🚀 Starting fetch for: SAB VN Equity +2026-01-12 10:39:47,937 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=55, Msg=Starting Bloomberg session..., Progress=20% +2026-01-12 10:39:48,418 - app.clients.bloomberg_client - INFO - Fetching Basic Data... +2026-01-12 10:39:48,418 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=55, Msg=Fetching Company Basic Info..., Progress=27% +2026-01-12 10:39:50,974 - app.clients.bloomberg_client - INFO - ✅ Parsed 2 items from remote. +2026-01-12 10:39:51,644 - app.clients.bloomberg_client - INFO - ✅ Saved 2 records to database. +2026-01-12 10:39:51,645 - app.clients.bloomberg_client - INFO - Using forced currency: CNY +2026-01-12 10:39:51,645 - app.clients.bloomberg_client - INFO - Fetching Currency Data... +2026-01-12 10:39:51,646 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=55, Msg=正在获取货币指标 (CNY)..., Progress=41% +2026-01-12 10:39:53,556 - app.clients.bloomberg_client - INFO - ✅ Parsed 275 items from remote. +2026-01-12 10:40:05,191 - app.clients.bloomberg_client - INFO - ✅ Saved 275 records to database. +2026-01-12 10:40:05,201 - app.clients.bloomberg_client - INFO - Fetching Non-Currency Data... +2026-01-12 10:40:05,201 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=55, Msg=正在获取非货币指标..., Progress=55% +2026-01-12 10:40:06,376 - app.clients.bloomberg_client - INFO - ✅ Parsed 290 items from remote. +2026-01-12 10:40:18,886 - app.clients.bloomberg_client - INFO - ✅ Saved 290 records to database. +2026-01-12 10:40:18,888 - app.clients.bloomberg_client - INFO - Fetching Price Data (Aligned)... +2026-01-12 10:40:18,888 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=55, Msg=正在获取价格指标..., Progress=69% +2026-01-12 10:40:19,463 - app.clients.bloomberg_client - INFO - Found 11 revenue reporting dates. Fetching aligned price data... +2026-01-12 10:40:24,699 - app.clients.bloomberg_client - INFO - ✅ Parsed 27 items from remote. +2026-01-12 10:40:26,363 - app.clients.bloomberg_client - INFO - ✅ Saved 27 records to database. +2026-01-12 10:40:26,366 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=55, Msg=Finalizing data..., Progress=82% +2026-01-12 10:40:27,693 - app.clients.bloomberg_client - INFO - ✅ Cleanup and View Refresh completed. +2026-01-12 10:40:27,694 - app.clients.bloomberg_client - INFO - ✅ Completed processing for SAB VN Equity +2026-01-12 10:40:27,694 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=55, Msg=Bloomberg data sync complete, Progress=90% +2026-01-12 10:40:28,421 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=55, Msg=Bloomberg 数据同步完成, Progress=100% +2026-01-12 10:42:39,579 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=56, Msg=正在初始化数据获取..., Progress=0% +2026-01-12 10:42:39,887 - app.clients.bloomberg_client - INFO - Connecting to Jupyter at http://192.168.3.161:8888... +2026-01-12 10:42:40,132 - app.clients.bloomberg_client - INFO - ✅ Authentication successful. +2026-01-12 10:42:40,160 - app.clients.bloomberg_client - INFO - ✅ Found existing kernel: bc27f3b1-b028-434a-99fa-c1cad4495a87 (remote_env) +2026-01-12 10:42:41,230 - app.clients.bloomberg_client - INFO - ✅ WebSocket connected. +2026-01-12 10:42:41,231 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=56, Msg=数据源连接成功, Progress=10% +2026-01-12 10:42:42,048 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=56, Msg=正在连接 Bloomberg 终端..., Progress=20% +2026-01-12 10:42:42,308 - app.clients.bloomberg_client - INFO - 🚀 Starting fetch for: SAB VN Equity +2026-01-12 10:42:42,309 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=56, Msg=Starting Bloomberg session..., Progress=20% +2026-01-12 10:42:42,624 - app.clients.bloomberg_client - INFO - Fetching Basic Data... +2026-01-12 10:42:42,625 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=56, Msg=Fetching Company Basic Info..., Progress=27% +2026-01-12 10:42:43,914 - app.clients.bloomberg_client - INFO - ✅ Parsed 2 items from remote. +2026-01-12 10:42:44,298 - app.clients.bloomberg_client - INFO - ✅ Saved 2 records to database. +2026-01-12 10:42:44,299 - app.clients.bloomberg_client - INFO - Using forced currency: USD +2026-01-12 10:42:44,299 - app.clients.bloomberg_client - INFO - Fetching Currency Data... +2026-01-12 10:42:44,299 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=56, Msg=正在获取货币指标 (USD)..., Progress=41% +2026-01-12 10:42:45,638 - app.clients.bloomberg_client - INFO - ✅ Parsed 275 items from remote. +2026-01-12 10:42:59,116 - app.clients.bloomberg_client - INFO - ✅ Saved 275 records to database. +2026-01-12 10:42:59,117 - app.clients.bloomberg_client - INFO - Fetching Non-Currency Data... +2026-01-12 10:42:59,118 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=56, Msg=正在获取非货币指标..., Progress=55% +2026-01-12 10:43:00,410 - app.clients.bloomberg_client - INFO - ✅ Parsed 290 items from remote. +2026-01-12 10:43:13,907 - app.clients.bloomberg_client - INFO - ✅ Saved 290 records to database. +2026-01-12 10:43:13,908 - app.clients.bloomberg_client - INFO - Fetching Price Data (Aligned)... +2026-01-12 10:43:13,909 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=56, Msg=正在获取价格指标..., Progress=69% +2026-01-12 10:43:14,174 - app.clients.bloomberg_client - INFO - Found 11 revenue reporting dates. Fetching aligned price data... +2026-01-12 10:43:19,382 - app.clients.bloomberg_client - INFO - ✅ Parsed 27 items from remote. +2026-01-12 10:43:20,821 - app.clients.bloomberg_client - INFO - ✅ Saved 27 records to database. +2026-01-12 10:43:20,821 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=56, Msg=Finalizing data..., Progress=82% +2026-01-12 10:43:21,609 - app.clients.bloomberg_client - INFO - ✅ Cleanup and View Refresh completed. +2026-01-12 10:43:21,609 - app.clients.bloomberg_client - INFO - ✅ Completed processing for SAB VN Equity +2026-01-12 10:43:21,609 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=56, Msg=Bloomberg data sync complete, Progress=90% +2026-01-12 10:43:21,873 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=56, Msg=Bloomberg 数据同步完成, Progress=100% +2026-01-12 10:58:49,794 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=57, Msg=正在初始化数据获取..., Progress=0% +2026-01-12 10:58:50,395 - app.clients.bloomberg_client - INFO - Connecting to Jupyter at http://192.168.3.161:8888... +2026-01-12 10:58:50,649 - app.clients.bloomberg_client - INFO - ✅ Authentication successful. +2026-01-12 10:58:50,676 - app.clients.bloomberg_client - INFO - ✅ Found existing kernel: bc27f3b1-b028-434a-99fa-c1cad4495a87 (remote_env) +2026-01-12 10:58:50,734 - app.clients.bloomberg_client - INFO - ✅ WebSocket connected. +2026-01-12 10:58:50,734 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=57, Msg=数据源连接成功, Progress=10% +2026-01-12 10:58:50,996 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=57, Msg=正在连接 Bloomberg 终端..., Progress=20% +2026-01-12 10:58:51,414 - app.clients.bloomberg_client - INFO - 🚀 Starting fetch for: 2503 JP Equity +2026-01-12 10:58:51,414 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=57, Msg=Starting Bloomberg session..., Progress=20% +2026-01-12 10:58:51,864 - app.clients.bloomberg_client - INFO - Using forced currency: CNY +2026-01-12 10:58:51,864 - app.clients.bloomberg_client - INFO - Fetching Basic Data... +2026-01-12 10:58:51,864 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=57, Msg=Fetching Company Basic Info..., Progress=27% +2026-01-12 10:58:53,027 - app.clients.bloomberg_client - INFO - ✅ Parsed 2 items from remote. +2026-01-12 10:58:53,435 - app.clients.bloomberg_client - INFO - ✅ Saved 2 records to database. +2026-01-12 10:58:53,435 - app.clients.bloomberg_client - INFO - Fetching Currency Data... +2026-01-12 10:58:53,436 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=57, Msg=正在获取货币指标 (CNY)..., Progress=41% +2026-01-12 10:58:54,938 - app.clients.bloomberg_client - INFO - ✅ Parsed 215 items from remote. +2026-01-12 10:59:04,571 - app.clients.bloomberg_client - INFO - ✅ Saved 215 records to database. +2026-01-12 10:59:04,583 - app.clients.bloomberg_client - INFO - Fetching Non-Currency Data... +2026-01-12 10:59:04,584 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=57, Msg=正在获取非货币指标..., Progress=55% +2026-01-12 10:59:05,645 - app.clients.bloomberg_client - INFO - ✅ Parsed 260 items from remote. +2026-01-12 10:59:16,477 - app.clients.bloomberg_client - INFO - ✅ Saved 260 records to database. +2026-01-12 10:59:16,477 - app.clients.bloomberg_client - INFO - Fetching Price Data (Aligned)... +2026-01-12 10:59:16,478 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=57, Msg=正在获取价格指标..., Progress=69% +2026-01-12 10:59:17,032 - app.clients.bloomberg_client - INFO - Found 9 revenue reporting dates. Fetching aligned price data... +2026-01-12 10:59:20,896 - app.clients.bloomberg_client - INFO - ✅ Parsed 27 items from remote. +2026-01-12 10:59:22,712 - app.clients.bloomberg_client - INFO - ✅ Saved 27 records to database. +2026-01-12 10:59:22,713 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=57, Msg=Finalizing data..., Progress=82% +2026-01-12 10:59:23,316 - app.clients.bloomberg_client - INFO - ✅ Cleanup and View Refresh completed. +2026-01-12 10:59:23,317 - app.clients.bloomberg_client - INFO - ✅ Completed processing for 2503 JP Equity +2026-01-12 10:59:23,317 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=57, Msg=Bloomberg data sync complete, Progress=90% +2026-01-12 10:59:23,593 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=57, Msg=Bloomberg 数据同步完成, Progress=100% +2026-01-12 11:00:00,129 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=58, Msg=正在初始化数据获取..., Progress=0% +2026-01-12 11:00:00,711 - app.clients.bloomberg_client - INFO - Connecting to Jupyter at http://192.168.3.161:8888... +2026-01-12 11:00:01,085 - app.clients.bloomberg_client - INFO - ✅ Authentication successful. +2026-01-12 11:00:01,113 - app.clients.bloomberg_client - INFO - ✅ Found existing kernel: bc27f3b1-b028-434a-99fa-c1cad4495a87 (remote_env) +2026-01-12 11:00:01,164 - app.clients.bloomberg_client - INFO - ✅ WebSocket connected. +2026-01-12 11:00:01,165 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=58, Msg=数据源连接成功, Progress=10% +2026-01-12 11:00:01,426 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=58, Msg=正在连接 Bloomberg 终端..., Progress=20% +2026-01-12 11:00:01,773 - app.clients.bloomberg_client - INFO - 🚀 Starting fetch for: 2503 JP Equity +2026-01-12 11:00:01,773 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=58, Msg=Starting Bloomberg session..., Progress=20% +2026-01-12 11:00:02,544 - app.clients.bloomberg_client - INFO - Using forced currency: USD +2026-01-12 11:00:02,545 - app.clients.bloomberg_client - INFO - Fetching Basic Data... +2026-01-12 11:00:02,545 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=58, Msg=Fetching Company Basic Info..., Progress=27% +2026-01-12 11:00:03,720 - app.clients.bloomberg_client - INFO - ✅ Parsed 2 items from remote. +2026-01-12 11:00:04,112 - app.clients.bloomberg_client - INFO - ✅ Saved 2 records to database. +2026-01-12 11:00:04,113 - app.clients.bloomberg_client - INFO - Fetching Currency Data... +2026-01-12 11:00:04,113 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=58, Msg=正在获取货币指标 (USD)..., Progress=41% +2026-01-12 11:00:05,964 - app.clients.bloomberg_client - INFO - ✅ Parsed 215 items from remote. +2026-01-12 11:00:16,994 - app.clients.bloomberg_client - INFO - ✅ Saved 215 records to database. +2026-01-12 11:00:16,996 - app.clients.bloomberg_client - INFO - Fetching Non-Currency Data... +2026-01-12 11:00:16,996 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=58, Msg=正在获取非货币指标..., Progress=55% +2026-01-12 11:00:18,214 - app.clients.bloomberg_client - INFO - ✅ Parsed 260 items from remote. +2026-01-12 11:00:31,167 - app.clients.bloomberg_client - INFO - ✅ Saved 260 records to database. +2026-01-12 11:00:31,169 - app.clients.bloomberg_client - INFO - Fetching Price Data (Aligned)... +2026-01-12 11:00:31,170 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=58, Msg=正在获取价格指标..., Progress=69% +2026-01-12 11:00:32,027 - app.clients.bloomberg_client - INFO - Found 9 revenue reporting dates. Fetching aligned price data... +2026-01-12 11:00:36,241 - app.clients.bloomberg_client - INFO - ✅ Parsed 27 items from remote. +2026-01-12 11:00:38,065 - app.clients.bloomberg_client - INFO - ✅ Saved 27 records to database. +2026-01-12 11:00:38,066 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=58, Msg=Finalizing data..., Progress=82% +2026-01-12 11:00:39,407 - app.clients.bloomberg_client - INFO - ✅ Cleanup and View Refresh completed. +2026-01-12 11:00:39,407 - app.clients.bloomberg_client - INFO - ✅ Completed processing for 2503 JP Equity +2026-01-12 11:00:39,408 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=58, Msg=Bloomberg data sync complete, Progress=90% +2026-01-12 11:00:39,748 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=58, Msg=Bloomberg 数据同步完成, Progress=100% +2026-01-12 11:44:44,232 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=59, Msg=正在初始化数据获取..., Progress=0% +2026-01-12 11:44:44,905 - app.clients.bloomberg_client - INFO - Connecting to Jupyter at http://192.168.3.161:8888... +2026-01-12 11:44:46,453 - app.clients.bloomberg_client - INFO - ✅ Authentication successful. +2026-01-12 11:44:46,649 - app.clients.bloomberg_client - INFO - ✅ Found existing kernel: bc27f3b1-b028-434a-99fa-c1cad4495a87 (remote_env) +2026-01-12 11:44:47,699 - app.clients.bloomberg_client - INFO - ✅ WebSocket connected. +2026-01-12 11:44:47,700 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=59, Msg=数据源连接成功, Progress=10% +2026-01-12 11:44:49,420 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=59, Msg=正在连接 Bloomberg 终端..., Progress=20% +2026-01-12 11:44:49,979 - app.clients.bloomberg_client - INFO - 🚀 Starting fetch for: 2503 JP Equity +2026-01-12 11:44:49,979 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=59, Msg=Starting Bloomberg session..., Progress=20% +2026-01-12 11:44:50,331 - app.clients.bloomberg_client - INFO - Using forced currency: CNY +2026-01-12 11:44:50,331 - app.clients.bloomberg_client - INFO - Fetching Basic Data... +2026-01-12 11:44:50,331 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=59, Msg=Fetching Company Basic Info..., Progress=27% +2026-01-12 11:44:52,345 - app.clients.bloomberg_client - INFO - ✅ Parsed 2 items from remote. +2026-01-12 11:44:53,037 - app.clients.bloomberg_client - INFO - ✅ Saved 2 records to database. +2026-01-12 11:44:53,038 - app.clients.bloomberg_client - INFO - Fetching Currency Data... +2026-01-12 11:44:53,038 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=59, Msg=正在获取货币指标 (CNY)..., Progress=41% +2026-01-12 11:44:54,522 - app.clients.bloomberg_client - INFO - ✅ Parsed 215 items from remote. +2026-01-12 11:45:08,541 - app.clients.bloomberg_client - INFO - ✅ Saved 215 records to database. +2026-01-12 11:45:08,543 - app.clients.bloomberg_client - INFO - Fetching Non-Currency Data... +2026-01-12 11:45:08,543 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=59, Msg=正在获取非货币指标..., Progress=55% +2026-01-12 11:45:09,996 - app.clients.bloomberg_client - INFO - ✅ Parsed 260 items from remote. +2026-01-12 11:45:25,647 - app.clients.bloomberg_client - INFO - ✅ Saved 260 records to database. +2026-01-12 11:45:25,649 - app.clients.bloomberg_client - INFO - Fetching Price Data (Aligned)... +2026-01-12 11:45:25,649 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=59, Msg=正在获取价格指标..., Progress=69% +2026-01-12 11:45:26,793 - app.clients.bloomberg_client - INFO - Found 9 revenue reporting dates. Fetching aligned price data... +2026-01-12 11:45:38,250 - app.clients.bloomberg_client - INFO - ✅ Parsed 27 items from remote. +2026-01-12 11:45:40,155 - app.clients.bloomberg_client - INFO - ✅ Saved 27 records to database. +2026-01-12 11:45:40,156 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=59, Msg=Finalizing data..., Progress=82% +2026-01-12 11:45:40,960 - app.clients.bloomberg_client - INFO - ✅ Cleanup and View Refresh completed. +2026-01-12 11:45:40,960 - app.clients.bloomberg_client - INFO - ✅ Completed processing for 2503 JP Equity +2026-01-12 11:45:40,961 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=59, Msg=Bloomberg data sync complete, Progress=90% +2026-01-12 11:45:41,250 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=59, Msg=Bloomberg 数据同步完成, Progress=100% +2026-01-12 11:46:08,013 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=60, Msg=正在初始化数据获取..., Progress=0% +2026-01-12 11:46:09,230 - app.clients.bloomberg_client - INFO - Connecting to Jupyter at http://192.168.3.161:8888... +2026-01-12 11:46:09,490 - app.clients.bloomberg_client - INFO - ✅ Authentication successful. +2026-01-12 11:46:09,518 - app.clients.bloomberg_client - INFO - ✅ Found existing kernel: bc27f3b1-b028-434a-99fa-c1cad4495a87 (remote_env) +2026-01-12 11:46:10,578 - app.clients.bloomberg_client - INFO - ✅ WebSocket connected. +2026-01-12 11:46:10,579 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=60, Msg=数据源连接成功, Progress=10% +2026-01-12 11:46:10,856 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=60, Msg=正在连接 Bloomberg 终端..., Progress=20% +2026-01-12 11:46:11,445 - app.clients.bloomberg_client - INFO - 🚀 Starting fetch for: 2503 JP Equity +2026-01-12 11:46:11,446 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=60, Msg=Starting Bloomberg session..., Progress=20% +2026-01-12 11:46:12,525 - app.clients.bloomberg_client - INFO - Using forced currency: USD +2026-01-12 11:46:12,525 - app.clients.bloomberg_client - INFO - Fetching Basic Data... +2026-01-12 11:46:12,525 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=60, Msg=Fetching Company Basic Info..., Progress=27% +2026-01-12 11:46:14,513 - app.clients.bloomberg_client - INFO - ✅ Parsed 2 items from remote. +2026-01-12 11:46:15,921 - app.clients.bloomberg_client - INFO - ✅ Saved 2 records to database. +2026-01-12 11:46:15,922 - app.clients.bloomberg_client - INFO - Fetching Currency Data... +2026-01-12 11:46:15,922 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=60, Msg=正在获取货币指标 (USD)..., Progress=41% +2026-01-12 11:46:17,800 - app.clients.bloomberg_client - INFO - ✅ Parsed 215 items from remote. +2026-01-12 11:46:35,038 - app.clients.bloomberg_client - INFO - ✅ Saved 215 records to database. +2026-01-12 11:46:35,039 - app.clients.bloomberg_client - INFO - Fetching Non-Currency Data... +2026-01-12 11:46:35,039 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=60, Msg=正在获取非货币指标..., Progress=55% +2026-01-12 11:46:35,982 - app.clients.bloomberg_client - INFO - ✅ Parsed 260 items from remote. +2026-01-12 11:46:52,433 - app.clients.bloomberg_client - INFO - ✅ Saved 260 records to database. +2026-01-12 11:46:52,440 - app.clients.bloomberg_client - INFO - Fetching Price Data (Aligned)... +2026-01-12 11:46:52,440 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=60, Msg=正在获取价格指标..., Progress=69% +2026-01-12 11:46:53,034 - app.clients.bloomberg_client - INFO - Found 9 revenue reporting dates. Fetching aligned price data... +2026-01-12 11:47:04,398 - app.clients.bloomberg_client - INFO - ✅ Parsed 27 items from remote. +2026-01-12 11:47:07,274 - app.clients.bloomberg_client - INFO - ✅ Saved 27 records to database. +2026-01-12 11:47:07,275 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=60, Msg=Finalizing data..., Progress=82% +2026-01-12 11:47:08,374 - app.clients.bloomberg_client - INFO - ✅ Cleanup and View Refresh completed. +2026-01-12 11:47:08,375 - app.clients.bloomberg_client - INFO - ✅ Completed processing for 2503 JP Equity +2026-01-12 11:47:08,375 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=60, Msg=Bloomberg data sync complete, Progress=90% +2026-01-12 11:47:09,101 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=60, Msg=Bloomberg 数据同步完成, Progress=100% +2026-01-12 11:51:11,068 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=61, Msg=正在初始化数据获取..., Progress=0% +2026-01-12 11:51:11,648 - app.clients.bloomberg_client - INFO - Connecting to Jupyter at http://192.168.3.161:8888... +2026-01-12 11:51:14,081 - app.clients.bloomberg_client - INFO - ✅ Authentication successful. +2026-01-12 11:51:14,108 - app.clients.bloomberg_client - INFO - ✅ Found existing kernel: bc27f3b1-b028-434a-99fa-c1cad4495a87 (remote_env) +2026-01-12 11:51:14,173 - app.clients.bloomberg_client - INFO - ✅ WebSocket connected. +2026-01-12 11:51:14,173 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=61, Msg=数据源连接成功, Progress=10% +2026-01-12 11:51:15,149 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=61, Msg=正在连接 Bloomberg 终端..., Progress=20% +2026-01-12 11:51:16,055 - app.clients.bloomberg_client - INFO - 🚀 Starting fetch for: 2503 JP Equity +2026-01-12 11:51:16,056 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=61, Msg=Starting Bloomberg session..., Progress=20% +2026-01-12 11:51:16,516 - app.clients.bloomberg_client - INFO - Using forced currency: CNY +2026-01-12 11:51:16,516 - app.clients.bloomberg_client - INFO - Fetching Basic Data... +2026-01-12 11:51:16,516 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=61, Msg=Fetching Company Basic Info..., Progress=27% +2026-01-12 11:51:18,000 - app.clients.bloomberg_client - INFO - ✅ Parsed 2 items from remote. +2026-01-12 11:51:20,192 - app.clients.bloomberg_client - INFO - ✅ Saved 2 records to database. +2026-01-12 11:51:20,193 - app.clients.bloomberg_client - INFO - Fetching Currency Data... +2026-01-12 11:51:20,193 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=61, Msg=正在获取货币指标 (CNY)..., Progress=41% +2026-01-12 11:51:21,634 - app.clients.bloomberg_client - INFO - ✅ Parsed 215 items from remote. +2026-01-12 11:51:38,825 - app.clients.bloomberg_client - INFO - ✅ Saved 215 records to database. +2026-01-12 11:51:38,827 - app.clients.bloomberg_client - INFO - Fetching Non-Currency Data... +2026-01-12 11:51:38,827 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=61, Msg=正在获取非货币指标..., Progress=55% +2026-01-12 11:51:39,821 - app.clients.bloomberg_client - INFO - ✅ Parsed 260 items from remote. +2026-01-12 11:51:58,838 - app.clients.bloomberg_client - INFO - ✅ Saved 260 records to database. +2026-01-12 11:51:58,839 - app.clients.bloomberg_client - INFO - Fetching Price Data (Aligned)... +2026-01-12 11:51:58,839 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=61, Msg=正在获取价格指标..., Progress=69% +2026-01-12 11:51:59,168 - app.clients.bloomberg_client - INFO - Fetching aligned price data for 11 dates (Revenue + Calendar Years)... +2026-01-12 11:52:13,001 - app.clients.bloomberg_client - INFO - ✅ Parsed 31 items from remote. +2026-01-12 11:52:15,056 - app.clients.bloomberg_client - INFO - ✅ Saved 31 records to database. +2026-01-12 11:52:15,057 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=61, Msg=Finalizing data..., Progress=82% +2026-01-12 11:52:17,040 - app.clients.bloomberg_client - INFO - ✅ Cleanup and View Refresh completed. +2026-01-12 11:52:17,040 - app.clients.bloomberg_client - INFO - ✅ Completed processing for 2503 JP Equity +2026-01-12 11:52:17,041 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=61, Msg=Bloomberg data sync complete, Progress=90% +2026-01-12 11:52:17,481 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=61, Msg=Bloomberg 数据同步完成, Progress=100% +2026-01-12 12:00:46,984 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=62, Msg=正在初始化数据获取..., Progress=0% +2026-01-12 12:00:47,396 - app.clients.bloomberg_client - INFO - Connecting to Jupyter at http://192.168.3.161:8888... +2026-01-12 12:00:47,788 - app.clients.bloomberg_client - INFO - ✅ Authentication successful. +2026-01-12 12:00:47,817 - app.clients.bloomberg_client - INFO - ✅ Found existing kernel: bc27f3b1-b028-434a-99fa-c1cad4495a87 (remote_env) +2026-01-12 12:00:48,022 - app.clients.bloomberg_client - INFO - ✅ WebSocket connected. +2026-01-12 12:00:48,022 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=62, Msg=数据源连接成功, Progress=10% +2026-01-12 12:00:48,956 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=62, Msg=正在连接 Bloomberg 终端..., Progress=20% +2026-01-12 12:00:50,482 - app.clients.bloomberg_client - INFO - 🚀 Starting fetch for: 2503 JP Equity +2026-01-12 12:00:50,483 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=62, Msg=Starting Bloomberg session..., Progress=20% +2026-01-12 12:00:50,789 - app.clients.bloomberg_client - INFO - Using forced currency: CNY +2026-01-12 12:00:50,789 - app.clients.bloomberg_client - INFO - Fetching Basic Data... +2026-01-12 12:00:50,789 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=62, Msg=Fetching Company Basic Info..., Progress=27% +2026-01-12 12:00:52,248 - app.clients.bloomberg_client - INFO - ✅ Parsed 2 items from remote. +2026-01-12 12:00:53,025 - app.clients.bloomberg_client - INFO - ✅ Saved 2 records to database. +2026-01-12 12:00:53,025 - app.clients.bloomberg_client - INFO - Fetching Currency Data... +2026-01-12 12:00:53,025 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=62, Msg=正在获取货币指标 (CNY)..., Progress=41% +2026-01-12 12:00:53,859 - app.clients.bloomberg_client - INFO - ✅ Parsed 215 items from remote. +2026-01-12 12:01:11,603 - app.clients.bloomberg_client - INFO - ✅ Saved 215 records to database. +2026-01-12 12:01:11,605 - app.clients.bloomberg_client - INFO - Fetching Non-Currency Data... +2026-01-12 12:01:11,605 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=62, Msg=正在获取非货币指标..., Progress=55% +2026-01-12 12:01:13,691 - app.clients.bloomberg_client - INFO - ✅ Parsed 260 items from remote. +2026-01-12 12:01:33,012 - app.clients.bloomberg_client - INFO - ✅ Saved 260 records to database. +2026-01-12 12:01:33,012 - app.clients.bloomberg_client - INFO - Fetching Price Data (Aligned)... +2026-01-12 12:01:33,012 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=62, Msg=正在获取价格指标..., Progress=69% +2026-01-12 12:01:33,424 - app.clients.bloomberg_client - INFO - Found 9 revenue reporting dates. Fetching aligned price data... +2026-01-12 12:01:44,341 - app.clients.bloomberg_client - INFO - ✅ Parsed 27 items from remote. +2026-01-12 12:01:46,319 - app.clients.bloomberg_client - INFO - ✅ Saved 27 records to database. +2026-01-12 12:01:46,320 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=62, Msg=Finalizing data..., Progress=82% +2026-01-12 12:01:47,279 - app.clients.bloomberg_client - INFO - ✅ Cleanup and View Refresh completed. +2026-01-12 12:01:47,280 - app.clients.bloomberg_client - INFO - ✅ Completed processing for 2503 JP Equity +2026-01-12 12:01:47,280 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=62, Msg=Bloomberg data sync complete, Progress=90% +2026-01-12 12:01:48,004 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=62, Msg=Bloomberg 数据同步完成, Progress=100% +2026-01-12 12:03:53,293 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=63, Msg=正在初始化数据获取..., Progress=0% +2026-01-12 12:03:54,343 - app.clients.bloomberg_client - INFO - Connecting to Jupyter at http://192.168.3.161:8888... +2026-01-12 12:03:54,619 - app.clients.bloomberg_client - INFO - ✅ Authentication successful. +2026-01-12 12:03:54,647 - app.clients.bloomberg_client - INFO - ✅ Found existing kernel: bc27f3b1-b028-434a-99fa-c1cad4495a87 (remote_env) +2026-01-12 12:03:54,699 - app.clients.bloomberg_client - INFO - ✅ WebSocket connected. +2026-01-12 12:03:54,699 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=63, Msg=数据源连接成功, Progress=10% +2026-01-12 12:03:55,171 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=63, Msg=正在连接 Bloomberg 终端..., Progress=20% +2026-01-12 12:03:55,838 - app.clients.bloomberg_client - INFO - 🚀 Starting fetch for: 2503 JP Equity +2026-01-12 12:03:55,839 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=63, Msg=Starting Bloomberg session..., Progress=20% +2026-01-12 12:03:56,708 - app.clients.bloomberg_client - INFO - Using forced currency: CNY +2026-01-12 12:03:56,709 - app.clients.bloomberg_client - INFO - Fetching Basic Data... +2026-01-12 12:03:56,709 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=63, Msg=Fetching Company Basic Info..., Progress=27% +2026-01-12 12:03:58,922 - app.clients.bloomberg_client - INFO - ✅ Parsed 2 items from remote. +2026-01-12 12:04:01,068 - app.clients.bloomberg_client - INFO - ✅ Saved 2 records to database. +2026-01-12 12:04:01,069 - app.clients.bloomberg_client - INFO - Fetching Currency Data... +2026-01-12 12:04:01,069 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=63, Msg=正在获取货币指标 (CNY)..., Progress=41% +2026-01-12 12:04:02,937 - app.clients.bloomberg_client - INFO - ✅ Parsed 215 items from remote. +2026-01-12 12:04:16,817 - app.clients.bloomberg_client - INFO - ✅ Saved 215 records to database. +2026-01-12 12:04:16,818 - app.clients.bloomberg_client - INFO - Fetching Non-Currency Data... +2026-01-12 12:04:16,819 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=63, Msg=正在获取非货币指标..., Progress=55% +2026-01-12 12:04:19,637 - app.clients.bloomberg_client - INFO - ✅ Parsed 260 items from remote. +2026-01-12 12:04:40,482 - app.clients.bloomberg_client - INFO - ✅ Saved 260 records to database. +2026-01-12 12:04:40,482 - app.clients.bloomberg_client - INFO - Fetching Price Data (Aligned)... +2026-01-12 12:04:40,482 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=63, Msg=正在获取价格指标..., Progress=69% +2026-01-12 12:04:41,016 - app.clients.bloomberg_client - INFO - Found 9 revenue reporting dates. Fetching aligned price data... +2026-01-12 12:04:53,208 - app.clients.bloomberg_client - INFO - ✅ Parsed 27 items from remote. +2026-01-12 12:04:53,210 - app.clients.bloomberg_client - INFO - 💾 [DEBUG] Saving Market_Cap: Date=2024-12-31, Value=86988.3177, Currency=CNY +2026-01-12 12:04:53,210 - app.clients.bloomberg_client - INFO - 💾 [DEBUG] Saving Market_Cap: Date=2023-12-31, Value=95209.9289, Currency=CNY +2026-01-12 12:04:53,211 - app.clients.bloomberg_client - INFO - 💾 [DEBUG] Saving Market_Cap: Date=2022-12-31, Value=96786.4997, Currency=CNY +2026-01-12 12:04:53,211 - app.clients.bloomberg_client - INFO - 💾 [DEBUG] Saving Market_Cap: Date=2021-12-31, Value=93410.0414, Currency=CNY +2026-01-12 12:04:53,211 - app.clients.bloomberg_client - INFO - 💾 [DEBUG] Saving Market_Cap: Date=2020-12-31, Value=140556.4302, Currency=CNY +2026-01-12 12:04:53,211 - app.clients.bloomberg_client - INFO - 💾 [DEBUG] Saving Market_Cap: Date=2019-12-31, Value=140163.3311, Currency=CNY +2026-01-12 12:04:53,211 - app.clients.bloomberg_client - INFO - 💾 [DEBUG] Saving Market_Cap: Date=2018-12-31, Value=130875.1203, Currency=CNY +2026-01-12 12:04:53,211 - app.clients.bloomberg_client - INFO - 💾 [DEBUG] Saving Market_Cap: Date=2017-12-31, Value=150051.5647, Currency=CNY +2026-01-12 12:04:53,211 - app.clients.bloomberg_client - INFO - 💾 [DEBUG] Saving Market_Cap: Date=2016-12-31, Value=103403.6124, Currency=CNY +2026-01-12 12:04:58,064 - app.clients.bloomberg_client - INFO - ✅ Saved 27 records to database. +2026-01-12 12:04:58,064 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=63, Msg=Finalizing data..., Progress=82% +2026-01-12 12:05:01,647 - app.clients.bloomberg_client - INFO - ✅ Cleanup and View Refresh completed. +2026-01-12 12:05:01,647 - app.clients.bloomberg_client - INFO - ✅ Completed processing for 2503 JP Equity +2026-01-12 12:05:01,648 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=63, Msg=Bloomberg data sync complete, Progress=90% +2026-01-12 12:05:01,910 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=63, Msg=Bloomberg 数据同步完成, Progress=100% +2026-01-12 12:09:12,429 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=64, Msg=正在初始化数据获取..., Progress=0% +2026-01-12 12:09:12,942 - app.clients.bloomberg_client - INFO - Connecting to Jupyter at http://192.168.3.161:8888... +2026-01-12 12:09:14,418 - app.clients.bloomberg_client - INFO - ✅ Authentication successful. +2026-01-12 12:09:14,447 - app.clients.bloomberg_client - INFO - ✅ Found existing kernel: bc27f3b1-b028-434a-99fa-c1cad4495a87 (remote_env) +2026-01-12 12:09:14,497 - app.clients.bloomberg_client - INFO - ✅ WebSocket connected. +2026-01-12 12:09:14,498 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=64, Msg=数据源连接成功, Progress=10% +2026-01-12 12:09:15,071 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=64, Msg=正在连接 Bloomberg 终端..., Progress=20% +2026-01-12 12:09:15,661 - app.clients.bloomberg_client - INFO - 🚀 Starting fetch for: 2503 JP Equity +2026-01-12 12:09:15,661 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=64, Msg=Starting Bloomberg session..., Progress=20% +2026-01-12 12:09:16,492 - app.clients.bloomberg_client - INFO - Using forced currency: CNY +2026-01-12 12:09:16,495 - app.clients.bloomberg_client - INFO - Fetching Basic Data... +2026-01-12 12:09:16,495 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=64, Msg=Fetching Company Basic Info..., Progress=27% +2026-01-12 12:09:18,548 - app.clients.bloomberg_client - INFO - ✅ Parsed 2 items from remote. +2026-01-12 12:09:20,215 - app.clients.bloomberg_client - INFO - ✅ Saved 2 records to database. +2026-01-12 12:09:20,215 - app.clients.bloomberg_client - INFO - Fetching Currency Data... +2026-01-12 12:09:20,215 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=64, Msg=正在获取货币指标 (CNY)..., Progress=41% +2026-01-12 12:09:21,781 - app.clients.bloomberg_client - INFO - ✅ Parsed 215 items from remote. +2026-01-12 12:09:40,266 - app.clients.bloomberg_client - INFO - ✅ Saved 215 records to database. +2026-01-12 12:09:40,268 - app.clients.bloomberg_client - INFO - Fetching Non-Currency Data... +2026-01-12 12:09:40,269 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=64, Msg=正在获取非货币指标..., Progress=55% +2026-01-12 12:09:41,884 - app.clients.bloomberg_client - INFO - ✅ Parsed 260 items from remote. +2026-01-12 12:10:05,761 - app.clients.bloomberg_client - INFO - ✅ Saved 260 records to database. +2026-01-12 12:10:05,766 - app.clients.bloomberg_client - INFO - Fetching Price Data (Aligned)... +2026-01-12 12:10:05,766 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=64, Msg=正在获取价格指标..., Progress=69% +2026-01-12 12:10:07,309 - app.clients.bloomberg_client - INFO - Found 9 revenue reporting dates. Fetching aligned price data... +2026-01-12 12:10:17,887 - app.clients.bloomberg_client - INFO - ✅ Parsed 27 items from remote. +2026-01-12 12:10:17,887 - app.clients.bloomberg_client - INFO - 💾 [DEBUG] Saving Market_Cap: Date=2024-12-31, Value=86988.3177, Currency=CNY +2026-01-12 12:10:17,887 - app.clients.bloomberg_client - INFO - 💾 [DEBUG] Saving Market_Cap: Date=2023-12-31, Value=95209.9289, Currency=CNY +2026-01-12 12:10:17,887 - app.clients.bloomberg_client - INFO - 💾 [DEBUG] Saving Market_Cap: Date=2022-12-31, Value=96786.4997, Currency=CNY +2026-01-12 12:10:17,887 - app.clients.bloomberg_client - INFO - 💾 [DEBUG] Saving Market_Cap: Date=2021-12-31, Value=93410.0414, Currency=CNY +2026-01-12 12:10:17,887 - app.clients.bloomberg_client - INFO - 💾 [DEBUG] Saving Market_Cap: Date=2020-12-31, Value=140556.4302, Currency=CNY +2026-01-12 12:10:17,887 - app.clients.bloomberg_client - INFO - 💾 [DEBUG] Saving Market_Cap: Date=2019-12-31, Value=140163.3311, Currency=CNY +2026-01-12 12:10:17,887 - app.clients.bloomberg_client - INFO - 💾 [DEBUG] Saving Market_Cap: Date=2018-12-31, Value=130875.1203, Currency=CNY +2026-01-12 12:10:17,887 - app.clients.bloomberg_client - INFO - 💾 [DEBUG] Saving Market_Cap: Date=2017-12-31, Value=150051.5647, Currency=CNY +2026-01-12 12:10:17,887 - app.clients.bloomberg_client - INFO - 💾 [DEBUG] Saving Market_Cap: Date=2016-12-31, Value=103403.6124, Currency=CNY +2026-01-12 12:10:21,706 - app.clients.bloomberg_client - INFO - ✅ Saved 27 records to database. +2026-01-12 12:10:21,708 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=64, Msg=Finalizing data..., Progress=82% +2026-01-12 12:10:25,944 - app.clients.bloomberg_client - INFO - ✅ Cleanup and View Refresh completed. +2026-01-12 12:10:25,945 - app.clients.bloomberg_client - INFO - ✅ Completed processing for 2503 JP Equity +2026-01-12 12:10:25,945 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=64, Msg=Bloomberg data sync complete, Progress=90% +2026-01-12 12:10:26,424 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=64, Msg=Bloomberg 数据同步完成, Progress=100% +2026-01-12 12:17:20,087 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=65, Msg=正在初始化数据获取..., Progress=0% +2026-01-12 12:17:21,105 - app.clients.bloomberg_client - INFO - Connecting to Jupyter at http://192.168.3.161:8888... +2026-01-12 12:17:22,164 - app.clients.bloomberg_client - INFO - ✅ Authentication successful. +2026-01-12 12:17:22,194 - app.clients.bloomberg_client - INFO - ✅ Found existing kernel: bc27f3b1-b028-434a-99fa-c1cad4495a87 (remote_env) +2026-01-12 12:17:22,251 - app.clients.bloomberg_client - INFO - ✅ WebSocket connected. +2026-01-12 12:17:22,251 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=65, Msg=数据源连接成功, Progress=10% +2026-01-12 12:17:23,267 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=65, Msg=正在连接 Bloomberg 终端..., Progress=20% +2026-01-12 12:17:23,545 - app.clients.bloomberg_client - INFO - 🚀 Starting fetch for: 2503 JP Equity +2026-01-12 12:17:23,545 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=65, Msg=Starting Bloomberg session..., Progress=20% +2026-01-12 12:17:25,394 - app.clients.bloomberg_client - INFO - Using forced currency: CNY +2026-01-12 12:17:25,395 - app.clients.bloomberg_client - INFO - Fetching Basic Data... +2026-01-12 12:17:25,395 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=65, Msg=Fetching Company Basic Info..., Progress=27% +2026-01-12 12:17:27,481 - app.clients.bloomberg_client - INFO - ✅ Parsed 2 items from remote. +2026-01-12 12:17:27,481 - app.clients.bloomberg_client - INFO - DEBUG: basic_data before save: [{'Company_code': '2503 JP Equity', 'update_date': '2026-01-12', 'currency': 'CNY', 'indicator': 'dividend_yield', 'value': '3.1230217345431526', 'value_date': '2026-01-12'}, {'Company_code': '2503 JP Equity', 'update_date': '2026-01-12', 'currency': 'CNY', 'indicator': 'IPO_date', 'value': 'None', 'value_date': '2026-01-12'}] +2026-01-12 12:17:29,452 - app.clients.bloomberg_client - INFO - ✅ Saved 2 records to database. +2026-01-12 12:17:29,452 - app.clients.bloomberg_client - INFO - Fetching Currency Data... +2026-01-12 12:17:29,452 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=65, Msg=正在获取货币指标 (CNY)..., Progress=41% +2026-01-12 12:17:31,460 - app.clients.bloomberg_client - INFO - ✅ Parsed 215 items from remote. +2026-01-12 12:17:52,620 - app.clients.bloomberg_client - INFO - ✅ Saved 215 records to database. +2026-01-12 12:17:52,623 - app.clients.bloomberg_client - INFO - Fetching Non-Currency Data... +2026-01-12 12:17:52,623 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=65, Msg=正在获取非货币指标..., Progress=55% +2026-01-12 12:17:54,783 - app.clients.bloomberg_client - INFO - ✅ Parsed 260 items from remote. +2026-01-12 12:18:31,861 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=66, Msg=正在初始化数据获取..., Progress=0% +2026-01-12 12:18:33,349 - app.clients.bloomberg_client - INFO - Connecting to Jupyter at http://192.168.3.161:8888... +2026-01-12 12:18:34,339 - app.clients.bloomberg_client - INFO - ✅ Authentication successful. +2026-01-12 12:18:34,372 - app.clients.bloomberg_client - INFO - ✅ Found existing kernel: bc27f3b1-b028-434a-99fa-c1cad4495a87 (remote_env) +2026-01-12 12:18:34,432 - app.clients.bloomberg_client - INFO - ✅ WebSocket connected. +2026-01-12 12:18:34,432 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=66, Msg=数据源连接成功, Progress=10% +2026-01-12 12:18:35,690 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=66, Msg=正在连接 Bloomberg 终端..., Progress=20% +2026-01-12 12:18:36,255 - app.clients.bloomberg_client - INFO - 🚀 Starting fetch for: 2503 JP Equity +2026-01-12 12:18:36,256 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=66, Msg=Starting Bloomberg session..., Progress=20% +2026-01-12 12:18:38,442 - app.clients.bloomberg_client - INFO - Using forced currency: CNY +2026-01-12 12:18:38,443 - app.clients.bloomberg_client - INFO - Fetching Basic Data... +2026-01-12 12:18:38,443 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=66, Msg=Fetching Company Basic Info..., Progress=27% +2026-01-12 12:18:40,961 - app.clients.bloomberg_client - INFO - ✅ Parsed 2 items from remote. +2026-01-12 12:18:40,961 - app.clients.bloomberg_client - INFO - DEBUG: basic_data before save: [{'Company_code': '2503 JP Equity', 'update_date': '2026-01-12 12:18:41', 'currency': 'CNY', 'indicator': 'dividend_yield', 'value': '3.1230217345431526', 'value_date': '2026-01-12 12:18:41'}, {'Company_code': '2503 JP Equity', 'update_date': '2026-01-12 12:18:41', 'currency': 'CNY', 'indicator': 'IPO_date', 'value': 'None', 'value_date': '2026-01-12 12:18:41'}] +2026-01-12 12:18:42,433 - app.clients.bloomberg_client - INFO - ✅ Saved 2 records to database. +2026-01-12 12:18:42,434 - app.clients.bloomberg_client - INFO - Fetching Currency Data... +2026-01-12 12:18:42,434 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=66, Msg=正在获取货币指标 (CNY)..., Progress=41% +2026-01-12 12:18:44,354 - app.clients.bloomberg_client - INFO - ✅ Parsed 215 items from remote. +2026-01-12 12:19:05,814 - app.clients.bloomberg_client - INFO - ✅ Saved 215 records to database. +2026-01-12 12:19:05,819 - app.clients.bloomberg_client - INFO - Fetching Non-Currency Data... +2026-01-12 12:19:05,820 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=66, Msg=正在获取非货币指标..., Progress=55% +2026-01-12 12:19:07,418 - app.clients.bloomberg_client - INFO - ✅ Parsed 260 items from remote. +2026-01-12 12:19:27,370 - app.clients.bloomberg_client - INFO - ✅ Saved 260 records to database. +2026-01-12 12:19:27,371 - app.clients.bloomberg_client - INFO - Fetching Price Data (Aligned)... +2026-01-12 12:19:27,371 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=66, Msg=正在获取价格指标..., Progress=69% +2026-01-12 12:19:28,080 - app.clients.bloomberg_client - INFO - Found 9 revenue reporting dates. Fetching aligned price data... +2026-01-12 12:19:39,293 - app.clients.bloomberg_client - INFO - ✅ Parsed 27 items from remote. +2026-01-12 12:19:43,961 - app.clients.bloomberg_client - INFO - ✅ Saved 27 records to database. +2026-01-12 12:19:43,962 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=66, Msg=Finalizing data..., Progress=82% +2026-01-12 12:19:45,511 - app.clients.bloomberg_client - INFO - ✅ Cleanup and View Refresh completed. +2026-01-12 12:19:45,512 - app.clients.bloomberg_client - INFO - ✅ Completed processing for 2503 JP Equity +2026-01-12 12:19:45,512 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=66, Msg=Bloomberg data sync complete, Progress=90% +2026-01-12 12:19:47,693 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=66, Msg=Bloomberg 数据同步完成, Progress=100% +2026-01-12 13:39:22,650 - app.main - INFO - 🔍 [搜索] 开始搜索股票: 三一国际 +2026-01-12 13:39:22,724 - app.main - INFO - 🤖 [搜索-LLM] 调用 gemini-2.5-flash 进行股票搜索 +2026-01-12 13:39:22,724 - google_genai.models - INFO - AFC is enabled with max remote calls: 10. +2026-01-12 13:39:27,383 - httpx - INFO - HTTP Request: POST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent "HTTP/1.1 200 OK" +2026-01-12 13:39:27,390 - app.main - INFO - ✅ [搜索-LLM] 模型响应完成, 耗时: 4.67秒, Tokens: prompt=166, completion=78, total=244 +2026-01-12 13:39:27,391 - app.main - INFO - ✅ [搜索] 搜索完成, 找到 1 个结果, 总耗时: 4.74秒 +2026-01-12 13:39:35,605 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=67, Msg=正在初始化数据获取..., Progress=0% +2026-01-12 13:39:36,193 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=67, Msg=数据获取失败: invalid syntax. Perhaps you forgot a comma? (bloomberg_client.py, line 587), Progress=0% +2026-01-12 13:54:13,489 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=68, Msg=正在初始化数据获取..., Progress=0% +2026-01-12 13:54:13,853 - app.clients.bloomberg_client - INFO - Connecting to Jupyter at http://192.168.3.161:8888... +2026-01-12 13:54:14,191 - app.clients.bloomberg_client - INFO - ✅ Authentication successful. +2026-01-12 13:54:14,229 - app.clients.bloomberg_client - INFO - ✅ Found existing kernel: bc27f3b1-b028-434a-99fa-c1cad4495a87 (remote_env) +2026-01-12 13:54:14,427 - app.clients.bloomberg_client - INFO - ✅ WebSocket connected. +2026-01-12 13:54:14,428 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=68, Msg=数据源连接成功, Progress=10% +2026-01-12 13:54:14,824 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=68, Msg=正在连接 Bloomberg 终端..., Progress=20% +2026-01-12 13:54:15,384 - app.clients.bloomberg_client - INFO - 🚀 Starting fetch for: 00631 HK Equity +2026-01-12 13:54:15,385 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=68, Msg=Starting Bloomberg session..., Progress=20% +2026-01-12 13:54:15,833 - app.clients.bloomberg_client - INFO - Using auto-detected currency: HKD +2026-01-12 13:54:15,834 - app.clients.bloomberg_client - INFO - Fetching Basic Data... +2026-01-12 13:54:15,834 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=68, Msg=Fetching Company Basic Info..., Progress=27% +2026-01-12 13:54:16,597 - app.clients.bloomberg_client - INFO - ✅ Parsed 0 items from remote. +2026-01-12 13:54:16,597 - app.clients.bloomberg_client - INFO - DEBUG: basic_data before save: [] +2026-01-12 13:54:16,597 - app.clients.bloomberg_client - INFO - Fetching Currency Data... +2026-01-12 13:54:16,597 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=68, Msg=正在获取货币指标 (HKD)..., Progress=41% +2026-01-12 13:54:17,282 - app.clients.bloomberg_client - INFO - ✅ Parsed 0 items from remote. +2026-01-12 13:54:17,283 - app.clients.bloomberg_client - INFO - Fetching Non-Currency Data... +2026-01-12 13:54:17,284 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=68, Msg=正在获取非货币指标..., Progress=55% +2026-01-12 13:54:18,408 - app.clients.bloomberg_client - INFO - ✅ Parsed 0 items from remote. +2026-01-12 13:54:18,408 - app.clients.bloomberg_client - INFO - Fetching Price Data (Aligned)... +2026-01-12 13:54:18,408 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=68, Msg=正在获取价格指标..., Progress=69% +2026-01-12 13:54:18,668 - app.clients.bloomberg_client - WARNING - No revenue dates found. Falling back to yearly price fetch. +2026-01-12 13:54:18,986 - app.clients.bloomberg_client - INFO - ✅ Parsed 0 items from remote. +2026-01-12 13:54:18,986 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=68, Msg=Finalizing data..., Progress=82% +2026-01-12 13:54:20,042 - app.clients.bloomberg_client - INFO - ✅ Cleanup and View Refresh completed. +2026-01-12 13:54:20,042 - app.clients.bloomberg_client - INFO - ✅ Completed processing for 00631 HK Equity +2026-01-12 13:54:20,043 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=68, Msg=Bloomberg data sync complete, Progress=90% +2026-01-12 13:54:20,603 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=68, Msg=Bloomberg 数据同步完成, Progress=100% +2026-01-12 13:54:24,013 - app.services.bloomberg_service - WARNING - No Bloomberg data found for symbol: 00631 +2026-01-12 13:54:24,293 - app.services.bloomberg_service - WARNING - No Bloomberg data found for symbol: 00631 +2026-01-12 14:10:53,933 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=69, Msg=正在初始化数据获取..., Progress=0% +2026-01-12 14:10:54,645 - app.clients.bloomberg_client - INFO - Connecting to Jupyter at http://192.168.3.161:8888... +2026-01-12 14:10:55,044 - app.clients.bloomberg_client - INFO - ✅ Authentication successful. +2026-01-12 14:10:55,071 - app.clients.bloomberg_client - INFO - ✅ Found existing kernel: bc27f3b1-b028-434a-99fa-c1cad4495a87 (remote_env) +2026-01-12 14:10:55,123 - app.clients.bloomberg_client - INFO - ✅ WebSocket connected. +2026-01-12 14:10:55,124 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=69, Msg=数据源连接成功, Progress=10% +2026-01-12 14:10:55,677 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=69, Msg=正在连接 Bloomberg 终端..., Progress=20% +2026-01-12 14:10:55,939 - app.clients.bloomberg_client - INFO - 🚀 Starting fetch for: 631 HK Equity +2026-01-12 14:10:55,939 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=69, Msg=Starting Bloomberg session..., Progress=20% +2026-01-12 14:10:56,480 - app.clients.bloomberg_client - INFO - Using auto-detected currency: HKD +2026-01-12 14:10:56,481 - app.clients.bloomberg_client - INFO - Fetching Basic Data... +2026-01-12 14:10:56,481 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=69, Msg=Fetching Company Basic Info..., Progress=27% +2026-01-12 14:10:57,704 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "631 HK Equity", "update_date": "2026-01-12 14:10:58", "currency": "HKD", "indicator": "company_name", "value": "SANY HEAVY EQUIPMENT INTL", "value_date": "2026-01-12 14:10:58"}, {"Company_code": "631 HK Equity", "update_date": "2026-01-12 14:10:58", "currency": "HKD", "indicator": "pe_ratio", "value": "19.98882739476631", "value_date": "2026-01-12 14:10:58"}, {"Company_code": "631 HK Equity", "update_date": "2026-01-12 14:10:58", "currency": "HKD", "indicator": "pb_ratio", "value": "2.116312093386662", "value_date": "2026-01-12 14:10:58"}, {"Company_code": "631 HK Equity", "update_date": "2026-01-12 14:10:58", "currency": "HKD", "indicator": "market_cap", "value": "29705920767.51", "value_date": "2026-01-12 14:10:58"}, {"Company_code": "631 HK Equity", "update_date": "2026-01-12 14:10:58", "currency": "HKD", "indicator": "Rev_Abroad", "value": "37.287945521334656", "value_date": "2026-01-12 14:10:58"}, {"Company_code": "631 HK Equity", "update_date": "2026 +2026-01-12 14:10:57,705 - app.clients.bloomberg_client - INFO - ✅ Parsed 7 items from remote. +2026-01-12 14:10:57,705 - app.clients.bloomberg_client - INFO - DEBUG: basic_data before save: [{'Company_code': '631 HK Equity', 'update_date': '2026-01-12 14:10:58', 'currency': 'HKD', 'indicator': 'company_name', 'value': 'SANY HEAVY EQUIPMENT INTL', 'value_date': '2026-01-12 14:10:58'}, {'Company_code': '631 HK Equity', 'update_date': '2026-01-12 14:10:58', 'currency': 'HKD', 'indicator': 'pe_ratio', 'value': '19.98882739476631', 'value_date': '2026-01-12 14:10:58'}, {'Company_code': '631 HK Equity', 'update_date': '2026-01-12 14:10:58', 'currency': 'HKD', 'indicator': 'pb_ratio', 'value': '2.116312093386662', 'value_date': '2026-01-12 14:10:58'}, {'Company_code': '631 HK Equity', 'update_date': '2026-01-12 14:10:58', 'currency': 'HKD', 'indicator': 'market_cap', 'value': '29705920767.51', 'value_date': '2026-01-12 14:10:58'}, {'Company_code': '631 HK Equity', 'update_date': '2026-01-12 14:10:58', 'currency': 'HKD', 'indicator': 'Rev_Abroad', 'value': '37.287945521334656', 'value_date': '2026-01-12 14:10:58'}, {'Company_code': '631 HK Equity', 'update_date': '2026-01-12 14:10:58', 'currency': 'HKD', 'indicator': 'dividend_yield', 'value': '3.1556038264999975', 'value_date': '2026-01-12 14:10:58'}, {'Company_code': '631 HK Equity', 'update_date': '2026-01-12 14:10:58', 'currency': 'HKD', 'indicator': 'IPO_date', 'value': '2009-11-25', 'value_date': '2026-01-12 14:10:58'}] +2026-01-12 14:10:58,534 - app.clients.bloomberg_client - INFO - ✅ Saved 7 records to database. +2026-01-12 14:10:58,534 - app.clients.bloomberg_client - INFO - Fetching Currency Data... +2026-01-12 14:10:58,534 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=69, Msg=正在获取货币指标 (HKD)..., Progress=41% +2026-01-12 14:10:59,715 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "631 HK Equity", "update_date": "2026-01-12 14:10:58", "currency": "HKD", "indicator": "Revenue", "value": "2152.9812", "value_date": "2016-12-31"}, {"Company_code": "631 HK Equity", "update_date": "2026-01-12 14:10:58", "currency": "HKD", "indicator": "Net_Income", "value": "-753.2314", "value_date": "2016-12-31"}, {"Company_code": "631 HK Equity", "update_date": "2026-01-12 14:10:58", "currency": "HKD", "indicator": "Cash_From_Operating", "value": "1557.419", "value_date": "2016-12-31"}, {"Company_code": "631 HK Equity", "update_date": "2026-01-12 14:10:58", "currency": "HKD", "indicator": "Capital_Expenditure", "value": "-179.3705", "value_date": "2016-12-31"}, {"Company_code": "631 HK Equity", "update_date": "2026-01-12 14:10:58", "currency": "HKD", "indicator": "Free_Cash_Flow", "value": "1378.0485", "value_date": "2016-12-31"}, {"Company_code": "631 HK Equity", "update_date": "2026-01-12 14:10:58", "currency": "HKD", "indicator": "Dividends_Paid", "va +2026-01-12 14:10:59,715 - app.clients.bloomberg_client - INFO - ✅ Parsed 216 items from remote. +2026-01-12 14:11:12,684 - app.clients.bloomberg_client - INFO - ✅ Saved 216 records to database. +2026-01-12 14:11:12,686 - app.clients.bloomberg_client - INFO - Fetching Non-Currency Data... +2026-01-12 14:11:12,686 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=69, Msg=正在获取非货币指标..., Progress=55% +2026-01-12 14:11:13,789 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "631 HK Equity", "update_date": "2026-01-12 14:11:12", "currency": "HKD", "indicator": "PE", "value": "111.1384", "value_date": "2016-12-30"}, {"Company_code": "631 HK Equity", "update_date": "2026-01-12 14:11:12", "currency": "HKD", "indicator": "PB", "value": "0.5588", "value_date": "2016-12-30"}, {"Company_code": "631 HK Equity", "update_date": "2026-01-12 14:11:12", "currency": "HKD", "indicator": "ROE", "value": "-10.132", "value_date": "2016-12-31"}, {"Company_code": "631 HK Equity", "update_date": "2026-01-12 14:11:12", "currency": "HKD", "indicator": "ROA", "value": "-6.0025", "value_date": "2016-12-31"}, {"Company_code": "631 HK Equity", "update_date": "2026-01-12 14:11:12", "currency": "HKD", "indicator": "Gross_Margin", "value": "14.994", "value_date": "2016-12-31"}, {"Company_code": "631 HK Equity", "update_date": "2026-01-12 14:11:12", "currency": "HKD", "indicator": "EBITDA_margin", "value": "-28.2708", "value_date": "2016-12-31"}, {"Company_c +2026-01-12 14:11:13,790 - app.clients.bloomberg_client - INFO - ✅ Parsed 219 items from remote. +2026-01-12 14:11:26,690 - app.clients.bloomberg_client - INFO - ✅ Saved 219 records to database. +2026-01-12 14:11:26,692 - app.clients.bloomberg_client - INFO - Fetching Price Data (Aligned)... +2026-01-12 14:11:26,692 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=69, Msg=正在获取价格指标..., Progress=69% +2026-01-12 14:11:26,975 - app.clients.bloomberg_client - INFO - Found 9 revenue reporting dates. Fetching aligned price data... +2026-01-12 14:11:37,480 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "631 HK Equity", "update_date": "2026-01-12 14:11:26", "currency": "HKD", "indicator": "Last_Price", "value": "4.51", "value_date": "2024-12-31"}, {"Company_code": "631 HK Equity", "update_date": "2026-01-12 14:11:26", "currency": "HKD", "indicator": "Market_Cap", "value": "14494.6462", "value_date": "2024-12-31"}, {"Company_code": "631 HK Equity", "update_date": "2026-01-12 14:11:26", "currency": "HKD", "indicator": "Dividend_Yield", "value": "4.2129", "value_date": "2024-12-31"}, {"Company_code": "631 HK Equity", "update_date": "2026-01-12 14:11:26", "currency": "HKD", "indicator": "Last_Price", "value": "7.55", "value_date": "2023-12-31"}, {"Company_code": "631 HK Equity", "update_date": "2026-01-12 14:11:26", "currency": "HKD", "indicator": "Market_Cap", "value": "24081.9354", "value_date": "2023-12-31"}, {"Company_code": "631 HK Equity", "update_date": "2026-01-12 14:11:26", "currency": "HKD", "indicator": "Dividend_Yield", "value": "2.5166", "value_da +2026-01-12 14:11:37,481 - app.clients.bloomberg_client - INFO - ✅ Parsed 25 items from remote. +2026-01-12 14:11:39,102 - app.clients.bloomberg_client - INFO - ✅ Saved 25 records to database. +2026-01-12 14:11:39,103 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=69, Msg=Finalizing data..., Progress=82% +2026-01-12 14:11:40,554 - app.clients.bloomberg_client - INFO - ✅ Cleanup and View Refresh completed. +2026-01-12 14:11:40,555 - app.clients.bloomberg_client - INFO - ✅ Completed processing for 631 HK Equity +2026-01-12 14:11:40,555 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=69, Msg=Bloomberg data sync complete, Progress=90% +2026-01-12 14:11:40,933 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=69, Msg=Bloomberg 数据同步完成, Progress=100% +2026-01-12 14:11:46,320 - app.services.bloomberg_service - WARNING - No Bloomberg data found for symbol: 00631 +2026-01-12 14:12:08,829 - app.services.bloomberg_service - WARNING - No Bloomberg data found for symbol: 00631 +2026-01-12 14:15:51,872 - app.services.bloomberg_service - WARNING - No Bloomberg data found for symbol: 00631 +2026-01-12 14:22:58,914 - app.services.bloomberg_service - WARNING - No Bloomberg data found for symbol: 00631 +2026-01-12 14:23:02,681 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=70, Msg=正在初始化数据获取..., Progress=0% +2026-01-12 14:23:03,405 - app.clients.bloomberg_client - INFO - Connecting to Jupyter at http://192.168.3.161:8888... +2026-01-12 14:23:03,673 - app.clients.bloomberg_client - INFO - ✅ Authentication successful. +2026-01-12 14:23:03,717 - app.clients.bloomberg_client - INFO - ✅ Found existing kernel: bc27f3b1-b028-434a-99fa-c1cad4495a87 (remote_env) +2026-01-12 14:23:03,914 - app.clients.bloomberg_client - INFO - ✅ WebSocket connected. +2026-01-12 14:23:03,914 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=70, Msg=数据源连接成功, Progress=10% +2026-01-12 14:23:04,185 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=70, Msg=正在连接 Bloomberg 终端..., Progress=20% +2026-01-12 14:23:04,628 - app.clients.bloomberg_client - INFO - 🚀 Starting fetch for: 00631 HK Equity +2026-01-12 14:23:04,628 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=70, Msg=Starting Bloomberg session..., Progress=20% +2026-01-12 14:23:05,408 - app.clients.bloomberg_client - INFO - Using auto-detected currency: HKD +2026-01-12 14:23:05,408 - app.clients.bloomberg_client - INFO - Fetching Basic Data... +2026-01-12 14:23:05,408 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=70, Msg=Fetching Company Basic Info..., Progress=27% +2026-01-12 14:23:06,372 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:23:06", "currency": "HKD", "indicator": "company_name", "value": "SANY HEAVY EQUIPMENT INTL", "value_date": "2026-01-12 14:23:06"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:23:06", "currency": "HKD", "indicator": "pe_ratio", "value": "20.052832333683007", "value_date": "2026-01-12 14:23:06"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:23:06", "currency": "HKD", "indicator": "pb_ratio", "value": "2.1230886002617653", "value_date": "2026-01-12 14:23:06"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:23:06", "currency": "HKD", "indicator": "market_cap", "value": "29802893305.38", "value_date": "2026-01-12 14:23:06"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:23:06", "currency": "HKD", "indicator": "Rev_Abroad", "value": "37.287945521334656", "value_date": "2026-01-12 14:23:06"}, {"Company_code": "00631 HK Equity", "updat +2026-01-12 14:23:06,373 - app.clients.bloomberg_client - INFO - ✅ Parsed 7 items from remote. +2026-01-12 14:23:06,373 - app.clients.bloomberg_client - INFO - DEBUG: basic_data before save: [{'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:23:06', 'currency': 'HKD', 'indicator': 'company_name', 'value': 'SANY HEAVY EQUIPMENT INTL', 'value_date': '2026-01-12 14:23:06'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:23:06', 'currency': 'HKD', 'indicator': 'pe_ratio', 'value': '20.052832333683007', 'value_date': '2026-01-12 14:23:06'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:23:06', 'currency': 'HKD', 'indicator': 'pb_ratio', 'value': '2.1230886002617653', 'value_date': '2026-01-12 14:23:06'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:23:06', 'currency': 'HKD', 'indicator': 'market_cap', 'value': '29802893305.38', 'value_date': '2026-01-12 14:23:06'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:23:06', 'currency': 'HKD', 'indicator': 'Rev_Abroad', 'value': '37.287945521334656', 'value_date': '2026-01-12 14:23:06'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:23:06', 'currency': 'HKD', 'indicator': 'dividend_yield', 'value': '3.145336135090561', 'value_date': '2026-01-12 14:23:06'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:23:06', 'currency': 'HKD', 'indicator': 'IPO_date', 'value': '2009-11-25', 'value_date': '2026-01-12 14:23:06'}] +2026-01-12 14:23:07,870 - app.clients.bloomberg_client - INFO - ✅ Saved 7 records to database. +2026-01-12 14:23:07,871 - app.clients.bloomberg_client - INFO - Fetching Currency Data... +2026-01-12 14:23:07,871 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=70, Msg=正在获取货币指标 (HKD)..., Progress=41% +2026-01-12 14:23:08,272 - app.clients.bloomberg_client - ERROR - Error fetching currency series: name 'timedelta' is not defined +2026-01-12 14:23:08,273 - app.clients.bloomberg_client - INFO - Fetching Non-Currency Data... +2026-01-12 14:23:08,273 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=70, Msg=正在获取非货币指标..., Progress=55% +2026-01-12 14:23:09,053 - app.clients.bloomberg_client - ERROR - Error fetching non-currency series: name 'timedelta' is not defined +2026-01-12 14:23:09,053 - app.clients.bloomberg_client - INFO - Fetching Price Data (Aligned)... +2026-01-12 14:23:09,053 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=70, Msg=正在获取价格指标..., Progress=69% +2026-01-12 14:23:09,347 - app.clients.bloomberg_client - WARNING - No revenue dates found. Falling back to yearly price fetch. +2026-01-12 14:23:09,347 - app.clients.bloomberg_client - ERROR - Error fetching fallback price data: name 'timedelta' is not defined +2026-01-12 14:23:09,348 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=70, Msg=Finalizing data..., Progress=82% +2026-01-12 14:23:10,275 - app.clients.bloomberg_client - INFO - ✅ Cleanup and View Refresh completed. +2026-01-12 14:23:10,275 - app.clients.bloomberg_client - INFO - ✅ Completed processing for 00631 HK Equity +2026-01-12 14:23:10,275 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=70, Msg=Bloomberg data sync complete, Progress=90% +2026-01-12 14:23:10,741 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=70, Msg=Bloomberg 数据同步完成, Progress=100% +2026-01-12 14:36:45,408 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=71, Msg=正在初始化数据获取..., Progress=0% +2026-01-12 14:36:45,934 - app.clients.bloomberg_client - INFO - Connecting to Jupyter at http://192.168.3.161:8888... +2026-01-12 14:36:46,331 - app.clients.bloomberg_client - INFO - ✅ Authentication successful. +2026-01-12 14:36:46,363 - app.clients.bloomberg_client - INFO - ✅ Found existing kernel: bc27f3b1-b028-434a-99fa-c1cad4495a87 (remote_env) +2026-01-12 14:36:46,418 - app.clients.bloomberg_client - INFO - ✅ WebSocket connected. +2026-01-12 14:36:46,418 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=71, Msg=数据源连接成功, Progress=10% +2026-01-12 14:36:47,610 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=71, Msg=正在连接 Bloomberg 终端..., Progress=20% +2026-01-12 14:36:48,331 - app.clients.bloomberg_client - INFO - 🚀 Starting fetch for: 00631 HK Equity +2026-01-12 14:36:48,332 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=71, Msg=Starting Bloomberg session..., Progress=20% +2026-01-12 14:36:49,795 - app.clients.bloomberg_client - INFO - Using auto-detected currency: HKD +2026-01-12 14:36:49,795 - app.clients.bloomberg_client - INFO - Fetching Basic Data... +2026-01-12 14:36:49,795 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=71, Msg=Fetching Company Basic Info..., Progress=27% +2026-01-12 14:36:50,804 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:36:51", "currency": "HKD", "indicator": "company_name", "value": "SANY HEAVY EQUIPMENT INTL", "value_date": "2026-01-12 14:36:51"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:36:51", "currency": "HKD", "indicator": "pe_ratio", "value": "20.029351716875", "value_date": "2026-01-12 14:36:51"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:36:51", "currency": "HKD", "indicator": "pb_ratio", "value": "2.120602595838916", "value_date": "2026-01-12 14:36:51"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:36:51", "currency": "HKD", "indicator": "market_cap", "value": "29770569126.09", "value_date": "2026-01-12 14:36:51"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:36:51", "currency": "HKD", "indicator": "Rev_Abroad", "value": "37.287945521334656", "value_date": "2026-01-12 14:36:51"}, {"Company_code": "00631 HK Equity", "update_da +2026-01-12 14:36:50,805 - app.clients.bloomberg_client - INFO - ✅ Parsed 7 items from remote. +2026-01-12 14:36:50,805 - app.clients.bloomberg_client - INFO - DEBUG: basic_data before save: [{'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:36:51', 'currency': 'HKD', 'indicator': 'company_name', 'value': 'SANY HEAVY EQUIPMENT INTL', 'value_date': '2026-01-12 14:36:51'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:36:51', 'currency': 'HKD', 'indicator': 'pe_ratio', 'value': '20.029351716875', 'value_date': '2026-01-12 14:36:51'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:36:51', 'currency': 'HKD', 'indicator': 'pb_ratio', 'value': '2.120602595838916', 'value_date': '2026-01-12 14:36:51'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:36:51', 'currency': 'HKD', 'indicator': 'market_cap', 'value': '29770569126.09', 'value_date': '2026-01-12 14:36:51'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:36:51', 'currency': 'HKD', 'indicator': 'Rev_Abroad', 'value': '37.287945521334656', 'value_date': '2026-01-12 14:36:51'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:36:51', 'currency': 'HKD', 'indicator': 'dividend_yield', 'value': '3.1487512666161748', 'value_date': '2026-01-12 14:36:51'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:36:51', 'currency': 'HKD', 'indicator': 'IPO_date', 'value': '2009-11-25', 'value_date': '2026-01-12 14:36:51'}] +2026-01-12 14:36:51,907 - app.clients.bloomberg_client - INFO - ✅ Saved 7 records to database. +2026-01-12 14:36:51,908 - app.clients.bloomberg_client - INFO - Fetching Currency Data... +2026-01-12 14:36:51,908 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=71, Msg=正在获取货币指标 (HKD)..., Progress=41% +2026-01-12 14:36:53,347 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:36:52", "currency": "HKD", "indicator": "Revenue", "value": "2152.9812", "value_date": "2017-01-12"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:36:52", "currency": "HKD", "indicator": "Net_Income", "value": "-753.2314", "value_date": "2017-01-12"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:36:52", "currency": "HKD", "indicator": "Cash_From_Operating", "value": "1557.419", "value_date": "2017-01-12"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:36:52", "currency": "HKD", "indicator": "Capital_Expenditure", "value": "-179.3705", "value_date": "2017-01-12"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:36:52", "currency": "HKD", "indicator": "Free_Cash_Flow", "value": "1378.0485", "value_date": "2017-01-12"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:36:52", "currency": "HKD", "indicator": "Dividend +2026-01-12 14:36:53,348 - app.clients.bloomberg_client - INFO - ✅ Parsed 240 items from remote. +2026-01-12 14:37:07,885 - app.clients.bloomberg_client - INFO - ✅ Saved 240 records to database. +2026-01-12 14:37:07,887 - app.clients.bloomberg_client - INFO - Fetching Non-Currency Data... +2026-01-12 14:37:07,888 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=71, Msg=正在获取非货币指标..., Progress=55% +2026-01-12 14:37:10,019 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:37:09", "currency": "HKD", "indicator": "ROE", "value": "-10.132", "value_date": "2017-01-12"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:37:09", "currency": "HKD", "indicator": "ROA", "value": "-6.0025", "value_date": "2017-01-12"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:37:09", "currency": "HKD", "indicator": "ROCE", "value": "0.3622", "value_date": "2017-01-12"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:37:09", "currency": "HKD", "indicator": "Gross_Margin", "value": "14.994", "value_date": "2017-01-12"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:37:09", "currency": "HKD", "indicator": "EBITDA_margin", "value": "-28.2708", "value_date": "2017-01-12"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:37:09", "currency": "HKD", "indicator": "Net_Profit_Margin", "value": "-34.9855", "value_date +2026-01-12 14:37:10,019 - app.clients.bloomberg_client - INFO - ✅ Parsed 173 items from remote. +2026-01-12 14:37:20,899 - app.clients.bloomberg_client - INFO - ✅ Saved 173 records to database. +2026-01-12 14:37:20,900 - app.clients.bloomberg_client - INFO - Fetching Price Data (Aligned)... +2026-01-12 14:37:20,900 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=71, Msg=正在获取价格指标..., Progress=69% +2026-01-12 14:37:21,161 - app.clients.bloomberg_client - WARNING - No revenue dates found. Falling back to yearly price fetch. +2026-01-12 14:37:21,790 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:37:21", "currency": "HKD", "indicator": "Last_Price", "value": "1.33", "value_date": "2017-01-12"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:37:21", "currency": "HKD", "indicator": "Market_Cap", "value": "4044.5631", "value_date": "2017-01-12"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:37:21", "currency": "HKD", "indicator": "Last_Price", "value": "2.28", "value_date": "2018-01-12"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:37:21", "currency": "HKD", "indicator": "Market_Cap", "value": "6933.537", "value_date": "2018-01-12"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:37:21", "currency": "HKD", "indicator": "Last_Price", "value": "2.45", "value_date": "2019-01-12"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:37:21", "currency": "HKD", "indicator": "Market_Cap", "value": "7450.5113", "value_ +2026-01-12 14:37:21,790 - app.clients.bloomberg_client - INFO - ✅ Parsed 28 items from remote. +2026-01-12 14:37:23,680 - app.clients.bloomberg_client - INFO - ✅ Saved 28 records to database. +2026-01-12 14:37:23,681 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=71, Msg=Finalizing data..., Progress=82% +2026-01-12 14:37:24,983 - app.clients.bloomberg_client - INFO - ✅ Cleanup and View Refresh completed. +2026-01-12 14:37:24,984 - app.clients.bloomberg_client - INFO - ✅ Completed processing for 00631 HK Equity +2026-01-12 14:37:24,984 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=71, Msg=Bloomberg data sync complete, Progress=90% +2026-01-12 14:37:25,270 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=71, Msg=Bloomberg 数据同步完成, Progress=100% +2026-01-12 14:43:07,865 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=72, Msg=正在初始化数据获取..., Progress=0% +2026-01-12 14:43:08,610 - app.clients.bloomberg_client - INFO - Connecting to Jupyter at http://192.168.3.161:8888... +2026-01-12 14:43:08,830 - app.clients.bloomberg_client - INFO - ✅ Authentication successful. +2026-01-12 14:43:09,009 - app.clients.bloomberg_client - INFO - ✅ Found existing kernel: bc27f3b1-b028-434a-99fa-c1cad4495a87 (remote_env) +2026-01-12 14:43:09,066 - app.clients.bloomberg_client - INFO - ✅ WebSocket connected. +2026-01-12 14:43:09,066 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=72, Msg=数据源连接成功, Progress=10% +2026-01-12 14:43:09,497 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=72, Msg=正在连接 Bloomberg 终端..., Progress=20% +2026-01-12 14:43:09,942 - app.clients.bloomberg_client - INFO - 🚀 Starting fetch for: 00631 HK Equity +2026-01-12 14:43:09,943 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=72, Msg=Starting Bloomberg session..., Progress=20% +2026-01-12 14:43:10,951 - app.clients.bloomberg_client - INFO - Using auto-detected currency: HKD +2026-01-12 14:43:10,951 - app.clients.bloomberg_client - INFO - Fetching Basic Data... +2026-01-12 14:43:10,952 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=72, Msg=Fetching Company Basic Info..., Progress=27% +2026-01-12 14:43:11,735 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:43:12", "currency": "HKD", "indicator": "company_name", "value": "SANY HEAVY EQUIPMENT INTL", "value_date": "2026-01-12 14:43:12"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:43:12", "currency": "HKD", "indicator": "pe_ratio", "value": "20.116743525594977", "value_date": "2026-01-12 14:43:12"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:43:12", "currency": "HKD", "indicator": "pb_ratio", "value": "2.1298551816962252", "value_date": "2026-01-12 14:43:12"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:43:12", "currency": "HKD", "indicator": "market_cap", "value": "29899865843.249996", "value_date": "2026-01-12 14:43:12"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:43:12", "currency": "HKD", "indicator": "Rev_Abroad", "value": "37.287945521334656", "value_date": "2026-01-12 14:43:12"}, {"Company_code": "00631 HK Equity", "u +2026-01-12 14:43:11,735 - app.clients.bloomberg_client - INFO - ✅ Parsed 7 items from remote. +2026-01-12 14:43:11,735 - app.clients.bloomberg_client - INFO - DEBUG: basic_data before save: [{'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:43:12', 'currency': 'HKD', 'indicator': 'company_name', 'value': 'SANY HEAVY EQUIPMENT INTL', 'value_date': '2026-01-12 14:43:12'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:43:12', 'currency': 'HKD', 'indicator': 'pe_ratio', 'value': '20.116743525594977', 'value_date': '2026-01-12 14:43:12'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:43:12', 'currency': 'HKD', 'indicator': 'pb_ratio', 'value': '2.1298551816962252', 'value_date': '2026-01-12 14:43:12'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:43:12', 'currency': 'HKD', 'indicator': 'market_cap', 'value': '29899865843.249996', 'value_date': '2026-01-12 14:43:12'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:43:12', 'currency': 'HKD', 'indicator': 'Rev_Abroad', 'value': '37.287945521334656', 'value_date': '2026-01-12 14:43:12'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:43:12', 'currency': 'HKD', 'indicator': 'dividend_yield', 'value': '3.1351350449227', 'value_date': '2026-01-12 14:43:12'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:43:12', 'currency': 'HKD', 'indicator': 'IPO_date', 'value': '2009-11-25', 'value_date': '2026-01-12 14:43:12'}] +2026-01-12 14:43:13,034 - app.clients.bloomberg_client - INFO - ✅ Saved 7 records to database. +2026-01-12 14:43:13,035 - app.clients.bloomberg_client - INFO - Fetching Currency Data... +2026-01-12 14:43:13,035 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=72, Msg=正在获取货币指标 (HKD)..., Progress=41% +2026-01-12 14:43:13,894 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:43:13", "currency": "HKD", "indicator": "Revenue", "value": "2152.9812", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:43:13", "currency": "HKD", "indicator": "Net_Income", "value": "-753.2314", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:43:13", "currency": "HKD", "indicator": "Cash_From_Operating", "value": "1557.419", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:43:13", "currency": "HKD", "indicator": "Capital_Expenditure", "value": "-179.3705", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:43:13", "currency": "HKD", "indicator": "Free_Cash_Flow", "value": "1378.0485", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:43:13", "currency": "HKD", "indicator": "Dividend +2026-01-12 14:43:13,894 - app.clients.bloomberg_client - INFO - ✅ Parsed 213 items from remote. +2026-01-12 14:43:25,211 - app.clients.bloomberg_client - INFO - ✅ Saved 213 records to database. +2026-01-12 14:43:25,212 - app.clients.bloomberg_client - INFO - Fetching Non-Currency Data... +2026-01-12 14:43:25,212 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=72, Msg=正在获取非货币指标..., Progress=55% +2026-01-12 14:43:26,114 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:43:25", "currency": "HKD", "indicator": "ROE", "value": "-10.132", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:43:25", "currency": "HKD", "indicator": "ROA", "value": "-6.0025", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:43:25", "currency": "HKD", "indicator": "Gross_Margin", "value": "14.994", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:43:25", "currency": "HKD", "indicator": "EBITDA_margin", "value": "-28.2708", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:43:25", "currency": "HKD", "indicator": "Net_Profit_Margin", "value": "-34.9855", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:43:25", "currency": "HKD", "indicator": "Tax_Rate", "value": "0.25", "value_da +2026-01-12 14:43:26,115 - app.clients.bloomberg_client - INFO - ✅ Parsed 150 items from remote. +2026-01-12 14:43:34,767 - app.clients.bloomberg_client - INFO - ✅ Saved 150 records to database. +2026-01-12 14:43:34,768 - app.clients.bloomberg_client - INFO - Fetching Price Data (Aligned)... +2026-01-12 14:43:34,769 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=72, Msg=正在获取价格指标..., Progress=69% +2026-01-12 14:43:35,176 - app.clients.bloomberg_client - WARNING - No revenue dates found. Falling back to yearly price fetch. +2026-01-12 14:43:35,719 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:43:35", "currency": "HKD", "indicator": "Last_Price", "value": "1.24", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:43:35", "currency": "HKD", "indicator": "Market_Cap", "value": "3770.8709", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:43:35", "currency": "HKD", "indicator": "Last_Price", "value": "1.71", "value_date": "2017-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:43:35", "currency": "HKD", "indicator": "Market_Cap", "value": "5200.1528", "value_date": "2017-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:43:35", "currency": "HKD", "indicator": "Last_Price", "value": "2.67", "value_date": "2018-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:43:35", "currency": "HKD", "indicator": "Market_Cap", "value": "8119.5368", "value +2026-01-12 14:43:35,719 - app.clients.bloomberg_client - INFO - ✅ Parsed 25 items from remote. +2026-01-12 14:43:37,996 - app.clients.bloomberg_client - INFO - ✅ Saved 25 records to database. +2026-01-12 14:43:37,996 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=72, Msg=Finalizing data..., Progress=82% +2026-01-12 14:43:38,939 - app.clients.bloomberg_client - INFO - ✅ Cleanup and View Refresh completed. +2026-01-12 14:43:38,939 - app.clients.bloomberg_client - INFO - ✅ Completed processing for 00631 HK Equity +2026-01-12 14:43:38,939 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=72, Msg=Bloomberg data sync complete, Progress=90% +2026-01-12 14:43:40,030 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=72, Msg=Bloomberg 数据同步完成, Progress=100% +2026-01-12 14:45:40,102 - app.services.bloomberg_service - WARNING - No Bloomberg data found for symbol: 00631 +2026-01-12 14:45:42,034 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=73, Msg=正在初始化数据获取..., Progress=0% +2026-01-12 14:45:42,964 - app.clients.bloomberg_client - INFO - Connecting to Jupyter at http://192.168.3.161:8888... +2026-01-12 14:45:43,352 - app.clients.bloomberg_client - INFO - ✅ Authentication successful. +2026-01-12 14:45:43,383 - app.clients.bloomberg_client - INFO - ✅ Found existing kernel: bc27f3b1-b028-434a-99fa-c1cad4495a87 (remote_env) +2026-01-12 14:45:43,448 - app.clients.bloomberg_client - INFO - ✅ WebSocket connected. +2026-01-12 14:45:43,449 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=73, Msg=数据源连接成功, Progress=10% +2026-01-12 14:45:43,881 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=73, Msg=正在连接 Bloomberg 终端..., Progress=20% +2026-01-12 14:45:44,623 - app.clients.bloomberg_client - INFO - 🚀 Starting fetch for: 00631 HK Equity +2026-01-12 14:45:44,623 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=73, Msg=Starting Bloomberg session..., Progress=20% +2026-01-12 14:45:45,178 - app.clients.bloomberg_client - INFO - Using auto-detected currency: HKD +2026-01-12 14:45:45,179 - app.clients.bloomberg_client - INFO - Fetching Basic Data... +2026-01-12 14:45:45,180 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=73, Msg=Fetching Company Basic Info..., Progress=27% +2026-01-12 14:45:46,576 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:45:47", "currency": "HKD", "indicator": "company_name", "value": "SANY HEAVY EQUIPMENT INTL", "value_date": "2026-01-12 14:45:47"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:45:47", "currency": "HKD", "indicator": "pe_ratio", "value": "20.138605869994777", "value_date": "2026-01-12 14:45:47"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:45:47", "currency": "HKD", "indicator": "pb_ratio", "value": "2.1321698519332197", "value_date": "2026-01-12 14:45:47"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:45:47", "currency": "HKD", "indicator": "market_cap", "value": "29932190022.539997", "value_date": "2026-01-12 14:45:47"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:45:47", "currency": "HKD", "indicator": "Rev_Abroad", "value": "37.287945521334656", "value_date": "2026-01-12 14:45:47"}, {"Company_code": "00631 HK Equity", "u +2026-01-12 14:45:46,576 - app.clients.bloomberg_client - INFO - ✅ Parsed 7 items from remote. +2026-01-12 14:45:46,576 - app.clients.bloomberg_client - INFO - DEBUG: basic_data before save: [{'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:45:47', 'currency': 'HKD', 'indicator': 'company_name', 'value': 'SANY HEAVY EQUIPMENT INTL', 'value_date': '2026-01-12 14:45:47'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:45:47', 'currency': 'HKD', 'indicator': 'pe_ratio', 'value': '20.138605869994777', 'value_date': '2026-01-12 14:45:47'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:45:47', 'currency': 'HKD', 'indicator': 'pb_ratio', 'value': '2.1321698519332197', 'value_date': '2026-01-12 14:45:47'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:45:47', 'currency': 'HKD', 'indicator': 'market_cap', 'value': '29932190022.539997', 'value_date': '2026-01-12 14:45:47'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:45:47', 'currency': 'HKD', 'indicator': 'Rev_Abroad', 'value': '37.287945521334656', 'value_date': '2026-01-12 14:45:47'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:45:47', 'currency': 'HKD', 'indicator': 'dividend_yield', 'value': '3.131749369928183', 'value_date': '2026-01-12 14:45:47'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:45:47', 'currency': 'HKD', 'indicator': 'IPO_date', 'value': '2009-11-25', 'value_date': '2026-01-12 14:45:47'}] +2026-01-12 14:45:48,142 - app.clients.bloomberg_client - INFO - ✅ Saved 7 records to database. +2026-01-12 14:45:48,142 - app.clients.bloomberg_client - INFO - Fetching Currency Data... +2026-01-12 14:45:48,142 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=73, Msg=正在获取货币指标 (HKD)..., Progress=41% +2026-01-12 14:45:50,239 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:45:49", "currency": "HKD", "indicator": "Revenue", "value": "2152.9812", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:45:49", "currency": "HKD", "indicator": "Net_Income", "value": "-753.2314", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:45:49", "currency": "HKD", "indicator": "Cash_From_Operating", "value": "1557.419", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:45:49", "currency": "HKD", "indicator": "Capital_Expenditure", "value": "-179.3705", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:45:49", "currency": "HKD", "indicator": "Free_Cash_Flow", "value": "1378.0485", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:45:49", "currency": "HKD", "indicator": "Dividend +2026-01-12 14:45:50,239 - app.clients.bloomberg_client - INFO - ✅ Parsed 213 items from remote. +2026-01-12 14:46:03,568 - app.clients.bloomberg_client - INFO - ✅ Saved 213 records to database. +2026-01-12 14:46:03,570 - app.clients.bloomberg_client - INFO - Fetching Non-Currency Data... +2026-01-12 14:46:03,570 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=73, Msg=正在获取非货币指标..., Progress=55% +2026-01-12 14:46:04,576 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:46:04", "currency": "HKD", "indicator": "ROE", "value": "-10.132", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:46:04", "currency": "HKD", "indicator": "ROA", "value": "-6.0025", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:46:04", "currency": "HKD", "indicator": "Gross_Margin", "value": "14.994", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:46:04", "currency": "HKD", "indicator": "EBITDA_margin", "value": "-28.2708", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:46:04", "currency": "HKD", "indicator": "Net_Profit_Margin", "value": "-34.9855", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:46:04", "currency": "HKD", "indicator": "Tax_Rate", "value": "0.25", "value_da +2026-01-12 14:46:04,576 - app.clients.bloomberg_client - INFO - ✅ Parsed 150 items from remote. +2026-01-12 14:46:16,087 - app.clients.bloomberg_client - INFO - ✅ Saved 150 records to database. +2026-01-12 14:46:16,090 - app.clients.bloomberg_client - INFO - Fetching Price Data (Aligned)... +2026-01-12 14:46:16,090 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=73, Msg=正在获取价格指标..., Progress=69% +2026-01-12 14:46:16,680 - app.clients.bloomberg_client - WARNING - No revenue dates found. Falling back to yearly price fetch. +2026-01-12 14:46:17,220 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:46:16", "currency": "HKD", "indicator": "Last_Price", "value": "1.24", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:46:16", "currency": "HKD", "indicator": "Market_Cap", "value": "3770.8709", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:46:16", "currency": "HKD", "indicator": "Last_Price", "value": "1.71", "value_date": "2017-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:46:16", "currency": "HKD", "indicator": "Market_Cap", "value": "5200.1528", "value_date": "2017-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:46:16", "currency": "HKD", "indicator": "Last_Price", "value": "2.67", "value_date": "2018-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:46:16", "currency": "HKD", "indicator": "Market_Cap", "value": "8119.5368", "value +2026-01-12 14:46:17,220 - app.clients.bloomberg_client - INFO - ✅ Parsed 25 items from remote. +2026-01-12 14:46:19,283 - app.clients.bloomberg_client - INFO - ✅ Saved 25 records to database. +2026-01-12 14:46:19,284 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=73, Msg=Finalizing data..., Progress=82% +2026-01-12 14:46:20,269 - app.clients.bloomberg_client - INFO - ✅ Cleanup and View Refresh completed. +2026-01-12 14:46:20,269 - app.clients.bloomberg_client - INFO - ✅ Completed processing for 00631 HK Equity +2026-01-12 14:46:20,269 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=73, Msg=Bloomberg data sync complete, Progress=90% +2026-01-12 14:46:20,840 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=73, Msg=Bloomberg 数据同步完成, Progress=100% +2026-01-12 14:47:40,832 - app.main - INFO - 🔍 [搜索] 开始搜索股票: 小松 +2026-01-12 14:47:40,891 - app.main - INFO - 🤖 [搜索-LLM] 调用 gemini-2.5-flash 进行股票搜索 +2026-01-12 14:47:40,892 - google_genai.models - INFO - AFC is enabled with max remote calls: 10. +2026-01-12 14:47:46,554 - httpx - INFO - HTTP Request: POST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent "HTTP/1.1 200 OK" +2026-01-12 14:47:46,561 - app.main - INFO - ✅ [搜索-LLM] 模型响应完成, 耗时: 5.67秒, Tokens: prompt=165, completion=116, total=281 +2026-01-12 14:47:46,561 - app.main - INFO - ✅ [搜索] 搜索完成, 找到 2 个结果, 总耗时: 5.73秒 +2026-01-12 14:47:55,573 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=74, Msg=正在初始化数据获取..., Progress=0% +2026-01-12 14:47:56,059 - app.clients.bloomberg_client - INFO - Connecting to Jupyter at http://192.168.3.161:8888... +2026-01-12 14:47:56,715 - app.clients.bloomberg_client - INFO - ✅ Authentication successful. +2026-01-12 14:47:56,744 - app.clients.bloomberg_client - INFO - ✅ Found existing kernel: bc27f3b1-b028-434a-99fa-c1cad4495a87 (remote_env) +2026-01-12 14:47:56,806 - app.clients.bloomberg_client - INFO - ✅ WebSocket connected. +2026-01-12 14:47:56,807 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=74, Msg=数据源连接成功, Progress=10% +2026-01-12 14:47:57,821 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=74, Msg=正在连接 Bloomberg 终端..., Progress=20% +2026-01-12 14:47:58,674 - app.clients.bloomberg_client - INFO - 🚀 Starting fetch for: 6301 JP Equity +2026-01-12 14:47:58,675 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=74, Msg=Starting Bloomberg session..., Progress=20% +2026-01-12 14:47:59,347 - app.clients.bloomberg_client - INFO - Using forced currency: CNY +2026-01-12 14:47:59,348 - app.clients.bloomberg_client - INFO - Fetching Basic Data... +2026-01-12 14:47:59,348 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=74, Msg=Fetching Company Basic Info..., Progress=27% +2026-01-12 14:48:01,112 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:48:01", "currency": "CNY", "indicator": "company_name", "value": "KOMATSU LTD", "value_date": "2026-01-12 14:48:01"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:48:01", "currency": "CNY", "indicator": "pe_ratio", "value": "11.538204871538206", "value_date": "2026-01-12 14:48:01"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:48:01", "currency": "CNY", "indicator": "pb_ratio", "value": "1.4637777168999744", "value_date": "2026-01-12 14:48:01"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:48:01", "currency": "CNY", "indicator": "market_cap", "value": "4825676795940.001", "value_date": "2026-01-12 14:48:01"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:48:01", "currency": "CNY", "indicator": "Rev_Abroad", "value": "86.05716369679564", "value_date": "2026-01-12 14:48:01"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01- +2026-01-12 14:48:01,113 - app.clients.bloomberg_client - INFO - ✅ Parsed 6 items from remote. +2026-01-12 14:48:01,114 - app.clients.bloomberg_client - INFO - DEBUG: basic_data before save: [{'Company_code': '6301 JP Equity', 'update_date': '2026-01-12 14:48:01', 'currency': 'CNY', 'indicator': 'company_name', 'value': 'KOMATSU LTD', 'value_date': '2026-01-12 14:48:01'}, {'Company_code': '6301 JP Equity', 'update_date': '2026-01-12 14:48:01', 'currency': 'CNY', 'indicator': 'pe_ratio', 'value': '11.538204871538206', 'value_date': '2026-01-12 14:48:01'}, {'Company_code': '6301 JP Equity', 'update_date': '2026-01-12 14:48:01', 'currency': 'CNY', 'indicator': 'pb_ratio', 'value': '1.4637777168999744', 'value_date': '2026-01-12 14:48:01'}, {'Company_code': '6301 JP Equity', 'update_date': '2026-01-12 14:48:01', 'currency': 'CNY', 'indicator': 'market_cap', 'value': '4825676795940.001', 'value_date': '2026-01-12 14:48:01'}, {'Company_code': '6301 JP Equity', 'update_date': '2026-01-12 14:48:01', 'currency': 'CNY', 'indicator': 'Rev_Abroad', 'value': '86.05716369679564', 'value_date': '2026-01-12 14:48:01'}, {'Company_code': '6301 JP Equity', 'update_date': '2026-01-12 14:48:01', 'currency': 'CNY', 'indicator': 'dividend_yield', 'value': '3.894351262772315', 'value_date': '2026-01-12 14:48:01'}] +2026-01-12 14:48:02,208 - app.clients.bloomberg_client - INFO - ✅ Saved 6 records to database. +2026-01-12 14:48:02,208 - app.clients.bloomberg_client - INFO - Fetching Currency Data... +2026-01-12 14:48:02,209 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=74, Msg=正在获取货币指标 (CNY)..., Progress=41% +2026-01-12 14:48:03,577 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:48:02", "currency": "CNY", "indicator": "Revenue", "value": "98388.5158", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:48:02", "currency": "CNY", "indicator": "Net_Income", "value": "7289.1658", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:48:02", "currency": "CNY", "indicator": "Cash_From_Operating", "value": "16953.5985", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:48:02", "currency": "CNY", "indicator": "Capital_Expenditure", "value": "-8830.1561", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:48:02", "currency": "CNY", "indicator": "Free_Cash_Flow", "value": "8123.4424", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:48:02", "currency": "CNY", "indicator": "Dividends_ +2026-01-12 14:48:03,578 - app.clients.bloomberg_client - INFO - ✅ Parsed 248 items from remote. +2026-01-12 14:48:18,179 - app.clients.bloomberg_client - INFO - ✅ Saved 248 records to database. +2026-01-12 14:48:18,181 - app.clients.bloomberg_client - INFO - Fetching Non-Currency Data... +2026-01-12 14:48:18,181 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=74, Msg=正在获取非货币指标..., Progress=55% +2026-01-12 14:48:19,384 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:48:18", "currency": "CNY", "indicator": "ROE", "value": "9.0222", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:48:18", "currency": "CNY", "indicator": "ROA", "value": "5.0776", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:48:18", "currency": "CNY", "indicator": "ROCE", "value": "10.4918", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:48:18", "currency": "CNY", "indicator": "Gross_Margin", "value": "29.0675", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:48:18", "currency": "CNY", "indicator": "EBITDA_margin", "value": "17.3073", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:48:18", "currency": "CNY", "indicator": "Net_Profit_Margin", "value": "7.4086", "value_date": "2016- +2026-01-12 14:48:19,384 - app.clients.bloomberg_client - INFO - ✅ Parsed 200 items from remote. +2026-01-12 14:48:30,521 - app.clients.bloomberg_client - INFO - ✅ Saved 200 records to database. +2026-01-12 14:48:30,522 - app.clients.bloomberg_client - INFO - Fetching Price Data (Aligned)... +2026-01-12 14:48:30,523 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=74, Msg=正在获取价格指标..., Progress=69% +2026-01-12 14:48:31,242 - app.clients.bloomberg_client - WARNING - No revenue dates found. Falling back to yearly price fetch. +2026-01-12 14:48:31,965 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:48:31", "currency": "CNY", "indicator": "Last_Price", "value": "109.89665", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:48:31", "currency": "CNY", "indicator": "Market_Cap", "value": "6126.6803", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:48:31", "currency": "CNY", "indicator": "Last_Price", "value": "179.2773", "value_date": "2017-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:48:31", "currency": "CNY", "indicator": "Market_Cap", "value": "10766.6315", "value_date": "2017-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:48:31", "currency": "CNY", "indicator": "Last_Price", "value": "209.97492", "value_date": "2018-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:48:31", "currency": "CNY", "indicator": "Market_Cap", "value": "12081.628 +2026-01-12 14:48:31,966 - app.clients.bloomberg_client - INFO - ✅ Parsed 20 items from remote. +2026-01-12 14:48:34,609 - app.clients.bloomberg_client - INFO - ✅ Saved 20 records to database. +2026-01-12 14:48:34,610 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=74, Msg=Finalizing data..., Progress=82% +2026-01-12 14:48:35,541 - app.clients.bloomberg_client - INFO - ✅ Cleanup and View Refresh completed. +2026-01-12 14:48:35,542 - app.clients.bloomberg_client - INFO - ✅ Completed processing for 6301 JP Equity +2026-01-12 14:48:35,542 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=74, Msg=Bloomberg data sync complete, Progress=90% +2026-01-12 14:48:36,209 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=74, Msg=Bloomberg 数据同步完成, Progress=100% +2026-01-12 14:49:44,963 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=75, Msg=正在初始化数据获取..., Progress=0% +2026-01-12 14:49:45,392 - app.clients.bloomberg_client - INFO - Connecting to Jupyter at http://192.168.3.161:8888... +2026-01-12 14:49:45,772 - app.clients.bloomberg_client - INFO - ✅ Authentication successful. +2026-01-12 14:49:45,800 - app.clients.bloomberg_client - INFO - ✅ Found existing kernel: bc27f3b1-b028-434a-99fa-c1cad4495a87 (remote_env) +2026-01-12 14:49:46,296 - app.clients.bloomberg_client - INFO - ✅ WebSocket connected. +2026-01-12 14:49:46,297 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=75, Msg=数据源连接成功, Progress=10% +2026-01-12 14:49:46,646 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=75, Msg=正在连接 Bloomberg 终端..., Progress=20% +2026-01-12 14:49:47,067 - app.clients.bloomberg_client - INFO - 🚀 Starting fetch for: 6301 JP Equity +2026-01-12 14:49:47,067 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=75, Msg=Starting Bloomberg session..., Progress=20% +2026-01-12 14:49:47,538 - app.clients.bloomberg_client - INFO - Using auto-detected currency: JPY +2026-01-12 14:49:47,538 - app.clients.bloomberg_client - INFO - Fetching Basic Data... +2026-01-12 14:49:47,539 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=75, Msg=Fetching Company Basic Info..., Progress=27% +2026-01-12 14:49:48,960 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:49:49", "currency": "JPY", "indicator": "company_name", "value": "KOMATSU LTD", "value_date": "2026-01-12 14:49:49"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:49:49", "currency": "JPY", "indicator": "pe_ratio", "value": "11.538204871538206", "value_date": "2026-01-12 14:49:49"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:49:49", "currency": "JPY", "indicator": "pb_ratio", "value": "1.4637777168999744", "value_date": "2026-01-12 14:49:49"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:49:49", "currency": "JPY", "indicator": "market_cap", "value": "4825676795940.001", "value_date": "2026-01-12 14:49:49"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:49:49", "currency": "JPY", "indicator": "Rev_Abroad", "value": "86.05716369679564", "value_date": "2026-01-12 14:49:49"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01- +2026-01-12 14:49:48,961 - app.clients.bloomberg_client - INFO - ✅ Parsed 6 items from remote. +2026-01-12 14:49:48,961 - app.clients.bloomberg_client - INFO - DEBUG: basic_data before save: [{'Company_code': '6301 JP Equity', 'update_date': '2026-01-12 14:49:49', 'currency': 'JPY', 'indicator': 'company_name', 'value': 'KOMATSU LTD', 'value_date': '2026-01-12 14:49:49'}, {'Company_code': '6301 JP Equity', 'update_date': '2026-01-12 14:49:49', 'currency': 'JPY', 'indicator': 'pe_ratio', 'value': '11.538204871538206', 'value_date': '2026-01-12 14:49:49'}, {'Company_code': '6301 JP Equity', 'update_date': '2026-01-12 14:49:49', 'currency': 'JPY', 'indicator': 'pb_ratio', 'value': '1.4637777168999744', 'value_date': '2026-01-12 14:49:49'}, {'Company_code': '6301 JP Equity', 'update_date': '2026-01-12 14:49:49', 'currency': 'JPY', 'indicator': 'market_cap', 'value': '4825676795940.001', 'value_date': '2026-01-12 14:49:49'}, {'Company_code': '6301 JP Equity', 'update_date': '2026-01-12 14:49:49', 'currency': 'JPY', 'indicator': 'Rev_Abroad', 'value': '86.05716369679564', 'value_date': '2026-01-12 14:49:49'}, {'Company_code': '6301 JP Equity', 'update_date': '2026-01-12 14:49:49', 'currency': 'JPY', 'indicator': 'dividend_yield', 'value': '3.894351262772315', 'value_date': '2026-01-12 14:49:49'}] +2026-01-12 14:49:49,780 - app.clients.bloomberg_client - INFO - ✅ Saved 6 records to database. +2026-01-12 14:49:49,781 - app.clients.bloomberg_client - INFO - Fetching Currency Data... +2026-01-12 14:49:49,781 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=75, Msg=正在获取货币指标 (JPY)..., Progress=41% +2026-01-12 14:49:50,861 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:49:50", "currency": "JPY", "indicator": "Revenue", "value": "1854964.0", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:49:50", "currency": "JPY", "indicator": "Net_Income", "value": "137426.0", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:49:50", "currency": "JPY", "indicator": "Cash_From_Operating", "value": "319634.0", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:49:50", "currency": "JPY", "indicator": "Capital_Expenditure", "value": "-166479.0", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:49:50", "currency": "JPY", "indicator": "Free_Cash_Flow", "value": "153155.0", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:49:50", "currency": "JPY", "indicator": "Dividends_Paid", +2026-01-12 14:49:50,862 - app.clients.bloomberg_client - INFO - ✅ Parsed 248 items from remote. +2026-01-12 14:50:05,970 - app.clients.bloomberg_client - INFO - ✅ Saved 248 records to database. +2026-01-12 14:50:05,972 - app.clients.bloomberg_client - INFO - Fetching Non-Currency Data... +2026-01-12 14:50:05,973 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=75, Msg=正在获取非货币指标..., Progress=55% +2026-01-12 14:50:08,245 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:50:07", "currency": "JPY", "indicator": "ROE", "value": "9.0222", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:50:07", "currency": "JPY", "indicator": "ROA", "value": "5.0776", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:50:07", "currency": "JPY", "indicator": "ROCE", "value": "10.4918", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:50:07", "currency": "JPY", "indicator": "Gross_Margin", "value": "29.0675", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:50:07", "currency": "JPY", "indicator": "EBITDA_margin", "value": "17.3073", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:50:07", "currency": "JPY", "indicator": "Net_Profit_Margin", "value": "7.4086", "value_date": "2016- +2026-01-12 14:50:08,245 - app.clients.bloomberg_client - INFO - ✅ Parsed 200 items from remote. +2026-01-12 14:50:21,679 - app.clients.bloomberg_client - INFO - ✅ Saved 200 records to database. +2026-01-12 14:50:21,680 - app.clients.bloomberg_client - INFO - Fetching Price Data (Aligned)... +2026-01-12 14:50:21,680 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=75, Msg=正在获取价格指标..., Progress=69% +2026-01-12 14:50:22,256 - app.clients.bloomberg_client - WARNING - No revenue dates found. Falling back to yearly price fetch. +2026-01-12 14:50:23,865 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:50:22", "currency": "JPY", "indicator": "Last_Price", "value": "1916.0", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:50:22", "currency": "JPY", "indicator": "Market_Cap", "value": "1862290.02", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:50:22", "currency": "JPY", "indicator": "Dividend_Yield", "value": "3.0271", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:50:22", "currency": "JPY", "indicator": "Last_Price", "value": "2901.5", "value_date": "2017-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:50:22", "currency": "JPY", "indicator": "Market_Cap", "value": "2820164.1404", "value_date": "2017-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 14:50:22", "currency": "JPY", "indicator": "Dividend_Yield", "value": "1.999" +2026-01-12 14:50:23,866 - app.clients.bloomberg_client - INFO - ✅ Parsed 30 items from remote. +2026-01-12 14:50:26,009 - app.clients.bloomberg_client - INFO - ✅ Saved 30 records to database. +2026-01-12 14:50:26,009 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=75, Msg=Finalizing data..., Progress=82% +2026-01-12 14:50:27,009 - app.clients.bloomberg_client - INFO - ✅ Cleanup and View Refresh completed. +2026-01-12 14:50:27,009 - app.clients.bloomberg_client - INFO - ✅ Completed processing for 6301 JP Equity +2026-01-12 14:50:27,009 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=75, Msg=Bloomberg data sync complete, Progress=90% +2026-01-12 14:50:27,898 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=75, Msg=Bloomberg 数据同步完成, Progress=100% +2026-01-12 14:51:20,076 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=76, Msg=正在初始化数据获取..., Progress=0% +2026-01-12 14:51:20,584 - app.clients.bloomberg_client - INFO - Connecting to Jupyter at http://192.168.3.161:8888... +2026-01-12 14:51:21,537 - app.clients.bloomberg_client - INFO - ✅ Authentication successful. +2026-01-12 14:51:21,567 - app.clients.bloomberg_client - INFO - ✅ Found existing kernel: bc27f3b1-b028-434a-99fa-c1cad4495a87 (remote_env) +2026-01-12 14:51:21,624 - app.clients.bloomberg_client - INFO - ✅ WebSocket connected. +2026-01-12 14:51:21,628 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=76, Msg=数据源连接成功, Progress=10% +2026-01-12 14:51:22,917 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=76, Msg=正在连接 Bloomberg 终端..., Progress=20% +2026-01-12 14:51:23,220 - app.clients.bloomberg_client - INFO - 🚀 Starting fetch for: 00631 HK Equity +2026-01-12 14:51:23,220 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=76, Msg=Starting Bloomberg session..., Progress=20% +2026-01-12 14:51:24,335 - app.clients.bloomberg_client - INFO - Using auto-detected currency: HKD +2026-01-12 14:51:24,335 - app.clients.bloomberg_client - INFO - Fetching Basic Data... +2026-01-12 14:51:24,335 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=76, Msg=Fetching Company Basic Info..., Progress=27% +2026-01-12 14:51:25,182 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:51:25", "currency": "HKD", "indicator": "company_name", "value": "SANY HEAVY EQUIPMENT INTL", "value_date": "2026-01-12 14:51:25"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:51:25", "currency": "HKD", "indicator": "pe_ratio", "value": "20.029578510589843", "value_date": "2026-01-12 14:51:25"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:51:25", "currency": "HKD", "indicator": "pb_ratio", "value": "2.120626607566665", "value_date": "2026-01-12 14:51:25"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:51:25", "currency": "HKD", "indicator": "market_cap", "value": "29770569126.09", "value_date": "2026-01-12 14:51:25"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:51:25", "currency": "HKD", "indicator": "Rev_Abroad", "value": "37.287945521334656", "value_date": "2026-01-12 14:51:25"}, {"Company_code": "00631 HK Equity", "update +2026-01-12 14:51:25,183 - app.clients.bloomberg_client - INFO - ✅ Parsed 7 items from remote. +2026-01-12 14:51:25,183 - app.clients.bloomberg_client - INFO - DEBUG: basic_data before save: [{'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:51:25', 'currency': 'HKD', 'indicator': 'company_name', 'value': 'SANY HEAVY EQUIPMENT INTL', 'value_date': '2026-01-12 14:51:25'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:51:25', 'currency': 'HKD', 'indicator': 'pe_ratio', 'value': '20.029578510589843', 'value_date': '2026-01-12 14:51:25'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:51:25', 'currency': 'HKD', 'indicator': 'pb_ratio', 'value': '2.120626607566665', 'value_date': '2026-01-12 14:51:25'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:51:25', 'currency': 'HKD', 'indicator': 'market_cap', 'value': '29770569126.09', 'value_date': '2026-01-12 14:51:25'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:51:25', 'currency': 'HKD', 'indicator': 'Rev_Abroad', 'value': '37.287945521334656', 'value_date': '2026-01-12 14:51:25'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:51:25', 'currency': 'HKD', 'indicator': 'dividend_yield', 'value': '3.1487512666161748', 'value_date': '2026-01-12 14:51:25'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 14:51:25', 'currency': 'HKD', 'indicator': 'IPO_date', 'value': '2009-11-25', 'value_date': '2026-01-12 14:51:25'}] +2026-01-12 14:51:26,622 - app.clients.bloomberg_client - INFO - ✅ Saved 7 records to database. +2026-01-12 14:51:26,624 - app.clients.bloomberg_client - INFO - Fetching Currency Data... +2026-01-12 14:51:26,624 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=76, Msg=正在获取货币指标 (HKD)..., Progress=41% +2026-01-12 14:51:27,834 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:51:27", "currency": "HKD", "indicator": "Revenue", "value": "2152.9812", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:51:27", "currency": "HKD", "indicator": "Net_Income", "value": "-753.2314", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:51:27", "currency": "HKD", "indicator": "Cash_From_Operating", "value": "1557.419", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:51:27", "currency": "HKD", "indicator": "Capital_Expenditure", "value": "-179.3705", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:51:27", "currency": "HKD", "indicator": "Free_Cash_Flow", "value": "1378.0485", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:51:27", "currency": "HKD", "indicator": "Dividend +2026-01-12 14:51:27,835 - app.clients.bloomberg_client - INFO - ✅ Parsed 213 items from remote. +2026-01-12 14:51:37,677 - app.clients.bloomberg_client - INFO - ✅ Saved 213 records to database. +2026-01-12 14:51:37,679 - app.clients.bloomberg_client - INFO - Fetching Non-Currency Data... +2026-01-12 14:51:37,679 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=76, Msg=正在获取非货币指标..., Progress=55% +2026-01-12 14:51:39,919 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:51:39", "currency": "HKD", "indicator": "ROE", "value": "-10.132", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:51:39", "currency": "HKD", "indicator": "ROA", "value": "-6.0025", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:51:39", "currency": "HKD", "indicator": "Gross_Margin", "value": "14.994", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:51:39", "currency": "HKD", "indicator": "EBITDA_margin", "value": "-28.2708", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:51:39", "currency": "HKD", "indicator": "Net_Profit_Margin", "value": "-34.9855", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:51:39", "currency": "HKD", "indicator": "Tax_Rate", "value": "0.25", "value_da +2026-01-12 14:51:39,919 - app.clients.bloomberg_client - INFO - ✅ Parsed 150 items from remote. +2026-01-12 14:51:50,298 - app.clients.bloomberg_client - INFO - ✅ Saved 150 records to database. +2026-01-12 14:51:50,300 - app.clients.bloomberg_client - INFO - Fetching Price Data (Aligned)... +2026-01-12 14:51:50,300 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=76, Msg=正在获取价格指标..., Progress=69% +2026-01-12 14:51:50,718 - app.clients.bloomberg_client - WARNING - No revenue dates found. Falling back to yearly price fetch. +2026-01-12 14:51:51,380 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:51:50", "currency": "HKD", "indicator": "Last_Price", "value": "1.24", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:51:50", "currency": "HKD", "indicator": "Market_Cap", "value": "3770.8709", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:51:50", "currency": "HKD", "indicator": "Last_Price", "value": "1.71", "value_date": "2017-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:51:50", "currency": "HKD", "indicator": "Market_Cap", "value": "5200.1528", "value_date": "2017-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:51:50", "currency": "HKD", "indicator": "Last_Price", "value": "2.67", "value_date": "2018-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 14:51:50", "currency": "HKD", "indicator": "Market_Cap", "value": "8119.5368", "value +2026-01-12 14:51:51,380 - app.clients.bloomberg_client - INFO - ✅ Parsed 25 items from remote. +2026-01-12 14:51:53,217 - app.clients.bloomberg_client - INFO - ✅ Saved 25 records to database. +2026-01-12 14:51:53,218 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=76, Msg=Finalizing data..., Progress=82% +2026-01-12 14:51:54,383 - app.clients.bloomberg_client - INFO - ✅ Cleanup and View Refresh completed. +2026-01-12 14:51:54,384 - app.clients.bloomberg_client - INFO - ✅ Completed processing for 00631 HK Equity +2026-01-12 14:51:54,384 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=76, Msg=Bloomberg data sync complete, Progress=90% +2026-01-12 14:51:54,664 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=76, Msg=Bloomberg 数据同步完成, Progress=100% +2026-01-12 15:00:38,249 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=77, Msg=正在初始化数据获取..., Progress=0% +2026-01-12 15:00:39,187 - app.clients.bloomberg_client - INFO - Connecting to Jupyter at http://192.168.3.161:8888... +2026-01-12 15:00:39,747 - app.clients.bloomberg_client - INFO - ✅ Authentication successful. +2026-01-12 15:00:39,779 - app.clients.bloomberg_client - INFO - ✅ Found existing kernel: bc27f3b1-b028-434a-99fa-c1cad4495a87 (remote_env) +2026-01-12 15:00:39,850 - app.clients.bloomberg_client - INFO - ✅ WebSocket connected. +2026-01-12 15:00:39,850 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=77, Msg=数据源连接成功, Progress=10% +2026-01-12 15:00:40,301 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=77, Msg=正在连接 Bloomberg 终端..., Progress=20% +2026-01-12 15:00:40,995 - app.clients.bloomberg_client - INFO - 🚀 Starting fetch for: 6301 JP Equity +2026-01-12 15:00:40,995 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=77, Msg=Starting Bloomberg session..., Progress=20% +2026-01-12 15:00:41,901 - app.clients.bloomberg_client - INFO - Using forced currency: CNY +2026-01-12 15:00:41,901 - app.clients.bloomberg_client - INFO - Fetching Basic Data... +2026-01-12 15:00:41,901 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=77, Msg=Fetching Company Basic Info..., Progress=27% +2026-01-12 15:00:43,438 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:00:43", "currency": "CNY", "indicator": "company_name", "value": "KOMATSU LTD", "value_date": "2026-01-12 15:00:43"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:00:43", "currency": "CNY", "indicator": "pe_ratio", "value": "11.538204871538206", "value_date": "2026-01-12 15:00:43"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:00:43", "currency": "CNY", "indicator": "pb_ratio", "value": "1.4637777168999744", "value_date": "2026-01-12 15:00:43"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:00:43", "currency": "CNY", "indicator": "market_cap", "value": "4825676795940.001", "value_date": "2026-01-12 15:00:43"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:00:43", "currency": "CNY", "indicator": "Rev_Abroad", "value": "86.05716369679564", "value_date": "2026-01-12 15:00:43"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01- +2026-01-12 15:00:43,438 - app.clients.bloomberg_client - INFO - ✅ Parsed 6 items from remote. +2026-01-12 15:00:43,439 - app.clients.bloomberg_client - INFO - DEBUG: basic_data before save: [{'Company_code': '6301 JP Equity', 'update_date': '2026-01-12 15:00:43', 'currency': 'CNY', 'indicator': 'company_name', 'value': 'KOMATSU LTD', 'value_date': '2026-01-12 15:00:43'}, {'Company_code': '6301 JP Equity', 'update_date': '2026-01-12 15:00:43', 'currency': 'CNY', 'indicator': 'pe_ratio', 'value': '11.538204871538206', 'value_date': '2026-01-12 15:00:43'}, {'Company_code': '6301 JP Equity', 'update_date': '2026-01-12 15:00:43', 'currency': 'CNY', 'indicator': 'pb_ratio', 'value': '1.4637777168999744', 'value_date': '2026-01-12 15:00:43'}, {'Company_code': '6301 JP Equity', 'update_date': '2026-01-12 15:00:43', 'currency': 'CNY', 'indicator': 'market_cap', 'value': '4825676795940.001', 'value_date': '2026-01-12 15:00:43'}, {'Company_code': '6301 JP Equity', 'update_date': '2026-01-12 15:00:43', 'currency': 'CNY', 'indicator': 'Rev_Abroad', 'value': '86.05716369679564', 'value_date': '2026-01-12 15:00:43'}, {'Company_code': '6301 JP Equity', 'update_date': '2026-01-12 15:00:43', 'currency': 'CNY', 'indicator': 'dividend_yield', 'value': '3.894351262772315', 'value_date': '2026-01-12 15:00:43'}] +2026-01-12 15:00:45,449 - app.clients.bloomberg_client - INFO - ✅ Saved 6 records to database. +2026-01-12 15:00:45,450 - app.clients.bloomberg_client - INFO - Fetching Currency Data... +2026-01-12 15:00:45,450 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=77, Msg=正在获取货币指标 (CNY)..., Progress=41% +2026-01-12 15:00:46,868 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:00:46", "currency": "CNY", "indicator": "Revenue", "value": "98388.5158", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:00:46", "currency": "CNY", "indicator": "Net_Income", "value": "7289.1658", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:00:46", "currency": "CNY", "indicator": "Cash_From_Operating", "value": "16953.5985", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:00:46", "currency": "CNY", "indicator": "Capital_Expenditure", "value": "-8830.1561", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:00:46", "currency": "CNY", "indicator": "Free_Cash_Flow", "value": "8123.4424", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:00:46", "currency": "CNY", "indicator": "Dividends_ +2026-01-12 15:00:46,869 - app.clients.bloomberg_client - INFO - ✅ Parsed 248 items from remote. +2026-01-12 15:01:02,833 - app.clients.bloomberg_client - INFO - ✅ Saved 248 records to database. +2026-01-12 15:01:02,835 - app.clients.bloomberg_client - INFO - Fetching Non-Currency Data... +2026-01-12 15:01:02,835 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=77, Msg=正在获取非货币指标..., Progress=55% +2026-01-12 15:01:03,945 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:01:03", "currency": "CNY", "indicator": "ROE", "value": "9.0222", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:01:03", "currency": "CNY", "indicator": "ROA", "value": "5.0776", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:01:03", "currency": "CNY", "indicator": "ROCE", "value": "10.4918", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:01:03", "currency": "CNY", "indicator": "Gross_Margin", "value": "29.0675", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:01:03", "currency": "CNY", "indicator": "EBITDA_margin", "value": "17.3073", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:01:03", "currency": "CNY", "indicator": "Net_Profit_Margin", "value": "7.4086", "value_date": "2016- +2026-01-12 15:01:03,946 - app.clients.bloomberg_client - INFO - ✅ Parsed 200 items from remote. +2026-01-12 15:01:16,421 - app.clients.bloomberg_client - INFO - ✅ Saved 200 records to database. +2026-01-12 15:01:16,422 - app.clients.bloomberg_client - INFO - Fetching Price Data (Aligned)... +2026-01-12 15:01:16,422 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=77, Msg=正在获取价格指标..., Progress=69% +2026-01-12 15:01:17,447 - app.clients.bloomberg_client - WARNING - No revenue dates found. Falling back to yearly price fetch (Dec 31). +2026-01-12 15:01:30,781 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:01:17", "currency": "CNY", "indicator": "Last_Price", "value": "223.73673", "value_date": "2025-12-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:01:17", "currency": "CNY", "indicator": "Market_Cap", "value": "208151.3659", "value_date": "2025-12-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:01:17", "currency": "CNY", "indicator": "Dividend_Yield", "value": "4.04", "value_date": "2025-12-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:01:17", "currency": "CNY", "indicator": "Last_Price", "value": "202.05148", "value_date": "2024-12-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:01:17", "currency": "CNY", "indicator": "Market_Cap", "value": "192141.4848", "value_date": "2024-12-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:01:17", "currency": "CNY", "indicator": "Dividend_Yield", "value": "4. +2026-01-12 15:01:30,783 - app.clients.bloomberg_client - INFO - ✅ Parsed 30 items from remote. +2026-01-12 15:01:33,358 - app.clients.bloomberg_client - INFO - ✅ Saved 30 records to database. +2026-01-12 15:01:33,358 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=77, Msg=Finalizing data..., Progress=82% +2026-01-12 15:01:34,774 - app.clients.bloomberg_client - INFO - ✅ Cleanup and View Refresh completed. +2026-01-12 15:01:34,774 - app.clients.bloomberg_client - INFO - ✅ Completed processing for 6301 JP Equity +2026-01-12 15:01:34,775 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=77, Msg=Bloomberg data sync complete, Progress=90% +2026-01-12 15:01:35,316 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=77, Msg=Bloomberg 数据同步完成, Progress=100% +2026-01-12 15:03:03,280 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=78, Msg=正在初始化数据获取..., Progress=0% +2026-01-12 15:03:04,370 - app.clients.bloomberg_client - INFO - Connecting to Jupyter at http://192.168.3.161:8888... +2026-01-12 15:03:04,916 - app.clients.bloomberg_client - INFO - ✅ Authentication successful. +2026-01-12 15:03:04,945 - app.clients.bloomberg_client - INFO - ✅ Found existing kernel: bc27f3b1-b028-434a-99fa-c1cad4495a87 (remote_env) +2026-01-12 15:03:05,071 - app.clients.bloomberg_client - INFO - ✅ WebSocket connected. +2026-01-12 15:03:05,196 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=78, Msg=数据源连接成功, Progress=10% +2026-01-12 15:03:06,469 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=78, Msg=正在连接 Bloomberg 终端..., Progress=20% +2026-01-12 15:03:06,746 - app.clients.bloomberg_client - INFO - 🚀 Starting fetch for: 6301 JP Equity +2026-01-12 15:03:06,746 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=78, Msg=Starting Bloomberg session..., Progress=20% +2026-01-12 15:03:07,404 - app.clients.bloomberg_client - INFO - Using forced currency: CNY +2026-01-12 15:03:07,405 - app.clients.bloomberg_client - INFO - Fetching Basic Data... +2026-01-12 15:03:07,406 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=78, Msg=Fetching Company Basic Info..., Progress=27% +2026-01-12 15:03:08,864 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:03:09", "currency": "CNY", "indicator": "company_name", "value": "KOMATSU LTD", "value_date": "2026-01-12 15:03:09"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:03:09", "currency": "CNY", "indicator": "pe_ratio", "value": "11.538204871538206", "value_date": "2026-01-12 15:03:09"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:03:09", "currency": "CNY", "indicator": "pb_ratio", "value": "1.4637777168999744", "value_date": "2026-01-12 15:03:09"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:03:09", "currency": "CNY", "indicator": "market_cap", "value": "4825676795940.001", "value_date": "2026-01-12 15:03:09"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:03:09", "currency": "CNY", "indicator": "Rev_Abroad", "value": "86.05716369679564", "value_date": "2026-01-12 15:03:09"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01- +2026-01-12 15:03:08,865 - app.clients.bloomberg_client - INFO - ✅ Parsed 6 items from remote. +2026-01-12 15:03:08,865 - app.clients.bloomberg_client - INFO - DEBUG: basic_data before save: [{'Company_code': '6301 JP Equity', 'update_date': '2026-01-12 15:03:09', 'currency': 'CNY', 'indicator': 'company_name', 'value': 'KOMATSU LTD', 'value_date': '2026-01-12 15:03:09'}, {'Company_code': '6301 JP Equity', 'update_date': '2026-01-12 15:03:09', 'currency': 'CNY', 'indicator': 'pe_ratio', 'value': '11.538204871538206', 'value_date': '2026-01-12 15:03:09'}, {'Company_code': '6301 JP Equity', 'update_date': '2026-01-12 15:03:09', 'currency': 'CNY', 'indicator': 'pb_ratio', 'value': '1.4637777168999744', 'value_date': '2026-01-12 15:03:09'}, {'Company_code': '6301 JP Equity', 'update_date': '2026-01-12 15:03:09', 'currency': 'CNY', 'indicator': 'market_cap', 'value': '4825676795940.001', 'value_date': '2026-01-12 15:03:09'}, {'Company_code': '6301 JP Equity', 'update_date': '2026-01-12 15:03:09', 'currency': 'CNY', 'indicator': 'Rev_Abroad', 'value': '86.05716369679564', 'value_date': '2026-01-12 15:03:09'}, {'Company_code': '6301 JP Equity', 'update_date': '2026-01-12 15:03:09', 'currency': 'CNY', 'indicator': 'dividend_yield', 'value': '3.894351262772315', 'value_date': '2026-01-12 15:03:09'}] +2026-01-12 15:03:10,135 - app.clients.bloomberg_client - INFO - ✅ Saved 6 records to database. +2026-01-12 15:03:10,135 - app.clients.bloomberg_client - INFO - Fetching Currency Data... +2026-01-12 15:03:10,136 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=78, Msg=正在获取货币指标 (CNY)..., Progress=41% +2026-01-12 15:03:11,570 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:03:10", "currency": "CNY", "indicator": "Revenue", "value": "98388.5158", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:03:10", "currency": "CNY", "indicator": "Net_Income", "value": "7289.1658", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:03:10", "currency": "CNY", "indicator": "Cash_From_Operating", "value": "16953.5985", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:03:10", "currency": "CNY", "indicator": "Capital_Expenditure", "value": "-8830.1561", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:03:10", "currency": "CNY", "indicator": "Free_Cash_Flow", "value": "8123.4424", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:03:10", "currency": "CNY", "indicator": "Dividends_ +2026-01-12 15:03:11,570 - app.clients.bloomberg_client - INFO - ✅ Parsed 248 items from remote. +2026-01-12 15:03:29,582 - app.clients.bloomberg_client - INFO - ✅ Saved 248 records to database. +2026-01-12 15:03:29,585 - app.clients.bloomberg_client - INFO - Fetching Non-Currency Data... +2026-01-12 15:03:29,585 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=78, Msg=正在获取非货币指标..., Progress=55% +2026-01-12 15:03:30,903 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:03:30", "currency": "CNY", "indicator": "ROE", "value": "9.0222", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:03:30", "currency": "CNY", "indicator": "ROA", "value": "5.0776", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:03:30", "currency": "CNY", "indicator": "ROCE", "value": "10.4918", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:03:30", "currency": "CNY", "indicator": "Gross_Margin", "value": "29.0675", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:03:30", "currency": "CNY", "indicator": "EBITDA_margin", "value": "17.3073", "value_date": "2016-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:03:30", "currency": "CNY", "indicator": "Net_Profit_Margin", "value": "7.4086", "value_date": "2016- +2026-01-12 15:03:30,904 - app.clients.bloomberg_client - INFO - ✅ Parsed 200 items from remote. +2026-01-12 15:03:42,872 - app.clients.bloomberg_client - INFO - ✅ Saved 200 records to database. +2026-01-12 15:03:42,874 - app.clients.bloomberg_client - INFO - Fetching Price Data (Aligned)... +2026-01-12 15:03:42,874 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=78, Msg=正在获取价格指标..., Progress=69% +2026-01-12 15:03:44,697 - app.clients.bloomberg_client - INFO - Found 10 revenue reporting dates. Fetching aligned price data... +2026-01-12 15:03:57,466 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:03:44", "currency": "CNY", "indicator": "Last_Price", "value": "208.47187", "value_date": "2025-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:03:44", "currency": "CNY", "indicator": "Market_Cap", "value": "198246.9783", "value_date": "2025-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:03:44", "currency": "CNY", "indicator": "Dividend_Yield", "value": "4.4124", "value_date": "2025-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:03:44", "currency": "CNY", "indicator": "Last_Price", "value": "211.10676", "value_date": "2024-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:03:44", "currency": "CNY", "indicator": "Market_Cap", "value": "205578.0066", "value_date": "2024-03-31"}, {"Company_code": "6301 JP Equity", "update_date": "2026-01-12 15:03:44", "currency": "CNY", "indicator": "Dividend_Yield", "value": " +2026-01-12 15:03:57,467 - app.clients.bloomberg_client - INFO - ✅ Parsed 30 items from remote. +2026-01-12 15:04:01,642 - app.clients.bloomberg_client - INFO - ✅ Saved 30 records to database. +2026-01-12 15:04:01,642 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=78, Msg=Finalizing data..., Progress=82% +2026-01-12 15:04:03,197 - app.clients.bloomberg_client - INFO - ✅ Cleanup and View Refresh completed. +2026-01-12 15:04:03,198 - app.clients.bloomberg_client - INFO - ✅ Completed processing for 6301 JP Equity +2026-01-12 15:04:03,199 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=78, Msg=Bloomberg data sync complete, Progress=90% +2026-01-12 15:04:03,616 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=78, Msg=Bloomberg 数据同步完成, Progress=100% +2026-01-12 18:12:48,235 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=79, Msg=正在初始化数据获取..., Progress=0% +2026-01-12 18:12:49,501 - app.clients.bloomberg_client - INFO - Connecting to Jupyter at http://192.168.3.161:8888... +2026-01-12 18:12:49,900 - app.clients.bloomberg_client - INFO - ✅ Authentication successful. +2026-01-12 18:12:50,098 - app.clients.bloomberg_client - INFO - ✅ Found existing kernel: bc27f3b1-b028-434a-99fa-c1cad4495a87 (remote_env) +2026-01-12 18:12:50,156 - app.clients.bloomberg_client - INFO - ✅ WebSocket connected. +2026-01-12 18:12:50,156 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=79, Msg=数据源连接成功, Progress=10% +2026-01-12 18:12:51,415 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=79, Msg=正在连接 Bloomberg 终端..., Progress=20% +2026-01-12 18:12:53,347 - app.clients.bloomberg_client - INFO - 🚀 Starting fetch for: 000725 CH Equity +2026-01-12 18:12:53,347 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=79, Msg=Starting Bloomberg session..., Progress=20% +2026-01-12 18:12:54,548 - app.clients.bloomberg_client - INFO - Using auto-detected currency: CNY +2026-01-12 18:12:54,548 - app.clients.bloomberg_client - INFO - Fetching Basic Data... +2026-01-12 18:12:54,548 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=79, Msg=Fetching Company Basic Info..., Progress=27% +2026-01-12 18:12:55,901 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:12:56", "currency": "CNY", "indicator": "company_name", "value": "BOE TECHNOLOGY GROUP CO LT-A", "value_date": "2026-01-12 18:12:56"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:12:56", "currency": "CNY", "indicator": "pe_ratio", "value": "25.959361598462067", "value_date": "2026-01-12 18:12:56"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:12:56", "currency": "CNY", "indicator": "pb_ratio", "value": "1.2417412746613823", "value_date": "2026-01-12 18:12:56"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:12:56", "currency": "CNY", "indicator": "market_cap", "value": "164036307936.54987", "value_date": "2026-01-12 18:12:56"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:12:56", "currency": "CNY", "indicator": "Rev_Abroad", "value": "49.83268989557015", "value_date": "2026-01-12 18:12:56"}, {"Company_code": "000725 CH Equ +2026-01-12 18:12:55,905 - app.clients.bloomberg_client - INFO - ✅ Parsed 7 items from remote. +2026-01-12 18:12:55,906 - app.clients.bloomberg_client - INFO - DEBUG: basic_data before save: [{'Company_code': '000725 CH Equity', 'update_date': '2026-01-12 18:12:56', 'currency': 'CNY', 'indicator': 'company_name', 'value': 'BOE TECHNOLOGY GROUP CO LT-A', 'value_date': '2026-01-12 18:12:56'}, {'Company_code': '000725 CH Equity', 'update_date': '2026-01-12 18:12:56', 'currency': 'CNY', 'indicator': 'pe_ratio', 'value': '25.959361598462067', 'value_date': '2026-01-12 18:12:56'}, {'Company_code': '000725 CH Equity', 'update_date': '2026-01-12 18:12:56', 'currency': 'CNY', 'indicator': 'pb_ratio', 'value': '1.2417412746613823', 'value_date': '2026-01-12 18:12:56'}, {'Company_code': '000725 CH Equity', 'update_date': '2026-01-12 18:12:56', 'currency': 'CNY', 'indicator': 'market_cap', 'value': '164036307936.54987', 'value_date': '2026-01-12 18:12:56'}, {'Company_code': '000725 CH Equity', 'update_date': '2026-01-12 18:12:56', 'currency': 'CNY', 'indicator': 'Rev_Abroad', 'value': '49.83268989557015', 'value_date': '2026-01-12 18:12:56'}, {'Company_code': '000725 CH Equity', 'update_date': '2026-01-12 18:12:56', 'currency': 'CNY', 'indicator': 'dividend_yield', 'value': '1.1210762498891942', 'value_date': '2026-01-12 18:12:56'}, {'Company_code': '000725 CH Equity', 'update_date': '2026-01-12 18:12:56', 'currency': 'CNY', 'indicator': 'IPO_date', 'value': '2001-01-12', 'value_date': '2026-01-12 18:12:56'}] +2026-01-12 18:12:56,950 - app.clients.bloomberg_client - INFO - ✅ Saved 7 records to database. +2026-01-12 18:12:56,951 - app.clients.bloomberg_client - INFO - Fetching Currency Data... +2026-01-12 18:12:56,951 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=79, Msg=正在获取货币指标 (CNY)..., Progress=41% +2026-01-12 18:13:00,033 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:12:59", "currency": "CNY", "indicator": "Revenue", "value": "68895.659", "value_date": "2016-12-31"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:12:59", "currency": "CNY", "indicator": "Net_Income", "value": "1882.5717", "value_date": "2016-12-31"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:12:59", "currency": "CNY", "indicator": "Cash_From_Operating", "value": "8308.9467", "value_date": "2016-12-31"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:12:59", "currency": "CNY", "indicator": "Capital_Expenditure", "value": "-30702.6147", "value_date": "2016-12-31"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:12:59", "currency": "CNY", "indicator": "Free_Cash_Flow", "value": "-22393.668", "value_date": "2016-12-31"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:12:59", "currency": "CNY", "indicator": +2026-01-12 18:13:00,034 - app.clients.bloomberg_client - INFO - ✅ Parsed 225 items from remote. +2026-01-12 18:13:21,758 - app.clients.bloomberg_client - INFO - ✅ Saved 225 records to database. +2026-01-12 18:13:21,759 - app.clients.bloomberg_client - INFO - Fetching Non-Currency Data... +2026-01-12 18:13:21,760 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=79, Msg=正在获取非货币指标..., Progress=55% +2026-01-12 18:13:22,781 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:13:22", "currency": "CNY", "indicator": "ROE", "value": "2.4107", "value_date": "2016-12-31"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:13:22", "currency": "CNY", "indicator": "ROA", "value": "1.0525", "value_date": "2016-12-31"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:13:22", "currency": "CNY", "indicator": "ROCE", "value": "2.905", "value_date": "2016-12-31"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:13:22", "currency": "CNY", "indicator": "Gross_Margin", "value": "17.8675", "value_date": "2016-12-31"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:13:22", "currency": "CNY", "indicator": "EBITDA_margin", "value": "18.8079", "value_date": "2016-12-31"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:13:22", "currency": "CNY", "indicator": "Net_Profit_Margin", "value": "2.7325", "value_dat +2026-01-12 18:13:22,781 - app.clients.bloomberg_client - INFO - ✅ Parsed 175 items from remote. +2026-01-12 18:13:42,509 - app.clients.bloomberg_client - INFO - ✅ Saved 175 records to database. +2026-01-12 18:13:42,510 - app.clients.bloomberg_client - INFO - Fetching Price Data (Aligned)... +2026-01-12 18:13:42,510 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=79, Msg=正在获取价格指标..., Progress=69% +2026-01-12 18:13:43,034 - app.clients.bloomberg_client - INFO - Found 9 revenue reporting dates. Fetching aligned price data... +2026-01-12 18:13:53,991 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:13:43", "currency": "CNY", "indicator": "Last_Price", "value": "4.39", "value_date": "2024-12-31"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:13:43", "currency": "CNY", "indicator": "Market_Cap", "value": "163990.883", "value_date": "2024-12-31"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:13:43", "currency": "CNY", "indicator": "Dividend_Yield", "value": "0.6834", "value_date": "2024-12-31"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:13:43", "currency": "CNY", "indicator": "Last_Price", "value": "3.9", "value_date": "2023-12-31"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:13:43", "currency": "CNY", "indicator": "Market_Cap", "value": "145742.6957", "value_date": "2023-12-31"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:13:43", "currency": "CNY", "indicator": "Dividend_Yield", "value": " +2026-01-12 18:13:53,992 - app.clients.bloomberg_client - INFO - ✅ Parsed 27 items from remote. +2026-01-12 18:13:56,649 - app.clients.bloomberg_client - INFO - ✅ Saved 27 records to database. +2026-01-12 18:13:56,649 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=79, Msg=Finalizing data..., Progress=82% +2026-01-12 18:13:59,126 - app.clients.bloomberg_client - INFO - ✅ Cleanup and View Refresh completed. +2026-01-12 18:13:59,127 - app.clients.bloomberg_client - INFO - ✅ Completed processing for 000725 CH Equity +2026-01-12 18:13:59,127 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=79, Msg=Bloomberg data sync complete, Progress=90% +2026-01-12 18:13:59,568 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=79, Msg=Bloomberg 数据同步完成, Progress=100% +2026-01-12 18:50:10,831 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=80, Msg=正在初始化数据获取..., Progress=0% +2026-01-12 18:50:11,898 - app.clients.bloomberg_client - INFO - Connecting to Jupyter at http://192.168.3.161:8888... +2026-01-12 18:50:12,774 - app.clients.bloomberg_client - INFO - ✅ Authentication successful. +2026-01-12 18:50:12,816 - app.clients.bloomberg_client - INFO - ✅ Found existing kernel: bc27f3b1-b028-434a-99fa-c1cad4495a87 (remote_env) +2026-01-12 18:50:12,900 - app.clients.bloomberg_client - INFO - ✅ WebSocket connected. +2026-01-12 18:50:12,900 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=80, Msg=数据源连接成功, Progress=10% +2026-01-12 18:50:13,188 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=80, Msg=正在连接 Bloomberg 终端..., Progress=20% +2026-01-12 18:50:13,808 - app.clients.bloomberg_client - INFO - 🚀 Starting fetch for: 000725 CH Equity +2026-01-12 18:50:13,808 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=80, Msg=Starting Bloomberg session..., Progress=20% +2026-01-12 18:50:14,304 - app.clients.bloomberg_client - INFO - Using auto-detected currency: CNY +2026-01-12 18:50:14,305 - app.clients.bloomberg_client - INFO - Fetching Basic Data... +2026-01-12 18:50:14,305 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=80, Msg=Fetching Company Basic Info..., Progress=27% +2026-01-12 18:50:16,663 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:50:17", "currency": "CNY", "indicator": "company_name", "value": "BOE TECHNOLOGY GROUP CO LT-A", "value_date": "2026-01-12 18:50:17"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:50:17", "currency": "CNY", "indicator": "pe_ratio", "value": "25.959361598462067", "value_date": "2026-01-12 18:50:17"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:50:17", "currency": "CNY", "indicator": "pb_ratio", "value": "1.2417412746613823", "value_date": "2026-01-12 18:50:17"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:50:17", "currency": "CNY", "indicator": "Rev_Abroad", "value": "49.83268989557015", "value_date": "2026-01-12 18:50:17"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:50:17", "currency": "CNY", "indicator": "dividend_yield", "value": "1.1210762498891942", "value_date": "2026-01-12 18:50:17"}, {"Company_code": "000725 CH +2026-01-12 18:50:16,664 - app.clients.bloomberg_client - INFO - ✅ Parsed 7 items from remote. +2026-01-12 18:50:16,664 - app.clients.bloomberg_client - INFO - DEBUG: basic_data before save: [{'Company_code': '000725 CH Equity', 'update_date': '2026-01-12 18:50:17', 'currency': 'CNY', 'indicator': 'company_name', 'value': 'BOE TECHNOLOGY GROUP CO LT-A', 'value_date': '2026-01-12 18:50:17'}, {'Company_code': '000725 CH Equity', 'update_date': '2026-01-12 18:50:17', 'currency': 'CNY', 'indicator': 'pe_ratio', 'value': '25.959361598462067', 'value_date': '2026-01-12 18:50:17'}, {'Company_code': '000725 CH Equity', 'update_date': '2026-01-12 18:50:17', 'currency': 'CNY', 'indicator': 'pb_ratio', 'value': '1.2417412746613823', 'value_date': '2026-01-12 18:50:17'}, {'Company_code': '000725 CH Equity', 'update_date': '2026-01-12 18:50:17', 'currency': 'CNY', 'indicator': 'Rev_Abroad', 'value': '49.83268989557015', 'value_date': '2026-01-12 18:50:17'}, {'Company_code': '000725 CH Equity', 'update_date': '2026-01-12 18:50:17', 'currency': 'CNY', 'indicator': 'dividend_yield', 'value': '1.1210762498891942', 'value_date': '2026-01-12 18:50:17'}, {'Company_code': '000725 CH Equity', 'update_date': '2026-01-12 18:50:17', 'currency': 'CNY', 'indicator': 'IPO_date', 'value': '2001-01-12', 'value_date': '2026-01-12 18:50:17'}, {'Company_code': '000725 CH Equity', 'update_date': '2026-01-12 18:50:17', 'currency': 'CNY', 'indicator': 'market_cap', 'value': '164036.2257', 'value_date': '2026-01-12 18:50:17'}] +2026-01-12 18:50:17,449 - app.clients.bloomberg_client - INFO - ✅ Saved 7 records to database. +2026-01-12 18:50:17,449 - app.clients.bloomberg_client - INFO - Fetching Currency Data... +2026-01-12 18:50:17,450 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=80, Msg=正在获取货币指标 (CNY)..., Progress=41% +2026-01-12 18:50:18,858 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:50:18", "currency": "CNY", "indicator": "Revenue", "value": "68895.659", "value_date": "2016-12-31"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:50:18", "currency": "CNY", "indicator": "Net_Income", "value": "1882.5717", "value_date": "2016-12-31"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:50:18", "currency": "CNY", "indicator": "Cash_From_Operating", "value": "8308.9467", "value_date": "2016-12-31"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:50:18", "currency": "CNY", "indicator": "Capital_Expenditure", "value": "-30702.6147", "value_date": "2016-12-31"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:50:18", "currency": "CNY", "indicator": "Free_Cash_Flow", "value": "-22393.668", "value_date": "2016-12-31"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:50:18", "currency": "CNY", "indicator": +2026-01-12 18:50:18,864 - app.clients.bloomberg_client - INFO - ✅ Parsed 225 items from remote. +2026-01-12 18:50:41,919 - app.clients.bloomberg_client - INFO - ✅ Saved 225 records to database. +2026-01-12 18:50:41,920 - app.clients.bloomberg_client - INFO - Fetching Non-Currency Data... +2026-01-12 18:50:41,920 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=80, Msg=正在获取非货币指标..., Progress=55% +2026-01-12 18:50:43,550 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:50:43", "currency": "CNY", "indicator": "ROE", "value": "2.4107", "value_date": "2016-12-31"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:50:43", "currency": "CNY", "indicator": "ROA", "value": "1.0525", "value_date": "2016-12-31"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:50:43", "currency": "CNY", "indicator": "ROCE", "value": "2.905", "value_date": "2016-12-31"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:50:43", "currency": "CNY", "indicator": "Gross_Margin", "value": "17.8675", "value_date": "2016-12-31"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:50:43", "currency": "CNY", "indicator": "EBITDA_margin", "value": "18.8079", "value_date": "2016-12-31"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:50:43", "currency": "CNY", "indicator": "Net_Profit_Margin", "value": "2.7325", "value_dat +2026-01-12 18:50:43,551 - app.clients.bloomberg_client - INFO - ✅ Parsed 175 items from remote. +2026-01-12 18:51:00,614 - app.clients.bloomberg_client - INFO - ✅ Saved 175 records to database. +2026-01-12 18:51:00,616 - app.clients.bloomberg_client - INFO - Fetching Price Data (Aligned)... +2026-01-12 18:51:00,616 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=80, Msg=正在获取价格指标..., Progress=69% +2026-01-12 18:51:01,579 - app.clients.bloomberg_client - INFO - Found 9 revenue reporting dates. Fetching aligned price data... +2026-01-12 18:51:12,149 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:51:01", "currency": "CNY", "indicator": "Last_Price", "value": "4.39", "value_date": "2024-12-31"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:51:01", "currency": "CNY", "indicator": "Market_Cap", "value": "163990.883", "value_date": "2024-12-31"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:51:01", "currency": "CNY", "indicator": "Dividend_Yield", "value": "0.6834", "value_date": "2024-12-31"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:51:01", "currency": "CNY", "indicator": "Last_Price", "value": "3.9", "value_date": "2023-12-31"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:51:01", "currency": "CNY", "indicator": "Market_Cap", "value": "145742.6957", "value_date": "2023-12-31"}, {"Company_code": "000725 CH Equity", "update_date": "2026-01-12 18:51:01", "currency": "CNY", "indicator": "Dividend_Yield", "value": " +2026-01-12 18:51:12,150 - app.clients.bloomberg_client - INFO - ✅ Parsed 27 items from remote. +2026-01-12 18:51:20,135 - app.clients.bloomberg_client - INFO - ✅ Saved 27 records to database. +2026-01-12 18:51:20,137 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=80, Msg=Finalizing data..., Progress=82% +2026-01-12 18:51:21,801 - app.clients.bloomberg_client - INFO - ✅ Cleanup and View Refresh completed. +2026-01-12 18:51:21,802 - app.clients.bloomberg_client - INFO - ✅ Completed processing for 000725 CH Equity +2026-01-12 18:51:21,803 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=80, Msg=Bloomberg data sync complete, Progress=90% +2026-01-12 18:51:24,153 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=80, Msg=Bloomberg 数据同步完成, Progress=100% +2026-01-12 19:07:13,245 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=81, Msg=正在初始化数据获取..., Progress=0% +2026-01-12 19:07:15,033 - app.clients.bloomberg_client - INFO - Connecting to Jupyter at http://192.168.3.161:8888... +2026-01-12 19:07:16,023 - app.clients.bloomberg_client - INFO - ✅ Authentication successful. +2026-01-12 19:07:16,065 - app.clients.bloomberg_client - INFO - ✅ Found existing kernel: bc27f3b1-b028-434a-99fa-c1cad4495a87 (remote_env) +2026-01-12 19:07:16,139 - app.clients.bloomberg_client - INFO - ✅ WebSocket connected. +2026-01-12 19:07:16,140 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=81, Msg=数据源连接成功, Progress=10% +2026-01-12 19:07:17,324 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=81, Msg=正在连接 Bloomberg 终端..., Progress=20% +2026-01-12 19:07:18,445 - app.clients.bloomberg_client - INFO - 🚀 Starting fetch for: 00631 HK Equity +2026-01-12 19:07:18,447 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=81, Msg=Starting Bloomberg session..., Progress=20% +2026-01-12 19:07:19,414 - app.clients.bloomberg_client - INFO - Using auto-detected currency: HKD +2026-01-12 19:07:19,414 - app.clients.bloomberg_client - INFO - Fetching Basic Data... +2026-01-12 19:07:19,415 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=81, Msg=Fetching Company Basic Info..., Progress=27% +2026-01-12 19:07:22,487 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "00631 HK Equity", "update_date": "2026-01-12 19:07:23", "currency": "HKD", "indicator": "company_name", "value": "SANY HEAVY EQUIPMENT INTL", "value_date": "2026-01-12 19:07:23"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 19:07:23", "currency": "HKD", "indicator": "pe_ratio", "value": "19.933741441016245", "value_date": "2026-01-12 19:07:23"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 19:07:23", "currency": "HKD", "indicator": "pb_ratio", "value": "2.110479881831945", "value_date": "2026-01-12 19:07:23"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 19:07:23", "currency": "HKD", "indicator": "Rev_Abroad", "value": "37.287945521334656", "value_date": "2026-01-12 19:07:23"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 19:07:23", "currency": "HKD", "indicator": "dividend_yield", "value": "3.162486277593781", "value_date": "2026-01-12 19:07:23"}, {"Company_code": "00631 HK Equity", +2026-01-12 19:07:22,488 - app.clients.bloomberg_client - INFO - ✅ Parsed 7 items from remote. +2026-01-12 19:07:22,488 - app.clients.bloomberg_client - INFO - DEBUG: basic_data before save: [{'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 19:07:23', 'currency': 'HKD', 'indicator': 'company_name', 'value': 'SANY HEAVY EQUIPMENT INTL', 'value_date': '2026-01-12 19:07:23'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 19:07:23', 'currency': 'HKD', 'indicator': 'pe_ratio', 'value': '19.933741441016245', 'value_date': '2026-01-12 19:07:23'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 19:07:23', 'currency': 'HKD', 'indicator': 'pb_ratio', 'value': '2.110479881831945', 'value_date': '2026-01-12 19:07:23'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 19:07:23', 'currency': 'HKD', 'indicator': 'Rev_Abroad', 'value': '37.287945521334656', 'value_date': '2026-01-12 19:07:23'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 19:07:23', 'currency': 'HKD', 'indicator': 'dividend_yield', 'value': '3.162486277593781', 'value_date': '2026-01-12 19:07:23'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 19:07:23', 'currency': 'HKD', 'indicator': 'IPO_date', 'value': '2009-11-25', 'value_date': '2026-01-12 19:07:23'}, {'Company_code': '00631 HK Equity', 'update_date': '2026-01-12 19:07:23', 'currency': 'HKD', 'indicator': 'market_cap', 'value': '29641.2727', 'value_date': '2026-01-12 19:07:23'}] +2026-01-12 19:07:23,816 - app.clients.bloomberg_client - INFO - ✅ Saved 7 records to database. +2026-01-12 19:07:23,818 - app.clients.bloomberg_client - INFO - Fetching Currency Data... +2026-01-12 19:07:23,818 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=81, Msg=正在获取货币指标 (HKD)..., Progress=41% +2026-01-12 19:07:26,292 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "00631 HK Equity", "update_date": "2026-01-12 19:07:24", "currency": "HKD", "indicator": "Revenue", "value": "2152.9812", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 19:07:24", "currency": "HKD", "indicator": "Net_Income", "value": "-753.2314", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 19:07:24", "currency": "HKD", "indicator": "Cash_From_Operating", "value": "1557.419", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 19:07:24", "currency": "HKD", "indicator": "Capital_Expenditure", "value": "-179.3705", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 19:07:24", "currency": "HKD", "indicator": "Free_Cash_Flow", "value": "1378.0485", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 19:07:24", "currency": "HKD", "indicator": "Dividend +2026-01-12 19:07:26,293 - app.clients.bloomberg_client - INFO - ✅ Parsed 213 items from remote. +2026-01-12 19:07:47,000 - app.clients.bloomberg_client - INFO - ✅ Saved 213 records to database. +2026-01-12 19:07:47,006 - app.clients.bloomberg_client - INFO - Fetching Non-Currency Data... +2026-01-12 19:07:47,006 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=81, Msg=正在获取非货币指标..., Progress=55% +2026-01-12 19:07:48,166 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "00631 HK Equity", "update_date": "2026-01-12 19:07:47", "currency": "HKD", "indicator": "ROE", "value": "-10.132", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 19:07:47", "currency": "HKD", "indicator": "ROA", "value": "-6.0025", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 19:07:47", "currency": "HKD", "indicator": "Gross_Margin", "value": "14.994", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 19:07:47", "currency": "HKD", "indicator": "EBITDA_margin", "value": "-28.2708", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 19:07:47", "currency": "HKD", "indicator": "Net_Profit_Margin", "value": "-34.9855", "value_date": "2016-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 19:07:47", "currency": "HKD", "indicator": "Tax_Rate", "value": "0.25", "value_da +2026-01-12 19:07:48,168 - app.clients.bloomberg_client - INFO - ✅ Parsed 150 items from remote. +2026-01-12 19:08:07,614 - app.clients.bloomberg_client - INFO - ✅ Saved 150 records to database. +2026-01-12 19:08:07,618 - app.clients.bloomberg_client - INFO - Fetching Price Data (Aligned)... +2026-01-12 19:08:07,619 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=81, Msg=正在获取价格指标..., Progress=69% +2026-01-12 19:08:08,123 - app.clients.bloomberg_client - INFO - Found 9 revenue reporting dates. Fetching aligned price data... +2026-01-12 19:08:18,378 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "00631 HK Equity", "update_date": "2026-01-12 19:08:08", "currency": "HKD", "indicator": "Last_Price", "value": "4.51", "value_date": "2024-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 19:08:08", "currency": "HKD", "indicator": "Market_Cap", "value": "14494.6462", "value_date": "2024-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 19:08:08", "currency": "HKD", "indicator": "Dividend_Yield", "value": "4.2129", "value_date": "2024-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 19:08:08", "currency": "HKD", "indicator": "Last_Price", "value": "7.55", "value_date": "2023-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 19:08:08", "currency": "HKD", "indicator": "Market_Cap", "value": "24081.9354", "value_date": "2023-12-31"}, {"Company_code": "00631 HK Equity", "update_date": "2026-01-12 19:08:08", "currency": "HKD", "indicator": "Dividend_Yield", "value": "2.5166 +2026-01-12 19:08:18,379 - app.clients.bloomberg_client - INFO - ✅ Parsed 25 items from remote. +2026-01-12 19:08:23,531 - app.clients.bloomberg_client - INFO - ✅ Saved 25 records to database. +2026-01-12 19:08:23,532 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=81, Msg=Finalizing data..., Progress=82% +2026-01-12 19:08:25,393 - app.clients.bloomberg_client - INFO - ✅ Cleanup and View Refresh completed. +2026-01-12 19:08:25,394 - app.clients.bloomberg_client - INFO - ✅ Completed processing for 00631 HK Equity +2026-01-12 19:08:25,394 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=81, Msg=Bloomberg data sync complete, Progress=90% +2026-01-12 19:08:26,834 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=81, Msg=Bloomberg 数据同步完成, Progress=100% diff --git a/backend/test_bloomberg_market_cap.py b/backend/test_bloomberg_market_cap.py new file mode 100644 index 0000000..71bba51 --- /dev/null +++ b/backend/test_bloomberg_market_cap.py @@ -0,0 +1,61 @@ + +import sys +import os +import logging +import json +from datetime import datetime, timedelta + +# Add app to path +sys.path.append(os.path.join(os.path.dirname(__file__), 'app')) + +from app.clients.bloomberg_client import BloombergClient + +# Config logging +logging.basicConfig(level=logging.INFO) + +def test_market_cap(): + print("Initializing Client...") + client = BloombergClient() + + # Target: 6301 JP Equity (Komatsu Ltd) + company_code = "6301 JP Equity" + + # Dates to fetch (last few years) + dates = ["2023-03-31", "2024-03-31"] # Komatsu fiscal year end is usually March 31 + + # 1. Fetch in JPY (Local) + print("\nfetching Market Cap in JPY...") + try: + data_jpy = client._fetch_price_by_dates_remote( + company_code=company_code, + currency="JPY", + dates=dates, + query_ticker=company_code + ) + print("--- Result JPY ---") + print(json.dumps(data_jpy, indent=2, ensure_ascii=False)) + except Exception as e: + print(f"Error JPY: {e}") + + # 2. Fetch in CNY (Converted) - Using Series Remote (Fallback Path) + print("\nfetching Market Cap in CNY (Series Remote Fallback)...") + try: + from app.clients.bloomberg_client import PRICE_CONFIG + + # We need to simulate the fallback call: + # price_data = self._fetch_series_remote(company_code, currency, PRICE_CONFIG, "price", query_ticker=query_ticker) + + data_cny = client._fetch_series_remote( + company_code=company_code, + currency="CNY", + config_dict=PRICE_CONFIG, + result_type="price", + query_ticker=company_code + ) + print("--- Result CNY (Series) ---") + print(json.dumps(data_cny[:5], indent=2, ensure_ascii=False)) + except Exception as e: + print(f"Error CNY: {e}") + +if __name__ == "__main__": + test_market_cap() diff --git a/backend/test_bloomberg_series.py b/backend/test_bloomberg_series.py new file mode 100644 index 0000000..e74d6a2 --- /dev/null +++ b/backend/test_bloomberg_series.py @@ -0,0 +1,66 @@ + +import sys +import os +import logging +import json +from datetime import datetime, timedelta + +# Add app to path +sys.path.append(os.path.join(os.path.dirname(__file__), 'app')) + +from app.clients.bloomberg_client import BloombergClient + +# Config logging +logging.basicConfig(level=logging.INFO) + +def test_series(): + print("Initializing Client...") + client = BloombergClient() + + # Simulate the logic in fetch_company for HK + symbol = "00631" + market = "HK" + + # 1. Ticker Logic + mapped_market = "CH" if market == "CN" else market + company_code = f"{symbol} {mapped_market} Equity" # "00631 HK Equity" + + query_ticker = company_code + if market == "HK" or (len(company_code.split()) > 1 and company_code.split()[1] == "HK"): + parts = company_code.split() + ticker_part = parts[0] + if ticker_part.isdigit(): + short_ticker = str(int(ticker_part)) + query_ticker = f"{short_ticker} {' '.join(parts[1:])}" # "631 HK Equity" + + print(f"Company Code (Storage): {company_code}") + print(f"Query Ticker (Bloomberg): {query_ticker}") + + currency = "HKD" + + # 2. Test Currency Data Fetch (Revenue) + print("\nfetching Currency Data (Series)...") + curr_indicators = { + "Revenue": "SALES_REV_TURN" + } + + try: + # Call the internal method directly + data = client._fetch_series_remote( + company_code=company_code, + currency=currency, + config_dict=curr_indicators, + result_type="currency", + query_ticker=query_ticker + ) + print("--- Result (First 5 items) ---") + print(json.dumps(data[:5], indent=2, ensure_ascii=False)) + print(f"Total items: {len(data)}") + except Exception as e: + print(f"Error: {e}") + + except Exception as e: + print(f"Error: {e}") + +if __name__ == "__main__": + test_series() diff --git a/backend/verify_currency.py b/backend/verify_currency.py new file mode 100644 index 0000000..b63559b --- /dev/null +++ b/backend/verify_currency.py @@ -0,0 +1,57 @@ + +import sys +import asyncio +from app.clients.bloomberg_client import BloombergClient + +async def run(): + client = BloombergClient() + company = "2503 JP Equity" + + # We want to check 2024-12-31 data for JPY, CNY, USD + currencies = ["JPY", "CNY", "USD"] + + print(f"Testing Market Cap for {company} on 2024-12-31 in {currencies}") + + remote_code = f""" +def test_currency(): + company = "{company}" + currencies = {currencies} + date = "20241231" + + results = {{}} + + try: + for curr in currencies: + print(f"Fetching for {{curr}}...") + # Use BDH for historical specific date + df = bquery.bdh( + [company], + ['CUR_MKT_CAP'], + start_date=date, + end_date=date, + options={{'currency': curr, 'periodicitySelection': 'DAILY', 'nonTradingDayFillOption': 'ALL_CALENDAR_DAYS', 'nonTradingDayFillMethod': 'PREVIOUS_VALUE'}} + ) + + if not df.empty and 'CUR_MKT_CAP' in df.columns: + val = df['CUR_MKT_CAP'].iloc[0] + results[curr] = val + else: + results[curr] = "No Data" + + except Exception as e: + print(f"Error: {{e}}") + + import json + print("JSON_START") + print(json.dumps(results)) + print("JSON_END") + +test_currency() +""" + + result = client.execute_remote_code(remote_code) + print("\nCheck Result:") + print(result) + +if __name__ == "__main__": + asyncio.run(run()) diff --git a/backend/verify_historical_currency.py b/backend/verify_historical_currency.py new file mode 100644 index 0000000..6011922 --- /dev/null +++ b/backend/verify_historical_currency.py @@ -0,0 +1,41 @@ + +import sys +import asyncio +import json +from app.clients.bloomberg_client import BloombergClient + +# Mock the PRICE_CONFIG to ensure we are fetching what we expect if it's not imported +# But BloombergClient imports it from configuration. +# Let's rely on the real client. + +async def run(): + client = BloombergClient() + company = "2503 JP Equity" + dates = ['2024-12-31', '2023-12-31', '2022-12-31', '2021-12-31', '2020-12-31', '2019-12-31', '2018-12-31', '2017-12-31', '2016-12-31'] + + currencies = ["CNY"] + + print(f"Testing _fetch_price_by_dates_remote for {company} on {dates}...") + + for curr in currencies: + print(f"\n--- Fetching in {curr} ---") + try: + # The method allows fetching price data for specific dates + # It uses PRICE_CONFIG which includes 'Market_Cap' + data = client._fetch_price_by_dates_remote(company, curr, dates) + + # Filter for Market_Cap to show user + mkt_caps = [d for d in data if d['indicator'] == 'Market_Cap'] + + if mkt_caps: + for item in mkt_caps: + print(f"Currency: {item['currency']}, Date: {item['value_date']}, Value: {item['value']}") + else: + print("No Market_Cap data returned.") + print("Raw data returned:", json.dumps(data, indent=2)) + + except Exception as e: + print(f"Error fetching {curr}: {e}") + +if __name__ == "__main__": + asyncio.run(run()) diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx index 2d56423..a5e042c 100644 --- a/frontend/src/app/page.tsx +++ b/frontend/src/app/page.tsx @@ -19,6 +19,8 @@ import { Progress } from "@/components/ui/progress" import { formatTimestamp } from "@/lib/formatters" import { BloombergView } from "@/components/bloomberg-view" import { HeaderPortal } from "@/components/header-portal" +import { AppSidebar } from "@/components/app-sidebar" +import { StockChart } from "@/components/stock-chart" export default function Home() { const searchParams = useSearchParams() @@ -27,18 +29,23 @@ export default function Home() { const [selectedCompany, setSelectedCompany] = useState(null) const [selectedDataSource, setSelectedDataSource] = useState("iFinD") const [companyId, setCompanyId] = useState(null) - const [showFinancialData, setShowFinancialData] = useState(false) const [analysisId, setAnalysisId] = useState(null) const [oneTimeModel, setOneTimeModel] = useState(undefined) + const [currency, setCurrency] = useState("Auto") + + // View State (home, financial, chart) + const [currentView, setCurrentView] = useState("home") // 处理公司选择 const handleCompanySelect = (company: SearchResult, dataSource?: string) => { setSelectedCompany(company) setCompanyId(null) - setShowFinancialData(false) setAnalysisId(null) setOneTimeModel(undefined) + // Switch to financial view by default when company is selected + setCurrentView("financial") + // 如果没有传入数据源,则根据市场设置默认值 const targetDataSource = dataSource || (company.market === 'CN' ? 'Tushare' : 'iFinD') setSelectedDataSource(targetDataSource) @@ -64,7 +71,6 @@ export default function Home() { // 数据准备就绪 const handleDataReady = (id: number) => { setCompanyId(id) - setShowFinancialData(true) } // AI分析完成 @@ -72,20 +78,30 @@ export default function Home() { setAnalysisId(id) } - // 返回搜索 + // 返回搜索 (Reset) const handleBackToSearch = () => { setSelectedCompany(null) setCompanyId(null) - setShowFinancialData(false) setAnalysisId(null) setOneTimeModel(undefined) + setCurrentView("home") } - return ( -
- {/* 标题和描述 */} - {!selectedCompany && ( -
+ // Navigation Handler + const handleTabChange = (tab: string) => { + if (tab === "home") { + handleBackToSearch() + } else { + setCurrentView(tab) + } + } + + // Render Content based on View + const renderContent = () => { + // Home View + if (!selectedCompany || currentView === "home") { + return ( +

股票分析

@@ -98,183 +114,220 @@ export default function Home() {

- {/* 最近的报告 */} -
-

最近的报告

- + {/* 历史记录 */} +
+
- )} + ) + } - {selectedCompany && ( -
- + // Chart View + if (currentView === "chart") { + return ( +
+ {/* Top Navigation for Chart View */} +
+
+ +
+

{selectedCompany.company_name}

+ {selectedCompany.symbol} + {selectedCompany.market} +
+
+
+
- )} + ) + } + + // Financial Data View (Default fallback) + return ( +
+ {/* 顶部导航栏 (Portal Target) */} + +
+ {/* 数据源选择 */} +
+
+ +
+ + {/* 数据获取状态 */} + +
+
+
+ ) + } + + return ( +
+ {/* Sidebar */} + + + {/* Main Content Area */} +
+ {renderContent()} +
) } -// 拆分出单独的组件以使用Hooks +// ---------------------------------------------------------------------- +// Sub-components +// ---------------------------------------------------------------------- + function CompanyAnalysisView({ company, dataSource, - onBack, - onDataSourceChange, - oneTimeModel + onDataReady, + onAnalysisComplete, + selectedModel, + currency, + setCurrency }: { - company: SearchResult, - dataSource: string, - onBack: () => void, - onDataSourceChange: (ds: string) => void, - oneTimeModel?: string + company: SearchResult + dataSource: string + onDataReady: (id: number) => void + onAnalysisComplete: (id: number) => void + selectedModel?: string + currency: string + setCurrency: (c: string) => void }) { + const { status, loading, fetching, - updateStatus, error, fetchData, - checkStatus + checkStatus, + updateStatus } = useFinancialData(company, dataSource) - const [companyId, setCompanyId] = useState(null) - const [analysisId, setAnalysisId] = useState(null) + const progress = updateStatus ? { + percentage: updateStatus.progress_percentage || 0, + message: updateStatus.progress_message || "" + } : null - // 当数据就绪时设置companyId useEffect(() => { - if (status?.has_data && status.company_id) { - setCompanyId(status.company_id) - } else { - setCompanyId(null) + if (status && status.has_data && status.company_id) { + onDataReady(status.company_id) } - }, [status]) - - const handleAnalysisComplete = (id: number) => { - setAnalysisId(id) - } - - const isUpdating = fetching && updateStatus - const progress = updateStatus?.progress_percentage || 0 - const progressStatus = updateStatus?.progress_message || "" - - const [currency, setCurrency] = useState("Auto") + }, [status, onDataReady]) return (
+ + {/* Header Controls */} -
- {/* 0. Operation Buttons (Update Data) */} - - - {/* 0.5 Currency Selector */} -
- {["Auto", "CNY", "USD"].map((curr) => ( - - ))} -
- - {/* 1. Status Display */} -
- {isUpdating ? ( -
- {Math.round(progress)}% - {progressStatus || "Processing..."} -
- ) : ( - status?.has_data && status.last_update && ( -
- - 已更新: {formatTimestamp(status.last_update.date)} -
- ) - )} -
- - {/* 2. 公司基础信息 */} -
- {company.company_name} - {company.market} {company.symbol} -
- +
+ {company.company_name} + {company.symbol} + {company.market}
+
+ +
+ +
+ {["Auto", "CNY", "USD"].map((opt) => ( + + ))} +
+ + {fetching && ( +
+ + {progress?.message || "准备中..."} + + +
+ )} + + {!fetching && !loading &&
+ 已更新: {status?.last_update?.date ? formatTimestamp(status.last_update.date) : "无记录"} +
} - {/* 数据状态详情 (Card) */} + {/* DataStatusCard usage removed because it duplicates logic and caused prop mismatch. + Status is now handled by HeaderPortal controls. + */} + {error && ( +
+ {/* Reuse icon or AlertCircle */} + {error} +
+ )} - - {/* 财务数据表格 */} - {status?.has_data && companyId && ( - dataSource === 'Bloomberg' ? ( + {dataSource === 'Bloomberg' ? ( + status?.company_id && ( - ) : ( + ) + ) : ( + status?.company_id && ( ) )} - - {/* AI 分析触发器 */} - {status?.has_data && companyId && !analysisId && ( - - )} - - {/* AI 分析报告 */} - {analysisId && ( - - )}
) } - -// 搜索组件的包装器,添加选择功能 -function SearchStockWithSelection({ onSelect }: { onSelect: (company: SearchResult) => void }) { +function SearchStockWithSelection({ onSelect }: { onSelect: (c: SearchResult, s?: string) => void }) { return ( - 开始新的分析 + 搜索股票 diff --git a/frontend/src/components/app-sidebar.tsx b/frontend/src/components/app-sidebar.tsx new file mode 100644 index 0000000..f08a77a --- /dev/null +++ b/frontend/src/components/app-sidebar.tsx @@ -0,0 +1,41 @@ + +import { Home, LineChart, BarChart3, Search } from "lucide-react" +import { cn } from "@/lib/utils" +import { Button } from "@/components/ui/button" + +interface AppSidebarProps { + activeTab: string + onTabChange: (tab: string) => void + className?: string + hasSelectedCompany: boolean +} + +export function AppSidebar({ activeTab, onTabChange, className, hasSelectedCompany }: AppSidebarProps) { + const navItems = [ + { id: "home", label: "首页", icon: Home, disabled: false }, + { id: "financial", label: "财务数据", icon: BarChart3, disabled: !hasSelectedCompany }, + { id: "chart", label: "股价图", icon: LineChart, disabled: !hasSelectedCompany }, + ] + + return ( +
+ + {navItems.map((item) => ( + + ))} +
+ ) +} diff --git a/frontend/src/components/bloomberg-view.tsx b/frontend/src/components/bloomberg-view.tsx index 19988ef..d6c0537 100644 --- a/frontend/src/components/bloomberg-view.tsx +++ b/frontend/src/components/bloomberg-view.tsx @@ -14,14 +14,17 @@ interface BloombergViewProps { onBack?: () => void selectedCurrency?: string userMarket?: string + lastUpdate?: string } -export function BloombergView({ companyId, onBack, selectedCurrency = "Auto", userMarket }: BloombergViewProps) { +export function BloombergView({ companyId, onBack, selectedCurrency = "Auto", userMarket, lastUpdate }: BloombergViewProps) { const [data, setData] = useState(null) const [loading, setLoading] = useState(true) const [error, setError] = useState("") const loadData = async () => { + if (!companyId) return + setLoading(true) setError("") try { @@ -39,7 +42,7 @@ export function BloombergView({ companyId, onBack, selectedCurrency = "Auto", us useEffect(() => { loadData() - }, [companyId]) + }, [companyId, lastUpdate]) if (loading) { return ( @@ -69,16 +72,25 @@ export function BloombergView({ companyId, onBack, selectedCurrency = "Auto", us const mergedData = data.unified_data || [] return ( -
-
-

- - Bloomberg 财务数据总览 -

- +
+
+
+
+

+ + 财务概览 +

+ {/* Insert Inline Header Info here */} + +
+ +
+ +
+
@@ -86,6 +98,150 @@ export function BloombergView({ companyId, onBack, selectedCurrency = "Auto", us ) } +// --------------------------------------------------------------------------- +// Basic Info Header Component +// --------------------------------------------------------------------------- +function BasicInfoHeader({ data, selectedCurrency = "Auto", userMarket }: { data: any[], selectedCurrency?: string, userMarket?: string }) { + if (!data || data.length === 0) return null + + // 1. Determine Target Currency (Logic shared with Table) + let targetCurrency = selectedCurrency + if (targetCurrency === "Auto" && userMarket) { + const market = userMarket.toUpperCase() + if (market.includes("JP")) targetCurrency = "JPY" + else if (market.includes("VN")) targetCurrency = "VND" + else if (market.includes("CN")) targetCurrency = "CNY" + else if (market.includes("HK")) targetCurrency = "HKD" + else targetCurrency = "USD" + } + + // 2. Find Latest Valid Data for each field + // We sort data by date descending to get latest first. + // Note: 'end_date' is the reporting period, 'update_date' is when it was fetched. + // Usually PE/PB/MarketCap are "current" values, so they might be associated with the latest reporting period or a special "current" row. + // Based on bloomberg logic, they are saved as time series. We take the latest available. + + // Sort rows by date descending + const sortedRows = [...data].sort((a, b) => new Date(b.end_date).getTime() - new Date(a.end_date).getTime()) + + // Helper to find first non-null value + const findValue = (keys: string[]) => { + for (const row of sortedRows) { + // Check currency match if required (PE/PB/MarketCap are currency dependent usually, or at least MarketCap is) + // However, PE/PB are ratios. + // Strict currency check for everything to be safe? + if (targetCurrency !== 'Auto') { + if (row.currency && row.currency !== targetCurrency) continue + } else { + // If auto, try to match first row's currency if established, or just take any? + // Let's stick to the targetCurrency logic used in Table which resolved 'Auto' to a specific one if possible. + } + + for (const key of keys) { + if (row[key] !== null && row[key] !== undefined && row[key] !== '') { + return { value: row[key], row } + } + } + } + return null + } + + // Extract Fields + const companyName = findValue(['company_name'])?.value || '-' + + // Find latest update_date from ALL rows matching currency + let maxUpdateDate = '' + for (const row of data) { + if (targetCurrency !== 'Auto' && row.currency && row.currency !== targetCurrency) continue + if (row.update_date && row.update_date > maxUpdateDate) { + maxUpdateDate = row.update_date + } + } + const updateDate = maxUpdateDate + // update_date is a timestamp string "2023-10-xx 10:00:00". User wants "Day only". + const displayDate = updateDate ? formatDate(updateDate) : '-' + + const pe = findValue(['pe', 'pe_ratio'])?.value + const pb = findValue(['pb', 'pb_ratio'])?.value + const marketCapTuple = findValue(['market_cap']) + const marketCap = marketCapTuple?.value + const marketCapCurrency = marketCapTuple?.row?.currency || targetCurrency + + const abroadRev = findValue(['rev_abroad', 'pct_revenue_from_foreign_sources'])?.value + const divYield = findValue(['dividend_yield', 'dividend_12_month_yield'])?.value + const ipoDateRaw = findValue(['ipo_date', 'IPO_date', 'eqy_init_po_dt'])?.value + const ipoDate = ipoDateRaw ? formatDate(ipoDateRaw) : '-' + + // Formatters + const formatRatio = (val: any) => { + if (val === undefined || val === null) return '-' + const num = parseFloat(val) + if (isNaN(num)) return '-' + return num.toFixed(2) + } + + const formatPercent = (val: any) => { + if (val === undefined || val === null) return '-' + const num = parseFloat(val) + if (isNaN(num)) return '-' + return num.toFixed(2) + '%' + } + + const formatMoney = (val: any, currency: string) => { + if (val === undefined || val === null) return '-' + let num = parseFloat(val) + if (isNaN(num)) return '-' + + // Backend now returns Market Cap in Millions for ALL currencies (via BDH). + // To convert Millions to "Yi" (100 Million), we divide by 100. + // This applies uniformly to JPY, USD, CNY, etc. + num = num / 100 + + return num.toLocaleString('en-US', { maximumFractionDigits: 2 }) + ' 亿' + } + + return ( +
+ {/* Group 1: Identity */} +
+ {companyName} +
+ IPO: {ipoDate} + 更新: {displayDate} +
+
+ + {/* Group 2: Key Ratios */} +
+
+ PE + {formatRatio(pe)} +
+
+ PB + {formatRatio(pb)} +
+
+ 股息率 + {formatPercent(divYield)} +
+
+ + {/* Group 3: Market Size & Biz */} +
+
+ 市值 ({marketCapCurrency}) + {formatMoney(marketCap, marketCapCurrency)} +
+
+ 海外收入 + {formatPercent(abroadRev)} +
+
+
+ ) +} + function RawDataTable({ data, title, selectedCurrency = "Auto", userMarket }: { data: any[], title: string, selectedCurrency?: string, userMarket?: string }) { if (!data || data.length === 0) { return ( @@ -418,7 +574,7 @@ function RawDataTable({ data, title, selectedCurrency = "Auto", userMarket }: { } return ( - + {formatCellValue(indicator, value)} ) diff --git a/frontend/src/components/financial-tables.tsx b/frontend/src/components/financial-tables.tsx index 1a4528b..7d8baec 100644 --- a/frontend/src/components/financial-tables.tsx +++ b/frontend/src/components/financial-tables.tsx @@ -155,7 +155,7 @@ function FinancialTable({ data, title }: FinancialTableProps) { {data.map((row, idx) => ( {columns.map((column) => ( - + {formatCellValue(column, row[column])} ))} @@ -220,7 +220,7 @@ function TransposedFinancialTable({ data, title }: FinancialTableProps) { {/* 值 */} {sortedData.map((row, rowIdx) => ( - + {formatCellValue(indicator, row[indicator])} ))} diff --git a/frontend/src/components/history-list.tsx b/frontend/src/components/history-list.tsx index 297ac0f..d9fdfb0 100644 --- a/frontend/src/components/history-list.tsx +++ b/frontend/src/components/history-list.tsx @@ -1,13 +1,17 @@ "use client" import { useEffect, useState } from "react" -import Link from "next/link" import { getReports } from "@/lib/api" import { Badge } from "@/components/ui/badge" import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card" import { Loader2 } from "lucide-react" +import type { SearchResult } from "@/lib/types" -export function HistoryList() { +interface HistoryListProps { + onSelect?: (company: SearchResult, dataSource?: string) => void +} + +export function HistoryList({ onSelect }: HistoryListProps) { const [reports, setReports] = useState([]) const [loading, setLoading] = useState(true) @@ -22,37 +26,47 @@ export function HistoryList() { return (
{reports.map((report: any) => ( - - - - {report.company_name} - - {report.market} {report.symbol} - - - -
- - {new Date(report.created_at).toLocaleString('zh-CN')} - - - {report.status === "completed" ? "已完成" : - report.status === "in_progress" ? "进行中" : - report.status === "failed" ? "失败" : "待处理"} - + { + if (onSelect) { + onSelect({ + symbol: report.symbol, + market: report.market, + company_name: report.company_name + }, report.data_source) + } + }} + > + + {report.company_name} + + {report.market} {report.symbol} + + + +
+ + {new Date(report.created_at).toLocaleString('zh-CN')} + + + {report.status === "completed" ? "已完成" : + report.status === "in_progress" ? "进行中" : + report.status === "failed" ? "失败" : "待处理"} + +
+ {report.ai_model && ( +
+ 模型: {report.ai_model}
- {report.ai_model && ( -
- 模型: {report.ai_model} -
- )} -
-
- + )} + + ))}
) diff --git a/frontend/src/components/nav-header.tsx b/frontend/src/components/nav-header.tsx index fc6380a..eabfcff 100644 --- a/frontend/src/components/nav-header.tsx +++ b/frontend/src/components/nav-header.tsx @@ -105,27 +105,27 @@ export function NavHeader() {
-
+
diff --git a/frontend/src/components/stock-chart.tsx b/frontend/src/components/stock-chart.tsx new file mode 100644 index 0000000..4583cfa --- /dev/null +++ b/frontend/src/components/stock-chart.tsx @@ -0,0 +1,83 @@ + +"use client" + +import { useEffect, useRef, useState } from "react" + +interface StockChartProps { + symbol: string + market: string +} + +export function StockChart({ symbol, market }: StockChartProps) { + const containerRef = useRef(null) + + useEffect(() => { + if (!containerRef.current) return + + // Clear previous widget + containerRef.current.innerHTML = "" + + // Create wrapper for widget + const widgetContainer = document.createElement("div") + widgetContainer.className = "tradingview-widget-container__widget h-full w-full" + containerRef.current.appendChild(widgetContainer) + + const script = document.createElement("script") + script.src = "https://s3.tradingview.com/external-embedding/embed-widget-advanced-chart.js" + script.type = "text/javascript" + script.async = true + + // Map Market/Symbol to TradingView format + let exchange = "NASDAQ" + let tvSymbol = symbol + + if (market === "CN") { + if (symbol.startsWith("6")) exchange = "SSE" + else if (symbol.startsWith("0") || symbol.startsWith("3")) exchange = "SZSE" + else if (symbol.startsWith("4") || symbol.startsWith("8")) exchange = "BSE" + } else if (market === "HK") { + exchange = "HKEX" + // TradingView usually expects HK stocks without leading zeros if they are 4 digits, but let's check. + // Actually HKEX:700 works, HKEX:0700 might work too. Let's try to keep it safe. + tvSymbol = parseInt(symbol).toString() + } else if (market === "JP") { + exchange = "TSE" + } else if (market === "VN") { + exchange = "HOSE" // Primary VN exchange + } else { + // US + exchange = "NASDAQ" // Default, could be NYSE + // Basic heuristic for US + // If 4 chars or more, likely Nasdaq, <=3 likely NYSE? Not 100% accurate but acceptable default. + } + + const fullSymbol = `${exchange}:${tvSymbol}` + + script.innerHTML = JSON.stringify({ + "autosize": true, + "symbol": fullSymbol, + "interval": "D", + "timezone": "Asia/Shanghai", + "theme": "light", + "style": "1", + "locale": "zh_CN", + "enable_publishing": false, + "allow_symbol_change": true, + "calendar": false, + "support_host": "https://www.tradingview.com" + }) + + containerRef.current.appendChild(script) + + }, [symbol, market]) + + return ( +
+
+
+ TradingView Chart by TradingView +
+
+
+ ) +}