第二章 金融数据基础:股票、期货、加密货币数据获取,pandas数据处理,OHLCV与K线图绘制

各位同学,欢迎来到第二章。这一章,我们要解决一个最实际的问题:数据从哪来?拿到手之后怎么处理?以及,怎么把枯燥的数字变成能一眼看懂的图表?

我个人习惯把数据获取比作「做饭前的买菜」。菜买不好,后面厨艺再好也白搭。量化投资更是如此——垃圾数据进,垃圾模型出。咱们今天就把「买菜」和「洗菜切菜」的功夫练扎实。

2.1 数据源:股票、期货、加密货币

金融数据源五花八门,我挑几个最常用的、且适合咱们强化学习场景的来说。

2.1.1 股票数据

国内股票数据,我个人最常用的是 TushareAKShare。Tushare 数据质量高,但部分接口需要积分;AKShare 完全免费,接口丰富,适合初学者上手。

核心要点: 对于强化学习,我们通常需要日线级别以上的数据。高频数据(分钟级)虽然信息量大,但噪声也大,初期不建议碰。

# 使用 AKShare 获取 A 股日线数据
import akshare as ak

# 获取贵州茅台(股票代码:600519)的历史日线数据
stock_zh_a_hist_df = ak.stock_zh_a_hist(symbol="600519", period="daily", 
                                         start_date="20200101", end_date="20231231", 
                                         adjust="qfq")  # qfq 表示前复权
print(stock_zh_a_hist_df.head())

嗯,这里要注意:复权处理。股票有分红送股,不复权的话,K线图上会出现跳空缺口,影响技术指标计算。我建议初学者直接用前复权,这样历史价格是连续的。

2.1.2 期货数据

期货数据和股票有个很大的不同:合约有到期日。你拿到的螺纹钢主力合约,过几个月就换月了。如果不做处理,数据会出现断崖。

我曾经在项目中吃过这个亏——直接用主力连续合约训练模型,结果模型学会了「换月跳空」的规律,实盘一跑就崩。后来我改用 指数合约 或者自己写 换月拼接逻辑,才把问题解决。

# 使用 Tushare 获取期货日线数据(需要 token)
import tushare as ts
pro = ts.pro_api('your_token_here')

# 获取螺纹钢主力连续合约
df = pro.fut_daily(ts_code='RB9999.XSGE', start_date='20200101', end_date='20231231')
print(df.head())

避坑指南: 我曾经用「成交量最大」作为换月标准,但遇到节假日前后成交量异常时,换月点会漂移。后来我改用「持仓量最大+固定日期窗口」的双重判断,稳定多了。

2.1.3 加密货币数据

加密货币是 7×24 小时交易的,数据量巨大。我推荐用 CCXT 库,它统一了上百家交易所的 API 接口,写一套代码就能跑遍 Binance、OKX、Coinbase。

# 使用 CCXT 获取比特币现货数据
import ccxt
import pandas as pd

exchange = ccxt.binance()
# 获取 BTC/USDT 的 1 天 K 线,限制 500 根
ohlcv = exchange.fetch_ohlcv('BTC/USDT', timeframe='1d', limit=500)

# 转换成 DataFrame
columns = ['timestamp', 'open', 'high', 'low', 'close', 'volume']
df = pd.DataFrame(ohlcv, columns=columns)
df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
print(df.head())

你想想看,加密货币数据有个特点:数据频率可以很高。对于强化学习,我个人建议先从 1 小时或 4 小时级别开始,别一上来就搞 1 分钟 tick 数据,那会让你的智能体「只见树木不见森林」。

2.2 pandas 数据处理:从原始数据到干净特征

数据拿到手,十有八九是脏的。缺失值、异常值、时间戳不对齐……这些都是家常便饭。pandas 就是咱们的「瑞士军刀」。

2.2.1 数据清洗三板斧

  1. 检查缺失值df.isnull().sum() 一眼看出哪些列有空洞。
  2. 处理异常值:比如某天收盘价突然变成 0,那肯定是数据错误。
  3. 对齐时间索引:把 timestamp 设为 index,确保数据按时间排序。
# 数据清洗示例
# 假设 df 是上一步获取的 BTC 数据

# 1. 检查缺失
print(df.isnull().sum())

# 2. 删除收盘价为 0 或负数的异常行
df = df[df['close'] > 0]

# 3. 设置时间索引并排序
df.set_index('timestamp', inplace=True)
df.sort_index(inplace=True)

# 4. 向前填充缺失值(比如周末无交易)
df.fillna(method='ffill', inplace=True)

注意: 向前填充(ffill)在金融数据中很常用,但要注意边界情况。比如停牌期间用 ffill,复牌后第一个数据点会失真。我一般会在 ffill 之后,再检查一下连续填充的长度,超过 5 天的就标记为「待处理」。

2.2.2 计算常用技术指标

强化学习需要状态特征,原始 OHLCV 往往不够。咱们得加工一下。下面是我常用的几个指标:

指标名称 计算公式 用途
收益率 (close - close.shift(1)) / close.shift(1) 衡量价格变化幅度
对数收益率 log(close / close.shift(1)) 更符合正态分布假设
波动率 收益率滚动 20 日标准差 衡量风险
RSI 14 日相对强弱指标 判断超买超卖
ATR 平均真实波幅 衡量市场波动
# 计算特征
import numpy as np

# 收益率
df['return'] = df['close'].pct_change()

# 对数收益率
df['log_return'] = np.log(df['close'] / df['close'].shift(1))

# 20 日滚动波动率
df['volatility'] = df['return'].rolling(window=20).std()

# RSI(14 日)
def compute_rsi(data, window=14):
    delta = data.diff()
    gain = (delta.where(delta > 0, 0)).rolling(window=window).mean()
    loss = (-delta.where(delta < 0, 0)).rolling(window=window).mean()
    rs = gain / loss
    rsi = 100 - (100 / (1 + rs))
    return rsi

df['rsi'] = compute_rsi(df['close'], 14)

# 删除前 20 行 NaN
df.dropna(inplace=True)
print(df.tail())

说白了,这些特征就是强化学习智能体的「眼睛」。特征选得好,模型学得快;特征选得烂,模型就是在瞎猜。

2.3 OHLCV 与 K 线图绘制

数据处理好之后,画个 K 线图看看,是最直观的验证方式。我习惯用 mplfinance 库,它是 matplotlib 的金融专用扩展,画 K 线图非常方便。

2.3.1 使用 mplfinance 绘制 K 线图

import mplfinance as mpf

# 确保数据格式正确:索引为 DatetimeIndex,包含 OHLCV 列
# 这里用我们清洗后的 BTC 数据
mpf.plot(df, type='candle', volume=True, style='charles',
         title='BTC/USDT K-line Chart', 
         ylabel='Price (USDT)', ylabel_lower='Volume')

运行这段代码,你会看到一张标准的 K 线图:红色阳线、绿色阴线、下方成交量柱状图。嗯,看到这个图,你心里就有底了——数据没问题。

2.3.2 自定义 K 线图:加入均线

我个人习惯在 K 线图上叠加均线,这样能快速判断趋势。

# 计算均线
df['ma5'] = df['close'].rolling(window=5).mean()
df['ma20'] = df['close'].rolling(window=20).mean()

# 绘制带均线的 K 线图
ap = [mpf.make_addplot(df['ma5'], color='blue', width=0.8),
      mpf.make_addplot(df['ma20'], color='orange', width=0.8)]

mpf.plot(df, type='candle', volume=True, style='charles',
         addplot=ap,
         title='BTC/USDT with MA5 & MA20',
         ylabel='Price (USDT)')

小技巧: 如果你觉得 mplfinance 的默认样式不好看,可以试试 style='binance' 或者自己定义颜色。我经常用 style='yahoo',那个配色比较经典。

2.4 本章知识体系总览

下面这张 SVG 图,把本章的核心逻辑串起来了。从数据获取到清洗,再到特征工程和可视化,每一步都是为后续的强化学习模型打基础。

第二章 金融数据基础:知识体系 数据源 数据获取 数据清洗 股票 (AKShare/Tushare) 期货 (主力连续/指数) 加密货币 (CCXT) OHLCV 原始数据 复权处理 时间对齐 缺失值处理 异常值过滤 向前填充 特征工程:收益率 | 波动率 | RSI | ATR | 均线 K 线图绘制 (mplfinance) 数据 → 清洗 → 特征 → 可视化,为强化学习智能体提供高质量状态输入

这张图里,从数据源到最终的可视化,每一步都环环相扣。你可能会问:「为什么要把可视化放在最后?」其实,可视化不仅是验证数据的手段,更是你理解市场行为的窗口。我每次拿到新数据,第一件事就是画 K 线图,看看有没有异常跳空、有没有数据断层——眼睛比代码更容易发现问题。

好了,这一章的内容就到这里。数据基础打牢了,后面咱们才能放心地搭建强化学习环境、训练智能体。记住:数据质量决定模型上限,别在这个环节偷懒。


专注资料整理