{
 "cells": [
  {
   "cell_type": "code",
   "id": "initial_id",
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2025-01-10T02:38:31.764906Z",
     "start_time": "2025-01-10T02:38:30.972805Z"
    }
   },
   "source": [
    "import tushare as ts\n",
    "\n",
    "ts_pro = ts.pro_api(token=\"64ebff4fa679167600b905ee45dd88e76f3963c0ff39157f3f085f0e\")"
   ],
   "outputs": [],
   "execution_count": 1
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-09T06:28:32.524630Z",
     "start_time": "2025-01-09T06:27:15.688831Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 从1989年开始循环年份\n",
    "for year in range(2000, 2024):\n",
    "    # ts_pro.balancesheet_vip(period=f\"{year}1231\").to_csv(f\"../temp/财务报表/资产负债表/{year}.csv\")\n",
    "    # ts_pro.cashflow_vip(period=f\"{year}1231\").to_csv(f\"../temp/财务报表/现金流量表/{year}.csv\")\n",
    "    # ts_pro.income_vip(period=f\"{year}1231\").to_csv(f\"../temp/财务报表/利润表/{year}.csv\")\n",
    "    ts_pro.fina_indicator_vip(period=f\"{year}1231\").to_csv(f\"../temp/财务报表/财务指标/{year}.csv\")\n",
    "    # ts_pro.fina_audit(period=f\"{year}1231\").to_csv(f\"../temp/财务报表/审计意见/{year}.csv\")"
   ],
   "id": "b03b118c70b21315",
   "outputs": [],
   "execution_count": 15
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-10T02:54:34.367006Z",
     "start_time": "2025-01-10T02:54:34.363702Z"
    }
   },
   "cell_type": "code",
   "source": "import pandas as pd",
   "id": "7e3783e99491ba52",
   "outputs": [],
   "execution_count": 19
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-10T03:01:43.076024Z",
     "start_time": "2025-01-10T03:01:42.644700Z"
    }
   },
   "cell_type": "code",
   "source": [
    "df_income = ts_pro.income(ts_code=\"600519.SH\", period=\"20231231\", fields=\"ts_code,end_date,n_income\")\n",
    "df_balancesheet = ts_pro.balancesheet(ts_code=\"600519.SH\", period=\"20231231\",\n",
    "                                      fields=\"ts_code,end_date,total_hldr_eqy_exc_min_int\")\n",
    "merged_df = pd.merge(df_income, df_balancesheet, on=['ts_code', 'end_date'])\n",
    "merged_df['roe'] = merged_df['n_income'] / merged_df['total_hldr_eqy_exc_min_int']\n",
    "merged_df"
   ],
   "id": "575590399bf15e70",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "     ts_code  end_date      n_income  total_hldr_eqy_exc_min_int       roe\n",
       "0  600519.SH  20231231  7.752148e+10                2.156686e+11  0.359447"
      ],
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>ts_code</th>\n",
       "      <th>end_date</th>\n",
       "      <th>n_income</th>\n",
       "      <th>total_hldr_eqy_exc_min_int</th>\n",
       "      <th>roe</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>600519.SH</td>\n",
       "      <td>20231231</td>\n",
       "      <td>7.752148e+10</td>\n",
       "      <td>2.156686e+11</td>\n",
       "      <td>0.359447</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 31
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-10T02:59:32.764968Z",
     "start_time": "2025-01-10T02:59:32.601657Z"
    }
   },
   "cell_type": "code",
   "source": "ts_pro.fina_indicator(ts_code=\"600519.SH\", period=\"20231231\")[\"roe\"]",
   "id": "d59f62a613379fbd",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    36.1755\n",
       "Name: roe, dtype: float64"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 26
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-10T04:01:33.511246Z",
     "start_time": "2025-01-10T04:01:33.382955Z"
    }
   },
   "cell_type": "code",
   "source": "ts_pro.income(ts_code='600519.SH', start_date='20220101', end_date='20241231', fields='end_date,n_income')",
   "id": "c43925cfb5552cd9",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "    end_date      n_income\n",
       "0   20240930  6.303146e+10\n",
       "1   20240630  4.317691e+10\n",
       "2   20240331  2.488235e+10\n",
       "3   20231231  7.752148e+10\n",
       "4   20230930  5.482717e+10\n",
       "5   20230630  3.733197e+10\n",
       "6   20230331  2.152473e+10\n",
       "7   20221231  6.537514e+10\n",
       "8   20221231  6.537514e+10\n",
       "9   20220930  4.631399e+10\n",
       "10  20220630  3.110536e+10\n",
       "11  20220331  1.795212e+10\n",
       "12  20211231  5.572053e+10\n",
       "13  20211231  5.572053e+10"
      ],
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>end_date</th>\n",
       "      <th>n_income</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>20240930</td>\n",
       "      <td>6.303146e+10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>20240630</td>\n",
       "      <td>4.317691e+10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>20240331</td>\n",
       "      <td>2.488235e+10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>20231231</td>\n",
       "      <td>7.752148e+10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>20230930</td>\n",
       "      <td>5.482717e+10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>20230630</td>\n",
       "      <td>3.733197e+10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>20230331</td>\n",
       "      <td>2.152473e+10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>20221231</td>\n",
       "      <td>6.537514e+10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>20221231</td>\n",
       "      <td>6.537514e+10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>20220930</td>\n",
       "      <td>4.631399e+10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>20220630</td>\n",
       "      <td>3.110536e+10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>20220331</td>\n",
       "      <td>1.795212e+10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>20211231</td>\n",
       "      <td>5.572053e+10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>20211231</td>\n",
       "      <td>5.572053e+10</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 40
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-10T04:17:56.196027Z",
     "start_time": "2025-01-10T04:17:55.879469Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 获取净利润\n",
    "income_df = ts_pro.income(ts_code='600519.SH', start_date='20220101', end_date='20241231', fields='end_date,n_income')\n",
    "net_profit = income_df[income_df['end_date'] == '20231231']['n_income'].values[0]\n",
    "\n",
    "# 获取期初和期末的股东权益和总资产\n",
    "balancesheet_df = ts_pro.balancesheet(ts_code='600519.SH', start_date='20220101', end_date='20241231',\n",
    "                                      fields='end_date,total_hldr_eqy_exc_min_int,total_assets')\n",
    "eqy_initial = balancesheet_df[balancesheet_df['end_date'] == '20230331']['total_hldr_eqy_exc_min_int'].values[0]\n",
    "eqy_final = balancesheet_df[balancesheet_df['end_date'] == '20231231']['total_hldr_eqy_exc_min_int'].values[0]\n",
    "total_assets_initial = balancesheet_df[balancesheet_df['end_date'] == '20230331']['total_assets'].values[0]\n",
    "total_assets_final = balancesheet_df[balancesheet_df['end_date'] == '20231231']['total_assets'].values[0]\n",
    "\n",
    "# 计算平均股东权益和平均总资产\n",
    "avg_eqy = (eqy_initial + eqy_final) / 2\n",
    "avg_assets = (total_assets_initial + total_assets_final) / 2\n",
    "\n",
    "# 计算ROE和ROA\n",
    "roe = net_profit / avg_eqy\n",
    "roa = net_profit / avg_assets\n",
    "\n",
    "print(f'ROE: {roe:.4f}')\n",
    "print(f'ROA: {roa:.4f}')"
   ],
   "id": "caf1a1555d4c972e",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ROE: 0.3573\n",
      "ROA: 0.2919\n"
     ]
    }
   ],
   "execution_count": 43
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-10T04:19:57.750533Z",
     "start_time": "2025-01-10T04:19:57.531524Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 获取营业收入净额\n",
    "income_df = ts_pro.income(ts_code='600519.SH', start_date='20220101', end_date='20241231', fields='end_date,revenue')\n",
    "revenue = income_df[income_df['end_date'] == '20231231']['revenue'].values[0]\n",
    "\n",
    "# 获取期初（上一年12月31日）和期末（当前年12月31日）的总资产\n",
    "balancesheet_df = ts_pro.balancesheet(ts_code='600519.SH', start_date='20220101', end_date='20241231',\n",
    "                                      fields='end_date,total_assets')\n",
    "total_assets_initial = balancesheet_df[balancesheet_df['end_date'] == '20221231']['total_assets'].values[0]\n",
    "total_assets_final = balancesheet_df[balancesheet_df['end_date'] == '20231231']['total_assets'].values[0]\n",
    "\n",
    "# 计算平均总资产\n",
    "avg_assets = (total_assets_initial + total_assets_final) / 2\n",
    "\n",
    "# 计算总资产周转率\n",
    "total_asset_turnover = revenue / avg_assets\n",
    "\n",
    "print(f'总资产周转率: {total_asset_turnover:.4f}')"
   ],
   "id": "49488c6640beb4ed",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "总资产周转率: 0.5604\n"
     ]
    }
   ],
   "execution_count": 48
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-10T04:23:50.762070Z",
     "start_time": "2025-01-10T04:23:50.585818Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 获取期末的现金及现金等价物和总资产\n",
    "balancesheet_df = ts_pro.balancesheet(ts_code='600519.SH', start_date='20220101', end_date='20241231',\n",
    "                                      fields='end_date, money_cap, total_assets')\n",
    "cash_and_equivalents = balancesheet_df[balancesheet_df['end_date'] == '20231231']['money_cap'].values[0]\n",
    "total_assets = balancesheet_df[balancesheet_df['end_date'] == '20231231']['total_assets'].values[0]\n",
    "\n",
    "# 计算现金和现金等价物总和占总资产的比率\n",
    "cash_ratio = cash_and_equivalents / total_assets\n",
    "\n",
    "print(f'现金和现金等价物总和占总资产的比率: {cash_ratio:.4f}')"
   ],
   "id": "526ef46373e1c8fe",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "现金和现金等价物总和占总资产的比率: 0.2533\n"
     ]
    }
   ],
   "execution_count": 49
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-10T04:27:11.461667Z",
     "start_time": "2025-01-10T04:27:11.160878Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 获取营业收入\n",
    "income_df = ts_pro.income(ts_code='600519.SH', start_date='20220101', end_date='20241231', fields='end_date, revenue')\n",
    "revenue = income_df[income_df['end_date'] == '20231231']['revenue'].values[0]\n",
    "\n",
    "# 获取期初和期末的应收账款\n",
    "balancesheet_df = ts_pro.balancesheet(ts_code='600519.SH', start_date='20220101', end_date='20241231',\n",
    "                                      fields='end_date, accounts_receiv')\n",
    "accounts_receiv_initial = balancesheet_df[balancesheet_df['end_date'] == '20221231']['accounts_receiv'].values[0]\n",
    "accounts_receiv_final = balancesheet_df[balancesheet_df['end_date'] == '20231231']['accounts_receiv'].values[0]\n",
    "\n",
    "# 计算平均应收账款余额\n",
    "avg_accounts_receiv = (accounts_receiv_initial + accounts_receiv_final) / 2\n",
    "\n",
    "# 计算应收账款周转率\n",
    "accounts_receiv_turnover = revenue / avg_accounts_receiv\n",
    "\n",
    "# 计算收现日数\n",
    "collection_period = 365 / accounts_receiv_turnover\n",
    "\n",
    "print(f'收现日数: {collection_period:.2f} 天')"
   ],
   "id": "dca87ef21cf425ee",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "收现日数: 0.10 天\n"
     ]
    }
   ],
   "execution_count": 50
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-10T07:10:09.564888Z",
     "start_time": "2025-01-10T07:10:08.771019Z"
    }
   },
   "cell_type": "code",
   "source": [
    "code = \"000672.SZ\"\n",
    "year = \"2023\"\n",
    "period = f\"{year}1231\"\n",
    "last_period = f\"{int(year) - 1}1231\"\n",
    "\n",
    "balancesheet_fields = \"total_assets,total_hldr_eqy_inc_min_int,money_cap,accounts_receiv,inventories\"\n",
    "balancesheet_df = ts_pro.balancesheet(ts_code=code, period=period, fields=balancesheet_fields)\n",
    "last_balancesheet_df = ts_pro.balancesheet(ts_code=code, period=last_period, fields=balancesheet_fields)\n",
    "\n",
    "income_fields = \"n_income,revenue,total_revenue,oper_cost,operate_profit,total_opcost\"\n",
    "income_df = ts_pro.income(ts_code=code, period=period, fields=income_fields)\n",
    "last_income_df = ts_pro.income(ts_code=code, period=last_period, fields=income_fields)\n",
    "\n",
    "cashflow_fields = \"cash_paid_for_trade_fin\"\n",
    "cashflow_df = ts_pro.cashflow(ts_code=code, period=period, fields=cashflow_fields)\n",
    "last_cashflow_df = ts_pro.cashflow(ts_code=code, period=last_period, fields=cashflow_fields)"
   ],
   "id": "524a18f138a84f4a",
   "outputs": [],
   "execution_count": 96
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-10T07:10:35.283014Z",
     "start_time": "2025-01-10T07:10:35.268876Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# ROE & ROA\n",
    "roe = income_df[\"n_income\"].values[0] / ((balancesheet_df[\"total_hldr_eqy_inc_min_int\"].values[0] +\n",
    "                                          last_balancesheet_df[\"total_hldr_eqy_inc_min_int\"].values[0]) / 2)\n",
    "roa = income_df[\"n_income\"].values[0] / (\n",
    "        (balancesheet_df[\"total_assets\"].values[0] + last_balancesheet_df[\"total_assets\"].values[0]) / 2)\n",
    "print(f\"ROE: {roe:.4f}\")\n",
    "print(f\"ROA: {roa:.4f}\")\n",
    "\n",
    "# 净利润（转换为百万为单位）\n",
    "net_profit = income_df[\"n_income\"].values[0] / 1000000\n",
    "print(f\"净利润: {net_profit:.4f}百万\")\n",
    "\n",
    "# 总资产周转率\n",
    "total_asset_turnover = income_df[\"total_revenue\"].values[0] / (\n",
    "        (balancesheet_df[\"total_assets\"].values[0] + last_balancesheet_df[\"total_assets\"].values[0]) / 2)\n",
    "print(f\"总资产周转率: {total_asset_turnover:.4f}\")\n",
    "\n",
    "# 现金比率\n",
    "cash_ratio = + balancesheet_df[\"money_cap\"].values[0] / balancesheet_df[\"total_assets\"].values[0]\n",
    "print(f\"现金比率: {cash_ratio:.4f}\")\n",
    "\n",
    "# 收现日数\n",
    "collection_period = 360 / (income_df[\"total_revenue\"].values[0] / balancesheet_df[\"accounts_receiv\"].values[0])\n",
    "print(f\"收现日数: {collection_period:.2f} 天\")\n",
    "\n",
    "# 销货日数\n",
    "sales_period = 360 / ((income_df[\"total_revenue\"].values[0]) / balancesheet_df[\"inventories\"].values[0])\n",
    "print(f\"销货日数: {sales_period:.2f} 天\")\n",
    "\n",
    "# 毛利率\n",
    "gross_profit_margin = (income_df[\"total_revenue\"].values[0] - income_df[\"oper_cost\"].values[0]) / income_df[\n",
    "    \"revenue\"].values[0]\n",
    "print(f\"毛利率: {gross_profit_margin:.4f}\")\n",
    "\n",
    "# 经营利润率\n",
    "operating_profit_margin = income_df[\"operate_profit\"].values[0] / income_df[\"total_revenue\"].values[0]\n",
    "print(f\"经营利润率: {operating_profit_margin:.4f}\")\n",
    "print(f\"经营安全边际率: {(operating_profit_margin / gross_profit_margin):.4f}\")"
   ],
   "id": "8707ca42171475a8",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ROE: 0.0747\n",
      "ROA: 0.0411\n",
      "净利润: 701.3791百万\n",
      "总资产周转率: 0.3745\n",
      "现金比率: 0.2253\n",
      "收现日数: 12.95 天\n",
      "销货日数: 59.70 天\n",
      "毛利率: 0.2775\n",
      "经营利润率: 0.1474\n",
      "经营安全边际率: 0.5312\n"
     ]
    }
   ],
   "execution_count": 98
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
