统一金融行情数据接口 — 多源互补、自动降级、永不单点故障
将整个 skills/financial-market-data/ 目录复制到目标机器的对应位置:
text
~/.openclaw/workspace/skills/financial-market-data/
目录结构:
text
financial-market-data/
├── SKILL.md # 本文件
├── skill.yaml # Skill 元数据
└── python/
├── pyproject.toml # Python 依赖
├── template.py # 基础接口(TickFlow/pytdx/baostock/akshare)
└── ths.py # 同花顺专用接口(新增)
bash
cd ~/.openclaw/workspace
uv sync
或使用 pip:
bash
pip install tickflow akshare baostock pytdx requests pandas
在任意 Python 脚本中引用:
python
import sys
sys.path.insert(0, 'skills/financial-market-data/python')
from ths import get_daily_k, get_1min_k, get_intraday, get_realtime
from template import get_daily_k as tk_daily, get_realtime_eastmoney
同花顺官方免费接口, 1分钟K线最强(约821条历史,覆盖2009年至今)。
python
import sys
sys.path.insert(0, 'skills/financial-market-data/python')
from ths import get_daily_k, get_daily_k_page
# 获取日K(每次最多140条,总量约3856条)
records = get_daily_k("300006") # 莱美药业
for r in records[-5:]:
print(r['date'], r['close'], r['volume'])
# 翻页获取更早数据(以第一条记录日期为end参数)
older = get_daily_k_page("300006", end_date="20250902")
python
from ths import get_1min_k
# 获取1分钟K(全部历史,约821条)
records = get_1min_k("300006")
print(f"共 {len(records)} 条, {records[0]['date']} ~ {records[-1]['date']}")
优势对比:
数据源1分钟K条数免费注册同花顺****约821条✅不需要pytdx有限制✅不需要BaoStock有限制✅不需要东方财富Level2完整❌需要付费
python
from ths import get_intraday
# 获取分时(每分钟汇总,需差分计算增量)
result = get_intraday("300006")
for r in result['records'][-10:]:
print(r['time'], r['price'], r['volume'], '手/分钟')
python
from ths import get_realtime, get_multi_realtime
# 单只
rt = get_realtime("300006")
print(rt['price'])
# 批量
data = get_multi_realtime(["300006", "002560", "601975"])
for d in data:
print(d.get('code'), d.get('price'))
周期URL路径返回条数数据格式日K/v6/line/hs_{code}/01/his.js140条/次,总3856条日期,开,高,低,收,量,额,换手1分钟K/v6/line/hs_{code}/11/last.js全部约821条同上60分钟K/v6/line/hs_{code}/60/last.js140条/次日期时间(YYYYMMDDHHMM),开,高,低,收,量,额,换手分时/v6/line/hs_{code}/01/last.js约140条/日累计量,需差分算增量实时/v6/realtime/hs_{code}.js1条即时价格/高/低/量/额/五档
注意: 同花顺接口返回JSONP格式(
quotebridge_v6_line_hs_xxx({"num":...})),需解析JSONP并用分号分割数据字段。
python
from tickflow import TickFlow
tf = TickFlow.free()
df = tf.klines.get("600519.SH", period="1d", count=100, as_dataframe=True)
# 返回字段:trade_date, open, high, low, close, volume
python
import baostock as bs
bs.login()
rs = bs.query_history_k_data_plus(
"sz.000001",
"date,code,open,high,low,close,volume,pctChg",
start_date="20200101",
end_date="20260404",
frequency="d",
adjustflag="3"
)
data_list = []
while rs.next:
data_list.append(rs.get_row_data())
bs.logout()
python
from pytdx.hq import TdxHq_API
api = TdxHq_API()
if api.connect('218.75.126.9', 7709):
data = api.get_security_bars(9, 0, "000001", 0, 100) # category=9=1分钟K
api.disconnect()
python
rs = bs.query_history_k_data_plus(
"sz.000001",
"date,time,code,open,high,low,close,volume",
start_date="20260401",
end_date="20260404",
frequency="5", # 5=5分钟
adjustflag="3"
)
python
# TickFlow(推荐)
df = tf.klines.get("00700.HK", period="1d", count=100)
# AkShare(备选)
import akshare as ak
df = ak.stock_hk_daily(symbol="00700", start_date="20240101", end_date="20260404", adjust="qfq")
python
# TickFlow(推荐)
df = tf.klines.get("AAPL.US", period="1d", count=100)
# AkShare(备选)
df = ak.stock_us_daily(symbol="AAPL", start_date="20240101", end_date="20260404", adjust="qfq")
python
# 港股实时
df = ak.stock_hk_spot_em()
# 美股实时
df = ak.stock_us_spot_em()
python
import akshare as ak
df = ak.futures_zh_daily(symbol="au2504", start_date="20240101", end_date="20260404")
python
# 上海期货(market=47)
data = api.get_security_bars(9, 47, "au2504", 0, 100)
# 大连/郑州(market=1)
data = api.get_security_bars(9, 1, "i2505", 0, 100)
python
import akshare as ak
# 沪深300ETF日K
df = ak.fund_etf_hist_sina(symbol="sh510300")
# ETF实时行情
df = ak.fund_etf_spot_em()
# 场外基金净值
df = ak.fund_open_fund_info_em(symbol="000001", indicator="累计净值走势")
python
import requests, json
api_key = "替换为你自己的MX API Key,申请地址:https://openapi.eastmoney.com/mx/v1/api-docs"
url = "https://mkapi2.dfcfs.com/finskillshub/api/claw/query"
payload = {
"toolQuery": json.dumps({
"func": "get_quote_list_ts",
"params": ["600519.SH,000001.SZ", 1]
})
}
headers = {"Content-Type": "application/json", "apiKey": api_key}
resp = requests.post(url, json=payload, headers=headers, timeout=15)
data = resp.json()
python
import requests
url = "https://push2.eastmoney.com/api/qt/stock/get"
params = {
"secid": "1.600519",
"fields": "f43,f44,f45,f46,f47,f48,f50,f57,f58,f107,f169,f170",
}
r = requests.get(url, params=params, timeout=10)
# f43=最新价 f170=涨跌幅 f57=代码 f58=名称
python
import akshare as ak
# 行业板块列表
df = ak.stock_board_industry_name_em()
# 概念板块列表
df = ak.stock_board_concept_name_em()
# 板块内个股
df = ak.stock_board_industry_cons_em(symbol="半导体")
# 行业涨幅榜
df = ak.stock_board_industry_rank_em()
python
import baostock as bs
bs.login()
# 盈利能力
rs = bs.query_profit_data(code="sz.000001", year=2024, quarter=4)
df = rs.get_data()
# 成长能力
rs = bs.query_growth_data(code="sz.000001", year=2024, quarter=4)
# 杜邦分析
rs = bs.query_dupont_data(code="sz.000001", year=2024, quarter=4)
bs.logout()
python
import akshare as ak
# 个股资金流向
df = ak.stock_individual_fund_flow(stock="000001", market="sh")
# 大单净流入
df = ak.stock_individual_fund_flow(stock="000001", market="sh", symbol="大单净流入")
python
import akshare as ak
df = ak.macro_china_gdp() # GDP
df = ak.macro_china_cpi() # CPI
df = ak.macro_china_money_supply() # 货币供应量
方案适用场景日K1分钟K实时行情板块/财务A纯免费无需注册TickFlow同花顺821条AkShare DirectAkShareB最佳体验(需Key)TickFlow同花顺****东方财富MX APIAkShare + BaoStockCA股专注BaoStockBaoStockAkShare DirectBaoStock + AkShare
问题解决方案同花顺1分钟K最强✅ 约821条,2009年至今,完全免费TickFlow免费版无分钟K→ 改用同花顺1分钟K 或 pytdxBaoStock分钟K日期格式报错→ 用 frequency="5" 而非 "1min"AkShare网络不稳定→ 添加重试机制,或切换到同花顺东方财富MX API中文乱码→ 数值正常,字段名用正则匹配数字ID绕过pytdx连接失败(防火墙/封禁)→ 换用 同花顺1分钟K东财push2his(K线)被拒→ 换用 同花顺日K英为财情(Cloudflare)→ 完全无法突破,需付费API
接口Key状态东方财富 MX API替换为你自己的MX API Key,申请地址:https://openapi.eastmoney.com/mx/v1/api-docs✅ 已配置
注意: 同花顺、TickFlow、BaoStock、AkShare、pytdx 均为免费无需注册接口, 同花顺1分钟K是免费接口中最强的。