前言
在大模型技术全面渗透的当下,将 AI 能力融入 A 股量化交易已经成为提升策略效率的核心方向。无需复杂的金融工程背景,借助大模型的语义理解与决策能力,普通人也能搭建出可落地的量化交易体系。
本文分上下两篇,带你从零实现一套AI 驱动的 A 股量化策略。上篇重点拆解策略的三层核心架构、参数配置体系,以及带缓存机制的行情数据模块;下篇将进入特征工程、大模型决策接口与风控模块的完整代码实现。
一、策略的三层核心骨架

整套策略遵循「市场识别 → 仓位决策 → 风控纠错」的经典量化框架,拆分为三个职责清晰、可独立优化的层级:
Layer 1:特征工程与市场状态分频
这是策略的感知层,负责把原始行情数据翻译成大模型能理解的结构化 "市场语言"。
- 输入:原始 OHLCV 日线行情(开盘、最高、最低、收盘、成交量)
- 处理:提取 7 类核心市场信号,最终划分出 12 种典型市场状态
- 价值:将非结构化的价格序列,转化为大模型可识别的标准化状态输入
Layer 2:月度策略与仓位决策
这是策略的决策大脑,由大模型担任核心决策引擎。
- 输入:Layer1 输出的市场状态分类 + 历史状态收益统计
- 处理:大模型评估每种市场状态的风险收益比,输出对应仓位等级
- 输出:对应当前市场状态的基础仓位建议
Layer 3:硬性风控护栏
这是策略的安全底线,在 AI 决策的基础上叠加规则化风控,应对极端黑天鹅行情。
- 输入:LLM 输出的基础仓位 + 实时波动率 / 策略回撤数据
- 处理:叠加波动率止损、回撤止损、冷静期、强制重新入场等规则
- 输出:最终可实盘执行的实际仓位
三层架构既保留了大模型决策的灵活性,又通过规则化风控锁住了极端下行风险,是 AI 量化策略落地的成熟范式。
二、核心参数配置详解
策略所有核心参数集中管理,方便后续调优、回测与实盘切换。以下按模块逐一说明:
1. 基础配置与策略模式
bash
# ==================== 策略模式 ====================
POLICY_MODE = 'llm' # 可选:'rule'=确定性规则基准;'llm'=大模型驱动策略
# ==================== 基础数据配置 ====================
SYMBOL = '******' # 标的股票代码
SYMBOL_NAME = 'xxxx' # 标的股票名称
START_DATE = '2016-01-01' # 历史回测起始日期
END_DATE = '2026-07-20' # 回测/数据截止日期
OOS_START = '2024-01-01' # 样本外测试起始时间
# 本地化行情缓存配置
DATA_CACHE_FILE = 'data_cache_xxxxx.csv' # 本地行情CSV缓存文件路径
REQUEST_DELAY = 3.0 # akshare接口请求间隔(秒),避免限流
2. 训练与特征工程参数
bash
# ==================== 滚动训练配置 ====================
TRAIN_YEARS = 3 # 滚动训练窗口长度(年)
OPT_FREQ_MONTHS = 1 # 风控护栏参数优化频率(每月一次)
# ==================== 特征工程窗口参数 ====================
VOL_WIN = 20 # 波动率计算滚动窗口
RET_WIN = 20 # 趋势得分计算滚动窗口
ZSCORE_WIN = 252 # Z-score标准化滚动窗口(约1年交易日)
Z_EDGE = 1.0 # Z-score状态分桶阈值
3. 交易成本配置
bash
# ==================== A股交易成本 ====================
COST_BPS = 5.0 # 单向综合佣金+印花税成本(万2.5双向+千0.5卖出)
SLIPPAGE_BPS = 2.0 # 滑点估算
TC_BPS = COST_BPS + SLIPPAGE_BPS # 总单向交易成本 = 7bps
4. 波动率目标与仓位映射
这部分是 AI 决策落地为实际仓位的核心桥梁。
bash
# ==================== 波动率目标控制 ====================
USE_VOL_TARGET = True # 是否开启波动率目标控制
TARGET_VOL = 0.30 # 组合年化波动率目标(适配A股高波动特性)
MAX_LEVERAGE = 1.0 # 最大杠杆限制,默认无杠杆
# ==================== LLM持仓映射规则 ====================
LONG_FULL_EXP = 1.0 # LLM判断强烈看多 → 持有100%仓位
LONG_HALF_EXP = 0.8 # LLM判断温和看多 → 持有80%仓位
FLAT_EXP = 0.5 # LLM判断中性/谨慎 → 持有50%仓位
设计细节 :
FLAT_EXP设为 0.5 而非 0.0 是刻意设计。当大模型表达谨慎态度时,策略是降低仓位 而非全部清仓,保证模型不确定时仍能参与市场长期正期望漂移,避免踏空风险。
5. 风控护栏参数
bash
# ==================== Guardrail风控护栏 ====================
VOL_STOP = 0.50 # 波动率止损阈值(年化)
DD_LIMIT = 0.15 # 最大回撤止损阈值
COOLDOWN_DAYS = 5 # 止损后冷静期天数
MAX_FLAT_DAYS = 10 # 最长空仓天数,到期强制重新入场
REENTRY_SIZE = 1.0 # 重新入场时的初始仓位大小
三、行情数据获取模块(带本地缓存)
数据是一切量化策略的基础。这里基于 akshare 实现 A 股日线前复权数据获取,并加入本地 CSV 缓存机制,既避免重复请求触发接口限流,又能大幅提升回测速度。
模块设计思路
- 缓存优先:优先读取本地 CSV,数据覆盖目标区间则零网络请求
- 自动补全:本地缓存不足时,自动在线拉取并更新本地缓存
- 异常降级:接口请求失败时,自动回退到已有本地缓存
- 限流保护:每次请求前内置等待时间,规避反爬限制
完整代码实现
bash
import akshare as ak
import pandas as pd
import numpy as np
import os
import time
# 请求间隔(秒),防止触发反爬限流
REQUEST_DELAY = 3.0
# 本地行情缓存文件
DATA_CACHE_FILE = 'data_cache_******.csv'
def download_data_akshare(symbol, start_date, end_date, cache_file=DATA_CACHE_FILE):
"""
使用akshare获取A股日线前复权数据,带本地CSV缓存机制
缓存策略:
1. 先检查本地CSV是否存在
2. 若存在且数据日期覆盖所需范围 → 直接读取本地文件
3. 若不存在或范围不足 → akshare在线获取 → 写入本地CSV
4. 请求前休眠REQUEST_DELAY秒,防止触发反爬机制
"""
# ------------------- 1. 检查本地缓存 -------------------
if os.path.exists(cache_file):
print(f"[缓存命中] 检测到本地数据文件: {cache_file}")
df_cached = pd.read_csv(cache_file, index_col=0, parse_dates=True)
df_cached = df_cached.sort_index()
cache_start = df_cached.index[0].strftime('%Y-%m-%d')
cache_end = df_cached.index[-1].strftime('%Y-%m-%d')
print(f"本地数据范围: {cache_start} ~ {cache_end}, 共{len(df_cached)}条")
# 校验缓存是否覆盖目标日期范围
if df_cached.index[0] <= pd.to_datetime(start_date) and \
df_cached.index[-1] >= pd.to_datetime(end_date):
print("缓存数据覆盖所需范围,直接使用本地文件,无需联网请求。")
return df_cached
else:
print("缓存数据不覆盖所需范围,将重新获取全量数据...")
# ------------------- 2. akshare在线获取 -------------------
print(f"[在线获取] 使用akshare获取 {symbol} 前复权日线数据.")
print(f"请求间隔 {REQUEST_DELAY}s,请耐心等待..")
try:
start_fmt = start_date.replace('-', '')
end_fmt = end_date.replace('-', '')
time.sleep(REQUEST_DELAY) # 请求前等待,避免触发限流
df = ak.stock_zh_a_hist(
symbol=symbol,
period="daily",
start_date=start_fmt,
end_date=end_fmt,
adjust="qfq" # 前复权处理
)
except Exception as e:
print(f"akshare接口获取失败: {e}")
# 在线获取失败时,回退到本地已有缓存
if os.path.exists(cache_file):
print(f"→ 回退使用本地缓存文件: {cache_file}")
return pd.read_csv(cache_file, index_col=0, parse_dates=True).sort_index()
return None
# 空数据校验
if df is None or len(df) == 0:
print("未获取到任何行情数据,请检查股票代码或日期范围是否正确。")
return None
# ------------------- 3. 数据清洗与格式化 -------------------
# akshare默认返回中文列名,统一改为英文便于后续代码处理
df = df.rename(columns={
'日期': 'date', '开盘': 'open', '收盘': 'close',
'最高': 'high', '最低': 'low', '成交量': 'volume'
})
df['date'] = pd.to_datetime(df['date'])
df = df.set_index('date').sort_index()
# 只保留核心行情字段
df = df[['open', 'high', 'low', 'close', 'volume']]
# ------------------- 4. 写入本地CSV缓存 -------------------
df.to_csv(cache_file)
print(f"[缓存写入] 数据已保存至本地: {cache_file}")
print(f"共{len(df)}个交易日,数据范围:{df.index[0].date()} ~ {df.index[-1].date()}")
return df
重要提醒 :
adjust="qfq"(前复权)是不可修改的核心配置。如果不进行复权处理,送转股、除权日会出现虚假的价格跳空,直接导致所有下游指标、回测结果失效。