1
0

尝试加载数据

This commit is contained in:
2026-01-29 18:10:40 +08:00
parent 9f06ebf87d
commit b90d030899
9 changed files with 499 additions and 75 deletions

16
.idea/csv-editor.xml generated Normal file
View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CsvFileAttributes">
<option name="attributeMap">
<map>
<entry key="/dumpDataPreview">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
</map>
</option>
</component>
</project>

7
.idea/dataSources.xml generated
View File

@@ -8,5 +8,12 @@
<jdbc-url>jdbc:postgresql://81.71.3.24:6785/leopard_dev</jdbc-url>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
<data-source source="LOCAL" name="leopard.sqlite" uuid="c9e16f8e-81be-45cf-847c-47a6750eeee2">
<driver-ref>sqlite.xerial</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
<jdbc-url>jdbc:sqlite:$USER_HOME$/Documents/leopard_data/leopard.sqlite</jdbc-url>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
</component>
</project>

1
.idea/sqldialects.xml generated
View File

@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="SqlDialectMappings">
<file url="file://$PROJECT_DIR$/sql/initial.sql" dialect="SQLite" />
<file url="PROJECT" dialect="PostgreSQL" />
</component>
</project>

1
.idea/vcs.xml generated
View File

@@ -2,6 +2,5 @@
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="$PROJECT_DIR$/backtestingpy" vcs="Git" />
</component>
</project>

View File

@@ -0,0 +1,138 @@
{
"cells": [
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-01-29T10:09:22.171634Z",
"start_time": "2026-01-29T08:27:03.148937Z"
}
},
"cell_type": "code",
"source": [
"import urllib.parse\n",
"\n",
"import pandas as pd\n",
"import sqlalchemy\n",
"from sqlalchemy.orm import DeclarativeBase, Session\n",
"\n",
"postgresql_engin = sqlalchemy.create_engine(\n",
" f\"postgresql://leopard:{urllib.parse.quote_plus(\"9NEzFzovnddf@PyEP?e*AYAWnCyd7UhYwQK$pJf>7?ccFiN^x4$eKEZ5~E<7<+~X\")}@81.71.3.24:6785/leopard\"\n",
")\n",
"sqlite_engine = sqlalchemy.create_engine(f\"sqlite:////Users/lanyuanxiaoyao/Documents/leopard_data/leopard.sqlite\")\n",
"\n",
"\n",
"class Base(DeclarativeBase):\n",
" pass\n",
"\n",
"\n",
"class Daily(Base):\n",
" __tablename__ = 'daily'\n",
"\n",
" code = sqlalchemy.Column(sqlalchemy.String, primary_key=True)\n",
" trade_date = sqlalchemy.Column(sqlalchemy.Date)\n",
" open = sqlalchemy.Column(sqlalchemy.Double)\n",
" close = sqlalchemy.Column(sqlalchemy.Double)\n",
" high = sqlalchemy.Column(sqlalchemy.Double)\n",
" low = sqlalchemy.Column(sqlalchemy.Double)\n",
" previous_close = sqlalchemy.Column(sqlalchemy.Double)\n",
" turnover = sqlalchemy.Column(sqlalchemy.Double)\n",
" volume = sqlalchemy.Column(sqlalchemy.Integer)\n",
" price_change_amount = sqlalchemy.Column(sqlalchemy.Double)\n",
" factor = sqlalchemy.Column(sqlalchemy.Double)\n",
"\n",
"\n",
"try:\n",
" stock_df = pd.read_sql_table(\"stock\", sqlite_engine)\n",
" for index, code in enumerate(stock_df[\"code\"]):\n",
" print(code)\n",
" daily_df = pd.read_sql(\n",
" f\"\"\"\n",
" select code,\n",
" trade_date,\n",
" open,\n",
" close,\n",
" high,\n",
" low,\n",
" previous_close,\n",
" turnover,\n",
" volume,\n",
" price_change_amount,\n",
" factor\n",
" from leopard_daily d\n",
" left join leopard_stock s on d.stock_id = s.id\n",
" where s.code = '{code}'\n",
" \"\"\",\n",
" postgresql_engin\n",
" )\n",
" with Session(sqlite_engine) as session:\n",
" for _, row in daily_df.iterrows():\n",
" session.add(\n",
" Daily(\n",
" code=row[\"code\"],\n",
" trade_date=row[\"trade_date\"],\n",
" open=row[\"open\"],\n",
" close=row[\"close\"],\n",
" high=row[\"high\"],\n",
" low=row[\"low\"],\n",
" previous_close=row[\"previous_close\"],\n",
" turnover=row[\"turnover\"],\n",
" volume=row[\"volume\"],\n",
" price_change_amount=row[\"price_change_amount\"],\n",
" factor=row[\"factor\"]\n",
" )\n",
" )\n",
" session.flush()\n",
" session.commit()\n",
"finally:\n",
" postgresql_engin.dispose()\n",
" sqlite_engine.dispose()"
],
"id": "48821306efc640a1",
"outputs": [
{
"ename": "KeyboardInterrupt",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001B[31m---------------------------------------------------------------------------\u001B[39m",
"\u001B[31mKeyboardInterrupt\u001B[39m Traceback (most recent call last)",
"\u001B[36mCell\u001B[39m\u001B[36m \u001B[39m\u001B[32mIn[26]\u001B[39m\u001B[32m, line 37\u001B[39m\n\u001B[32m 35\u001B[39m \u001B[38;5;28;01mfor\u001B[39;00m index, code \u001B[38;5;129;01min\u001B[39;00m \u001B[38;5;28menumerate\u001B[39m(stock_df[\u001B[33m\"\u001B[39m\u001B[33mcode\u001B[39m\u001B[33m\"\u001B[39m]):\n\u001B[32m 36\u001B[39m \u001B[38;5;28mprint\u001B[39m(code)\n\u001B[32m---> \u001B[39m\u001B[32m37\u001B[39m daily_df = \u001B[43mpd\u001B[49m\u001B[43m.\u001B[49m\u001B[43mread_sql\u001B[49m\u001B[43m(\u001B[49m\n\u001B[32m 38\u001B[39m \u001B[43m \u001B[49m\u001B[33;43mf\u001B[39;49m\u001B[33;43m\"\"\"\u001B[39;49m\n\u001B[32m 39\u001B[39m \u001B[33;43m select code,\u001B[39;49m\n\u001B[32m 40\u001B[39m \u001B[33;43m trade_date,\u001B[39;49m\n\u001B[32m 41\u001B[39m \u001B[33;43m open,\u001B[39;49m\n\u001B[32m 42\u001B[39m \u001B[33;43m close,\u001B[39;49m\n\u001B[32m 43\u001B[39m \u001B[33;43m high,\u001B[39;49m\n\u001B[32m 44\u001B[39m \u001B[33;43m low,\u001B[39;49m\n\u001B[32m 45\u001B[39m \u001B[33;43m previous_close,\u001B[39;49m\n\u001B[32m 46\u001B[39m \u001B[33;43m turnover,\u001B[39;49m\n\u001B[32m 47\u001B[39m \u001B[33;43m volume,\u001B[39;49m\n\u001B[32m 48\u001B[39m \u001B[33;43m price_change_amount,\u001B[39;49m\n\u001B[32m 49\u001B[39m \u001B[33;43m factor\u001B[39;49m\n\u001B[32m 50\u001B[39m \u001B[33;43m from leopard_daily d\u001B[39;49m\n\u001B[32m 51\u001B[39m \u001B[33;43m left join leopard_stock s on d.stock_id = s.id\u001B[39;49m\n\u001B[32m 52\u001B[39m \u001B[33;43m where s.code = \u001B[39;49m\u001B[33;43m'\u001B[39;49m\u001B[38;5;132;43;01m{\u001B[39;49;00m\u001B[43mcode\u001B[49m\u001B[38;5;132;43;01m}\u001B[39;49;00m\u001B[33;43m'\u001B[39;49m\n\u001B[32m 53\u001B[39m \u001B[33;43m \u001B[39;49m\u001B[33;43m\"\"\"\u001B[39;49m\u001B[43m,\u001B[49m\n\u001B[32m 54\u001B[39m \u001B[43m \u001B[49m\u001B[43mpostgresql_engin\u001B[49m\n\u001B[32m 55\u001B[39m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 56\u001B[39m \u001B[38;5;28;01mwith\u001B[39;00m Session(sqlite_engine) \u001B[38;5;28;01mas\u001B[39;00m session:\n\u001B[32m 57\u001B[39m \u001B[38;5;28;01mfor\u001B[39;00m _, row \u001B[38;5;129;01min\u001B[39;00m daily_df.iterrows():\n",
"\u001B[36mFile \u001B[39m\u001B[32m~/Project/leopard_analysis/.venv/lib/python3.14/site-packages/pandas/io/sql.py:736\u001B[39m, in \u001B[36mread_sql\u001B[39m\u001B[34m(sql, con, index_col, coerce_float, params, parse_dates, columns, chunksize, dtype_backend, dtype)\u001B[39m\n\u001B[32m 726\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m pandas_sql.read_table(\n\u001B[32m 727\u001B[39m sql,\n\u001B[32m 728\u001B[39m index_col=index_col,\n\u001B[32m (...)\u001B[39m\u001B[32m 733\u001B[39m dtype_backend=dtype_backend,\n\u001B[32m 734\u001B[39m )\n\u001B[32m 735\u001B[39m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[32m--> \u001B[39m\u001B[32m736\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[43mpandas_sql\u001B[49m\u001B[43m.\u001B[49m\u001B[43mread_query\u001B[49m\u001B[43m(\u001B[49m\n\u001B[32m 737\u001B[39m \u001B[43m \u001B[49m\u001B[43msql\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 738\u001B[39m \u001B[43m \u001B[49m\u001B[43mindex_col\u001B[49m\u001B[43m=\u001B[49m\u001B[43mindex_col\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 739\u001B[39m \u001B[43m \u001B[49m\u001B[43mparams\u001B[49m\u001B[43m=\u001B[49m\u001B[43mparams\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 740\u001B[39m \u001B[43m \u001B[49m\u001B[43mcoerce_float\u001B[49m\u001B[43m=\u001B[49m\u001B[43mcoerce_float\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 741\u001B[39m \u001B[43m \u001B[49m\u001B[43mparse_dates\u001B[49m\u001B[43m=\u001B[49m\u001B[43mparse_dates\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 742\u001B[39m \u001B[43m \u001B[49m\u001B[43mchunksize\u001B[49m\u001B[43m=\u001B[49m\u001B[43mchunksize\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 743\u001B[39m \u001B[43m \u001B[49m\u001B[43mdtype_backend\u001B[49m\u001B[43m=\u001B[49m\u001B[43mdtype_backend\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 744\u001B[39m \u001B[43m \u001B[49m\u001B[43mdtype\u001B[49m\u001B[43m=\u001B[49m\u001B[43mdtype\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 745\u001B[39m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n",
"\u001B[36mFile \u001B[39m\u001B[32m~/Project/leopard_analysis/.venv/lib/python3.14/site-packages/pandas/io/sql.py:1848\u001B[39m, in \u001B[36mSQLDatabase.read_query\u001B[39m\u001B[34m(self, sql, index_col, coerce_float, parse_dates, params, chunksize, dtype, dtype_backend)\u001B[39m\n\u001B[32m 1791\u001B[39m \u001B[38;5;28;01mdef\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[34mread_query\u001B[39m(\n\u001B[32m 1792\u001B[39m \u001B[38;5;28mself\u001B[39m,\n\u001B[32m 1793\u001B[39m sql: \u001B[38;5;28mstr\u001B[39m,\n\u001B[32m (...)\u001B[39m\u001B[32m 1800\u001B[39m dtype_backend: DtypeBackend | Literal[\u001B[33m\"\u001B[39m\u001B[33mnumpy\u001B[39m\u001B[33m\"\u001B[39m] = \u001B[33m\"\u001B[39m\u001B[33mnumpy\u001B[39m\u001B[33m\"\u001B[39m,\n\u001B[32m 1801\u001B[39m ) -> DataFrame | Iterator[DataFrame]:\n\u001B[32m 1802\u001B[39m \u001B[38;5;250m \u001B[39m\u001B[33;03m\"\"\"\u001B[39;00m\n\u001B[32m 1803\u001B[39m \u001B[33;03m Read SQL query into a DataFrame.\u001B[39;00m\n\u001B[32m 1804\u001B[39m \n\u001B[32m (...)\u001B[39m\u001B[32m 1846\u001B[39m \n\u001B[32m 1847\u001B[39m \u001B[33;03m \"\"\"\u001B[39;00m\n\u001B[32m-> \u001B[39m\u001B[32m1848\u001B[39m result = \u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mexecute\u001B[49m\u001B[43m(\u001B[49m\u001B[43msql\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mparams\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 1849\u001B[39m columns = result.keys()\n\u001B[32m 1851\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m chunksize \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m:\n",
"\u001B[36mFile \u001B[39m\u001B[32m~/Project/leopard_analysis/.venv/lib/python3.14/site-packages/pandas/io/sql.py:1671\u001B[39m, in \u001B[36mSQLDatabase.execute\u001B[39m\u001B[34m(self, sql, params)\u001B[39m\n\u001B[32m 1669\u001B[39m args = [] \u001B[38;5;28;01mif\u001B[39;00m params \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m \u001B[38;5;28;01melse\u001B[39;00m [params]\n\u001B[32m 1670\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(sql, \u001B[38;5;28mstr\u001B[39m):\n\u001B[32m-> \u001B[39m\u001B[32m1671\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mcon\u001B[49m\u001B[43m.\u001B[49m\u001B[43mexec_driver_sql\u001B[49m\u001B[43m(\u001B[49m\u001B[43msql\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43m*\u001B[49m\u001B[43margs\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 1672\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28mself\u001B[39m.con.execute(sql, *args)\n",
"\u001B[36mFile \u001B[39m\u001B[32m~/Project/leopard_analysis/.venv/lib/python3.14/site-packages/sqlalchemy/engine/base.py:1779\u001B[39m, in \u001B[36mConnection.exec_driver_sql\u001B[39m\u001B[34m(self, statement, parameters, execution_options)\u001B[39m\n\u001B[32m 1774\u001B[39m execution_options = \u001B[38;5;28mself\u001B[39m._execution_options.merge_with(\n\u001B[32m 1775\u001B[39m execution_options\n\u001B[32m 1776\u001B[39m )\n\u001B[32m 1778\u001B[39m dialect = \u001B[38;5;28mself\u001B[39m.dialect\n\u001B[32m-> \u001B[39m\u001B[32m1779\u001B[39m ret = \u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43m_execute_context\u001B[49m\u001B[43m(\u001B[49m\n\u001B[32m 1780\u001B[39m \u001B[43m \u001B[49m\u001B[43mdialect\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 1781\u001B[39m \u001B[43m \u001B[49m\u001B[43mdialect\u001B[49m\u001B[43m.\u001B[49m\u001B[43mexecution_ctx_cls\u001B[49m\u001B[43m.\u001B[49m\u001B[43m_init_statement\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 1782\u001B[39m \u001B[43m \u001B[49m\u001B[43mstatement\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 1783\u001B[39m \u001B[43m \u001B[49m\u001B[38;5;28;43;01mNone\u001B[39;49;00m\u001B[43m,\u001B[49m\n\u001B[32m 1784\u001B[39m \u001B[43m \u001B[49m\u001B[43mexecution_options\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 1785\u001B[39m \u001B[43m \u001B[49m\u001B[43mstatement\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 1786\u001B[39m \u001B[43m \u001B[49m\u001B[43mdistilled_parameters\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 1787\u001B[39m \u001B[43m\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 1789\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m ret\n",
"\u001B[36mFile \u001B[39m\u001B[32m~/Project/leopard_analysis/.venv/lib/python3.14/site-packages/sqlalchemy/engine/base.py:1846\u001B[39m, in \u001B[36mConnection._execute_context\u001B[39m\u001B[34m(self, dialect, constructor, statement, parameters, execution_options, *args, **kw)\u001B[39m\n\u001B[32m 1844\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28mself\u001B[39m._exec_insertmany_context(dialect, context)\n\u001B[32m 1845\u001B[39m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[32m-> \u001B[39m\u001B[32m1846\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43m_exec_single_context\u001B[49m\u001B[43m(\u001B[49m\n\u001B[32m 1847\u001B[39m \u001B[43m \u001B[49m\u001B[43mdialect\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mcontext\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mstatement\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mparameters\u001B[49m\n\u001B[32m 1848\u001B[39m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n",
"\u001B[36mFile \u001B[39m\u001B[32m~/Project/leopard_analysis/.venv/lib/python3.14/site-packages/sqlalchemy/engine/base.py:1986\u001B[39m, in \u001B[36mConnection._exec_single_context\u001B[39m\u001B[34m(self, dialect, context, statement, parameters)\u001B[39m\n\u001B[32m 1983\u001B[39m result = context._setup_result_proxy()\n\u001B[32m 1985\u001B[39m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mBaseException\u001B[39;00m \u001B[38;5;28;01mas\u001B[39;00m e:\n\u001B[32m-> \u001B[39m\u001B[32m1986\u001B[39m \u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43m_handle_dbapi_exception\u001B[49m\u001B[43m(\u001B[49m\n\u001B[32m 1987\u001B[39m \u001B[43m \u001B[49m\u001B[43me\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mstr_statement\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43meffective_parameters\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mcursor\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mcontext\u001B[49m\n\u001B[32m 1988\u001B[39m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 1990\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m result\n",
"\u001B[36mFile \u001B[39m\u001B[32m~/Project/leopard_analysis/.venv/lib/python3.14/site-packages/sqlalchemy/engine/base.py:2366\u001B[39m, in \u001B[36mConnection._handle_dbapi_exception\u001B[39m\u001B[34m(self, e, statement, parameters, cursor, context, is_sub_exec)\u001B[39m\n\u001B[32m 2364\u001B[39m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[32m 2365\u001B[39m \u001B[38;5;28;01massert\u001B[39;00m exc_info[\u001B[32m1\u001B[39m] \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m\n\u001B[32m-> \u001B[39m\u001B[32m2366\u001B[39m \u001B[38;5;28;01mraise\u001B[39;00m exc_info[\u001B[32m1\u001B[39m].with_traceback(exc_info[\u001B[32m2\u001B[39m])\n\u001B[32m 2367\u001B[39m \u001B[38;5;28;01mfinally\u001B[39;00m:\n\u001B[32m 2368\u001B[39m \u001B[38;5;28;01mdel\u001B[39;00m \u001B[38;5;28mself\u001B[39m._reentrant_error\n",
"\u001B[36mFile \u001B[39m\u001B[32m~/Project/leopard_analysis/.venv/lib/python3.14/site-packages/sqlalchemy/engine/base.py:1967\u001B[39m, in \u001B[36mConnection._exec_single_context\u001B[39m\u001B[34m(self, dialect, context, statement, parameters)\u001B[39m\n\u001B[32m 1965\u001B[39m \u001B[38;5;28;01mbreak\u001B[39;00m\n\u001B[32m 1966\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m evt_handled:\n\u001B[32m-> \u001B[39m\u001B[32m1967\u001B[39m \u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mdialect\u001B[49m\u001B[43m.\u001B[49m\u001B[43mdo_execute\u001B[49m\u001B[43m(\u001B[49m\n\u001B[32m 1968\u001B[39m \u001B[43m \u001B[49m\u001B[43mcursor\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mstr_statement\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43meffective_parameters\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mcontext\u001B[49m\n\u001B[32m 1969\u001B[39m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 1971\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mself\u001B[39m._has_events \u001B[38;5;129;01mor\u001B[39;00m \u001B[38;5;28mself\u001B[39m.engine._has_events:\n\u001B[32m 1972\u001B[39m \u001B[38;5;28mself\u001B[39m.dispatch.after_cursor_execute(\n\u001B[32m 1973\u001B[39m \u001B[38;5;28mself\u001B[39m,\n\u001B[32m 1974\u001B[39m cursor,\n\u001B[32m (...)\u001B[39m\u001B[32m 1978\u001B[39m context.executemany,\n\u001B[32m 1979\u001B[39m )\n",
"\u001B[36mFile \u001B[39m\u001B[32m~/Project/leopard_analysis/.venv/lib/python3.14/site-packages/sqlalchemy/engine/default.py:952\u001B[39m, in \u001B[36mDefaultDialect.do_execute\u001B[39m\u001B[34m(self, cursor, statement, parameters, context)\u001B[39m\n\u001B[32m 951\u001B[39m \u001B[38;5;28;01mdef\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[34mdo_execute\u001B[39m(\u001B[38;5;28mself\u001B[39m, cursor, statement, parameters, context=\u001B[38;5;28;01mNone\u001B[39;00m):\n\u001B[32m--> \u001B[39m\u001B[32m952\u001B[39m \u001B[43mcursor\u001B[49m\u001B[43m.\u001B[49m\u001B[43mexecute\u001B[49m\u001B[43m(\u001B[49m\u001B[43mstatement\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mparameters\u001B[49m\u001B[43m)\u001B[49m\n",
"\u001B[36mFile \u001B[39m\u001B[32m~/.local/share/uv/python/cpython-3.14.2-macos-x86_64-none/lib/python3.14/encodings/utf_8.py:15\u001B[39m, in \u001B[36mdecode\u001B[39m\u001B[34m(input, errors)\u001B[39m\n\u001B[32m 11\u001B[39m \u001B[38;5;66;03m### Codec APIs\u001B[39;00m\n\u001B[32m 13\u001B[39m encode = codecs.utf_8_encode\n\u001B[32m---> \u001B[39m\u001B[32m15\u001B[39m \u001B[38;5;28;01mdef\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[34mdecode\u001B[39m(\u001B[38;5;28minput\u001B[39m, errors=\u001B[33m'\u001B[39m\u001B[33mstrict\u001B[39m\u001B[33m'\u001B[39m):\n\u001B[32m 16\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m codecs.utf_8_decode(\u001B[38;5;28minput\u001B[39m, errors, \u001B[38;5;28;01mTrue\u001B[39;00m)\n\u001B[32m 18\u001B[39m \u001B[38;5;28;01mclass\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[34;01mIncrementalEncoder\u001B[39;00m(codecs.IncrementalEncoder):\n",
"\u001B[31mKeyboardInterrupt\u001B[39m: "
]
}
],
"execution_count": 26
}
],
"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
}

File diff suppressed because one or more lines are too long

View File

@@ -4,6 +4,7 @@ version = "0.1.0"
description = "Stock analysis"
requires-python = ">=3.14"
dependencies = [
"akshare>=1.18.20",
"backtesting~=0.6.5",
"duckdb>=1.4.4",
"jupyter~=1.1.1",
@@ -18,4 +19,5 @@ dependencies = [
"ta-lib>=0.6.8",
"tabulate>=0.9.0",
"tqdm>=4.67.1",
"tushare>=1.4.24",
]

92
sql/initial.sql Normal file
View File

@@ -0,0 +1,92 @@
CREATE TABLE stock
(
code varchar primary key,
fullname varchar,
industry varchar,
listed_date date,
market varchar,
name varchar
);
CREATE TABLE daily
(
code varchar not null,
trade_date date not null,
open double not null,
close double not null,
high double not null,
low double not null,
previous_close double not null,
turnover double not null,
volume integer not null,
price_change_amount double not null,
factor double not null,
primary key (code, trade_date)
);
CREATE TABLE finance_indicator
(
code varchar,
year integer,
accounts_payable double,
accounts_payable_to_total_assets_ratio double,
accounts_receivable double,
accounts_receivable_to_total_assets_ratio double,
accounts_receivable_turnover double,
capital_surplus double,
cash_and_cash_equivalents double,
cash_and_cash_equivalents_to_total_assets_ratio double,
cash_flow_adequacy_ratio double,
cash_flow_from_financing_activities double,
cash_flow_from_investing_activities double,
cash_flow_from_operating_activities double,
cash_flow_ratio double,
cash_reinvestment_ratio double,
current_assets double,
current_assets_to_total_assets_ratio double,
current_liabilities double,
current_liabilities_to_total_assets_ratio double,
current_liabilities_to_total_liabilities_ratio double,
current_ratio double,
days_accounts_receivable_turnover double,
days_fixed_assets_turnover double,
days_inventory_turnover double,
days_total_assets_turnover double,
earnings_per_share double,
fixed_assets double,
fixed_assets_to_total_assets_ratio double,
fixed_assets_turnover double,
goodwill double,
goodwill_to_total_assets_ratio double,
inventory double,
inventory_to_total_assets_ratio double,
inventory_turnover double,
liabilities_to_total_assets_ratio double,
long_term_funds_to_fixed_assets_ratio double,
long_term_liabilities double,
long_term_liabilities_to_total_assets_ratio double,
long_term_liabilities_to_total_liabilities_ratio double,
net_cash_flow_from_operating_activities double,
net_profit double,
net_profit_margin double,
operating_cost double,
operating_expenses double,
operating_gross_profit_margin double,
operating_profit double,
operating_profit_margin double,
operating_revenue double,
operating_safety_margin_ratio double,
quick_ratio double,
return_on_assets double,
return_on_equity double,
shareholders_equity double,
shareholders_equity_to_total_assets_ratio double,
surplus_reserve double,
total_assets double,
total_assets_turnover double,
total_liabilities double,
total_share_capital double,
undistributed_profit double,
primary key (code, year)
)

216
uv.lock generated
View File

@@ -2,6 +2,42 @@ version = 1
revision = 3
requires-python = ">=3.14"
[[package]]
name = "akracer"
version = "0.0.14"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/1e/c6/f38feed5b961d73e1b4cb049fdb45338356e0f5b828b230c00d0e51f3137/akracer-0.0.14.tar.gz", hash = "sha256:e084c14bf6d9a02d5da375e3af1cba3d46f103aa1cf3a2010593b3e95bf1c29a", size = 10047643, upload-time = "2025-09-10T13:47:34.811Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/53/cb/1041355b14cd4b76ac082e8c676858f6eddb78f0ba37c59284adf36e5103/akracer-0.0.14-py3-none-any.whl", hash = "sha256:629eaccd0e1d18366804b797eb2692ed47bed0028f55b5a5af3cc277d521df04", size = 10076442, upload-time = "2025-09-10T13:47:29.061Z" },
]
[[package]]
name = "akshare"
version = "1.18.20"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "akracer", marker = "sys_platform == 'linux'" },
{ name = "beautifulsoup4" },
{ name = "curl-cffi" },
{ name = "decorator" },
{ name = "html5lib" },
{ name = "jsonpath" },
{ name = "lxml" },
{ name = "mini-racer", marker = "sys_platform != 'linux'" },
{ name = "openpyxl" },
{ name = "pandas" },
{ name = "py-mini-racer", marker = "sys_platform == 'linux'" },
{ name = "requests" },
{ name = "tabulate" },
{ name = "tqdm" },
{ name = "urllib3" },
{ name = "xlrd" },
]
sdist = { url = "https://files.pythonhosted.org/packages/da/e0/48c0d7fc2527787b3179960454037dbe5b8d3409aa00eab23748a34317be/akshare-1.18.20.tar.gz", hash = "sha256:f3797d454fd2bc9e75f85e24abdd2af2c29989d4f89379b3385998bbf1464d16", size = 855384, upload-time = "2026-01-27T14:35:25.261Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/e6/b4/2743787e5366eb281b966f8c3fcc85d6e3a8456cefbac27d30ca7baafedd/akshare-1.18.20-py3-none-any.whl", hash = "sha256:9ba6cb3a17ee4cf957cf81e01cec59d55962a3fd867ab669d151a213bb5a9fc3", size = 1074968, upload-time = "2026-01-27T14:35:23.937Z" },
]
[[package]]
name = "anyio"
version = "4.12.1"
@@ -180,6 +216,18 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/f6/a8/877f306720bc114c612579c5af36bcb359026b83d051226945499b306b1a/bokeh-3.8.2-py3-none-any.whl", hash = "sha256:5e2c0d84f75acb25d60efb9e4d2f434a791c4639b47d685534194c4e07bd0111", size = 7207131, upload-time = "2026-01-06T00:20:04.917Z" },
]
[[package]]
name = "bs4"
version = "0.0.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "beautifulsoup4" },
]
sdist = { url = "https://files.pythonhosted.org/packages/c9/aa/4acaf814ff901145da37332e05bb510452ebed97bc9602695059dd46ef39/bs4-0.0.2.tar.gz", hash = "sha256:a48685c58f50fe127722417bae83fe6badf500d54b55f7e39ffe43b798653925", size = 698, upload-time = "2024-01-17T18:15:47.371Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/51/bb/bf7aab772a159614954d84aa832c129624ba6c32faa559dfb200a534e50b/bs4-0.0.2-py2.py3-none-any.whl", hash = "sha256:abf8742c0805ef7f662dce4b51cca104cffe52b835238afc169142ab9b3fbccc", size = 1189, upload-time = "2024-01-17T18:15:48.613Z" },
]
[[package]]
name = "build"
version = "1.4.0"
@@ -312,6 +360,29 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/ae/8c/469afb6465b853afff216f9528ffda78a915ff880ed58813ba4faf4ba0b6/contourpy-1.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b", size = 203831, upload-time = "2025-07-26T12:02:51.449Z" },
]
[[package]]
name = "curl-cffi"
version = "0.14.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "certifi" },
{ name = "cffi" },
]
sdist = { url = "https://files.pythonhosted.org/packages/9b/c9/0067d9a25ed4592b022d4558157fcdb6e123516083700786d38091688767/curl_cffi-0.14.0.tar.gz", hash = "sha256:5ffbc82e59f05008ec08ea432f0e535418823cda44178ee518906a54f27a5f0f", size = 162633, upload-time = "2025-12-16T03:25:07.931Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/aa/f0/0f21e9688eaac85e705537b3a87a5588d0cefb2f09d83e83e0e8be93aa99/curl_cffi-0.14.0-cp39-abi3-macosx_14_0_arm64.whl", hash = "sha256:e35e89c6a69872f9749d6d5fda642ed4fc159619329e99d577d0104c9aad5893", size = 3087277, upload-time = "2025-12-16T03:24:49.607Z" },
{ url = "https://files.pythonhosted.org/packages/ba/a3/0419bd48fce5b145cb6a2344c6ac17efa588f5b0061f212c88e0723da026/curl_cffi-0.14.0-cp39-abi3-macosx_15_0_x86_64.whl", hash = "sha256:5945478cd28ad7dfb5c54473bcfb6743ee1d66554d57951fdf8fc0e7d8cf4e45", size = 5804650, upload-time = "2025-12-16T03:24:51.518Z" },
{ url = "https://files.pythonhosted.org/packages/e2/07/a238dd062b7841b8caa2fa8a359eb997147ff3161288f0dd46654d898b4d/curl_cffi-0.14.0-cp39-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c42e8fa3c667db9ccd2e696ee47adcd3cd5b0838d7282f3fc45f6c0ef3cfdfa7", size = 8231918, upload-time = "2025-12-16T03:24:52.862Z" },
{ url = "https://files.pythonhosted.org/packages/7c/d2/ce907c9b37b5caf76ac08db40cc4ce3d9f94c5500db68a195af3513eacbc/curl_cffi-0.14.0-cp39-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:060fe2c99c41d3cb7f894de318ddf4b0301b08dca70453d769bd4e74b36b8483", size = 8654624, upload-time = "2025-12-16T03:24:54.579Z" },
{ url = "https://files.pythonhosted.org/packages/f2/ae/6256995b18c75e6ef76b30753a5109e786813aa79088b27c8eabb1ef85c9/curl_cffi-0.14.0-cp39-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b158c41a25388690dd0d40b5bc38d1e0f512135f17fdb8029868cbc1993d2e5b", size = 8010654, upload-time = "2025-12-16T03:24:56.507Z" },
{ url = "https://files.pythonhosted.org/packages/fb/10/ff64249e516b103cb762e0a9dca3ee0f04cf25e2a1d5d9838e0f1273d071/curl_cffi-0.14.0-cp39-abi3-manylinux_2_28_i686.whl", hash = "sha256:1439fbef3500fb723333c826adf0efb0e2e5065a703fb5eccce637a2250db34a", size = 7781969, upload-time = "2025-12-16T03:24:57.885Z" },
{ url = "https://files.pythonhosted.org/packages/51/76/d6f7bb76c2d12811aa7ff16f5e17b678abdd1b357b9a8ac56310ceccabd5/curl_cffi-0.14.0-cp39-abi3-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e7176f2c2d22b542e3cf261072a81deb018cfa7688930f95dddef215caddb469", size = 7969133, upload-time = "2025-12-16T03:24:59.261Z" },
{ url = "https://files.pythonhosted.org/packages/23/7c/cca39c0ed4e1772613d3cba13091c0e9d3b89365e84b9bf9838259a3cd8f/curl_cffi-0.14.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:03f21ade2d72978c2bb8670e9b6de5260e2755092b02d94b70b906813662998d", size = 9080167, upload-time = "2025-12-16T03:25:00.946Z" },
{ url = "https://files.pythonhosted.org/packages/75/03/a942d7119d3e8911094d157598ae0169b1c6ca1bd3f27d7991b279bcc45b/curl_cffi-0.14.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:58ebf02de64ee5c95613209ddacb014c2d2f86298d7080c0a1c12ed876ee0690", size = 9520464, upload-time = "2025-12-16T03:25:02.922Z" },
{ url = "https://files.pythonhosted.org/packages/a2/77/78900e9b0833066d2274bda75cba426fdb4cef7fbf6a4f6a6ca447607bec/curl_cffi-0.14.0-cp39-abi3-win_amd64.whl", hash = "sha256:6e503f9a103f6ae7acfb3890c843b53ec030785a22ae7682a22cc43afb94123e", size = 1677416, upload-time = "2025-12-16T03:25:04.902Z" },
{ url = "https://files.pythonhosted.org/packages/5c/7c/d2ba86b0b3e1e2830bd94163d047de122c69a8df03c5c7c36326c456ad82/curl_cffi-0.14.0-cp39-abi3-win_arm64.whl", hash = "sha256:2eed50a969201605c863c4c31269dfc3e0da52916086ac54553cfa353022425c", size = 1425067, upload-time = "2025-12-16T03:25:06.454Z" },
]
[[package]]
name = "cycler"
version = "0.12.1"
@@ -367,6 +438,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/dd/2d/13e6024e613679d8a489dd922f199ef4b1d08a456a58eadd96dc2f05171f/duckdb-1.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:53cd6423136ab44383ec9955aefe7599b3fb3dd1fe006161e6396d8167e0e0d4", size = 13458633, upload-time = "2026-01-26T11:50:17.657Z" },
]
[[package]]
name = "et-xmlfile"
version = "2.0.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/d3/38/af70d7ab1ae9d4da450eeec1fa3918940a5fafb9055e934af8d6eb0c2313/et_xmlfile-2.0.0.tar.gz", hash = "sha256:dab3f4764309081ce75662649be815c4c9081e88f0837825f90fd28317d4da54", size = 17234, upload-time = "2024-10-25T17:25:40.039Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c1/8b/5fe2cc11fee489817272089c4203e679c63b570a5aaeb18d852ae3cbba6a/et_xmlfile-2.0.0-py3-none-any.whl", hash = "sha256:7a91720bc756843502c3b7504c77b8fe44217c85c537d85037f0f536151b2caa", size = 18059, upload-time = "2024-10-25T17:25:39.051Z" },
]
[[package]]
name = "executing"
version = "2.2.1"
@@ -451,6 +531,19 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" },
]
[[package]]
name = "html5lib"
version = "1.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "six" },
{ name = "webencodings" },
]
sdist = { url = "https://files.pythonhosted.org/packages/ac/b6/b55c3f49042f1df3dcd422b7f224f939892ee94f22abcf503a9b7339eaf2/html5lib-1.1.tar.gz", hash = "sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f", size = 272215, upload-time = "2020-06-22T23:32:38.834Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl", hash = "sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d", size = 112173, upload-time = "2020-06-22T23:32:36.781Z" },
]
[[package]]
name = "httpcore"
version = "1.0.9"
@@ -606,6 +699,12 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/d7/9e/038522f50ceb7e74f1f991bf1b699f24b0c2bbe7c390dd36ad69f4582258/json5-0.13.0-py3-none-any.whl", hash = "sha256:9a08e1dd65f6a4d4c6fa82d216cf2477349ec2346a38fd70cc11d2557499fbcc", size = 36163, upload-time = "2026-01-01T19:42:13.962Z" },
]
[[package]]
name = "jsonpath"
version = "0.82.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/cf/a1/693351acd0a9edca4de9153372a65e75398898ea7f8a5c722ab00f464929/jsonpath-0.82.2.tar.gz", hash = "sha256:d87ef2bcbcded68ee96bc34c1809b69457ecec9b0c4dd471658a12bd391002d1", size = 10353, upload-time = "2023-08-24T18:57:55.459Z" }
[[package]]
name = "jsonpointer"
version = "3.0.0"
@@ -914,6 +1013,7 @@ name = "leopard-analysis"
version = "0.1.0"
source = { virtual = "." }
dependencies = [
{ name = "akshare" },
{ name = "backtesting" },
{ name = "duckdb" },
{ name = "jupyter" },
@@ -928,10 +1028,12 @@ dependencies = [
{ name = "ta-lib" },
{ name = "tabulate" },
{ name = "tqdm" },
{ name = "tushare" },
]
[package.metadata]
requires-dist = [
{ name = "akshare", specifier = ">=1.18.20" },
{ name = "backtesting", specifier = "~=0.6.5" },
{ name = "duckdb", specifier = ">=1.4.4" },
{ name = "jupyter", specifier = "~=1.1.1" },
@@ -946,6 +1048,51 @@ requires-dist = [
{ name = "ta-lib", specifier = ">=0.6.8" },
{ name = "tabulate", specifier = ">=0.9.0" },
{ name = "tqdm", specifier = ">=4.67.1" },
{ name = "tushare", specifier = ">=1.4.24" },
]
[[package]]
name = "lxml"
version = "6.0.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/aa/88/262177de60548e5a2bfc46ad28232c9e9cbde697bd94132aeb80364675cb/lxml-6.0.2.tar.gz", hash = "sha256:cd79f3367bd74b317dda655dc8fcfa304d9eb6e4fb06b7168c5cf27f96e0cd62", size = 4073426, upload-time = "2025-09-22T04:04:59.287Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/03/15/d4a377b385ab693ce97b472fe0c77c2b16ec79590e688b3ccc71fba19884/lxml-6.0.2-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:b0c732aa23de8f8aec23f4b580d1e52905ef468afb4abeafd3fec77042abb6fe", size = 8659801, upload-time = "2025-09-22T04:02:30.113Z" },
{ url = "https://files.pythonhosted.org/packages/c8/e8/c128e37589463668794d503afaeb003987373c5f94d667124ffd8078bbd9/lxml-6.0.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:4468e3b83e10e0317a89a33d28f7aeba1caa4d1a6fd457d115dd4ffe90c5931d", size = 4659403, upload-time = "2025-09-22T04:02:32.119Z" },
{ url = "https://files.pythonhosted.org/packages/00/ce/74903904339decdf7da7847bb5741fc98a5451b42fc419a86c0c13d26fe2/lxml-6.0.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:abd44571493973bad4598a3be7e1d807ed45aa2adaf7ab92ab7c62609569b17d", size = 4966974, upload-time = "2025-09-22T04:02:34.155Z" },
{ url = "https://files.pythonhosted.org/packages/1f/d3/131dec79ce61c5567fecf82515bd9bc36395df42501b50f7f7f3bd065df0/lxml-6.0.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:370cd78d5855cfbffd57c422851f7d3864e6ae72d0da615fca4dad8c45d375a5", size = 5102953, upload-time = "2025-09-22T04:02:36.054Z" },
{ url = "https://files.pythonhosted.org/packages/3a/ea/a43ba9bb750d4ffdd885f2cd333572f5bb900cd2408b67fdda07e85978a0/lxml-6.0.2-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:901e3b4219fa04ef766885fb40fa516a71662a4c61b80c94d25336b4934b71c0", size = 5055054, upload-time = "2025-09-22T04:02:38.154Z" },
{ url = "https://files.pythonhosted.org/packages/60/23/6885b451636ae286c34628f70a7ed1fcc759f8d9ad382d132e1c8d3d9bfd/lxml-6.0.2-cp314-cp314-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:a4bf42d2e4cf52c28cc1812d62426b9503cdb0c87a6de81442626aa7d69707ba", size = 5352421, upload-time = "2025-09-22T04:02:40.413Z" },
{ url = "https://files.pythonhosted.org/packages/48/5b/fc2ddfc94ddbe3eebb8e9af6e3fd65e2feba4967f6a4e9683875c394c2d8/lxml-6.0.2-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b2c7fdaa4d7c3d886a42534adec7cfac73860b89b4e5298752f60aa5984641a0", size = 5673684, upload-time = "2025-09-22T04:02:42.288Z" },
{ url = "https://files.pythonhosted.org/packages/29/9c/47293c58cc91769130fbf85531280e8cc7868f7fbb6d92f4670071b9cb3e/lxml-6.0.2-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:98a5e1660dc7de2200b00d53fa00bcd3c35a3608c305d45a7bbcaf29fa16e83d", size = 5252463, upload-time = "2025-09-22T04:02:44.165Z" },
{ url = "https://files.pythonhosted.org/packages/9b/da/ba6eceb830c762b48e711ded880d7e3e89fc6c7323e587c36540b6b23c6b/lxml-6.0.2-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:dc051506c30b609238d79eda75ee9cab3e520570ec8219844a72a46020901e37", size = 4698437, upload-time = "2025-09-22T04:02:46.524Z" },
{ url = "https://files.pythonhosted.org/packages/a5/24/7be3f82cb7990b89118d944b619e53c656c97dc89c28cfb143fdb7cd6f4d/lxml-6.0.2-cp314-cp314-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8799481bbdd212470d17513a54d568f44416db01250f49449647b5ab5b5dccb9", size = 5269890, upload-time = "2025-09-22T04:02:48.812Z" },
{ url = "https://files.pythonhosted.org/packages/1b/bd/dcfb9ea1e16c665efd7538fc5d5c34071276ce9220e234217682e7d2c4a5/lxml-6.0.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9261bb77c2dab42f3ecd9103951aeca2c40277701eb7e912c545c1b16e0e4917", size = 5097185, upload-time = "2025-09-22T04:02:50.746Z" },
{ url = "https://files.pythonhosted.org/packages/21/04/a60b0ff9314736316f28316b694bccbbabe100f8483ad83852d77fc7468e/lxml-6.0.2-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:65ac4a01aba353cfa6d5725b95d7aed6356ddc0a3cd734de00124d285b04b64f", size = 4745895, upload-time = "2025-09-22T04:02:52.968Z" },
{ url = "https://files.pythonhosted.org/packages/d6/bd/7d54bd1846e5a310d9c715921c5faa71cf5c0853372adf78aee70c8d7aa2/lxml-6.0.2-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:b22a07cbb82fea98f8a2fd814f3d1811ff9ed76d0fc6abc84eb21527596e7cc8", size = 5695246, upload-time = "2025-09-22T04:02:54.798Z" },
{ url = "https://files.pythonhosted.org/packages/fd/32/5643d6ab947bc371da21323acb2a6e603cedbe71cb4c99c8254289ab6f4e/lxml-6.0.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:d759cdd7f3e055d6bc8d9bec3ad905227b2e4c785dc16c372eb5b5e83123f48a", size = 5260797, upload-time = "2025-09-22T04:02:57.058Z" },
{ url = "https://files.pythonhosted.org/packages/33/da/34c1ec4cff1eea7d0b4cd44af8411806ed943141804ac9c5d565302afb78/lxml-6.0.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:945da35a48d193d27c188037a05fec5492937f66fb1958c24fc761fb9d40d43c", size = 5277404, upload-time = "2025-09-22T04:02:58.966Z" },
{ url = "https://files.pythonhosted.org/packages/82/57/4eca3e31e54dc89e2c3507e1cd411074a17565fa5ffc437c4ae0a00d439e/lxml-6.0.2-cp314-cp314-win32.whl", hash = "sha256:be3aaa60da67e6153eb15715cc2e19091af5dc75faef8b8a585aea372507384b", size = 3670072, upload-time = "2025-09-22T04:03:38.05Z" },
{ url = "https://files.pythonhosted.org/packages/e3/e0/c96cf13eccd20c9421ba910304dae0f619724dcf1702864fd59dd386404d/lxml-6.0.2-cp314-cp314-win_amd64.whl", hash = "sha256:fa25afbadead523f7001caf0c2382afd272c315a033a7b06336da2637d92d6ed", size = 4080617, upload-time = "2025-09-22T04:03:39.835Z" },
{ url = "https://files.pythonhosted.org/packages/d5/5d/b3f03e22b3d38d6f188ef044900a9b29b2fe0aebb94625ce9fe244011d34/lxml-6.0.2-cp314-cp314-win_arm64.whl", hash = "sha256:063eccf89df5b24e361b123e257e437f9e9878f425ee9aae3144c77faf6da6d8", size = 3754930, upload-time = "2025-09-22T04:03:41.565Z" },
{ url = "https://files.pythonhosted.org/packages/5e/5c/42c2c4c03554580708fc738d13414801f340c04c3eff90d8d2d227145275/lxml-6.0.2-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:6162a86d86893d63084faaf4ff937b3daea233e3682fb4474db07395794fa80d", size = 8910380, upload-time = "2025-09-22T04:03:01.645Z" },
{ url = "https://files.pythonhosted.org/packages/bf/4f/12df843e3e10d18d468a7557058f8d3733e8b6e12401f30b1ef29360740f/lxml-6.0.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:414aaa94e974e23a3e92e7ca5b97d10c0cf37b6481f50911032c69eeb3991bba", size = 4775632, upload-time = "2025-09-22T04:03:03.814Z" },
{ url = "https://files.pythonhosted.org/packages/e4/0c/9dc31e6c2d0d418483cbcb469d1f5a582a1cd00a1f4081953d44051f3c50/lxml-6.0.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:48461bd21625458dd01e14e2c38dd0aea69addc3c4f960c30d9f59d7f93be601", size = 4975171, upload-time = "2025-09-22T04:03:05.651Z" },
{ url = "https://files.pythonhosted.org/packages/e7/2b/9b870c6ca24c841bdd887504808f0417aa9d8d564114689266f19ddf29c8/lxml-6.0.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:25fcc59afc57d527cfc78a58f40ab4c9b8fd096a9a3f964d2781ffb6eb33f4ed", size = 5110109, upload-time = "2025-09-22T04:03:07.452Z" },
{ url = "https://files.pythonhosted.org/packages/bf/0c/4f5f2a4dd319a178912751564471355d9019e220c20d7db3fb8307ed8582/lxml-6.0.2-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5179c60288204e6ddde3f774a93350177e08876eaf3ab78aa3a3649d43eb7d37", size = 5041061, upload-time = "2025-09-22T04:03:09.297Z" },
{ url = "https://files.pythonhosted.org/packages/12/64/554eed290365267671fe001a20d72d14f468ae4e6acef1e179b039436967/lxml-6.0.2-cp314-cp314t-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:967aab75434de148ec80597b75062d8123cadf2943fb4281f385141e18b21338", size = 5306233, upload-time = "2025-09-22T04:03:11.651Z" },
{ url = "https://files.pythonhosted.org/packages/7a/31/1d748aa275e71802ad9722df32a7a35034246b42c0ecdd8235412c3396ef/lxml-6.0.2-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d100fcc8930d697c6561156c6810ab4a508fb264c8b6779e6e61e2ed5e7558f9", size = 5604739, upload-time = "2025-09-22T04:03:13.592Z" },
{ url = "https://files.pythonhosted.org/packages/8f/41/2c11916bcac09ed561adccacceaedd2bf0e0b25b297ea92aab99fd03d0fa/lxml-6.0.2-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ca59e7e13e5981175b8b3e4ab84d7da57993eeff53c07764dcebda0d0e64ecd", size = 5225119, upload-time = "2025-09-22T04:03:15.408Z" },
{ url = "https://files.pythonhosted.org/packages/99/05/4e5c2873d8f17aa018e6afde417c80cc5d0c33be4854cce3ef5670c49367/lxml-6.0.2-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:957448ac63a42e2e49531b9d6c0fa449a1970dbc32467aaad46f11545be9af1d", size = 4633665, upload-time = "2025-09-22T04:03:17.262Z" },
{ url = "https://files.pythonhosted.org/packages/0f/c9/dcc2da1bebd6275cdc723b515f93edf548b82f36a5458cca3578bc899332/lxml-6.0.2-cp314-cp314t-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b7fc49c37f1786284b12af63152fe1d0990722497e2d5817acfe7a877522f9a9", size = 5234997, upload-time = "2025-09-22T04:03:19.14Z" },
{ url = "https://files.pythonhosted.org/packages/9c/e2/5172e4e7468afca64a37b81dba152fc5d90e30f9c83c7c3213d6a02a5ce4/lxml-6.0.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e19e0643cc936a22e837f79d01a550678da8377d7d801a14487c10c34ee49c7e", size = 5090957, upload-time = "2025-09-22T04:03:21.436Z" },
{ url = "https://files.pythonhosted.org/packages/a5/b3/15461fd3e5cd4ddcb7938b87fc20b14ab113b92312fc97afe65cd7c85de1/lxml-6.0.2-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:1db01e5cf14345628e0cbe71067204db658e2fb8e51e7f33631f5f4735fefd8d", size = 4764372, upload-time = "2025-09-22T04:03:23.27Z" },
{ url = "https://files.pythonhosted.org/packages/05/33/f310b987c8bf9e61c4dd8e8035c416bd3230098f5e3cfa69fc4232de7059/lxml-6.0.2-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:875c6b5ab39ad5291588aed6925fac99d0097af0dd62f33c7b43736043d4a2ec", size = 5634653, upload-time = "2025-09-22T04:03:25.767Z" },
{ url = "https://files.pythonhosted.org/packages/70/ff/51c80e75e0bc9382158133bdcf4e339b5886c6ee2418b5199b3f1a61ed6d/lxml-6.0.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:cdcbed9ad19da81c480dfd6dd161886db6096083c9938ead313d94b30aadf272", size = 5233795, upload-time = "2025-09-22T04:03:27.62Z" },
{ url = "https://files.pythonhosted.org/packages/56/4d/4856e897df0d588789dd844dbed9d91782c4ef0b327f96ce53c807e13128/lxml-6.0.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:80dadc234ebc532e09be1975ff538d154a7fa61ea5031c03d25178855544728f", size = 5257023, upload-time = "2025-09-22T04:03:30.056Z" },
{ url = "https://files.pythonhosted.org/packages/0f/85/86766dfebfa87bea0ab78e9ff7a4b4b45225df4b4d3b8cc3c03c5cd68464/lxml-6.0.2-cp314-cp314t-win32.whl", hash = "sha256:da08e7bb297b04e893d91087df19638dc7a6bb858a954b0cc2b9f5053c922312", size = 3911420, upload-time = "2025-09-22T04:03:32.198Z" },
{ url = "https://files.pythonhosted.org/packages/fe/1a/b248b355834c8e32614650b8008c69ffeb0ceb149c793961dd8c0b991bb3/lxml-6.0.2-cp314-cp314t-win_amd64.whl", hash = "sha256:252a22982dca42f6155125ac76d3432e548a7625d56f5a273ee78a5057216eca", size = 4406837, upload-time = "2025-09-22T04:03:34.027Z" },
{ url = "https://files.pythonhosted.org/packages/92/aa/df863bcc39c5e0946263454aba394de8a9084dbaff8ad143846b0d844739/lxml-6.0.2-cp314-cp314t-win_arm64.whl", hash = "sha256:bb4c1847b303835d89d785a18801a883436cdfd5dc3d62947f9c49e24f0f5a2c", size = 3822205, upload-time = "2025-09-22T04:03:36.249Z" },
]
[[package]]
@@ -1023,6 +1170,18 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/af/33/ee4519fa02ed11a94aef9559552f3b17bb863f2ecfe1a35dc7f548cde231/matplotlib_inline-0.2.1-py3-none-any.whl", hash = "sha256:d56ce5156ba6085e00a9d54fead6ed29a9c47e215cd1bba2e976ef39f5710a76", size = 9516, upload-time = "2025-10-23T09:00:20.675Z" },
]
[[package]]
name = "mini-racer"
version = "0.14.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/55/7b/2f417069fb8fcb85c1458e51ea83c12d37f892a41544ef28479e37a315a3/mini_racer-0.14.0.tar.gz", hash = "sha256:7f812d6f21a8828e99e986bf4bb184c04bd906c845061aa43d7dd3edc8b8e6f5", size = 41238, upload-time = "2026-01-05T07:28:50.336Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/4f/b5/d184a34787edae8301ec5bd1a454c9bfdce2c58fb3c887f8d12416589057/mini_racer-0.14.0-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:b02b3e15c548958a75afec12b9c21afa01c4a3aacbea66f5856036ff9b6c1a36", size = 19847149, upload-time = "2026-01-05T07:28:24.682Z" },
{ url = "https://files.pythonhosted.org/packages/d4/09/f7afb45b4e54ccacc88fb543d7d87040904c7bbcbeed3f944959189f93c1/mini_racer-0.14.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:049a239a1174d40e2a38da71b55aa0ad73a1a7be90956d4ab9ddf9a1dcfa8178", size = 18396834, upload-time = "2026-01-05T07:28:27.653Z" },
{ url = "https://files.pythonhosted.org/packages/ba/c5/305d16ea858e9be168e00b2cd5d4e7b74524d9c4b1349b1267386c25964e/mini_racer-0.14.0-py3-none-win_amd64.whl", hash = "sha256:7e4cd3fef3df603c0d1feea6e258cf02c6c09e8619d43d4ff0f0a8595cf96715", size = 15474619, upload-time = "2026-01-05T07:28:45.059Z" },
{ url = "https://files.pythonhosted.org/packages/bd/27/e313b5ff8f6583253e5f9fee64ab88476a570c7307554acb0e2899668a97/mini_racer-0.14.0-py3-none-win_arm64.whl", hash = "sha256:2cb21a959c7045c46d727db015e614903217f3648d24fcdbde6de3b4bd17a498", size = 14795219, upload-time = "2026-01-05T07:28:48.25Z" },
]
[[package]]
name = "mistune"
version = "3.2.0"
@@ -1175,6 +1334,18 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/ad/0d/eca3d962f9eef265f01a8e0d20085c6dd1f443cbffc11b6dede81fd82356/numpy-2.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:6436cffb4f2bf26c974344439439c95e152c9a527013f26b3577be6c2ca64295", size = 10667121, upload-time = "2026-01-10T06:44:41.644Z" },
]
[[package]]
name = "openpyxl"
version = "3.1.5"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "et-xmlfile" },
]
sdist = { url = "https://files.pythonhosted.org/packages/3d/f9/88d94a75de065ea32619465d2f77b29a0469500e99012523b91cc4141cd1/openpyxl-3.1.5.tar.gz", hash = "sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050", size = 186464, upload-time = "2024-06-28T14:03:44.161Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c0/da/977ded879c29cbd04de313843e76868e6e13408a94ed6b987245dc7c8506/openpyxl-3.1.5-py2.py3-none-any.whl", hash = "sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2", size = 250910, upload-time = "2024-06-28T14:03:41.161Z" },
]
[[package]]
name = "packaging"
version = "25.0"
@@ -1385,6 +1556,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0", size = 11842, upload-time = "2024-07-21T12:58:20.04Z" },
]
[[package]]
name = "py-mini-racer"
version = "0.6.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/50/97/a578b918b2e5923dd754cb60bb8b8aeffc85255ffb92566e3c65b148ff72/py_mini_racer-0.6.0.tar.gz", hash = "sha256:f71e36b643d947ba698c57cd9bd2232c83ca997b0802fc2f7f79582377040c11", size = 5994836, upload-time = "2021-04-22T07:58:35.993Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/29/a9/8ce0ca222ef04d602924a1e099be93f5435ca6f3294182a30574d4159ca2/py_mini_racer-0.6.0-py2.py3-none-manylinux1_x86_64.whl", hash = "sha256:42896c24968481dd953eeeb11de331f6870917811961c9b26ba09071e07180e2", size = 5416149, upload-time = "2021-04-22T07:58:25.615Z" },
]
[[package]]
name = "pycparser"
version = "2.23"
@@ -1634,6 +1814,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486, upload-time = "2025-05-27T00:56:49.664Z" },
]
[[package]]
name = "simplejson"
version = "3.20.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/41/f4/a1ac5ed32f7ed9a088d62a59d410d4c204b3b3815722e2ccfb491fa8251b/simplejson-3.20.2.tar.gz", hash = "sha256:5fe7a6ce14d1c300d80d08695b7f7e633de6cd72c80644021874d985b3393649", size = 85784, upload-time = "2025-09-26T16:29:36.64Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/05/5b/83e1ff87eb60ca706972f7e02e15c0b33396e7bdbd080069a5d1b53cf0d8/simplejson-3.20.2-py3-none-any.whl", hash = "sha256:3b6bb7fb96efd673eac2e4235200bfffdc2353ad12c54117e1e4e2fc485ac017", size = 57309, upload-time = "2025-09-26T16:29:35.312Z" },
]
[[package]]
name = "six"
version = "1.17.0"
@@ -1786,6 +1975,24 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f", size = 85359, upload-time = "2024-04-19T11:11:46.763Z" },
]
[[package]]
name = "tushare"
version = "1.4.24"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "bs4" },
{ name = "lxml" },
{ name = "pandas" },
{ name = "requests" },
{ name = "simplejson" },
{ name = "tqdm" },
{ name = "websocket-client" },
]
sdist = { url = "https://files.pythonhosted.org/packages/89/09/2141aaccb90a8249edb42d6b31330606d8cf9345237773775a3aa4c71986/tushare-1.4.24.tar.gz", hash = "sha256:786acbf6ee7dfb0b152bdd570b673f74e58b86a0d9908a221c6bdc4254a4e0ea", size = 128539, upload-time = "2025-08-25T02:02:05.451Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/80/75/63810958023595b460f2a5ef6baf5a60ffd8166e5fc06a3c2f22e9ca7b34/tushare-1.4.24-py3-none-any.whl", hash = "sha256:778e3128262747cb0cdadac2e5a5e6cd1a520c239b4ffbde2776652424451b08", size = 143587, upload-time = "2025-08-25T02:02:03.554Z" },
]
[[package]]
name = "types-pytz"
version = "2025.2.0.20251108"
@@ -1876,6 +2083,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl", hash = "sha256:8156704e4346a571d9ce73b84bee86a29906c9abfd7223b7228a28899ccf3366", size = 2196503, upload-time = "2025-11-01T21:15:53.565Z" },
]
[[package]]
name = "xlrd"
version = "2.0.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/07/5a/377161c2d3538d1990d7af382c79f3b2372e880b65de21b01b1a2b78691e/xlrd-2.0.2.tar.gz", hash = "sha256:08b5e25de58f21ce71dc7db3b3b8106c1fa776f3024c54e45b45b374e89234c9", size = 100167, upload-time = "2025-06-14T08:46:39.039Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/1a/62/c8d562e7766786ba6587d09c5a8ba9f718ed3fa8af7f4553e8f91c36f302/xlrd-2.0.2-py2.py3-none-any.whl", hash = "sha256:ea762c3d29f4cca48d82df517b6d89fbce4db3107f9d78713e48cd321d5c9aa9", size = 96555, upload-time = "2025-06-14T08:46:37.766Z" },
]
[[package]]
name = "xyzservices"
version = "2025.11.0"