优化表结构,增加表数据
This commit is contained in:
16
.idea/csv-editor.xml
generated
16
.idea/csv-editor.xml
generated
@@ -1,16 +0,0 @@
|
||||
<?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/data_source_mapping.xml
generated
Normal file
7
.idea/data_source_mapping.xml
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DataSourcePerFileMappings">
|
||||
<file url="file://$APPLICATION_CONFIG_DIR$/consoles/db/bd7b5f2a-eb99-4aad-81ec-1fec76b3d7fc/console.sql" value="bd7b5f2a-eb99-4aad-81ec-1fec76b3d7fc" />
|
||||
<file url="file://$APPLICATION_CONFIG_DIR$/consoles/db/c9e16f8e-81be-45cf-847c-47a6750eeee2/console.sql" value="c9e16f8e-81be-45cf-847c-47a6750eeee2" />
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/db-forest-config.xml
generated
Normal file
6
.idea/db-forest-config.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="db-tree-configuration">
|
||||
<option name="data" value="" />
|
||||
</component>
|
||||
</project>
|
||||
136
data.py
Normal file
136
data.py
Normal file
@@ -0,0 +1,136 @@
|
||||
from datetime import date, datetime, timedelta
|
||||
from time import sleep
|
||||
|
||||
from sqlalchemy import Column, Double, Integer, String, create_engine
|
||||
from sqlalchemy.orm import DeclarativeBase, Session
|
||||
from tushare import pro_api
|
||||
|
||||
TUSHARE_API_KEY = '64ebff4fa679167600b905ee45dd88e76f3963c0ff39157f3f085f0e'
|
||||
|
||||
|
||||
class Base(DeclarativeBase):
|
||||
pass
|
||||
|
||||
|
||||
class Stock(Base):
|
||||
__tablename__ = 'stock'
|
||||
|
||||
code = Column(String, primary_key=True, comment="代码")
|
||||
name = Column(String, comment="名称")
|
||||
fullname = Column(String, comment="全名")
|
||||
market = Column(String, comment="市场")
|
||||
exchange = Column(String, comment="交易所")
|
||||
industry = Column(String, comment="行业")
|
||||
list_date = Column(String, comment="上市日期")
|
||||
|
||||
|
||||
class Daily(Base):
|
||||
__tablename__ = 'daily'
|
||||
|
||||
code = Column(String, primary_key=True)
|
||||
trade_date = Column(String, primary_key=True)
|
||||
open = Column(Double)
|
||||
close = Column(Double)
|
||||
high = Column(Double)
|
||||
low = Column(Double)
|
||||
previous_close = Column(Double)
|
||||
turnover = Column(Double)
|
||||
volume = Column(Integer)
|
||||
price_change_amount = Column(Double)
|
||||
factor = Column(Double)
|
||||
|
||||
|
||||
def main():
|
||||
print("开始更新数据")
|
||||
|
||||
engine = create_engine(f"sqlite:////Users/lanyuanxiaoyao/Documents/leopard_data/leopard.sqlite")
|
||||
try:
|
||||
Stock.metadata.create_all(engine, checkfirst=True)
|
||||
Daily.metadata.create_all(engine, checkfirst=True)
|
||||
pro = pro_api(TUSHARE_API_KEY)
|
||||
# with engine.connect() as connection:
|
||||
# stocks = pro.stock_basic(list_status="L", market="主板", fields="ts_code,name,fullname,market,exchange,industry,list_date")
|
||||
# for row in stocks.itertuples():
|
||||
# stmt = insert(Stock).values(
|
||||
# code=row.ts_code,
|
||||
# name=row.name,
|
||||
# fullname=row.fullname,
|
||||
# market=row.market,
|
||||
# exchange=row.exchange,
|
||||
# industry=row.industry,
|
||||
# list_date=row.list_date,
|
||||
# )
|
||||
# stmt = stmt.on_conflict_do_update(
|
||||
# index_elements=["code"],
|
||||
# set_={
|
||||
# "name": stmt.excluded.name,
|
||||
# "fullname": stmt.excluded.fullname,
|
||||
# "market": stmt.excluded.market,
|
||||
# "exchange": stmt.excluded.exchange,
|
||||
# "industry": stmt.excluded.industry,
|
||||
# "list_date": stmt.excluded.list_date,
|
||||
# },
|
||||
# )
|
||||
# print(stmt)
|
||||
# connection.execute(stmt)
|
||||
# connection.commit()
|
||||
#
|
||||
# print("清理行情数据")
|
||||
# connection.execute(text("delete from daily where code not in (select distinct code from stock)"))
|
||||
# connection.commit()
|
||||
#
|
||||
# print("清理财务数据")
|
||||
# connection.execute(text("delete from finance_indicator where code not in (select distinct code from stock)"))
|
||||
# connection.commit()
|
||||
|
||||
with Session(engine) as session:
|
||||
stock_codes = [row[0] for row in session.query(Stock.code).all()]
|
||||
|
||||
latest_date = session.query(Daily.trade_date).order_by(Daily.trade_date.desc()).first()
|
||||
if latest_date is None:
|
||||
latest_date = '1990-12-19'
|
||||
else:
|
||||
latest_date = latest_date.trade_date
|
||||
latest_date = datetime.strptime(latest_date, '%Y-%m-%d').date()
|
||||
current_date = date.today() - timedelta(days=1)
|
||||
delta = (current_date - latest_date).days
|
||||
print(f"最新数据日期:{latest_date},当前日期:{current_date},待更新天数:{delta}")
|
||||
if delta > 0:
|
||||
update_dates = []
|
||||
for i in range(delta):
|
||||
latest_date = latest_date + timedelta(days=1)
|
||||
update_dates.append(latest_date.strftime('%Y%m%d'))
|
||||
for target_date in update_dates:
|
||||
print(f"正在采集:{target_date}")
|
||||
dailies = pro.daily(trade_date=target_date)
|
||||
dailies.set_index("ts_code", inplace=True)
|
||||
factors = pro.adj_factor(trade_date=target_date)
|
||||
factors.set_index("ts_code", inplace=True)
|
||||
results = dailies.join(factors, lsuffix="_daily", rsuffix="_factor", how="left")
|
||||
rows = []
|
||||
for row in results.itertuples():
|
||||
if row.Index in stock_codes:
|
||||
rows.append(
|
||||
Daily(
|
||||
code=row.Index,
|
||||
trade_date=datetime.strptime(target_date, '%Y%m%d').strftime("%Y-%m-%d"),
|
||||
open=row.open,
|
||||
close=row.close,
|
||||
high=row.high,
|
||||
low=row.low,
|
||||
previous_close=row.pre_close,
|
||||
turnover=row.amount,
|
||||
volume=row.vol,
|
||||
price_change_amount=row.pct_chg,
|
||||
factor=row.adj_factor,
|
||||
)
|
||||
)
|
||||
session.add_all(rows)
|
||||
session.commit()
|
||||
sleep(1)
|
||||
finally:
|
||||
engine.dispose()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
1300
notebook/datasource/data.ipynb
Normal file
1300
notebook/datasource/data.ipynb
Normal file
File diff suppressed because it is too large
Load Diff
@@ -3,8 +3,8 @@
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2026-01-29T10:09:22.171634Z",
|
||||
"start_time": "2026-01-29T08:27:03.148937Z"
|
||||
"end_time": "2026-01-30T05:41:51.291397Z",
|
||||
"start_time": "2026-01-30T04:34:22.917761Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
@@ -13,6 +13,7 @@
|
||||
"\n",
|
||||
"import pandas as pd\n",
|
||||
"import sqlalchemy\n",
|
||||
"from sqlalchemy import text\n",
|
||||
"from sqlalchemy.orm import DeclarativeBase, Session\n",
|
||||
"\n",
|
||||
"postgresql_engin = sqlalchemy.create_engine(\n",
|
||||
@@ -29,7 +30,7 @@
|
||||
" __tablename__ = 'daily'\n",
|
||||
"\n",
|
||||
" code = sqlalchemy.Column(sqlalchemy.String, primary_key=True)\n",
|
||||
" trade_date = sqlalchemy.Column(sqlalchemy.Date)\n",
|
||||
" trade_date = sqlalchemy.Column(sqlalchemy.Date, primary_key=True)\n",
|
||||
" open = sqlalchemy.Column(sqlalchemy.Double)\n",
|
||||
" close = sqlalchemy.Column(sqlalchemy.Double)\n",
|
||||
" high = sqlalchemy.Column(sqlalchemy.Double)\n",
|
||||
@@ -42,47 +43,52 @@
|
||||
"\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",
|
||||
" with Session(postgresql_engin) as pg_session:\n",
|
||||
" results = pg_session.execute(text(\"select distinct trade_date from leopard_daily\")).fetchall()\n",
|
||||
" results = list(map(lambda x: x[0].strftime(\"%Y-%m-%d\"), results))\n",
|
||||
" dates = [results[i: i + 30] for i in range(0, len(results), 30)]\n",
|
||||
"\n",
|
||||
" for index, date in enumerate(dates):\n",
|
||||
" print(date)\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 d.trade_date in ('{\"','\".join(date)}')\n",
|
||||
" \"\"\",\n",
|
||||
" postgresql_engin\n",
|
||||
" )\n",
|
||||
" with Session(sqlite_engine) as session:\n",
|
||||
" rows = []\n",
|
||||
" for _, row in daily_df.iterrows():\n",
|
||||
" rows.append(\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",
|
||||
" )\n",
|
||||
" session.flush()\n",
|
||||
" session.commit()\n",
|
||||
" session.add_all(rows)\n",
|
||||
" session.commit()\n",
|
||||
"finally:\n",
|
||||
" postgresql_engin.dispose()\n",
|
||||
" sqlite_engine.dispose()"
|
||||
@@ -90,28 +96,339 @@
|
||||
"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: "
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"['2025-12-25', '2025-12-26', '2025-12-29', '2025-12-30', '2025-12-31', '2026-01-05', '2026-01-06', '2026-01-07', '2026-01-08', '2026-01-09']\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 26
|
||||
"execution_count": 22
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2026-01-30T09:24:09.859231Z",
|
||||
"start_time": "2026-01-30T09:24:09.746912Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"import tushare as ts\n",
|
||||
"\n",
|
||||
"pro = ts.pro_api(\"64ebff4fa679167600b905ee45dd88e76f3963c0ff39157f3f085f0e\")\n",
|
||||
"# stocks = pro.stock_basic(ts_code=\"600200.SH\", list_status=\"D\", fields=\"ts_code,name,fullname,market,exchange,industry,list_date,delist_date\")\n",
|
||||
"# stocks"
|
||||
],
|
||||
"id": "ed58a1faaf2cdb8e",
|
||||
"outputs": [],
|
||||
"execution_count": 34
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2026-01-30T07:14:29.897120Z",
|
||||
"start_time": "2026-01-30T07:14:29.664124Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": "# stocks.to_csv(\"dlist.csv\")",
|
||||
"id": "3c8c0a38d6b2992e",
|
||||
"outputs": [],
|
||||
"execution_count": 24
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2026-01-30T09:46:34.808300Z",
|
||||
"start_time": "2026-01-30T09:46:34.129412Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"daily_df = pro.daily(trade_date=\"20251231\")\n",
|
||||
"daily_df.set_index(\"ts_code\", inplace=True)\n",
|
||||
"factor_df = pro.adj_factor(trade_date=\"20251231\")\n",
|
||||
"factor_df.set_index(\"ts_code\", inplace=True)"
|
||||
],
|
||||
"id": "c052a945869aa329",
|
||||
"outputs": [],
|
||||
"execution_count": 50
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2026-01-30T09:46:36.697015Z",
|
||||
"start_time": "2026-01-30T09:46:36.642975Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"result_df = daily_df.join(factor_df, lsuffix=\"_daily\", rsuffix=\"_factor\", how=\"left\")\n",
|
||||
"result_df\n",
|
||||
"# factor_df"
|
||||
],
|
||||
"id": "d61ee80d2cd9f06b",
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
" trade_date_daily open high low close pre_close change \\\n",
|
||||
"ts_code \n",
|
||||
"000001.SZ 20251231 11.48 11.49 11.40 11.41 11.48 -0.07 \n",
|
||||
"000002.SZ 20251231 4.66 4.68 4.62 4.65 4.62 0.03 \n",
|
||||
"000004.SZ 20251231 11.30 11.35 11.07 11.08 11.27 -0.19 \n",
|
||||
"000006.SZ 20251231 9.95 10.03 9.69 9.95 9.86 0.09 \n",
|
||||
"000007.SZ 20251231 11.72 11.75 11.28 11.44 11.62 -0.18 \n",
|
||||
"... ... ... ... ... ... ... ... \n",
|
||||
"920978.BJ 20251231 37.64 38.39 36.88 36.90 37.78 -0.88 \n",
|
||||
"920981.BJ 20251231 32.20 32.29 31.75 31.96 32.07 -0.11 \n",
|
||||
"920982.BJ 20251231 233.00 238.49 232.10 233.70 234.80 -1.10 \n",
|
||||
"920985.BJ 20251231 7.32 7.35 7.17 7.19 7.30 -0.11 \n",
|
||||
"920992.BJ 20251231 17.33 17.60 17.29 17.39 17.38 0.01 \n",
|
||||
"\n",
|
||||
" pct_chg vol amount trade_date_factor adj_factor \n",
|
||||
"ts_code \n",
|
||||
"000001.SZ -0.6098 590620.37 675457.357 20251231 134.5794 \n",
|
||||
"000002.SZ 0.6494 1075561.25 499883.113 20251231 181.7040 \n",
|
||||
"000004.SZ -1.6859 18056.00 20248.567 20251231 4.0640 \n",
|
||||
"000006.SZ 0.9128 270369.08 267758.676 20251231 39.7400 \n",
|
||||
"000007.SZ -1.5491 80556.00 92109.366 20251231 8.2840 \n",
|
||||
"... ... ... ... ... ... \n",
|
||||
"920978.BJ -2.3293 33945.04 126954.937 20251231 1.2885 \n",
|
||||
"920981.BJ -0.3430 8237.16 26301.206 20251231 1.4343 \n",
|
||||
"920982.BJ -0.4685 5210.09 122452.646 20251231 4.2831 \n",
|
||||
"920985.BJ -1.5068 35174.30 25350.257 20251231 1.6280 \n",
|
||||
"920992.BJ 0.0575 6991.87 12193.445 20251231 1.4932 \n",
|
||||
"\n",
|
||||
"[5458 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>trade_date_daily</th>\n",
|
||||
" <th>open</th>\n",
|
||||
" <th>high</th>\n",
|
||||
" <th>low</th>\n",
|
||||
" <th>close</th>\n",
|
||||
" <th>pre_close</th>\n",
|
||||
" <th>change</th>\n",
|
||||
" <th>pct_chg</th>\n",
|
||||
" <th>vol</th>\n",
|
||||
" <th>amount</th>\n",
|
||||
" <th>trade_date_factor</th>\n",
|
||||
" <th>adj_factor</th>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>ts_code</th>\n",
|
||||
" <th></th>\n",
|
||||
" <th></th>\n",
|
||||
" <th></th>\n",
|
||||
" <th></th>\n",
|
||||
" <th></th>\n",
|
||||
" <th></th>\n",
|
||||
" <th></th>\n",
|
||||
" <th></th>\n",
|
||||
" <th></th>\n",
|
||||
" <th></th>\n",
|
||||
" <th></th>\n",
|
||||
" <th></th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>000001.SZ</th>\n",
|
||||
" <td>20251231</td>\n",
|
||||
" <td>11.48</td>\n",
|
||||
" <td>11.49</td>\n",
|
||||
" <td>11.40</td>\n",
|
||||
" <td>11.41</td>\n",
|
||||
" <td>11.48</td>\n",
|
||||
" <td>-0.07</td>\n",
|
||||
" <td>-0.6098</td>\n",
|
||||
" <td>590620.37</td>\n",
|
||||
" <td>675457.357</td>\n",
|
||||
" <td>20251231</td>\n",
|
||||
" <td>134.5794</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>000002.SZ</th>\n",
|
||||
" <td>20251231</td>\n",
|
||||
" <td>4.66</td>\n",
|
||||
" <td>4.68</td>\n",
|
||||
" <td>4.62</td>\n",
|
||||
" <td>4.65</td>\n",
|
||||
" <td>4.62</td>\n",
|
||||
" <td>0.03</td>\n",
|
||||
" <td>0.6494</td>\n",
|
||||
" <td>1075561.25</td>\n",
|
||||
" <td>499883.113</td>\n",
|
||||
" <td>20251231</td>\n",
|
||||
" <td>181.7040</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>000004.SZ</th>\n",
|
||||
" <td>20251231</td>\n",
|
||||
" <td>11.30</td>\n",
|
||||
" <td>11.35</td>\n",
|
||||
" <td>11.07</td>\n",
|
||||
" <td>11.08</td>\n",
|
||||
" <td>11.27</td>\n",
|
||||
" <td>-0.19</td>\n",
|
||||
" <td>-1.6859</td>\n",
|
||||
" <td>18056.00</td>\n",
|
||||
" <td>20248.567</td>\n",
|
||||
" <td>20251231</td>\n",
|
||||
" <td>4.0640</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>000006.SZ</th>\n",
|
||||
" <td>20251231</td>\n",
|
||||
" <td>9.95</td>\n",
|
||||
" <td>10.03</td>\n",
|
||||
" <td>9.69</td>\n",
|
||||
" <td>9.95</td>\n",
|
||||
" <td>9.86</td>\n",
|
||||
" <td>0.09</td>\n",
|
||||
" <td>0.9128</td>\n",
|
||||
" <td>270369.08</td>\n",
|
||||
" <td>267758.676</td>\n",
|
||||
" <td>20251231</td>\n",
|
||||
" <td>39.7400</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>000007.SZ</th>\n",
|
||||
" <td>20251231</td>\n",
|
||||
" <td>11.72</td>\n",
|
||||
" <td>11.75</td>\n",
|
||||
" <td>11.28</td>\n",
|
||||
" <td>11.44</td>\n",
|
||||
" <td>11.62</td>\n",
|
||||
" <td>-0.18</td>\n",
|
||||
" <td>-1.5491</td>\n",
|
||||
" <td>80556.00</td>\n",
|
||||
" <td>92109.366</td>\n",
|
||||
" <td>20251231</td>\n",
|
||||
" <td>8.2840</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>920978.BJ</th>\n",
|
||||
" <td>20251231</td>\n",
|
||||
" <td>37.64</td>\n",
|
||||
" <td>38.39</td>\n",
|
||||
" <td>36.88</td>\n",
|
||||
" <td>36.90</td>\n",
|
||||
" <td>37.78</td>\n",
|
||||
" <td>-0.88</td>\n",
|
||||
" <td>-2.3293</td>\n",
|
||||
" <td>33945.04</td>\n",
|
||||
" <td>126954.937</td>\n",
|
||||
" <td>20251231</td>\n",
|
||||
" <td>1.2885</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>920981.BJ</th>\n",
|
||||
" <td>20251231</td>\n",
|
||||
" <td>32.20</td>\n",
|
||||
" <td>32.29</td>\n",
|
||||
" <td>31.75</td>\n",
|
||||
" <td>31.96</td>\n",
|
||||
" <td>32.07</td>\n",
|
||||
" <td>-0.11</td>\n",
|
||||
" <td>-0.3430</td>\n",
|
||||
" <td>8237.16</td>\n",
|
||||
" <td>26301.206</td>\n",
|
||||
" <td>20251231</td>\n",
|
||||
" <td>1.4343</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>920982.BJ</th>\n",
|
||||
" <td>20251231</td>\n",
|
||||
" <td>233.00</td>\n",
|
||||
" <td>238.49</td>\n",
|
||||
" <td>232.10</td>\n",
|
||||
" <td>233.70</td>\n",
|
||||
" <td>234.80</td>\n",
|
||||
" <td>-1.10</td>\n",
|
||||
" <td>-0.4685</td>\n",
|
||||
" <td>5210.09</td>\n",
|
||||
" <td>122452.646</td>\n",
|
||||
" <td>20251231</td>\n",
|
||||
" <td>4.2831</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>920985.BJ</th>\n",
|
||||
" <td>20251231</td>\n",
|
||||
" <td>7.32</td>\n",
|
||||
" <td>7.35</td>\n",
|
||||
" <td>7.17</td>\n",
|
||||
" <td>7.19</td>\n",
|
||||
" <td>7.30</td>\n",
|
||||
" <td>-0.11</td>\n",
|
||||
" <td>-1.5068</td>\n",
|
||||
" <td>35174.30</td>\n",
|
||||
" <td>25350.257</td>\n",
|
||||
" <td>20251231</td>\n",
|
||||
" <td>1.6280</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>920992.BJ</th>\n",
|
||||
" <td>20251231</td>\n",
|
||||
" <td>17.33</td>\n",
|
||||
" <td>17.60</td>\n",
|
||||
" <td>17.29</td>\n",
|
||||
" <td>17.39</td>\n",
|
||||
" <td>17.38</td>\n",
|
||||
" <td>0.01</td>\n",
|
||||
" <td>0.0575</td>\n",
|
||||
" <td>6991.87</td>\n",
|
||||
" <td>12193.445</td>\n",
|
||||
" <td>20251231</td>\n",
|
||||
" <td>1.4932</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>\n",
|
||||
"<p>5458 rows × 12 columns</p>\n",
|
||||
"</div>"
|
||||
]
|
||||
},
|
||||
"execution_count": 51,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"execution_count": 51
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
|
||||
82
notebook/sqlalchemy.ipynb
Normal file
82
notebook/sqlalchemy.ipynb
Normal file
File diff suppressed because one or more lines are too long
@@ -4,8 +4,10 @@ version = "0.1.0"
|
||||
description = "Stock analysis"
|
||||
requires-python = ">=3.14"
|
||||
dependencies = [
|
||||
"adata>=2.9.5",
|
||||
"akshare>=1.18.20",
|
||||
"backtesting~=0.6.5",
|
||||
"baostock>=0.8.9",
|
||||
"duckdb>=1.4.4",
|
||||
"jupyter~=1.1.1",
|
||||
"jupyter-bokeh>=4.0.5",
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
CREATE TABLE stock
|
||||
(
|
||||
code varchar primary key,
|
||||
code varchar not null,
|
||||
name varchar not null,
|
||||
fullname varchar,
|
||||
industry varchar,
|
||||
listed_date date,
|
||||
market varchar,
|
||||
name varchar
|
||||
exchange varchar,
|
||||
primary key (code)
|
||||
);
|
||||
|
||||
|
||||
@@ -13,22 +15,22 @@ 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,
|
||||
open double,
|
||||
close double,
|
||||
high double,
|
||||
low double,
|
||||
previous_close double,
|
||||
turnover double,
|
||||
volume integer,
|
||||
price_change_amount double,
|
||||
factor double,
|
||||
primary key (code, trade_date)
|
||||
);
|
||||
|
||||
CREATE TABLE finance_indicator
|
||||
(
|
||||
code varchar,
|
||||
year integer,
|
||||
code varchar not null,
|
||||
year integer not null,
|
||||
accounts_payable double,
|
||||
accounts_payable_to_total_assets_ratio double,
|
||||
accounts_receivable double,
|
||||
|
||||
33
uv.lock
generated
33
uv.lock
generated
@@ -2,6 +2,21 @@ version = 1
|
||||
revision = 3
|
||||
requires-python = ">=3.14"
|
||||
|
||||
[[package]]
|
||||
name = "adata"
|
||||
version = "2.9.5"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "beautifulsoup4" },
|
||||
{ name = "pandas" },
|
||||
{ name = "py-mini-racer" },
|
||||
{ name = "requests" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/0e/da/1eb2f05b14e4d41edcc017b9d6b428f30712d0d046f1b85cd54201b423a5/adata-2.9.5.tar.gz", hash = "sha256:b398fd885ee31baca41b8a141c586d3430ef0fec633f6088a830429437210cf6", size = 188823, upload-time = "2025-12-26T11:09:29.759Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/1d/9f/51a65fb438febc0ab38f493a837c5aeb9135dfee2e2c1224920038bbc686/adata-2.9.5-py3-none-any.whl", hash = "sha256:f9dc5d276f8771cf5a5f11fb81c6d97a00d188e20cfcef67022f210c8b23cbf1", size = 229158, upload-time = "2025-12-26T11:09:23.007Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "akracer"
|
||||
version = "0.0.14"
|
||||
@@ -165,6 +180,18 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b3/b6/cf57538b968c5caa60ee626ec8be1c31e420067d2a4cf710d81605356f8c/backtesting-0.6.5-py3-none-any.whl", hash = "sha256:8ac2fa500c8fd83dc783b72957b600653a72687986fe3ca86d6ef6c8b8d74363", size = 192105, upload-time = "2025-07-30T05:57:03.322Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "baostock"
|
||||
version = "0.8.9"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "pandas" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ee/d5/0fb2c61f392f89b1655490acb17a02861f1f1c38e973c9fc6aa049e54401/baostock-0.8.9.tar.gz", hash = "sha256:8169cdbed14fa442ace63c59549bef3f92b0c3dd1df9e5d9069f7bd04a76b0da", size = 21876, upload-time = "2024-05-31T02:56:54.546Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b2/37/bbabac2d33723d71bd8dbd5e819d9cbe5dc1e031b7dd12ed7de8fa040816/baostock-0.8.9-py3-none-any.whl", hash = "sha256:7a51fb30cd6b4325f5517198e350dc2fffaaab2923cd132b9f747b8b73ae7303", size = 45923, upload-time = "2024-05-31T02:56:53.161Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "beautifulsoup4"
|
||||
version = "4.14.3"
|
||||
@@ -1013,8 +1040,10 @@ name = "leopard-analysis"
|
||||
version = "0.1.0"
|
||||
source = { virtual = "." }
|
||||
dependencies = [
|
||||
{ name = "adata" },
|
||||
{ name = "akshare" },
|
||||
{ name = "backtesting" },
|
||||
{ name = "baostock" },
|
||||
{ name = "duckdb" },
|
||||
{ name = "jupyter" },
|
||||
{ name = "jupyter-bokeh" },
|
||||
@@ -1033,8 +1062,10 @@ dependencies = [
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [
|
||||
{ name = "adata", specifier = ">=2.9.5" },
|
||||
{ name = "akshare", specifier = ">=1.18.20" },
|
||||
{ name = "backtesting", specifier = "~=0.6.5" },
|
||||
{ name = "baostock", specifier = ">=0.8.9" },
|
||||
{ name = "duckdb", specifier = ">=1.4.4" },
|
||||
{ name = "jupyter", specifier = "~=1.1.1" },
|
||||
{ name = "jupyter-bokeh", specifier = ">=4.0.5" },
|
||||
@@ -1562,7 +1593,9 @@ 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/13/13/058240c7fd1fbf29a24bda048d93346c2a56275736b76b56afe64050a161/py_mini_racer-0.6.0-py2.py3-none-macosx_10_10_x86_64.whl", hash = "sha256:346e73bb89a2024888244d487834be24a121089ceb0641dd0200cb96c4e24b57", size = 5280865, upload-time = "2021-04-22T07:58:29.118Z" },
|
||||
{ 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" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5d/71/76ac5d593e14b148a4847b608c5ad9a2c7c4827c796c33b396d0437fa113/py_mini_racer-0.6.0-py2.py3-none-win_amd64.whl", hash = "sha256:97cab31bbf63ce462ba4cd6e978c572c916d8b15586156c7c5e0b2e42c10baab", size = 4797809, upload-time = "2021-04-22T07:58:32.286Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
Reference in New Issue
Block a user