Java量化系列(五十)|股票资金信息爬取全落地!搞懂资金运用+SQL+代码,精准捕捉主力动向

📅 2026/8/24 4:30:18
Java量化系列(五十)|股票资金信息爬取全落地!搞懂资金运用+SQL+代码,精准捕捉主力动向
重要提示本篇是「股票资金数据」实战落地篇衔接前49篇量化策略优化内容全程围绕「资金运用逻辑数据爬取存储落地」展开——从资金流向底层逻辑到SQL表设计、Do实体类给定直接用再到某券商资金数据爬取、解析、存储全代码所有代码均为可运行版本复制粘贴即可嵌入你的量化项目新手也能快速打通资金数据闭环量化交易的核心逻辑资金决定涨跌异动只是表象。前49篇我们搞定了异动数据但很多量化新手依然会踩坑——只看异动信号不看资金流向导致误判假突破、追高被套。其实股票的涨跌本质是资金的“进”与“出”主力资金净流入股价大概率拉升主力资金持续净流出再强的异动也只是昙花一现。想要做高胜率量化策略必须先搞懂「股票资金是怎么运用的」再落地「资金数据的爬取与存储」让资金流向成为策略的“定海神针”。今天第50篇我将从实战角度出发先通俗讲解股票资金的运用逻辑新手也能听懂再把给定的SQL、StockBkMoneyHistoryDo实体类、爬取解析代码一步步拆解落地全程无冗余、无废话所有代码可直接复用帮你彻底搞定股票资金数据注全文无敏感词基于Java主流量化框架开发适配某券商最新资金接口兼容前49篇的量化框架建议收藏转发避免后续找不到一、先搞懂核心股票资金到底是怎么运用的很多新手看资金数据只看“主力净流入/流出”却不知道资金是如何在市场中流转、影响股价的。其实股票资金的运用本质是「不同资金主体的博弈」核心分为4类资金每类资金的运用逻辑的都直接决定股价走势——这也是我们爬取资金数据的核心意义。结合实战场景用通俗的语言拆解不用复杂术语新手也能秒懂1. 主力资金核心主导者核心定义机构、游资等大资金主体资金量庞大通常千万级以上是决定股价中期走势的核心力量也是我们量化策略重点跟踪的对象。运用逻辑主力资金不会盲目买卖通常分为3个阶段① 建仓阶段悄悄买入资金净流入温和增加股价波动不大避免引起市场注意② 拉升阶段资金大量净流入股价快速上涨借助利好消息吸引散户跟风③ 出货阶段资金净流出股价缓慢下跌悄悄卖出套牢跟风散户。我们爬取的「today_main_inflow」主力净注入净额就是跟踪主力资金动向的核心指标——持续净流入大概率是建仓或拉升阶段持续净流出需警惕出货风险。2. 超大单资金主力的“先锋部队”核心定义单笔成交金额超大的资金通常500万以上主要是主力资金的“快速操作通道”用于快速建仓、拉升或出货。运用逻辑超大单资金净流入突然激增往往是主力开始发力的信号比如突发利好主力快速抢筹超大单净流出激增可能是主力紧急出货需立即规避风险。对应爬取数据中的「today_super_inflow」超大净注入净额可辅助判断主力的操作节奏——超大单主力资金双净流入信号更可靠。3. 大单/中单/小单资金市场跟随者① 大单资金单笔成交金额较大100-500万多为中小机构或大户资金跟随主力操作是股价拉升的“辅助力量”② 中单资金单笔成交金额中等10-100万多为散户中的大户操作相对理性对股价影响有限③ 小单资金单笔成交金额较小10万以下主要是普通散户资金资金分散、操作频繁是市场的“跟风者”往往成为主力收割的对象。对应爬取数据中的「today_more_inflow」大单、「today_middle_inflow」中单、「today_small_inflow」小单通过这三类资金的流向可判断市场情绪如果小单净流入激增说明散户跟风严重主力可能随时出货。4. 资金运用的核心逻辑实战重点记住一句话主力资金主导趋势超大单决定节奏中小单反映情绪。举个实战例子某股票主力资金净流入1亿超大单净流入8000万大单净流入2000万中单、小单净流出——说明主力在快速建仓中小散户在卖出此时是量化策略的介入时机反之主力净流出1亿超大单净流出8000万小单净流入激增——说明主力出货散户接盘需立即止损。这也是我们为什么要爬取、存储这些资金数据只有掌握资金的流向和运用逻辑才能让量化策略摆脱“只看异动、不看本质”的误区提升胜率。二、核心前提3个关键组件资金数据落地的基础想要实现股票资金数据的爬取与存储必须先搞定「存储→实体→枚举」三大组件给定的Do类直接复用这是数据闭环的基础——SQL表负责存储资金历史数据Do类映射数据库表枚举类统一管理资金类型三者联动才能确保数据抓取、解析、存储无缝衔接。以下组件均为实战可运行版本给定的代码直接复制使用无需修改重点讲解使用方法和核心细节。1. SQL表设计stock_bk_money_history板块资金注入历史表核心作用存储板块、概念、地域、股票四个维度的资金注入历史数据包含主力、超大单、大单等所有核心资金字段适配后续策略回测、资金流向分析索引优化到位查询效率拉满给定SQL直接执行。CREATE TABLE stock_bk_money_history ( id int NOT NULL AUTO_INCREMENT COMMENT id编号, bk_code varchar(20) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT 版块编号, bk_name varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT 版块名称, curr_date timestamp NULL DEFAULT NULL COMMENT 当前日期, type int DEFAULT 1 COMMENT 类型 1是版块 2是 概念 3是地域 4是股票, bk_now_price decimal(10,4) DEFAULT NULL COMMENT 最新价, bk_now_proportion varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT 版块涨跌比例, market varchar(20) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT 市场, today_main_inflow varchar(30) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT 今日主力净注入净额, today_main_inflow_proportion varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT 今日主力净注入净额 占比, today_super_inflow varchar(30) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT 今日 超大净注入净额, today_super_inflow_proportion varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT 今日 超大净注入净额 占比, today_more_inflow varchar(30) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT 今日 大单净注入净额, today_more_inflow_proportion varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT 今日 大单净注入净额 占比, today_middle_inflow varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT 今日 中单净注入净额, today_middle_inflow_proportion varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT 今日 中单净注入净额 占比, today_small_inflow varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT 今日 小单净注入净额, today_small_inflow_proportion varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT 今日 小单净注入净额 占比, today_main_inflow_code varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT 今日主力净注入股票编码, today_main_inflow_name varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT 今日主力净注入股票名称, sort_num int DEFAULT NULL COMMENT 排序顺序, PRIMARY KEY (id) USING BTREE, KEY idx_stock_bk_money_history_1 (bk_code,curr_date) USING BTREE, KEY stock_bk_money_history_type_IDX (type,curr_date) USING BTREE ) ENGINEInnoDB AUTO_INCREMENT2639449 DEFAULT CHARSETutf8mb3 ROW_FORMATDYNAMIC COMMENT版块资金注入历史;关键说明① 支持4种类型板块/概念/地域/股票适配多维度资金分析② 字段全面覆盖所有资金流向指标同时包含最新价、涨跌比例可联动行情数据③ 双索引优化按“板块编码日期”“类型日期”查询适配策略回测和多维度分析大幅提升查询效率④ 字段类型适配资金数据特点避免数据精度丢失或存储失败。2. Do实体类StockBkMoneyHistoryDo适配MyBatis-Plus给定直接用核心作用映射stock_bk_money_history表适配MyBatis-Plus实现资金数据的CRUD操作无需手动编写SQL直接调用BaseMapper即可完成资金数据的存储与查询节省开发时间。给定的Do类已完善所有字段映射、数据转换和工具方法重点讲解2个核心亮点和使用方法Data EqualsAndHashCode(callSuper false) TableName(stock_bk_money_history) public class StockBkMoneyHistoryDo implements Serializable { private static final long serialVersionUID 1L; /** * id编号 */ TableId(value id, type IdType.AUTO) private Integer id; /** * 板块编号 */ TableField(bk_code) private String bkCode; /** * 板块名称 */ TableField(bk_name) private String bkName; /** * 当前日期 */ TableField(curr_date) private Date currentDate; /** * 类型 1是板块 2是 概念 3是地域 4是股票列表 */ TableField(type) private Integer type; /** * 最新价 */ TableField(bk_now_price) private BigDecimal bkNowPrice; /** * 板块涨跌比例 */ TableField(bk_now_proportion) private String bkNowProportion; /** * 市场 */ TableField(market) private String market; /** * 今日主力净注入净额 */ TableField(today_main_inflow) private String todayMainInflow; /** * 今日主力净注入净额 占比 */ TableField(today_main_inflow_proportion) private String todayMainInflowProportion; /** * 今日 超大净注入净额 */ TableField(today_super_inflow) private String todaySuperInflow; /** * 今日 超大净注入净额 占比 */ TableField(today_super_inflow_proportion) private String todaySuperInflowProportion; /** * 今日 大单净注入净额 */ TableField(today_more_inflow) private String todayMoreInflow; /** * 今日 大单净注入净额 占比 */ TableField(today_more_inflow_proportion) private String todayMoreInflowProportion; /** * 今日 中单净注入净额 */ TableField(today_middle_inflow) private String todayMiddleInflow; /** * 今日 中单净注入净额 占比 */ TableField(today_middle_inflow_proportion) private String todayMiddleInflowProportion; /** * 今日 小单净注入净额 */ TableField(today_small_inflow) private String todaySmallInflow; /** * 今日 小单净注入净额 占比 */ TableField(today_small_inflow_proportion) private String todaySmallInflowProportion; /** * 今日主力净注入股票编码 */ TableField(today_main_inflow_code) private String todayMainInflowCode; /** * 今日主力净注入股票名称 */ TableField(today_main_inflow_name) private String todayMainInflowName; /** * 排序 */ TableField(sort_num) private Integer sortNum; TableField(exist false) private Boolean convertData true; TableField(exist false) Schema(description ai消息) private String aiMessage; public StockBkMoneyHistoryDo convertData(Boolean convertData) { this.convertData convertData; return this; } public String getTodayMainInflow() { return convertData(todayMainInflow); } public String getTodaySuperInflow() { return convertData(todaySuperInflow); } public String getTodayMoreInflow() { return convertData(todayMoreInflow); } public String getTodayMiddleInflow() { return convertData(todayMiddleInflow); } public String getTodaySmallInflow() { return convertData(todaySmallInflow); } public String convertData(String value) { return value; } public String getAiMessage() { return 主力净注入净额: todayMainInflow 主力净注入净额占比: todayMainInflowProportion 超大净注入净额: todaySuperInflow 超大净注入净额占比: todaySuperInflowProportion 大单净注入净额: todayMoreInflow 大单净注入净额占比: todayMoreInflowProportion 中单净注入净额: todayMiddleInflow 中单净注入净额占比: todayMiddleInflowProportion; } }✅ 核心亮点使用说明① 字段完全映射SQL表无需修改直接复制到项目entity包下确保MyBatis-Plus依赖配置正确即可使用② 内置数据转换方法convertData可根据需求扩展数据格式比如将资金净额转换为万元/亿元适配展示需求③ 自动生成AI消息getAiMessage可直接用于策略提醒、数据展示无需额外拼接字符串④ 非数据库字段convertData、aiMessage标注TableField(exist false)避免MyBatis-Plus查询报错。3. 补充枚举BKType资金类型枚举适配爬取代码核心作用统一管理4种资金类型板块/概念/地域/股票封装类型code和中文描述与爬取代码、Do类的type字段联动避免硬编码减少解析错误适配多维度资金抓取。/** * 资金类型枚举适配stock_bk_money_history表的type字段 * 对应关系1-板块 2-概念 3-地域 4-股票 */ public enum BKType { BK(1, 板块), CONCEPT(2, 概念), REGION(3, 地域), STOCK(4, 股票); private Integer code; private String desc; // 根据code获取枚举对象核心方法用于爬取代码联动 public static BKType getByCode(Integer code) { for (BKType bkType : BKType.values()) { if (bkType.getCode().equals(code)) { return bkType; } } return null; } // 构造方法getter BKType(Integer code, String desc) { this.code code; this.desc desc; } public Integer getCode() { return code; } public String getDesc() { return desc; } }✅ 使用说明直接复制到项目enum包下与爬取代码中的BKType参数联动确保资金类型的一致性避免type字段赋值错误。三、核心落地某券商资金数据爬取代码避反爬完整可运行搞定了基础组件接下来就是核心的「资金数据爬取」——基于某券商专属资金接口复用前48篇的反爬逻辑实现单股票/板块资金数据的精准抓取、JSONP解析、异常处理确保数据抓取稳定、不中断给定的爬取代码已完善核心逻辑重点拆解使用方法和反爬重点。以下所有爬取、解析代码均为实战可运行版本直接复制到项目对应包下注入相关依赖即可运行全程拆解关键细节新手也能看懂。1. 核心接口Controller层接收请求返回资金数据作用接收前端/策略的请求传入股票编码调用Service层方法获取并处理资金数据返回标准化结果适配策略调用或前端展示。/** * 股票/板块资金数据Controller * 核心功能接收请求返回今日资金流向详细数据 */ RestController RequestMapping(/stock/money) public class StockMoneyController { Autowired private StockMoneyService stockMoneyService; /** * 获取今日股票资金流向详细数据 * param code 股票编码6位如600000 * return 今日资金流向列表按时间维度 */ GetMapping(/today) public OutputResultListBKMoneyInfo showTodayMoney(String code) { // 1. 校验股票编码获取真实编码避免输入错误、全称等情况 String realCode stockService.getByCodeOrNameOrFullCode(code).getCode(); // 2. 转换股票编码为某券商接口所需的secid格式如sh600000→0.600000 String secid stockCodeHelper.convertCode(realCode); // 3. 设置资金类型为股票对应BKType.STOCKcode4 BKType bkType BKType.STOCK; // 4. 调用Service层方法抓取今日资金详细数据 ListBKMoneyInfo historyBkMoneyList extCrawlerService.findTodayDetailBkMoneyList(1, secid, bkType); // 5. 数据转换处理适配展示/存储需求可扩展 convertMoneyShow(historyBkMoneyList); // 6. 返回标准化结果 return OutputResult.buildSucc(historyBkMoneyList); } /** * 资金数据转换处理可根据需求扩展 * 示例将资金净额转换为万元单位优化展示效果 */ private void convertMoneyShow(ListBKMoneyInfo historyBkMoneyList) { if (CollUtil.isEmpty(historyBkMoneyList)) { return; } historyBkMoneyList.forEach(info - { // 主力资金净额转换单位元→万元 if (StrUtil.isNotBlank(info.getTodayMainInflow())) { try { BigDecimal mainInflow new BigDecimal(info.getTodayMainInflow()); info.setTodayMainInflow(mainInflow.divide(new BigDecimal(10000), 2, RoundingMode.HALF_UP) 万); } catch (Exception e) { // 异常兜底不影响整体数据 } } // 可继续扩展超大单、大单等资金净额的单位转换 }); } }2. 核心实现Service层爬取逻辑给定代码完善作用拼接某券商资金接口URL处理反爬调用Parser层解析数据异常兜底确保数据抓取稳定是资金爬取的核心逻辑。/** * 某券商资金数据爬取实现类 * 核心功能抓取股票/板块今日资金流向详细数据处理反爬异常兜底 */ Service public class ExtCrawlerServiceImpl implements ExtCrawlerService { Autowired private StockInfoParser stockInfoParser; // 解析器下文会补充 Autowired private HttpClientConfig httpClientConfig; // HttpClient配置反爬用 // 固定回调函数cb参数避免动态变化导致JSONP解析失败反爬关键 private static final String CB_ASYNC_BK yueshushu; Override public ListBKMoneyInfo findTodayDetailBkMoneyList(Integer size, String code, BKType bkType) { // 1. 拼接某券商资金接口URL固定格式动态替换回调函数、secid String urlInfo https://push2.eastmoney.com/api/qt/stock/fflow/kline/get?cb{0}lmt0klt1 fields1f1,f2,f3,f7fields2f51,f52,f53,f54,f55,f56,f57,f58,f59,f60,f61,f62,f63,f64,f65utb2884a393a59ad64002292a3e90d46a5 secid{1}_; // 2. 格式化URL替换回调函数CB_ASYNC_BK和股票secid String url MessageFormat.format(urlInfo, CB_ASYNC_BK, code); // 3. 调用解析方法拼接时间戳反爬关键返回资金数据列表 return parseMoneyTodayDetailInfoList(url MyDateUtil.getTimezone(), bkType); } /** * 解析今日资金详细数据核心方法 * param url 拼接好的接口URL含时间戳 * param bkType 资金类型股票/板块等 * return 解析后的资金数据列表 */ private ListBKMoneyInfo parseMoneyTodayDetailInfoList(String url, BKType bkType) { try { // 1. 发送HTTP请求复用反爬配置避免IP封禁 String content HttpUtil.sendGet(HttpClientConfig.proxyNoUseCloseableHttpClient(), url, buildDfHeaderMap()); // 2. 处理JSONP格式去掉回调函数包裹转换为纯JSON解析关键 content content.substring(CB_ASYNC_BK.length() 1); // 去掉前缀asyncBk( content content.substring(0, content.length() - 2); // 去掉后缀) // 3. 调用Parser层解析JSON数据转换为BKMoneyInfo列表 ListBKMoneyInfo bkMoneyInfos stockInfoParser.parseTodayMoneyDetailInfoList(content); // 4. 给每条资金数据设置类型股票/板块等与Do类联动 if (!CollUtil.isEmpty(bkMoneyInfos)) { bkMoneyInfos.forEach(n - n.setType(bkType.getCode())); } return bkMoneyInfos; } catch (Exception e) { // 5. 异常兜底记录日志返回空列表避免策略崩溃 log.error({} parseMoneyTodayDetailInfoList 获取资金数据出错, ThreadLocalUtils.getIp(), e); return Collections.emptyList(); } } /** * 构建请求头反爬关键模拟真实浏览器请求 */ private MapString, String buildDfHeaderMap() { MapString, String header new HashMap(); header.put(User-Agent, Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36); header.put(Referer, https://finance.eastmoney.com/); header.put(Accept-Encoding, gzip, deflate, br); return header; } }反爬重点必看① 固定回调函数CB_ASYNC_BK避免动态变化导致JSONP解析失败② 拼接时间戳MyDateUtil.getTimezone()模拟真实用户请求避免被接口识别为机器人③ 构建真实请求头User-Agent、Referer进一步提升反爬成功率④ 复用HttpClient代理配置高频抓取时可添加多IP代理彻底规避IP封禁⑤ 异常兜底避免抓取失败导致策略崩溃。3. 核心解析Parser层解析JSON数据给定代码完善作用将接口返回的JSON数据去掉JSONP包裹后解析提取核心资金字段封装为BKMoneyInfo列表适配存储和策略使用给定的解析代码已兼容接口格式重点讲解解析逻辑。/** * 股票资金数据解析器 * 核心功能解析某券商资金接口返回的JSON数据转换为BKMoneyInfo列表 */ Component public class StockInfoParser { /** * 解析今日资金详细数据核心方法 * param content 处理后的纯JSON内容已去掉JSONP回调包裹 * return 解析后的资金数据列表按时间维度 */ public ListBKMoneyInfo parseTodayMoneyDetailInfoList(String content) { // 1. 解析JSON对象 JSONObject jsonObject JSONObject.parseObject(content); // 2. 获取data字段核心数据所在空值校验 JSONObject data jsonObject.getJSONObject(data); if (ObjectUtils.isEmpty(data)) { return Collections.emptyList(); } // 3. 提取股票/板块核心信息编码、名称、市场 String code data.getString(code); String name data.getString(name); Integer market data.getInteger(market); // 4. 获取资金数据列表接口返回的klines字段按时间排序 JSONArray jsonArray data.getJSONArray(klines); if (jsonArray.size() 0) { return Collections.emptyList(); } // 5. 解析每一条资金数据封装为BKMoneyInfo ListBKMoneyInfo result new ArrayList(32); jsonArray.forEach(n - { String singleContent n.toString(); if (StrUtil.isNotBlank(singleContent)) { // 5.1 按逗号分割数据接口返回格式固定splitArr对应不同字段 String[] splitArr singleContent.split(Const.JOB_PARAM_SPLIT); BKMoneyInfo bkMoneyInfo new BKMoneyInfo(); // 5.2 封装基础信息编码、名称、时间 bkMoneyInfo.setBkCode(code); bkMoneyInfo.setBkName(name); // 时间格式转换接口返回格式→标准格式HH:mm:ss bkMoneyInfo.setCurrentDate(DateUtil.parse(splitArr[0], DatePattern.NORM_DATETIME_MINUTE_PATTERN)); bkMoneyInfo.setCurrentDateStr(DateUtil.format(bkMoneyInfo.getCurrentDate(), DatePattern.NORM_DATETIME_MINUTE_PATTERN)); // 5.3 封装价格、涨跌比例可后续补充关联行情数据 bkMoneyInfo.setBkNowPrice(null); bkMoneyInfo.setBkNowProportion(null); // 5.4 封装市场信息1沪市0深市可后续转换为中文 bkMoneyInfo.setMarket(market); // 5.5 封装核心资金数据对应splitArr索引接口返回格式固定 bkMoneyInfo.setTodayMainInflow(splitArr[1]); // 主力净注入净额 bkMoneyInfo.setTodayMainInflowProportion(null); // 占比可后续计算补充 bkMoneyInfo.setTodaySuperInflow(splitArr[5]); // 超大净注入净额 bkMoneyInfo.setTodaySuperInflowProportion(null); bkMoneyInfo.setTodayMoreInflow(splitArr[4]); // 大单净注入净额 bkMoneyInfo.setTodayMoreInflowProportion(null); bkMoneyInfo.setTodayMiddleInflow(splitArr[3]); // 中单净注入净额 bkMoneyInfo.setTodayMiddleInflowProportion(null); bkMoneyInfo.setTodaySmallInflow(splitArr[2]); // 小单净注入净额 bkMoneyInfo.setTodaySmallInflowProportion(null); // 5.6 主力净注入股票编码、名称可后续关联补充 bkMoneyInfo.setTodayMainInflowCode(null); bkMoneyInfo.setTodayMainInflowName(null); // 5.7 添加到结果列表 result.add(bkMoneyInfo); } }); return result; } }✅ 解析重点必看① 接口返回的klines字段是核心数据每条数据按逗号分割splitArr索引对应固定字段1主力、2小单、3中单、4大单、5超大单不可随意修改② 时间格式转换确保时间统一便于后续策略的时间维度分析③ 空值校验和异常规避跳过空数据避免解析报错④ 可扩展补充资金占比计算、市场中文转换1→沪市0→深市、主力净注入股票关联等。补充BKMoneyInfo实体类解析结果封装适配爬取存储用于封装解析后的资金数据适配爬取、解析、策略调用全流程与StockBkMoneyHistoryDo对应可直接转换为Do类存储到数据库Data public class BKMoneyInfo implements Serializable { private static final long serialVersionUID 1L; // 基础信息 private String bkCode; // 板块/股票编码 private String bkName; // 板块/股票名称 private Date currentDate; // 当前日期时间戳 private String currentDateStr; // 当前日期字符串HH:mm:ss便于展示 private Integer type; // 类型对应BKType1-板块4-股票等 // 价格信息 private BigDecimal bkNowPrice; // 最新价 private String bkNowProportion; // 涨跌比例 private Integer market; // 市场1沪市0深市 // 核心资金数据 private String todayMainInflow; // 今日主力净注入净额 private String todayMainInflowProportion; // 主力净注入占比 private String todaySuperInflow; // 今日超大净注入净额 private String todaySuperInflowProportion; // 超大净注入占比 private String todayMoreInflow; // 今日大单净注入净额 private String todayMoreInflowProportion; // 大单净注入占比 private String todayMiddleInflow; // 今日中单净注入净额 private String todayMiddleInflowProportion; // 中单净注入占比 private String todaySmallInflow; // 今日小单净注入净额 private String todaySmallInflowProportion; // 小单净注入占比 // 关联信息 private String todayMainInflowCode; // 今日主力净注入股票编码 private String todayMainInflowName; // 今日主力净注入股票名称 private Integer sortNum; // 排序顺序 }四、实战联动资金数据存储策略使用闭环落地爬取、解析完成后需要将资金数据存储到数据库stock_bk_money_history表同时联动前49篇的短线策略实现「资金流向异动信号股票池」的三维策略闭环以下是核心落地步骤可直接复用。1. 资金数据存储Service层补充核心落地将解析后的BKMoneyInfo列表转换为StockBkMoneyHistoryDo存储到数据库实现资金历史数据的持久化用于后续策略回测、资金流向分析支持批量存储提升效率。Autowired private StockBkMoneyHistoryMapper stockBkMoneyHistoryMapper; // MyBatis-Plus Mapper /** * 存储资金数据到数据库批量存储提升效率 * param bkMoneyInfoList 解析后的资金数据列表 * param currDate 当日日期完整时间戳 */ public void saveBkMoneyData(ListBKMoneyInfo bkMoneyInfoList, Date currDate) { if (CollUtil.isEmpty(bkMoneyInfoList)) { return; } // 转换为StockBkMoneyHistoryDo批量存储 ListStockBkMoneyHistoryDo moneyHistoryDoList bkMoneyInfoList.stream().map(info - { StockBkMoneyHistoryDo moneyHistoryDo new StockBkMoneyHistoryDo(); // 基础信息赋值 moneyHistoryDo.setBkCode(info.getBkCode()); moneyHistoryDo.setBkName(info.getBkName()); moneyHistoryDo.setCurrentDate(currDate); // 统一设置当日日期 moneyHistoryDo.setType(info.getType()); // 资金类型1-板块4-股票等 // 价格信息赋值可关联行情数据补充 moneyHistoryDo.setBkNowPrice(info.getBkNowPrice()); moneyHistoryDo.setBkNowProportion(info.getBkNowProportion()); // 市场转换1→沪市0→深市优化存储可读性 moneyHistoryDo.setMarket(info.getMarket() 1 ? 沪市 : 深市); // 核心资金数据赋值 moneyHistoryDo.setTodayMainInflow(info.getTodayMainInflow()); moneyHistoryDo.setTodayMainInflowProportion(info.getTodayMainInflowProportion()); moneyHistoryDo.setTodaySuperInflow(info.getTodaySuperInflow()); moneyHistoryDo.setTodaySuperInflowProportion(info.getTodaySuperInflowProportion()); moneyHistoryDo.setTodayMoreInflow(info.getTodayMoreInflow()); moneyHistoryDo.setTodayMoreInflowProportion(info.getTodayMoreInflowProportion()); moneyHistoryDo.setTodayMiddleInflow(info.getTodayMiddleInflow()); moneyHistoryDo.setTodayMiddleInflowProportion(info.getTodayMiddleInflowProportion()); moneyHistoryDo.setTodaySmallInflow(info.getTodaySmallInflow()); moneyHistoryDo.setTodaySmallInflowProportion(info.getTodaySmallInflowProportion()); // 关联信息赋值可后续补充 moneyHistoryDo.setTodayMainInflowCode(info.getTodayMainInflowCode()); moneyHistoryDo.setTodayMainInflowName(info.getTodayMainInflowName()); moneyHistoryDo.setSortNum(info.getSortNum()); return moneyHistoryDo; }).collect(Collectors.toList()); // 批量插入提升存储效率MyBatis-Plus核心方法 stockBkMoneyHistoryMapper.insertBatchSomeColumn(moneyHistoryDoList); }✅ 存储重点① 统一设置当日日期currDate确保数据的时间一致性便于后续按日期查询② 市场类型转换数字→中文提升数据可读性③ 批量插入避免单条插入效率低下适配高频抓取需求④ 字段一一对应避免存储失败。2. 与量化策略联动实战核心高胜率关键结合前48篇的异动数据、前49篇的短线策略加入资金流向指标实现「三维筛选」大幅提升策略胜率示例如下高胜率短线策略片段/** * 资金异动涨停股池 组合策略短线高胜率 * param ztList 涨停股池列表复用前47篇方法 * param ydList 异动数据列表复用前48篇方法 * param moneyList 资金数据列表本篇方法 * return 筛选后的优质标的 */ public ListStrategyStockInfo moneyYiDongZtStrategy( ListStockPoolInfo ztList, ListStrategyStockInfo ydList, ListBKMoneyInfo moneyList) { if (CollUtil.isEmpty(ztList) || CollUtil.isEmpty(ydList) || CollUtil.isEmpty(moneyList)) { return Collections.emptyList(); } // 1. 提取涨停股编码用于联动异动、资金数据 SetString ztCodeSet ztList.stream().map(StockPoolInfo::getCode).collect(Collectors.toSet()); // 2. 筛选涨停股 看多异动 主力/超大单双净流入 return ydList.stream() .filter(yd - ztCodeSet.contains(yd.getCode())) // 属于涨停股池 .filter(yd - YiDongType.containsDuo(Collections.singletonList(yd.getType()))) // 看多异动复用前48篇枚举方法 .filter(yd - { // 联动资金数据筛选主力超大单双净流入 BKMoneyInfo moneyInfo moneyList.stream() .filter(m - m.getBkCode().equals(yd.getCode())) .findFirst() .orElse(null); if (moneyInfo null) { return false; } // 主力净流入0超大单净流入0确保资金支撑 return StrUtil.isNotBlank(moneyInfo.getTodayMainInflow()) new BigDecimal(moneyInfo.getTodayMainInflow().replace(万, )).compareTo(BigDecimal.ZERO) 0 StrUtil.isNotBlank(moneyInfo.getTodaySuperInflow()) new BigDecimal(moneyInfo.getTodaySuperInflow().replace(万, )).compareTo(BigDecimal.ZERO) 0; }) .collect(Collectors.toList()); }✅ 策略亮点通过「涨停股池优质标的 看多异动时机信号 资金净流入支撑信号」三维筛选避免假突破、无资金支撑的异动大幅提升短线策略的胜率和盈利能力——这也是我们落地资金数据的核心意义。五、资金爬取存储10大避坑指南⚠️实战必看少走弯路结合实战经验整理了资金数据爬取、解析、存储全流程的10大高频坑每一个都附解决方案帮你避免数据抓取失败、解析报错、存储异常等问题确保资金数据正常落地适配量化策略使用。爬取层面4大坑1. 坑1回调函数cb不固定导致JSONP解析失败✅ 解决严格固定cb为「asyncBk」与爬取代码一致避免动态变化导致解析报错2. 坑2未拼接时间戳被接口识别为机器人请求✅ 解决接口URL必须拼接MyDateUtil.getTimezone()模拟真实用户请求提升爬取成功率3. 坑3未设置请求头高频抓取导致IP封禁✅ 解决必须调用buildDfHeaderMap()方法设置User-Agent、Referer等请求头模拟浏览器请求4. 坑4股票编码未转换为secid接口返回无数据✅ 解决必须通过stockCodeHelper.convertCode()方法将6位股票编码转换为某券商接口所需的secid格式如600000→0.600000。解析层面3大坑5. 坑5splitArr索引对应错误导致资金数据赋值错误✅ 解决牢记接口返回格式splitArr[1]主力、[2]小单、[3]中单、[4]大单、[5]超大单不可随意修改索引6. 坑6未做空值校验导致JSON解析空指针异常✅ 解决解析data、klines字段时先判断是否为空避免空指针解析资金数据时判断singleContent是否非空7. 坑7时间格式未转换导致存储后时间混乱✅ 解决严格使用DateUtil.parse()方法将接口返回的时间转换为标准格式确保时间统一。存储使用层面3大坑8. 坑8资金数据未转换单位存储后可读性差✅ 解决存储前将资金净额转换为万元/亿元单位同时保留原始数据兼顾可读性和策略计算需求9. 坑9未批量存储单条插入效率低高频抓取卡顿✅ 解决严格使用MyBatis-Plus的insertBatchSomeColumn方法批量插入资金数据提升存储效率10. 坑10资金数据与策略未联动单独使用资金信号✅ 解决资金信号必须结合异动、股票池使用比如主力净流入看多异动涨停股避免单一资金信号误判。六、福利领取资金全流程完整代码包免费送为了帮大家快速落地资金数据的爬取、解析、存储与策略联动整理了本次第50篇的完整可运行代码包包含所有代码片段直接导入项目即可运行无需二次开发1. ① SQL表脚本stock_bk_money_history直接执行2. ② 所有实体类/枚举类StockBkMoneyHistoryDo、BKMoneyInfo、BKType3. ③ 爬取解析完整代码ControllerServiceParser含反爬优化4. ④ 数据存储策略联动代码直接嵌入量化项目5. ⑤ 避坑手册图文版含常见问题解决方案。私信回复【资金爬取完整代码】即可免费领取所有代码均注释完善适配最新某券商接口兼容前49篇的量化框架新手也能快速上手打通资金数据全流程。下期预告✨第50篇我们搞定了股票资金数据的全落地实现了「资金异动股票池」的三维策略闭环下一篇第51篇我们将聚焦 获取当前全市场的股票实时数据。结尾互动你在爬取股票资金数据时有没有踩过IP封禁、解析报错、存储失败的坑需要我提前补充「多IP代理配置代码」帮你彻底规避反爬风险吗欢迎在评论区留言讨论如果觉得这篇文章对你有帮助别忘了点赞在看转发让更多量化开发者少走弯路一起完善自己的量化交易体系 关注我持续解锁Java量化实战干货#金亥跃江聊量化 #股票量化 #金亥跃江 #Java量化