国际财务报告赚钱机器指标
This commit is contained in:
316
finance/money-machine-N.py
Normal file
316
finance/money-machine-N.py
Normal file
@ -0,0 +1,316 @@
|
||||
import pandas as pd
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
from datetime import datetime
|
||||
|
||||
try:
|
||||
from WindPy import w
|
||||
WIND_AVAILABLE = True
|
||||
# 启动Wind
|
||||
w.start()
|
||||
if not w.isconnected():
|
||||
WIND_AVAILABLE = False
|
||||
print("❌ 请先启动Wind金融终端")
|
||||
else:
|
||||
print("✅ Wind连接成功")
|
||||
except ImportError:
|
||||
WIND_AVAILABLE = False
|
||||
print("❌ 未安装WindPy库")
|
||||
|
||||
# 设置中文字体
|
||||
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'DejaVu Sans']
|
||||
plt.rcParams['axes.unicode_minus'] = False
|
||||
|
||||
def get_ten_year_financial_data(symbol):
|
||||
"""
|
||||
使用ED-10Y参数获取十年财务数据 - 使用新指标
|
||||
"""
|
||||
if not WIND_AVAILABLE:
|
||||
print("Wind不可用")
|
||||
return None
|
||||
|
||||
# 台积电的Wind代码
|
||||
wind_code = f"{symbol}"
|
||||
|
||||
try:
|
||||
end_date = datetime.now().strftime('%Y-%m-%d')
|
||||
|
||||
print(f"📊 获取 {wind_code} 十年财务数据...")
|
||||
print(f"查询参数: ED-10Y 到 {end_date}")
|
||||
|
||||
# 获取三个指标的数据 - 使用您提供的新参数格式
|
||||
print("获取财务数据 (资本支出、经营性资产现金流、税前利润)...")
|
||||
financial_data = w.wsd(wind_code, "wgsd_capex_ff,wgsd_assets_bus_cf,wgsd_inc_pretax",
|
||||
"ED-10Y", end_date,
|
||||
"unit=1;rptType=1;currencyType=;Period=Y;Days=Alldays;Currency=CNY")
|
||||
|
||||
print(f"数据点数量: {len(financial_data.Data[0]) if financial_data.Data else 0}")
|
||||
|
||||
# 检查数据错误代码
|
||||
print(f"错误代码: {financial_data.ErrorCode}")
|
||||
|
||||
# 创建包含所有数据的DataFrame
|
||||
data_list = []
|
||||
|
||||
if financial_data.Data and len(financial_data.Data) >= 3:
|
||||
# 确定数据长度
|
||||
data_length = min(len(financial_data.Times),
|
||||
len(financial_data.Data[0]),
|
||||
len(financial_data.Data[1]),
|
||||
len(financial_data.Data[2]))
|
||||
print(f"有效数据长度: {data_length}")
|
||||
|
||||
for i in range(data_length):
|
||||
date = financial_data.Times[i]
|
||||
capex_value = financial_data.Data[0][i] # wgsd_capex_ff
|
||||
assets_bus_cf_value = financial_data.Data[1][i] # wgsd_assets_bus_cf
|
||||
pretax_income_value = financial_data.Data[2][i] # wgsd_inc_pretax
|
||||
|
||||
# 计算调整后的资本支出 (wgsd_capex_ff - wgsd_assets_bus_cf)
|
||||
adjusted_capex = None
|
||||
if (capex_value is not None and not np.isnan(capex_value) and
|
||||
assets_bus_cf_value is not None and not np.isnan(assets_bus_cf_value)):
|
||||
adjusted_capex = capex_value - assets_bus_cf_value
|
||||
|
||||
# 计算比率(如果数据有效)- 改为百分比
|
||||
ratio = None
|
||||
is_capex_valid = adjusted_capex is not None and not np.isnan(adjusted_capex)
|
||||
is_profit_valid = pretax_income_value is not None and not np.isnan(pretax_income_value) and pretax_income_value != 0
|
||||
|
||||
if is_capex_valid and is_profit_valid:
|
||||
ratio = (abs(adjusted_capex) / pretax_income_value) * 100 # 乘以100转换为百分比
|
||||
|
||||
data_list.append({
|
||||
'year': date.year,
|
||||
'report_date': date,
|
||||
'wgsd_capex_ff': capex_value,
|
||||
'wgsd_assets_bus_cf': assets_bus_cf_value,
|
||||
'adjusted_capital_expenditure': adjusted_capex, # 调整后的资本支出
|
||||
'pretax_income': pretax_income_value, # 税前利润
|
||||
'capex_to_profit_ratio_pct': ratio, # 百分比比率
|
||||
'is_capex_valid': is_capex_valid,
|
||||
'is_profit_valid': is_profit_valid,
|
||||
'is_ratio_valid': ratio is not None
|
||||
})
|
||||
else:
|
||||
print("❌ 数据获取失败")
|
||||
return None
|
||||
|
||||
df = pd.DataFrame(data_list)
|
||||
|
||||
print(f"✅ 成功获取 {len(df)} 年数据")
|
||||
return df, financial_data
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 数据获取失败: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return None, None
|
||||
|
||||
def print_ten_year_analysis(df, symbol):
|
||||
"""打印十年数据分析"""
|
||||
print(f"\n{'='*80}")
|
||||
print(f"📊 {symbol} - 十年财务数据分析报告")
|
||||
print(f"{'='*80}")
|
||||
|
||||
print(f"\n📈 数据完整性统计:")
|
||||
total_years = len(df)
|
||||
valid_capex = df['is_capex_valid'].sum()
|
||||
valid_profit = df['is_profit_valid'].sum()
|
||||
valid_ratio = df['is_ratio_valid'].sum()
|
||||
|
||||
print(f"总年份数: {total_years}")
|
||||
print(f"有效资本支出年份: {valid_capex} ({valid_capex/total_years*100:.1f}%)")
|
||||
print(f"有效税前利润年份: {valid_profit} ({valid_profit/total_years*100:.1f}%)")
|
||||
print(f"有效比率年份: {valid_ratio} ({valid_ratio/total_years*100:.1f}%)")
|
||||
|
||||
print(f"\n🔍 详细年度数据:")
|
||||
for i, row in df.iterrows():
|
||||
year = row['year']
|
||||
capex_ff_str = f"{row['wgsd_capex_ff']/1e8:8.2f}亿" if row['wgsd_capex_ff'] is not None and not np.isnan(row['wgsd_capex_ff']) else " NaN"
|
||||
assets_cf_str = f"{row['wgsd_assets_bus_cf']/1e8:8.2f}亿" if row['wgsd_assets_bus_cf'] is not None and not np.isnan(row['wgsd_assets_bus_cf']) else " NaN"
|
||||
adjusted_capex_str = f"{row['adjusted_capital_expenditure']/1e8:8.2f}亿" if row['is_capex_valid'] else " NaN"
|
||||
profit_str = f"{row['pretax_income']/1e8:8.2f}亿" if row['is_profit_valid'] else " NaN"
|
||||
ratio_str = f"{row['capex_to_profit_ratio_pct']:6.2f}%" if row['is_ratio_valid'] else " NaN"
|
||||
|
||||
capex_status = "✅" if row['is_capex_valid'] else "❌"
|
||||
profit_status = "✅" if row['is_profit_valid'] else "❌"
|
||||
ratio_status = "✅" if row['is_ratio_valid'] else "❌"
|
||||
|
||||
print(f" {year}年:")
|
||||
print(f" wgsd_capex_ff: {capex_ff_str}")
|
||||
print(f" wgsd_assets_bus_cf: {assets_cf_str}")
|
||||
print(f" 调整后资本支出: {adjusted_capex_str} {capex_status}")
|
||||
print(f" 税前利润: {profit_str} {profit_status}")
|
||||
print(f" 比率: {ratio_str} {ratio_status}")
|
||||
print()
|
||||
|
||||
def analyze_valid_ten_year_data(df, symbol):
|
||||
"""分析十年有效数据"""
|
||||
valid_df = df[df['is_ratio_valid']].copy()
|
||||
|
||||
if valid_df.empty:
|
||||
print(f"\n❌ {symbol} 无有效比率数据")
|
||||
return None
|
||||
|
||||
print(f"\n📊 {symbol} - 有效数据分析 (共{len(valid_df)}年):")
|
||||
print("-" * 60)
|
||||
|
||||
for i, row in valid_df.iterrows():
|
||||
year = row['year']
|
||||
adjusted_capex = row['adjusted_capital_expenditure'] / 1e8
|
||||
profit = row['pretax_income'] / 1e8
|
||||
ratio = row['capex_to_profit_ratio_pct'] # 已经是百分比
|
||||
|
||||
print(f" {year}年: 调整后资本支出 {adjusted_capex:6.2f}亿 / 税前利润 {profit:6.2f}亿 = 比率 {ratio:.2f}%")
|
||||
|
||||
# 统计信息
|
||||
adjusted_capex_mean = valid_df['adjusted_capital_expenditure'].mean() / 1e8
|
||||
profit_mean = valid_df['pretax_income'].mean() / 1e8
|
||||
ratio_mean = valid_df['capex_to_profit_ratio_pct'].mean()
|
||||
ratio_std = valid_df['capex_to_profit_ratio_pct'].std()
|
||||
ratio_min = valid_df['capex_to_profit_ratio_pct'].min()
|
||||
ratio_max = valid_df['capex_to_profit_ratio_pct'].max()
|
||||
|
||||
print(f"\n💡 统计摘要:")
|
||||
print(f" 平均调整后资本支出: {adjusted_capex_mean:.2f} 亿元")
|
||||
print(f" 平均税前利润: {profit_mean:.2f} 亿元")
|
||||
print(f" 平均比率: {ratio_mean:.2f}%")
|
||||
print(f" 比率标准差: {ratio_std:.2f}%")
|
||||
print(f" 比率范围: {ratio_min:.2f}% - {ratio_max:.2f}%")
|
||||
|
||||
return valid_df
|
||||
|
||||
def plot_ten_year_analysis(valid_df, symbol):
|
||||
"""绘制十年分析图表"""
|
||||
if valid_df is None or valid_df.empty:
|
||||
print("❌ 无有效数据可绘制")
|
||||
return
|
||||
|
||||
# 提取数据
|
||||
years = valid_df['year'].tolist()
|
||||
adjusted_capex = valid_df['adjusted_capital_expenditure'] / 1e8 # 转换为亿元
|
||||
profit = valid_df['pretax_income'] / 1e8 # 转换为亿元
|
||||
ratios = valid_df['capex_to_profit_ratio_pct'] # 已经是百分比
|
||||
|
||||
# 创建图表
|
||||
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(14, 15))
|
||||
|
||||
x = np.arange(len(years))
|
||||
|
||||
# 1. 调整后资本支出和税前利润对比
|
||||
bars1 = ax1.bar(x - 0.2, adjusted_capex, 0.4, label='调整后资本支出(亿元)', alpha=0.8, color='#FF6B6B')
|
||||
bars2 = ax1.bar(x + 0.2, profit, 0.4, label='税前利润(亿元)', alpha=0.8, color='#4ECDC4')
|
||||
ax1.set_title(f'{symbol} - 十年调整后资本支出 vs 税前利润', fontsize=14, fontweight='bold')
|
||||
ax1.set_xticks(x)
|
||||
ax1.set_xticklabels(years, rotation=45)
|
||||
ax1.legend()
|
||||
ax1.grid(True, alpha=0.3)
|
||||
|
||||
# 添加数值标签
|
||||
for bar in bars1:
|
||||
height = bar.get_height()
|
||||
ax1.text(bar.get_x() + bar.get_width()/2., height, f'{height:.1f}',
|
||||
ha='center', va='bottom', fontsize=8)
|
||||
|
||||
for bar in bars2:
|
||||
height = bar.get_height()
|
||||
ax1.text(bar.get_x() + bar.get_width()/2., height, f'{height:.0f}',
|
||||
ha='center', va='bottom', fontsize=8)
|
||||
|
||||
# 2. 比率趋势图 - 百分比
|
||||
ax2.plot(x, ratios, 'o-', linewidth=3, markersize=8, color='#45B7D1',
|
||||
markerfacecolor='white', markeredgewidth=2)
|
||||
ax2.axhline(y=ratios.mean(), color='red', linestyle='--', alpha=0.7,
|
||||
label=f'平均比率: {ratios.mean():.2f}%')
|
||||
ax2.set_title(f'{symbol} - 十年调整后资本支出/税前利润比率趋势', fontsize=14, fontweight='bold')
|
||||
ax2.set_xlabel('年份')
|
||||
ax2.set_ylabel('比率 (%)')
|
||||
ax2.set_xticks(x)
|
||||
ax2.set_xticklabels(years, rotation=45)
|
||||
ax2.legend()
|
||||
ax2.grid(True, alpha=0.3)
|
||||
|
||||
# 添加比率数值标签 - 百分比
|
||||
for i, (xi, ratio) in enumerate(zip(x, ratios)):
|
||||
ax2.annotate(f'{ratio:.2f}%', (xi, ratio), textcoords="offset points",
|
||||
xytext=(0,10), ha='center', fontsize=9, fontweight='bold')
|
||||
|
||||
# 3. 比率柱状图 - 百分比
|
||||
colors = ['#FF9999' if ratio > ratios.mean() else '#99FF99' for ratio in ratios]
|
||||
bars3 = ax3.bar(x, ratios, color=colors, alpha=0.8, edgecolor='black', linewidth=0.5)
|
||||
ax3.axhline(y=ratios.mean(), color='red', linestyle='--', alpha=0.7,
|
||||
label=f'平均比率: {ratios.mean():.2f}%')
|
||||
ax3.set_title(f'{symbol} - 十年调整后资本支出/税前利润比率', fontsize=14, fontweight='bold')
|
||||
ax3.set_xlabel('年份')
|
||||
ax3.set_ylabel('比率 (%)')
|
||||
ax3.set_xticks(x)
|
||||
ax3.set_xticklabels(years, rotation=45)
|
||||
ax3.legend()
|
||||
ax3.grid(True, alpha=0.3)
|
||||
|
||||
# 添加比率数值标签 - 百分比
|
||||
for i, (bar, ratio) in enumerate(zip(bars3, ratios)):
|
||||
ax3.text(bar.get_x() + bar.get_width()/2., ratio, f'{ratio:.2f}%',
|
||||
ha='center', va='bottom', fontsize=9, fontweight='bold')
|
||||
|
||||
plt.tight_layout()
|
||||
plt.show()
|
||||
|
||||
def print_financial_insights(valid_df, symbol):
|
||||
"""打印财务洞察"""
|
||||
if valid_df is None or valid_df.empty:
|
||||
return
|
||||
|
||||
avg_ratio = valid_df['capex_to_profit_ratio_pct'].mean() # 已经是百分比
|
||||
|
||||
print(f"\n💡 {symbol} 财务洞察:")
|
||||
print("=" * 50)
|
||||
|
||||
if avg_ratio < 10:
|
||||
insight = "公司资本支出相对税前利润非常保守"
|
||||
explanation = "这表明公司可能处于成熟期,不需要大量资本投入来维持运营"
|
||||
elif avg_ratio < 30:
|
||||
insight = "公司资本支出相对税前利润较为适中"
|
||||
explanation = "公司在维持现有业务的同时进行适度投资"
|
||||
elif avg_ratio < 50:
|
||||
insight = "公司资本支出相对税前利润较高"
|
||||
explanation = "公司可能处于扩张期或进行重大投资项目"
|
||||
else:
|
||||
insight = "公司资本支出相对税前利润非常高"
|
||||
explanation = "这可能表明公司正在进行大规模扩张或面临高资本需求"
|
||||
|
||||
print(f"平均比率: {avg_ratio:.2f}%")
|
||||
print(f"主要特征: {insight}")
|
||||
print(f"含义: {explanation}")
|
||||
|
||||
# 使用示例
|
||||
if __name__ == "__main__":
|
||||
if WIND_AVAILABLE:
|
||||
# 台积电股票代码
|
||||
symbol = "2330.TW" # 台积电在台湾交易所的代码
|
||||
|
||||
print(f"🔍 开始分析 {symbol} (台积电)...")
|
||||
|
||||
# 获取十年数据
|
||||
df, financial_data = get_ten_year_financial_data(symbol)
|
||||
|
||||
if df is not None:
|
||||
# 打印十年数据分析
|
||||
print_ten_year_analysis(df, symbol)
|
||||
|
||||
# 分析有效数据
|
||||
valid_df = analyze_valid_ten_year_data(df, symbol)
|
||||
|
||||
# 绘制图表
|
||||
if valid_df is not None:
|
||||
plot_ten_year_analysis(valid_df, symbol)
|
||||
|
||||
# 打印财务洞察
|
||||
print_financial_insights(valid_df, symbol)
|
||||
|
||||
else:
|
||||
print("❌ 无法获取数据")
|
||||
|
||||
else:
|
||||
print("❌ Wind不可用")
|
||||
Reference in New Issue
Block a user