1988 lines
71 KiB
Plaintext
1988 lines
71 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "code",
|
||
"id": "initial_id",
|
||
"metadata": {
|
||
"collapsed": true,
|
||
"ExecuteTime": {
|
||
"end_time": "2025-01-17T02:07:55.001963Z",
|
||
"start_time": "2025-01-17T02:07:54.772694Z"
|
||
}
|
||
},
|
||
"source": [
|
||
"import pandas as pd\n",
|
||
"import tushare as ts\n",
|
||
"\n",
|
||
"ts_pro = ts.pro_api(token=\"64ebff4fa679167600b905ee45dd88e76f3963c0ff39157f3f085f0e\")"
|
||
],
|
||
"outputs": [],
|
||
"execution_count": 2
|
||
},
|
||
{
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2025-01-17T08:18:12.685428Z",
|
||
"start_time": "2025-01-17T08:18:12.676949Z"
|
||
}
|
||
},
|
||
"cell_type": "code",
|
||
"source": [
|
||
"df = pd.DataFrame([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20]])\n",
|
||
"df.loc[df[0] > 2, 2] += 100\n",
|
||
"df"
|
||
],
|
||
"id": "e19fd115ed8cb631",
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
" 0 1 2 3 4\n",
|
||
"0 1 2 3 4 5\n",
|
||
"1 6 7 108 9 10\n",
|
||
"2 11 12 113 14 15\n",
|
||
"3 16 17 118 19 20"
|
||
],
|
||
"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>0</th>\n",
|
||
" <th>1</th>\n",
|
||
" <th>2</th>\n",
|
||
" <th>3</th>\n",
|
||
" <th>4</th>\n",
|
||
" </tr>\n",
|
||
" </thead>\n",
|
||
" <tbody>\n",
|
||
" <tr>\n",
|
||
" <th>0</th>\n",
|
||
" <td>1</td>\n",
|
||
" <td>2</td>\n",
|
||
" <td>3</td>\n",
|
||
" <td>4</td>\n",
|
||
" <td>5</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>1</th>\n",
|
||
" <td>6</td>\n",
|
||
" <td>7</td>\n",
|
||
" <td>108</td>\n",
|
||
" <td>9</td>\n",
|
||
" <td>10</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>2</th>\n",
|
||
" <td>11</td>\n",
|
||
" <td>12</td>\n",
|
||
" <td>113</td>\n",
|
||
" <td>14</td>\n",
|
||
" <td>15</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>3</th>\n",
|
||
" <td>16</td>\n",
|
||
" <td>17</td>\n",
|
||
" <td>118</td>\n",
|
||
" <td>19</td>\n",
|
||
" <td>20</td>\n",
|
||
" </tr>\n",
|
||
" </tbody>\n",
|
||
"</table>\n",
|
||
"</div>"
|
||
]
|
||
},
|
||
"execution_count": 86,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"execution_count": 86
|
||
},
|
||
{
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2025-01-17T10:11:56.563929Z",
|
||
"start_time": "2025-01-17T10:11:52.872684Z"
|
||
}
|
||
},
|
||
"cell_type": "code",
|
||
"source": [
|
||
"import loader as loader\n",
|
||
"\n",
|
||
"# 加载股票信息\n",
|
||
"stock_df = pd.read_csv(\"../材料/股票基础信息.csv\")\n",
|
||
"# 加载财报信息\n",
|
||
"source_finance_df = loader.load_finance()\n",
|
||
"finance_df = pd.DataFrame()\n",
|
||
"finance_df[[\n",
|
||
" \"code\",\n",
|
||
" # 年份\n",
|
||
" \"year\",\n",
|
||
" # 股东权益合计(含少数股东权益)\n",
|
||
" \"total_stockholder_interest\",\n",
|
||
" # 净利润\n",
|
||
" \"net_income\",\n",
|
||
" # 总资产\n",
|
||
" \"total_assets\",\n",
|
||
" # 营业总收入\n",
|
||
" \"total_revenue\",\n",
|
||
" # 存货\n",
|
||
" \"inventories\",\n",
|
||
" # 应收账款\n",
|
||
" \"accounts_receivable\",\n",
|
||
" # 营业成本\n",
|
||
" \"operating_costs\",\n",
|
||
" # 营业利润\n",
|
||
" \"operating_profit\",\n",
|
||
" # 现金与现金等价物\n",
|
||
" \"cash\",\n",
|
||
" # 营业活动现金流量净值\n",
|
||
" \"operating_net_cash_flow\",\n",
|
||
"]] = source_finance_df[[\n",
|
||
" \"ts_code\",\n",
|
||
" \"end_date\",\n",
|
||
" \"total_hldr_eqy_inc_min_int\",\n",
|
||
" \"n_income\",\n",
|
||
" \"total_assets\",\n",
|
||
" \"total_revenue\",\n",
|
||
" \"inventories\",\n",
|
||
" \"accounts_receiv\",\n",
|
||
" \"oper_cost\",\n",
|
||
" \"operate_profit\",\n",
|
||
" \"money_cap\",\n",
|
||
" \"n_cashflow_act\",\n",
|
||
"]]\n",
|
||
"finance_df[\"score\"] = 0\n",
|
||
"finance_df = finance_df.sort_values(by=[\"code\", \"year\"], ascending=True)"
|
||
],
|
||
"id": "68b2debc14502fd5",
|
||
"outputs": [],
|
||
"execution_count": 148
|
||
},
|
||
{
|
||
"metadata": {},
|
||
"cell_type": "markdown",
|
||
"source": "过滤上市时间大于5年的企业,由于计算很多数值需要与前一年比,所以实际上需要的是上市时间至少6年的企业",
|
||
"id": "3052b8c4442f3643"
|
||
},
|
||
{
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2025-01-17T10:11:57.531470Z",
|
||
"start_time": "2025-01-17T10:11:57.287352Z"
|
||
}
|
||
},
|
||
"cell_type": "code",
|
||
"source": "finance_df = finance_df.groupby(\"code\").filter(lambda x: len(x) > 6)",
|
||
"id": "4293bd93ea8f9ed",
|
||
"outputs": [],
|
||
"execution_count": 149
|
||
},
|
||
{
|
||
"metadata": {},
|
||
"cell_type": "markdown",
|
||
"source": [
|
||
"ROE\n",
|
||
"\n",
|
||
"股东权益报酬率(%) RoE\t股东权益报酬率RoE 是判断股票是否具备”长期上涨潜力“最重要的指标之一, RoE 如果既稳定又优秀,那这家公司的其他指标也基本不会差。 \n",
|
||
"RoE均值 >= 35\t550分 \n",
|
||
"35 > RoE均值 >= 30\t500分 \n",
|
||
"30 > RoE均值 >= 25\t450分 \n",
|
||
"25 > RoE均值 >= 20\t400分 \n",
|
||
"20 > RoE均值 >= 15\t300分 \n",
|
||
"15 > RoE均值 >= 10\t250分 \n",
|
||
"10 > RoE均值 或 0 >= 其中一年\t0分 "
|
||
],
|
||
"id": "336aa970ee46709d"
|
||
},
|
||
{
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2025-01-17T10:12:05.859920Z",
|
||
"start_time": "2025-01-17T10:12:00.853021Z"
|
||
}
|
||
},
|
||
"cell_type": "code",
|
||
"source": [
|
||
"finance_df[\"prev_total_stockholder_interest\"] = finance_df.groupby(\"code\")[\"total_stockholder_interest\"].shift(1)\n",
|
||
"finance_df[\"roe\"] = finance_df[\"net_income\"] / (\n",
|
||
" (finance_df[\"prev_total_stockholder_interest\"] + finance_df[\"total_stockholder_interest\"]) / 2)\n",
|
||
"finance_df[\"average_roe\"] = finance_df.groupby(\"code\")[\"roe\"].rolling(window=5).mean().reset_index(0, drop=True)\n",
|
||
"finance_df.loc[finance_df[\"average_roe\"] >= 0.35, \"score\"] += 550\n",
|
||
"finance_df.loc[(finance_df[\"average_roe\"] >= 0.30) & (finance_df[\"average_roe\"] < 0.35), \"score\"] += 500\n",
|
||
"finance_df.loc[(finance_df[\"average_roe\"] >= 0.25) & (finance_df[\"average_roe\"] < 0.30), \"score\"] += 450\n",
|
||
"finance_df.loc[(finance_df[\"average_roe\"] >= 0.20) & (finance_df[\"average_roe\"] < 0.25), \"score\"] += 400\n",
|
||
"finance_df.loc[(finance_df[\"average_roe\"] >= 0.15) & (finance_df[\"average_roe\"] < 0.20), \"score\"] += 300\n",
|
||
"finance_df.loc[(finance_df[\"average_roe\"] >= 0.10) & (finance_df[\"average_roe\"] < 0.15), \"score\"] += 250\n",
|
||
"finance_df[\"score\"] = finance_df.groupby(\"code\").apply(\n",
|
||
" lambda x: x[\"score\"].mask(x[\"average_roe\"].rolling(window=5).apply(lambda y: (y < 0).any(), raw=False) > 0, 0)\n",
|
||
").reset_index(drop=True)\n",
|
||
"\n",
|
||
"finance_df[finance_df[\"code\"] == '000002.SZ']"
|
||
],
|
||
"id": "f050d33c4a0cd720",
|
||
"outputs": [
|
||
{
|
||
"name": "stderr",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"/var/folders/7h/w0cmp4zj6mn9br_6nyj310m40000gn/T/ipykernel_54636/2126828454.py:12: DeprecationWarning: DataFrameGroupBy.apply operated on the grouping columns. This behavior is deprecated, and in a future version of pandas the grouping columns will be excluded from the operation. Either pass `include_groups=False` to exclude the groupings or explicitly select the grouping columns after groupby to silence this warning.\n",
|
||
" finance_df[\"score\"] = finance_df.groupby(\"code\").apply(\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
" code year total_stockholder_interest net_income \\\n",
|
||
"1945 000002.SZ 2005 8.581223e+09 1.433426e+09 \n",
|
||
"3432 000002.SZ 2006 1.745350e+10 2.422997e+09 \n",
|
||
"5449 000002.SZ 2007 3.391952e+10 5.317501e+09 \n",
|
||
"7921 000002.SZ 2008 3.881855e+10 4.639869e+09 \n",
|
||
"10605 000002.SZ 2009 4.540851e+10 6.430008e+09 \n",
|
||
"13934 000002.SZ 2010 5.458620e+10 8.839611e+09 \n",
|
||
"17289 000002.SZ 2011 6.783254e+10 1.159961e+10 \n",
|
||
"20376 000002.SZ 2012 8.213819e+10 1.566259e+10 \n",
|
||
"25215 000002.SZ 2013 1.054394e+11 1.829755e+10 \n",
|
||
"29387 000002.SZ 2014 1.158936e+11 1.928752e+10 \n",
|
||
"33753 000002.SZ 2015 1.363096e+11 2.594944e+10 \n",
|
||
"37463 000002.SZ 2016 1.616766e+11 2.835026e+10 \n",
|
||
"42678 000002.SZ 2017 1.866739e+11 3.720839e+10 \n",
|
||
"47756 000002.SZ 2018 2.356207e+11 4.927229e+10 \n",
|
||
"52944 000002.SZ 2019 2.705791e+11 5.513161e+10 \n",
|
||
"57414 000002.SZ 2020 3.498445e+11 5.929812e+10 \n",
|
||
"59180 000002.SZ 2021 3.927728e+11 3.806953e+10 \n",
|
||
"62929 000002.SZ 2022 4.049915e+11 3.755091e+10 \n",
|
||
"68422 000002.SZ 2023 4.029335e+11 2.045556e+10 \n",
|
||
"\n",
|
||
" total_assets total_revenue inventories accounts_receivable \\\n",
|
||
"1945 2.199239e+10 1.055885e+10 1.484948e+10 3.773077e+08 \n",
|
||
"3432 4.991984e+10 1.791833e+10 3.416711e+10 3.646097e+08 \n",
|
||
"5449 1.000945e+11 3.552661e+10 6.647288e+10 8.648830e+08 \n",
|
||
"7921 1.192366e+11 4.099178e+10 8.589870e+10 9.227748e+08 \n",
|
||
"10605 1.376086e+11 4.888101e+10 9.008529e+10 7.131919e+08 \n",
|
||
"13934 2.156376e+11 5.071385e+10 1.333335e+11 1.594025e+09 \n",
|
||
"17289 2.962084e+11 7.178275e+10 2.083355e+11 1.514814e+09 \n",
|
||
"20376 3.788016e+11 1.031162e+11 2.551641e+11 1.886549e+09 \n",
|
||
"25215 4.792053e+11 1.354188e+11 3.311332e+11 3.078970e+09 \n",
|
||
"29387 5.084088e+11 1.463880e+11 3.177264e+11 1.894072e+09 \n",
|
||
"33753 6.112956e+11 1.955491e+11 3.681219e+11 2.510653e+09 \n",
|
||
"37463 8.306742e+11 2.404772e+11 4.673613e+11 2.075257e+09 \n",
|
||
"42678 1.165347e+12 2.428971e+11 5.980877e+11 1.432734e+09 \n",
|
||
"47756 1.528579e+12 2.976793e+11 7.503026e+11 1.586181e+09 \n",
|
||
"52944 1.729929e+12 3.678939e+11 8.970190e+11 1.988076e+09 \n",
|
||
"57414 1.869177e+12 4.191117e+11 1.002063e+12 2.992423e+09 \n",
|
||
"59180 1.938638e+12 4.527978e+11 1.075617e+12 4.743597e+09 \n",
|
||
"62929 1.757124e+12 5.038384e+11 9.070569e+11 7.504692e+09 \n",
|
||
"68422 1.504850e+12 4.657391e+11 7.016958e+11 7.293628e+09 \n",
|
||
"\n",
|
||
" operating_costs operating_profit cash \\\n",
|
||
"1945 6.884921e+09 1.958371e+09 3.249035e+09 \n",
|
||
"3432 1.144126e+10 3.426907e+09 1.074370e+10 \n",
|
||
"5449 2.060734e+10 7.652897e+09 1.704650e+10 \n",
|
||
"7921 2.500527e+10 6.364790e+09 1.997829e+10 \n",
|
||
"10605 3.451472e+10 8.685083e+09 2.300192e+10 \n",
|
||
"13934 3.007350e+10 1.189489e+10 3.781693e+10 \n",
|
||
"17289 4.322816e+10 1.576322e+10 3.423951e+10 \n",
|
||
"20376 6.542161e+10 2.101304e+10 5.229154e+10 \n",
|
||
"25215 9.279765e+10 2.426134e+10 4.436541e+10 \n",
|
||
"29387 1.025571e+11 2.497936e+10 6.271525e+10 \n",
|
||
"33753 1.381506e+11 3.312278e+10 5.318038e+10 \n",
|
||
"37463 1.697424e+11 3.902378e+10 8.703212e+10 \n",
|
||
"42678 1.600799e+11 5.081292e+10 1.741210e+11 \n",
|
||
"47756 1.861042e+11 6.749861e+10 1.884174e+11 \n",
|
||
"52944 2.345503e+11 7.661314e+10 1.661946e+11 \n",
|
||
"57414 2.965407e+11 7.995864e+10 1.952307e+11 \n",
|
||
"59180 3.539771e+11 5.253100e+10 1.493524e+11 \n",
|
||
"62929 4.053193e+11 5.200694e+10 1.372076e+11 \n",
|
||
"68422 3.947839e+11 2.925170e+10 9.981376e+10 \n",
|
||
"\n",
|
||
" operating_net_cash_flow score prev_total_stockholder_interest \\\n",
|
||
"1945 8.434391e+08 0.0 NaN \n",
|
||
"3432 -3.024121e+09 0.0 8.581223e+09 \n",
|
||
"5449 -1.043772e+10 0.0 1.745350e+10 \n",
|
||
"7921 -3.415183e+07 0.0 3.391952e+10 \n",
|
||
"10605 9.253351e+09 0.0 3.881855e+10 \n",
|
||
"13934 2.237255e+09 250.0 4.540851e+10 \n",
|
||
"17289 3.389425e+09 0.0 5.458620e+10 \n",
|
||
"20376 3.725958e+09 0.0 6.783254e+10 \n",
|
||
"25215 1.923869e+09 300.0 8.213819e+10 \n",
|
||
"29387 4.172482e+10 0.0 1.054394e+11 \n",
|
||
"33753 1.604602e+10 0.0 1.158936e+11 \n",
|
||
"37463 3.956613e+10 400.0 1.363096e+11 \n",
|
||
"42678 8.232283e+10 250.0 1.616766e+11 \n",
|
||
"47756 3.361818e+10 0.0 1.866739e+11 \n",
|
||
"52944 4.568681e+10 400.0 2.356207e+11 \n",
|
||
"57414 5.318802e+10 0.0 2.705791e+11 \n",
|
||
"59180 4.113161e+09 250.0 3.498445e+11 \n",
|
||
"62929 2.750449e+09 0.0 3.927728e+11 \n",
|
||
"68422 3.912324e+09 300.0 4.049915e+11 \n",
|
||
"\n",
|
||
" roe average_roe \n",
|
||
"1945 NaN NaN \n",
|
||
"3432 0.186136 NaN \n",
|
||
"5449 0.207015 NaN \n",
|
||
"7921 0.127577 NaN \n",
|
||
"10605 0.152683 NaN \n",
|
||
"13934 0.176802 0.170043 \n",
|
||
"17289 0.189507 0.170717 \n",
|
||
"20376 0.208875 0.171089 \n",
|
||
"25215 0.195093 0.184592 \n",
|
||
"29387 0.174285 0.188912 \n",
|
||
"33753 0.205782 0.194708 \n",
|
||
"37463 0.190279 0.194863 \n",
|
||
"42678 0.213626 0.195813 \n",
|
||
"47756 0.233355 0.203465 \n",
|
||
"52944 0.217825 0.212174 \n",
|
||
"57414 0.191154 0.209248 \n",
|
||
"59180 0.102528 0.191698 \n",
|
||
"62929 0.094140 0.167801 \n",
|
||
"68422 0.050637 0.131257 "
|
||
],
|
||
"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>code</th>\n",
|
||
" <th>year</th>\n",
|
||
" <th>total_stockholder_interest</th>\n",
|
||
" <th>net_income</th>\n",
|
||
" <th>total_assets</th>\n",
|
||
" <th>total_revenue</th>\n",
|
||
" <th>inventories</th>\n",
|
||
" <th>accounts_receivable</th>\n",
|
||
" <th>operating_costs</th>\n",
|
||
" <th>operating_profit</th>\n",
|
||
" <th>cash</th>\n",
|
||
" <th>operating_net_cash_flow</th>\n",
|
||
" <th>score</th>\n",
|
||
" <th>prev_total_stockholder_interest</th>\n",
|
||
" <th>roe</th>\n",
|
||
" <th>average_roe</th>\n",
|
||
" </tr>\n",
|
||
" </thead>\n",
|
||
" <tbody>\n",
|
||
" <tr>\n",
|
||
" <th>1945</th>\n",
|
||
" <td>000002.SZ</td>\n",
|
||
" <td>2005</td>\n",
|
||
" <td>8.581223e+09</td>\n",
|
||
" <td>1.433426e+09</td>\n",
|
||
" <td>2.199239e+10</td>\n",
|
||
" <td>1.055885e+10</td>\n",
|
||
" <td>1.484948e+10</td>\n",
|
||
" <td>3.773077e+08</td>\n",
|
||
" <td>6.884921e+09</td>\n",
|
||
" <td>1.958371e+09</td>\n",
|
||
" <td>3.249035e+09</td>\n",
|
||
" <td>8.434391e+08</td>\n",
|
||
" <td>0.0</td>\n",
|
||
" <td>NaN</td>\n",
|
||
" <td>NaN</td>\n",
|
||
" <td>NaN</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>3432</th>\n",
|
||
" <td>000002.SZ</td>\n",
|
||
" <td>2006</td>\n",
|
||
" <td>1.745350e+10</td>\n",
|
||
" <td>2.422997e+09</td>\n",
|
||
" <td>4.991984e+10</td>\n",
|
||
" <td>1.791833e+10</td>\n",
|
||
" <td>3.416711e+10</td>\n",
|
||
" <td>3.646097e+08</td>\n",
|
||
" <td>1.144126e+10</td>\n",
|
||
" <td>3.426907e+09</td>\n",
|
||
" <td>1.074370e+10</td>\n",
|
||
" <td>-3.024121e+09</td>\n",
|
||
" <td>0.0</td>\n",
|
||
" <td>8.581223e+09</td>\n",
|
||
" <td>0.186136</td>\n",
|
||
" <td>NaN</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>5449</th>\n",
|
||
" <td>000002.SZ</td>\n",
|
||
" <td>2007</td>\n",
|
||
" <td>3.391952e+10</td>\n",
|
||
" <td>5.317501e+09</td>\n",
|
||
" <td>1.000945e+11</td>\n",
|
||
" <td>3.552661e+10</td>\n",
|
||
" <td>6.647288e+10</td>\n",
|
||
" <td>8.648830e+08</td>\n",
|
||
" <td>2.060734e+10</td>\n",
|
||
" <td>7.652897e+09</td>\n",
|
||
" <td>1.704650e+10</td>\n",
|
||
" <td>-1.043772e+10</td>\n",
|
||
" <td>0.0</td>\n",
|
||
" <td>1.745350e+10</td>\n",
|
||
" <td>0.207015</td>\n",
|
||
" <td>NaN</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>7921</th>\n",
|
||
" <td>000002.SZ</td>\n",
|
||
" <td>2008</td>\n",
|
||
" <td>3.881855e+10</td>\n",
|
||
" <td>4.639869e+09</td>\n",
|
||
" <td>1.192366e+11</td>\n",
|
||
" <td>4.099178e+10</td>\n",
|
||
" <td>8.589870e+10</td>\n",
|
||
" <td>9.227748e+08</td>\n",
|
||
" <td>2.500527e+10</td>\n",
|
||
" <td>6.364790e+09</td>\n",
|
||
" <td>1.997829e+10</td>\n",
|
||
" <td>-3.415183e+07</td>\n",
|
||
" <td>0.0</td>\n",
|
||
" <td>3.391952e+10</td>\n",
|
||
" <td>0.127577</td>\n",
|
||
" <td>NaN</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>10605</th>\n",
|
||
" <td>000002.SZ</td>\n",
|
||
" <td>2009</td>\n",
|
||
" <td>4.540851e+10</td>\n",
|
||
" <td>6.430008e+09</td>\n",
|
||
" <td>1.376086e+11</td>\n",
|
||
" <td>4.888101e+10</td>\n",
|
||
" <td>9.008529e+10</td>\n",
|
||
" <td>7.131919e+08</td>\n",
|
||
" <td>3.451472e+10</td>\n",
|
||
" <td>8.685083e+09</td>\n",
|
||
" <td>2.300192e+10</td>\n",
|
||
" <td>9.253351e+09</td>\n",
|
||
" <td>0.0</td>\n",
|
||
" <td>3.881855e+10</td>\n",
|
||
" <td>0.152683</td>\n",
|
||
" <td>NaN</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>13934</th>\n",
|
||
" <td>000002.SZ</td>\n",
|
||
" <td>2010</td>\n",
|
||
" <td>5.458620e+10</td>\n",
|
||
" <td>8.839611e+09</td>\n",
|
||
" <td>2.156376e+11</td>\n",
|
||
" <td>5.071385e+10</td>\n",
|
||
" <td>1.333335e+11</td>\n",
|
||
" <td>1.594025e+09</td>\n",
|
||
" <td>3.007350e+10</td>\n",
|
||
" <td>1.189489e+10</td>\n",
|
||
" <td>3.781693e+10</td>\n",
|
||
" <td>2.237255e+09</td>\n",
|
||
" <td>250.0</td>\n",
|
||
" <td>4.540851e+10</td>\n",
|
||
" <td>0.176802</td>\n",
|
||
" <td>0.170043</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>17289</th>\n",
|
||
" <td>000002.SZ</td>\n",
|
||
" <td>2011</td>\n",
|
||
" <td>6.783254e+10</td>\n",
|
||
" <td>1.159961e+10</td>\n",
|
||
" <td>2.962084e+11</td>\n",
|
||
" <td>7.178275e+10</td>\n",
|
||
" <td>2.083355e+11</td>\n",
|
||
" <td>1.514814e+09</td>\n",
|
||
" <td>4.322816e+10</td>\n",
|
||
" <td>1.576322e+10</td>\n",
|
||
" <td>3.423951e+10</td>\n",
|
||
" <td>3.389425e+09</td>\n",
|
||
" <td>0.0</td>\n",
|
||
" <td>5.458620e+10</td>\n",
|
||
" <td>0.189507</td>\n",
|
||
" <td>0.170717</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>20376</th>\n",
|
||
" <td>000002.SZ</td>\n",
|
||
" <td>2012</td>\n",
|
||
" <td>8.213819e+10</td>\n",
|
||
" <td>1.566259e+10</td>\n",
|
||
" <td>3.788016e+11</td>\n",
|
||
" <td>1.031162e+11</td>\n",
|
||
" <td>2.551641e+11</td>\n",
|
||
" <td>1.886549e+09</td>\n",
|
||
" <td>6.542161e+10</td>\n",
|
||
" <td>2.101304e+10</td>\n",
|
||
" <td>5.229154e+10</td>\n",
|
||
" <td>3.725958e+09</td>\n",
|
||
" <td>0.0</td>\n",
|
||
" <td>6.783254e+10</td>\n",
|
||
" <td>0.208875</td>\n",
|
||
" <td>0.171089</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>25215</th>\n",
|
||
" <td>000002.SZ</td>\n",
|
||
" <td>2013</td>\n",
|
||
" <td>1.054394e+11</td>\n",
|
||
" <td>1.829755e+10</td>\n",
|
||
" <td>4.792053e+11</td>\n",
|
||
" <td>1.354188e+11</td>\n",
|
||
" <td>3.311332e+11</td>\n",
|
||
" <td>3.078970e+09</td>\n",
|
||
" <td>9.279765e+10</td>\n",
|
||
" <td>2.426134e+10</td>\n",
|
||
" <td>4.436541e+10</td>\n",
|
||
" <td>1.923869e+09</td>\n",
|
||
" <td>300.0</td>\n",
|
||
" <td>8.213819e+10</td>\n",
|
||
" <td>0.195093</td>\n",
|
||
" <td>0.184592</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>29387</th>\n",
|
||
" <td>000002.SZ</td>\n",
|
||
" <td>2014</td>\n",
|
||
" <td>1.158936e+11</td>\n",
|
||
" <td>1.928752e+10</td>\n",
|
||
" <td>5.084088e+11</td>\n",
|
||
" <td>1.463880e+11</td>\n",
|
||
" <td>3.177264e+11</td>\n",
|
||
" <td>1.894072e+09</td>\n",
|
||
" <td>1.025571e+11</td>\n",
|
||
" <td>2.497936e+10</td>\n",
|
||
" <td>6.271525e+10</td>\n",
|
||
" <td>4.172482e+10</td>\n",
|
||
" <td>0.0</td>\n",
|
||
" <td>1.054394e+11</td>\n",
|
||
" <td>0.174285</td>\n",
|
||
" <td>0.188912</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>33753</th>\n",
|
||
" <td>000002.SZ</td>\n",
|
||
" <td>2015</td>\n",
|
||
" <td>1.363096e+11</td>\n",
|
||
" <td>2.594944e+10</td>\n",
|
||
" <td>6.112956e+11</td>\n",
|
||
" <td>1.955491e+11</td>\n",
|
||
" <td>3.681219e+11</td>\n",
|
||
" <td>2.510653e+09</td>\n",
|
||
" <td>1.381506e+11</td>\n",
|
||
" <td>3.312278e+10</td>\n",
|
||
" <td>5.318038e+10</td>\n",
|
||
" <td>1.604602e+10</td>\n",
|
||
" <td>0.0</td>\n",
|
||
" <td>1.158936e+11</td>\n",
|
||
" <td>0.205782</td>\n",
|
||
" <td>0.194708</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>37463</th>\n",
|
||
" <td>000002.SZ</td>\n",
|
||
" <td>2016</td>\n",
|
||
" <td>1.616766e+11</td>\n",
|
||
" <td>2.835026e+10</td>\n",
|
||
" <td>8.306742e+11</td>\n",
|
||
" <td>2.404772e+11</td>\n",
|
||
" <td>4.673613e+11</td>\n",
|
||
" <td>2.075257e+09</td>\n",
|
||
" <td>1.697424e+11</td>\n",
|
||
" <td>3.902378e+10</td>\n",
|
||
" <td>8.703212e+10</td>\n",
|
||
" <td>3.956613e+10</td>\n",
|
||
" <td>400.0</td>\n",
|
||
" <td>1.363096e+11</td>\n",
|
||
" <td>0.190279</td>\n",
|
||
" <td>0.194863</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>42678</th>\n",
|
||
" <td>000002.SZ</td>\n",
|
||
" <td>2017</td>\n",
|
||
" <td>1.866739e+11</td>\n",
|
||
" <td>3.720839e+10</td>\n",
|
||
" <td>1.165347e+12</td>\n",
|
||
" <td>2.428971e+11</td>\n",
|
||
" <td>5.980877e+11</td>\n",
|
||
" <td>1.432734e+09</td>\n",
|
||
" <td>1.600799e+11</td>\n",
|
||
" <td>5.081292e+10</td>\n",
|
||
" <td>1.741210e+11</td>\n",
|
||
" <td>8.232283e+10</td>\n",
|
||
" <td>250.0</td>\n",
|
||
" <td>1.616766e+11</td>\n",
|
||
" <td>0.213626</td>\n",
|
||
" <td>0.195813</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>47756</th>\n",
|
||
" <td>000002.SZ</td>\n",
|
||
" <td>2018</td>\n",
|
||
" <td>2.356207e+11</td>\n",
|
||
" <td>4.927229e+10</td>\n",
|
||
" <td>1.528579e+12</td>\n",
|
||
" <td>2.976793e+11</td>\n",
|
||
" <td>7.503026e+11</td>\n",
|
||
" <td>1.586181e+09</td>\n",
|
||
" <td>1.861042e+11</td>\n",
|
||
" <td>6.749861e+10</td>\n",
|
||
" <td>1.884174e+11</td>\n",
|
||
" <td>3.361818e+10</td>\n",
|
||
" <td>0.0</td>\n",
|
||
" <td>1.866739e+11</td>\n",
|
||
" <td>0.233355</td>\n",
|
||
" <td>0.203465</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>52944</th>\n",
|
||
" <td>000002.SZ</td>\n",
|
||
" <td>2019</td>\n",
|
||
" <td>2.705791e+11</td>\n",
|
||
" <td>5.513161e+10</td>\n",
|
||
" <td>1.729929e+12</td>\n",
|
||
" <td>3.678939e+11</td>\n",
|
||
" <td>8.970190e+11</td>\n",
|
||
" <td>1.988076e+09</td>\n",
|
||
" <td>2.345503e+11</td>\n",
|
||
" <td>7.661314e+10</td>\n",
|
||
" <td>1.661946e+11</td>\n",
|
||
" <td>4.568681e+10</td>\n",
|
||
" <td>400.0</td>\n",
|
||
" <td>2.356207e+11</td>\n",
|
||
" <td>0.217825</td>\n",
|
||
" <td>0.212174</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>57414</th>\n",
|
||
" <td>000002.SZ</td>\n",
|
||
" <td>2020</td>\n",
|
||
" <td>3.498445e+11</td>\n",
|
||
" <td>5.929812e+10</td>\n",
|
||
" <td>1.869177e+12</td>\n",
|
||
" <td>4.191117e+11</td>\n",
|
||
" <td>1.002063e+12</td>\n",
|
||
" <td>2.992423e+09</td>\n",
|
||
" <td>2.965407e+11</td>\n",
|
||
" <td>7.995864e+10</td>\n",
|
||
" <td>1.952307e+11</td>\n",
|
||
" <td>5.318802e+10</td>\n",
|
||
" <td>0.0</td>\n",
|
||
" <td>2.705791e+11</td>\n",
|
||
" <td>0.191154</td>\n",
|
||
" <td>0.209248</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>59180</th>\n",
|
||
" <td>000002.SZ</td>\n",
|
||
" <td>2021</td>\n",
|
||
" <td>3.927728e+11</td>\n",
|
||
" <td>3.806953e+10</td>\n",
|
||
" <td>1.938638e+12</td>\n",
|
||
" <td>4.527978e+11</td>\n",
|
||
" <td>1.075617e+12</td>\n",
|
||
" <td>4.743597e+09</td>\n",
|
||
" <td>3.539771e+11</td>\n",
|
||
" <td>5.253100e+10</td>\n",
|
||
" <td>1.493524e+11</td>\n",
|
||
" <td>4.113161e+09</td>\n",
|
||
" <td>250.0</td>\n",
|
||
" <td>3.498445e+11</td>\n",
|
||
" <td>0.102528</td>\n",
|
||
" <td>0.191698</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>62929</th>\n",
|
||
" <td>000002.SZ</td>\n",
|
||
" <td>2022</td>\n",
|
||
" <td>4.049915e+11</td>\n",
|
||
" <td>3.755091e+10</td>\n",
|
||
" <td>1.757124e+12</td>\n",
|
||
" <td>5.038384e+11</td>\n",
|
||
" <td>9.070569e+11</td>\n",
|
||
" <td>7.504692e+09</td>\n",
|
||
" <td>4.053193e+11</td>\n",
|
||
" <td>5.200694e+10</td>\n",
|
||
" <td>1.372076e+11</td>\n",
|
||
" <td>2.750449e+09</td>\n",
|
||
" <td>0.0</td>\n",
|
||
" <td>3.927728e+11</td>\n",
|
||
" <td>0.094140</td>\n",
|
||
" <td>0.167801</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>68422</th>\n",
|
||
" <td>000002.SZ</td>\n",
|
||
" <td>2023</td>\n",
|
||
" <td>4.029335e+11</td>\n",
|
||
" <td>2.045556e+10</td>\n",
|
||
" <td>1.504850e+12</td>\n",
|
||
" <td>4.657391e+11</td>\n",
|
||
" <td>7.016958e+11</td>\n",
|
||
" <td>7.293628e+09</td>\n",
|
||
" <td>3.947839e+11</td>\n",
|
||
" <td>2.925170e+10</td>\n",
|
||
" <td>9.981376e+10</td>\n",
|
||
" <td>3.912324e+09</td>\n",
|
||
" <td>300.0</td>\n",
|
||
" <td>4.049915e+11</td>\n",
|
||
" <td>0.050637</td>\n",
|
||
" <td>0.131257</td>\n",
|
||
" </tr>\n",
|
||
" </tbody>\n",
|
||
"</table>\n",
|
||
"</div>"
|
||
]
|
||
},
|
||
"execution_count": 150,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"execution_count": 150
|
||
},
|
||
{
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2025-01-17T10:19:25.031141Z",
|
||
"start_time": "2025-01-17T10:19:25.020325Z"
|
||
}
|
||
},
|
||
"cell_type": "code",
|
||
"source": [
|
||
"df = pd.DataFrame([[1, 2, 0], [1, 3, 0], [1, -4, 0]], columns=[\"code\", \"average\", \"score\"])\n",
|
||
"df[\"condition\"] = df.groupby(\"code\")[\"average\"].transform(\n",
|
||
" lambda x: x.rolling(window=2).apply(lambda y: (y < 0).any(), raw=False)\n",
|
||
") > 0\n",
|
||
"df[\"score\"].mask(\n",
|
||
" df.groupby(\"code\")[\"average\"].transform(\n",
|
||
" lambda x: x.rolling(window=2).apply(lambda y: (y < 0).any(), raw=False)\n",
|
||
" ) > 0,\n",
|
||
" 0\n",
|
||
")\n",
|
||
"df"
|
||
],
|
||
"id": "1a6a739df5b6f3a9",
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
" code average score condition\n",
|
||
"0 1 2 0 False\n",
|
||
"1 1 3 0 False\n",
|
||
"2 1 -4 0 True"
|
||
],
|
||
"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>code</th>\n",
|
||
" <th>average</th>\n",
|
||
" <th>score</th>\n",
|
||
" <th>condition</th>\n",
|
||
" </tr>\n",
|
||
" </thead>\n",
|
||
" <tbody>\n",
|
||
" <tr>\n",
|
||
" <th>0</th>\n",
|
||
" <td>1</td>\n",
|
||
" <td>2</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>False</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>1</th>\n",
|
||
" <td>1</td>\n",
|
||
" <td>3</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>False</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>2</th>\n",
|
||
" <td>1</td>\n",
|
||
" <td>-4</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>True</td>\n",
|
||
" </tr>\n",
|
||
" </tbody>\n",
|
||
"</table>\n",
|
||
"</div>"
|
||
]
|
||
},
|
||
"execution_count": 165,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"execution_count": 165
|
||
},
|
||
{
|
||
"metadata": {},
|
||
"cell_type": "markdown",
|
||
"source": [
|
||
"总资产报酬率(%) RoA\t总资产报酬率RoA 能真实反映出一家公司的获利能力, 相当于一家公司的 「投资年化率」,当然越高越好。\n",
|
||
"RoA均值 >= 15\t100分\n",
|
||
"15 > RoA均值 >= 11\t80分\n",
|
||
"11 > RoA均值 >= 7\t50分\n",
|
||
"7 > RoA均值\t0分"
|
||
],
|
||
"id": "6c2e1c602898e342"
|
||
},
|
||
{
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2025-01-14T14:23:20.494927Z",
|
||
"start_time": "2025-01-14T14:23:12.064079Z"
|
||
}
|
||
},
|
||
"cell_type": "code",
|
||
"source": [
|
||
"def cal_roa(df):\n",
|
||
" df[\"prev_total_assets\"] = df[\"total_assets\"].shift(1)\n",
|
||
" df[\"roa\"] = df[\"net_income\"] / ((df[\"prev_total_assets\"] + df[\"total_assets\"]) / 2)\n",
|
||
" df.drop(columns=[\"prev_total_assets\"], inplace=True)\n",
|
||
"\n",
|
||
"\n",
|
||
"def score_by_roa(code):\n",
|
||
" temp_df = finance_df[finance_df[\"code\"] == code].copy()\n",
|
||
" cal_roa(temp_df)\n",
|
||
"\n",
|
||
" average_roa = temp_df.nlargest(5, \"year\")[\"roa\"].mean() * 100\n",
|
||
"\n",
|
||
" if average_roa >= 15:\n",
|
||
" return 100\n",
|
||
" elif average_roa >= 11:\n",
|
||
" return 80\n",
|
||
" elif average_roa >= 7:\n",
|
||
" return 50\n",
|
||
" else:\n",
|
||
" return 0\n",
|
||
"\n",
|
||
"\n",
|
||
"codes = list(map(lambda x: add_score(x, score_by_roa(x[0])), codes))"
|
||
],
|
||
"id": "25d1d5c0f7de460c",
|
||
"outputs": [],
|
||
"execution_count": 8
|
||
},
|
||
{
|
||
"metadata": {},
|
||
"cell_type": "markdown",
|
||
"source": [
|
||
"税后净利 规模(百万)\t获利规模大,那股价的”长期上涨潜力“也就会越稳健、越确定。选择时,大公司的优先级要高于小公司。\n",
|
||
"税后净利均值 >= 10000\t150分\n",
|
||
"10000 > 税后净利均值 >= 1000\t100分\n",
|
||
"1000 > 税后净利均值\t0分"
|
||
],
|
||
"id": "dbcb1d6b23582f3e"
|
||
},
|
||
{
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2025-01-14T14:23:29.214393Z",
|
||
"start_time": "2025-01-14T14:23:22.256675Z"
|
||
}
|
||
},
|
||
"cell_type": "code",
|
||
"source": [
|
||
"def score_by_net_income(code):\n",
|
||
" temp_df = finance_df[finance_df[\"code\"] == code].copy()\n",
|
||
" average_net_income = temp_df.nlargest(5, \"year\")[\"net_income\"].mean()\n",
|
||
"\n",
|
||
" if average_net_income >= 10000 * 10000000:\n",
|
||
" return 150\n",
|
||
" elif average_net_income >= 1000 * 10000000:\n",
|
||
" return 100\n",
|
||
" else:\n",
|
||
" return 0\n",
|
||
"\n",
|
||
"\n",
|
||
"codes = list(map(lambda x: add_score(x, score_by_net_income(x[0])), codes))"
|
||
],
|
||
"id": "2f19c7fbb0afaa49",
|
||
"outputs": [],
|
||
"execution_count": 9
|
||
},
|
||
{
|
||
"metadata": {},
|
||
"cell_type": "markdown",
|
||
"source": [
|
||
"现金状况 分析\t总资产周转率 与 现金与约当现金占总资产的关系,可以看出公司的现金状况是否健康。\n",
|
||
"规则①:总资产周转率 > 0.8 且 现金与约当现金占总资产(%) >= 10\t50分\n",
|
||
"规则②:总资产周转率 < 0.8 且 现金与约当现金占总资产(%) >= 20\t50分\n",
|
||
"不符合 规则① 或 规则②\t0分"
|
||
],
|
||
"id": "2c6c934a376eef0d"
|
||
},
|
||
{
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2025-01-14T14:23:39.246944Z",
|
||
"start_time": "2025-01-14T14:23:30.739476Z"
|
||
}
|
||
},
|
||
"cell_type": "code",
|
||
"source": [
|
||
"def cal_total_assets_turnover_ratio(df):\n",
|
||
" df[\"prev_total_assets\"] = df[\"total_assets\"].shift(1)\n",
|
||
" df[\"total_assets_turnover_ratio\"] = df[\"total_revenue\"] / ((df[\"prev_total_assets\"] + df[\"total_assets\"]) / 2)\n",
|
||
" df.drop(columns=[\"prev_total_assets\"], inplace=True)\n",
|
||
"\n",
|
||
"\n",
|
||
"def cal_cash_ratio(df):\n",
|
||
" df[\"cash_ratio\"] = df[\"cash\"] / df[\"total_assets\"]\n",
|
||
"\n",
|
||
"\n",
|
||
"def score_by_assets_turnover_and_cash(code):\n",
|
||
" temp_df = finance_df[finance_df[\"code\"] == code].copy()\n",
|
||
"\n",
|
||
" # 总资产周转率\n",
|
||
" cal_total_assets_turnover_ratio(temp_df)\n",
|
||
" total_assets_turnover_ratio = \\\n",
|
||
" temp_df[temp_df[\"year\"] == temp_df[\"year\"].max()][\"total_assets_turnover_ratio\"].values[0] * 100\n",
|
||
"\n",
|
||
" # 现金比率\n",
|
||
" cal_cash_ratio(temp_df)\n",
|
||
" cash_ratio = temp_df[temp_df[\"year\"] == temp_df[\"year\"].max()][\"cash_ratio\"].values[0] * 100\n",
|
||
"\n",
|
||
" if total_assets_turnover_ratio > 80 and cash_ratio >= 10:\n",
|
||
" return 50\n",
|
||
" elif total_assets_turnover_ratio < 80 and cash_ratio >= 20:\n",
|
||
" return 50\n",
|
||
" else:\n",
|
||
" return 0\n",
|
||
"\n",
|
||
"\n",
|
||
"codes = list(map(lambda x: add_score(x, score_by_assets_turnover_and_cash(x[0])), codes))"
|
||
],
|
||
"id": "31be2cb671b7adde",
|
||
"outputs": [],
|
||
"execution_count": 10
|
||
},
|
||
{
|
||
"metadata": {},
|
||
"cell_type": "markdown",
|
||
"source": [
|
||
"收现日数(日)\t平均收现日数越短,说明公司的经营能力越强。\n",
|
||
"30 >= 平均收现日数\t20分\n",
|
||
"平均收现日数 > 30\t0分\n",
|
||
"\n",
|
||
"销货日数(日)\t平均销货日数越短,说明公司商品越畅销。\n",
|
||
"30 >= 平均销货日数\t20分\n",
|
||
"平均销货日数 > 30\t0分\n",
|
||
"\n",
|
||
"收现日数+销货日数(日)\t生意周期 是否足够优秀,越短说明每年能做的生意趟数越多,经营能力就越强。\n",
|
||
"40 >= 收现日数+销货日数\t20分\n",
|
||
"60 >= 收现日数+销货日数 > 40\t10分\n",
|
||
"平均销货日数 > 60\t0分"
|
||
],
|
||
"id": "41ac526b0296b44b"
|
||
},
|
||
{
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2025-01-14T14:23:47.733800Z",
|
||
"start_time": "2025-01-14T14:23:40.102117Z"
|
||
}
|
||
},
|
||
"cell_type": "code",
|
||
"source": [
|
||
"# 收现日数\n",
|
||
"def cal_collection_cash_period(df):\n",
|
||
" df[\"collection_cash_period\"] = 360 / (df[\"total_revenue\"] / df[\"accounts_receivable\"])\n",
|
||
"\n",
|
||
"\n",
|
||
"# 销货日数\n",
|
||
"def cal_sales_period(df):\n",
|
||
" df[\"sales_period\"] = 360 / (df[\"operating_costs\"] / df[\"inventories\"])\n",
|
||
"\n",
|
||
"\n",
|
||
"def score_by_collection_cash_period_and_sales_period(code):\n",
|
||
" temp_df = finance_df[finance_df[\"code\"] == code].copy()\n",
|
||
"\n",
|
||
" cal_collection_cash_period(temp_df)\n",
|
||
" collection_cash_period = temp_df[temp_df[\"year\"] == temp_df[\"year\"].max()][\"collection_cash_period\"].values[0]\n",
|
||
"\n",
|
||
" cal_sales_period(temp_df)\n",
|
||
" sales_period = temp_df[temp_df[\"year\"] == temp_df[\"year\"].max()][\"sales_period\"].values[0]\n",
|
||
"\n",
|
||
" score = 0\n",
|
||
" if collection_cash_period < 30:\n",
|
||
" score += 20\n",
|
||
"\n",
|
||
" if sales_period < 30:\n",
|
||
" score += 20\n",
|
||
"\n",
|
||
" if (collection_cash_period + sales_period) < 40:\n",
|
||
" score += 20\n",
|
||
" elif (collection_cash_period + sales_period) < 60:\n",
|
||
" score += 10\n",
|
||
"\n",
|
||
" return score\n",
|
||
"\n",
|
||
"\n",
|
||
"codes = list(map(lambda x: add_score(x, score_by_collection_cash_period_and_sales_period(x[0])), codes))"
|
||
],
|
||
"id": "ab6ff79c2650db7c",
|
||
"outputs": [],
|
||
"execution_count": 11
|
||
},
|
||
{
|
||
"metadata": {},
|
||
"cell_type": "markdown",
|
||
"source": [
|
||
"毛利率(%)\t毛利率 是否保持平稳,不大起大落。\n",
|
||
"30% >= 毛利率平均波动幅度\t50分\n",
|
||
"毛利率平均波动幅度 > 30%\t0分"
|
||
],
|
||
"id": "a53bfdb799df8f48"
|
||
},
|
||
{
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2025-01-14T14:23:57.280972Z",
|
||
"start_time": "2025-01-14T14:23:49.457909Z"
|
||
}
|
||
},
|
||
"cell_type": "code",
|
||
"source": [
|
||
"# 毛利率\n",
|
||
"def cal_gross_profit_ratio(df):\n",
|
||
" df[\"gross_profit_ratio\"] = (df[\"total_revenue\"] - df[\"operating_costs\"]) / df[\"total_revenue\"]\n",
|
||
"\n",
|
||
"\n",
|
||
"def score_by_gross_profit_ratio_volatility(code):\n",
|
||
" temp_df = finance_df[finance_df[\"code\"] == code].copy()\n",
|
||
" cal_gross_profit_ratio(temp_df)\n",
|
||
" gross_profit_ratio_std = temp_df.nlargest(5, \"year\")[\"gross_profit_ratio\"].std() * 100\n",
|
||
"\n",
|
||
" if gross_profit_ratio_std < 30:\n",
|
||
" return 50\n",
|
||
" else:\n",
|
||
" return 0\n",
|
||
"\n",
|
||
"\n",
|
||
"codes = list(map(lambda x: add_score(x, score_by_gross_profit_ratio_volatility(x[0])), codes))"
|
||
],
|
||
"id": "8e58e0114851ebcb",
|
||
"outputs": [],
|
||
"execution_count": 12
|
||
},
|
||
{
|
||
"metadata": {},
|
||
"cell_type": "markdown",
|
||
"source": [
|
||
"经营安全边际率(%)\t经营安全边际率越高,说明公司能够很好的控制成本,把大部分利润转化成实际收益, 获利能力很强,有利于抵御经济波动和价格竞争等影响。\n",
|
||
"经营安全边际率 >= 70\t50分\n",
|
||
"70 > 经营安全边际率 >= 50\t30分\n",
|
||
"50 > 经营安全边际率 >= 30\t10分\n",
|
||
"30 > 经营安全边际率\t0分"
|
||
],
|
||
"id": "6613ab8263d4afef"
|
||
},
|
||
{
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2025-01-14T14:24:05.675449Z",
|
||
"start_time": "2025-01-14T14:23:58.156821Z"
|
||
}
|
||
},
|
||
"cell_type": "code",
|
||
"source": [
|
||
"# 经营安全边际\n",
|
||
"def cal_operating_safety_margin(df):\n",
|
||
" # 经营利润率\n",
|
||
" df[\"operating_profit_ratio\"] = df[\"operating_profit\"] / df[\"total_revenue\"]\n",
|
||
" df[\"operating_safety_margin\"] = df[\"operating_profit_ratio\"] / df[\"gross_profit_ratio\"]\n",
|
||
"\n",
|
||
"\n",
|
||
"def score_by_operating_safety_margin(code):\n",
|
||
" temp_df = finance_df[finance_df[\"code\"] == code].copy()\n",
|
||
" cal_gross_profit_ratio(temp_df)\n",
|
||
" cal_operating_safety_margin(temp_df)\n",
|
||
"\n",
|
||
" operating_safety_margin = temp_df[temp_df[\"year\"] == temp_df[\"year\"].max()][\"operating_safety_margin\"].values[0]\n",
|
||
"\n",
|
||
" if operating_safety_margin >= 70:\n",
|
||
" return 50\n",
|
||
" elif operating_safety_margin >= 50:\n",
|
||
" return 30\n",
|
||
" elif operating_safety_margin >= 30:\n",
|
||
" return 10\n",
|
||
" else:\n",
|
||
" return 0\n",
|
||
"\n",
|
||
"\n",
|
||
"codes = list(map(lambda x: add_score(x, score_by_operating_safety_margin(x[0])), codes))"
|
||
],
|
||
"id": "d07048f574e163ab",
|
||
"outputs": [],
|
||
"execution_count": 13
|
||
},
|
||
{
|
||
"metadata": {},
|
||
"cell_type": "markdown",
|
||
"source": [
|
||
"税后净利\n",
|
||
"年份由近(A)~远(E)\t公司赚的钱是否在逐年增长,是股价能长期上涨的基础。\n",
|
||
"A年 > B年 (+) / A年 < B年 (-)\t+30分 / -30分\n",
|
||
"B年 > C年 (+) / B年 < C年 (-)\t+25分 / -25分\n",
|
||
"C年 > D年 (+) / C年 < D年 (-)\t+20分 / -20分\n",
|
||
"D年 > E年 (+) / D年 < E年 (-)\t+15分 / -15分"
|
||
],
|
||
"id": "2ee3712525455954"
|
||
},
|
||
{
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2025-01-14T14:24:13.783225Z",
|
||
"start_time": "2025-01-14T14:24:06.605156Z"
|
||
}
|
||
},
|
||
"cell_type": "code",
|
||
"source": [
|
||
"def score_by_net_income_ascending(code):\n",
|
||
" temp_df = finance_df[finance_df[\"code\"] == code].copy()[[\"year\", \"net_income\"]]\n",
|
||
" temp_df.sort_values(by=\"year\", ascending=False, inplace=True)\n",
|
||
" temp_df.set_index(keys=\"year\", drop=True, inplace=True)\n",
|
||
"\n",
|
||
" score = 0\n",
|
||
" if temp_df.iloc[0].values[0] > temp_df.iloc[1].values[0]:\n",
|
||
" score += 30\n",
|
||
" else:\n",
|
||
" score -= 30\n",
|
||
"\n",
|
||
" if temp_df.iloc[1].values[0] > temp_df.iloc[2].values[0]:\n",
|
||
" score += 25\n",
|
||
" else:\n",
|
||
" score -= 25\n",
|
||
"\n",
|
||
" if temp_df.iloc[2].values[0] > temp_df.iloc[3].values[0]:\n",
|
||
" score += 20\n",
|
||
" else:\n",
|
||
" score -= 20\n",
|
||
"\n",
|
||
" if temp_df.iloc[3].values[0] > temp_df.iloc[4].values[0]:\n",
|
||
" score += 15\n",
|
||
" else:\n",
|
||
" score -= 15\n",
|
||
"\n",
|
||
" return score\n",
|
||
"\n",
|
||
"\n",
|
||
"codes = list(map(lambda x: add_score(x, score_by_net_income_ascending(x[0])), codes))"
|
||
],
|
||
"id": "4ab6a7b485dc9349",
|
||
"outputs": [],
|
||
"execution_count": 14
|
||
},
|
||
{
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2025-01-14T14:24:21.962980Z",
|
||
"start_time": "2025-01-14T14:24:14.785970Z"
|
||
}
|
||
},
|
||
"cell_type": "code",
|
||
"source": [
|
||
"def score_by_operating_net_cash_flow_ascending(code):\n",
|
||
" temp_df = finance_df[finance_df[\"code\"] == code].copy()[[\"year\", \"operating_net_cash_flow\"]]\n",
|
||
" temp_df.sort_values(by=\"year\", ascending=False, inplace=True)\n",
|
||
" temp_df.set_index(keys=\"year\", drop=True, inplace=True)\n",
|
||
"\n",
|
||
" score = 0\n",
|
||
" if temp_df.iloc[0].values[0] > temp_df.iloc[1].values[0]:\n",
|
||
" score += 30\n",
|
||
" else:\n",
|
||
" score -= 30\n",
|
||
"\n",
|
||
" if temp_df.iloc[1].values[0] > temp_df.iloc[2].values[0]:\n",
|
||
" score += 25\n",
|
||
" else:\n",
|
||
" score -= 25\n",
|
||
"\n",
|
||
" if temp_df.iloc[2].values[0] > temp_df.iloc[3].values[0]:\n",
|
||
" score += 20\n",
|
||
" else:\n",
|
||
" score -= 20\n",
|
||
"\n",
|
||
" if temp_df.iloc[3].values[0] > temp_df.iloc[4].values[0]:\n",
|
||
" score += 15\n",
|
||
" else:\n",
|
||
" score -= 15\n",
|
||
"\n",
|
||
" return score\n",
|
||
"\n",
|
||
"\n",
|
||
"codes = list(map(lambda x: add_score(x, score_by_operating_net_cash_flow_ascending(x[0])), codes))"
|
||
],
|
||
"id": "d6644089e803a79d",
|
||
"outputs": [],
|
||
"execution_count": 15
|
||
},
|
||
{
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2025-01-14T14:24:24.969522Z",
|
||
"start_time": "2025-01-14T14:24:24.957769Z"
|
||
}
|
||
},
|
||
"cell_type": "code",
|
||
"source": [
|
||
"df = pd.DataFrame(\n",
|
||
" codes,\n",
|
||
" columns=[\"code\", \"name\", \"score\", \"roe_score\", \"roa_score\", \"net_income\", \"assets_turnover_and_cash\",\n",
|
||
" \"collection_cash_period_and_sales_period\", \"gross_profit_ratio_volatility\",\n",
|
||
" \"operating_safety_margin\", \"net_income_ascending\",\n",
|
||
" \"operating_net_cash_flow_ascending\"]\n",
|
||
")\n",
|
||
"df.sort_values(by=\"score\", ascending=False, inplace=True)\n",
|
||
"df"
|
||
],
|
||
"id": "ef9e6259efc1c1d0",
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
" code name score roe_score roa_score net_income \\\n",
|
||
"2393 600519.SH 贵州茅台 950 500 100 100 \n",
|
||
"323 000858.SZ 五粮液 910 450 100 100 \n",
|
||
"3238 603688.SH 石英股份 850 500 100 0 \n",
|
||
"144 000568.SZ 泸州老窖 850 450 100 0 \n",
|
||
"2336 600438.SH 通威股份 840 450 80 100 \n",
|
||
"... ... ... ... ... ... ... \n",
|
||
"1703 300436.SZ 广生堂 -100 0 0 0 \n",
|
||
"2441 600579.SH 克劳斯 -100 0 0 0 \n",
|
||
"1054 002672.SZ 东江环保 -130 0 0 0 \n",
|
||
"1488 300204.SZ 舒泰神 -130 0 0 0 \n",
|
||
"1619 300345.SZ 华民股份 -130 0 0 0 \n",
|
||
"\n",
|
||
" assets_turnover_and_cash collection_cash_period_and_sales_period \\\n",
|
||
"2393 50 20 \n",
|
||
"323 50 20 \n",
|
||
"3238 50 0 \n",
|
||
"144 50 20 \n",
|
||
"2336 50 50 \n",
|
||
"... ... ... \n",
|
||
"1703 0 0 \n",
|
||
"2441 0 0 \n",
|
||
"1054 0 0 \n",
|
||
"1488 0 0 \n",
|
||
"1619 0 0 \n",
|
||
"\n",
|
||
" gross_profit_ratio_volatility operating_safety_margin \\\n",
|
||
"2393 50 0 \n",
|
||
"323 50 0 \n",
|
||
"3238 50 0 \n",
|
||
"144 50 0 \n",
|
||
"2336 50 0 \n",
|
||
"... ... ... \n",
|
||
"1703 50 0 \n",
|
||
"2441 50 0 \n",
|
||
"1054 50 0 \n",
|
||
"1488 50 0 \n",
|
||
"1619 50 0 \n",
|
||
"\n",
|
||
" net_income_ascending operating_net_cash_flow_ascending \n",
|
||
"2393 90 40 \n",
|
||
"323 90 50 \n",
|
||
"3238 90 60 \n",
|
||
"144 90 90 \n",
|
||
"2336 30 30 \n",
|
||
"... ... ... \n",
|
||
"1703 -60 -90 \n",
|
||
"2441 -90 -60 \n",
|
||
"1054 -90 -90 \n",
|
||
"1488 -90 -90 \n",
|
||
"1619 -90 -90 \n",
|
||
"\n",
|
||
"[3384 rows x 12 columns]"
|
||
],
|
||
"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>code</th>\n",
|
||
" <th>name</th>\n",
|
||
" <th>score</th>\n",
|
||
" <th>roe_score</th>\n",
|
||
" <th>roa_score</th>\n",
|
||
" <th>net_income</th>\n",
|
||
" <th>assets_turnover_and_cash</th>\n",
|
||
" <th>collection_cash_period_and_sales_period</th>\n",
|
||
" <th>gross_profit_ratio_volatility</th>\n",
|
||
" <th>operating_safety_margin</th>\n",
|
||
" <th>net_income_ascending</th>\n",
|
||
" <th>operating_net_cash_flow_ascending</th>\n",
|
||
" </tr>\n",
|
||
" </thead>\n",
|
||
" <tbody>\n",
|
||
" <tr>\n",
|
||
" <th>2393</th>\n",
|
||
" <td>600519.SH</td>\n",
|
||
" <td>贵州茅台</td>\n",
|
||
" <td>950</td>\n",
|
||
" <td>500</td>\n",
|
||
" <td>100</td>\n",
|
||
" <td>100</td>\n",
|
||
" <td>50</td>\n",
|
||
" <td>20</td>\n",
|
||
" <td>50</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>90</td>\n",
|
||
" <td>40</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>323</th>\n",
|
||
" <td>000858.SZ</td>\n",
|
||
" <td>五粮液</td>\n",
|
||
" <td>910</td>\n",
|
||
" <td>450</td>\n",
|
||
" <td>100</td>\n",
|
||
" <td>100</td>\n",
|
||
" <td>50</td>\n",
|
||
" <td>20</td>\n",
|
||
" <td>50</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>90</td>\n",
|
||
" <td>50</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>3238</th>\n",
|
||
" <td>603688.SH</td>\n",
|
||
" <td>石英股份</td>\n",
|
||
" <td>850</td>\n",
|
||
" <td>500</td>\n",
|
||
" <td>100</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>50</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>50</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>90</td>\n",
|
||
" <td>60</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>144</th>\n",
|
||
" <td>000568.SZ</td>\n",
|
||
" <td>泸州老窖</td>\n",
|
||
" <td>850</td>\n",
|
||
" <td>450</td>\n",
|
||
" <td>100</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>50</td>\n",
|
||
" <td>20</td>\n",
|
||
" <td>50</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>90</td>\n",
|
||
" <td>90</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>2336</th>\n",
|
||
" <td>600438.SH</td>\n",
|
||
" <td>通威股份</td>\n",
|
||
" <td>840</td>\n",
|
||
" <td>450</td>\n",
|
||
" <td>80</td>\n",
|
||
" <td>100</td>\n",
|
||
" <td>50</td>\n",
|
||
" <td>50</td>\n",
|
||
" <td>50</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>30</td>\n",
|
||
" <td>30</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>...</th>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" <td>...</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>1703</th>\n",
|
||
" <td>300436.SZ</td>\n",
|
||
" <td>广生堂</td>\n",
|
||
" <td>-100</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>50</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>-60</td>\n",
|
||
" <td>-90</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>2441</th>\n",
|
||
" <td>600579.SH</td>\n",
|
||
" <td>克劳斯</td>\n",
|
||
" <td>-100</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>50</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>-90</td>\n",
|
||
" <td>-60</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>1054</th>\n",
|
||
" <td>002672.SZ</td>\n",
|
||
" <td>东江环保</td>\n",
|
||
" <td>-130</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>50</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>-90</td>\n",
|
||
" <td>-90</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>1488</th>\n",
|
||
" <td>300204.SZ</td>\n",
|
||
" <td>舒泰神</td>\n",
|
||
" <td>-130</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>50</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>-90</td>\n",
|
||
" <td>-90</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>1619</th>\n",
|
||
" <td>300345.SZ</td>\n",
|
||
" <td>华民股份</td>\n",
|
||
" <td>-130</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>50</td>\n",
|
||
" <td>0</td>\n",
|
||
" <td>-90</td>\n",
|
||
" <td>-90</td>\n",
|
||
" </tr>\n",
|
||
" </tbody>\n",
|
||
"</table>\n",
|
||
"<p>3384 rows × 12 columns</p>\n",
|
||
"</div>"
|
||
]
|
||
},
|
||
"execution_count": 16,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"execution_count": 16
|
||
},
|
||
{
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2025-01-14T14:25:22.482926Z",
|
||
"start_time": "2025-01-14T14:25:22.476830Z"
|
||
}
|
||
},
|
||
"cell_type": "code",
|
||
"source": "df[:100][\"code\"]",
|
||
"id": "32b5b4778985afaa",
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"2393 600519.SH\n",
|
||
"323 000858.SZ\n",
|
||
"3238 603688.SH\n",
|
||
"144 000568.SZ\n",
|
||
"2336 600438.SH\n",
|
||
" ... \n",
|
||
"3318 603871.SH\n",
|
||
"2542 600702.SH\n",
|
||
"1166 002801.SZ\n",
|
||
"1227 002867.SZ\n",
|
||
"1754 300487.SZ\n",
|
||
"Name: code, Length: 100, dtype: object"
|
||
]
|
||
},
|
||
"execution_count": 17,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"execution_count": 17
|
||
},
|
||
{
|
||
"metadata": {
|
||
"ExecuteTime": {
|
||
"end_time": "2025-01-13T03:17:08.882164Z",
|
||
"start_time": "2025-01-13T03:17:08.862820Z"
|
||
}
|
||
},
|
||
"cell_type": "code",
|
||
"source": [
|
||
"temp_df = finance_df[finance_df[\"code\"] == \"600763.SH\"]\n",
|
||
"cal_roe(temp_df)\n",
|
||
"cal_roa(temp_df)\n",
|
||
"temp_df[[\"year\", \"roe\", \"roa\"]]"
|
||
],
|
||
"id": "e6d973f4ff98ebef",
|
||
"outputs": [
|
||
{
|
||
"name": "stderr",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"/var/folders/7h/w0cmp4zj6mn9br_6nyj310m40000gn/T/ipykernel_51974/3287426981.py:2: SettingWithCopyWarning: \n",
|
||
"A value is trying to be set on a copy of a slice from a DataFrame.\n",
|
||
"Try using .loc[row_indexer,col_indexer] = value instead\n",
|
||
"\n",
|
||
"See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
|
||
" df[\"prev_total_stockholder_interest\"] = df[\"total_stockholder_interest\"].shift(1)\n",
|
||
"/var/folders/7h/w0cmp4zj6mn9br_6nyj310m40000gn/T/ipykernel_51974/3287426981.py:3: SettingWithCopyWarning: \n",
|
||
"A value is trying to be set on a copy of a slice from a DataFrame.\n",
|
||
"Try using .loc[row_indexer,col_indexer] = value instead\n",
|
||
"\n",
|
||
"See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
|
||
" df[\"roe\"] = df[\"net_income\"] / ((df[\"prev_total_stockholder_interest\"] + df[\"total_stockholder_interest\"]) / 2)\n",
|
||
"/var/folders/7h/w0cmp4zj6mn9br_6nyj310m40000gn/T/ipykernel_51974/3287426981.py:4: SettingWithCopyWarning: \n",
|
||
"A value is trying to be set on a copy of a slice from a DataFrame\n",
|
||
"\n",
|
||
"See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
|
||
" df.drop(columns=[\"prev_total_stockholder_interest\"], inplace=True)\n",
|
||
"/var/folders/7h/w0cmp4zj6mn9br_6nyj310m40000gn/T/ipykernel_51974/3105409447.py:2: SettingWithCopyWarning: \n",
|
||
"A value is trying to be set on a copy of a slice from a DataFrame.\n",
|
||
"Try using .loc[row_indexer,col_indexer] = value instead\n",
|
||
"\n",
|
||
"See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
|
||
" df[\"prev_total_assets\"] = df[\"total_assets\"].shift(1)\n",
|
||
"/var/folders/7h/w0cmp4zj6mn9br_6nyj310m40000gn/T/ipykernel_51974/3105409447.py:3: SettingWithCopyWarning: \n",
|
||
"A value is trying to be set on a copy of a slice from a DataFrame.\n",
|
||
"Try using .loc[row_indexer,col_indexer] = value instead\n",
|
||
"\n",
|
||
"See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
|
||
" df[\"roa\"] = df[\"net_income\"] / ((df[\"prev_total_assets\"] + df[\"total_assets\"]) / 2)\n",
|
||
"/var/folders/7h/w0cmp4zj6mn9br_6nyj310m40000gn/T/ipykernel_51974/3105409447.py:4: SettingWithCopyWarning: \n",
|
||
"A value is trying to be set on a copy of a slice from a DataFrame\n",
|
||
"\n",
|
||
"See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
|
||
" df.drop(columns=[\"prev_total_assets\"], inplace=True)\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
" year roe roa\n",
|
||
"2979 2014 NaN NaN\n",
|
||
"7615 2015 0.245119 0.182412\n",
|
||
"12121 2016 0.148244 0.101560\n",
|
||
"16405 2017 0.226923 0.147172\n",
|
||
"21964 2018 0.282053 0.182929\n",
|
||
"25657 2019 0.297166 0.211903\n",
|
||
"29113 2020 0.252412 0.190406\n",
|
||
"36313 2021 0.286244 0.196068\n",
|
||
"40855 2022 0.182081 0.121805\n",
|
||
"45977 2023 0.149449 0.103658"
|
||
],
|
||
"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>year</th>\n",
|
||
" <th>roe</th>\n",
|
||
" <th>roa</th>\n",
|
||
" </tr>\n",
|
||
" </thead>\n",
|
||
" <tbody>\n",
|
||
" <tr>\n",
|
||
" <th>2979</th>\n",
|
||
" <td>2014</td>\n",
|
||
" <td>NaN</td>\n",
|
||
" <td>NaN</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>7615</th>\n",
|
||
" <td>2015</td>\n",
|
||
" <td>0.245119</td>\n",
|
||
" <td>0.182412</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>12121</th>\n",
|
||
" <td>2016</td>\n",
|
||
" <td>0.148244</td>\n",
|
||
" <td>0.101560</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>16405</th>\n",
|
||
" <td>2017</td>\n",
|
||
" <td>0.226923</td>\n",
|
||
" <td>0.147172</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>21964</th>\n",
|
||
" <td>2018</td>\n",
|
||
" <td>0.282053</td>\n",
|
||
" <td>0.182929</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>25657</th>\n",
|
||
" <td>2019</td>\n",
|
||
" <td>0.297166</td>\n",
|
||
" <td>0.211903</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>29113</th>\n",
|
||
" <td>2020</td>\n",
|
||
" <td>0.252412</td>\n",
|
||
" <td>0.190406</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>36313</th>\n",
|
||
" <td>2021</td>\n",
|
||
" <td>0.286244</td>\n",
|
||
" <td>0.196068</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>40855</th>\n",
|
||
" <td>2022</td>\n",
|
||
" <td>0.182081</td>\n",
|
||
" <td>0.121805</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>45977</th>\n",
|
||
" <td>2023</td>\n",
|
||
" <td>0.149449</td>\n",
|
||
" <td>0.103658</td>\n",
|
||
" </tr>\n",
|
||
" </tbody>\n",
|
||
"</table>\n",
|
||
"</div>"
|
||
]
|
||
},
|
||
"execution_count": 204,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"execution_count": 204
|
||
},
|
||
{
|
||
"metadata": {},
|
||
"cell_type": "code",
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
" ts_code end_date roe roa\n",
|
||
"4 600763.SH 20231231 14.0666 13.4808\n",
|
||
"10 600763.SH 20221231 17.7106 15.4075\n",
|
||
"11 600763.SH 20221231 17.7106 15.4075\n",
|
||
"18 600763.SH 20211231 27.9402 24.7367\n",
|
||
"19 600763.SH 20211231 27.9402 24.7367\n",
|
||
"26 600763.SH 20201231 25.0345 24.1350\n",
|
||
"27 600763.SH 20201231 25.0345 24.1350\n",
|
||
"34 600763.SH 20191231 29.8694 27.2723\n",
|
||
"35 600763.SH 20191231 29.8694 27.2723\n",
|
||
"42 600763.SH 20181231 28.7803 23.4500\n",
|
||
"43 600763.SH 20181231 28.7803 23.4500\n",
|
||
"50 600763.SH 20171231 23.9279 18.8885\n",
|
||
"51 600763.SH 20171231 23.9279 18.8885\n",
|
||
"58 600763.SH 20161231 16.6081 13.5829\n",
|
||
"59 600763.SH 20161231 16.6081 13.5829\n",
|
||
"66 600763.SH 20151231 26.5184 22.2861\n",
|
||
"67 600763.SH 20151231 26.5184 22.2861\n",
|
||
"74 600763.SH 20141231 19.1679 20.0538\n",
|
||
"75 600763.SH 20141231 19.1679 20.0538"
|
||
],
|
||
"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>roe</th>\n",
|
||
" <th>roa</th>\n",
|
||
" </tr>\n",
|
||
" </thead>\n",
|
||
" <tbody>\n",
|
||
" <tr>\n",
|
||
" <th>4</th>\n",
|
||
" <td>600763.SH</td>\n",
|
||
" <td>20231231</td>\n",
|
||
" <td>14.0666</td>\n",
|
||
" <td>13.4808</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>10</th>\n",
|
||
" <td>600763.SH</td>\n",
|
||
" <td>20221231</td>\n",
|
||
" <td>17.7106</td>\n",
|
||
" <td>15.4075</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>11</th>\n",
|
||
" <td>600763.SH</td>\n",
|
||
" <td>20221231</td>\n",
|
||
" <td>17.7106</td>\n",
|
||
" <td>15.4075</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>18</th>\n",
|
||
" <td>600763.SH</td>\n",
|
||
" <td>20211231</td>\n",
|
||
" <td>27.9402</td>\n",
|
||
" <td>24.7367</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>19</th>\n",
|
||
" <td>600763.SH</td>\n",
|
||
" <td>20211231</td>\n",
|
||
" <td>27.9402</td>\n",
|
||
" <td>24.7367</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>26</th>\n",
|
||
" <td>600763.SH</td>\n",
|
||
" <td>20201231</td>\n",
|
||
" <td>25.0345</td>\n",
|
||
" <td>24.1350</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>27</th>\n",
|
||
" <td>600763.SH</td>\n",
|
||
" <td>20201231</td>\n",
|
||
" <td>25.0345</td>\n",
|
||
" <td>24.1350</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>34</th>\n",
|
||
" <td>600763.SH</td>\n",
|
||
" <td>20191231</td>\n",
|
||
" <td>29.8694</td>\n",
|
||
" <td>27.2723</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>35</th>\n",
|
||
" <td>600763.SH</td>\n",
|
||
" <td>20191231</td>\n",
|
||
" <td>29.8694</td>\n",
|
||
" <td>27.2723</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>42</th>\n",
|
||
" <td>600763.SH</td>\n",
|
||
" <td>20181231</td>\n",
|
||
" <td>28.7803</td>\n",
|
||
" <td>23.4500</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>43</th>\n",
|
||
" <td>600763.SH</td>\n",
|
||
" <td>20181231</td>\n",
|
||
" <td>28.7803</td>\n",
|
||
" <td>23.4500</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>50</th>\n",
|
||
" <td>600763.SH</td>\n",
|
||
" <td>20171231</td>\n",
|
||
" <td>23.9279</td>\n",
|
||
" <td>18.8885</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>51</th>\n",
|
||
" <td>600763.SH</td>\n",
|
||
" <td>20171231</td>\n",
|
||
" <td>23.9279</td>\n",
|
||
" <td>18.8885</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>58</th>\n",
|
||
" <td>600763.SH</td>\n",
|
||
" <td>20161231</td>\n",
|
||
" <td>16.6081</td>\n",
|
||
" <td>13.5829</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>59</th>\n",
|
||
" <td>600763.SH</td>\n",
|
||
" <td>20161231</td>\n",
|
||
" <td>16.6081</td>\n",
|
||
" <td>13.5829</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>66</th>\n",
|
||
" <td>600763.SH</td>\n",
|
||
" <td>20151231</td>\n",
|
||
" <td>26.5184</td>\n",
|
||
" <td>22.2861</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>67</th>\n",
|
||
" <td>600763.SH</td>\n",
|
||
" <td>20151231</td>\n",
|
||
" <td>26.5184</td>\n",
|
||
" <td>22.2861</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>74</th>\n",
|
||
" <td>600763.SH</td>\n",
|
||
" <td>20141231</td>\n",
|
||
" <td>19.1679</td>\n",
|
||
" <td>20.0538</td>\n",
|
||
" </tr>\n",
|
||
" <tr>\n",
|
||
" <th>75</th>\n",
|
||
" <td>600763.SH</td>\n",
|
||
" <td>20141231</td>\n",
|
||
" <td>19.1679</td>\n",
|
||
" <td>20.0538</td>\n",
|
||
" </tr>\n",
|
||
" </tbody>\n",
|
||
"</table>\n",
|
||
"</div>"
|
||
]
|
||
},
|
||
"execution_count": 206,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"execution_count": 206,
|
||
"source": [
|
||
"temp_df = ts_pro.fina_indicator(\n",
|
||
" ts_code=\"600763.SH\", start_date=\"20140101\", end_date=\"20241231\",\n",
|
||
" fields=\"ts_code,end_date,roe,roa\"\n",
|
||
")\n",
|
||
"temp_df = temp_df[temp_df[\"end_date\"].str.endswith(\"1231\")]\n",
|
||
"# temp_df[\"end_date\"] = temp_df[\"end_date\"].str[:4]\n",
|
||
"# temp_df = temp_df.drop_duplicates(subset=[\"end_date\"], keep=\"last\")\n",
|
||
"temp_df"
|
||
],
|
||
"id": "b220252765677c76"
|
||
}
|
||
],
|
||
"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
|
||
}
|