送给编程小白的福利:用 Python 获取行情数据的极简入门指南
“一台能开网页的电脑,三行Python代码,你就能亲手揭开A股市场实时跳动的脉搏。市场里没有神话,只有不会用工具的人。
”
“喂,十方,你说咱们小散户,看盘是不是就盯着那几条傻愣愣的均线,听消息跟风跑?” 上周酒桌上,一个刚入市半年的兄弟问我。
我抿了口酒,没直接回答,掏出手机给他看了段我自己写的 Python 脚本跑出来的结果:过去一个月,某只热门股在每天下午两点半到三点之间,出现超过7次振幅突然放大但收盘又被强行拉回的诡异图形。
他盯着屏幕愣了几秒:“这……你是从哪儿搞来的‘内部数据’?”
我笑了。哪有什么内部数据,这不过是从网上公开接口里,用不到50行代码捞出来的。今天,我就把这些年攒下的、用Python摸市场脉搏的“野路子”,掰开揉碎,送给所有不想再做信息韭菜的战友。
01 工具观:为什么你必须亲手抓数据?
先讲个真事。2024年初,我注意到某个新能源车板块的ETF,所有券商APP显示的“实时估值”和它实际持仓股的加权涨跌幅,每天收盘前总有那么零点几个百分点的微小偏差。
这偏差时正时负,看上去像是计算误差。但我用Python写了个脚本,专门在每天下午2点55分抓取它所有成分股的实时价,自己算了一遍。
连续跟踪两周后,发现这不是误差——在14个交易日里,有9天“估值”比实际算出来的要“好看”一点点,尤其在板块下跌的日子更明显。
我后来知道,这叫“IOPV优化”,是基金管理人的合法操作。但如果你只看APP给你喂的结果,你永远意识不到,你接收的“事实”已经被加工过一次。
市场如战场,情报的获取方式决定你的生存概率。别人嚼好喂给你的信息,和自己从源头获取的信息,完全是两码事。
亲手抓数据,不是为了当黑客,而是为了获得信息自主权:你能知道数据原本的样子,能追溯每个数字的时间戳,能用自己的逻辑验证市场共识。这是从散户思维转向系统化思考的第一步。
02 环境准备:别在第一步就掉坑里
很多教程一上来就让你装Python、配环境,搞得像要重装操作系统。咱们不搞那么复杂。
如果你是纯小白,记住一个最省事的法子:直接用 Google Colab。这是个在浏览器里就能写Python的免费工具,不用安装任何东西。
打开浏览器,输入 colab.research.google.com,新建一个笔记本,下面所有代码你都能直接在里面运行。网络、环境、库依赖,Google全给你准备好了。
如果你想在自己电脑上弄,那就装个 Anaconda(去官网下载,选最新的Python 3.x版本)。它自带Python和一堆数据分析要用的库,安装时记得把“Add Anaconda to my PATH environment variable”打勾,省去后面一堆配置麻烦。
验证安装成不成功,打开命令行(Windows叫cmd或PowerShell,Mac叫Terminal),输入python --version,能看到版本号就行。
然后,无论你在Colab还是自己电脑上,先把咱们今天要用的核心武器装上。在代码单元格里(Colab),或命令行里(本地),输入:
!pip install tushare yfinance pandas
按个回车,等它噼里啪啦装完。tushare是抓A股数据的利器,yfinance是抓美股和全球市场的,pandas是处理数据的万能工具箱。
如果中途报错,大概率是网络问题,换个时间再试,或者在某条命令后面加上 -i https://pypi.tuna.tsinghua.edu.cn/simple,用国内镜像源下载,速度更快。
记住,环境配置出问题是正常的,就像你新兵入伍第一天打靶总脱靶。别自己硬琢磨,把报错信息完整复制下来,去百度或者知乎一搜,99%的问题前人都踩过坑了。
03 A股数据抓取:用Tushare摸清自家地盘
搞定了环境,咱们先拿最熟悉的A股开刀。这里首推 Tushare,一个国内开发者维护的免费财经数据接口,数据源相对稳定,对A股市场覆盖很全。
第一步,领个“通行证”。
Tushare现在需要注册获取 token(一个身份验证字符串)。打开 tushare.pro 网站,微信扫码注册一下,完全免费。登录后,在“个人主页”就能看到你的 token,长得像一长串乱码。
拿到token后,在你的Python环境里,用下面两行代码初始化:
import tushare as ts
pro = ts.pro_api('你的token')
这就好比你在战区拿到了敌我识别码,可以安全通行了。
第二步,试试水深,捞点基础信息。
想知道沪深两市到底有多少只股票?上市公司的基本信息从哪查?一行代码就够了:
# 获取当前沪深两市所有上市股票的基本信息
df_basic = pro.stock_basic(exchange='', list_status='L', fields='ts_code,symbol,name,area,industry,list_date')
print(df_basic.head())
这行代码捞回来的数据,包含股票代码、名称、地域、行业和上市日期。list_status='L' 表示只要“上市”状态的,排除已退市(‘D’)或暂停上市(‘P’)的。
第三步,抓取历史行情,看看K线的“素颜”。
真正的分析始于历史数据。假设你想分析“贵州茅台”(代码 600519.SH)从2024年年初到现在的日线行情:
df = pro.daily(ts_code='600519.SH', start_date='20240101', end_date='20250129')
print(df[['trade_date', 'open', 'high', 'low', 'close', 'vol']].head())
这里返回的数据,是你见过最干净的K线:交易日期、开盘、最高、最低、收盘、成交量,没有复权,没有杂七杂八的指标,就是市场最原始的成交记录。
第四步,盯住实时动态,感受市场脉搏。
如果你想在交易时间看看某只股票的实时情况(比如买一卖一报价),可以这样:
# 获取实时行情(交易时间段内有效)
df_realtime = ts.get_realtime_quotes(['600519', '000001']) # 可以传入多个股票代码
print(df_realtime[['code', 'name', 'price', 'bid', 'ask', 'volume', 'amount', 'time']])
bid是买一价,ask是卖一价,time是数据时间。你立刻就能感受到,你获取数据的那一刻,市场正在发生什么。
这里插一句干货:Tushare的免费数据有频率限制,别用循环疯狂请求,容易被封。简单看看、学学,完全够用。真要大批量、自动化抓取,得去官网看看积分和付费规则。
04 全球市场数据:用yfinance打开世界地图
A股只是全球市场的一个角落。美股、港股、期货、加密货币……这些市场的行情怎么抓?用 yfinance,一个封装了雅虎财经(Yahoo! Finance)公开接口的Python库。
首先,它有两点必须清醒认识:
第一,yfinance 是第三方开源工具,并非雅虎官方产品,用的是雅虎公开的API。第二,雅虎财经的服务条款明确说,其数据仅限个人使用。所以你用它来学习、做个人研究完全没问题,但别想着扒了数据去做商业产品。
然后,咱们开干。
安装后(前面已经装过了),抓取苹果公司(AAPL)的历史数据,简单到令人发指:
import yfinance as yf
import pandas as pd
# 下载苹果公司过去一年的日线数据
apple = yf.download('AAPL', start='2024-01-01', end='2026-01-29')
print(apple.head())
这条命令返回的数据框(DataFrame),索引是日期,列是 Open, High, Low, Close, Adj Close, Volume,极其规整。
yfinance 的方便之处在于,它理解人类的自然表达。你不必精确计算起止日期:
# 获取过去一个月的数据
data = yf.download('AAPL', period='1mo')
# 获取过去五年的数据,按周间隔
data_weekly = yf.download('AAPL', period='5y', interval='1wk')
period 参数可以是 '1d’, ‘5d’, ‘1mo’, ‘3mo’, ‘6mo’, ‘1y’, ‘2y’, ‘5y’, ‘10y’, ‘ytd’(今年至今), ‘max’(全部历史)。
除了股票,它还能抓很多东西:
- 指数:
^GSPC(标普500), ^IXIC(纳斯达克), ^HSI(恒生指数) - ETF:
SPY(标普500 ETF), QQQ(纳斯达克100 ETF) - 加密货币:
BTC-USD(比特币), ETH-USD(以太坊) - 大宗商品:
GC=F(黄金期货), CL=F(原油期货)
比如,你想同时对比特斯拉(TSLA)、比特币和黄金的近期走势,一个列表搞定:
data = yf.download(['TSLA', 'BTC-USD', 'GC=F'], start='2024-01-01')
返回的数据是一个多级索引(MultiIndex)的DataFrame,所有数据自动按时间对齐,省去了你手动对齐时间戳的麻烦。
最后,说一个关键细节:复权价格。
yfinance 返回的 Adj Close(调整后收盘价)已经考虑了分红、拆股等公司行为的影响,是进行长期趋势分析和计算收益率最常用的价格序列。
而Tushare等A股接口,通常返回的是未经复权的原始价格,你需要调用专门的 adj_factor(复权因子)接口自己进行计算。这个差异,在跨市场比较时至关重要。
05 专业数据接口:当免费午餐不够吃时
Tushare和yfinance是绝佳的起点,但如果你玩得深入了,就会发现它们的局限:数据延迟可能几分钟,历史分钟级或tick数据难以获取,接口稳定性在极端行情下可能波动,大批量数据抓取有限制。
这时候,你就得了解专业的数据服务了。它们像战地里的“军用级”情报系统,稳定、快速、全面,但,要花钱。
国内的代表是 RQData(米筐),它提供的是涵盖A股、期货、基金等全市场的历史与实时数据,数据质量经过清洗和校验。
它的使用模式很典型:注册获取许可证,本地安装客户端,然后通过API调用。
import rqdatac
rqdatac.init() # 用你的账号信息初始化
# 获取“平安银行”某段时间的日线数据
price = rqdatac.get_price('000001.XSHE', start_date='20240101', end_date='20250129')
000001.XSHE 是米筐内部的证券代码(order_book_id),它保证了跨市场、跨品种的唯一性。数据返回即是整洁的Pandas DataFrame。
这类服务的关键在于“流量配额”。通常试用账户每天有1GB左右的免费流量,超出或想获取更高质量(如tick数据)、更多维度的数据(如财务、资金流),就需要付费订阅。
国外的类似服务有 Alpha Vantage、Quandl(已被纳斯达克收购)、IEX Cloud 等。它们的共同特点是:提供结构化API,有免费层级但限制严格,付费后解锁全部能力和更高调用频率。
选择这些服务,你买的不只是数据,更是 时间的确定性和数据的可信度。在你搭建自动化交易系统时,一个在开盘瞬间崩溃的数据接口,带来的可能是真金白银的损失。
据一篇2026年1月的技术文章分析,超过85%的量化策略失效,核心原因之一就是行情数据的延迟或接口不稳定。所以,当你从“玩一玩”进阶到“动真格”时,为可靠数据付费,是最值得的投资之一。
06 数据清洗:从“矿渣”里提炼“真金”
从网上抓下来的原始数据,就像刚从河里淘出来的金矿砂,里面混着泥土、石块。直接拿来分析,结论肯定失真。数据清洗,就是你的炼金术。
第一关,处理缺失值。
市场在节假日休市,数据就是缺失的(NaN)。如果你要计算连续收益率,这些缺口会导致错误。
import pandas as pd
# 假设df是你的原始数据
print(df.isnull().sum()) # 查看各列缺失值数量
# 方法1:直接删除缺失行(慎用,可能破坏时间连续性)
df_cleaned = df.dropna()
# 方法2:向前填充(用前一个交易日的值填充节假日)
df_filled = df.fillna(method='ffill')
# 方法3:对价格序列,更合理的做法是,先将日期设为索引,生成完整的交易日历,再对齐填充。
# 但这需要你有一个可靠的交易日历。
第二关,处理异常值。
某天收盘价突然比前一天涨了500%,然后又恢复原样?这可能是“脏数据”,也可能是真的涨跌停或乌龙指,需要鉴别。
# 一个简单的基于统计的异常值检测:找出收盘价变化率超过3倍标准差的日子
returns = df['close'].pct_change()
mean_return = returns.mean()
std_return = returns.std()
threshold = 3 * std_return
outliers = returns[(returns > mean_return + threshold) | (returns < mean_return - threshold)]
print(f'发现异常波动日期:{outliers.index.tolist()}')
对于这些异常点,你不能简单地删除或平滑,而要结合公告、新闻去判断它是“数据错误”还是“重大事件”。清洗不是掩盖,而是识别并标记。
第三关,格式统一化。
不同数据源的时间戳格式可能不同(如‘2025-01-30’、‘2025/01/30’、时间戳整数),价格可能是字符串(‘128.50’),成交量单位可能不同(手 vs 股)。
# 确保日期列为datetime类型
df['trade_date'] = pd.to_datetime(df['trade_date'])
# 确保价格、成交量为数值类型
df['close'] = pd.to_numeric(df['close'])
df['volume'] = pd.to_numeric(df['volume'])
# 设置日期为索引,这是处理时间序列数据的标准做法
df.set_index('trade_date', inplace=True)
第四关,也是最关键的一步:复权计算(针对A股)。
前复权、后复权、定点复权,各有各的用途。Tushare提供了复权因子接口:
# 获取复权因子
df_factor = pro.adj_factor(ts_code='600519.SH', trade_date='20250129')
# 然后根据因子,对原始价格序列进行计算,得到你需要的复权价格。
这一步做不对,你计算的所有技术指标、画的所有趋势线,全都是错的。很多免费网站提供的“复权K线”,其算法是个黑箱,这就是为什么你必须自己掌握这个过程。
07 实战分析:给你的数据注入灵魂
数据洗干净了,躺在Excel里只是一堆数字。只有当你用逻辑去分析它,它才开始讲述市场的故事。这里给你几个最简单的、立刻就能上手的分析思路。
分析一:计算你的“武器”——技术指标
移动平均线(MA)是最基础的装备。用Pandas,一行代码就能给股价装上“瞄准镜”:
df['MA_5'] = df['close'].rolling(window=5).mean() # 5日均线
df['MA_20'] = df['close'].rolling(window=20).mean() # 20日均线
df['MA_60'] = df['close'].rolling(window=60).mean() # 60日生命线
稍微复杂点的,如相对强弱指数(RSI),用来衡量市场“气喘得有多急”:
defcalculate_rsi(series, period=14):
delta = series.diff(1)
gain = delta.where(delta > 0, 0)
loss = -delta.where(delta < 0, 0)
avg_gain = gain.rolling(window=period).mean()
avg_loss = loss.rolling(window=period).mean()
rs = avg_gain / avg_loss
rsi = 100 - (100 / (1 + rs))
return rsi
df['RSI_14'] = calculate_rsi(df['close'])
分析二:执行简单的“战术回测”
比如,测试一个简单的双均线金叉死叉策略在过去一年的表现:
# 生成信号
df['Signal'] = 0
df.loc[df['MA_5'] > df['MA_20'], 'Signal'] = 1# 金叉,假设为买入信号1
df.loc[df['MA_5'] < df['MA_20'], 'Signal'] = -1# 死叉,假设为卖出信号-1
# 计算策略每日收益率(这里简化处理,不考虑交易成本、滑点)
df['Strategy_Return'] = df['Signal'].shift(1) * df['close'].pct_change()
# 对比策略收益和简单持有(买入并持有)收益
df['Buy_Hold_Return'] = df['close'].pct_change()
cum_strategy_return = (1 + df['Strategy_Return'].dropna()).cumprod()
cum_buyhold_return = (1 + df['Buy_Hold_Return'].dropna()).cumprod()
分析三:制作你的“战场态势图”
人眼对图形的敏感度远高于数字。用 matplotlib 或 seaborn 把你的发现画出来。
import matplotlib.pyplot as plt
fig, axes = plt.subplots(2, 1, figsize=(15, 10))
# 子图1:价格与均线
axes[0].plot(df.index, df['close'], label='Close Price', linewidth=1)
axes[0].plot(df.index, df['MA_20'], label='20-day MA', linewidth=1)
axes[0].plot(df.index, df['MA_60'], label='60-day MA', linewidth=1)
axes[0].set_title('Stock Price with Moving Averages')
axes[0].legend()
axes[0].grid(True, linestyle='--', alpha=0.5)
# 子图2:RSI指标
axes[1].plot(df.index, df['RSI_14'], label='RSI (14)', color='orange')
axes[1].axhline(y=70, color='r', linestyle='--', label='Overbought (70)')
axes[1].axhline(y=30, color='g', linestyle='--', label='Oversold (30)')
axes[1].set_title('Relative Strength Index (RSI)')
axes[1].legend()
axes[1].grid(True, linestyle='--', alpha=0.5)
plt.tight_layout()
plt.show()
当你亲手运行这些代码,看到图表在自己的屏幕上生成时,你对市场的理解,就从一个“听消息的旁观者”,向一个“看数据的参与者”迈进了一大步。
08 写在最后:工具理性与市场敬畏
敲了这么多代码,讲了这么多方法,最后我得给你泼盆冷水,也是最重要的提醒:工具永远只是工具,它不产生盈利,只放大你的认知和能力。
你能用Python抓到毫秒级数据,能跑复杂的机器学习模型预测下一秒的价格,但如果你对“市场为什么波动”的本质缺乏理解,对“风险”没有刻骨的敬畏,那么最先进的工具,只会让你以更快的速度、更大的规模亏钱。
我见过太多这样的“技术狂人”,沉迷于构建复杂的策略,回测曲线漂亮得像个神话,一上实盘,遇到一个没见过的极端行情(比如2015年股市异常波动,2020年新冠疫情全球熔断),模型瞬间崩溃,净值直线归零。
Python、数据、算法,是你的“矛”和“盾”,但你的“心法”才是真正的内功。心法是什么?是对价值的基本判断,是对周期轮回的认知,是在极端恐惧和贪婪中保持冷静的纪律,是承认自己永远无法预测未来的谦卑。
所以,当你学会抓取数据之后,请把它用在正确的地方:不是去预测明天是涨是跌,而是去验证你的投资逻辑,去量化你感受到的市场情绪,去管理你已经暴露的风险。
从今天起,少看那些神乎其神的“战法”,少听那些煞有介事的“内幕”。打开你的编辑器,从抓取一只股票的历史数据开始,亲手计算它的波动率,亲手画出它的价值区间。
市场的真相,永远藏在最原始的数据里,等待着那些愿意亲手去挖掘、并用独立思考去解读的人。
这条路没有捷径,但每一步,都算数。