mirror of
https://ghfast.top/https://github.com/aeroxw/easy-tdx.git
synced 2026-09-12 15:44:15 +08:00
feat: merge datetime fields in DataFrame output, hide MinuteBar internal fields
- K-line: daily+ periods output 'date' only, minute periods output 'datetime' - Transactions (tick-by-tick): combine date param + hour/minute into 'datetime' - XdxrRecord, HistoricalFundFlow: year/month/day merged to 'date' - MinuteBar: rename unknown_1 to _unknown_1 (hidden from DataFrame) - MinuteBar: add datetime column computed from bar index (A-share 240-bar pattern) - get_minute_time_data: use history endpoint only (current-day endpoint broken in pytdx too) - Update all examples to reflect new DataFrame column names
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
"""演示:异步客户端连接与基本用法。"""
|
||||
|
||||
import asyncio
|
||||
from easy_tdx import AsyncTdxClient, Market, KlineCategory
|
||||
|
||||
from easy_tdx import AsyncTdxClient, KlineCategory, Market
|
||||
|
||||
|
||||
async def main():
|
||||
@@ -12,13 +13,8 @@ async def main():
|
||||
|
||||
# 自动优选服务器
|
||||
async with AsyncTdxClient.from_best_host() as c:
|
||||
bars = await c.get_security_bars(
|
||||
Market.SH, "600000", KlineCategory.DAY, 0, 5
|
||||
)
|
||||
for bar in bars:
|
||||
print(f"{bar.year}-{bar.month:02d}-{bar.day:02d} "
|
||||
f"开:{bar.open:.2f} 高:{bar.high:.2f} "
|
||||
f"低:{bar.low:.2f} 收:{bar.close:.2f}")
|
||||
df = await c.get_security_bars(Market.SH, "600000", KlineCategory.DAY, 0, 5)
|
||||
print(df.to_string(index=False))
|
||||
|
||||
|
||||
asyncio.run(main())
|
||||
|
||||
@@ -1,19 +1,7 @@
|
||||
"""演示:获取全市场涨跌统计概况。"""
|
||||
|
||||
import pandas as pd
|
||||
from easy_tdx import TdxClient
|
||||
|
||||
with TdxClient.from_best_host() as c:
|
||||
stat = c.get_market_stat()
|
||||
df = pd.DataFrame([{
|
||||
"上涨": stat.up_count,
|
||||
"下跌": stat.down_count,
|
||||
"平盘": stat.neutral_count,
|
||||
"停牌(估算)": stat.suspended_count,
|
||||
"总计": stat.total_count,
|
||||
"成交额(亿)": round(stat.total_amount / 1e8, 2),
|
||||
"总市值(万亿)": round(stat.total_market_cap / 1e12, 4),
|
||||
"涨停": stat.limit_up_count,
|
||||
"跌停": stat.limit_down_count,
|
||||
}])
|
||||
print(df.T.to_string(header=False))
|
||||
print(stat)
|
||||
|
||||
@@ -1,40 +1,63 @@
|
||||
"""演示:获取市场证券列表(分页)。
|
||||
|
||||
展示 SecurityInfo 全部字段的中文映射与表结构。
|
||||
"""
|
||||
"""演示:获取市场证券列表(分页)。"""
|
||||
|
||||
import pandas as pd
|
||||
from easy_tdx import TdxClient, Market
|
||||
from easy_tdx import Market, TdxClient
|
||||
|
||||
with TdxClient.from_best_host() as c:
|
||||
stocks = c.get_security_list(Market.SH, start=0)
|
||||
df = c.get_security_list(Market.SH, start=0)
|
||||
|
||||
# 表结构说明
|
||||
print("=" * 70)
|
||||
print("SecurityInfo 表结构(字段中英文对照)")
|
||||
print("=" * 70)
|
||||
schema = pd.DataFrame([
|
||||
{"英文字段": "market", "中文含义": "市场", "类型": "Market", "说明": "SZ=深圳 SH=上海 BJ=北京"},
|
||||
{"英文字段": "code", "中文含义": "证券代码", "类型": "str", "说明": "6位代码,如 600000"},
|
||||
{"英文字段": "name", "中文含义": "证券名称", "类型": "str", "说明": "GBK 解码"},
|
||||
{"英文字段": "volunit", "中文含义": "成交量单位", "类型": "int", "说明": "1手 = volunit 股"},
|
||||
{"英文字段": "decimal_point", "中文含义": "价格小数位", "类型": "int", "说明": "通常为 2"},
|
||||
{"英文字段": "pre_close", "中文含义": "昨收价", "类型": "float", "说明": "通达信自定义浮点"},
|
||||
{"英文字段": "industry_tdx", "中文含义": "通达信行业", "类型": "str", "说明": "需 get_security_list_all()"},
|
||||
{"英文字段": "industry_sw", "中文含义": "申万行业", "类型": "str", "说明": "需 get_security_list_all()"},
|
||||
])
|
||||
schema = pd.DataFrame(
|
||||
[
|
||||
{
|
||||
"英文字段": "market",
|
||||
"中文含义": "市场",
|
||||
"类型": "Market",
|
||||
"说明": "SZ=深圳 SH=上海 BJ=北京",
|
||||
},
|
||||
{
|
||||
"英文字段": "code",
|
||||
"中文含义": "证券代码",
|
||||
"类型": "str",
|
||||
"说明": "6位代码,如 600000",
|
||||
},
|
||||
{"英文字段": "name", "中文含义": "证券名称", "类型": "str", "说明": "GBK 解码"},
|
||||
{
|
||||
"英文字段": "volunit",
|
||||
"中文含义": "成交量单位",
|
||||
"类型": "int",
|
||||
"说明": "1手 = volunit 股",
|
||||
},
|
||||
{
|
||||
"英文字段": "decimal_point",
|
||||
"中文含义": "价格小数位",
|
||||
"类型": "int",
|
||||
"说明": "通常为 2",
|
||||
},
|
||||
{
|
||||
"英文字段": "pre_close",
|
||||
"中文含义": "昨收价",
|
||||
"类型": "float",
|
||||
"说明": "通达信自定义浮点",
|
||||
},
|
||||
{
|
||||
"英文字段": "industry_tdx",
|
||||
"中文含义": "通达信行业",
|
||||
"类型": "str",
|
||||
"说明": "需 get_security_list_all()",
|
||||
},
|
||||
{
|
||||
"英文字段": "industry_sw",
|
||||
"中文含义": "申万行业",
|
||||
"类型": "str",
|
||||
"说明": "需 get_security_list_all()",
|
||||
},
|
||||
]
|
||||
)
|
||||
print(schema.to_string(index=False))
|
||||
|
||||
# 全字段中文 DataFrame
|
||||
print(f"\n沪市第 1 页,共 {len(stocks)} 只:")
|
||||
df = pd.DataFrame([{
|
||||
"市场": s.market.name,
|
||||
"代码": s.code,
|
||||
"名称": s.name,
|
||||
"成交量单位(股/手)": s.volunit,
|
||||
"价格小数位": s.decimal_point,
|
||||
"昨收价": s.pre_close,
|
||||
"通达信行业": s.industry_tdx or "",
|
||||
"申万行业": s.industry_sw or "",
|
||||
} for s in stocks])
|
||||
print(f"\n沪市第 1 页,共 {len(df)} 只:")
|
||||
print(df.head(20).to_string(index=False))
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
"""演示:获取沪深 A 股完整列表(含行业映射)。
|
||||
|
||||
展示 SecurityInfo 全部字段(含扩展行业字段)的中文映射。
|
||||
注意:此方法需要拉取 tdxhy.cfg 并遍历全部证券,耗时较长。
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
import pandas as pd
|
||||
from easy_tdx import TdxClient
|
||||
|
||||
@@ -13,34 +13,60 @@ logging.basicConfig(level=logging.INFO, format="%(message)s")
|
||||
|
||||
# timeout 调大到 30 秒,避免全量拉取时分页请求超时
|
||||
with TdxClient.from_best_host(timeout=30.0) as c:
|
||||
all_stocks = c.get_security_list_all()
|
||||
df = c.get_security_list_all()
|
||||
|
||||
# 表结构说明
|
||||
print("=" * 70)
|
||||
print("SecurityInfo 表结构(字段中英文对照)")
|
||||
print("=" * 70)
|
||||
schema = pd.DataFrame([
|
||||
{"英文字段": "market", "中文含义": "市场", "类型": "Market", "说明": "SZ=深圳 SH=上海 BJ=北京"},
|
||||
{"英文字段": "code", "中文含义": "证券代码", "类型": "str", "说明": "6位代码,如 600000"},
|
||||
{"英文字段": "name", "中文含义": "证券名称", "类型": "str", "说明": "GBK 解码"},
|
||||
{"英文字段": "volunit", "中文含义": "成交量单位", "类型": "int", "说明": "1手 = volunit 股"},
|
||||
{"英文字段": "decimal_point", "中文含义": "价格小数位", "类型": "int", "说明": "通常为 2"},
|
||||
{"英文字段": "pre_close", "中文含义": "昨收价", "类型": "float", "说明": "通达信自定义浮点"},
|
||||
{"英文字段": "industry_tdx", "中文含义": "通达信行业", "类型": "str", "说明": "如 T1001,来自 tdxhy.cfg"},
|
||||
{"英文字段": "industry_sw", "中文含义": "申万行业", "类型": "str", "说明": "如 X500102,来自 tdxhy.cfg"},
|
||||
])
|
||||
schema = pd.DataFrame(
|
||||
[
|
||||
{
|
||||
"英文字段": "market",
|
||||
"中文含义": "市场",
|
||||
"类型": "Market",
|
||||
"说明": "SZ=深圳 SH=上海 BJ=北京",
|
||||
},
|
||||
{
|
||||
"英文字段": "code",
|
||||
"中文含义": "证券代码",
|
||||
"类型": "str",
|
||||
"说明": "6位代码,如 600000",
|
||||
},
|
||||
{"英文字段": "name", "中文含义": "证券名称", "类型": "str", "说明": "GBK 解码"},
|
||||
{
|
||||
"英文字段": "volunit",
|
||||
"中文含义": "成交量单位",
|
||||
"类型": "int",
|
||||
"说明": "1手 = volunit 股",
|
||||
},
|
||||
{
|
||||
"英文字段": "decimal_point",
|
||||
"中文含义": "价格小数位",
|
||||
"类型": "int",
|
||||
"说明": "通常为 2",
|
||||
},
|
||||
{
|
||||
"英文字段": "pre_close",
|
||||
"中文含义": "昨收价",
|
||||
"类型": "float",
|
||||
"说明": "通达信自定义浮点",
|
||||
},
|
||||
{
|
||||
"英文字段": "industry_tdx",
|
||||
"中文含义": "通达信行业",
|
||||
"类型": "str",
|
||||
"说明": "如 T1001,来自 tdxhy.cfg",
|
||||
},
|
||||
{
|
||||
"英文字段": "industry_sw",
|
||||
"中文含义": "申万行业",
|
||||
"类型": "str",
|
||||
"说明": "如 X500102,来自 tdxhy.cfg",
|
||||
},
|
||||
]
|
||||
)
|
||||
print(schema.to_string(index=False))
|
||||
|
||||
# 全字段中文 DataFrame
|
||||
print(f"\n沪深 A 股总数: {len(all_stocks)}")
|
||||
df = pd.DataFrame([{
|
||||
"市场": s.market.name,
|
||||
"代码": s.code,
|
||||
"名称": s.name,
|
||||
"成交量单位(股/手)": s.volunit,
|
||||
"价格小数位": s.decimal_point,
|
||||
"昨收价": s.pre_close,
|
||||
"通达信行业": s.industry_tdx or "",
|
||||
"申万行业": s.industry_sw or "",
|
||||
} for s in all_stocks])
|
||||
print(f"\n沪深 A 股总数: {len(df)}")
|
||||
print(df.head(20).to_string(index=False))
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"""演示:批量获取实时五档行情。最多支持 80 只/次。"""
|
||||
|
||||
import pandas as pd
|
||||
from easy_tdx import TdxClient, Market
|
||||
from easy_tdx import Market, TdxClient
|
||||
|
||||
with TdxClient.from_best_host() as c:
|
||||
stocks = [
|
||||
@@ -10,16 +9,10 @@ with TdxClient.from_best_host() as c:
|
||||
(Market.SZ, "000001"), # 平安银行
|
||||
(Market.SZ, "000858"), # 五粮液
|
||||
]
|
||||
quotes = c.get_security_quotes(stocks)
|
||||
df = pd.DataFrame([{
|
||||
"代码": q.code,
|
||||
"现价": q.price,
|
||||
"涨跌幅%": (q.price - q.pre_close) / q.pre_close * 100,
|
||||
"今开": q.open,
|
||||
"最高": q.high,
|
||||
"最低": q.low,
|
||||
"昨收": q.pre_close,
|
||||
"成交量(手)": q.vol,
|
||||
"成交额": q.amount,
|
||||
} for q in quotes])
|
||||
print(df.to_string(index=False))
|
||||
df = c.get_security_quotes(stocks)
|
||||
df["change_pct"] = (df["price"] - df["pre_close"]) / df["pre_close"] * 100
|
||||
print(
|
||||
df[
|
||||
["code", "price", "change_pct", "open", "high", "low", "pre_close", "vol", "amount"]
|
||||
].to_string(index=False)
|
||||
)
|
||||
|
||||
@@ -6,20 +6,9 @@
|
||||
创业板指: Market.SZ, "399006"
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
from easy_tdx import TdxClient, Market, KlineCategory
|
||||
from easy_tdx import KlineCategory, Market, TdxClient
|
||||
|
||||
with TdxClient.from_best_host() as c:
|
||||
bars = c.get_index_bars(Market.SH, "999999", KlineCategory.DAY, 0, 10)
|
||||
df = pd.DataFrame([{
|
||||
"日期": f"{b.year}-{b.month:02d}-{b.day:02d}",
|
||||
"开盘": b.open,
|
||||
"最高": b.high,
|
||||
"最低": b.low,
|
||||
"收盘": b.close,
|
||||
"成交量": b.vol,
|
||||
"成交额": b.amount,
|
||||
} for b in reversed(bars)])
|
||||
df = c.get_index_bars(Market.SH, "999999", KlineCategory.DAY, 0, 10)
|
||||
print("上证指数 日K线:")
|
||||
fmt = {"成交量": lambda x: f"{x:,.0f}", "成交额": lambda x: f"{x:,.0f}"}
|
||||
print(df.to_string(index=False, formatters=fmt))
|
||||
print(df.to_string(index=False))
|
||||
|
||||
@@ -5,19 +5,9 @@ K 线类别:
|
||||
KlineCategory.DAY / WEEK / MONTH / YEAR
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
from easy_tdx import TdxClient, Market, KlineCategory
|
||||
from easy_tdx import KlineCategory, Market, TdxClient
|
||||
|
||||
with TdxClient.from_best_host() as c:
|
||||
bars = c.get_security_bars(Market.SZ, "002176", KlineCategory.DAY, 0, 100)
|
||||
df = pd.DataFrame([{
|
||||
"日期": f"{b.year}-{b.month:02d}-{b.day:02d}",
|
||||
"开盘": b.open,
|
||||
"最高": b.high,
|
||||
"最低": b.low,
|
||||
"收盘": b.close,
|
||||
"成交量": b.vol,
|
||||
"成交额": b.amount,
|
||||
} for b in reversed(bars)])
|
||||
print("上证指数 日K线:")
|
||||
df = c.get_security_bars(Market.SZ, "002176", KlineCategory.DAY, 0, 100)
|
||||
print("江特电机 日K线:")
|
||||
print(df.to_string(index=False))
|
||||
|
||||
@@ -1,15 +1,9 @@
|
||||
"""演示:获取历史某日分时数据。date 参数为 YYYYMMDD 格式的整数。"""
|
||||
|
||||
import pandas as pd
|
||||
from easy_tdx import TdxClient, Market
|
||||
from easy_tdx import Market, TdxClient
|
||||
|
||||
with TdxClient.from_best_host() as c:
|
||||
date = 20250110
|
||||
bars = c.get_history_minute_time_data(Market.SH, "600000", date)
|
||||
df = pd.DataFrame([{
|
||||
"序号": i + 1,
|
||||
"价格": bar.price,
|
||||
"成交量": bar.vol,
|
||||
} for i, bar in enumerate(bars)])
|
||||
df = c.get_history_minute_time_data(Market.SH, "600000", date)
|
||||
print(f"浦发银行 {date} 分时数据,共 {len(df)} 条:")
|
||||
print(df.to_string(index=False))
|
||||
print(df.head(20).to_string(index=False))
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
"""演示:获取今日分时数据(240 条)。"""
|
||||
|
||||
import pandas as pd
|
||||
from easy_tdx import TdxClient, Market
|
||||
from easy_tdx import Market, TdxClient
|
||||
|
||||
with TdxClient.from_best_host() as c:
|
||||
bars = c.get_minute_time_data(Market.SH, "600000")
|
||||
df = pd.DataFrame([{
|
||||
"序号": i + 1,
|
||||
"价格": bar.price,
|
||||
"成交量": bar.vol,
|
||||
} for i, bar in enumerate(bars)])
|
||||
df = c.get_minute_time_data(Market.SH, "600000")
|
||||
print(f"浦发银行今日分时,共 {len(df)} 条:")
|
||||
print(df.to_string(index=False))
|
||||
print(df.head(20).to_string(index=False))
|
||||
|
||||
@@ -1,16 +1,10 @@
|
||||
"""演示:获取历史逐笔成交数据。date 参数为 YYYYMMDD 格式的整数。"""
|
||||
|
||||
import pandas as pd
|
||||
from easy_tdx import TdxClient, Market
|
||||
from easy_tdx import Market, TdxClient
|
||||
|
||||
with TdxClient.from_best_host() as c:
|
||||
date = 20250110
|
||||
records = c.get_history_transaction_data(Market.SH, "600000", date, 0, 20)
|
||||
df = pd.DataFrame([{
|
||||
"时间": f"{r.hour:02d}:{r.minute:02d}",
|
||||
"成交价": r.price,
|
||||
"成交量": r.vol,
|
||||
"方向": "买" if r.buyorsell == 0 else "卖",
|
||||
} for r in records])
|
||||
df = c.get_history_transaction_data(Market.SH, "600000", date, 0, 20)
|
||||
df["方向"] = df["buyorsell"].map({0: "买", 1: "卖", 2: "中性", 8: "集合竞价"})
|
||||
print(f"浦发银行 {date} 最近 {len(df)} 笔成交:")
|
||||
print(df.to_string(index=False))
|
||||
print(df[["datetime", "price", "vol", "方向"]].to_string(index=False))
|
||||
|
||||
@@ -1,15 +1,9 @@
|
||||
"""演示:获取当日逐笔成交数据。"""
|
||||
|
||||
import pandas as pd
|
||||
from easy_tdx import TdxClient, Market
|
||||
from easy_tdx import Market, TdxClient
|
||||
|
||||
with TdxClient.from_best_host() as c:
|
||||
records = c.get_transaction_data(Market.SH, "600000", 0, 20)
|
||||
df = pd.DataFrame([{
|
||||
"时间": f"{r.hour:02d}:{r.minute:02d}",
|
||||
"成交价": r.price,
|
||||
"成交量": r.vol,
|
||||
"方向": "买" if r.buyorsell == 0 else "卖",
|
||||
} for r in records])
|
||||
df = c.get_transaction_data(Market.SH, "600000", 0, 20)
|
||||
df["方向"] = df["buyorsell"].map({0: "买", 1: "卖", 2: "中性", 8: "集合竞价"})
|
||||
print(f"浦发银行最近 {len(df)} 笔成交:")
|
||||
print(df.to_string(index=False))
|
||||
print(df[["datetime", "price", "vol", "方向"]].to_string(index=False))
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"""演示:获取公司信息目录与各个分类的详细内容。"""
|
||||
|
||||
import pandas as pd
|
||||
from easy_tdx import TdxClient, Market
|
||||
from easy_tdx import Market, TdxClient
|
||||
|
||||
CODE = "600519"
|
||||
NAME = "贵州茅台"
|
||||
@@ -28,51 +27,36 @@ SHOW_CATEGORIES = [
|
||||
]
|
||||
|
||||
|
||||
def show_categories(categories):
|
||||
"""显示公司信息目录。"""
|
||||
df = pd.DataFrame([{
|
||||
"目录名": cat.name,
|
||||
"文件名": cat.filename,
|
||||
"起始偏移": cat.start,
|
||||
"内容长度": cat.length,
|
||||
} for cat in categories])
|
||||
print(f"{NAME} 公司信息目录:")
|
||||
print(df.to_string(index=False))
|
||||
|
||||
|
||||
def show_category_content(client, categories, category_name, max_chars=500):
|
||||
"""获取并展示指定分类的内容。"""
|
||||
cat = next((c for c in categories if c.name == category_name), None)
|
||||
if not cat:
|
||||
row = categories[categories["name"] == category_name]
|
||||
if row.empty:
|
||||
print(f" 未找到分类: {category_name}")
|
||||
return
|
||||
|
||||
r = row.iloc[0]
|
||||
content = client.get_company_info_content(
|
||||
MARKET, CODE, cat.filename, cat.start, cat.length
|
||||
MARKET, CODE, r["filename"], int(r["start"]), int(r["length"])
|
||||
)
|
||||
text = content.strip()
|
||||
if len(text) > max_chars:
|
||||
text = text[:max_chars] + f"\n... (共 {len(content.strip())} 字,仅显示前 {max_chars} 字)"
|
||||
print(f"\n{'='*60}")
|
||||
print(f"【{cat.name}】 (共 {cat.length} 字节)")
|
||||
print(f"{'='*60}")
|
||||
print(f"\n{'=' * 60}")
|
||||
print(f"【{r['name']}】 (共 {r['length']} 字节)")
|
||||
print(f"{'=' * 60}")
|
||||
print(text)
|
||||
|
||||
|
||||
def show_all_categories(client, categories):
|
||||
"""依次展示所有 SHOW_CATEGORIES 中列出的分类内容。"""
|
||||
for name in SHOW_CATEGORIES:
|
||||
show_category_content(client, categories, name)
|
||||
|
||||
|
||||
with TdxClient.from_best_host() as c:
|
||||
categories = c.get_company_info_category(MARKET, CODE)
|
||||
|
||||
# 1. 显示目录
|
||||
show_categories(categories)
|
||||
print(f"{NAME} 公司信息目录:")
|
||||
print(categories.to_string(index=False))
|
||||
|
||||
# 2. 显示所有分类内容(每个分类默认只显示前500字)
|
||||
show_all_categories(c, categories)
|
||||
for name in SHOW_CATEGORIES:
|
||||
show_category_content(c, categories, name)
|
||||
|
||||
# 3. 也可以单独获取某个分类的完整内容,例如:
|
||||
# show_category_content(c, categories, "公司概况", max_chars=99999)
|
||||
|
||||
@@ -1,21 +1,8 @@
|
||||
"""演示:获取最新财务数据。"""
|
||||
|
||||
import pandas as pd
|
||||
from easy_tdx import TdxClient, Market
|
||||
from easy_tdx import Market, TdxClient
|
||||
|
||||
with TdxClient.from_best_host() as c:
|
||||
info = c.get_finance_info(Market.SH, "600519")
|
||||
df = pd.DataFrame([
|
||||
{"项目": "总股本(万股)", "数值": info.zong_guben},
|
||||
{"项目": "流通股本(万股)", "数值": info.liutong_guben},
|
||||
{"项目": "每股净资产", "数值": info.meigujing_zichan},
|
||||
{"项目": "净利润(元)", "数值": info.jing_lirun},
|
||||
{"项目": "主营收入(元)", "数值": info.zhuying_shouru},
|
||||
{"项目": "主营利润(元)", "数值": info.zhuying_lirun},
|
||||
{"项目": "净资产(元)", "数值": info.jing_zichan},
|
||||
{"项目": "总资产(元)", "数值": info.zong_zichan},
|
||||
{"项目": "股东人数", "数值": info.gudong_renshu},
|
||||
{"项目": "上市日期", "数值": info.ipo_date},
|
||||
])
|
||||
print("贵州茅台 最新财务数据:")
|
||||
print(df.to_string(index=False, formatters={"数值": lambda x: f"{x:,.0f}"}))
|
||||
print(info.T.to_string(header=False))
|
||||
|
||||
@@ -1,23 +1,16 @@
|
||||
"""演示:计算个股涨跌停价格。"""
|
||||
|
||||
import pandas as pd
|
||||
from easy_tdx import TdxClient, Market
|
||||
from easy_tdx import Market, TdxClient
|
||||
|
||||
CODE = "600519"
|
||||
NAME = "贵州茅台"
|
||||
|
||||
with TdxClient.from_best_host() as c:
|
||||
quotes = c.get_security_quotes([(Market.SH, CODE)])
|
||||
if quotes:
|
||||
q = quotes[0]
|
||||
limit_up, limit_down = c.get_price_limits(
|
||||
Market.SH, CODE, NAME, q.pre_close
|
||||
)
|
||||
df = pd.DataFrame([{
|
||||
"代码": CODE,
|
||||
"名称": NAME,
|
||||
"昨收": q.pre_close,
|
||||
"涨停价": limit_up,
|
||||
"跌停价": limit_down,
|
||||
}])
|
||||
print(df.to_string(index=False))
|
||||
if not quotes.empty:
|
||||
q = quotes.iloc[0]
|
||||
limit_up, limit_down = c.get_price_limits(Market.SH, CODE, NAME, q["pre_close"])
|
||||
print(f"代码: {CODE} 名称: {NAME}")
|
||||
print(f"昨收: {q['pre_close']}")
|
||||
print(f"涨停价: {limit_up}")
|
||||
print(f"跌停价: {limit_down}")
|
||||
|
||||
@@ -1,17 +1,8 @@
|
||||
"""演示:获取除权除息历史记录。"""
|
||||
|
||||
import pandas as pd
|
||||
from easy_tdx import TdxClient, Market, XDXR_CATEGORY_NAMES
|
||||
from easy_tdx import Market, TdxClient
|
||||
|
||||
with TdxClient.from_best_host() as c:
|
||||
records = c.get_xdxr_info(Market.SH, "600519")
|
||||
df = pd.DataFrame([{
|
||||
"日期": f"{r.year}-{r.month:02d}-{r.day:02d}",
|
||||
"类型": XDXR_CATEGORY_NAMES.get(r.category, f"未知({r.category})"),
|
||||
"每股分红(元)": r.fenhong,
|
||||
"送转股比例": r.songzhuangu,
|
||||
"配股价": r.peigujia,
|
||||
"配股比例": r.peigu,
|
||||
} for r in records])
|
||||
df = c.get_xdxr_info(Market.SH, "600519")
|
||||
print(f"贵州茅台 除权除息记录,共 {len(df)} 条:")
|
||||
print(df.tail(10).to_string(index=False))
|
||||
|
||||
@@ -6,16 +6,9 @@
|
||||
'block_fg.dat' - 风格板块
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
from easy_tdx import TdxClient
|
||||
|
||||
with TdxClient.from_best_host() as c:
|
||||
blocks = c.get_block_info("block_gn.dat")
|
||||
df = pd.DataFrame([{
|
||||
"板块名称": b.name,
|
||||
"分类": b.category,
|
||||
"成分股数": b.count,
|
||||
"代码(前5)": ", ".join(b.codes[:5]),
|
||||
} for b in blocks])
|
||||
df = c.get_block_info("block_gn.dat")
|
||||
print(f"概念板块,共 {len(df)} 个:")
|
||||
print(df.head(20).to_string(index=False))
|
||||
print(df[["name", "category", "count"]].head(20).to_string(index=False))
|
||||
|
||||
@@ -4,16 +4,20 @@
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
from easy_tdx import TdxClient, Market
|
||||
from easy_tdx import Market, TdxClient
|
||||
|
||||
with TdxClient.from_best_host() as c:
|
||||
flow = c.get_fund_flow(Market.SH, "600519")
|
||||
df = pd.DataFrame([
|
||||
{"级别": "超大单", "流入(亿)": flow.super_in / 1e8, "流出(亿)": flow.super_out / 1e8},
|
||||
{"级别": "大单", "流入(亿)": flow.large_in / 1e8, "流出(亿)": flow.large_out / 1e8},
|
||||
{"级别": "中单", "流入(亿)": flow.medium_in / 1e8, "流出(亿)": flow.medium_out / 1e8},
|
||||
{"级别": "小单", "流入(亿)": flow.small_in / 1e8, "流出(亿)": flow.small_out / 1e8},
|
||||
])
|
||||
# flow 是单行 DataFrame,转换为万元便于阅读
|
||||
in_cols = ["super_in", "large_in", "medium_in", "small_in"]
|
||||
out_cols = ["super_out", "large_out", "medium_out", "small_out"]
|
||||
df = pd.DataFrame(
|
||||
{
|
||||
"级别": ["超大单", "大单", "中单", "小单"],
|
||||
"流入(亿)": [flow[c].iloc[0] / 1e8 for c in in_cols],
|
||||
"流出(亿)": [flow[c].iloc[0] / 1e8 for c in out_cols],
|
||||
}
|
||||
)
|
||||
df["净流入(亿)"] = df["流入(亿)"] - df["流出(亿)"]
|
||||
print("贵州茅台 当日资金流向:")
|
||||
print(df.to_string(index=False))
|
||||
|
||||
@@ -1,15 +1,8 @@
|
||||
"""演示:获取个股历史日线资金流向序列。"""
|
||||
|
||||
import pandas as pd
|
||||
from easy_tdx import TdxClient, Market
|
||||
from easy_tdx import Market, TdxClient
|
||||
|
||||
with TdxClient.from_best_host() as c:
|
||||
flows = c.get_history_fund_flow(Market.SH, "600519", 0, 10)
|
||||
df = pd.DataFrame([{
|
||||
"日期": f"{f.year}-{f.month:02d}-{f.day:02d}",
|
||||
"超大单净流入(亿)": (f.super_in - f.super_out) / 1e8,
|
||||
"大单净流入(亿)": (f.large_in - f.large_out) / 1e8,
|
||||
"主力净流入(亿)": f.main_net_inflow / 1e8,
|
||||
} for f in flows])
|
||||
df = c.get_history_fund_flow(Market.SH, "600519", 0, 10)
|
||||
print(f"贵州茅台 历史资金流向,共 {len(df)} 天:")
|
||||
print(df.to_string(index=False))
|
||||
|
||||
@@ -59,8 +59,7 @@ with TdxClient.from_best_host() as c:
|
||||
print("行业板块 (block_zs.dat)")
|
||||
print("=" * 50)
|
||||
blocks = c.get_block_info("block_zs.dat")
|
||||
for b in blocks[:5]:
|
||||
print(f" {b.name:<10} 分类={b.category} 成分={b.count}")
|
||||
print(blocks[["name", "category", "count"]].head(5).to_string(index=False))
|
||||
print(f" ... 共 {len(blocks)} 个")
|
||||
|
||||
# ── 2. 计算服务器:专业财务数据 ────────────────────────
|
||||
@@ -74,29 +73,25 @@ calc_host = CALC_HOSTS[0]
|
||||
with TdxClient(calc_host) as c:
|
||||
# 获取文件列表
|
||||
file_list = c.get_financial_file_list()
|
||||
for fi in file_list[:5]:
|
||||
print(f" {fi.filename} {fi.filesize:>12,} 字节 hash={fi.hash[:8]}...")
|
||||
print(file_list.head(5).to_string(index=False))
|
||||
print(f" ... 共 {len(file_list)} 个文件")
|
||||
|
||||
# 下载并解析最近一期有实际数据的财报
|
||||
real_files = [f for f in file_list if f.filesize > 10000]
|
||||
if real_files:
|
||||
latest = real_files[0]
|
||||
fname = f"tdxfin/{latest.filename}"
|
||||
print(f"\n下载: {fname} ({latest.filesize:,} 字节)")
|
||||
real_files = file_list[file_list["filesize"] > 10000]
|
||||
if not real_files.empty:
|
||||
latest = real_files.iloc[0]
|
||||
fname = f"tdxfin/{latest['filename']}"
|
||||
print(f"\n下载: {fname} ({latest['filesize']:,} 字节)")
|
||||
|
||||
# 保存原始 .zip
|
||||
zip_data = c.get_financial_file(fname)
|
||||
zip_path = OUTPUT_DIR / latest.filename
|
||||
zip_path = OUTPUT_DIR / latest["filename"]
|
||||
zip_path.write_bytes(zip_data)
|
||||
print(f" .zip 已保存到 {zip_path}")
|
||||
|
||||
# 解析财报记录
|
||||
records = c.get_financial_records(fname)
|
||||
print(f" 解析出 {len(records)} 只股票")
|
||||
if records:
|
||||
for r in records[:5]:
|
||||
print(f" {r.market.name} {r.code} 报告期={r.report_date} 字段数={len(r.fields)}")
|
||||
if not records.empty:
|
||||
print(records[["market", "code", "report_date"]].head(5).to_string(index=False))
|
||||
print(f" ... 共 {len(records)} 只")
|
||||
r = records[0]
|
||||
print(f" 示例: {r.market.name} {r.code}, 报告期={r.report_date}, 字段数={len(r.fields)}")
|
||||
|
||||
@@ -54,8 +54,15 @@ if need_fetch:
|
||||
print(f"\n正在连接服务器获取 {len(need_fetch)} 个板块文件...")
|
||||
with TdxClient.from_best_host() as c:
|
||||
for name in need_fetch:
|
||||
blocks = c.get_block_info(name)
|
||||
_print_blocks(blocks, f"{block_labels[name]} ({name}, 网络)")
|
||||
df = c.get_block_info(name)
|
||||
print(f"\n{block_labels[name]} ({name}, 网络) ({len(df)} 个板块):")
|
||||
for _, row in df.head(5).iterrows():
|
||||
codes = row["codes"]
|
||||
codes_preview = ", ".join(str(c) for c in codes[:5])
|
||||
suffix = "..." if len(codes) > 5 else ""
|
||||
print(f" {row['name']} ({row['count']}只): {codes_preview}{suffix}")
|
||||
if len(df) > 5:
|
||||
print(f" ... 还有 {len(df) - 5} 个板块")
|
||||
|
||||
# --- 自定义板块 ---
|
||||
print(f"\n{'=' * 60}")
|
||||
|
||||
Reference in New Issue
Block a user